[
  {
    "path": ".clang-format",
    "content": "# The style used for all options not specifically set in the configuration.\nBasedOnStyle: LLVM\n\n# The extra indent or outdent of access modifiers, e.g. public:.\nAccessModifierOffset: -4\n\n# If true, aligns escaped newlines as far left as possible. Otherwise puts them into the right-most column.\nAlignEscapedNewlinesLeft: true\n\n# If true, aligns trailing comments.\nAlignTrailingComments: false\n\n# Allow putting all parameters of a function declaration onto the next line even if BinPackParameters is false.\nAllowAllParametersOfDeclarationOnNextLine: false\n\n# Allows contracting simple braced statements to a single line.\nAllowShortBlocksOnASingleLine: false\n\n# If true, short case labels will be contracted to a single line.\nAllowShortCaseLabelsOnASingleLine: false\n\n# Dependent on the value, int f() { return 0; } can be put on a single line. Possible values: None, Inline, All.\nAllowShortFunctionsOnASingleLine: None\n\n# If true, if (a) return; can be put on a single line.\nAllowShortIfStatementsOnASingleLine: false\n\n# If true, while (true) continue; can be put on a single line.\nAllowShortLoopsOnASingleLine: false\n\n# If true, always break after function definition return types.\nAlwaysBreakAfterDefinitionReturnType: false\n\n# If true, always break before multiline string literals.\nAlwaysBreakBeforeMultilineStrings: false\n\n# If true, always break after the template<...> of a template declaration.\nAlwaysBreakTemplateDeclarations: true\n\n# If false, a function call's arguments will either be all on the same line or will have one line each.\nBinPackArguments: true\n\n# If false, a function declaration's or function definition's parameters will either all be on the same line\n# or will have one line each.\nBinPackParameters: true\n\n# The way to wrap binary operators. Possible values: None, NonAssignment, All.\nBreakBeforeBinaryOperators: None\n\n# The brace breaking style to use. Possible values: Attach, Linux, Stroustrup, Allman, GNU.\nBreakBeforeBraces: Allman\n\n# If true, ternary operators will be placed after line breaks.\nBreakBeforeTernaryOperators: false\n\n# Always break constructor initializers before commas and align the commas with the colon.\nBreakConstructorInitializersBeforeComma: true\n\n# The column limit. A column limit of 0 means that there is no column limit.\nColumnLimit: 120\n\n# A regular expression that describes comments with special meaning, which should not be split into lines or otherwise changed.\nCommentPragmas: '^ *'\n\n# If the constructor initializers don't fit on a line, put each initializer on its own line.\nConstructorInitializerAllOnOneLineOrOnePerLine: false\n\n# The number of characters to use for indentation of constructor initializer lists.\nConstructorInitializerIndentWidth: 4\n\n# Indent width for line continuations.\nContinuationIndentWidth: 4\n\n# If true, format braced lists as best suited for C++11 braced lists.\nCpp11BracedListStyle: false\n\n# Disables formatting at all.\nDisableFormat: false\n\n# A vector of macros that should be interpreted as foreach loops instead of as function calls.\n#ForEachMacros: ''\n\n# Indent case labels one level from the switch statement.\n# When false, use the same indentation level as for the switch statement.\n# Switch statement body is always indented one level more than case labels.\nIndentCaseLabels: false\n\n# The number of columns to use for indentation.\nIndentWidth: 4\n\n# Indent if a function definition or declaration is wrapped after the type.\nIndentWrappedFunctionNames: false\n\n# If true, empty lines at the start of blocks are kept.\nKeepEmptyLinesAtTheStartOfBlocks: true\n\n# Language, this format style is targeted at. Possible values: None, Cpp, Java, JavaScript, Proto.\nLanguage: Cpp\n\n# The maximum number of consecutive empty lines to keep.\nMaxEmptyLinesToKeep: 1\n\n# The indentation used for namespaces. Possible values: None, Inner, All.\nNamespaceIndentation: None\n\n# The penalty for breaking a function call after \"call(\".\nPenaltyBreakBeforeFirstCallParameter: 19\n\n# The penalty for each line break introduced inside a comment.\nPenaltyBreakComment: 300\n\n# The penalty for breaking before the first <<.\nPenaltyBreakFirstLessLess: 120\n\n# The penalty for each line break introduced inside a string literal.\nPenaltyBreakString: 1000\n\n# The penalty for each character outside of the column limit.\nPenaltyExcessCharacter: 1000000\n\n# Penalty for putting the return type of a function onto its own line.\nPenaltyReturnTypeOnItsOwnLine: 1000000000\n\n# Pointer and reference alignment style. Possible values: Left, Right, Middle.\nPointerAlignment: Right\n\n# If true, a space may be inserted after C style casts.\nSpaceAfterCStyleCast: false\n\n# If false, spaces will be removed before assignment operators.\nSpaceBeforeAssignmentOperators: true\n\n# Defines in which cases to put a space before opening parentheses. Possible values: Never, ControlStatements, Always.\nSpaceBeforeParens: ControlStatements\n\n# If true, spaces may be inserted into '()'.\nSpaceInEmptyParentheses: false\n\n# The number of spaces before trailing line comments (// - comments).\nSpacesBeforeTrailingComments: 1\n\n# If true, spaces will be inserted after '<' and before '>' in template argument lists.\nSpacesInAngles: false\n\n# If true, spaces may be inserted into C style casts.\nSpacesInCStyleCastParentheses: false\n\n# If true, spaces are inserted inside container literals (e.g. ObjC and Javascript array and dict literals).\nSpacesInContainerLiterals: false\n\n# If true, spaces will be inserted after '(' and before ')'.\nSpacesInParentheses: false\n\n# If true, spaces will be inserted after '[' and befor']'.\nSpacesInSquareBrackets: false\n\n# Format compatible with this standard, e.g. use A<A<int> > instead of A<A<int>> for LS_Cpp03. Possible values: Cpp03, Cpp11, Auto.\nStandard: Cpp11\n\n# The number of columns used for tab stops.\nTabWidth: 4\n\n# The way to use tab characters in the resulting file. Possible values: Never, ForIndentation, Always.\nUseTab: ForIndentation\n\n# Do not reflow comments\nReflowComments: false\n"
  },
  {
    "path": ".gitattributes",
    "content": "shaders/**/* linguist-language=GLSL\nreference/**/* linguist-generated\n"
  },
  {
    "path": ".gitignore",
    "content": "/cmake-build-debug\n/cmake-build-release\n*.iml\n/.idea\n/.vs\n/.vscode\n/external/dxc*\n/external/DirectXShaderCompiler\n/external/llvm\n/shaders-dxil\n/shaders-dxbc\n/reference/shaders-dxil\n/reference/shaders-dxbc\n/build\n/out/build\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"third_party/spirv-headers\"]\n\tpath = third_party/spirv-headers\n\turl = https://github.com/KhronosGroup/SPIRV-Headers\n[submodule \"third_party/SPIRV-Tools\"]\n\tpath = third_party/SPIRV-Tools\n\turl = https://github.com/KhronosGroup/SPIRV-Tools\n[submodule \"third_party/SPIRV-Cross\"]\n\tpath = third_party/SPIRV-Cross\n\turl = https://github.com/KhronosGroup/SPIRV-Cross\n[submodule \"third_party/dxbc-spirv\"]\n\tpath = subprojects/dxbc-spirv\n\turl = https://github.com/doitsujin/dxbc-spirv\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "#\n# Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n#\n# SPDX-License-Identifier: MIT\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\ncmake_minimum_required(VERSION 3.10)\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_C_STANDARD 99)\nproject(dxil-spirv LANGUAGES CXX C)\n\nadd_library(dxil-debug STATIC debug/logging.hpp debug/logging.cpp)\ntarget_include_directories(dxil-debug PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/debug)\nset_target_properties(dxil-debug PROPERTIES POSITION_INDEPENDENT_CODE ON)\n\noption(DXIL_SPIRV_CLI \"Enable CLI support.\" ON)\noption(DXIL_SPIRV_NATIVE_LLVM \"Enable native LLVM support.\" OFF)\n\ninclude(GNUInstallDirs)\n\nif (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES \"Clang\"))\n    set(DXIL_SPV_CXX_FLAGS -Wall -Wextra -Wno-missing-field-initializers -Wno-empty-body -Wno-unused-parameter -fno-exceptions -fno-rtti -fvisibility=hidden)\nelseif (MSVC)\n    set(DXIL_SPV_CXX_FLAGS /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4244 /wd4267 /wd4244 /wd4309 /wd4005 /MP /DNOMINMAX)\nendif()\n\nadd_library(dxil-utils STATIC util/thread_local_allocator.hpp util/thread_local_allocator.cpp)\ntarget_include_directories(dxil-utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/util)\ntarget_compile_options(dxil-utils PRIVATE ${DXIL_SPV_CXX_FLAGS})\nset_target_properties(dxil-utils PROPERTIES POSITION_INDEPENDENT_CODE ON)\n\nadd_subdirectory(third_party EXCLUDE_FROM_ALL)\nadd_subdirectory(bc EXCLUDE_FROM_ALL)\nadd_subdirectory(external EXCLUDE_FROM_ALL)\n\nadd_library(spirv-module STATIC\n        ir.hpp\n        descriptor_qa.cpp descriptor_qa.hpp\n        spirv_module.hpp spirv_module.cpp\n        spirv_module_instrumentation.hpp spirv_module_instrumentation.cpp)\nset_target_properties(spirv-module PROPERTIES POSITION_INDEPENDENT_CODE ON)\ntarget_include_directories(spirv-module PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\ntarget_link_libraries(spirv-module PUBLIC glslang-spirv-builder dxil-spirv-headers)\ntarget_link_libraries(spirv-module PRIVATE dxil-utils dxil-debug)\ntarget_compile_options(spirv-module PRIVATE ${DXIL_SPV_CXX_FLAGS})\n\nadd_library(dxil-converter STATIC\n        memory_stream.hpp memory_stream.cpp\n        llvm_bitcode_parser.hpp llvm_bitcode_parser.cpp\n        dxil.hpp\n        dxil_converter.hpp dxil_converter.cpp\n        cfg_structurizer.hpp cfg_structurizer.cpp\n        node_pool.hpp node_pool.cpp\n        node.hpp node.cpp\n        dxil_parser.hpp dxil_parser.cpp\n        scratch_pool.hpp\n        opcodes/converter_impl.hpp\n        opcodes/opcodes.hpp\n        opcodes/dxil/dxil_common.hpp opcodes/dxil/dxil_common.cpp\n        opcodes/dxil/dxil_resources.hpp opcodes/dxil/dxil_resources.cpp\n        opcodes/dxil/dxil_compute.hpp opcodes/dxil/dxil_compute.cpp\n        opcodes/dxil/dxil_arithmetic.hpp opcodes/dxil/dxil_arithmetic.cpp\n        opcodes/dxil/dxil_pixel_ops.hpp opcodes/dxil/dxil_pixel_ops.cpp\n        opcodes/dxil/dxil_geometry.hpp opcodes/dxil/dxil_geometry.cpp\n        opcodes/dxil/dxil_tessellation.hpp opcodes/dxil/dxil_tessellation.cpp\n        opcodes/dxil/dxil_waveops.hpp opcodes/dxil/dxil_waveops.cpp\n        opcodes/dxil/dxil_sampling.hpp opcodes/dxil/dxil_sampling.cpp\n        opcodes/dxil/dxil_buffer.hpp opcodes/dxil/dxil_buffer.cpp\n        opcodes/dxil/dxil_ray_tracing.hpp opcodes/dxil/dxil_ray_tracing.cpp\n        opcodes/dxil/dxil_mesh.hpp opcodes/dxil/dxil_mesh.cpp\n        opcodes/dxil/dxil_workgraph.hpp opcodes/dxil/dxil_workgraph.cpp\n        opcodes/dxil/dxil_ags.hpp opcodes/dxil/dxil_ags.cpp\n        opcodes/dxil/dxil_nvapi.hpp opcodes/dxil/dxil_nvapi.cpp\n        opcodes/opcodes_llvm_builtins.hpp opcodes/opcodes_llvm_builtins.cpp\n        opcodes/opcodes_dxil_builtins.hpp opcodes/opcodes_dxil_builtins.cpp)\nset_target_properties(dxil-converter PROPERTIES POSITION_INDEPENDENT_CODE ON)\ntarget_include_directories(dxil-converter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\ntarget_compile_options(dxil-converter PRIVATE ${DXIL_SPV_CXX_FLAGS})\ntarget_link_libraries(dxil-converter PRIVATE dxil-debug external::llvm dxil-utils)\n\ntarget_link_libraries(dxil-converter PUBLIC spirv-module)\n\nadd_library(dxil-spirv-c-shared SHARED dxil_spirv_c.h dxil_spirv_c.cpp)\ntarget_include_directories(dxil-spirv-c-shared\n        PUBLIC\n        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>\n        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/dxil-spirv>)\ntarget_link_libraries(dxil-spirv-c-shared PRIVATE dxil-debug dxil-converter external::llvm dxil-utils)\n\ntarget_compile_options(dxil-spirv-c-shared PRIVATE ${DXIL_SPV_CXX_FLAGS})\ntarget_compile_definitions(dxil-spirv-c-shared PRIVATE DXIL_SPV_EXPORT_SYMBOLS)\nset_target_properties(dxil-spirv-c-shared PROPERTIES PUBLIC_HEADERS dxil_spirv_c.h)\n\nif (WIN32 AND CMAKE_COMPILER_IS_GNUCXX)\n    target_link_libraries(dxil-spirv-c-shared PRIVATE -static gcc stdc++ winpthread)\nendif()\n\n# If we're linking in full LLVM statically, ensure we don't export all LLVM symbols.\nif (NOT MSVC AND DXIL_SPIRV_NATIVE_LLVM)\n    set_target_properties(dxil-spirv-c-shared PROPERTIES LINK_FLAGS \"-Wl,--version-script ${CMAKE_CURRENT_SOURCE_DIR}/link.T\")\nendif()\n\nadd_library(dxil-spirv-c-static STATIC dxil_spirv_c.h dxil_spirv_c.cpp)\ntarget_include_directories(dxil-spirv-c-static\n        PUBLIC\n        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>\n        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/dxil-spirv>)\ntarget_link_libraries(dxil-spirv-c-static PRIVATE dxil-debug dxil-converter external::llvm dxil-utils)\n\ntarget_compile_options(dxil-spirv-c-static PRIVATE ${DXIL_SPV_CXX_FLAGS})\nset_target_properties(dxil-spirv-c-static PROPERTIES PUBLIC_HEADERS dxil_spirv_c.h)\nset_target_properties(dxil-spirv-c-static PROPERTIES POSITION_INDEPENDENT_CODE ON)\n\nif (DXIL_SPIRV_CLI)\n    add_library(cli-parser STATIC\n            third_party/cli_parser/cli_parser.hpp\n            third_party/cli_parser/cli_parser.cpp)\n    target_include_directories(cli-parser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/third_party/cli_parser)\n    target_link_libraries(cli-parser PUBLIC dxil-debug)\n    target_compile_options(cli-parser PRIVATE ${DXIL_SPV_CXX_FLAGS})\n\n    add_executable(dxil-spirv dxil_spirv.cpp)\n    add_executable(dxil-extract dxil_extract.cpp)\n    target_link_libraries(dxil-spirv PRIVATE dxil-spirv-c-shared cli-parser SPIRV-Tools-static spirv-cross-c dxil-debug)\n    target_compile_options(dxil-spirv PRIVATE ${DXIL_SPV_CXX_FLAGS})\n    target_link_libraries(dxil-extract PRIVATE dxil-spirv-c-shared cli-parser external::llvm)\n    target_compile_options(dxil-extract PRIVATE ${DXIL_SPV_CXX_FLAGS})\n\n    if (WIN32 AND CMAKE_COMPILER_IS_GNUCXX)\n        target_link_libraries(dxil-spirv PRIVATE -static gcc stdc++ winpthread)\n        target_link_libraries(dxil-extract PRIVATE -static gcc stdc++ winpthread)\n    endif()\n\n    if (NOT DXIL_SPV_NATIVE_LLVM)\n        add_executable(dxbc-spirv-sandbox dxbc_spirv_sandbox.cpp)\n        target_link_libraries(dxbc-spirv-sandbox PRIVATE\n                dxil-utils dxil-debug llvm-bc dxil-converter\n                dxbc-spirv dxbc-spirv-test\n                spirv-cross-c SPIRV-Tools-static)\n    endif()\nendif()\n\nset(DXIL_SPV_VERSION_MAJOR 2)\nset(DXIL_SPV_VERSION_MINOR 66)\nset(DXIL_SPV_VERSION_PATCH 0)\nset(DXIL_SPV_VERSION ${DXIL_SPV_VERSION_MAJOR}.${DXIL_SPV_VERSION_MINOR}.${DXIL_SPV_VERSION_PATCH})\nset_target_properties(dxil-spirv-c-shared PROPERTIES\n        VERSION ${DXIL_SPV_VERSION}\n        SOVERSION ${DXIL_SPV_VERSION_MAJOR})\n\nset(DXIL_SPV_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})\nset(DXIL_SPV_INSTALL_INC_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/dxil-spirv)\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/pkg-config/dxil-spirv-c-shared.pc.in\n               ${CMAKE_CURRENT_BINARY_DIR}/dxil-spirv-c-shared.pc @ONLY)\ninstall(FILES ${CMAKE_CURRENT_BINARY_DIR}/dxil-spirv-c-shared.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)\n\nif (DXIL_SPIRV_CLI)\n    install(TARGETS dxil-spirv RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})\n    install(TARGETS dxil-extract RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})\nendif()\ninstall(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dxil_spirv_c.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dxil-spirv)\ninstall(TARGETS dxil-spirv-c-shared\n        EXPORT dxil_spirv_c_sharedConfig\n        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}\n        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}\n        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}\n        PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dxil-spirv)\ninstall(EXPORT dxil_spirv_c_sharedConfig DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/dxil_spirv_c_shared/cmake)\n\noption(DXIL_SPV_MISC_CLI \"Enable misc CLI apps.\" OFF)\n\nif (DXIL_SPV_MISC_CLI)\n    add_executable(structurize-test misc/structurize_test.cpp)\n    target_link_libraries(structurize-test PRIVATE dxil-converter SPIRV-Tools-static spirv-cross-c dxil-debug dxil-utils)\n    target_compile_options(structurize-test PRIVATE ${DXIL_SPV_CXX_FLAGS})\nendif()\n"
  },
  {
    "path": "DESCRIPTORS.md",
    "content": "# Full SM 6.0+ descriptor compatibility in Vulkan\n\nIn this document, I aim to rethink how we implement descriptors.\nThe goal is to efficiently implement descriptors even in bindless scenarios, i.e. SM 5.1/6.0+.\n\n## Descriptor heaps in D3D12\n\nThe API lets you allocate a descriptor heap with N elements. Each element can be a SRV, UAV or CBV or any arbitrary type.\nThe API exposes some kind of \"stride\" here, which implies that max(sizeof(SRV), sizeof(UAV), sizeof(CBV)) is some value, i.e. 32 on drivers I've tested.\n\n## Root signatures\n\nHere we can specify up to 64 DWORDs (256 bytes) which gets passed to the shader.\n\n- Descriptor table pointer: 1 DWORD, (not two? interesting ...)\n- Root descriptor (UAV/CBV), apparently not bounds checked? (2 DWORD)\n- Root constants (1 DWORD each)\n\nFirst thought that comes to mind is that a descriptor table pointer can correlate to a descriptor set, but this will not work.\nWe only have 8 descriptor sets available. (4 is technically min-spec, but only some mobile chips expose that. I think it's fair to rely on 8.)\n\n### Descriptor table pointer as an offset\n\nA weird design of D3D12 is SetDescriptorHeaps which lets you bind only two heaps, one SRV/CBV/UAV heap and one SAMPLER heap, and all descriptor table pointers\nmust refer to one of these.\nLooking at the descriptor table pointer only taking 1 DWORD this starts making sense. We should just encode offsets here into the two heaps.\n\nSetDesciptorHeaps now becomes vkCmdBindDescriptorSets directly. The root signature becomes push constants (for 256 byte implementations),\nor spills into a versioned uniform buffer (for 128 byte implementations and root sig > 128 bytes, which should be rare).\n\n### Descriptor types\n\nWhile descriptor types are kind of irrelevant in D3D12 inside heaps, we have very particular types in Vulkan.\n`SAMPLED_IMAGE`, `UNIFORM_TEXEL_BUFFER`, `STORAGE_TEXEL_BUFFER`, `UNIFORM_BUFFER` and friends. Ideally, we'd have a \"GENERAL\" descriptor type which could be anything and we'd save on a lot of bloat in this scenario.\n\nWith a descriptor heap, we do not know the root signature yet, so we have two choices on how to allocate the descriptors, either with `VARIABLE_COUNT` or not.\nWith `VARIABLE_COUNT` we can declare descriptor set layouts which have the maximum number of bindings we expect to support (At least 1M according to Tier2),\nand then allocating the descriptor pools we can allocate just the right amount of descriptors. This seems like the correct approach.\nTwo effects of this is that each descriptor type must live in their own descriptor sets, as only one descriptor binding can have VARYING count.\n\nSo far, we thus have 6 descriptor set layouts which will be common across all pipelines. Each set contains one binding, with VARYING size array of that type.\n\n- Set0: `SAMPLED_IMAGE` - Texture\n- Set1: `UNIFORM_TEXEL_BUFFER` - TypedBuffer, StructuredBuffer, ByteAddressBuffer\n- Set2: `STORAGE_TEXEL_BUFFER` - RWTypedBuffer, RWStructuredBuffer, RWByteAddressBuffer. Descriptors come in pairs of two, the odd indices can deal with UAV counters.\n- Set3: `STORAGE_IMAGE`\n- Set4: `UNIFORM_BUFFER`\n- Set5: `SAMPLER`\n\nThis leaves three sets which can be derived from a root signature directly. These include:\n\n- Set6: Immutable samplers. It's useful to keep these in their own set since we don't have to deal with push descriptor restrictions of having to push immutable samplers\n(and thus having to keep track of them as well).\n\n- Set4 (reuse `UNIFORM_BUFFER` set): Virtualized bindings. These are bindings we have to repack from descriptor heaps to support implementations with few CBVs (like older Nvidia cards).\nDue to RS 1.0 volatile descriptor behavior (descriptor needs only be valid in GPU timeline and can change anytime)\nwe need to defer the actual vkUpdateDescriptorSet calls to QueueSubmit() time. Using a descriptor update template here would be nice!\nVirtualized bindings is currently the *only* path used by vkd3d and it crumbles down for any interesting uses of SM 5.1 and up, i.e. larger arrays of resources.\nIf we use virtualized descriptors, we can pilfer the set used for uniform buffers as that's the descriptor type we're going to virtualize anyways.\n\n- Set7 (reuse `UNIFORM_BUFFER` set): Versioned push descriptor set. Here we can place:\n- Root constants which spill outside maxPushConstantSize\n- Root descriptors\n\nFor implementations which don't support push descriptors, we can fallback to a versioned descriptor set instead, just like vkd3d does.\n\n#### Why not `STORAGE_BUFFER` for buffer UAVs?\n\nAlignment is a big issue for SSBOs, especially on Nvidia. StructuredBuffers can be bound at very awkward alignments and only `STORAGE_TEXEL_BUFFER` of R32UI can express those.\nThis might lead us into an awkward path when dealing with 16-bit load/store in SM 6.2. Using physical storage buffers (PSB) for untyped buffers would be great, but we need to consider out-of-bounds behavior, which PSB does not support. Also, if we go the PSB route, we will have another indirection to consider. Since rather than going:\n\n- Load UAV descriptor\n- Load/Store data\n\nwe end up with:\n\n- Load CBV/UAV descriptor\n- Load PSB pointer\n- Load/store data\n\n## Sample shader\n\n```\nlayout(push_constant) uniform RootConstants\n{\n\tuint descriptor_table_offset0;\n\tuint descriptor_table_offset1;\n\tuint descriptor_table_offset2;\n\tuint descriptor_table_offset3;\n\tuint root_constant0;\n\tuint root_constant1;\n\tuint root_constant2;\n\tuint root_constant3;\n} root;\n\n// We can alias descriptors.\nlayout(set = 0, binding = 0) uniform texture2D Tex2D[];\nlayout(set = 0, binding = 0) uniform texture3D Tex3D[];\n\nlayout(set = 1, binding = 0) textureBuffer TypedBuffers[];\nlayout(set = 1, binding = 0) textureBuffer StructuredBuffers[];\nlayout(set = 1, binding = 0) textureBuffer ByteAddressBuffers[];\n\nlayout(set = 2, binding = 0) imageBuffer RWTypedBuffers[];\nlayout(set = 2, binding = 1, r32ui) uimageBuffer RWStructureBuffers[];\nlayout(set = 2, binding = 2, r32ui) uimageBuffer RWByteAddressBuffers[];\n\nlayout(set = 3, binding = 0) uniform image2D RWTex2D[];\nlayout(set = 3, binding = 0) uniform image3D RWTex3D[];\n\n#if SUPPORTS_MANY_CBVS\nlayout(set = 4, binding = 0, std140) uniform UBOs\n{\n\tvec4 data[MAX_SIZE];\n} CBV[];\n#else\n// Versioned descriptors.\nlayout(set = 4, binding = 0, std140) uniform UBO0\n{\n\tvec4 data[MAX_SIZE];\n} ubo0;\nlayout(set = 4, binding = 1, std140) uniform UBO0\n{\n\tvec4 data[MAX_SIZE];\n} ubo0;\n#endif\n\nlayout(set = 5, binding = 0) uniform sampler DynamicSamplers[];\nlayout(set = 6, binding = 0) uniform sampler ImmutableSampler0;\nlayout(set = 6, binding = 1) uniform sampler ImmutableSampler1;\nlayout(set = 6, binding = 2) uniform sampler ImmutableSampler2;\n\n// Root descriptors.\nlayout(set = 7, binding = 0) uniform RootCBV0\n{\n\tvec4 data[MAX_SIZE];\n} root_cbv0;\n\nlayout(set = 7, binding = 1) uniform RootCBV1\n{\n\tvec4 data[MAX_SIZE];\n} root_cbv1;\n\nvoid main()\n{\n\tconst uint OffsetIntoRootTable = 42; // This is deduced from D3D12_DESCRIPTOR_RANGE.\n\n\t// descriptor_table_offset is offset into a SetDescriptorHeaps, which we can find by looking at\n\t// SetGraphicsRootDescriptor table compared to SetDescriptorHeaps.\n\t// Tack on nonuniformEXT as required by IL.\n\ttexelFetch(Tex2D[OffsetIntoRootTable + root.descriptor_table_offset1]);\n}\n"
  },
  {
    "path": "LICENSE.MIT",
    "content": "Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n\nSPDX-License-Identifier: MIT\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nFor third_party/bc-decoder:\n\n/******************************************************************************\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2020 Baldur Karlsson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n ******************************************************************************/\n\nFor third_party/glslang-spirv (glslang):\n\n--------------------------------------------------------------------------------\nThe MIT License\n--------------------------------------------------------------------------------\n\nCopyright 2020 The Khronos Group Inc\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n"
  },
  {
    "path": "README.md",
    "content": "# dxil-spirv\n\nThis project aims to provide translation of DXIL (SM 6.x) shaders to SPIR-V which can be used in the vkd3d project,\nwhich implements D3D12 on top of Vulkan.\nUsing [dxbc-spirv](https://github.com/doitsujin/dxbc-spirv) it also handles legacy DXBC shaders.\n\n## Building\n\n### Dependencies\n\nCheck out submodules first with `git submodule update --init --recursive`.\nNo external dependencies apart from the submodules are required to build.\n\nThis project implements a \"small\" LLVM C++ API subset which acts as a drop-in replacement for the full LLVM.\nIt is possible to build against the true LLVM C++ API if llvm is checked out in `external/llvm` and `-DDXIL_SPIRV_NATIVE_LLVM=ON` CMake option is used.\nSee `checkout_llvm.sh` script.\n\n### Build\n\nStandard CMake build.\n\n```shell\nmkdir build\ncd build\ncmake .. -DCMAKE_BUILD_TYPE=Release\ncmake --build . --config Release\n```\n\n## Linking against dxil-spirv\n\nOnly the C API is installed and is expected to be kept ABI/API stable when it releases.\n\n### pkg-config\n\n```shell\npkg-config dxil-spirv-c-shared --cflags --libs\n```\n\n### CMake module\n\nSomething like:\n\n```\nfind_package(dxil_spirv_c_shared)\nif (dxil_spirv_c_shared_FOUND)\n\tmessage(\"Found dxil-spirv! Enabling DXIL support.\")\n\ttarget_link_libraries(vkd3d-shader PRIVATE dxil-spirv-c-shared)\n\ttarget_compile_definitions(vkd3d-shader PRIVATE HAVE_DXIL_SPV)\n\ttarget_sources(vkd3d-shader PRIVATE vkd3d/libs/vkd3d-shader/dxil.c)\nelse()\n\tmessage(\"Did not find dxil-spirv :( Disabling DXIL support.\")\nendif()\n```\n\n## Testing\n\nThe primary method of testing dxil-spirv and avoiding regressions is through a reference shader suite.\n\n### Build DXC\n\nFirst, build DXC. To keep output consistent, we must use a fixed version of DXC.\nCurrently, this only works on Linux, the Windows build of DXC does not seem to support CMake properly.\n\n```shell\n./checkout_dxc.sh\n./build_dxc.sh\n```\n\nThe test suite accepts an arbitrary path to DXC, so if you have a standalone binary somewhere, that can work as well.\n\n### Run test suite\n\nWhen adding new tests, place the HLSL test in `shaders/` somewhere and run:\n\n```shell\n./test_shaders.py shaders --dxc external/dxc-build/bin/dxc --dxil-spirv cmake-build-debug/dxil-spirv\n```\n\nIf there is any mismatch, the test script will complain. If there are legitimate changes to be made,\nadd `--update` to the command. The updated files should now be committed alongside the dxil-spirv change.\n`--parallel` can (and should) be used to speed up the process.\n\nTo update DXBC references, run:\n\n```shell\n./cmake-build-debug/dxbc-spirv-sandbox ./reference-dxbc\n```\n\n### Running large repro suites\n\nFor internal development, we also have an extensive repro suite which cover real-world content.\nThese cannot be made public for obvious reasons, so the intent is that symlinks are set up during development.\nShaders can be dumped with `VKD3D_SHADER_DUMP_PATH`.\n\n```shell\n# The scripts might not work properly if the paths aren't laid out like this.\nln -s ${DXIL_SPIRV_REPO}/shaders shaders-dxil\nln -s ${DXBC_SPIRV_REPO}/shaders shaders-dxbc\nln -s ${DXIL_SPIRV_REPO}/reference/shaders reference/shaders-dxil\nln -s ${DXBC_SPIRV_REPO}/reference/shaders reference/shaders-dxbc\n\n./test_shaders.py shaders-dxil --dxil-spirv cmake-build-release/dxil-spirv --parallel --update\n./test_shaders.py shaders-dxbc --dxil-spirv cmake-build-release/dxil-spirv --parallel --update\n```\n\nTo import shaders into the suite:\n\n```shell\nmkdir shaders-dxil/dxilgame\nmkdir shaders-dxbc/dxbcgame\n# For DXIL\n./copy_reference_shaders.py --dxil /tmp/path/to/vkd3d-shader-dump-path --raw --output shaders-dxil/dxilgame\n# For DXBC\n./copy_reference_shaders.py --dxbc /tmp/path/to/vkd3d-shader-dump-path --raw --output shaders-dxbc/dxbcgame\n```\n\nTo run an isolated subfolder only, there's `--subfolder`.\n\n## License\n\ndxil-spirv is currently licensed as MIT. See LICENSE.MIT for more details.\n\n```c\n/* Copyright (c) 2019-2025 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n```\n\n"
  },
  {
    "path": "bc/CMakeLists.txt",
    "content": "add_library(llvm-bc STATIC\n        cast.hpp iterator.hpp\n        data_structures.hpp\n        value.hpp value.cpp\n        instruction.hpp instruction.cpp\n        function.hpp function.cpp\n        context.hpp context.cpp\n        type.hpp type.cpp\n        module.hpp module.cpp module_dxbc_ir.cpp\n        metadata.hpp metadata.cpp\n        disassembler.cpp)\ntarget_compile_options(llvm-bc PRIVATE ${DXIL_SPV_CXX_FLAGS})\ntarget_compile_definitions(llvm-bc PUBLIC HAVE_LLVMBC)\ntarget_link_libraries(llvm-bc PRIVATE bc-decoder dxil-debug dxil-utils)\ntarget_include_directories(llvm-bc PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\nset_target_properties(llvm-bc PROPERTIES POSITION_INDEPENDENT_CODE ON)\ntarget_link_libraries(llvm-bc PRIVATE dxbc-spirv)\n"
  },
  {
    "path": "bc/cast.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n\n#pragma once\n\n#include \"logging.hpp\"\n#include \"metadata.hpp\"\n#include \"type.hpp\"\n#include \"value.hpp\"\n#include <exception>\n\nnamespace LLVMBC\n{\nstruct ModuleParseContext;\n\ntemplate <typename T>\ninline T *cast(Type *type)\n{\n\tif (type->getTypeID() != T::get_type_id())\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n\treturn static_cast<T *>(type);\n}\n\ntemplate <typename T>\ninline const T *cast(const Type *type)\n{\n\tif (type->getTypeID() != T::get_type_id())\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n\treturn static_cast<const T *>(type);\n}\n\ntemplate <typename T>\ninline T *dyn_cast(Type *type)\n{\n\tif (!type)\n\t\treturn nullptr;\n\n\tif (type->getTypeID() != T::get_type_id())\n\t\treturn nullptr;\n\telse\n\t\treturn static_cast<T *>(type);\n}\n\ntemplate <typename T>\ninline const T *dyn_cast(const Type *type)\n{\n\tif (!type)\n\t\treturn nullptr;\n\n\tif (type->getTypeID() != T::get_type_id())\n\t\treturn nullptr;\n\telse\n\t\treturn static_cast<const T *>(type);\n}\n\ntemplate <typename T>\ninline bool isa(const Type *type)\n{\n\treturn type->getTypeID() == T::get_type_id();\n}\n\nclass ValueProxy : public Value\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Proxy;\n\t}\n\tValueProxy(Type *type, ModuleParseContext &context, uint64_t id);\n\n\tValue *get_proxy_value() const;\n\tbool resolve();\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tuint64_t id;\n\tModuleParseContext &context;\n\tValue *proxy = nullptr;\n};\n\nnamespace Internal\n{\ninline Value *resolve_proxy(Value *value);\ninline const Value *resolve_proxy(const Value *value);\n} // namespace Internal\n\ntemplate <typename T>\ninline T *cast(Value *value)\n{\n\tif (T::get_value_kind() != ValueKind::Proxy)\n\t\tvalue = Internal::resolve_proxy(value);\n\n\tif (T::is_base_of_value_kind(value->get_value_kind()))\n\t\treturn static_cast<T *>(value);\n\telse\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n}\n\ntemplate <typename T>\ninline const T *cast(const Value *value)\n{\n\tif (T::get_value_kind() != ValueKind::Proxy)\n\t\tvalue = Internal::resolve_proxy(value);\n\n\tif (T::is_base_of_value_kind(value->get_value_kind()))\n\t\treturn static_cast<const T *>(value);\n\telse\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n}\n\ntemplate <typename T>\ninline T *dyn_cast(Value *value)\n{\n\tif (!value)\n\t\treturn nullptr;\n\n\tif (T::get_value_kind() != ValueKind::Proxy)\n\t\tvalue = Internal::resolve_proxy(value);\n\n\tif (T::is_base_of_value_kind(value->get_value_kind()))\n\t\treturn static_cast<T *>(value);\n\telse\n\t\treturn nullptr;\n}\n\ntemplate <typename T>\ninline const T *dyn_cast(const Value *value)\n{\n\tif (!value)\n\t\treturn nullptr;\n\n\tif (T::get_value_kind() != ValueKind::Proxy)\n\t\tvalue = Internal::resolve_proxy(value);\n\n\tif (T::is_base_of_value_kind(value->get_value_kind()))\n\t\treturn static_cast<const T *>(value);\n\telse\n\t\treturn nullptr;\n}\n\ntemplate <typename T>\ninline bool isa(const Value *value)\n{\n\tif (T::get_value_kind() != ValueKind::Proxy)\n\t\tvalue = Internal::resolve_proxy(value);\n\n\treturn T::is_base_of_value_kind(value->get_value_kind());\n}\n\nnamespace Internal\n{\ninline Value *resolve_proxy(Value *value)\n{\n\twhile (value && value->get_value_kind() == ValueKind::Proxy)\n\t\tvalue = cast<ValueProxy>(value)->get_proxy_value();\n\treturn value;\n}\n\ninline const Value *resolve_proxy(const Value *value)\n{\n\twhile (value && value->get_value_kind() == ValueKind::Proxy)\n\t\tvalue = cast<ValueProxy>(value)->get_proxy_value();\n\treturn value;\n}\n} // namespace Internal\n\ntemplate <typename T>\ninline T *cast(MDOperand &md)\n{\n\tif (md.get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<T *>(&md);\n\telse\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n}\n\ntemplate <typename T>\ninline T *cast(MDOperand *md)\n{\n\tif (md->get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<T *>(md);\n\telse\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n}\n\ntemplate <typename T>\ninline const T *cast(const MDOperand &md)\n{\n\tif (md.get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<const T *>(&md);\n\telse\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n}\n\ntemplate <typename T>\ninline const T *cast(const MDOperand *md)\n{\n\tif (md->get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<const T *>(md);\n\telse\n\t{\n\t\tLOGE(\"Invalid type ID in cast<T>.\\n\");\n\t\tstd::terminate();\n\t}\n}\n\ntemplate <typename T>\ninline T *dyn_cast(MDOperand &md)\n{\n\tif (md.get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<T *>(&md);\n\telse\n\t\treturn nullptr;\n}\n\ntemplate <typename T>\ninline T *dyn_cast(MDOperand *md)\n{\n\tif (!md)\n\t\treturn nullptr;\n\n\tif (md->get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<T *>(md);\n\telse\n\t\treturn nullptr;\n}\n\ntemplate <typename T>\ninline const T *dyn_cast(const MDOperand &md)\n{\n\tif (md.get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<const T *>(&md);\n\telse\n\t\treturn nullptr;\n}\n\ntemplate <typename T>\ninline const T *dyn_cast(const MDOperand *md)\n{\n\tif (!md)\n\t\treturn nullptr;\n\n\tif (md->get_metadata_kind() == T::get_metadata_kind())\n\t\treturn static_cast<const T *>(md);\n\telse\n\t\treturn nullptr;\n}\n\ntemplate <typename T>\ninline bool isa(const MDOperand &md)\n{\n\treturn md.get_metadata_kind() == T::get_metadata_kind();\n}\n\ntemplate <typename T>\ninline bool isa(const MDOperand *md)\n{\n\treturn md->get_metadata_kind() == T::get_metadata_kind();\n}\n\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/context.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"context.hpp\"\n#include <stdlib.h>\n\nnamespace LLVMBC\n{\nLLVMContext::LLVMContext()\n{\n}\n\nLLVMContext::~LLVMContext()\n{\n\tfor (size_t i = typed_allocations.size(); i; i--)\n\t\ttyped_allocations[i - 1]->run();\n\tfor (size_t i = raw_allocations.size(); i; i--)\n\t\tdxil_spv::free_in_thread(raw_allocations[i - 1]);\n}\n\nvoid *LLVMContext::allocate_from_chain(uintptr_t size, uintptr_t align)\n{\n\tcurrent_block = (current_block + align - 1) & ~(align - 1);\n\tif (current_block + size <= current_block_end)\n\t{\n\t\tvoid *ret = reinterpret_cast<void *>(current_block);\n\t\tcurrent_block += size;\n\t\treturn ret;\n\t}\n\telse\n\t{\n\t\tcurrent_block = 0;\n\t\tcurrent_block_end = 0;\n\t\treturn nullptr;\n\t}\n}\n\nvoid LLVMContext::allocate_new_chain(size_t size, size_t align)\n{\n\tsize_t min_size = size + align;\n\tif (min_size < 64 * 1024)\n\t\tmin_size = 64 * 1024;\n\n\tvoid *ptr = dxil_spv::allocate_in_thread(min_size);\n\tif (ptr)\n\t{\n\t\traw_allocations.push_back(ptr);\n\t\tcurrent_block = reinterpret_cast<uintptr_t>(ptr);\n\t\tcurrent_block_end = current_block + min_size;\n\t}\n\telse\n\t{\n\t\tcurrent_block = 0;\n\t\tcurrent_block_end = 0;\n\t}\n}\n\nvoid *LLVMContext::allocate(size_t size, size_t align)\n{\n\tvoid *ptr = allocate_from_chain(size, align);\n\tif (!ptr)\n\t{\n\t\tallocate_new_chain(size, align);\n\t\tptr = allocate_from_chain(size, align);\n\t}\n\treturn ptr;\n}\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/context.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"data_structures.hpp\"\n#include <exception>\n#include <stdint.h>\n#include <stddef.h>\n\nnamespace LLVMBC\n{\nclass Type;\n\nclass LLVMContext\n{\npublic:\n\tLLVMContext();\n\t~LLVMContext();\n\tvoid operator=(const LLVMContext &) = delete;\n\tLLVMContext(const LLVMContext &) = delete;\n\n\ttemplate <typename T, typename... U>\n\tT *construct(U &&... u)\n\t{\n\t\tT *mem = static_cast<T *>(allocate(sizeof(T), alignof(T)));\n\t\tif (!mem)\n\t\t\tstd::terminate();\n\t\tT *t = new (mem) T(std::forward<U>(u)...);\n\n\t\tif (!std::is_trivially_destructible<T>::value)\n\t\t\tappend_typed_destructor(t);\n\t\treturn t;\n\t}\n\n\ttemplate <typename T, typename... U>\n\tT *construct_n(size_t n, const U &... u)\n\t{\n\t\tT *mem = static_cast<T *>(allocate(sizeof(T) * n, alignof(T)));\n\t\tif (!mem)\n\t\t\tstd::terminate();\n\n\t\tfor (size_t i = 0; i < n; i++)\n\t\t{\n\t\t\tT *tmp = new (&mem[i]) T(u...);\n\t\t\tif (!std::is_trivially_destructible<T>::value)\n\t\t\t\tappend_typed_destructor(tmp);\n\t\t}\n\t\treturn mem;\n\t}\n\n\tVector<Type *> &get_type_cache()\n\t{\n\t\treturn type_cache;\n\t}\n\nprivate:\n\tvoid *allocate(size_t size, size_t align);\n\n\tstruct Deleter\n\t{\n\t\tvirtual ~Deleter() = default;\n\t\tvirtual void run() = 0;\n\t};\n\n\ttemplate <typename T>\n\tstruct TypedDeleter : Deleter\n\t{\n\t\texplicit TypedDeleter(T *ptr_)\n\t\t    : ptr(ptr_)\n\t\t{\n\t\t}\n\t\tvoid run() override\n\t\t{\n\t\t\tptr->~T();\n\t\t}\n\t\tT *ptr;\n\t};\n\n\tuintptr_t current_block = 0;\n\tuintptr_t current_block_end = 0;\n\n\tvoid *allocate_from_chain(uintptr_t size, uintptr_t align);\n\tvoid allocate_new_chain(size_t size, size_t align);\n\n\tVector<void *> raw_allocations;\n\tVector<Deleter *> typed_allocations;\n\tVector<Type *> type_cache;\n\n\ttemplate <typename T, typename... U>\n\tT *construct_trivial(U &&... u)\n\t{\n\t\tT *mem = static_cast<T *>(allocate(sizeof(T), alignof(T)));\n\t\tif (!mem)\n\t\t\tstd::terminate();\n\t\tT *t = new (mem) T(std::forward<U>(u)...);\n\t\treturn t;\n\t}\n\n\ttemplate <typename T>\n\tvoid append_typed_destructor(T *ptr)\n\t{\n\t\ttyped_allocations.push_back(construct_trivial<TypedDeleter<T>>(ptr));\n\t}\n};\n\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/data_structures.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n\nnamespace LLVMBC\n{\ntemplate <typename T>\nusing Vector = dxil_spv::Vector<T>;\ntemplate <typename T>\nusing UnorderedSet = dxil_spv::UnorderedSet<T>;\ntemplate <typename Key, typename Value>\nusing UnorderedMap = dxil_spv::UnorderedMap<Key, Value>;\nusing String = dxil_spv::String;\nusing StringStream = dxil_spv::StringStream;\n}\n"
  },
  {
    "path": "bc/disassembler.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"cast.hpp\"\n#include \"context.hpp\"\n#include \"function.hpp\"\n#include \"instruction.hpp\"\n#include \"metadata.hpp\"\n#include \"module.hpp\"\n#include \"type.hpp\"\n#include \"value.hpp\"\n#include <assert.h>\n#include <sstream>\n#include <type_traits>\n\nnamespace LLVMBC\n{\nstruct StreamState\n{\n\tStringStream stream;\n\tunsigned indent = 0;\n\n\tvoid append(Type *type);\n\tvoid append(IntegerType *type);\n\tvoid append(PointerType *type);\n\tvoid append(ArrayType *type);\n\tvoid append(StructType *type);\n\tvoid append(FunctionType *type);\n\tvoid append(VectorType *type);\n\n\tvoid append(const String &str);\n\tvoid append(Value *value, bool decl = false);\n\tvoid append(GlobalVariable *value, bool decl = false);\n\tvoid append(Instruction *value);\n\tvoid append(Argument *value, bool decl = false);\n\tvoid append(ShuffleVectorInst *shuf, bool decl = false);\n\tvoid append(ExtractElementInst *extr, bool decl = false);\n\tvoid append(InsertElementInst *inst, bool decl = false);\n\tvoid append(Function *value, bool decl = false);\n\tvoid append(BinaryOperator *value, bool decl = false);\n\tvoid append(UnaryOperator *uop, bool decl = false);\n\tvoid append(CallInst *value, bool decl = false);\n\tvoid append(BranchInst *value, bool decl = false);\n\tvoid append(SwitchInst *branch, bool decl = false);\n\tvoid append(ReturnInst *value, bool decl = false);\n\tvoid append(UndefValue *value, bool decl = false);\n\tvoid append(Constant *value, bool decl = false);\n\tvoid append(ConstantInt *value, bool decl = false);\n\tvoid append(ConstantFP *value, bool decl = false);\n\tvoid append(BasicBlock *bb, bool decl = false);\n\tvoid append(FCmpInst *value, bool decl = false);\n\tvoid append(ICmpInst *value, bool decl = false);\n\tvoid append(PHINode *value, bool decl = false);\n\tvoid append(CastInst *value, bool decl = false);\n\tvoid append(SelectInst *value, bool decl = false);\n\tvoid append(ExtractValueInst *value, bool decl = false);\n\tvoid append(AllocaInst *value, bool decl = false);\n\tvoid append(GetElementPtrInst *value, bool decl = false);\n\tvoid append(LoadInst *value, bool decl = false);\n\tvoid append(StoreInst *value, bool decl = false);\n\tvoid append(AtomicRMWInst *value, bool decl = false);\n\tvoid append(AtomicCmpXchgInst *xchg, bool decl = false);\n\tvoid append(ConstantAggregate *agg, bool decl = false);\n\tvoid append(ConstantAggregateZero *zero, bool decl = false);\n\tvoid append(ConstantDataArray *data, bool decl = false);\n\tvoid append(ConstantDataVector *vec, bool decl = false);\n\tvoid append(ConstantExpr *expr, bool decl = false);\n\n\tvoid append(MDOperand *md);\n\tvoid append(NamedMDNode *md);\n\tvoid append(MDNode *md, bool decl = false);\n\n\tvoid append(float v);\n\tvoid append(double v);\n\tvoid append(bool v);\n\tvoid append(const char *str);\n\n\tvoid newline();\n\tvoid newline_noindent();\n\tvoid begin_scope();\n\tvoid end_scope();\n\n\ttemplate <typename T, typename... Ts>\n\tvoid append(T &&t, Ts &&... ts)\n\t{\n\t\tappend(std::forward<T>(t));\n\t\tappend(std::forward<Ts>(ts)...);\n\t}\n\n\t// Only want this overload to trigger on various integer types.\n\ttemplate <typename T>\n\ttypename std::enable_if<std::is_integral<T>::value, void>::type append(T value)\n\t{\n\t\tstream << value;\n\t}\n\n\t// Need this to avoid the generic template to be deduced.\n\ttemplate <size_t N>\n\tvoid append(char (&str)[N])\n\t{\n\t\treturn append(static_cast<const char *>(str));\n\t}\n};\n\nvoid StreamState::append(IntegerType *type)\n{\n\tappend(\"i\", type->getBitWidth());\n}\n\nvoid StreamState::append(StructType *type)\n{\n\tappend(\"{ \");\n\tfor (unsigned i = 0; i < type->getNumElements(); i++)\n\t{\n\t\tappend(type->getElementType(i));\n\t\tif (i + 1 < type->getNumElements())\n\t\t\tappend(\", \");\n\t}\n\tappend(\" }\");\n}\n\nvoid StreamState::append(PointerType *type)\n{\n\tif (type->getAddressSpace() != 0)\n\t\tappend(type->getElementType(), \" addrspace(\", type->getAddressSpace(), \")*\");\n\telse\n\t\tappend(type->getElementType(), \"*\");\n}\n\nvoid StreamState::append(ArrayType *type)\n{\n\tappend(\"[\", type->getArrayNumElements(), \" x \", type->getArrayElementType(), \"]\");\n}\n\nvoid StreamState::append(FunctionType *type)\n{\n\tappend(\"(\", type->getReturnType(), \" (*) (\");\n\tfor (unsigned i = 0; i < type->getNumParams(); i++)\n\t{\n\t\tappend(type->getParamType(i));\n\t\tif (i + 1 < type->getNumParams())\n\t\t\tappend(\", \");\n\t}\n\tappend(\"))\");\n}\n\nvoid StreamState::append(VectorType *type)\n{\n\tappend(type->getElementType(), \"x\", type->getVectorSize());\n}\n\nvoid StreamState::append(bool v)\n{\n\tstream << (v ? \"true\" : \"false\");\n}\n\nvoid StreamState::append(float v)\n{\n\tchar buf[1024];\n\tsprintf(buf, \"%e\", v);\n\tappend(buf);\n}\n\nvoid StreamState::append(double v)\n{\n\tchar buf[1024];\n\tsprintf(buf, \"%e\", v);\n\tappend(buf);\n}\n\nvoid StreamState::newline()\n{\n\tstream << \"\\n\";\n\tfor (unsigned i = 0; i < indent; i++)\n\t\tstream << \"  \";\n}\n\nvoid StreamState::newline_noindent()\n{\n\tstream << \"\\n\";\n}\n\nvoid StreamState::append(const char *str)\n{\n\tstream << str;\n}\n\nvoid StreamState::append(const String &str)\n{\n\tstream << str;\n}\n\nvoid StreamState::begin_scope()\n{\n\tappend(\" {\");\n\tindent++;\n}\n\nvoid StreamState::end_scope()\n{\n\tassert(indent > 0);\n\tindent--;\n\tnewline();\n\tappend(\"}\");\n}\n\nvoid StreamState::append(Type *type)\n{\n\tswitch (type->getTypeID())\n\t{\n\tcase Type::TypeID::IntegerTyID:\n\t\treturn append(cast<IntegerType>(type));\n\tcase Type::TypeID::PointerTyID:\n\t\treturn append(cast<PointerType>(type));\n\tcase Type::TypeID::StructTyID:\n\t\treturn append(cast<StructType>(type));\n\tcase Type::TypeID::ArrayTyID:\n\t\treturn append(cast<ArrayType>(type));\n\tcase Type::TypeID::FunctionTyID:\n\t\treturn append(cast<FunctionType>(type));\n\tcase Type::TypeID::VectorTyID:\n\t\treturn append(cast<VectorType>(type));\n\tcase Type::TypeID::HalfTyID:\n\t\treturn append(\"half\");\n\tcase Type::TypeID::FloatTyID:\n\t\treturn append(\"float\");\n\tcase Type::TypeID::DoubleTyID:\n\t\treturn append(\"double\");\n\tcase Type::TypeID::Unknown:\n\t\treturn append(\"unknown\");\n\tcase Type::TypeID::VoidTyID:\n\t\treturn append(\"void\");\n\tcase Type::TypeID::OpaqueTyID:\n\t\treturn append(\"opaque\");\n\tdefault:\n\t\tbreak;\n\t}\n\n\tLOGE(\"Unknown Type %u.\\n\", unsigned(type->getTypeID()));\n}\n\nvoid StreamState::append(ShuffleVectorInst *shuf, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", shuf->get_tween_id(), \" = shufflevector \", shuf->getType(), \" \", shuf->getOperand(0), \", \", shuf->getOperand(1), \" <\");\n\t\tauto *vec_type = cast<VectorType>(shuf->getType());\n\t\tfor (unsigned i = 0; i < vec_type->getVectorSize(); i++)\n\t\t{\n\t\t\tappend(shuf->getMaskValue(i));\n\t\t\tif (i + 1 < vec_type->getVectorSize())\n\t\t\t\tappend(\", \");\n\t\t}\n\t\tappend(\">\");\n\t}\n\telse\n\t\tappend(\"%\", shuf->get_tween_id());\n}\n\nvoid StreamState::append(ExtractElementInst *extr, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", extr->get_tween_id(), \" = extractelement \",\n\t\t       extr->getType(), \" \", extr->getVectorOperand(), \", \", extr->getIndexOperand());\n\t}\n\telse\n\t\tappend(\"%\", extr->get_tween_id());\n}\n\nvoid StreamState::append(InsertElementInst *inst, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", inst->get_tween_id(), \" = insertelement \",\n\t\t       inst->getOperand(0), \", \", inst->getOperand(1), \", \", inst->getOperand(2));\n\t}\n\telse\n\t\tappend(\"%\", inst->get_tween_id());\n}\n\nvoid StreamState::append(Argument *arg, bool decl)\n{\n\tappend(\"%arg\", arg->getArgNo());\n}\n\nvoid StreamState::append(Function *func, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"define \", func->getType(), \" @\", func->getName(), \"(\");\n\t\tauto *type = func->getFunctionType();\n\t\tfor (unsigned i = 0; i < type->getNumParams(); i++)\n\t\t{\n\t\t\tappend(type->getParamType(i));\n\t\t\tif (i + 1 < type->getNumParams())\n\t\t\t\tappend(\", \");\n\t\t}\n\t\tappend(\")\");\n\n\t\tif (func->begin() != func->end())\n\t\t{\n\t\t\tbegin_scope();\n\t\t\tfor (auto &bb : *func)\n\t\t\t\tappend(&bb, true);\n\t\t\tend_scope();\n\t\t}\n\t}\n\telse\n\t\tappend(\"@\", func->getName());\n}\n\nvoid StreamState::append(GlobalVariable *var, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"@\", var->get_tween_id(), \" = \");\n\n\t\tif (cast<PointerType>(var->getType())->getAddressSpace() != 0)\n\t\t\tappend(\"groupshared \");\n\t\telse\n\t\t\tappend(var->isConstant() ? \"constant\" : \"global\", \" \");\n\t\tappend(var->getType()->getPointerElementType());\n\n\t\tif (var->hasInitializer())\n\t\t\tappend(\" \", var->getInitializer());\n\t\tnewline();\n\t}\n\telse\n\t{\n\t\tappend(\"@\", var->get_tween_id());\n\t}\n}\n\nstatic const char *to_string(BinaryOperator::BinaryOps op)\n{\n\tswitch (op)\n\t{\n#define BINOP(op, str)                  \\\n\tcase BinaryOperator::BinaryOps::op: \\\n\t\treturn str\n\t\tBINOP(InvalidBinaryOp, \"invalid\");\n\t\tBINOP(Add, \"add\");\n\t\tBINOP(FAdd, \"fadd\");\n\t\tBINOP(Sub, \"sub\");\n\t\tBINOP(FSub, \"fsub\");\n\t\tBINOP(Mul, \"mul\");\n\t\tBINOP(FMul, \"fmul\");\n\t\tBINOP(UDiv, \"udiv\");\n\t\tBINOP(SDiv, \"sdiv\");\n\t\tBINOP(FDiv, \"fdiv\");\n\t\tBINOP(URem, \"urem\");\n\t\tBINOP(SRem, \"srem\");\n\t\tBINOP(FRem, \"frem\");\n\t\tBINOP(Shl, \"shl\");\n\t\tBINOP(LShr, \"lshr\");\n\t\tBINOP(AShr, \"ashr\");\n\t\tBINOP(And, \"and\");\n\t\tBINOP(Or, \"or\");\n\t\tBINOP(Xor, \"xor\");\n\t}\n#undef BINOP\n\treturn \"???\";\n}\n\nstatic const char *to_string(UnaryOperator::UnaryOps op)\n{\n\tswitch (op)\n\t{\n\tcase UnaryOperator::UnaryOps::FNeg:\n\t\treturn \"fneg\";\n\tdefault:\n\t\treturn \"invalid\";\n\t}\n}\n\nstatic const char *to_string(Instruction::Predicate pred)\n{\n\tswitch (pred)\n\t{\n#define PRED(op, str)            \\\n\tcase Instruction::FCMP_##op: \\\n\t\treturn str\n\t\tPRED(FALSE, \"false\");\n\t\tPRED(OEQ, \"oeq\");\n\t\tPRED(OGT, \"ogt\");\n\t\tPRED(OGE, \"oge\");\n\t\tPRED(OLT, \"olt\");\n\t\tPRED(OLE, \"ole\");\n\t\tPRED(ONE, \"one\");\n\t\tPRED(ORD, \"ord\");\n\t\tPRED(UNO, \"uno\");\n\t\tPRED(UEQ, \"ueq\");\n\t\tPRED(UGT, \"ugt\");\n\t\tPRED(UGE, \"uge\");\n\t\tPRED(ULT, \"ult\");\n\t\tPRED(ULE, \"ule\");\n\t\tPRED(UNE, \"une\");\n\t\tPRED(TRUE, \"true\");\n#undef PRED\n#define PRED(op, str)            \\\n\tcase Instruction::ICMP_##op: \\\n\t\treturn str\n\t\tPRED(EQ, \"eq\");\n\t\tPRED(NE, \"ne\");\n\t\tPRED(UGT, \"ugt\");\n\t\tPRED(UGE, \"uge\");\n\t\tPRED(ULT, \"ult\");\n\t\tPRED(ULE, \"ule\");\n\t\tPRED(SGT, \"sgt\");\n\t\tPRED(SGE, \"sge\");\n\t\tPRED(SLT, \"slt\");\n\t\tPRED(SLE, \"sle\");\n\t}\n#undef PRED\n\treturn \"???\";\n}\n\nstatic const char *to_string(Instruction::CastOps op)\n{\n\tswitch (op)\n\t{\n#define CAST(op, str)     \\\n\tcase Instruction::op: \\\n\t\treturn str\n\t\tCAST(Trunc, \"trunc\");\n\t\tCAST(ZExt, \"zext\");\n\t\tCAST(SExt, \"sext\");\n\t\tCAST(FPToUI, \"fptoui\");\n\t\tCAST(FPToSI, \"fptosi\");\n\t\tCAST(UIToFP, \"uitofp\");\n\t\tCAST(SIToFP, \"sitofp\");\n\t\tCAST(FPTrunc, \"fptrunc\");\n\t\tCAST(FPExt, \"fpext\");\n\t\tCAST(PtrToInt, \"ptrtoint\");\n\t\tCAST(IntToPtr, \"inttoptr\");\n\t\tCAST(BitCast, \"bitcast\");\n\t\tCAST(AddrSpaceCast, \"addrspacecast\");\n\tdefault:\n\t\tbreak;\n\t}\n#undef CAST\n\treturn \"???\";\n}\n\nstatic const char *to_string(AtomicRMWInst::BinOp op)\n{\n\tswitch (op)\n\t{\n#define RMW(op, str)               \\\n\tcase AtomicRMWInst::BinOp::op: \\\n\t\treturn str\n\t\tRMW(Add, \"add\");\n\t\tRMW(Sub, \"sub\");\n\t\tRMW(Xchg, \"xchg\");\n\t\tRMW(And, \"and\");\n\t\tRMW(Xor, \"xor\");\n\t\tRMW(Or, \"or\");\n\t\tRMW(Nand, \"nand\");\n\t\tRMW(Max, \"max\");\n\t\tRMW(Min, \"min\");\n\t\tRMW(UMax, \"umax\");\n\t\tRMW(UMin, \"umin\");\n\t\tRMW(FAdd, \"fadd\");\n\t\tRMW(FSub, \"fsub\");\n\tdefault:\n\t\tbreak;\n\t}\n#undef RMW\n\treturn \"???\";\n}\n\nvoid StreamState::append(BinaryOperator *binop, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", binop->get_tween_id(), \" = \", to_string(binop->getOpcode()), \" \", binop->getType(), \" \",\n\t\t       binop->getOperand(0), \", \", binop->getOperand(1));\n\t}\n\telse\n\t{\n\t\tappend(\"%\", binop->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(UnaryOperator *uop, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", uop->get_tween_id(), \" = \", to_string(uop->getOpcode()), \" \", uop->getType(), \" \",\n\t\t       uop->getOperand(0), \", \", uop->getOperand(1));\n\t}\n\telse\n\t{\n\t\tappend(\"%\", uop->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(BasicBlock *bb, bool decl)\n{\n\tif (decl)\n\t{\n\t\tnewline_noindent();\n\t\tnewline_noindent();\n\t\tappend(bb->get_tween_id(), \":\");\n\t\tfor (auto &inst : *bb)\n\t\t{\n\t\t\tnewline();\n\t\t\tappend(&inst);\n\t\t}\n\t}\n\telse\n\t{\n\t\tappend(\"label %\", bb->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(FCmpInst *value, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", value->get_tween_id(), \" = fcmp \", to_string(value->getPredicate()), \" \", value->getOperand(0),\n\t\t       \", \", value->getOperand(1));\n\t}\n\telse\n\t{\n\t\tappend(\"%\", value->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(ICmpInst *value, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", value->get_tween_id(), \" = icmp \", to_string(value->getPredicate()), \" \", value->getOperand(0),\n\t\t       \", \", value->getOperand(1));\n\t}\n\telse\n\t{\n\t\tappend(\"%\", value->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(BranchInst *br, bool)\n{\n\tappend(\"br \");\n\tif (br->getCondition())\n\t\tappend(br->getCondition(), \", \", br->getSuccessor(0), \", \", br->getSuccessor(1));\n\telse\n\t\tappend(br->getSuccessor(0));\n}\n\nvoid StreamState::append(SwitchInst *branch, bool)\n{\n\tappend(\"switch \", branch->getCondition(), \", \", branch->getDefaultDest());\n\tbegin_scope();\n\tfor (auto itr = branch->case_begin(); itr != branch->case_end(); ++itr)\n\t{\n\t\tnewline();\n\t\tappend(itr->getCaseValue(), \", \", itr->getCaseSuccessor());\n\t}\n\tend_scope();\n}\n\nvoid StreamState::append(CallInst *call, bool decl)\n{\n\tif (decl)\n\t{\n\t\tif (call->getType()->getTypeID() != Type::TypeID::VoidTyID)\n\t\t\tappend(\"%\", call->get_tween_id(), \" = \");\n\t\tappend(\"call \", call->getType(), \" @\", call->getCalledFunction()->getName(), \"(\");\n\t\tfor (unsigned i = 0; i < call->getNumOperands(); i++)\n\t\t{\n\t\t\tappend(call->getOperand(i));\n\t\t\tif (i + 1 < call->getNumOperands())\n\t\t\t\tappend(\", \");\n\t\t}\n\t\tappend(\")\");\n\n\t\tfor (auto itr = call->metadata_begin(); itr != call->metadata_end(); ++itr)\n\t\t{\n\t\t\tappend(\" !\", itr->first, \" \", itr->second);\n\t\t}\n\t}\n\telse\n\t{\n\t\tappend(\"%\", call->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(CastInst *cast, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", cast->get_tween_id(), \" = \", to_string(cast->getOpcode()), \" \", cast->getOperand(0), \" to \",\n\t\t       cast->getType());\n\t}\n\telse\n\t{\n\t\tappend(\"%\", cast->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(SelectInst *cast, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", cast->get_tween_id(), \" = \", \"select \", cast->getOperand(0), \", \", cast->getOperand(1), \", \",\n\t\t       cast->getOperand(2));\n\t}\n\telse\n\t{\n\t\tappend(\"%\", cast->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(ExtractValueInst *ext, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", ext->get_tween_id(), \" = \", \"extractvalue \", ext->getType(), \" \", ext->getAggregateOperand());\n\t\tfor (unsigned i = 0; i < ext->getNumIndices(); i++)\n\t\t{\n\t\t\tappend(\", \");\n\t\t\tappend(ext->getIndices()[i]);\n\t\t}\n\t}\n\telse\n\t{\n\t\tappend(\"%\", ext->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(AllocaInst *alloca, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", alloca->get_tween_id(), \" = alloca \", cast<PointerType>(alloca->getType())->getElementType());\n\t}\n\telse\n\t{\n\t\tappend(\"%\", alloca->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(GetElementPtrInst *ptr, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", ptr->get_tween_id(), \" = getelementptr \", ptr->isInBounds() ? \"inbounds \" : \"\", ptr->getType());\n\t\tfor (unsigned i = 0; i < ptr->getNumOperands(); i++)\n\t\t{\n\t\t\tappend(\", \");\n\t\t\tappend(ptr->getOperand(i));\n\t\t}\n\t}\n\telse\n\t{\n\t\tappend(\"%\", ptr->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(LoadInst *ptr, bool decl)\n{\n\tif (decl)\n\t\tappend(\"%\", ptr->get_tween_id(), \" = load \", ptr->getType(), \" \", ptr->getPointerOperand());\n\telse\n\t\tappend(\"%\", ptr->get_tween_id());\n}\n\nvoid StreamState::append(StoreInst *ptr, bool decl)\n{\n\tif (decl)\n\t\tappend(\"store \", ptr->getOperand(0), \", \", ptr->getOperand(1));\n\telse\n\t\tappend(\"%\", ptr->get_tween_id());\n}\n\nvoid StreamState::append(AtomicRMWInst *atomic_op, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", atomic_op->get_tween_id(), \" = atomicrmw \", to_string(atomic_op->getOperation()), \" \",\n\t\t       atomic_op->getType(), \" \", atomic_op->getPointerOperand(), \", \", atomic_op->getValOperand());\n\t}\n\telse\n\t\tappend(\"%\", atomic_op->get_tween_id());\n}\n\nvoid StreamState::append(AtomicCmpXchgInst *xchg, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", xchg->get_tween_id(), \" = cmpxchg \", xchg->getType(), \" \", xchg->getPointerOperand(), \", \",\n\t\t       xchg->getCompareOperand(), \", \", xchg->getNewValOperand());\n\t}\n\telse\n\t\tappend(\"%\", xchg->get_tween_id());\n}\n\nvoid StreamState::append(ConstantAggregate *agg, bool)\n{\n\tappend(\"[\");\n\n\tif (agg->getNumOperands())\n\t\tappend(agg->getOperand(0));\n\n\tfor (unsigned i = 1; i < agg->getNumOperands(); i++)\n\t\tappend(\", \", agg->getOperand(i));\n\n\tappend(\"]\");\n}\n\nvoid StreamState::append(ConstantAggregateZero *zero, bool)\n{\n\tappend(\"[zeroinitialized]\");\n}\n\nvoid StreamState::append(ConstantDataArray *arr, bool)\n{\n\tappend(\"[\");\n\tfor (unsigned i = 0; i < arr->getNumElements(); i++)\n\t{\n\t\tappend(arr->getElementAsConstant(i));\n\t\tif (i + 1 < arr->getNumElements())\n\t\t\tappend(\", \");\n\t}\n\tappend(\"]\");\n}\n\nvoid StreamState::append(ConstantDataVector *vec, bool)\n{\n\tappend(\"<\");\n\tfor (unsigned i = 0; i < vec->getNumElements(); i++)\n\t{\n\t\tappend(vec->getElementAsConstant(i));\n\t\tif (i + 1 < vec->getNumElements())\n\t\t\tappend(\", \");\n\t}\n\tappend(\">\");\n}\n\nvoid StreamState::append(ConstantExpr *expr, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", expr->get_tween_id(), \" = \", expr->getOpcode(), \" \", expr->getType());\n\n\t\tif (expr->getNumOperands())\n\t\t\tappend(\" \", expr->getOperand(0));\n\n\t\tfor (unsigned i = 1; i < expr->getNumOperands(); i++)\n\t\t\tappend(\", \", expr->getOperand(i));\n\t}\n\telse\n\t{\n\t\tappend(\"%\", expr->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(PHINode *phi, bool decl)\n{\n\tif (decl)\n\t{\n\t\tappend(\"%\", phi->get_tween_id(), \" = phi \", phi->getType(), \" \");\n\t\tunsigned count = phi->getNumIncomingValues();\n\t\tfor (unsigned i = 0; i < count; i++)\n\t\t{\n\t\t\tValue *value = phi->getIncomingValue(i);\n\t\t\tBasicBlock *bb = phi->getIncomingBlock(i);\n\t\t\tappend(\"[ \", value, \", \", bb, \" ]\");\n\t\t\tif (i + 1 < count)\n\t\t\t\tappend(\", \");\n\t\t}\n\t}\n\telse\n\t{\n\t\tappend(\"%\", phi->get_tween_id());\n\t}\n}\n\nvoid StreamState::append(ReturnInst *value, bool)\n{\n\tif (value->getReturnValue())\n\t\tappend(\"ret \", value);\n\telse\n\t\tappend(\"ret void\");\n}\n\nvoid StreamState::append(UndefValue *undef, bool decl)\n{\n\tappend(undef->getType(), \" undef\");\n}\n\nvoid StreamState::append(ConstantFP *value, bool decl)\n{\n\tappend(value->getValueAPF().convertToDouble());\n}\n\nvoid StreamState::append(ConstantInt *value, bool decl)\n{\n\tappend(value->getType(), \" \", value->getUniqueInteger().getSExtValue());\n}\n\nvoid StreamState::append(Constant *value, bool decl)\n{\n\tappend(static_cast<Value *>(value), decl);\n}\n\nvoid StreamState::append(Instruction *inst)\n{\n\tappend(static_cast<Value *>(inst), true);\n}\n\nvoid StreamState::append(MDNode *md, bool decl)\n{\n\tif (md)\n\t{\n\t\tif (decl)\n\t\t{\n\t\t\tappend(\"!\", md->get_tween_id(), \" = !{\");\n\t\t\tfor (unsigned i = 0; i < md->getNumOperands(); i++)\n\t\t\t{\n\t\t\t\tappend(&md->getOperand(i));\n\t\t\t\tif (i + 1 < md->getNumOperands())\n\t\t\t\t\tappend(\", \");\n\t\t\t}\n\t\t\tappend(\"}\");\n\t\t}\n\t\telse\n\t\t\tappend(\"!\", md->get_tween_id());\n\t}\n\telse\n\t\tappend(\"null\");\n}\n\nvoid StreamState::append(NamedMDNode *md)\n{\n\tappend(\"!\", md->getName(), \" = !{\");\n\tfor (unsigned i = 0; i < md->getNumOperands(); i++)\n\t{\n\t\tappend(md->getOperand(i), false);\n\t\tif (i + 1 < md->getNumOperands())\n\t\t\tappend(\", \");\n\t}\n\n\tappend(\"}\");\n}\n\nvoid StreamState::append(MDOperand *md)\n{\n\tif (md)\n\t{\n\t\tswitch (md->get_metadata_kind())\n\t\t{\n\t\tcase MetadataKind::NamedNode:\n\t\t\treturn append(cast<NamedMDNode>(md));\n\t\tcase MetadataKind::Node:\n\t\t\treturn append(cast<MDNode>(md), false);\n\t\tcase MetadataKind::Constant:\n\t\t\treturn append(cast<ConstantAsMetadata>(md)->getValue());\n\t\tcase MetadataKind::String:\n\t\t\treturn append(\"\\\"\", cast<MDString>(md)->getString(), \"\\\"\");\n\t\tcase MetadataKind::None:\n\t\t\treturn append(\"null\");\n\t\tdefault:\n\t\t\tLOGE(\"Unknown MetadataKind %u.\\n\", unsigned(md->get_metadata_kind()));\n\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t\tappend(\"null\");\n}\n\nvoid StreamState::append(Value *value, bool decl)\n{\n\tswitch (value->get_value_kind())\n\t{\n\tcase ValueKind::Argument:\n\t\treturn append(cast<Argument>(value), decl);\n\tcase ValueKind::Function:\n\t\treturn append(cast<Function>(value), decl);\n\tcase ValueKind::BinaryOperator:\n\t\treturn append(cast<BinaryOperator>(value), decl);\n\tcase ValueKind::UnaryOperator:\n\t\treturn append(cast<UnaryOperator>(value), decl);\n\tcase ValueKind::Call:\n\t\treturn append(cast<CallInst>(value), decl);\n\tcase ValueKind::Branch:\n\t\treturn append(cast<BranchInst>(value), decl);\n\tcase ValueKind::FCmp:\n\t\treturn append(cast<FCmpInst>(value), decl);\n\tcase ValueKind::ICmp:\n\t\treturn append(cast<ICmpInst>(value), decl);\n\tcase ValueKind::Return:\n\t\treturn append(cast<ReturnInst>(value), decl);\n\tcase ValueKind::Undef:\n\t\treturn append(cast<UndefValue>(value), decl);\n\tcase ValueKind::ConstantInt:\n\t\treturn append(cast<ConstantInt>(value), decl);\n\tcase ValueKind::ConstantFP:\n\t\treturn append(cast<ConstantFP>(value), decl);\n\tcase ValueKind::BasicBlock:\n\t\treturn append(cast<BasicBlock>(value), decl);\n\tcase ValueKind::PHI:\n\t\treturn append(cast<PHINode>(value), decl);\n\tcase ValueKind::Cast:\n\t\treturn append(cast<CastInst>(value), decl);\n\tcase ValueKind::Select:\n\t\treturn append(cast<SelectInst>(value), decl);\n\tcase ValueKind::ExtractValue:\n\t\treturn append(cast<ExtractValueInst>(value), decl);\n\tcase ValueKind::Alloca:\n\t\treturn append(cast<AllocaInst>(value), decl);\n\tcase ValueKind::GetElementPtr:\n\t\treturn append(cast<GetElementPtrInst>(value), decl);\n\tcase ValueKind::Load:\n\t\treturn append(cast<LoadInst>(value), decl);\n\tcase ValueKind::Store:\n\t\treturn append(cast<StoreInst>(value), decl);\n\tcase ValueKind::AtomicRMW:\n\t\treturn append(cast<AtomicRMWInst>(value), decl);\n\tcase ValueKind::AtomicCmpXchg:\n\t\treturn append(cast<AtomicCmpXchgInst>(value), decl);\n\tcase ValueKind::Global:\n\t\treturn append(cast<GlobalVariable>(value), decl);\n\tcase ValueKind::ConstantAggregate:\n\t\treturn append(cast<ConstantAggregate>(value), decl);\n\tcase ValueKind::ConstantAggregateZero:\n\t\treturn append(cast<ConstantAggregateZero>(value), decl);\n\tcase ValueKind::ConstantDataArray:\n\t\treturn append(cast<ConstantDataArray>(value), decl);\n\tcase ValueKind::ConstantDataVector:\n\t\treturn append(cast<ConstantDataVector>(value), decl);\n\tcase ValueKind::ConstantExpr:\n\t\treturn append(cast<ConstantExpr>(value), decl);\n\tcase ValueKind::Switch:\n\t\treturn append(cast<SwitchInst>(value), decl);\n\tcase ValueKind::ShuffleVector:\n\t\treturn append(cast<ShuffleVectorInst>(value), decl);\n\tcase ValueKind::ExtractElement:\n\t\treturn append(cast<ExtractElementInst>(value), decl);\n\tcase ValueKind::InsertElement:\n\t\treturn append(cast<InsertElementInst>(value), decl);\n\tdefault:\n\t\tbreak;\n\t}\n\n\tLOGE(\"Unknown ValueKind %u.\\n\", unsigned(value->get_value_kind()));\n\n\tif (decl)\n\t\tappend(\"%\", value->get_tween_id(), \" = unimplemented\");\n\telse\n\t\tappend(\"%\", value->get_tween_id());\n}\n\nbool disassemble(Module &module, String &str)\n{\n\tStreamState state;\n\n\tfor (auto itr = module.global_begin(); itr != module.global_end(); ++itr)\n\t\tstate.append(&*itr, true);\n\n\tfor (auto *func : module)\n\t{\n\t\tstate.newline();\n\t\tstate.append(func, true);\n\t\tstate.newline();\n\t}\n\n\tstate.newline();\n\n\tfor (auto itr = module.named_metadata_begin(); itr != module.named_metadata_end(); ++itr)\n\t{\n\t\tstate.newline();\n\t\tstate.append(itr->second);\n\t}\n\n\tstate.newline();\n\n\tfor (auto itr = module.unnamed_metadata_begin(); itr != module.unnamed_metadata_end(); ++itr)\n\t{\n\t\tstate.newline();\n\t\tstate.append(*itr, true);\n\t}\n\n\tstr = state.stream.str();\n\treturn true;\n}\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/function.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"function.hpp\"\n#include \"context.hpp\"\n#include \"instruction.hpp\"\n#include \"module.hpp\"\n#include \"type.hpp\"\n#include <algorithm>\n#include <assert.h>\n\nnamespace LLVMBC\n{\nFunction::Function(FunctionType *function_type_, uint64_t value_id_, Module &module_)\n    : Constant(function_type_, ValueKind::Function)\n    , module(module_)\n    , value_id(value_id_)\n    , function_type(function_type_)\n{\n}\n\nconst String &Function::getName() const\n{\n\treturn module.get_value_name(value_id);\n}\n\nvoid Function::set_basic_blocks(Vector<BasicBlock *> basic_blocks_)\n{\n\tbasic_blocks = std::move(basic_blocks_);\n}\n\nFunctionType *Function::getFunctionType() const\n{\n\treturn function_type;\n}\n\nIteratorAdaptor<BasicBlock, Vector<BasicBlock *>::const_iterator> Function::begin() const\n{\n\treturn basic_blocks.begin();\n}\n\nIteratorAdaptor<BasicBlock, Vector<BasicBlock *>::const_iterator> Function::end() const\n{\n\treturn basic_blocks.end();\n}\n\nBasicBlock &Function::getEntryBlock() const\n{\n\treturn *basic_blocks.front();\n}\n\nvoid Function::add_argument(Argument *arg)\n{\n\targuments.push_back(arg);\n}\n\nString Attribute::getValueAsString() const\n{\n\t// LLVM implementation does this.\n\tif (value)\n\t\treturn *value;\n\telse\n\t\treturn {};\n}\n\nAttribute::Attribute(const String *value_)\n\t: value(value_)\n{\n}\n\nAttribute Function::getFnAttribute(const char *attribute) const\n{\n\tfor (auto &attr : attributes)\n\t\tif (attr.first == attribute)\n\t\t\treturn Attribute(&attr.second);\n\treturn Attribute(nullptr);\n}\n\nbool Function::hasFnAttribute(const char *attribute) const\n{\n\tfor (auto &attr : attributes)\n\t\tif (attr.first == attribute)\n\t\t\treturn true;\n\treturn false;\n}\n\nvoid Function::set_attributes(Vector<std::pair<String, String>> attributes_)\n{\n\tattributes = std::move(attributes_);\n}\n\nvoid Function::set_structured_control_flow()\n{\n\tstructured_control_flow = true;\n}\n\nbool Function::get_structured_control_flow() const\n{\n\treturn structured_control_flow;\n}\n\nIteratorAdaptor<const Argument, Vector<Argument *>::const_iterator> Function::arg_begin() const\n{\n\treturn arguments.begin();\n}\n\nIteratorAdaptor<const Argument, Vector<Argument *>::const_iterator> Function::arg_end() const\n{\n\treturn arguments.end();\n}\n\nBasicBlock::BasicBlock(LLVMContext &context_)\n    : Value(Type::getLabelTy(context_), ValueKind::BasicBlock)\n{\n}\n\nvoid BasicBlock::add_instruction(Instruction *inst)\n{\n\tinstructions.push_back(inst);\n}\n\nInstruction *BasicBlock::getTerminator() const\n{\n\tif (!instructions.empty() && instructions.back()->isTerminator())\n\t\treturn instructions.back();\n\telse\n\t\treturn nullptr;\n}\n\nvoid BasicBlock::add_successor(BasicBlock *succ)\n{\n\tif (std::find(succs.begin(), succs.end(), succ) == succs.end())\n\t\tsuccs.push_back(succ);\n}\n\nBasicBlock::Merge BasicBlock::get_merge() const\n{\n\treturn merge;\n}\n\nBasicBlock *BasicBlock::get_merge_bb() const\n{\n\treturn merge_bb;\n}\n\nBasicBlock *BasicBlock::get_continue_bb() const\n{\n\treturn continue_bb;\n}\n\nvoid BasicBlock::set_selection_merge(BasicBlock *bb)\n{\n\tmerge = Merge::Selection;\n\tmerge_bb = bb;\n}\n\nvoid BasicBlock::set_loop_merge(BasicBlock *merge_bb_, BasicBlock *continue_bb_)\n{\n\tmerge = Merge::Loop;\n\tmerge_bb = merge_bb_;\n\tcontinue_bb = continue_bb_;\n}\n\nIteratorAdaptor<Instruction, Vector<Instruction *>::const_iterator> BasicBlock::begin() const\n{\n\treturn instructions.begin();\n}\n\nIteratorAdaptor<Instruction, Vector<Instruction *>::const_iterator> BasicBlock::end() const\n{\n\treturn instructions.end();\n}\n\nVector<BasicBlock *>::const_iterator BasicBlock::succ_begin() const\n{\n\treturn succs.begin();\n}\n\nVector<BasicBlock *>::const_iterator BasicBlock::succ_end() const\n{\n\treturn succs.end();\n}\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/function.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"iterator.hpp\"\n#include \"value.hpp\"\n\nnamespace LLVMBC\n{\nclass LLVMContext;\nclass Instruction;\nclass Module;\nclass FunctionType;\n\nclass BasicBlock : public Value\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::BasicBlock;\n\t}\n\texplicit BasicBlock(LLVMContext &context);\n\n\tvoid add_instruction(Instruction *inst);\n\tInstruction *getTerminator() const;\n\n\tIteratorAdaptor<Instruction, Vector<Instruction *>::const_iterator> begin() const;\n\tIteratorAdaptor<Instruction, Vector<Instruction *>::const_iterator> end() const;\n\n\tvoid add_successor(BasicBlock *succ);\n\n\tenum class Merge\n\t{\n\t\tNone,\n\t\tSelection,\n\t\tLoop\n\t};\n\tMerge get_merge() const;\n\tvoid set_selection_merge(BasicBlock *bb);\n\tvoid set_loop_merge(BasicBlock *merge_bb, BasicBlock *continue_bb);\n\tBasicBlock *get_merge_bb() const;\n\tBasicBlock *get_continue_bb() const;\n\n\tVector<BasicBlock *>::const_iterator succ_begin() const;\n\tVector<BasicBlock *>::const_iterator succ_end() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tVector<Instruction *> instructions;\n\tVector<BasicBlock *> succs;\n\tMerge merge = Merge::None;\n\tBasicBlock *merge_bb = nullptr;\n\tBasicBlock *continue_bb = nullptr;\n};\n\ninline Vector<BasicBlock *>::const_iterator succ_begin(const BasicBlock *bb)\n{\n\treturn bb->succ_begin();\n}\n\ninline Vector<BasicBlock *>::const_iterator succ_end(const BasicBlock *bb)\n{\n\treturn bb->succ_end();\n}\n\nclass Attribute\n{\npublic:\n\texplicit Attribute(const String *value);\n\tString getValueAsString() const;\n\nprivate:\n\tconst String *value;\n};\n\nclass Function : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Function;\n\t}\n\texplicit Function(FunctionType *function_type, uint64_t value_id, Module &module);\n\tconst String &getName() const;\n\n\tvoid set_basic_blocks(Vector<BasicBlock *> basic_blocks);\n\tIteratorAdaptor<BasicBlock, Vector<BasicBlock *>::const_iterator> begin() const;\n\tIteratorAdaptor<BasicBlock, Vector<BasicBlock *>::const_iterator> end() const;\n\tFunctionType *getFunctionType() const;\n\n\tBasicBlock &getEntryBlock() const;\n\n\tvoid add_argument(Argument *arg);\n\tIteratorAdaptor<const Argument, Vector<Argument *>::const_iterator> arg_begin() const;\n\tIteratorAdaptor<const Argument, Vector<Argument *>::const_iterator> arg_end() const;\n\n\t// Bare bones implementation, we only need it for fp32-denorm-mode attribute.\n\tAttribute getFnAttribute(const char *attribute) const;\n\tbool hasFnAttribute(const char *attribute) const;\n\tvoid set_attributes(Vector<std::pair<String, String>> attributes);\n\n\tbool get_structured_control_flow() const;\n\tvoid set_structured_control_flow();\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tModule &module;\n\tuint64_t value_id;\n\tFunctionType *function_type;\n\tVector<BasicBlock *> basic_blocks;\n\tVector<Argument *> arguments;\n\tVector<std::pair<String, String>> attributes;\n\tbool structured_control_flow = false;\n};\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/instruction.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"instruction.hpp\"\n#include \"cast.hpp\"\n#include <assert.h>\n\nnamespace LLVMBC\n{\nInstruction::Instruction(Type *type, ValueKind kind)\n    : Value(type, kind)\n{\n}\n\nvoid Instruction::set_operands(Vector<Value *> op)\n{\n\toperands = std::move(op);\n}\n\nunsigned Instruction::getNumOperands() const\n{\n\treturn operands.size();\n}\n\nValue *Instruction::getOperand(unsigned index) const\n{\n\tif (index >= operands.size())\n\t{\n\t\tLOGE(\"Operand index is out of range.\\n\");\n\t\treturn nullptr;\n\t}\n\n\treturn Internal::resolve_proxy(operands[index]);\n}\n\nbool Instruction::isTerminator() const\n{\n\treturn is_terminator;\n}\n\nvoid Instruction::set_terminator()\n{\n\tis_terminator = true;\n}\n\nbool Instruction::resolve_proxy_values()\n{\n\tfor (auto &op : operands)\n\t\twhile (op && op->get_value_kind() == ValueKind::Proxy)\n\t\t\top = cast<ValueProxy>(op)->get_proxy_value();\n\n\tif (get_value_kind() == ValueKind::PHI)\n\t{\n\t\tauto *phi = cast<PHINode>(this);\n\t\tif (!phi->resolve_proxy_values_incoming())\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid Instruction::setMetadata(const String &str, MDNode *node)\n{\n\tattachments[str] = node;\n}\n\nUnorderedMap<String, MDNode *>::const_iterator Instruction::metadata_begin() const\n{\n\treturn attachments.begin();\n}\n\nUnorderedMap<String, MDNode *>::const_iterator Instruction::metadata_end() const\n{\n\treturn attachments.end();\n}\n\nbool Instruction::hasMetadata(const String &str) const\n{\n\treturn attachments.find(str) != attachments.end();\n}\n\nMDNode *Instruction::getMetadata(const String &str) const\n{\n\tauto itr = attachments.find(str);\n\tif (itr != attachments.end())\n\t\treturn itr->second;\n\telse\n\t\treturn nullptr;\n}\n\nbool Instruction::is_base_of_value_kind(ValueKind kind)\n{\n\tswitch (kind)\n\t{\n\tcase ValueKind::Return:\n\tcase ValueKind::Unreachable:\n\tcase ValueKind::Call:\n\tcase ValueKind::UnaryOperator:\n\tcase ValueKind::BinaryOperator:\n\tcase ValueKind::Cast:\n\tcase ValueKind::Select:\n\tcase ValueKind::ExtractValue:\n\tcase ValueKind::Alloca:\n\tcase ValueKind::GetElementPtr:\n\tcase ValueKind::Load:\n\tcase ValueKind::Store:\n\tcase ValueKind::CompareBase:\n\tcase ValueKind::FCmp:\n\tcase ValueKind::ICmp:\n\tcase ValueKind::Branch:\n\tcase ValueKind::Switch:\n\tcase ValueKind::PHI:\n\tcase ValueKind::AtomicRMW:\n\tcase ValueKind::AtomicCmpXchg:\n\tcase ValueKind::ShuffleVector:\n\tcase ValueKind::ExtractElement:\n\tcase ValueKind::InsertElement:\n\t\treturn true;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nBinaryOperator::BinaryOperator(Value *LHS, Value *RHS, BinaryOps op_)\n    : Instruction(LHS->getType(), ValueKind::BinaryOperator)\n    , op(op_)\n{\n\tset_operands({ LHS, RHS });\n}\n\nBinaryOperator::BinaryOps BinaryOperator::getOpcode() const\n{\n\treturn op;\n}\n\nbool BinaryOperator::isFast() const\n{\n\treturn fast_math;\n}\n\nvoid BinaryOperator::setFast(bool enabled)\n{\n\tfast_math = enabled;\n}\n\nUnaryOperator::UnaryOperator(UnaryOps uop, Value *value)\n    : Instruction(value->getType(), ValueKind::UnaryOperator), op(uop)\n{\n\tset_operands({ value });\n}\n\nUnaryOperator::UnaryOps UnaryOperator::getOpcode() const\n{\n\treturn op;\n}\n\nReturnInst::ReturnInst(Value *value_)\n    : Instruction(value_ ? value_->getType() : nullptr, ValueKind::Return)\n    , value(value_)\n{\n\tset_terminator();\n}\n\nUnreachableInst::UnreachableInst()\n\t: Instruction(nullptr, ValueKind::Unreachable)\n{\n\tset_terminator();\n}\n\nCallInst::CallInst(FunctionType *function_type_, Function *callee_, Vector<Value *> params)\n    : Instruction(function_type_->getReturnType(), ValueKind::Call)\n    , callee(callee_)\n{\n\tset_operands(std::move(params));\n}\n\nFunction *CallInst::getCalledFunction() const\n{\n\treturn callee;\n}\n\nValue *ReturnInst::getReturnValue() const\n{\n\treturn Internal::resolve_proxy(value);\n}\n\nCmpInst::CmpInst(ValueKind kind, Predicate pred_, Value *LHS, Value *RHS)\n    : Instruction(Type::getInt1Ty(LHS->getType()->getContext()), kind)\n    , pred(pred_)\n{\n\tset_operands({ LHS, RHS });\n}\n\nCastInst::CastInst(Type *type, Value *value, Instruction::CastOps op_)\n    : Instruction(type, ValueKind::Cast)\n    , op(op_)\n{\n\tset_operands({ value });\n}\n\nSelectInst::SelectInst(Value *true_value, Value *false_value, Value *cond)\n    : Instruction(true_value->getType(), ValueKind::Select)\n{\n\tset_operands({ cond, true_value, false_value });\n}\n\nExtractValueInst::ExtractValueInst(Type *type, Value *aggregate, Vector<unsigned> indices_)\n    : Instruction(type, ValueKind::ExtractValue)\n    , indices(std::move(indices_))\n{\n\tset_operands({ aggregate });\n}\n\nValue *ExtractValueInst::getAggregateOperand() const\n{\n\treturn Internal::resolve_proxy(operands[0]);\n}\n\nunsigned ExtractValueInst::getNumIndices() const\n{\n\treturn indices.size();\n}\n\nconst unsigned *ExtractValueInst::getIndices() const\n{\n\treturn indices.data();\n}\n\nInstruction::CastOps CastInst::getOpcode() const\n{\n\treturn op;\n}\n\nInstruction::Predicate CmpInst::getPredicate() const\n{\n\treturn pred;\n}\n\nbool CmpInst::is_base_of_value_kind(ValueKind kind)\n{\n\treturn kind == ValueKind::ICmp || kind == ValueKind::FCmp;\n}\n\nFCmpInst::FCmpInst(Predicate pred_, Value *LHS, Value *RHS)\n    : CmpInst(ValueKind::FCmp, pred_, LHS, RHS)\n{\n\tset_operands({ LHS, RHS });\n}\n\nICmpInst::ICmpInst(Predicate pred_, Value *LHS, Value *RHS)\n    : CmpInst(ValueKind::ICmp, pred_, LHS, RHS)\n{\n\tset_operands({ LHS, RHS });\n}\n\nBranchInst::BranchInst(BasicBlock *true_block, BasicBlock *false_block, Value *cond_)\n    : Instruction(nullptr, ValueKind::Branch)\n    , cond(cond_)\n{\n\tset_terminator();\n\tnum_blocks = 2;\n\tbbs[0] = true_block;\n\tbbs[1] = false_block;\n}\n\nBranchInst::BranchInst(BasicBlock *true_block)\n    : Instruction(nullptr, ValueKind::Branch)\n{\n\tset_terminator();\n\tnum_blocks = 1;\n\tbbs[0] = true_block;\n}\n\nbool BranchInst::isConditional() const\n{\n\treturn cond != nullptr;\n}\n\nValue *BranchInst::getCondition() const\n{\n\treturn Internal::resolve_proxy(cond);\n}\n\nBasicBlock *BranchInst::getSuccessor(unsigned index) const\n{\n\tassert(index < num_blocks);\n\treturn bbs[index];\n}\n\nunsigned BranchInst::getNumSuccessors() const\n{\n\treturn num_blocks;\n}\n\nSwitchInst::SwitchInst(Value *cond_, BasicBlock *default_block_, unsigned num_cases)\n    : Instruction(Type::getVoidTy(cond_->getType()->getContext()), ValueKind::Switch)\n    , cond(cond_)\n    , default_block(default_block_)\n{\n\tset_terminator();\n\tcases.reserve(num_cases);\n}\n\nvoid SwitchInst::addCase(Value *case_value, BasicBlock *bb)\n{\n\tcases.push_back({ case_value, bb });\n}\n\nVector<SwitchInst::Case>::const_iterator SwitchInst::case_begin() const\n{\n\treturn cases.begin();\n}\n\nVector<SwitchInst::Case>::const_iterator SwitchInst::case_end() const\n{\n\treturn cases.end();\n}\n\nBasicBlock *SwitchInst::getDefaultDest() const\n{\n\treturn default_block;\n}\n\nValue *SwitchInst::getCondition() const\n{\n\treturn Internal::resolve_proxy(cond);\n}\n\nConstantInt *SwitchInst::Case::getCaseValue() const\n{\n\treturn cast<ConstantInt>(value);\n}\n\nBasicBlock *SwitchInst::Case::getCaseSuccessor() const\n{\n\treturn bb;\n}\n\nPHINode::PHINode(Type *type, size_t num_edges)\n    : Instruction(type, ValueKind::PHI)\n{\n\tincoming.reserve(num_edges);\n}\n\nvoid PHINode::add_incoming(Value *value, BasicBlock *bb)\n{\n\tincoming.push_back({ value, bb });\n}\n\nunsigned PHINode::getNumIncomingValues() const\n{\n\treturn unsigned(incoming.size());\n}\n\nAllocaInst::AllocaInst(Type *pointer_type, Type *element_type_, Value *size)\n    : Instruction(pointer_type, ValueKind::Alloca)\n    , array_size(size)\n{\n}\n\nValue *AllocaInst::getArraySize() const\n{\n\treturn Internal::resolve_proxy(array_size);\n}\n\nGetElementPtrInst::GetElementPtrInst(Type *pointer_type, Vector<Value *> indices, bool inbounds_)\n    : Instruction(pointer_type, ValueKind::GetElementPtr)\n    , inbounds(inbounds_)\n{\n\tset_operands(std::move(indices));\n}\n\nbool GetElementPtrInst::isInBounds() const\n{\n\treturn inbounds;\n}\n\nLoadInst::LoadInst(Type *type, Value *ptr)\n    : Instruction(type, ValueKind::Load)\n{\n\tset_operands({ ptr });\n}\n\nValue *LoadInst::getPointerOperand() const\n{\n\treturn getOperand(0);\n}\n\nStoreInst::StoreInst(Value *ptr, Value *value)\n    : Instruction(Type::getVoidTy(ptr->getType()->getContext()), ValueKind::Store)\n{\n\tset_operands({ value, ptr });\n}\n\nBasicBlock *PHINode::getIncomingBlock(unsigned index) const\n{\n\tif (index >= incoming.size())\n\t\treturn nullptr;\n\treturn incoming[index].bb;\n}\n\nValue *PHINode::getIncomingValue(unsigned index) const\n{\n\tif (index >= incoming.size())\n\t\treturn nullptr;\n\treturn Internal::resolve_proxy(incoming[index].value);\n}\n\nbool PHINode::resolve_proxy_values_incoming()\n{\n\tfor (auto &node : incoming)\n\t{\n\t\twhile (node.value && node.value->get_value_kind() == ValueKind::Proxy)\n\t\t{\n\t\t\tnode.value = cast<ValueProxy>(node.value)->get_proxy_value();\n\t\t\tif (!node.value)\n\t\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nAtomicRMWInst::AtomicRMWInst(Type *type, Value *ptr_, Value *value_, BinOp op_)\n    : Instruction(type, ValueKind::AtomicRMW)\n    , ptr(ptr_)\n    , value(value_)\n    , op(op_)\n{\n\tset_operands({ ptr, value });\n}\n\nValue *AtomicRMWInst::getPointerOperand() const\n{\n\treturn Internal::resolve_proxy(ptr);\n}\n\nValue *AtomicRMWInst::getValOperand() const\n{\n\treturn Internal::resolve_proxy(value);\n}\n\nAtomicRMWInst::BinOp AtomicRMWInst::getOperation() const\n{\n\treturn op;\n}\n\nAtomicCmpXchgInst::AtomicCmpXchgInst(Value *ptr_, Value *cmp_, Value *new_value_, Type *type_override)\n\t: Instruction(type_override ?\n\t              type_override :\n\t              StructType::get(new_value_->getType()->getContext(),\n\t                              { new_value_->getType(), Type::getInt1Ty(new_value_->getType()->getContext()) }),\n\t              ValueKind::AtomicCmpXchg)\n\t, ptr(ptr_)\n\t, new_value(new_value_)\n\t, cmp_value(cmp_)\n{\n\tset_operands({ ptr, new_value, cmp_value });\n}\n\nValue *AtomicCmpXchgInst::getPointerOperand() const\n{\n\treturn Internal::resolve_proxy(ptr);\n}\n\nValue *AtomicCmpXchgInst::getCompareOperand() const\n{\n\treturn Internal::resolve_proxy(cmp_value);\n}\n\nValue *AtomicCmpXchgInst::getNewValOperand() const\n{\n\treturn Internal::resolve_proxy(new_value);\n}\n\nShuffleVectorInst::ShuffleVectorInst(Type *type, Value *a, Value *b, Value *shuf)\n\t: Instruction(type, ValueKind::ShuffleVector)\n{\n\tset_operands({ a, b });\n\tauto *masks = cast<ConstantDataVector>(shuf);\n\tshuffle_mask.reserve(masks->getNumElements());\n\tfor (unsigned i = 0; i < masks->getNumElements(); i++)\n\t\tshuffle_mask.push_back(cast<ConstantInt>(masks->getElementAsConstant(i))->getUniqueInteger().getSExtValue());\n}\n\nint ShuffleVectorInst::getMaskValue(unsigned index) const\n{\n\tassert(index < shuffle_mask.size());\n\treturn shuffle_mask[index];\n}\n\nExtractElementInst::ExtractElementInst(Value *vec_, Value *index_)\n\t: Instruction(cast<VectorType>(vec_->getType())->getElementType(), ValueKind::ExtractElement),\n\t  vec(vec_), index(index_)\n{\n\tset_operands({ vec, index });\n}\n\nValue *ExtractElementInst::getVectorOperand() const\n{\n\treturn Internal::resolve_proxy(vec);\n}\n\nValue *ExtractElementInst::getIndexOperand() const\n{\n\treturn Internal::resolve_proxy(index);\n}\n\nInsertElementInst::InsertElementInst(Value *vec, Value *value, Value *index)\n\t: Instruction(vec->getType(), ValueKind::InsertElement)\n{\n\tset_operands({ vec, value, index });\n}\n\nCompositeConstructInst::CompositeConstructInst(Type *type, Vector<Value *> constituents)\n\t: Instruction(type, ValueKind::CompositeConstruct)\n{\n\tset_operands(std::move(constituents));\n}\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/instruction.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"value.hpp\"\n\nnamespace LLVMBC\n{\nclass FunctionType;\nclass Function;\nclass BasicBlock;\nclass MDNode;\n\nclass Instruction : public Value\n{\npublic:\n\tInstruction(Type *type, ValueKind kind);\n\n\tenum Predicate\n\t{\n\t\tFCMP_FALSE = 0,\n\t\tFCMP_OEQ = 1,\n\t\tFCMP_OGT = 2,\n\t\tFCMP_OGE = 3,\n\t\tFCMP_OLT = 4,\n\t\tFCMP_OLE = 5,\n\t\tFCMP_ONE = 6,\n\t\tFCMP_ORD = 7,\n\t\tFCMP_UNO = 8,\n\t\tFCMP_UEQ = 9,\n\t\tFCMP_UGT = 10,\n\t\tFCMP_UGE = 11,\n\t\tFCMP_ULT = 12,\n\t\tFCMP_ULE = 13,\n\t\tFCMP_UNE = 14,\n\t\tFCMP_TRUE = 15,\n\n\t\tICMP_EQ = 32,\n\t\tICMP_NE = 33,\n\t\tICMP_UGT = 34,\n\t\tICMP_UGE = 35,\n\t\tICMP_ULT = 36,\n\t\tICMP_ULE = 37,\n\t\tICMP_SGT = 38,\n\t\tICMP_SGE = 39,\n\t\tICMP_SLT = 40,\n\t\tICMP_SLE = 41\n\t};\n\n\tenum CastOps\n\t{\n\t\tInvalidCastOp = 100,\n\t\tTrunc,\n\t\tZExt,\n\t\tSExt,\n\t\tFPToUI,\n\t\tFPToSI,\n\t\tUIToFP,\n\t\tSIToFP,\n\t\tFPTrunc,\n\t\tFPExt,\n\t\tPtrToInt,\n\t\tIntToPtr,\n\t\tBitCast,\n\t\tAddrSpaceCast\n\t};\n\n\tenum GEPOps\n\t{\n\t\tGetElementPtr = 200\n\t};\n\n\tenum BinaryOps\n\t{\n\t\tInvalidBinaryOp = 300,\n\t\tAdd,\n\t\tFAdd,\n\t\tSub,\n\t\tFSub,\n\t\tMul,\n\t\tFMul,\n\t\tUDiv,\n\t\tSDiv,\n\t\tFDiv,\n\t\tURem,\n\t\tSRem,\n\t\tFRem,\n\t\tShl,\n\t\tLShr,\n\t\tAShr,\n\t\tAnd,\n\t\tOr,\n\t\tXor\n\t};\n\n\tbool isTerminator() const;\n\n\tValue *getOperand(unsigned index) const;\n\tunsigned getNumOperands() const;\n\n\tbool resolve_proxy_values();\n\n\tMDNode *getMetadata(const String &str) const;\n\tbool hasMetadata(const String &str) const;\n\tvoid setMetadata(const String &str, MDNode *node);\n\n\tUnorderedMap<String, MDNode *>::const_iterator metadata_begin() const;\n\tUnorderedMap<String, MDNode *>::const_iterator metadata_end() const;\n\n\tstatic bool is_base_of_value_kind(ValueKind kind);\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::InstructionBase;\n\t}\n\nprotected:\n\tvoid set_terminator();\n\tbool is_terminator = false;\n\tvoid set_operands(Vector<Value *> op);\n\tVector<Value *> operands;\n\tUnorderedMap<String, MDNode *> attachments;\n};\n\nclass ReturnInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Return;\n\t}\n\texplicit ReturnInst(Value *value);\n\tValue *getReturnValue() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tValue *value;\n};\n\nclass UnreachableInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Unreachable;\n\t}\n\n\tUnreachableInst();\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass CallInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Call;\n\t}\n\tCallInst(FunctionType *function_type, Function *callee, Vector<Value *> params);\n\tFunction *getCalledFunction() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tFunction *callee;\n};\n\nclass UnaryOperator : public Instruction\n{\npublic:\n\tenum class UnaryOps\n\t{\n\t\tInvalid,\n\t\tFNeg,\n\t\tINeg, // custom extension\n\t};\n\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::UnaryOperator;\n\t}\n\tUnaryOperator(UnaryOps uop, Value *value);\n\tUnaryOps getOpcode() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tUnaryOps op;\n};\n\nclass BinaryOperator : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::BinaryOperator;\n\t}\n\tBinaryOperator(Value *LHS, Value *RHS, BinaryOps op);\n\tBinaryOps getOpcode() const;\n\n\tvoid setFast(bool enabled);\n\tbool isFast() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tBinaryOps op;\n\tbool fast_math = false;\n};\n\nclass CastInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Cast;\n\t}\n\tCastInst(Type *type, Value *value, Instruction::CastOps op);\n\tInstruction::CastOps getOpcode() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tInstruction::CastOps op;\n};\n\nclass SelectInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Select;\n\t}\n\tSelectInst(Value *true_value, Value *false_value, Value *cond);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass ExtractValueInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ExtractValue;\n\t}\n\tExtractValueInst(Type *type, Value *aggregate, Vector<unsigned> indices);\n\tValue *getAggregateOperand() const;\n\tunsigned getNumIndices() const;\n\tconst unsigned *getIndices() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tVector<unsigned> indices;\n};\n\nclass AllocaInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Alloca;\n\t}\n\tAllocaInst(Type *pointer_type, Type *element_type, Value *size);\n\tValue *getArraySize() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tValue *array_size;\n};\n\nclass GetElementPtrInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::GetElementPtr;\n\t}\n\tGetElementPtrInst(Type *pointer_type, Vector<Value *> arguments, bool inbounds);\n\tbool isInBounds() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tbool inbounds;\n};\n\nclass LoadInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Load;\n\t}\n\tLoadInst(Type *type, Value *ptr);\n\tValue *getPointerOperand() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass StoreInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Store;\n\t}\n\tStoreInst(Value *ptr, Value *value);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass CmpInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::CompareBase;\n\t}\n\tCmpInst(ValueKind kind, Predicate pred, Value *LHS, Value *RHS);\n\tPredicate getPredicate() const;\n\n\tstatic bool is_base_of_value_kind(ValueKind kind);\n\nprivate:\n\tPredicate pred;\n};\n\nclass FCmpInst : public CmpInst\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::FCmp;\n\t}\n\tFCmpInst(Predicate pred, Value *LHS, Value *RHS);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass ICmpInst : public CmpInst\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ICmp;\n\t}\n\tICmpInst(Predicate pred, Value *LHS, Value *RHS);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass BranchInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Branch;\n\t}\n\tBranchInst(BasicBlock *true_block, BasicBlock *false_block, Value *cond);\n\texplicit BranchInst(BasicBlock *true_block);\n\n\tbool isConditional() const;\n\tValue *getCondition() const;\n\n\tunsigned getNumSuccessors() const;\n\tBasicBlock *getSuccessor(unsigned index) const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tBasicBlock *bbs[2] = {};\n\tunsigned num_blocks = 0;\n\tValue *cond = nullptr;\n};\n\nclass SwitchInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Switch;\n\t}\n\tSwitchInst(Value *cond, BasicBlock *default_block, unsigned num_cases);\n\tvoid addCase(Value *case_value, BasicBlock *bb);\n\n\tstruct Case\n\t{\n\t\tValue *value;\n\t\tBasicBlock *bb;\n\n\t\tBasicBlock *getCaseSuccessor() const;\n\t\tConstantInt *getCaseValue() const;\n\t};\n\n\tVector<Case>::const_iterator case_begin() const;\n\tVector<Case>::const_iterator case_end() const;\n\n\tValue *getCondition() const;\n\tBasicBlock *getDefaultDest() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tValue *cond;\n\tBasicBlock *default_block;\n\tVector<Case> cases;\n};\n\nclass PHINode : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::PHI;\n\t}\n\tPHINode(Type *type, size_t num_edges);\n\n\tunsigned getNumIncomingValues() const;\n\tValue *getIncomingValue(unsigned index) const;\n\tBasicBlock *getIncomingBlock(unsigned index) const;\n\n\tvoid add_incoming(Value *value, BasicBlock *bb);\n\tbool resolve_proxy_values_incoming();\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tstruct Incoming\n\t{\n\t\tValue *value;\n\t\tBasicBlock *bb;\n\t};\n\tVector<Incoming> incoming;\n};\n\nclass AtomicRMWInst : public Instruction\n{\npublic:\n\tenum class BinOp\n\t{\n\t\tInvalid,\n\t\tXchg,\n\t\tAdd,\n\t\tSub,\n\t\tAnd,\n\t\tNand,\n\t\tOr,\n\t\tXor,\n\t\tMax,\n\t\tMin,\n\t\tUMax,\n\t\tUMin,\n\t\tFAdd, // wat\n\t\tFSub\n\t};\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::AtomicRMW;\n\t}\n\tAtomicRMWInst(Type *type, Value *ptr, Value *value, BinOp op);\n\n\tValue *getPointerOperand() const;\n\tValue *getValOperand() const;\n\tBinOp getOperation() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tValue *ptr;\n\tValue *value;\n\tBinOp op;\n};\n\nclass AtomicCmpXchgInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::AtomicCmpXchg;\n\t}\n\tAtomicCmpXchgInst(Value *ptr, Value *cmp, Value *new_value, Type *type_override = nullptr);\n\n\tValue *getPointerOperand() const;\n\tValue *getNewValOperand() const;\n\tValue *getCompareOperand() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tValue *ptr;\n\tValue *new_value;\n\tValue *cmp_value;\n};\n\nclass ShuffleVectorInst : public Instruction\n{\npublic:\n\tShuffleVectorInst(Type *type, Value *a, Value *b, Value *shuf);\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ShuffleVector;\n\t}\n\n\tint getMaskValue(unsigned index) const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tVector<int> shuffle_mask;\n};\n\nclass ExtractElementInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ExtractElement;\n\t}\n\tExtractElementInst(Value *vec, Value *offset);\n\tValue *getVectorOperand() const;\n\tValue *getIndexOperand() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tValue *vec;\n\tValue *index;\n};\n\nclass InsertElementInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::InsertElement;\n\t}\n\tInsertElementInst(Value *vec, Value *value, Value *index);\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\n// Extension of LLVM to better map to SPIR-V / DXBC-IR\nclass CompositeConstructInst : public Instruction\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::CompositeConstruct;\n\t}\n\tCompositeConstructInst(Type *type, Vector<Value *> constituents);\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/iterator.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include <stddef.h>\n\nnamespace LLVMBC\n{\n// An iterator adaptor which lets us receive reference types instead of pointer types.\ntemplate <typename T, typename Iter>\nstruct IteratorAdaptor\n{\n\tIteratorAdaptor(Iter iter_)\n\t    : iter(iter_)\n\t{\n\t}\n\n\tT &operator*()\n\t{\n\t\treturn **iter;\n\t}\n\n\tT *operator->()\n\t{\n\t\treturn *iter;\n\t}\n\n\tIteratorAdaptor operator++()\n\t{\n\t\t++iter;\n\t\treturn *this;\n\t}\n\n\tbool operator==(const IteratorAdaptor &other) const\n\t{\n\t\treturn iter == other.iter;\n\t}\n\n\tbool operator!=(const IteratorAdaptor &other) const\n\t{\n\t\treturn !(*this == other);\n\t}\n\n\tptrdiff_t operator-(const IteratorAdaptor &other) const\n\t{\n\t\treturn iter - other.iter;\n\t}\n\n\tIter iter;\n};\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/metadata.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"metadata.hpp\"\n#include \"module.hpp\"\n#include \"value.hpp\"\n#include <assert.h>\n#include <utility>\n\nnamespace LLVMBC\n{\nMDOperand::MDOperand(Module *parent_, MetadataKind kind_)\n    : parent(parent_)\n    , kind(kind_)\n{\n}\n\nMDOperand::MDOperand(Module *parent_)\n    : parent(parent_)\n{\n}\n\nModule *MDOperand::getParent() const\n{\n\treturn parent;\n}\n\nMetadataKind MDOperand::get_metadata_kind() const\n{\n\treturn kind;\n}\n\nMDNode::MDNode(Module *module, Vector<MDOperand *> operands_)\n    : MDOperand(module, MetadataKind::Node)\n    , operands(std::move(operands_))\n{\n}\n\nunsigned MDNode::getNumOperands() const\n{\n\treturn unsigned(operands.size());\n}\n\nMDOperand &MDNode::getOperand(unsigned index) const\n{\n\tassert(index < operands.size());\n\treturn *operands[index];\n}\n\nuint64_t MDNode::get_tween_id() const\n{\n\treturn tween;\n}\n\nvoid MDNode::set_tween_id(uint64_t id)\n{\n\ttween = id;\n}\n\nNamedMDNode::NamedMDNode(Module *module, String name_, Vector<MDNode *> operands_)\n    : MDOperand(module, MetadataKind::NamedNode)\n    , name(std::move(name_))\n    , operands(std::move(operands_))\n{\n}\n\nunsigned NamedMDNode::getNumOperands() const\n{\n\treturn unsigned(operands.size());\n}\n\nMDNode *NamedMDNode::getOperand(unsigned index) const\n{\n\tassert(index < operands.size());\n\treturn operands[index];\n}\n\nconst String &NamedMDNode::getName() const\n{\n\treturn name;\n}\n\nConstantAsMetadata::ConstantAsMetadata(Module *module, Constant *value_)\n    : MDOperand(module, MetadataKind::Constant)\n    , value(value_)\n{\n}\n\nConstant *ConstantAsMetadata::getValue() const\n{\n\treturn value;\n}\n\nMDString::MDString(LLVMBC::Module *module, String str_)\n    : MDOperand(module, MetadataKind::String)\n    , str(std::move(str_))\n{\n}\n\nconst String &MDString::getString() const\n{\n\treturn str;\n}\n\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/metadata.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"data_structures.hpp\"\n\nnamespace LLVMBC\n{\nclass Value;\nclass Module;\nclass Constant;\n\nenum class MetadataKind\n{\n\tNamedNode,\n\tNode,\n\tConstant,\n\tString,\n\tNone\n};\n\nclass MDOperand\n{\npublic:\n\texplicit MDOperand(Module *parent);\n\tMDOperand(Module *parent, MetadataKind kind);\n\tModule *getParent() const;\n\n\tMetadataKind get_metadata_kind() const;\n\n\texplicit operator bool() const\n\t{\n\t\treturn kind != MetadataKind::None;\n\t}\n\nprivate:\n\tModule *parent;\n\tMetadataKind kind = MetadataKind::None;\n};\n\nclass MDNode : public MDOperand\n{\npublic:\n\tstatic constexpr MetadataKind get_metadata_kind()\n\t{\n\t\treturn MetadataKind::Node;\n\t}\n\tMDNode(Module *module, Vector<MDOperand *> operands);\n\n\tMDOperand &getOperand(unsigned index) const;\n\tunsigned getNumOperands() const;\n\n\tvoid set_tween_id(uint64_t id);\n\tuint64_t get_tween_id() const;\n\nprivate:\n\tVector<MDOperand *> operands;\n\tuint64_t tween = 0;\n};\n\nclass NamedMDNode : public MDOperand\n{\npublic:\n\tstatic constexpr MetadataKind get_metadata_kind()\n\t{\n\t\treturn MetadataKind::NamedNode;\n\t}\n\tNamedMDNode(Module *module, String name, Vector<MDNode *> operands);\n\tconst String &getName() const;\n\n\tMDNode *getOperand(unsigned index) const;\n\tunsigned getNumOperands() const;\n\nprivate:\n\tString name;\n\tVector<MDNode *> operands;\n};\n\nclass ConstantAsMetadata : public MDOperand\n{\npublic:\n\tstatic constexpr MetadataKind get_metadata_kind()\n\t{\n\t\treturn MetadataKind::Constant;\n\t}\n\tConstantAsMetadata(Module *module, Constant *value);\n\tConstant *getValue() const;\n\nprivate:\n\tConstant *value;\n};\n\nclass MDString : public MDOperand\n{\npublic:\n\tstatic constexpr MetadataKind get_metadata_kind()\n\t{\n\t\treturn MetadataKind::String;\n\t}\n\tMDString(Module *module, String str);\n\tconst String &getString() const;\n\nprivate:\n\tString str;\n};\n\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/module.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"module.hpp\"\n#include \"cast.hpp\"\n#include \"context.hpp\"\n#include \"function.hpp\"\n#include \"instruction.hpp\"\n#include \"logging.hpp\"\n#include \"metadata.hpp\"\n#include \"type.hpp\"\n#include \"value.hpp\"\n#include <algorithm>\n\n#include \"llvm_decoder.h\"\n\nnamespace LLVMBC\n{\nenum class KnownBlocks : uint32_t\n{\n\tBLOCKINFO = 0,\n\n\t// 1-7 reserved,\n\n\tMODULE_BLOCK = 8,\n\tPARAMATTR_BLOCK = 9,\n\tPARAMATTR_GROUP_BLOCK = 10,\n\tCONSTANTS_BLOCK = 11,\n\tFUNCTION_BLOCK = 12,\n\tTYPE_SYMTAB_BLOCK = 13,\n\tVALUE_SYMTAB_BLOCK = 14,\n\tMETADATA_BLOCK = 15,\n\tMETADATA_ATTACHMENT = 16,\n\tTYPE_BLOCK = 17,\n};\n\nenum class AttributeRecord : uint32_t\n{\n\tNONE = 0,\n\tALIGNMENT = 1,\n\tBY_VAL = 3,\n\tSTACK_ALIGNMENT = 25,\n\tDEREFERENCEABLE = 41,\n\tDEREFERENCEABLE_OR_NULL = 42,\n\tALLOC_SIZE = 51\n};\n\nenum class ModuleRecord : uint32_t\n{\n\tVERSION = 1,\n\tTRIPLE = 2,\n\tDATALAYOUT = 3,\n\tGLOBAL_VARIABLE = 7,\n\tFUNCTION = 8,\n};\n\nenum class ConstantsRecord : uint32_t\n{\n\tSETTYPE = 1,\n\tCONST_NULL = 2,\n\tUNDEF = 3,\n\tINTEGER = 4,\n\tWIDE_INTEGER = 5,\n\tFLOAT = 6,\n\tAGGREGATE = 7,\n\tSTRING = 8,\n\tBINOP = 10,\n\tCE_CAST = 11,\n\tGEP = 12,\n\tINBOUNDS_GEP = 20,\n\tDATA = 22,\n\tGEP_WITH_INRANGE_INDEX = 24\n};\n\nenum class FunctionRecord : uint32_t\n{\n\tDECLAREBLOCKS = 1,\n\tINST_BINOP = 2,\n\tINST_CAST = 3,\n\tINST_GEP_OLD = 4,\n\tINST_SELECT = 5,\n\tINST_EXTRACTELT = 6,\n\tINST_INSERTELT = 7,\n\tINST_SHUFFLEVEC = 8,\n\tINST_CMP = 9,\n\tINST_RET = 10,\n\tINST_BR = 11,\n\tINST_SWITCH = 12,\n\tINST_INVOKE = 13,\n\tINST_UNREACHABLE = 15,\n\tINST_PHI = 16,\n\tINST_ALLOCA = 19,\n\tINST_LOAD = 20,\n\tINST_VAARG = 23,\n\tINST_STORE_OLD = 24,\n\tINST_EXTRACTVAL = 26,\n\tINST_INSERTVAL = 27,\n\tINST_CMP2 = 28,\n\tINST_VSELECT = 29,\n\tINST_INBOUNDS_GEP_OLD = 30,\n\tINST_INDIRECTBR = 31,\n\tDEBUG_LOC_AGAIN = 33,\n\tINST_CALL = 34,\n\tDEBUG_LOC = 35,\n\tINST_FENCE = 36,\n\tINST_CMPXCHG_OLD = 37,\n\tINST_ATOMICRMW = 38,\n\tINST_RESUME = 39,\n\tINST_LANDINGPAD_OLD = 40,\n\tINST_LOADATOMIC = 41,\n\tINST_STOREATOMIC_OLD = 42,\n\tINST_GEP = 43,\n\tINST_STORE = 44,\n\tINST_STOREATOMIC = 45,\n\tINST_CMPXCHG = 46,\n\tINST_LANDINGPAD = 47,\n\tINST_CLEANUPRET = 48,\n\tINST_CATCHRET = 49,\n\tINST_CATCHPAD = 50,\n\tINST_CLEANUPPAD = 51,\n\tINST_CATCHSWITCH = 52,\n\tOPERAND_BUNDLE = 55,\n\tINST_UNOP = 56,\n\tINST_CALLBR = 57,\n};\n\nenum class ValueSymtabRecord : uint32_t\n{\n\tENTRY = 1,\n\tBBENTRY = 2,\n\tFNENTRY = 3,\n\tCOMBINED_ENTRY = 5,\n};\n\nenum class MetaDataRecord : uint32_t\n{\n\tSTRING_OLD = 1,\n\tVALUE = 2,\n\tNODE = 3,\n\tNAME = 4,\n\tDISTINCT_NODE = 5,\n\tKIND = 6,\n\tLOCATION = 7,\n\tOLD_NODE = 8,\n\tOLD_FN_NODE = 9,\n\tNAMED_NODE = 10,\n\tATTACHMENT = 11,\n\tGENERIC_DEBUG = 12,\n\tSUBRANGE = 13,\n\tENUMERATOR = 14,\n\tBASIC_TYPE = 15,\n\tFILE = 16,\n\tDERIVED_TYPE = 17,\n\tCOMPOSITE_TYPE = 18,\n\tSUBROUTINE_TYPE = 19,\n\tCOMPILE_UNIT = 20,\n\tSUBPROGRAM = 21,\n\tLEXICAL_BLOCK = 22,\n\tLEXICAL_BLOCK_FILE = 23,\n\tNAMESPACE = 24,\n\tTEMPLATE_TYPE = 25,\n\tTEMPLATE_VALUE = 26,\n\tGLOBAL_VAR = 27,\n\tLOCAL_VAR = 28,\n\tEXPRESSION = 29,\n\tOBJC_PROPERTY = 30,\n\tIMPORTED_ENTITY = 31,\n\tMODULE = 32,\n\tMACRO = 33,\n\tMACRO_FILE = 34,\n\tSTRINGS = 35,\n\tGLOBAL_DECL_ATTACHMENT = 36,\n\tGLOBAL_VAR_EXPR = 37,\n\tINDEX_OFFSET = 38,\n\tINDEX = 39,\n\tLABEL = 40,\n\tCOMMON_BLOCK = 44,\n};\n\nenum class AttributeCodes : uint32_t\n{\n\tCodeEntryOld = 1,\n\tCodeEntry = 2,\n\tGroupCodeEntry = 3\n};\n\nenum class TypeRecord : uint32_t\n{\n\tNUMENTRY = 1,\n\tVOID_TYPE = 2,\n\tFLOAT = 3,\n\tDOUBLE = 4,\n\tLABEL = 5,\n\tOPAQUE_TYPE = 6,\n\tINTEGER = 7,\n\tPOINTER = 8,\n\tFUNCTION_OLD = 9,\n\tHALF = 10,\n\tARRAY = 11,\n\tVECTOR = 12,\n\tMETADATA = 16,\n\tSTRUCT_ANON = 18,\n\tSTRUCT_NAME = 19,\n\tSTRUCT_NAMED = 20,\n\tFUNCTION = 21,\n\tTOKEN = 22,\n};\n\nenum class UnaryOp : uint32_t\n{\n\tFNEG = 0\n};\n\nenum class BinOp : uint32_t\n{\n\tADD = 0,\n\tSUB = 1,\n\tMUL = 2,\n\tUDIV = 3,\n\tSDIV = 4,\n\tUREM = 5,\n\tSREM = 6,\n\tSHL = 7,\n\tLSHR = 8,\n\tASHR = 9,\n\tAND = 10,\n\tOR = 11,\n\tXOR = 12\n};\n\nenum class AtomicBinOp : uint32_t\n{\n\tRMW_XCHG = 0,\n\tRMW_ADD = 1,\n\tRMW_SUB = 2,\n\tRMW_AND = 3,\n\tRMW_NAND = 4,\n\tRMW_OR = 5,\n\tRMW_XOR = 6,\n\tRMW_MAX = 7,\n\tRMW_MIN = 8,\n\tRMW_UMAX = 9,\n\tRMW_UMIN = 10,\n\tRMW_FADD = 11,\n\tRMW_FSUB = 12\n};\n\nenum class CastOp : uint32_t\n{\n\tTRUNC = 0,\n\tZEXT = 1,\n\tSEXT = 2,\n\tFPTOUI = 3,\n\tFPTOSI = 4,\n\tUITOFP = 5,\n\tSITOFP = 6,\n\tFPTRUNC = 7,\n\tFPEXT = 8,\n\tPTRTOINT = 9,\n\tINTTOPTR = 10,\n\tBITCAST = 11,\n\tADDSPACECAST = 12\n};\n\nenum CallFlagBits\n{\n\tCALL_TAIL_BIT = 1 << 0,\n\tCALL_CCONV_BIT = 1 << 1,\n\tCALL_MUSTTAIL_BIT = 1 << 14,\n\tCALL_EXPLICIT_TYPE_BIT = 1 << 15,\n\tCALL_NOTAIL_BIT = 1 << 16,\n\tCALL_FMF_BIT = 1 << 17\n};\n\nenum FastMathFlagBits\n{\n\tFAST_MATH_UNSAFE_ALGEBRA_BIT = 1 << 0,\n\tFAST_MATH_ALLOW_CONTRACT_BIT = 1 << 5\n};\n\nstatic int64_t decode_sign_rotated_value(uint64_t v)\n{\n\tbool sign = (v & 1) != 0;\n\tv >>= 1;\n\tif (sign)\n\t\tv = v ? -int64_t(v) : (1ull << 63u);\n\treturn int64_t(v);\n}\n\nstruct ModuleParseContext\n{\n\tFunction *function = nullptr;\n\tModule *module = nullptr;\n\tLLVMContext *context = nullptr;\n\tVector<BasicBlock *> basic_blocks;\n\n\tVector<Value *> values;\n\tVector<Instruction *> instructions;\n\n\tVector<Type *> types;\n\tVector<Function *> functions_with_bodies;\n\tUnorderedMap<uint64_t, MDOperand *> metadata;\n\tUnorderedMap<uint64_t, String> metadata_kind_map;\n\tVector<Vector<std::pair<String, String>>> attribute_lists;\n\tUnorderedMap<uint64_t, Vector<std::pair<String, String>>> attribute_groups;\n\tType *constant_type = nullptr;\n\tString current_metadata_name;\n\n\tbool parse_function_child_block(const BlockOrRecord &entry);\n\tbool parse_record(const BlockOrRecord &entry);\n\tbool parse_constants_record(const BlockOrRecord &entry);\n\tbool parse_constants_block(const BlockOrRecord &entry);\n\tbool parse_metadata_block(const BlockOrRecord &entry);\n\tbool parse_paramattr_block(const BlockOrRecord &entry);\n\tbool parse_paramattr_group_block(const BlockOrRecord &entry);\n\tbool parse_metadata_attachment_record(const BlockOrRecord &entry);\n\tbool parse_metadata_record(const BlockOrRecord &entry, unsigned index);\n\tType *get_constant_type();\n\tbool parse_function_body(const BlockOrRecord &entry);\n\tbool parse_types(const BlockOrRecord &entry);\n\tbool parse_value_symtab(const BlockOrRecord &entry);\n\tbool parse_function_record(const BlockOrRecord &entry);\n\tbool parse_global_variable_record(const BlockOrRecord &entry);\n\tbool parse_version_record(const BlockOrRecord &entry);\n\tbool parse_type(const BlockOrRecord &entry);\n\tbool add_instruction(Instruction *inst);\n\tbool add_value(Value *value);\n\n\tbool add_type(Type *type);\n\tType *get_type(uint64_t index);\n\tbool finish_basic_block();\n\tbool add_successor(BasicBlock *bb);\n\tBasicBlock *get_basic_block(uint64_t index) const;\n\tBasicBlock *current_bb = nullptr;\n\tunsigned basic_block_index = 0;\n\n\tValue *get_value(uint64_t op, Type *expected_type = nullptr, bool force_absolute = false);\n\tstd::pair<Value *, Type *> get_value_and_type(const Vector<uint64_t> &ops, unsigned &index);\n\tValue *get_value(const Vector<uint64_t> &ops, unsigned &index, Type *expected_type);\n\tValue *get_value_signed(uint64_t op, Type *expected_type = nullptr);\n\tMDOperand *get_metadata(uint64_t index) const;\n\tconst char *get_metadata_kind(uint64_t index) const;\n\n\tInstruction *get_instruction(uint64_t index) const;\n\n\tVector<ValueProxy *> pending_forward_references;\n\tVector<std::pair<GlobalVariable *, uint64_t>> global_initializations;\n\tbool resolve_forward_references();\n\tbool resolve_global_initializations();\n\n\tuint64_t tween_id = 1;\n\tuint64_t metadata_tween_id = 1;\n\n\tbool use_relative_id = true;\n\tbool use_strtab = false;\n\tbool seen_first_function_body = false;\n};\n\nValueProxy::ValueProxy(Type *type, ModuleParseContext &context_, uint64_t id_)\n    : Value(type, ValueKind::Proxy)\n    , id(id_)\n    , context(context_)\n{\n}\n\nbool ValueProxy::resolve()\n{\n\tif (proxy)\n\t\treturn true;\n\n\tif (id >= context.values.size())\n\t{\n\t\tLOGE(\"Value proxy is out of range.\\n\");\n\t\treturn false;\n\t}\n\n\tproxy = context.values[id];\n\twhile (proxy && proxy->get_value_kind() == ValueKind::Proxy)\n\t{\n\t\tcast<ValueProxy>(proxy)->resolve();\n\t\tproxy = cast<ValueProxy>(proxy)->get_proxy_value();\n\t}\n\n\tif (!proxy)\n\t{\n\t\tLOGE(\"Failed to resolve proxy value.\\n\");\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nValue *ValueProxy::get_proxy_value() const\n{\n\treturn proxy;\n}\n\nbool ModuleParseContext::finish_basic_block()\n{\n\tbasic_block_index++;\n\tif (basic_block_index >= basic_blocks.size())\n\t\tcurrent_bb = nullptr;\n\telse\n\t{\n\t\tcurrent_bb = basic_blocks[basic_block_index];\n\t\tcurrent_bb->set_tween_id(tween_id++);\n\t}\n\n\treturn true;\n}\n\nbool ModuleParseContext::add_successor(BasicBlock *bb)\n{\n\tif (!current_bb)\n\t{\n\t\tLOGE(\"No basic block is active in add_successor().\\n\");\n\t\treturn false;\n\t}\n\n\tcurrent_bb->add_successor(bb);\n\treturn true;\n}\n\nBasicBlock *ModuleParseContext::get_basic_block(uint64_t index) const\n{\n\tif (index >= basic_blocks.size())\n\t{\n\t\tLOGE(\"Basic block index is out of bounds!\\n\");\n\t\treturn nullptr;\n\t}\n\n\treturn basic_blocks[index];\n}\n\nValue *ModuleParseContext::get_value(uint64_t op, Type *expected_type, bool force_absolute)\n{\n\tif (!force_absolute && use_relative_id)\n\t\top = uint32_t(values.size() - op);\n\n\tif (op >= values.size())\n\t{\n\t\tif (!expected_type)\n\t\t{\n\t\t\tLOGE(\"Must have an expected type for forward references!\\n\");\n\t\t\treturn nullptr;\n\t\t}\n\t\tauto *proxy = context->construct<ValueProxy>(expected_type, *this, op);\n\t\tpending_forward_references.push_back(proxy);\n\t\treturn proxy;\n\t}\n\telse\n\t{\n\t\t// A pointer to function and a constant function do match.\n\t\tif (auto *ptr_type = dyn_cast<PointerType>(expected_type))\n\t\t\tif (ptr_type->getPointerElementType()->getTypeID() == Type::TypeID::FunctionTyID)\n\t\t\t\texpected_type = ptr_type->getPointerElementType();\n\n\t\tif (expected_type && expected_type != values[op]->getType())\n\t\t{\n\t\t\tLOGE(\"Type mismatch.\\n\");\n\t\t\treturn nullptr;\n\t\t}\n\t\treturn values[op];\n\t}\n}\n\nValue *ModuleParseContext::get_value(const Vector<uint64_t> &ops, unsigned &index, Type *expected_type)\n{\n\tif (index >= ops.size())\n\t\treturn nullptr;\n\treturn get_value(ops[index++], expected_type);\n}\n\nstd::pair<Value *, Type *> ModuleParseContext::get_value_and_type(const Vector<uint64_t> &ops, unsigned &index)\n{\n\tif (index >= ops.size())\n\t\treturn {};\n\n\tuint64_t op = ops[index++];\n\tif (use_relative_id)\n\t\top = uint32_t(values.size() - op);\n\n\tif (op < values.size())\n\t{\n\t\t// Normal reference.\n\t\treturn { values[op], values[op]->getType() };\n\t}\n\telse\n\t{\n\t\t// Forward reference, the type is encoded in the next element.\n\t\tif (index >= ops.size())\n\t\t\treturn {};\n\n\t\tauto *type = get_type(ops[index++]);\n\t\tauto *proxy = context->construct<ValueProxy>(type, *this, op);\n\t\tpending_forward_references.push_back(proxy);\n\t\treturn { proxy, type };\n\t}\n}\n\nInstruction *ModuleParseContext::get_instruction(uint64_t index) const\n{\n\tif (index >= instructions.size())\n\t{\n\t\tLOGE(\"Instruction index is out of range!\\n\");\n\t\treturn nullptr;\n\t}\n\n\treturn instructions[index];\n}\n\nMDOperand *ModuleParseContext::get_metadata(uint64_t index) const\n{\n\tauto itr = metadata.find(index);\n\tif (itr != metadata.end())\n\t\treturn itr->second;\n\telse\n\t{\n\t\t// Need to return a null-node like this since MDOperand is used as a reference in the LLVM API for some reason.\n\t\treturn context->construct<MDOperand>(module);\n\t}\n}\n\nconst char *ModuleParseContext::get_metadata_kind(uint64_t index) const\n{\n\tauto itr = metadata_kind_map.find(index);\n\tif (itr != metadata_kind_map.end())\n\t\treturn itr->second.c_str();\n\telse\n\t\treturn nullptr;\n}\n\nValue *ModuleParseContext::get_value_signed(uint64_t op, Type *expected_type)\n{\n\tint64_t signed_op = decode_sign_rotated_value(op);\n\tif (use_relative_id)\n\t\tsigned_op = values.size() - signed_op;\n\top = signed_op;\n\n\tif (op >= values.size())\n\t{\n\t\tif (!expected_type)\n\t\t{\n\t\t\tLOGE(\"Must have an expected type for forward references!\\n\");\n\t\t\treturn nullptr;\n\t\t}\n\t\tauto *proxy = context->construct<ValueProxy>(expected_type, *this, op);\n\t\tpending_forward_references.push_back(proxy);\n\t\treturn proxy;\n\t}\n\telse\n\t\treturn values[op];\n}\n\nbool ModuleParseContext::add_instruction(Instruction *inst)\n{\n\tinstructions.push_back(inst);\n\n\tif (current_bb)\n\t\tcurrent_bb->add_instruction(inst);\n\telse\n\t{\n\t\tLOGE(\"No basic block is currently set!\\n\");\n\t\treturn false;\n\t}\n\n\tif (inst->isTerminator())\n\t\treturn finish_basic_block();\n\telse\n\t\treturn add_value(inst);\n}\n\nbool ModuleParseContext::add_value(Value *value)\n{\n\tif (value->getType()->getTypeID() != Type::TypeID::VoidTyID)\n\t{\n\t\tvalue->set_tween_id(tween_id++);\n\t\tvalues.push_back(value);\n\t}\n\treturn true;\n}\n\nType *ModuleParseContext::get_constant_type()\n{\n\tif (constant_type)\n\t\treturn constant_type;\n\telse\n\t\treturn Type::getInt32Ty(*context);\n}\n\nstatic Type *resolve_gep_element_type(Type *type, const Vector<Value *> &args)\n{\n\tfor (unsigned i = 2; i < args.size(); i++)\n\t{\n\t\tauto *arg = args[i];\n\t\tif (type->getTypeID() == Type::TypeID::StructTyID)\n\t\t{\n\t\t\tauto *const_int = dyn_cast<ConstantInt>(arg);\n\t\t\tif (!const_int)\n\t\t\t{\n\t\t\t\tLOGE(\"Indexing into a struct without a constant integer.\\n\");\n\t\t\t\treturn nullptr;\n\t\t\t}\n\n\t\t\tunsigned index = const_int->getUniqueInteger().getZExtValue();\n\t\t\tif (index >= cast<StructType>(type)->getNumElements())\n\t\t\t{\n\t\t\t\tLOGE(\"Struct element index out of range.\\n\");\n\t\t\t\treturn nullptr;\n\t\t\t}\n\t\t\ttype = cast<StructType>(type)->getElementType(index);\n\t\t}\n\t\telse if (type->getTypeID() == Type::TypeID::ArrayTyID)\n\t\t{\n\t\t\ttype = type->getArrayElementType();\n\t\t}\n\t\telse if (type->getTypeID() == Type::TypeID::VectorTyID)\n\t\t{\n\t\t\ttype = cast<VectorType>(type)->getElementType();\n\t\t}\n\t\telse\n\t\t\treturn nullptr;\n\t}\n\n\treturn type;\n}\n\nstatic BinaryOperator::BinaryOps translate_binop(BinOp op, Type *type)\n{\n\tbool is_fp = type->isFloatingPointTy();\n\tswitch (op)\n\t{\n\tcase BinOp::ADD:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::FAdd : BinaryOperator::BinaryOps::Add;\n\tcase BinOp::SUB:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::FSub : BinaryOperator::BinaryOps::Sub;\n\tcase BinOp::MUL:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::FMul : BinaryOperator::BinaryOps::Mul;\n\tcase BinOp::UDIV:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::UDiv;\n\tcase BinOp::SDIV:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::FDiv : BinaryOperator::BinaryOps::SDiv;\n\tcase BinOp::UREM:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::URem;\n\tcase BinOp::SREM:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::FRem : BinaryOperator::BinaryOps::SRem;\n\tcase BinOp::SHL:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::Shl;\n\tcase BinOp::LSHR:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::LShr;\n\tcase BinOp::ASHR:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::AShr;\n\tcase BinOp::AND:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::And;\n\tcase BinOp::OR:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::Or;\n\tcase BinOp::XOR:\n\t\treturn is_fp ? BinaryOperator::BinaryOps::InvalidBinaryOp : BinaryOperator::BinaryOps::Xor;\n\tdefault:\n\t\treturn BinaryOperator::BinaryOps::InvalidBinaryOp;\n\t}\n}\n\nstatic Instruction::CastOps translate_castop(CastOp op)\n{\n\tswitch (op)\n\t{\n\tcase CastOp::TRUNC:\n\t\treturn Instruction::Trunc;\n\tcase CastOp::ZEXT:\n\t\treturn Instruction::ZExt;\n\tcase CastOp::SEXT:\n\t\treturn Instruction::SExt;\n\tcase CastOp::FPTOUI:\n\t\treturn Instruction::FPToUI;\n\tcase CastOp::FPTOSI:\n\t\treturn Instruction::FPToSI;\n\tcase CastOp::UITOFP:\n\t\treturn Instruction::UIToFP;\n\tcase CastOp::SITOFP:\n\t\treturn Instruction::SIToFP;\n\tcase CastOp::FPTRUNC:\n\t\treturn Instruction::FPTrunc;\n\tcase CastOp::FPEXT:\n\t\treturn Instruction::FPExt;\n\tcase CastOp::PTRTOINT:\n\t\treturn Instruction::PtrToInt;\n\tcase CastOp::INTTOPTR:\n\t\treturn Instruction::IntToPtr;\n\tcase CastOp::BITCAST:\n\t\treturn Instruction::BitCast;\n\tcase CastOp::ADDSPACECAST:\n\t\treturn Instruction::AddrSpaceCast;\n\t}\n\treturn Instruction::CastOps::InvalidCastOp;\n}\n\nbool ModuleParseContext::parse_constants_record(const BlockOrRecord &entry)\n{\n\tif (entry.IsBlock())\n\t\treturn true;\n\n\tswitch (ConstantsRecord(entry.id))\n\t{\n\tcase ConstantsRecord::SETTYPE:\n\t\tif (entry.ops.size() < 1)\n\t\t\treturn false;\n\t\tconstant_type = get_type(entry.ops[0]);\n\t\tbreak;\n\n\tcase ConstantsRecord::CONST_NULL:\n\t{\n\t\tauto *type = get_constant_type();\n\t\tValue *value = nullptr;\n\t\tif (type->isIntegerTy())\n\t\t\tvalue = ConstantInt::get(type, 0);\n\t\telse if (type->isFloatingPointTy())\n\t\t\tvalue = ConstantFP::get(type, 0);\n\t\telse if (isa<ArrayType>(type) || isa<StructType>(type) || isa<VectorType>(type))\n\t\t\tvalue = context->construct<ConstantAggregateZero>(type);\n\t\telse if (isa<PointerType>(type))\n\t\t\tvalue = context->construct<ConstantPointerNull>(type);\n\n\t\tif (!value)\n\t\t{\n\t\t\tLOGE(\"Unknown type for CONST_NULL.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::UNDEF:\n\t{\n\t\tauto *type = get_constant_type();\n\t\tvalues.push_back(UndefValue::get(type));\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::INTEGER:\n\t{\n\t\tif (entry.ops.size() < 1)\n\t\t\treturn false;\n\t\tauto *type = get_constant_type();\n\t\tif (!type->isIntegerTy())\n\t\t{\n\t\t\tLOGE(\"Constant type is not integer.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tuint64_t literal = entry.ops[0];\n\t\tint64_t signed_literal = decode_sign_rotated_value(literal);\n\t\tConstantInt *value = ConstantInt::get(type, signed_literal);\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::WIDE_INTEGER:\n\t\tLOGE(\"WIDE_INTEGER unimplemented.\\n\");\n\t\treturn false;\n\n\tcase ConstantsRecord::FLOAT:\n\t{\n\t\tif (entry.ops.size() < 1)\n\t\t\treturn false;\n\t\tauto *type = get_constant_type();\n\t\tif (!type->isFloatingPointTy())\n\t\t{\n\t\t\tLOGE(\"Constant type is not FP.\\n\");\n\t\t\treturn false;\n\t\t}\n\t\tConstantFP *value = ConstantFP::get(type, entry.ops[0]);\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::AGGREGATE:\n\t{\n\t\tVector<Value *> constants;\n\t\tValue *value;\n\t\tconstants.reserve(entry.ops.size());\n\n\t\tif (auto *struct_type = dyn_cast<StructType>(get_constant_type()))\n\t\t{\n\t\t\tif (entry.ops.size() != struct_type->getStructNumElements())\n\t\t\t{\n\t\t\t\tLOGE(\"Mismatch in struct element counts.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor (unsigned i = 0; i < struct_type->getStructNumElements(); i++)\n\t\t\t\tconstants.push_back(get_value(entry.ops[i], struct_type->getStructElementType(i), true));\n\t\t\tvalue = context->construct<ConstantAggregate>(get_constant_type(), std::move(constants));\n\t\t}\n\t\telse if (isa<ArrayType>(get_constant_type()))\n\t\t{\n\t\t\tauto *element_type = get_constant_type()->getArrayElementType();\n\t\t\tfor (auto &op : entry.ops)\n\t\t\t\tconstants.push_back(get_value(op, element_type, true));\n\t\t\tvalue = context->construct<ConstantAggregate>(get_constant_type(), std::move(constants));\n\t\t}\n\t\telse if (isa<VectorType>(get_constant_type()))\n\t\t{\n\t\t\tauto *element_type = cast<VectorType>(get_constant_type())->getElementType();\n\t\t\tfor (auto &op : entry.ops)\n\t\t\t\tconstants.push_back(get_value(op, element_type, true));\n\t\t\tvalue = context->construct<ConstantAggregate>(get_constant_type(), std::move(constants));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvalue = UndefValue::get(get_constant_type());\n\t\t}\n\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::STRING:\n\t\tLOGE(\"STRING unimplemented.\\n\");\n\t\treturn false;\n\n\tcase ConstantsRecord::BINOP:\n\t{\n\t\tunsigned index = 0;\n\t\tauto *type = get_constant_type();\n\t\tauto op = translate_binop(BinOp(entry.ops[index++]), type);\n\t\tauto *a = get_value(entry.ops[index++], type, true);\n\t\tauto *b = get_value(entry.ops[index++], type, true);\n\t\tauto elements = Vector<Value *>{a, b};\n\t\tValue *value = context->construct<ConstantExpr>(op, type, std::move(elements));\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::CE_CAST:\n\t{\n\t\tunsigned index = 0;\n\n\t\tauto op = translate_castop(CastOp(entry.ops[index++]));\n\n\t\tauto *type = get_constant_type();\n\n\t\tauto *input_value_type = get_type(entry.ops[index++]);\n\t\tif (!input_value_type)\n\t\t\treturn false;\n\t\tauto *input_value = get_value(entry.ops[index++], input_value_type, true);\n\n\t\tauto elements = Vector<Value *>{input_value};\n\t\tValue *value = context->construct<ConstantExpr>(op, type, std::move(elements));\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::DATA:\n\t{\n\t\tbool is_vector = false;\n\t\tType *element_type = nullptr;\n\t\tif (isa<ArrayType>(get_constant_type()))\n\t\t\telement_type = get_constant_type()->getArrayElementType();\n\t\telse if (isa<VectorType>(get_constant_type()))\n\t\t{\n\t\t\telement_type = cast<VectorType>(get_constant_type())->getElementType();\n\t\t\tis_vector = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tLOGE(\"Unknown DATA type.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tbool is_fp = element_type->isFloatingPointTy();\n\t\tbool is_int = element_type->isIntegerTy();\n\t\tVector<Value *> constants;\n\t\tconstants.reserve(entry.ops.size());\n\t\tif (is_fp)\n\t\t{\n\t\t\tfor (auto &op : entry.ops)\n\t\t\t\tconstants.push_back(ConstantFP::get(element_type, op));\n\t\t}\n\t\telse if (is_int)\n\t\t{\n\t\t\tfor (auto &op : entry.ops)\n\t\t\t\tconstants.push_back(ConstantInt::get(element_type, op));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tLOGE(\"Unknown DATA type.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tValue *value;\n\t\tif (is_vector)\n\t\t\tvalue = context->construct<ConstantDataVector>(get_constant_type(), std::move(constants));\n\t\telse\n\t\t\tvalue = context->construct<ConstantDataArray>(get_constant_type(), std::move(constants));\n\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tcase ConstantsRecord::GEP:\n\tcase ConstantsRecord::INBOUNDS_GEP:\n\tcase ConstantsRecord::GEP_WITH_INRANGE_INDEX:\n\t{\n\t\tif (entry.ops.size() < 2)\n\t\t\treturn false;\n\t\tType *pointee_type = nullptr;\n\t\tunsigned index = 0;\n\t\tif (ConstantsRecord(entry.id) == ConstantsRecord::GEP_WITH_INRANGE_INDEX ||\n\t\t\t(entry.ops.size() & 1))\n\t\t{\n\t\t\tpointee_type = get_type(entry.ops[index++]);\n\t\t}\n\n\t\tif (ConstantsRecord(entry.id) == ConstantsRecord::GEP_WITH_INRANGE_INDEX)\n\t\t\tindex++;\n\n\t\tVector<Value *> elements;\n\t\telements.reserve(entry.ops.size() / 2);\n\t\twhile (index < entry.ops.size())\n\t\t{\n\t\t\tauto *type = get_type(entry.ops[index++]);\n\t\t\tauto *value = get_value(entry.ops[index++], type, true);\n\t\t\telements.push_back(value);\n\t\t}\n\n\t\tif (elements.size() < 2)\n\t\t\treturn false;\n\n\t\tif (!pointee_type)\n\t\t\tpointee_type = elements[0]->getType()->getPointerElementType();\n\n\t\tpointee_type = resolve_gep_element_type(pointee_type, elements);\n\t\tif (!pointee_type)\n\t\t\treturn false;\n\t\tpointee_type = PointerType::get(pointee_type, cast<PointerType>(elements[0]->getType())->getAddressSpace());\n\n\t\tauto *value = context->construct<ConstantExpr>(Instruction::GetElementPtr, pointee_type, std::move(elements));\n\t\tvalues.push_back(value);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tLOGE(\"UNKNOWN unimplemented.\\n\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool ModuleParseContext::parse_constants_block(const BlockOrRecord &entry)\n{\n\tconstant_type = nullptr;\n\tfor (auto &child : entry.children)\n\t\tif (!parse_constants_record(child))\n\t\t\treturn false;\n\treturn true;\n}\n\nbool ModuleParseContext::parse_metadata_attachment_record(const BlockOrRecord &entry)\n{\n\tif (MetaDataRecord(entry.id) != MetaDataRecord::ATTACHMENT)\n\t\treturn true;\n\n\tif (entry.ops.size() < 1)\n\t\treturn false;\n\n\tsize_t size = entry.ops.size();\n\tsize_t num_nodes = (size - 1) / 2;\n\tauto *inst = get_instruction(entry.ops[0]);\n\n\tif (!inst)\n\t{\n\t\tLOGE(\"Invalid instruction.\\n\");\n\t\treturn false;\n\t}\n\n\tfor (size_t i = 0; i < num_nodes; i++)\n\t{\n\t\tauto *kind = get_metadata_kind(entry.ops[2 * i + 1]);\n\t\tauto *operand = get_metadata(entry.ops[2 * i + 2]);\n\t\tauto *node = dyn_cast<MDNode>(operand);\n\n\t\tif (!kind)\n\t\t{\n\t\t\tLOGE(\"Invalid metadata kind.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!node)\n\t\t{\n\t\t\tLOGE(\"Invalid metadata attachment.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tinst->setMetadata(kind, node);\n\t}\n\treturn true;\n}\n\nbool ModuleParseContext::parse_metadata_record(const BlockOrRecord &entry, unsigned index)\n{\n\tswitch (MetaDataRecord(entry.id))\n\t{\n\tcase MetaDataRecord::NAME:\n\t{\n\t\tcurrent_metadata_name = entry.getString();\n\t\tbreak;\n\t}\n\n\tcase MetaDataRecord::NAMED_NODE:\n\t{\n\t\tVector<MDNode *> ops;\n\t\tops.reserve(entry.ops.size());\n\t\tfor (auto &op : entry.ops)\n\t\t{\n\t\t\tauto *md = get_metadata(op);\n\t\t\tauto *node = dyn_cast<MDNode>(md);\n\t\t\tops.push_back(node);\n\t\t}\n\n\t\tauto *node = context->construct<NamedMDNode>(module, current_metadata_name, std::move(ops));\n\t\tmodule->add_named_metadata(current_metadata_name, node);\n\t\tmetadata[index] = node;\n\t\tbreak;\n\t}\n\n\tcase MetaDataRecord::DISTINCT_NODE:\n\tcase MetaDataRecord::NODE:\n\t{\n\t\tVector<MDOperand *> ops;\n\t\tops.reserve(entry.ops.size());\n\t\tfor (auto &op : entry.ops)\n\t\t{\n\t\t\t// For some reason, here metadata is indexed with -1?\n\t\t\tauto *md = get_metadata(op - 1);\n\t\t\tops.push_back(md);\n\t\t}\n\n\t\tauto *node = context->construct<MDNode>(module, std::move(ops));\n\t\tnode->set_tween_id(metadata_tween_id++);\n\t\tmodule->add_unnamed_metadata(node);\n\t\tmetadata[index] = node;\n\t\tbreak;\n\t}\n\n\tcase MetaDataRecord::STRING_OLD:\n\t{\n\t\tauto *node = context->construct<MDString>(module, entry.getString());\n\t\tmetadata[index] = node;\n\t\tbreak;\n\t}\n\n\tcase MetaDataRecord::VALUE:\n\t{\n\t\tif (entry.ops.size() < 2)\n\t\t\treturn false;\n\n\t\tauto *value = get_value(entry.ops[1], nullptr, true);\n\t\tif (!value)\n\t\t{\n\t\t\tLOGE(\"Null value!\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto *constant_value = dyn_cast<Constant>(value);\n\t\tif (!constant_value)\n\t\t{\n\t\t\tLOGE(\"Not a constant!\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto *node = context->construct<ConstantAsMetadata>(module, constant_value);\n\t\tmetadata[index] = node;\n\t\tbreak;\n\t}\n\n\tcase MetaDataRecord::KIND:\n\t{\n\t\tif (entry.ops.size() < 1)\n\t\t\treturn false;\n\n\t\tmetadata_kind_map[entry.ops[0]] = entry.getString(1);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn true;\n}\n\nbool ModuleParseContext::parse_metadata_block(const BlockOrRecord &entry)\n{\n\tunsigned index = 0;\n\tfor (auto &child : entry.children)\n\t\tif (!parse_metadata_record(child, index++))\n\t\t\treturn false;\n\treturn true;\n}\n\nbool ModuleParseContext::parse_paramattr_block(const BlockOrRecord &entry)\n{\n\tfor (auto &child : entry.children)\n\t{\n\t\tif (!child.IsRecord())\n\t\t\tcontinue;\n\n\t\t// Don't support the OLD variant unless we observe it in the wild.\n\t\t// DXC doesn't generate it.\n\t\tif (AttributeCodes(child.id) != AttributeCodes::CodeEntry)\n\t\t\treturn false;\n\n\t\tVector<std::pair<String, String>> pairs;\n\t\tfor (auto op : child.ops)\n\t\t{\n\t\t\tauto &grp = attribute_groups[op];\n\t\t\tfor (auto &elem : grp)\n\t\t\t\tpairs.push_back(elem);\n\t\t}\n\t\tattribute_lists.push_back(std::move(pairs));\n\t}\n\treturn true;\n}\n\nbool ModuleParseContext::parse_paramattr_group_block(const BlockOrRecord &entry)\n{\n\tif (!attribute_groups.empty())\n\t{\n\t\tLOGE(\"Cannot use multiple group blocks.\\n\");\n\t\treturn false;\n\t}\n\n\tfor (auto &child : entry.children)\n\t{\n\t\tif (!child.IsRecord())\n\t\t\tcontinue;\n\t\tif (AttributeCodes(child.id) != AttributeCodes::GroupCodeEntry)\n\t\t\tcontinue;\n\n\t\tif (child.ops.size() < 3)\n\t\t\treturn false;\n\n\t\tuint64_t group_id = child.ops[0];\n\t\tuint64_t index = child.ops[1];\n\n\t\tif (index != ~0u) // Only care about attributes on function scope\n\t\t\tcontinue;\n\n\t\tauto &attr_group = attribute_groups[group_id];\n\n\t\tsize_t i = 2;\n\t\tsize_t count = child.ops.size();\n\t\twhile (i < count)\n\t\t{\n\t\t\tif (child.ops[i] == 0) // Enum attribute, skip 2 values\n\t\t\t{\n\t\t\t\ti += 2;\n\t\t\t}\n\t\t\telse if (child.ops[i] == 1) // Integer attribute, skip 2 or 3 values\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t\tif (i >= count)\n\t\t\t\t\treturn false;\n\n\t\t\t\tswitch (AttributeRecord(child.ops[i++]))\n\t\t\t\t{\n\t\t\t\tcase AttributeRecord::ALIGNMENT:\n\t\t\t\tcase AttributeRecord::STACK_ALIGNMENT:\n\t\t\t\tcase AttributeRecord::ALLOC_SIZE:\n\t\t\t\tcase AttributeRecord::DEREFERENCEABLE:\n\t\t\t\tcase AttributeRecord::DEREFERENCEABLE_OR_NULL:\n\t\t\t\t\ti++;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (child.ops[i] == 3 || child.ops[i] == 4) // String attribute\n\t\t\t{\n\t\t\t\tbool has_value = child.ops[i++] == 4;\n\t\t\t\tString kind, value;\n\n\t\t\t\twhile (child.ops[i] != 0 && i < count)\n\t\t\t\t\tkind.push_back(char(child.ops[i++]));\n\t\t\t\tif (child.ops[i] != 0)\n\t\t\t\t\treturn false;\n\t\t\t\ti++;\n\n\t\t\t\tif (has_value)\n\t\t\t\t{\n\t\t\t\t\twhile (child.ops[i] != 0 && i < count)\n\t\t\t\t\t\tvalue.push_back(char(child.ops[i++]));\n\t\t\t\t\tif (child.ops[i] != 0)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\tattr_group.emplace_back(std::move(kind), std::move(value));\n\t\t\t}\n\t\t\telse if (child.ops[i] == 5 || child.ops[i] == 6) // Value attribute\n\t\t\t{\n\t\t\t\tbool has_type = child.ops[i++] == 6;\n\t\t\t\tif (i >= count)\n\t\t\t\t\treturn false;\n\t\t\t\tif (AttributeRecord(child.ops[i++]) == AttributeRecord::BY_VAL && has_type)\n\t\t\t\t\ti++;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\tif (i > count)\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool ModuleParseContext::parse_function_child_block(const BlockOrRecord &entry)\n{\n\tswitch (KnownBlocks(entry.id))\n\t{\n\tcase KnownBlocks::CONSTANTS_BLOCK:\n\t{\n\t\tfor (auto &child : entry.children)\n\t\t\tif (!parse_constants_record(child))\n\t\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase KnownBlocks::METADATA_ATTACHMENT:\n\t{\n\t\tfor (auto &child : entry.children)\n\t\t\tif (!parse_metadata_attachment_record(child))\n\t\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn true;\n}\n\nstatic UnaryOperator::UnaryOps translate_uop(UnaryOp op, Type *type)\n{\n\tbool is_fp = type->isFloatingPointTy();\n\tif (op == UnaryOp::FNEG && is_fp)\n\t\treturn UnaryOperator::UnaryOps::FNeg;\n\telse\n\t\treturn UnaryOperator::UnaryOps::Invalid;\n}\n\nstatic AtomicRMWInst::BinOp translate_atomic_binop(AtomicBinOp op)\n{\n\tswitch (op)\n\t{\n\tcase AtomicBinOp::RMW_XCHG:\n\t\treturn AtomicRMWInst::BinOp::Xchg;\n\tcase AtomicBinOp::RMW_ADD:\n\t\treturn AtomicRMWInst::BinOp::Add;\n\tcase AtomicBinOp::RMW_SUB:\n\t\treturn AtomicRMWInst::BinOp::Sub;\n\tcase AtomicBinOp::RMW_AND:\n\t\treturn AtomicRMWInst::BinOp::And;\n\tcase AtomicBinOp::RMW_NAND:\n\t\treturn AtomicRMWInst::BinOp::Nand;\n\tcase AtomicBinOp::RMW_OR:\n\t\treturn AtomicRMWInst::BinOp::Or;\n\tcase AtomicBinOp::RMW_XOR:\n\t\treturn AtomicRMWInst::BinOp::Xor;\n\tcase AtomicBinOp::RMW_MAX:\n\t\treturn AtomicRMWInst::BinOp::Max;\n\tcase AtomicBinOp::RMW_MIN:\n\t\treturn AtomicRMWInst::BinOp::Min;\n\tcase AtomicBinOp::RMW_UMAX:\n\t\treturn AtomicRMWInst::BinOp::UMax;\n\tcase AtomicBinOp::RMW_UMIN:\n\t\treturn AtomicRMWInst::BinOp::UMin;\n\tcase AtomicBinOp::RMW_FADD:\n\t\treturn AtomicRMWInst::BinOp::FAdd;\n\tcase AtomicBinOp::RMW_FSUB:\n\t\treturn AtomicRMWInst::BinOp::FSub;\n\tdefault:\n\t\treturn AtomicRMWInst::BinOp::Invalid;\n\t}\n}\n\nbool ModuleParseContext::parse_record(const BlockOrRecord &entry)\n{\n\tswitch (FunctionRecord(entry.id))\n\t{\n\tcase FunctionRecord::DECLAREBLOCKS:\n\t{\n\t\tif (entry.ops.size() < 1)\n\t\t\treturn false;\n\t\tbasic_blocks.resize(entry.ops[0]);\n\t\tbasic_block_index = 0;\n\t\tfor (auto &bb : basic_blocks)\n\t\t\tbb = context->construct<BasicBlock>(*context);\n\t\tcurrent_bb = basic_blocks.front();\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_CALL:\n\t{\n\t\tunsigned index = 1;\n\n\t\tif (index >= entry.ops.size())\n\t\t\treturn false;\n\t\tauto CCInfo = entry.ops[index++];\n\n\t\tif (CCInfo & CALL_FMF_BIT)\n\t\t{\n\t\t\tif (index >= entry.ops.size())\n\t\t\t\treturn false;\n\t\t\tauto fmf = entry.ops[index++];\n\t\t\t(void)fmf;\n\t\t}\n\n\t\tFunctionType *function_type = nullptr;\n\t\tif (CCInfo & CALL_EXPLICIT_TYPE_BIT)\n\t\t{\n\t\t\tif (index >= entry.ops.size())\n\t\t\t\treturn false;\n\t\t\tfunction_type = cast<FunctionType>(get_type(entry.ops[index++]));\n\t\t}\n\n\t\tif (index >= entry.ops.size())\n\t\t\treturn false;\n\n\t\tauto *callee = dyn_cast<Function>(get_value(entry.ops[index++]));\n\t\tif (!callee)\n\t\t\treturn false;\n\n\t\tif (!function_type)\n\t\t\tfunction_type = callee->getFunctionType();\n\n\t\tif (!function_type)\n\t\t\treturn false;\n\n\t\tunsigned num_params = function_type->getNumParams();\n\t\tif (entry.ops.size() != index + num_params)\n\t\t{\n\t\t\tLOGE(\"Number of params does not match record.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tVector<Value *> params;\n\t\tparams.reserve(num_params);\n\n\t\tfor (unsigned i = 0; i < num_params; i++)\n\t\t{\n\t\t\tauto *arg = get_value(entry.ops[index + i], function_type->getParamType(i));\n\t\t\tif (!arg)\n\t\t\t\treturn false;\n\t\t\tparams.push_back(arg);\n\t\t}\n\n\t\tauto *value = context->construct<CallInst>(function_type, callee, std::move(params));\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_RET:\n\t{\n\t\tValue *return_val = !entry.ops.empty() ? get_value(entry.ops[0]) : nullptr;\n\t\tauto *ret = context->construct<ReturnInst>(return_val);\n\t\tif (!add_instruction(ret))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_UNREACHABLE:\n\t{\n\t\tauto *ret = context->construct<UnreachableInst>();\n\t\tif (!add_instruction(ret))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_UNOP:\n\t{\n\t\tunsigned index = 0;\n\t\tauto val = get_value_and_type(entry.ops, index);\n\t\tif (!val.first)\n\t\t\treturn false;\n\t\tif (index == entry.ops.size())\n\t\t\treturn false;\n\t\tauto op = UnaryOp(entry.ops[index++]);\n\t\tauto *value = context->construct<UnaryOperator>(translate_uop(op, val.second), val.first);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_CMP:\n\tcase FunctionRecord::INST_CMP2:\n\t{\n\t\tunsigned index = 0;\n\t\tauto lhs = get_value_and_type(entry.ops, index);\n\t\tif (!lhs.first)\n\t\t\treturn false;\n\t\tauto *rhs = get_value(entry.ops, index, lhs.second);\n\t\tif (index == entry.ops.size())\n\t\t\treturn false;\n\t\tauto pred = Instruction::Predicate(entry.ops[index++]);\n\n\t\tif (!rhs)\n\t\t\treturn false;\n\n\t\tInstruction *value = nullptr;\n\t\tif (lhs.second->isFloatingPointTy())\n\t\t\tvalue = context->construct<FCmpInst>(pred, lhs.first, rhs);\n\t\telse\n\t\t\tvalue = context->construct<ICmpInst>(pred, lhs.first, rhs);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_PHI:\n\t{\n\t\tif (entry.ops.size() < 1)\n\t\t\treturn false;\n\n\t\tauto *type = get_type(entry.ops[0]);\n\t\tsize_t num_args = (entry.ops.size() - 1) / 2;\n\n\t\tauto *phi_node = context->construct<PHINode>(type, num_args);\n\n\t\tfor (size_t i = 0; i < num_args; i++)\n\t\t{\n\t\t\tValue *value = nullptr;\n\t\t\tif (use_relative_id)\n\t\t\t\tvalue = get_value_signed(entry.ops[2 * i + 1], type);\n\t\t\telse\n\t\t\t\tvalue = get_value(entry.ops[2 * i + 1], type);\n\n\t\t\tBasicBlock *bb = get_basic_block(entry.ops[2 * i + 2]);\n\t\t\tif (!value || !bb)\n\t\t\t\treturn false;\n\t\t\tphi_node->add_incoming(value, bb);\n\t\t}\n\t\tif (!add_instruction(phi_node))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_BINOP:\n\t{\n\t\tunsigned index = 0;\n\t\tauto lhs = get_value_and_type(entry.ops, index);\n\t\tif (!lhs.first)\n\t\t\treturn false;\n\t\tauto *rhs = get_value(entry.ops, index, lhs.second);\n\t\tif (!lhs.first || !rhs)\n\t\t\treturn false;\n\t\tif (index == entry.ops.size())\n\t\t\treturn false;\n\t\tauto op = BinOp(entry.ops[index++]);\n\t\tauto *value = context->construct<BinaryOperator>(lhs.first, rhs, translate_binop(op, lhs.second));\n\t\tif (index < entry.ops.size())\n\t\t{\n\t\t\t// Only relevant for FP math, but we only look at fast math state for\n\t\t\t// FP operations anyways.\n\t\t\tauto fast_math_flags = entry.ops[index];\n\t\t\tbool fast = (fast_math_flags & (FAST_MATH_UNSAFE_ALGEBRA_BIT | FAST_MATH_ALLOW_CONTRACT_BIT)) != 0;\n\t\t\tvalue->setFast(fast);\n\t\t}\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_ATOMICRMW:\n\t{\n\t\tunsigned index = 0;\n\t\tauto ptr = get_value_and_type(entry.ops, index);\n\t\tif (!ptr.first || !isa<PointerType>(ptr.second))\n\t\t\treturn false;\n\t\tauto *val = get_value(entry.ops, index, ptr.second->getPointerElementType());\n\t\tif (!val)\n\t\t\treturn false;\n\t\tif (index == entry.ops.size())\n\t\t\treturn false;\n\t\tAtomicRMWInst::BinOp op = translate_atomic_binop(AtomicBinOp(entry.ops[index++]));\n\t\tauto *value = context->construct<AtomicRMWInst>(val->getType(), ptr.first, val, op);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_CMPXCHG:\n\t{\n\t\tunsigned index = 0;\n\t\tauto ptr = get_value_and_type(entry.ops, index);\n\t\tauto cmp = get_value_and_type(entry.ops, index);\n\t\tif (!ptr.first || !cmp.first || !isa<PointerType>(ptr.second))\n\t\t\treturn false;\n\t\tauto *new_value = get_value(entry.ops, index, cmp.second);\n\t\tauto *value = context->construct<AtomicCmpXchgInst>(ptr.first, cmp.first, new_value);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_CAST:\n\t{\n\t\tunsigned index = 0;\n\t\tauto input_value = get_value_and_type(entry.ops, index);\n\t\tif (!input_value.first || index + 2 > entry.ops.size())\n\t\t\treturn false;\n\t\tauto *type = get_type(entry.ops[index++]);\n\t\tif (!type)\n\t\t\treturn false;\n\t\tauto op = Instruction::CastOps(translate_castop(CastOp(entry.ops[index++])));\n\t\tauto *value = context->construct<CastInst>(type, input_value.first, op);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_SELECT:\n\tcase FunctionRecord::INST_VSELECT:\n\t{\n\t\tunsigned index = 0;\n\t\tauto true_value = get_value_and_type(entry.ops, index);\n\t\tif (!true_value.first || index + 2 > entry.ops.size())\n\t\t\treturn false;\n\t\tauto *false_value = get_value(entry.ops[index++], true_value.second);\n\t\tauto *cond_value = get_value(entry.ops[index++], Type::getInt1Ty(*context));\n\t\tif (!false_value || !cond_value)\n\t\t\treturn false;\n\t\tauto *value = context->construct<SelectInst>(true_value.first, false_value, cond_value);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_EXTRACTVAL:\n\t{\n\t\tunsigned index = 0;\n\t\tauto aggregate = get_value_and_type(entry.ops, index);\n\t\tif (!aggregate.first)\n\t\t\treturn false;\n\n\t\tif (index == entry.ops.size())\n\t\t\treturn false;\n\n\t\tVector<unsigned> indices;\n\t\tindices.reserve(entry.ops.size() - index);\n\t\tunsigned num_args = entry.ops.size();\n\n\t\tType *type = aggregate.second;\n\t\tfor (; index < num_args; index++)\n\t\t{\n\t\t\tauto element = unsigned(entry.ops[index]);\n\t\t\tif (type->getTypeID() == Type::TypeID::StructTyID)\n\t\t\t{\n\t\t\t\tif (element >= cast<StructType>(type)->getNumElements())\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Struct element index out of range.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\ttype = cast<StructType>(type)->getElementType(element);\n\t\t\t}\n\t\t\telse if (type->getTypeID() == Type::TypeID::ArrayTyID)\n\t\t\t{\n\t\t\t\ttype = type->getArrayElementType();\n\t\t\t}\n\t\t\telse if (type->getTypeID() == Type::TypeID::VectorTyID)\n\t\t\t{\n\t\t\t\ttype = cast<VectorType>(type)->getElementType();\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\n\t\t\t// DXIL does not support vectors, so we're not supposed to index into them any further.\n\t\t\tindices.push_back(element);\n\t\t}\n\n\t\tauto *value = context->construct<ExtractValueInst>(type, aggregate.first, std::move(indices));\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_BR:\n\t{\n\t\tif (entry.ops.size() < 1)\n\t\t\treturn false;\n\n\t\tauto *true_block = get_basic_block(entry.ops[0]);\n\t\tif (!true_block)\n\t\t\treturn false;\n\n\t\tif (!add_successor(true_block))\n\t\t\treturn false;\n\n\t\tif (entry.ops.size() == 1)\n\t\t{\n\t\t\tauto *value = context->construct<BranchInst>(true_block);\n\t\t\tif (!add_instruction(value))\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (entry.ops.size() == 3)\n\t\t{\n\t\t\tauto *false_block = get_basic_block(entry.ops[1]);\n\t\t\tif (!false_block)\n\t\t\t\treturn false;\n\t\t\tif (!add_successor(false_block))\n\t\t\t\treturn false;\n\t\t\tauto *cond = get_value(entry.ops[2], Type::getInt1Ty(*context));\n\t\t\tauto *value = context->construct<BranchInst>(true_block, false_block, cond);\n\t\t\tif (!add_instruction(value))\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_SWITCH:\n\t{\n\t\tif (entry.ops.size() < 3)\n\t\t\treturn false;\n\n\t\tauto *type = get_type(entry.ops[0]);\n\t\tauto *cond = get_value(entry.ops[1]);\n\t\tauto *default_block = get_basic_block(entry.ops[2]);\n\n\t\tif (!type || !cond || !default_block)\n\t\t\treturn false;\n\t\tif (!add_successor(default_block))\n\t\t\treturn false;\n\n\t\tunsigned num_cases = (entry.ops.size() - 3) / 2;\n\t\tauto *inst = context->construct<SwitchInst>(cond, default_block, num_cases);\n\t\tfor (unsigned i = 0; i < num_cases; i++)\n\t\t{\n\t\t\t// For some reason, case values are encoded in absolute terms.\n\t\t\tauto *case_value = get_value(entry.ops[3 + 2 * i], type, true);\n\t\t\tBasicBlock *bb = get_basic_block(entry.ops[4 + 2 * i]);\n\t\t\tif (!case_value || !bb)\n\t\t\t{\n\t\t\t\tLOGE(\"Invalid switch record.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!add_successor(bb))\n\t\t\t\treturn false;\n\t\t\tinst->addCase(case_value, bb);\n\t\t}\n\t\tif (!add_instruction(inst))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_ALLOCA:\n\t{\n\t\tif (entry.ops.size() < 3)\n\t\t\treturn false;\n\t\tauto *allocated_type = get_type(entry.ops[0]);\n\t\tauto *type = get_type(entry.ops[1]);\n\t\tauto *size = get_value(entry.ops[2], nullptr, true);\n\n\t\tif (!allocated_type || !type || !size)\n\t\t\treturn false;\n\n\t\tauto *ptr_type = PointerType::get(allocated_type, 0);\n\n\t\tauto *value = context->construct<AllocaInst>(ptr_type, type, size);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_GEP:\n\t{\n\t\tif (entry.ops.size() < 3)\n\t\t\treturn false;\n\n\t\tbool inbounds = entry.ops[0] != 0;\n\t\tauto *type = get_type(entry.ops[1]);\n\t\tunsigned count = entry.ops.size();\n\t\tVector<Value *> args;\n\t\targs.reserve(count);\n\t\tfor (unsigned i = 2; i < count;)\n\t\t{\n\t\t\tauto value = get_value_and_type(entry.ops, i);\n\t\t\tif (!value.first)\n\t\t\t\treturn false;\n\t\t\targs.push_back(value.first);\n\t\t}\n\n\t\ttype = resolve_gep_element_type(type, args);\n\t\tif (!type)\n\t\t\treturn false;\n\t\ttype = PointerType::get(type, cast<PointerType>(args[0]->getType())->getAddressSpace());\n\n\t\tauto *value = context->construct<GetElementPtrInst>(type, std::move(args), inbounds);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_LOAD:\n\t{\n\t\tunsigned index = 0;\n\t\tauto ptr = get_value_and_type(entry.ops, index);\n\t\tif (index + 2 != entry.ops.size() && index + 3 != entry.ops.size())\n\t\t\treturn false;\n\n\t\tif (!ptr.first || !isa<PointerType>(ptr.second))\n\t\t{\n\t\t\tLOGE(\"Loading from something that is not a pointer.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tType *loaded_type = nullptr;\n\t\tif (index + 3 == entry.ops.size())\n\t\t\tloaded_type = get_type(entry.ops[index++]);\n\t\telse\n\t\t\tloaded_type = cast<PointerType>(ptr.second)->getElementType();\n\n\t\tauto *value = context->construct<LoadInst>(loaded_type, ptr.first);\n\t\tadd_instruction(value);\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_STORE:\n\t{\n\t\tunsigned index = 0;\n\t\tauto ptr = get_value_and_type(entry.ops, index);\n\t\tauto val = get_value_and_type(entry.ops, index);\n\t\tif (!ptr.first || !val.first || index + 2 != entry.ops.size())\n\t\t\treturn false;\n\t\tauto *value = context->construct<StoreInst>(ptr.first, val.first);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_SHUFFLEVEC:\n\t{\n\t\tunsigned index = 0;\n\t\tauto a = get_value_and_type(entry.ops, index);\n\t\tauto *b = get_value(entry.ops, index, a.second);\n\t\tauto shuf = get_value_and_type(entry.ops, index);\n\t\tif (!a.first || !b || !shuf.first || !isa<VectorType>(a.second))\n\t\t\treturn false;\n\n\t\tauto *vec_type = VectorType::get(cast<ConstantDataVector>(shuf.first)->getNumElements(),\n\t\t                                 cast<VectorType>(a.second)->getElementType());\n\t\tauto *value = context->construct<ShuffleVectorInst>(vec_type, a.first, b, shuf.first);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_EXTRACTELT:\n\t{\n\t\tunsigned index = 0;\n\t\tauto vec = get_value_and_type(entry.ops, index);\n\t\tif (!vec.first || !isa<VectorType>(vec.second))\n\t\t\treturn false;\n\t\tauto element_index = get_value_and_type(entry.ops, index);\n\t\tif (!element_index.first)\n\t\t\treturn false;\n\n\t\tauto *value = context->construct<ExtractElementInst>(vec.first, element_index.first);\n\t\tif (!add_instruction(value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase FunctionRecord::INST_INSERTELT:\n\t{\n\t\tunsigned index = 0;\n\t\tauto vec = get_value_and_type(entry.ops, index);\n\t\tif (!vec.first || !isa<VectorType>(vec.second))\n\t\t\treturn false;\n\t\tauto *value = get_value(entry.ops, index, cast<VectorType>(vec.second)->getElementType());\n\t\tauto element_index = get_value_and_type(entry.ops, index);\n\t\tif (!value || !element_index.first)\n\t\t\treturn false;\n\t\tauto *new_value = context->construct<InsertElementInst>(vec.first, value, element_index.first);\n\t\tif (!add_instruction(new_value))\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tLOGE(\"Unhandled instruction!\\n\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool ModuleParseContext::resolve_forward_references()\n{\n\tfor (auto *ref : pending_forward_references)\n\t\tif (!ref->resolve())\n\t\t\treturn false;\n\tpending_forward_references.clear();\n\n\tfor (auto *bb : basic_blocks)\n\t\tfor (auto &inst : *bb)\n\t\t\tif (!inst.resolve_proxy_values())\n\t\t\t\treturn false;\n\n\treturn true;\n}\n\nbool ModuleParseContext::resolve_global_initializations()\n{\n\tfor (auto &ref : global_initializations)\n\t{\n\t\tValue *value = get_value(ref.second, nullptr, true);\n\t\tif (!value)\n\t\t\treturn false;\n\t\tauto *constant_value = dyn_cast<Constant>(value);\n\t\tif (!constant_value)\n\t\t{\n\t\t\tLOGE(\"Global initializer is not a constant!\\n\");\n\t\t\treturn false;\n\t\t}\n\t\tref.first->set_initializer(constant_value);\n\t}\n\tglobal_initializations.clear();\n\treturn true;\n}\n\nbool ModuleParseContext::parse_function_body(const BlockOrRecord &entry)\n{\n\tauto global_values = values;\n\n\t// I think we are supposed to process functions in same order as the module declared them?\n\tif (!seen_first_function_body)\n\t{\n\t\tstd::reverse(functions_with_bodies.begin(), functions_with_bodies.end());\n\t\tseen_first_function_body = true;\n\t}\n\n\tif (functions_with_bodies.empty())\n\t{\n\t\tLOGE(\"No more functions to process?\\n\");\n\t\treturn false;\n\t}\n\n\tfunction = functions_with_bodies.back();\n\tfunctions_with_bodies.pop_back();\n\n\tauto *func_type = function->getFunctionType();\n\tfor (unsigned i = 0; i < func_type->getNumParams(); i++)\n\t{\n\t\tauto *param_type = func_type->getParamType(i);\n\t\tauto *arg = context->construct<Argument>(param_type, i);\n\t\tfunction->add_argument(arg);\n\t\tadd_value(arg);\n\t}\n\n\tfor (auto &child : entry.children)\n\t{\n\t\tif (child.IsBlock())\n\t\t{\n\t\t\tif (!parse_function_child_block(child))\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!parse_record(child))\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (!resolve_forward_references())\n\t\treturn false;\n\tif (!resolve_global_initializations())\n\t\treturn false;\n\n\tfunction->set_basic_blocks(std::move(basic_blocks));\n\tbasic_blocks = {};\n\tbasic_block_index = 0;\n\tmodule->add_function_implementation(function);\n\n\tvalues = global_values;\n\tinstructions.clear();\n\treturn true;\n}\n\nbool ModuleParseContext::parse_type(const BlockOrRecord &child)\n{\n\tType *type = nullptr;\n\tswitch (TypeRecord(child.id))\n\t{\n\tcase TypeRecord::NUMENTRY:\n\tcase TypeRecord::STRUCT_NAME:\n\t\treturn true;\n\n\tcase TypeRecord::VOID_TYPE:\n\t\ttype = Type::getVoidTy(*context);\n\t\tbreak;\n\n\tcase TypeRecord::HALF:\n\t\ttype = Type::getHalfTy(*context);\n\t\tbreak;\n\n\tcase TypeRecord::FLOAT:\n\t\ttype = Type::getFloatTy(*context);\n\t\tbreak;\n\n\tcase TypeRecord::DOUBLE:\n\t\ttype = Type::getDoubleTy(*context);\n\t\tbreak;\n\n\tcase TypeRecord::POINTER:\n\t{\n\t\tif (child.ops.size() < 2)\n\t\t\treturn false;\n\n\t\tauto *pointee_type = get_type(child.ops[0]);\n\t\tif (!pointee_type)\n\t\t\treturn false;\n\t\ttype = PointerType::get(pointee_type, child.ops[1]);\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::ARRAY:\n\t{\n\t\tif (child.ops.size() < 2)\n\t\t\treturn false;\n\n\t\tauto *elem_type = get_type(child.ops[1]);\n\t\tif (!elem_type)\n\t\t\treturn false;\n\t\ttype = ArrayType::get(elem_type, child.ops[0]);\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::INTEGER:\n\t{\n\t\tif (child.ops.size() < 1)\n\t\t\treturn false;\n\n\t\tauto bit_width = child.ops[0];\n\t\tif (bit_width <= 64)\n\t\t\ttype = Type::getIntTy(*context, unsigned(bit_width));\n\t\telse\n\t\t\treturn false;\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::STRUCT_NAMED:\n\tcase TypeRecord::STRUCT_ANON:\n\t{\n\t\tif (child.ops.size() < 1)\n\t\t\treturn false;\n\n\t\tVector<Type *> members;\n\t\tunsigned num_members = child.ops.size() - 1;\n\t\tmembers.reserve(num_members);\n\t\tfor (unsigned i = 0; i < num_members; i++)\n\t\t\tmembers.push_back(get_type(child.ops[i + 1]));\n\t\ttype = StructType::get(*context, std::move(members));\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::VECTOR:\n\t{\n\t\tif (child.ops.size() < 2)\n\t\t\treturn false;\n\n\t\tauto *elem_type = get_type(child.ops[1]);\n\t\tif (!elem_type)\n\t\t\treturn false;\n\t\ttype = VectorType::get(child.ops[0], elem_type);\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::FUNCTION:\n\t{\n\t\tif (child.ops.size() < 2)\n\t\t\treturn false;\n\t\tVector<Type *> argument_types;\n\t\targument_types.reserve(child.ops.size() - 2);\n\t\tfor (size_t i = 2; i < child.ops.size(); i++)\n\t\t\targument_types.push_back(get_type(child.ops[i]));\n\n\t\tauto *func_type = get_type(child.ops[1]);\n\t\tif (!func_type)\n\t\t\treturn false;\n\n\t\ttype = context->construct<FunctionType>(*context, func_type, std::move(argument_types));\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::LABEL:\n\t{\n\t\ttype = Type::getLabelTy(*context);\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::METADATA:\n\t{\n\t\ttype = Type::getMetadataTy(*context);\n\t\tbreak;\n\t}\n\n\tcase TypeRecord::OPAQUE_TYPE:\n\t{\n\t\ttype = Type::getOpaqueTy(*context);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tLOGE(\"Unknown type!\\n\");\n\t\treturn false;\n\t}\n\n\tadd_type(type);\n\treturn true;\n}\n\nbool ModuleParseContext::parse_types(const BlockOrRecord &entry)\n{\n\tfor (auto &child : entry.children)\n\t\tif (!parse_type(child))\n\t\t\treturn false;\n\treturn true;\n}\n\nbool ModuleParseContext::parse_value_symtab(const BlockOrRecord &entry)\n{\n\tfor (auto &symtab : entry.children)\n\t{\n\t\tswitch (ValueSymtabRecord(symtab.id))\n\t\t{\n\t\tcase ValueSymtabRecord::ENTRY:\n\t\t{\n\t\t\tif (symtab.ops.size() < 1)\n\t\t\t\treturn false;\n\n\t\t\tauto name = symtab.getString(1);\n\t\t\tmodule->add_value_name(symtab.ops[0], name);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn true;\n}\n\nstatic GlobalVariable::LinkageTypes decode_linkage(uint64_t v)\n{\n\tswitch (v)\n\t{\n\tcase 0:\n\tcase 5:\n\tcase 6:\n\tcase 15:\n\t\treturn GlobalVariable::ExternalLinkage;\n\n\tcase 2:\n\t\treturn GlobalVariable::AppendingLinkage;\n\n\tdefault:\n\t\treturn GlobalVariable::InternalLinkage;\n\t}\n}\n\nbool ModuleParseContext::parse_global_variable_record(const BlockOrRecord &entry)\n{\n\tif (use_strtab)\n\t{\n\t\tLOGE(\"Unknown module code 2 which uses strtab.\\n\");\n\t\treturn false;\n\t}\n\n\tif (entry.ops.size() < 4)\n\t\treturn false;\n\n\tauto *type = get_type(entry.ops[0]);\n\tbool is_const = (entry.ops[1] & 1) != 0;\n\tbool explicit_type = (entry.ops[1] & 2) != 0;\n\tunsigned address_space = 0;\n\tif (explicit_type)\n\t\taddress_space = entry.ops[1] >> 2;\n\telse\n\t{\n\t\taddress_space = cast<PointerType>(type)->getAddressSpace();\n\t\ttype = cast<PointerType>(type)->getElementType();\n\t}\n\n\tif (!type)\n\t\treturn false;\n\n\tauto linkage = decode_linkage(entry.ops[3]);\n\n\tauto *value = context->construct<GlobalVariable>(PointerType::get(type, address_space), linkage, is_const);\n\tmodule->add_global_variable(value);\n\tadd_value(value);\n\n\tuint64_t init_id = entry.ops[2];\n\tif (init_id != 0)\n\t\tglobal_initializations.push_back({ value, init_id - 1 });\n\n\treturn true;\n}\n\nbool ModuleParseContext::parse_function_record(const BlockOrRecord &entry)\n{\n\tif (use_strtab)\n\t{\n\t\tLOGE(\"Unknown module code 2 which uses strtab.\\n\");\n\t\treturn false;\n\t}\n\n\tif (entry.ops.size() < 3)\n\t\treturn false;\n\n\tauto *type = get_type(entry.ops[0]);\n\tif (!type)\n\t\treturn false;\n\n\t// Calling convention is [1], not relevant.\n\tbool is_proto = entry.ops[2];\n\t// Lots of other irrelevant arguments ...\n\n\tauto *func_type = dyn_cast<FunctionType>(type);\n\tif (!func_type)\n\t\tfunc_type = cast<FunctionType>(cast<PointerType>(type)->getElementType());\n\n\tif (!func_type)\n\t\treturn false;\n\n\tauto id = values.size();\n\tauto *func = context->construct<Function>(func_type, id, *module);\n\n\tif (entry.ops.size() >= 5 && entry.ops[4] != 0 && (entry.ops[4] - 1) < attribute_lists.size())\n\t\tfunc->set_attributes(attribute_lists[entry.ops[4] - 1]);\n\n\tvalues.push_back(func);\n\n\tif (!is_proto)\n\t\tfunctions_with_bodies.push_back(func);\n\n\treturn true;\n}\n\nbool ModuleParseContext::parse_version_record(const BlockOrRecord &entry)\n{\n\tif (entry.ops.size() < 1)\n\t\treturn false;\n\tunsigned version = entry.ops[0];\n\tuse_relative_id = version >= 1;\n\tuse_strtab = version >= 2;\n\treturn true;\n}\n\nType *ModuleParseContext::get_type(uint64_t index)\n{\n\tif (index >= types.size())\n\t\treturn nullptr;\n\treturn types[index];\n}\n\nbool ModuleParseContext::add_type(Type *type)\n{\n\ttypes.push_back(type);\n\treturn true;\n}\n\nvoid Module::add_value_name(uint64_t id, const String &name)\n{\n\tvalue_symtab[id] = name;\n}\n\nvoid Module::add_function_implementation(Function *func)\n{\n\tfunctions.push_back(func);\n}\n\nvoid Module::add_global_variable(GlobalVariable *variable)\n{\n\tglobals.push_back(variable);\n}\n\nvoid Module::add_named_metadata(const String &name, NamedMDNode *node)\n{\n\tnamed_metadata[name] = node;\n}\n\nvoid Module::add_unnamed_metadata(MDNode *node)\n{\n\tunnamed_metadata.push_back(node);\n}\n\nFunction *Module::getFunction(const String &name) const\n{\n\tauto itr =\n\t    std::find_if(functions.begin(), functions.end(), [&](const Function *func) { return func->getName() == name; });\n\n\tif (itr != functions.end())\n\t\treturn *itr;\n\telse\n\t\treturn nullptr;\n}\n\nNamedMDNode *Module::getNamedMetadata(const String &name) const\n{\n\tauto itr = named_metadata.find(name);\n\tif (itr != named_metadata.end())\n\t\treturn itr->second;\n\telse\n\t\treturn nullptr;\n}\n\nstatic const String empty_string;\nconst String &Module::get_value_name(uint64_t id) const\n{\n\tauto itr = value_symtab.find(id);\n\tif (itr != value_symtab.end())\n\t\treturn itr->second;\n\telse\n\t\treturn empty_string;\n}\n\nLLVMContext &Module::getContext()\n{\n\treturn context;\n}\n\nModule::Module(LLVMContext &context_)\n    : context(context_)\n{\n}\n\nVector<Function *>::const_iterator Module::begin() const\n{\n\treturn functions.begin();\n}\n\nVector<Function *>::const_iterator Module::end() const\n{\n\treturn functions.end();\n}\n\nIteratorAdaptor<GlobalVariable, Vector<GlobalVariable *>::const_iterator> Module::global_begin() const\n{\n\treturn globals.begin();\n}\n\nIteratorAdaptor<GlobalVariable, Vector<GlobalVariable *>::const_iterator> Module::global_end() const\n{\n\treturn globals.end();\n}\n\nUnorderedMap<String, NamedMDNode *>::const_iterator Module::named_metadata_begin() const\n{\n\treturn named_metadata.begin();\n}\n\nUnorderedMap<String, NamedMDNode *>::const_iterator Module::named_metadata_end() const\n{\n\treturn named_metadata.end();\n}\n\nVector<MDNode *>::const_iterator Module::unnamed_metadata_begin() const\n{\n\treturn unnamed_metadata.begin();\n}\n\nVector<MDNode *>::const_iterator Module::unnamed_metadata_end() const\n{\n\treturn unnamed_metadata.end();\n}\n\nModule *parseIR(LLVMContext &context, const void *data, size_t size)\n{\n\tLLVMBC::BitcodeReader reader(static_cast<const uint8_t *>(data), size);\n\tauto toplevel = reader.ReadToplevelBlock();\n\n\t// The top-level block must be MODULE_BLOCK.\n\tif (KnownBlocks(toplevel.id) != KnownBlocks::MODULE_BLOCK)\n\t\treturn nullptr;\n\n\t// We should have consumed all bits, only one top-level block.\n\tif (!reader.AtEndOfStream())\n\t\treturn nullptr;\n\n\tauto *module = context.construct<Module>(context);\n\n\tModuleParseContext parse_context;\n\tparse_context.module = module;\n\tparse_context.context = &module->getContext();\n\n\tfor (auto &child : toplevel.children)\n\t{\n\t\tif (child.IsBlock())\n\t\t{\n\t\t\tswitch (KnownBlocks(child.id))\n\t\t\t{\n\t\t\tcase KnownBlocks::VALUE_SYMTAB_BLOCK:\n\t\t\t\tif (!parse_context.parse_value_symtab(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase KnownBlocks::FUNCTION_BLOCK:\n\t\t\t\tif (!parse_context.parse_function_body(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase KnownBlocks::TYPE_BLOCK:\n\t\t\t\tif (!parse_context.parse_types(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase KnownBlocks::CONSTANTS_BLOCK:\n\t\t\t\tif (!parse_context.parse_constants_block(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase KnownBlocks::METADATA_BLOCK:\n\t\t\t\tif (!parse_context.parse_metadata_block(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase KnownBlocks::PARAMATTR_BLOCK:\n\t\t\t\tif (!parse_context.parse_paramattr_block(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase KnownBlocks::PARAMATTR_GROUP_BLOCK:\n\t\t\t\tif (!parse_context.parse_paramattr_group_block(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tswitch (ModuleRecord(child.id))\n\t\t\t{\n\t\t\tcase ModuleRecord::VERSION:\n\t\t\t\tif (!parse_context.parse_version_record(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase ModuleRecord::FUNCTION:\n\t\t\t\tif (!parse_context.parse_function_record(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tcase ModuleRecord::GLOBAL_VARIABLE:\n\t\t\t\tif (!parse_context.parse_global_variable_record(child))\n\t\t\t\t\treturn nullptr;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn module;\n}\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/module.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\nnamespace dxbc_spv\n{\nnamespace ir\n{\nclass Builder;\n}\n}\n\n#include \"data_structures.hpp\"\n#include \"iterator.hpp\"\n#include <exception>\n#include <stddef.h>\n#include <type_traits>\n#include <utility>\n\n// A reasonably small LLVM C++ API lookalike.\n\n#define llvm LLVMBC\n\nnamespace LLVMBC\n{\nclass Function;\nclass LLVMContext;\nclass Type;\nclass Instruction;\nclass Function;\nclass BasicBlock;\nclass GlobalVariable;\nclass NamedMDNode;\nclass MDNode;\n\nclass Module\n{\npublic:\n\texplicit Module(LLVMContext &context);\n\tLLVMContext &getContext();\n\n\tNamedMDNode *getNamedMetadata(const String &name) const;\n\n\tFunction *getFunction(const String &name) const;\n\n\tvoid add_value_name(uint64_t id, const String &name);\n\tvoid add_function_implementation(Function *func);\n\tvoid add_global_variable(GlobalVariable *variable);\n\tvoid add_named_metadata(const String &name, NamedMDNode *node);\n\tvoid add_unnamed_metadata(MDNode *node);\n\tconst String &get_value_name(uint64_t id) const;\n\n\tVector<Function *>::const_iterator begin() const;\n\tVector<Function *>::const_iterator end() const;\n\n\tIteratorAdaptor<GlobalVariable, Vector<GlobalVariable *>::const_iterator> global_begin() const;\n\tIteratorAdaptor<GlobalVariable, Vector<GlobalVariable *>::const_iterator> global_end() const;\n\n\tUnorderedMap<String, NamedMDNode *>::const_iterator named_metadata_begin() const;\n\tUnorderedMap<String, NamedMDNode *>::const_iterator named_metadata_end() const;\n\n\tVector<MDNode *>::const_iterator unnamed_metadata_begin() const;\n\tVector<MDNode *>::const_iterator unnamed_metadata_end() const;\n\nprivate:\n\tLLVMContext &context;\n\tVector<Function *> functions;\n\tVector<GlobalVariable *> globals;\n\tUnorderedMap<uint64_t, String> value_symtab;\n\tUnorderedMap<String, NamedMDNode *> named_metadata;\n\tVector<MDNode *> unnamed_metadata;\n};\n\nModule *parseIR(LLVMContext &context, const void *data, size_t size);\nModule *parseDXBCIR(LLVMContext &context, dxbc_spv::ir::Builder &builder);\nModule *parseDXBCBinary(LLVMContext &context, const void *data, size_t size);\nbool disassemble(Module &module, String &str);\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/module_dxbc_ir.cpp",
    "content": "/* Copyright (c) 2025 Hans-Kristian Arntzen for Valve Corporation\n*\n* SPDX-License-Identifier: MIT\n*\n* Permission is hereby granted, free of charge, to any person obtaining\n* a copy of this software and associated documentation files (the\n* \"Software\"), to deal in the Software without restriction, including\n* without limitation the rights to use, copy, modify, merge, publish,\n* distribute, sublicense, and/or sell copies of the Software, and to\n* permit persons to whom the Software is furnished to do so, subject to\n* the following conditions:\n*\n* The above copyright notice and this permission notice shall be\n* included in all copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#include \"module.hpp\"\n#include \"context.hpp\"\n#include \"metadata.hpp\"\n#include \"cast.hpp\"\n#include \"function.hpp\"\n#include \"instruction.hpp\"\n#include <array>\n\n#include \"../dxil.hpp\"\n#include <assert.h>\n\n// dxbc-spirv\n#include \"ir/ir.h\"\n#include \"ir/ir_builder.h\"\n#include \"dxbc/dxbc_api.h\"\n#include \"util/util_log.h\"\nusing namespace dxbc_spv;\n\nclass ScopedLogger : util::Logger\n{\n\npublic:\n\n\tvirtual void message(util::LogLevel severity, const char* text)\n\t{\n\t\tswitch (severity)\n\t\t{\n\t\t\tcase util::LogLevel::eDebug:\n\t\t\tcase util::LogLevel::eInfo: LOGI(\"%s\\n\", text); break;\n\t\t\tcase util::LogLevel::eWarn: LOGW(\"%s\\n\", text); break;\n\t\t\tcase util::LogLevel::eError: LOGE(\"%s\\n\", text); break;\n\t\t}\n\t}\n\n\tvirtual util::LogLevel getMinimumSeverity()\n\t{\n\t\treturn util::LogLevel::eInfo;\n\t}\n\n};\n\nnamespace LLVMBC\n{\ntemplate <typename Func>\nstatic void for_all_opcodes(ir::Builder &builder, ir::OpCode opcode, const Func &func)\n{\n\tfor (auto &op : builder)\n\t\tif (op.getOpCode() == opcode)\n\t\t\tif (!func(op))\n\t\t\t\treturn;\n}\n\nstatic const char *shader_stage_to_meta(ir::ShaderStage stage)\n{\n\tswitch (stage)\n\t{\n\tcase ir::ShaderStage::eVertex:\n\t\treturn \"vs\";\n\tcase ir::ShaderStage::eHull:\n\t\treturn \"hs\";\n\tcase ir::ShaderStage::eDomain:\n\t\treturn \"ds\";\n\tcase ir::ShaderStage::eGeometry:\n\t\treturn \"gs\";\n\tcase ir::ShaderStage::ePixel:\n\t\treturn \"ps\";\n\tcase ir::ShaderStage::eCompute:\n\t\treturn \"cs\";\n\tdefault:\n\t\treturn \"\";\n\t}\n}\n\nstatic DXIL::InputPrimitive convert_input_primitive_type(ir::PrimitiveType type)\n{\n\tswitch (type)\n\t{\n\tcase ir::PrimitiveType::eLines:\n\t\treturn DXIL::InputPrimitive::Line;\n\tcase ir::PrimitiveType::eLinesAdj:\n\t\treturn DXIL::InputPrimitive::LineWithAdjacency;\n\tcase ir::PrimitiveType::ePoints:\n\t\treturn DXIL::InputPrimitive::Point;\n\tcase ir::PrimitiveType::eTriangles:\n\t\treturn DXIL::InputPrimitive::Triangle;\n\tcase ir::PrimitiveType::eTrianglesAdj:\n\t\treturn DXIL::InputPrimitive::TriangleWithAdjaceny;\n\tdefault:\n\t\treturn DXIL::InputPrimitive::Undefined;\n\t}\n}\n\nstatic DXIL::PrimitiveTopology convert_output_primitive_type(ir::PrimitiveType type)\n{\n\tswitch (type)\n\t{\n\tcase ir::PrimitiveType::eLines:\n\t\treturn DXIL::PrimitiveTopology::LineStrip;\n\tcase ir::PrimitiveType::ePoints:\n\t\treturn DXIL::PrimitiveTopology::PointList;\n\tcase ir::PrimitiveType::eTriangles:\n\t\treturn DXIL::PrimitiveTopology::TriangleStrip;\n\tdefault:\n\t\treturn DXIL::PrimitiveTopology::Undefined;\n\t}\n}\n\nstatic DXIL::ResourceKind convert_resource_kind(ir::ResourceKind kind)\n{\n\tswitch (kind)\n\t{\n\tcase ir::ResourceKind::eBufferRaw:\n\t\treturn DXIL::ResourceKind::RawBuffer;\n\tcase ir::ResourceKind::eBufferStructured:\n\t\treturn DXIL::ResourceKind::StructuredBuffer;\n\tcase ir::ResourceKind::eBufferTyped:\n\t\treturn DXIL::ResourceKind::TypedBuffer;\n\tcase ir::ResourceKind::eImage1D:\n\t\treturn DXIL::ResourceKind::Texture1D;\n\tcase ir::ResourceKind::eImage1DArray:\n\t\treturn DXIL::ResourceKind::Texture1DArray;\n\tcase ir::ResourceKind::eImage2D:\n\t\treturn DXIL::ResourceKind::Texture2D;\n\tcase ir::ResourceKind::eImage2DArray:\n\t\treturn DXIL::ResourceKind::Texture2DArray;\n\tcase ir::ResourceKind::eImage3D:\n\t\treturn DXIL::ResourceKind::Texture3D;\n\tcase ir::ResourceKind::eImageCube:\n\t\treturn DXIL::ResourceKind::TextureCube;\n\tcase ir::ResourceKind::eImageCubeArray:\n\t\treturn DXIL::ResourceKind::TextureCubeArray;\n\tcase ir::ResourceKind::eImage2DMS:\n\t\treturn DXIL::ResourceKind::Texture2DMS;\n\tcase ir::ResourceKind::eImage2DMSArray:\n\t\treturn DXIL::ResourceKind::Texture2DMSArray;\n\tdefault:\n\t\tLOGE(\"Unrecognized resource kind %d\\n\", int(kind));\n\t\treturn DXIL::ResourceKind::Invalid;\n\t}\n}\n\nstatic DXIL::Op convert_builtin_opcode(ir::BuiltIn builtin)\n{\n\tswitch (builtin)\n\t{\n\tcase ir::BuiltIn::eSampleCount:\n\t\treturn DXIL::Op::RenderTargetGetSampleCount;\n\tcase ir::BuiltIn::eLocalThreadIndex:\n\t\treturn DXIL::Op::FlattenedThreadIdInGroup;\n\tcase ir::BuiltIn::eIsFullyCovered:\n\t\treturn DXIL::Op::InnerCoverage;\n\tcase ir::BuiltIn::eGsInstanceId:\n\t\treturn DXIL::Op::GSInstanceID;\n\tcase ir::BuiltIn::ePrimitiveId:\n\t\treturn DXIL::Op::PrimitiveID;\n\tcase ir::BuiltIn::eTessControlPointId:\n\t\treturn DXIL::Op::OutputControlPointID;\n\tcase ir::BuiltIn::eTessControlPointCountIn:\n\t\treturn DXIL::Op::ExtendedSpirvControlPointCountIn;\n\n\tdefault:\n\t\treturn DXIL::Op::Count;\n\t}\n}\n\nstatic DXIL::Semantic convert_semantic(ir::BuiltIn builtin)\n{\n\tswitch (builtin)\n\t{\n\tcase ir::BuiltIn::ePosition:\n\t\treturn DXIL::Semantic::Position;\n\tcase ir::BuiltIn::eClipDistance:\n\t\treturn DXIL::Semantic::ClipDistance;\n\tcase ir::BuiltIn::eCullDistance:\n\t\treturn DXIL::Semantic::CullDistance;\n\tcase ir::BuiltIn::eVertexId:\n\t\treturn DXIL::Semantic::VertexID;\n\tcase ir::BuiltIn::eInstanceId:\n\t\treturn DXIL::Semantic::InstanceID;\n\tcase ir::BuiltIn::ePrimitiveId:\n\t\treturn DXIL::Semantic::PrimitiveID;\n\tcase ir::BuiltIn::eLayerIndex:\n\t\treturn DXIL::Semantic::RenderTargetArrayIndex;\n\tcase ir::BuiltIn::eViewportIndex:\n\t\treturn DXIL::Semantic::ViewPortArrayIndex;\n\tcase ir::BuiltIn::eGsInstanceId:\n\t\treturn DXIL::Semantic::GSInstanceID;\n\tcase ir::BuiltIn::eTessControlPointId:\n\t\treturn DXIL::Semantic::OutputControlPointID;\n\tcase ir::BuiltIn::eTessCoord:\n\t\treturn DXIL::Semantic::DomainLocation;\n\tcase ir::BuiltIn::eTessFactorInner:\n\t\treturn DXIL::Semantic::InsideTessFactor;\n\tcase ir::BuiltIn::eTessFactorOuter:\n\t\treturn DXIL::Semantic::TessFactor;\n\tcase ir::BuiltIn::eSampleId:\n\t\treturn DXIL::Semantic::SampleIndex;\n\tcase ir::BuiltIn::eSampleMask:\n\t\treturn DXIL::Semantic::Coverage;\n\tcase ir::BuiltIn::eIsFrontFace:\n\t\treturn DXIL::Semantic::IsFrontFace;\n\tcase ir::BuiltIn::eDepth:\n\t\treturn DXIL::Semantic::Depth;\n\tcase ir::BuiltIn::eStencilRef:\n\t\treturn DXIL::Semantic::StencilRef;\n\tcase ir::BuiltIn::eGlobalThreadId:\n\t\treturn DXIL::Semantic::DispatchThreadID;\n\tcase ir::BuiltIn::eLocalThreadId:\n\t\treturn DXIL::Semantic::GroupThreadID;\n\tcase ir::BuiltIn::eWorkgroupId:\n\t\treturn DXIL::Semantic::GroupID;\n\n\tdefault:\n\t\treturn DXIL::Semantic::User;\n\t}\n}\n\nstatic DXIL::InterpolationMode convert_interpolation_mode(ir::InterpolationMode mode)\n{\n\tswitch (mode)\n\t{\n\tcase ir::InterpolationMode::eCentroid:\n\t\treturn DXIL::InterpolationMode::LinearCentroid;\n\tcase ir::InterpolationMode::eNoPerspective:\n\t\treturn DXIL::InterpolationMode::LinearNoperspective;\n\tcase ir::InterpolationMode::eFlat:\n\t\treturn DXIL::InterpolationMode::Constant;\n\tcase ir::InterpolationMode::eSample:\n\t\treturn DXIL::InterpolationMode::LinearSample;\n\tdefault:\n\t\treturn DXIL::InterpolationMode::Undefined;\n\t}\n}\n\nstatic DXIL::AtomicBinOp convert_atomic_binop(ir::AtomicOp binop)\n{\n\tswitch (binop)\n\t{\n\tcase ir::AtomicOp::eAdd:\n\tcase ir::AtomicOp::eInc:\n\t\treturn DXIL::AtomicBinOp::IAdd;\n\tcase ir::AtomicOp::eAnd:\n\t\treturn DXIL::AtomicBinOp::And;\n\tcase ir::AtomicOp::eOr:\n\t\treturn DXIL::AtomicBinOp::Or;\n\tcase ir::AtomicOp::eXor:\n\t\treturn DXIL::AtomicBinOp::Xor;\n\tcase ir::AtomicOp::eExchange:\n\t\treturn DXIL::AtomicBinOp::Exchange;\n\tcase ir::AtomicOp::eSMax:\n\t\treturn DXIL::AtomicBinOp::IMax;\n\tcase ir::AtomicOp::eSMin:\n\t\treturn DXIL::AtomicBinOp::IMin;\n\tcase ir::AtomicOp::eUMax:\n\t\treturn DXIL::AtomicBinOp::UMax;\n\tcase ir::AtomicOp::eUMin:\n\t\treturn DXIL::AtomicBinOp::UMin;\n\tcase ir::AtomicOp::eSub:\n\tcase ir::AtomicOp::eDec:\n\t\treturn DXIL::AtomicBinOp::Sub;\n\tcase ir::AtomicOp::eLoad:\n\t\treturn DXIL::AtomicBinOp::Load;\n\tcase ir::AtomicOp::eStore:\n\t\treturn DXIL::AtomicBinOp::Store;\n\tdefault:\n\t\treturn DXIL::AtomicBinOp::Invalid;\n\t}\n}\n\nstatic AtomicRMWInst::BinOp convert_atomic_binop_llvm(ir::AtomicOp binop)\n{\n\tswitch (binop)\n\t{\n\tcase ir::AtomicOp::eAdd:\n\tcase ir::AtomicOp::eInc:\n\t\treturn AtomicRMWInst::BinOp::Add;\n\tcase ir::AtomicOp::eAnd:\n\t\treturn AtomicRMWInst::BinOp::And;\n\tcase ir::AtomicOp::eOr:\n\t\treturn AtomicRMWInst::BinOp::Or;\n\tcase ir::AtomicOp::eXor:\n\t\treturn AtomicRMWInst::BinOp::Xor;\n\tcase ir::AtomicOp::eExchange:\n\t\treturn AtomicRMWInst::BinOp::Xchg;\n\tcase ir::AtomicOp::eSMax:\n\t\treturn AtomicRMWInst::BinOp::Max;\n\tcase ir::AtomicOp::eSMin:\n\t\treturn AtomicRMWInst::BinOp::Min;\n\tcase ir::AtomicOp::eUMax:\n\t\treturn AtomicRMWInst::BinOp::UMax;\n\tcase ir::AtomicOp::eUMin:\n\t\treturn AtomicRMWInst::BinOp::UMin;\n\tcase ir::AtomicOp::eSub:\n\tcase ir::AtomicOp::eDec:\n\t\treturn AtomicRMWInst::BinOp::Sub;\n\tcase ir::AtomicOp::eLoad:\n\t\treturn AtomicRMWInst::BinOp::Or;\n\tcase ir::AtomicOp::eStore:\n\t\treturn AtomicRMWInst::BinOp::Xchg;\n\tdefault:\n\t\treturn AtomicRMWInst::BinOp::Invalid;\n\t}\n}\n\nstatic DXIL::Op convert_round_mode(ir::RoundMode mode)\n{\n\tswitch (mode)\n\t{\n\tcase ir::RoundMode::ePositiveInf:\n\t\treturn DXIL::Op::Round_pi;\n\tcase ir::RoundMode::eNegativeInf:\n\t\treturn DXIL::Op::Round_ni;\n\tcase ir::RoundMode::eZero:\n\t\treturn DXIL::Op::Round_z;\n\tdefault:\n\t\treturn DXIL::Op::Round_ne;\n\t}\n}\n\nstruct ComponentMapping\n{\n\tDXIL::ComponentType type = DXIL::ComponentType::Invalid;\n\tuint32_t num_rows = 1;\n\tuint32_t num_cols = 1;\n};\n\nstatic ComponentMapping convert_component_mapping(const ir::Type &type, bool need_axis)\n{\n\tComponentMapping mapping = {};\n\n\tswitch (type.getBaseType(0).getBaseType())\n\t{\n\tcase ir::ScalarType::eF16:\n\t\tmapping.type = DXIL::ComponentType::F16;\n\t\tbreak;\n\n\tcase ir::ScalarType::eI16:\n\t\tmapping.type = DXIL::ComponentType::I16;\n\t\tbreak;\n\n\tcase ir::ScalarType::eU16:\n\t\tmapping.type = DXIL::ComponentType::U16;\n\t\tbreak;\n\n\tcase ir::ScalarType::eF32:\n\t\tmapping.type = DXIL::ComponentType::F32;\n\t\tbreak;\n\n\tcase ir::ScalarType::eI32:\n\t\tmapping.type = DXIL::ComponentType::I32;\n\t\tbreak;\n\n\tcase ir::ScalarType::eU32:\n\t\tmapping.type = DXIL::ComponentType::U32;\n\t\tbreak;\n\n\tcase ir::ScalarType::eF64:\n\t\tmapping.type = DXIL::ComponentType::F64;\n\t\tbreak;\n\n\tcase ir::ScalarType::eI64:\n\t\tmapping.type = DXIL::ComponentType::I64;\n\t\tbreak;\n\n\tcase ir::ScalarType::eU64:\n\t\tmapping.type = DXIL::ComponentType::U64;\n\t\tbreak;\n\n\tcase ir::ScalarType::eBool:\n\t\tmapping.type = DXIL::ComponentType::I1;\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unrecognized component type.\\n\");\n\t\tbreak;\n\t}\n\n\tif (need_axis)\n\t{\n\t\t// Strip the outermost dimension.\n\t\tif (type.getArrayDimensions() >= 2)\n\t\t\tmapping.num_rows = type.getArraySize(type.getArrayDimensions() - 2);\n\t}\n\telse if (type.isArrayType())\n\t{\n\t\tmapping.num_rows = type.getArraySize(0);\n\t\tif (type.getArrayDimensions() != 1)\n\t\t\tLOGE(\"Unexpected number of array dimensions.\\n\");\n\t}\n\n\tmapping.num_cols = type.getBaseType(0).getVectorSize();\n\n\treturn mapping;\n}\n\nstatic DXIL::TessellatorDomain convert_hull_domain(ir::PrimitiveType type)\n{\n\tswitch (type)\n\t{\n\tcase ir::PrimitiveType::eTriangles:\n\t\treturn DXIL::TessellatorDomain::Tri;\n\tcase ir::PrimitiveType::eQuads:\n\t\treturn DXIL::TessellatorDomain::Quad;\n\tcase ir::PrimitiveType::eLines:\n\t\treturn DXIL::TessellatorDomain::IsoLine;\n\tdefault:\n\t\treturn DXIL::TessellatorDomain::Undefined;\n\t}\n}\n\nstatic DXIL::TessellatorPartitioning convert_hull_partitioning(ir::TessPartitioning part)\n{\n\tswitch (part)\n\t{\n\tcase ir::TessPartitioning::eInteger:\n\t\treturn DXIL::TessellatorPartitioning::Integer;\n\tcase ir::TessPartitioning::eFractEven:\n\t\treturn DXIL::TessellatorPartitioning::FractionalEven;\n\tcase ir::TessPartitioning::eFractOdd:\n\t\treturn DXIL::TessellatorPartitioning::FractionalOdd;\n\tdefault:\n\t\treturn DXIL::TessellatorPartitioning::Undefined;\n\t}\n}\n\nstatic DXIL::TessellatorOutputPrimitive convert_hull_output_primitive(ir::PrimitiveType type, ir::TessWindingOrder winding)\n{\n\tswitch (type)\n\t{\n\tcase ir::PrimitiveType::eTriangles:\n\t\treturn winding == ir::TessWindingOrder::eCw ?\n\t\t       DXIL::TessellatorOutputPrimitive::TriangleCW :\n\t\t       DXIL::TessellatorOutputPrimitive::TriangleCCW;\n\tcase ir::PrimitiveType::eLines:\n\t\treturn DXIL::TessellatorOutputPrimitive::Line;\n\tcase ir::PrimitiveType::ePoints:\n\t\treturn DXIL::TessellatorOutputPrimitive::Point;\n\tdefault:\n\t\treturn DXIL::TessellatorOutputPrimitive::Undefined;\n\t}\n}\n\nstruct DXILIntrinsicTable\n{\n\tstruct FunctionOverload\n\t{\n\t\tFunction *func;\n\t\t// Either overloaded on return type, or the primary argument for e.g. stores.\n\t\tType *overload_type;\n\t};\n\n\tstruct FunctionEntry\n\t{\n\t\t// At most should be overload for i32/u32/f32 x 16/32/64\n\t\tstd::array<FunctionOverload, 9> overloads;\n\t\tunsigned num_overloads;\n\t};\n\n\tFunctionEntry intrinsic_functions[int(DXIL::Op::Count)] = {};\n\n\tFunction *get(Module &module, DXIL::Op op,\n\t              Type *return_type,\n\t              const Vector<Type *> &argument_types,\n\t              Type *overload_type, uint64_t &tween);\n};\n\nFunction *DXILIntrinsicTable::get(\n\tModule &module, DXIL::Op op,\n\tType *return_type, const Vector<Type *> &argument_types,\n\tType *overload_type, uint64_t &tween)\n{\n\tauto &entry = intrinsic_functions[int(op)];\n\n\tfor (unsigned i = 0; i < entry.num_overloads; i++)\n\t\tif (entry.overloads[i].overload_type == overload_type)\n\t\t\treturn entry.overloads[i].func;\n\n\tauto &context = module.getContext();\n\n\tassert(entry.num_overloads < entry.overloads.size());\n\tauto *func_type = context.construct<FunctionType>(context, return_type, argument_types);\n\tauto *func = context.construct<Function>(func_type, ++tween, module);\n\t// TODO: Can have a look-up for expected intrinsics name.\n\tmodule.add_value_name(tween, \"dx.op.intrinsic\");\n\tentry.overloads[entry.num_overloads++] = { func, overload_type };\n\treturn func;\n}\n\nclass ParseContext\n{\npublic:\n\tParseContext(LLVMContext &context_, ir::Builder &builder_, Module &module_)\n\t    : context(context_), builder(builder_), module(module_) {}\n\n\tbool emit_metadata();\n\tbool emit_entry_point();\n\tbool emit_function_bodies();\n\nprivate:\n\tLLVMContext &context;\n\tir::Builder &builder;\n\tModule &module;\n\tuint64_t metadata_tween_id = 0;\n\tuint64_t tween_id = 0;\n\n\tir::ShaderStage shader_stage = {};\n\n\tConstantInt *get_constant_uint(uint32_t value);\n\n\t// Metadata wrangling\n\tConstantAsMetadata *create_constant_uint_meta(uint32_t value);\n\tConstantAsMetadata *create_constant_uint64_meta(uint32_t value);\n\tMDString *create_string_meta(const String &str);\n\tConstantAsMetadata *create_constant_meta(Constant *c);\n\n\ttemplate <typename... Ops>\n\tMDNode *create_md_node(Ops&&... ops)\n\t{\n\t\tVector<MDOperand *> vops { std::forward<Ops>(ops)... };\n\t\treturn create_md_node(std::move(vops));\n\t}\n\n\tvoid create_named_md_node(const String &name, MDNode *node);\n\tMDNode *create_md_node(Vector<MDOperand *> ops);\n\n\tMDOperand *create_entry_point_meta(llvm::Function *patch_control_func);\n\tMDNode *create_stage_io_meta();\n\tMDOperand *create_null_meta();\n\n\tvoid set_function_attributes(Function *func);\n\n\tstruct MetadataMapping\n\t{\n\t\tVector<MDOperand *> nodes;\n\t};\n\tMetadataMapping srvs, uavs, cbvs, samplers, inputs, outputs, patches;\n\n\tuint32_t build_texture_srv(uint32_t space, uint32_t index, uint32_t size,\n\t                           DXIL::ResourceKind kind,\n\t                           DXIL::ComponentType type);\n\n\tuint32_t build_texture_uav(uint32_t space, uint32_t index, uint32_t size,\n\t                           DXIL::ResourceKind kind,\n\t                           DXIL::ComponentType type, bool coherent, bool rov);\n\n\tuint32_t build_buffer_uav(uint32_t space, uint32_t index, uint32_t size,\n\t                          DXIL::ResourceKind kind, uint32_t stride,\n\t                          bool coherent, bool counter, bool rov);\n\n\tuint32_t build_buffer_srv(uint32_t space, uint32_t index, uint32_t size,\n\t                          DXIL::ResourceKind kind, uint32_t stride);\n\n\tuint32_t build_cbv(uint32_t space, uint32_t index, uint32_t size, uint32_t cbv_size);\n\n\tuint32_t build_sampler(uint32_t space, uint32_t index, uint32_t size);\n\n\tuint32_t build_stage_io(MetadataMapping &mapping, ir::SsaDef ssa, const String &name,\n\t                        DXIL::ComponentType type,\n\t                        DXIL::Semantic semantic,\n\t                        uint32_t semantic_index,\n\t                        DXIL::InterpolationMode interpolation,\n\t                        uint32_t rows, uint32_t cols,\n\t                        uint32_t start_row, uint32_t start_col,\n\t                        uint32_t stream,\n\t                        bool need_axis);\n\n\t// DXIL intrinsic build.\n\tDXILIntrinsicTable dxil_intrinsics;\n\n\ttemplate <typename... Values>\n\tInstruction *build_dxil_call(DXIL::Op op, Type *return_type, Type *overload_type, Values&&... values);\n\tInstruction *build_dxil_call(DXIL::Op op, Type *return_type, Type *overload_type, Vector<Value *> values);\n\n\t// Resource access hell.\n\tInstruction *build_load_input(\n\t\tuint32_t index, Type *type,\n\t\tValue *row, uint32_t col, Value *axis, bool patch);\n\tInstruction *build_load_output(\n\t\tuint32_t index, Type *type,\n\t\tValue *row, uint32_t col, Value *axis, bool patch);\n\tInstruction *build_store_output(uint32_t index, Value *row, uint32_t col, Value *value, bool patch);\n\tInstruction *build_load_builtin(DXIL::Op opcode, ir::SsaDef addr);\n\tInstruction *build_descriptor_load(ir::SsaDef resource, ir::SsaDef index, bool nonuniform);\n\n\tbool build_input_load(const ir::Op &op);\n\tbool build_output_load(const ir::Op &op);\n\tbool build_output_store(const ir::Op &op);\n\tbool build_gep_load(const ir::Op &op);\n\tbool build_gep_store(const ir::Op &op);\n\tbool build_composite_construct(const ir::Op &op);\n\tbool build_composite_extract(const ir::Op &op);\n\tbool build_composite_insert(const ir::Op &op);\n\tbool build_descriptor_load(const ir::Op &op);\n\tbool build_buffer_load(const ir::Op &op);\n\tbool build_buffer_load_cbv(const ir::Op &op);\n\tbool build_buffer_load(const ir::Op &op, DXIL::ResourceKind kind);\n\tbool build_buffer_load_return_composite(const ir::Op &op, Value *value);\n\tInstruction *build_extract_composite(const ir::Op &op, Value *value, unsigned num_elements);\n\tbool build_buffer_query_size(const ir::Op &op);\n\tbool build_buffer_store(const ir::Op &op);\n\tbool build_buffer_store(const ir::Op &op, DXIL::ResourceKind kind);\n\tbool build_buffer_atomic(const ir::Op &op);\n\tbool build_lds_atomic(const ir::Op &op);\n\tbool build_buffer_atomic_binop(const ir::Op &op, DXIL::ResourceKind kind);\n\tbool build_counter_atomic(const ir::Op &op);\n\tbool build_image_load(const ir::Op &op);\n\tbool build_image_store(const ir::Op &op);\n\tbool build_image_atomic(const ir::Op &op);\n\tbool build_image_query_size(const ir::Op &op);\n\tbool build_image_query_mips_samples(const ir::Op &op);\n\tbool build_image_sample(const ir::Op &op);\n\tbool build_image_gather(const ir::Op &op);\n\tbool build_image_compute_lod(const ir::Op &op);\n\tbool build_deriv(const ir::Op &op);\n\tbool build_check_sparse_access(const ir::Op &op);\n\tbool build_fround(const ir::Op &op);\n\tbool build_frcp(const ir::Op &op);\n\tbool build_binary_op(const ir::Op &op, BinaryOperator::BinaryOps binop);\n\tbool build_interpolate_at_centroid(const ir::Op &op);\n\tbool build_interpolate_at_sample(const ir::Op &op);\n\tbool build_interpolate_at_offset(const ir::Op &op);\n\tbool build_barrier(const ir::Op &op);\n\tbool build_demote(const ir::Op &op);\n\n\ttemplate <DXIL::Op dxop>\n\tbool build_dxil_unary(const ir::Op &op);\n\ttemplate <DXIL::Op dxop>\n\tbool build_dxil_constant_unary(const ir::Op &op);\n\ttemplate <DXIL::Op dxop>\n\tbool build_dxil_binary(const ir::Op &op);\n\ttemplate <DXIL::Op dxop>\n\tbool build_dxil_trinary(const ir::Op &op);\n\ttemplate <DXIL::Op dxop>\n\tbool build_dxil_quaternary(const ir::Op &op);\n\n\tValue *get_extracted_composite_component(Value *value, unsigned component);\n\tValue *get_constant_mul(Value *value, uint32_t scale);\n\n\t// BasicBlock emission.\n\tBasicBlock *current_bb = nullptr;\n\tvoid push_instruction(Instruction *instruction, ir::SsaDef ssa = {});\n\tbool push_instruction(const ir::Op &op);\n\n\t// ir::Builder helpers.\n\t// Need ways to translate between ir::SsaDef <-> LLVM values for the most part.\n\tUnorderedMap<ir::SsaDef, Function *> function_map;\n\tUnorderedMap<ir::SsaDef, BasicBlock *> bb_map;\n\tUnorderedMap<ir::SsaDef, Type *> param_types;\n\tVector<std::pair<ir::SsaDef, Type *>> params;\n\tUnorderedMap<ir::SsaDef, Value *> value_map;\n\n\t// Maps stage IO and resources since we need to resolve them back to type + metadata index\n\t// when loading descriptor.\n\tstruct StageIOHandler\n\t{\n\t\tuint32_t index = UINT32_MAX;\n\t\tDXIL::Op op = DXIL::Op::Count;\n\t\tbool need_axis = false;\n\t};\n\tUnorderedMap<ir::SsaDef, StageIOHandler> stage_io_map;\n\n\tstruct StageIOAccess\n\t{\n\t\tValue *axis;\n\t\tValue *row;\n\t\tuint32_t col;\n\t};\n\tStageIOAccess build_stage_io_access(const StageIOHandler &handler, ir::SsaDef io_decl, ir::SsaDef addr);\n\n\tstruct ResourceHandler\n\t{\n\t\tDXIL::ResourceType resource_type;\n\t\tDXIL::ResourceKind resource_kind;\n\t\tuint32_t index;\n\t\tuint32_t binding_offset; // DXIL is weird.\n\t};\n\tUnorderedMap<ir::SsaDef, ResourceHandler> resource_map;\n\n\tType *convert_type(const ir::Type &type);\n\tBasicBlock *get_basic_block(ir::SsaDef ssa);\n\n\tValue *get_value(const ir::Operand &op) const;\n\tValue *get_value(const ir::SsaDef &op) const;\n\n\tbool emit_constant(const ir::Op &op);\n\n\tir::OpFlags global_fp_flags = {};\n};\n\nstatic inline Type *get_value_type(Value *value)\n{\n\tassert(value);\n\treturn value->getType();\n}\n\nstatic Type *get_scalar_type(Type *type)\n{\n\tif (auto *vec = dyn_cast<VectorType>(type))\n\t\treturn vec->getElementType();\n\telse if (isa<StructType>(type))\n\t\treturn type->getStructElementType(0);\n\telse\n\t\treturn type;\n}\n\ntemplate <typename... Values>\nInstruction *ParseContext::build_dxil_call(DXIL::Op op, Type *return_type, Type *overload_type, Values&&... values)\n{\n\tauto *func = dxil_intrinsics.get(\n\t    module, op, return_type,\n\t    Vector<Type *> { Type::getInt32Ty(context), get_value_type(values)... }, overload_type, tween_id);\n\n\tauto *inst = context.construct<CallInst>(\n\t    func->getFunctionType(), func,\n\t    Vector<Value *> { get_constant_uint(uint32_t(op)), values... });\n\n\treturn inst;\n}\n\nInstruction *ParseContext::build_dxil_call(DXIL::Op op, Type *return_type, Type *overload_type, Vector<Value *> values)\n{\n\tVector<Type *> types;\n\ttypes.reserve(values.size() + 1);\n\ttypes.push_back(Type::getInt32Ty(context));\n\tfor (auto *v : values)\n\t\ttypes.push_back(v->getType());\n\n\tauto *func = dxil_intrinsics.get(module, op, return_type, types, overload_type, tween_id);\n\tvalues.insert(values.begin(), get_constant_uint(uint32_t(op)));\n\tauto *inst = context.construct<CallInst>(func->getFunctionType(), func, std::move(values));\n\treturn inst;\n}\n\nbool ParseContext::emit_constant(const ir::Op &op)\n{\n\tauto &type = op.getType();\n\tValue *value = nullptr;\n\n\tif (type.isBasicType())\n\t{\n\t\tauto *llvm_type = convert_type(type);\n\t\tif (type.isScalarType())\n\t\t{\n\t\t\tif (type.getBaseType(0).isIntType())\n\t\t\t\tvalue = ConstantInt::get(llvm_type, uint64_t(op.getOperand(0)));\n\t\t\telse if (type.getBaseType(0).isFloatType())\n\t\t\t\tvalue = ConstantFP::get(llvm_type, uint64_t(op.getOperand(0)));\n\t\t\telse if (type.getBaseType(0).isBoolType())\n\t\t\t\tvalue = ConstantInt::get(llvm_type, bool(op.getOperand(0)));\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tVector<Value *> constants;\n\t\t\tconstants.reserve(op.getOperandCount());\n\n\t\t\tauto *llvm_sub_type = get_scalar_type(llvm_type);\n\n\t\t\tif (type.getBaseType(0).isIntType())\n\t\t\t{\n\t\t\t\tfor (uint32_t i = 0; i < op.getOperandCount(); i++)\n\t\t\t\t\tconstants.push_back(ConstantInt::get(llvm_sub_type, uint64_t(op.getOperand(i))));\n\t\t\t}\n\t\t\telse if (type.getBaseType(0).isFloatType())\n\t\t\t{\n\t\t\t\tfor (uint32_t i = 0; i < op.getOperandCount(); i++)\n\t\t\t\t\tconstants.push_back(ConstantFP::get(llvm_sub_type, uint64_t(op.getOperand(i))));\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\n\t\t\tvalue = context.construct<ConstantDataVector>(convert_type(type), std::move(constants));\n\t\t}\n\t}\n\telse if (type.isArrayType())\n\t{\n\t\t// This is quite flexible, but only support what we can reasonably expect to see. Extend and generalize if needed.\n\t\tauto elem_type = type.getSubType(0);\n\t\tif (!elem_type.isScalarType() && !elem_type.isVectorType())\n\t\t\treturn false;\n\n\t\tuint32_t vecsize = elem_type.getBaseType(0).getVectorSize();\n\t\tassert(vecsize && op.getOperandCount() % vecsize == 0);\n\t\tuint32_t array_elements = op.getOperandCount() / vecsize;\n\n\t\tVector<Value *> constants;\n\t\tVector<Value *> values;\n\n\t\tvalues.reserve(array_elements);\n\t\tconstants.reserve(vecsize);\n\n\t\tauto *llvm_sub_type = convert_type(elem_type);\n\n\t\tfor (uint32_t elem = 0; elem < array_elements; elem++)\n\t\t{\n\t\t\tconstants.clear();\n\n\t\t\tfor (uint32_t c = 0; c < vecsize; c++)\n\t\t\t{\n\t\t\t\tif (elem_type.getBaseType(0).isIntType())\n\t\t\t\t{\n\t\t\t\t\tconstants.push_back(ConstantInt::get(get_scalar_type(llvm_sub_type),\n\t\t\t\t\t                                     uint64_t(op.getOperand(elem * vecsize + c))));\n\t\t\t\t}\n\t\t\t\telse if (elem_type.getBaseType(0).isFloatType())\n\t\t\t\t{\n\t\t\t\t\tconstants.push_back(ConstantFP::get(get_scalar_type(llvm_sub_type),\n\t\t\t\t\t                                    uint64_t(op.getOperand(elem * vecsize + c))));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (elem_type.isVectorType())\n\t\t\t\tvalues.push_back(context.construct<ConstantDataVector>(convert_type(elem_type), constants));\n\t\t\telse\n\t\t\t\tvalues.push_back(constants[0]);\n\t\t}\n\n\t\tauto *constant_value = context.construct<ConstantDataArray>(convert_type(op.getType()), values);\n\t\tauto *lut = context.construct<GlobalVariable>(\n\t\t\tPointerType::get(convert_type(op.getType()), uint32_t(DXIL::AddressSpace::Thread)),\n\t\t\tGlobalVariable::LinkageTypes::InternalLinkage, false);\n\t\tlut->set_initializer(constant_value);\n\t\tmodule.add_global_variable(lut);\n\t\tvalue = lut;\n\t}\n\n\tif (!value)\n\t\treturn false;\n\n\tvalue_map[op.getDef()] = value;\n\treturn true;\n}\n\nType *ParseContext::convert_type(const ir::Type &type)\n{\n\tif (type.isArrayType())\n\t{\n\t\tauto *llvm_type = convert_type(type.getSubType(0));\n\t\tfor (unsigned dim = 0; dim < type.getArrayDimensions(); dim++)\n\t\t\tllvm_type = ArrayType::get(llvm_type, type.getArraySize(dim));\n\t\treturn llvm_type;\n\t}\n\telse if (type.isStructType())\n\t{\n\t\tVector<Type *> members;\n\t\tfor (unsigned index = 0; index < type.getStructMemberCount(); index++)\n\t\t\tmembers.push_back(convert_type(type.getSubType(index)));\n\t\treturn StructType::get(context, std::move(members));\n\t}\n\telse if (type.isVoidType())\n\t{\n\t\treturn Type::getVoidTy(context);\n\t}\n\telse if (type.isBasicType())\n\t{\n\t\tType *llvm_type;\n\t\tir::BasicType base = type.getBaseType(0);\n\t\tswitch (base.getBaseType())\n\t\t{\n\t\tcase ir::ScalarType::eF16:\n\t\t\tllvm_type = Type::getHalfTy(context);\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eF32:\n\t\t\tllvm_type = Type::getFloatTy(context);\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eF64:\n\t\t\tllvm_type = Type::getDoubleTy(context);\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eI16:\n\t\tcase ir::ScalarType::eU16:\n\t\t\tllvm_type = Type::getInt16Ty(context);\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eI32:\n\t\tcase ir::ScalarType::eU32:\n\t\t\tllvm_type = Type::getInt32Ty(context);\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eI64:\n\t\tcase ir::ScalarType::eU64:\n\t\t\tllvm_type = Type::getInt64Ty(context);\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eBool:\n\t\t\tllvm_type = Type::getInt1Ty(context);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unrecognized basic scalar type %u\\n\", unsigned(base.getBaseType()));\n\t\t\treturn nullptr;\n\t\t}\n\n\t\tif (base.isVector())\n\t\t\tllvm_type = VectorType::get(base.getVectorSize(), llvm_type);\n\n\t\treturn llvm_type;\n\t}\n\telse\n\t{\n\t\tLOGE(\"Unrecognized type.\\n\");\n\t\treturn nullptr;\n\t}\n}\n\nvoid ParseContext::push_instruction(Instruction *instruction, ir::SsaDef ssa)\n{\n\tassert(current_bb);\n\tinstruction->set_tween_id(++tween_id);\n\tcurrent_bb->add_instruction(instruction);\n\tif (ssa)\n\t\tvalue_map[ssa] = instruction;\n}\n\nParseContext::StageIOAccess\nParseContext::build_stage_io_access(const StageIOHandler &handler, ir::SsaDef io_decl, ir::SsaDef addr)\n{\n\tValue *axis = nullptr;\n\tValue *row = get_constant_uint(0);\n\tuint32_t col = 0;\n\n\tif (addr)\n\t{\n\t\tauto &decl = builder.getOp(io_decl);\n\t\tauto &addr_op = builder.getOp(addr);\n\n\t\tuint32_t chain_length = addr_op.getType().getBaseType(0).getVectorSize();\n\t\tuint32_t dim = 0;\n\n\t\tauto *addr_value = get_value(addr);\n\n\t\tif (handler.need_axis)\n\t\t\taxis = get_extracted_composite_component(addr_value, dim++);\n\t\tif (dim + 1 == decl.getType().getArrayDimensions())\n\t\t\trow = get_extracted_composite_component(addr_value, dim++);\n\n\t\t// This is optional if we're loading from a scalar, or we're loading the full vector.\n\t\tif (dim < chain_length)\n\t\t{\n\t\t\tassert(dim == chain_length - 1);\n\n\t\t\t// The last element is the column. It must be constant.\n\t\t\tif (const auto *c = dyn_cast<ConstantInt>(get_extracted_composite_component(addr_value, dim)))\n\t\t\t{\n\t\t\t\tcol = c->getUniqueInteger().getZExtValue();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tLOGE(\"Column index is not compile-time constant.\\n\");\n\t\t\t\treturn {};\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { axis, row, col };\n}\n\nstatic bool io_decl_is_patch(ir::ShaderStage stage, const ir::Op &op)\n{\n\tif (stage != ir::ShaderStage::eHull && stage != ir::ShaderStage::eDomain)\n\t\treturn false;\n\n\tswitch (op.getOpCode())\n\t{\n\tcase ir::OpCode::eDclInput:\n\t\treturn stage == ir::ShaderStage::eDomain && !op.getType().isArrayType();\n\tcase ir::OpCode::eDclOutput:\n\t\treturn stage == ir::ShaderStage::eHull && !op.getType().isArrayType();\n\tcase ir::OpCode::eDclOutputBuiltIn:\n\t\tif (stage == ir::ShaderStage::eDomain)\n\t\t\treturn false;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\t// For builtin-IO, there's tess factors and clip/cull distance that is a bit \"special\".\n\tauto builtin = ir::BuiltIn(op.getOperand(1));\n\n\tif (builtin == ir::BuiltIn::eTessCoord)\n\t\treturn false;\n\n\treturn builtin == ir::BuiltIn::eTessFactorOuter || builtin == ir::BuiltIn::eTessFactorInner ||\n\t       !op.getType().isArrayType();\n}\n\nbool ParseContext::build_input_load(const ir::Op &op)\n{\n\tauto &ref = stage_io_map[ir::SsaDef(op.getOperand(0))];\n\n\t// Redirect to magic opcode as needed.\n\tif (ref.op != DXIL::Op::Count)\n\t{\n\t\tauto *inst = build_load_builtin(ref.op, ir::SsaDef(op.getOperand(1)));\n\t\tpush_instruction(inst, op.getDef());\n\t\treturn true;\n\t}\n\n\tauto *type = convert_type(op.getType());\n\tauto *scalar_type = type;\n\n\tunsigned components = 1;\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t{\n\t\tcomponents = vec->getVectorSize();\n\t\tscalar_type = vec->getElementType();\n\t}\n\n\tInstruction *insts[4] = {};\n\n\tauto access = build_stage_io_access(ref, ir::SsaDef(op.getOperand(0)), ir::SsaDef(op.getOperand(1)));\n\tbool patch = io_decl_is_patch(shader_stage, builder.getOp(ir::SsaDef(op.getOperand(0))));\n\n\tfor (unsigned c = 0; c < components; c++)\n\t{\n\t\tinsts[c] = build_load_input(ref.index, scalar_type, access.row, access.col + c, access.axis, patch);\n\t\tpush_instruction(insts[c], op.getDef());\n\t}\n\n\tif (components != 1)\n\t{\n\t\tauto *inst = context.construct<CompositeConstructInst>(\n\t\t    type, Vector<Value *>{ insts, insts + components });\n\t\tpush_instruction(inst, op.getDef());\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_output_load(const ir::Op &op)\n{\n\tauto &ref = stage_io_map[ir::SsaDef(op.getOperand(0))];\n\n\tauto *type = convert_type(op.getType());\n\tauto *scalar_type = type;\n\n\tunsigned components = 1;\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t{\n\t\tcomponents = vec->getVectorSize();\n\t\tscalar_type = vec->getElementType();\n\t}\n\n\tInstruction *insts[4] = {};\n\n\tauto access = build_stage_io_access(ref, ir::SsaDef(op.getOperand(0)), ir::SsaDef(op.getOperand(1)));\n\tbool patch = io_decl_is_patch(shader_stage, builder.getOp(ir::SsaDef(op.getOperand(0))));\n\n\tfor (unsigned c = 0; c < components; c++)\n\t{\n\t\tinsts[c] = build_load_output(ref.index, scalar_type, access.row, access.col + c, access.axis, patch);\n\t\tpush_instruction(insts[c], op.getDef());\n\t}\n\n\tif (components != 1)\n\t{\n\t\tauto *inst = context.construct<CompositeConstructInst>(\n\t\t    type, Vector<Value *>{ insts, insts + components });\n\t\tpush_instruction(inst, op.getDef());\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_interpolate_at_centroid(const ir::Op &op)\n{\n\tauto &ref = stage_io_map[ir::SsaDef(op.getOperand(0))];\n\tauto *type = convert_type(op.getType());\n\tauto *scalar_type = type;\n\n\tunsigned components = 1;\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t{\n\t\tcomponents = vec->getVectorSize();\n\t\tscalar_type = vec->getElementType();\n\t}\n\n\tInstruction *insts[4] = {};\n\n\tauto access = build_stage_io_access(ref, ir::SsaDef(op.getOperand(0)), ir::SsaDef(op.getOperand(1)));\n\n\tfor (unsigned c = 0; c < components; c++)\n\t{\n\t\tinsts[c] = build_dxil_call(DXIL::Op::EvalCentroid, scalar_type, scalar_type,\n\t\t                           get_constant_uint(ref.index),\n\t\t                           access.row, get_constant_uint(access.col + c));\n\t\tpush_instruction(insts[c], op.getDef());\n\t}\n\n\tif (components != 1)\n\t{\n\t\tauto *inst = context.construct<CompositeConstructInst>(\n\t\t    type, Vector<Value *>{ insts, insts + components });\n\t\tpush_instruction(inst, op.getDef());\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_interpolate_at_sample(const ir::Op &op)\n{\n\tauto &ref = stage_io_map[ir::SsaDef(op.getOperand(0))];\n\tauto *type = convert_type(op.getType());\n\tauto *scalar_type = type;\n\n\tunsigned components = 1;\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t{\n\t\tcomponents = vec->getVectorSize();\n\t\tscalar_type = vec->getElementType();\n\t}\n\n\tInstruction *insts[4] = {};\n\n\tauto access = build_stage_io_access(ref, ir::SsaDef(op.getOperand(0)), ir::SsaDef(op.getOperand(1)));\n\n\tfor (unsigned c = 0; c < components; c++)\n\t{\n\t\tinsts[c] = build_dxil_call(DXIL::Op::EvalSampleIndex, scalar_type, scalar_type,\n\t\t                           get_constant_uint(ref.index),\n\t\t                           access.row, get_constant_uint(access.col + c), get_value(op.getOperand(2)));\n\t\tpush_instruction(insts[c], op.getDef());\n\t}\n\n\tif (components != 1)\n\t{\n\t\tauto *inst = context.construct<CompositeConstructInst>(\n\t\t    type, Vector<Value *>{ insts, insts + components });\n\t\tpush_instruction(inst, op.getDef());\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_interpolate_at_offset(const ir::Op &op)\n{\n\tauto &ref = stage_io_map[ir::SsaDef(op.getOperand(0))];\n\tauto *type = convert_type(op.getType());\n\tauto *scalar_type = type;\n\n\tunsigned components = 1;\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t{\n\t\tcomponents = vec->getVectorSize();\n\t\tscalar_type = vec->getElementType();\n\t}\n\n\tInstruction *insts[4] = {};\n\n\tauto access = build_stage_io_access(ref, ir::SsaDef(op.getOperand(0)), ir::SsaDef(op.getOperand(1)));\n\n\tfor (unsigned c = 0; c < components; c++)\n\t{\n\t\tinsts[c] = build_dxil_call(DXIL::Op::ExtendedEvalSnapped, scalar_type, scalar_type,\n\t\t                           get_constant_uint(ref.index),\n\t\t                           access.row, get_constant_uint(access.col + c), get_value(op.getOperand(2)));\n\t\tpush_instruction(insts[c], op.getDef());\n\t}\n\n\tif (components != 1)\n\t{\n\t\tauto *inst = context.construct<CompositeConstructInst>(\n\t\t    type, Vector<Value *>{ insts, insts + components });\n\t\tpush_instruction(inst, op.getDef());\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_output_store(const ir::Op &op)\n{\n\tauto *store_value = get_value(op.getOperand(2));\n\tauto &ref = stage_io_map[ir::SsaDef(op.getOperand(0))];\n\tunsigned components = 1;\n\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(store_value->getType()))\n\t\tcomponents = vec->getVectorSize();\n\n\tauto access = build_stage_io_access(ref, ir::SsaDef(op.getOperand(0)), ir::SsaDef(op.getOperand(1)));\n\tbool patch = io_decl_is_patch(shader_stage, builder.getOp(ir::SsaDef(op.getOperand(0))));\n\n\tif (components == 1)\n\t{\n\t\tpush_instruction(build_store_output(ref.index, access.row, access.col, store_value, patch));\n\t}\n\telse\n\t{\n\t\tfor (unsigned c = 0; c < components; c++)\n\t\t{\n\t\t\tauto *value = get_extracted_composite_component(store_value, c);\n\t\t\tpush_instruction(build_store_output(ref.index, access.row, access.col + c, value, patch));\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_gep_load(const ir::Op &op)\n{\n\tauto *type = convert_type(op.getType());\n\tVector<Value *> args;\n\targs.push_back(get_value(op.getOperand(0)));\n\targs.push_back(get_constant_uint(0));\n\n\tif (op.getOperand(1))\n\t{\n\t\tauto &addr = builder.getOp(ir::SsaDef(op.getOperand(1)));\n\t\tauto *addr_value = get_value(op.getOperand(1));\n\t\tfor (uint32_t i = 0; i < addr.getType().getBaseType(0).getVectorSize(); i++)\n\t\t\targs.push_back(get_extracted_composite_component(addr_value, i));\n\t}\n\n\tauto addr_space = op.getOpCode() == ir::OpCode::eLdsLoad ?\n\t                  DXIL::AddressSpace::GroupShared : DXIL::AddressSpace::Thread;\n\n\tauto *gep = context.construct<GetElementPtrInst>(\n\t\tPointerType::get(type, uint32_t(addr_space)), std::move(args), true);\n\tauto *load = context.construct<LoadInst>(type, gep);\n\tpush_instruction(gep);\n\tpush_instruction(load, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_gep_store(const ir::Op &op)\n{\n\tauto *type = convert_type(builder.getOp(ir::SsaDef(op.getOperand(2))).getType());\n\tVector<Value *> args;\n\targs.push_back(get_value(op.getOperand(0)));\n\targs.push_back(get_constant_uint(0));\n\n\tif (op.getOperand(1))\n\t{\n\t\tauto &addr = builder.getOp(ir::SsaDef(op.getOperand(1)));\n\t\tauto *addr_value = get_value(op.getOperand(1));\n\t\tfor (uint32_t i = 0; i < addr.getType().getBaseType(0).getVectorSize(); i++)\n\t\t\targs.push_back(get_extracted_composite_component(addr_value, i));\n\t}\n\n\tauto addr_space = op.getOpCode() == ir::OpCode::eLdsStore ?\n\t                  DXIL::AddressSpace::GroupShared : DXIL::AddressSpace::Thread;\n\n\tauto *gep = context.construct<GetElementPtrInst>(\n\t    PointerType::get(type, uint32_t(addr_space)), std::move(args), true);\n\tauto *store = context.construct<StoreInst>(gep, get_value(op.getOperand(2)));\n\tpush_instruction(gep);\n\tpush_instruction(store, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_composite_construct(const ir::Op &op)\n{\n\tauto *type = convert_type(op.getType());\n\n\tVector<Value *> values;\n\tvalues.reserve(op.getOperandCount());\n\n\tfor (unsigned i = 0; i < op.getOperandCount(); i++)\n\t\tvalues.push_back(get_value(op.getOperand(i)));\n\n\tauto *inst = context.construct<CompositeConstructInst>(type, std::move(values));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_composite_extract(const ir::Op &op)\n{\n\tauto &address = builder.getOpForOperand(op, 1);\n\tif (!address.isConstant())\n\t{\n\t\tLOGE(\"CompositeExtract must take a constant index.\\n\");\n\t\treturn false;\n\t}\n\n\tauto *value = get_value(op.getOperand(0));\n\n\tfor (unsigned i = 0; i < address.getOperandCount(); i++)\n\t\tvalue = get_extracted_composite_component(value, uint32_t(address.getOperand(i)));\n\n\tvalue_map[op.getDef()] = value;\n\treturn true;\n}\n\nbool ParseContext::build_composite_insert(const ir::Op &op)\n{\n\tauto *inst = context.construct<InsertElementInst>(\n\t    get_value(op.getOperand(0)), get_value(op.getOperand(2)), get_value(op.getOperand(1)));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_descriptor_load(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\tauto &dcl_op = builder.getOp(descriptor);\n\tif (dcl_op.getOpCode() == ir::OpCode::eDclUavCounter)\n\t\tdescriptor = ir::SsaDef(dcl_op.getOperand(1));\n\n\tauto *inst = build_descriptor_load(descriptor, ir::SsaDef(op.getOperand(1)),\n\t                                   bool(op.getFlags() & ir::OpFlag::eNonUniform));\n\n\tif (!inst)\n\t\treturn false;\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_deriv(const ir::Op &op)\n{\n\tauto *inst = build_dxil_call(DXIL::Op::ExtendedDeriv,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_value(op.getOperand(0)),\n\t                             get_constant_uint(op.getOpCode() == ir::OpCode::eDerivY),\n\t                             get_constant_uint(uint32_t(op.getOperand(1))));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_check_sparse_access(const ir::Op &op)\n{\n\tauto *inst = build_dxil_call(DXIL::Op::CheckAccessFullyMapped,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_value(op.getOperand(0)));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_fround(const ir::Op &op)\n{\n\tauto dxop = convert_round_mode(ir::RoundMode(op.getOperand(op.getFirstLiteralOperandIndex())));\n\tauto *inst = build_dxil_call(dxop,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_value(op.getOperand(0)));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_frcp(const ir::Op &op)\n{\n\tConstant *const1;\n\n\tswitch (op.getType().getBaseType(0).getBaseType())\n\t{\n\tcase ir::ScalarType::eF16:\n\t\tconst1 = ConstantFP::get(Type::getHalfTy(context), 0x3c00);\n\t\tbreak;\n\n\tcase ir::ScalarType::eF32:\n\t{\n\t\tconst float one = 1.0f;\n\t\tuint32_t v;\n\t\tmemcpy(&v, &one, sizeof(one));\n\t\tconst1 = ConstantFP::get(Type::getFloatTy(context), v);\n\t\tbreak;\n\t}\n\n\tcase ir::ScalarType::eF64:\n\t{\n\t\tconst double one = 1.0;\n\t\tuint64_t v;\n\t\tmemcpy(&v, &one, sizeof(one));\n\t\tconst1 = ConstantFP::get(Type::getDoubleTy(context), v);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tif (op.getType().isVectorType())\n\t{\n\t\tunsigned num_components = op.getType().getBaseType(0).getVectorSize();\n\t\tVector<Value *> values;\n\t\tvalues.reserve(num_components);\n\t\tfor (unsigned i = 0; i < num_components; i++)\n\t\t\tvalues.push_back(const1);\n\t\tconst1 = context.construct<ConstantDataVector>(VectorType::get(num_components, const1->getType()), std::move(values));\n\t}\n\n\tauto *inst = context.construct<BinaryOperator>(const1, get_value(op.getOperand(0)),\n\t                                               BinaryOperator::BinaryOps::FDiv);\n\tinst->setFast(!((op.getFlags() | global_fp_flags) & ir::OpFlag::ePrecise));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_binary_op(const ir::Op &op, BinaryOperator::BinaryOps binop)\n{\n\tauto *inst = context.construct<BinaryOperator>(\n\t    get_value(op.getOperand(0)), get_value(op.getOperand(1)), binop);\n\tpush_instruction(inst, op.getDef());\n\tif (op.getType().getBaseType(0).isFloatType())\n\t\tinst->setFast(!((op.getFlags() | global_fp_flags) & ir::OpFlag::ePrecise));\n\treturn true;\n}\n\ntemplate <DXIL::Op dxop>\nbool ParseContext::build_dxil_unary(const ir::Op &op)\n{\n\tassert(op.getOperandCount() == 1);\n\tauto *inst = build_dxil_call(dxop,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_value(op.getOperand(0)));\n\tif ((op.getFlags() | global_fp_flags) & ir::OpFlag::ePrecise)\n\t\tinst->setMetadata(\"dx.precise\", create_md_node(create_null_meta()));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\ntemplate <DXIL::Op dxop>\nbool ParseContext::build_dxil_constant_unary(const ir::Op &op)\n{\n\tassert(op.getOperandCount() == 1);\n\tauto *inst = build_dxil_call(dxop,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_constant_uint(uint32_t(op.getOperand(0))));\n\tif ((op.getFlags() | global_fp_flags) & ir::OpFlag::ePrecise)\n\t\tinst->setMetadata(\"dx.precise\", create_md_node(create_null_meta()));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\ntemplate <DXIL::Op dxop>\nbool ParseContext::build_dxil_binary(const ir::Op &op)\n{\n\tassert(op.getOperandCount() == 2);\n\tauto *inst = build_dxil_call(dxop,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_value(op.getOperand(0)), get_value(op.getOperand(1)));\n\tif ((op.getFlags() | global_fp_flags) & ir::OpFlag::ePrecise)\n\t\tinst->setMetadata(\"dx.precise\", create_md_node(create_null_meta()));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\ntemplate <DXIL::Op dxop>\nbool ParseContext::build_dxil_trinary(const ir::Op &op)\n{\n\tassert(op.getOperandCount() == 3);\n\tauto *inst = build_dxil_call(dxop,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_value(op.getOperand(0)),\n\t                             get_value(op.getOperand(1)),\n\t                             get_value(op.getOperand(2)));\n\tif ((op.getFlags() | global_fp_flags) & ir::OpFlag::ePrecise)\n\t\tinst->setMetadata(\"dx.precise\", create_md_node(create_null_meta()));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\ntemplate <DXIL::Op dxop>\nbool ParseContext::build_dxil_quaternary(const ir::Op &op)\n{\n\tassert(op.getOperandCount() == 4);\n\tauto *inst = build_dxil_call(dxop,\n\t                             convert_type(op.getType()), convert_type(op.getType()),\n\t                             get_value(op.getOperand(0)),\n\t                             get_value(op.getOperand(1)),\n\t                             get_value(op.getOperand(2)),\n\t                             get_value(op.getOperand(3)));\n\tif ((op.getFlags() | global_fp_flags) & ir::OpFlag::ePrecise)\n\t\tinst->setMetadata(\"dx.precise\", create_md_node(create_null_meta()));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_barrier(const ir::Op &op)\n{\n\tauto exec_scope = ir::Scope(op.getOperand(0));\n\tauto mem_scope = ir::Scope(op.getOperand(1));\n\tauto memory_type = ir::MemoryTypeFlags(op.getOperand(2));\n\tauto *void_type = Type::getVoidTy(context);\n\n\tuint32_t memory_flags = 0;\n\tuint32_t semantic_flags = 0;\n\n\tsemantic_flags |= DXIL::GroupScopeBit;\n\tif (exec_scope != ir::Scope::eThread)\n\t\tsemantic_flags |= DXIL::GroupSyncBit;\n\tif (mem_scope == ir::Scope::eGlobal)\n\t\tsemantic_flags |= DXIL::DeviceScopeBit;\n\n\tif (memory_type & ir::MemoryType::eLds)\n\t\tmemory_flags |= DXIL::MemoryTypeGroupSharedBit;\n\tif (memory_type & ir::MemoryType::eUav)\n\t\tmemory_flags |= DXIL::MemoryTypeUavBit;\n\n\tauto *inst = build_dxil_call(DXIL::Op::BarrierByMemoryType, void_type, void_type,\n\t                             get_constant_uint(memory_flags),\n\t                             get_constant_uint(semantic_flags));\n\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_demote(const ir::Op &op)\n{\n\tauto *void_type = Type::getVoidTy(context);\n\tauto *inst = build_dxil_call(DXIL::Op::Discard, void_type, void_type,\n\t                             get_constant_uint(1));\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::push_instruction(const ir::Op &op)\n{\n\tswitch (op.getOpCode())\n\t{\n#define OPMAP(irop, llvmop) case ir::OpCode::e##irop: if (!build_##llvmop(op)) return false; break\n\tOPMAP(InputLoad, input_load);\n\tOPMAP(OutputLoad, output_load);\n\tOPMAP(OutputStore, output_store);\n\tOPMAP(CompositeConstruct, composite_construct);\n\tOPMAP(CompositeExtract, composite_extract);\n\tOPMAP(CompositeInsert, composite_insert);\n\tOPMAP(DescriptorLoad, descriptor_load);\n\tOPMAP(BufferLoad, buffer_load);\n\tOPMAP(BufferStore, buffer_store);\n\tOPMAP(BufferAtomic, buffer_atomic);\n\tOPMAP(CounterAtomic, counter_atomic);\n\tOPMAP(BufferQuerySize, buffer_query_size);\n\tOPMAP(ImageLoad, image_load);\n\tOPMAP(ImageStore, image_store);\n\tOPMAP(ImageAtomic, image_atomic);\n\tOPMAP(ImageQuerySize, image_query_size);\n\tOPMAP(ImageQueryMips, image_query_mips_samples);\n\tOPMAP(ImageQuerySamples, image_query_mips_samples);\n\tOPMAP(ImageSample, image_sample);\n\tOPMAP(ImageGather, image_gather);\n\tOPMAP(ImageComputeLod, image_compute_lod);\n\tOPMAP(DerivX, deriv);\n\tOPMAP(DerivY, deriv);\n\tOPMAP(CheckSparseAccess, check_sparse_access);\n\tOPMAP(FRound, fround);\n\tOPMAP(FAbs, dxil_unary<DXIL::Op::FAbs>);\n\tOPMAP(IAbs, dxil_unary<DXIL::Op::ExtendedIAbs>);\n\tOPMAP(FMad, dxil_trinary<DXIL::Op::Fma>);\n\tOPMAP(FRcp, frcp);\n\tOPMAP(FFract, dxil_unary<DXIL::Op::Frc>);\n\tOPMAP(FMin, dxil_binary<DXIL::Op::FMin>);\n\tOPMAP(FMax, dxil_binary<DXIL::Op::FMax>);\n\tOPMAP(SMin, dxil_binary<DXIL::Op::IMin>);\n\tOPMAP(SMax, dxil_binary<DXIL::Op::IMax>);\n\tOPMAP(UMin, dxil_binary<DXIL::Op::UMin>);\n\tOPMAP(UMax, dxil_binary<DXIL::Op::UMax>);\n\tOPMAP(FClamp, dxil_trinary<DXIL::Op::ExtendedFClamp>);\n\tOPMAP(SClamp, dxil_trinary<DXIL::Op::ExtendedIClamp>);\n\tOPMAP(UClamp, dxil_trinary<DXIL::Op::ExtendedUClamp>);\n\tOPMAP(FLog2, dxil_unary<DXIL::Op::Log>);\n\tOPMAP(FExp2, dxil_unary<DXIL::Op::Exp>);\n\tOPMAP(FSin, dxil_unary<DXIL::Op::Sin>);\n\tOPMAP(FCos, dxil_unary<DXIL::Op::Cos>);\n\tOPMAP(FSqrt, dxil_unary<DXIL::Op::Sqrt>);\n\tOPMAP(FRsq, dxil_unary<DXIL::Op::Rsqrt>);\n\tOPMAP(FPow, dxil_binary<DXIL::Op::ExtendedPow>);\n\tOPMAP(FIsNan, dxil_unary<DXIL::Op::IsNan>);\n\tOPMAP(ConvertF32toPackedF16, dxil_unary<DXIL::Op::ExtendedLegacyF32ToF16>);\n\tOPMAP(ConvertPackedF16toF32, dxil_unary<DXIL::Op::ExtendedLegacyF16ToF32>);\n\tOPMAP(InterpolateAtCentroid, interpolate_at_centroid);\n\tOPMAP(InterpolateAtSample, interpolate_at_sample);\n\tOPMAP(InterpolateAtOffset, interpolate_at_offset);\n\tOPMAP(UBitExtract, dxil_trinary<DXIL::Op::ExtendedSpirvUbfe>);\n\tOPMAP(SBitExtract, dxil_trinary<DXIL::Op::ExtendedSpirvIbfe>);\n\tOPMAP(IBitInsert, dxil_quaternary<DXIL::Op::ExtendedSpirvBfi>);\n\tOPMAP(EmitVertex, dxil_constant_unary<DXIL::Op::EmitStream>);\n\tOPMAP(EmitPrimitive, dxil_constant_unary<DXIL::Op::CutStream>);\n\tOPMAP(IBitCount, dxil_unary<DXIL::Op::Countbits>);\n\tOPMAP(IBitReverse, dxil_unary<DXIL::Op::Bfrev>);\n\tOPMAP(IFindLsb, dxil_unary<DXIL::Op::ExtendedSpirvFindLSB>);\n\tOPMAP(SFindMsb, dxil_unary<DXIL::Op::ExtendedSpirvIFindMSB>);\n\tOPMAP(UFindMsb, dxil_unary<DXIL::Op::ExtendedSpirvUFindMSB>);\n\tOPMAP(IAddCarry, dxil_binary<DXIL::Op::ExtendedSpirvIAddCarry>);\n\tOPMAP(ISubBorrow, dxil_binary<DXIL::Op::ExtendedSpirvISubBorrow>);\n\tOPMAP(SMulExtended, dxil_binary<DXIL::Op::ExtendedSpirvSMulExtended>);\n\tOPMAP(UMulExtended, dxil_binary<DXIL::Op::ExtendedSpirvUMulExtended>);\n\tOPMAP(ScratchLoad, gep_load);\n\tOPMAP(ScratchStore, gep_store);\n\tOPMAP(LdsLoad, gep_load);\n\tOPMAP(LdsStore, gep_store);\n\tOPMAP(ConstantLoad, gep_load);\n\tOPMAP(Barrier, barrier);\n\tOPMAP(LdsAtomic, lds_atomic);\n\tOPMAP(Demote, demote);\n#undef OPMAP\n\n\t// Plain instructions\n\tcase ir::OpCode::eCast:\n\t{\n\t\tif (convert_type(op.getType()) == convert_type(builder.getOp(ir::SsaDef(op.getOperand(0))).getType()))\n\t\t{\n\t\t\t// I <-> U casts are meaningless.\n\t\t\tvalue_map[op.getDef()] = get_value(op.getOperand(0));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tpush_instruction(context.construct<CastInst>(convert_type(op.getType()), get_value(op.getOperand(0)),\n\t\t\t                                             Instruction::CastOps::BitCast),\n\t\t\t                 op.getDef());\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase ir::OpCode::eSelect:\n\t{\n\t\tpush_instruction(context.construct<SelectInst>(\n\t\t\t                 get_value(op.getOperand(1)),\n\t\t\t                 get_value(op.getOperand(2)),\n\t\t\t                 get_value(op.getOperand(0))),\n\t\t                 op.getDef());\n\t\tbreak;\n\t}\n\n\tcase ir::OpCode::eFNeg:\n\tcase ir::OpCode::eINeg:\n\t{\n\t\tpush_instruction(context.construct<UnaryOperator>(\n\t\t\t                 op.getOpCode() == ir::OpCode::eFNeg ?\n\t\t\t                 UnaryOperator::UnaryOps::FNeg : UnaryOperator::UnaryOps::INeg,\n\t\t\t                 get_value(op.getOperand(0))),\n\t\t                 op.getDef());\n\t\tbreak;\n\t}\n\n#define CMP(irop, type, llvmop) \\\n\tcase ir::OpCode::irop: \\\n\t\tpush_instruction(context.construct<type##CmpInst>( \\\n\t\t\t                 CmpInst::Predicate::llvmop, \\\n\t\t\t                 get_value(op.getOperand(0)), \\\n\t\t\t                 get_value(op.getOperand(1))), \\\n\t\t                 op.getDef()); break\n\tCMP(eFNe, F, FCMP_UNE);\n\tCMP(eFEq, F, FCMP_OEQ);\n\tCMP(eFGt, F, FCMP_OGT);\n\tCMP(eFGe, F, FCMP_OGE);\n\tCMP(eFLt, F, FCMP_OLT);\n\tCMP(eFLe, F, FCMP_OLE);\n\tCMP(eINe, I, ICMP_NE);\n\tCMP(eIEq, I, ICMP_EQ);\n\tCMP(eBNe, I, ICMP_NE);\n\tCMP(eBEq, I, ICMP_EQ);\n\tCMP(eSGt, I, ICMP_SGT);\n\tCMP(eSGe, I, ICMP_SGE);\n\tCMP(eSLt, I, ICMP_SLT);\n\tCMP(eSLe, I, ICMP_SLE);\n\tCMP(eUGt, I, ICMP_UGT);\n\tCMP(eUGe, I, ICMP_UGE);\n\tCMP(eULt, I, ICMP_ULT);\n\tCMP(eULe, I, ICMP_ULE);\n\n#define BOP(irop, llvmop) case ir::OpCode::irop: if (!build_binary_op(op, BinaryOperator::BinaryOps::llvmop)) return false; break\n\tBOP(eFAdd, FAdd);\n\tBOP(eFSub, FSub);\n\tBOP(eFMul, FMul);\n\tBOP(eFDiv, FDiv);\n\tBOP(eIAdd, Add);\n\tBOP(eISub, Sub);\n\tBOP(eIMul, Mul);\n\tBOP(eUDiv, UDiv);\n\tBOP(eUMod, URem);\n\tBOP(eIAnd, And);\n\tBOP(eIOr, Or);\n\tBOP(eIXor, Xor);\n\tBOP(eBAnd, And);\n\tBOP(eBOr, Or);\n\tBOP(eIShl, Shl);\n\tBOP(eUShr, LShr);\n\tBOP(eSShr, AShr);\n#undef BOP\n\n\tcase ir::OpCode::eConvertFtoF:\n\t{\n\t\tauto &out_type = op.getType();\n\t\tauto &in_type = builder.getOp(ir::SsaDef(op.getOperand(0))).getType();\n\n\t\tif (out_type.byteSize() == in_type.byteSize())\n\t\t{\n\t\t\tvalue_map[op.getDef()] = get_value(op.getOperand(0));\n\t\t\tbreak;\n\t\t}\n\n\t\tbool ext = out_type.byteSize() > in_type.byteSize();\n\t\tauto *inst = context.construct<CastInst>(convert_type(out_type),\n\t\t                                         get_value(op.getOperand(0)),\n\t\t                                         ext ? Instruction::CastOps::FPExt : Instruction::CastOps::FPTrunc);\n\t\tpush_instruction(inst, op.getDef());\n\t\tbreak;\n\t}\n\n\tcase ir::OpCode::eConvertFtoI:\n\t{\n\t\tauto &out_type = op.getType();\n\t\tbool is_signed = out_type.getBaseType(0).isSignedIntType();\n\t\tauto *inst = context.construct<CastInst>(convert_type(out_type), get_value(op.getOperand(0)),\n\t\t                                         is_signed ? Instruction::CastOps::FPToSI : Instruction::CastOps::FPToUI);\n\t\tpush_instruction(inst, op.getDef());\n\t\tbreak;\n\t}\n\n\tcase ir::OpCode::eConvertItoF:\n\t{\n\t\tauto &out_type = op.getType();\n\t\tauto &in_type = builder.getOp(ir::SsaDef(op.getOperand(0))).getType();\n\t\tbool is_signed = in_type.getBaseType(0).isSignedIntType();\n\t\tauto *inst = context.construct<CastInst>(convert_type(out_type), get_value(op.getOperand(0)),\n\t\t                                         is_signed ? Instruction::CastOps::SIToFP : Instruction::CastOps::UIToFP);\n\t\tpush_instruction(inst, op.getDef());\n\t\tbreak;\n\t}\n\n\tcase ir::OpCode::eConvertItoI:\n\t{\n\t\tauto &out_type = op.getType();\n\t\tauto &in_type = builder.getOp(ir::SsaDef(op.getOperand(0))).getType();\n\t\tbool is_signed = in_type.getBaseType(0).isSignedIntType();\n\t\tbool ext = out_type.byteSize() > in_type.byteSize();\n\n\t\tif (out_type.byteSize() == in_type.byteSize())\n\t\t{\n\t\t\tvalue_map[op.getDef()] = get_value(op.getOperand(0));\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!ext)\n\t\t{\n\t\t\tauto *inst = context.construct<CastInst>(convert_type(out_type), get_value(op.getOperand(0)), Instruction::CastOps::Trunc);\n\t\t\tpush_instruction(inst, op.getDef());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *inst = context.construct<CastInst>(\n\t\t\t\tconvert_type(out_type), get_value(op.getOperand(0)),\n\t\t\t\tis_signed ? Instruction::CastOps::SExt : Instruction::CastOps::ZExt);\n\t\t\tpush_instruction(inst, op.getDef());\n\t\t}\n\n\t\tbreak;\n\t}\n\n\tcase ir::OpCode::eINot:\n\tcase ir::OpCode::eBNot:\n\t{\n\t\tauto *result_type = convert_type(op.getType());\n\t\tauto *scalar_type = result_type;\n\t\tConstant *constant_max;\n\t\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(result_type))\n\t\t{\n\t\t\tscalar_type = vec->getElementType();\n\t\t\tconstant_max = ConstantInt::get(scalar_type, UINT64_MAX);\n\t\t\t// Only vec2 is supported.\n\t\t\tconstant_max = context.construct<ConstantDataVector>(result_type, Vector<Value *>{ constant_max, constant_max });\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconstant_max = ConstantInt::get(scalar_type, UINT64_MAX);\n\t\t}\n\n\t\tauto *inst = context.construct<BinaryOperator>(get_value(op.getOperand(0)),\n\t\t                                               constant_max,\n\t\t                                               Instruction::BinaryOps::Xor);\n\n\t\tpush_instruction(inst, op.getDef());\n\t\tbreak;\n\t}\n\n\tcase ir::OpCode::eFunctionCall:\n\t{\n\t\tauto itr = function_map.find(ir::SsaDef(op.getOperand(0)));\n\t\tif (itr == function_map.end())\n\t\t\treturn false;\n\n\t\tauto *func = itr->second;\n\t\tVector<Value *> args;\n\t\targs.reserve(op.getOperandCount() - 1);\n\n\t\tfor (uint32_t i = 1; i < op.getOperandCount(); i++)\n\t\t\targs.push_back(get_value(op.getOperand(i)));\n\n\t\tpush_instruction(context.construct<CallInst>(func->getFunctionType(), func, std::move(args)),\n\t\t                 op.getDef());\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tLOGE(\"Unimplemented opcode %u\\n\", unsigned(op.getOpCode()));\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nInstruction *ParseContext::build_load_input(\n    uint32_t index, Type *type, Value *row, uint32_t col, Value *axis, bool patch)\n{\n\tassert(index != UINT32_MAX);\n\tauto *inst = build_dxil_call(\n\t\tpatch ? DXIL::Op::LoadPatchConstant : DXIL::Op::ExtendedSpirvLoadInput, type, type,\n\t\tget_constant_uint(index),\n\t\trow,\n\t\tget_constant_uint(col),\n\t\taxis ? axis : UndefValue::get(Type::getInt32Ty(context)));\n\n\treturn inst;\n}\n\nInstruction *ParseContext::build_load_output(\n    uint32_t index, Type *type, Value *row, uint32_t col, Value *axis, bool patch)\n{\n\tassert(index != UINT32_MAX);\n\n\tInstruction *inst;\n\n\t// This is slightly extended internally to allow loading outputs in general.\n\tif (patch)\n\t{\n\t\tinst = build_dxil_call(DXIL::Op::LoadPatchConstant, type, type, get_constant_uint(index), row,\n\t\t                       get_constant_uint(col));\n\t}\n\telse\n\t{\n\t\tinst = build_dxil_call(DXIL::Op::LoadOutputControlPoint, type, type, get_constant_uint(index), row,\n\t\t                       get_constant_uint(col), axis ? axis : UndefValue::get(Type::getInt32Ty(context)));\n\t}\n\n\treturn inst;\n}\n\nInstruction *ParseContext::build_store_output(uint32_t index, Value *row, uint32_t col, Value *value, bool patch)\n{\n\tassert(index != UINT32_MAX);\n\tauto *inst = build_dxil_call(\n\t\tpatch ? DXIL::Op::StorePatchConstant : DXIL::Op::StoreOutput, Type::getVoidTy(context), value->getType(),\n\t\tget_constant_uint(index),\n\t\trow,\n\t\tget_constant_uint(col),\n\t\tvalue);\n\n\treturn inst;\n}\n\nInstruction *ParseContext::build_load_builtin(DXIL::Op opcode, ir::SsaDef addr)\n{\n\tType *type;\n\n\tif (opcode == DXIL::Op::InnerCoverage)\n\t\ttype = Type::getInt1Ty(context);\n\telse\n\t\ttype = Type::getInt32Ty(context);\n\n\tif (addr)\n\t\treturn build_dxil_call(opcode, type, nullptr, get_value(addr));\n\telse\n\t\treturn build_dxil_call(opcode, type, nullptr);\n}\n\nValue *ParseContext::get_extracted_composite_component(Value *value, unsigned component)\n{\n\tif (!isa<VectorType>(value->getType()) && !isa<StructType>(value->getType()))\n\t{\n\t\tassert(component == 0);\n\t\treturn value;\n\t}\n\n\t// Common pattern where composites are constructed only to be extracted again.\n\tif (const auto *comp = dyn_cast<CompositeConstructInst>(value))\n\t\treturn comp->getOperand(component);\n\tif (const auto *vec = dyn_cast<ConstantDataVector>(value))\n\t\treturn vec->getElementAsConstant(component);\n\n\tExtractValueInst *extracted;\n\tif (const auto *vec_type = dyn_cast<VectorType>(value->getType()))\n\t\textracted = context.construct<ExtractValueInst>(vec_type->getElementType(), value, Vector<unsigned>{ component });\n\telse if (const auto *struct_type = dyn_cast<StructType>(value->getType()))\n\t\textracted = context.construct<ExtractValueInst>(struct_type->getStructElementType(component), value, Vector<unsigned>{ component });\n\telse\n\t\treturn nullptr;\n\n\tpush_instruction(extracted);\n\treturn extracted;\n}\n\nValue *ParseContext::get_constant_mul(Value *value, uint32_t scale)\n{\n\t// If there is already a multiplier, fold it in to help dxil-spirv analysis get proper vectorization.\n\tif (const auto *cint = dyn_cast<ConstantInt>(value))\n\t{\n\t\treturn get_constant_uint(cint->getUniqueInteger().getZExtValue() * scale);\n\t}\n\telse if (const auto *bop = dyn_cast<BinaryOperator>(value))\n\t{\n\t\tif (bop->getOpcode() == BinaryOperator::BinaryOps::Mul)\n\t\t{\n\t\t\tauto *ca = dyn_cast<ConstantInt>(bop->getOperand(0));\n\t\t\tauto *cb = dyn_cast<ConstantInt>(bop->getOperand(1));\n\n\t\t\tif (ca && cb)\n\t\t\t{\n\t\t\t\treturn get_constant_uint(\n\t\t\t\t    ca->getUniqueInteger().getZExtValue() * cb->getUniqueInteger().getZExtValue() * scale);\n\t\t\t}\n\t\t\telse if (ca || cb)\n\t\t\t{\n\t\t\t\tauto *c = ca ? ca : cb;\n\t\t\t\tauto *other = bop->getOperand(ca ? 1 : 0);\n\t\t\t\tauto *inst =\n\t\t\t\t\tcontext.construct<BinaryOperator>(\n\t\t\t\t\t\tget_constant_uint(\n\t\t\t\t\t\t\tc->getUniqueInteger().getZExtValue() * scale), other, BinaryOperator::BinaryOps::Mul);\n\t\t\t\tpush_instruction(inst);\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\t\telse if (bop->getOpcode() == BinaryOperator::BinaryOps::Add)\n\t\t{\n\t\t\tif (isa<ConstantInt>(bop->getOperand(0)) || isa<ConstantInt>(bop->getOperand(1)))\n\t\t\t{\n\t\t\t\t// Avoid nested scaling. Scale each side. Probably only worth it if at least one of them is a constant.\n\t\t\t\tauto *scaled_a = get_constant_mul(bop->getOperand(0), scale);\n\t\t\t\tauto *scaled_b = get_constant_mul(bop->getOperand(1), scale);\n\t\t\t\tauto *inst = context.construct<BinaryOperator>(scaled_a, scaled_b, BinaryOperator::BinaryOps::Add);\n\t\t\t\tpush_instruction(inst);\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\t}\n\n\tauto *inst = context.construct<BinaryOperator>(get_constant_uint(scale), value, BinaryOperator::BinaryOps::Mul);\n\tpush_instruction(inst);\n\treturn inst;\n}\n\nstatic VectorType *get_vec4_variant(Type *type)\n{\n\tif (auto *vec = dyn_cast<VectorType>(type))\n\t{\n\t\tif (vec->getVectorSize() == 4)\n\t\t\treturn vec;\n\t\telse\n\t\t\treturn VectorType::get(4, vec->getElementType());\n\t}\n\telse\n\t\treturn VectorType::get(4, type);\n}\n\nstatic StructType *get_sparse_feedback_variant(Type *type)\n{\n\tauto *scalar_type = get_scalar_type(type->getStructElementType(1));\n\treturn StructType::get(\n\t\ttype->getContext(),\n\t\t{ scalar_type, scalar_type, scalar_type, scalar_type, Type::getInt32Ty(type->getContext()) });\n}\n\nstatic Type *get_composite_return_type(Type *type)\n{\n\tif (isa<StructType>(type))\n\t\treturn get_sparse_feedback_variant(type);\n\telse\n\t\treturn get_vec4_variant(type);\n}\n\nInstruction *ParseContext::build_extract_composite(const ir::Op &op, Value *value, unsigned num_elements)\n{\n\tif (!num_elements)\n\t\tnum_elements = op.getType().getBaseType(0).getVectorSize();\n\n\tif (num_elements == 1)\n\t\treturn context.construct<ExtractValueInst>(get_scalar_type(value->getType()), value, Vector<unsigned>{ 0 });\n\n\tValue *values[4];\n\tfor (unsigned c = 0; c < num_elements; c++)\n\t\tvalues[c] = get_extracted_composite_component(value, c);\n\n\tassert(num_elements > 1);\n\tauto *result_type = VectorType::get(num_elements, get_scalar_type(value->getType()));\n\tauto *comp = context.construct<CompositeConstructInst>(\n\t\tresult_type, Vector<Value *> { values, values + num_elements });\n\treturn comp;\n}\n\nbool ParseContext::build_buffer_load_return_composite(const ir::Op &op, Value *value)\n{\n\tif (op.getType().isStructType())\n\t{\n\t\t// Sparse feedback.\n\t\tauto *code = get_extracted_composite_component(value, 4);\n\t\tauto *sampled_value = build_extract_composite(op, value, op.getType().getBaseType(1).getVectorSize());\n\t\tpush_instruction(sampled_value);\n\t\tauto *inst = context.construct<CompositeConstructInst>(convert_type(op.getType()), Vector<Value *>{ code, sampled_value });\n\t\tpush_instruction(inst, op.getDef());\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\tunsigned num_elements = op.getType().getBaseType(0).getVectorSize();\n\t\tif (num_elements != 1)\n\t\t\tpush_instruction(build_extract_composite(op, value, num_elements), op.getDef());\n\t\telse\n\t\t\tvalue_map[op.getDef()] = get_extracted_composite_component(value, 0);\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_buffer_load(const ir::Op &op, DXIL::ResourceKind kind)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\tauto *int_type = Type::getInt32Ty(context);\n\n\tauto *addr_value = get_value(op.getOperand(1));\n\n\tValue *first;\n\tValue *second;\n\n\tif (kind == DXIL::ResourceKind::StructuredBuffer)\n\t{\n\t\tfirst = get_extracted_composite_component(addr_value, 0);\n\t\tsecond = get_extracted_composite_component(addr_value, 1);\n\t\tsecond = get_constant_mul(second, 4);\n\t}\n\telse\n\t{\n\t\tfirst = addr_value;\n\t\tif (kind == DXIL::ResourceKind::RawBuffer)\n\t\t\tfirst = get_constant_mul(first, 4);\n\t\tsecond = UndefValue::get(int_type);\n\t}\n\n\tauto *result_type = convert_type(op.getType());\n\tauto *dxil_result_type = get_composite_return_type(result_type);\n\n\tauto *inst = build_dxil_call(\n\t\tDXIL::Op::BufferLoad, dxil_result_type, dxil_result_type,\n\t\tget_value(descriptor), first, second);\n\tpush_instruction(inst);\n\treturn build_buffer_load_return_composite(op, inst);\n}\n\nbool ParseContext::build_buffer_load_cbv(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\tauto addr = ir::SsaDef(op.getOperand(1));\n\tInstruction *inst = nullptr;\n\n\tif (op.getType().isScalarType())\n\t{\n\t\tif (op.getType().byteSize() != 4)\n\t\t{\n\t\t\tLOGE(\"Only support 4 byte scalar CBV loads.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto *result_type = convert_type(op.getType());\n\n\t\tauto *addr_value = get_value(addr);\n\t\tif (!llvm::isa<llvm::VectorType>(addr_value->getType()))\n\t\t{\n\t\t\tLOGE(\"Expected a vector type addr for vectors.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto *index16 = get_extracted_composite_component(addr_value, 0);\n\t\tauto *index4 = get_extracted_composite_component(addr_value, 1);\n\n\t\tauto *mul16 = get_constant_mul(index16, 16);\n\t\tauto *mul4 = get_constant_mul(index4, 4);\n\n\t\tValue *byte_addr;\n\n\t\tif (isa<ConstantInt>(mul16) && isa<ConstantInt>(mul4))\n\t\t{\n\t\t\tbyte_addr = get_constant_uint(cast<ConstantInt>(mul16)->getUniqueInteger().getZExtValue() +\n\t\t\t                              cast<ConstantInt>(mul4)->getUniqueInteger().getZExtValue());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *byte_addr_inst = context.construct<BinaryOperator>(mul16, mul4, llvm::BinaryOperator::BinaryOps::Add);\n\t\t\tpush_instruction(byte_addr_inst);\n\t\t\tbyte_addr = byte_addr_inst;\n\t\t}\n\n\t\tinst = build_dxil_call(DXIL::Op::CBufferLoad, result_type, result_type,\n\t\t                       get_value(descriptor),\n\t\t                       byte_addr);\n\t}\n\telse if (op.getType().isVectorType())\n\t{\n\t\tif (op.getType().getBaseType(0).getVectorSize() != 4 || op.getType().byteSize() != 16)\n\t\t{\n\t\t\tLOGE(\"We can only support vec4 or scalar loads from CBV.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto *result_type = convert_type(op.getType());\n\t\tauto *addr_value = get_value(addr);\n\n\t\tinst = build_dxil_call(DXIL::Op::CBufferLoadLegacy, result_type, result_type,\n\t\t                       get_value(descriptor),\n\t\t                       addr_value);\n\t}\n\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_buffer_load(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\t// This function is overloaded, so need to figure out which type of load we should generate.\n\tif (itr->second.resource_type == DXIL::ResourceType::CBV)\n\t\treturn build_buffer_load_cbv(op);\n\telse\n\t\treturn build_buffer_load(op, itr->second.resource_kind);\n}\n\nbool ParseContext::build_image_store(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto layer = ir::SsaDef(op.getOperand(1));\n\tauto coord = ir::SsaDef(op.getOperand(2));\n\tauto value = ir::SsaDef(op.getOperand(3));\n\n\tValue *coords[3] = {};\n\tValue *values[4] = {};\n\n\tunsigned num_coord_components = builder.getOp(coord).getType().getBaseType(0).getVectorSize();\n\tunsigned num_value_components = builder.getOp(value).getType().getBaseType(0).getVectorSize();\n\n\tauto *scalar_type = get_scalar_type(get_value(value)->getType());\n\tauto *coord_value = get_value(coord);\n\n\tfor (unsigned c = 0; c < num_coord_components; c++)\n\t\tcoords[c] = get_extracted_composite_component(coord_value, c);\n\tfor (unsigned c = num_coord_components; c < 3; c++)\n\t\tcoords[c] = UndefValue::get(Type::getInt32Ty(context));\n\n\tswitch (itr->second.resource_kind)\n\t{\n\tcase DXIL::ResourceKind::Texture1DArray:\n\tcase DXIL::ResourceKind::Texture2DArray:\n\t\tcoords[num_coord_components] = get_value(layer);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tfor (unsigned c = 0; c < num_value_components; c++)\n\t\tvalues[c] = get_extracted_composite_component(get_value(value), c);\n\tfor (unsigned c = num_value_components; c < 4; c++)\n\t\tvalues[c] = UndefValue::get(scalar_type);\n\n\tunsigned mask = (1u << num_value_components) - 1u;\n\n\tauto *inst = build_dxil_call(DXIL::Op::TextureStore, Type::getVoidTy(context),\n\t                             scalar_type,\n\t                             get_value(descriptor),\n\t                             coords[0], coords[1], coords[2],\n\t                             values[0], values[1], values[2], values[3],\n\t                             get_constant_uint(mask));\n\n\tpush_instruction(inst);\n\treturn true;\n}\n\nbool ParseContext::build_image_atomic(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto layer = ir::SsaDef(op.getOperand(1));\n\tauto coord = ir::SsaDef(op.getOperand(2));\n\tauto atomic_op = ir::AtomicOp(op.getOperand(op.getFirstLiteralOperandIndex()));\n\n\tValue *coords[3] = {};\n\n\tunsigned num_coord_components = builder.getOp(coord).getType().getBaseType(0).getVectorSize();\n\n\tauto *int_type = Type::getInt32Ty(context);\n\n\tfor (unsigned c = 0; c < num_coord_components; c++)\n\t\tcoords[c] = get_extracted_composite_component(get_value(coord), c);\n\tfor (unsigned c = num_coord_components; c < 3; c++)\n\t\tcoords[c] = UndefValue::get(Type::getInt32Ty(context));\n\n\tswitch (itr->second.resource_kind)\n\t{\n\tcase DXIL::ResourceKind::Texture1DArray:\n\tcase DXIL::ResourceKind::Texture2DArray:\n\t\tcoords[num_coord_components] = get_value(layer);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (atomic_op == ir::AtomicOp::eCompareExchange)\n\t{\n\t\tauto *inst = build_dxil_call(\n\t\t    DXIL::Op::AtomicCompareExchange,\n\t\t    int_type, int_type,\n\t\t    get_value(descriptor),\n\t\t    coords[0], coords[1], coords[2],\n\t\t    get_extracted_composite_component(get_value(op.getOperand(3)), 0),\n\t\t    get_extracted_composite_component(get_value(op.getOperand(3)), 1));\n\n\t\tpush_instruction(inst, op.getDef());\n\t\treturn true;\n\t}\n\n\tauto binop = convert_atomic_binop(atomic_op);\n\n\tauto *return_type = convert_type(op.getType());\n\tValue *value;\n\n\tif (binop == DXIL::AtomicBinOp::Load)\n\t{\n\t\tvalue = UndefValue::get(int_type);\n\t}\n\telse if (atomic_op == ir::AtomicOp::eInc || atomic_op == ir::AtomicOp::eDec)\n\t{\n\t\tvalue = get_constant_uint(1);\n\t}\n\telse\n\t{\n\t\tvalue = get_value(op.getOperand(3));\n\t\tif (binop != DXIL::AtomicBinOp::Store && op.getType().isVoidType())\n\t\t\treturn_type = int_type;\n\t}\n\n\tauto *inst = build_dxil_call(\n\t\tDXIL::Op::AtomicBinOp,\n\t\treturn_type, return_type,\n\t\tget_value(descriptor), get_constant_uint(uint32_t(binop)),\n\t\tcoords[0], coords[1], coords[2],\n\t\tvalue);\n\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_image_load(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto kind = itr->second.resource_kind;\n\tauto *int_type = Type::getInt32Ty(context);\n\n\tauto mip = ir::SsaDef(op.getOperand(1));\n\tauto layer = ir::SsaDef(op.getOperand(2));\n\tauto coord = ir::SsaDef(op.getOperand(3));\n\tauto sample = ir::SsaDef(op.getOperand(4));\n\tauto offset = ir::SsaDef(op.getOperand(5));\n\n\tValue *mip_or_sample = nullptr;\n\tValue *offsets[3] = {};\n\tValue *coords[3] = {};\n\n\tif (kind == DXIL::ResourceKind::TextureCube || kind == DXIL::ResourceKind::TextureCubeArray)\n\t{\n\t\tLOGE(\"Cubes not allowed for loads.\\n\");\n\t\treturn false;\n\t}\n\n\tif (kind == DXIL::ResourceKind::Texture2DMS || kind == DXIL::ResourceKind::Texture2DMSArray)\n\t\tmip_or_sample = get_value(sample);\n\telse if (itr->second.resource_type == DXIL::ResourceType::SRV)\n\t\tmip_or_sample = get_value(mip);\n\n\tunsigned coord_components = builder.getOp(coord).getType().getBaseType(0).getVectorSize();\n\n\tfor (unsigned c = 0; c < coord_components; c++)\n\t{\n\t\tcoords[c] = get_extracted_composite_component(get_value(coord), c);\n\t\tif (offset)\n\t\t\toffsets[c] = get_extracted_composite_component(get_value(offset), c);\n\t}\n\n\tif (kind == DXIL::ResourceKind::Texture1DArray ||\n\t    kind == DXIL::ResourceKind::Texture2DArray ||\n\t    kind == DXIL::ResourceKind::Texture2DMSArray)\n\t{\n\t\tcoords[coord_components] = get_value(layer);\n\t}\n\n\tif (!mip_or_sample)\n\t\tmip_or_sample = UndefValue::get(int_type);\n\n\tfor (auto &off : offsets)\n\t\tif (!off)\n\t\t\toff = UndefValue::get(int_type);\n\n\tfor (auto &c : coords)\n\t\tif (!c)\n\t\t\tc = UndefValue::get(int_type);\n\n\tauto *result_type = convert_type(op.getType());\n\tauto *dxil_result_type = get_composite_return_type(result_type);\n\n\tauto *inst = build_dxil_call(\n\t\tDXIL::Op::TextureLoad, dxil_result_type, dxil_result_type,\n\t\tget_value(descriptor), mip_or_sample,\n\t\tcoords[0], coords[1], coords[2],\n\t\toffsets[0], offsets[1], offsets[2]);\n\tpush_instruction(inst);\n\treturn build_buffer_load_return_composite(op, inst);\n}\n\nbool ParseContext::build_image_query_size(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto *result_type = convert_type(op.getType());\n\tauto *dxil_result_type = VectorType::get(4, Type::getInt32Ty(context));\n\tauto kind = itr->second.resource_kind;\n\n\tauto *inst = build_dxil_call(\n\t\tDXIL::Op::GetDimensions, dxil_result_type, dxil_result_type,\n\t\tget_value(descriptor),\n\t\top.getOperand(1) ? get_value(op.getOperand(1)) : UndefValue::get(Type::getInt32Ty(context)));\n\tpush_instruction(inst);\n\n\tunsigned num_dimensions = op.getType().getSubType(0).getBaseType(0).getVectorSize();\n\n\tauto *dims = build_extract_composite(op, inst, num_dimensions);\n\tpush_instruction(dims);\n\n\tValue *layers;\n\n\tif (kind == DXIL::ResourceKind::Texture1DArray || kind == DXIL::ResourceKind::Texture2DArray ||\n\t    kind == DXIL::ResourceKind::Texture2DMSArray || kind == DXIL::ResourceKind::TextureCubeArray)\n\t{\n\t\tlayers = get_extracted_composite_component(inst, num_dimensions);\n\t}\n\telse\n\t{\n\t\tlayers = get_constant_uint(1);\n\t}\n\n\tinst = context.construct<CompositeConstructInst>(result_type, Vector<Value *>{ dims, layers });\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_image_query_mips_samples(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto *dxil_result_type = VectorType::get(4, Type::getInt32Ty(context));\n\n\tauto *inst = build_dxil_call(\n\t    DXIL::Op::GetDimensions, dxil_result_type, dxil_result_type,\n\t    get_value(descriptor), get_constant_uint(0));\n\tpush_instruction(inst);\n\n\t// Mips are encoded in the last structure element, for reasons.\n\tauto *value = get_extracted_composite_component(inst, 3);\n\tvalue_map[op.getDef()] = value;\n\treturn true;\n}\n\nbool ParseContext::build_image_sample(const ir::Op &op)\n{\n\tauto image_desc = ir::SsaDef(op.getOperand(0));\n\tauto &resource_op = builder.getOp(image_desc);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto layer = ir::SsaDef(op.getOperand(2));\n\tauto coord = ir::SsaDef(op.getOperand(3));\n\tauto offset = ir::SsaDef(op.getOperand(4));\n\tauto lod_index = ir::SsaDef(op.getOperand(5));\n\tauto lod_bias = ir::SsaDef(op.getOperand(6));\n\tauto lod_clamp = ir::SsaDef(op.getOperand(7));\n\tauto dx = ir::SsaDef(op.getOperand(8));\n\tauto dy = ir::SsaDef(op.getOperand(9));\n\tauto dref = ir::SsaDef(op.getOperand(10));\n\n\tauto opcode = DXIL::Op::Sample;\n\tif (lod_index)\n\t\topcode = DXIL::Op::SampleLevel;\n\telse if (lod_bias)\n\t\topcode = DXIL::Op::SampleBias;\n\telse if (dx && dy)\n\t\topcode = DXIL::Op::SampleGrad;\n\n\tif (op.getType().isScalarType())\n\t{\n\t\tswitch (opcode)\n\t\t{\n\t\tcase DXIL::Op::Sample: opcode = DXIL::Op::SampleCmp; break;\n\t\tcase DXIL::Op::SampleLevel: opcode = DXIL::Op::SampleCmpLevel; break;\n\t\tcase DXIL::Op::SampleBias: opcode = DXIL::Op::SampleCmpBias; break;\n\t\tcase DXIL::Op::SampleGrad: opcode = DXIL::Op::SampleCmpGrad; break;\n\t\tdefault: return false;\n\t\t}\n\t}\n\n\tunsigned num_coord_components = builder.getOp(coord).getType().getBaseType(0).getVectorSize();\n\n\tValue *coords[4] = {};\n\tValue *offsets[3] = {};\n\tValue *ddx[3] = {};\n\tValue *ddy[3] = {};\n\n\tfor (unsigned c = 0; c < num_coord_components; c++)\n\t{\n\t\tcoords[c] = get_extracted_composite_component(get_value(coord), c);\n\t\tif (offset)\n\t\t\toffsets[c] = get_extracted_composite_component(get_value(offset), c);\n\t\tif (dx)\n\t\t\tddx[c] = get_extracted_composite_component(get_value(dx), c);\n\t\tif (dy)\n\t\t\tddy[c] = get_extracted_composite_component(get_value(dy), c);\n\t}\n\n\tswitch (itr->second.resource_kind)\n\t{\n\tcase DXIL::ResourceKind::Texture1DArray:\n\tcase DXIL::ResourceKind::Texture2DArray:\n\tcase DXIL::ResourceKind::TextureCubeArray:\n\t\tcoords[num_coord_components] = get_value(layer);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tVector<Value *> values;\n\tvalues.push_back(get_value(image_desc));\n\tvalues.push_back(get_value(op.getOperand(1))); // sampler\n\tfor (auto *c : coords)\n\t\tvalues.push_back(c ? c : UndefValue::get(Type::getFloatTy(context)));\n\tfor (auto *o : offsets)\n\t\tvalues.push_back(o ? o : UndefValue::get(Type::getInt32Ty(context)));\n\n\tif (op.getType().isScalarType())\n\t\tvalues.push_back(get_value(dref));\n\n\tif (opcode == DXIL::Op::SampleGrad || opcode == DXIL::Op::SampleCmpGrad)\n\t{\n\t\tfor (auto *d : ddx)\n\t\t\tvalues.push_back(d ? d : UndefValue::get(Type::getFloatTy(context)));\n\t\tfor (auto *d : ddy)\n\t\t\tvalues.push_back(d ? d : UndefValue::get(Type::getFloatTy(context)));\n\t}\n\n\tif (opcode == DXIL::Op::SampleBias || opcode == DXIL::Op::SampleCmpBias)\n\t\tvalues.push_back(get_value(lod_bias));\n\n\tif (opcode != DXIL::Op::SampleLevel && opcode != DXIL::Op::SampleCmpLevel)\n\t\tvalues.push_back(lod_clamp ? get_value(lod_clamp) : UndefValue::get(Type::getFloatTy(context)));\n\telse if (lod_index)\n\t\tvalues.push_back(get_value(lod_index));\n\n\tauto *result_type = convert_type(op.getType());\n\tauto *dxil_result_type = get_composite_return_type(result_type);\n\tauto *inst = build_dxil_call(opcode, dxil_result_type, dxil_result_type, std::move(values));\n\tpush_instruction(inst);\n\treturn build_buffer_load_return_composite(op, inst);\n}\n\nbool ParseContext::build_image_gather(const ir::Op &op)\n{\n\tauto image_desc = ir::SsaDef(op.getOperand(0));\n\tauto &resource_op = builder.getOp(image_desc);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto layer = ir::SsaDef(op.getOperand(2));\n\tauto coord = ir::SsaDef(op.getOperand(3));\n\tauto offset = ir::SsaDef(op.getOperand(4));\n\tauto dref = ir::SsaDef(op.getOperand(5));\n\tauto comp = uint32_t(op.getOperand(6));\n\n\tauto opcode = dref ? DXIL::Op::TextureGatherCmp : DXIL::Op::TextureGather;\n\tunsigned num_coord_components = builder.getOp(coord).getType().getBaseType(0).getVectorSize();\n\n\tValue *coords[4] = {};\n\tValue *offsets[2] = {};\n\n\tfor (unsigned c = 0; c < num_coord_components; c++)\n\t{\n\t\tcoords[c] = get_extracted_composite_component(get_value(coord), c);\n\t\tif (offset)\n\t\t\toffsets[c] = get_extracted_composite_component(get_value(offset), c);\n\t}\n\n\tswitch (itr->second.resource_kind)\n\t{\n\tcase DXIL::ResourceKind::Texture2DArray:\n\tcase DXIL::ResourceKind::TextureCubeArray:\n\t\tcoords[num_coord_components] = get_value(layer);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tVector<Value *> values;\n\tvalues.push_back(get_value(image_desc));\n\tvalues.push_back(get_value(op.getOperand(1))); // sampler\n\tfor (auto *c : coords)\n\t\tvalues.push_back(c ? c : UndefValue::get(Type::getFloatTy(context)));\n\tfor (auto *o : offsets)\n\t\tvalues.push_back(o ? o : UndefValue::get(Type::getInt32Ty(context)));\n\tvalues.push_back(get_constant_uint(comp));\n\tif (dref)\n\t\tvalues.push_back(get_value(dref));\n\n\tauto *result_type = convert_type(op.getType());\n\tauto *dxil_result_type = get_composite_return_type(result_type);\n\tauto *inst = build_dxil_call(opcode, dxil_result_type, dxil_result_type, std::move(values));\n\tpush_instruction(inst);\n\treturn build_buffer_load_return_composite(op, inst);\n}\n\nbool ParseContext::build_image_compute_lod(const ir::Op &op)\n{\n\tauto image_desc = ir::SsaDef(op.getOperand(0));\n\tauto &resource_op = builder.getOp(image_desc);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto coord = ir::SsaDef(op.getOperand(2));\n\tunsigned num_coord_components = builder.getOp(coord).getType().getBaseType(0).getVectorSize();\n\n\tValue *coords[3] = {};\n\tfor (unsigned c = 0; c < num_coord_components; c++)\n\t\tcoords[c] = get_extracted_composite_component(get_value(coord), c);\n\tfor (unsigned c = num_coord_components; c < 3; c++)\n\t\tcoords[c] = UndefValue::get(Type::getFloatTy(context));\n\n\t// Alternate extended formulation since DXIL is weird.\n\tauto *inst = build_dxil_call(DXIL::Op::ExtendedCalculateLOD, convert_type(op.getType()), nullptr,\n\t                             get_value(image_desc), get_value(op.getOperand(1)),\n\t                             coords[0], coords[1], coords[2]);\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_buffer_store(const ir::Op &op, DXIL::ResourceKind kind)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\tauto *int_type = Type::getInt32Ty(context);\n\n\tauto *addr_value = get_value(op.getOperand(1));\n\n\tValue *first;\n\tValue *second;\n\n\t// TODO: Adjust byte offset.\n\tif (kind == DXIL::ResourceKind::StructuredBuffer)\n\t{\n\t\tfirst = get_extracted_composite_component(addr_value, 0);\n\t\tsecond = get_extracted_composite_component(addr_value, 1);\n\t\tsecond = get_constant_mul(second, 4);\n\t}\n\telse\n\t{\n\t\tfirst = addr_value;\n\t\tif (kind == DXIL::ResourceKind::RawBuffer)\n\t\t\tfirst = get_constant_mul(first, 4);\n\t\tsecond = UndefValue::get(int_type);\n\t}\n\n\tauto *value = get_value(op.getOperand(2));\n\tValue *scalar_values[4];\n\n\tauto *scalar_type = value->getType();\n\tunsigned num_components = 1;\n\tif (const auto *vec = dyn_cast<VectorType>(scalar_type))\n\t{\n\t\tscalar_type = vec->getElementType();\n\t\tnum_components = vec->getVectorSize();\n\t}\n\n\tunsigned mask = (1u << num_components) - 1u;\n\n\tfor (unsigned c = 0; c < num_components; c++)\n\t\tscalar_values[c] = get_extracted_composite_component(value, c);\n\tfor (unsigned c = num_components; c < 4; c++)\n\t\tscalar_values[c] = UndefValue::get(scalar_type);\n\n\tauto *inst = build_dxil_call(DXIL::Op::BufferStore, Type::getVoidTy(context), scalar_type,\n\t                             get_value(descriptor),\n\t                             first, second,\n\t                             scalar_values[0], scalar_values[1], scalar_values[2], scalar_values[3],\n\t                             get_constant_uint(mask));\n\n\tpush_instruction(inst);\n\treturn true;\n}\n\nbool ParseContext::build_buffer_store(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\treturn build_buffer_store(op, itr->second.resource_kind);\n}\n\nbool ParseContext::build_buffer_atomic_binop(const ir::Op &op, DXIL::ResourceKind kind)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\tauto *int_type = Type::getInt32Ty(context);\n\tauto *addr_value = get_value(op.getOperand(1));\n\n\tValue *first;\n\tValue *second;\n\n\t// TODO: Adjust byte offset.\n\tif (kind == DXIL::ResourceKind::StructuredBuffer)\n\t{\n\t\tfirst = get_extracted_composite_component(addr_value, 0);\n\t\tsecond = get_extracted_composite_component(addr_value, 1);\n\t\tsecond = get_constant_mul(second, 4);\n\t}\n\telse\n\t{\n\t\tfirst = addr_value;\n\t\tif (kind == DXIL::ResourceKind::RawBuffer)\n\t\t\tfirst = get_constant_mul(first, 4);\n\t\tsecond = UndefValue::get(int_type);\n\t}\n\n\tauto atomic_op = ir::AtomicOp(op.getOperand(op.getFirstLiteralOperandIndex()));\n\n\tValue *value;\n\tauto *return_type = convert_type(op.getType());\n\n\tif (atomic_op == ir::AtomicOp::eCompareExchange)\n\t{\n\t\tauto *inst = build_dxil_call(\n\t\t    DXIL::Op::AtomicCompareExchange,\n\t\t    int_type, int_type,\n\t\t    get_value(descriptor),\n\t\t    first, second, UndefValue::get(int_type),\n\t\t    get_extracted_composite_component(get_value(op.getOperand(2)), 0),\n\t\t    get_extracted_composite_component(get_value(op.getOperand(2)), 1));\n\n\t\tpush_instruction(inst, op.getDef());\n\t\treturn true;\n\t}\n\n\tauto binop = convert_atomic_binop(atomic_op);\n\n\tif (binop == DXIL::AtomicBinOp::Load)\n\t{\n\t\tvalue = UndefValue::get(int_type);\n\t}\n\telse if (atomic_op == ir::AtomicOp::eInc || atomic_op == ir::AtomicOp::eDec)\n\t{\n\t\tvalue = get_constant_uint(1);\n\t}\n\telse\n\t{\n\t\tvalue = get_value(op.getOperand(2));\n\t\tif (binop != DXIL::AtomicBinOp::Store && op.getType().isVoidType())\n\t\t\treturn_type = int_type;\n\t}\n\n\tauto *inst = build_dxil_call(\n\t\tDXIL::Op::AtomicBinOp, return_type, return_type,\n\t\tget_value(descriptor),\n\t\tget_constant_uint(uint32_t(binop)),\n\t\tfirst, second, UndefValue::get(int_type),\n\t\tvalue);\n\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_lds_atomic(const ir::Op &op)\n{\n\tauto *lds = get_value(op.getOperand(0));\n\tVector<Value *> args;\n\targs.push_back(lds);\n\targs.push_back(get_constant_uint(0));\n\n\tif (op.getOperand(1))\n\t{\n\t\tauto &addr = builder.getOp(ir::SsaDef(op.getOperand(1)));\n\t\tauto *addr_value = get_value(op.getOperand(1));\n\t\tfor (uint32_t i = 0; i < addr.getType().getBaseType(0).getVectorSize(); i++)\n\t\t\targs.push_back(get_extracted_composite_component(addr_value, i));\n\t}\n\n\tType *type;\n\tif (!op.getType().isVoidType())\n\t\ttype = convert_type(op.getType());\n\telse\n\t\ttype = convert_type(builder.getOp(ir::SsaDef(op.getOperand(2))).getType());\n\n\tauto *gep = context.construct<GetElementPtrInst>(\n\t\tPointerType::get(type, uint32_t(DXIL::AddressSpace::GroupShared)), std::move(args), true);\n\tpush_instruction(gep);\n\n\tauto *value = get_value(op.getOperand(2));\n\tauto atomic_op = ir::AtomicOp(op.getOperand(3));\n\n\tif (atomic_op == ir::AtomicOp::eCompareExchange)\n\t{\n\t\tauto *inst = context.construct<AtomicCmpXchgInst>(\n\t\t\tgep,\n\t\t\tget_extracted_composite_component(value, 0),\n\t\t\tget_extracted_composite_component(value, 1), type);\n\n\t\tpush_instruction(inst, op.getDef());\n\t}\n\telse\n\t{\n\t\tif (atomic_op == ir::AtomicOp::eInc || atomic_op == ir::AtomicOp::eDec)\n\t\t\tvalue = get_constant_uint(1);\n\t\telse if (atomic_op == ir::AtomicOp::eLoad)\n\t\t\tvalue = get_constant_uint(0);\n\n\t\tassert(value);\n\n\t\tauto *inst = context.construct<AtomicRMWInst>(\n\t\t    type, gep, value, convert_atomic_binop_llvm(atomic_op));\n\t\tpush_instruction(inst, op.getDef());\n\t}\n\n\treturn true;\n}\n\nbool ParseContext::build_buffer_atomic(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\treturn build_buffer_atomic_binop(op, itr->second.resource_kind);\n}\n\nbool ParseContext::build_counter_atomic(const ir::Op &op)\n{\n\tauto &load_desc_op = builder.getOp(ir::SsaDef(op.getOperand(0)));\n\tauto counter_descriptor = ir::SsaDef(load_desc_op.getOperand(0));\n\tauto *int_type = Type::getInt32Ty(context);\n\n\tauto &counter_resource_op = builder.getOp(counter_descriptor);\n\tauto descriptor = ir::SsaDef(counter_resource_op.getOperand(1));\n\tauto itr = resource_map.find(descriptor);\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto *inst = build_dxil_call(\n\t        DXIL::Op::BufferUpdateCounter, int_type, int_type,\n\t        get_value(load_desc_op.getDef()),\n\t        get_constant_uint(ir::AtomicOp(op.getOperand(1)) == ir::AtomicOp::eInc ? 1 : -1));\n\n\tpush_instruction(inst, op.getDef());\n\treturn true;\n}\n\nbool ParseContext::build_buffer_query_size(const ir::Op &op)\n{\n\tauto descriptor = ir::SsaDef(op.getOperand(0));\n\n\tauto &resource_op = builder.getOp(descriptor);\n\tauto itr = resource_map.find(ir::SsaDef(resource_op.getOperand(0)));\n\tif (itr == resource_map.end())\n\t\treturn false;\n\n\tauto *result_type = convert_type(op.getType());\n\tauto *vec4_type = get_vec4_variant(result_type);\n\n\t// Fold in the mul + div into a plain OpArrayLength.\n\tauto *inst = build_dxil_call(\n\t\tDXIL::Op::ExtendedGetDimensions, vec4_type, nullptr,\n\t\tget_value(descriptor),\n\t\tUndefValue::get(Type::getInt32Ty(context)),\n\t    get_constant_uint(itr->second.resource_kind == DXIL::ResourceKind::RawBuffer ? 4 : 1));\n\n\tpush_instruction(inst);\n\n\tauto *value = get_extracted_composite_component(inst, 0);\n\tvalue_map[op.getDef()] = value;\n\n\treturn true;\n}\n\nInstruction *ParseContext::build_descriptor_load(ir::SsaDef resource, ir::SsaDef index, bool nonuniform)\n{\n\tauto itr = resource_map.find(resource);\n\tif (itr == resource_map.end())\n\t\treturn nullptr;\n\n\t// Dummy pointer type which represents handles.\n\t// It's not directly used.\n\tauto *ptr_type = PointerType::get(Type::getVoidTy(context), 0);\n\tauto *bool_type = Type::getInt1Ty(context);\n\n\tValue *binding_offset;\n\n\tif (index)\n\t{\n\t\tauto *dynamic_offset = get_value(index);\n\t\tif (const auto *const_offset = llvm::dyn_cast<ConstantInt>(dynamic_offset))\n\t\t{\n\t\t\tbinding_offset = get_constant_uint(\n\t\t\t\tconst_offset->getUniqueInteger().getZExtValue() +\n\t\t\t\titr->second.binding_offset);\n\t\t}\n\t\telse if (itr->second.binding_offset)\n\t\t{\n\t\t\t// SM 5.1 bindless.\n\t\t\tauto *add = context.construct<BinaryOperator>(dynamic_offset,\n\t\t\t                                              get_constant_uint(itr->second.binding_offset),\n\t\t\t                                              BinaryOperator::BinaryOps::Add);\n\t\t\tpush_instruction(add);\n\t\t\tbinding_offset = add;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbinding_offset = dynamic_offset;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// DXIL is a bit silly and takes effective register index instead of offset into binding space.\n\t\tbinding_offset = get_constant_uint(itr->second.binding_offset);\n\t}\n\n\treturn build_dxil_call(DXIL::Op::CreateHandle, ptr_type, nullptr,\n\t                       get_constant_uint(uint32_t(itr->second.resource_type)),\n\t                       get_constant_uint(itr->second.index),\n\t                       binding_offset,\n\t                       ConstantInt::get(bool_type, nonuniform));\n}\n\nMDOperand *ParseContext::create_null_meta()\n{\n\treturn context.construct<MDOperand>(&module, MetadataKind::None);\n}\n\nMDNode *ParseContext::create_md_node(Vector<MDOperand *> ops)\n{\n\tauto *node = context.construct<MDNode>(&module, std::move(ops));\n\tnode->set_tween_id(++metadata_tween_id);\n\tmodule.add_unnamed_metadata(node);\n\treturn node;\n}\n\nvoid ParseContext::create_named_md_node(const String &name, MDNode *node)\n{\n\tVector<MDNode *> vops { node };\n\tauto *n = context.construct<NamedMDNode>(&module, name, std::move(vops));\n\tmodule.add_named_metadata(name, n);\n}\n\nMDNode *ParseContext::create_stage_io_meta()\n{\n\tstruct IOOp\n\t{\n\t\tconst ir::Op *op;\n\t\tstd::string semantic;\n\t\tuint32_t index;\n\t};\n\tstd::vector<IOOp> io_inputs, io_outputs, io_patch;\n\n\tfor (auto &op : builder)\n\t{\n\t\tswitch (op.getOpCode())\n\t\t{\n\t\tcase ir::OpCode::eDclInput:\n\t\tcase ir::OpCode::eDclInputBuiltIn:\n\t\t\t// For user-IO the general rule is that if it's an array it's a control point of some kind.\n\t\t\t// Multiple rows for stage IO is not used except for certain builtins.\n\t\t\tif (io_decl_is_patch(shader_stage, op))\n\t\t\t\tio_patch.push_back({ &op });\n\t\t\telse\n\t\t\t\tio_inputs.push_back({ &op });\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eDclOutput:\n\t\tcase ir::OpCode::eDclOutputBuiltIn:\n\t\t\t// For user-IO the general rule is that if it's an array it's a control point of some kind.\n\t\t\t// Multiple rows for stage IO is not used except for certain builtins.\n\t\t\tif (io_decl_is_patch(shader_stage, op))\n\t\t\t\tio_patch.push_back({ &op });\n\t\t\telse\n\t\t\t\tio_outputs.push_back({ &op });\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eSemantic:\n\t\t{\n\t\t\tstd::vector<IOOp> *sems[] = { &io_inputs, &io_outputs, &io_patch };\n\t\t\tfor (auto *sem : sems)\n\t\t\t{\n\t\t\t\tfor (auto &ioop : *sem)\n\t\t\t\t{\n\t\t\t\t\tif (ioop.op->getDef() == ir::SsaDef(op.getOperand(0)))\n\t\t\t\t\t{\n\t\t\t\t\t\tioop.index = uint32_t(op.getOperand(1));\n\t\t\t\t\t\tioop.semantic = op.getLiteralString(2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst struct\n\t{\n\t\tstd::vector<IOOp> *ioop;\n\t\tMetadataMapping *mapping;\n\t} mappings[] = {\n\t\t{ &io_inputs, &inputs },\n\t\t{ &io_outputs, &outputs },\n\t\t{ &io_patch, &patches },\n\t};\n\n\tfor (auto &mapping : mappings)\n\t{\n\t\tfor (auto &io : *mapping.ioop)\n\t\t{\n\t\t\tDXIL::Semantic builtin = shader_stage == ir::ShaderStage::ePixel &&\n\t\t\t                         io.op->getOpCode() == ir::OpCode::eDclOutput ?\n\t\t\t                         DXIL::Semantic::Target : DXIL::Semantic::User;\n\n\t\t\tuint32_t location, component;\n\t\t\tuint32_t stream = UINT32_MAX;\n\n\t\t\tbool is_input =\n\t\t\t\tio.op->getOpCode() == ir::OpCode::eDclInput ||\n\t\t\t\tio.op->getOpCode() == ir::OpCode::eDclInputBuiltIn;\n\n\t\t\tbool is_user =\n\t\t\t\tio.op->getOpCode() == ir::OpCode::eDclInput ||\n\t\t\t\tio.op->getOpCode() == ir::OpCode::eDclOutput;\n\n\t\t\tif (is_user)\n\t\t\t{\n\t\t\t\tlocation = uint32_t(io.op->getOperand(1));\n\t\t\t\tcomponent = uint32_t(io.op->getOperand(2));\n\t\t\t\tif (!is_input && io.op->getOperandCount() == 4)\n\t\t\t\t\tstream = uint32_t(io.op->getOperand(3));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbuiltin = convert_semantic(ir::BuiltIn(io.op->getOperand(1)));\n\t\t\t\tlocation = UINT32_MAX;\n\t\t\t\tcomponent = UINT32_MAX;\n\n\t\t\t\tif (!is_input && io.op->getOperandCount() == 3)\n\t\t\t\t\tstream = uint32_t(io.op->getOperand(2));\n\n\t\t\t\tif (builtin == DXIL::Semantic::Depth)\n\t\t\t\t{\n\t\t\t\t\tfor_all_opcodes(builder, ir::OpCode::eSetPsDepthLessEqual,\n\t\t\t\t\t                [&](const ir::Op &op) { builtin = DXIL::Semantic::DepthLessEqual; return false; });\n\t\t\t\t\tfor_all_opcodes(builder, ir::OpCode::eSetPsDepthGreaterEqual,\n\t\t\t\t\t                [&](const ir::Op &op) { builtin = DXIL::Semantic::DepthGreaterEqual; return false; });\n\t\t\t\t}\n\n\t\t\t\tif (io.op->getOpCode() == ir::OpCode::eDclInputBuiltIn)\n\t\t\t\t{\n\t\t\t\t\t// Some stage IO builtins are resolved through opcodes, not IO.\n\t\t\t\t\tauto op = convert_builtin_opcode(ir::BuiltIn(io.op->getOperand(1)));\n\n\t\t\t\t\tif (builtin == DXIL::Semantic::Coverage)\n\t\t\t\t\t\top = DXIL::Op::Coverage;\n\n\t\t\t\t\tif (op != DXIL::Op::Count)\n\t\t\t\t\t{\n\t\t\t\t\t\tstage_io_map[io.op->getDef()] = { UINT32_MAX, op, false };\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tauto interpolation = DXIL::InterpolationMode::Invalid;\n\t\t\tif (is_input)\n\t\t\t\tinterpolation = convert_interpolation_mode(ir::InterpolationMode(io.op->getOperand(is_user ? 3 : 2)));\n\n\t\t\tbool is_geom = shader_stage == ir::ShaderStage::eGeometry;\n\t\t\tbool is_tess = shader_stage == ir::ShaderStage::eHull || shader_stage == ir::ShaderStage::eDomain;\n\t\t\tbool is_geom_tess_input = is_input && (is_geom || is_tess);\n\t\t\tbool is_hull_output = !is_input && shader_stage == ir::ShaderStage::eHull;\n\n\t\t\t// TessFactors is the exception since it's a patch array.\n\t\t\tbool need_axis = io.op->getType().isArrayType() &&\n\t\t\t                 (builtin != DXIL::Semantic::TessFactor && builtin != DXIL::Semantic::InsideTessFactor) &&\n\t\t\t                 (is_geom_tess_input || is_hull_output);\n\n\t\t\tauto comp = convert_component_mapping(io.op->getType(), need_axis);\n\t\t\tbuild_stage_io(*mapping.mapping, io.op->getDef(), String(io.semantic),\n\t\t\t               comp.type, builtin, io.index, interpolation,\n\t\t\t               comp.num_rows, comp.num_cols, location, component, stream, need_axis);\n\t\t}\n\t}\n\n\treturn create_md_node(\n\t\tinputs.nodes.empty() ? create_null_meta() : create_md_node(inputs.nodes),\n\t\toutputs.nodes.empty() ? create_null_meta() : create_md_node(outputs.nodes),\n\t\tpatches.nodes.empty() ? create_null_meta() : create_md_node(patches.nodes));\n}\n\nMDOperand *ParseContext::create_entry_point_meta(Function *patch_control_func)\n{\n\tVector<MDOperand *> flag_ops;\n\n\tuint64_t shader_flags = 0;\n\tflag_ops.push_back(create_constant_uint_meta(uint32_t(DXIL::ShaderPropertyTag::ShaderFlags)));\n\n\tif (shader_stage == ir::ShaderStage::ePixel)\n\t{\n\t\tfor_all_opcodes(builder, ir::OpCode::eSetPsEarlyFragmentTest, [&](const ir::Op &) {\n\t\t\tshader_flags |= DXIL::ShaderFlagEarlyDepthStencil;\n\t\t\treturn false;\n\t\t});\n\t}\n\n\tflag_ops.push_back(create_constant_uint64_meta(shader_flags));\n\n\tif (shader_stage == ir::ShaderStage::eCompute)\n\t{\n\t\tflag_ops.push_back(create_constant_uint_meta(uint32_t(DXIL::ShaderPropertyTag::NumThreads)));\n\t\tconst ir::Op *threads = nullptr;\n\t\tfor_all_opcodes(builder, ir::OpCode::eSetCsWorkgroupSize,\n\t\t                [&](const ir::Op &op) { threads = &op; return false; });\n\n\t\tif (!threads)\n\t\t{\n\t\t\tLOGE(\"Need to declare threads.\\n\");\n\t\t\treturn nullptr;\n\t\t}\n\n\t\tflag_ops.push_back(create_md_node(\n\t\t    create_constant_uint_meta(uint32_t(threads->getOperand(1))),\n\t\t    create_constant_uint_meta(uint32_t(threads->getOperand(2))),\n\t\t    create_constant_uint_meta(uint32_t(threads->getOperand(3)))));\n\t}\n\telse if (shader_stage == ir::ShaderStage::eGeometry)\n\t{\n\t\tflag_ops.push_back(create_constant_uint_meta(uint32_t(DXIL::ShaderPropertyTag::GSState)));\n\n\t\tir::PrimitiveType input_primitive = {};\n\t\tir::PrimitiveType output_primitive = {};\n\t\tuint32_t stream_mask = 0;\n\t\tuint32_t instances = 0;\n\t\tuint32_t output_vertices = 0;\n\n\t\tfor (auto &op : builder)\n\t\t{\n\t\t\tswitch (op.getOpCode())\n\t\t\t{\n\t\t\tcase ir::OpCode::eSetGsInstances:\n\t\t\t\tinstances = uint32_t(op.getOperand(1));\n\t\t\t\tbreak;\n\n\t\t\tcase ir::OpCode::eSetGsOutputVertices:\n\t\t\t\toutput_vertices = uint32_t(op.getOperand(1));\n\t\t\t\tbreak;\n\n\t\t\tcase ir::OpCode::eSetGsInputPrimitive:\n\t\t\t\tinput_primitive = ir::PrimitiveType(op.getOperand(1));\n\t\t\t\tbreak;\n\n\t\t\tcase ir::OpCode::eSetGsOutputPrimitive:\n\t\t\t\toutput_primitive = ir::PrimitiveType(op.getOperand(1));\n\t\t\t\tstream_mask = uint32_t(op.getOperand(2));\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tflag_ops.push_back(create_md_node(\n\t\t    create_constant_uint_meta(uint32_t(convert_input_primitive_type(input_primitive))),\n\t\t    create_constant_uint_meta(output_vertices),\n\t\t    create_constant_uint_meta(stream_mask),\n\t\t    create_constant_uint_meta(uint32_t(convert_output_primitive_type(output_primitive))),\n\t\t    create_constant_uint_meta(instances)));\n\t}\n\telse if (shader_stage == ir::ShaderStage::eHull)\n\t{\n\t\tir::PrimitiveType prim = {};\n\t\tir::PrimitiveType domain = {};\n\t\tir::TessWindingOrder winding = {};\n\t\tir::TessPartitioning partitioning = {};\n\t\tuint32_t input_control_points = 0;\n\t\tuint32_t output_control_points = 0;\n\n\t\tfor (auto &op : builder)\n\t\t{\n\t\t\tswitch (op.getOpCode())\n\t\t\t{\n\t\t\tcase ir::OpCode::eSetTessControlPoints:\n\t\t\t\tinput_control_points = uint32_t(op.getOperand(1));\n\t\t\t\toutput_control_points = uint32_t(op.getOperand(2));\n\t\t\t\tbreak;\n\n\t\t\tcase ir::OpCode::eSetTessPrimitive:\n\t\t\t\tprim = ir::PrimitiveType(op.getOperand(1));\n\t\t\t\twinding = ir::TessWindingOrder(op.getOperand(2));\n\t\t\t\tpartitioning = ir::TessPartitioning(op.getOperand(3));\n\t\t\t\tbreak;\n\n\t\t\tcase ir::OpCode::eSetTessDomain:\n\t\t\t\tdomain = ir::PrimitiveType(op.getOperand(1));\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tflag_ops.push_back(create_constant_uint_meta(uint32_t(DXIL::ShaderPropertyTag::HSState)));\n\t\tflag_ops.push_back(create_md_node(\n\t\t    patch_control_func ? create_constant_meta(patch_control_func) : create_null_meta(),\n\t\t    create_constant_uint_meta(input_control_points),\n\t\t    create_constant_uint_meta(output_control_points),\n\t\t    create_constant_uint_meta(uint32_t(convert_hull_domain(domain))),\n\t\t    create_constant_uint_meta(uint32_t(convert_hull_partitioning(partitioning))),\n\t\t    create_constant_uint_meta(uint32_t(convert_hull_output_primitive(prim, winding)))));\n\t}\n\telse if (shader_stage == ir::ShaderStage::eDomain)\n\t{\n\t\tir::PrimitiveType domain = {};\n\t\tfor_all_opcodes(builder, ir::OpCode::eSetTessDomain, [&](const ir::Op &op) {\n\t\t\tdomain = ir::PrimitiveType(op.getOperand(1));\n\t\t\treturn false;\n\t\t});\n\t\tflag_ops.push_back(create_constant_uint_meta(uint32_t(DXIL::ShaderPropertyTag::DSState)));\n\t\tflag_ops.push_back(create_md_node(\n\t\t    create_constant_uint_meta(uint32_t(convert_hull_domain(domain))),\n\t\t    create_constant_uint_meta(32 /* somewhat irrelevant? */)));\n\t}\n\n\treturn flag_ops.empty() ? create_null_meta() : create_md_node(std::move(flag_ops));\n}\n\nvoid ParseContext::set_function_attributes(Function *func)\n{\n\tVector<std::pair<String, String>> attrs;\n\n\tfor_all_opcodes(builder, ir::OpCode::eSetFpMode, [&](const ir::Op &op) {\n\t\tauto round = ir::RoundMode(op.getOperand(1));\n\t\tauto denorm = ir::DenormMode(op.getOperand(2));\n\n\t\tconst char *round_mode = nullptr;\n\t\tconst char *denorm_mode = nullptr;\n\n\t\tswitch (op.getType().getBaseType(0).getBaseType())\n\t\t{\n\t\tcase ir::ScalarType::eF16:\n\t\t\tround_mode = \"dxbc-fp16-round-mode\";\n\t\t\tdenorm_mode = \"dxbc-fp16-denorm-mode\";\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eF32:\n\t\t\tround_mode = \"dxbc-fp32-round-mode\";\n\t\t\tdenorm_mode = \"dxbc-fp32-denorm-mode\";\n\t\t\tbreak;\n\n\t\tcase ir::ScalarType::eF64:\n\t\t\tround_mode = \"dxbc-fp64-round-mode\";\n\t\t\tdenorm_mode = \"dxbc-fp64-denorm-mode\";\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tif (round == ir::RoundMode::eZero)\n\t\t\tattrs.emplace_back(round_mode, \"rtz\");\n\t\telse if (round == ir::RoundMode::eNearestEven)\n\t\t\tattrs.emplace_back(round_mode, \"rte\");\n\n\t\tif (denorm == ir::DenormMode::eFlush)\n\t\t\tattrs.emplace_back(denorm_mode, \"ftz\");\n\t\telse if (denorm == ir::DenormMode::ePreserve)\n\t\t\tattrs.emplace_back(denorm_mode, \"preserve\");\n\n\t\tglobal_fp_flags |= op.getFlags();\n\t\treturn true;\n\t});\n\n\tfunc->set_attributes(std::move(attrs));\n}\n\nbool ParseContext::emit_entry_point()\n{\n\tconst ir::Op *entry = nullptr;\n\tfor_all_opcodes(builder, ir::OpCode::eEntryPoint, [&](const ir::Op &op) { entry = &op; return false; });\n\tif (!entry)\n\t\treturn false;\n\n\tshader_stage = ir::ShaderStage(entry->getOperand(entry->getFirstLiteralOperandIndex()));\n\n\tFunction *patch_control_func = nullptr;\n\n\t// Process patch constant func first so we can emit metadata.\n\tfor (uint32_t i_plus1 = entry->getFirstLiteralOperandIndex(); i_plus1; i_plus1--)\n\t{\n\t\tauto i = i_plus1 - 1;\n\t\tauto ssa = ir::SsaDef(entry->getOperand(i));\n\n\t\tType *type = convert_type(entry->getType());\n\n\t\t// Entry points don't take arguments.\n\t\tauto *func_type = context.construct<FunctionType>(context, type, Vector<Type *>{});\n\t\tauto *func = context.construct<Function>(func_type, ++tween_id, module);\n\t\tmodule.add_value_name(tween_id, i == 0 ? \"main\" : \"patchMain\");\n\n\t\tif (i == 1)\n\t\t\tpatch_control_func = func;\n\n\t\t// We're not barbarians.\n\t\tfunc->set_structured_control_flow();\n\n\t\tfunction_map[ssa] = func;\n\n\t\tif (i == 0)\n\t\t{\n\t\t\tcreate_named_md_node(\"dx.entryPoints\",\n\t\t\t                     create_md_node(create_constant_meta(func), create_string_meta(\"main\"),\n\t\t\t                                    create_stage_io_meta(), create_null_meta(),\n\t\t\t                                    create_entry_point_meta(patch_control_func)));\n\n\t\t\tset_function_attributes(func);\n\t\t}\n\t}\n\n\tauto *name = create_string_meta(\"dxbc-spirv\");\n\tcreate_named_md_node(\"llvm.ident\", create_md_node(name));\n\n\tconst char *stage_str = shader_stage_to_meta(shader_stage);\n\tauto *stage_type = create_string_meta(stage_str);\n\tauto *major = create_constant_uint_meta(6);\n\tauto *minor = create_constant_uint_meta(0);\n\tcreate_named_md_node(\"dx.shaderModel\", create_md_node(stage_type, major, minor));\n\treturn true;\n}\n\nuint32_t ParseContext::build_texture_srv(\n    uint32_t space, uint32_t index, uint32_t size,\n    DXIL::ResourceKind kind, DXIL::ComponentType type)\n{\n\tuint32_t ret = srvs.nodes.size();\n\tauto *srv = create_md_node(\n\t    create_constant_uint_meta(ret),\n\t    create_null_meta(),\n\t    create_string_meta(\"\"),\n\t    create_constant_uint_meta(space),\n\t    create_constant_uint_meta(index),\n\t    create_constant_uint_meta(size),\n\t    create_constant_uint_meta(uint32_t(kind)),\n\t    create_null_meta(), // SRV sample count? We don't care about that.\n\t    create_md_node(\n\t        create_constant_uint_meta(0),\n\t        create_constant_uint_meta(uint32_t(type))));\n\n\tsrvs.nodes.push_back(srv);\n\treturn ret;\n}\n\nuint32_t ParseContext::build_texture_uav(\n    uint32_t space, uint32_t index, uint32_t size,\n    DXIL::ResourceKind kind, DXIL::ComponentType type,\n    bool coherent, bool rov)\n{\n\tuint32_t ret = uavs.nodes.size();\n\n\tauto *uav = create_md_node(\n\t    create_constant_uint_meta(ret),\n\t    create_null_meta(),\n\t    create_string_meta(\"\"),\n\t    create_constant_uint_meta(space),\n\t    create_constant_uint_meta(index),\n\t    create_constant_uint_meta(size),\n\t    create_constant_uint_meta(uint32_t(kind)),\n\t    create_constant_uint_meta(coherent),\n\t    create_constant_uint_meta(false),\n\t    create_constant_uint_meta(rov),\n\t    create_md_node(\n\t        create_constant_uint_meta(0),\n\t        create_constant_uint_meta(uint32_t(type))));\n\n\tuavs.nodes.push_back(uav);\n\treturn ret;\n}\n\nuint32_t ParseContext::build_buffer_uav(\n    uint32_t space, uint32_t index, uint32_t size,\n    DXIL::ResourceKind kind, uint32_t stride,\n    bool coherent, bool counter, bool rov)\n{\n\tuint32_t ret = uavs.nodes.size();\n\n\tauto *uav = create_md_node(\n\t    create_constant_uint_meta(ret),\n\t    create_null_meta(),\n\t    create_string_meta(\"\"),\n\t    create_constant_uint_meta(space),\n\t    create_constant_uint_meta(index),\n\t    create_constant_uint_meta(size),\n\t    create_constant_uint_meta(uint32_t(kind)),\n\t    create_constant_uint_meta(coherent),\n\t    create_constant_uint_meta(counter),\n\t    create_constant_uint_meta(rov),\n\t    create_md_node(\n\t        create_constant_uint_meta(1),\n\t        create_constant_uint_meta(stride)));\n\n\tuavs.nodes.push_back(uav);\n\treturn ret;\n}\n\nuint32_t ParseContext::build_buffer_srv(\n    uint32_t space, uint32_t index, uint32_t size,\n    DXIL::ResourceKind kind, uint32_t stride)\n{\n\tuint32_t ret = srvs.nodes.size();\n\tauto *srv = create_md_node(\n\t    create_constant_uint_meta(ret),\n\t    create_null_meta(),\n\t    create_string_meta(\"\"),\n\t    create_constant_uint_meta(space),\n\t    create_constant_uint_meta(index),\n\t    create_constant_uint_meta(size),\n\t    create_constant_uint_meta(uint32_t(kind)),\n\t    create_null_meta(), // SRV sample count? We don't care about that.\n\t    create_md_node(\n\t        create_constant_uint_meta(1),\n\t        create_constant_uint_meta(stride)));\n\n\tsrvs.nodes.push_back(srv);\n\treturn ret;\n}\n\nuint32_t ParseContext::build_sampler(uint32_t space, uint32_t index, uint32_t size)\n{\n\tuint32_t ret = samplers.nodes.size();\n\tauto *sampler = create_md_node(\n\t    create_constant_uint_meta(ret),\n\t    create_null_meta(),\n\t    create_string_meta(\"\"),\n\t    create_constant_uint_meta(space),\n\t    create_constant_uint_meta(index),\n\t    create_constant_uint_meta(size));\n\n\tsamplers.nodes.push_back(sampler);\n\treturn ret;\n}\n\nuint32_t ParseContext::build_cbv(\n    uint32_t space, uint32_t index, uint32_t size, uint32_t cbv_size)\n{\n\tuint32_t ret = cbvs.nodes.size();\n\tauto *sampler = create_md_node(\n\t    create_constant_uint_meta(ret),\n\t    create_null_meta(),\n\t    create_string_meta(\"\"),\n\t    create_constant_uint_meta(space),\n\t    create_constant_uint_meta(index),\n\t    create_constant_uint_meta(size),\n\t    create_constant_uint_meta(cbv_size));\n\n\tcbvs.nodes.push_back(sampler);\n\treturn ret;\n}\n\nuint32_t ParseContext::build_stage_io(\n    MetadataMapping &mapping, ir::SsaDef ssa,\n\tconst String &name, DXIL::ComponentType type, DXIL::Semantic semantic, uint32_t semantic_index,\n    DXIL::InterpolationMode interpolation,\n    uint32_t rows, uint32_t cols,\n    uint32_t start_row, uint32_t start_col, uint32_t stream, bool need_axis)\n{\n\tuint32_t ret = mapping.nodes.size();\n\n\tstage_io_map[ssa] = { ret, DXIL::Op::Count, need_axis };\n\n\tMDOperand *stream_meta;\n\n\tif (stream != UINT32_MAX)\n\t{\n\t\tstream_meta = create_md_node(\n\t\t\tcreate_constant_uint_meta(uint32_t(DXIL::GSStageOutTags::Stream)),\n\t\t\tcreate_constant_uint_meta(stream));\n\t}\n\telse\n\t\tstream_meta = create_null_meta();\n\n\tauto *input = create_md_node(\n\t\tcreate_constant_uint_meta(ret),\n\t\tcreate_string_meta(name),\n\t\tcreate_constant_uint_meta(uint32_t(type)),\n\t\tcreate_constant_uint_meta(uint32_t(semantic)),\n\t\tsemantic_index ? create_md_node(create_constant_uint_meta(semantic_index)) : create_null_meta(),\n\t\tcreate_constant_uint_meta(uint32_t(interpolation)),\n\t\tcreate_constant_uint_meta(rows),\n\t\tcreate_constant_uint_meta(cols),\n\t\tcreate_constant_uint_meta(start_row),\n\t\tcreate_constant_uint_meta(start_col),\n\t    stream_meta);\n\n\tmapping.nodes.push_back(input);\n\treturn ret;\n}\n\nbool ParseContext::emit_metadata()\n{\n\tUnorderedSet<ir::SsaDef> uav_counters;\n\tfor (auto &op : builder)\n\t\tif (op.getOpCode() == ir::OpCode::eDclUavCounter)\n\t\t\tuav_counters.insert(ir::SsaDef(op.getOperand(1)));\n\n\tfor (auto &op : builder)\n\t{\n\t\tswitch (op.getOpCode())\n\t\t{\n\t\tcase ir::OpCode::eDclCbv:\n\t\t{\n\t\t\tuint32_t space = uint32_t(op.getOperand(1));\n\t\t\tuint32_t binding = uint32_t(op.getOperand(2));\n\t\t\tuint32_t count = uint32_t(op.getOperand(3));\n\t\t\tif (!count)\n\t\t\t\tcount = UINT32_MAX;\n\n\t\t\tuint32_t cbv_size = op.getType().byteSize();\n\t\t\tuint32_t index = build_cbv(space, binding, count, cbv_size);\n\t\t\tresource_map[op.getDef()] = { DXIL::ResourceType::CBV, DXIL::ResourceKind::CBuffer, index, binding };\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::eDclSampler:\n\t\t{\n\t\t\tuint32_t space = uint32_t(op.getOperand(1));\n\t\t\tuint32_t binding = uint32_t(op.getOperand(2));\n\t\t\tuint32_t count = uint32_t(op.getOperand(3));\n\t\t\tif (!count)\n\t\t\t\tcount = UINT32_MAX;\n\n\t\t\tuint32_t index = build_sampler(space, binding, count);\n\t\t\tresource_map[op.getDef()] = { DXIL::ResourceType::Sampler, DXIL::ResourceKind::Sampler, index, binding };\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::eDclSrv:\n\t\tcase ir::OpCode::eDclUav:\n\t\t{\n\t\t\tuint32_t space = uint32_t(op.getOperand(1));\n\t\t\tuint32_t binding = uint32_t(op.getOperand(2));\n\t\t\tuint32_t count = uint32_t(op.getOperand(3));\n\t\t\tif (!count)\n\t\t\t\tcount = UINT32_MAX;\n\n\t\t\tauto kind = convert_resource_kind(ir::ResourceKind(uint32_t(op.getOperand(4))));\n\t\t\tbool srv = op.getOpCode() == ir::OpCode::eDclSrv;\n\t\t\tuint32_t index;\n\n\t\t\tir::UavFlag uav_flags = {};\n\t\t\tif (!srv)\n\t\t\t\tuav_flags = ir::UavFlag(op.getOperand(5));\n\n\t\t\tif (kind == DXIL::ResourceKind::RawBuffer || kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t\t{\n\t\t\t\tuint32_t stride = 0;\n\n\t\t\t\tif (kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t\t\t{\n\t\t\t\t\tif (op.getType().getArrayDimensions() != 2)\n\t\t\t\t\t{\n\t\t\t\t\t\tLOGE(\"Expected 2 array dimensions.\\n\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tstride = op.getType().getArraySize(0) * 4;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (op.getType().getArrayDimensions() != 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tLOGE(\"Expected 1 array dimension.\\n\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (op.getType().getArraySize(op.getType().getArrayDimensions() - 1) != 0)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Last dimension must be unsized.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (op.getType().getBaseType(0).byteSize() != 4)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Expected 4 byte base type for raw buffers.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (srv)\n\t\t\t\t{\n\t\t\t\t\tindex = build_buffer_srv(space, binding, count, kind, stride);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tindex = build_buffer_uav(space, binding, count, kind, stride,\n\t\t\t\t\t                         bool(uav_flags & ir::UavFlag::eCoherent),\n\t\t\t\t\t                         uav_counters.count(op.getDef()) != 0,\n\t\t\t\t\t                         bool(uav_flags & ir::UavFlag::eRasterizerOrdered));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto mapping = convert_component_mapping(op.getType(), false);\n\n\t\t\t\tif (srv)\n\t\t\t\t{\n\t\t\t\t\tindex = build_texture_srv(space, binding, count, kind, mapping.type);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tindex = build_texture_uav(space, binding, count, kind, mapping.type,\n\t\t\t\t\t                          bool(uav_flags & ir::UavFlag::eCoherent),\n\t\t\t\t\t                          bool(uav_flags & ir::UavFlag::eRasterizerOrdered));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresource_map[op.getDef()] = {\n\t\t\t\tsrv ? DXIL::ResourceType::SRV : DXIL::ResourceType::UAV, kind, index, binding\n\t\t\t};\n\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tcreate_named_md_node(\"dx.resources\", create_md_node(\n\t\tsrvs.nodes.empty() ? create_null_meta() : create_md_node(srvs.nodes),\n\t\tuavs.nodes.empty() ? create_null_meta() : create_md_node(uavs.nodes),\n\t\tcbvs.nodes.empty() ? create_null_meta() : create_md_node(cbvs.nodes),\n\t\tsamplers.nodes.empty() ? create_null_meta() : create_md_node(samplers.nodes)));\n\n\treturn true;\n}\n\nbool ParseContext::emit_function_bodies()\n{\n\tVector<BasicBlock *> bbs;\n\tFunction *func = nullptr;\n\n\tfor (auto &op : builder)\n\t{\n\t\tswitch (op.getOpCode())\n\t\t{\n\t\tcase ir::OpCode::eEntryPoint:\n\t\tcase ir::OpCode::eDebugName:\n\t\tcase ir::OpCode::eDebugMemberName:\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eDclSpecConstant:\n\t\tcase ir::OpCode::eDclPushData:\n\t\tcase ir::OpCode::eDclTmp:\n\t\tcase ir::OpCode::eScopedIf:\n\t\tcase ir::OpCode::eScopedElse:\n\t\tcase ir::OpCode::eScopedEndIf:\n\t\tcase ir::OpCode::eScopedLoop:\n\t\tcase ir::OpCode::eScopedLoopBreak:\n\t\tcase ir::OpCode::eScopedLoopContinue:\n\t\tcase ir::OpCode::eScopedEndLoop:\n\t\tcase ir::OpCode::eScopedSwitch:\n\t\tcase ir::OpCode::eScopedSwitchCase:\n\t\tcase ir::OpCode::eScopedSwitchDefault:\n\t\tcase ir::OpCode::eScopedSwitchBreak:\n\t\tcase ir::OpCode::eScopedEndSwitch:\n\t\tcase ir::OpCode::eConsumeAs:\n\t\tcase ir::OpCode::eTmpLoad:\n\t\tcase ir::OpCode::eTmpStore:\n\t\tcase ir::OpCode::ePushDataLoad:\n\t\tcase ir::OpCode::eMemoryLoad:\n\t\tcase ir::OpCode::eMemoryStore:\n\t\tcase ir::OpCode::eMemoryAtomic:\n\t\tcase ir::OpCode::ePointer:\n\t\tcase ir::OpCode::eFMulLegacy:\n\t\tcase ir::OpCode::eFMadLegacy:\n\t\tcase ir::OpCode::eFDot:\n\t\tcase ir::OpCode::eFDotLegacy:\n\t\tcase ir::OpCode::eFPowLegacy:\n\t\tcase ir::OpCode::eUMSad:\n\t\tcase ir::OpCode::eDrain:\n\t\t\tLOGE(\"Opcode %u should not appear in final IR at this point.\\n\", unsigned(op.getOpCode()));\n\t\t\treturn false;\n\n\t\tcase ir::OpCode::eDclXfb:\n\t\tcase ir::OpCode::eRovScopedLockBegin:\n\t\tcase ir::OpCode::eRovScopedLockEnd:\n\t\t\t// Should not appear, but we can just ignore it since it has no semantic impact at this stage.\n\t\t\t// ROV is done automatically by dxil-spirv path already, so ignore that here.\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eDclInput:\n\t\tcase ir::OpCode::eDclInputBuiltIn:\n\t\tcase ir::OpCode::eDclOutput:\n\t\tcase ir::OpCode::eDclOutputBuiltIn:\n\t\tcase ir::OpCode::eDclSrv:\n\t\tcase ir::OpCode::eDclUav:\n\t\tcase ir::OpCode::eDclUavCounter:\n\t\tcase ir::OpCode::eDclCbv:\n\t\tcase ir::OpCode::eDclSampler:\n\t\tcase ir::OpCode::eSemantic:\n\t\tcase ir::OpCode::eSetCsWorkgroupSize:\n\t\tcase ir::OpCode::eSetPsDepthGreaterEqual:\n\t\tcase ir::OpCode::eSetPsDepthLessEqual:\n\t\tcase ir::OpCode::eSetGsInputPrimitive:\n\t\tcase ir::OpCode::eSetGsOutputPrimitive:\n\t\tcase ir::OpCode::eSetGsOutputVertices:\n\t\tcase ir::OpCode::eSetGsInstances:\n\t\tcase ir::OpCode::eSetTessControlPoints:\n\t\tcase ir::OpCode::eSetTessDomain:\n\t\tcase ir::OpCode::eSetTessPrimitive:\n\t\tcase ir::OpCode::eSetFpMode:\n\t\tcase ir::OpCode::eSetPsEarlyFragmentTest:\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eConstant:\n\t\t\tif (!emit_constant(op))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eUndef:\n\t\t\tvalue_map[op.getDef()] = UndefValue::get(convert_type(op.getType()));\n\t\t\tbreak;\n\n\t\t// Functions\n\t\tcase ir::OpCode::eDclParam:\n\t\t\tparam_types[op.getDef()] = convert_type(op.getType());\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eFunction:\n\t\t{\n\t\t\tauto itr = function_map.find(op.getDef());\n\t\t\tif (itr == function_map.end())\n\t\t\t{\n\t\t\t\tType *type = convert_type(op.getType());\n\n\t\t\t\tVector<Type *> types;\n\t\t\t\ttypes.reserve(op.getOperandCount());\n\t\t\t\tparams.clear();\n\n\t\t\t\tfor (unsigned i = 0; i < op.getOperandCount(); i++)\n\t\t\t\t{\n\t\t\t\t\tauto *param_type = param_types[ir::SsaDef(op.getOperand(i))];\n\t\t\t\t\ttypes.push_back(param_type);\n\t\t\t\t\tparams.emplace_back(ir::SsaDef(op.getOperand(i)), param_type);\n\t\t\t\t}\n\n\t\t\t\tauto *func_type = context.construct<FunctionType>(context, type, types);\n\t\t\t\tfunc = context.construct<Function>(func_type, ++tween_id, module);\n\n\t\t\t\tfor (unsigned i = 0; i < op.getOperandCount(); i++)\n\t\t\t\t\tfunc->add_argument(context.construct<Argument>(types[i], i));\n\n\t\t\t\tfunc->set_structured_control_flow();\n\t\t\t\tfunction_map[op.getDef()] = func;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfunc = itr->second;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::eFunctionEnd:\n\t\t\tif (!func)\n\t\t\t{\n\t\t\t\tLOGE(\"Cannot end function without a function.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfunc->set_basic_blocks(std::move(bbs));\n\t\t\tmodule.add_function_implementation(func);\n\t\t\tbbs = {};\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eParamLoad:\n\t\t{\n\t\t\tif (!func)\n\t\t\t{\n\t\t\t\tLOGE(\"Cannot get parameter without a function.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tauto &func_op = builder.getOp(ir::SsaDef(op.getOperand(0)));\n\t\t\tauto param = ir::SsaDef(op.getOperand(1));\n\n\t\t\tauto arg_iter = func->arg_begin();\n\t\t\tfor (uint32_t i = 0; i < func_op.getOperandCount(); i++, ++arg_iter)\n\t\t\t\tif (ir::SsaDef(func_op.getOperand(i)) == param)\n\t\t\t\t\tbreak;\n\n\t\t\tif (arg_iter == func->arg_end())\n\t\t\t\treturn false;\n\n\t\t\tauto &arg = *arg_iter;\n\t\t\tvalue_map[op.getDef()] = const_cast<Argument *>(&arg);\n\t\t\tbreak;\n\t\t}\n\n\t\t// Basic Blocks\n\t\tcase ir::OpCode::eLabel:\n\t\t{\n\t\t\tauto *bb = get_basic_block(op.getDef());\n\t\t\tcurrent_bb = bb;\n\t\t\tbbs.push_back(bb);\n\n\t\t\tswitch (ir::Construct(op.getOperand(op.getFirstLiteralOperandIndex())))\n\t\t\t{\n\t\t\tcase ir::Construct::eStructuredSelection:\n\t\t\t\tbb->set_selection_merge(get_basic_block(ir::SsaDef(op.getOperand(0))));\n\t\t\t\tbreak;\n\n\t\t\tcase ir::Construct::eStructuredLoop:\n\t\t\t\tbb->set_loop_merge(get_basic_block(ir::SsaDef(op.getOperand(0))),\n\t\t\t\t                   get_basic_block(ir::SsaDef(op.getOperand(1))));\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::ePhi:\n\t\t{\n\t\t\t// We might not have emitted all inputs yet. Defer that to a fixup pass later.\n\t\t\tauto *phi = context.construct<PHINode>(convert_type(op.getType()), op.getOperandCount() / 2);\n\t\t\tpush_instruction(phi, op.getDef());\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::eReturn:\n\t\t\tif (!current_bb)\n\t\t\t\treturn false;\n\n\t\t\tif (op.getOperand(0))\n\t\t\t\tpush_instruction(context.construct<ReturnInst>(get_value(op.getOperand(0))));\n\t\t\telse\n\t\t\t\tpush_instruction(context.construct<ReturnInst>(nullptr));\n\n\t\t\tcurrent_bb = nullptr;\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eBranch:\n\t\t{\n\t\t\tif (!current_bb)\n\t\t\t\treturn false;\n\t\t\tauto *target = get_basic_block(ir::SsaDef(op.getOperand(0)));\n\t\t\tcurrent_bb->add_successor(target);\n\t\t\tpush_instruction(context.construct<BranchInst>(target));\n\t\t\tcurrent_bb = nullptr;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::eBranchConditional:\n\t\t{\n\t\t\tif (!current_bb)\n\t\t\t\treturn false;\n\t\t\tauto *value = get_value(op.getOperand(0));\n\t\t\tauto *true_path = get_basic_block(ir::SsaDef(op.getOperand(1)));\n\t\t\tauto *false_path = get_basic_block(ir::SsaDef(op.getOperand(2)));\n\t\t\tcurrent_bb->add_successor(true_path);\n\t\t\tcurrent_bb->add_successor(false_path);\n\t\t\tpush_instruction(context.construct<BranchInst>(true_path, false_path, value));\n\t\t\tcurrent_bb = nullptr;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::eSwitch:\n\t\t{\n\t\t\tif (!current_bb)\n\t\t\t\treturn false;\n\t\t\tauto *default_block = get_basic_block(ir::SsaDef(op.getOperand(1)));\n\t\t\tcurrent_bb->add_successor(default_block);\n\n\t\t\tunsigned num_cases = (op.getOperandCount() - 2) / 2;\n\t\t\tauto *inst = context.construct<SwitchInst>(get_value(op.getOperand(0)), default_block, num_cases);\n\t\t\tfor (unsigned i = 0; i < num_cases; i++)\n\t\t\t{\n\t\t\t\tauto *value = get_value(op.getOperand(2 * i + 2));\n\t\t\t\tauto *case_label = get_basic_block(ir::SsaDef(op.getOperand(2 * i + 3)));\n\t\t\t\tcurrent_bb->add_successor(case_label);\n\t\t\t\tinst->addCase(value, case_label);\n\t\t\t}\n\n\t\t\tpush_instruction(inst);\n\t\t\tcurrent_bb = nullptr;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase ir::OpCode::eUnreachable:\n\t\t\tif (!current_bb)\n\t\t\t\treturn false;\n\t\t\tpush_instruction(context.construct<UnreachableInst>());\n\t\t\tcurrent_bb = nullptr;\n\t\t\tbreak;\n\n\t\tcase ir::OpCode::eDclScratch:\n\t\tcase ir::OpCode::eDclLds:\n\t\t{\n\t\t\tauto *type = convert_type(op.getType());\n\n\t\t\tauto *value = context.construct<GlobalVariable>(\n\t\t\t\tPointerType::get(type, uint32_t(\n\t\t\t\t\top.getOpCode() == ir::OpCode::eDclLds ?\n\t\t\t\t\tDXIL::AddressSpace::GroupShared :\n\t\t\t\t\tDXIL::AddressSpace::Thread)),\n\t\t\t\tGlobalVariable::LinkageTypes::InternalLinkage, false);\n\n\t\t\tvalue_map[op.getDef()] = value;\n\t\t\tmodule.add_global_variable(value);\n\t\t\tbreak;\n\t\t}\n\n\t\t// Opcodes\n\t\tdefault:\n\t\t\tif (!current_bb)\n\t\t\t{\n\t\t\t\tLOGE(\"No BB to insert instructions into.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (!push_instruction(op))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Resolve PHI incoming values since we have value-defs for them now.\n\tfor (auto &op : builder)\n\t{\n\t\tif (op.getOpCode() == ir::OpCode::ePhi)\n\t\t{\n\t\t\tauto *phi = cast<PHINode>(get_value(op.getDef()));\n\t\t\tfor (uint32_t i = 0; i < op.getOperandCount(); i += 2)\n\t\t\t\tphi->add_incoming(get_value(op.getOperand(i + 1)), get_basic_block(ir::SsaDef(op.getOperand(i))));\n\t\t}\n\t}\n\n\treturn true;\n}\n\nValue *ParseContext::get_value(const ir::Operand &op) const\n{\n\treturn get_value(ir::SsaDef(op));\n}\n\nValue *ParseContext::get_value(const ir::SsaDef &op) const\n{\n\tauto itr = value_map.find(op);\n\treturn itr == value_map.end() ? nullptr : itr->second;\n}\n\nBasicBlock *ParseContext::get_basic_block(ir::SsaDef ssa)\n{\n\tauto &bb = bb_map[ssa];\n\tif (!bb)\n\t\tbb = context.construct<BasicBlock>(context);\n\treturn bb;\n}\n\nConstantInt *ParseContext::get_constant_uint(uint32_t value)\n{\n\treturn ConstantInt::get(Type::getInt32Ty(context), value);\n}\n\nConstantAsMetadata *ParseContext::create_constant_uint_meta(uint32_t value)\n{\n\treturn create_constant_meta(get_constant_uint(value));\n}\n\nConstantAsMetadata *ParseContext::create_constant_uint64_meta(uint32_t value)\n{\n\treturn create_constant_meta(ConstantInt::get(Type::getInt64Ty(context), value));\n}\n\nConstantAsMetadata *ParseContext::create_constant_meta(Constant *c)\n{\n\treturn context.construct<ConstantAsMetadata>(&module, c);\n}\n\nMDString *ParseContext::create_string_meta(const String &str)\n{\n\treturn context.construct<MDString>(&module, str);\n}\n\n// Parses the highly simplified and SSA-ified IR coming from dxbc-spirv.\nModule *parseDXBCIR(LLVMContext &context, ir::Builder &builder)\n{\n\tauto *module = context.construct<Module>(context);\n\tParseContext ctx(context, builder, *module);\n\tif (!ctx.emit_entry_point())\n\t\treturn nullptr;\n\tif (!ctx.emit_metadata())\n\t\treturn nullptr;\n\tif (!ctx.emit_function_bodies())\n\t\treturn nullptr;\n\treturn module;\n}\n\nModule *parseDXBCBinary(LLVMContext &context, const void* data, size_t size)\n{\n\tScopedLogger logger;\n\n\tdxbc::Converter::Options convertOptions = { };\n\tconvertOptions.includeDebugNames = false;\n\tconvertOptions.boundCheckShaderIo = true;\n\n\tir::CompileOptions options = { };\n\toptions.scratchOptions.enableBoundChecking = true;\n\toptions.scratchOptions.resolveCbvCopy = false;\n\toptions.scratchOptions.unpackConstantIndexedArrays = true;\n\toptions.scratchOptions.unpackSmallArrays = true;\n\n\toptions.arithmeticOptions.lowerDot = true;\n\toptions.arithmeticOptions.lowerSinCos = false;\n\toptions.arithmeticOptions.lowerMsad = true;\n\toptions.arithmeticOptions.lowerF32toF16 = true;\n\toptions.arithmeticOptions.lowerConvertFtoI = false;\n\toptions.arithmeticOptions.lowerGsVertexCountIn = true;\n\toptions.arithmeticOptions.hasNvUnsignedItoFBug = true;\n\n\toptions.min16Options.enableFloat16 = true;\n\toptions.min16Options.enableInt16 = true;\n\n\toptions.resourceOptions.allowSubDwordScratchAndLds = false;\n\toptions.resourceOptions.flattenLds = true;\n\toptions.resourceOptions.flattenScratch = true;\n\toptions.resourceOptions.structuredCbv = false;\n\toptions.resourceOptions.structuredSrvUav = false;\n\n\toptions.bufferOptions.useTypedForRaw = false;\n\toptions.bufferOptions.useTypedForStructured = false;\n\toptions.bufferOptions.useTypedForSparseFeedback = true;\n\toptions.bufferOptions.useRawForTypedAtomic = false;\n\n\toptions.scalarizeOptions.subDwordVectors = true;\n\n\toptions.syncOptions.allowWorkgroupCoherence = false;\n\toptions.syncOptions.insertRovLocks = false;\n\toptions.syncOptions.insertLdsBarriers = false;\n\toptions.syncOptions.insertUavBarriers = false;\n\n\toptions.derivativeOptions.hoistNontrivialDerivativeOps = true;\n\toptions.derivativeOptions.hoistNontrivialImplicitLodOps = false;\n\toptions.derivativeOptions.hoistDescriptorLoads = false;\n\n\toptions.cseOptions.relocateDescriptorLoad = false;\n\n\toptions.descriptorIndexing.optimizeDescriptorIndexing = false;\n\n\tauto builder = dxbc::compileShaderToLegalizedIr(data, size, convertOptions, options);\n\n\tif (!builder)\n\t\treturn nullptr;\n\n\treturn parseDXBCIR(context, *builder);\n}\n\n}\n"
  },
  {
    "path": "bc/type.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"type.hpp\"\n#include \"cast.hpp\"\n#include \"context.hpp\"\n#include <assert.h>\n\nnamespace LLVMBC\n{\nPointerType::PointerType(Type *type, uint32_t addr_space)\n    : Type(type->getContext(), TypeID::PointerTyID)\n    , contained_type(type)\n{\n\taddress_space = addr_space;\n}\n\nPointerType *PointerType::get(Type *pointee, unsigned addr_space)\n{\n\tauto &context = pointee->getContext();\n\tauto &cache = context.get_type_cache();\n\tfor (auto *type : cache)\n\t{\n\t\tif (type->getTypeID() == TypeID::PointerTyID)\n\t\t{\n\t\t\tauto *pointer_type = cast<PointerType>(type);\n\t\t\tif (pointer_type->getAddressSpace() == addr_space && pointer_type->getElementType() == pointee)\n\t\t\t\treturn pointer_type;\n\t\t}\n\t}\n\n\tauto *type = context.construct<PointerType>(pointee, addr_space);\n\tcache.push_back(type);\n\treturn type;\n}\n\nunsigned Type::getAddressSpace() const\n{\n\treturn address_space;\n}\n\nType *PointerType::getElementType() const\n{\n\treturn contained_type;\n}\n\nArrayType::ArrayType(Type *type, uint64_t elements_)\n    : Type(type->getContext(), TypeID::ArrayTyID)\n    , contained_type(type)\n    , elements(elements_)\n{\n}\n\nArrayType *ArrayType::get(Type *element, uint64_t size)\n{\n\tauto &context = element->getContext();\n\tauto &cache = context.get_type_cache();\n\tfor (auto *type : cache)\n\t{\n\t\tif (type->getTypeID() == TypeID::ArrayTyID)\n\t\t{\n\t\t\tauto *array_type = cast<ArrayType>(type);\n\t\t\tif (array_type->getArrayNumElements() == size && array_type->getArrayElementType() == element)\n\t\t\t\treturn array_type;\n\t\t}\n\t}\n\n\tauto *type = context.construct<ArrayType>(element, size);\n\tcache.push_back(type);\n\treturn type;\n}\n\nVectorType::VectorType(LLVMBC::LLVMContext &context, unsigned vector_size_, LLVMBC::Type *type)\n    : Type(context, TypeID::VectorTyID)\n    , element_type(type)\n    , vector_size(vector_size_)\n{\n}\n\nunsigned VectorType::getVectorSize() const\n{\n\treturn vector_size;\n}\n\nType *VectorType::getElementType() const\n{\n\treturn element_type;\n}\n\nVectorType *VectorType::get(unsigned vector_size, Type *element)\n{\n\tauto &context = element->getContext();\n\tauto &cache = context.get_type_cache();\n\tfor (auto *type : cache)\n\t{\n\t\tif (type->getTypeID() == TypeID::VectorTyID)\n\t\t{\n\t\t\tauto *vector_type = cast<VectorType>(type);\n\t\t\tif (vector_type->getVectorSize() == vector_size && vector_type->getElementType() == element)\n\t\t\t\treturn vector_type;\n\t\t}\n\t}\n\n\tauto *type = context.construct<VectorType>(context, vector_size, element);\n\tcache.push_back(type);\n\treturn type;\n}\n\nuint64_t Type::getArrayNumElements() const\n{\n\tassert(type_id == TypeID::ArrayTyID);\n\treturn cast<ArrayType>(this)->elements;\n}\n\nunsigned Type::getVectorNumElements() const\n{\n\tassert(type_id == TypeID::VectorTyID);\n\treturn cast<VectorType>(this)->getVectorSize();\n}\n\nunsigned Type::getPointerAddressSpace() const\n{\n\tassert(type_id == TypeID::PointerTyID);\n\treturn cast<PointerType>(this)->getAddressSpace();\n}\n\nType *Type::getArrayElementType() const\n{\n\tassert(type_id == TypeID::ArrayTyID);\n\treturn cast<ArrayType>(this)->contained_type;\n}\n\nType *Type::getStructElementType(unsigned index) const\n{\n\tassert(type_id == TypeID::StructTyID);\n\treturn cast<StructType>(this)->getElementType(index);\n}\n\nunsigned Type::getStructNumElements() const\n{\n\tassert(type_id == TypeID::StructTyID);\n\treturn cast<StructType>(this)->getNumElements();\n}\n\nunsigned Type::getIntegerBitWidth() const\n{\n\tassert(type_id == TypeID::IntegerTyID);\n\treturn cast<IntegerType>(this)->getBitWidth();\n}\n\nType *Type::getPointerElementType() const\n{\n\tassert(type_id == TypeID::PointerTyID);\n\treturn cast<PointerType>(this)->getElementType();\n}\n\nStructType::StructType(LLVMContext &context, Vector<Type *> member_types_)\n    : Type(context, TypeID::StructTyID)\n    , member_types(std::move(member_types_))\n{\n}\n\nunsigned StructType::getNumElements() const\n{\n\treturn member_types.size();\n}\n\nType *StructType::getElementType(unsigned N) const\n{\n\tassert(N < member_types.size());\n\treturn member_types[N];\n}\n\nStructType *StructType::get(LLVMContext &context, Vector<Type *> member_types)\n{\n\tauto &cache = context.get_type_cache();\n\tfor (auto *type : cache)\n\t{\n\t\tif (type->getTypeID() == TypeID::StructTyID)\n\t\t{\n\t\t\tauto *struct_type = cast<StructType>(type);\n\t\t\tif (struct_type->getNumElements() == member_types.size())\n\t\t\t{\n\t\t\t\tbool equal = true;\n\t\t\t\tunsigned count = member_types.size();\n\t\t\t\tfor (unsigned i = 0; i < count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (member_types[i] != struct_type->getElementType(i))\n\t\t\t\t\t{\n\t\t\t\t\t\tequal = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (equal)\n\t\t\t\t\treturn struct_type;\n\t\t\t}\n\t\t}\n\t}\n\n\tauto *type = context.construct<StructType>(context, std::move(member_types));\n\tcache.push_back(type);\n\treturn type;\n}\n\nFunctionType::FunctionType(LLVMContext &context, Type *return_type_, Vector<Type *> argument_types_)\n    : Type(context, TypeID::FunctionTyID)\n    , return_type(return_type_)\n    , argument_types(std::move(argument_types_))\n{\n}\n\nunsigned FunctionType::getNumParams() const\n{\n\treturn unsigned(argument_types.size());\n}\n\nType *FunctionType::getParamType(unsigned index) const\n{\n\tassert(index < argument_types.size());\n\treturn argument_types[index];\n}\n\nType *FunctionType::getReturnType() const\n{\n\treturn return_type;\n}\n\nIntegerType::IntegerType(LLVMContext &context, uint32_t width_)\n    : Type(context, TypeID::IntegerTyID)\n    , width(width_)\n{\n}\n\nuint32_t IntegerType::getBitWidth() const\n{\n\treturn width;\n}\n\nType::Type(LLVMContext &context_, TypeID type_id_)\n    : context(context_)\n    , type_id(type_id_)\n{\n}\n\nType::TypeID Type::getTypeID() const\n{\n\treturn type_id;\n}\n\nType *Type::getIntTy(LLVMContext &context, uint32_t width)\n{\n\tauto &cache = context.get_type_cache();\n\tfor (auto *type : cache)\n\t\tif (type->getTypeID() == TypeID::IntegerTyID && cast<IntegerType>(type)->getBitWidth() == width)\n\t\t\treturn type;\n\n\tauto *type = context.construct<IntegerType>(context, width);\n\tcache.push_back(type);\n\treturn type;\n}\n\nType *Type::getTy(LLVMContext &context, TypeID id)\n{\n\tauto &cache = context.get_type_cache();\n\tfor (auto *type : cache)\n\t\tif (type->getTypeID() == id)\n\t\t\treturn type;\n\n\tauto *type = context.construct<Type>(context, id);\n\tcache.push_back(type);\n\treturn type;\n}\n\nType *Type::getVoidTy(LLVMContext &context)\n{\n\treturn getTy(context, TypeID::VoidTyID);\n}\n\nType *Type::getHalfTy(LLVMContext &context)\n{\n\treturn getTy(context, TypeID::HalfTyID);\n}\n\nType *Type::getFloatTy(LLVMContext &context)\n{\n\treturn getTy(context, TypeID::FloatTyID);\n}\n\nType *Type::getDoubleTy(LLVMContext &context)\n{\n\treturn getTy(context, TypeID::DoubleTyID);\n}\n\nType *Type::getLabelTy(LLVMContext &context)\n{\n\treturn getTy(context, TypeID::LabelTyID);\n}\n\nType *Type::getOpaqueTy(LLVMBC::LLVMContext &context)\n{\n\treturn getTy(context, TypeID::OpaqueTyID);\n}\n\nType *Type::getMetadataTy(LLVMContext &context)\n{\n\treturn getTy(context, TypeID::MetadataTyID);\n}\n\nType *Type::getInt1Ty(LLVMContext &context)\n{\n\treturn getIntTy(context, 1);\n}\n\nType *Type::getInt8Ty(LLVMContext &context)\n{\n\treturn getIntTy(context, 8);\n}\n\nType *Type::getInt16Ty(LLVMContext &context)\n{\n\treturn getIntTy(context, 16);\n}\n\nType *Type::getInt32Ty(LLVMContext &context)\n{\n\treturn getIntTy(context, 32);\n}\n\nType *Type::getInt64Ty(LLVMContext &context)\n{\n\treturn getIntTy(context, 64);\n}\n\nbool Type::isIntegerTy() const\n{\n\treturn type_id == TypeID::IntegerTyID;\n}\n\nbool Type::isFloatingPointTy() const\n{\n\treturn type_id == TypeID::HalfTyID || type_id == TypeID::FloatTyID || type_id == TypeID::DoubleTyID;\n}\n\nLLVMContext &Type::getContext()\n{\n\treturn context;\n}\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/type.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"data_structures.hpp\"\n#include <stdint.h>\n\nnamespace LLVMBC\n{\nclass LLVMContext;\n\nclass Type\n{\npublic:\n\tenum class TypeID\n\t{\n\t\tUnknown,\n\t\tVoidTyID,\n\t\tHalfTyID,\n\t\tFloatTyID,\n\t\tDoubleTyID,\n\t\tIntegerTyID,\n\t\tPointerTyID,\n\t\tArrayTyID,\n\t\tStructTyID,\n\t\tFunctionTyID,\n\t\tLabelTyID,\n\t\tVectorTyID,\n\t\tMetadataTyID,\n\t\tOpaqueTyID\n\t};\n\n\tType(LLVMContext &context, TypeID type_id);\n\tLLVMContext &getContext();\n\tTypeID getTypeID() const;\n\n\tstatic Type *getVoidTy(LLVMContext &context);\n\tstatic Type *getHalfTy(LLVMContext &context);\n\tstatic Type *getFloatTy(LLVMContext &context);\n\tstatic Type *getDoubleTy(LLVMContext &context);\n\tstatic Type *getInt1Ty(LLVMContext &context);\n\tstatic Type *getInt8Ty(LLVMContext &context);\n\tstatic Type *getInt16Ty(LLVMContext &context);\n\tstatic Type *getInt32Ty(LLVMContext &context);\n\tstatic Type *getInt64Ty(LLVMContext &context);\n\tstatic Type *getIntTy(LLVMContext &context, uint32_t width);\n\tstatic Type *getLabelTy(LLVMContext &context);\n\tstatic Type *getMetadataTy(LLVMContext &context);\n\tstatic Type *getOpaqueTy(LLVMContext &context);\n\n\tbool isIntegerTy() const;\n\tbool isFloatingPointTy() const;\n\n\tuint64_t getArrayNumElements() const;\n\tType *getArrayElementType() const;\n\tType *getPointerElementType() const;\n\tType *getStructElementType(unsigned index) const;\n\tunsigned getStructNumElements() const;\n\tunsigned getIntegerBitWidth() const;\n\tunsigned getAddressSpace() const;\n\tunsigned getVectorNumElements() const;\n\tunsigned getPointerAddressSpace() const;\n\nprotected:\n\tLLVMContext &context;\n\tTypeID type_id;\n\tstatic Type *getTy(LLVMContext &context, TypeID id);\n\tunsigned address_space = 0;\n};\n\nclass PointerType : public Type\n{\npublic:\n\tstatic constexpr TypeID get_type_id()\n\t{\n\t\treturn TypeID::PointerTyID;\n\t}\n\tPointerType(Type *type, unsigned addr_space);\n\tstatic PointerType *get(Type *pointee, unsigned addr_space);\n\n\tType *getElementType() const;\n\nprivate:\n\tType *contained_type = nullptr;\n};\n\nclass ArrayType : public Type\n{\npublic:\n\tstatic constexpr TypeID get_type_id()\n\t{\n\t\treturn TypeID::ArrayTyID;\n\t}\n\tArrayType(Type *type, uint64_t elements);\n\tstatic ArrayType *get(Type *element, uint64_t size);\n\nprivate:\n\tfriend class Type;\n\tType *contained_type = nullptr;\n\tuint64_t elements = 0;\n};\n\nclass IntegerType : public Type\n{\npublic:\n\tstatic constexpr TypeID get_type_id()\n\t{\n\t\treturn TypeID::IntegerTyID;\n\t}\n\tIntegerType(LLVMContext &context, uint32_t width);\n\tuint32_t getBitWidth() const;\n\nprivate:\n\tuint32_t width = 0;\n};\n\nclass StructType : public Type\n{\npublic:\n\tstatic constexpr TypeID get_type_id()\n\t{\n\t\treturn TypeID::StructTyID;\n\t}\n\tStructType(LLVMContext &context, Vector<Type *> member_types);\n\tstatic StructType *get(LLVMContext &context, Vector<Type *> member_types);\n\n\tunsigned getNumElements() const;\n\tType *getElementType(unsigned N) const;\n\nprivate:\n\tVector<Type *> member_types;\n};\n\nclass VectorType : public Type\n{\npublic:\n\tstatic constexpr TypeID get_type_id()\n\t{\n\t\treturn TypeID::VectorTyID;\n\t}\n\tVectorType(LLVMContext &context, unsigned vector_size, Type *type);\n\tstatic VectorType *get(unsigned vector_size, Type *type);\n\n\tunsigned getVectorSize() const;\n\tType *getElementType() const;\n\nprivate:\n\tType *element_type;\n\tunsigned vector_size;\n};\n\nclass FunctionType : public Type\n{\npublic:\n\tstatic constexpr TypeID get_type_id()\n\t{\n\t\treturn TypeID::FunctionTyID;\n\t}\n\tFunctionType(LLVMContext &context, Type *return_type, Vector<Type *> argument_types);\n\tunsigned getNumParams() const;\n\tType *getParamType(unsigned index) const;\n\tType *getReturnType() const;\n\nprivate:\n\tType *return_type = nullptr;\n\tVector<Type *> argument_types;\n};\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/value.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"value.hpp\"\n#include \"cast.hpp\"\n#include \"context.hpp\"\n#include \"instruction.hpp\"\n#include \"logging.hpp\"\n#include \"type.hpp\"\n#include <string.h>\n\nnamespace LLVMBC\n{\nValue::Value(Type *type_, ValueKind kind_)\n    : type(type_)\n    , kind(kind_)\n{\n}\n\nvoid Value::set_tween_id(uint64_t id)\n{\n\ttween_id = id;\n}\n\nuint64_t Value::get_tween_id() const\n{\n\treturn tween_id;\n}\n\nType *Value::getType() const\n{\n\treturn type;\n}\n\nValueKind Value::get_value_kind() const\n{\n\treturn kind;\n}\n\nArgument::Argument(Type *type, unsigned argument_number_)\n\t: Value(type, ValueKind::Argument), argument_number(argument_number_)\n{\n}\n\nunsigned Argument::getArgNo() const\n{\n\treturn argument_number;\n}\n\nbool Constant::is_base_of_value_kind(ValueKind kind)\n{\n\tswitch (kind)\n\t{\n\tcase ValueKind::ConstantFP:\n\tcase ValueKind::ConstantInt:\n\tcase ValueKind::ConstantDataArray:\n\tcase ValueKind::ConstantDataVector:\n\tcase ValueKind::ConstantAggregate:\n\tcase ValueKind::ConstantAggregateZero:\n\tcase ValueKind::ConstantBase:\n\tcase ValueKind::Undef:\n\tcase ValueKind::Function:\n\tcase ValueKind::Global:\n\tcase ValueKind::ConstantExpr:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nConstant::Constant(Type *type, ValueKind kind)\n    : Value(type, kind)\n{\n}\n\nConstantInt *ConstantInt::get(Type *type, uint64_t value)\n{\n\tauto &context = type->getContext();\n\treturn context.construct<ConstantInt>(type, value);\n}\n\nconst APInt &Constant::getUniqueInteger() const\n{\n\treturn apint;\n}\n\nvoid Constant::set_integer(const APInt &apint_)\n{\n\tapint = apint_;\n}\n\nvoid Constant::set_float(const APFloat &apfloat_)\n{\n\tapfloat = apfloat_;\n}\n\nAPInt::APInt(Type *type_, uint64_t value_)\n    : type(type_)\n    , value(value_)\n{\n}\n\nAPFloat::APFloat(Type *type_, uint64_t value_)\n    : type(type_)\n    , value(value_)\n{\n}\n\nint64_t APInt::getSExtValue() const\n{\n\tauto width = cast<IntegerType>(type)->getBitWidth();\n\tif (width == 64)\n\t\treturn int64_t(value);\n\tauto mask = (1ull << width) - 1;\n\tbool sign_bit = ((value >> (width - 1)) & 1) != 0;\n\tuint64_t extended = sign_bit ? ~mask : 0ull;\n\treturn int64_t((value & mask) | extended);\n}\n\nuint64_t APInt::getZExtValue() const\n{\n\tauto width = cast<IntegerType>(type)->getBitWidth();\n\tif (width == 64)\n\t\treturn value;\n\tauto mask = (1ull << width) - 1u;\n\treturn value & mask;\n}\n\nuint64_t APInt::get_raw_value() const\n{\n\treturn value;\n}\n\nConstantFP *ConstantFP::get(Type *type, uint64_t value)\n{\n\tauto &context = type->getContext();\n\treturn context.construct<ConstantFP>(type, value);\n}\n\nConstantInt::ConstantInt(Type *type, uint64_t value)\n    : Constant(type, ValueKind::ConstantInt)\n{\n\tset_integer(APInt(type, value));\n}\n\nConstantFP::ConstantFP(Type *type, uint64_t value)\n    : Constant(type, ValueKind::ConstantFP)\n{\n\tset_float(APFloat(type, value));\n}\n\nconst APFloat &Constant::getValueAPF() const\n{\n\treturn apfloat;\n}\n\nfloat APFloat::convertToFloat() const\n{\n\tswitch (type->getTypeID())\n\t{\n\tcase Type::TypeID::FloatTyID:\n\t{\n\t\tfloat f;\n\t\tauto u = uint32_t(value);\n\t\tstatic_assert(sizeof(f) == sizeof(u), \"Float is not 32-bit.\");\n\t\tmemcpy(&f, &u, sizeof(float));\n\t\treturn f;\n\t}\n\tcase Type::TypeID::DoubleTyID:\n\t{\n\t\tdouble f;\n\t\tstatic_assert(sizeof(f) == sizeof(value), \"Double is not 64-bit.\");\n\t\tmemcpy(&f, &value, sizeof(double));\n\t\treturn float(f);\n\t}\n\n\tdefault:\n\t\tLOGE(\"Unknown FP type in APFloat::convertToFloat().\\n\");\n\t\treturn 0.0f;\n\t}\n}\n\nAPInt APFloat::bitcastToAPInt() const\n{\n\tType *int_type = nullptr;\n\tswitch (type->getTypeID())\n\t{\n\tcase Type::TypeID::HalfTyID:\n\t\tint_type = Type::getInt16Ty(type->getContext());\n\t\tbreak;\n\n\tcase Type::TypeID::FloatTyID:\n\t\tint_type = Type::getInt32Ty(type->getContext());\n\t\tbreak;\n\n\tcase Type::TypeID::DoubleTyID:\n\t\tint_type = Type::getInt64Ty(type->getContext());\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn { int_type, value };\n}\n\ndouble APFloat::convertToDouble() const\n{\n\tswitch (type->getTypeID())\n\t{\n\tcase Type::TypeID::FloatTyID:\n\t{\n\t\tfloat f;\n\t\tauto u = uint32_t(value);\n\t\tstatic_assert(sizeof(f) == sizeof(u), \"Float is not 32-bit.\");\n\t\tmemcpy(&f, &u, sizeof(float));\n\t\treturn double(f);\n\t}\n\tcase Type::TypeID::DoubleTyID:\n\t{\n\t\tdouble f;\n\t\tstatic_assert(sizeof(f) == sizeof(value), \"Double is not 64-bit.\");\n\t\tmemcpy(&f, &value, sizeof(double));\n\t\treturn f;\n\t}\n\n\tdefault:\n\t\tLOGE(\"Unknown FP type in APFloat::convertToDouble().\\n\");\n\t\treturn 0.0f;\n\t}\n}\n\nUndefValue::UndefValue(Type *type)\n    : Constant(type, ValueKind::Undef)\n{\n}\n\nUndefValue *UndefValue::get(Type *type)\n{\n\tauto &context = type->getContext();\n\treturn context.construct<UndefValue>(type);\n}\n\nConstantAggregateZero::ConstantAggregateZero(Type *type)\n    : Constant(type, ValueKind::ConstantAggregateZero)\n{\n}\n\nConstantPointerNull::ConstantPointerNull(Type *type)\n    : Constant(type, ValueKind::ConstantPointerNull)\n{\n}\n\nConstantDataArray::ConstantDataArray(Type *type, Vector<Value *> elements_)\n    : Constant(type, ValueKind::ConstantDataArray)\n    , elements(std::move(elements_))\n{\n}\n\nunsigned ConstantDataArray::getNumElements() const\n{\n\treturn elements.size();\n}\n\nConstant *ConstantDataArray::getElementAsConstant(unsigned index) const\n{\n\treturn cast<Constant>(elements[index]);\n}\n\nConstantDataVector::ConstantDataVector(Type *type, Vector<Value *> elements_)\n\t: Constant(type, ValueKind::ConstantDataVector)\n\t, elements(std::move(elements_))\n{\n}\n\nunsigned ConstantDataVector::getNumElements() const\n{\n\treturn elements.size();\n}\n\nConstant *ConstantDataVector::getElementAsConstant(unsigned index) const\n{\n\treturn cast<Constant>(elements[index]);\n}\n\nConstantAggregate::ConstantAggregate(Type *type, Vector<Value *> elements_)\n\t: Constant(type, ValueKind::ConstantAggregate)\n\t, elements(std::move(elements_))\n{\n}\n\nunsigned ConstantAggregate::getNumOperands() const\n{\n\treturn elements.size();\n}\n\nConstant *ConstantAggregate::getOperand(unsigned index) const\n{\n\treturn cast<Constant>(elements[index]);\n}\n\nConstantExpr::ConstantExpr(unsigned opcode_, Type *type, Vector<Value *> elements_)\n\t: Constant(type, ValueKind::ConstantExpr)\n\t, opcode(opcode_)\n\t, elements(std::move(elements_))\n{\n}\n\nunsigned ConstantExpr::getOpcode() const\n{\n\treturn opcode;\n}\n\nConstant *ConstantExpr::getOperand(unsigned int N) const\n{\n\treturn cast<Constant>(elements[N]);\n}\n\nunsigned ConstantExpr::getNumOperands() const\n{\n\treturn unsigned(elements.size());\n}\n\nGlobalVariable::GlobalVariable(Type *type, LinkageTypes linkage_, bool is_const_)\n\t: Constant(type, ValueKind::Global)\n\t, linkage(linkage_)\n\t, is_const(is_const_)\n{\n}\n\nGlobalVariable::LinkageTypes GlobalVariable::getLinkage() const\n{\n\treturn linkage;\n}\n\nbool GlobalVariable::hasInitializer() const\n{\n\treturn initializer != nullptr;\n}\n\nConstant *GlobalVariable::getInitializer() const\n{\n\treturn initializer;\n}\n\nvoid GlobalVariable::set_initializer(Constant *value)\n{\n\tinitializer = value;\n}\n\nbool GlobalVariable::isConstant() const\n{\n\treturn is_const;\n}\n} // namespace LLVMBC\n"
  },
  {
    "path": "bc/value.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"data_structures.hpp\"\n#include <stdint.h>\n\nnamespace LLVMBC\n{\nclass Type;\n\nenum class ValueKind\n{\n\tArgument,\n\tFunction,\n\tInstructionBase,\n\tConstantBase,\n\tConstantInt,\n\tConstantFP,\n\tConstantAggregateZero,\n\tConstantPointerNull,\n\tConstantAggregate,\n\tConstantDataArray,\n\tConstantDataVector,\n\tConstantExpr,\n\tUndef,\n\tUnaryOperator,\n\tBinaryOperator,\n\tCall,\n\tCompareBase,\n\tFCmp,\n\tICmp,\n\tBasicBlock,\n\tPHI,\n\tCast,\n\tSelect,\n\tExtractValue,\n\tAlloca,\n\tGetElementPtr,\n\tLoad,\n\tStore,\n\tAtomicRMW,\n\tAtomicCmpXchg,\n\tReturn,\n\tUnreachable,\n\tBranch,\n\tSwitch,\n\tProxy,\n\tGlobal,\n\tShuffleVector,\n\tExtractElement,\n\tInsertElement,\n\tCompositeConstruct\n};\n\n#define LLVMBC_DEFAULT_VALUE_KIND_IMPL                \\\n\tstatic bool is_base_of_value_kind(ValueKind kind) \\\n\t{                                                 \\\n\t\treturn get_value_kind() == kind;              \\\n\t}\n\nclass Value\n{\npublic:\n\tValue(Type *type, ValueKind kind);\n\tType *getType() const;\n\n\tValueKind get_value_kind() const;\n\tvoid set_tween_id(uint64_t id);\n\tuint64_t get_tween_id() const;\n\nprotected:\n\tType *type;\n\tValueKind kind;\n\tuint64_t tween_id = 0;\n};\n\nclass Argument : public Value\n{\npublic:\n\tArgument(Type *type, unsigned argument_number);\n\tunsigned getArgNo() const;\n\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Argument;\n\t}\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tunsigned argument_number;\n};\n\nclass APInt\n{\npublic:\n\tAPInt() = default;\n\tAPInt(Type *type, uint64_t value);\n\tuint64_t getZExtValue() const;\n\tint64_t getSExtValue() const;\n\n\t// LLVMBC specific hack to make minprecision with signed ints work.\n\t// We need a sign-extended value which fortunately the DXIL emits,\n\t// but LLVM itself will mask off the bits for you.\n\tuint64_t get_raw_value() const;\n\nprivate:\n\tType *type = nullptr;\n\tuint64_t value = 0;\n};\n\nclass APFloat\n{\npublic:\n\tAPFloat() = default;\n\tAPFloat(Type *type, uint64_t value);\n\n\tfloat convertToFloat() const;\n\tdouble convertToDouble() const;\n\n\tAPInt bitcastToAPInt() const;\n\nprivate:\n\tType *type = nullptr;\n\tuint64_t value = 0;\n};\n\nclass Constant : public Value\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantBase;\n\t}\n\tConstant(Type *type, ValueKind kind);\n\n\tvoid set_integer(const APInt &apint);\n\tvoid set_float(const APFloat &apfloat);\n\tconst APFloat &getValueAPF() const;\n\tconst APInt &getUniqueInteger() const;\n\n\tstatic bool is_base_of_value_kind(ValueKind kind);\n\nprivate:\n\tAPInt apint;\n\tAPFloat apfloat;\n};\n\nclass ConstantInt : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantInt;\n\t}\n\tstatic ConstantInt *get(Type *type, uint64_t value);\n\tConstantInt(Type *type, uint64_t value);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass ConstantFP : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantFP;\n\t}\n\tstatic ConstantFP *get(Type *type, uint64_t bits);\n\tConstantFP(Type *type, uint64_t bits);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass ConstantAggregateZero : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantAggregateZero;\n\t}\n\texplicit ConstantAggregateZero(Type *type);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass ConstantPointerNull : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantPointerNull;\n\t}\n\n\texplicit ConstantPointerNull(Type *type);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass ConstantDataArray : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantDataArray;\n\t}\n\tConstantDataArray(Type *type, Vector<Value *> elements);\n\n\tunsigned getNumElements() const;\n\tConstant *getElementAsConstant(unsigned index) const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tVector<Value *> elements;\n};\n\nclass ConstantDataVector : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantDataVector;\n\t}\n\tConstantDataVector(Type *type, Vector<Value *> elements);\n\n\tunsigned getNumElements() const;\n\tConstant *getElementAsConstant(unsigned index) const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tVector<Value *> elements;\n};\n\nclass ConstantAggregate : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantAggregate;\n\t}\n\tConstantAggregate(Type *type, Vector<Value *> elements);\n\n\tunsigned getNumOperands() const;\n\tConstant *getOperand(unsigned index) const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tVector<Value *> elements;\n};\n\nclass ConstantExpr : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::ConstantExpr;\n\t}\n\tConstantExpr(unsigned opcode, Type *type, Vector<Value *> elements);\n\n\tunsigned getOpcode() const;\n\tunsigned getNumOperands() const;\n\tConstant *getOperand(unsigned N) const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tunsigned opcode;\n\tVector<Value *> elements;\n};\n\nclass UndefValue : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Undef;\n\t}\n\texplicit UndefValue(Type *type);\n\tstatic UndefValue *get(Type *type);\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n};\n\nclass GlobalVariable : public Constant\n{\npublic:\n\tstatic constexpr ValueKind get_value_kind()\n\t{\n\t\treturn ValueKind::Global;\n\t}\n\n\tenum LinkageTypes\n\t{\n\t\tExternalLinkage,\n\t\tInternalLinkage,\n\t\tAppendingLinkage\n\t};\n\n\texplicit GlobalVariable(Type *type, LinkageTypes linkage, bool is_const);\n\tvoid set_initializer(Constant *value);\n\tConstant *getInitializer() const;\n\tbool hasInitializer() const;\n\tbool isConstant() const;\n\tLinkageTypes getLinkage() const;\n\n\tLLVMBC_DEFAULT_VALUE_KIND_IMPL\n\nprivate:\n\tConstant *initializer = nullptr;\n\tLinkageTypes linkage;\n\tbool is_const;\n};\n} // namespace LLVMBC\n"
  },
  {
    "path": "build_dxc.sh",
    "content": "#!/bin/bash\n\nPROFILE=Release\n\nif [ ! -z $1 ]; then\n\tPROFILE=$1\nfi\n\nif [ ! -z $2 ]; then\n\tNPROC=\"--parallel $2\"\nfi\n\necho \"Building DXC.\"\nmkdir -p external/dxc-build\ncd external/dxc-build\n# CLANG_FORMAT_EXE=OFF avoids a broken build where it expects clang-format to produce exact results for some dumb reason.\ncmake ../DirectXShaderCompiler -DCMAKE_BUILD_TYPE=$PROFILE -C ../DirectXShaderCompiler/cmake/caches/PredefinedParams.cmake -G Ninja -DSPIRV_WERROR=OFF -DCLANG_FORMAT_EXE=OFF -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++\ncmake --build . --config $PROFILE ${NPROC}\n\n"
  },
  {
    "path": "cfg_structurizer.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"cfg_structurizer.hpp\"\n#include \"SpvBuilder.h\"\n#include \"logging.hpp\"\n#include \"node.hpp\"\n#include \"node_pool.hpp\"\n#include \"spirv_module.hpp\"\n#include <algorithm>\n#include <assert.h>\n\nnamespace dxil_spv\n{\nCFGStructurizer::CFGStructurizer(CFGNode *entry, CFGNodePool &pool_, SPIRVModule &module_)\n    : entry_block(entry)\n    , pool(pool_)\n    , module(module_)\n{\n\texit_block = pool.create_node();\n\texit_block->name = \"EXIT\";\n}\n\nvoid CFGStructurizer::log_cfg_graphviz(const char *path) const\n{\n\tFILE *file = fopen(path, \"w\");\n\tif (!file)\n\t{\n\t\tLOGE(\"Failed to open graphviz dump path: %s\\n\", path);\n\t\treturn;\n\t}\n\n\tUnorderedMap<const CFGNode *, uint32_t> node_to_id;\n\tuint32_t accum_id = 0;\n\n\tconst auto get_node_id = [&](const CFGNode *node) -> uint32_t {\n\t\tauto itr = node_to_id.find(node);\n\t\tif (itr == node_to_id.end())\n\t\t{\n\t\t\tconst char *shape = nullptr;\n\t\t\tif (node->merge == MergeType::Loop)\n\t\t\t\tshape = \"circle\";\n\t\t\telse if (node->merge == MergeType::Selection)\n\t\t\t\tshape = \"triangle\";\n\t\t\telse\n\t\t\t\tshape = \"box\";\n\n\t\t\tnode_to_id[node] = ++accum_id;\n\t\t\tfprintf(file, \"%u [label=\\\"%s\\\", shape=\\\"%s\\\"];\\n\", accum_id, node->name.c_str(), shape);\n\t\t\treturn accum_id;\n\t\t}\n\t\telse\n\t\t\treturn itr->second;\n\t};\n\n\tfprintf(file, \"digraph {\\n\");\n\tfor (auto index = forward_post_visit_order.size(); index; index--)\n\t{\n\t\tauto *node = forward_post_visit_order[index - 1];\n\t\tswitch (node->ir.terminator.type)\n\t\t{\n\t\tcase Terminator::Type::Branch:\n\t\t\tfprintf(file, \"%u -> %u;\\n\", get_node_id(node), get_node_id(node->ir.terminator.direct_block));\n\t\t\tbreak;\n\n\t\tcase Terminator::Type::Condition:\n\t\t\tfprintf(file, \"%u -> %u;\\n\", get_node_id(node), get_node_id(node->ir.terminator.true_block));\n\t\t\tfprintf(file, \"%u -> %u;\\n\", get_node_id(node), get_node_id(node->ir.terminator.false_block));\n\t\t\tbreak;\n\n\t\tcase Terminator::Type::Switch:\n\t\t\tfor (auto &c : node->ir.terminator.cases)\n\t\t\t\tfprintf(file, \"%u -> %u;\\n\", get_node_id(node), get_node_id(c.node));\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tif (node->merge == MergeType::Loop)\n\t\t{\n\t\t\tif (node->pred_back_edge)\n\t\t\t\tfprintf(file, \"%u -> %u [style=\\\"dotted\\\"];\\n\", get_node_id(node), get_node_id(node->pred_back_edge));\n\t\t\tif (node->loop_merge_block)\n\t\t\t\tfprintf(file, \"%u -> %u [style=\\\"dashed\\\"];\\n\", get_node_id(node), get_node_id(node->loop_merge_block));\n\t\t}\n\t\telse if (node->merge == MergeType::Selection)\n\t\t{\n\t\t\tif (node->selection_merge_block)\n\t\t\t\tfprintf(file, \"%u -> %u [style=\\\"dashed\\\"];\\n\", get_node_id(node), get_node_id(node->selection_merge_block));\n\t\t}\n\t}\n\n\tfprintf(file, \"}\\n\");\n\tfclose(file);\n}\n\nvoid CFGStructurizer::log_cfg(const char *tag) const\n{\n\tLOGI(\"\\n======== %s =========\\n\", tag);\n\tfor (auto index = forward_post_visit_order.size(); index; index--)\n\t{\n\t\tauto *node = forward_post_visit_order[index - 1];\n\n\t\tLOGI(\"%s:\\n\", node->name.c_str());\n\t\tswitch (node->ir.terminator.type)\n\t\t{\n\t\tcase Terminator::Type::Branch:\n\t\t\tLOGI(\"  Branch -> %s\\n\", node->ir.terminator.direct_block->name.c_str());\n\t\t\tbreak;\n\n\t\tcase Terminator::Type::Condition:\n\t\t\tLOGI(\"  Cond -> %s | %s\\n\", node->ir.terminator.true_block->name.c_str(),\n\t\t\t     node->ir.terminator.false_block->name.c_str());\n\t\t\tbreak;\n\n\t\tcase Terminator::Type::Return:\n\t\t\tLOGI(\"  Return\\n\");\n\t\t\tbreak;\n\n\t\tcase Terminator::Type::Unreachable:\n\t\t\tLOGI(\"  Unreachable\\n\");\n\t\t\tbreak;\n\n\t\tcase Terminator::Type::Switch:\n\t\t\tLOGI(\"  Switch\\n\");\n\t\t\tfor (auto &c : node->ir.terminator.cases)\n\t\t\t{\n\t\t\t\tif (c.is_default)\n\t\t\t\t\tLOGI(\"    Default -> %s\\n\", c.node->name.c_str());\n\t\t\t\telse\n\t\t\t\t\tLOGI(\"    Case %u -> %s\\n\", c.value, c.node->name.c_str());\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Terminator::Type::Kill:\n\t\t\tLOGI(\"  Kill\\n\");\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch (node->merge)\n\t\t{\n\t\tcase MergeType::Selection:\n\t\t\tLOGI(\"  SelectionMerge -> %s\\n\",\n\t\t\t     node->selection_merge_block ? node->selection_merge_block->name.c_str() : \"N/A\");\n\t\t\tbreak;\n\n\t\tcase MergeType::Loop:\n\t\t\tLOGI(\"  LoopMerge -> %s\\n\", node->loop_merge_block ? node->loop_merge_block->name.c_str() : \"N/A\");\n\t\t\tLOGI(\"    Continue -> %s\\n\", node->pred_back_edge ? node->pred_back_edge->name.c_str() : \"N/A\");\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tLOGI(\"\\n\");\n\t}\n\tLOGI(\"\\n=====================\\n\");\n}\n\n//#define PHI_DEBUG\n#ifdef PHI_DEBUG\nstatic void validate_phi(const PHI &phi)\n{\n\tauto incomings = phi.incoming;\n\tstd::sort(incomings.begin(), incomings.end(), [](const IncomingValue &a, const IncomingValue &b) {\n\t\treturn a.block < b.block;\n\t});\n\tauto itr = std::unique(incomings.begin(), incomings.end(), [](const IncomingValue &a, const IncomingValue &b) {\n\t\treturn a.block == b.block;\n\t});\n\tif (itr != incomings.end())\n\t\tabort();\n}\n\nstatic void validate_phi(const Vector<PHI> &phis)\n{\n\tfor (auto &phi : phis)\n\t\tvalidate_phi(phi);\n}\n#else\n#define validate_phi(phi) ((void)0)\n#endif\n\nvoid CFGStructurizer::eliminate_node_link_preds_to_succ(CFGNode *node)\n{\n\tassert(node->succ.size() == 1 || node->succ.size() == 2);\n\n#ifdef PHI_DEBUG\n\tfor (auto *succ : node->succ)\n\t\tvalidate_phi(succ->ir.phi);\n#endif\n\n\tVector<CFGNode *> break_nodes;\n\tauto pred_copy = node->pred;\n\tauto succ_copy = node->succ;\n\n\tfor (auto *pred : pred_copy)\n\t{\n\t\tauto *break_node = pool.create_node();\n\t\tbreak_node->name = node->name + \".break.\" + pred->name;\n\n\t\tbreak_node->ir.terminator = node->ir.terminator;\n\t\tfor (auto *succ : succ_copy)\n\t\t\tbreak_node->add_branch(succ);\n\n\t\tbreak_node->immediate_post_dominator = node->immediate_post_dominator;\n\t\tbreak_node->immediate_dominator = pred;\n\t\tpred->retarget_branch(node, break_node);\n\n\t\tbreak_nodes.push_back(break_node);\n\n\t\tfor (auto &phi : node->ir.phi)\n\t\t{\n\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t{\n\t\t\t\tif (incoming.block == pred)\n\t\t\t\t{\n\t\t\t\t\tincoming.block = break_node;\n\t\t\t\t\t// We have no opcodes in this block, but we may depend on a PHI variable to do conditional branch.\n\t\t\t\t\tif (phi.id == break_node->ir.terminator.conditional_id)\n\t\t\t\t\t\tbreak_node->ir.terminator.conditional_id = incoming.id;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tassert(node->pred.empty());\n\n\tfor (auto *succ : node->succ)\n\t{\n\t\tfor (auto &phi : succ->ir.phi)\n\t\t{\n\t\t\t// Find incoming ID from the block we're splitting up.\n\t\t\tauto incoming_itr = std::find_if(phi.incoming.begin(), phi.incoming.end(),\n\t\t\t                                 [&](const IncomingValue &incoming) { return incoming.block == node; });\n\n\t\t\tassert(incoming_itr != phi.incoming.end());\n\t\t\tspv::Id incoming_from_node = incoming_itr->id;\n\t\t\tphi.incoming.erase(incoming_itr);\n\n\t\t\t// Try to see if the ID is a PHI that was generated by this block.\n\t\t\tauto outgoing_itr = std::find_if(node->ir.phi.begin(), node->ir.phi.end(),\n\t\t\t                                 [&](const PHI &phi) { return phi.id == incoming_from_node; });\n\n\t\t\tif (outgoing_itr != node->ir.phi.end())\n\t\t\t{\n\t\t\t\t// If it was then we need to split up the PHI node. The break block will serve as a proxy\n\t\t\t\t// incoming block instead.\n\t\t\t\tphi.incoming.insert(phi.incoming.end(), outgoing_itr->incoming.begin(), outgoing_itr->incoming.end());\n\t\t\t\tvalidate_phi(succ->ir.phi);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// A plain value is passed down to succ, most likely a constant which lives at global scope.\n\t\t\t\t// We know this block does not generate this ID, so it must be either a value generated at global scope\n\t\t\t\t// (constant), or a value created by a block which dominates this node,\n\t\t\t\t// which also means it dominates all preds to this node.\n\t\t\t\tfor (auto *break_pred : break_nodes)\n\t\t\t\t\tphi.incoming.push_back({ break_pred, incoming_from_node });\n\t\t\t\tvalidate_phi(succ->ir.phi);\n\t\t\t}\n\t\t}\n\n\t\t// Remove any lingering pred, since node is now unreachable, and if we do more transforms without\n\t\t// recomputing CFG, we'll add impossible PHI inputs.\n\t\tauto erase_itr = std::find(succ->pred.begin(), succ->pred.end(), node);\n\t\tif (erase_itr != succ->pred.end())\n\t\t\tsucc->pred.erase(erase_itr);\n\t}\n\n\tnode->ir.phi.clear();\n}\n\nbool CFGStructurizer::cleanup_breaking_return_constructs()\n{\n\tunsigned post_dominating_returns = 0;\n\tCFGNode *split_candidate = nullptr;\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->ir.terminator.type != Terminator::Type::Return)\n\t\t\tcontinue;\n\n\t\t// If this block is only serving to return, it's meaningless to merge.\n\t\t// It will only complicate the CFG.\n\t\tif (node->ir.operations.empty() && node->num_forward_preds() > 1 && !node->post_dominates_any_work())\n\t\t{\n\t\t\tsplit_candidate = node;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// If we're actually post-dominating other blocks, the split candidate is relevant.\n\t\t\tfor (auto *pred : node->pred)\n\t\t\t{\n\t\t\t\tif (node->post_dominates(pred))\n\t\t\t\t{\n\t\t\t\t\tpost_dominating_returns++;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Only bother if we have more than one return and at least another return that is actually post-dominating\n\t// work. Avoids potential false positives.\n\tif (!post_dominating_returns)\n\t\treturn false;\n\n\tif (split_candidate)\n\t{\n\t\tauto preds = split_candidate->pred;\n\n\t\tfor (auto *pred : preds)\n\t\t{\n\t\t\tauto *dummy_return = pool.create_node();\n\t\t\tdummy_return->name = split_candidate->name + \".dup\";\n\t\t\tdummy_return->immediate_dominator = split_candidate->immediate_dominator;\n\t\t\tdummy_return->immediate_post_dominator = exit_block;\n\t\t\tdummy_return->forward_post_visit_order = split_candidate->forward_post_visit_order;\n\t\t\tdummy_return->backward_post_visit_order = split_candidate->backward_post_visit_order;\n\t\t\tdummy_return->ir.terminator.type = Terminator::Type::Return;\n\t\t\tpred->retarget_branch(split_candidate, dummy_return);\n\t\t}\n\n\t\t// Iterate until we are done.\n\t\trecompute_cfg();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool CFGStructurizer::block_is_breaking_phi_construct(const CFGNode *node) const\n{\n\t// Only bother with blocks which don't do anything useful work.\n\t// The only opcodes they should have are PHI nodes and a (conditional) branch.\n\tif (!node->ir.operations.empty())\n\t\treturn false;\n\tif (node->pred.size() <= 1)\n\t\treturn false;\n\n\t// Don't bother with anything that could be considered load bearing.\n\tif (node->post_dominates_perfect_structured_construct())\n\t\treturn false;\n\n\t// Anything related to loop/continue blocks, we don't bother with.\n\tif (node->succ_back_edge || node->pred_back_edge)\n\t\treturn false;\n\n\tif (node->succ.size() == 1)\n\t{\n\t\tif (node->ir.terminator.type != Terminator::Type::Branch)\n\t\t\treturn false;\n\t}\n\telse if (node->succ.size() == 2)\n\t{\n\t\tif (node->ir.terminator.type != Terminator::Type::Condition)\n\t\t\treturn false;\n\t}\n\telse\n\t\treturn false;\n\n\tfor (auto *succ : node->succ)\n\t{\n\t\tif (node->dominates(succ))\n\t\t\treturn false;\n\n\t\t// Checks if either the merge block or successor is sensitive to PHI somehow.\n\t\tif (!ladder_chain_has_phi_dependencies(succ, node))\n\t\t\treturn false;\n\t}\n\n\t// This is a merge block candidate for a loop, don't split.\n\t// It will only confuse things where we'll need to re-merge the split blocks anyways.\n\tfor (auto *pred : node->pred)\n\t\tif (pred->succ_back_edge)\n\t\t\treturn false;\n\n\t// A more complicated case where we want the block to remain as a ladder block.\n\tauto *loop_header = get_innermost_loop_header_for(node);\n\tif (loop_header && loop_header->pred_back_edge &&\n\t    loop_header->dominates(node) && loop_header->pred_back_edge->succ.empty())\n\t{\n\t\tbool merge_is_outside_loop = !query_reachability(*node, *loop_header->pred_back_edge);\n\t\tif (merge_is_outside_loop)\n\t\t{\n\t\t\tauto *header_pdom = loop_header->pred_back_edge->immediate_post_dominator;\n\n\t\t\t// We only want to avoid the split when this is a meaningful ladder.\n\t\t\t// If the paths all end up in the same merge anyway, it's safer to split.\n\t\t\tfor (auto *df : node->dominance_frontier)\n\t\t\t\tif (df == header_pdom)\n\t\t\t\t\treturn true;\n\n\t\t\tfor (auto *pdf : node->post_dominance_frontier)\n\t\t\t{\n\t\t\t\t// We can't reach, but the PDF can. We're confident we're a loop exit.\n\t\t\t\tif (query_reachability(*pdf, *loop_header->pred_back_edge))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n}\n\nvoid CFGStructurizer::cleanup_breaking_phi_constructs()\n{\n\tbool did_work = false;\n\n\t// There might be cases where we have a common break block from different scopes which only serves to PHI together some values\n\t// before actually breaking, and passing that PHI node on to the actual break block.\n\t// This causes problems because this looks very much like a merge, but it is actually not and forces validation errors.\n\t// Another case is where the succ block takes PHI nodes from the breaking block only,\n\t// which is relevant if only constants are somehow used in the PHI construct.\n\n\tfor (size_t i = forward_post_visit_order.size(); i; i--)\n\t{\n\t\tauto *node = forward_post_visit_order[i - 1];\n\n\t\tif (block_is_breaking_phi_construct(node))\n\t\t{\n\t\t\teliminate_node_link_preds_to_succ(node);\n\t\t\tdid_work = true;\n\t\t}\n\t}\n\n\tif (did_work)\n\t\trecompute_cfg();\n}\n\nstatic void scrub_rov_begin_lock(CFGNode *node, bool preserve_first_begin)\n{\n\tauto begin_itr = node->ir.operations.begin();\n\tif (preserve_first_begin)\n\t{\n\t\tbegin_itr = std::find_if(node->ir.operations.begin(), node->ir.operations.end(),\n\t\t                         [](const Operation *op) { return op->op == spv::OpBeginInvocationInterlockEXT; });\n\t\tassert(begin_itr != node->ir.operations.end());\n\t\t++begin_itr;\n\t}\n\n\tauto itr = std::remove_if(begin_itr, node->ir.operations.end(),\n\t                          [](const Operation *op) { return op->op == spv::OpBeginInvocationInterlockEXT; });\n\tnode->ir.operations.erase(itr, node->ir.operations.end());\n}\n\nstatic void scrub_rov_end_lock(CFGNode *node, bool preserve_last_end)\n{\n\tauto end_itr = node->ir.operations.end();\n\n\tif (preserve_last_end)\n\t{\n\t\tfor (size_t i = node->ir.operations.size(); i; i--)\n\t\t{\n\t\t\tsize_t index = i - 1;\n\t\t\tauto &op = node->ir.operations[index];\n\t\t\tif (op->op == spv::OpEndInvocationInterlockEXT)\n\t\t\t{\n\t\t\t\tend_itr = node->ir.operations.begin() + index;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tauto itr = std::remove_if(node->ir.operations.begin(), end_itr,\n\t                          [](const Operation *op) { return op->op == spv::OpEndInvocationInterlockEXT; });\n\tnode->ir.operations.erase(itr, end_itr);\n}\n\nstatic void scrub_rov_lock_regions(CFGNode *node, bool preserve_first_begin, bool preserve_last_end)\n{\n\tscrub_rov_begin_lock(node, preserve_first_begin);\n\tscrub_rov_end_lock(node, preserve_last_end);\n}\n\nbool CFGStructurizer::find_single_entry_exit_lock_region(\n\tCFGNode *&idom, CFGNode *&pdom, const Vector<CFGNode *> &rov_blocks)\n{\n\t// If the lock region has multiple instances, i.e. a loop, give up right away, unless the construct is simple\n\t// and we can trivially do:\n\t// begin(); for(;;) {} end();\n\t// For this to work, all ROV blocks must be contained by one loop. The must be a trivial input branch to the loop\n\t// header, and trivial exit out of the loop, i.e. one loop exit which is covered by the continue block.\n\tauto *outermost_loop_header = idom ? const_cast<CFGNode *>(get_innermost_loop_header_for(entry_block, idom)) : nullptr;\n\n\twhile (outermost_loop_header && outermost_loop_header != entry_block)\n\t{\n\t\tauto *innermost_loop_header = const_cast<CFGNode *>(\n\t\t    get_innermost_loop_header_for(entry_block, outermost_loop_header->immediate_dominator));\n\n\t\t// Stop right before we hit the entry block.\n\t\tif (innermost_loop_header && innermost_loop_header != entry_block)\n\t\t\toutermost_loop_header = innermost_loop_header;\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tif (idom && outermost_loop_header != entry_block)\n\t{\n\t\t// First, all ROV blocks must be inside the loop construct.\n\t\tfor (auto *rov : rov_blocks)\n\t\t{\n\t\t\tif (!outermost_loop_header->dominates(rov) ||\n\t\t\t    !query_reachability(*rov, *outermost_loop_header->pred_back_edge))\n\t\t\t{\n\t\t\t\t// Cannot promote directly. Can only promote if idom is entered once.\n\t\t\t\treturn execution_path_is_single_entry_and_dominates_exit(idom, pdom);\n\t\t\t}\n\t\t}\n\n\t\tidom = outermost_loop_header;\n\n\t\tauto analysis = analyze_loop(outermost_loop_header);\n\t\tauto merge = analyze_loop_merge(outermost_loop_header, analysis);\n\t\tif (!merge.merge || !merge.dominated_merge || merge.infinite_continue_ladder ||\n\t\t    merge.merge != merge.dominated_merge)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tpdom = merge.merge;\n\t\t}\n\n\t\t// We must insert the lock before entering loop.\n\t\t// This only works if we have exactly one pred and that pred directly branches to us.\n\t\tif (idom->pred.size() == 1 && idom->pred.front()->ir.terminator.type == Terminator::Type::Branch)\n\t\t\tidom = idom->pred.front();\n\t\telse\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool CFGStructurizer::execution_path_is_single_entry_and_dominates_exit(CFGNode *idom, CFGNode *pdom)\n{\n\tif (!idom->dominates_all_reachable_exits())\n\t\treturn false;\n\n\tpdom = CFGNode::find_common_post_dominator(pdom, idom);\n\n\tbool internal_early_return = !pdom || pdom->immediate_post_dominator == pdom;\n\tif (internal_early_return)\n\t\treturn false;\n\n\t// If we're dominating all reachable exits despite being inside a loop, it's okay to use ROV as-is.\n\t// We have proven that this path will only be executed once per thread.\n\t// We will have to make sure that this exit path doesn't loop itself.\n\t// Just prove this by making sure there are no back-edges on the path from idom to pdom.\n\t// If there are back-edges that loop back to an earlier header, that is covered by dominates_all_reachable_exits.\n\n\tif (idom->pred_back_edge || !idom->dominates(pdom))\n\t\treturn false;\n\n\twhile (pdom != idom)\n\t{\n\t\tif (pdom->pred_back_edge)\n\t\t\treturn false;\n\t\tpdom = pdom->immediate_dominator;\n\t}\n\n\treturn true;\n}\n\nvoid CFGStructurizer::flatten_subgroup_shuffles()\n{\n\trecompute_cfg();\n\n\t// Look for cases where shuffles happen inside small branches.\n\t// This comes up due to HLSL's short-cicruit rules.\n\tfor (auto *n : forward_post_visit_order)\n\t{\n\t\t// Only care about blocks which don't dominate anything.\n\t\tif (n->succ.size() != 1 || n->dominance_frontier.size() != 1 || n->dominance_frontier.front() != n->succ.front())\n\t\t\tcontinue;\n\t\tif (n->pred.size() != 1)\n\t\t\tcontinue;\n\t\tif (!n->pred.front()->dominates(n->succ.front()))\n\t\t\tcontinue;\n\t\tif (n->pred.front()->succ.size() != 2)\n\t\t\tcontinue;\n\n\t\t// There's a limit to how much we want to peephole.\n\t\tif (n->ir.operations.size() > 4)\n\t\t\tcontinue;\n\n\t\t// We don't want to hoist if both sides of the branch have meaningful work associated with them.\n\t\tauto *succ = n->succ.front();\n\t\tauto *pred = n->pred.front();\n\t\tauto *sibling0 = pred->succ[0];\n\t\tauto *sibling1 = pred->succ[1];\n\n\t\tif (sibling0 != succ && sibling0 != n && !sibling0->ir.operations.empty())\n\t\t\tcontinue;\n\t\tif (sibling1 != succ && sibling1 != n && !sibling1->ir.operations.empty())\n\t\t\tcontinue;\n\n\t\t// Now we've detected:\n\t\t// if (blah) { a = shuffle(); } phi(a);\n\n\t\tbool has_dubious_shuffle = false;\n\n\t\tfor (auto *op : n->ir.operations)\n\t\t{\n\t\t\tif (op->op == spv::OpGroupNonUniformShuffle || op->op == spv::OpGroupNonUniformBroadcast)\n\t\t\t{\n\t\t\t\tfor (auto &phi : n->succ.front()->ir.phi)\n\t\t\t\t{\n\t\t\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (incoming.id == op->id)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thas_dubious_shuffle = true;\n\t\t\t\t\t\t\tgoto out;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tout:\n\n\t\tif (has_dubious_shuffle)\n\t\t{\n\t\t\t// Now the question is if it's safe to do this. There can be nothing control dependent (except for shuffles).\n\t\t\tfor (auto *op : n->ir.operations)\n\t\t\t{\n\t\t\t\tif (op->op == spv::OpGroupNonUniformShuffle ||\n\t\t\t\t    op->op == spv::OpGroupNonUniformBroadcast)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (op->op == spv::OpLoad)\n\t\t\t\t{\n\t\t\t\t\t// Only allow loads if it's loading from plain OpVariables.\n\t\t\t\t\t// Hoisting a buffer read is not acceptable.\n\t\t\t\t\tif (!module.get_builder().hasDecoration(op->arguments[0], spv::DecorationBuiltIn))\n\t\t\t\t\t{\n\t\t\t\t\t\thas_dubious_shuffle = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (SPIRVModule::opcode_is_control_dependent(op->op) || op->id == 0 ||\n\t\t\t\t    SPIRVModule::opcode_has_side_effect_and_result(op->op))\n\t\t\t\t{\n\t\t\t\t\thas_dubious_shuffle = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (has_dubious_shuffle)\n\t\t{\n\t\t\tfor (auto *op : n->ir.operations)\n\t\t\t\tn->pred.front()->ir.operations.push_back(op);\n\t\t\tn->ir.operations.clear();\n\t\t}\n\t}\n}\n\nvoid CFGStructurizer::rewrite_auto_group_shared_barrier()\n{\n\trecompute_cfg();\n\n\tenum class Kind { None, Load, Store, Atomic };\n\n\tstruct Block\n\t{\n\t\tCFGNode *node;\n\t\tconst CFGNode *innermost_loop;\n\t\tKind pre_kind;\n\t\tKind post_kind;\n\t};\n\n\t// In linear traversal order, find all BBs that use group shared.\n\tVector<Block> shared_blocks;\n\n\tfor (size_t i = forward_post_visit_order.size(); i; i--)\n\t{\n\t\tauto *node = forward_post_visit_order[i - 1];\n\t\tfor (auto *op : node->ir.operations)\n\t\t{\n\t\t\tif ((op->flags & Operation::AutoGroupSharedBarrier) != 0)\n\t\t\t{\n\t\t\t\tshared_blocks.push_back({ node, get_innermost_loop_header_for(node), Kind::None, Kind::None });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Deal with intra-BB hazards.\n\tfor (auto &block : shared_blocks)\n\t{\n\t\tKind pending = Kind::None;\n\n\t\t// If we're the first BB to access shared, no need for a post block.\n\t\t// Similar for the last block.\n\t\t// Loops can complicate this analysis, but ... eh.\n\t\t// This is a workaround, not required by spec or anything.\n\n\t\tfor (auto *op : block.node->ir.operations)\n\t\t{\n\t\t\tif ((op->flags & Operation::AutoGroupSharedBarrier) != 0)\n\t\t\t{\n\t\t\t\tif (op->op == spv::OpLoad || op->op == spv::PseudoOpMaskedLoad)\n\t\t\t\t{\n\t\t\t\t\tif (pending != Kind::Load && pending != Kind::None)\n\t\t\t\t\t\top->flags |= Operation::SubgroupSyncPre;\n\t\t\t\t\tpending = Kind::Load;\n\t\t\t\t}\n\t\t\t\telse if (op->op == spv::OpStore || op->op == spv::PseudoOpMaskedStore)\n\t\t\t\t{\n\t\t\t\t\tif (pending != Kind::Store && pending != Kind::None)\n\t\t\t\t\t\top->flags |= Operation::SubgroupSyncPre;\n\t\t\t\t\tpending = Kind::Store;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (pending != Kind::Atomic && pending != Kind::None)\n\t\t\t\t\t\top->flags |= Operation::SubgroupSyncPre;\n\t\t\t\t\tpending = Kind::Atomic;\n\t\t\t\t}\n\n\t\t\t\tif (block.pre_kind == Kind::None)\n\t\t\t\t\tblock.pre_kind = pending;\n\t\t\t}\n\t\t}\n\n\t\tblock.post_kind = pending;\n\t}\n\n\tfor (size_t i = 0; i < shared_blocks.size(); i++)\n\t{\n\t\tauto &first = shared_blocks[i];\n\n\t\tfor (size_t j = i + 1; j < shared_blocks.size(); j++)\n\t\t{\n\t\t\tauto &second = shared_blocks[j];\n\t\t\tif (!query_reachability(*first.node, *second.node))\n\t\t\t\tcontinue;\n\n\t\t\tif (first.post_kind != second.pre_kind)\n\t\t\t{\n\t\t\t\t// Find an intermediate block which:\n\t\t\t\t// - post dominates the first\n\t\t\t\t// - dominates the second\n\t\t\t\t// Has the maximal number of invocations.\n\t\t\t\t// The subgroup barrier should be run with as many threads as possible.\n\t\t\t\tif (second.node->post_dominates(first.node))\n\t\t\t\t\tsecond.node->ir.operations.front()->flags |= Operation::SubgroupSyncPre;\n\t\t\t\telse if (first.node->dominates(second.node))\n\t\t\t\t\tfirst.node->ir.operations.back()->flags |= Operation::SubgroupSyncPost;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Try to find some intermediate node. If we cannot find it, just yolo in a barrier\n\t\t\t\t\t// somewhere. This is just a workaround, so if it doesn't work 100%, it's not a big deal.\n\t\t\t\t\tauto *pdom = first.node->immediate_post_dominator;\n\t\t\t\t\twhile (pdom && query_reachability(*pdom, *second.node) && !pdom->dominates(second.node) &&\n\t\t\t\t\t       pdom->immediate_post_dominator && pdom->immediate_post_dominator != pdom)\n\t\t\t\t\t{\n\t\t\t\t\t\tpdom = pdom->immediate_post_dominator;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (pdom && pdom != second.node)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (pdom->ir.operations.empty())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto *nop = module.allocate_op(spv::OpNop);\n\t\t\t\t\t\t\tnop->flags |= Operation::SubgroupSyncPost;\n\t\t\t\t\t\t\tpdom->ir.operations.push_back(nop);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tpdom->ir.operations.back()->flags |= Operation::SubgroupSyncPost;\n\t\t\t\t\t}\n\t\t\t\t\telse if (pdom == second.node)\n\t\t\t\t\t{\n\t\t\t\t\t\tsecond.node->ir.operations.front()->flags |= Operation::SubgroupSyncPre;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// We've added appropriate barriers for this node now.\n\t\t\t\tsecond.pre_kind = Kind::None;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\t// Analyze re-entrant code. We may depend on memory coming from an earlier loop iteration.\n\t\tif (first.pre_kind != Kind::None && first.innermost_loop != entry_block && first.innermost_loop->pred_back_edge)\n\t\t{\n\t\t\tbool has_complex_dependency = false;\n\t\t\t// Other blocks within the loop may require a dependency.\n\t\t\tfor (size_t j = i + 1; j < shared_blocks.size() && !has_complex_dependency; j++)\n\t\t\t{\n\t\t\t\tif (query_reachability(*shared_blocks[j].node, *first.innermost_loop->pred_back_edge))\n\t\t\t\t{\n\t\t\t\t\tfirst.node->ir.operations.front()->flags |= Operation::SubgroupSyncPre;\n\t\t\t\t\thas_complex_dependency = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!has_complex_dependency && first.pre_kind != first.post_kind)\n\t\t\t{\n\t\t\t\t// Self-dependency within the BB.\n\t\t\t\tfirst.node->ir.operations.back()->flags |= Operation::SubgroupSyncPost;\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool CFGStructurizer::rewrite_rov_lock_region()\n{\n\trecompute_cfg();\n\n\t// First, find all BBs that use ROV.\n\tVector<CFGNode *> rov_blocks;\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tfor (auto &op : node->ir.operations)\n\t\t{\n\t\t\tif (op->op == spv::OpBeginInvocationInterlockEXT)\n\t\t\t{\n\t\t\t\trov_blocks.push_back(node);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If we declare ROVs but never actually use them ... *shrug*\n\tif (rov_blocks.empty())\n\t\treturn true;\n\n\t// Rules: OpBegin and OpEnd must be dynamically called exactly once.\n\t// To simplify, we want to only emit one begin and one end that covers the entire shader.\n\t// Usually ROV access is constrained to a single BB as a simple case.\n\t// Simple BB case fails with control flow. E.g. a loop or conditional. In this case we must widen the range\n\t// of the lock such that: end post-dominates begin. Begin post-dominates entry.\n\t// If we cannot make this work, flag as non-trivial and wrap the entire shader in a big lock.\n\n\tauto *idom = rov_blocks.front();\n\tfor (size_t i = 1; i < rov_blocks.size() && idom; i++)\n\t\tidom = CFGNode::find_common_dominator(idom, rov_blocks[i]);\n\n\t// Stretch scope as long as we don't post-dominate entry.\n\twhile (idom && idom != entry_block && !idom->post_dominates(entry_block))\n\t\tidom = idom->immediate_dominator;\n\n\tauto *pdom = find_common_post_dominator(rov_blocks);\n\n\tif (!pdom || !idom ||\n\t    !find_single_entry_exit_lock_region(idom, pdom, rov_blocks) ||\n\t    !idom->dominates(pdom))\n\t{\n\t\tidom = nullptr;\n\t\tpdom = nullptr;\n\t}\n\n\t// Stretch post-dominator if we need to.\n\tif (idom && pdom)\n\t\tpdom = CFGNode::find_common_post_dominator(pdom, idom);\n\n\tbool internal_early_return = !pdom || pdom->immediate_post_dominator == pdom;\n\n\t// Non trivial case.\n\tif (!idom || !pdom || internal_early_return)\n\t{\n\t\tfor (auto *node : rov_blocks)\n\t\t\tscrub_rov_lock_regions(node, false, false);\n\t\treturn false;\n\t}\n\n\tbool begin_block_has_lock = std::find(rov_blocks.begin(), rov_blocks.end(), idom) != rov_blocks.end();\n\tbool end_block_has_lock = std::find(rov_blocks.begin(), rov_blocks.end(), pdom) != rov_blocks.end();\n\n\tfor (auto *node : rov_blocks)\n\t\tscrub_rov_lock_regions(node, node == idom, node == pdom);\n\n\tif (!begin_block_has_lock)\n\t\tidom->ir.operations.push_back(module.allocate_op(spv::OpBeginInvocationInterlockEXT));\n\n\tif (!end_block_has_lock)\n\t\tpdom->ir.operations.insert(pdom->ir.operations.begin(), module.allocate_op(spv::OpEndInvocationInterlockEXT));\n\n\treturn true;\n}\n\nvoid CFGStructurizer::rewrite_multiple_back_edges()\n{\n\treset_traversal();\n\tvisit_for_back_edge_analysis(*entry_block);\n}\n\nvoid CFGStructurizer::sink_ssa_constructs()\n{\n\tsink_ssa_constructs_run(true);\n\tsink_ssa_constructs_run(false);\n}\n\nvoid CFGStructurizer::sink_ssa_constructs_run(bool dry_run)\n{\n\t// First, propagate sinkability state to any operation that uses a sinkable SSA.\n\t// If an SSA expression is used in a BB, but that use of the SSA can be sunk, we need to\n\t// sink everything as a group.\n\tVector<spv::Id> sinkable_ops;\n\n\tstruct RewriteState\n\t{\n\t\tCFGNode *consumed_block;\n\t\tOperation *op;\n\t};\n\tUnorderedMap<spv::Id, RewriteState> sinks;\n\n\tfor (auto *n : forward_post_visit_order)\n\t{\n\t\tsinkable_ops.clear();\n\n\t\tauto &ops = n->ir.operations;\n\t\tfor (auto *op : ops)\n\t\t{\n\t\t\tif ((op->flags & Operation::SinkableBit) != 0)\n\t\t\t{\n\t\t\t\tsinkable_ops.push_back(op->id);\n\t\t\t\tsinks[op->id] = { nullptr, op };\n\t\t\t}\n\t\t\telse if (op->id && !SPIRVModule::opcode_is_control_dependent(op->op) &&\n\t\t\t         !SPIRVModule::opcode_has_side_effect_and_result(op->op))\n\t\t\t{\n\t\t\t\t// We cannot sink any opcode which is control dependent, or has side effects.\n\t\t\t\tfor (uint32_t i = 0; i < op->num_arguments; i++)\n\t\t\t\t{\n\t\t\t\t\tif ((op->literal_mask & (1u << i)) != 0)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tspv::Id consumed_id = op->arguments[i];\n\t\t\t\t\tif (std::find(sinkable_ops.begin(), sinkable_ops.end(), consumed_id) != sinkable_ops.end())\n\t\t\t\t\t{\n\t\t\t\t\t\tsinkable_ops.push_back(op->id);\n\t\t\t\t\t\top->flags |= Operation::DependencySinkableBit;\n\t\t\t\t\t\tsinks[op->id] = { nullptr, op };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (op->op == spv::OpControlBarrier || op->op == spv::OpMemoryBarrier)\n\t\t\t{\n\t\t\t\t// We cannot sink beyond this barrier. Invalidate every sinkable op we saw so far.\n\t\t\t\tfor (spv::Id id : sinkable_ops)\n\t\t\t\t{\n\t\t\t\t\tauto *op_ptr = sinks[id].op;\n\t\t\t\t\tassert(op_ptr);\n\t\t\t\t\top_ptr->flags &= ~(Operation::SinkableBit | Operation::DependencySinkableBit);\n\t\t\t\t}\n\t\t\t\tsinkable_ops.clear();\n\t\t\t}\n\t\t}\n\t}\n\n\t// If an expression is used as a PHI input assume we cannot sink.\n\t// It gets a bit awkward to deal with this, and it's not required for this workaround pass.\n\tfor (auto *n : forward_post_visit_order)\n\t{\n\t\tfor (auto &phi : n->ir.phi)\n\t\t{\n\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t{\n\t\t\t\tauto itr = sinks.find(incoming.id);\n\t\t\t\tif (itr != sinks.end())\n\t\t\t\t{\n\t\t\t\t\tauto *op_ptr = itr->second.op;\n\t\t\t\t\tassert(op_ptr);\n\t\t\t\t\top_ptr->flags &= ~(Operation::SinkableBit | Operation::DependencySinkableBit);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst auto consume_id = [&](spv::Id consumed_id, CFGNode *n) {\n\t\tauto itr = sinks.find(consumed_id);\n\t\tif (itr != sinks.end())\n\t\t{\n\t\t\tif (!itr->second.consumed_block)\n\t\t\t\titr->second.consumed_block = n;\n\t\t\telse if (itr->second.consumed_block != n)\n\t\t\t\titr->second.op->flags &= ~(Operation::SinkableBit | Operation::DependencySinkableBit);\n\t\t}\n\t};\n\n\tconst auto path_is_reorderable = [&](const CFGNode *src, const CFGNode *dst) {\n\t\t// There cannot be any control or memory barriers along the way, or we have to be conservative.\n\n\t\t// There is absolutely no point in sinking if dst ends up post-dominating src anyway.\n\t\t// We cannot avoid any bug from happening.\n\t\tif (dst->post_dominates(src))\n\t\t\treturn false;\n\n\t\t// Never sink into a loop.\n\t\tif (dst->pred_back_edge)\n\t\t\treturn false;\n\n\t\t// Could deal with multiple preds, but we mostly just care about trivial sinks.\n\t\tif (dst->pred.size() > 1)\n\t\t\treturn false;\n\t\tdst = dst->immediate_dominator;\n\n\t\twhile (src != dst)\n\t\t{\n\t\t\tif (dst->pred.size() > 1 || dst->pred_back_edge)\n\t\t\t\treturn false;\n\n\t\t\tfor (auto *op : dst->ir.operations)\n\t\t\t\tif (op->op == spv::OpControlBarrier || op->op == spv::OpMemoryBarrier)\n\t\t\t\t\treturn false;\n\n\t\t\tdst = dst->pred.front();\n\t\t}\n\n\t\t// We reached src, and we validated that block already when deciding on what is sinkable or not, so we're good.\n\t\treturn true;\n\t};\n\n\t// Walk all instructions in reverse order.\n\t// We can sink an instruction if:\n\t// - An ID was only consumed in a BB != generating BB.\n\t//   The consumed BB must be unique for us to consider it for simplicity.\n\tfor (auto *n : forward_post_visit_order)\n\t{\n\t\tif (n->ir.terminator.type == Terminator::Type::Condition ||\n\t\t    n->ir.terminator.type == Terminator::Type::Switch)\n\t\t{\n\t\t\tconsume_id(n->ir.terminator.conditional_id, n);\n\t\t}\n\t\telse if (n->ir.terminator.type == Terminator::Type::Return &&\n\t\t         n->ir.terminator.return_value != 0)\n\t\t{\n\t\t\tconsume_id(n->ir.terminator.return_value, n);\n\t\t}\n\n\t\tauto &ops = n->ir.operations;\n\n\t\tfor (size_t i = ops.size(); i; i--)\n\t\t{\n\t\t\tauto *op = ops[i - 1];\n\t\t\tauto *target_block = n;\n\n\t\t\tif (op->id && (op->flags & (Operation::SinkableBit | Operation::DependencySinkableBit)) != 0)\n\t\t\t{\n\t\t\t\tauto sink_itr = sinks.find(op->id);\n\n\t\t\t\tif (sink_itr != sinks.end() &&\n\t\t\t\t    sink_itr->second.consumed_block &&\n\t\t\t\t    sink_itr->second.consumed_block != n &&\n\t\t\t\t    path_is_reorderable(n, sink_itr->second.consumed_block))\n\t\t\t\t{\n\t\t\t\t\t// Move the operation to the beginning of the consumed block instead.\n\t\t\t\t\ttarget_block = sink_itr->second.consumed_block;\n\n\t\t\t\t\t// Don't actually move the instruction until we have confirmed the entire chain can be sunk,\n\t\t\t\t\t// otherwise this exercise is meaningless.\n\t\t\t\t\tif (!dry_run)\n\t\t\t\t\t{\n\t\t\t\t\t\ttarget_block->ir.operations.insert(target_block->ir.operations.begin(), op);\n\t\t\t\t\t\tops.erase(ops.begin() + int(i - 1));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// This failed to sink. Remember this for the next run.\n\t\t\t\t\top->flags &= ~Operation::SinkableBit;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Mark uses after we have sunk the instruction. This allows us to sink a chain of SSA instructions.\n\t\t\tfor (uint32_t j = 0; j < op->num_arguments; j++)\n\t\t\t\tif ((op->literal_mask & (1u << j)) == 0)\n\t\t\t\t\tconsume_id(op->arguments[j], target_block);\n\t\t}\n\t}\n\n\tif (dry_run)\n\t\tfor (auto *n : forward_post_visit_order)\n\t\t\tfor (auto *op : n->ir.operations)\n\t\t\t\top->flags &= ~Operation::DependencySinkableBit;\n}\n\nvoid CFGStructurizer::propagate_branch_control_hints()\n{\n\tfor (auto *n : forward_post_visit_order)\n\t{\n\t\tif (n->pred_back_edge)\n\t\t{\n\t\t\tif (n->pred_back_edge->ir.terminator.force_loop)\n\t\t\t\tn->ir.merge_info.loop_control_mask = spv::LoopControlDontUnrollMask;\n\t\t\telse if (n->pred_back_edge->ir.terminator.force_unroll)\n\t\t\t\tn->ir.merge_info.loop_control_mask = spv::LoopControlUnrollMask;\n\t\t}\n\n\t\tif (n->ir.terminator.type == Terminator::Type::Condition)\n\t\t{\n\t\t\tif (n->ir.terminator.force_flatten)\n\t\t\t\tn->ir.merge_info.selection_control_mask = spv::SelectionControlFlattenMask;\n\t\t\telse if (n->ir.terminator.force_branch)\n\t\t\t\tn->ir.merge_info.selection_control_mask = spv::SelectionControlDontFlattenMask;\n\t\t}\n\n\t\t// Both are possible if a selection construct is also a loop header.\n\t}\n}\n\nvoid CFGStructurizer::remove_unused_ssa()\n{\n\tUnorderedSet<spv::Id> removed_ids;\n\tUnorderedSet<spv::Id> used_ids;\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tfor (auto &phi : node->ir.phi)\n\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t\tused_ids.insert(incoming.id);\n\n\t\tfor (auto *op : node->ir.operations)\n\t\t\tfor (unsigned i = 0; i < op->num_arguments; i++)\n\t\t\t\tif ((op->literal_mask & (1u << i)) == 0)\n\t\t\t\t\tused_ids.insert(op->arguments[i]);\n\n\t\tif (node->ir.terminator.conditional_id)\n\t\t\tused_ids.insert(node->ir.terminator.conditional_id);\n\n\t\tif (node->ir.terminator.type == Terminator::Type::Return &&\n\t\t    node->ir.terminator.return_value != 0)\n\t\t{\n\t\t\tused_ids.insert(node->ir.terminator.return_value);\n\t\t}\n\t}\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tnode->ir.phi.erase(std::remove_if(node->ir.phi.begin(), node->ir.phi.end(),\n\t\t                                  [&](const PHI &phi) { return used_ids.count(phi.id) == 0; }),\n\t\t                   node->ir.phi.end());\n\n\t\tnode->ir.operations.erase(\n\t\t\tstd::remove_if(\n\t\t\t\tnode->ir.operations.begin(), node->ir.operations.end(),\n\t\t\t\t[&](const Operation *op)\n\t\t\t\t{\n\t\t\t\t\tbool ret = op->id != 0 &&\n\t\t\t\t\t           !SPIRVModule::opcode_has_side_effect_and_result(op->op) &&\n\t\t\t\t\t           used_ids.count(op->id) == 0;\n\t\t\t\t\tif (ret)\n\t\t\t\t\t\tremoved_ids.insert(op->id);\n\t\t\t\t\treturn ret;\n\t\t\t\t}),\n\t\t\tnode->ir.operations.end());\n\t}\n\n\tmodule.get_builder().removeDecorations(removed_ids);\n}\n\nbool CFGStructurizer::rewrite_impossible_back_edges()\n{\n\tbool did_rewrite = false;\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (!node->succ_back_edge)\n\t\t\tcontinue;\n\n\t\t// Make sure that the continue block in question branches to the innermost loop header.\n\t\t// If this is not the case, it is not a valid structured CFG.\n\t\t// In unstructured CFG, as long as the continue block cannot reach the back-edge of any inner loop constructs,\n\t\t// it's technically not considered part of their loops, even if the loops dominate it.\n\t\t// Utter nonsense ... >_<\n\t\t// The only viable solution is to transpose out the continue block and use ladder selection\n\t\t// to resolve the control flow.\n\n\t\tauto *header = get_innermost_loop_header_for(node);\n\t\tif (header == node->succ_back_edge)\n\t\t\tcontinue;\n\n\t\t// Make sure that we're in valid unstructured control flow. Our node cannot reach any back edge on the way,\n\t\t// meaning it's okay to transpose code. If the continue block can reach us, it means we're already\n\t\t// outside the loop, stop any attempt to transpose.\n\t\tconst auto validate_header_suitability = [this, node](const CFGNode *header) {\n\t\t\treturn !query_reachability(*node, *header->pred_back_edge) &&\n\t\t\t       !query_reachability(*header->pred_back_edge, *node);\n\t\t};\n\n\t\t// Find a more appropriate place to put it.\n\t\t// We want to rewrite the flow so that the continue block lives outside any inner scopes.\n\t\t// The succ of the outer continue block is appropriate.\n\t\tconst CFGNode *next_header;\n\t\twhile ((next_header = get_innermost_loop_header_for(header->immediate_dominator)) != node->succ_back_edge &&\n\t\t       validate_header_suitability(next_header))\n\t\t{\n\t\t\theader = next_header;\n\t\t}\n\n\t\tif (next_header != node->succ_back_edge || !validate_header_suitability(header))\n\t\t\tcontinue;\n\n\t\tauto *outer_continue = header->pred_back_edge;\n\n\t\t// The outer continue must have a normal succ.\n\t\tif (outer_continue->succ.size() != 1)\n\t\t\tcontinue;\n\n\t\t// This succ is now in the loop scope of node->succ_back_edge. We can do the continue construct here.\n\t\tauto *succ = outer_continue->succ.front();\n\t\tauto *ladder = create_helper_pred_block(succ);\n\n\t\tauto orig_preds = node->pred;\n\t\ttraverse_dominated_blocks_and_rewrite_branch(node->succ_back_edge, node, ladder);\n\t\trewrite_ladder_conditional_branch_from_incoming_blocks(\n\t\t\tladder, node, succ,\n\t\t\t[&orig_preds](const CFGNode *n) { return std::find(orig_preds.begin(), orig_preds.end(), n) != orig_preds.end(); },\n\t\t\t\"tranpose_continue_phi\");\n\n\t\tdid_rewrite = true;\n\t\tbreak;\n\t}\n\n\tif (did_rewrite)\n\t\trecompute_cfg();\n\treturn did_rewrite;\n}\n\nbool CFGStructurizer::run_trivial()\n{\n\trecompute_cfg();\n\tsink_ssa_constructs();\n\tpropagate_branch_control_hints();\n\t// Remove unused SSA ops in this path.\n\tremove_unused_ssa();\n\n\treturn true;\n}\n\nbool CFGStructurizer::run()\n{\n\tString graphviz_path;\n\tif (const char *env = getenv(\"DXIL_SPIRV_GRAPHVIZ_PATH\"))\n\t\tgraphviz_path = env;\n\n\t// We make the assumption during traversal that there is only one back edge.\n\t// Fix this up here.\n\trewrite_multiple_back_edges();\n\n\t//log_cfg(\"Input state\");\n\tif (!graphviz_path.empty())\n\t{\n\t\treset_traversal();\n\t\tvisit(*entry_block);\n\t\tauto graphviz_input = graphviz_path + \".input\";\n\t\tlog_cfg_graphviz(graphviz_input.c_str());\n\t}\n\n\trecompute_cfg();\n\tsink_ssa_constructs();\n\tpropagate_branch_control_hints();\n\n\tcleanup_breaking_phi_constructs();\n\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_split = graphviz_path + \".phi-split\";\n\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t}\n\n\twhile (cleanup_breaking_return_constructs())\n\t{\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_split = graphviz_path + \".break-return\";\n\t\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t\t}\n\t}\n\n\tcreate_continue_block_ladders();\n\n\twhile (serialize_interleaved_early_returns())\n\t{\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_split = graphviz_path + \".serialize-early-return\";\n\t\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t\t}\n\t}\n\n\twhile (serialize_interleaved_merge_scopes_aggressive())\n\t{\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_split = graphviz_path + \".serialize-aggressive\";\n\t\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t\t}\n\t}\n\n\twhile (serialize_interleaved_merge_scopes())\n\t{\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_split = graphviz_path + \".serialize\";\n\t\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t\t}\n\t}\n\n\tsplit_merge_scopes();\n\trecompute_cfg();\n\n\t//log_cfg(\"Split merge scopes\");\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_split = graphviz_path + \".split\";\n\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t}\n\n\t// We will have generated lots of ladder blocks\n\t// which might cause issues with further analysis, so\n\t// nuke them as required.\n\teliminate_degenerate_blocks();\n\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_split = graphviz_path + \".eliminate0\";\n\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t}\n\n\t// Similar to cleanup_breaking_phi_constructs() in spirit,\n\t// but here we are forced to duplicate code blocks to make it work.\n\tduplicate_impossible_merge_constructs();\n\n\t//log_cfg(\"Split impossible merges\");\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_split = graphviz_path + \".duplicate\";\n\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t}\n\n\twhile (rewrite_transposed_loops())\n\t{\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_split = graphviz_path + \".transpose-loop-rewrite\";\n\t\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t\t}\n\t}\n\n\t// If there are back-edges that punch through multiple loop headers, fix this up.\n\twhile (rewrite_impossible_back_edges())\n\t{\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_split = graphviz_path + \".impossible-continue\";\n\t\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t\t}\n\t}\n\n\t//LOGI(\"=== Structurize pass ===\\n\");\n\twhile (structurize(0))\n\t{\n\t\trecompute_cfg();\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_final = graphviz_path + \".partial-struct0\";\n\t\t\tlog_cfg_graphviz(graphviz_final.c_str());\n\t\t}\n\t}\n\n\tupdate_structured_loop_merge_targets();\n\n\t//log_cfg(\"Structurize pass 0\");\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_final = graphviz_path + \".struct0\";\n\t\tlog_cfg_graphviz(graphviz_final.c_str());\n\t}\n\n\t// We will have generated lots of ladder blocks\n\t// which might cause issues with further analysis, so\n\t// nuke them as required.\n\teliminate_degenerate_blocks();\n\n\t//log_cfg(\"Split merge scopes\");\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_split = graphviz_path + \".eliminate1\";\n\t\tlog_cfg_graphviz(graphviz_split.c_str());\n\t}\n\n\t//LOGI(\"=== Structurize pass ===\\n\");\n\tstructurize(1);\n\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_final = graphviz_path + \".struct1\";\n\t\tlog_cfg_graphviz(graphviz_final.c_str());\n\t}\n\n\tbool need_restructure = false;\n\twhile (rewrite_invalid_loop_breaks())\n\t{\n\t\tif (!graphviz_path.empty())\n\t\t{\n\t\t\tauto graphviz_final = graphviz_path + \".loop-break-rewrite\";\n\t\t\tlog_cfg_graphviz(graphviz_final.c_str());\n\t\t}\n\n\t\tneed_restructure = true;\n\t}\n\n\tif (need_restructure)\n\t{\n\t\t// Need to redo the final structurization pass if we end up here.\n\t\tstructurize(1);\n\t}\n\n\t//log_cfg(\"Final\");\n\tif (!graphviz_path.empty())\n\t{\n\t\tauto graphviz_final = graphviz_path + \".final\";\n\t\tlog_cfg_graphviz(graphviz_final.c_str());\n\t}\n\n\tinsert_phi();\n\n\treturn true;\n}\n\nCFGNode *CFGStructurizer::get_entry_block() const\n{\n\treturn entry_block;\n}\n\nstatic bool block_is_control_dependent(const CFGNode *node)\n{\n\tfor (auto *op : node->ir.operations)\n\t\tif (SPIRVModule::opcode_is_control_dependent(op->op))\n\t\t\treturn true;\n\treturn false;\n}\n\nbool CFGStructurizer::continue_block_can_merge(CFGNode *node) const\n{\n\tconst CFGNode *pred_candidate = nullptr;\n\tauto *header = node->succ_back_edge;\n\n\t// This algorithm is very arbitrary and should be seen as a nasty heuristic which solves real shaders\n\t// we see in the wild. It's probably safe to block continue merge in far more cases than this, but we\n\t// want to be maximally convergent as often as we can.\n\n\tfor (auto *pred : node->pred)\n\t{\n\t\t// This is the merge block of another inner loop, we really need an intermediate merge.\n\t\tif (pred->succ_back_edge && header != pred->succ_back_edge && header->dominates(pred->succ_back_edge))\n\t\t\treturn true;\n\t}\n\n\t// Plain continue block that does nothing useful. No point merging this.\n\t// A continue block's succ is sometimes used to aid analysis and simplify other passes,\n\t// use terminator here explicitly.\n\tif (node->ir.operations.empty() && node->ir.terminator.type == Terminator::Type::Branch)\n\t\treturn false;\n\n\tif (header->ir.terminator.type == Terminator::Type::Switch)\n\t{\n\t\t// If the loop header is also a switch statement, there can be some nasty edge cases.\n\t\t// We likely never intend for the continue block to be maximally convergent here\n\t\t// if the natural merge block is not the continue block.\n\t\tauto *merge = find_common_post_dominator(header->succ);\n\t\tauto *natural_merge = find_natural_switch_merge_block(header, merge);\n\t\tif (merge == node && natural_merge != merge)\n\t\t\treturn false;\n\t}\n\n\tfor (auto *pred : node->pred)\n\t{\n\t\t// If we have a situation where a continue block has a pred which is itself a selection merge target, that\n\t\t// block is the merge target where we follow maximum convergence.\n\t\t// The candidate must be inside loop body and not the header itself.\n\t\t// Neither continue block nor merge target have any dominance relationship.\n\n\t\tif (pred->num_forward_preds() >= 2 && pred->succ.size() >= 2 &&\n\t\t    header != pred && !pred->dominates(node) &&\n\t\t    !node->post_dominates(pred))\n\t\t{\n\t\t\t// If execution does not merge up right at the natural break block,\n\t\t\t// things will get very complicated.\n\t\t\t// In practice, we can handle merges as long as the candidate just breaks out normally.\n\t\t\t// If not, we have to introduce ladder breaking and this is (almost) impossible to get right.\n\t\t\tauto *common_post_dominator = CFGNode::find_common_post_dominator(node, pred);\n\t\t\tif (common_post_dominator &&\n\t\t\t    std::find(node->succ.begin(), node->succ.end(), common_post_dominator) == node->succ.end())\n\t\t\t{\n\t\t\t\tpred_candidate = pred;\n\t\t\t}\n\t\t}\n\n\t\t// If we have a situation where a switch block inside our loop uses the continue block\n\t\t// as a continue target, it's important that we keep this block as a continue block,\n\t\t// otherwise, it will complicate the switch block greatly.\n\t\tif (pred->ir.terminator.type == Terminator::Type::Switch && !node->post_dominates(pred))\n\t\t\treturn false;\n\t}\n\n\t// No obviously nasty case to handle, probably safe to let the algorithm do its thing ...\n\tif (!pred_candidate)\n\t\treturn true;\n\n\t// Need to find another escape edge which is neither header nor the candidate.\n\tbool found_another_escape_edge = false;\n\tfor (auto *pred : node->pred)\n\t{\n\t\tif (pred != header && pred != pred_candidate && !pred->dominates(node))\n\t\t{\n\t\t\tfound_another_escape_edge = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// If we have yet another escape edge, we probably cannot merge to continue ...\n\treturn !found_another_escape_edge;\n}\n\nvoid CFGStructurizer::create_continue_block_ladders()\n{\n\t// It does not seem to be legal to merge directly to continue blocks.\n\t// To make it possible to merge execution, we need to create a ladder block which we can merge to.\n\t// There are certain scenarios where it is impossible to merge to a continue block.\n\t// In this case, we will abandom maximum convergence and use the continue block as a \"break\"-like target.\n\tbool need_recompute_cfg = false;\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (block_is_plain_continue(node) && continue_block_can_merge(node))\n\t\t{\n\t\t\t//LOGI(\"Creating helper pred block for continue block: %s\\n\", node->name.c_str());\n\t\t\tcreate_helper_pred_block(node);\n\t\t\tneed_recompute_cfg = true;\n\t\t}\n\t}\n\n\tif (need_recompute_cfg)\n\t\trecompute_cfg();\n}\n\nvoid CFGStructurizer::update_structured_loop_merge_targets()\n{\n\t// First, we need to do this before recomputing the CFG, since we lose\n\t// normal loop merge targets when recomputing.\n\tstructured_loop_merge_targets.clear();\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->loop_merge_block)\n\t\t\tstructured_loop_merge_targets.insert(node->loop_merge_block);\n\t\tif (node->loop_ladder_block)\n\t\t\tstructured_loop_merge_targets.insert(node->loop_ladder_block);\n\t}\n\n\trecompute_cfg();\n\n\t// Make sure we include merge blocks which are frozen merge targets in ladder blocks, which\n\t// were not included in the post visit order yet.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->loop_merge_block)\n\t\t\tstructured_loop_merge_targets.insert(node->loop_merge_block);\n\t\tif (node->loop_ladder_block)\n\t\t\tstructured_loop_merge_targets.insert(node->loop_ladder_block);\n\t}\n}\n\nstatic spv::Id get_remapped_id_for_duplicated_block(spv::Id id, const UnorderedMap<spv::Id, spv::Id> &remap)\n{\n\tauto itr = remap.find(id);\n\tif (itr != remap.end())\n\t\treturn itr->second;\n\telse\n\t\treturn id;\n}\n\nOperation *CFGStructurizer::duplicate_op(Operation *op, UnorderedMap<spv::Id, spv::Id> &id_remap)\n{\n\tOperation *duplicated_op;\n\tif (op->id)\n\t\tduplicated_op = module.allocate_op(op->op, module.allocate_id(), op->type_id);\n\telse\n\t\tduplicated_op = module.allocate_op(op->op);\n\n\tfor (unsigned i = 0; i < op->num_arguments; i++)\n\t{\n\t\tif (op->literal_mask & (1u << i))\n\t\t\tduplicated_op->add_literal(op->arguments[i]);\n\t\telse\n\t\t\tduplicated_op->add_id(get_remapped_id_for_duplicated_block(op->arguments[i], id_remap));\n\t}\n\n\tif (op->id)\n\t\tid_remap[op->id] = duplicated_op->id;\n\n\treturn duplicated_op;\n}\n\nbool CFGStructurizer::can_duplicate_phis(const CFGNode *node)\n{\n\t// If we want to duplicate nodes, we cannot do so in complicated scenarios where\n\t// we need to resolve PHIs. For example, if a node is split, the split nodes might have to\n\t// insert PHI nodes covering the subset of nodes which can reach each split.\n\t// This get very hairy, very quickly.\n\t// To check this, ensure that the node we want to split does not require any complex PHI handling.\n\n\t// First, validate that we can even find incoming values properly.\n\tfor (auto *pred : node->pred)\n\t{\n\t\tfor (auto &phi : node->ir.phi)\n\t\t{\n\t\t\tauto itr = find_incoming_value(pred, phi.incoming);\n\t\t\tif (itr == phi.incoming.end())\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Then, make sure that every incoming value dominates at least pred of node.\n\t// This way, we know that we don't need complicated PHI frontier merges along the way.\n\tfor (auto &phi : node->ir.phi)\n\t{\n\t\tfor (auto &incoming : phi.incoming)\n\t\t{\n\t\t\tbool dominates_at_least_one_pred = false;\n\t\t\tfor (auto *pred : node->pred)\n\t\t\t{\n\t\t\t\tif (incoming.block->dominates(pred))\n\t\t\t\t{\n\t\t\t\t\tdominates_at_least_one_pred = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!dominates_at_least_one_pred)\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nvoid CFGStructurizer::duplicate_node(CFGNode *node)\n{\n\tVector<UnorderedMap<spv::Id, spv::Id>> rewritten_ids;\n\tassert(node->succ.size() == 1);\n\tassert(node->pred.size() >= 2);\n\tassert(!node->dominates(node->succ.front()));\n\n\tVector<CFGNode *> break_blocks(node->pred.size());\n\trewritten_ids.resize(node->pred.size());\n\tauto *succ = node->succ.front();\n\n\tauto tmp_pred = node->pred;\n\tfor (size_t i = 0, n = tmp_pred.size(); i < n; i++)\n\t{\n\t\tauto *pred = tmp_pred[i];\n\t\tauto &remap = rewritten_ids[i];\n\n\t\t// First, rewrite PHI inputs.\n\t\t// Since we only have one pred now, we can resolve PHIs directly.\n\t\tauto *block = pool.create_node();\n\t\tblock->name = node->name + \".dup.\" + pred->name;\n\t\tblock->ir.terminator.type = Terminator::Type::Branch;\n\t\tblock->ir.terminator.direct_block = succ;\n\t\tblock->immediate_post_dominator = succ;\n\t\tblock->immediate_dominator = pred;\n\t\tpred->retarget_branch(node, block);\n\t\tblock->add_branch(succ);\n\n\t\tfor (auto &phi : node->ir.phi)\n\t\t{\n\t\t\tauto itr = find_incoming_value(pred, phi.incoming);\n\t\t\tassert(itr != phi.incoming.end());\n\t\t\tremap[phi.id] = itr->id;\n\t\t}\n\n\t\tUnorderedSet<spv::Id> remove_decoration_ids;\n\n\t\tfor (auto *op : node->ir.operations)\n\t\t{\n\t\t\tauto *dup_op = duplicate_op(op, remap);\n\t\t\tbool nocontract = module.get_builder().hasDecoration(op->id, spv::DecorationNoContraction);\n\t\t\tif (nocontract)\n\t\t\t{\n\t\t\t\tremove_decoration_ids.insert(op->id);\n\t\t\t\tmodule.get_builder().addDecoration(dup_op->id, spv::DecorationNoContraction);\n\t\t\t}\n\t\t\tblock->ir.operations.push_back(dup_op);\n\t\t}\n\n\t\tmodule.get_builder().removeDecorations(remove_decoration_ids);\n\n\t\tbreak_blocks[i] = block;\n\t}\n\n\tassert(node->pred.empty());\n\n\t// Finally, look at succ. If it takes PHI inputs from node, we'll have to rewrite the PHIs.\n\t// We know that node does not dominate succ,\n\t// so succ cannot use any SSA variables node generated directly\n\t// without using PHI nodes.\n\n\t// We might have placed ladders in between so that we need to fixup PHI later than just plain succ.\n\t// Chase down the chain and replace all PHIs.\n\n\t// First, collect all the succs that we are supposed to examine.\n\t// The list should also include succ_back_edge because it is not in the succ chain after recompute_cfg.\n\tVector<CFGNode *> succs;\n\twhile (succ)\n\t{\n\t\tif (succ->succ_back_edge)\n\t\t\tsuccs.push_back(succ->succ_back_edge);\n\t\tsuccs.push_back(succ);\n\t\tif (succ->succ.size() == 1)\n\t\t\tsucc = succ->succ.front();\n\t\telse\n\t\t\tsucc = nullptr;\n\t}\n\n\tfor (auto *succ : succs)\n\t{\n\t\tbool done = false;\n\t\tfor (auto &phi : succ->ir.phi)\n\t\t{\n\t\t\t// Find incoming ID from the block we're splitting up.\n\t\t\tauto incoming_itr = std::find_if(phi.incoming.begin(), phi.incoming.end(), [&](const IncomingValue &incoming) {\n\t\t\t\treturn incoming.block == node;\n\t\t\t});\n\n\t\t\tif (incoming_itr != phi.incoming.end())\n\t\t\t{\n\t\t\t\tspv::Id incoming_from_node = incoming_itr->id;\n\t\t\t\tphi.incoming.erase(incoming_itr);\n\n\t\t\t\tfor (size_t i = 0, n = tmp_pred.size(); i < n; i++)\n\t\t\t\t{\n\t\t\t\t\tauto &remap = rewritten_ids[i];\n\t\t\t\t\tphi.incoming.push_back({ break_blocks[i], get_remapped_id_for_duplicated_block(incoming_from_node, remap) });\n\t\t\t\t}\n\n\t\t\t\t// We've found the block we wanted to rewrite, terminate loop now.\n\t\t\t\tdone = true;\n\t\t\t}\n\t\t}\n\n\t\tif (done)\n\t\t\tbreak;\n\t}\n}\n\nvoid CFGStructurizer::duplicate_impossible_merge_constructs()\n{\n\tVector<CFGNode *> duplicate_queue;\n\n\tfor (size_t i = forward_post_visit_order.size(); i; i--)\n\t{\n\t\tauto *node = forward_post_visit_order[i - 1];\n\n\t\t// Never duplicate back-edges.\n\t\tif (node->succ_back_edge)\n\t\t\tcontinue;\n\n\t\t// Check for breaking merge blocks which were not considered degenerate.\n\t\t// This can happen if we actually have code in the breaking construct ... (scary!)\n\t\t// We'll have to split this block somehow.\n\t\t// If the candidate has control dependent effects like barriers and such,\n\t\t// this will likely break completely,\n\t\t// but I don't see how that would work on native drivers either ...\n\n\t\t// WARNING: This check is EXTREMELY sensitive and microscopic changes to the implementation\n\t\t// will dramatically affect codegen.\n\t\tbool breaking = merge_candidate_is_on_breaking_path(node);\n\n\t\tif (breaking && !node->ir.operations.empty() && !block_is_control_dependent(node))\n\t\t\tduplicate_queue.push_back(node);\n\t}\n\n\tif (duplicate_queue.empty())\n\t\treturn;\n\n\tfor (auto *node : duplicate_queue)\n\t{\n\t\tif (!can_duplicate_phis(node))\n\t\t{\n\t\t\t// A block could be subtly load bearing, in that if we split the node, it becomes impossible to resolve\n\t\t\t// PHIs and we hit assertions in duplicate_node().\n\t\t\t// This means the block is probably load bearing after all, and we should not split it.\n\t\t\t// Normally, we only want to break up blocks which have fairly trivial PHI resolves.\n\t\t\tLOGW(\"Was asked to duplicate node %s, but cannot split phis without crashing ...\\n\", node->name.c_str());\n\t\t\tcontinue;\n\t\t}\n\n\t\tduplicate_node(node);\n\t}\n\trecompute_cfg();\n}\n\nbool CFGStructurizer::ladder_chain_has_phi_dependencies(const CFGNode *succ, const CFGNode *node)\n{\n\twhile (succ)\n\t{\n\t\tfor (auto &phi : succ->ir.phi)\n\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t\tif (incoming.block == node)\n\t\t\t\t\treturn true;\n\n\t\tif (succ->succ.size() == 1)\n\t\t\tsucc = succ->succ.front();\n\t\telse\n\t\t\tsucc = nullptr;\n\t}\n\n\treturn false;\n}\n\nvoid CFGStructurizer::eliminate_degenerate_blocks()\n{\n\t// After we create ladder blocks, we will likely end up with a lot of blocks which don't do much.\n\t// We might also have created merge scenarios which should *not* merge, i.e. cleanup_breaking_phi_constructs(),\n\t// except we caused it ourselves.\n\n\t// Eliminate bottom-up. First eliminate B, in A -> B -> C, where B contributes nothing.\n\tbool did_work = false;\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->ir.operations.empty() &&\n\t\t    node->ir.phi.empty() &&\n\t\t    !node->pred_back_edge &&\n\t\t    !node->succ_back_edge &&\n\t\t    !node->is_pseudo_back_edge &&\n\t\t    node->succ.size() == 1 &&\n\t\t    node->ir.terminator.type == Terminator::Type::Branch &&\n\t\t    node->merge == MergeType::None &&\n\t\t    // Loop merge targets are sacred, and must not be removed.\n\t\t    structured_loop_merge_targets.count(node) == 0 &&\n\t\t    !ladder_chain_has_phi_dependencies(node->succ.front(), node))\n\t\t{\n\t\t\tauto check_is_load_bearing_continue_succ = [node](const CFGNode *n) {\n\t\t\t\tif (!n->succ_back_edge)\n\t\t\t\t\treturn false;\n\n\t\t\t\t// If we eliminate the block, we want the succ to post-dominate the header,\n\t\t\t\t// so it can be considered a merge block.\n\t\t\t\t// Similarly, we want the header to dominate the succ.\n\t\t\t\tif (!node->succ.front()->post_dominates(n->succ_back_edge))\n\t\t\t\t\treturn true;\n\t\t\t\tif (!n->succ_back_edge->dominates(node->succ.front()))\n\t\t\t\t\treturn true;\n\n\t\t\t\t// No point in eliminating since we're inside the construct.\n\t\t\t\tif (n->dominates(node))\n\t\t\t\t\treturn true;\n\n\t\t\t\treturn false;\n\t\t\t};\n\n\t\t\t// If any pred is a continue block, this block is also load-bearing, since it can be used as a merge block.\n\t\t\t// Even if a continue block branches to us, it may be a fake load bearing block.\n\t\t\t// If the succ of node post-dominates the entire loop construct, we can eliminate the block safely\n\t\t\t// since we're not taking away a nice merge target.\n\t\t\tif (std::find_if(node->pred.begin(), node->pred.end(), check_is_load_bearing_continue_succ) != node->pred.end())\n\t\t\t\tcontinue;\n\n\t\t\t// We might be a viable merge target for an infinite loop. If we only have one pred, we're probably not\n\t\t\t// a painful break merge. Removing this block shouldn't be problematic for correctness, but removing\n\t\t\t// a block only to add back a ladder is a little silly.\n\t\t\tif (node->pred.size() == 1 && node->pred.front()->pred_back_edge &&\n\t\t\t\tnode->pred.front()->pred_back_edge->succ.empty())\n\t\t\t\tcontinue;\n\n\t\t\t// If any succ is a continue block, this block is also load-bearing, since it can be used as a merge block\n\t\t\t// (merge-to-continue ladder).\n\t\t\tif (std::find_if(node->succ.begin(), node->succ.end(),\n\t\t\t                 [](const CFGNode *n) { return n->succ_back_edge != nullptr; }) != node->succ.end())\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tauto *succ = node->succ.front();\n\n\t\t\tif (node->pred.size() == 1 && node->post_dominates(node->pred.front()))\n\t\t\t{\n\t\t\t\t// Trivial case.\n\t\t\t\tdid_work = true;\n\t\t\t\tauto *pred = node->pred.front();\n\t\t\t\tpred->retarget_branch(node, succ);\n\n\t\t\t\tpred->dominance_frontier.clear();\n\t\t\t\t// Propagates any idom information up to pred if pred dominates succ.\n\t\t\t\trecompute_dominance_frontier(succ);\n\t\t\t\trecompute_dominance_frontier(pred);\n\t\t\t}\n\t\t\telse if (merge_candidate_is_inside_continue_construct(node) || merge_candidate_is_on_breaking_path(node))\n\t\t\t{\n\t\t\t\t// If we have two or more preds, we have to be really careful.\n\t\t\t\t// If this node is on a breaking path, without being important for merging control flow,\n\t\t\t\t// it is fine to eliminate the block.\n\t\t\t\tdid_work = true;\n\t\t\t\tauto tmp_pred = node->pred;\n\t\t\t\tfor (auto *pred : tmp_pred)\n\t\t\t\t\tpred->retarget_branch_with_intermediate_node(node, node->succ.front());\n\n\t\t\t\t// Iteratively, we need to recompute the dominance frontier for all preds.\n\t\t\t\t// When we eliminate nodes like this, we might cause the pred blocks to become degenerate in\n\t\t\t\t// future iterations in this loop.\n\t\t\t\tstd::sort(tmp_pred.begin(), tmp_pred.end(), [](const CFGNode *a, const CFGNode *b) {\n\t\t\t\t\treturn a->forward_post_visit_order < b->forward_post_visit_order;\n\t\t\t\t});\n\n\t\t\t\t// Need to compute dominance frontiers from inside out.\n\t\t\t\tfor (auto *pred : tmp_pred)\n\t\t\t\t{\n\t\t\t\t\tpred->dominance_frontier.clear();\n\t\t\t\t\trecompute_dominance_frontier(pred);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (did_work)\n\t\trecompute_cfg();\n}\n\nvoid CFGStructurizer::prune_dead_preds()\n{\n\t// We do not want to see unreachable preds.\n\t// Having a pred means we need to map it to an incoming value when dealing with PHI.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tauto itr = std::remove_if(node->pred.begin(), node->pred.end(),\n\t\t                          [&](const CFGNode *node) { return reachable_nodes.count(node) == 0; });\n\t\tnode->pred.erase(itr, node->pred.end());\n\t}\n}\n\nstatic void rewrite_consumed_ids(IRBlock &ir, spv::Id from, spv::Id to)\n{\n\tfor (auto *op : ir.operations)\n\t{\n\t\tfor (unsigned i = 0; i < op->num_arguments; i++)\n\t\t{\n\t\t\tif ((op->literal_mask & (1u << i)) == 0)\n\t\t\t\tif (op->arguments[i] == from)\n\t\t\t\t\top->arguments[i] = to;\n\t\t}\n\t}\n\n\tif (ir.terminator.conditional_id == from)\n\t\tir.terminator.conditional_id = to;\n\tif (ir.terminator.return_value == from)\n\t\tir.terminator.return_value = to;\n}\n\nvoid CFGStructurizer::fixup_loop_header_undef_phis()\n{\n\tauto &builder = module.get_builder();\n\n\trecompute_cfg();\n\n\t// If the incoming value to the loop is undef, something is deeply wrong.\n\t// This is almost a guarantee that we will consume the value as undef, causing breakage in the wild.\n\t// Observed in Dune.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (!node->pred_back_edge)\n\t\t\tcontinue;\n\n\t\tfor (auto &phi : node->ir.phi)\n\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t\tif (incoming.block != node && incoming.block->dominates(node))\n\t\t\t\t\tif (const auto *inst = builder.getInstruction(incoming.id))\n\t\t\t\t\t\tif (inst->getOpCode() == spv::OpUndef)\n\t\t\t\t\t\t\tincoming.id = builder.makeNullConstant(phi.type_id);\n\t}\n}\n\nstatic bool type_class_is_opaque(spv::Op type_op)\n{\n\treturn type_op == spv::OpTypeImage || type_op == spv::OpTypeSampler ||\n\t       type_op == spv::OpTypeAccelerationStructureKHR;\n}\n\nvoid CFGStructurizer::fixup_broken_value_dominance()\n{\n\tstruct Origin\n\t{\n\t\tCFGNode *node;\n\t\tspv::Id type_id;\n\t\tconst Operation *rematerialize_op;\n\t};\n\n\tUnorderedMap<spv::Id, Origin> origin;\n\tUnorderedMap<spv::Id, Vector<CFGNode *>> id_to_non_local_consumers;\n\n\t// First, scan through all blocks and figure out which block creates an ID.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tfor (auto *op : node->ir.operations)\n\t\t{\n\t\t\t// OpVariable is always hoisted to function entry or above.\n\t\t\t// It can never not have dominance relationship.\n\t\t\tif (op->op != spv::OpVariable && op->id)\n\t\t\t\torigin[op->id] = { node, op->type_id, op->op == spv::OpSampledImage ? op : nullptr };\n\t\t}\n\n\t\tfor (auto &phi : node->ir.phi)\n\t\t\torigin[phi.id] = { node, phi.type_id, nullptr };\n\t}\n\n\tconst auto sort_unique_node_vector = [](Vector<CFGNode *> &nodes) {\n\t\t// Fixup nodes in order.\n\t\tstd::sort(nodes.begin(), nodes.end(), [](const CFGNode *a, const CFGNode *b) -> bool {\n\t\t\treturn a->forward_post_visit_order > b->forward_post_visit_order;\n\t\t});\n\t\tnodes.erase(std::unique(nodes.begin(), nodes.end()), nodes.end());\n\t};\n\n\tconst auto mark_node_value_access = [&](CFGNode *node, spv::Id id) {\n\t\tauto origin_itr = origin.find(id);\n\t\tif (origin_itr == origin.end())\n\t\t\treturn;\n\n\t\tauto *origin_node = origin_itr->second.node;\n\t\tif (!origin_node->dominates(node) || (origin_itr->second.rematerialize_op && node != origin_node))\n\t\t{\n\t\t\t// We have a problem. Mark that we need to rewrite a certain variable.\n\t\t\tid_to_non_local_consumers[id].push_back(node);\n\t\t}\n\t};\n\n\t// Need value copy here since we might be updating node->ir.operations inline leading to iterator invalidation.\n\tVector<Operation> variable_pointer_like_operations[2];\n\n\t// Now, scan through all blocks and figure out which values are consumed in different blocks.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tfor (auto *op : node->ir.operations)\n\t\t{\n\t\t\tauto literal_mask = op->literal_mask;\n\t\t\tfor (unsigned i = 0; i < op->num_arguments; i++)\n\t\t\t\tif (((1u << i) & literal_mask) == 0)\n\t\t\t\t\tmark_node_value_access(node, op->arguments[i]);\n\n\t\t\tif (op->op == spv::OpLoad && type_class_is_opaque(module.get_builder().getTypeClass(op->type_id)))\n\t\t\t\tvariable_pointer_like_operations[0].push_back(*op);\n\t\t\telse if (op->op == spv::OpAccessChain)\n\t\t\t\tvariable_pointer_like_operations[1].push_back(*op);\n\t\t}\n\n\t\t// Incoming PHI values are handled elsewhere by modifying the incoming block to the creating block.\n\t\t// Ignore these kinds of usage here.\n\n\t\tif (node->ir.terminator.conditional_id != 0)\n\t\t\tmark_node_value_access(node, node->ir.terminator.conditional_id);\n\t\tif (node->ir.terminator.return_value != 0)\n\t\t\tmark_node_value_access(node, node->ir.terminator.return_value);\n\t}\n\n\t// First, sink any opaque objects which are accessed in unexpected blocks after CFG rewrite.\n\n\tfor (auto &rewrite_ordering : variable_pointer_like_operations)\n\t{\n\t\tfor (auto &variable_op : rewrite_ordering)\n\t\t{\n\t\t\tauto itr = id_to_non_local_consumers.find(variable_op.id);\n\t\t\tif (itr != id_to_non_local_consumers.end())\n\t\t\t{\n\t\t\t\t// We will need to sink the operation.\n\t\t\t\t// Make sure all dependencies are also marked as used in potentially non-local block.\n\n\t\t\t\t// Sort for deterministic output.\n\t\t\t\tVector<CFGNode *> local_consumers_sorted;\n\t\t\t\tfor (auto *non_local_node : itr->second)\n\t\t\t\t\tlocal_consumers_sorted.push_back(non_local_node);\n\n\t\t\t\tstd::sort(local_consumers_sorted.begin(), local_consumers_sorted.end(),\n\t\t\t\t\t\t  [](const CFGNode *a, const CFGNode *b) {\n\t\t\t\t\t\t\t  return a->forward_post_visit_order < b->forward_post_visit_order;\n\t\t\t\t\t\t  });\n\n\t\t\t\tauto literal_mask = variable_op.literal_mask;\n\n\t\t\t\tfor (unsigned i = 0; i < variable_op.num_arguments; i++)\n\t\t\t\t\tif (((1u << i) & literal_mask) == 0)\n\t\t\t\t\t\tfor (auto *non_local_node : local_consumers_sorted)\n\t\t\t\t\t\t\tmark_node_value_access(non_local_node, variable_op.arguments[i]);\n\n\t\t\t\tfor (auto *non_local_node : local_consumers_sorted)\n\t\t\t\t{\n\t\t\t\t\tauto *sunk_chain = module.allocate_op();\n\t\t\t\t\t*sunk_chain = variable_op;\n\t\t\t\t\tsunk_chain->id = module.allocate_id();\n\n\t\t\t\t\tif (module.get_builder().hasDecoration(variable_op.id, spv::DecorationNonUniform))\n\t\t\t\t\t\tmodule.get_builder().addDecoration(sunk_chain->id, spv::DecorationNonUniform);\n\n\t\t\t\t\tauto &ops = non_local_node->ir.operations;\n\t\t\t\t\trewrite_consumed_ids(non_local_node->ir, variable_op.id, sunk_chain->id);\n\t\t\t\t\tops.insert(ops.begin(), sunk_chain);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Resolve these broken PHIs by using OpVariable. It is the simplest solution, and this is a very rare case to begin with.\n\tstruct Rewrite\n\t{\n\t\tspv::Id id;\n\t\tconst Vector<CFGNode *> *consumers;\n\t};\n\tVector<Rewrite> rewrites;\n\trewrites.reserve(id_to_non_local_consumers.size());\n\n\tfor (auto &pair : id_to_non_local_consumers)\n\t{\n\t\tsort_unique_node_vector(pair.second);\n\t\trewrites.push_back({ pair.first, &pair.second });\n\t}\n\n\t// Ensure ordering so that output remains stable.\n\tstd::sort(rewrites.begin(), rewrites.end(), [](const Rewrite &a, const Rewrite &b) {\n\t\treturn a.id < b.id;\n\t});\n\n\tfor (auto &rewrite : rewrites)\n\t{\n\t\tauto &orig = origin[rewrite.id];\n\n\t\t// We don't rely on VariablePointers, so if this comes up, we need to figure out something else.\n\t\t// These kinds of ops are handled specially by re-creating them as needed.\n\t\tbool rematerialized = module.get_builder().isPointerType(orig.type_id) ||\n\t\t                      type_class_is_opaque(module.get_builder().getTypeClass(orig.type_id));\n\n\t\tif (orig.rematerialize_op)\n\t\t{\n\t\t\tauto *rematerialize_op = module.allocate_op();\n\t\t\t*rematerialize_op = *orig.rematerialize_op;\n\t\t\trematerialize_op->id = module.allocate_id();\n\n\t\t\tif (module.get_builder().hasDecoration(orig.rematerialize_op->id, spv::DecorationNonUniform))\n\t\t\t\tmodule.get_builder().addDecoration(rematerialize_op->id, spv::DecorationNonUniform);\n\n\t\t\tfor (auto *consumer : *rewrite.consumers)\n\t\t\t{\n\t\t\t\trewrite_consumed_ids(consumer->ir, rewrite.id, rematerialize_op->id);\n\t\t\t\tconsumer->ir.operations.insert(consumer->ir.operations.begin(), rematerialize_op);\n\t\t\t}\n\t\t}\n\t\telse if (!rematerialized)\n\t\t{\n\t\t\t// Invalid access chains are resolved above. We end up rewriting any non-dominated values instead.\n\t\t\tspv::Id alloca_var_id = module.create_variable(spv::StorageClassFunction, orig.type_id);\n\n\t\t\tauto *store_op = module.allocate_op(spv::OpStore);\n\t\t\tstore_op->add_id(alloca_var_id);\n\t\t\tstore_op->add_id(rewrite.id);\n\t\t\torig.node->ir.operations.push_back(store_op);\n\n\t\t\t// For every non-local node which consumes ID, we load from the alloca'd variable instead.\n\t\t\t// Rewrite all ID references to point to the loaded value.\n\t\t\tfor (auto *consumer : *rewrite.consumers)\n\t\t\t{\n\t\t\t\tspv::Id loaded_id = module.allocate_id();\n\t\t\t\tauto *load_op = module.allocate_op(spv::OpLoad, loaded_id, orig.type_id);\n\t\t\t\tload_op->add_id(alloca_var_id);\n\n\t\t\t\trewrite_consumed_ids(consumer->ir, rewrite.id, loaded_id);\n\n\t\t\t\tconsumer->ir.operations.insert(consumer->ir.operations.begin(), load_op);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid CFGStructurizer::insert_phi()\n{\n\t// If we inserted dummy branches from back-edge to rewrite infinite loops, we must prune these branches\n\t// now, so we don't end up creating a wrong amount of PHI incoming values.\n\t// We don't have to recompute the CFG since we don't really care about post-visit orders at this stage.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->pred_back_edge && node->pred_back_edge->ir.terminator.type == Terminator::Type::Branch &&\n\t\t    node->pred_back_edge->succ_back_edge == node->pred_back_edge->ir.terminator.direct_block &&\n\t\t    node->pred_back_edge->succ.size() == 1)\n\t\t{\n\t\t\tauto *back_edge = node->pred_back_edge;\n\t\t\tauto *succ = back_edge->succ.front();\n\t\t\tback_edge->succ.clear();\n\t\t\tauto itr = std::find(succ->pred.begin(), succ->pred.end(), back_edge);\n\t\t\tassert(itr != succ->pred.end());\n\t\t\tsucc->pred.erase(itr);\n\t\t\tsucc->recompute_immediate_dominator();\n\t\t}\n\t}\n\n\tprune_dead_preds();\n\n\t// It is possible that an SSA value was created in a block, and consumed in another.\n\t// With CFG rewriting branches, it is possible that dominance relationship no longer holds\n\t// and we must insert new dummy IDs to resolve this.\n\tfixup_broken_value_dominance();\n\n\t// Build a map of value ID -> creating block.\n\t// This allows us to detect if a value is consumed in a situation where the declaration does not dominate use.\n\t// This can happen when introducing ladder blocks or similar.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tunsigned phi_index = 0;\n\t\tfor (auto &phi : node->ir.phi)\n\t\t{\n\t\t\tphi_nodes.push_back({ node, phi_index });\n\t\t\tif (phi.id)\n\t\t\t\tvalue_id_to_block[phi.id] = node;\n\t\t\tphi_index++;\n\t\t}\n\n\t\tfor (auto *op : node->ir.operations)\n\t\t\tif (op->id)\n\t\t\t\tvalue_id_to_block[op->id] = node;\n\t}\n\n\t// Resolve phi-nodes top-down since PHI nodes may depend on other PHI nodes.\n\tstd::sort(phi_nodes.begin(), phi_nodes.end(),\n\t          [](const PHINode &a, const PHINode &b) { return a.block->forward_post_visit_order > b.block->forward_post_visit_order; });\n\n\tfor (auto &phi_node : phi_nodes)\n\t{\n\t\tfixup_phi(phi_node);\n\t\tinsert_phi(phi_node);\n\t}\n}\n\nVector<IncomingValue>::const_iterator CFGStructurizer::find_incoming_value(\n    const CFGNode *frontier_pred, const Vector<IncomingValue> &incoming)\n{\n\t// Find the incoming block which dominates frontier_pred and has the lowest post visit order.\n\t// There are cases where two or more blocks dominate, but we want the most immediate dominator.\n\tauto candidate = incoming.end();\n\n\tfor (auto itr = incoming.begin(); itr != incoming.end(); ++itr)\n\t{\n\t\tauto *block = itr->block;\n\t\tif (block->dominates(frontier_pred))\n\t\t{\n\t\t\tif (candidate == incoming.end() || (block->forward_post_visit_order < candidate->block->forward_post_visit_order))\n\t\t\t\tcandidate = itr;\n\t\t}\n\t}\n\n\treturn candidate;\n}\n\nstatic IncomingValue *phi_incoming_blocks_find_block(Vector<IncomingValue> &incomings, const CFGNode *block)\n{\n\tfor (auto &incoming : incomings)\n\t\tif (incoming.block == block)\n\t\t\treturn &incoming;\n\treturn nullptr;\n}\n\nstatic bool id_is_generated_by_block(const CFGNode *block, spv::Id id)\n{\n\tfor (const auto *op : block->ir.operations)\n\t\tif (op->id == id)\n\t\t\treturn true;\n\n\tfor (const auto &phi : block->ir.phi)\n\t\tif (phi.id == id)\n\t\t\treturn true;\n\n\treturn false;\n}\n\nstatic void retarget_phi_incoming_block(PHI &phi, CFGNode *from, CFGNode *to)\n{\n\tauto *value = phi_incoming_blocks_find_block(phi.incoming, from);\n\tif (value)\n\t\tvalue->block = to;\n}\n\nvoid CFGStructurizer::fixup_phi(PHINode &node)\n{\n\t// We want to move any incoming block to where the ID was created.\n\t// This avoids some problematic cases of crossing edges when using ladders.\n\tauto &phi = node.block->ir.phi[node.phi_index];\n\tauto &incomings = phi.incoming;\n\n\tfor (auto &incoming : incomings)\n\t{\n\t\tauto itr = value_id_to_block.find(incoming.id);\n\t\tif (itr == end(value_id_to_block))\n\t\t{\n\t\t\t// This is a global.\n\t\t\tcontinue;\n\t\t}\n\n\t\tauto *source_block = itr->second;\n\n\t\t// Only hoist PHI inputs if there used to be a dominance relationship in the original CFG,\n\t\t// but there no longer is.\n\t\tif (!source_block->dominates(incoming.block))\n\t\t{\n\t\t\tbool hoist_incoming = true;\n\t\t\tif (phi_incoming_blocks_find_block(incomings, source_block) != nullptr)\n\t\t\t{\n\t\t\t\t// Sanity check. This would create ambiguity.\n\t\t\t\thoist_incoming = false;\n\t\t\t}\n\n\t\t\t// Don't hoist PHI inputs across the loop header boundary.\n\t\t\tif (incoming.block->succ_back_edge && query_reachability(*source_block, *incoming.block->succ_back_edge))\n\t\t\t{\n\t\t\t\t// If this happens somehow, we have a problem. It's a bit unclear how this is supposed to work.\n\t\t\t\t// It's possible we'd need to synthesize a fake input to back-edge which can be resolved\n\t\t\t\t// in a code path that does dominate the loop ...\n\t\t\t\tLOGW(\"Incoming value to back edge does not dominate loop header.\\n\");\n\t\t\t\thoist_incoming = false;\n\t\t\t}\n\n\t\t\tif (hoist_incoming)\n\t\t\t{\n#ifdef PHI_DEBUG\n\t\t\t\tLOGI(\"For node %s, move incoming node %s to %s.\\n\", node.block->name.c_str(),\n\t\t\t\t     incoming.block->name.c_str(), itr->second->name.c_str());\n#endif\n\t\t\t\tincoming.block = itr->second;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We cannot hoist, so need to use dummy OpVariable instead.\n\t\t\t\tspv::Id alloca_var_id = module.create_variable(spv::StorageClassFunction, phi.type_id, \"phi_fixup\");\n\t\t\t\tauto *store_op = module.allocate_op(spv::OpStore);\n\t\t\t\tstore_op->add_id(alloca_var_id);\n\t\t\t\tstore_op->add_id(incoming.id);\n\t\t\t\titr->second->ir.operations.push_back(store_op);\n\n\t\t\t\tspv::Id loaded_id = module.allocate_id();\n\t\t\t\tauto *load_op = module.allocate_op(spv::OpLoad, loaded_id, phi.type_id);\n\t\t\t\tload_op->add_id(alloca_var_id);\n\t\t\t\tincoming.block->ir.operations.push_back(load_op);\n\n\t\t\t\tincoming.id = loaded_id;\n\t\t\t}\n\n\t\t\tvalidate_phi(node.block->ir.phi[node.phi_index]);\n\t\t}\n\t}\n}\n\nbool CFGStructurizer::can_complete_phi_insertion(const PHI &phi, const CFGNode *block)\n{\n\t// If all incoming values have at least one pred block they dominate, we can merge the final PHI.\n\tauto &incoming_values = phi.incoming;\n\tfor (auto &incoming : incoming_values)\n\t{\n\t\tauto itr = std::find_if(block->pred.begin(), block->pred.end(),\n\t\t                        [&](const CFGNode *n) { return incoming.block->dominates(n); });\n\n\t\tif (itr == block->pred.end() &&\n\t\t    (!block->pred_back_edge || !incoming.block->dominates(block->pred_back_edge)))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool CFGStructurizer::query_reachability_through_back_edges(const CFGNode &from, const CFGNode &to) const\n{\n\tif (to.dominates(&from))\n\t{\n\t\t// If we're dominated by end node, only way we can reach is through a back edge.\n\t\treturn to.pred_back_edge && query_reachability(from, *to.pred_back_edge);\n\t}\n\telse\n\t\treturn query_reachability(from, to);\n}\n\nbool CFGStructurizer::query_reachability_split_loop_header(const CFGNode &from, const CFGNode &to, const CFGNode &end_node) const\n{\n\t// A special query where from and to must lie on the same side of a loop header to be considered reachable.\n\tif (!end_node.pred_back_edge)\n\t\treturn query_reachability(from, to);\n\n\tbool from_reaches_header = query_reachability(from, end_node);\n\tbool to_reaches_header = query_reachability(to, end_node);\n\tif (from_reaches_header != to_reaches_header)\n\t\treturn false;\n\n\treturn query_reachability(from, to);\n}\n\nbool CFGStructurizer::phi_frontier_makes_forward_progress(const PHI &phi, const CFGNode *frontier,\n                                                          const CFGNode *end_node) const\n{\n\t// Not all PHI frontiers are nodes we need to care about.\n\t// There are two conditions we must meet to disregard a placement.\n\t// - We do not remove any inputs as a result.\n\t// - The frontier can reach another incoming value.\n\t// In this situation, a frontier is completely meaningless.\n\tauto &incoming = phi.incoming;\n\n\tfor (auto &incoming_value : incoming)\n\t{\n\t\tauto *incoming_block = incoming_value.block;\n\t\t// We will remove an input, this is forward progress.\n\t\t// Avoid checking the edge case where frontier candidate == incoming block.\n\t\t// Removing an input only to place a new frontier there is nonsensical.\n\t\tif (frontier != incoming_block && !exists_path_in_cfg_without_intermediate_node(incoming_block, end_node, frontier))\n\t\t\treturn true;\n\t}\n\n\t// Nothing is removed as a result, so check if the frontier can reach another incoming value.\n\t// If end_node is a loop header, makes sure we only consider a node visible if they are both on the correct side of the\n\t// loop header.\n\tfor (auto &incoming_value : incoming)\n\t\tif (query_reachability_split_loop_header(*frontier, *incoming_value.block, *end_node))\n\t\t\treturn false;\n\n\t// Assume we make forward progress. Either way, we will never look at a frontier twice,\n\t// so this should be safe. The only real risk is that we add some redundant PHI nodes.\n\treturn true;\n}\n\nvoid CFGStructurizer::insert_phi(PHINode &node)\n{\n\t// We start off with N values defined in N blocks.\n\t// These N blocks *used* to branch to the PHI node, but due to our structurizer,\n\t// there might not be branch targets here anymore, primary example here is ladders.\n\t// In order to fix this we need to follow control flow from these values and insert phi nodes as necessary to link up\n\t// a set of values where dominance frontiers are shared.\n\n#ifdef PHI_DEBUG\n\tLOGI(\"\\n=== INSERT PHI FOR %s ===\\n\", node.block->name.c_str());\n#endif\n\n\tauto &phi = node.block->ir.phi[node.phi_index];\n\tauto &incoming_values = phi.incoming;\n\n\tUnorderedSet<const CFGNode *> placed_frontiers;\n\n\tfor (;;)\n\t{\n#ifdef PHI_DEBUG\n\t\tLOGI(\"\\n=== PHI iteration ===\\n\");\n\n\t\tfor (auto &incoming : incoming_values)\n\t\t\tLOGI(\"  Incoming value from %s\\n\", incoming.block->name.c_str());\n#endif\n\n\t\t// Inside the CFG subset, find a dominance frontiers where we merge PHIs this iteration.\n\t\tCFGNode *frontier = node.block;\n\t\tif (!can_complete_phi_insertion(phi, node.block))\n\t\t{\n\t\t\tfrontier = nullptr;\n\n\t\t\t// We need some intermediate merge, so find a frontier node to work on.\n\t\t\tfor (auto &incoming : incoming_values)\n\t\t\t{\n\t\t\t\tfor (auto *candidate_frontier : incoming.block->dominance_frontier)\n\t\t\t\t{\n\t\t\t\t\tif (placed_frontiers.count(candidate_frontier))\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tif (!phi_frontier_makes_forward_progress(phi, candidate_frontier, node.block))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Makes sure we don't redundantly test this again.\n\t\t\t\t\t\tplaced_frontiers.insert(candidate_frontier);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only consider a frontier if we can reach node.block or its back edge from it.\n\t\t\t\t\tif (query_reachability_through_back_edges(*candidate_frontier, *node.block))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (frontier == nullptr || candidate_frontier->forward_post_visit_order > frontier->forward_post_visit_order)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Pick the earliest frontier in the CFG.\n\t\t\t\t\t\t\t// We want to merge top to bottom.\n\t\t\t\t\t\t\tfrontier = candidate_frontier;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (frontier)\n\t\t\t\tplaced_frontiers.insert(frontier);\n\t\t}\n\n\t\tassert(frontier);\n\n\t\tif (frontier == node.block)\n\t\t{\n\t\t\tif (frontier->pred.size() == 1 && !frontier->pred_back_edge)\n\t\t\t{\n\t\t\t\t// The PHI node has already been merged.\n\t\t\t\t// This can happen if a ladder pred block merged all inputs, and we would\n\t\t\t\t// end up with a single-pred PHI, which makes no sense (even if it should work).\n\t\t\t\t// Just copy the ID for the frontier node which made the final merge.\n\t\t\t\tauto itr = find_incoming_value(frontier->pred.front(), incoming_values);\n\t\t\t\tassert(itr != incoming_values.end());\n\n\t\t\t\tauto *op = module.allocate_op(spv::OpCopyObject, phi.id, phi.type_id);\n\t\t\t\top->add_id(itr->id);\n\t\t\t\tfrontier->pred.front()->ir.operations.push_back(op);\n\n\t\t\t\t// Ignore this one when emitting PHIs later.\n\t\t\t\tphi.id = 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tVector<IncomingValue> final_incoming;\n\n\t\t\t\t// Final merge.\n\t\t\t\tfor (auto *input : frontier->pred)\n\t\t\t\t{\n\t\t\t\t\tauto itr = find_incoming_value(input, incoming_values);\n\n\t\t\t\t\tIncomingValue value = {};\n\t\t\t\t\tif (itr != incoming_values.end())\n\t\t\t\t\t\tvalue.id = itr->id;\n\t\t\t\t\telse\n\t\t\t\t\t\tvalue.id = module.get_builder().createUndefined(phi.type_id);\n\n\t\t\t\t\tvalue.block = input;\n\t\t\t\t\tfinal_incoming.push_back(value);\n\t\t\t\t}\n\n\t\t\t\tif (frontier->pred_back_edge)\n\t\t\t\t{\n\t\t\t\t\tauto itr = find_incoming_value(frontier->pred_back_edge, incoming_values);\n\n\t\t\t\t\tIncomingValue value = {};\n\t\t\t\t\tif (itr != incoming_values.end())\n\t\t\t\t\t\tvalue.id = itr->id;\n\t\t\t\t\telse\n\t\t\t\t\t\tvalue.id = module.get_builder().createUndefined(phi.type_id);\n\n\t\t\t\t\tvalue.block = frontier->pred_back_edge;\n\t\t\t\t\tfinal_incoming.push_back(value);\n\t\t\t\t}\n\n\t\t\t\tincoming_values = std::move(final_incoming);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// A candidate dominance frontier is a place where we might want to place a PHI node in order to merge values.\n\t\t// For a successful iteration, we need to find at least one candidate where we can merge PHI.\n\n#ifdef PHI_DEBUG\n\t\tLOGI(\"Testing dominance frontier %s ...\\n\", frontier->name.c_str());\n#endif\n\n\t\t// Remove old inputs.\n\t\tPHI frontier_phi;\n\t\tfrontier_phi.id = module.allocate_id();\n\t\tfrontier_phi.type_id = phi.type_id;\n\t\tfrontier_phi.relaxed = phi.relaxed;\n\t\tmodule.get_builder().addName(frontier_phi.id, (String(\"frontier_phi_\") + frontier->name).c_str());\n\n\t\tassert(!frontier->pred_back_edge);\n\t\tfor (auto *input : frontier->pred)\n\t\t{\n\t\t\tauto itr = find_incoming_value(input, incoming_values);\n\t\t\tif (itr != incoming_values.end())\n\t\t\t{\n#ifdef PHI_DEBUG\n\t\t\t\tauto *incoming_block = itr->block;\n\t\t\t\tLOGI(\"   ... found incoming block %s for input %s.\\n\", incoming_block->name.c_str(), input->name.c_str());\n\t\t\t\tLOGI(\" ... For pred %s (%p), found incoming value from %s (%p)\\n\", input->name.c_str(),\n\t\t\t\t     static_cast<const void *>(input), incoming_block->name.c_str(),\n\t\t\t\t     static_cast<const void *>(incoming_block));\n#endif\n\n\t\t\t\tIncomingValue value = {};\n\t\t\t\tvalue.id = itr->id;\n\t\t\t\tvalue.block = input;\n\t\t\t\tfrontier_phi.incoming.push_back(value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n#ifdef PHI_DEBUG\n\t\t\t\tLOGI(\"   ... creating undefined input for %s\\n\", input->name.c_str());\n#endif\n\t\t\t\t// If there is no incoming value, we need to hallucinate an undefined value.\n\t\t\t\tIncomingValue value = {};\n\t\t\t\tvalue.id = module.get_builder().createUndefined(phi.type_id);\n\t\t\t\tvalue.block = input;\n\t\t\t\tfrontier_phi.incoming.push_back(value);\n\t\t\t}\n\t\t}\n\n\t\t// Do we remove the incoming value now or not?\n\t\t// If all paths from incoming value must go through frontier, we can remove it,\n\t\t// otherwise, we might still need to use the incoming value somewhere else.\n\t\tsize_t num_alive_incoming_values = incoming_values.size();\n\t\tfor (size_t i = 0; i < num_alive_incoming_values; )\n\t\t{\n\t\t\tauto *incoming_block = incoming_values[i].block;\n\n\t\t\t// This is fundamentally ambiguous and should never happen.\n\t\t\tif (incoming_block == frontier)\n\t\t\t\tLOGE(\"Invalid PHI collapse detected!\\n\");\n\t\t\tassert(incoming_block != frontier);\n\n\t\t\tif (!exists_path_in_cfg_without_intermediate_node(incoming_block, node.block, frontier))\n\t\t\t{\n#ifdef PHI_DEBUG\n\t\t\t\tLOGI(\"     ... removing input in %s\\n\", incoming_block->name.c_str());\n#endif\n\t\t\t\tif (i != num_alive_incoming_values - 1)\n\t\t\t\t\tstd::swap(incoming_values[num_alive_incoming_values - 1], incoming_values[i]);\n\t\t\t\tnum_alive_incoming_values--;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n#ifdef PHI_DEBUG\n\t\t\t\tLOGI(\"     ... keeping input in %s\\n\", incoming_block->name.c_str());\n#endif\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\t// Need to clean up exhausted incoming values after the loop,\n\t\t// since an incoming value can be used multiple times before a frontier PHI is resolved.\n\t\tincoming_values.erase(incoming_values.begin() + num_alive_incoming_values, incoming_values.end());\n\n\t\tIncomingValue *dominated_incoming = nullptr;\n\t\tfor (auto &incoming : incoming_values)\n\t\t{\n\t\t\tif (frontier->dominates(incoming.block) &&\n\t\t\t    !exists_path_in_cfg_without_intermediate_node(frontier, node.block, incoming.block))\n\t\t\t{\n\t\t\t\t// There should be only one block the frontier can dominate.\n\t\t\t\t// The candidate block must also post-dominate the frontier on the CFG subset which terminates at node.block,\n\t\t\t\t// otherwise we will get a proper merge later anyways.\n\t\t\t\tassert(!dominated_incoming);\n\t\t\t\tdominated_incoming = &incoming;\n\t\t\t}\n\t\t}\n\n\t\tif (dominated_incoming)\n\t\t{\n\t\t\t// If our frontier dominates another incoming block, we need to merge two incoming values\n\t\t\t// using an auxillary phi node as well as an OpSelect to resolve two conflicting values into one.\n\n\t\t\t// For every pred edge of the frontier where pred did not dominate, we are now suddenly dominating.\n\t\t\t// If we came from such a block,\n\t\t\t// we should replace the incoming value of dominating_incoming rather than adding a new incoming value.\n\t\t\tPHI merge_phi = {};\n\t\t\tmerge_phi.relaxed = phi.relaxed;\n\n\t\t\t// Here we need to figure out if we have a cross branch which functions as a ladder.\n\t\t\t// If we have such a special edge, the PHI value we find here will override any other value on this path.\n\t\t\t// However, if we only have expected branches, there is nothing to override, and any PHI values\n\t\t\t// we created along this path turned out to be irrelevant after all.\n\n\t\t\tunsigned normal_branch_count = 0;\n\t\t\tfor (auto *input : frontier->pred)\n\t\t\t{\n\t\t\t\tIncomingValue value = {};\n\t\t\t\tauto itr = find_incoming_value(input, incoming_values);\n\t\t\t\tif (itr != incoming_values.end())\n\t\t\t\t{\n\t\t\t\t\t// If the input does not dominate the frontier, this might be a case of cross-edge PHI merge.\n\t\t\t\t\t// However, if we still have an incoming value which dominates the input block, ignore.\n\t\t\t\t\t// This is considered a normal path and we will merge the actual result in a later iteration, because\n\t\t\t\t\t// the frontier is not a post-dominator of the input value.\n\t\t\t\t\tbool input_is_normal_edge = true;\n\t\t\t\t\tif (!input->dominates(frontier))\n\t\t\t\t\t{\n\t\t\t\t\t\tinput_is_normal_edge = false;\n\t\t\t\t\t\tfor (auto &incoming : incoming_values)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (incoming.block->dominates(input))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tinput_is_normal_edge = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (input_is_normal_edge)\n\t\t\t\t\t\tnormal_branch_count++;\n\n\t\t\t\t\tvalue.id = module.get_builder().makeBoolConstant(input_is_normal_edge);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// The input is undefined, so we don't really care. Just treat this as a normal edge.\n\t\t\t\t\tnormal_branch_count++;\n\t\t\t\t\tvalue.id = module.get_builder().makeBoolConstant(true);\n\t\t\t\t}\n\n\t\t\t\tvalue.block = input;\n\t\t\t\tmerge_phi.incoming.push_back(value);\n\t\t\t}\n\n\t\t\tif (normal_branch_count != frontier->pred.size())\n\t\t\t{\n\t\t\t\tmerge_phi.id = module.allocate_id();\n\t\t\t\tmerge_phi.type_id = module.get_builder().makeBoolType();\n\n\t\t\t\tOperation *op = module.allocate_op(spv::OpSelect, module.allocate_id(), phi.type_id);\n\t\t\t\top->add_id(merge_phi.id);\n\t\t\t\top->add_id(dominated_incoming->id);\n\t\t\t\top->add_id(frontier_phi.id);\n\t\t\t\tdominated_incoming->block->ir.operations.push_back(op);\n\t\t\t\tdominated_incoming->id = op->id;\n\n\t\t\t\tmodule.get_builder().addName(merge_phi.id,\n\t\t\t\t                             (String(\"merged_phi_\") + dominated_incoming->block->name).c_str());\n\t\t\t\tfrontier->ir.phi.push_back(std::move(merge_phi));\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Replace with merged value.\n\t\t\tIncomingValue new_incoming = {};\n\t\t\tnew_incoming.id = frontier_phi.id;\n\t\t\tnew_incoming.block = frontier;\n\t\t\tincoming_values.push_back(new_incoming);\n\t\t}\n\n#ifdef PHI_DEBUG\n\t\tLOGI(\"=========================\\n\");\n#endif\n\t\tfrontier->ir.phi.push_back(std::move(frontier_phi));\n\t}\n}\n\nvoid CFGStructurizer::compute_dominance_frontier()\n{\n\tfor (auto *node : forward_post_visit_order)\n\t\tnode->dominance_frontier.clear();\n\tfor (auto *node : forward_post_visit_order)\n\t\trecompute_dominance_frontier(node);\n}\n\nvoid CFGStructurizer::compute_post_dominance_frontier()\n{\n\tfor (auto *node : backward_post_visit_order)\n\t\tnode->post_dominance_frontier.clear();\n\tfor (auto *node : backward_post_visit_order)\n\t\trecompute_post_dominance_frontier(node);\n}\n\nvoid CFGStructurizer::build_immediate_dominators()\n{\n\tfor (auto i = forward_post_visit_order.size(); i; i--)\n\t{\n\t\tauto *block = forward_post_visit_order[i - 1];\n\t\tblock->recompute_immediate_dominator();\n\t}\n}\n\nvoid CFGStructurizer::build_immediate_post_dominators()\n{\n\tfor (auto i = backward_post_visit_order.size(); i; i--)\n\t{\n\t\tauto *block = backward_post_visit_order[i - 1];\n\t\tblock->recompute_immediate_post_dominator();\n\t}\n}\n\nvoid CFGStructurizer::reset_traversal()\n{\n\treachable_nodes.clear();\n\tforward_post_visit_order.clear();\n\tbackward_post_visit_order.clear();\n\n\tpool.for_each_node([](CFGNode &node) {\n\t\tnode.visited = false;\n\t\tnode.backward_visited = false;\n\t\tnode.traversing = false;\n\t\tnode.immediate_dominator = nullptr;\n\t\tnode.immediate_post_dominator = nullptr;\n\t\tnode.fake_pred.clear();\n\t\tnode.fake_succ.clear();\n\t\tnode.headers.clear();\n\n\t\tif (!node.freeze_structured_analysis)\n\t\t{\n\t\t\tnode.merge = MergeType::None;\n\t\t\tnode.loop_merge_block = nullptr;\n\t\t\tnode.loop_ladder_block = nullptr;\n\t\t\tnode.selection_merge_block = nullptr;\n\t\t}\n\n\t\tif (node.succ_back_edge)\n\t\t\tnode.succ.push_back(node.succ_back_edge);\n\t\tif (node.pred_back_edge)\n\t\t\tnode.pred.push_back(node.pred_back_edge);\n\t\tnode.succ_back_edge = nullptr;\n\t\tnode.pred_back_edge = nullptr;\n\t});\n}\n\nstruct LoopBacktracer\n{\n\tvoid trace_to_parent(CFGNode *header, CFGNode *block);\n\tUnorderedSet<CFGNode *> traced_blocks;\n};\n\nstruct LoopMergeTracer\n{\n\texplicit LoopMergeTracer(const LoopBacktracer &backtracer_)\n\t\t: backtracer(backtracer_)\n\t{\n\t}\n\n\tvoid trace_from_parent(CFGNode *header);\n\tconst LoopBacktracer &backtracer;\n\tVector<CFGNode *> loop_exits;\n\tUnorderedSet<CFGNode *> traced_blocks;\n};\n\nvoid LoopBacktracer::trace_to_parent(CFGNode *header, CFGNode *block)\n{\n\tif (block == header)\n\t{\n\t\ttraced_blocks.insert(block);\n\t\treturn;\n\t}\n\n\tif (traced_blocks.count(block) == 0)\n\t{\n\t\ttraced_blocks.insert(block);\n\t\tfor (auto *p : block->pred)\n\t\t\ttrace_to_parent(header, p);\n\n\t\t// A backtrace will not pick up continue blocks which only branch back to header,\n\t\t// and thus they will be considered loop exists by mistake.\n\t\t// Start traversing from the continue block to catch these nodes as well.\n\t\t// If a loop header is part of an outer loop construct, the loop body must\n\t\t// also be part of the loop construct.\n\t\tif (block->pred_back_edge)\n\t\t\ttrace_to_parent(header, block->pred_back_edge);\n\t}\n}\n\nvoid LoopMergeTracer::trace_from_parent(CFGNode *header)\n{\n\tif (backtracer.traced_blocks.count(header) == 0)\n\t{\n\t\tif (std::find(loop_exits.begin(), loop_exits.end(), header) == loop_exits.end())\n\t\t\tloop_exits.push_back(header);\n\t\treturn;\n\t}\n\n\tfor (auto *succ : header->succ)\n\t{\n\t\tif (traced_blocks.count(succ) == 0)\n\t\t{\n\t\t\ttrace_from_parent(succ);\n\t\t\ttraced_blocks.insert(succ);\n\t\t}\n\t}\n}\n\nvoid CFGStructurizer::backwards_visit()\n{\n\tVector<CFGNode *> leaf_nodes;\n\n\t// Traverse from leaf nodes, back through their preds instead.\n\t// Clear out some state set by forward visit earlier.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tnode->backward_visited = false;\n\t\tnode->traversing = false;\n\n\t\t// For loops which can only exit from their header block,\n\t\t// certain loops will be unreachable when doing a backwards traversal.\n\t\t// We'll visit them explicitly later.\n\t\tif (node->succ.empty() && !node->succ_back_edge)\n\t\t\tleaf_nodes.push_back(node);\n\t}\n\n\tfor (auto *leaf : leaf_nodes)\n\t\tbackwards_visit(*leaf);\n\n\t// It might be case that some continue blocks are not reachable through backwards traversal.\n\t// This effectively means that our flipped CFG is not reducible, which is rather annoying.\n\t// To work around this, we fake some branches from the continue block out to other blocks.\n\t// This way, we ensure that every forward-reachable block is reachable in a backwards traversal as well.\n\t// The algorithm works where given the innermost loop header A, a block B (A dom B) and continue block C,\n\t// For successors of B, we will observe some successors which can reach C ({E}), and some successors which can not reach C.\n\t// C will add fake successor edges to {E}.\n\tbool need_revisit = false;\n\tfor (size_t i = forward_post_visit_order.size(); i; i--)\n\t{\n\t\t// Resolve outer loops before inner loops since we can have nested loops which need\n\t\t// to link into each other.\n\t\tauto *node = forward_post_visit_order[i - 1];\n\n\t\tif (node->pred_back_edge)\n\t\t{\n\t\t\tif (!node->pred_back_edge->backward_visited)\n\t\t\t{\n\t\t\t\tLoopBacktracer tracer;\n\t\t\t\ttracer.trace_to_parent(node, node->pred_back_edge);\n\t\t\t\tLoopMergeTracer merge_tracer(tracer);\n\t\t\t\tmerge_tracer.trace_from_parent(node);\n\n\t\t\t\t// If we have an infinite loop, the continue block will not be reachable with backwards traversal.\n\t\t\t\t// Also, the only way to exit the loop construct could be through a single return block.\n\t\t\t\t// In this case, the return block should be moved and considered to be the merge block.\n\t\t\t\t// We add true branches from the continue block to return block instead of fake branches.\n\n\t\t\t\t// Ensure stable codegen order.\n\t\t\t\tVector<CFGNode *> exits;\n\t\t\t\texits.reserve(merge_tracer.loop_exits.size());\n\t\t\t\tfor (auto *exit_node : merge_tracer.loop_exits)\n\t\t\t\t\texits.push_back(exit_node);\n\t\t\t\tstd::sort(exits.begin(), exits.end(), [](const CFGNode *a, const CFGNode *b) {\n\t\t\t\t\treturn a->forward_post_visit_order > b->forward_post_visit_order;\n\t\t\t\t});\n\n\t\t\t\tbool transpose_loop_exit = false;\n\t\t\t\tif (exits.size() == 1)\n\t\t\t\t{\n\t\t\t\t\tauto *exit_node = exits.front();\n\t\t\t\t\t// If this is true, we never really leave the loop, which is problematic.\n\t\t\t\t\ttranspose_loop_exit = exit_node->dominates_all_reachable_exits();\n\n\t\t\t\t\t// Only transpose if we're the innermost header, otherwise, inner loops which try to branch\n\t\t\t\t\t// to the return will be considered a multi-break which is very awkward.\n\t\t\t\t\tif (transpose_loop_exit)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *innermost_header = get_innermost_loop_header_for(node, exit_node);\n\t\t\t\t\t\ttranspose_loop_exit = innermost_header == node;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (transpose_loop_exit)\n\t\t\t\t{\n\t\t\t\t\tfor (auto *f : exits)\n\t\t\t\t\t\tnode->pred_back_edge->add_branch(f);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Only consider exits that are themselves backwards reachable.\n\t\t\t\t\t// Otherwise, we'll be adding fake succs that resolve to outer infinite loops again.\n\t\t\t\t\tfor (auto *f : exits)\n\t\t\t\t\t\tif (f->reaches_backward_visited_node())\n\t\t\t\t\t\t\tnode->pred_back_edge->add_fake_branch(f);\n\t\t\t\t}\n\n\t\t\t\tif (!node->pred_back_edge->succ.empty() ||\n\t\t\t\t    !node->pred_back_edge->fake_succ.empty())\n\t\t\t\t{\n\t\t\t\t\t// Consider this to be backwards visited in case we have a nested inner loop\n\t\t\t\t\t// that needs to link up to node->pred_back_edge.\n\t\t\t\t\tnode->pred_back_edge->backward_visited = true;\n\t\t\t\t}\n\n\t\t\t\tneed_revisit = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (need_revisit)\n\t{\n\t\tfor (auto *node : forward_post_visit_order)\n\t\t{\n\t\t\tnode->backward_visited = false;\n\t\t\tnode->traversing = false;\n\t\t\tnode->backward_post_visit_order = 0;\n\t\t}\n\n\t\tfor (auto *leaf : leaf_nodes)\n\t\t\tbackwards_visit(*leaf);\n\t}\n\n\texit_block->backward_post_visit_order = backward_post_visit_order.size();\n\texit_block->immediate_post_dominator = exit_block;\n\texit_block->backward_visited = true;\n\tfor (auto *leaf : leaf_nodes)\n\t\tleaf->immediate_post_dominator = exit_block;\n}\n\nvoid CFGStructurizer::backwards_visit(CFGNode &entry)\n{\n\tentry.backward_visited = true;\n\n\tfor (auto *pred : entry.pred)\n\t\tif (!pred->backward_visited)\n\t\t\tbackwards_visit(*pred);\n\n\tfor (auto *pred : entry.fake_pred)\n\t\tif (!pred->backward_visited)\n\t\t\tbackwards_visit(*pred);\n\n\tentry.backward_post_visit_order = backward_post_visit_order.size();\n\tbackward_post_visit_order.push_back(&entry);\n}\n\nvoid CFGStructurizer::visit_for_back_edge_analysis(CFGNode &entry)\n{\n\tentry.visited = true;\n\tentry.traversing = true;\n\treachable_nodes.insert(&entry);\n\n\tfor (auto *succ : entry.succ)\n\t{\n\t\t// Reuse the existing vector to keep track of back edges.\n\t\tif (succ->traversing)\n\t\t\tsucc->fake_pred.push_back(&entry);\n\t\telse if (!succ->visited)\n\t\t\tvisit_for_back_edge_analysis(*succ);\n\t}\n\n\tentry.traversing = false;\n\n\t// After we get here, we must have observed all back edges.\n\t// If there is more than one back edge, merge them.\n\tif (entry.fake_pred.size() >= 2)\n\t{\n\t\tauto *new_back_edge = pool.create_node();\n\t\tnew_back_edge->name = entry.name + \".back-edge-merge\";\n\t\tfor (auto *n : entry.fake_pred)\n\t\t\tn->retarget_branch_pre_traversal(&entry, new_back_edge);\n\t\tnew_back_edge->succ.push_back(&entry);\n\t\tnew_back_edge->ir.terminator.type = Terminator::Type::Branch;\n\t\tnew_back_edge->ir.terminator.direct_block = &entry;\n\t\tnew_back_edge->add_branch(&entry);\n\t}\n}\n\nvoid CFGStructurizer::visit(CFGNode &entry)\n{\n\tentry.visited = true;\n\tentry.traversing = true;\n\treachable_nodes.insert(&entry);\n\n\tfor (auto *succ : entry.succ)\n\t{\n\t\tif (succ->traversing)\n\t\t{\n\t\t\t// For now, only support one back edge.\n\t\t\t// DXIL seems to obey this.\n\t\t\tassert(!entry.succ_back_edge || entry.succ_back_edge == succ);\n\t\t\tentry.succ_back_edge = succ;\n\n\t\t\t// For now, only support one back edge.\n\t\t\t// DXIL seems to obey this.\n\t\t\tassert(!succ->pred_back_edge || succ->pred_back_edge == &entry);\n\t\t\tsucc->pred_back_edge = &entry;\n\t\t}\n\t\telse if (!succ->visited)\n\t\t\tvisit(*succ);\n\t}\n\n\t// Any back edges need to be handled specifically, only keep forward edges in succ/pred lists.\n\t// This avoids any infinite loop scenarios and needing to special case a lot of checks.\n\tif (entry.succ_back_edge)\n\t{\n\t\tauto itr = std::find(entry.succ.begin(), entry.succ.end(), entry.succ_back_edge);\n\t\tif (itr != entry.succ.end())\n\t\t\tentry.succ.erase(itr);\n\t}\n\n\tif (entry.pred_back_edge)\n\t{\n\t\tauto itr = std::find(entry.pred.begin(), entry.pred.end(), entry.pred_back_edge);\n\t\tif (itr != entry.pred.end())\n\t\t\tentry.pred.erase(itr);\n\t}\n\n\tentry.traversing = false;\n\tentry.forward_post_visit_order = forward_post_visit_order.size();\n\tforward_post_visit_order.push_back(&entry);\n}\n\nvoid CFGStructurizer::merge_to_succ(CFGNode *node, unsigned index)\n{\n\tnode->succ[index]->headers.push_back(node);\n\tnode->selection_merge_block = node->succ[index];\n\tnode->merge = MergeType::Selection;\n\t//LOGI(\"Fixup selection merge %s -> %s\\n\", node->name.c_str(), node->selection_merge_block->name.c_str());\n}\n\nvoid CFGStructurizer::isolate_structured(UnorderedSet<CFGNode *> &nodes, const CFGNode *header,\n                                         const CFGNode *merge)\n{\n\tfor (auto *pred : merge->pred)\n\t{\n\t\tif (pred != header && nodes.count(pred) == 0)\n\t\t{\n\t\t\tnodes.insert(pred);\n\t\t\tisolate_structured(nodes, header, pred);\n\t\t}\n\t}\n}\n\nVector<CFGNode *> CFGStructurizer::isolate_structured_sorted(const CFGNode *header, const CFGNode *merge)\n{\n\tUnorderedSet<CFGNode *> nodes;\n\tisolate_structured(nodes, header, merge);\n\n\tVector<CFGNode *> sorted;\n\tsorted.reserve(nodes.size());\n\n\tfor (auto *node : nodes)\n\t\tsorted.push_back(node);\n\n\tstd::sort(sorted.begin(), sorted.end(),\n\t          [](const CFGNode *a, const CFGNode *b) { return a->forward_post_visit_order > b->forward_post_visit_order; });\n\treturn sorted;\n}\n\nbool CFGStructurizer::block_is_load_bearing(const CFGNode *node, const CFGNode *merge) const\n{\n\twhile (merge->succ.size() == 1)\n\t{\n\t\t// If we're going to eliminate a block due to impossible merge,\n\t\t// we should look ahead since we might get a false positive.\n\t\tbool breaking = merge_candidate_is_on_breaking_path(merge);\n\t\tif (breaking && !merge->ir.operations.empty() && !block_is_control_dependent(merge))\n\t\t\tmerge = merge->succ.front();\n\t\telse\n\t\t\tbreak;\n\t}\n\n\treturn node->pred.size() >= 2 &&\n\t       !exists_path_in_cfg_without_intermediate_node(node->immediate_dominator, merge, node);\n}\n\nbool CFGStructurizer::control_flow_is_escaping_from_loop(const CFGNode *node, const CFGNode *merge) const\n{\n\tbool escaping_path = false;\n\n\tif (node == merge)\n\t\treturn escaping_path;\n\n\tassert(merge->post_dominates(node));\n\n\t// First, test the loop scenario.\n\t// If we're inside a loop, we're a break construct if we can prove that:\n\t// - node has a loop header which dominates it.\n\t// - node cannot reach the continue block.\n\t// - Continue block cannot reach node.\n\t// - All post-domination frontiers can reach the continue block, meaning that at some point control flow\n\t//   decided to break out of the loop construct.\n\tauto *innermost_loop_header = get_innermost_loop_header_for(node);\n\tif (innermost_loop_header && innermost_loop_header->pred_back_edge)\n\t{\n\t\tbool dominates_merge = node->dominates(merge);\n\t\tbool can_reach_continue = query_reachability(*node, *innermost_loop_header->pred_back_edge);\n\t\tbool continue_can_reach = query_reachability(*innermost_loop_header->pred_back_edge, *node);\n\t\tbool pdf_can_reach_continue = true;\n\n\t\tfor (auto *frontier : node->post_dominance_frontier)\n\t\t{\n\t\t\tbool header_dominates_frontier = innermost_loop_header->dominates(frontier);\n\t\t\tbool frontier_is_inside_loop_construct =\n\t\t\t\tquery_reachability(*frontier, *innermost_loop_header->pred_back_edge);\n\t\t\tif (!header_dominates_frontier || !frontier_is_inside_loop_construct)\n\t\t\t{\n\t\t\t\tpdf_can_reach_continue = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!dominates_merge && !continue_can_reach && !can_reach_continue && pdf_can_reach_continue)\n\t\t\tescaping_path = true;\n\t}\n\n\treturn escaping_path;\n}\n\nbool CFGStructurizer::control_flow_is_escaping(const CFGNode *node, const CFGNode *merge) const\n{\n\tif (node == merge)\n\t\treturn false;\n\n\tif (control_flow_is_escaping_from_loop(node, merge))\n\t\treturn true;\n\n\t// Try to test if our block is load bearing, in which case it cannot be considered a break block.\n\t// If the only path from idom to merge goes through node, it must be considered load bearing,\n\t// since removing break paths must not change reachability.\n\tif (block_is_load_bearing(node, merge))\n\t\treturn false;\n\n\t// If we have two different switch blocks in our PDF frontier something ridiculous is happening\n\t// where we effectively have one switch block falling through to another switch block (?!?!?!)\n\t// Definitely needs to be split up.\n\tunsigned switch_pdf_frontiers = 0;\n\tfor (auto *frontier : node->post_dominance_frontier)\n\t\tif (frontier->ir.terminator.type == Terminator::Type::Switch)\n\t\t\tswitch_pdf_frontiers++;\n\n\tif (switch_pdf_frontiers >= 2)\n\t\treturn true;\n\n\t// If we cannot prove the escape through loop analysis, we might be able to deduce it from domination frontiers.\n\t// If control flow is not escaping, then there must exist a dominance frontier node A,\n\t// where merge strictly post-dominates A.\n\t// This means that control flow can merge somewhere before we hit the merge block, and we consider that\n\t// normal structured control flow.\n\n\tbool escaping_path = !node->reaches_domination_frontier_before_merge(merge);\n\n\t// This is a strong check.\n\t// If node directly branches to merge, but PDF does not,\n\t// we have detected a control flow pattern which is clearly a break.\n\t// The PDF candidate must dominate node for this check to be meaningful.\n\tif (escaping_path)\n\t{\n\t\tfor (auto *frontier : node->post_dominance_frontier)\n\t\t\tif (frontier->dominates(node) && frontier->reaches_domination_frontier_before_merge(merge))\n\t\t\t\treturn true;\n\n\t\t// Strong check as well.\n\t\t// If branching directly to continue block like this, this is a non-merging continue,\n\t\t// which we should always consider an escape.\n\t\tif (node->succ.size() == 1 && node->succ.front()->succ_back_edge)\n\t\t\treturn true;\n\t}\n\n\tif (escaping_path && node->ir.operations.empty() && node->ir.phi.empty())\n\t{\n\t\t// If we post-dominate nothing useful or do nothing useful ourselves,\n\t\t// this is a good indication we're a common escape edge ladder block.\n\t\t// This can happen if we have a graph of:\n\t\t// A -> B\n\t\t// A -> C\n\t\t// B -> merge\n\t\t// C -> merge\n\t\t// B -> node\n\t\t// C -> node\n\t\t// node -> merge\n\t\t// This super jank diamond pattern will break the heuristics.\n\n\t\t// If we only post dominate work from one pred, we're not meaningfully merging anything,\n\t\t// so it should be safe to elide.\n\t\tif (node->count_post_dominates_work_from_incoming_preds() <= 1)\n\t\t\treturn true;\n\t}\n\n\tif (escaping_path && node->pred.size() >= 2)\n\t{\n\t\t// We also need to consider false positives here, which are mostly only relevant for merge candidates.\n\n\t\t// One case would be selection construct A, which terminates in block B. B then branches to C.\n\t\t// Earlier in the A -> B construct, there might be a break block D which also branches to B.\n\t\t// This means that C will be a \"false\" domination frontier of B and our analysis above is wrong.\n\n\t\t// The algorithm here:\n\t\t// - Get idom of node, which represents the header. For this analysis, we're only interested\n\t\t//   in code paths which are dominated by idom.\n\t\t// - Find all preds of merge which are dominated by idom(node).\n\t\t// - Backtrace every pred P until they can reach B, or B can reach P.\n\t\t// - If B has strictly lowest post-visit order, we are not escaping. P was.\n\n\t\tauto *idom = node->immediate_dominator;\n\t\tbool found_false_positive = false;\n\n\t\tfor (auto *pred : merge->pred)\n\t\t{\n\t\t\t// Don't care about these.\n\t\t\tif (!idom->dominates(pred))\n\t\t\t\tcontinue;\n\n\t\t\twhile (pred != node && !query_reachability(*pred, *node) && !query_reachability(*node, *pred))\n\t\t\t\tpred = pred->immediate_dominator;\n\n\t\t\t// Ignore these.\n\t\t\tif (pred == node)\n\t\t\t\tcontinue;\n\n\t\t\tif (query_reachability(*pred, *node))\n\t\t\t{\n\t\t\t\t// Seems good. Keep going. If we don't find a counter example, we'll accept this as a false positive.\n\t\t\t\tfound_false_positive = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Indeed, this is an escape.\n\t\t\t\tfound_false_positive = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tescaping_path = !found_false_positive;\n\t}\n\n\treturn escaping_path;\n}\n\nbool CFGStructurizer::block_is_plain_continue(const CFGNode *node)\n{\n\treturn node->succ_back_edge != nullptr && node != node->succ_back_edge;\n}\n\nconst CFGNode *CFGStructurizer::scan_plain_continue_block(const CFGNode *node)\n{\n\tauto *base_node = node;\n\twhile (!block_is_plain_continue(node) &&\n\t       base_node->dominates(node) &&\n\t       !node->succ_back_edge &&\n\t       !node->pred_back_edge &&\n\t       node->immediate_post_dominator &&\n\t       node->immediate_post_dominator != node)\n\t{\n\t\tnode = node->immediate_post_dominator;\n\t}\n\n\treturn node;\n}\n\nbool CFGStructurizer::selection_requires_structured_header(const CFGNode *node) const\n{\n\t// From SPIR-V spec. SelectionMerge is required for:\n\t// ... an OpBranchConditional instruction that has different\n\t// True Label and False Label operands where neither are declared merge blocks or Continue Targets.\n\t// Ensure that there is a real merge block.\n\t// Only safe to do this in pass1, since we're not supposed to rewrite control flow there.\n\t// In first passes, it's okay to merge in the wrong direction.\n\n\t// Only consider normal selection merges. Switch and loop exits are stronger than selection exits,\n\t// so we don't need to apply special cases.\n\t// This consideration is purely to avoid excessive deltas in shader outputs, and having merge\n\t// blocks makes SPIRV-Cross output a little more readable.\n\tassert(node->succ.size() == 2 && !node->succ_back_edge);\n\n\t// We can use proper merge blocks if both paths converge to same location.\n\t// If we have a direct branch to continue block on one path,\n\t// we can use merge blocks in the opposing path just fine.\n\tfor (int i = 0; i < 2; i++)\n\t\tif (query_reachability(*node->succ[i], *node->succ[1 - i]) || block_is_plain_continue(node->succ[i]))\n\t\t\treturn true;\n\n\tfor (int i = 0; i < 2; i++)\n\t{\n\t\tauto *s = node->succ[i];\n\n\t\tbool succ_is_plain_selection_merge =\n\t\t\tstd::find_if(s->headers.begin(), s->headers.end(), [&](const CFGNode *head) {\n\t\t\t  return head->ir.terminator.type != Terminator::Type::Switch &&\n\t\t\t         head->merge == MergeType::Selection && head->selection_merge_block == s;\n\t\t\t}) != s->headers.end();\n\n\t\tif (succ_is_plain_selection_merge)\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nvoid CFGStructurizer::fixup_broken_selection_merges(unsigned pass)\n{\n\t// Here we deal with selection branches where one path breaks and one path merges.\n\t// This is common case for ladder blocks where we need to merge to the \"true\" merge block.\n\t// The selection header has two succs, but the merge block might only have one pred block,\n\t// which means it was not considered a merge candidate earlier in find_selection_merges().\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->succ.size() != 2)\n\t\t\tcontinue;\n\t\tif (node->merge != MergeType::None)\n\t\t\tcontinue;\n\n\t\t// A continue block will never need to merge execution, but it shouldn't have succ.size() == 2,\n\t\t// but rather succ.size() == 1 and a back edge.\n\t\tif (node->succ_back_edge)\n\t\t\tcontinue;\n\n\t\tbool dominates_a = node->dominates(node->succ[0]);\n\t\tbool dominates_b = node->dominates(node->succ[1]);\n\n\t\t// Continue blocks should also be considered to have a header already. Makes sure we don't merge to them.\n\t\tbool merge_a_has_header = !node->succ[0]->headers.empty() || block_is_plain_continue(node->succ[0]);\n\t\tbool merge_b_has_header = !node->succ[1]->headers.empty() || block_is_plain_continue(node->succ[1]);\n\n\t\tif (pass == 1 && !selection_requires_structured_header(node))\n\t\t\tcontinue;\n\n\t\tint trivial_merge_index = -1;\n\n\t\t// Only allow the obvious merge candidates in pass 1.\n\t\t// In pass 0, we might have a clear merge candidate,\n\t\t// but the other path might be an escaping edge, which needs to be considered.\n\t\tif (dominates_a && !dominates_b && !merge_a_has_header)\n\t\t{\n\t\t\t// A is obvious candidate. B is a direct break/continue construct target most likely.\n\t\t\tmerge_to_succ(node, 0);\n\t\t\ttrivial_merge_index = 0;\n\t\t}\n\t\telse if (dominates_b && !dominates_a && !merge_b_has_header)\n\t\t{\n\t\t\t// B is obvious candidate. A is a direct break/continue construct target most likely.\n\t\t\tmerge_to_succ(node, 1);\n\t\t\ttrivial_merge_index = 1;\n\t\t}\n\t\telse if (dominates_a && dominates_b && !merge_a_has_header && merge_b_has_header)\n\t\t{\n\t\t\t// Not as obvious of a candidate, but this can happen if one path hits continue block,\n\t\t\t// and other path hits a ladder merge block.\n\t\t\t// For do/while(false) style loop, the loop body may dominate the merge block.\n\t\t\tmerge_to_succ(node, 0);\n\t\t\ttrivial_merge_index = 0;\n\t\t}\n\t\telse if (dominates_a && dominates_b && !merge_b_has_header && merge_a_has_header)\n\t\t{\n\t\t\t// Not as obvious of a candidate, but this can happen if one path hits continue block,\n\t\t\t// and other path hits a ladder merge block.\n\t\t\t// For do/while style loop, the loop body may dominate the merge block.\n\t\t\tmerge_to_succ(node, 1);\n\t\t\ttrivial_merge_index = 1;\n\t\t}\n\t\telse if (dominates_a && dominates_b && !merge_a_has_header && !merge_b_has_header)\n\t\t{\n\t\t\t// We could merge to both, no obvious merge point.\n\t\t\t// Figure out where execution reconvenes.\n\t\t\t// If we have a \"break\"-like construct inside a selection construct, we will not end up dominating the merge block.\n\t\t\t// This will be fixed up with ladder constructs later in first pass.\n\n\t\t\t// In second pass, we will have redirected any branches which escape through a ladder block.\n\t\t\t// If we find that one path of the selection construct must go through that ladder block, we know we have a break construct.\n\t\t\tCFGNode *merge = CFGStructurizer::find_common_post_dominator(node->succ);\n\t\t\tif (merge)\n\t\t\t{\n\t\t\t\tbool dominates_merge = node->dominates(merge);\n\t\t\t\tbool merges_to_continue = block_is_plain_continue(merge);\n\n\t\t\t\t// Here we have a likely case where one block is doing a clean \"break\" out of a loop, and\n\t\t\t\t// the other path continues as normal, and then conditionally breaks in a continue block or something similar.\n\t\t\t\tbool ambiguous_merge_case = !merges_to_continue && dominates_merge && !merge->headers.empty();\n\n\t\t\t\t// Happens first iteration. We'll have to split blocks, so register a merge target where we want it.\n\t\t\t\t// Otherwise, this is the easy case if we observe it in pass 1.\n\t\t\t\t// This shouldn't really happen though, as we'd normally resolve this earlier in find_selection_merges.\n\t\t\t\tbool mark_merge_block_case = !merges_to_continue && (merge->headers.empty() || pass == 0);\n\n\t\t\t\t// Another scenario is that we don't dominate the merge block in pass 1. We cannot split blocks now.\n\t\t\t\t// Check to see which paths can actually reach the merge target without going through a ladder block.\n\t\t\t\t// If we don't go through ladder it means an outer scope will actually reach the merge node.\n\t\t\t\t// If we reach a ladder it means a block we dominate will make the escape.\n\n\t\t\t\t// If we're in pass 1 and we still don't dominate our merge target, consider it ambiguous.\n\t\t\t\tif (pass == 1 && !dominates_merge)\n\t\t\t\t\tambiguous_merge_case = true;\n\n\t\t\t\t// Another case is when one path is \"breaking\" out to a continue block which we don't dominate.\n\t\t\t\t// We should not attempt to do ladder breaking here in pass 0 since it's unnecessary.\n\t\t\t\tbool tie_break_merge = ambiguous_merge_case || !mark_merge_block_case;\n\n\t\t\t\tbool a_path_is_break = control_flow_is_escaping(node->succ[0], merge);\n\t\t\t\tbool a_path_is_continue = block_is_plain_continue(scan_plain_continue_block(node->succ[0]));\n\t\t\t\tbool b_path_is_break = control_flow_is_escaping(node->succ[1], merge);\n\t\t\t\tbool b_path_is_continue = block_is_plain_continue(scan_plain_continue_block(node->succ[1]));\n\n\t\t\t\tbool a_path_is_break_or_continue = a_path_is_break || a_path_is_continue;\n\t\t\t\tbool b_path_is_break_or_continue = b_path_is_break || b_path_is_continue;\n\n\t\t\t\t// Continue is stronger than break. A breaking path may still need to merge control flow\n\t\t\t\t// especially if that breaking path is very complicated. If we detect continue, the back-edge\n\t\t\t\t// post-dominates our succ, so we are guaranteed to never need to merge control flow on that path.\n\t\t\t\t// Demote the other path to a non-breaking path.\n\t\t\t\tif (a_path_is_continue != b_path_is_continue)\n\t\t\t\t{\n\t\t\t\t\ttie_break_merge = true;\n\t\t\t\t\tif (a_path_is_continue)\n\t\t\t\t\t\tb_path_is_break_or_continue = false;\n\t\t\t\t\telse\n\t\t\t\t\t\ta_path_is_break_or_continue = false;\n\t\t\t\t}\n\n\t\t\t\tif (tie_break_merge)\n\t\t\t\t{\n\t\t\t\t\tif (a_path_is_break_or_continue && b_path_is_break_or_continue)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Both paths break, so we don't need to merge anything. Use Unreachable merge target.\n\t\t\t\t\t\tnode->merge = MergeType::Selection;\n\t\t\t\t\t\tnode->selection_merge_block = nullptr;\n\t\t\t\t\t\t//LOGI(\"Merging %s -> Unreachable\\n\", node->name.c_str());\n\t\t\t\t\t}\n\t\t\t\t\telse if (b_path_is_break_or_continue)\n\t\t\t\t\t\tmerge_to_succ(node, 0);\n\t\t\t\t\telse if (a_path_is_break_or_continue)\n\t\t\t\t\t\tmerge_to_succ(node, 1);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Need more interesting tie-breaking.\n\t\t\t\t\t\t// We can deduce which path is breaking or not based on the dominance frontier.\n\t\t\t\t\t\t// If a dominance frontier for A can reach B, then we assume that B is breaking further than A\n\t\t\t\t\t\t// is, so we should merge to A.\n\t\t\t\t\t\t// The breaking path for B will likely need to ensure that the selection header can\n\t\t\t\t\t\t// support such a break.\n\t\t\t\t\t\t// If we hit this path, the common post-dominator will not find the intended merge\n\t\t\t\t\t\t// target for B, so we never get to perform the necessary fixup.\n\t\t\t\t\t\tauto *a_front = node->succ[0]->dominance_frontier.size() == 1 ?\n\t\t\t\t\t\t                node->succ[0]->dominance_frontier.front() : nullptr;\n\t\t\t\t\t\tauto *b_front = node->succ[1]->dominance_frontier.size() == 1 ?\n\t\t\t\t\t\t                node->succ[1]->dominance_frontier.front() : nullptr;\n\t\t\t\t\t\tbool found_candidate = false;\n\n\t\t\t\t\t\tCFGNode *inner_merge_candidate = nullptr;\n\n\t\t\t\t\t\t// If there is no unique dominance frontier for one path, pick the one that has a unique frontier\n\t\t\t\t\t\t// as that in considered a merge.\n\t\t\t\t\t\tif ((a_front || b_front) && a_front != b_front)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!b_front || (a_front && query_reachability(*a_front, *b_front)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmerge_to_succ(node, 0);\n\t\t\t\t\t\t\t\tinner_merge_candidate = b_front;\n\t\t\t\t\t\t\t\tfound_candidate = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (!a_front || (b_front && query_reachability(*b_front, *a_front)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmerge_to_succ(node, 1);\n\t\t\t\t\t\t\t\tinner_merge_candidate = a_front;\n\t\t\t\t\t\t\t\tfound_candidate = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!found_candidate)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnode->merge = MergeType::Selection;\n\t\t\t\t\t\t\tnode->selection_merge_block = nullptr;\n\n\t\t\t\t\t\t\tif (a_front && b_front && a_front->headers.size() == 1 && b_front->headers.size() == 1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Extremely ambiguous merge where the selection construct can merge to two different paths.\n\t\t\t\t\t\t\t\t// Our only option at this point is to pick an arbitrary winner\n\t\t\t\t\t\t\t\t// and consider one path the breaking one arbitrarily.\n\t\t\t\t\t\t\t\tauto *a_header = a_front->headers.front();\n\t\t\t\t\t\t\t\tauto *b_header = b_front->headers.front();\n\n\t\t\t\t\t\t\t\t// Pick the largest enclosing header as a heuristic.\n\t\t\t\t\t\t\t\tinner_merge_candidate =\n\t\t\t\t\t\t\t\t\ta_header->forward_post_visit_order > b_header->forward_post_visit_order ?\n\t\t\t\t\t\t\t\t\ta_front : b_front;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inner_merge_candidate && inner_merge_candidate->headers.size() == 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// The breaking path tries to break to this node.\n\t\t\t\t\t\t\t// This will only trigger in pass 1.\n\t\t\t\t\t\t\tauto *header = inner_merge_candidate->headers.front();\n\t\t\t\t\t\t\tif (header->merge == MergeType::Selection)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Promote to loop header instead.\n\t\t\t\t\t\t\t\t// We might have to enter the loop ladder fixup stages later\n\t\t\t\t\t\t\t\t// to insert ladders as required.\n\t\t\t\t\t\t\t\theader->merge = MergeType::Loop;\n\t\t\t\t\t\t\t\theader->loop_merge_block = header->selection_merge_block;\n\t\t\t\t\t\t\t\theader->selection_merge_block = nullptr;\n\t\t\t\t\t\t\t\theader->freeze_structured_analysis = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tassert(merge);\n\t\t\t\t\tnode->selection_merge_block = merge;\n\t\t\t\t\tnode->merge = MergeType::Selection;\n\t\t\t\t\tmerge->headers.push_back(node);\n\t\t\t\t\t//LOGI(\"Merging %s -> %s\\n\", node->name.c_str(), node->selection_merge_block->name.c_str());\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We likely had one side of the branch take an \"exit\", in which case there is no common post-dominator.\n\t\t\t\tbool a_dominates_exit = node->succ[0]->dominates_all_reachable_exits();\n\t\t\t\tbool b_dominates_exit = node->succ[1]->dominates_all_reachable_exits();\n\t\t\t\tif (!a_dominates_exit && b_dominates_exit)\n\t\t\t\t\tmerge_to_succ(node, 0);\n\t\t\t\telse if (!b_dominates_exit && a_dominates_exit)\n\t\t\t\t\tmerge_to_succ(node, 1);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Both paths lead to exit. Do we even need to merge here?\n\t\t\t\t\t// In worst case we can always merge to an unreachable node in the CFG.\n\t\t\t\t\tnode->merge = MergeType::Selection;\n\t\t\t\t\tnode->selection_merge_block = nullptr;\n\n\t\t\t\t\tconst auto node_is_degenerate_merge_block = [](const CFGNode *n) {\n\t\t\t\t\t\treturn n->ir.terminator.type == Terminator::Type::Unreachable ||\n\t\t\t\t\t\t       (n->ir.terminator.type == Terminator::Type::Return &&\n\t\t\t\t\t\t        n->ir.operations.empty());\n\t\t\t\t\t};\n\n\t\t\t\t\t// In some cases however, we have to try even harder to tie-break these blocks,\n\t\t\t\t\t// since post-domination analysis may break due to early exit blocks.\n\t\t\t\t\t// Use principle of least break to tie-break.\n\t\t\t\t\tif (node->succ[0]->dominance_frontier.size() == 1 &&\n\t\t\t\t\t    node->succ[1]->dominance_frontier.size() == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *a_frontier = node->succ[0]->dominance_frontier.front();\n\t\t\t\t\t\tauto *b_frontier = node->succ[1]->dominance_frontier.front();\n\t\t\t\t\t\tif (a_frontier != b_frontier)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Try to merge in the direction of early returns, since the other direction\n\t\t\t\t\t\t\t// will likely result in a loop break or something like that.\n\t\t\t\t\t\t\t// Inner constructs tend to use weaker selection merges, which means we need\n\t\t\t\t\t\t\t// to merge in that direction to stay valid.\n\t\t\t\t\t\t\tif (query_reachability(*a_frontier, *b_frontier))\n\t\t\t\t\t\t\t\tmerge_to_succ(node, 0);\n\t\t\t\t\t\t\telse if (query_reachability(*b_frontier, *a_frontier))\n\t\t\t\t\t\t\t\tmerge_to_succ(node, 1);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tauto a_succ_count = a_frontier->succ.size();\n\t\t\t\t\t\t\t\tauto b_succ_count = b_frontier->succ.size();\n\n\t\t\t\t\t\t\t\t// First look at the idoms. This can give us an idea how the code is nested.\n\t\t\t\t\t\t\t\t// Merge towards innermost idom.\n\t\t\t\t\t\t\t\t// If that fails, merge against early returns as a last resort.\n\n\t\t\t\t\t\t\t\ta_frontier = a_frontier->immediate_dominator;\n\t\t\t\t\t\t\t\tb_frontier = b_frontier->immediate_dominator;\n\t\t\t\t\t\t\t\tif (a_frontier != b_frontier && query_reachability(*a_frontier, *b_frontier))\n\t\t\t\t\t\t\t\t\tmerge_to_succ(node, 1);\n\t\t\t\t\t\t\t\telse if (a_frontier != b_frontier && query_reachability(*b_frontier, *a_frontier))\n\t\t\t\t\t\t\t\t\tmerge_to_succ(node, 0);\n\t\t\t\t\t\t\t\telse if (a_succ_count == 0 && b_succ_count != 0)\n\t\t\t\t\t\t\t\t\tmerge_to_succ(node, 0);\n\t\t\t\t\t\t\t\telse if (b_succ_count == 0 && a_succ_count != 0)\n\t\t\t\t\t\t\t\t\tmerge_to_succ(node, 1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (node_is_degenerate_merge_block(node->succ[1]) &&\n\t\t\t\t\t         !node_is_degenerate_merge_block(node->succ[0]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Try to merge away from blank returns.\n\t\t\t\t\t\tmerge_to_succ(node, 0);\n\t\t\t\t\t}\n\t\t\t\t\telse if (node_is_degenerate_merge_block(node->succ[0]) &&\n\t\t\t\t\t         !node_is_degenerate_merge_block(node->succ[1]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Try to merge away from blank returns.\n\t\t\t\t\t\tmerge_to_succ(node, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (pass == 0)\n\t\t{\n\t\t\t// No possible merge target. Just need to pick whatever node is the merge block here.\n\t\t\t// Only do this in first pass, so that we can get a proper ladder breaking mechanism in place if we are escaping.\n\t\t\tCFGNode *merge = CFGStructurizer::find_common_post_dominator(node->succ);\n\n\t\t\tif (merge)\n\t\t\t{\n\t\t\t\t// Don't try to merge to our switch block.\n\t\t\t\tauto *inner_header = node->get_outer_header_dominator();\n\t\t\t\tbool conditional_switch_break = inner_header && inner_header->merge == MergeType::Selection &&\n\t\t\t\t                                inner_header->selection_merge_block == merge;\n\n\t\t\t\tif (!conditional_switch_break)\n\t\t\t\t{\n\t\t\t\t\tnode->selection_merge_block = merge;\n\t\t\t\t\tnode->merge = MergeType::Selection;\n\t\t\t\t\tmerge->headers.push_back(node);\n\t\t\t\t\t//LOGI(\"Merging %s -> %s\\n\", node->name.c_str(), node->selection_merge_block->name.c_str());\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t//LOGI(\"Cannot find a merge target for block %s ...\\n\", node->name.c_str());\n\t\t\t}\n\t\t}\n\n\t\tif (trivial_merge_index >= 0 && pass == 0)\n\t\t{\n\t\t\tCFGNode *merge = CFGStructurizer::find_common_post_dominator(node->succ);\n\t\t\tif (merge && !node->dominates(merge) && !block_is_plain_continue(merge))\n\t\t\t{\n\t\t\t\tif (!merge->headers.empty())\n\t\t\t\t{\n\t\t\t\t\t// We might have a trivial merge, yet the other branch direction\n\t\t\t\t\t// is a breaking construct. We will have to split some blocks.\n\t\t\t\t\tmerge->headers.push_back(node);\n\t\t\t\t}\n\n\t\t\t\tauto *current_candidate = node->succ[trivial_merge_index];\n\t\t\t\tauto *other_candidate = node->succ[1 - trivial_merge_index];\n\n\t\t\t\tbool current_escapes = current_candidate == merge || control_flow_is_escaping(current_candidate, merge);\n\n\t\t\t\t// It's possible that our other candidate is a merge target. If we don't dominate the candidate,\n\t\t\t\t// it means it's on the dominance frontier and we should not consider it escaping.\n\n\t\t\t\t// Trivial heuristic for escape.\n\t\t\t\tbool other_escapes = other_candidate == merge || block_is_plain_continue(other_candidate);\n\n\t\t\t\t// Second level heuristic.\n\t\t\t\tif (!other_escapes && control_flow_is_escaping(other_candidate, merge))\n\t\t\t\t{\n\t\t\t\t\t// Final layer of hell.\n\t\t\t\t\tif (node->dominates(other_candidate))\n\t\t\t\t\t{\n\t\t\t\t\t\t// There is no frontier, so we accept escape analysis as-is.\n\t\t\t\t\t\tother_escapes = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// This is a frontier, so it shouldn't be considered an escape,\n\t\t\t\t\t\t// but if this is a \"weak\" frontier, we can avoid creating a dummy interim block.\n\t\t\t\t\t\t// If the other candidate is a loop merge, then we will resolve the merge in another way,\n\t\t\t\t\t\t// which will make the interim block superfluous.\n\t\t\t\t\t\tbool other_is_loop_merge_candidate =\n\t\t\t\t\t\t\tother_candidate->headers.size() == 1 &&\n\t\t\t\t\t\t\tother_candidate->headers.front()->merge == MergeType::Loop &&\n\t\t\t\t\t\t\t(other_candidate->headers.front()->loop_merge_block == other_candidate ||\n\t\t\t\t\t\t\t other_candidate->headers.front()->loop_ladder_block == other_candidate);\n\t\t\t\t\t\tother_escapes = other_is_loop_merge_candidate;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!current_escapes && !other_escapes)\n\t\t\t\t{\n\t\t\t\t\t// Neither is considered an escape. This is strange and should not happen unless we have\n\t\t\t\t\t// a fake frontier block to contend with.\n\t\t\t\t\t// Attempt to tie-break by observing if current candidate has a direct branch to merge,\n\t\t\t\t\t// but other does not.\n\t\t\t\t\tif (std::find(current_candidate->succ.begin(), current_candidate->succ.end(), merge) != current_candidate->succ.end() &&\n\t\t\t\t\t    std::find(other_candidate->succ.begin(), other_candidate->succ.end(), merge) == other_candidate->succ.end())\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrent_escapes = true;\n\n\t\t\t\t\t\t// If current candidate's frontier can reach the other candidate directly,\n\t\t\t\t\t\t// this is a final tie-break to show that we should accept the current situation.\n\t\t\t\t\t\tfor (auto *frontier : current_candidate->dominance_frontier)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (frontier != other_candidate && query_reachability(*frontier, *other_candidate))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcurrent_escapes = false;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If we tried to merge in a direction which is a breaking construct,\n\t\t\t\t// this means that the other path is actual desired break path.\n\t\t\t\tif (current_escapes && !other_escapes)\n\t\t\t\t{\n\t\t\t\t\tauto *target_block = node->succ[1 - trivial_merge_index];\n\t\t\t\t\t// We kinda want to merge the other way, but to do that, we need an interim block.\n\t\t\t\t\tauto *ladder = pool.create_node();\n\t\t\t\t\tladder->name = node->name + \".\" + target_block->name + \".interim\";\n\t\t\t\t\tladder->add_branch(target_block);\n\t\t\t\t\tladder->ir.terminator.type = Terminator::Type::Branch;\n\t\t\t\t\tladder->ir.terminator.direct_block = target_block;\n\t\t\t\t\tladder->immediate_dominator = node;\n\t\t\t\t\tladder->immediate_post_dominator = target_block;\n\t\t\t\t\tladder->dominance_frontier.push_back(target_block);\n\t\t\t\t\tladder->forward_post_visit_order = node->forward_post_visit_order;\n\t\t\t\t\tladder->backward_post_visit_order = node->backward_post_visit_order;\n\t\t\t\t\tnode->retarget_branch(target_block, ladder);\n\t\t\t\t\tnode->selection_merge_block = ladder;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid CFGStructurizer::rewrite_selection_breaks(CFGNode *header, CFGNode *ladder_to)\n{\n\t// Don't rewrite loops here (since this is likely a loop merge block),\n\t// unless we're rewriting header -> inner construct scenario.\n\t// Check if the ladder_to block has a path to continue block.\n\t// If it does, it is part of the loop construct, and cannot be a loop merge block.\n\tif (header->pred_back_edge && !header->pred_back_edge->can_backtrace_to(ladder_to))\n\t\treturn;\n\n\t// Don't rewrite switch blocks either.\n\tif (header->ir.terminator.type == Terminator::Type::Switch)\n\t\treturn;\n\n\t//LOGI(\"Rewriting selection breaks %s -> %s\\n\", header->name.c_str(), ladder_to->name.c_str());\n\n\tUnorderedSet<CFGNode *> construct;\n\n\t// Be careful about rewriting branches in continuing constructs.\n\tCFGNode *inner_continue_block = nullptr;\n\tCFGNode *inner_continue_succ = nullptr;\n\tbool ladder_to_dominates_continue = false;\n\tbool break_post_dominates_ladder_to = false;\n\tauto *innermost_loop_header = get_innermost_loop_header_for(header);\n\tif (innermost_loop_header && innermost_loop_header->pred_back_edge)\n\t\tinner_continue_block = innermost_loop_header->pred_back_edge;\n\tif (inner_continue_block && inner_continue_block->succ.size() == 1)\n\t{\n\t\tinner_continue_succ = inner_continue_block->succ.front();\n\t\tbreak_post_dominates_ladder_to = inner_continue_succ->post_dominates(ladder_to);\n\t\tladder_to_dominates_continue = ladder_to->dominates(inner_continue_block);\n\t}\n\n\theader->traverse_dominated_blocks([&](CFGNode *node) -> bool {\n\t\t// Inner loop headers are not candidates for a rewrite. They are split in split_merge_blocks.\n\t\t// Similar with switch blocks.\n\t\t// Also, we need to stop traversing when we hit the target block ladder_to.\n\t\tif (node != ladder_to)\n\t\t{\n\t\t\tif (!query_reachability(*node, *ladder_to))\n\t\t\t\treturn false;\n\n\t\t\tbool branch_is_loop_or_switch = node->pred_back_edge ||\n\t\t\t                                node->ir.terminator.type == Terminator::Type::Switch;\n\n\t\t\t// If our candidate scope splits a loop scope in half, ignore this candidate.\n\t\t\tif (break_post_dominates_ladder_to && !ladder_to_dominates_continue &&\n\t\t\t    node->dominates(inner_continue_block))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (node->succ.size() >= 2 && !branch_is_loop_or_switch)\n\t\t\t{\n\t\t\t\tauto *outer_header = get_post_dominance_frontier_with_cfg_subset_that_reaches(node, ladder_to, nullptr);\n\t\t\t\tif (outer_header == header)\n\t\t\t\t\tconstruct.insert(node);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t});\n\n\tVector<CFGNode *> sorted_construct;\n\tsorted_construct.reserve(construct.size());\n\tfor (auto *inner_block : construct)\n\t\tsorted_construct.push_back(inner_block);\n\n\t// Emit inner constructs before outer constructs.\n\t// This way we get natural nesting in case of certain if/else if ladders.\n\tstd::sort(sorted_construct.begin(), sorted_construct.end(), [](const CFGNode *a, const CFGNode *b) {\n\t\treturn a->forward_post_visit_order < b->forward_post_visit_order;\n\t});\n\n\tfor (auto *inner_block : sorted_construct)\n\t{\n\t\t//LOGI(\"Header: %s, Inner: %s.\\n\", header->name.c_str(), inner_block->name.c_str());\n\t\tauto *ladder = pool.create_node();\n\t\tladder->name = ladder_to->name + \".\" + inner_block->name + \".ladder\";\n\t\t//LOGI(\"Walking dominated blocks of %s, rewrite branches %s -> %s.\\n\", inner_block->name.c_str(),\n\t\t//     ladder_to->name.c_str(), ladder->name.c_str());\n\n\t\tladder->add_branch(ladder_to);\n\t\tladder->ir.terminator.type = Terminator::Type::Branch;\n\t\tladder->ir.terminator.direct_block = ladder_to;\n\t\tladder->immediate_post_dominator = ladder_to;\n\t\tladder->dominance_frontier.push_back(ladder_to);\n\t\tladder->forward_post_visit_order = ladder_to->forward_post_visit_order;\n\t\tladder->backward_post_visit_order = ladder_to->backward_post_visit_order;\n\n\t\t// Stop rewriting once we hit a merge block.\n\t\ttraverse_dominated_blocks_and_rewrite_branch(inner_block,\n\t\t    ladder_to, ladder, [inner_block](CFGNode *node) -> bool {\n\t\t\t    return inner_block->selection_merge_block != node;\n\t\t    }, {});\n\n\t\tladder->recompute_immediate_dominator();\n\t\trewrite_selection_breaks(inner_block, ladder);\n\t}\n}\n\nbool CFGStructurizer::is_strictly_dominance_ordered(const CFGNode *a, const CFGNode *b, const CFGNode *c)\n{\n\treturn a != b && a->dominates(b) && b != c && b->dominates(c);\n}\n\nbool CFGStructurizer::is_reachability_ordered(const CFGNode *a, const CFGNode *b, const CFGNode *c)\n{\n\treturn a != b && query_reachability(*a, *b) && b != c && query_reachability(*b, *c);\n}\n\nbool CFGStructurizer::header_and_merge_block_have_entry_exit_relationship(const CFGNode *header, const CFGNode *merge) const\n{\n\tif (!merge->post_dominates(header))\n\t\treturn false;\n\n\t// If there are other blocks which need merging, and that idom is the header,\n\t// then header is some kind of exit block.\n\tbool found_inner_merge_target = false;\n\tconst CFGNode *potential_inner_merge_target = nullptr;\n\n\tconst auto is_earlier = [](const CFGNode *candidate, const CFGNode *existing) {\n\t\treturn !existing || (candidate->forward_post_visit_order > existing->forward_post_visit_order);\n\t};\n\n\tconst auto is_later = [](const CFGNode *candidate, const CFGNode *existing) {\n\t\treturn !existing || (candidate->forward_post_visit_order < existing->forward_post_visit_order);\n\t};\n\n\theader->traverse_dominated_blocks([&](const CFGNode *node) {\n\t\tif (node == merge)\n\t\t\treturn false;\n\n\t\t// Don't analyze loops, this path is mostly for selections only.\n\t\tif (node->pred_back_edge)\n\t\t\treturn false;\n\n\t\tif (node->num_forward_preds() <= 1)\n\t\t\treturn true;\n\t\tauto *idom = node->immediate_dominator;\n\n\t\tif (idom == header)\n\t\t{\n\t\t\tfound_inner_merge_target = true;\n\t\t\treturn false;\n\t\t}\n\t\telse if (is_later(node, potential_inner_merge_target) &&\n\t\t         idom->immediate_post_dominator == merge &&\n\t\t         !exists_path_in_cfg_without_intermediate_node(header, node, idom))\n\t\t{\n\t\t\t// Need to analyze this further to determine if it's one of those insane crossing merge cases ...\n\t\t\t// Find the lowest post visit order if there are multiple candidates.\n\t\t\tpotential_inner_merge_target = node;\n\t\t}\n\n\t\treturn true;\n\t});\n\n\tif (found_inner_merge_target)\n\t\treturn true;\n\tif (!potential_inner_merge_target)\n\t\treturn false;\n\n\t// Alternatively, try to find a situation where the natural merge is difficult to determine.\n\t// In this scenario, selection constructs appear to be \"breaking\" in different directions.\n\t// Any attempt to split scopes here will fail spectacularly.\n\n\tconst CFGNode *first_natural_breaks_to_outer = nullptr;\n\tconst CFGNode *first_natural_breaks_to_inner = nullptr;\n\tconst CFGNode *last_natural_breaks_to_outer = nullptr;\n\tconst CFGNode *last_natural_breaks_to_inner = nullptr;\n\n\theader->traverse_dominated_blocks([&](const CFGNode *node) {\n\t\tif (node == merge || node == potential_inner_merge_target)\n\t\t\treturn false;\n\t\tif (!query_reachability(*node, *merge) || !query_reachability(*node, *potential_inner_merge_target))\n\t\t\treturn false;\n\n\t\tif (node->succ.size() < 2)\n\t\t\treturn true;\n\n\t\tbool breaks_to_outer = std::find_if(node->succ.begin(), node->succ.end(), [&](const CFGNode *candidate) {\n\t\t\treturn merge->post_dominates(candidate);\n\t\t}) != node->succ.end();\n\n\t\tbool breaks_to_inner = std::find_if(node->succ.begin(), node->succ.end(), [&](const CFGNode *candidate) {\n\t\t\treturn potential_inner_merge_target->post_dominates(candidate);\n\t\t}) != node->succ.end();\n\n\t\tif (breaks_to_inner)\n\t\t\tbreaks_to_outer = false;\n\n\t\tif (breaks_to_outer)\n\t\t{\n\t\t\tif (is_earlier(node, first_natural_breaks_to_outer))\n\t\t\t\tfirst_natural_breaks_to_outer = node;\n\t\t\tif (is_later(node, last_natural_breaks_to_outer))\n\t\t\t\tlast_natural_breaks_to_outer = node;\n\t\t}\n\n\t\tif (breaks_to_inner)\n\t\t{\n\t\t\tif (is_earlier(node, first_natural_breaks_to_inner))\n\t\t\t\tfirst_natural_breaks_to_inner = node;\n\t\t\tif (is_later(node, last_natural_breaks_to_inner))\n\t\t\t\tlast_natural_breaks_to_inner = node;\n\t\t}\n\n\t\treturn true;\n\t});\n\n\tif (!first_natural_breaks_to_outer || !first_natural_breaks_to_inner ||\n\t    !last_natural_breaks_to_outer || !last_natural_breaks_to_inner)\n\t{\n\t\treturn false;\n\t}\n\n\t// Crossing break scenario.\n\tif (is_strictly_dominance_ordered(first_natural_breaks_to_inner, first_natural_breaks_to_outer, last_natural_breaks_to_inner))\n\t\treturn true;\n\telse if (is_strictly_dominance_ordered(first_natural_breaks_to_outer, first_natural_breaks_to_inner, last_natural_breaks_to_outer))\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nbool CFGStructurizer::serialize_interleaved_early_returns()\n{\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->num_forward_preds() <= 1)\n\t\t\tcontinue;\n\n\t\t// Never merge to continue block.\n\t\t// We should never hit this path unless we explicitly\n\t\t// avoided creating a continue ladder block earlier.\n\t\tif (block_is_plain_continue(node))\n\t\t\tcontinue;\n\n\t\tauto *idom = node->immediate_dominator;\n\t\tauto *merge_candidate = CFGNode::find_common_post_dominator(idom, node);\n\t\tbool post_dominator_is_exit_node =\n\t\t    merge_candidate && merge_candidate->immediate_post_dominator == merge_candidate;\n\t\tbool merged_into_terminating_path = post_dominator_is_exit_node && node->dominates_all_reachable_exits();\n\n\t\t// If our candidate idom post dominates the entry block, we consider this the main path of execution.\n\t\tif (merged_into_terminating_path && idom->post_dominates(entry_block))\n\t\t\tmerged_into_terminating_path = false;\n\n\t\tif (merged_into_terminating_path)\n\t\t{\n\t\t\t// Similar to loops, find the break target for this construct.\n\t\t\tauto *break_target = find_break_target_for_selection_construct(idom, node);\n\n\t\t\tif (break_target)\n\t\t\t{\n\t\t\t\tVector<CFGNode *> valid = { break_target, node };\n\t\t\t\tcollect_and_dispatch_control_flow(idom, break_target, valid, false, false);\n\n\t\t\t\t// This completely transposes the CFG, so need to recompute CFG to keep going.\n\t\t\t\trecompute_cfg();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool CFGStructurizer::serialize_interleaved_merge_scopes_aggressive()\n{\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\t// Eagerly collapse ridiculous unrolled loops if they exist.\n\t\t// We normally handle it, but we need to consider cases with cross-branches as well.\n\t\tconstexpr size_t PredThreshold = 32;\n\t\tif (node->num_forward_preds() < PredThreshold)\n\t\t\tcontinue;\n\t\tif (block_is_plain_continue(node))\n\t\t\tcontinue;\n\n\t\tauto *idom = node->immediate_dominator;\n\n\t\t// Only consider simpler cases that we can collapse.\n\t\tif (!node->post_dominates(idom))\n\t\t\tcontinue;\n\n\t\t// node->forward_post_visit_order should map 1:1 to the post-visit array,\n\t\t// but in extreme circumstances where there have been inline cfg rewrites before recompute,\n\t\t// this may not be true, so be defensive.\n\t\tauto itr = std::find(forward_post_visit_order.begin(), forward_post_visit_order.end(), node);\n\t\tauto end = std::find(forward_post_visit_order.begin(), forward_post_visit_order.end(), idom);\n\t\tassert(itr != forward_post_visit_order.end());\n\t\tassert(end != forward_post_visit_order.end());\n\n\t\tVector<CFGNode *> constructs;\n\n\t\tfor (; itr != end; ++itr)\n\t\t{\n\t\t\tauto *candidate = *itr;\n\t\t\tif (candidate->num_forward_preds() < PredThreshold)\n\t\t\t\tcontinue;\n\t\t\tif (!idom->dominates(candidate))\n\t\t\t\tcontinue;\n\t\t\tauto &df = candidate->dominance_frontier;\n\t\t\tif (std::find(df.begin(), df.end(), node) != df.end())\n\t\t\t\tconstructs.push_back(candidate);\n\t\t}\n\n\t\tif (constructs.empty())\n\t\t\tcontinue;\n\n\t\tif (constructs.size() >= 2)\n\t\t\tfilter_serialization_candidates(constructs);\n\n\t\tif (constructs.empty())\n\t\t\tcontinue;\n\n\t\tconstructs.push_back(node);\n\t\tcollect_and_dispatch_control_flow(idom, node, constructs, false, true);\n\t\trecompute_cfg();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nVector<std::pair<CFGNode *, CFGNode *>> CFGStructurizer::build_pdf_ranges(const Vector<CFGNode *> &candidates)\n{\n\tVector<std::pair<CFGNode *, CFGNode *>> pdf_ranges;\n\tpdf_ranges.reserve(candidates.size());\n\n\t// If breaking merge constructs are entangled, their PDFs will overlap.\n\tfor (auto *candidate : candidates)\n\t{\n\t\tauto &pdf = candidate->post_dominance_frontier;\n\t\tassert(!pdf.empty());\n\t\tCFGNode *first = pdf.front();\n\t\tCFGNode *last = first;\n\n\t\tfor (auto *n : pdf)\n\t\t{\n\t\t\tif (n->forward_post_visit_order > first->forward_post_visit_order)\n\t\t\t\tfirst = n;\n\t\t\tif (n->forward_post_visit_order < last->forward_post_visit_order)\n\t\t\t\tlast = n;\n\t\t}\n\n\t\tpdf_ranges.push_back({ first, last });\n\t}\n\n\treturn pdf_ranges;\n}\n\nbool CFGStructurizer::pdf_ranges_have_strict_dominance_ordering(const Vector<std::pair<CFGNode *, CFGNode *>> &pdf_ranges)\n{\n\tbool need_deinterleave = false;\n\tauto count = pdf_ranges.size();\n\tfor (size_t i = 0; i < count && !need_deinterleave; i++)\n\t\tfor (size_t j = 0; j < count && !need_deinterleave; j++)\n\t\t\tif (i != j)\n\t\t\t\tneed_deinterleave = is_strictly_dominance_ordered(pdf_ranges[i].first, pdf_ranges[j].first, pdf_ranges[i].second);\n\n\treturn need_deinterleave;\n}\n\nvoid CFGStructurizer::filter_serialization_candidates(Vector<CFGNode *> &candidates) const\n{\n\t// Ensure stable order.\n\tstd::sort(candidates.begin(), candidates.end(), [](const CFGNode *a, const CFGNode *b)\n\t          { return a->forward_post_visit_order < b->forward_post_visit_order; });\n\n\tauto *common_idom = candidates[0];\n\tfor (size_t i = 1, n = candidates.size(); i < n; i++)\n\t\tcommon_idom = CFGNode::find_common_dominator(common_idom, candidates[i]);\n\n\t// Filter out false positive inner constructs.\n\t// If we're dominated by another inner construct, and we don't post-dominate that construct, we should yield.\n\tfor (auto itr = candidates.begin(); itr != candidates.end(); )\n\t{\n\t\tbool eliminated = false;\n\t\tfor (auto candidate_itr = itr + 1; candidate_itr != candidates.end(); ++candidate_itr)\n\t\t{\n\t\t\tbool keep_candidate = (*candidate_itr) == common_idom || !(*candidate_itr)->dominates(*itr) ||\n\t\t\t                      (*itr)->post_dominates(*candidate_itr);\n\n\t\t\t// Don't let the common idom of constructs consume subsequent constructs.\n\t\t\tif (!keep_candidate)\n\t\t\t{\n\t\t\t\t// To accept a dominator, we don't want any common idom removing every node.\n\t\t\t\tstd::move(itr + 1, candidates.end(), itr);\n\t\t\t\tcandidates.pop_back();\n\t\t\t\teliminated = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!eliminated)\n\t\t\t++itr;\n\t}\n\n\tVector<CFGNode *> valid_constructs;\n\n\t// Prune any candidate that can reach another candidate. The sort ensures that candidate to be removed comes last.\n\tsize_t count = candidates.size();\n\tfor (size_t i = 0; i < count; i++)\n\t{\n\t\tbool valid = true;\n\t\tfor (size_t j = 0; j < i; j++)\n\t\t{\n\t\t\tif (query_reachability(*candidates[i], *candidates[j]))\n\t\t\t{\n\t\t\t\tvalid = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Another sanity check for candidates, the idom must be able to reach other nodes.\n\t\tif (valid)\n\t\t{\n\t\t\tvalid = false;\n\t\t\tfor (size_t j = 0; j < count; j++)\n\t\t\t{\n\t\t\t\tif (i == j)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (query_reachability(*candidates[i]->immediate_dominator, *candidates[j]))\n\t\t\t\t{\n\t\t\t\t\tvalid = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (valid)\n\t\t\tvalid_constructs.push_back(candidates[i]);\n\t}\n\n\tcandidates = std::move(valid_constructs);\n}\n\nbool CFGStructurizer::serialize_interleaved_merge_scopes()\n{\n\t// Try to fixup scenarios which arise from unrolled loops with multiple break blocks.\n\t// DXC will emit maximal convergence and force all dynamic instances of a given break to branch to the same\n\t// block, which then breaks, e.g.:\n\t// for (int i = 0; i < CONSTANT; i++) { cond_break_construct1(); cond_break_construct2(); cond_break_construct3(); }\n\t// When this unrolls we can end up with merge blocks which are entangled. Only sane way to make this work\n\t// is to serialize the breaks to after the merge block.\n\tUnorderedSet<CFGNode *> potential_merge_nodes;\n\n\tfor (auto *node : forward_post_visit_order)\n\t\tif (node->num_forward_preds() >= 2 && !block_is_plain_continue(node))\n\t\t\tpotential_merge_nodes.insert(node);\n\n\tUnorderedSet<const CFGNode *> visited;\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->num_forward_preds() <= 1)\n\t\t\tcontinue;\n\t\tif (block_is_plain_continue(node))\n\t\t\tcontinue;\n\n\t\tauto *idom = node->immediate_dominator;\n\n\t\tVector<CFGNode *> complex_inner_constructs;\n\t\tVector<CFGNode *> constructs;\n\n\t\t// Find merge block candidates that are strictly dominated by idom and immediately post-dominated by node.\n\t\t// They also must not be good merge candidates on their own.\n\t\t// Also, we're not interested in any loop merge candidates.\n\t\tfor (auto *candidate : potential_merge_nodes)\n\t\t{\n\t\t\tif (candidate != idom && idom->dominates(candidate) &&\n\t\t\t\tnode->post_dominates(candidate) &&\n\t\t\t    !candidate->post_dominates_perfect_structured_construct() &&\n\t\t\t    get_innermost_loop_header_for(idom, candidate) == idom)\n\t\t\t{\n\t\t\t\tbool direct_dominance_frontier = candidate->dominance_frontier.size() == 1 &&\n\t\t\t\t                                 candidate->dominance_frontier.front() == node;\n\t\t\t\t// The candidate must not try to merge to other code since we might end up introducing loops that way.\n\t\t\t\t// All code reachable by candidate must cleanly break to node.\n\t\t\t\t// We can make use of a simpler rewrite path if all code paths to node goes through our candidates.\n\t\t\t\t// Accept a construct and determine if we need to promote the complex constructs instead of the inner constructs.\n\t\t\t\t// The inner construct may just be a false positive that ends up blocking the rewrite.\n\t\t\t\tif (direct_dominance_frontier)\n\t\t\t\t\tconstructs.push_back(candidate);\n\t\t\t\telse\n\t\t\t\t\tcomplex_inner_constructs.push_back(candidate);\n\t\t\t}\n\t\t}\n\n\t\t// If true, we need a complex rewrite. This means taking unrelated branches to node and fuse them into\n\t\t// one big merge. This requires very simple control flow from the candidates,\n\t\t// since otherwise we end up with unintended loops in the rewrite.\n\t\t// The simplified flow requires that all code paths from idom flow through the complex inner candidates.\n\t\tbool collect_all_paths_to_pdom = true;\n\n\t\tif (constructs.size() == 1 && complex_inner_constructs.size() >= 2)\n\t\t{\n\t\t\tauto *candidate_inner = constructs.front();\n\t\t\tauto *common_idom = candidate_inner;\n\n\t\t\tconstructs.clear();\n\n\t\t\t// Try to detect a false positive where we should ignore inner_constructs.\n\n\t\t\t// Ensure that the inner construct comes after the candidate constructs.\n\t\t\tbool should_promote_complex = true;\n\t\t\tfor (auto *candidate : complex_inner_constructs)\n\t\t\t{\n\t\t\t\tif (!query_reachability(*candidate, *candidate_inner))\n\t\t\t\t{\n\t\t\t\t\tshould_promote_complex = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (should_promote_complex)\n\t\t\t{\n\t\t\t\t// The inner candidate should not post-dominate any other candidate block.\n\t\t\t\t// We're looking for unusual merge patterns here.\n\t\t\t\tfor (auto *pred : complex_inner_constructs)\n\t\t\t\t{\n\t\t\t\t\tif (candidate_inner->post_dominates(pred))\n\t\t\t\t\t{\n\t\t\t\t\t\tshould_promote_complex = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (should_promote_complex)\n\t\t\t{\n\t\t\t\t// In complex merges, we focus on merging as early as possible, rather than as late as possible.\n\t\t\t\t// Remove any candidates which are reachable by other candidates.\n\n\t\t\t\t// Disregard the inner constructs, promote the complex ones.\n\t\t\t\tcollect_all_paths_to_pdom = false;\n\n\t\t\t\t// Ensure stable order.\n\t\t\t\tstd::sort(complex_inner_constructs.begin(), complex_inner_constructs.end(), [](const CFGNode *a, const CFGNode *b) {\n\t\t\t\t\treturn a->forward_post_visit_order > b->forward_post_visit_order;\n\t\t\t\t});\n\n\t\t\t\tsize_t count = complex_inner_constructs.size();\n\t\t\t\tfor (size_t j = 0; j < count; j++)\n\t\t\t\t{\n\t\t\t\t\tbool is_reachable = false;\n\t\t\t\t\tfor (size_t i = 0; i < j && !is_reachable; i++)\n\t\t\t\t\t\tif (query_reachability(*complex_inner_constructs[i], *complex_inner_constructs[j]))\n\t\t\t\t\t\t\tis_reachable = true;\n\n\t\t\t\t\tif (!is_reachable)\n\t\t\t\t\t\tconstructs.push_back(complex_inner_constructs[j]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (should_promote_complex && constructs.size() >= 2)\n\t\t\t{\n\t\t\t\tfor (auto *inner : constructs)\n\t\t\t\t\tcommon_idom = CFGNode::find_common_dominator(common_idom, inner);\n\n\t\t\t\t// Verify that all paths to node must go through the inner constructs.\n\t\t\t\t// We cannot handle more awkward merges.\n\t\t\t\tshould_promote_complex = !node->can_backtrace_to_with_blockers(common_idom, constructs);\n\t\t\t}\n\n\t\t\tif (!should_promote_complex)\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tif (constructs.size() < 2)\n\t\t\tcontinue;\n\n\t\tfilter_serialization_candidates(constructs);\n\n\t\tif (constructs.size() < 2)\n\t\t\tcontinue;\n\n\t\tauto pdf_ranges = build_pdf_ranges(constructs);\n\t\tbool need_deinterleave = pdf_ranges_have_strict_dominance_ordering(pdf_ranges);\n\t\tsize_t count = constructs.size();\n\n\t\tCFGNode *common_anchor = nullptr;\n\n\t\tif (!need_deinterleave)\n\t\t{\n\t\t\t// Detect a complicated pattern that comes up which looks a lot like interleaved merges, but isn't really.\n\t\t\t// A       B\n\t\t\t// |\\     /|\n\t\t\t// | \\   / |\n\t\t\t// |   E   |\n\t\t\t// | /  \\  |\n\t\t\t// C      D\n\t\t\t//  \\    /\n\t\t\t//   \\  /\n\t\t\t//    F\n\t\t\t// Candidates: {C, D}\n\t\t\t// Where {A, E} is pdf range of C\n\t\t\t// and {B, E} is pdf range of D\n\t\t\t// The last PDF can be considered a merge anchor that distributes code further.\n\t\t\t// E must have {C, D} - and only those - in the dominance frontier.\n\t\t\tcommon_anchor = pdf_ranges[0].second;\n\n\t\t\tbool can_be_anchor = common_anchor->pred.size() >= 2 ||\n\t\t\t                     (common_anchor->pred.size() == 1 && common_anchor->pred.front()->succ_back_edge);\n\n\t\t\tneed_deinterleave = common_anchor->dominance_frontier.size() == count &&\n\t\t\t                    common_anchor->succ.size() == count &&\n\t\t\t                    common_anchor->ir.terminator.type == Terminator::Type::Condition &&\n\t\t\t                    can_be_anchor;\n\n\t\t\tfor (size_t i = 0; i < count && need_deinterleave; i++)\n\t\t\t{\n\t\t\t\tneed_deinterleave =\n\t\t\t\t\tquery_reachability(*pdf_ranges[i].first, *pdf_ranges[i].second) &&\n\t\t\t\t\tpdf_ranges[0].second == pdf_ranges[i].second;\n\n\t\t\t\tneed_deinterleave = need_deinterleave &&\n\t\t\t\t                    std::find(common_anchor->dominance_frontier.begin(),\n\t\t\t\t                              common_anchor->dominance_frontier.end(),\n\t\t\t\t                              constructs[i]) != common_anchor->dominance_frontier.end();\n\t\t\t}\n\n\t\t\tif (!need_deinterleave)\n\t\t\t\tcommon_anchor = nullptr;\n\t\t}\n\n\t\tif (!need_deinterleave)\n\t\t{\n\t\t\tconst CFGNode *interleaved_exit_loop = nullptr;\n\n\t\t\t// Try finding interleaved loops exits. Extremely rare and awkward scenario.\n\t\t\t// This pattern makes it so that loop resolves cannot work well since nothing ends up being nested.\n\t\t\t// We can deal with one, but if two or more loops end up with awkward resolves, we have to employ magic.\n\n\t\t\t// First, look at the PDFs, try to find a node in an inner loop.\n\t\t\t// If the loop exits in a way where they can both reach the interleaving candidates,\n\t\t\t// that's a scenario where we need to consider rewriting.\n\t\t\tfor (auto *candidate : constructs)\n\t\t\t{\n\t\t\t\tauto &pdf = candidate->post_dominance_frontier;\n\t\t\t\tfor (auto *pdf_candidate : pdf)\n\t\t\t\t{\n\t\t\t\t\tauto *inner_header = get_innermost_loop_header_for(idom, pdf_candidate);\n\t\t\t\t\tif (inner_header != idom && inner_header != interleaved_exit_loop)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Don't allow nested loops to be considered as two loops.\n\t\t\t\t\t\tif (interleaved_exit_loop && query_reachability(*inner_header, *interleaved_exit_loop))\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tif (query_reachability(*pdf_candidate, *inner_header->pred_back_edge))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// The back-edge can only reach one of the interleave nodes, while the candidate PDF\n\t\t\t\t\t\t\t// can reach both. This proves weird break cases.\n\n\t\t\t\t\t\t\tunsigned back_edge_reach_count = 0;\n\t\t\t\t\t\t\tunsigned pdf_reach_count = 0;\n\t\t\t\t\t\t\tfor (auto *reach_candidate : constructs)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (query_reachability(*inner_header->pred_back_edge, *reach_candidate))\n\t\t\t\t\t\t\t\t\tback_edge_reach_count++;\n\t\t\t\t\t\t\t\tif (query_reachability(*pdf_candidate, *reach_candidate))\n\t\t\t\t\t\t\t\t\tpdf_reach_count++;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (back_edge_reach_count == 1 && pdf_reach_count == constructs.size())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// We've found two candidates now, break out.\n\t\t\t\t\t\t\t\tneed_deinterleave = interleaved_exit_loop != nullptr;\n\t\t\t\t\t\t\t\tinterleaved_exit_loop = inner_header;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (need_deinterleave)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!need_deinterleave && count >= 3)\n\t\t{\n\t\t\t// More special cases.\n\t\t\t// We might not find an interleaving scenario by looking at strict dominance,\n\t\t\t// but there might be difficult cases lurking if we look at pure reachability.\n\t\t\tfor (size_t i = 0; i < count && !need_deinterleave; i++)\n\t\t\t{\n\t\t\t\tfor (size_t j = 0; j < count && !need_deinterleave; j++)\n\t\t\t\t{\n\t\t\t\t\tif (i == j)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tif (!is_reachability_ordered(pdf_ranges[i].first, pdf_ranges[j].first, pdf_ranges[i].second))\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tauto &df = pdf_ranges[i].second->dominance_frontier;\n\t\t\t\t\tbool all_in_frontier = true;\n\t\t\t\t\t// If all the valid constructs are in the dominance frontier, consider this a highly difficult case.\n\t\t\t\t\t// If there's just two candidate blocks we can resolve them with ladder breaks, but three and above\n\t\t\t\t\t// can be nested in unexpected ways. This threshold is mostly a heuristic to avoid\n\t\t\t\t\t// doing complex transforms unless we really know for sure we need them.\n\t\t\t\t\tfor (size_t k = 0; k < count && all_in_frontier; k++)\n\t\t\t\t\t\tall_in_frontier = std::find(df.begin(), df.end(), constructs[k]) != df.end();\n\t\t\t\t\tneed_deinterleave = all_in_frontier;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!need_deinterleave && pdf_ranges[0].first != pdf_ranges[0].second)\n\t\t{\n\t\t\t// Special case of the above. If the PDFs overlap exactly we have criss-cross merge patterns.\n\t\t\t// Be very conservative when we accept this since this pattern comes up as innocent\n\t\t\t// breaking patterns. Some complicating factors is when idom is a loop header and\n\t\t\t// We don't post-dominate the idom and is more likely a breaking path.\n\n\t\t\tbool same_pdfs = true;\n\t\t\tfor (size_t i = 1; i < count && !same_pdfs; i++)\n\t\t\t\tsame_pdfs = pdf_ranges[i].first == pdf_ranges[0].first && pdf_ranges[i].second == pdf_ranges[0].second;\n\n\t\t\t// Heuristic to avoid needing to do needless rewrites.\n\t\t\t// The issues only seem to manifest in this situation.\n\t\t\t// Likely the problem is that different idoms with wrong ladder resolve order\n\t\t\t// can lead to backwards branches in some extremely rare cases ...\n\t\t\tauto *first = pdf_ranges[0].first->immediate_dominator;\n\t\t\tauto *second = pdf_ranges[0].second->immediate_dominator;\n\t\t\tauto *common_idom = CFGNode::find_common_dominator(first, second);\n\n\t\t\tbool crossing_idoms = first != second && first != common_idom && second != common_idom &&\n\t\t\t                      (query_reachability(*first, *second) || query_reachability(*second, *first));\n\n\t\t\tif (same_pdfs && crossing_idoms)\n\t\t\t{\n\t\t\t\t// All PDFs must have all candidates in their DFs.\n\t\t\t\tbool all_in_frontier = true;\n\t\t\t\t// If all the valid constructs are in the dominance frontier, consider this a highly difficult case.\n\t\t\t\t// If there's just two candidate blocks we can resolve them with ladder breaks, but three and above\n\t\t\t\t// can be nested in unexpected ways. This threshold is mostly a heuristic to avoid\n\t\t\t\t// doing complex transforms unless we really know for sure we need them.\n\n\t\t\t\tconst Vector<CFGNode *> *dfs[] = {\n\t\t\t\t\t&pdf_ranges[0].first->dominance_frontier,\n\t\t\t\t\t&pdf_ranges[0].second->dominance_frontier,\n\t\t\t\t};\n\n\t\t\t\tfor (auto *df : dfs)\n\t\t\t\t\tfor (size_t i = 0; i < count && all_in_frontier; i++)\n\t\t\t\t\t\tall_in_frontier = std::find(df->begin(), df->end(), constructs[i]) != df->end();\n\n\t\t\t\tneed_deinterleave = all_in_frontier;\n\t\t\t}\n\t\t}\n\n\t\tif (need_deinterleave)\n\t\t{\n\t\t\tif (common_anchor)\n\t\t\t\tcollect_and_dispatch_control_flow_from_anchor(common_anchor, constructs);\n\t\t\telse\n\t\t\t\tcollect_and_dispatch_control_flow(idom, node, constructs, collect_all_paths_to_pdom, false);\n\n\t\t\t// This completely transposes the CFG, so need to recompute CFG to keep going.\n\t\t\trecompute_cfg();\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid CFGStructurizer::split_merge_scopes()\n{\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\t// Setup a preliminary merge scope so we know when to stop traversal.\n\t\t// We don't care about traversing inner scopes, out starting from merge block as well.\n\t\tif (node->num_forward_preds() <= 1)\n\t\t\tcontinue;\n\n\t\tif (block_is_plain_continue(node))\n\t\t\tcontinue;\n\n\t\t// The idom is the natural header block.\n\t\tauto *idom = node->immediate_dominator;\n\t\tassert(idom->succ.size() >= 2);\n\n\t\tif (idom->merge == MergeType::None)\n\t\t{\n\t\t\tidom->merge = MergeType::Selection;\n\t\t\tidom->selection_merge_block = node;\n\t\t}\n\t\tnode->headers.push_back(idom);\n\t}\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->num_forward_preds() <= 1)\n\t\t\tcontinue;\n\n\t\t// Continue blocks can always be branched to, from any scope, so don't rewrite anything here.\n\t\tif (node->succ_back_edge)\n\t\t\tcontinue;\n\n\t\t// The idom is the natural header block.\n\t\tauto *idom = node->immediate_dominator;\n\t\tassert(idom->succ.size() >= 2);\n\n\t\t// We already rewrote this selection construct in serialize_interleaved_merge_scopes.\n\t\t// Don't try to introduce unnecessary ladders.\n\t\tif (idom->merge == MergeType::Loop && idom->loop_merge_block == node)\n\t\t\tcontinue;\n\n\t\t// If we find a construct which is a typical entry <-> exit scenario, do not attempt to rewrite\n\t\t// any branches. The real merge block might be contained inside this construct, and this block merely\n\t\t// serves as the exit merge point. It should generally turn into a loop merge later.\n\t\tif (header_and_merge_block_have_entry_exit_relationship(idom, node))\n\t\t\tcontinue;\n\n\t\t// Now we want to deal with cases where we are using this selection merge block as \"goto\" target for inner selection constructs.\n\t\t// Using a loop header might be possible,\n\t\t// but we will need to split up blocks to make sure that we don't end up with headers where the only branches\n\t\t// are either merges or breaks.\n\n\t\t// This case is relevant when we have something like:\n\t\t// A -> B -> C -> D -> M\n\t\t// A -> M\n\t\t// B -> M\n\t\t// C -> M\n\t\t// D -> M\n\t\t// We'll need intermediate blocks which merge each layer of the selection \"onion\".\n\t\trewrite_selection_breaks(idom, node);\n\t}\n}\n\nbool CFGStructurizer::query_reachability(const CFGNode &from, const CFGNode &to) const\n{\n\tif (&from == &to)\n\t\treturn true;\n\n\tconst uint32_t *src_reachability = &reachability_bitset[from.forward_post_visit_order * reachability_stride];\n\treturn (src_reachability[to.forward_post_visit_order / 32] & (1u << (to.forward_post_visit_order & 31u))) != 0;\n}\n\nvoid CFGStructurizer::visit_reachability(const CFGNode &node)\n{\n\tuint32_t *dst_reachability = &reachability_bitset[node.forward_post_visit_order * reachability_stride];\n\n\tfor (auto *succ : node.succ)\n\t{\n\t\t// Inherit reachability from all successors.\n\t\tconst uint32_t *src_reachability = &reachability_bitset[succ->forward_post_visit_order * reachability_stride];\n\t\tfor (unsigned i = 0; i < reachability_stride; i++)\n\t\t\tdst_reachability[i] |= src_reachability[i];\n\t}\n\n\t// We can reach ourselves.\n\tdst_reachability[node.forward_post_visit_order / 32] |= 1u << (node.forward_post_visit_order & 31u);\n}\n\nvoid CFGStructurizer::build_reachability()\n{\n\treachability_stride = (forward_post_visit_order.size() + 31) / 32;\n\treachability_bitset.clear();\n\treachability_bitset.resize(reachability_stride * forward_post_visit_order.size());\n\tfor (auto *node : forward_post_visit_order)\n\t\tvisit_reachability(*node);\n}\n\nvoid CFGStructurizer::recompute_cfg()\n{\n\treset_traversal();\n\tvisit(*entry_block);\n\t// Need to prune dead preds before computing dominance.\n\tprune_dead_preds();\n\tbuild_immediate_dominators();\n\tbuild_reachability();\n\n\tbackwards_visit();\n\tbuild_immediate_post_dominators();\n\n\tcompute_dominance_frontier();\n\tcompute_post_dominance_frontier();\n}\n\nCFGNode *CFGStructurizer::find_natural_switch_merge_block(CFGNode *node, CFGNode *post_dominator) const\n{\n\t// Maintain the original switch block order if possible to avoid awkward churn in reference output.\n\tuint64_t order = 1;\n\tfor (auto &c : node->ir.terminator.cases)\n\t{\n\t\t// We'll need to decrement global order up to N times in the worst case.\n\t\t// Use 64-bit here as a safeguard in case the module is using a ridiculous amount of case labels.\n\t\tc.global_order = order * node->ir.terminator.cases.size();\n\t\torder++;\n\t}\n\n\t// First, sort so that any fallthrough parent comes before fallthrough target.\n\tstd::sort(node->ir.terminator.cases.begin(), node->ir.terminator.cases.end(),\n\t\t\t  [](const Terminator::Case &a, const Terminator::Case &b)\n\t\t\t  { return a.node->forward_post_visit_order > b.node->forward_post_visit_order; });\n\n\t// Look at all potential fallthrough candidates and reassign global order.\n\tfor (size_t i = 0, n = node->ir.terminator.cases.size(); i < n; i++)\n\t{\n\t\tfor (size_t j = i + 1; j < n; j++)\n\t\t{\n\t\t\tauto &parent = node->ir.terminator.cases[i];\n\t\t\tauto &child = node->ir.terminator.cases[j];\n\n\t\t\t// A case label might be the merge block candidate of the switch.\n\t\t\t// Don't consider case fallthrough if b post-dominates the entire switch statement.\n\t\t\t// If a case label is a continue block, ignore it, since it will be a pure continue break in this scenario.\n\t\t\t// This is not considered a fallthrough, just a common break.\n\t\t\tif (child.node != post_dominator && parent.node != child.node &&\n\t\t\t    !(child.node->succ_back_edge || child.node->is_pseudo_back_edge) &&\n\t\t\t    query_reachability(*parent.node, *child.node))\n\t\t\t{\n\t\t\t\tparent.global_order = child.global_order - 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sort again, but this time, by global order.\n\tstd::stable_sort(node->ir.terminator.cases.begin(), node->ir.terminator.cases.end(),\n\t\t\t\t\t [](const Terminator::Case &a, const Terminator::Case &b)\n\t\t\t\t\t { return a.global_order < b.global_order; });\n\n\t// Detect impossible fallthrough scenarios. We can have A -> B -> C fallthrough, but not\n\t// A -> C and B -> C. In this situation, we should see C as the actual switch merge block,\n\t// and rewrite the switch to loop + switch.\n\t// Detect this by having two entries with identical global order.\n\n\tbool has_impossible_fallthrough = false;\n\tuint64_t target_order = 0;\n\n\tfor (size_t i = 1, n = node->ir.terminator.cases.size(); i < n; i++)\n\t{\n\t\tif (node->ir.terminator.cases[i].global_order == node->ir.terminator.cases[i - 1].global_order)\n\t\t{\n\t\t\ttarget_order = node->ir.terminator.cases[i].global_order + 1;\n\t\t\thas_impossible_fallthrough = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tCFGNode *candidate = nullptr;\n\tif (has_impossible_fallthrough)\n\t{\n\t\tfor (auto &c : node->ir.terminator.cases)\n\t\t{\n\t\t\tif (c.global_order == target_order)\n\t\t\t{\n\t\t\t\t// Pick the earliest one.\n\t\t\t\tcandidate = c.node;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tbool case_labels_can_be_candidate_frontier = false;\n\n\tif (has_impossible_fallthrough && !candidate)\n\t{\n\t\t// This can happen if the impossible candidate block is a pred of yet another case label ?!?!\n\t\t// If this happens, do the full analysis in the loop below.\n\t\tcase_labels_can_be_candidate_frontier = true;\n\t}\n\n\t// We found a candidate, but there might be multiple candidates which are considered impossible.\n\n\t// If two case labels merge execution before the candidate merge, we should consider that the natural merge,\n\t// since it is not possible to express this without a switch merge.\n\tfor (auto &c : node->ir.terminator.cases)\n\t{\n\t\tfor (auto *front : c.node->dominance_frontier)\n\t\t{\n\t\t\t// Never consider continue constructs here.\n\t\t\tif (front->succ_back_edge || front->is_pseudo_back_edge)\n\t\t\t\tcontinue;\n\n\t\t\tif (!case_labels_can_be_candidate_frontier)\n\t\t\t{\n\t\t\t\t// Ignore frontiers that are other case labels.\n\t\t\t\t// We allow simple fallthrough, and if we found an impossible case we would have handled it already.\n\t\t\t\tfor (auto &ic : node->ir.terminator.cases)\n\t\t\t\t{\n\t\t\t\t\tif (ic.node == front)\n\t\t\t\t\t{\n\t\t\t\t\t\tfront = nullptr;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!front)\n\t\t\t\tcontinue;\n\n\t\t\tif (!post_dominator ||\n\t\t\t    (front->forward_post_visit_order != post_dominator->forward_post_visit_order &&\n\t\t\t     query_reachability(*front, *post_dominator)))\n\t\t\t{\n\t\t\t\t// If this is reachable by a different case label, we have a winner. This must be a fake fallthrough\n\t\t\t\t// that we should promote to switch merge.\n\t\t\t\tfor (auto &ic : node->ir.terminator.cases)\n\t\t\t\t{\n\t\t\t\t\tif (ic.node != c.node && query_reachability(*ic.node, *front))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Select the innermost block that is impossible.\n\t\t\t\t\t\t// Breaking further out can be handled with loops, etc.\n\t\t\t\t\t\tif (!candidate || front->forward_post_visit_order > candidate->forward_post_visit_order)\n\t\t\t\t\t\t\tcandidate = front;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn candidate ? candidate : post_dominator;\n}\n\nCFGNode *CFGStructurizer::create_switch_merge_ladder(CFGNode *header, CFGNode *merge)\n{\n\t// We did not rewrite switch blocks w.r.t. selection breaks.\n\t// We might be in a situation where the switch block is trying to merge to a block which is already being merged to.\n\t// Create a ladder which the switch block could merge to.\n\treturn create_ladder_block(header, merge, \".switch-merge\");\n}\n\nOperation *CFGStructurizer::build_switch_case_equal_check(\n    const CFGNode *header, CFGNode *insert_node, const Terminator::Case &c)\n{\n\tOperation *ieq;\n\n\tif (c.is_default)\n\t{\n\t\t// Awkward since we have to compare all other case labels.\n\t\tOperation *neq_and = nullptr;\n\t\tfor (auto &label : header->ir.terminator.cases)\n\t\t{\n\t\t\tif (!label.is_default)\n\t\t\t{\n\t\t\t\tOperation *neq = module.allocate_op(spv::OpINotEqual,\n\t\t\t\t                                    module.allocate_id(),\n\t\t\t\t                                    module.get_builder().makeBoolType());\n\t\t\t\tneq->add_id(header->ir.terminator.conditional_id);\n\t\t\t\tneq->add_id(module.get_builder().makeUintConstant(label.value));\n\t\t\t\tinsert_node->ir.operations.push_back(neq);\n\n\t\t\t\tif (neq_and)\n\t\t\t\t{\n\t\t\t\t\tOperation *and_op = module.allocate_op(spv::OpLogicalAnd,\n\t\t\t\t\t                                       module.allocate_id(),\n\t\t\t\t\t                                       module.get_builder().makeBoolType());\n\t\t\t\t\tand_op->add_id(neq_and->id);\n\t\t\t\t\tand_op->add_id(neq->id);\n\t\t\t\t\tinsert_node->ir.operations.push_back(and_op);\n\t\t\t\t\tneq_and = and_op;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tneq_and = neq;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tieq = neq_and;\n\t}\n\telse\n\t{\n\t\tieq = module.allocate_op(spv::OpIEqual, module.allocate_id(), module.get_builder().makeBoolType());\n\t\tieq->add_id(header->ir.terminator.conditional_id);\n\t\tieq->add_id(module.get_builder().makeUintConstant(c.value));\n\t\tinsert_node->ir.operations.push_back(ieq);\n\t}\n\n\treturn ieq;\n}\n\nvoid CFGStructurizer::hoist_switch_branches_to_frontier(CFGNode *node, CFGNode *merge,\n                                                        CFGNode *dominance_frontier_candidate)\n{\n\t// Dispatch to the dominance frontier before we enter switch scope.\n\tauto *pred = create_helper_pred_block(node);\n\tstd::swap(pred->ir.operations, node->ir.operations);\n\n\tauto succs = node->succ;\n\tfor (auto *succ : succs)\n\t{\n\t\tif (!query_reachability(*succ, *dominance_frontier_candidate))\n\t\t\tcontinue;\n\n\t\t// Rewrite the case label to reach merge block in a unique path.\n\t\t// That way we can PHI select whether to branch to dominance frontier or not\n\t\t// in the switch merge block.\n\n\t\tspv::Id cond_id = 0;\n\t\tfor (auto &c : node->ir.terminator.cases)\n\t\t{\n\t\t\tif (c.node == succ)\n\t\t\t{\n\t\t\t\tauto *ieq = build_switch_case_equal_check(node, pred, c);\n\n\t\t\t\tif (cond_id)\n\t\t\t\t{\n\t\t\t\t\tauto *bor = module.allocate_op(spv::OpLogicalOr, module.allocate_id(),\n\t\t\t\t\t                               module.get_builder().makeBoolType());\n\t\t\t\t\tbor->add_id(cond_id);\n\t\t\t\t\tbor->add_id(ieq->id);\n\t\t\t\t\tpred->ir.operations.push_back(bor);\n\t\t\t\t\tcond_id = bor->id;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcond_id = ieq->id;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (succ == dominance_frontier_candidate)\n\t\t{\n\t\t\t// We're directly branching to target, so might have to rewrite PHI incoming\n\t\t\t// block to pred helper block instead.\n\t\t\tfor (auto &phi : dominance_frontier_candidate->ir.phi)\n\t\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t\t\tif (incoming.block == node)\n\t\t\t\t\t\tincoming.block = pred;\n\t\t}\n\n\t\tfor (auto *&p : succ->pred)\n\t\t\tif (p == node)\n\t\t\t\tp = pred;\n\n\t\tfor (auto &c : node->ir.terminator.cases)\n\t\t\tif (c.node == succ)\n\t\t\t\tc.node = merge;\n\n\t\tnode->succ.erase(std::find(node->succ.begin(), node->succ.end(), succ));\n\t\tnode->add_branch(merge);\n\t\tpred->add_branch(succ);\n\n\t\t// Make sure that our selection branch has somewhere to merge if it has to.\n\t\tif (succ == dominance_frontier_candidate)\n\t\t{\n\t\t\tsucc = pred->rewrite_branch_through_intermediate_node(dominance_frontier_candidate,\n\t\t\t                                                      dominance_frontier_candidate);\n\t\t}\n\n\t\tpred->ir.terminator.type = Terminator::Type::Condition;\n\t\tpred->ir.terminator.conditional_id = cond_id;\n\t\tpred->ir.terminator.true_block = succ;\n\t\tpred->ir.terminator.false_block = node;\n\t\tpred->ir.terminator.direct_block = nullptr;\n\n\t\t// Have to assume that there is only one path to this frontier,\n\t\t// otherwise we're in a world of impossible case merges\n\t\t// which should have been handled elsewhere ...\n\t\treturn;\n\t}\n}\n\nCFGStructurizer::SwitchProgressMode CFGStructurizer::process_switch_blocks(unsigned pass)\n{\n\tbool modified_cfg = false;\n\tfor (auto index = forward_post_visit_order.size(); index; index--)\n\t{\n\t\tauto *node = forward_post_visit_order[index - 1];\n\t\tif (node->ir.terminator.type != Terminator::Type::Switch)\n\t\t\tcontinue;\n\n\t\tauto *merge = find_common_post_dominator(node->succ);\n\t\tauto *natural_merge = find_natural_switch_merge_block(node, merge);\n\n\t\t// If there are early exits inside the switch statement, post-dominance analysis won't work.\n\t\t// Just pick the natural merge.\n\t\t// This only seems to happen in dxbc2dxil.\n\t\tif (!merge)\n\t\t\tmerge = natural_merge;\n\n\t\t// If there is still nothing, it's possible one of the case labels is the only non-exiting path.\n\t\t// If we have no natural merge either, this is the likely merge point.\n\t\tif (!merge)\n\t\t{\n\t\t\tCFGNode *pdom = nullptr;\n\t\t\tfor (auto *succ : node->succ)\n\t\t\t{\n\t\t\t\tif (!succ->dominates_all_reachable_exits())\n\t\t\t\t{\n\t\t\t\t\tif (!pdom)\n\t\t\t\t\t{\n\t\t\t\t\t\tpdom = succ;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *new_pdom = CFGNode::find_common_post_dominator(pdom, succ);\n\t\t\t\t\t\tif (new_pdom)\n\t\t\t\t\t\t\tpdom = new_pdom;\n\t\t\t\t\t}\n\n\t\t\t\t\t// If there is at least one exit, have a fallback.\n\t\t\t\t\tmerge = succ;\n\t\t\t\t\tnatural_merge = succ;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we have a valid pdom, that is the more reasonable target.\n\t\t\tif (pdom)\n\t\t\t{\n\t\t\t\tmerge = pdom;\n\t\t\t\tnatural_merge = pdom;\n\t\t\t}\n\t\t}\n\n\t\tif (!merge)\n\t\t{\n\t\t\t// Merge to unreachable.\n\t\t\tnode->merge = MergeType::Selection;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (node->freeze_structured_analysis && node->merge == MergeType::Selection)\n\t\t{\n\t\t\tnatural_merge = node->selection_merge_block;\n\t\t}\n\t\telse if (pass == 0)\n\t\t{\n\t\t\t// It is possible that we don't necessarily want to merge to the post-dominator.\n\t\t\t// There might be inner constructs which are better suited.\n\t\t\t// This can happen if some branches break farther out than some other branches.\n\t\t\t// We should let the loop ladder system take care of that.\n\t\t\t// The switch merge should consume the smallest possible scope.\n\t\t\tif (merge != natural_merge)\n\t\t\t{\n\t\t\t\tCFGNode *inner_merge = merge;\n\t\t\t\tfor (auto *frontier_node : natural_merge->dominance_frontier)\n\t\t\t\t{\n\t\t\t\t\tif (node->dominates(frontier_node) && merge->post_dominates(frontier_node) &&\n\t\t\t\t\t    frontier_node->forward_post_visit_order > inner_merge->forward_post_visit_order)\n\t\t\t\t\t{\n\t\t\t\t\t\tinner_merge = frontier_node;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (merge != inner_merge && inner_merge != natural_merge && node->dominates(merge))\n\t\t\t\t{\n\t\t\t\t\t// If node dominates the merge, it's important that node remains a header block.\n\t\t\t\t\t// If we have an inner merge, we need to transpose the control flow so that\n\t\t\t\t\t// we avoid the inner merge altogether.\n\t\t\t\t\tVector<CFGNode *> constructs = { natural_merge };\n\t\t\t\t\tfor (auto *pred : inner_merge->pred)\n\t\t\t\t\t\tif (!query_reachability(*pred, *natural_merge) && !query_reachability(*natural_merge, *pred))\n\t\t\t\t\t\t\tconstructs.push_back(pred);\n\n\t\t\t\t\tif (constructs.size() >= 2)\n\t\t\t\t\t{\n\t\t\t\t\t\tcollect_and_dispatch_control_flow(node, merge, constructs, false, false);\n\t\t\t\t\t\treturn SwitchProgressMode::IterativeModify;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tmerge = inner_merge;\n\n\t\t\t\t// Relying on loop ladder system might not be possible in all situations.\n\t\t\t\t// It's possible that the switch block is also a loop header for example.\n\t\t\t\t// Need to transpose the code with a ladder to avoid impossible problems later.\n\t\t\t\tif (node->pred_back_edge)\n\t\t\t\t\tnatural_merge = transpose_code_path_through_ladder_block(node, natural_merge, inner_merge);\n\t\t\t}\n\t\t\telse if (merge && !node->dominates(merge))\n\t\t\t{\n\t\t\t\tCFGNode *dominance_frontier_candidate = nullptr;\n\n\t\t\t\t// If we have a normal merge scenario (merge == natural_merge),\n\t\t\t\t// there might still be breaks which can reach the switch merge block.\n\t\t\t\t// This can happen if a switch block is in an if() {} block, and\n\t\t\t\t// one of the case labels branch to the else() block. Both the switch and else() block\n\t\t\t\t// reconvene later, which means that we should hoist the break so it's not contained\n\t\t\t\t// in switch scope.\n\t\t\t\tfor (auto *frontier : node->dominance_frontier)\n\t\t\t\t{\n\t\t\t\t\tif (frontier->forward_post_visit_order != merge->forward_post_visit_order &&\n\t\t\t\t\t    query_reachability(*frontier, *merge))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Uncertain if we can deal with this.\n\t\t\t\t\t\t// Multiple nested branches perhaps?\n\t\t\t\t\t\tif (dominance_frontier_candidate)\n\t\t\t\t\t\t\tLOGW(\"Multiple candidates for switch break transposition.\\n\");\n\t\t\t\t\t\tdominance_frontier_candidate = frontier;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (dominance_frontier_candidate)\n\t\t\t\t\thoist_switch_branches_to_frontier(node, merge, dominance_frontier_candidate);\n\t\t\t}\n\n\t\t\tbool can_merge_to_post_dominator = merge && node->dominates(merge) && merge->headers.empty();\n\n\t\t\t// Need to guarantee that we can merge somewhere.\n\t\t\t// If possible we want to make it so that by creating a ladder,\n\t\t\t// we change the post-dominator to something we dominate.\n\t\t\t// For this to work, the dominance frontier of node must only contain the merge node.\n\t\t\tif (merge != natural_merge && !can_merge_to_post_dominator &&\n\t\t\t    node->dominance_frontier.size() == 1 && node->dominance_frontier.front() == merge)\n\t\t\t{\n\t\t\t\tmerge = create_switch_merge_ladder(node, merge);\n\t\t\t\tassert(node->dominates(merge));\n\t\t\t\tmodified_cfg = true;\n\t\t\t\tcan_merge_to_post_dominator = true;\n\t\t\t}\n\n\t\t\t// Need to rewrite the switch if we're not already a loop header.\n\t\t\tif (merge != natural_merge && can_merge_to_post_dominator && !node->pred_back_edge)\n\t\t\t{\n\t\t\t\tauto *switch_outer = create_helper_pred_block(node);\n\t\t\t\tswitch_outer->merge = MergeType::Loop;\n\t\t\t\tswitch_outer->loop_merge_block = merge;\n\t\t\t\tswitch_outer->freeze_structured_analysis = true;\n\t\t\t\tmerge->headers.push_back(switch_outer);\n\n\t\t\t\t// Shouldn't be needed (I believe), but spirv-val is a bit temperamental when double breaking\n\t\t\t\t// straight out of a switch block in some situations,\n\t\t\t\t// so try not to ruffle too many feathers.\n\t\t\t\tif (std::find(node->succ.begin(), node->succ.end(), natural_merge) != node->succ.end())\n\t\t\t\t{\n\t\t\t\t\tauto *dummy_case = pool.create_node();\n\t\t\t\t\tdummy_case->name = natural_merge->name + \".pred\";\n\t\t\t\t\tdummy_case->immediate_dominator = node;\n\t\t\t\t\tdummy_case->immediate_post_dominator = natural_merge;\n\t\t\t\t\tdummy_case->forward_post_visit_order = node->forward_post_visit_order;\n\t\t\t\t\tdummy_case->backward_post_visit_order = node->backward_post_visit_order;\n\t\t\t\t\tdummy_case->ir.terminator.type = Terminator::Type::Branch;\n\t\t\t\t\tdummy_case->ir.terminator.direct_block = natural_merge;\n\t\t\t\t\tdummy_case->add_branch(natural_merge);\n\t\t\t\t\tnode->retarget_branch(natural_merge, dummy_case);\n\t\t\t\t}\n\n\t\t\t\tnode->freeze_structured_analysis = true;\n\t\t\t}\n\n\t\t\t// Switch case labels must be contained within the switch statement.\n\t\t\t// Use a dummy label if we have to.\n\t\t\tauto succs = node->succ;\n\t\t\tfor (auto *succ : succs)\n\t\t\t{\n\t\t\t\tbool need_fixup = false;\n\t\t\t\tif (succ == merge)\n\t\t\t\t{\n\t\t\t\t\tif (merge != natural_merge)\n\t\t\t\t\t{\n\t\t\t\t\t\t// If we used outer shell method, we dominate merge,\n\t\t\t\t\t\t// but not structurally, since there's a loop merge already.\n\t\t\t\t\t\tneed_fixup = can_merge_to_post_dominator;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// If this happens we are our own outer shell.\n\t\t\t\t\t\t// The node itself is both a loop header *and* switch header,\n\t\t\t\t\t\t// so similar analysis applies.\n\t\t\t\t\t\t// Only consider fixup if we cannot reach continue block.\n\t\t\t\t\t\t// This can still be a normal inner merge for the switch, which then branches to continue block.\n\t\t\t\t\t\tneed_fixup = node->pred_back_edge != nullptr &&\n\t\t\t\t\t\t             !query_reachability(*succ, *node->pred_back_edge);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If we don't dominate succ, but it's not the common merge block, this is\n\t\t\t\t\t// an edge case we have to handle as well.\n\t\t\t\t\t// We might dominate a continue block, but these actually belong to outer loop scope.\n\t\t\t\t\tneed_fixup = !node->dominates(succ) || succ->succ_back_edge;\n\t\t\t\t}\n\n\t\t\t\t// Guard against duplicate label branches.\n\t\t\t\tbool has_succ = std::find(node->succ.begin(), node->succ.end(), succ) != node->succ.end();\n\n\t\t\t\tif (need_fixup && has_succ)\n\t\t\t\t{\n\t\t\t\t\tauto *dummy_break = pool.create_node();\n\t\t\t\t\tdummy_break->name = node->name + (succ->succ_back_edge ? \".continue\" : \".break\");\n\t\t\t\t\tdummy_break->immediate_dominator = node;\n\t\t\t\t\tdummy_break->immediate_post_dominator = succ;\n\t\t\t\t\tdummy_break->forward_post_visit_order = node->forward_post_visit_order;\n\t\t\t\t\tdummy_break->backward_post_visit_order = node->backward_post_visit_order;\n\t\t\t\t\tdummy_break->ir.terminator.type = Terminator::Type::Branch;\n\t\t\t\t\tdummy_break->ir.terminator.direct_block = succ;\n\t\t\t\t\tdummy_break->is_pseudo_back_edge = succ->succ_back_edge != nullptr;\n\t\t\t\t\tdummy_break->add_branch(succ);\n\t\t\t\t\tnode->retarget_branch(succ, dummy_break);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tmerge = natural_merge;\n\n\t\tCFGNode *merge_ladder = nullptr;\n\n\t\t// We cannot rewrite the CFG in pass 1 safely, this should have happened in pass 0.\n\t\tif (pass == 0 && (!node->dominates(merge) || block_is_plain_continue(merge)))\n\t\t{\n\t\t\tmerge_ladder = create_switch_merge_ladder(node, merge);\n\t\t\tmerge = find_common_post_dominator(node->succ);\n\t\t\t// If there are early-exits, the pdom may be nullptr. Safeguard against this.\n\t\t\t// This only seems to happen in dxbc2dxil.\n\t\t\tif (!merge)\n\t\t\t\tmerge = merge_ladder;\n\t\t\tmodified_cfg = true;\n\t\t}\n\n\t\tif (node->dominates(merge))\n\t\t{\n\t\t\t//LOGI(\"Switch merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(node), node->name.c_str(),\n\t\t\t//     static_cast<const void *>(merge), merge->name.c_str());\n\t\t\tnode->merge = MergeType::Selection;\n\n\t\t\t// There is a small chance that this is supposed to be a loop merge target.\n\t\t\t// We'll fix that up later if needed. In that case, the switch block will merge to unreachable.\n\n\t\t\tnode->selection_merge_block = merge;\n\t\t\tmerge->add_unique_header(node);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// We got a switch block where someone is escaping. Similar idea as for loop analysis.\n\t\t\t// Find a post-dominator where we ignore branches which are \"escaping\".\n\t\t\tauto *dominated_merge_target = find_common_post_dominator_with_ignored_break(node->succ, merge);\n\n\t\t\tif (!dominated_merge_target)\n\t\t\t{\n\t\t\t\tLOGW(\"No dominated merge target found. Likely a bug. Falling back to merge ladder.\\n\");\n\t\t\t\tdominated_merge_target = merge_ladder;\n\t\t\t}\n\n\t\t\tassert(dominated_merge_target);\n\n\t\t\tif (node->dominates(dominated_merge_target))\n\t\t\t{\n\t\t\t\tnode->merge = MergeType::Selection;\n\t\t\t\tnode->selection_merge_block = merge;\n\t\t\t\tdominated_merge_target->add_unique_header(node);\n\t\t\t\tmerge->add_unique_header(node);\n\t\t\t}\n\t\t}\n\n\t\t// A switch header might also be a loop header. Create a helper succ block for this case.\n\t\tif (pass == 0 && node->pred_back_edge)\n\t\t{\n\t\t\tnode = create_helper_succ_block(node);\n\t\t\tmodified_cfg = true;\n\t\t}\n\t}\n\n\treturn modified_cfg ? SwitchProgressMode::SimpleModify : SwitchProgressMode::Done;\n}\n\nbool CFGStructurizer::merge_candidate_is_inside_continue_construct(const CFGNode *node) const\n{\n\t// If we've reached the continue construct, we cannot merge away from that construct.\n\t// Any such merge must be eliminated. We can know this for certain if the succ of node\n\t// post dominates the entire loop construct, since that node is the obvious merge node.\n\tassert(node->succ.size() == 1);\n\tfor (auto *pred : node->pred)\n\t{\n\t\tif (pred->succ_back_edge &&\n\t\t    node->succ.front()->post_dominates(pred->succ_back_edge) &&\n\t\t\tpred->succ_back_edge->dominates(node->succ.front()) &&\n\t\t    !pred->dominates(node))\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool CFGStructurizer::merge_candidate_is_on_breaking_path(const CFGNode *node) const\n{\n\treturn node->pred.size() >= 2 && node->succ.size() == 1 &&\n\t       !node->dominates(node->succ.front()) &&\n\t       node->succ.front()->post_dominates(node) &&\n\t       control_flow_is_escaping(node, node->succ.front()) &&\n\t       !node->post_dominates_perfect_structured_construct();\n}\n\nvoid CFGStructurizer::find_selection_merges(unsigned pass)\n{\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->num_forward_preds() <= 1)\n\t\t\tcontinue;\n\n\t\t// Never merge to continue block.\n\t\t// We should never hit this path unless we explicitly\n\t\t// avoided creating a continue ladder block earlier.\n\t\tif (block_is_plain_continue(node))\n\t\t\tcontinue;\n\n\t\t// If there are 2 or more pred edges, try to merge execution.\n\n\t\t// The idom is the natural header block.\n\t\tauto *idom = node->immediate_dominator;\n\t\tassert(idom->succ.size() >= 2);\n\n\t\t// Check for case fallthrough here. In this case, we do not have a merge scenario, just ignore.\n\t\tauto *inner_header = node->get_outer_selection_dominator();\n\t\tif (inner_header && inner_header->ir.terminator.type == Terminator::Type::Switch)\n\t\t{\n\t\t\tif (inner_header->selection_merge_block == node)\n\t\t\t{\n\t\t\t\t// We just found a switch block which we have already handled.\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (std::find(inner_header->succ.begin(), inner_header->succ.end(), node) != inner_header->succ.end())\n\t\t\t{\n\t\t\t\t// Fallthrough.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tfor (auto *header : node->headers)\n\t\t{\n\t\t\t// If we have a loop header already associated with this block, treat that as our idom.\n\t\t\tif (header->forward_post_visit_order > idom->forward_post_visit_order)\n\t\t\t\tidom = header;\n\t\t}\n\n\t\t// Similar, but also check if we have associated ladder blocks with the idom.\n\t\tif (!idom->pred_back_edge)\n\t\t{\n\t\t\tauto *inner_loop_header = get_innermost_loop_header_for(idom);\n\t\t\tif (inner_loop_header && inner_loop_header->loop_ladder_block == node)\n\t\t\t\tidom = const_cast<CFGNode *>(inner_loop_header);\n\t\t}\n\n\t\tif (idom->merge == MergeType::None || idom->merge == MergeType::Selection)\n\t\t{\n\t\t\t// We just found a switch block which we have already handled.\n\t\t\tif (idom->ir.terminator.type == Terminator::Type::Switch)\n\t\t\t\tcontinue;\n\n\t\t\t// If the idom is already a selection construct, this must mean\n\t\t\t// we have some form of breaking construct inside this inner construct.\n\t\t\t// This fooled find_selection_merges() to think we had a selection merge target at the break target.\n\t\t\t// Fix this up here, where we rewrite the outer construct as a fixed loop instead.\n\t\t\tif (idom->merge == MergeType::Selection)\n\t\t\t{\n\t\t\t\tif (pass == 0)\n\t\t\t\t{\n\t\t\t\t\tassert(idom->selection_merge_block);\n\n\t\t\t\t\t// If we turn the outer selection construct into a loop,\n\t\t\t\t\t// we remove the possibility to break further out (without adding ladders like we do for loops).\n\t\t\t\t\t// To make this work, we must ensure that the new merge block post-dominates the loop and selection merge.\n\t\t\t\t\tauto *merge_candidate = CFGNode::find_common_post_dominator(idom->selection_merge_block, idom);\n\n\t\t\t\t\tif (!merge_candidate || merge_candidate == idom->selection_merge_block)\n\t\t\t\t\t{\n\t\t\t\t\t\tidom->loop_merge_block = idom->selection_merge_block;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Make sure we split merge scopes. Pretend we have a true loop.\n\t\t\t\t\t\tidom->loop_ladder_block = idom->selection_merge_block;\n\t\t\t\t\t\tidom->loop_merge_block = merge_candidate;\n\t\t\t\t\t}\n\n\t\t\t\t\tidom->loop_merge_block->add_unique_header(idom);\n\n\t\t\t\t\tidom->merge = MergeType::Loop;\n\t\t\t\t\tidom->selection_merge_block = nullptr;\n\t\t\t\t\tidom->freeze_structured_analysis = true;\n\t\t\t\t\tidom = create_helper_succ_block(idom);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tLOGW(\"Mismatch headers in pass 1 ... ?\\n\");\n\t\t\t}\n\n\t\t\t// If we're in a pass 1, opting for a selection merge better make sure that we can\n\t\t\t// actually use this as a merge block.\n\t\t\t// If we have more than 2 preds, there is no way this is not a break block merge.\n\t\t\t// It is not a switch statement and selections spawn two new scopes.\n\t\t\t// We should have resolved this in pass 0, but it can slip through the cracks if there\n\t\t\t// are multiple interleaving merge scopes in play.\n\t\t\tbool force_loop = pass == 1 &&\n\t\t\t                  node->num_forward_preds() > 2 &&\n\t\t\t                  idom->merge == MergeType::None;\n\n\t\t\tif (force_loop)\n\t\t\t{\n\t\t\t\tidom->merge = MergeType::Loop;\n\t\t\t\tnode->add_unique_header(idom);\n\t\t\t\tidom->loop_merge_block = node;\n\t\t\t\tidom->freeze_structured_analysis = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tidom->merge = MergeType::Selection;\n\t\t\t\tnode->add_unique_header(idom);\n\t\t\t\tassert(node);\n\t\t\t\tidom->selection_merge_block = node;\n\t\t\t\t//LOGI(\"Selection merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(idom), idom->name.c_str(),\n\t\t\t\t//     static_cast<const void *>(node), node->name.c_str());\n\t\t\t}\n\t\t}\n\t\telse if (idom->merge == MergeType::Loop)\n\t\t{\n\t\t\tif (pass == 0)\n\t\t\t{\n\t\t\t\tif (idom->loop_merge_block == node && idom->loop_ladder_block)\n\t\t\t\t{\n\t\t\t\t\t// We need to create an outer shell for this header since we need to ladder break to this node.\n\t\t\t\t\tauto *loop = create_helper_pred_block(idom);\n\t\t\t\t\tloop->merge = MergeType::Loop;\n\t\t\t\t\tloop->loop_merge_block = node;\n\t\t\t\t\tloop->freeze_structured_analysis = true;\n\t\t\t\t\tnode->add_unique_header(loop);\n\t\t\t\t\t//LOGI(\"Loop merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(loop), loop->name.c_str(),\n\t\t\t\t\t//     static_cast<const void *>(node), node->name.c_str());\n\t\t\t\t}\n\t\t\t\telse if (idom->loop_merge_block != node && idom->loop_ladder_block != node)\n\t\t\t\t{\n\t\t\t\t\tauto *selection_idom = create_helper_succ_block(idom);\n\t\t\t\t\t// If we split the loop header into the loop header -> selection merge header,\n\t\t\t\t\t// then we can merge into a continue block for example.\n\t\t\t\t\tselection_idom->merge = MergeType::Selection;\n\t\t\t\t\tselection_idom->selection_merge_block = node;\n\t\t\t\t\tnode->add_unique_header(selection_idom);\n\t\t\t\t\t//LOGI(\"Selection merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(selection_idom),\n\t\t\t\t\t//     selection_idom->name.c_str(), static_cast<const void *>(node), node->name.c_str());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// We are hosed. There is no obvious way to merge execution here.\n\t\t\t// This might be okay.\n\t\t\tLOGW(\"Cannot merge execution for node %p (%s).\\n\", static_cast<const void *>(node), node->name.c_str());\n\t\t}\n\t}\n}\n\nconst CFGNode *CFGStructurizer::get_innermost_loop_header_for(const CFGNode *header, const CFGNode *other) const\n{\n\tauto *node = other;\n\n\twhile (header != other)\n\t{\n\t\t// Entry block case.\n\t\tif (other->pred.empty())\n\t\t\tbreak;\n\n\t\t// Found a loop header. This better be the one.\n\t\t// Detect false positive if back-edge can reach the node, this means we just skip over\n\t\t// the loop. We want to detect loops in a structured sense.\n\t\t// Breaking constructs should still detect the loop header as we'd expect.\n\t\tif (other->pred_back_edge && (other->pred_back_edge == node || !query_reachability(*other->pred_back_edge, *node)))\n\t\t\tbreak;\n\n\t\tassert(other->immediate_dominator);\n\t\tother = other->immediate_dominator;\n\t}\n\n\treturn other;\n}\n\nconst CFGNode *CFGStructurizer::get_innermost_loop_header_for(const CFGNode *other) const\n{\n\treturn get_innermost_loop_header_for(entry_block, other);\n}\n\nbool CFGStructurizer::loop_exit_supports_infinite_loop(const CFGNode *header, const CFGNode *loop_exit) const\n{\n\tauto *inner_header = get_innermost_loop_header_for(header, loop_exit);\n\t// A loop exit can exit out to an outer scope such that inner_header dominates the header.\n\t// If there is no inner loop we can transform the loop exit into a merge block quite easily\n\t// and avoid the infinite loop.\n\tif (inner_header->dominates(header))\n\t\treturn false;\n\n\t// We have a candidate. If the candidates dominates all reachable exits, there is never a need to merge later.\n\treturn loop_exit->dominates_all_reachable_exits();\n}\n\nCFGStructurizer::LoopExitType CFGStructurizer::get_loop_exit_type(const CFGNode &header, const CFGNode &node) const\n{\n\t// If there exists an inner loop which dominates this exit, we treat it as an inner loop exit.\n\tconst CFGNode *innermost_loop_header = get_innermost_loop_header_for(&header, &node);\n\tbool is_innermost_loop_header = &header == innermost_loop_header;\n\n\t// If a back-edge can reach this node, it's not really an exit, but an Escape.\n\t// Exits must never branch \"out\" of the loop.\n\tif (header.dominates(&node) &&\n\t    (!header.pred_back_edge || !query_reachability(*header.pred_back_edge, node)) &&\n\t    node.dominates_all_reachable_exits())\n\t{\n\t\tif (is_innermost_loop_header)\n\t\t\treturn LoopExitType::Exit;\n\t\telse\n\t\t\treturn LoopExitType::InnerLoopExit;\n\t}\n\n\tif (header.dominates(&node))\n\t{\n\t\tif (is_innermost_loop_header)\n\t\t{\n\t\t\t// Even if we dominate node, we might not be able to merge to it.\n\t\t\tif (!header.can_loop_merge_to(&node))\n\t\t\t{\n\t\t\t\t// This is an escape we dominate, but this could also be a case where we break\n\t\t\t\t// to a continue construct in the outer loop which is not reachable through back traversal.\n\t\t\t\t// This will confuse loop analysis, since this kind of double continue will not resolve properly.\n\t\t\t\t// In this case we need to rendezvous at this block with a ladder to avoid\n\t\t\t\t// double-continue.\n\n\t\t\t\tauto *outer_infinite_loop = get_innermost_loop_header_for(entry_block,\n\t\t\t\t                                                          innermost_loop_header->immediate_dominator);\n\t\t\t\tif (outer_infinite_loop && outer_infinite_loop->pred_back_edge &&\n\t\t\t\t    outer_infinite_loop->pred_back_edge->succ.empty() &&\n\t\t\t\t    outer_infinite_loop->pred_back_edge->post_dominates(&node))\n\t\t\t\t{\n\t\t\t\t\treturn LoopExitType::MergeToInfiniteLoop;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treturn LoopExitType::Escape;\n\t\t\t}\n\n\t\t\treturn LoopExitType::Merge;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Try to detect if this is a degenerate inner loop merge.\n\t\t\t// If the inner loop header is the only way to exit the loop construct,\n\t\t\t// the loop exit block is a false exit.\n\t\t\t// This is the case if the candidate must pass through the back edge, and the back edge can only branch to header.\n\t\t\t// In this case, the loop will not be visible through back-propagation, but it is definitely part of the loop construct.\n\n\t\t\tif (!innermost_loop_header->pred_back_edge || innermost_loop_header->pred_back_edge->ir.terminator.type != Terminator::Type::Branch)\n\t\t\t\treturn LoopExitType::InnerLoopMerge;\n\n\t\t\tauto *post = find_common_post_dominator({ const_cast<CFGNode *>(&node), innermost_loop_header->pred_back_edge });\n\t\t\tif (post == innermost_loop_header->pred_back_edge)\n\t\t\t\treturn LoopExitType::InnerLoopFalsePositive;\n\t\t\telse\n\t\t\t\treturn LoopExitType::InnerLoopMerge;\n\t\t}\n\t}\n\telse\n\t\treturn LoopExitType::Escape;\n}\n\nCFGNode *CFGStructurizer::create_helper_pred_block(CFGNode *node)\n{\n\tauto *pred_node = pool.create_node();\n\tpred_node->name = node->name + \".pred\";\n\n\t// Fixup visit order later.\n\tpred_node->forward_post_visit_order = node->forward_post_visit_order;\n\tpred_node->backward_post_visit_order = node->backward_post_visit_order;\n\n\tstd::swap(pred_node->pred, node->pred);\n\tfor (auto *header : node->headers)\n\t\theader->fixup_merge_info_after_branch_rewrite(node, pred_node);\n\tnode->headers.clear();\n\n\t// We're replacing entry block.\n\tif (node == node->immediate_dominator)\n\t\tpred_node->immediate_dominator = pred_node;\n\telse\n\t\tpred_node->immediate_dominator = node->immediate_dominator;\n\n\tpred_node->immediate_post_dominator = node;\n\tnode->immediate_dominator = pred_node;\n\n\tretarget_pred_from(pred_node, node);\n\n\tpred_node->add_branch(node);\n\n\tif (node == entry_block)\n\t\tentry_block = pred_node;\n\n\tpred_node->ir.terminator.type = Terminator::Type::Branch;\n\tpred_node->ir.terminator.direct_block = node;\n\n\treturn pred_node;\n}\n\nvoid CFGStructurizer::retarget_pred_from(CFGNode *new_node, CFGNode *old_succ)\n{\n\tfor (auto *p : new_node->pred)\n\t{\n\t\tfor (auto &s : p->succ)\n\t\t\tif (s == old_succ)\n\t\t\t\ts = new_node;\n\n\t\tauto &p_term = p->ir.terminator;\n\t\tif (p_term.direct_block == old_succ)\n\t\t\tp_term.direct_block = new_node;\n\t\tif (p_term.true_block == old_succ)\n\t\t\tp_term.true_block = new_node;\n\t\tif (p_term.false_block == old_succ)\n\t\t\tp_term.false_block = new_node;\n\t\tfor (auto &c : p_term.cases)\n\t\t\tif (c.node == old_succ)\n\t\t\t\tc.node = new_node;\n\t}\n\n\t// Do not swap back edges.\n\n\t// Retarget immediate post dominators.\n\tfor (auto *n : forward_post_visit_order)\n\t\tif (n->immediate_post_dominator == old_succ)\n\t\t\tn->immediate_post_dominator = new_node;\n}\n\nvoid CFGStructurizer::retarget_succ_from(CFGNode *new_node, CFGNode *old_pred)\n{\n\tfor (auto *s : new_node->succ)\n\t\tfor (auto &p : s->pred)\n\t\t\tif (p == old_pred)\n\t\t\t\tp = new_node;\n\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node != old_pred)\n\t\t{\n\t\t\t// Don't override immediate dominator for entry block.\n\t\t\tif (node->immediate_dominator == old_pred)\n\t\t\t\tnode->immediate_dominator = new_node;\n\t\t}\n\t}\n\tnew_node->immediate_dominator = old_pred;\n\n\t// Do not swap back edges.\n}\n\nCFGNode *CFGStructurizer::create_helper_succ_block(CFGNode *node)\n{\n\tauto *succ_node = pool.create_node();\n\tsucc_node->name = node->name + \".succ\";\n\n\t// Fixup visit order later.\n\tsucc_node->forward_post_visit_order = node->forward_post_visit_order;\n\tsucc_node->backward_post_visit_order = node->backward_post_visit_order;\n\n\tstd::swap(succ_node->succ, node->succ);\n\t// Do not swap back edges, only forward edges.\n\n\tsucc_node->immediate_post_dominator = node->immediate_post_dominator;\n\tnode->immediate_post_dominator = succ_node;\n\n\tsucc_node->ir.terminator = node->ir.terminator;\n\tnode->ir.terminator.type = Terminator::Type::Branch;\n\tnode->ir.terminator.direct_block = succ_node;\n\n\t// Inherit selection construct from parent since we're taking over any selection.\n\tif (succ_node->ir.terminator.type == Terminator::Type::Condition)\n\t\tsucc_node->ir.merge_info.selection_control_mask = node->ir.merge_info.selection_control_mask;\n\n\tretarget_succ_from(succ_node, node);\n\n\tnode->add_branch(succ_node);\n\treturn succ_node;\n}\n\nCFGNode *CFGStructurizer::find_common_post_dominator(const Vector<CFGNode *> &candidates)\n{\n\tif (candidates.empty())\n\t\treturn nullptr;\n\telse if (candidates.size() == 1)\n\t\treturn candidates.front();\n\n\tCFGNode *common_post = CFGNode::find_common_post_dominator(candidates[0], candidates[1]);\n\tfor (size_t i = 2; i < candidates.size(); i++)\n\t\tcommon_post = CFGNode::find_common_post_dominator(common_post, candidates[i]);\n\treturn common_post != common_post->immediate_post_dominator ? common_post : nullptr;\n}\n\nCFGNode *CFGStructurizer::find_break_target_for_selection_construct(CFGNode *idom, CFGNode *merge)\n{\n\tVector<CFGNode *> new_visit_queue;\n\tUnorderedSet<CFGNode *> visited;\n\tVector<CFGNode *> visit_queue;\n\tVector<CFGNode *> candidates;\n\n\tvisit_queue.push_back(idom);\n\tdo\n\t{\n\t\tfor (auto *n : visit_queue)\n\t\t{\n\t\t\tif (visited.count(n))\n\t\t\t\tcontinue;\n\t\t\tvisited.insert(n);\n\n\t\t\tif (query_reachability(*merge, *n))\n\t\t\t\tcontinue;\n\n\t\t\tif (query_reachability(*n, *merge))\n\t\t\t{\n\t\t\t\tfor (auto *succ : n->succ)\n\t\t\t\t\tnew_visit_queue.push_back(succ);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Cannot merge into a loop construct.\n\t\t\t\t// Merging towards an outer loop construct would probably lead to weird results,\n\t\t\t\t// but allow it here.\n\t\t\t\tauto *inner = get_innermost_loop_header_for(n);\n\t\t\t\tif (inner != entry_block && query_reachability(*idom, *inner))\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// The breaking path might be vestigal.\n\t\t\t\t// I.e., it might just be exiting directly without dominating anything.\n\t\t\t\t// Have to detect this false positive, since it's not really a break, just early return.\n\t\t\t\t// If we hit a dominance frontier, allow it as a candidate since it cannot be early return within\n\t\t\t\t// the construct.\n\t\t\t\tif (!n->dominates_all_reachable_exits() || !idom->dominates(n))\n\t\t\t\t\tcandidates.push_back(n);\n\t\t\t}\n\t\t}\n\n\t\tvisit_queue = new_visit_queue;\n\t\tnew_visit_queue.clear();\n\t} while (!visit_queue.empty());\n\n\tif (candidates.empty())\n\t\treturn nullptr;\n\telse\n\t\treturn find_common_post_dominator(candidates);\n}\n\nCFGNode *CFGStructurizer::find_common_post_dominator_with_ignored_break(Vector<CFGNode *> candidates,\n                                                                        const CFGNode *ignored_node)\n{\n\tif (candidates.empty())\n\t\treturn nullptr;\n\n\tVector<CFGNode *> next_nodes;\n\tconst auto add_unique_next_node = [&](CFGNode *node) {\n\t\tif (node != ignored_node)\n\t\t\tif (std::find(next_nodes.begin(), next_nodes.end(), node) == next_nodes.end())\n\t\t\t\tnext_nodes.push_back(node);\n\t};\n\n\twhile (candidates.size() != 1)\n\t{\n\t\t// Sort candidates by post visit order.\n\t\tstd::sort(candidates.begin(), candidates.end(),\n\t\t          [](const CFGNode *a, const CFGNode *b) { return a->forward_post_visit_order > b->forward_post_visit_order; });\n\n\t\t// We reached exit without merging execution, there is no common post dominator.\n\t\t// A continue block which only branches back to header is conveniently ignored here.\n\t\tif (candidates.front()->succ.empty() && !candidates.front()->succ_back_edge)\n\t\t\treturn nullptr;\n\n\t\tfor (auto *succ : candidates.front()->succ)\n\t\t\tadd_unique_next_node(succ);\n\t\tfor (auto itr = candidates.begin() + 1; itr != candidates.end(); ++itr)\n\t\t\tadd_unique_next_node(*itr);\n\n\t\tcandidates.clear();\n\t\tstd::swap(candidates, next_nodes);\n\t}\n\n\tif (candidates.empty())\n\t\treturn nullptr;\n\n\treturn candidates.front();\n}\n\nvoid CFGStructurizer::rewrite_ladder_conditional_branch_from_incoming_blocks(\n\tCFGNode *ladder, CFGNode *true_block, CFGNode *false_block,\n\tconst std::function<bool (const CFGNode *)> &path_cb, const String &name)\n{\n\tladder->add_branch(true_block);\n\tladder->add_branch(false_block);\n\n\tladder->ir.terminator.type = Terminator::Type::Condition;\n\tladder->ir.terminator.conditional_id = module.allocate_id();\n\tladder->ir.terminator.true_block = true_block;\n\tladder->ir.terminator.false_block = false_block;\n\tladder->ir.terminator.direct_block = nullptr;\n\n\tPHI phi;\n\tphi.id = ladder->ir.terminator.conditional_id;\n\tphi.type_id = module.get_builder().makeBoolType();\n\tmodule.get_builder().addName(phi.id, name.c_str());\n\n\tfor (auto *pred : ladder->pred)\n\t{\n\t\tIncomingValue incoming = {};\n\t\tincoming.block = pred;\n\t\tincoming.id = module.get_builder().makeBoolConstant(path_cb(pred));\n\t\tphi.incoming.push_back(incoming);\n\t}\n\n\tladder->ir.phi.push_back(std::move(phi));\n}\n\nCFGNode *CFGStructurizer::transpose_code_path_through_ladder_block(\n    CFGNode *header, CFGNode *merge, CFGNode *path)\n{\n\tassert(header->dominates(merge) && header->dominates(path));\n\tassert(query_reachability(*merge, *path));\n\tassert(!merge->dominates(path));\n\tassert(header != merge);\n\tassert(merge != path);\n\tassert(header != path);\n\n\t// Rewrite the merge block into merge.pred where merge.pred will branch to either merge or path.\n\tauto *ladder = create_ladder_block(header, merge, \".transpose\");\n\n\tUnorderedSet<const CFGNode *> normal_preds;\n\tfor (auto *p : ladder->pred)\n\t\tnormal_preds.insert(p);\n\ttraverse_dominated_blocks_and_rewrite_branch(header, path, ladder);\n\trewrite_ladder_conditional_branch_from_incoming_blocks(\n\t\tladder, path, merge, [&](const CFGNode *n) { return normal_preds.count(n) == 0; },\n\t\tString(\"transpose_ladder_phi_\") + ladder->name);\n\treturn ladder;\n}\n\nvoid CFGStructurizer::rewrite_transposed_loop_outer(CFGNode *node, CFGNode *impossible_merge_target,\n                                                    const LoopMergeAnalysis &analysis)\n{\n\tauto impossible_preds = impossible_merge_target->pred;\n\n\tauto *replaced_merge_block = create_helper_pred_block(analysis.dominated_merge);\n\treplaced_merge_block->name = analysis.dominated_merge->name + \".transposed-merge-outer\";\n\n\tfor (auto *pred : impossible_preds)\n\t\tif (!query_reachability(*analysis.dominated_merge, *pred))\n\t\t\tpred->retarget_branch(impossible_merge_target, replaced_merge_block);\n\n\trewrite_ladder_conditional_branch_from_incoming_blocks(\n\t\treplaced_merge_block,\n\t\timpossible_merge_target, analysis.dominated_merge,\n\t\t[&](const CFGNode *n) {\n\t\t\treturn std::find(impossible_preds.begin(), impossible_preds.end(), n) != impossible_preds.end();\n\t\t}, String(\"transposed_selector_\") + node->name);\n}\n\nvoid CFGStructurizer::rewrite_transposed_loop_inner(CFGNode *node, CFGNode *impossible_merge_target,\n                                                    const LoopMergeAnalysis &analysis)\n{\n\t// Rewrite the control flow from the inside out through a transposition.\n\t// The common break target will become the merge block instead.\n\t// The continue will break out to the transposed merge instead.\n\t// In the ladder, we will enter a breaking path which branches out to loop_ladder.\n\n\t// We just arbitrary call this \"inner\", since I don't think it has a formal name.\n\t// In this case, dominated merge cannot reach impossible merge target.\n\n\tauto *merge = analysis.merge;\n\tauto *dominated_merge = analysis.dominated_merge;\n\n\tauto *ladder_break = pool.create_node();\n\tladder_break->name = node->name + \".transposed-merge-inner.break\";\n\tladder_break->ir.terminator.type = Terminator::Type::Branch;\n\tladder_break->ir.terminator.direct_block = impossible_merge_target;\n\tladder_break->immediate_post_dominator = impossible_merge_target;\n\tladder_break->forward_post_visit_order = impossible_merge_target->forward_post_visit_order;\n\tladder_break->backward_post_visit_order = impossible_merge_target->backward_post_visit_order;\n\n\tauto *ladder_selection = pool.create_node();\n\tladder_selection->name = node->name + \".transposed-merge-inner\";\n\tladder_selection->forward_post_visit_order = impossible_merge_target->forward_post_visit_order;\n\tladder_selection->backward_post_visit_order = impossible_merge_target->backward_post_visit_order;\n\tladder_selection->immediate_post_dominator = merge;\n\tladder_break->immediate_dominator = ladder_selection;\n\n\tauto ladder_preds = dominated_merge->pred;\n\n\tladder_selection->add_branch(ladder_break);\n\tladder_selection->add_branch(dominated_merge);\n\ttraverse_dominated_blocks_and_rewrite_branch(node, impossible_merge_target, ladder_selection);\n\tladder_selection->recompute_immediate_dominator();\n\n\tladder_break->add_branch(impossible_merge_target);\n\n\t// Branches from these blocks should be rewritten to target transposed-merge.\n\tfor (auto *ladder_pred : ladder_preds)\n\t\tladder_pred->retarget_branch(dominated_merge, ladder_selection);\n\n\trewrite_ladder_conditional_branch_from_incoming_blocks(\n\t\tladder_selection,\n\t\tdominated_merge, ladder_break,\n\t\t[&](const CFGNode *n) { return std::find(ladder_preds.begin(), ladder_preds.end(), n) != ladder_preds.end(); },\n\t\tString(\"transposed_selector_\") + node->name);\n}\n\nbool CFGStructurizer::rewrite_transposed_loops()\n{\n\tbool did_rewrite = false;\n\n\tfor (auto index = forward_post_visit_order.size(); index && !did_rewrite; index--)\n\t{\n\t\t// Visit in reverse order so we resolve outer loops first,\n\t\t// this lets us detect ladder-breaking loops.\n\t\tauto *node = forward_post_visit_order[index - 1];\n\n\t\tif (node->freeze_structured_analysis && node->merge == MergeType::Loop)\n\t\t\tcontinue;\n\t\tif (!node->has_pred_back_edges())\n\t\t\tcontinue;\n\n\t\tauto result = analyze_loop(node);\n\t\tauto merge_result = analyze_loop_merge(node, result);\n\n\t\tauto *merge = merge_result.merge;\n\t\tauto *dominated_merge = merge_result.dominated_merge;\n\n\t\tif (!merge || !dominated_merge)\n\t\t\tcontinue;\n\n\t\t// We might have a horribly complex scenario where a loop breaks, but it breaks to an outer scope\n\t\t// which is not consistent with the merge block, i.e. we need structured control flow to resolve properly\n\t\t// before we can break. This is ... problematic.\n\n\t\t// We call this an \"inner\" transposed loop here since merge block cannot reach this block.\n\n\t\t// Always resolve infinite continue ladders. This is where we break to\n\t\t// an outer infinite loop. We must resolve the scopes by making this ladder the\n\t\t// merge point, then we can break further.\n\t\tCFGNode *impossible_merge_target = merge_result.infinite_continue_ladder;\n\n\t\tif (!impossible_merge_target && !result.non_dominated_exit.empty())\n\t\t{\n\t\t\tauto *common_break_target = find_common_post_dominator(result.non_dominated_exit);\n\t\t\tif (common_break_target && common_break_target != merge &&\n\t\t\t    !query_reachability(*dominated_merge, *common_break_target) &&\n\t\t\t    !query_reachability(*common_break_target, *dominated_merge))\n\t\t\t{\n\t\t\t\t// Another weird scenario is where we dominate the outer continue,\n\t\t\t\t// which would escape the DF analysis, but that is strong evidence we need to transpose.\n\t\t\t\t// A normal break would never dominate anything like that.\n\t\t\t\tif (common_break_target->reaches_domination_frontier_before_merge(merge) ||\n\t\t\t\t\tcommon_break_target->dominates_outer_continue(node))\n\t\t\t\t{\n\t\t\t\t\timpossible_merge_target = common_break_target;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!impossible_merge_target)\n\t\t{\n\t\t\t// We might have a different scenario where there are multiple breaks, but they break out to different\n\t\t\t// scopes. One of these might require a similar impossible merge.\n\t\t\t// Common post dominator analysis would not catch this.\n\t\t\t// What we're looking for is a node which:\n\t\t\t// - Is dominated by loop header (or is in the domination frontier of loop header)\n\t\t\t// - Is reachable, but not dominated by dominated_merge.\n\t\t\t// - Post dominates one of the non_dominated_exits.\n\t\t\t// This means the node is in a twilight zone where the node is kinda in the loop construct, but kinda not.\n\n\t\t\t// Structured rules for a loop state that a node is in the construct if:\n\t\t\t// - It is dominated by loop header\n\t\t\t// - Not dominated by merge block.\n\t\t\t// In a sense, the merge block ends up branching back into its own loop, which is irreducible, kinda ...\n\n\t\t\t// We call this an \"outer\" transposed loop here since merge block *can* reach this block.\n\n\t\t\tfor (size_t i = 0, n = result.non_dominated_exit.size(); i < n && !impossible_merge_target; i++)\n\t\t\t{\n\t\t\t\tauto *candidate = result.non_dominated_exit[i];\n\n\t\t\t\twhile (candidate != merge && candidate != dominated_merge)\n\t\t\t\t{\n\t\t\t\t\tif (query_reachability(*dominated_merge, *candidate) && !dominated_merge->dominates(candidate))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Merge block attempts to branch back into its own loop construct (yikes).\n\t\t\t\t\t\timpossible_merge_target = candidate;\n\n\t\t\t\t\t\t// If we don't dominate the merge target, i.e. we're in the domination frontier,\n\t\t\t\t\t\t// we have to synthesize a fake impossible merge target first since the rewrite\n\t\t\t\t\t\t// algorithm depends on node dominating the merge target.\n\t\t\t\t\t\tif (!node->dominates(impossible_merge_target))\n\t\t\t\t\t\t\timpossible_merge_target = create_ladder_block(node, impossible_merge_target, \".impossible-ladder\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse if (node->dominates(candidate) && candidate != candidate->immediate_post_dominator)\n\t\t\t\t\t{\n\t\t\t\t\t\tcandidate = candidate->immediate_post_dominator;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// We will be able to select a candidate in the domination frontier once.\n\t\t\t\t\t\t// If we failed to find a candidate in the domination frontier, we're done checking.\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (impossible_merge_target)\n\t\t{\n\t\t\tif (query_reachability(*dominated_merge, *impossible_merge_target))\n\t\t\t\trewrite_transposed_loop_outer(node, impossible_merge_target, merge_result);\n\t\t\telse\n\t\t\t\trewrite_transposed_loop_inner(node, impossible_merge_target, merge_result);\n\n\t\t\t// We have obliterated the existing control flow through transposition,\n\t\t\t// and any domination or post-domination analysis will break.\n\t\t\t// Re-traverse the CFG and try again.\n\t\t\t// Continue until we have eliminated all impossible loops (should be extremely rare).\n\t\t\tdid_rewrite = true;\n\t\t}\n\t\telse if (!result.non_dominated_exit.empty() && dominated_merge->dominance_frontier.size() >= 2)\n\t\t{\n\t\t\t// If we cannot find the impossible merge target through post-domination analysis,\n\t\t\t// we might find it through domination frontier analysis.\n\t\t\t// If all loop exits and the loop header share a domination frontier,\n\t\t\t// it's probably our candidate.\n\n\t\t\t// Only apply this analysis to cases where a loop has at least two dominance frontiers,\n\t\t\t// which also don't have a dominance relationship with each other.\n\t\t\t// This is evidence that the loop is attempting to break to multiple different scopes.\n\t\t\tauto frontier = dominated_merge->dominance_frontier;\n\n\t\t\tstd::stable_sort(frontier.begin(), frontier.end(), [](const CFGNode *a, const CFGNode *b)\n\t\t\t{\n\t\t\t\treturn a->forward_post_visit_order > b->forward_post_visit_order;\n\t\t\t});\n\n\t\t\tbool frontier_has_dominance_relationship = false;\n\t\t\tfor (size_t i = 0, n = frontier.size(); i < n && !frontier_has_dominance_relationship; i++)\n\t\t\t\tfor (size_t j = i + 1; j < n && !frontier_has_dominance_relationship; j++)\n\t\t\t\t\tif (frontier[i]->dominates(frontier[j]))\n\t\t\t\t\t\tfrontier_has_dominance_relationship = true;\n\n\t\t\tif (frontier_has_dominance_relationship)\n\t\t\t\tcontinue;\n\n\t\t\tfor (auto *candidate : dominated_merge->dominance_frontier)\n\t\t\t{\n\t\t\t\tbool all_frontier = std::find(node->dominance_frontier.begin(), node->dominance_frontier.end(),\n\t\t\t\t                              candidate) != node->dominance_frontier.end();\n\n\t\t\t\tif (all_frontier)\n\t\t\t\t{\n\t\t\t\t\tfor (auto *non_dominated : result.non_dominated_exit)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!node->dominates(non_dominated))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tall_frontier = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (std::find(non_dominated->dominance_frontier.begin(), non_dominated->dominance_frontier.end(),\n\t\t\t\t\t\t\t\t\t  candidate) == non_dominated->dominance_frontier.end())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tall_frontier = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (all_frontier)\n\t\t\t\t{\n\t\t\t\t\tif (!impossible_merge_target ||\n\t\t\t\t\t\tcandidate->forward_post_visit_order > impossible_merge_target->forward_post_visit_order)\n\t\t\t\t\t{\n\t\t\t\t\t\timpossible_merge_target = candidate;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\timpossible_merge_target = nullptr;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (impossible_merge_target)\n\t\t\t{\n\t\t\t\tauto constructs = result.non_dominated_exit;\n\t\t\t\tconstructs.push_back(dominated_merge);\n\t\t\t\tcollect_and_dispatch_control_flow(node, dominated_merge, constructs, false, false);\n\t\t\t\tdid_rewrite = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (did_rewrite)\n\t\trecompute_cfg();\n\treturn did_rewrite;\n}\n\nCFGStructurizer::LoopAnalysis CFGStructurizer::analyze_loop(CFGNode *node) const\n{\n\tLoopAnalysis result;\n\n\t// Now, we need to figure out which blocks belong in the loop construct.\n\t// The way to figure out a natural loop is any block which is dominated by loop header\n\t// and control flow passes to one of the back edges.\n\n\t// Unfortunately, it can be ambiguous which block is the merge block for a loop.\n\t// Ideally, there is a unique block which is the loop exit block, but if there are multiple breaks\n\t// there are multiple blocks which are not part of the loop construct.\n\n\tLoopBacktracer tracer;\n\tauto *pred = node->pred_back_edge;\n\n\t// Back-trace from here.\n\t// The CFG is reducible, so node must dominate pred.\n\t// Since node dominates pred, there is no pred chain we can follow without\n\t// eventually hitting node, and we'll stop traversal there.\n\n\t// All nodes which are touched during this traversal must be part of the loop construct.\n\ttracer.trace_to_parent(node, pred);\n\n\tLoopMergeTracer merge_tracer(tracer);\n\tmerge_tracer.trace_from_parent(node);\n\n\tfor (auto *loop_exit : merge_tracer.loop_exits)\n\t{\n\t\tauto exit_type = get_loop_exit_type(*node, *loop_exit);\n\t\tswitch (exit_type)\n\t\t{\n\t\tcase LoopExitType::Exit:\n\t\t\tresult.direct_exits.push_back(loop_exit);\n\t\t\tbreak;\n\n\t\tcase LoopExitType::InnerLoopExit:\n\t\t\t// It's not an exit for us, but the inner loop.\n\t\t\tresult.inner_direct_exits.push_back(loop_exit);\n\t\t\tbreak;\n\n\t\tcase LoopExitType::Merge:\n\t\t\tresult.dominated_exit.push_back(loop_exit);\n\t\t\tbreak;\n\n\t\tcase LoopExitType::InnerLoopMerge:\n\t\t\tresult.inner_dominated_exit.push_back(loop_exit);\n\t\t\tbreak;\n\n\t\tcase LoopExitType::InnerLoopFalsePositive:\n\t\t\t// In this case, the inner loop can only exit at the loop header,\n\t\t\t// and thus post-dominance analysis will always fail.\n\t\t\t// Ignore this case as it's a false exit.\n\t\t\tbreak;\n\n\t\tcase LoopExitType::Escape:\n\t\t\tresult.non_dominated_exit.push_back(loop_exit);\n\t\t\tbreak;\n\n\t\tcase LoopExitType::MergeToInfiniteLoop:\n\t\t\tresult.dominated_continue_exit.push_back(loop_exit);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// A dominated continue exit should not be considered as such if it can reach other \"normal\" exits.\n\t// In this case, it's just a break.\n\tauto continue_itr = result.dominated_continue_exit.begin();\n\twhile (continue_itr != result.dominated_continue_exit.end())\n\t{\n\t\tauto *candidate = *continue_itr;\n\t\tbool found_candidate = false;\n\t\tfor (auto *dominated : result.dominated_exit)\n\t\t{\n\t\t\tif (query_reachability(*candidate, *dominated))\n\t\t\t{\n\t\t\t\tresult.non_dominated_exit.push_back(candidate);\n\t\t\t\tcontinue_itr = result.dominated_continue_exit.erase(continue_itr);\n\t\t\t\tfound_candidate = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!found_candidate)\n\t\t{\n\t\t\tfor (auto *non_dominated : result.non_dominated_exit)\n\t\t\t{\n\t\t\t\tif (query_reachability(*candidate, *non_dominated))\n\t\t\t\t{\n\t\t\t\t\tresult.non_dominated_exit.push_back(candidate);\n\t\t\t\t\tcontinue_itr = result.dominated_continue_exit.erase(continue_itr);\n\t\t\t\t\tfound_candidate = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!found_candidate)\n\t\t\t++continue_itr;\n\t}\n\n\tif (result.dominated_continue_exit.size() > 1)\n\t{\n\t\t// If we have multiple continue exit candidates, they better merge into a single clean candidate that we\n\t\t// still dominate, otherwise, ignore this case and treat them all as normal Escape nodes.\n\t\tauto *common = find_common_post_dominator(result.dominated_continue_exit);\n\t\tif (common && node->dominates(common))\n\t\t{\n\t\t\tresult.dominated_continue_exit.clear();\n\t\t\tresult.dominated_continue_exit.push_back(common);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tresult.non_dominated_exit.insert(result.non_dominated_exit.end(),\n\t\t\t                                 result.dominated_continue_exit.begin(),\n\t\t\t                                 result.dominated_continue_exit.end());\n\t\t\tresult.dominated_continue_exit.clear();\n\t\t}\n\t}\n\n\t// If the only merge candidates we have are inner dominated, treat them as true dominated exits.\n\tif (result.dominated_exit.empty() && !result.inner_dominated_exit.empty())\n\t\tstd::swap(result.dominated_exit, result.inner_dominated_exit);\n\n\t// If there are no direct exists, treat inner direct exists as direct exits.\n\tif (result.direct_exits.empty())\n\t\tstd::swap(result.direct_exits, result.inner_direct_exits);\n\n\t// A direct exit can be considered a dominated exit if there are no better candidates.\n\tif (result.dominated_exit.empty() && !result.direct_exits.empty())\n\t\tstd::swap(result.dominated_exit, result.direct_exits);\n\n\t// If we only have one direct exit, consider it our merge block.\n\t// Pick either Merge or Escape.\n\tif (result.direct_exits.size() == 1 && result.dominated_exit.empty() && result.non_dominated_exit.empty())\n\t{\n\t\tif (node->dominates(result.direct_exits.front()))\n\t\t\tstd::swap(result.dominated_exit, result.direct_exits);\n\t\telse\n\t\t\tstd::swap(result.non_dominated_exit, result.direct_exits);\n\t}\n\n\tif (result.dominated_exit.size() >= 2)\n\t{\n\t\t// Try to see if we can reduce the number of merge blocks to just 1.\n\t\t// This is relevant if we have various \"clean\" break blocks.\n\t\tauto *post_dominator = find_common_post_dominator(result.dominated_exit);\n\t\tif (std::find(result.dominated_exit.begin(), result.dominated_exit.end(),\n\t\t              post_dominator) != result.dominated_exit.end())\n\t\t{\n\t\t\tresult.dominated_exit.clear();\n\t\t\tresult.dominated_exit.push_back(post_dominator);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nCFGStructurizer::LoopMergeAnalysis CFGStructurizer::analyze_loop_merge(CFGNode *node, const LoopAnalysis &analysis)\n{\n\t// We have multiple blocks which are merge candidates. We need to figure out where execution reconvenes.\n\tVector<CFGNode *> merges;\n\tmerges.reserve(analysis.inner_dominated_exit.size() + analysis.dominated_exit.size() + analysis.non_dominated_exit.size());\n\tmerges.insert(merges.end(), analysis.inner_dominated_exit.begin(), analysis.inner_dominated_exit.end());\n\tmerges.insert(merges.end(), analysis.dominated_exit.begin(), analysis.dominated_exit.end());\n\tmerges.insert(merges.end(), analysis.non_dominated_exit.begin(), analysis.non_dominated_exit.end());\n\tCFGNode *merge = CFGStructurizer::find_common_post_dominator(merges);\n\n\tCFGNode *dominated_merge = nullptr;\n\n\t// Try to find the sensible target first.\n\t// If one of our merge blocks is the successor of the continue block,\n\t// this is a prime candidate for a ladder block.\n\tif (node->pred_back_edge && node->pred_back_edge->succ.size() == 1 &&\n\t    std::find(analysis.dominated_exit.begin(),\n\t              analysis.dominated_exit.end(),\n\t              node->pred_back_edge->succ.front()) != analysis.dominated_exit.end())\n\t{\n\t\tdominated_merge = node->pred_back_edge->succ.front();\n\t}\n\telse if (merge && !node->dominates(merge) && analysis.dominated_exit.size() > 1)\n\t{\n\t\t// Now, we might have Merge blocks which end up escaping out of the loop construct.\n\t\t// We might have to remove candidates which end up being break blocks after all.\n\t\tVector<CFGNode *> non_breaking_exits;\n\t\tnon_breaking_exits.reserve(analysis.dominated_exit.size());\n\t\tfor (auto *exit : analysis.dominated_exit)\n\t\t\tif (!control_flow_is_escaping(exit, merge))\n\t\t\t\tnon_breaking_exits.push_back(exit);\n\n\t\tif (!non_breaking_exits.empty())\n\t\t\tdominated_merge = CFGStructurizer::find_common_post_dominator(non_breaking_exits);\n\n\t\tif (!dominated_merge)\n\t\t{\n\t\t\t// If we get here, we likely have some questionable tie-break situation.\n\t\t\t// One possible case is an infinite loop where one path does a multi-level break,\n\t\t\t// and other paths branch to outer loop's continue. We'll want to only look at dominated exits\n\t\t\t// with the smallest break scope and try to find a common post dominator.\n\t\t\tauto *innermost_header = get_innermost_loop_header_for(node->immediate_dominator);\n\t\t\tVector<CFGNode *> continue_exits;\n\n\t\t\tif (innermost_header && innermost_header->pred_back_edge)\n\t\t\t\tfor (auto *exit : analysis.dominated_exit)\n\t\t\t\t\tif (query_reachability(*exit, *innermost_header->pred_back_edge))\n\t\t\t\t\t\tcontinue_exits.push_back(exit);\n\n\t\t\tif (!continue_exits.empty())\n\t\t\t\tdominated_merge = CFGStructurizer::find_common_post_dominator(continue_exits);\n\t\t}\n\t}\n\telse\n\t{\n\t\tdominated_merge = CFGStructurizer::find_common_post_dominator(analysis.dominated_exit);\n\t}\n\n\tif (!dominated_merge)\n\t{\n\t\tLOGW(\"There is no candidate for ladder merging.\\n\");\n\t}\n\n\tif (dominated_merge && !node->dominates(dominated_merge))\n\t{\n\t\tLOGW(\"We don't dominate the merge target ...\\n\");\n\t\tdominated_merge = nullptr;\n\t}\n\n\tLoopMergeAnalysis merge_result = {};\n\tmerge_result.merge = merge;\n\tmerge_result.weak_merge = merge;\n\tmerge_result.dominated_merge = dominated_merge;\n\n\tif (!merge)\n\t{\n\t\t// Try to find a candidate merge point which ignores any early exits through common post domination frontier\n\t\t// analysis.\n\t\tVector<CFGNode *> frontiers;\n\t\tfor (auto *m : merges)\n\t\t\tfrontiers.insert(frontiers.end(), m->dominance_frontier.begin(), m->dominance_frontier.end());\n\n\t\t// Find the innermost frontier that satisfies the requirements.\n\t\tstd::stable_sort(frontiers.begin(), frontiers.end(), [](const CFGNode *a, const CFGNode *b)\n\t\t{\n\t\t\treturn a->forward_post_visit_order > b->forward_post_visit_order;\n\t\t});\n\t\tfrontiers.erase(std::unique(frontiers.begin(), frontiers.end()), frontiers.end());\n\n\t\tfor (auto *front : frontiers)\n\t\t{\n\t\t\t// All merge nodes must reach the candidate for it to be considered a proper merge.\n\t\t\tauto itr = std::find_if(merges.begin(), merges.end(), [&](const CFGNode *c)\n\t\t\t{\n\t\t\t\treturn !query_reachability(*c, *front);\n\t\t\t});\n\n\t\t\tif (itr == merges.end())\n\t\t\t{\n\t\t\t\tmerge_result.weak_merge = front;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!analysis.dominated_continue_exit.empty())\n\t{\n\t\tassert(analysis.dominated_continue_exit.size() == 1);\n\t\tmerge_result.infinite_continue_ladder = analysis.dominated_continue_exit.front();\n\t}\n\n\treturn merge_result;\n}\n\nvoid CFGStructurizer::collect_and_dispatch_control_flow_from_anchor(\n\tCFGNode *anchor, const Vector<CFGNode *> &constructs)\n{\n\tauto &builder = module.get_builder();\n\n\t// If we have an anchor, it should collect all control flow, maybe dispatch itself, then dispatch to the constructs.\n\t// It must be a conditional branch, since it's too much of a mess to deal with switch.\n\tassert(anchor->ir.terminator.type == Terminator::Type::Condition);\n\tassert(constructs.size() == 2);\n\tassert(constructs[0]->post_dominates(anchor->ir.terminator.true_block) ||\n\t       constructs[0]->post_dominates(anchor->ir.terminator.false_block));\n\tassert(constructs[1]->post_dominates(anchor->ir.terminator.true_block) ||\n\t       constructs[1]->post_dominates(anchor->ir.terminator.false_block));\n\n\tauto *anchor_pred = create_helper_pred_block(anchor);\n\n\tauto *anchor_to_construct0 = pool.create_node();\n\tauto *anchor_to_construct1 = pool.create_node();\n\tauto *anchor_terminator = pool.create_node();\n\tauto *anchor_dispatcher = pool.create_node();\n\n\tanchor_to_construct0->name = anchor->name + \".anchor0\";\n\tanchor_to_construct1->name = anchor->name + \".anchor1\";\n\n\tanchor_to_construct0->immediate_dominator = anchor;\n\tanchor_to_construct1->immediate_dominator = anchor;\n\tanchor_to_construct0->immediate_post_dominator = constructs[0];\n\tanchor_to_construct1->immediate_post_dominator = constructs[1];\n\tanchor_to_construct0->forward_post_visit_order = constructs[0]->forward_post_visit_order;\n\tanchor_to_construct1->forward_post_visit_order = constructs[1]->forward_post_visit_order;\n\tanchor_to_construct0->backward_post_visit_order = constructs[0]->backward_post_visit_order;\n\tanchor_to_construct1->backward_post_visit_order = constructs[1]->backward_post_visit_order;\n\n\tanchor_to_construct0->add_branch(anchor_terminator);\n\tanchor_to_construct1->add_branch(anchor_terminator);\n\tanchor_to_construct0->ir.terminator.type = Terminator::Type::Branch;\n\tanchor_to_construct0->ir.terminator.direct_block = anchor_terminator;\n\tanchor_to_construct1->ir.terminator.type = Terminator::Type::Branch;\n\tanchor_to_construct1->ir.terminator.direct_block = anchor_terminator;\n\tanchor_terminator->name = anchor->name + \".anchor-term\";\n\tanchor_terminator->add_branch(anchor_dispatcher);\n\tanchor_terminator->ir.terminator.type = Terminator::Type::Branch;\n\tanchor_terminator->ir.terminator.direct_block = anchor_dispatcher;\n\tanchor_dispatcher->name = anchor->name + \".anchor-dispatch\";\n\n\tPHI terminator_selector;\n\tterminator_selector.id = module.allocate_id();\n\tterminator_selector.type_id = builder.makeBoolType();\n\tterminator_selector.incoming.push_back({ anchor_to_construct0, builder.makeBoolConstant(true) });\n\tterminator_selector.incoming.push_back({ anchor_to_construct1, builder.makeBoolConstant(false) });\n\n\ttraverse_dominated_blocks_and_rewrite_branch(anchor, constructs[0], anchor_to_construct0);\n\ttraverse_dominated_blocks_and_rewrite_branch(anchor, constructs[1], anchor_to_construct1);\n\n\tsize_t cutoff_normal_path = anchor_pred->pred.size();\n\ttraverse_dominated_blocks_and_rewrite_branch(constructs[0]->immediate_dominator, constructs[0], anchor_pred);\n\tsize_t cutoff_path0 = anchor_pred->pred.size();\n\ttraverse_dominated_blocks_and_rewrite_branch(constructs[1]->immediate_dominator, constructs[1], anchor_pred);\n\n\tassert(constructs[0]->pred.empty());\n\tassert(constructs[1]->pred.empty());\n\n\t// Branch to anchor as normal if we have a pre-existing pred.\n\tPHI take_anchor_phi;\n\ttake_anchor_phi.id = module.allocate_id();\n\ttake_anchor_phi.type_id = builder.makeBoolType();\n\tfor (size_t i = 0; i < cutoff_normal_path; i++)\n\t\ttake_anchor_phi.incoming.push_back({ anchor_pred->pred[i], builder.makeBoolConstant(true) });\n\tfor (size_t i = cutoff_normal_path; i < anchor_pred->pred.size(); i++)\n\t\ttake_anchor_phi.incoming.push_back({ anchor_pred->pred[i], builder.makeBoolConstant(false) });\n\n\tanchor_pred->add_branch(anchor);\n\tanchor_pred->add_branch(anchor_dispatcher);\n\tanchor_pred->ir.terminator.type = Terminator::Type::Condition;\n\tanchor_pred->ir.terminator.true_block = anchor;\n\tanchor_pred->ir.terminator.false_block = anchor_dispatcher;\n\tanchor_pred->ir.terminator.direct_block = nullptr;\n\tanchor_pred->ir.terminator.conditional_id = take_anchor_phi.id;\n\n\tPHI outside_true_phi;\n\toutside_true_phi.id = module.allocate_id();\n\toutside_true_phi.type_id = builder.makeBoolType();\n\tfor (size_t i = 0; i < cutoff_path0; i++)\n\t\toutside_true_phi.incoming.push_back({ anchor_pred->pred[i], builder.makeBoolConstant(true) });\n\tfor (size_t i = cutoff_path0; i < anchor_pred->pred.size(); i++)\n\t\toutside_true_phi.incoming.push_back({ anchor_pred->pred[i], builder.makeBoolConstant(false) });\n\n\tPHI anchor_cond_phi;\n\tanchor_cond_phi.id = module.allocate_id();\n\tanchor_cond_phi.type_id = builder.makeBoolType();\n\t// If we took the path through anchor, use that conditional. Otherwise, use the selector between path 0 or 1.\n\tanchor_cond_phi.incoming.push_back({ anchor, terminator_selector.id });\n\tanchor_cond_phi.incoming.push_back({ anchor_pred, outside_true_phi.id });\n\n\tanchor_pred->ir.phi.push_back(std::move(take_anchor_phi));\n\tanchor_pred->ir.phi.push_back(std::move(outside_true_phi));\n\tanchor_terminator->ir.phi.push_back(std::move(terminator_selector));\n\tanchor_dispatcher->ir.terminator.conditional_id = anchor_cond_phi.id;\n\tanchor_dispatcher->ir.terminator.type = Terminator::Type::Condition;\n\tanchor_dispatcher->ir.terminator.true_block = constructs[0];\n\tanchor_dispatcher->ir.terminator.false_block = constructs[1];\n\tanchor_dispatcher->add_branch(constructs[0]);\n\tanchor_dispatcher->add_branch(constructs[1]);\n\tanchor_dispatcher->ir.phi.push_back(std::move(anchor_cond_phi));\n}\n\nvoid CFGStructurizer::collect_and_dispatch_control_flow(\n\tCFGNode *common_idom, CFGNode *common_pdom, const Vector<CFGNode *> &constructs,\n\tbool collect_all_code_paths_to_pdom, bool allow_crossing_branches)\n{\n\tassert(constructs.size() >= 2);\n\tauto &builder = module.get_builder();\n\tbool need_default_case = false;\n\tbool plain_branch = false;\n\tsize_t cutoff_index = 0;\n\tCFGNode *dispatcher;\n\n\t// If there is no strict dominance relationship, it's too risky to freeze a loop here,\n\t// since we may have stray breaks that will invert merge ordering, and cause issues.\n\t// Freezing control flow is important for interleaved merge patterns where we don't want to explode\n\t// the control flow ladders all over the place.\n\tbool freeze_control_flow = !common_idom->pred_back_edge && common_pdom->post_dominates(common_idom);\n\n\tif (freeze_control_flow)\n\t{\n\t\t// Also check that there are no edges that leave the scope between common_idom\n\t\t// and common_pdom and don't freeze if so.\n\n\t\t// node->forward_post_visit_order should map 1:1 to the post-visit array,\n\t\t// but in extreme circumstances where there have been inline cfg rewrites before recompute,\n\t\t// this may not be true, so be defensive.\n\t\tauto itr = std::find(forward_post_visit_order.begin(), forward_post_visit_order.end(), common_pdom);\n\t\tauto end = std::find(forward_post_visit_order.begin(), forward_post_visit_order.end(), common_idom);\n\n\t\tassert(itr != forward_post_visit_order.end());\n\t\tassert(end != forward_post_visit_order.end());\n\n\t\tconst auto can_reach_any_construct = [&](const CFGNode *succ)\n\t\t{\n\t\t\tfor (auto *construct : constructs)\n\t\t\t\tif (query_reachability(*succ, *construct))\n\t\t\t\t\treturn true;\n\n\t\t\treturn false;\n\t\t};\n\n\t\tconst auto any_succ_escapes_constructs = [&](const CFGNode *n)\n\t\t{\n\t\t\t// idom is not included in the loop below, but it can branch beyond all constructs.\n\t\t\tfor (auto *succ : n->succ)\n\t\t\t\tif (!can_reach_any_construct(succ))\n\t\t\t\t\treturn true;\n\n\t\t\treturn false;\n\t\t};\n\n\t\tconst auto is_construct = [&](const CFGNode *n)\n\t\t{\n\t\t\treturn std::find(constructs.begin(), constructs.end(), n) != constructs.end();\n\t\t};\n\n\t\tif (!collect_all_code_paths_to_pdom)\n\t\t{\n\t\t\t// idom is not included in the loop below, but it can branch beyond all constructs.\n\t\t\tfreeze_control_flow = !any_succ_escapes_constructs(common_idom);\n\t\t}\n\n\t\tfor (; itr != end && freeze_control_flow; ++itr)\n\t\t{\n\t\t\tCFGNode *node = *itr;\n\n\t\t\tif (!common_idom->dominates(node))\n\t\t\t\tcontinue;\n\n\t\t\tif (node->succ_back_edge != nullptr && node->succ_back_edge != common_idom &&\n\t\t\t    query_reachability(*node->succ_back_edge, *common_idom))\n\t\t\t{\n\t\t\t\t// Branches backwards.\n\t\t\t\tfreeze_control_flow = false;\n\t\t\t}\n\t\t\telse if (!collect_all_code_paths_to_pdom && !is_construct(node) && common_idom->dominates(node) &&\n\t\t\t         can_reach_any_construct(node) && any_succ_escapes_constructs(node))\n\t\t\t{\n\t\t\t\t// If we're using the simple collector, we merge at the constructs instead.\n\t\t\t\t// Make absolutely sure this is safe to merge to be checking that the dispatch point would be\n\t\t\t\t// a suitable merge.\n\t\t\t\tfreeze_control_flow = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tPHI phi;\n\tphi.id = module.allocate_id();\n\n\tif (collect_all_code_paths_to_pdom)\n\t{\n\t\t// In some merge scenarios, we need to make sure we encapsulate all code into this new dispatcher.\n\t\t// This will become our new merge block. Incoming impossible merges will be transposed to after this new merge.\n\t\tdispatcher = create_helper_pred_block(common_pdom);\n\t\tfor (auto *candidate : constructs)\n\t\t\ttraverse_dominated_blocks_and_rewrite_branch(candidate, dispatcher, common_pdom);\n\n\t\tcutoff_index = dispatcher->pred.size();\n\n\t\t// If there is no direct branch intended for node, the default case label will never be reached,\n\t\t// so just pilfer one of the cases as default.\n\t\tneed_default_case = !dispatcher->pred.empty();\n\n\t\tplain_branch = !need_default_case && constructs.size() == 2;\n\t\tif (!plain_branch)\n\t\t{\n\t\t\tfor (size_t i = 0; i < cutoff_index; i++)\n\t\t\t\tphi.incoming.push_back({ dispatcher->pred[i], builder.makeIntConstant(-1) });\n\t\t\tphi.type_id = builder.makeIntType(32);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tphi.type_id = builder.makeBoolType();\n\t\t}\n\t}\n\telse\n\t{\n\t\tdispatcher = pool.create_node();\n\t\tdispatcher->name = common_idom->name + \".collector\";\n\t\tdispatcher->immediate_dominator = common_idom;\n\t\tdispatcher->immediate_post_dominator = common_pdom;\n\t\tdispatcher->forward_post_visit_order = common_pdom->forward_post_visit_order;\n\t\tdispatcher->backward_post_visit_order = common_pdom->backward_post_visit_order;\n\t\tplain_branch = constructs.size() == 2;\n\t}\n\n\tphi.type_id = plain_branch ? builder.makeBoolType() : builder.makeIntType(32);\n\n\tfor (size_t i = 0, n = constructs.size(); i < n; i++)\n\t{\n\t\tauto *candidate = constructs[i];\n\n\t\tif (allow_crossing_branches)\n\t\t{\n\t\t\ttraverse_dominated_blocks_and_rewrite_branch(common_idom, candidate, dispatcher,\n\t\t\t\t[](const CFGNode *) { return true; },\n\t\t\t\tconstructs);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttraverse_dominated_blocks_and_rewrite_branch(common_idom, candidate, dispatcher);\n\t\t}\n\n\t\tsize_t next_cutoff_index = dispatcher->pred.size();\n\t\tfor (size_t j = cutoff_index; j < next_cutoff_index; j++)\n\t\t{\n\t\t\tspv::Id cond_id;\n\t\t\tif (plain_branch)\n\t\t\t\tcond_id = builder.makeBoolConstant(i != 0);\n\t\t\telse\n\t\t\t\tcond_id = builder.makeIntConstant(int32_t(i));\n\n\t\t\tphi.incoming.push_back({ dispatcher->pred[j], cond_id });\n\t\t}\n\t\tcutoff_index = next_cutoff_index;\n\t}\n\n\tif (freeze_control_flow)\n\t{\n\t\tcommon_idom->freeze_structured_analysis = true;\n\t\tcommon_idom->merge = MergeType::Loop;\n\t\tcommon_idom->loop_merge_block = dispatcher;\n\t}\n\n\tdispatcher->ir.terminator.conditional_id = phi.id;\n\tdispatcher->ir.phi.push_back(std::move(phi));\n\tbuilder.addName(phi.id, String(\"selector_\" + common_pdom->name).c_str());\n\n\tdispatcher->ir.terminator.direct_block = nullptr;\n\tdispatcher->clear_branches();\n\n\tif (plain_branch)\n\t{\n\t\tdispatcher->ir.terminator.type = Terminator::Type::Condition;\n\t\tdispatcher->ir.terminator.false_block = constructs[0];\n\t\tdispatcher->ir.terminator.true_block = constructs[1];\n\t\tdispatcher->add_branch(constructs[0]);\n\t\tdispatcher->add_branch(constructs[1]);\n\t}\n\telse\n\t{\n\t\tdispatcher->ir.terminator.type = Terminator::Type::Switch;\n\t\tTerminator::Case default_case;\n\t\tdefault_case.node = need_default_case ? common_pdom : constructs[0];\n\t\tdefault_case.is_default = true;\n\t\tdispatcher->ir.terminator.cases.push_back(default_case);\n\t\tdispatcher->add_branch(default_case.node);\n\n\t\tfor (size_t i = 0, n = constructs.size(); i < n; i++)\n\t\t{\n\t\t\tauto *candidate = constructs[i];\n\t\t\tassert(allow_crossing_branches || candidate->pred.empty() || candidate == default_case.node);\n\t\t\tdispatcher->add_branch(candidate);\n\n\t\t\tif (need_default_case || i)\n\t\t\t{\n\t\t\t\tTerminator::Case break_case;\n\t\t\t\tbreak_case.node = candidate;\n\t\t\t\tbreak_case.value = uint32_t(i);\n\t\t\t\tdispatcher->ir.terminator.cases.push_back(break_case);\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool CFGStructurizer::rewrite_complex_loop_exits(CFGNode *node, CFGNode *merge, Vector<CFGNode *> &dominated_exits)\n{\n\tif (!merge || !node->pred_back_edge->succ.empty() || dominated_exits.size() < 2)\n\t\treturn false;\n\n\t// This heuristic is somewhat questionable. :')\n\tbool needs_early_explicit_ladder = false;\n\tCFGNode *common_idom = node;\n\n\t// Use a stricter definition when there is a clean merge candidate.\n\tif (node->can_loop_merge_to(merge))\n\t{\n\t\t// If all nodes share a frontier node which is not the target merge block, we have a spicy merge\n\t\t// that should be collected in a ladder first, since there is no natural latter block\n\t\t// in this scenario. The shared frontier node is the more plausible true merge target,\n\t\t// and the outer merge was a red herring, but since we don't have a proper ladder block,\n\t\t// it will complicate things.\n\t\tVector<const CFGNode *> frontier_nodes;\n\t\tfor (auto *n : dominated_exits)\n\t\t{\n\t\t\tfrontier_nodes.insert(frontier_nodes.end(),\n\t\t\t                      n->dominance_frontier.begin(),\n\t\t\t                      n->dominance_frontier.end());\n\t\t}\n\n\t\tstd::sort(frontier_nodes.begin(), frontier_nodes.end());\n\t\tconst CFGNode *frontier_base = nullptr;\n\t\tuint32_t count = 0;\n\n\t\tfor (auto *n : frontier_nodes)\n\t\t{\n\t\t\tif (n == frontier_base)\n\t\t\t\tcount++;\n\t\t\telse\n\t\t\t\tcount = 1;\n\n\t\t\tfrontier_base = n;\n\n\t\t\tif (count == dominated_exits.size() && n != merge && query_reachability(*n, *merge))\n\t\t\t{\n\t\t\t\tneeds_early_explicit_ladder = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\t// If we cannot do a clean merge anyway, then we should try to look for frontier nodes.\n\t\tauto frontier_nodes = dominated_exits;\n\n\t\t// Skip forward to the dominance frontier. This makes control flow easier to deal with\n\t\t// since unrelated branches to the frontiers can also be resolved.\n\t\t// This heuristic is admittedly somewhat arbitrary,\n\t\t// but it is meant to help on some specific real-world shaders.\n\t\tfor (auto *&n : frontier_nodes)\n\t\t{\n\t\t\tif (n->dominance_frontier.size() == 1 && !node->dominates(n->dominance_frontier.front()))\n\t\t\t{\n\t\t\t\tn = n->dominance_frontier.front();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We don't have a clean frontier, skip this check.\n\t\t\t\tfrontier_nodes.clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!frontier_nodes.empty())\n\t\t{\n\t\t\t// If the frontiers are all different, and it's not the merge block, something is afoot.\n\t\t\t// Don't sort by pointer since we care about codegen invariance.\n\t\t\tstd::sort(frontier_nodes.begin(), frontier_nodes.end(), [](const CFGNode *a, const CFGNode *b)\n\t\t\t          { return a->forward_post_visit_order > b->forward_post_visit_order; });\n\n\t\t\tbool has_dup_frontier = false;\n\t\t\tfor (size_t i = 1, n = frontier_nodes.size(); i < n && !has_dup_frontier; i++)\n\t\t\t\tif (frontier_nodes[i] == frontier_nodes[i - 1] || frontier_nodes[i] == merge)\n\t\t\t\t\thas_dup_frontier = true;\n\n\t\t\tif (has_dup_frontier)\n\t\t\t\tfrontier_nodes.clear();\n\t\t}\n\n\t\tif (!frontier_nodes.empty())\n\t\t{\n\t\t\t// Make sure that the frontier nodes we found fully dominate all preds of merge,\n\t\t\t// otherwise, the transpose of code will likely break.\n\t\t\tfor (auto *pred : merge->pred)\n\t\t\t{\n\t\t\t\tbool has_dominating = false;\n\t\t\t\tfor (auto *f : frontier_nodes)\n\t\t\t\t{\n\t\t\t\t\tif (f->dominates(pred))\n\t\t\t\t\t{\n\t\t\t\t\t\thas_dominating = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!has_dominating)\n\t\t\t\t{\n\t\t\t\t\tfrontier_nodes.clear();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!frontier_nodes.empty())\n\t\t{\n\t\t\tneeds_early_explicit_ladder = true;\n\t\t\t// First collect the inner break blocks in a neat bow.\n\t\t\tnode->pred_back_edge->fake_succ.clear();\n\t\t\tnode->pred_back_edge->fake_pred.clear();\n\t\t\tcollect_and_dispatch_control_flow(node, merge, dominated_exits, false, false);\n\n\t\t\trecompute_cfg();\n\n\t\t\t// Then collect the outer layer.\n\t\t\tdominated_exits = std::move(frontier_nodes);\n\t\t\tcommon_idom = merge->immediate_dominator;\n\t\t}\n\t}\n\n\tif (needs_early_explicit_ladder)\n\t{\n\t\t// Avoids false-positive assertions when trying to rewrite branches.\n\t\t// We're going to recompute the CFG after this anyway.\n\t\tnode->pred_back_edge->fake_succ.clear();\n\t\tnode->pred_back_edge->fake_pred.clear();\n\t\tcollect_and_dispatch_control_flow(common_idom, merge, dominated_exits, false, false);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool CFGStructurizer::find_loops(unsigned pass)\n{\n\tfor (auto index = forward_post_visit_order.size(); index; index--)\n\t{\n\t\t// Visit in reverse order so we resolve outer loops first,\n\t\t// this lets us detect ladder-breaking loops.\n\t\tauto *node = forward_post_visit_order[index - 1];\n\n\t\tif (node->freeze_structured_analysis)\n\t\t{\n\t\t\t// If we have a pre-created dummy loop for ladding breaking,\n\t\t\t// just propagate the header information and be done with it.\n\t\t\tif (node->merge == MergeType::Loop)\n\t\t\t{\n\t\t\t\tnode->loop_merge_block->headers.push_back(node);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (!node->has_pred_back_edges())\n\t\t\tcontinue;\n\n\t\t// There are back-edges here, this must be a loop header.\n\t\tnode->merge = MergeType::Loop;\n\n\t\tauto result = analyze_loop(node);\n\t\tauto &dominated_exit = result.dominated_exit;\n\t\tauto &inner_dominated_exit = result.inner_dominated_exit;\n\t\tauto &non_dominated_exit = result.non_dominated_exit;\n\n\t\t// This should not come up here, and must be handled in transpose loops.\n\t\tassert(result.dominated_continue_exit.empty());\n\n\t\t// Detect infinite loop with an exit which is only in inner loop construct.\n\t\t// It is impossible to construct a merge block in this case since the merge targets,\n\t\t// so just merge to unreachable.\n\t\tbool force_infinite_loop = false;\n\n\t\t// If we have a trivial case where there is only one possible loop exit which we dominate,\n\t\t// we shouldn't consider it an infinite loop, but a merge.\n\t\tbool trivial_exit_loop = dominated_exit.size() == 1 && result.non_dominated_exit.empty() &&\n\t\t                         result.inner_dominated_exit.empty() && result.direct_exits.empty() &&\n\t\t                         result.inner_direct_exits.empty();\n\n\t\tif (trivial_exit_loop)\n\t\t{\n\t\t\tauto *candidate = dominated_exit.front();\n\n\t\t\t// Resolve some false positives. It's possible that a loop exit can be detected as inner,\n\t\t\t// but it's just a good merge candidate for an inner infinite loop.\n\t\t\tbool loop_exit_dominates_continue =\n\t\t\t\tcandidate->immediate_dominator &&\n\t\t\t    candidate->immediate_dominator->dominates(node->pred_back_edge);\n\n\t\t\t// If we promoted inner header, this is not a trivial exit.\n\t\t\tconst CFGNode *innermost_loop_header = get_innermost_loop_header_for(node, dominated_exit.front());\n\t\t\tif (node != innermost_loop_header)\n\t\t\t{\n\t\t\t\t// There are at least two scenarios where we have to be careful:\n\t\t\t\t// - If the innermost header has a edge out of continue block.\n\t\t\t\t//   If we still detect this as belong to inner loop, it must be the case.\n\t\t\t\t// - Also, only accept this as a trivial exit if the immediate dominator of exit also dominates\n\t\t\t\t//   continue block.\n\t\t\t\tif (!innermost_loop_header->pred_back_edge->succ.empty() || !loop_exit_dominates_continue)\n\t\t\t\t\ttrivial_exit_loop = false;\n\t\t\t}\n\t\t}\n\n\t\tif (node->pred_back_edge->succ.empty() && !trivial_exit_loop)\n\t\t{\n\t\t\tforce_infinite_loop = true;\n\t\t\tfor (auto *e : result.dominated_exit)\n\t\t\t\tforce_infinite_loop = force_infinite_loop && loop_exit_supports_infinite_loop(node, e);\n\t\t\tfor (auto *e : result.non_dominated_exit)\n\t\t\t\tforce_infinite_loop = force_infinite_loop && loop_exit_supports_infinite_loop(node, e);\n\t\t\tfor (auto *e : result.inner_dominated_exit)\n\t\t\t\tforce_infinite_loop = force_infinite_loop && loop_exit_supports_infinite_loop(node, e);\n\t\t\tfor (auto *e : result.direct_exits)\n\t\t\t\tforce_infinite_loop = force_infinite_loop && loop_exit_supports_infinite_loop(node, e);\n\t\t\tfor (auto *e : result.inner_direct_exits)\n\t\t\t\tforce_infinite_loop = force_infinite_loop && loop_exit_supports_infinite_loop(node, e);\n\t\t}\n\n\t\tif (force_infinite_loop ||\n\t\t    (dominated_exit.empty() && inner_dominated_exit.empty() && non_dominated_exit.empty()))\n\t\t{\n\t\t\t// There can be zero loop exits, i.e. infinite loop. This means we have no merge block.\n\t\t\t// We will invent a merge block to satisfy SPIR-V validator, and declare it as unreachable.\n\t\t\tnode->loop_merge_block = nullptr;\n\t\t\t//LOGI(\"Loop without merge: %p (%s)\\n\", static_cast<const void *>(node), node->name.c_str());\n\t\t}\n\t\telse if (dominated_exit.size() == 1 && non_dominated_exit.empty() && inner_dominated_exit.empty())\n\t\t{\n\t\t\tCFGNode *direct_exit_pdom = nullptr;\n\t\t\tif (!result.direct_exits.empty())\n\t\t\t\tdirect_exit_pdom = find_common_post_dominator(result.direct_exits);\n\n\t\t\tif (direct_exit_pdom && query_reachability(*dominated_exit.front(), *direct_exit_pdom))\n\t\t\t{\n\t\t\t\tnode->loop_ladder_block = dominated_exit.front();\n\t\t\t\tnode->loop_merge_block = direct_exit_pdom;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Clean merge.\n\t\t\t\t// This is a unique merge block. There can be no other merge candidate.\n\t\t\t\tnode->loop_merge_block = dominated_exit.front();\n\t\t\t}\n\n\t\t\tconst_cast<CFGNode *>(node->loop_merge_block)->add_unique_header(node);\n\t\t\t//LOGI(\"Loop with simple merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(node), node->name.c_str(),\n\t\t\t//     static_cast<const void *>(node->loop_merge_block), node->loop_merge_block->name.c_str());\n\t\t}\n\t\telse if (dominated_exit.empty() && inner_dominated_exit.empty() && non_dominated_exit.size() == 1)\n\t\t{\n\t\t\t// Single-escape merge.\n\t\t\t// It is unique, but we need workarounds later.\n\t\t\tauto *merge_block = non_dominated_exit.front();\n\n\t\t\t// We can make the non-dominated exit dominated by\n\t\t\t// adding a ladder block in-between. This allows us to merge the loop cleanly\n\t\t\t// before breaking out.\n\t\t\tauto *ladder = create_ladder_block(node, merge_block, \".merge\");\n\t\t\tnode->loop_ladder_block = nullptr;\n\t\t\tnode->loop_merge_block = ladder;\n\n\t\t\tconst_cast<CFGNode *>(node->loop_merge_block)->add_unique_header(node);\n\t\t\t//LOGI(\"Loop with ladder merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(node), node->name.c_str(),\n\t\t\t//     static_cast<const void *>(node->loop_merge_block), node->loop_merge_block->name.c_str());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto merge_result = analyze_loop_merge(node, result);\n\t\t\tauto *merge = merge_result.merge;\n\t\t\tauto *dominated_merge = merge_result.dominated_merge;\n\n\t\t\tif (pass == 0 && rewrite_complex_loop_exits(node, merge, dominated_exit))\n\t\t\t\treturn true;\n\n\t\t\tif (!merge)\n\t\t\t{\n\t\t\t\t// Most likely this means we have an early return somewhere. Try the weak merge candidate.\n\t\t\t\tmerge = merge_result.weak_merge;\n\t\t\t}\n\n\t\t\tif (!merge)\n\t\t\t{\n\t\t\t\tLOGW(\"Failed to find a common merge point ...\\n\");\n\t\t\t}\n\t\t\telse if (node->can_loop_merge_to(merge))\n\t\t\t{\n\t\t\t\t// Clean merge.\n\t\t\t\t// This is a unique merge block. There can be no other merge candidate.\n\t\t\t\t//LOGI(\"Loop with simple multi-exit merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(node),\n\t\t\t\t//     node->name.c_str(), static_cast<const void *>(node->loop_merge_block),\n\t\t\t\t//     node->loop_merge_block->name.c_str());\n\n\t\t\t\tnode->loop_merge_block = merge;\n\t\t\t\tconst_cast<CFGNode *>(node->loop_merge_block)->add_unique_header(node);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!dominated_merge && node->pred_back_edge->succ.size() == 1)\n\t\t\t\t{\n\t\t\t\t\t// If continue block exits, and it still does not dominate, we should invent a ladder block\n\t\t\t\t\t// so we get one, otherwise splitting merge scopes will break.\n\t\t\t\t\tdominated_merge = create_ladder_block(node->pred_back_edge, node->pred_back_edge->succ.front(), \".merge\");\n\t\t\t\t}\n\n\t\t\t\t// Single-escape merge.\n\t\t\t\t// It is unique, but we need workarounds later.\n\t\t\t\t//LOGI(\"Loop with ladder multi-exit merge: %p (%s) -> %p (%s)\\n\", static_cast<const void *>(node),\n\t\t\t\t//     node->name.c_str(), static_cast<const void *>(node->loop_merge_block),\n\t\t\t\t//     node->loop_merge_block->name.c_str());\n\n\t\t\t\t//if (dominated_merge)\n\t\t\t\t//{\n\t\t\t\t\t//LOGI(\"    Ladder block: %p (%s)\\n\", static_cast<const void *>(dominated_merge),\n\t\t\t\t\t//     dominated_merge->name.c_str());\n\t\t\t\t//}\n\n\t\t\t\t// We will use this block as a ladder.\n\t\t\t\tnode->loop_ladder_block = dominated_merge;\n\t\t\t\tnode->loop_merge_block = merge;\n\n\t\t\t\tconst_cast<CFGNode *>(node->loop_merge_block)->add_unique_header(node);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nCFGNode *CFGStructurizer::get_target_break_block_for_inner_header(const CFGNode *node, size_t header_index)\n{\n\tCFGNode *inner_header = node->headers[header_index];\n\tCFGNode *target_header = nullptr;\n\n\tfor (size_t j = header_index; j && !target_header; j--)\n\t{\n\t\tauto *candidate_header = node->headers[j - 1];\n\n\t\tif (candidate_header->merge == MergeType::Loop)\n\t\t{\n\t\t\t// We might have two loops, each at equal scopes.\n\t\t\t// In order to break out to an outer loop, we must verify that the loops actually nest.\n\t\t\t// We must not introduce any backwards branches here.\n\t\t\tCFGNode *candidate_merge = nullptr;\n\t\t\tif (candidate_header->loop_ladder_block)\n\t\t\t\tcandidate_merge = candidate_header->loop_ladder_block;\n\t\t\telse if (candidate_header->loop_merge_block)\n\t\t\t\tcandidate_merge = candidate_header->loop_merge_block;\n\n\t\t\tif (!candidate_merge)\n\t\t\t\tcontinue;\n\n\t\t\t// Check for backwards branch.\n\t\t\tif (query_reachability(*candidate_merge, *inner_header))\n\t\t\t\tcontinue;\n\n\t\t\t// An outer header is expected to dominate the inner header. Otherwise, they live in\n\t\t\t// separate scopes, and we should look for a header that is further out.\n\t\t\tif (!candidate_header->dominates(inner_header))\n\t\t\t\tcontinue;\n\n\t\t\ttarget_header = candidate_header;\n\t\t}\n\t}\n\n\treturn target_header;\n}\n\nCFGNode *CFGStructurizer::create_ladder_block(CFGNode *header, CFGNode *node, const char *tag)\n{\n\tauto *ladder = pool.create_node();\n\tladder->name = node->name + tag;\n\tladder->add_branch(node);\n\tladder->ir.terminator.type = Terminator::Type::Branch;\n\tladder->ir.terminator.direct_block = node;\n\tladder->immediate_post_dominator = node;\n\tladder->forward_post_visit_order = node->forward_post_visit_order;\n\tladder->backward_post_visit_order = node->backward_post_visit_order;\n\tladder->dominance_frontier.push_back(node);\n\n\ttraverse_dominated_blocks_and_rewrite_branch(header, node, ladder);\n\tladder->recompute_immediate_dominator();\n\n\treturn ladder;\n}\n\nCFGNode *CFGStructurizer::get_or_create_ladder_block(CFGNode *node, size_t header_index)\n{\n\tauto *header = node->headers[header_index];\n\tauto *loop_ladder = header->loop_ladder_block;\n\n\tif (!loop_ladder)\n\t{\n\t\t// We don't have a ladder, because the loop merged to an outer scope, so we need to fake a ladder.\n\t\t// If we hit this case, we did not hit the simpler case in find_loops().\n\t\tauto *ladder = create_ladder_block(header, node, \".merge\");\n\t\theader->loop_ladder_block = ladder;\n\n\t\t// If this is the second outermost scope, we don't need to deal with ladders.\n\t\t// ladder is a dummy branch straight out to the outer merge point.\n\t\tif (header_index > 1)\n\t\t\tloop_ladder = header->loop_ladder_block;\n\t}\n\n\treturn loop_ladder;\n}\n\nCFGNode *CFGStructurizer::build_enclosing_break_target_for_loop_ladder(CFGNode *&node, CFGNode *loop_ladder)\n{\n\t// A loop ladder needs to break out somewhere. If we don't have a candidate\n\t// place to break out to, we will need to create one for the outer scope.\n\t// This is the purpose of the full_break_target fallback.\n\n\tbool ladder_to_merge_is_trivial = loop_ladder->succ.size() == 1 && loop_ladder->succ.front() == node;\n\n\tif (ladder_to_merge_is_trivial)\n\t{\n\t\tauto *succ = loop_ladder->succ.front();\n\n\t\t// Chase through dummy ladders until we find something tangible that is actually PHI sensitive.\n\t\twhile (succ->ir.phi.empty() && succ->succ.size() == 1)\n\t\t\tsucc = succ->succ.front();\n\n\t\tIncomingValue *incoming_from_ladder = nullptr;\n\t\tif (!succ->ir.phi.empty())\n\t\t{\n\t\t\t// All PHIs are fundamentally the same w.r.t. input blocks.\n\t\t\tauto &phi = succ->ir.phi.front();\n\t\t\tincoming_from_ladder = phi_incoming_blocks_find_block(phi.incoming, loop_ladder);\n\t\t}\n\n\t\tCFGNode *retarget_idom = nullptr;\n\t\tif (incoming_from_ladder != nullptr)\n\t\t{\n\t\t\t// If succ takes this ladder as a PHI input, we have to be careful.\n\t\t\t// We can only treat this merge as trivial if we can trivially hoist the input to the idom.\n\t\t\t// Hoisting to idom only works if that idom is not already a PHI input for succ,\n\t\t\t// and that idom dominates the input value.\n\t\t\tretarget_idom = loop_ladder->immediate_dominator;\n\n\t\t\tbool can_hoist_incoming_value =\n\t\t\t    retarget_idom && retarget_idom != loop_ladder &&\n\t\t\t    !phi_incoming_blocks_find_block(succ->ir.phi.front().incoming, retarget_idom);\n\n\t\t\tif (!can_hoist_incoming_value)\n\t\t\t\tretarget_idom = nullptr;\n\t\t}\n\n\t\tif (retarget_idom)\n\t\t{\n\t\t\tbool is_generated = false;\n\n\t\t\t// We have no opcodes in loop ladder, but theoretically,\n\t\t\t// we can have some PHI values that are being depended on.\n\t\t\tfor (auto &override_phi : succ->ir.phi)\n\t\t\t{\n\t\t\t\tauto *incoming = phi_incoming_blocks_find_block(override_phi.incoming, loop_ladder);\n\t\t\t\tif (!incoming)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (id_is_generated_by_block(loop_ladder, incoming->id))\n\t\t\t\t{\n\t\t\t\t\tis_generated = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!is_generated)\n\t\t\t{\n\t\t\t\t// If we don't generate the ID ourselves and idom dominates this block we can prove\n\t\t\t\t// that idom is a valid incoming value.\n\t\t\t\tfor (auto &override_phi : succ->ir.phi)\n\t\t\t\t\tretarget_phi_incoming_block(override_phi, loop_ladder, retarget_idom);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// It's not a trivial merge after all :(\n\t\t\t\tladder_to_merge_is_trivial = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tCFGNode *full_break_target = nullptr;\n\n\t// We have to break somewhere, turn the outer selection construct into\n\t// a loop.\n\tif (!ladder_to_merge_is_trivial)\n\t{\n\t\t// Selection merge to this dummy instead.\n\t\tauto *new_selection_merge = create_helper_pred_block(node);\n\n\t\t// This is now our fallback loop break target.\n\t\tfull_break_target = node;\n\n\t\tauto *loop = create_helper_pred_block(new_selection_merge->headers[0]);\n\n\t\t// Reassign header node.\n\t\tassert(new_selection_merge->headers[0]->merge == MergeType::Selection);\n\t\tnew_selection_merge->headers[0]->selection_merge_block = new_selection_merge;\n\t\tnew_selection_merge->headers[0] = loop;\n\n\t\tloop->merge = MergeType::Loop;\n\t\tloop->loop_merge_block = node;\n\t\tloop->freeze_structured_analysis = true;\n\n\t\t// After the loop ladder, make sure we always branch to the break target.\n\t\ttraverse_dominated_blocks_and_rewrite_branch(loop_ladder, new_selection_merge, node);\n\n\t\tnode = new_selection_merge;\n\t}\n\n\treturn full_break_target;\n}\n\nCFGNode *CFGStructurizer::build_ladder_block_for_escaping_edge_handling(CFGNode *node, CFGNode *header,\n                                                                        CFGNode *loop_ladder,\n                                                                        CFGNode *target_header,\n                                                                        CFGNode *full_break_target,\n                                                                        const UnorderedSet<const CFGNode *> &normal_preds)\n{\n\tCFGNode *new_ladder_block = nullptr;\n\n\tif (target_header || full_break_target)\n\t{\n\t\t// If we have a ladder block, there exists a merge candidate which the loop header dominates.\n\t\t// We create a ladder block before the merge block, which becomes the true merge block.\n\t\t// In this ladder block, we can detect with Phi nodes whether the break was \"clean\",\n\t\t// or if we had an escape edge.\n\t\t// If we have an escape edge, we can break to outer level, and continue the ladder that way.\n\t\t// Otherwise we branch to the existing merge block and continue as normal.\n\t\t// We'll also need to rewrite a lot of Phi nodes this way as well.\n\t\tauto *ladder = create_helper_pred_block(loop_ladder);\n\t\tnew_ladder_block = ladder;\n\n\t\tunsigned header_index;\n\t\tfor (header_index = 0; header_index < uint32_t(node->headers.size()); header_index++)\n\t\t\tif (node->headers[header_index] == header)\n\t\t\t\tbreak;\n\n\t\tassert(header_index != node->headers.size());\n\n\t\t// Merge to ladder instead.\n\t\t// If we're fixing up ladders for header index 0 it means we've already rewritten everything,\n\t\t// only apply the last fixup branch.\n\t\tif (header_index != 0 || block_is_plain_continue(node))\n\t\t{\n\t\t\ttraverse_dominated_blocks_and_rewrite_branch(\n\t\t\t\theader, node, ladder,\n\t\t\t\t[node, header_index](const CFGNode *next)\n\t\t\t\t{\n\t\t\t\t\tfor (unsigned i = 0; i < header_index; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *target = node->headers[i];\n\t\t\t\t\t\t// Do not introduce cycles. Outer scopes must never be rewritten to branch to inner scopes.\n\t\t\t\t\t\tif (target && target->loop_ladder_block == next)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}, {});\n\t\t}\n\n\t\tCFGNode *true_block = nullptr;\n\n\t\t// Ladder breaks out to outer scope.\n\t\tif (target_header && target_header->loop_ladder_block)\n\t\t\ttrue_block = target_header->loop_ladder_block;\n\t\telse if (target_header && target_header->loop_merge_block)\n\t\t\ttrue_block = target_header->loop_merge_block;\n\t\telse if (full_break_target)\n\t\t\ttrue_block = full_break_target;\n\t\telse\n\t\t\tLOGW(\"No loop merge block?\\n\");\n\n\t\tif (true_block)\n\t\t{\n\t\t\trewrite_ladder_conditional_branch_from_incoming_blocks(\n\t\t\t\tladder,\n\t\t\t\ttrue_block, loop_ladder, [&](const CFGNode *n) { return normal_preds.count(n) == 0; },\n\t\t\t\tString(\"ladder_phi_\") + loop_ladder->name);\n\n\t\t\t// This can happen in some scenarios, fixup the branch to be a direct one instead.\n\t\t\tif (ladder->ir.terminator.true_block == ladder->ir.terminator.false_block)\n\t\t\t{\n\t\t\t\tladder->ir.terminator.direct_block = ladder->ir.terminator.true_block;\n\t\t\t\tladder->ir.terminator.type = Terminator::Type::Branch;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\t// Here, loop_ladder -> final merge is a trivial, direct branch.\n\n\t\tif (loop_ladder->ir.operations.empty())\n\t\t{\n\t\t\t// Simplest common case.\n\t\t\t// If the loop ladder just branches to outer scope, and this block does not perform\n\t\t\t// any operations we can avoid messing around with ladder PHI variables and just execute the branch.\n\t\t\t// This block will likely become a frontier node when merging PHI instead.\n\t\t\t// This is a common case when breaking out of a simple for loop.\n\t\t\ttraverse_dominated_blocks_and_rewrite_branch(header, node, loop_ladder);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// We have a case where we're trivially breaking out of a selection construct,\n\t\t\t// but the loop ladder block contains operations which we must not execute,\n\t\t\t// since we were supposed to branch directly out to node.\n\t\t\t// We cannot directly break out of a selection construct, so our ladder must be a bit more sophisticated.\n\t\t\t// ladder-pre -> merge -> ladder-post -> selection merge\n\t\t\t//      \\-------------------/\n\t\t\tauto *ladder_pre = create_helper_pred_block(loop_ladder);\n\t\t\tauto *ladder_post = create_helper_succ_block(loop_ladder);\n\n\t\t\t// Merge to ladder instead.\n\t\t\ttraverse_dominated_blocks_and_rewrite_branch(header, node, ladder_pre);\n\n\t\t\trewrite_ladder_conditional_branch_from_incoming_blocks(\n\t\t\t\tladder_pre,\n\t\t\t\tladder_post, loop_ladder,\n\t\t\t\t[&](const CFGNode *n) { return normal_preds.count(n) == 0; },\n\t\t\t\tString(\"ladder_phi_\") + loop_ladder->name);\n\n\t\t\tnew_ladder_block = ladder_pre;\n\t\t}\n\t}\n\n\treturn new_ladder_block;\n}\n\nvoid CFGStructurizer::eliminate_degenerate_switch_merges()\n{\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\tif (node->headers.size() <= 1)\n\t\t\tcontinue;\n\n\t\t// In the second pass, it's illegal to have more than two target headers, so we have to turn some\n\t\t// headers into unreachable. The outermost scope wins.\n\t\tstd::sort(node->headers.begin(), node->headers.end(),\n\t\t          [](const CFGNode *a, const CFGNode *b) -> bool {\n\t\t\t          if (a->dominates(b))\n\t\t\t\t          return true;\n\t\t\t          else if (b->dominates(a))\n\t\t\t\t          return false;\n\t\t\t          else\n\t\t\t\t          return a->forward_post_visit_order > b->forward_post_visit_order;\n\t\t          });\n\n\t\t// Can only elide if we have a true loop merge to this node.\n\t\tif (node->headers[0]->merge != MergeType::Loop || node->headers[0]->loop_merge_block != node)\n\t\t\tcontinue;\n\n\t\tfor (size_t i = 1, n = node->headers.size(); i < n; i++)\n\t\t{\n\t\t\tauto *header = node->headers[i];\n\t\t\t// This cannot possibly work with loops.\n\t\t\t// We can generally turn selections into unreachable merges without trouble however ...\n\t\t\tif (header->merge == MergeType::Selection && header->selection_merge_block == node)\n\t\t\t\theader->selection_merge_block = nullptr;\n\t\t}\n\t}\n}\n\nbool CFGStructurizer::is_rewind_candidate_split_node(\n\tconst Vector<const CFGNode *> &visited_orphans, CFGNode *node, CFGNode *candidate) const\n{\n\tif (node->forward_post_visit_order != candidate->forward_post_visit_order)\n\t\treturn false;\n\n\tif (is_trivially_no_split_node(candidate))\n\t\treturn false;\n\n\tif (std::find(visited_orphans.begin(), visited_orphans.end(), candidate) != visited_orphans.end())\n\t\treturn false;\n\n\t// For whatever reason, the node is no longer a meaningful merge target.\n\tfor (auto *header : candidate->headers)\n\t\tif (!candidate->can_backtrace_to(header))\n\t\t\treturn false;\n\n\t// If we created a new helper pred block during traversal, it might not\n\t// exist in forward_post_visit_order.\n\t// Look for the replacement block here to make sure it gets processed in the appropriate order.\n\t// The replacement can happen in-line in this function,\n\t// so there is no chance to re-traverse the CFG.\n\t// Only consider blocks that we trivially post-dominate and that\n\t// definitely have no entry in forward_post_visit_order already.\n\tif (candidate->succ.size() != 1 || candidate->succ.front() != node)\n\t{\n\t\t// This is a ladder block of some sort. It's possible we're already in a \"resolved\" state,\n\t\t// so we really should not try to split further.\n\t\t// If we're considered a proper ladder block by any of our headers, bail.\n\t\tfor (auto *header : candidate->headers)\n\t\t\tif (header->loop_ladder_block == node || header->loop_merge_block == node)\n\t\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool CFGStructurizer::is_trivially_no_split_node(CFGNode *node) const\n{\n\tif (node->headers.size() <= 1 && !block_is_plain_continue(node))\n\t\treturn true;\n\n\t// It's possible that we have just one header.\n\t// One loop has a ladder block which is not this block, but the post-dominator is a pure continue block.\n\t// This gets rather awkward, since we need to special case this scenario.\n\tif (node->headers.empty())\n\t\treturn true;\n\n\treturn false;\n}\n\nbool CFGStructurizer::split_merge_blocks(CFGNode *node)\n{\n\tif (is_trivially_no_split_node(node))\n\t\treturn false;\n\n\t// If this block was the merge target for more than one construct,\n\t// we will need to split the block. In SPIR-V, a merge block can only be the merge target for one construct.\n\t// However, we can set up a chain of merges where inner scope breaks to outer scope with a dummy basic block.\n\t// The outer scope comes before the inner scope merge.\n\n\t// We cannot fully trust a sort on post-visit order, since if we have two split blocks here,\n\t// they will have the same post-visit order until we recompute them.\n\t// FIXME: Should probably be smarter about this ...\n\tstd::sort(node->headers.begin(), node->headers.end(),\n\t          [](const CFGNode *a, const CFGNode *b) -> bool\n\t          {\n\t\t          if (a->dominates(b))\n\t\t\t          return true;\n\t\t          else if (b->dominates(a))\n\t\t\t          return false;\n\t\t          else\n\t\t\t          return a->forward_post_visit_order > b->forward_post_visit_order;\n\t          });\n\n\t//LOGI(\"Splitting merge blocks for %s\\n\", node->name.c_str());\n\t//for (auto *header : node->headers)\n\t//\tLOGI(\"  Header: %s.\\n\", header->name.c_str());\n\n\tCFGNode *full_break_target = nullptr;\n\n\t// If we're a plain continue block, we're implicitly the full break target.\n\tbool plain_continue_resolve = block_is_plain_continue(node);\n\tif (plain_continue_resolve)\n\t\tfull_break_target = node;\n\n\t// Before we start splitting and rewriting branches, we need to know which preds are considered \"normal\",\n\t// and which branches are considered ladder breaking branches (rewritten branches).\n\t// This will influence if a pred block gets false or true when emitting ladder breaking blocks later.\n\tVector<UnorderedSet<const CFGNode *>> normal_preds(node->headers.size());\n\tfor (size_t i = 0; i < node->headers.size(); i++)\n\t\tif (node->headers[i]->loop_ladder_block)\n\t\t\tfor (auto *pred : node->headers[i]->loop_ladder_block->pred)\n\t\t\t\tnormal_preds[i].insert(pred);\n\n\tbool has_rewrites_to_outer_ladder = false;\n\n\t// Start from innermost scope, and rewrite all escape branches to a merge block which is dominated by the loop header in question.\n\t// The merge block for the loop must have a ladder block before the old merge block.\n\t// This ladder block will break to outer scope, or keep executing the old merge block.\n\tfor (size_t i = node->headers.size() - 1; i || plain_continue_resolve; i--)\n\t{\n\t\tauto *current_node = node->headers[i];\n\n\t\t// Find innermost loop header scope we can break to when resolving ladders.\n\t\tCFGNode *target_header = i != 0 ? get_target_break_block_for_inner_header(node, i) : nullptr;\n\n\t\t//LOGI(\"Current: %s, target: %s.\\n\", current_node->name.c_str(), target_header->name.c_str());\n\n\t\tif (current_node->merge == MergeType::Loop)\n\t\t{\n\t\t\tauto *loop_ladder = get_or_create_ladder_block(node, i);\n\n\t\t\t// The loop ladder needs to break to somewhere.\n\t\t\t// Either this is an outer loop scope, or we need to create a fake loop we can break out of if\n\t\t\t// the break is non-trivial.\n\t\t\tif (loop_ladder && !target_header && !full_break_target)\n\t\t\t\tfull_break_target = build_enclosing_break_target_for_loop_ladder(node, loop_ladder);\n\n\t\t\tCFGNode *new_ladder_block = nullptr;\n\t\t\tif (loop_ladder)\n\t\t\t{\n\t\t\t\tnew_ladder_block = build_ladder_block_for_escaping_edge_handling(\n\t\t\t\t    node, current_node, loop_ladder, target_header, full_break_target, normal_preds[i]);\n\n\t\t\t\tif (target_header == node->headers[0])\n\t\t\t\t\thas_rewrites_to_outer_ladder = true;\n\t\t\t}\n\n\t\t\t// We won't analyze this again, so make sure header knows\n\t\t\t// about the new merge block.\n\t\t\tif (current_node->freeze_structured_analysis)\n\t\t\t{\n\t\t\t\tif (new_ladder_block)\n\t\t\t\t\tcurrent_node->loop_ladder_block = new_ladder_block;\n\t\t\t\tcurrent_node->loop_merge_block = current_node->loop_ladder_block;\n\t\t\t\tcurrent_node->loop_ladder_block = nullptr;\n\t\t\t}\n\t\t}\n\t\telse if (current_node->merge == MergeType::Selection)\n\t\t{\n\t\t\tif (target_header)\n\t\t\t{\n\t\t\t\t// Breaks out to outer available scope.\n\t\t\t\tCFGNode *rewrite_to = nullptr;\n\t\t\t\tif (target_header->loop_ladder_block)\n\t\t\t\t\trewrite_to = target_header->loop_ladder_block;\n\t\t\t\telse if (target_header->loop_merge_block)\n\t\t\t\t\trewrite_to = target_header->loop_merge_block;\n\n\t\t\t\tif (rewrite_to)\n\t\t\t\t{\n\t\t\t\t\ttraverse_dominated_blocks_and_rewrite_branch(current_node, node, rewrite_to);\n\t\t\t\t\tif (target_header == node->headers[0])\n\t\t\t\t\t\thas_rewrites_to_outer_ladder = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tLOGW(\"No loop merge block?\\n\");\n\t\t\t}\n\t\t\telse if (full_break_target)\n\t\t\t{\n\t\t\t\ttraverse_dominated_blocks_and_rewrite_branch(current_node, node, full_break_target);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// The outer scope *must* now become a loop, no matter what.\n\t\t\t\t// We cannot rely on a traversal to rewrite breaking constructs in the entire loop,\n\t\t\t\t// so \"everything\" must essentially become a break instead.\n\t\t\t\tfull_break_target = node;\n\t\t\t\tassert(node->headers[0]->merge == MergeType::Selection);\n\t\t\t\tnode->headers[0]->merge = MergeType::Loop;\n\t\t\t\tnode->headers[0]->freeze_structured_analysis = true;\n\n\t\t\t\tassert(node->headers[0]->selection_merge_block == node);\n\t\t\t\tnode->headers[0]->loop_merge_block = node->headers[0]->selection_merge_block;\n\t\t\t\tnode->headers[0]->selection_merge_block = nullptr;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tLOGE(\"Invalid merge type.\\n\");\n\n\t\tif (i == 0)\n\t\t\tbreak;\n\t}\n\n\tauto *outer_header = node->headers[0];\n\tif (has_rewrites_to_outer_ladder && outer_header->merge == MergeType::Loop && outer_header->loop_ladder_block &&\n\t    outer_header->loop_merge_block && outer_header->loop_ladder_block->dominates(outer_header->loop_merge_block))\n\t{\n\t\tauto *ladder = outer_header->loop_ladder_block;\n\t\tbool non_trivial_ladder =\n\t\t    !ladder->ir.operations.empty() || ladder_chain_has_phi_dependencies(ladder, outer_header->loop_merge_block);\n\n\t\tif (non_trivial_ladder)\n\t\t{\n\t\t\t// It's possible we have branches that intended to rewrite to loop_merge_block\n\t\t\t// but ended up writing to loop_ladder_block instead.\n\t\t\t// Perform a final fixup branch if this is necessary.\n\t\t\t// If the ladder block is a dummy, we can ignore this.\n\t\t\tbuild_ladder_block_for_escaping_edge_handling(node, outer_header, outer_header->loop_ladder_block, nullptr,\n\t\t\t                                              outer_header->loop_merge_block, normal_preds[0]);\n\t\t}\n\t}\n\n\treturn true;\n}\n\nvoid CFGStructurizer::split_merge_blocks_and_visit_orphan_preds(\n\tVector<const CFGNode *> &visited_orphans, CFGNode *merge, CFGNode *node)\n{\n\tif (split_merge_blocks(node))\n\t\treturn;\n\n\tfor (auto *pred : node->pred)\n\t{\n\t\tif (is_rewind_candidate_split_node(visited_orphans, merge, pred))\n\t\t{\n\t\t\tvisited_orphans.push_back(pred);\n\t\t\tsplit_merge_blocks_and_visit_orphan_preds(visited_orphans, merge, pred);\n\t\t}\n\t}\n}\n\nvoid CFGStructurizer::split_merge_blocks()\n{\n\tVector<const CFGNode *> visited_orphans;\n\tfor (auto *node : forward_post_visit_order)\n\t\tsplit_merge_blocks_and_visit_orphan_preds(visited_orphans, node, node);\n}\n\nbool CFGStructurizer::structurize(unsigned pass)\n{\n\tauto switch_mode = process_switch_blocks(pass);\n\twhile (switch_mode == SwitchProgressMode::IterativeModify)\n\t{\n\t\t// For complex rewrites, we damage the CFG, so need to start over every iteration.\n\t\trecompute_cfg();\n\t\tswitch_mode = process_switch_blocks(pass);\n\t}\n\n\t// After a trivial modify, we must be able to complete the process in one iteration.\n\tif (switch_mode == SwitchProgressMode::SimpleModify)\n\t{\n\t\trecompute_cfg();\n\t\tif (process_switch_blocks(pass) != SwitchProgressMode::Done)\n\t\t{\n\t\t\tLOGE(\"Fatal, detected infinite loop.\\n\");\n\t\t\tabort();\n\t\t}\n\t}\n\n\tif (find_loops(pass))\n\t\treturn true;\n\tfind_selection_merges(pass);\n\tfixup_broken_selection_merges(pass);\n\tif (pass == 0)\n\t\tsplit_merge_blocks();\n\telse\n\t\teliminate_degenerate_switch_merges();\n\n\treturn false;\n}\n\nbool CFGStructurizer::exists_path_in_cfg_without_intermediate_node(const CFGNode *start_block,\n                                                                   const CFGNode *end_block,\n                                                                   const CFGNode *stop_block) const\n{\n\t// If we're resolving PHI for a frontier inside a loop, consider the back-edge as the end target for analysis.\n\t// If we start outside the loop, don't move the end block.\n\tif (end_block->pred_back_edge &&\n\t    !query_reachability(*stop_block, *end_block) &&\n\t    !query_reachability(*start_block, *end_block))\n\t{\n\t\tend_block = end_block->pred_back_edge;\n\t}\n\n\tif (query_reachability(*start_block, *end_block) &&\n\t    query_reachability(*start_block, *stop_block) &&\n\t    query_reachability(*stop_block, *end_block))\n\t{\n\t\tauto *frontier = get_post_dominance_frontier_with_cfg_subset_that_reaches(stop_block, end_block, start_block);\n\t\t// We already know start_block reaches the frontier.\n\t\treturn frontier != nullptr;\n\t}\n\telse\n\t{\n\t\tbool ret = query_reachability_through_back_edges(*start_block, *end_block);\n\t\treturn ret;\n\t}\n}\n\nCFGNode *CFGStructurizer::get_post_dominance_frontier_with_cfg_subset_that_reaches(const CFGNode *node,\n                                                                                   const CFGNode *must_reach,\n                                                                                   const CFGNode *must_reach_frontier) const\n{\n\tUnorderedSet<const CFGNode *> promoted_post_dominators;\n\tpromoted_post_dominators.insert(node);\n\tauto frontiers = node->post_dominance_frontier;\n\n\tassert(query_reachability(*node, *must_reach));\n\n\tif (frontiers.empty())\n\t\treturn nullptr;\n\n\twhile (!frontiers.empty())\n\t{\n\t\t// We might not be interested in post-domination-frontiers that we cannot reach.\n\t\t// Filter our search based on this.\n\t\tif (must_reach_frontier)\n\t\t{\n\t\t\tauto itr = std::remove_if(frontiers.begin(), frontiers.end(), [&](CFGNode *candidate) {\n\t\t\t    return !query_reachability(*must_reach_frontier, *candidate);\n\t\t\t});\n\t\t\tfrontiers.erase(itr, frontiers.end());\n\t\t}\n\n\t\tif (frontiers.size() > 1)\n\t\t{\n\t\t\tstd::sort(frontiers.begin(), frontiers.end(), [](const CFGNode *a, const CFGNode *b) {\n\t\t\t\treturn a->backward_post_visit_order < b->backward_post_visit_order;\n\t\t\t});\n\t\t\tfrontiers.erase(std::unique(frontiers.begin(), frontiers.end()), frontiers.end());\n\t\t}\n\t\telse if (frontiers.empty())\n\t\t\tbreak;\n\n\t\tauto *frontier = frontiers.back();\n\n\t\t// For a frontier to be discounted, we look at all successors and check\n\t\t// if there no node in promoted_post_dominators that post-dominate the successor, that path cannot reach must_reach.\n\t\t// If a post dominance frontier satisfies this rule, it is promoted to be considered an alias of node.\n\n\t\tbool all_succs_must_go_via_node = true;\n\t\tfor (auto *succ : frontier->succ)\n\t\t{\n\t\t\tbool promote = true;\n\t\t\tif (query_reachability(*succ, *must_reach))\n\t\t\t{\n\t\t\t\tpromote = false;\n\t\t\t\tfor (auto *pdom : promoted_post_dominators)\n\t\t\t\t{\n\t\t\t\t\tif (pdom->post_dominates(succ))\n\t\t\t\t\t{\n\t\t\t\t\t\tpromote = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!promote)\n\t\t\t{\n\t\t\t\tall_succs_must_go_via_node = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!all_succs_must_go_via_node)\n\t\t{\n\t\t\treturn frontier;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tpromoted_post_dominators.insert(frontier);\n\t\t\tfrontiers.pop_back();\n\t\t\tfor (auto *pdoms : frontier->post_dominance_frontier)\n\t\t\t\tfrontiers.push_back(pdoms);\n\t\t}\n\t}\n\n\treturn frontiers.empty() ? nullptr : frontiers.front();\n}\n\nvoid CFGStructurizer::recompute_post_dominance_frontier(CFGNode *node)\n{\n\tfor (auto *pred : node->pred)\n\t{\n\t\tif (pred->immediate_post_dominator != node &&\n\t\t    std::find(node->post_dominance_frontier.begin(),\n\t\t              node->post_dominance_frontier.end(),\n\t\t              pred) == node->post_dominance_frontier.end())\n\t\t{\n\t\t\tnode->post_dominance_frontier.push_back(pred);\n\t\t}\n\n\t\tif (auto *ipdom = node->immediate_post_dominator)\n\t\t{\n\t\t\tfor (auto *frontier_node : node->post_dominance_frontier)\n\t\t\t{\n\t\t\t\tif (!ipdom->post_dominates(frontier_node) &&\n\t\t\t\t    std::find(ipdom->post_dominance_frontier.begin(),\n\t\t\t\t              ipdom->post_dominance_frontier.end(),\n\t\t\t\t              frontier_node) == ipdom->post_dominance_frontier.end())\n\t\t\t\t{\n\t\t\t\t\tipdom->post_dominance_frontier.push_back(frontier_node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid CFGStructurizer::recompute_dominance_frontier(CFGNode *node)\n{\n\tfor (auto *succ : node->succ)\n\t{\n\t\tif (succ->immediate_dominator != node &&\n\t\t    std::find(node->dominance_frontier.begin(),\n\t\t              node->dominance_frontier.end(),\n\t\t              succ) == node->dominance_frontier.end())\n\t\t{\n\t\t\tnode->dominance_frontier.push_back(succ);\n\t\t}\n\n\t\tif (auto *idom = node->immediate_dominator)\n\t\t{\n\t\t\tfor (auto *frontier_node : node->dominance_frontier)\n\t\t\t{\n\t\t\t\tif (!idom->dominates(frontier_node) &&\n\t\t\t\t    std::find(idom->dominance_frontier.begin(),\n\t\t\t\t              idom->dominance_frontier.end(),\n\t\t\t\t              frontier_node) == idom->dominance_frontier.end())\n\t\t\t\t{\n\t\t\t\t\tidom->dominance_frontier.push_back(frontier_node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool CFGStructurizer::rewrite_invalid_loop_breaks()\n{\n\t// Keep iterating here until we have validated a clean CFG w.r.t. block-like loops.\n\t// This should pass through first time without issue with extremely high probability,\n\t// so hitting the slow path isn't a real concern until proven otherwise.\n\tCFGNode *rewrite_header = nullptr;\n\tCFGNode *invalid_target = nullptr;\n\tCFGNode *invalid_merge = nullptr;\n\n\t// Process from inside out.\n\tfor (auto *node : forward_post_visit_order)\n\t{\n\t\t// Structured loop constructs can end up with problematic merge scenarios where we missed\n\t\t// some cases where blocks branch outside our construct.\n\t\t// At some point, we were considered mere selection constructs and breaking out of it is fine,\n\t\t// but if the selection is promoted to a loop at some point after this analysis, we are a bit screwed.\n\t\t// This can happen in complex ladder resolve scenarios.\n\t\t// The fix-up means introducing multiple levels of ladder blocks.\n\t\tif (node->merge == MergeType::Loop && node->freeze_structured_analysis)\n\t\t{\n\t\t\tauto *merge = node->loop_merge_block;\n\t\t\tif (!merge || merge->post_dominates(node))\n\t\t\t\tcontinue;\n\n\t\t\tnode->traverse_dominated_blocks([&](CFGNode *candidate) {\n\t\t\t\tif (candidate == merge || invalid_target)\n\t\t\t\t\treturn false;\n\n\t\t\t\t// If the succ can reach outside the loop construct, we have an error condition.\n\t\t\t\tfor (auto *succ : candidate->succ)\n\t\t\t\t{\n\t\t\t\t\tbool can_reach_merge = query_reachability(*succ, *merge);\n\t\t\t\t\tauto *candidate_continue = scan_plain_continue_block(succ);\n\n\t\t\t\t\t// Need to be a bit more careful about continue blocks in infinite loops.\n\t\t\t\t\t// Include loop exits as well in the reachability analysis.\n\t\t\t\t\tif (!can_reach_merge && candidate_continue->succ_back_edge)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (auto *fake_succ : candidate_continue->fake_succ)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (query_reachability(*fake_succ, *merge))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcan_reach_merge = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!can_reach_merge)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Determine if we're an inner terminate/return, or a loop exit.\n\t\t\t\t\t\t// If the common post-dominator is EXIT node, this is a return-like relationship,\n\t\t\t\t\t\t// and we skip any fixup.\n\t\t\t\t\t\tauto *pdom = CFGNode::find_common_post_dominator(succ, merge);\n\t\t\t\t\t\tif (pdom != nullptr && !pdom->pred.empty())\n\t\t\t\t\t\t\tinvalid_target = succ;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\t\tif (invalid_target)\n\t\t\t{\n\t\t\t\trewrite_header = node;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (node->merge == MergeType::Loop && node->loop_merge_block && node->pred_back_edge &&\n\t\t         node->pred_back_edge->succ.empty())\n\t\t{\n\t\t\t// Only consider \"infinite\" loops here. Otherwise, the break from continue will always be\n\t\t\t// a suitable merge target and the ladder block for any loop exits.\n\n\t\t\tif (!node->dominates(node->loop_merge_block))\n\t\t\t{\n\t\t\t\t// We must dominate the loop merge block here.\n\t\t\t\t// There is a risk that with breaks happening into multiple scopes in certain cases,\n\t\t\t\t// we won't be able to guarantee this in the two-phase structurizer.\n\t\t\t\tinvalid_merge = node;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (invalid_merge)\n\t{\n\t\tauto result = analyze_loop(invalid_merge);\n\t\tresult.dominated_exit.insert(result.dominated_exit.end(), result.non_dominated_exit.begin(),\n\t\t                             result.non_dominated_exit.end());\n\t\tcollect_and_dispatch_control_flow(invalid_merge, invalid_merge->loop_merge_block, result.dominated_exit, false,\n\t\t                                  false);\n\t\trecompute_cfg();\n\t\treturn true;\n\t}\n\n\tif (invalid_target)\n\t{\n\t\tauto *merge = rewrite_header->loop_merge_block;\n\t\tauto *dispatcher = create_helper_pred_block(merge);\n\t\trewrite_header->loop_merge_block = dispatcher;\n\n\t\tsize_t natural_preds = dispatcher->pred.size();\n\t\ttraverse_dominated_blocks_and_rewrite_branch(rewrite_header, invalid_target, dispatcher);\n\n\t\tPHI phi;\n\t\tphi.id = module.allocate_id();\n\t\tphi.type_id = module.get_builder().makeBoolType();\n\t\tmodule.get_builder().addName(phi.id, (String(\"break_selector_\") + merge->name).c_str());\n\n\t\tfor (size_t i = 0; i < natural_preds; i++)\n\t\t{\n\t\t\tIncomingValue incoming = {};\n\t\t\tincoming.block = dispatcher->pred[i];\n\t\t\tincoming.id = module.get_builder().makeBoolConstant(true);\n\t\t\tphi.incoming.push_back(incoming);\n\t\t}\n\n\t\tfor (size_t i = natural_preds, n = dispatcher->pred.size(); i < n; i++)\n\t\t{\n\t\t\tIncomingValue incoming = {};\n\t\t\tincoming.block = dispatcher->pred[i];\n\t\t\tincoming.id = module.get_builder().makeBoolConstant(false);\n\t\t\tphi.incoming.push_back(incoming);\n\t\t}\n\n\t\tdispatcher->ir.terminator.type = Terminator::Type::Condition;\n\t\tdispatcher->ir.terminator.true_block = merge;\n\t\tdispatcher->ir.terminator.false_block = invalid_target;\n\t\tdispatcher->ir.terminator.direct_block = nullptr;\n\t\tdispatcher->ir.terminator.conditional_id = phi.id;\n\n\t\tdispatcher->ir.phi.push_back(std::move(phi));\n\t\tdispatcher->add_branch(invalid_target);\n\n\t\trecompute_cfg();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nvoid CFGStructurizer::traverse(BlockEmissionInterface &iface)\n{\n\t// Make sure all blocks are known to the backend before we emit code.\n\t// Prefer that IDs grow the further down the function we go.\n\tfor (auto itr = forward_post_visit_order.rbegin(); itr != forward_post_visit_order.rend(); ++itr)\n\t{\n\t\t(*itr)->id = 0;\n\t\tiface.register_block(*itr);\n\t}\n\n\t// Need to emit blocks such that dominating blocks come before dominated blocks.\n\tfor (auto index = forward_post_visit_order.size(); index; index--)\n\t{\n\t\tauto *block = forward_post_visit_order[index - 1];\n\n\t\tauto &merge = block->ir.merge_info;\n\n\t\tswitch (block->merge)\n\t\t{\n\t\tcase MergeType::Selection:\n\t\t\tmerge.merge_block = block->selection_merge_block;\n\t\t\tif (merge.merge_block)\n\t\t\t\tiface.register_block(merge.merge_block);\n\t\t\tmerge.merge_type = block->merge;\n\t\t\tiface.emit_basic_block(block);\n\t\t\tbreak;\n\n\t\tcase MergeType::Loop:\n\t\t\tmerge.merge_block = block->loop_merge_block;\n\t\t\tmerge.merge_type = block->merge;\n\t\t\tmerge.continue_block = block->pred_back_edge;\n\t\t\tif (merge.merge_block)\n\t\t\t\tiface.register_block(merge.merge_block);\n\t\t\tif (merge.continue_block)\n\t\t\t\tiface.register_block(merge.continue_block);\n\n\t\t\tiface.emit_basic_block(block);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tiface.emit_basic_block(block);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\ntemplate <typename Op>\nvoid CFGStructurizer::traverse_dominated_blocks_and_rewrite_branch(const CFGNode *dominator, CFGNode *candidate,\n                                                                   CFGNode *from, CFGNode *to, const Op &op,\n                                                                   const Vector<CFGNode *> &barrier,\n                                                                   UnorderedSet<CFGNode *> &visitation_cache)\n{\n\tvisitation_cache.insert(candidate);\n\n\tfor (auto *node : candidate->succ)\n\t{\n\t\tif (!op(node))\n\t\t\tcontinue;\n\n\t\tif (node == from)\n\t\t{\n\t\t\t// Don't introduce a cycle.\n\t\t\t// We only retarget branches when we have \"escape-like\" edges.\n\t\t\tbool introduces_cycle;\n\n\t\t\tif ((to->forward_post_visit_order == candidate->forward_post_visit_order && to != candidate) ||\n\t\t\t    (from->forward_post_visit_order == candidate->forward_post_visit_order && from != candidate))\n\t\t\t{\n\t\t\t\t// Can happen when resolving ladders. We cannot use reachability query, do it slow way.\n\t\t\t\tintroduces_cycle = candidate->can_backtrace_to(to);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tintroduces_cycle = query_reachability(*to, *candidate);\n\t\t\t}\n\n\t\t\tif (!introduces_cycle)\n\t\t\t{\n\t\t\t\t// If we already have a branch to \"to\", need to branch there via an intermediate node.\n\t\t\t\t// This way, we can distinguish between a normal branch and a rewritten branch.\n\t\t\t\tcandidate->retarget_branch_with_intermediate_node(from, to);\n\t\t\t}\n\t\t}\n\t\telse if (dominator->dominates(node) && node != to &&\n\t\t         std::find(barrier.begin(), barrier.end(), node) == barrier.end())\n\t\t{\n\t\t\t// Do not traverse beyond the new branch target.\n\t\t\tif (!visitation_cache.count(node))\n\t\t\t\ttraverse_dominated_blocks_and_rewrite_branch(dominator, node, from, to, op, barrier, visitation_cache);\n\t\t}\n\t}\n\n\t// In case we are rewriting branches to a new merge block, we might\n\t// change the immediate post dominator for continue blocks inside this loop construct.\n\t// When analysing post dominance in these cases, we need to make sure that we merge to the new merge block,\n\t// and not the old one. This avoids some redundant awkward loop constructs.\n\tfor (auto &fake_next : candidate->fake_succ)\n\t{\n\t\tif (fake_next == from)\n\t\t{\n\t\t\tcandidate->retarget_fake_succ(from, to);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\ntemplate <typename Op>\nvoid CFGStructurizer::traverse_dominated_blocks_and_rewrite_branch(CFGNode *dominator, CFGNode *from, CFGNode *to,\n                                                                   const Op &op, const Vector<CFGNode *> &barrier)\n{\n\tif (from == to)\n\t\treturn;\n\n\tUnorderedSet<CFGNode *> visitation_cache;\n\ttraverse_dominated_blocks_and_rewrite_branch(dominator, dominator, from, to, op, barrier, visitation_cache);\n\tdominator->fixup_merge_info_after_branch_rewrite(from, to);\n\n\t// Force all post-domination information to be recomputed.\n\tVector<CFGNode *> linear_visitation_cache;\n\tlinear_visitation_cache.reserve(visitation_cache.size());\n\n\tfor (auto *n : visitation_cache)\n\t{\n\t\tif (n->immediate_post_dominator == from)\n\t\t{\n\t\t\tif (n->fake_succ.empty())\n\t\t\t{\n\t\t\t\tn->immediate_post_dominator = nullptr;\n\t\t\t\t// Ignore any infinite continue blocks.\n\t\t\t\t// They wreak havoc in post-dominance analysis.\n\t\t\t\tlinear_visitation_cache.push_back(n);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Infinite loop blocks must not be traversed again.\n\t\t\t\tn->immediate_post_dominator = to;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Will recompute everything that was cleared out.\n\t// Compute later nodes first. This way we avoid a potential recursive loop.\n\tstd::sort(linear_visitation_cache.begin(), linear_visitation_cache.end(), [](const CFGNode *a, const CFGNode *b) {\n\t\treturn a->forward_post_visit_order < b->forward_post_visit_order;\n\t});\n\n\tfor (auto *n : linear_visitation_cache)\n\t\tif (!n->immediate_post_dominator)\n\t\t\tn->recompute_immediate_post_dominator();\n\tdominator->recompute_immediate_post_dominator();\n}\n\nvoid CFGStructurizer::traverse_dominated_blocks_and_rewrite_branch(CFGNode *dominator, CFGNode *from, CFGNode *to)\n{\n\ttraverse_dominated_blocks_and_rewrite_branch(dominator, from, to, [](const CFGNode *node) -> bool { return true; }, {});\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "cfg_structurizer.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"ir.hpp\"\n\n#include <memory>\n#include <stdint.h>\n\nnamespace dxil_spv\n{\nclass BlockEmissionInterface;\nclass SPIRVModule;\nstruct CFGNode;\nclass CFGNodePool;\n\nclass BlockEmissionInterface\n{\npublic:\n\tvirtual ~BlockEmissionInterface() = default;\n\tvirtual void emit_basic_block(CFGNode *node) = 0;\n\tvirtual void register_block(CFGNode *node) = 0;\n};\n\nclass CFGStructurizer\n{\npublic:\n\tCFGStructurizer(CFGNode *entry, CFGNodePool &pool, SPIRVModule &module);\n\tbool run();\n\tbool run_trivial();\n\tvoid traverse(BlockEmissionInterface &iface);\n\tCFGNode *get_entry_block() const;\n\n\tbool rewrite_rov_lock_region();\n\tvoid rewrite_auto_group_shared_barrier();\n\tvoid flatten_subgroup_shuffles();\n\tvoid fixup_loop_header_undef_phis();\n\nprivate:\n\tCFGNode *entry_block;\n\tCFGNode *exit_block;\n\tCFGNodePool &pool;\n\tSPIRVModule &module;\n\n\t// For dominance analysis.\n\tVector<CFGNode *> forward_post_visit_order;\n\t// For post-dominance analysis.\n\tVector<CFGNode *> backward_post_visit_order;\n\n\tVector<uint32_t> reachability_bitset;\n\tunsigned reachability_stride = 0;\n\n\tUnorderedSet<const CFGNode *> reachable_nodes;\n\tUnorderedSet<const CFGNode *> structured_loop_merge_targets;\n\tvoid visit(CFGNode &entry);\n\tvoid visit_for_back_edge_analysis(CFGNode &entry);\n\tvoid backwards_visit();\n\tvoid backwards_visit(CFGNode &entry);\n\tvoid build_immediate_dominators();\n\tvoid build_immediate_post_dominators();\n\tvoid build_reachability();\n\tvoid visit_reachability(const CFGNode &node);\n\tbool query_reachability(const CFGNode &from, const CFGNode &to) const;\n\tbool structurize(unsigned pass);\n\tbool find_loops(unsigned pass);\n\tbool rewrite_complex_loop_exits(CFGNode *node, CFGNode *merge, Vector<CFGNode *> &dominated_exits);\n\tbool rewrite_transposed_loops();\n\n\tstruct LoopAnalysis\n\t{\n\t\tVector<CFGNode *> direct_exits;\n\t\tVector<CFGNode *> inner_direct_exits;\n\t\tVector<CFGNode *> dominated_exit;\n\t\tVector<CFGNode *> inner_dominated_exit;\n\t\tVector<CFGNode *> non_dominated_exit;\n\t\tVector<CFGNode *> dominated_continue_exit;\n\t};\n\tLoopAnalysis analyze_loop(CFGNode *node) const;\n\n\tstruct LoopMergeAnalysis\n\t{\n\t\tCFGNode *merge;\n\t\tCFGNode *weak_merge;\n\t\tCFGNode *dominated_merge;\n\t\tCFGNode *infinite_continue_ladder;\n\t};\n\tLoopMergeAnalysis analyze_loop_merge(CFGNode *node, const LoopAnalysis &analysis);\n\tvoid rewrite_transposed_loop_inner(CFGNode *node, CFGNode *impossible_merge_target,\n\t                                   const LoopMergeAnalysis &analysis);\n\tvoid rewrite_transposed_loop_outer(CFGNode *node, CFGNode *impossible_merge_target,\n\t                                   const LoopMergeAnalysis &analysis);\n\n\tstatic bool is_strictly_dominance_ordered(const CFGNode *a, const CFGNode *b, const CFGNode *c);\n\tbool is_reachability_ordered(const CFGNode *a, const CFGNode *b, const CFGNode *c);\n\tbool serialize_interleaved_merge_scopes_aggressive();\n\tbool serialize_interleaved_merge_scopes();\n\tbool serialize_interleaved_early_returns();\n\tstatic Vector<std::pair<CFGNode *, CFGNode *>> build_pdf_ranges(const Vector<CFGNode *> &candidates);\n\tstatic bool pdf_ranges_have_strict_dominance_ordering(\n\t\tconst Vector<std::pair<CFGNode *, CFGNode *>> &candidates);\n\tvoid filter_serialization_candidates(Vector<CFGNode *> &candidates) const;\n\tvoid split_merge_scopes();\n\tbool is_rewind_candidate_split_node(const Vector<const CFGNode *> &visited_orphans, CFGNode *node,\n\t                                    CFGNode *candidate) const;\n\tbool is_trivially_no_split_node(CFGNode *node) const;\n\tvoid eliminate_degenerate_blocks();\n\tstatic bool ladder_chain_has_phi_dependencies(const CFGNode *chain, const CFGNode *incoming);\n\tvoid duplicate_impossible_merge_constructs();\n\tvoid duplicate_node(CFGNode *node);\n\tstatic bool can_duplicate_phis(const CFGNode *node);\n\tOperation *duplicate_op(Operation *op, UnorderedMap<spv::Id, spv::Id> &id_remap);\n\tvoid update_structured_loop_merge_targets();\n\tvoid find_selection_merges(unsigned pass);\n\tbool header_and_merge_block_have_entry_exit_relationship(const CFGNode *header, const CFGNode *merge) const;\n\tvoid fixup_broken_selection_merges(unsigned pass);\n\tbool selection_requires_structured_header(const CFGNode *node) const;\n\n\tenum class SwitchProgressMode { Done, SimpleModify, IterativeModify };\n\tSwitchProgressMode process_switch_blocks(unsigned pass);\n\n\tvoid hoist_switch_branches_to_frontier(CFGNode *node, CFGNode *merge, CFGNode *frontier);\n\tOperation *build_switch_case_equal_check(const CFGNode *header, CFGNode *insert_node,\n\t                                         const Terminator::Case &case_label);\n\tCFGNode *create_switch_merge_ladder(CFGNode *header, CFGNode *merge);\n\tCFGNode *find_natural_switch_merge_block(CFGNode *node, CFGNode *post_dominator) const;\n\tconst CFGNode *get_innermost_loop_header_for(const CFGNode *node) const;\n\tconst CFGNode *get_innermost_loop_header_for(const CFGNode *header, const CFGNode *node) const;\n\tbool loop_exit_supports_infinite_loop(const CFGNode *header, const CFGNode *loop_exit) const;\n\n\tvoid split_merge_blocks();\n\tbool split_merge_blocks(CFGNode *node);\n\tvoid split_merge_blocks_and_visit_orphan_preds(Vector<const CFGNode *> &visited, CFGNode *merge, CFGNode *node);\n\tvoid eliminate_degenerate_switch_merges();\n\tbool merge_candidate_is_on_breaking_path(const CFGNode *node) const;\n\tbool merge_candidate_is_inside_continue_construct(const CFGNode *node) const;\n\tbool continue_block_can_merge(CFGNode *node) const;\n\tstatic bool block_is_plain_continue(const CFGNode *node);\n\tstatic const CFGNode *scan_plain_continue_block(const CFGNode *node);\n\n\t// Create a new block. Rewrite all branches to node from blocks that are dominated by header to that block.\n\t// The new block then branches to node.\n\tCFGNode *create_ladder_block(CFGNode *header, CFGNode *node, const char *tag);\n\n\tCFGNode *get_target_break_block_for_inner_header(const CFGNode *node, size_t header_index);\n\tCFGNode *get_or_create_ladder_block(CFGNode *node, size_t header_index);\n\tCFGNode *build_enclosing_break_target_for_loop_ladder(CFGNode *&node, CFGNode *loop_ladder);\n\tCFGNode *build_ladder_block_for_escaping_edge_handling(CFGNode *node, CFGNode *header,\n\t                                                       CFGNode *loop_ladder,\n\t                                                       CFGNode *target_header,\n\t                                                       CFGNode *full_break_target,\n\t                                                       const UnorderedSet<const CFGNode *> &normal_preds);\n\n\tstatic CFGNode *find_common_post_dominator(const Vector<CFGNode *> &candidates);\n\tstatic CFGNode *find_common_post_dominator_with_ignored_break(Vector<CFGNode *> candidates,\n\t                                                              const CFGNode *break_node);\n\tCFGNode *find_break_target_for_selection_construct(CFGNode *idom, CFGNode *merge);\n\tbool control_flow_is_escaping(const CFGNode *node, const CFGNode *merge) const;\n\tbool control_flow_is_escaping_from_loop(const CFGNode *node, const CFGNode *merge) const;\n\tbool block_is_load_bearing(const CFGNode *node, const CFGNode *merge) const;\n\tstatic Vector<CFGNode *> isolate_structured_sorted(const CFGNode *header, const CFGNode *merge);\n\tstatic void isolate_structured(UnorderedSet<CFGNode *> &nodes, const CFGNode *header, const CFGNode *merge);\n\n\tstatic Vector<IncomingValue>::const_iterator find_incoming_value(const CFGNode *frontier_pred,\n\t                                                                 const Vector<IncomingValue> &incoming);\n\n\tvoid rewrite_selection_breaks(CFGNode *header, CFGNode *ladder_to);\n\n\tenum class LoopExitType\n\t{\n\t\tExit,\n\t\tMerge,\n\t\tEscape,\n\t\tMergeToInfiniteLoop,\n\t\tInnerLoopExit,\n\t\tInnerLoopMerge,\n\t\tInnerLoopFalsePositive\n\t};\n\tLoopExitType get_loop_exit_type(const CFGNode &header, const CFGNode &node) const;\n\tCFGNode *create_helper_pred_block(CFGNode *node);\n\tCFGNode *create_helper_succ_block(CFGNode *node);\n\tvoid reset_traversal();\n\tbool rewrite_invalid_loop_breaks();\n\tvoid recompute_cfg();\n\tvoid rewrite_multiple_back_edges();\n\tbool rewrite_impossible_back_edges();\n\tvoid compute_dominance_frontier();\n\tvoid compute_post_dominance_frontier();\n\tvoid create_continue_block_ladders();\n\tstatic void recompute_dominance_frontier(CFGNode *node);\n\tstatic void recompute_post_dominance_frontier(CFGNode *node);\n\tstatic void merge_to_succ(CFGNode *node, unsigned index);\n\tvoid retarget_pred_from(CFGNode *new_node, CFGNode *old_succ);\n\tvoid retarget_succ_from(CFGNode *new_node, CFGNode *old_pred);\n\n\tCFGNode *get_post_dominance_frontier_with_cfg_subset_that_reaches(const CFGNode *node,\n\t                                                                  const CFGNode *must_reach,\n\t                                                                  const CFGNode *must_reach_frontier) const;\n\tbool exists_path_in_cfg_without_intermediate_node(const CFGNode *start_block,\n\t                                                  const CFGNode *end_block,\n\t                                                  const CFGNode *stop_block) const;\n\n\tstruct PHINode\n\t{\n\t\tCFGNode *block;\n\t\tunsigned phi_index;\n\t};\n\tVector<PHINode> phi_nodes;\n\tvoid insert_phi();\n\tvoid insert_phi(PHINode &node);\n\tvoid fixup_phi(PHINode &node);\n\tvoid cleanup_breaking_phi_constructs();\n\tbool block_is_breaking_phi_construct(const CFGNode *node) const;\n\tbool cleanup_breaking_return_constructs();\n\tvoid eliminate_node_link_preds_to_succ(CFGNode *node);\n\tvoid prune_dead_preds();\n\n\tvoid fixup_broken_value_dominance();\n\n\tUnorderedMap<uint32_t, CFGNode *> value_id_to_block;\n\n\tvoid log_cfg(const char *tag) const;\n\tvoid log_cfg_graphviz(const char *path) const;\n\n\tstatic bool can_complete_phi_insertion(const PHI &phi, const CFGNode *end_node);\n\tbool query_reachability_through_back_edges(const CFGNode &from, const CFGNode &to) const;\n\tbool query_reachability_split_loop_header(const CFGNode &from, const CFGNode &to, const CFGNode &end_node) const;\n\tbool phi_frontier_makes_forward_progress(const PHI &phi, const CFGNode *frontier,\n\t                                         const CFGNode *end_node) const;\n\n\tvoid traverse_dominated_blocks_and_rewrite_branch(CFGNode *dominator, CFGNode *from, CFGNode *to);\n\ttemplate <typename Op>\n\tvoid traverse_dominated_blocks_and_rewrite_branch(CFGNode *dominator, CFGNode *from, CFGNode *to, const Op &op,\n\t                                                  const Vector<CFGNode *> &barrier);\n\n\ttemplate <typename Op>\n\tvoid traverse_dominated_blocks_and_rewrite_branch(const CFGNode *dominator, CFGNode *candidate,\n\t                                                  CFGNode *from, CFGNode *to, const Op &op,\n\t                                                  const Vector<CFGNode *> &barrier,\n\t                                                  UnorderedSet<CFGNode *> &visitation_cache);\n\n\tCFGNode *transpose_code_path_through_ladder_block(CFGNode *header, CFGNode *merge, CFGNode *succ);\n\tvoid rewrite_ladder_conditional_branch_from_incoming_blocks(\n\t\tCFGNode *ladder, CFGNode *true_block, CFGNode *false_block,\n\t\tconst std::function<bool (const CFGNode *)> &path_cb, const String &name);\n\n\tvoid propagate_branch_control_hints();\n\tvoid remove_unused_ssa();\n\n\tbool find_single_entry_exit_lock_region(\n\t    CFGNode *&idom, CFGNode *&pdom, const Vector<CFGNode *> &rov_blocks);\n\tbool execution_path_is_single_entry_and_dominates_exit(CFGNode *idom, CFGNode *pdom);\n\n\tvoid collect_and_dispatch_control_flow(\n\t\tCFGNode *common_idom, CFGNode *common_pdom, const Vector<CFGNode *> &constructs,\n\t\tbool collect_all_code_paths_to_pdom, bool allow_crossing_branches);\n\n\tvoid collect_and_dispatch_control_flow_from_anchor(\n\t\tCFGNode *anchor, const Vector<CFGNode *> &constructs);\n\n\tvoid sink_ssa_constructs();\n\tvoid sink_ssa_constructs_run(bool dry_run);\n};\n} // namespace dxil_spv\n"
  },
  {
    "path": "checkout_dxc.sh",
    "content": "#!/bin/bash\n\nDXC_REV=a9d33d3500d37bd24c10288c76aca8e1c948d4a2\n\nif [ -d external/DirectXShaderCompiler ]; then\n\techo \"Updating DirectXShaderCompiler to revision $DXC_REV.\"\n\tcd external/DirectXShaderCompiler\n\tgit fetch origin\n\tgit checkout $DXC_REV\n\tgit submodule update --init\nelse\n\techo \"Cloning DirectXShaderCompiler revision $DXC_REV.\"\n\tmkdir -p external\n\tcd external\n\tgit clone https://github.com/Microsoft/DirectXShaderCompiler.git\n\tcd DirectXShaderCompiler\n\tgit checkout $DXC_REV\n\tgit submodule update --init\nfi\n\n"
  },
  {
    "path": "checkout_llvm.sh",
    "content": "#!/bin/bash\n\nLLVM_REV=2c4ca6832fa6b306ee6a\n\nif [ -z $PROTOCOL ]; then\n\tPROTOCOL=git\nfi\n\necho \"Using protocol \\\"$PROTOCOL\\\" for checking out repositories. If this is problematic, try PROTOCOL=https $0.\"\n\nif [ -d external/llvm ]; then\n\techo \"Updating LLVM to revision $LLVM_REV.\"\n\tcd external/llvm\n\tgit fetch origin\n\tgit checkout $LLVM_REV\nelse\n\techo \"Cloning LLVM revision $LLVM_REV.\"\n\tmkdir -p external\n\tcd external\n\tgit clone $PROTOCOL://github.com/llvm-mirror/llvm.git\n\tcd llvm\n\tgit checkout $LLVM_REV\nfi\n\n"
  },
  {
    "path": "copy_reference_shaders.py",
    "content": "#!/usr/bin/env python3\n\n# Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n#\n# SPDX-License-Identifier: MIT\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nimport sys\nimport os\nimport argparse\nimport shutil\nimport hashlib\n\ndef hashstr(path):\n    with open(path, 'rb') as f:\n        bytes = f.read()\n        if len(bytes) < 4:\n            print('Skipping file', path, 'due to size < 4.')\n            return None\n\n        if bytes[0:4] != b'DXBC':\n            print('Skipping broken file', path)\n            return None\n\n        result = hashlib.sha1(bytes).hexdigest()\n    return result\n\ndef add_tags(path, noglsl):\n    if not noglsl:\n        return path\n    else:\n        return path[:-4] + 'noglsl.dxil'\n\ndef copy_reference_shader(output_dir, input_path, raw, noglsl):\n    modified_input_path = add_tags(input_path, noglsl)\n    if raw:\n        shutil.copy(input_path, os.path.join(output_dir, os.path.basename(modified_input_path)))\n    else:\n        name = hashstr(input_path)\n        if name is not None:\n            shutil.copy(input_path, os.path.join(output_dir, name + ('.noglsl' if noglsl else '') + '.dxil'))\n\ndef main():\n    parser = argparse.ArgumentParser(description = 'Script for copying VKD3D shader dumps to regression suite.')\n    parser.add_argument('--dxil', help = 'Folder containing a bunch of .dxil shaders.')\n    parser.add_argument('--dxbc', help = 'Folder containing a bunch of .dxbc shaders.')\n    parser.add_argument('--output', required = True, help = 'Output directory.')\n    parser.add_argument('--raw', help = 'Skip hashing. Files must be in format $hash.dxil', action = 'store_true')\n    parser.add_argument('--noglsl', help = 'Add .noglsl. tag.', action = 'store_true')\n\n    args = parser.parse_args()\n\n    if args.dxil is not None:\n        for root, dirs, files in os.walk(args.dxil):\n            for file in files:\n                ext = os.path.splitext(file)[1]\n                if ext == '.dxil':\n                    print('Copying DXIL reference file:', file)\n                    copy_reference_shader(args.output, os.path.join(args.dxil, file), args.raw, args.noglsl)\n\n    if args.dxbc is not None:\n        for root, dirs, files in os.walk(args.dxbc):\n            for file in files:\n                ext = os.path.splitext(file)[1]\n                if ext == '.dxbc':\n                    print('Copying DXBC reference file:', file)\n                    copy_reference_shader(args.output, os.path.join(args.dxbc, file), args.raw, args.noglsl)\n\nif __name__ == '__main__':\n    main()\n\n"
  },
  {
    "path": "debug/logging.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"logging.hpp\"\n\nnamespace dxil_spv\n{\nstatic thread_local LoggingCallback log_callback;\nstatic thread_local void *log_userdata;\n\nvoid set_thread_log_callback(LoggingCallback callback, void *userdata)\n{\n\tlog_callback = callback;\n\tlog_userdata = userdata;\n}\n\nLoggingCallback get_thread_log_callback()\n{\n\treturn log_callback;\n}\n\nvoid *get_thread_log_callback_userdata()\n{\n\treturn log_userdata;\n}\n}\n"
  },
  {
    "path": "debug/logging.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include <stdint.h>\n#include <stdio.h>\n\n#if defined(_MSC_VER)\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#define LOGE_INNER(...)                                            \\\n\tdo                                                             \\\n\t{                                                              \\\n\t\tfprintf(stderr, \"[ERROR]: \" __VA_ARGS__);                  \\\n\t\tfflush(stderr);                                            \\\n\t\tchar buffer[4096];                                         \\\n\t\tsnprintf(buffer, sizeof(buffer), \"[ERROR]: \" __VA_ARGS__); \\\n\t\tOutputDebugStringA(buffer);                                \\\n\t} while (false)\n\n#define LOGW_INNER(...)                                           \\\n\tdo                                                            \\\n\t{                                                             \\\n\t\tfprintf(stderr, \"[WARN]: \" __VA_ARGS__);                  \\\n\t\tfflush(stderr);                                           \\\n\t\tchar buffer[4096];                                        \\\n\t\tsnprintf(buffer, sizeof(buffer), \"[WARN]: \" __VA_ARGS__); \\\n\t\tOutputDebugStringA(buffer);                               \\\n\t} while (false)\n\n#define LOGI_INNER(...)                                           \\\n\tdo                                                            \\\n\t{                                                             \\\n\t\tfprintf(stderr, \"[INFO]: \" __VA_ARGS__);                  \\\n\t\tfflush(stderr);                                           \\\n\t\tchar buffer[4096];                                        \\\n\t\tsnprintf(buffer, sizeof(buffer), \"[INFO]: \" __VA_ARGS__); \\\n\t\tOutputDebugStringA(buffer);                               \\\n\t} while (false)\n#elif defined(ANDROID)\n#include <android/log.h>\n#define LOGE_INNER(...) __android_log_print(ANDROID_LOG_ERROR, \"dxil-spirv\", __VA_ARGS__)\n#define LOGW_INNER(...) __android_log_print(ANDROID_LOG_WARN, \"dxil-spirv\", __VA_ARGS__)\n#define LOGI_INNER(...) __android_log_print(ANDROID_LOG_INFO, \"dxil-spirv\", __VA_ARGS__)\n#else\n#define LOGE_INNER(...)                           \\\n\tdo                                            \\\n\t{                                             \\\n\t\tfprintf(stderr, \"[ERROR]: \" __VA_ARGS__); \\\n\t\tfflush(stderr);                           \\\n\t} while (false)\n\n#define LOGW_INNER(...)                          \\\n\tdo                                           \\\n\t{                                            \\\n\t\tfprintf(stderr, \"[WARN]: \" __VA_ARGS__); \\\n\t\tfflush(stderr);                          \\\n\t} while (false)\n\n#define LOGI_INNER(...)                          \\\n\tdo                                           \\\n\t{                                            \\\n\t\tfprintf(stderr, \"[INFO]: \" __VA_ARGS__); \\\n\t\tfflush(stderr);                          \\\n\t} while (false)\n#endif\n\nnamespace dxil_spv\n{\nenum class LogLevel : uint32_t\n{\n\tDebug = 0,\n\tWarn = 1,\n\tError = 2\n};\nusing LoggingCallback = void (*)(void *, LogLevel, const char *);\n\nvoid set_thread_log_callback(LoggingCallback callback, void *userdata);\nLoggingCallback get_thread_log_callback();\nvoid *get_thread_log_callback_userdata();\n}\n\n#define LOGI(...) do {                                                                           \\\n\tif (auto *cb = ::dxil_spv::get_thread_log_callback())                                        \\\n\t{                                                                                            \\\n\t\tchar buffer[4096];                                                                       \\\n\t\tsnprintf(buffer, sizeof(buffer), __VA_ARGS__);                                           \\\n\t\tcb(::dxil_spv::get_thread_log_callback_userdata(), ::dxil_spv::LogLevel::Debug, buffer); \\\n\t}                                                                                            \\\n\telse                                                                                         \\\n\t{                                                                                            \\\n        LOGI_INNER(__VA_ARGS__);                                                                 \\\n\t}                                                                                            \\\n} while(0)\n\n#define LOGW(...) do {                                                                           \\\n\tif (auto *cb = ::dxil_spv::get_thread_log_callback())                                        \\\n\t{                                                                                            \\\n\t\tchar buffer[4096];                                                                       \\\n\t\tsnprintf(buffer, sizeof(buffer), __VA_ARGS__);                                           \\\n\t\tcb(::dxil_spv::get_thread_log_callback_userdata(), ::dxil_spv::LogLevel::Warn, buffer);  \\\n\t}                                                                                            \\\n\telse                                                                                         \\\n\t{                                                                                            \\\n        LOGW_INNER(__VA_ARGS__);                                                                 \\\n\t}                                                                                            \\\n} while(0)\n\n#define LOGE(...) do {                                                                           \\\n\tif (auto *cb = ::dxil_spv::get_thread_log_callback())                                        \\\n\t{                                                                                            \\\n\t\tchar buffer[4096];                                                                       \\\n\t\tsnprintf(buffer, sizeof(buffer), __VA_ARGS__);                                           \\\n\t\tcb(::dxil_spv::get_thread_log_callback_userdata(), ::dxil_spv::LogLevel::Error, buffer); \\\n\t}                                                                                            \\\n\telse                                                                                         \\\n\t{                                                                                            \\\n        LOGE_INNER(__VA_ARGS__);                                                                 \\\n\t}                                                                                            \\\n} while(0)\n\n\n"
  },
  {
    "path": "descriptor_qa.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"descriptor_qa.hpp\"\n#include \"spirv_module.hpp\"\n#include \"SpvBuilder.h\"\n#include \"logging.hpp\"\n\nnamespace dxil_spv\n{\nstatic spv::Id build_descriptor_qa_heap_buffer_type(spv::Builder &builder)\n{\n\tVector<spv::Id> member_types;\n\t// DescriptorHeapQAData {\n\t//  uint descriptor_count;\n\t//  uint heap_id;\n\t//  uvec3 cookies_descriptor_info[];\n\t// }\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id uvec3_type = builder.makeVectorType(u32_type, 3);\n\tspv::Id uvec3_arr_type = builder.makeRuntimeArray(uvec3_type);\n\tbuilder.addDecoration(uvec3_arr_type, spv::DecorationArrayStride, 12);\n\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(uvec3_arr_type);\n\n\tspv::Id id = builder.makeStructType(member_types, \"DescriptorHeapQAData\");\n\n\tconst auto set_info = [&](DescriptorQAHeapMembers member, int offset, const char *name) {\n\t\tbuilder.addMemberDecoration(id, int(member), spv::DecorationOffset, offset);\n\t\tbuilder.addMemberName(id, int(member), name);\n\t};\n\n\tset_info(DescriptorQAHeapMembers::DescriptorCount, 0, \"descriptor_count\");\n\tset_info(DescriptorQAHeapMembers::HeapIndex, 4, \"heap_index\");\n\tset_info(DescriptorQAHeapMembers::CookiesDescriptorInfo, 8, \"cookies_descriptor_info\");\n\n\tbuilder.addDecoration(id, spv::DecorationBlock);\n\treturn id;\n}\n\nstatic spv::Id build_descriptor_global_buffer_type(spv::Builder &builder)\n{\n\tVector<spv::Id> member_types;\n\t// DescriptorHeapQAGlobalData {\n\t//  uvec2 failed_shader_hash;\n\t//  uint failed_offset;\n\t//  uint failed_heap;\n\t//  uint failed_cookie;\n\t//  uint fault_atomic;\n\t//  uint failed_instruction;\n\t//  uint failed_descriptor_type_mask;\n\t//  uint actual_descriptor_type_mask;\n\t//  uint fault_type;\n\t//  uint va_map_timestamp;\n\t//  uint live_status_table[];\n\t// }\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id uvec2_type = builder.makeVectorType(u32_type, 2);\n\tspv::Id u32_arr_type = builder.makeRuntimeArray(u32_type);\n\tbuilder.addDecoration(u32_arr_type, spv::DecorationArrayStride, 4);\n\n\tmember_types.push_back(uvec2_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_type);\n\tmember_types.push_back(u32_arr_type);\n\n\tspv::Id id = builder.makeStructType(member_types, \"DescriptorHeapGlobalQAData\");\n\n\tconst auto set_info = [&](DescriptorQAGlobalMembers member, int offset, const char *name) {\n\t\tbuilder.addMemberDecoration(id, int(member), spv::DecorationOffset, offset);\n\t\tbuilder.addMemberName(id, int(member), name);\n\t};\n\n\tset_info(DescriptorQAGlobalMembers::FailedShaderHash, 0, \"failed_shader_hash\");\n\tset_info(DescriptorQAGlobalMembers::FailedOffset, 8, \"failed_offset\");\n\tset_info(DescriptorQAGlobalMembers::FailedHeap, 12, \"failed_heap\");\n\tset_info(DescriptorQAGlobalMembers::FailedCookie, 16, \"failed_cookie\");\n\tset_info(DescriptorQAGlobalMembers::FaultAtomic, 20, \"fault_atomic\");\n\tset_info(DescriptorQAGlobalMembers::FailedInstruction, 24, \"failed_instruction\");\n\tset_info(DescriptorQAGlobalMembers::FailedDescriptorTypeMask, 28, \"failed_descriptor_type_mask\");\n\tset_info(DescriptorQAGlobalMembers::ActualDescriptorTypeMask, 32, \"actual_descriptor_type_mask\");\n\tset_info(DescriptorQAGlobalMembers::FaultType, 36, \"fault_type\");\n\tset_info(DescriptorQAGlobalMembers::VAMapTimestamp, 40, \"va_map_timestamp\");\n\tset_info(DescriptorQAGlobalMembers::LiveStatusTable, 44, \"live_status_table\");\n\n\tbuilder.addDecoration(id, spv::DecorationBlock);\n\n\treturn id;\n}\n\nstatic spv::Id build_ssbo_load(spv::Builder &builder, spv::Id value_type, spv::Id ssbo_id, uint32_t member)\n{\n\tspv::Id ptr_id = builder.makePointer(spv::StorageClassStorageBuffer, value_type);\n\tauto chain = std::make_unique<spv::Instruction>(builder.getUniqueId(), ptr_id, spv::OpAccessChain);\n\tchain->addIdOperand(ssbo_id);\n\tchain->addIdOperand(builder.makeUintConstant(member));\n\n\tauto load = std::make_unique<spv::Instruction>(builder.getUniqueId(), value_type, spv::OpLoad);\n\tload->addIdOperand(chain->getResultId());\n\tspv::Id result_id = load->getResultId();\n\n\tbuilder.getBuildPoint()->addInstruction(std::move(chain));\n\tbuilder.getBuildPoint()->addInstruction(std::move(load));\n\treturn result_id;\n}\n\nstatic void build_ssbo_store(spv::Builder &builder, spv::Id value_type, spv::Id ssbo_id, uint32_t member, spv::Id value_id)\n{\n\tspv::Id ptr_id = builder.makePointer(spv::StorageClassStorageBuffer, value_type);\n\tauto chain = std::make_unique<spv::Instruction>(builder.getUniqueId(), ptr_id, spv::OpAccessChain);\n\tchain->addIdOperand(ssbo_id);\n\tchain->addIdOperand(builder.makeUintConstant(member));\n\n\tauto store = std::make_unique<spv::Instruction>(spv::OpStore);\n\tstore->addIdOperand(chain->getResultId());\n\tstore->addIdOperand(value_id);\n\tif (builder.hasCapability(spv::CapabilityVulkanMemoryModel))\n\t\tstore->addImmediateOperand(spv::MemoryAccessNonPrivatePointerMask);\n\n\tbuilder.getBuildPoint()->addInstruction(std::move(chain));\n\tbuilder.getBuildPoint()->addInstruction(std::move(store));\n}\n\nstatic spv::Id build_ssbo_load_array(spv::Builder &builder, spv::Id value_type, spv::Id ssbo_id, uint32_t member,\n                                     spv::Id offset)\n{\n\tspv::Id ptr_id = builder.makePointer(spv::StorageClassStorageBuffer, value_type);\n\tauto chain = std::make_unique<spv::Instruction>(builder.getUniqueId(), ptr_id, spv::OpAccessChain);\n\tchain->addIdOperand(ssbo_id);\n\tchain->addIdOperand(builder.makeUintConstant(member));\n\tchain->addIdOperand(offset);\n\n\tauto load = std::make_unique<spv::Instruction>(builder.getUniqueId(), value_type, spv::OpLoad);\n\tload->addIdOperand(chain->getResultId());\n\tspv::Id result_id = load->getResultId();\n\n\tbuilder.getBuildPoint()->addInstruction(std::move(chain));\n\tbuilder.getBuildPoint()->addInstruction(std::move(load));\n\treturn result_id;\n}\n\nstatic void build_cookie_descriptor_info_split(spv::Builder &builder, spv::Id composite_id,\n                                               spv::Id &cookie_id,\n                                               spv::Id &cookie_shifted_id,\n                                               spv::Id &cookie_masked_id,\n                                               spv::Id &descriptor_timestamp_id,\n                                               spv::Id &descriptor_info_id)\n{\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tauto *cookie = builder.addInstruction(u32_type, spv::OpCompositeExtract);\n\tcookie->addIdOperand(composite_id);\n\tcookie->addImmediateOperand(0);\n\n\tauto *descriptor_timestamp = builder.addInstruction(u32_type, spv::OpCompositeExtract);\n\tdescriptor_timestamp->addIdOperand(composite_id);\n\tdescriptor_timestamp->addImmediateOperand(1);\n\n\tauto *descriptor_type = builder.addInstruction(u32_type, spv::OpCompositeExtract);\n\tdescriptor_type->addIdOperand(composite_id);\n\tdescriptor_type->addImmediateOperand(2);\n\n\tauto *shifted = builder.addInstruction(u32_type, spv::OpShiftRightLogical);\n\tshifted->addIdOperand(cookie->getResultId());\n\tshifted->addIdOperand(builder.makeUintConstant(5));\n\n\tauto *masked = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\tmasked->addIdOperand(cookie->getResultId());\n\tmasked->addIdOperand(builder.makeUintConstant(31));\n\n\tcookie_id = cookie->getResultId();\n\tdescriptor_timestamp_id = descriptor_timestamp->getResultId();\n\tdescriptor_info_id = descriptor_type->getResultId();\n\tcookie_shifted_id = shifted->getResultId();\n\tcookie_masked_id = masked->getResultId();\n}\n\nstatic spv::Id build_live_check(spv::Builder &builder, spv::Id status_id, spv::Id bit_id)\n{\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tauto shift_up = std::make_unique<spv::Instruction>(builder.getUniqueId(), u32_type, spv::OpShiftLeftLogical);\n\tshift_up->addIdOperand(builder.makeUintConstant(1));\n\tshift_up->addIdOperand(bit_id);\n\n\tauto mask = std::make_unique<spv::Instruction>(builder.getUniqueId(), u32_type, spv::OpBitwiseAnd);\n\tmask->addIdOperand(status_id);\n\tmask->addIdOperand(shift_up->getResultId());\n\n\tauto cond = std::make_unique<spv::Instruction>(builder.getUniqueId(), builder.makeBoolType(), spv::OpINotEqual);\n\tcond->addIdOperand(mask->getResultId());\n\tcond->addIdOperand(builder.makeUintConstant(0));\n\tspv::Id res = cond->getResultId();\n\n\tbuilder.getBuildPoint()->addInstruction(std::move(shift_up));\n\tbuilder.getBuildPoint()->addInstruction(std::move(mask));\n\tbuilder.getBuildPoint()->addInstruction(std::move(cond));\n\treturn res;\n}\n\nstatic spv::Id build_binary_op(spv::Builder &builder, spv::Id type, spv::Op opcode, spv::Id a, spv::Id b)\n{\n\tauto op = std::make_unique<spv::Instruction>(builder.getUniqueId(), type, opcode);\n\top->addIdOperand(a);\n\top->addIdOperand(b);\n\tspv::Id ret = op->getResultId();\n\tbuilder.getBuildPoint()->addInstruction(std::move(op));\n\treturn ret;\n}\n\nstatic void build_ssbo_barrier(spv::Builder &builder)\n{\n\tauto barrier = std::make_unique<spv::Instruction>(spv::OpMemoryBarrier);\n\tbarrier->addIdOperand(builder.getAtomicDeviceScopeId());\n\tbarrier->addIdOperand(builder.makeUintConstant(spv::MemorySemanticsUniformMemoryMask |\n\t                                               spv::MemorySemanticsAcquireReleaseMask));\n\tbuilder.getBuildPoint()->addInstruction(std::move(barrier));\n}\n\nstatic void build_descriptor_qa_fault_report(SPIRVModule &module, spv::Id &func_id, spv::Id &buffer_id)\n{\n\tauto &builder = module.get_builder();\n\tspv::Id global_buffer_type_id = build_descriptor_global_buffer_type(builder);\n\tspv::Id descriptor_qa_global_buffer_id = module.create_variable(spv::StorageClassStorageBuffer,\n\t                                                                global_buffer_type_id, \"QAGlobalData\");\n\tbuffer_id = descriptor_qa_global_buffer_id;\n\n\tbuilder.addDecoration(descriptor_qa_global_buffer_id, spv::DecorationDescriptorSet,\n\t                      module.get_descriptor_qa_info().global_desc_set);\n\tbuilder.addDecoration(descriptor_qa_global_buffer_id, spv::DecorationBinding,\n\t                      module.get_descriptor_qa_info().global_binding);\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\n\tVector<spv::Id> param_types(7, builder.makeUintType(32));\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(),\n\t                                       \"descriptor_qa_report_fault\", param_types, {}, &entry);\n\n\tfunc_id = func->getId();\n\n\tspv::Id fault_type_id = func->getParamId(0);\n\tspv::Id heap_offset_id = func->getParamId(1);\n\tspv::Id cookie_id = func->getParamId(2);\n\tspv::Id heap_id = func->getParamId(3);\n\tspv::Id descriptor_type_id = func->getParamId(4);\n\tspv::Id actual_descriptor_type_id = func->getParamId(5);\n\tspv::Id instruction_id = func->getParamId(6);\n\tbuilder.addName(fault_type_id, \"fault_type\");\n\tbuilder.addName(heap_offset_id, \"heap_offset\");\n\tbuilder.addName(cookie_id, \"cookie\");\n\tbuilder.addName(heap_id, \"heap_index\");\n\tbuilder.addName(descriptor_type_id, \"descriptor_type\");\n\tbuilder.addName(actual_descriptor_type_id, \"actual_descriptor_type\");\n\tbuilder.addName(instruction_id, \"instruction\");\n\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id u32_ptr_type = builder.makePointer(spv::StorageClassStorageBuffer, u32_type);\n\n\tauto chain = std::make_unique<spv::Instruction>(builder.getUniqueId(), u32_ptr_type, spv::OpAccessChain);\n\tchain->addIdOperand(descriptor_qa_global_buffer_id);\n\tchain->addIdOperand(builder.makeUintConstant(uint32_t(DescriptorQAGlobalMembers::FaultAtomic)));\n\n\tauto increment = std::make_unique<spv::Instruction>(builder.getUniqueId(), u32_type, spv::OpAtomicIAdd);\n\tincrement->addIdOperand(chain->getResultId());\n\tincrement->addIdOperand(builder.getAtomicDeviceScopeId());\n\tincrement->addIdOperand(builder.makeUintConstant(0));\n\tincrement->addIdOperand(builder.makeUintConstant(1));\n\n\tauto check = std::make_unique<spv::Instruction>(builder.getUniqueId(), builder.makeBoolType(), spv::OpIEqual);\n\tcheck->addIdOperand(increment->getResultId());\n\tcheck->addIdOperand(builder.makeUintConstant(0));\n\tspv::Id check_id = check->getResultId();\n\n\tauto *true_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *false_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tbuilder.setBuildPoint(entry);\n\tentry->addInstruction(std::move(chain));\n\tentry->addInstruction(std::move(increment));\n\tentry->addInstruction(std::move(check));\n\tbuilder.createSelectionMerge(false_block, 0);\n\tbuilder.createConditionalBranch(check_id, true_block, false_block);\n\tbuilder.setBuildPoint(true_block);\n\t{\n\t\tbuild_ssbo_store(builder, u32_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::FailedCookie), cookie_id);\n\t\tbuild_ssbo_store(builder, u32_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::FailedOffset), heap_offset_id);\n\t\tbuild_ssbo_store(builder, u32_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::FailedHeap), heap_id);\n\t\tbuild_ssbo_store(builder, u32_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::FailedDescriptorTypeMask), descriptor_type_id);\n\t\tbuild_ssbo_store(builder, u32_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::ActualDescriptorTypeMask), actual_descriptor_type_id);\n\t\tbuild_ssbo_store(builder, u32_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::FailedInstruction), instruction_id);\n\n\t\tspv::Id uvec2_type = builder.makeVectorType(u32_type, 2);\n\n\t\tVector<spv::Id> comps;\n\t\tcomps.push_back(builder.makeUintConstant(uint32_t(module.get_descriptor_qa_info().shader_hash)));\n\t\tcomps.push_back(builder.makeUintConstant(uint32_t(module.get_descriptor_qa_info().shader_hash >> 32u)));\n\t\tspv::Id hash_id = builder.makeCompositeConstant(uvec2_type, comps);\n\t\tbuild_ssbo_store(builder, uvec2_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::FailedShaderHash), hash_id);\n\n\t\t// Device memory barrier here so that if host observed fault_type != 0,\n\t\t// we're certain that the other values are correct as well.\n\t\tbuild_ssbo_barrier(builder);\n\n\t\tbuild_ssbo_store(builder, u32_type, descriptor_qa_global_buffer_id,\n\t\t                 uint32_t(DescriptorQAGlobalMembers::FaultType), fault_type_id);\n\n\t\tbuilder.createBranch(false_block);\n\t}\n\tbuilder.setBuildPoint(false_block);\n\tbuilder.makeReturn(false);\n\tbuilder.setBuildPoint(current_build_point);\n}\n\nspv::Id build_descriptor_qa_check_function(SPIRVModule &module)\n{\n\tauto &builder = module.get_builder();\n\tspv::Id fault_func_id, global_buffer_id;\n\tbuild_descriptor_qa_fault_report(module, fault_func_id, global_buffer_id);\n\n\tspv::Id heap_buffer_type_id = build_descriptor_qa_heap_buffer_type(builder);\n\tspv::Id descriptor_qa_heap_buffer_id = module.create_variable(spv::StorageClassStorageBuffer,\n\t                                                              heap_buffer_type_id, \"QAHeapData\");\n\tbuilder.addDecoration(descriptor_qa_heap_buffer_id, spv::DecorationDescriptorSet,\n\t                      module.get_descriptor_qa_info().heap_desc_set);\n\tbuilder.addDecoration(descriptor_qa_heap_buffer_id, spv::DecorationBinding,\n\t                      module.get_descriptor_qa_info().heap_binding);\n\tbuilder.addDecoration(descriptor_qa_heap_buffer_id, spv::DecorationNonWritable);\n\n\tauto heap_buffer_id = descriptor_qa_heap_buffer_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\n\tVector<spv::Id> param_types(3, builder.makeUintType(32));\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, builder.makeUintType(32),\n\t                                       \"descriptor_qa_check\",\n\t                                       param_types, {}, &entry);\n\tbuilder.setBuildPoint(entry);\n\n\tspv::Id offset_id = func->getParamId(0);\n\tspv::Id descriptor_type_id = func->getParamId(1);\n\tspv::Id instruction_id = func->getParamId(2);\n\n\tbuilder.addName(offset_id, \"heap_offset\");\n\tbuilder.addName(descriptor_type_id, \"descriptor_type_mask\");\n\tbuilder.addName(instruction_id, \"instruction\");\n\n\tspv::Id descriptor_count_id = build_ssbo_load(builder, builder.makeUintType(32), heap_buffer_id,\n\t                                              uint32_t(DescriptorQAHeapMembers::DescriptorCount));\n\n\tspv::Id fallback_offset_id = descriptor_count_id;\n\n\tspv::Id heap_id = build_ssbo_load(builder, builder.makeUintType(32), heap_buffer_id,\n\t                                  uint32_t(DescriptorQAHeapMembers::HeapIndex));\n\tspv::Id timestamp_id = build_ssbo_load(builder, builder.makeUintType(32), global_buffer_id,\n\t                                       uint32_t(DescriptorQAGlobalMembers::VAMapTimestamp));\n\tspv::Id cookie_descriptor_info = build_ssbo_load_array(builder, builder.makeVectorType(builder.makeUintType(32), 3),\n\t                                                       heap_buffer_id,\n\t                                                       uint32_t(DescriptorQAHeapMembers::CookiesDescriptorInfo),\n\t                                                       offset_id);\n\tspv::Id cookie_id;\n\tspv::Id cookie_shifted_id;\n\tspv::Id cookie_mask_id;\n\tspv::Id descriptor_timestamp_id;\n\tspv::Id descriptor_info_id;\n\tbuild_cookie_descriptor_info_split(builder, cookie_descriptor_info, cookie_id,\n\t                                   cookie_shifted_id, cookie_mask_id,\n\t                                   descriptor_timestamp_id, descriptor_info_id);\n\n\tspv::Id live_status_id = build_ssbo_load_array(builder, builder.makeUintType(32),\n\t                                               global_buffer_id,\n\t                                               uint32_t(DescriptorQAGlobalMembers::LiveStatusTable),\n\t                                               cookie_shifted_id);\n\tspv::Id live_status_cond_id = build_live_check(builder, live_status_id, cookie_mask_id);\n\n\tspv::Id type_cond_id = build_binary_op(builder, builder.makeUintType(32), spv::OpBitwiseAnd, descriptor_info_id, descriptor_type_id);\n\ttype_cond_id = build_binary_op(builder, builder.makeBoolType(), spv::OpIEqual,\n\t                               type_cond_id, descriptor_type_id);\n\n\tspv::Id out_of_range_id = build_binary_op(builder, builder.makeBoolType(), spv::OpUGreaterThanEqual,\n\t                                          offset_id, descriptor_count_id);\n\n\t// First check: descriptor index is in range of heap.\n\tauto *range_check = builder.addInstruction(builder.makeUintType(32), spv::OpSelect);\n\trange_check->addIdOperand(out_of_range_id);\n\trange_check->addIdOperand(builder.makeUintConstant(DESCRIPTOR_QA_FAULT_INDEX_OUT_OF_RANGE_BIT));\n\trange_check->addIdOperand(builder.makeUintConstant(0u));\n\n\t// Second: Check if type matches.\n\tauto *type_check = builder.addInstruction(builder.makeUintType(32), spv::OpSelect);\n\ttype_check->addIdOperand(type_cond_id);\n\ttype_check->addIdOperand(builder.makeUintConstant(0u));\n\ttype_check->addIdOperand(builder.makeUintConstant(DESCRIPTOR_QA_FAULT_INVALID_TYPE_BIT));\n\n\t// Third: Check if cookie is alive.\n\tauto *alive_check = builder.addInstruction(builder.makeUintType(32), spv::OpSelect);\n\talive_check->addIdOperand(live_status_cond_id);\n\talive_check->addIdOperand(builder.makeUintConstant(0u));\n\talive_check->addIdOperand(builder.makeUintConstant(DESCRIPTOR_QA_FAULT_RESOURCE_DESTROYED_BIT));\n\n\t// Fourth: Check if the view was created before GPU submission happened.\n\tauto *time_check_cond = builder.addInstruction(builder.makeBoolType(), spv::OpUGreaterThanEqual);\n\ttime_check_cond->addIdOperand(timestamp_id);\n\ttime_check_cond->addIdOperand(descriptor_timestamp_id);\n\n\tauto *time_check = builder.addInstruction(builder.makeUintType(32), spv::OpSelect);\n\ttime_check->addIdOperand(time_check_cond->getResultId());\n\ttime_check->addIdOperand(builder.makeUintConstant(0u));\n\ttime_check->addIdOperand(builder.makeUintConstant(DESCRIPTOR_QA_FAULT_VA_TIMESTAMP_INVALID_BIT));\n\n\tauto *merge_check0 = builder.addInstruction(builder.makeUintType(32), spv::OpBitwiseOr);\n\tauto *merge_check1 = builder.addInstruction(builder.makeUintType(32), spv::OpBitwiseOr);\n\tauto *merge_check2 = builder.addInstruction(builder.makeUintType(32), spv::OpBitwiseOr);\n\tmerge_check0->addIdOperand(range_check->getResultId());\n\tmerge_check0->addIdOperand(type_check->getResultId());\n\tmerge_check1->addIdOperand(merge_check0->getResultId());\n\tmerge_check1->addIdOperand(alive_check->getResultId());\n\tmerge_check2->addIdOperand(merge_check1->getResultId());\n\tmerge_check2->addIdOperand(time_check->getResultId());\n\n\tauto *fault_cond = builder.addInstruction(builder.makeBoolType(), spv::OpINotEqual);\n\tfault_cond->addIdOperand(merge_check2->getResultId());\n\tfault_cond->addIdOperand(builder.makeUintConstant(0u));\n\n\tspv::Id fault_type_id = merge_check2->getResultId();\n\tspv::Id fault_cond_id = fault_cond->getResultId();\n\n\tauto *fault_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *correct_block = new spv::Block(builder.getUniqueId(), *func);\n\tbuilder.createSelectionMerge(correct_block, 0);\n\tbuilder.createConditionalBranch(fault_cond_id, fault_block, correct_block);\n\t{\n\t\tbuilder.setBuildPoint(fault_block);\n\t\tauto *call = builder.addInstruction(builder.makeVoidType(), spv::OpFunctionCall);\n\t\tcall->addIdOperand(fault_func_id);\n\t\tcall->addIdOperand(fault_type_id);\n\t\tcall->addIdOperand(offset_id);\n\t\tcall->addIdOperand(cookie_id);\n\t\tcall->addIdOperand(heap_id);\n\t\tcall->addIdOperand(descriptor_type_id);\n\t\tcall->addIdOperand(descriptor_info_id);\n\t\tcall->addIdOperand(instruction_id);\n\t\tbuilder.makeReturn(false, fallback_offset_id);\n\t}\n\tbuilder.setBuildPoint(correct_block);\n\tbuilder.makeReturn(false, offset_id);\n\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n}\n"
  },
  {
    "path": "descriptor_qa.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include <stdint.h>\n#include \"spirv.hpp\"\n\nnamespace dxil_spv\n{\nstatic constexpr uint32_t Version = 2;\n\nstruct DescriptorQAInfo\n{\n\tuint32_t version = 0;\n\tuint32_t global_desc_set = 0;\n\tuint32_t global_binding = 0;\n\tuint32_t heap_desc_set = 0;\n\tuint32_t heap_binding = 0;\n\tuint64_t shader_hash = 0;\n};\n\nenum class InstructionInstrumentationType\n{\n\tFullNanInf = 0,\n\t// Only instrument writes to externally visible memory, etc.\n\t// Gets rid of potential false positives.\n\tExternallyVisibleWriteNanInf = 1,\n\t// Flushes all NaNs to zero.\n\t// Useful when trying to figure out where a NaN is first generated.\n\tFlushNaNToZero = 2,\n\t// Adds assertions with OpAssumeTrueKHR. For now, these are resolved internally,\n\t// but we could add a more that forwards them to driver.\n\tExpectAssume = 3,\n\tBufferSynchronizationValidation = 4\n};\n\nstruct InstructionInstrumentationInfo\n{\n\tuint32_t version = 0;\n\tbool enabled = false;\n\tbool fp16 = false;\n\tbool fp32 = false;\n\tbool fp64 = false;\n\tuint32_t control_desc_set = 0;\n\tuint32_t control_binding = 0;\n\tuint32_t payload_desc_set = 0;\n\tuint32_t payload_binding = 0;\n\tuint64_t shader_hash = 0;\n\tInstructionInstrumentationType type = {};\n};\n\nstruct InstructionInstrumentationState\n{\n\tuint32_t instruction_count = 0;\n\tspv::Id nan_inf_instrument_fp16_call_id = 0;\n\tspv::Id nan_inf_instrument_fp32_call_id = 0;\n\tspv::Id nan_inf_instrument_fp64_call_id = 0;\n\tspv::Id assume_true_call_id = 0;\n\tspv::Id should_report_instrumentation_id = 0;\n\tspv::Id global_nan_inf_control_var_id = 0;\n\tspv::Id global_nan_inf_data_var_id = 0;\n\tInstructionInstrumentationInfo info = {};\n};\n\nenum DescriptorQATypeFlagBits\n{\n\tDESCRIPTOR_QA_TYPE_NONE_BIT = 0,\n\tDESCRIPTOR_QA_TYPE_SAMPLED_IMAGE_BIT = 1 << 0,\n\tDESCRIPTOR_QA_TYPE_STORAGE_IMAGE_BIT = 1 << 1,\n\tDESCRIPTOR_QA_TYPE_UNIFORM_BUFFER_BIT = 1 << 2,\n\tDESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT = 1 << 3,\n\tDESCRIPTOR_QA_TYPE_UNIFORM_TEXEL_BUFFER_BIT = 1 << 4,\n\tDESCRIPTOR_QA_TYPE_STORAGE_TEXEL_BUFFER_BIT = 1 << 5,\n\tDESCRIPTOR_QA_TYPE_RT_ACCELERATION_STRUCTURE_BIT = 1 << 6,\n\tDESCRIPTOR_QA_TYPE_SAMPLER_BIT = 1 << 7,\n\tDESCRIPTOR_QA_TYPE_RAW_VA_BIT = 1 << 8\n};\nusing DescriptorQATypeFlags = uint32_t;\n\nenum class DescriptorQAGlobalMembers\n{\n\tFailedShaderHash = 0,\n\tFailedOffset,\n\tFailedHeap,\n\tFailedCookie,\n\tFaultAtomic,\n\tFailedInstruction,\n\tFailedDescriptorTypeMask,\n\tActualDescriptorTypeMask,\n\tFaultType,\n\tVAMapTimestamp,\n\tLiveStatusTable\n};\n\nenum DescriptorQAFaultTypeBits\n{\n\tDESCRIPTOR_QA_FAULT_INDEX_OUT_OF_RANGE_BIT = 1 << 0,\n\tDESCRIPTOR_QA_FAULT_INVALID_TYPE_BIT = 1 << 1,\n\tDESCRIPTOR_QA_FAULT_RESOURCE_DESTROYED_BIT = 1 << 2,\n\tDESCRIPTOR_QA_FAULT_VA_TIMESTAMP_INVALID_BIT = 1 << 3\n};\n\nenum class DescriptorQAHeapMembers\n{\n\tDescriptorCount = 0,\n\tHeapIndex,\n\tCookiesDescriptorInfo\n};\n\nclass SPIRVModule;\nspv::Id build_descriptor_qa_check_function(SPIRVModule &module);\n}\n"
  },
  {
    "path": "dxbc_spirv_sandbox.cpp",
    "content": "/* Copyright (c) 2025 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n */\n\n#include \"ir/ir.h\"\n#include \"ir/ir_builder.h\"\n#include \"dxil_converter.hpp\"\n#include \"module.hpp\"\n#include \"api/test_api.h\"\n#include \"context.hpp\"\n#include \"thread_local_allocator.hpp\"\n#include \"cfg_structurizer.hpp\"\n#include \"logging.hpp\"\n#include \"spirv_cross_c.h\"\n#include \"spirv-tools/libspirv.hpp\"\n\nusing namespace dxil_spv;\nusing namespace dxbc_spv;\n\nstruct Remapper : ResourceRemappingInterface\n{\n\tbool remap_srv(const D3DBinding &d3d_binding, VulkanSRVBinding &vulkan_binding) override\n\t{\n\t\tvulkan_binding = {};\n\t\tvulkan_binding.buffer_binding.descriptor_set = d3d_binding.register_space;\n\t\tvulkan_binding.buffer_binding.binding = d3d_binding.register_index;\n\t\tif (d3d_binding.kind == DXIL::ResourceKind::StructuredBuffer || d3d_binding.kind == DXIL::ResourceKind::RawBuffer)\n\t\t\tvulkan_binding.buffer_binding.descriptor_type = VulkanDescriptorType::SSBO;\n\t\treturn true;\n\t}\n\n\tbool remap_sampler(const D3DBinding &d3d_binding, VulkanBinding &vulkan_binding) override\n\t{\n\t\tvulkan_binding = {};\n\t\tvulkan_binding.descriptor_set = d3d_binding.register_space;\n\t\tvulkan_binding.binding = d3d_binding.register_index;\n\t\treturn true;\n\t}\n\n\tbool remap_uav(const D3DUAVBinding &d3d_binding, VulkanUAVBinding &vulkan_binding) override\n\t{\n\t\tvulkan_binding = {};\n\t\tvulkan_binding.buffer_binding.descriptor_set = d3d_binding.binding.register_space;\n\t\tvulkan_binding.buffer_binding.binding = d3d_binding.binding.register_index;\n\n\t\tif (d3d_binding.binding.kind == DXIL::ResourceKind::StructuredBuffer ||\n\t\t    d3d_binding.binding.kind == DXIL::ResourceKind::RawBuffer)\n\t\t\tvulkan_binding.buffer_binding.descriptor_type = VulkanDescriptorType::SSBO;\n\n\t\tif (d3d_binding.counter)\n\t\t{\n\t\t\tvulkan_binding.counter_binding.descriptor_set = d3d_binding.binding.register_space;\n\t\t\tvulkan_binding.counter_binding.binding = d3d_binding.binding.register_index;\n\t\t\tvulkan_binding.counter_binding.descriptor_type = VulkanDescriptorType::TexelBuffer;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tbool remap_cbv(const D3DBinding &d3d_binding, VulkanCBVBinding &vulkan_binding) override\n\t{\n\t\tvulkan_binding = {};\n\t\tvulkan_binding.buffer.descriptor_set = d3d_binding.register_space;\n\t\tvulkan_binding.buffer.binding = d3d_binding.register_index;\n\t\treturn true;\n\t}\n\n\tbool remap_vertex_input(const D3DStageIO &d3d_input, VulkanStageIO &vulkan_location) override\n\t{\n\t\tvulkan_location = {};\n\t\tvulkan_location.location = d3d_input.start_row;\n\t\treturn true;\n\t}\n\n\tbool remap_stream_output(const D3DStreamOutput &, VulkanStreamOutput &vk_output) override\n\t{\n\t\tvk_output = {};\n\t\treturn true;\n\t}\n\n\tbool remap_stage_input(const D3DStageIO &d3d_input, VulkanStageIO &vk_input) override\n\t{\n\t\treturn true;\n\t}\n\n\tbool remap_stage_output(const D3DStageIO &d3d_output, VulkanStageIO &vk_output) override\n\t{\n\t\treturn true;\n\t}\n\n\tunsigned get_root_constant_word_count() override\n\t{\n\t\treturn 0;\n\t}\n\n\tunsigned get_root_descriptor_count() override\n\t{\n\t\treturn 0;\n\t}\n\n\tbool has_nontrivial_stage_input_remapping() override\n\t{\n\t\treturn false;\n\t}\n};\n\nstatic std::string convert_to_asm(const void *code, size_t size)\n{\n\tspvtools::SpirvTools tools(SPV_ENV_VULKAN_1_3);\n\ttools.SetMessageConsumer([](spv_message_level_t, const char *, const spv_position_t &, const char *message) {\n\t\t                         LOGE(\"SPIRV-Tools message: %s\\n\", message);\n\t                         });\n\n\tstd::string str;\n\tif (!tools.Disassemble(static_cast<const uint32_t *>(code), size / sizeof(uint32_t), &str,\n\t                       SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES |\n\t                       SPV_BINARY_TO_TEXT_OPTION_INDENT |\n\t                       SPV_BINARY_TO_TEXT_OPTION_NESTED_INDENT))\n\t\treturn \"\";\n\telse\n\t\treturn str;\n}\n\nstatic bool validate_spirv(const void *code, size_t size)\n{\n\tspvtools::SpirvTools tools(SPV_ENV_VULKAN_1_3);\n\tbool expected_failure = false;\n\tbool unexpected_failure = false;\n\n\ttools.SetMessageConsumer([&](spv_message_level_t, const char *, const spv_position_t &, const char *message) {\n\t\t                         if (strstr(message, \"08721\") || strstr(message, \"08722\"))\n\t\t                         {\n\t\t\t                         LOGW(\"SPIRV-Tools message expected failure: %s\\n\", message);\n\t\t\t                         expected_failure = true;\n\t\t                         }\n\t\t                         else\n\t\t                         {\n\t\t\t                         LOGE(\"SPIRV-Tools message: %s\\n\", message);\n\t\t\t                         unexpected_failure = true;\n\t\t                         }\n\t                         });\n\n\tspvtools::ValidatorOptions opts;\n\topts.SetScalarBlockLayout(true);\n\treturn tools.Validate(static_cast<const uint32_t *>(code), size / sizeof(uint32_t), opts) ||\n\t       (expected_failure && !unexpected_failure);\n}\n\nstatic std::string convert_to_glsl(const void *code, size_t size)\n{\n\tstd::string ret;\n\tspvc_context context;\n\tif (spvc_context_create(&context) != SPVC_SUCCESS)\n\t\treturn ret;\n\n\tspvc_parsed_ir ir;\n\tif (spvc_context_parse_spirv(context, static_cast<const SpvId *>(code), size / sizeof(uint32_t), &ir) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler compiler;\n\tif (spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler_options opts;\n\tif (spvc_compiler_create_compiler_options(compiler, &opts) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler_options_set_bool(opts, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_FALSE);\n\tspvc_compiler_options_set_uint(opts, SPVC_COMPILER_OPTION_GLSL_VERSION, 460);\n\tspvc_compiler_options_set_bool(opts, SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS, SPVC_TRUE);\n\tspvc_compiler_install_compiler_options(compiler, opts);\n\n\tconst char *source;\n\tif (spvc_compiler_compile(compiler, &source) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tret = source;\n\ncleanup:\n\tspvc_context_destroy(context);\n\treturn ret;\n}\n\nstatic Vector<uint32_t> run_test(const char *name, ir::Builder &builder)\n{\n\tLOGI(\"Testing %s ...\\n\", name);\n\n\tLLVMBCParser parser;\n\tif (!parser.parseDXBC(builder))\n\t{\n\t\tLOGE(\"Failed to parse.\\n\");\n\t\treturn {};\n\t}\n\n\tSPIRVModule module;\n\tConverter converter(parser, nullptr, module);\n\tRemapper remapper;\n\n\tOptionSSBOAlignment align;\n\talign.alignment = 1;\n\tconverter.add_option(align);\n\n\tOptionShaderDemoteToHelper demote;\n\tdemote.supported = true;\n\tconverter.add_option(demote);\n\n#if 1\n\tOptionMinPrecisionNative16Bit native_16bit;\n\tnative_16bit.enabled = true;\n\tconverter.add_option(native_16bit);\n#endif\n\n\tconverter.set_resource_remapping_interface(&remapper);\n\tauto entry = converter.convert_entry_point();\n\n\tif (!entry.entry.entry)\n\t{\n\t\tLOGE(\"Failed to convert function.\\n\");\n\t\treturn {};\n\t}\n\n\t{\n\t\tCFGStructurizer structurizer(entry.entry.entry, *entry.node_pool, module);\n\t\tif (entry.entry.is_structured)\n\t\t\tstructurizer.run_trivial();\n\t\telse\n\t\t\tstructurizer.run();\n\t\tmodule.emit_entry_point_function_body(structurizer);\n\t}\n\n\tfor (auto &leaf : entry.leaf_functions)\n\t{\n\t\tif (!leaf.entry)\n\t\t{\n\t\t\tLOGE(\"Leaf function is nullptr!\\n\");\n\t\t\treturn {};\n\t\t}\n\t\tCFGStructurizer structurizer(leaf.entry, *entry.node_pool, module);\n\t\tmodule.set_entry_build_point(leaf.func);\n\n\t\tif (leaf.is_structured)\n\t\t\tstructurizer.run_trivial();\n\t\telse\n\t\t\tstructurizer.run();\n\n\t\tmodule.emit_leaf_function_body(leaf.func, structurizer);\n\t}\n\n\tVector<uint32_t> spirv;\n\tif (!module.finalize_spirv(spirv))\n\t{\n\t\tLOGE(\"Failed to finalize SPIR-V.\\n\");\n\t\treturn {};\n\t}\n\n#if 1\n\tif (!validate_spirv(spirv.data(), spirv.size() * sizeof(uint32_t)))\n\t{\n\t\tLOGE(\"Failed to validate SPIR-V.\\n\");\n\t\treturn {};\n\t}\n#endif\n\n\treturn spirv;\n}\n\nint main(int argc, char **argv)\n{\n\tauto tests = test_api::enumerateTests(nullptr);\n\n\tfor (auto &test : tests)\n\t{\n#if 0\n\t\tif (test.name != \"test_arithmetic_fp32_special\")\n\t\t\tcontinue;\n#endif\n\n\t\tbegin_thread_allocator_context();\n\t\t{\n\t\t\tauto spirv = run_test(test.name.c_str(), test.builder);\n\n\t\t\tif (spirv.empty())\n\t\t\t{\n\t\t\t\tLOGE(\"Failure to convert test to SPIR-V!\\n\");\n\t\t\t\treturn EXIT_FAILURE;\n\t\t\t}\n\n\t\t\tauto disasm = convert_to_asm(spirv.data(), spirv.size() * sizeof(uint32_t));\n\t\t\tauto glsl = convert_to_glsl(spirv.data(), spirv.size() * sizeof(uint32_t));\n\n\t\t\tFILE *file_asm = nullptr;\n\t\t\tFILE *file_glsl = nullptr;\n\n\t\t\tif (argc == 2)\n\t\t\t{\n\t\t\t\tstd::string path = argv[1];\n\t\t\t\tpath += '/';\n\t\t\t\tpath += test.name;\n\n\t\t\t\tauto path_asm = path + \".asm\";\n\t\t\t\tauto path_glsl = path + \".glsl\";\n\n\t\t\t\tfile_asm = fopen(path_asm.c_str(), \"w\");\n\t\t\t\tfile_glsl = fopen(path_glsl.c_str(), \"w\");\n\t\t\t\tif (!file_asm || !file_glsl)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to open file \\\"%s\\\" and \\\"%s\\\"\\n\",\n\t\t\t\t\t     path_asm.c_str(), path_glsl.c_str());\n\t\t\t\t\treturn EXIT_FAILURE;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (file_asm && file_glsl)\n\t\t\t{\n\t\t\t\tfprintf(file_asm, \"SPIR-V:\\n%s\\n\", disasm.c_str());\n\t\t\t\tfprintf(file_glsl, \"GLSL:\\n%s\\n\", glsl.c_str());\n\t\t\t\tfclose(file_asm);\n\t\t\t\tfclose(file_glsl);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tLOGI(\"SPIR-V:\\n%s\\n\", disasm.c_str());\n\t\t\t\tLOGI(\"GLSL:\\n%s\\n\", glsl.c_str());\n\t\t\t}\n\t\t}\n\t\tend_thread_allocator_context();\n\t}\n}"
  },
  {
    "path": "dxil-disasm.py",
    "content": "#!/usr/bin/env python3\n\n# Copyright (c) 2019-2023 Hans-Kristian Arntzen for Valve Corporation\n#\n# SPDX-License-Identifier: MIT\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n# \n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n# \n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nimport sys\nimport os\nimport os.path\nimport subprocess\nimport argparse\nimport tempfile\nimport re\nimport multiprocessing\n\ndef disasm_shader_regex(input_file, args, regex):\n    f, path = tempfile.mkstemp(suffix = 'dxil')\n    f2, path2 = tempfile.mkstemp(suffix = 'dxil2')\n    os.close(f)\n    os.close(f2)\n    result = None\n\n    try:\n        dxil_extract_cmd = [args.dxil_extract, input_file, '--output']\n        p = subprocess.Popen(dxil_extract_cmd + [path, '--verbose'], stdout = subprocess.PIPE)\n        subprocess.check_call(dxil_extract_cmd + [path2, '--reflection'], stdout = subprocess.DEVNULL)\n        llvm_dis_cmd = [args.llvm_dis, '-o', '/dev/stdout']\n        main_pipe = subprocess.Popen(llvm_dis_cmd + [path], stdout = subprocess.PIPE)\n        refl_pipe = subprocess.Popen(llvm_dis_cmd + [path2], stdout = subprocess.PIPE)\n        lines_main = main_pipe.communicate()[0].decode()\n        lines_refl = refl_pipe.communicate()[0].decode()\n\n        if args.isolate:\n            allow = re.search(regex, lines_main + lines_refl)\n        else:\n            allow = True\n\n        if allow:\n            result = p.communicate()[0].decode()\n            result += '  DXIL:\\n'\n            for line in lines_main.splitlines():\n                if re.search(regex, line):\n                    result += '    ' + line + '\\n'\n            result += '  STAT:\\n'\n            for line in lines_refl.splitlines():\n                if re.search(regex, line):\n                    result += '    ' + line + '\\n'\n    except:\n        pass\n\n    os.remove(path)\n    os.remove(path2)\n    return result\n\ndef disasm_shader_plain(input_file, args, regex):\n    f, path = tempfile.mkstemp(suffix = 'dxil')\n    result = ''\n    try:\n        dxil_extract_cmd = [args.dxil_extract, '--verbose', input_file, '--output', path]\n        if args.reflect:\n            dxil_extract_cmd.append('--reflection')\n        p = subprocess.Popen(dxil_extract_cmd, stdout = subprocess.PIPE)\n        result += p.communicate()[0].decode()\n        llvm_dis_cmd = [args.llvm_dis, '-o', '/dev/stdout', path]\n        p = subprocess.Popen(llvm_dis_cmd, stdout = subprocess.PIPE)\n        result += p.communicate()[0].decode()\n    except:\n        pass\n\n    os.remove(path)\n    return result\n\ndef main():\n    parser = argparse.ArgumentParser(description = 'Script for disassembling DXIL.')\n    parser.add_argument('input',\n            help = 'File or folder containing shader files to convert.')\n    parser.add_argument('--output',\n            help = 'Path where LLVM asm is output.',\n            default = '/dev/stdout')\n    parser.add_argument('--dxil-extract',\n            help = 'Path to dxil-extract',\n            default = 'dxil-extract')\n    parser.add_argument('--llvm-dis',\n            help = 'Path to llvm-dis',\n            default = 'llvm-dis')\n    parser.add_argument('--reflect', action = 'store_true',\n            help = 'Use reflection section')\n    parser.add_argument('--isolate', action = 'store_true',\n            help = 'Isolate regex output to hits only')\n    parser.add_argument('--symbol-regex', type = str,\n            help = 'Grep disassemblies for a symbol')\n\n    args = parser.parse_args()\n    if not args.input:\n        sys.stderr.write('Need input shader.\\n')\n        sys.exit(1)\n    if not args.dxil_extract:\n        sys.stderr.write('Need dxil-extract path.\\n')\n        sys.exit(1)\n\n    if args.symbol_regex:\n        regex = re.compile(args.symbol_regex)\n    else:\n        regex = None\n\n    if os.path.isfile(args.input):\n        files = [args.input]\n    else:\n        files = []\n        for file in os.scandir(args.input):\n            if os.path.splitext(file.name)[1] == '.dxil':\n                files.append(os.path.join(args.input, file.name))\n\n    pool = multiprocessing.Pool(multiprocessing.cpu_count())\n    results = []\n    counter = 0\n\n    with open(args.output, 'w') as f:\n        for input_file in files:\n            results.append(pool.apply_async(disasm_shader_regex if regex else disasm_shader_plain,\n                                            args = (input_file, args, regex)))\n\n        for res in results:\n            lines = res.get()\n            counter += 1\n            print('Progress {} / {}'.format(counter, len(files)))\n            if lines is not None:\n                f.writelines(lines)\n                f.writelines('\\n\\n')\n\nif __name__ == '__main__':\n    main()\n\n"
  },
  {
    "path": "dxil.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace DXIL\n{\nconstexpr size_t ContainerHashSize = 16;\n\nstruct ContainerHeader\n{\n\tuint32_t header_fourcc;\n\tuint8_t digest[ContainerHashSize];\n\tuint16_t major_version;\n\tuint16_t minor_version;\n\tuint32_t container_size_in_bytes;\n\tuint32_t part_count;\n};\n\nstruct PartHeader\n{\n\tuint32_t part_fourcc;\n\tuint32_t part_size;\n};\n\nstruct ProgramHeader\n{\n\tuint32_t program_version;\n\tuint32_t size_in_uint32;\n\tuint32_t dxil_magic;\n\tuint32_t dxil_version;\n\tuint32_t bitcode_offset;\n\tuint32_t bitcode_size;\n};\n\nstruct IOElement\n{\n\tdxil_spv::String semantic_name;\n\tuint32_t stream_index;\n\tuint32_t semantic_index;\n\tuint32_t system_value_semantic;\n\tuint32_t component_type;\n\tuint32_t register_index;\n\tuint32_t mask;\n\tuint32_t min_precision;\n};\n\nconstexpr uint32_t fourcc(uint32_t a, uint32_t b, uint32_t c, uint32_t d)\n{\n\treturn a | (b << 8) | (c << 16) | (d << 24);\n}\n\nenum class FourCC : uint32_t\n{\n\tContainer = fourcc('D', 'X', 'B', 'C'),\n\tResourceDef = fourcc('R', 'D', 'E', 'F'),\n\tInputSignature = fourcc('I', 'S', 'G', '1'),\n\tOutputSignature = fourcc('O', 'S', 'G', '1'),\n\tPatchConstantSignature = fourcc('P', 'S', 'G', '1'),\n\tShaderStatistics = fourcc('S', 'T', 'A', 'T'),\n\tShaderDebugInfoDXIL = fourcc('I', 'L', 'D', 'B'),\n\tShaderDebugName = fourcc('I', 'L', 'D', 'N'),\n\tFeatureInfo = fourcc('S', 'F', 'I', '0'),\n\tPrivateData = fourcc('P', 'R', 'I', 'V'),\n\tRootSignature = fourcc('R', 'T', 'S', '0'),\n\tDXIL = fourcc('D', 'X', 'I', 'L'),\n\tSHDR = fourcc('S', 'H', 'D', 'R'),\n\tSHEX = fourcc('S', 'H', 'E', 'X'),\n\tPipelineStateValidation = fourcc('P', 'S', 'V', '0'),\n\tRuntimeData = fourcc('R', 'D', 'A', 'T'),\n\tShaderHash = fourcc('H', 'A', 'S', 'H')\n};\n\nenum class RuntimeDataPartType : uint32_t\n{\n\tInvalid = 0,\n\tStringBuffer = 1,\n\tIndexArrays = 2,\n\tResourceTable = 3,\n\tFunctionTable = 4,\n\tRawBytes = 5,\n\tSubobjectTable = 6\n};\n\nenum class SubobjectKind : uint32_t\n{\n\tStateObjectConfig = 0,\n\tGlobalRootSignature = 1,\n\tLocalRootSignature = 2,\n\tSubobjectToExportsAssociation = 8,\n\tRaytracingShaderConfig = 9,\n\tRaytracingPipelineConfig = 10,\n\tHitGroup = 11,\n\tRaytracingPipelineConfig1 = 12\n};\n\nenum class HitGroupType : uint32_t\n{\n\tTriangle = 0,\n\tProcedural = 1\n};\n\nenum class ComponentType : uint8_t\n{\n\tInvalid = 0,\n\tI1,\n\tI16,\n\tU16,\n\tI32,\n\tU32,\n\tI64,\n\tU64,\n\tF16,\n\tF32,\n\tF64,\n\tSNormF16,\n\tUNormF16,\n\tSNormF32,\n\tUNormF32,\n\tSNormF64,\n\tUNormF64,\n\tInternalU8 = 0xff // Doesn't exist, but dummy value to signal 8-bit SSBO\n};\n\nenum class InterpolationMode : uint8_t\n{\n\tUndefined,\n\tConstant,\n\tLinear,\n\tLinearCentroid,\n\tLinearNoperspective,\n\tLinearNoperspectiveCentroid,\n\tLinearSample,\n\tLinearNoperspectiveSample,\n\tInvalid\n};\n\nenum class Semantic : uint8_t\n{\n\tUser,\n\tVertexID,\n\tInstanceID,\n\tPosition,\n\tRenderTargetArrayIndex,\n\tViewPortArrayIndex,\n\tClipDistance,\n\tCullDistance,\n\tOutputControlPointID,\n\tDomainLocation,\n\tPrimitiveID,\n\tGSInstanceID,\n\tSampleIndex,\n\tIsFrontFace,\n\tCoverage,\n\tInnerCoverage,\n\tTarget,\n\tDepth,\n\tDepthLessEqual,\n\tDepthGreaterEqual,\n\tStencilRef,\n\tDispatchThreadID,\n\tGroupID,\n\tGroupIndex,\n\tGroupThreadID,\n\tTessFactor,\n\tInsideTessFactor,\n\tViewID,\n\tBarycentrics,\n\tShadingRate,\n\tCullPrimitive,\n\n\t// Fake semantics to disambiguate semantics based on interpolation flags.\n\tInternalBarycentricsNoPerspective = 255\n};\n\nenum class ResourceType : uint8_t\n{\n\tSRV = 0,\n\tUAV = 1,\n\tCBV = 2,\n\tSampler = 3\n};\n\nenum class ResourceKind : uint8_t\n{\n\tInvalid = 0,\n\tTexture1D,\n\tTexture2D,\n\tTexture2DMS,\n\tTexture3D,\n\tTextureCube,\n\tTexture1DArray,\n\tTexture2DArray,\n\tTexture2DMSArray,\n\tTextureCubeArray,\n\tTypedBuffer,\n\tRawBuffer,\n\tStructuredBuffer,\n\tCBuffer,\n\tSampler,\n\tTBuffer,\n\tRTAccelerationStructure,\n\tFeedbackTexture2D,\n\tFeedbackTexture2DArray\n};\n\nenum class Op : unsigned\n{\n\t// Input output\n\tTempRegLoad = 0,\n\tTempRegStore = 1,\n\tMinPrecXRegLoad = 2,\n\tMinPrecXRegStore = 3,\n\tLoadInput = 4,\n\tStoreOutput = 5,\n\tFAbs = 6,\n\tSaturate = 7,\n\tIsNan = 8,\n\tIsInf = 9,\n\tIsFinite = 10,\n\tIsNormal = 11,\n\tCos = 12,\n\tSin = 13,\n\tTan = 14,\n\tAcos = 15,\n\tAsin = 16,\n\tAtan = 17,\n\tHcos = 18,\n\tHsin = 19,\n\tHtan = 20,\n\tExp = 21,\n\tFrc = 22,\n\tLog = 23,\n\tSqrt = 24,\n\tRsqrt = 25,\n\tRound_ne = 26,\n\tRound_ni = 27,\n\tRound_pi = 28,\n\tRound_z = 29,\n\tBfrev = 30,\n\tCountbits = 31,\n\tFirstbitLo = 32,\n\tFirstbitHi = 33,\n\tFirstbitSHi = 34,\n\tFMax = 35,\n\tFMin = 36,\n\tIMax = 37,\n\tIMin = 38,\n\tUMax = 39,\n\tUMin = 40,\n\tIMul = 41,\n\tUMul = 42,\n\tUDiv = 43,\n\tUAddc = 44,\n\tUSubb = 45,\n\tFMad = 46,\n\tFma = 47,\n\tIMad = 48,\n\tUMad = 49,\n\tMsad = 50,\n\tIbfe = 51,\n\tUbfe = 52,\n\tBfi = 53,\n\tDot2 = 54,\n\tDot3 = 55,\n\tDot4 = 56,\n\tCreateHandle = 57,\n\tCBufferLoad = 58,\n\tCBufferLoadLegacy = 59,\n\tSample = 60,\n\tSampleBias = 61,\n\tSampleLevel = 62,\n\tSampleGrad = 63,\n\tSampleCmp = 64,\n\tSampleCmpLevelZero = 65,\n\tTextureLoad = 66,\n\tTextureStore = 67,\n\tBufferLoad = 68,\n\tBufferStore = 69,\n\tBufferUpdateCounter = 70,\n\tCheckAccessFullyMapped = 71,\n\tGetDimensions = 72,\n\tTextureGather = 73,\n\tTextureGatherCmp = 74,\n\tTexture2DMSGetSamplePosition = 75,\n\tRenderTargetGetSamplePosition = 76,\n\tRenderTargetGetSampleCount = 77,\n\tAtomicBinOp = 78,\n\tAtomicCompareExchange = 79,\n\tBarrier = 80,\n\tCalculateLOD = 81,\n\tDiscard = 82,\n\tDerivCoarseX = 83,\n\tDerivCoarseY = 84,\n\tDerivFineX = 85,\n\tDerivFineY = 86,\n\tEvalSnapped = 87,\n\tEvalSampleIndex = 88,\n\tEvalCentroid = 89,\n\tSampleIndex = 90,\n\tCoverage = 91,\n\tInnerCoverage = 92,\n\tThreadId = 93,\n\tGroupId = 94,\n\tThreadIdInGroup = 95,\n\tFlattenedThreadIdInGroup = 96,\n\tEmitStream = 97,\n\tCutStream = 98,\n\tEmitThenCutStream = 99,\n\tGSInstanceID = 100,\n\tMakeDouble = 101,\n\tSplitDouble = 102,\n\tLoadOutputControlPoint = 103,\n\tLoadPatchConstant = 104,\n\tDomainLocation = 105,\n\tStorePatchConstant = 106,\n\tOutputControlPointID = 107,\n\tPrimitiveID = 108,\n\tCycleCounterLegacy = 109,\n\tWaveIsFirstLane = 110,\n\tWaveGetLaneIndex = 111,\n\tWaveGetLaneCount = 112,\n\tWaveAnyTrue = 113,\n\tWaveAllTrue = 114,\n\tWaveActiveAllEqual = 115,\n\tWaveActiveBallot = 116,\n\tWaveReadLaneAt = 117,\n\tWaveReadLaneFirst = 118,\n\tWaveActiveOp = 119,\n\tWaveActiveBit = 120,\n\tWavePrefixOp = 121,\n\tQuadReadLaneAt = 122,\n\tQuadOp = 123,\n\tBitcastI16toF16 = 124,\n\tBitcastF16toI16 = 125,\n\tBitcastI32toF32 = 126,\n\tBitcastF32toI32 = 127,\n\tBitcastI64toF64 = 128,\n\tBitcastF64toI64 = 129,\n\tLegacyF32ToF16 = 130,\n\tLegacyF16ToF32 = 131,\n\tLegacyDoubleToFloat = 132,\n\tLegacyDoubleToSInt32 = 133,\n\tLegacyDoubleToUInt32 = 134,\n\tWaveAllBitCount = 135,\n\tWavePrefixBitCount = 136,\n\tAttributeAtVertex = 137,\n\tViewID = 138,\n\tRawBufferLoad = 139,\n\tRawBufferStore = 140,\n\tInstanceID = 141,\n\tInstanceIndex = 142,\n\tHitKind = 143,\n\tRayFlags = 144,\n\tDispatchRaysIndex = 145,\n\tDispatchRaysDimensions = 146,\n\tWorldRayOrigin = 147,\n\tWorldRayDirection = 148,\n\tObjectRayOrigin = 149,\n\tObjectRayDirection = 150,\n\tObjectToWorld = 151,\n\tWorldToObject = 152,\n\tRayTMin = 153,\n\tRayTCurrent = 154,\n\tIgnoreHit = 155,\n\tAcceptHitAndEndSearch = 156,\n\tTraceRay = 157,\n\tReportHit = 158,\n\tCallShader = 159,\n\tCreateHandleForLib = 160,\n\tPrimitiveIndex = 161,\n\tDot2AddHalf = 162,\n\tDot4AddI8Packed = 163,\n\tDot4AddU8Packed = 164,\n\tWaveMatch = 165,\n\tWaveMultiPrefixOp = 166,\n\tWaveMultiPrefixBitCount = 167,\n\tSetMeshOutputCounts = 168,\n\tEmitIndices = 169,\n\tGetMeshPayload = 170,\n\tStoreVertexOutput = 171,\n\tStorePrimitiveOutput = 172,\n\tDispatchMesh = 173,\n\tWriteSamplerFeedback = 174,\n\tWriteSamplerFeedbackBias = 175,\n\tWriteSamplerFeedbackLevel = 176,\n\tWriteSamplerFeedbackGrad = 177,\n\tAllocateRayQuery = 178,\n\tRayQuery_TraceRayInline = 179,\n\tRayQuery_Proceed = 180,\n\tRayQuery_Abort = 181,\n\tRayQuery_CommitNonOpaqueTriangleHit = 182,\n\tRayQuery_CommitProceduralPrimitiveHit = 183,\n\tRayQuery_CommittedStatus = 184,\n\tRayQuery_CandidateType = 185,\n\tRayQuery_CandidateObjectToWorld3x4 = 186,\n\tRayQuery_CandidateWorldToObject3x4 = 187,\n\tRayQuery_CommittedObjectToWorld3x4 = 188,\n\tRayQuery_CommittedWorldToObject3x4 = 189,\n\tRayQuery_CandidateProceduralPrimitiveNonOpaque = 190,\n\tRayQuery_CandidateTriangleFrontFace = 191,\n\tRayQuery_CommittedTriangleFrontFace = 192,\n\tRayQuery_CandidateTriangleBarycentrics = 193,\n\tRayQuery_CommittedTriangleBarycentrics = 194,\n\tRayQuery_RayFlags = 195,\n\tRayQuery_WorldRayOrigin = 196,\n\tRayQuery_WorldRayDirection = 197,\n\tRayQuery_RayTMin = 198,\n\tRayQuery_CandidateTriangleRayT = 199,\n\tRayQuery_CommittedRayT = 200,\n\tRayQuery_CandidateInstanceIndex = 201,\n\tRayQuery_CandidateInstanceID = 202,\n\tRayQuery_CandidateGeometryIndex = 203,\n\tRayQuery_CandidatePrimitiveIndex = 204,\n\tRayQuery_CandidateObjectRayOrigin = 205,\n\tRayQuery_CandidateObjectRayDirection = 206,\n\tRayQuery_CommittedInstanceIndex = 207,\n\tRayQuery_CommittedInstanceID = 208,\n\tRayQuery_CommittedGeometryIndex = 209,\n\tRayQuery_CommittedPrimitiveIndex = 210,\n\tRayQuery_CommittedObjectRayOrigin = 211,\n\tRayQuery_CommittedObjectRayDirection = 212,\n\tRayQuery_GeometryIndex = 213,\n\tRayQuery_CandidateInstanceContributionToHitGroupIndex = 214,\n\tRayQuery_CommittedInstanceContributionToHitGroupIndex = 215,\n\tAnnotateHandle = 216,\n\tCreateHandleFromBinding = 217,\n\tCreateHandleFromHeap = 218,\n\tUnpack4x8 = 219,\n\tPack4x8 = 220,\n\tIsHelperLane = 221,\n\tQuadVote = 222,\n\tTextureGatherRaw = 223,\n\tSampleCmpLevel = 224,\n\tTextureStoreSample = 225,\n\tWaveMatrix_Annotate = 226,\n\tWaveMatrix_Depth = 227,\n\tWaveMatrix_Fill = 228,\n\tWaveMatrix_LoadRawBuf = 229,\n\tWaveMatrix_LoadGroupShared = 230,\n\tWaveMatrix_StoreRawBuf = 231,\n\tWaveMatrix_StoreGroupShared = 232,\n\tWaveMatrix_Multiply = 233,\n\tWaveMatrix_MultiplyAccumulate = 234,\n\tWaveMatrix_ScalarOp = 235,\n\tWaveMatrix_SumAccumulate = 236,\n\tWaveMatrix_Add = 237,\n\tAllocateNodeOutputRecords = 238,\n\tGetNodeRecordPtr = 239,\n\tIncrementOutputCount = 240,\n\tOutputComplete = 241,\n\tGetInputRecordCount = 242,\n\tFinishedCrossGroupSharing = 243,\n\tBarrierByMemoryType = 244,\n\tBarrierByMemoryHandle = 245,\n\tBarrierByNodeRecordHandle = 246,\n\tCreateNodeOutputHandle = 247,\n\tIndexNodeHandle = 248,\n\tAnnotateNodeHandle = 249,\n\tCreateNodeInputRecordHandle = 250,\n\tAnnotateNodeRecordHandle = 251,\n\tNodeOutputIsValid = 252,\n\tGetRemainingRecursionLevels = 253,\n\tSampleCmpGrad = 254,\n\tSampleCmpBias = 255,\n\tStartVertexLocation = 256,\n\tStartInstanceLocation = 257,\n\n\t// Internal extensions for where there is impedance mismatch\n\tExtendedDeriv,\n\tExtendedCalculateLOD,\n\tExtendedGetDimensions,\n\tExtendedFClamp,\n\tExtendedIClamp,\n\tExtendedUClamp,\n\tExtendedLegacyF32ToF16,\n\tExtendedLegacyF16ToF32,\n\tExtendedIAbs,\n\tExtendedEvalSnapped,\n\tExtendedSpirvIbfe,\n\tExtendedSpirvUbfe,\n\tExtendedSpirvBfi,\n\tExtendedSpirvFindLSB,\n\tExtendedSpirvIFindMSB,\n\tExtendedSpirvUFindMSB,\n\tExtendedSpirvIAddCarry,\n\tExtendedSpirvISubBorrow,\n\tExtendedSpirvSMulExtended,\n\tExtendedSpirvUMulExtended,\n\tExtendedSpirvLoadInput,\n\tExtendedSpirvControlPointCountIn,\n\tExtendedPow,\n\n\tCount\n};\n\nenum class AtomicBinOp : uint8_t\n{\n\tIAdd = 0,\n\tAnd = 1,\n\tOr = 2,\n\tXor = 3,\n\tIMin = 4,\n\tIMax = 5,\n\tUMin = 6,\n\tUMax = 7,\n\tExchange = 8,\n\n\t// Internal extensions for custom IR\n\t// Load = optimized or/add of 0\n\t// Store = optimized exchange\n\tSub = 200,\n\tLoad,\n\tStore,\n\tInvalid = 255\n};\n\nenum class ShaderPropertyTag : uint8_t\n{\n\tShaderFlags = 0,\n\tGSState = 1,\n\tDSState = 2,\n\tHSState = 3,\n\tNumThreads = 4,\n\tAutoBindingSpace = 5,\n\tRayPayloadSize = 6,\n\tRayAttribSizeTag = 7,\n\tShaderKind = 8,\n\tMSState = 9,\n\tASState = 10,\n\tWaveSize = 11,\n\tNodeLaunchType = 13,\n\tNodeIsProgramEntry = 14,\n\tNodeID = 15,\n\tNodeLocalRootArgumentsTableIndex = 16,\n\tNodeShareInputOf = 17,\n\tNodeDispatchGrid = 18,\n\tNodeMaxRecursionDepth = 19,\n\tNodeInputs = 20,\n\tNodeOutputs = 21,\n\tNodeMaxDispatchGrid = 22,\n\tRangedWaveSize = 23\n};\n\nenum class GSStageOutTags : uint32_t\n{\n\tStream = 0,\n\tInvalid\n};\n\nenum BarrierModeBits : uint8_t\n{\n\tSyncThreadGroup = 1 << 0,\n\tAccessUAVGlobal = 1 << 1,\n\tAccessUAVThreadGroup = 1 << 2,\n\tAccessGroupShared = 1 << 3\n};\n\nenum class AddressSpace : uint8_t\n{\n\tThread = 0,\n\tGroupShared = 3,\n\tPhysicalNodeIO = 6,\n\tInvalid\n};\n\nenum class InputPrimitive : uint8_t\n{\n\tUndefined = 0,\n\tPoint = 1,\n\tLine = 2,\n\tTriangle = 3,\n\tLineWithAdjacency = 6,\n\tTriangleWithAdjaceny = 7\n};\n\nenum class PrimitiveTopology : uint8_t\n{\n\tUndefined = 0,\n\tPointList = 1,\n\tLineList = 2,\n\tLineStrip = 3,\n\tTriangleList = 4,\n\tTriangleStrip = 5\n};\n\nenum class TessellatorDomain : uint8_t\n{\n\tUndefined = 0,\n\tIsoLine = 1,\n\tTri = 2,\n\tQuad = 3\n};\n\nenum class TessellatorOutputPrimitive : uint8_t\n{\n\tUndefined = 0,\n\tPoint = 1,\n\tLine = 2,\n\tTriangleCW = 3,\n\tTriangleCCW = 4\n};\n\nenum class TessellatorPartitioning : uint8_t\n{\n\tUndefined = 0,\n\tInteger = 1,\n\tPow2 = 2,\n\tFractionalOdd = 3,\n\tFractionalEven = 4\n};\n\nenum class MeshOutputTopology\n{\n\tUndefined = 0,\n\tLine = 1,\n\tTriangle = 2\n};\n\nenum ShaderFlag\n{\n\tShaderFlagEarlyDepthStencil = 1 << 3,\n\tShaderFlagNativeLowPrecision = 1 << 23\n};\n\nenum class WaveOpKind : uint8_t\n{\n\tSum = 0,\n\tProduct = 1,\n\tMin = 2,\n\tMax = 3\n};\n\nenum class WaveBitOpKind : uint8_t\n{\n\tAnd = 0,\n\tOr = 1,\n\tXor = 2\n};\n\nenum class WaveMultiPrefixOpKind : uint8_t\n{\n\tSum = 0,\n\tAnd = 1,\n\tOr = 2,\n\tXor = 3,\n\tProduct = 4\n};\n\nenum class SignedOpKind : uint8_t\n{\n\tSigned = 0,\n\tUnsigned = 1\n};\n\nenum class ShaderKind\n{\n\tPixel = 0,\n\tVertex,\n\tGeometry,\n\tHull,\n\tDomain,\n\tCompute,\n\tLibrary,\n\tRayGeneration,\n\tIntersection,\n\tAnyHit,\n\tClosestHit,\n\tMiss,\n\tCallable,\n\tMesh,\n\tAmplification,\n\tNode,\n\tInvalid\n};\n\nenum class NodeLaunchType\n{\n\tInvalid = 0,\n\tBroadcasting = 1,\n\tCoalescing = 2,\n\tThread = 3\n};\n\nenum class NodeMetadataTag\n{\n\tNodeOutputID = 0,\n\tNodeIOFlags = 1,\n\tNodeRecordType = 2,\n\tNodeMaxRecords = 3,\n\tNodeMaxRecordsSharedWith = 4,\n\tNodeOutputArraySize = 5,\n\tNodeAllowSparseNodes = 6\n};\n\nenum NodeIOFlagBits\n{\n\tNodeIOInputBit = 0x1,\n\tNodeIOOutputBit = 0x2,\n\tNodeIOReadWriteBit = 0x4,\n\tNodeIOEmptyRecordBit = 0x8,\n\tNodeIONodeArrayBit = 0x10,\n\tNodeIOThreadRecordBit = 0x20,\n\tNodeIOGroupRecordBit = 0x40,\n\tNodeIODispatchRecordBit = 0x60,\n\tRecordGranularityMask = 0x60,\n\tNodeIOKindMask = 0x7f,\n\tNodeIOTrackRWInputSharingBit = 0x100,\n\tNodeIOGloballyCoherentBit = 0x200,\n\tNodeFlagsMask = 0x100,\n\tRecordFlagsMask = 0x200\n};\n\nenum class NodeIOKind\n{\n\tInvalid = 0,\n\tEmptyInput = NodeIOEmptyRecordBit | NodeIOInputBit,\n\tNodeOutput = NodeIOReadWriteBit | NodeIOOutputBit,\n\tNodeOutputArray = NodeIOReadWriteBit | NodeIOOutputBit | NodeIONodeArrayBit,\n\tEmptyOutput = NodeIOEmptyRecordBit | NodeIOOutputBit,\n\tEmptyOutputArray = NodeIOEmptyRecordBit | NodeIOOutputBit | NodeIONodeArrayBit,\n\n\t// Records:\n\tDispatchNodeInputRecord = NodeIOInputBit | NodeIODispatchRecordBit,\n\tGroupNodeInputRecords   = NodeIOInputBit | NodeIOGroupRecordBit,\n\tThreadNodeInputRecord   = NodeIOInputBit | NodeIOThreadRecordBit,\n\n\tRWDispatchNodeInputRecord = NodeIOReadWriteBit | NodeIOInputBit | NodeIODispatchRecordBit,\n\tRWGroupNodeInputRecords   = NodeIOReadWriteBit | NodeIOInputBit | NodeIOGroupRecordBit,\n\tRWThreadNodeInputRecord   = NodeIOReadWriteBit | NodeIOInputBit | NodeIOThreadRecordBit,\n\n\tGroupNodeOutputRecords  = NodeIOReadWriteBit | NodeIOOutputBit | NodeIOGroupRecordBit,\n\tThreadNodeOutputRecords = NodeIOReadWriteBit | NodeIOOutputBit | NodeIOThreadRecordBit\n};\n\nenum MemoryTypeFlagBits\n{\n\tMemoryTypeUavBit = 0x1,\n\tMemoryTypeGroupSharedBit = 0x2,\n\tMemoryTypeNodeInputBit = 0x4,\n\tMemoryTypeNodeOutputBit = 0x8,\n\tMemoryTypeAllBits = 0xf\n};\n\nenum BarrierSemanticsFlagBits\n{\n\tGroupSyncBit = 0x1,\n\tGroupScopeBit = 0x2,\n\tDeviceScopeBit = 0x4\n};\n} // namespace DXIL\n"
  },
  {
    "path": "dxil_converter.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"opcodes/converter_impl.hpp\"\n#include \"opcodes/opcodes_dxil_builtins.hpp\"\n#include \"opcodes/opcodes_llvm_builtins.hpp\"\n#include \"opcodes/dxil/dxil_common.hpp\"\n#include \"opcodes/dxil/dxil_workgraph.hpp\"\n#include \"opcodes/dxil/dxil_geometry.hpp\"\n\n#include \"dxil_converter.hpp\"\n#include \"logging.hpp\"\n#include \"node.hpp\"\n#include \"node_pool.hpp\"\n#include \"spirv_module.hpp\"\n\n#include <utility>\n#include <algorithm>\n\nnamespace dxil_spv\n{\nConverter::Converter(LLVMBCParser &bitcode_parser_, LLVMBCParser *bitcode_reflection_parser_, SPIRVModule &module_)\n{\n\timpl = std::make_unique<Impl>(bitcode_parser_, bitcode_reflection_parser_, module_);\n}\n\nConverter::~Converter()\n{\n}\n\nvoid Converter::add_local_root_constants(uint32_t register_space, uint32_t register_index, uint32_t num_words)\n{\n\tLocalRootSignatureEntry entry = {};\n\tentry.type = LocalRootSignatureType::Constants;\n\tentry.constants.num_words = num_words;\n\tentry.constants.register_space = register_space;\n\tentry.constants.register_index = register_index;\n\timpl->local_root_signature.push_back(entry);\n}\n\nvoid Converter::add_local_root_descriptor(ResourceClass type, uint32_t register_space, uint32_t register_index)\n{\n\tLocalRootSignatureEntry entry = {};\n\tentry.type = LocalRootSignatureType::Descriptor;\n\tentry.descriptor.type = type;\n\tentry.descriptor.register_space = register_space;\n\tentry.descriptor.register_index = register_index;\n\timpl->local_root_signature.push_back(entry);\n}\n\nvoid Converter::add_local_root_descriptor_table(Vector<DescriptorTableEntry> entries)\n{\n\tLocalRootSignatureEntry entry = {};\n\tentry.type = LocalRootSignatureType::Table;\n\tentry.table_entries = std::move(entries);\n\timpl->local_root_signature.push_back(std::move(entry));\n}\n\nvoid Converter::add_local_root_descriptor_table(const DescriptorTableEntry *entries, size_t count)\n{\n\tadd_local_root_descriptor_table({ entries, entries + count });\n}\n\nuint32_t Converter::get_patch_location_offset() const\n{\n\treturn impl->patch_location_offset;\n}\n\nvoid Converter::set_patch_location_offset(uint32_t offset)\n{\n\timpl->patch_location_offset = offset;\n}\n\nvoid Converter::get_workgroup_dimensions(uint32_t &x, uint32_t &y, uint32_t &z) const\n{\n\tx = impl->execution_mode_meta.workgroup_threads[0];\n\ty = impl->execution_mode_meta.workgroup_threads[1];\n\tz = impl->execution_mode_meta.workgroup_threads[2];\n}\n\nuint32_t Converter::get_patch_vertex_count() const\n{\n\treturn impl->execution_mode_meta.stage_input_num_vertex;\n}\n\nvoid Converter::get_compute_wave_size_range(uint32_t &min, uint32_t &max, uint32_t &preferred) const\n{\n\tmin = impl->execution_mode_meta.wave_size_min;\n\tmax = impl->execution_mode_meta.wave_size_max;\n\tpreferred = impl->execution_mode_meta.wave_size_preferred;\n}\n\nuint32_t Converter::get_compute_heuristic_max_wave_size() const\n{\n\tif (impl->execution_mode_meta.wave_size_min)\n\t\treturn 0;\n\n\treturn impl->execution_mode_meta.heuristic_max_wave_size;\n}\n\nuint32_t Converter::get_compute_heuristic_min_wave_size() const\n{\n\tif (impl->execution_mode_meta.wave_size_min)\n\t\treturn 0;\n\n\treturn impl->execution_mode_meta.heuristic_min_wave_size;\n}\n\nbool Converter::is_multiview_compatible() const\n{\n\t// We're not multiview compatible if ViewIndex does not correspond 1:1 with output layer index.\n\t// ViewIndex is limited, and if the constant Layer offset is too large, it may force \"slow\" path\n\t// with draw-level instancing.\n\treturn impl->options.multiview.enable && !impl->multiview.custom_layer_index &&\n\t       impl->options.multiview.view_index_to_view_instance_spec_id != UINT32_MAX;\n}\n\nbool Converter::shader_requires_feature(ShaderFeature feature) const\n{\n\tswitch (feature)\n\t{\n\tcase ShaderFeature::Native16BitOperations:\n\t\treturn impl->builder().hasCapability(spv::CapabilityFloat16) ||\n\t\t       impl->builder().hasCapability(spv::CapabilityInt16);\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool Converter::get_driver_version(uint32_t &driver_id, uint32_t &driver_version) const\n{\n\tif (impl->options.driver_version == 0)\n\t\treturn false;\n\n\tdriver_id = impl->options.driver_id;\n\tdriver_version = impl->options.driver_version;\n\treturn true;\n}\n\nConvertedFunction Converter::convert_entry_point()\n{\n\treturn impl->convert_entry_point();\n}\n\ntemplate <typename T = uint32_t>\nstatic T get_constant_metadata(const llvm::MDNode *node, unsigned index)\n{\n\treturn T(\n\t    llvm::cast<llvm::ConstantAsMetadata>(node->getOperand(index))->getValue()->getUniqueInteger().getSExtValue());\n}\n\nstatic String get_string_metadata(const llvm::MDNode *node, unsigned index)\n{\n#ifdef HAVE_LLVMBC\n\treturn llvm::cast<llvm::MDString>(node->getOperand(index))->getString();\n#else\n\tstd::string tmp = llvm::cast<llvm::MDString>(node->getOperand(index))->getString();\n\tString str(tmp.begin(), tmp.end());\n\treturn str;\n#endif\n}\n\nstatic String get_resource_name_metadata(const llvm::MDNode *node, const llvm::MDNode *reflections)\n{\n\tif (reflections)\n\t{\n\t\tunsigned bind_space = get_constant_metadata(node, 3);\n\t\tunsigned bind_register = get_constant_metadata(node, 4);\n\t\tunsigned num_operands = reflections->getNumOperands();\n\t\tfor (unsigned i = 0; i < num_operands; i++)\n\t\t{\n\t\t\tauto *refl_node = llvm::cast<llvm::MDNode>(reflections->getOperand(i));\n\t\t\tif (get_constant_metadata(refl_node, 3) == bind_space &&\n\t\t\t    get_constant_metadata(refl_node, 4) == bind_register)\n\t\t\t{\n\t\t\t\treturn get_string_metadata(refl_node, 2);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn get_string_metadata(node, 2);\n}\n\nstatic spv::Dim image_dimension_from_resource_kind(DXIL::ResourceKind kind)\n{\n\tswitch (kind)\n\t{\n\tcase DXIL::ResourceKind::Texture1D:\n\tcase DXIL::ResourceKind::Texture1DArray:\n\t\treturn spv::Dim1D;\n\tcase DXIL::ResourceKind::Texture2D:\n\tcase DXIL::ResourceKind::Texture2DMS:\n\tcase DXIL::ResourceKind::Texture2DArray:\n\tcase DXIL::ResourceKind::Texture2DMSArray:\n\tcase DXIL::ResourceKind::FeedbackTexture2D:\n\tcase DXIL::ResourceKind::FeedbackTexture2DArray:\n\t\treturn spv::Dim2D;\n\tcase DXIL::ResourceKind::Texture3D:\n\t\treturn spv::Dim3D;\n\tcase DXIL::ResourceKind::TextureCube:\n\tcase DXIL::ResourceKind::TextureCubeArray:\n\t\treturn spv::DimCube;\n\n\tcase DXIL::ResourceKind::TypedBuffer:\n\tcase DXIL::ResourceKind::StructuredBuffer:\n\tcase DXIL::ResourceKind::RawBuffer:\n\t\treturn spv::DimBuffer;\n\n\tdefault:\n\t\treturn spv::DimMax;\n\t}\n}\n\nstatic bool image_dimension_is_arrayed(DXIL::ResourceKind kind)\n{\n\tswitch (kind)\n\t{\n\tcase DXIL::ResourceKind::Texture1DArray:\n\tcase DXIL::ResourceKind::Texture2DArray:\n\tcase DXIL::ResourceKind::Texture2DMSArray:\n\tcase DXIL::ResourceKind::TextureCubeArray:\n\tcase DXIL::ResourceKind::FeedbackTexture2DArray:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstatic bool image_dimension_is_multisampled(DXIL::ResourceKind kind)\n{\n\tswitch (kind)\n\t{\n\tcase DXIL::ResourceKind::Texture2DMS:\n\tcase DXIL::ResourceKind::Texture2DMSArray:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstatic DXIL::ComponentType convert_16bit_component_to_32bit(DXIL::ComponentType type)\n{\n\tswitch (type)\n\t{\n\tcase DXIL::ComponentType::F16:\n\t\treturn DXIL::ComponentType::F32;\n\tcase DXIL::ComponentType::I16:\n\t\treturn DXIL::ComponentType::I32;\n\tcase DXIL::ComponentType::U16:\n\t\treturn DXIL::ComponentType::U32;\n\tdefault:\n\t\treturn type;\n\t}\n}\n\nstatic DXIL::ComponentType convert_component_to_unsigned(DXIL::ComponentType type)\n{\n\tswitch (type)\n\t{\n\tcase DXIL::ComponentType::I16:\n\t\treturn DXIL::ComponentType::U16;\n\tcase DXIL::ComponentType::I32:\n\t\treturn DXIL::ComponentType::U32;\n\tcase DXIL::ComponentType::I64:\n\t\treturn DXIL::ComponentType::U64;\n\tdefault:\n\t\treturn type;\n\t}\n}\n\nstatic DXIL::ComponentType normalize_component_type(DXIL::ComponentType type)\n{\n\tswitch (type)\n\t{\n\tcase DXIL::ComponentType::UNormF16:\n\tcase DXIL::ComponentType::SNormF16:\n\t\treturn DXIL::ComponentType::F16;\n\n\tcase DXIL::ComponentType::UNormF32:\n\tcase DXIL::ComponentType::SNormF32:\n\t\treturn DXIL::ComponentType::F32;\n\n\tcase DXIL::ComponentType::UNormF64:\n\tcase DXIL::ComponentType::SNormF64:\n\t\treturn DXIL::ComponentType::F64;\n\n\tdefault:\n\t\treturn type;\n\t}\n}\n\nstatic spv::Id build_ssbo_runtime_array_type(Converter::Impl &impl, RawType type, unsigned bits, unsigned vecsize,\n                                             unsigned range_size, const String &name)\n{\n\tauto &builder = impl.builder();\n\tspv::Id value_type = type == RawType::Integer ? builder.makeUintType(bits) : builder.makeFloatType(bits);\n\tif (vecsize > 1)\n\t\tvalue_type = builder.makeVectorType(value_type, vecsize);\n\tspv::Id element_array_type = builder.makeRuntimeArray(value_type);\n\tbuilder.addDecoration(element_array_type, spv::DecorationArrayStride, vecsize * (bits / 8));\n\tspv::Id block_type_id = impl.get_struct_type({ element_array_type }, 0, name.c_str());\n\tbuilder.addMemberDecoration(block_type_id, 0, spv::DecorationOffset, 0);\n\tbuilder.addDecoration(block_type_id, spv::DecorationBlock);\n\n\tspv::Id type_id = block_type_id;\n\tif (range_size != 1)\n\t{\n\t\tassert(range_size != 0);\n\t\tif (range_size == ~0u)\n\t\t\ttype_id = builder.makeRuntimeArray(type_id);\n\t\telse\n\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(range_size), 0);\n\t}\n\n\treturn type_id;\n}\n\nVector<Converter::Impl::RawDeclarationVariable>\nConverter::Impl::create_bindless_heap_variable_alias_group(const BindlessInfo &base_info,\n                                                           const Vector<RawDeclaration> &raw_decls)\n{\n\tVector<RawDeclarationVariable> decls;\n\tdecls.reserve(raw_decls.size());\n\n\tfor (auto &decl : raw_decls)\n\t{\n\t\tRawDeclarationVariable var = {};\n\t\tvar.declaration = decl;\n\n\t\tauto info = base_info;\n\t\tinfo.component = raw_width_to_component_type(decl.type, decl.width);\n\t\tinfo.raw_vecsize = decl.vecsize;\n\t\tvar.var_id = create_bindless_heap_variable(info);\n\t\tdecls.push_back(var);\n\t}\n\n\treturn decls;\n}\n\nspv::Id Converter::Impl::create_ubo_variable(const RawDeclaration &raw_decl, uint32_t range_size, const String &name,\n                                             unsigned cbv_size)\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tunsigned element_size = raw_width_to_bits(raw_decl.width) * raw_vecsize_to_vecsize(raw_decl.vecsize) / 8;\n\tunsigned array_length = (cbv_size + element_size - 1) / element_size;\n\n\t// It seems like we will have to bitcast ourselves away from vec4 here after loading.\n\tspv::Id size_id = builder.makeUintConstant(array_length, false);\n\n\tunsigned bits = raw_width_to_bits(raw_decl.width);\n\tspv::Id element_type = raw_decl.type == RawType::Float ? builder.makeFloatType(bits) : builder.makeUintType(bits);\n\n\tif (raw_decl.vecsize != RawVecSize::V1)\n\t\telement_type = builder.makeVectorType(element_type, raw_vecsize_to_vecsize(raw_decl.vecsize));\n\tspv::Id member_array_type = builder.makeArrayType(element_type, size_id, element_size);\n\n\tbuilder.addDecoration(member_array_type, spv::DecorationArrayStride, element_size);\n\n\tauto ubo_block_name = name.empty() ? \"\" : (name + \"UBO\");\n\tspv::Id type_id = get_struct_type({ member_array_type }, 0, ubo_block_name.c_str());\n\tbuilder.addMemberDecoration(type_id, 0, spv::DecorationOffset, 0);\n\tbuilder.addDecoration(type_id, spv::DecorationBlock);\n\n\tif (range_size != 1)\n\t{\n\t\tif (range_size == ~0u)\n\t\t\ttype_id = builder.makeRuntimeArray(type_id);\n\t\telse\n\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(range_size), 0);\n\t}\n\n\tif (raw_decl.width == RawWidth::B16)\n\t\tbuilder.addCapability(spv::CapabilityUniformAndStorageBuffer16BitAccess);\n\telse if (raw_decl.width == RawWidth::B8)\n\t{\n\t\tbuilder.addExtension(\"SPV_KHR_8bit_storage\");\n\t\tbuilder.addCapability(spv::CapabilityUniformAndStorageBuffer8BitAccess);\n\t}\n\n\treturn create_variable(spv::StorageClassUniform,\n\t                       type_id, name.empty() ? nullptr : name.c_str());\n}\n\nspv::Id Converter::Impl::create_raw_ssbo_variable(const RawDeclaration &raw_decl, uint32_t range_size, const String &name)\n{\n\tspv::Id type_id = build_ssbo_runtime_array_type(*this,\n\t                                                raw_decl.type,\n\t                                                raw_width_to_bits(raw_decl.width),\n\t                                                raw_vecsize_to_vecsize(raw_decl.vecsize),\n\t                                                range_size, name + \"SSBO\");\n\n\tif (raw_decl.width == RawWidth::B16)\n\t\tbuilder().addCapability(spv::CapabilityStorageBuffer16BitAccess);\n\telse if (raw_decl.width == RawWidth::B8)\n\t{\n\t\tbuilder().addExtension(\"SPV_KHR_8bit_storage\");\n\t\tbuilder().addCapability(spv::CapabilityStorageBuffer8BitAccess);\n\t}\n\n\treturn create_variable(spv::StorageClassStorageBuffer, type_id, name.empty() ? nullptr : name.c_str());\n}\n\nVector<Converter::Impl::RawDeclarationVariable> Converter::Impl::create_raw_ssbo_variable_alias_group(\n\t\tconst Vector<RawDeclaration> &raw_decls,\n\t\tuint32_t range_size, const String &name)\n{\n\tVector<RawDeclarationVariable> group;\n\tgroup.reserve(raw_decls.size());\n\tfor (auto &decl : raw_decls)\n\t\tgroup.push_back({ decl, create_raw_ssbo_variable(decl, range_size, name) });\n\treturn group;\n}\n\nVector<Converter::Impl::RawDeclarationVariable> Converter::Impl::create_ubo_variable_alias_group(\n\t\tconst Vector<RawDeclaration> &raw_decls,\n\t\tuint32_t range_size, const String &name, unsigned cbv_size)\n{\n\tVector<RawDeclarationVariable> group;\n\tgroup.reserve(raw_decls.size());\n\tfor (auto &decl : raw_decls)\n\t\tgroup.push_back({ decl, create_ubo_variable(decl, range_size, name, cbv_size) });\n\treturn group;\n}\n\nstatic const char *convert_component_type_to_str(DXIL::ComponentType type)\n{\n\tswitch (type)\n\t{\n\tcase DXIL::ComponentType::U16: return \"U16\";\n\tcase DXIL::ComponentType::U32: return \"U32\";\n\tcase DXIL::ComponentType::U64: return \"U64\";\n\tcase DXIL::ComponentType::I16: return \"I16\";\n\tcase DXIL::ComponentType::I32: return \"I32\";\n\tcase DXIL::ComponentType::I64: return \"I64\";\n\tcase DXIL::ComponentType::F16: return \"F16\";\n\tcase DXIL::ComponentType::F32: return \"F32\";\n\tcase DXIL::ComponentType::F64: return \"F64\";\n\tdefault: return \"\";\n\t}\n}\n\nspv::Id Converter::Impl::create_bindless_heap_variable(const BindlessInfo &info)\n{\n\tauto itr = std::find_if(bindless_resources.begin(), bindless_resources.end(), [&](const BindlessResource &resource) {\n\t\treturn\n\t\t\tresource.info.type == info.type &&\n\t\t\tresource.info.component == info.component &&\n\t\t\tresource.info.raw_vecsize == info.raw_vecsize &&\n\t\t\tresource.info.kind == info.kind &&\n\t\t\tresource.info.desc_set == info.desc_set &&\n\t\t\tresource.info.format == info.format &&\n\t\t\tresource.info.binding == info.binding &&\n\t\t\tresource.info.uav_read == info.uav_read &&\n\t\t\tresource.info.uav_written == info.uav_written &&\n\t\t\tresource.info.uav_coherent == info.uav_coherent &&\n\t\t\tresource.info.relaxed_precision == info.relaxed_precision &&\n\t\t\tresource.info.aliased == info.aliased &&\n\t\t\tresource.info.counters == info.counters &&\n\t\t\tresource.info.offsets == info.offsets &&\n\t\t\tresource.info.descriptor_type == info.descriptor_type &&\n\t\t\t(!options.extended_non_semantic_info || resource.info.debug.stride == info.debug.stride);\n\t});\n\n\tif (itr != bindless_resources.end())\n\t{\n\t\treturn itr->var_id;\n\t}\n\telse\n\t{\n\t\tBindlessResource resource = {};\n\t\tresource.info = info;\n\n\t\tspv::Id type_id = 0;\n\t\tauto storage = spv::StorageClassMax;\n\n\t\tswitch (info.type)\n\t\t{\n\t\tcase DXIL::ResourceType::SRV:\n\t\t{\n\t\t\tif (info.kind == DXIL::ResourceKind::RTAccelerationStructure)\n\t\t\t{\n\t\t\t\tif (info.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t\t{\n\t\t\t\t\ttype_id = build_ssbo_runtime_array_type(*this, RawType::Integer, 32, 2, 1, \"RTASHeap\");\n\t\t\t\t\tstorage = spv::StorageClassStorageBuffer;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttype_id = builder().makeAccelerationStructureType();\n\t\t\t\t\ttype_id = builder().makeRuntimeArray(type_id);\n\t\t\t\t\tstorage = spv::StorageClassUniformConstant;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (info.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t{\n\t\t\t\tRawType raw_type = raw_component_type_to_type(info.component);\n\t\t\t\tunsigned bits = raw_component_type_to_bits(info.component);\n\n\t\t\t\tif (info.offsets)\n\t\t\t\t\ttype_id = build_ssbo_runtime_array_type(*this, raw_type, 32, 2, 1, \"SSBO_Offsets\");\n\t\t\t\telse\n\t\t\t\t\ttype_id = build_ssbo_runtime_array_type(*this, raw_type, bits, raw_vecsize_to_vecsize(info.raw_vecsize),\n\t\t\t\t\t                                        ~0u, \"SSBO\");\n\t\t\t\tstorage = spv::StorageClassStorageBuffer;\n\t\t\t\tif (bits == 16)\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityStorageBuffer16BitAccess);\n\t\t\t\telse if (bits == 8)\n\t\t\t\t{\n\t\t\t\t\tbuilder().addExtension(\"SPV_KHR_8bit_storage\");\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityStorageBuffer8BitAccess);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (info.component != DXIL::ComponentType::U32 &&\n\t\t\t\t    info.component != DXIL::ComponentType::I32 &&\n\t\t\t\t    info.component != DXIL::ComponentType::F32)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Invalid component type for image.\\n\");\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\tspv::Id sampled_type_id = get_type_id(info.component, 1, 1);\n\t\t\t\ttype_id = builder().makeImageType(sampled_type_id, image_dimension_from_resource_kind(info.kind), false,\n\t\t\t\t                                  image_dimension_is_arrayed(info.kind),\n\t\t\t\t                                  image_dimension_is_multisampled(info.kind), 1, spv::ImageFormatUnknown);\n\t\t\t\ttype_id = builder().makeRuntimeArray(type_id);\n\t\t\t\tstorage = spv::StorageClassUniformConstant;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::ResourceType::UAV:\n\t\t{\n\t\t\tif (info.counters)\n\t\t\t{\n\t\t\t\tif (info.kind == DXIL::ResourceKind::Invalid)\n\t\t\t\t{\n\t\t\t\t\tauto &mapping = options.meta_descriptor_mappings[int(MetaDescriptor::RawDescriptorHeapView)];\n\n\t\t\t\t\tif (mapping.kind == MetaDescriptorKind::UBOContainingBDA)\n\t\t\t\t\t{\n\t\t\t\t\t\t// This is faster access than the normal SSBO descriptor path.\n\t\t\t\t\t\tif (info.desc_set != mapping.desc_set || info.binding != mapping.desc_binding)\n\t\t\t\t\t\t\tLOGW(\"Using meta CBV mapping for physical descriptors, but there is a mismatch in requested bindings.\\n\");\n\n\t\t\t\t\t\tif (!emit_descriptor_heap_introspection_buffer())\n\t\t\t\t\t\t\treturn 0;\n\t\t\t\t\t\treturn instrumentation.descriptor_heap_introspection_var_id;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tspv::Id uint_type = builder().makeUintType(32);\n\t\t\t\t\t\tspv::Id uvec2_type = builder().makeVectorType(uint_type, 2);\n\n\t\t\t\t\t\tspv::Id runtime_array_type_id = builder().makeRuntimeArray(uvec2_type);\n\t\t\t\t\t\tbuilder().addDecoration(runtime_array_type_id, spv::DecorationArrayStride, sizeof(uint64_t));\n\n\t\t\t\t\t\ttype_id = get_struct_type({ runtime_array_type_id }, 0, \"AtomicCounters\");\n\t\t\t\t\t\tbuilder().addDecoration(type_id, spv::DecorationBlock);\n\t\t\t\t\t\tbuilder().addMemberName(type_id, 0, \"counters\");\n\t\t\t\t\t\tbuilder().addMemberDecoration(type_id, 0, spv::DecorationOffset, 0);\n\t\t\t\t\t\tbuilder().addMemberDecoration(type_id, 0, spv::DecorationNonWritable);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tspv::Id uint_type = builder().makeUintType(32);\n\t\t\t\t\ttype_id = get_struct_type({ uint_type }, 0, \"AtomicCounters\");\n\t\t\t\t\tbuilder().addDecoration(type_id, spv::DecorationBlock);\n\t\t\t\t\tbuilder().addMemberName(type_id, 0, \"counter\");\n\t\t\t\t\tbuilder().addMemberDecoration(type_id, 0, spv::DecorationOffset, 0);\n\t\t\t\t\ttype_id = builder().makeRuntimeArray(type_id);\n\t\t\t\t}\n\n\t\t\t\tstorage = spv::StorageClassStorageBuffer;\n\t\t\t}\n\t\t\telse if (info.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t{\n\t\t\t\tRawType raw_type = raw_component_type_to_type(info.component);\n\t\t\t\tunsigned bits = raw_component_type_to_bits(info.component);\n\n\t\t\t\ttype_id = build_ssbo_runtime_array_type(*this, raw_type, bits, raw_vecsize_to_vecsize(info.raw_vecsize),\n\t\t\t\t                                        ~0u, \"SSBO\");\n\t\t\t\tstorage = spv::StorageClassStorageBuffer;\n\t\t\t\tif (bits == 16)\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityStorageBuffer16BitAccess);\n\t\t\t\telse if (bits == 8)\n\t\t\t\t{\n\t\t\t\t\tbuilder().addExtension(\"SPV_KHR_8bit_storage\");\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityStorageBuffer8BitAccess);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (info.component != DXIL::ComponentType::U32 &&\n\t\t\t\t    info.component != DXIL::ComponentType::I32 &&\n\t\t\t\t    info.component != DXIL::ComponentType::F32 &&\n\t\t\t\t    info.component != DXIL::ComponentType::U64)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Invalid component type for image.\\n\");\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\tspv::Id sampled_type_id = get_type_id(info.component, 1, 1);\n\t\t\t\ttype_id = builder().makeImageType(sampled_type_id, image_dimension_from_resource_kind(info.kind), false,\n\t\t\t\t                                  image_dimension_is_arrayed(info.kind),\n\t\t\t\t                                  image_dimension_is_multisampled(info.kind), 2, info.format);\n\t\t\t\ttype_id = builder().makeRuntimeArray(type_id);\n\t\t\t\tstorage = spv::StorageClassUniformConstant;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::ResourceType::Sampler:\n\t\t\ttype_id = builder().makeSamplerType();\n\t\t\ttype_id = builder().makeRuntimeArray(type_id);\n\t\t\tstorage = spv::StorageClassUniformConstant;\n\t\t\tbreak;\n\n\t\tcase DXIL::ResourceType::CBV:\n\t\t{\n\t\t\tRawType raw_type = raw_component_type_to_type(info.component);\n\t\t\tunsigned bits = raw_component_type_to_bits(info.component);\n\n\t\t\tunsigned vecsize = raw_vecsize_to_vecsize(info.raw_vecsize);\n\t\t\ttype_id = raw_type == RawType::Float ? builder().makeFloatType(bits) : builder().makeUintType(bits);\n\t\t\tif (vecsize > 1)\n\t\t\t\ttype_id = builder().makeVectorType(type_id, vecsize);\n\n\t\t\tunsigned element_size = (bits / 8) * vecsize;\n\t\t\tunsigned num_elements = 0x10000 / element_size;\n\n\t\t\ttype_id = builder().makeArrayType(type_id, builder().makeUintConstant(num_elements), element_size);\n\t\t\tbuilder().addDecoration(type_id, spv::DecorationArrayStride, element_size);\n\t\t\ttype_id = get_struct_type({ type_id }, 0, \"BindlessCBV\");\n\t\t\tbuilder().addDecoration(type_id, spv::DecorationBlock);\n\t\t\tif (options.bindless_cbv_ssbo_emulation)\n\t\t\t\tbuilder().addMemberDecoration(type_id, 0, spv::DecorationNonWritable);\n\t\t\tbuilder().addMemberDecoration(type_id, 0, spv::DecorationOffset, 0);\n\t\t\ttype_id = builder().makeRuntimeArray(type_id);\n\t\t\tstorage = options.bindless_cbv_ssbo_emulation ? spv::StorageClassStorageBuffer : spv::StorageClassUniform;\n\n\t\t\tif (bits == 16)\n\t\t\t{\n\t\t\t\tif (options.bindless_cbv_ssbo_emulation)\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityStorageBuffer16BitAccess);\n\t\t\t\telse\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityUniformAndStorageBuffer16BitAccess);\n\t\t\t}\n\t\t\telse if (bits == 8)\n\t\t\t{\n\t\t\t\tbuilder().addExtension(\"SPV_KHR_8bit_storage\");\n\t\t\t\tif (options.bindless_cbv_ssbo_emulation)\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityStorageBuffer8BitAccess);\n\t\t\t\telse\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityUniformAndStorageBuffer8BitAccess);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn 0;\n\t\t}\n\n\t\tbuilder().addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\tbuilder().addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);\n\t\tresource.var_id = create_variable(storage, type_id);\n\n\t\tif (options.extended_non_semantic_info)\n\t\t{\n\t\t\tString name;\n\t\t\tswitch (info.type)\n\t\t\t{\n\t\t\tcase DXIL::ResourceType::SRV: name = \"SRV\"; break;\n\t\t\tcase DXIL::ResourceType::UAV: name = \"UAV\"; break;\n\t\t\tcase DXIL::ResourceType::CBV: name = \"CBV\"; break;\n\t\t\tcase DXIL::ResourceType::Sampler: name = \"Sampler\"; break;\n\t\t\tdefault: break;\n\t\t\t}\n\n\t\t\tconst char *component_type_name = convert_component_type_to_str(info.component);\n\n\t\t\tswitch (info.kind)\n\t\t\t{\n\t\t\tcase DXIL::ResourceKind::RawBuffer:\n\t\t\t\tname += \"_ByteAddressBuffer\";\n\t\t\t\tname += \"_vec\";\n\t\t\t\tname += std::to_string(raw_vecsize_to_vecsize(info.raw_vecsize)).c_str();\n\t\t\t\tbuilder().addName(builder().getContainedTypeId(type_id), (name + \"_Block\").c_str());\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::StructuredBuffer:\n\t\t\t\tname += \"_StructuredBuffer_\";\n\t\t\t\tname += std::to_string(info.debug.stride).c_str();\n\t\t\t\tname += \"_vec\";\n\t\t\t\tname += std::to_string(raw_vecsize_to_vecsize(info.raw_vecsize)).c_str();\n\t\t\t\tbuilder().addName(builder().getContainedTypeId(type_id), (name + \"_Block\").c_str());\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::CBuffer:\n\t\t\t\tbuilder().addName(builder().getContainedTypeId(type_id), (name + \"_Block\").c_str());\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::TypedBuffer:\n\t\t\t\tname += \"_TypedBuffer_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Texture1D:\n\t\t\t\tname += \"_1D_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Texture1DArray:\n\t\t\t\tname += \"_1DArray_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Texture2D:\n\t\t\t\tname += \"_2D_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Texture2DArray:\n\t\t\t\tname += \"_2DArray_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Texture2DMS:\n\t\t\t\tname += \"_2DMS_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Texture2DMSArray:\n\t\t\t\tname += \"_2DMSArray_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::TextureCube:\n\t\t\t\tname += \"_Cube_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::TextureCubeArray:\n\t\t\t\tname += \"_CubeArray_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Texture3D:\n\t\t\t\tname += \"_3D_\";\n\t\t\t\tname += component_type_name;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbuilder().addName(resource.var_id, name.c_str());\n\t\t}\n\n\t\tauto &meta = handle_to_resource_meta[resource.var_id];\n\t\tmeta = {};\n\t\tmeta.kind = info.kind;\n\t\tmeta.component_type = info.component;\n\t\tmeta.raw_component_vecsize = info.raw_vecsize;\n\t\tmeta.var_id = resource.var_id;\n\t\tmeta.storage = storage;\n\n\t\tbuilder().addDecoration(resource.var_id, spv::DecorationDescriptorSet, info.desc_set);\n\t\tbuilder().addDecoration(resource.var_id, spv::DecorationBinding, info.binding);\n\n\t\tif (info.relaxed_precision)\n\t\t{\n\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationRelaxedPrecision);\n\n\t\t\t// Signal the intended component type.\n\t\t\tswitch (meta.component_type)\n\t\t\t{\n\t\t\tcase DXIL::ComponentType::F32:\n\t\t\t\tmeta.component_type = DXIL::ComponentType::F16;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ComponentType::I32:\n\t\t\t\tmeta.component_type = DXIL::ComponentType::I16;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ComponentType::U32:\n\t\t\t\tmeta.component_type = DXIL::ComponentType::U16;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (info.type == DXIL::ResourceType::UAV && !info.counters)\n\t\t{\n\t\t\tif (!info.uav_read)\n\t\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationNonReadable);\n\t\t\tif (!info.uav_written)\n\t\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationNonWritable);\n\t\t\tif (info.uav_coherent && execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationCoherent);\n\t\t}\n\t\telse if (info.counters && info.kind == DXIL::ResourceKind::Invalid)\n\t\t{\n\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationAliasedPointer);\n\t\t}\n\t\telse if (info.type == DXIL::ResourceType::SRV && info.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t{\n\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationNonWritable);\n\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationRestrict);\n\t\t}\n\n\t\t// The default in Vulkan environment is Restrict.\n\t\tif (info.aliased && info.type == DXIL::ResourceType::UAV)\n\t\t\tbuilder().addDecoration(resource.var_id, spv::DecorationAliased);\n\n\t\tbindless_resources.push_back(resource);\n\t\treturn resource.var_id;\n\t}\n}\n\nConverter::Impl::ResourceVariableMeta Converter::Impl::get_resource_variable_meta(const llvm::MDNode *resource) const\n{\n\tResourceVariableMeta meta = {};\n\n\tif (!resource)\n\t\treturn meta;\n\n\tif (const auto *variable = llvm::dyn_cast<llvm::ConstantAsMetadata>(resource->getOperand(1)))\n\t{\n\t\tconst llvm::Value *val = variable->getValue();\n\t\tconst auto *global = llvm::dyn_cast<llvm::GlobalVariable>(val);\n\n\t\t// It's possible that the variable is a constexpr bitcast, so resolve those ...\n\t\twhile (!global && val)\n\t\t{\n\t\t\tauto *constexpr_op = llvm::dyn_cast<llvm::ConstantExpr>(val);\n\t\t\tval = nullptr;\n\n\t\t\tif (constexpr_op && constexpr_op->getOpcode() == llvm::UnaryOperator::BitCast)\n\t\t\t{\n\t\t\t\tval = constexpr_op->getOperand(0);\n\t\t\t\tglobal = llvm::dyn_cast<llvm::GlobalVariable>(val);\n\t\t\t}\n\t\t}\n\n\t\tif (global)\n\t\t{\n\t\t\tmeta.is_lib_variable = true;\n\t\t\tmeta.is_active = llvm_active_global_resource_variables.count(global) != 0;\n\t\t\treturn meta;\n\t\t}\n\t}\n\n\tmeta.is_active = true;\n\treturn meta;\n}\n\nvoid Converter::Impl::register_resource_meta_reference(const llvm::MDOperand &operand, DXIL::ResourceType type, unsigned index)\n{\n\t// In RT shaders, apps will load dummy structs from global variables.\n\t// Here we get the chance to redirect them towards the resource meta declaration.\n\tif (operand)\n\t{\n\t\tauto *value = llvm::cast<llvm::ConstantAsMetadata>(operand)->getValue();\n\n\t\t// In lib_6_6, this is somehow a bitcasted pointer expression, sigh ...\n\t\t// Drill deep until we actually find the original resource.\n\t\twhile (auto *cexpr = llvm::dyn_cast<llvm::ConstantExpr>(value))\n\t\t{\n\t\t\tif (cexpr->getOpcode() == llvm::Instruction::BitCast)\n\t\t\t\tvalue = cexpr->getOperand(0);\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\n\t\tauto *global_variable = llvm::dyn_cast<llvm::GlobalVariable>(value);\n\t\tif (global_variable)\n\t\t\tllvm_global_variable_to_resource_mapping[global_variable] = { type, index, nullptr, global_variable, false };\n\t}\n}\n\nbool Converter::Impl::emit_resources_global_mapping(DXIL::ResourceType type, const llvm::MDNode *node)\n{\n\tunsigned num_resources = node->getNumOperands();\n\tfor (unsigned i = 0; i < num_resources; i++)\n\t{\n\t\tauto *resource = llvm::cast<llvm::MDNode>(node->getOperand(i));\n\t\tunsigned index = get_constant_metadata(resource, 0);\n\n\t\tif (type == DXIL::ResourceType::UAV)\n\t\t{\n\t\t\tunsigned bind_space = get_constant_metadata(resource, 3);\n\t\t\tunsigned bind_register = get_constant_metadata(resource, 4);\n\t\t\tauto resource_kind = static_cast<DXIL::ResourceKind>(get_constant_metadata(resource, 6));\n\n\t\t\tif (bind_space == AgsUAVMagicRegisterSpace && resource_kind == DXIL::ResourceKind::RawBuffer)\n\t\t\t{\n\t\t\t\tags.uav_magic_resource_type_index = index;\n\t\t\t}\n\t\t\telse if (options.nvapi.enabled &&\n\t\t\t         options.nvapi.register_index == bind_register &&\n\t\t\t         options.nvapi.register_space == bind_space &&\n\t\t\t         resource_kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t\t{\n\t\t\t\tnvapi.uav_magic_resource_type_index = index;\n\t\t\t}\n\t\t}\n\t\tregister_resource_meta_reference(resource->getOperand(1), type, index);\n\t}\n\treturn true;\n}\n\nspv::Id Converter::Impl::get_physical_pointer_block_type(spv::Id base_type_id, const PhysicalPointerMeta &meta)\n{\n\tauto itr = std::find_if(physical_pointer_entries.begin(), physical_pointer_entries.end(), [&](const PhysicalPointerEntry &entry) {\n\t\treturn entry.meta.coherent == meta.coherent &&\n\t\t       entry.meta.nonreadable == meta.nonreadable &&\n\t\t       entry.meta.nonwritable == meta.nonwritable &&\n\t\t       entry.meta.size == meta.size &&\n\t\t       entry.meta.stride == meta.stride &&\n\t\t       entry.base_type_id == base_type_id;\n\t});\n\n\tif (itr != physical_pointer_entries.end())\n\t\treturn itr->ptr_type_id;\n\n\tint vecsize = builder().getNumTypeComponents(base_type_id);\n\tint width = builder().getScalarTypeWidth(base_type_id);\n\n\tspv::Op op = builder().getTypeClass(base_type_id);\n\tif (op == spv::OpTypeVector)\n\t\top = builder().getTypeClass(builder().getScalarTypeId(base_type_id));\n\n\tString type = \"PhysicalPointer\";\n\tswitch (op)\n\t{\n\tcase spv::OpTypeFloat:\n\t\tif (width == 16)\n\t\t\ttype += \"Half\";\n\t\telse if (width == 32)\n\t\t\ttype += \"Float\";\n\t\telse if (width == 64)\n\t\t\ttype += \"Double\";\n\t\tbreak;\n\n\tcase spv::OpTypeInt:\n\t\tif (width == 16)\n\t\t\ttype += \"Ushort\";\n\t\telse if (width == 32)\n\t\t\ttype += \"Uint\";\n\t\telse if (width == 64)\n\t\t\ttype += \"Uint64\";\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (vecsize > 1)\n\t\ttype += std::to_string(vecsize).c_str();\n\n\tif (meta.nonwritable)\n\t\ttype += \"NonWrite\";\n\tif (meta.nonreadable)\n\t\ttype += \"NonRead\";\n\tif (meta.coherent)\n\t\ttype += \"Coherent\";\n\n\tspv::Id type_id = base_type_id;\n\n\tif (meta.stride > 0)\n\t{\n\t\tif (meta.size == 0)\n\t\t{\n\t\t\ttype_id = builder().makeRuntimeArray(type_id);\n\t\t\ttype += \"Array\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttype_id = builder().makeArrayType(type_id, builder().makeUintConstant(meta.size / meta.stride),\n\t\t\t                                  meta.stride);\n\t\t\ttype += \"CBVArray\";\n\t\t}\n\t\tbuilder().addDecoration(type_id, spv::DecorationArrayStride, meta.stride);\n\t}\n\n\tspv::Id block_type_id = builder().makeStructType({ type_id }, type.c_str());\n\tbuilder().addMemberDecoration(block_type_id, 0, spv::DecorationOffset, 0);\n\tbuilder().addMemberName(block_type_id, 0, \"value\");\n\tbuilder().addDecoration(block_type_id, spv::DecorationBlock);\n\n\tif (meta.nonwritable)\n\t\tbuilder().addMemberDecoration(block_type_id, 0, spv::DecorationNonWritable);\n\tif (meta.nonreadable)\n\t\tbuilder().addMemberDecoration(block_type_id, 0, spv::DecorationNonReadable);\n\tif (meta.coherent && execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\tbuilder().addMemberDecoration(block_type_id, 0, spv::DecorationCoherent);\n\n\tspv::Id ptr_type_id = builder().makePointer(spv::StorageClassPhysicalStorageBuffer, block_type_id);\n\tPhysicalPointerEntry new_entry = {};\n\tnew_entry.ptr_type_id = ptr_type_id;\n\tnew_entry.base_type_id = base_type_id;\n\tnew_entry.meta = meta;\n\tphysical_pointer_entries.push_back(new_entry);\n\treturn ptr_type_id;\n}\n\nstatic bool component_type_is_16bit(DXIL::ComponentType type)\n{\n\tswitch (type)\n\t{\n\tcase DXIL::ComponentType::F16:\n\tcase DXIL::ComponentType::I16:\n\tcase DXIL::ComponentType::U16:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool Converter::Impl::analyze_aliased_access(const AccessTracking &tracking,\n                                             VulkanDescriptorType descriptor_type,\n                                             AliasedAccess &aliased_access) const\n{\n\tbool raw_access_16bit = false;\n\tbool raw_access_64bit = false;\n\n\tfor (int type_ = 0; type_ < int(RawType::Count); type_++)\n\t{\n\t\tfor (int width_ = 0; width_ < int(RawWidth::Count); width_++)\n\t\t{\n\t\t\tauto width = RawWidth(width_);\n\t\t\tif (width == RawWidth::B16 && !execution_mode_meta.native_16bit_operations)\n\t\t\t\tcontinue;\n\n\t\t\tfor (int vecsize_ = 0; vecsize_ < int(RawVecSize::Count); vecsize_++)\n\t\t\t{\n\t\t\t\tauto vecsize = RawVecSize(vecsize_);\n\t\t\t\tauto type = RawType(type_);\n\t\t\t\t// Non-native 16-bit SSBOs are declared as 32-bit, so avoid false aliases.\n\t\t\t\tbool has_decl = tracking.raw_access_buffer_declarations[type_][width_][vecsize_];\n\t\t\t\tif (!has_decl && RawWidth(width) == RawWidth::B32 && !execution_mode_meta.native_16bit_operations)\n\t\t\t\t\thas_decl = tracking.raw_access_buffer_declarations[type_][unsigned(RawWidth::B16)][vecsize_];\n\n\t\t\t\tif (has_decl)\n\t\t\t\t{\n\t\t\t\t\tif (width == RawWidth::B16)\n\t\t\t\t\t\traw_access_16bit = true;\n\t\t\t\t\telse if (width == RawWidth::B64)\n\t\t\t\t\t\traw_access_64bit = true;\n\t\t\t\t\taliased_access.raw_declarations.push_back({ type, width, vecsize });\n\n\t\t\t\t\taliased_access.primary_component_type = raw_width_to_component_type(type, width);\n\t\t\t\t\taliased_access.primary_raw_vecsize = vecsize;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (raw_access_16bit &&\n\t    descriptor_type != VulkanDescriptorType::SSBO &&\n\t    descriptor_type != VulkanDescriptorType::UBO &&\n\t    descriptor_type != VulkanDescriptorType::BufferDeviceAddress)\n\t{\n\t\tLOGE(\"Raw 16-bit load-store was used, which must be implemented with SSBO, UBO or BDA.\\n\");\n\t\treturn false;\n\t}\n\n\tif (raw_access_64bit &&\n\t    descriptor_type != VulkanDescriptorType::SSBO &&\n\t    descriptor_type != VulkanDescriptorType::UBO &&\n\t    descriptor_type != VulkanDescriptorType::BufferDeviceAddress)\n\t{\n\t\tLOGE(\"Raw 64-bit load-store was used, which must be implemented with SSBO, UBO or BDA.\\n\");\n\t\treturn false;\n\t}\n\n\t// Only SSBO and UBO can be reclared with different types.\n\t// Typed descriptors are always scalar.\n\taliased_access.requires_alias_decoration = (descriptor_type == VulkanDescriptorType::SSBO ||\n\t                                            descriptor_type == VulkanDescriptorType::UBO) &&\n\t                                           aliased_access.raw_declarations.size() > 1;\n\n\t// If we only emit one 16-bit or 64-bit SSBO/UBO, we need to override the component type of that meta declaration.\n\taliased_access.override_primary_component_types = (descriptor_type == VulkanDescriptorType::SSBO ||\n\t                                                   descriptor_type == VulkanDescriptorType::UBO) &&\n\t                                                  aliased_access.raw_declarations.size() == 1;\n\n\t// If the SSBO is never actually accessed (UAV counters for example), fudge the default type.\n\tif (descriptor_type == VulkanDescriptorType::SSBO && aliased_access.raw_declarations.empty())\n\t\taliased_access.raw_declarations.push_back({ RawType::Integer, RawWidth::B32, RawVecSize::V1 });\n\n\t// If the CBV is never actually accessed, fudge the default legacy CBV type.\n\tif (descriptor_type == VulkanDescriptorType::UBO && aliased_access.raw_declarations.empty())\n\t\taliased_access.raw_declarations.push_back({ RawType::Float, RawWidth::B32, RawVecSize::V4 });\n\n\t// Safeguard against unused variables where we never end up setting any primary component type.\n\tif ((descriptor_type == VulkanDescriptorType::SSBO ||\n\t     descriptor_type == VulkanDescriptorType::UBO) &&\n\t    aliased_access.raw_declarations.size() == 1)\n\t{\n\t\taliased_access.primary_component_type =\n\t\t\t\traw_width_to_component_type(aliased_access.raw_declarations.front().type, aliased_access.raw_declarations.front().width);\n\t\taliased_access.primary_raw_vecsize = aliased_access.raw_declarations.front().vecsize;\n\t\taliased_access.override_primary_component_types = true;\n\t}\n\n\treturn true;\n}\n\nvoid Converter::Impl::emit_non_semantic_debug_info(const NonSemanticDebugInfo &info)\n{\n\tauto &b = spirv_module.get_builder();\n\tb.addExtension(\"SPV_KHR_non_semantic_info\");\n\tspv::Id ext = b.import(\"NonSemantic.dxil-spirv.signature\");\n\tauto *u8_data = static_cast<const uint8_t *>(info.data);\n\n\t// If the root sig is massive (likely because it came from a full DXIL blob or something),\n\t// need to dump in multiple stages due to opcode limits.\n\tfor (size_t i = 0; i < info.size; i += 64 * 1024)\n\t{\n\t\tsize_t to_dump = std::min<size_t>(info.size - i, 64 * 1024);\n\t\tauto inst = std::make_unique<spv::Instruction>(\n\t\t    b.getUniqueId(), b.makeVoidType(), spv::OpExtInst);\n\t\tinst->addIdOperand(ext);\n\t\tinst->addImmediateOperand(1);\n\t\tinst->addIdOperand(b.addString(info.tag));\n\n\t\tfor (size_t j = 0; j < (to_dump & ~size_t(3)); j += 4)\n\t\t{\n\t\t\tuint32_t v;\n\t\t\tmemcpy(&v, u8_data + i + j, sizeof(v));\n\t\t\tinst->addIdOperand(b.makeUintConstant(v));\n\t\t}\n\n\t\tfor (size_t j = to_dump & ~size_t(3); j < to_dump; j++)\n\t\t\tinst->addIdOperand(b.makeUint8Constant(u8_data[i + j]));\n\n\t\tb.addExternal(std::move(inst));\n\t}\n}\n\nvoid Converter::Impl::emit_root_parameter_index_from_push_index(const char *tag, uint32_t index, uint32_t size, bool bda)\n{\n    bool descriptor_packing = (index & 0x80000000) != 0;\n    uint32_t parameter_index = UINT32_MAX;\n    uint32_t effective_offset = 0;\n\n    if (descriptor_packing)\n    {\n        for (auto &mapping : root_parameter_mappings)\n        {\n            if (mapping.offset == index)\n            {\n                parameter_index = mapping.root_parameter_index;\n                break;\n            }\n        }\n    }\n    else\n    {\n        effective_offset = bda ? index * 8 : (index * 4 + root_descriptor_count * 8);\n        for (auto &mapping: root_parameter_mappings)\n        {\n            if (mapping.offset == effective_offset)\n            {\n                parameter_index = mapping.root_parameter_index;\n                break;\n            }\n        }\n    }\n\n\tif (parameter_index == UINT32_MAX)\n\t\treturn;\n\n\t// Avoid lots of spam.\n\tif ((1ull << parameter_index) & root_parameter_emit_mask)\n\t\treturn;\n\troot_parameter_emit_mask |= 1ull << parameter_index;\n\n\tauto &b = spirv_module.get_builder();\n\tb.addExtension(\"SPV_KHR_non_semantic_info\");\n\tspv::Id ext = b.import(\"NonSemantic.dxil-spirv.signature\");\n\tauto inst = std::make_unique<spv::Instruction>(b.getUniqueId(), b.makeVoidType(), spv::OpExtInst);\n\tinst->addIdOperand(ext);\n\tinst->addImmediateOperand(0);\n\tinst->addIdOperand(b.addString(tag));\n\tinst->addIdOperand(b.makeUintConstant(parameter_index));\n\n    if (descriptor_packing)\n    {\n        inst->addIdOperand(b.makeUintConstant((index >> 24) & 0x7f));\n        inst->addIdOperand(b.makeUintConstant(index & 0xffffff));\n    }\n    else\n    {\n        inst->addIdOperand(b.makeUintConstant(effective_offset));\n        inst->addIdOperand(b.makeUintConstant(size));\n    }\n\n\tb.addExternal(std::move(inst));\n}\n\nbool Converter::Impl::emit_srvs(const llvm::MDNode *srvs, const llvm::MDNode *refl)\n{\n\tauto &builder = spirv_module.get_builder();\n\tunsigned num_srvs = srvs->getNumOperands();\n\n\tfor (unsigned i = 0; i < num_srvs; i++)\n\t{\n\t\tauto *srv = llvm::cast<llvm::MDNode>(srvs->getOperand(i));\n\n\t\tauto var_meta = get_resource_variable_meta(srv);\n\t\tif (!var_meta.is_active)\n\t\t\tcontinue;\n\n\t\tunsigned index = get_constant_metadata(srv, 0);\n\t\tauto name = get_resource_name_metadata(srv, refl);\n\t\tunsigned bind_space = get_constant_metadata(srv, 3);\n\t\tunsigned bind_register = get_constant_metadata(srv, 4);\n\t\tunsigned range_size = get_constant_metadata(srv, 5);\n\n\t\tif (bind_register == UINT32_MAX && bind_space == UINT32_MAX)\n\t\t{\n\t\t\t// This seems to be possible in RT shaders when explicit register() is missing?\n\t\t\tLOGE(\"Nonsensical SRV binding detected.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto resource_kind = static_cast<DXIL::ResourceKind>(get_constant_metadata(srv, 6));\n\n\t\tllvm::MDNode *tags = nullptr;\n\t\tif (srv->getNumOperands() >= 9 && srv->getOperand(8))\n\t\t\ttags = llvm::dyn_cast<llvm::MDNode>(srv->getOperand(8));\n\n\t\tauto actual_component_type = DXIL::ComponentType::U32;\n\t\tauto effective_component_type = actual_component_type;\n\n\t\tunsigned stride = 0;\n\n\t\tif (tags && get_constant_metadata(tags, 0) == 0)\n\t\t{\n\t\t\t// Sampled format.\n\t\t\tactual_component_type = normalize_component_type(static_cast<DXIL::ComponentType>(get_constant_metadata(tags, 1)));\n\t\t\teffective_component_type = get_effective_typed_resource_type(actual_component_type);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Structured/Raw buffers, just use uint for good measure, we'll bitcast as needed.\n\t\t\t// Field 1 is stride, but we don't care about that unless we will support an SSBO path.\n\t\t\tif (tags)\n\t\t\t\tstride = get_constant_metadata(tags, 1);\n\t\t}\n\n\t\tunsigned alignment = resource_kind == DXIL::ResourceKind::RawBuffer ? 16 : (stride & -int(stride));\n\n\t\tDescriptorTableEntry local_table_entry = {};\n\t\tint local_root_signature_entry = get_local_root_signature_entry(\n\t\t\tResourceClass::SRV, bind_space, bind_register, local_table_entry);\n\t\tbool need_resource_remapping = local_root_signature_entry < 0 ||\n\t\t                               local_root_signature[local_root_signature_entry].type == LocalRootSignatureType::Table;\n\n\t\tD3DBinding d3d_binding = {\n\t\t\tget_remapping_stage(execution_model), resource_kind, index, bind_space, bind_register, range_size, alignment,\n\t\t};\n\t\tVulkanSRVBinding vulkan_binding = { { bind_space, bind_register }, {} };\n\t\tif (need_resource_remapping && resource_mapping_iface &&\n\t\t    !resource_mapping_iface->remap_srv(d3d_binding, vulkan_binding))\n\t\t{\n\t\t\t// We may be rejected if the unbound range has 1 non-bindless descriptor.\n\t\t\tbool retry = d3d_binding.range_size == UINT32_MAX;\n\t\t\tif (retry)\n\t\t\t{\n\t\t\t\td3d_binding.range_size = 1;\n\t\t\t\trange_size = 1;\n\t\t\t}\n\n\t\t\tif (!retry || !resource_mapping_iface->remap_srv(d3d_binding, vulkan_binding))\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to remap SRV %u:%u.\\n\", bind_space, bind_register);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tauto &access_meta = srv_access_tracking[index];\n\n\t\tAliasedAccess aliased_access;\n\t\tif (!analyze_aliased_access(access_meta,\n\t\t                            need_resource_remapping ?\n\t\t                            vulkan_binding.buffer_binding.descriptor_type :\n\t\t                            VulkanDescriptorType::BufferDeviceAddress, aliased_access))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tif (range_size != 1 && resource_kind != DXIL::ResourceKind::RTAccelerationStructure)\n\t\t{\n\t\t\tif (range_size == ~0u)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);\n\t\t\t}\n\n\t\t\tif ((resource_kind == DXIL::ResourceKind::StructuredBuffer ||\n\t\t\t     resource_kind == DXIL::ResourceKind::RawBuffer) &&\n\t\t\t    vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t{\n\t\t\t\tbuilder.addCapability(spv::CapabilityStorageBufferArrayDynamicIndexing);\n\t\t\t}\n\t\t\telse if (resource_kind == DXIL::ResourceKind::StructuredBuffer ||\n\t\t\t         resource_kind == DXIL::ResourceKind::RawBuffer || resource_kind == DXIL::ResourceKind::TypedBuffer)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT);\n\t\t\t}\n\t\t\telse\n\t\t\t\tbuilder.addCapability(spv::CapabilitySampledImageArrayDynamicIndexing);\n\t\t}\n\n\t\tsrv_index_to_reference.resize(std::max(srv_index_to_reference.size(), size_t(index + 1)));\n\t\tsrv_index_to_offset.resize(std::max(srv_index_to_offset.size(), size_t(index + 1)));\n\n\t\tif (!get_ssbo_offset_buffer_id(srv_index_to_offset[index], vulkan_binding.buffer_binding,\n\t\t                               vulkan_binding.offset_binding, resource_kind, alignment))\n\t\t\treturn false;\n\n\t\tBindlessInfo bindless_info = {};\n\t\tbindless_info.type = DXIL::ResourceType::SRV;\n\t\tbindless_info.component = effective_component_type;\n\t\tbindless_info.kind = resource_kind;\n\t\tbindless_info.desc_set = vulkan_binding.buffer_binding.descriptor_set;\n\t\tbindless_info.binding = vulkan_binding.buffer_binding.binding;\n\t\tbindless_info.descriptor_type = vulkan_binding.buffer_binding.descriptor_type;\n\t\tbindless_info.relaxed_precision = actual_component_type != effective_component_type &&\n\t\t                                  component_type_is_16bit(actual_component_type);\n\t\tbindless_info.debug.stride = stride;\n\n\t\tif (local_root_signature_entry >= 0)\n\t\t{\n\t\t\tauto &entry = local_root_signature[local_root_signature_entry];\n\t\t\tif (entry.type == LocalRootSignatureType::Table)\n\t\t\t{\n\t\t\t\tif (!vulkan_binding.buffer_binding.bindless.use_heap)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Table SBT entries must be bindless.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (!var_meta.is_lib_variable)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Local root signature requires global lib variables.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tuint32_t heap_offset = local_table_entry.offset_in_heap;\n\t\t\t\theap_offset += bind_register - local_table_entry.register_index;\n\n\t\t\t\tauto &ref = srv_index_to_reference[index];\n\t\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t\t{\n\t\t\t\t\tref.var_alias_group = create_bindless_heap_variable_alias_group(\n\t\t\t\t\t\tbindless_info, aliased_access.raw_declarations);\n\t\t\t\t}\n\t\t\t\telse if (aliased_access.override_primary_component_types)\n\t\t\t\t{\n\t\t\t\t\tauto tmp_info = bindless_info;\n\t\t\t\t\ttmp_info.component = aliased_access.primary_component_type;\n\t\t\t\t\ttmp_info.raw_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\t\t\tref.var_id = create_bindless_heap_variable(tmp_info);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tref.var_id = create_bindless_heap_variable(bindless_info);\n\t\t\t\t}\n\n\t\t\t\tref.aliased = aliased_access.requires_alias_decoration;\n\t\t\t\tref.base_offset = heap_offset;\n\t\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\t\tref.stride = stride;\n\t\t\t\tref.bindless = true;\n\t\t\t\tref.local_root_signature_entry = local_root_signature_entry;\n\t\t\t\tref.resource_kind = resource_kind;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Otherwise, we simply refer to the SBT directly to obtain a pointer.\n\t\t\t\tif (resource_kind != DXIL::ResourceKind::RawBuffer &&\n\t\t\t\t    resource_kind != DXIL::ResourceKind::StructuredBuffer &&\n\t\t\t\t    resource_kind != DXIL::ResourceKind::RTAccelerationStructure)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"SRV SBT root descriptors must be raw buffers, structured buffers or RTAS.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tauto &ref = srv_index_to_reference[index];\n\t\t\t\tref.var_id = shader_record_buffer_id;\n\t\t\t\tref.stride = stride;\n\t\t\t\tref.local_root_signature_entry = local_root_signature_entry;\n\t\t\t\tref.resource_kind = resource_kind;\n\n\t\t\t\tif (range_size != 1)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Cannot use descriptor array for root descriptors.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::BufferDeviceAddress)\n\t\t{\n\t\t\tif (resource_kind != DXIL::ResourceKind::RawBuffer &&\n\t\t\t    resource_kind != DXIL::ResourceKind::StructuredBuffer &&\n\t\t\t    resource_kind != DXIL::ResourceKind::RTAccelerationStructure)\n\t\t\t{\n\t\t\t\tLOGE(\"BDA root descriptors must be raw buffers, structured buffers or RTAS.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tauto &ref = srv_index_to_reference[index];\n\t\t\tref.var_id = root_constant_id;\n\t\t\tref.root_descriptor = true;\n\t\t\tref.push_constant_member = vulkan_binding.buffer_binding.root_constant_index;\n\t\t\tref.stride = stride;\n\t\t\tref.resource_kind = resource_kind;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t\temit_root_parameter_index_from_push_index(\"SRV\", ref.push_constant_member, 8, true);\n\n\t\t\tif (range_size != 1)\n\t\t\t{\n\t\t\t\tLOGE(\"Cannot use descriptor array for root descriptors.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse if (vulkan_binding.buffer_binding.bindless.use_heap)\n\t\t{\n\t\t\t// DXIL already applies the t# register offset to any dynamic index, so counteract that here.\n\t\t\t// The exception is with lib_* where we access resources by variable, not through\n\t\t\t// createResource() >_____<.\n\t\t\tuint32_t heap_offset = vulkan_binding.buffer_binding.bindless.heap_root_offset;\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\theap_offset -= bind_register;\n\n\t\t\tauto &ref = srv_index_to_reference[index];\n\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t{\n\t\t\t\tref.var_alias_group = create_bindless_heap_variable_alias_group(\n\t\t\t\t\tbindless_info, aliased_access.raw_declarations);\n\t\t\t}\n\t\t\telse if (aliased_access.override_primary_component_types)\n\t\t\t{\n\t\t\t\tauto tmp_info = bindless_info;\n\t\t\t\ttmp_info.component = aliased_access.primary_component_type;\n\t\t\t\ttmp_info.raw_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\t\tref.var_id = create_bindless_heap_variable(tmp_info);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tref.var_id = create_bindless_heap_variable(bindless_info);\n\t\t\t}\n\n\t\t\tref.aliased = aliased_access.requires_alias_decoration;\n\t\t\tref.push_constant_member = vulkan_binding.buffer_binding.root_constant_index + root_descriptor_count;\n\t\t\tref.base_offset = heap_offset;\n\t\t\tref.stride = stride;\n\t\t\tref.bindless = true;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.resource_kind = resource_kind;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t\temit_root_parameter_index_from_push_index(\"ResourceTable\", vulkan_binding.buffer_binding.root_constant_index, 4, false);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto sampled_type_id = get_type_id(effective_component_type, 1, 1);\n\n\t\t\tspv::Id type_id = 0;\n\t\t\tauto storage = spv::StorageClassUniformConstant;\n\n\t\t\tif (resource_kind == DXIL::ResourceKind::RTAccelerationStructure)\n\t\t\t{\n\t\t\t\ttype_id = builder.makeAccelerationStructureType();\n\t\t\t}\n\t\t\telse if (vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t{\n\t\t\t\tstorage = spv::StorageClassStorageBuffer;\n\t\t\t\t// Defer typing the SSBOs.\n\t\t\t}\n\t\t\telse if (vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::InputAttachment)\n\t\t\t{\n\t\t\t\tif (execution_model != spv::ExecutionModelFragment)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"InputAttachments can only be used in pixel shaders.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (range_size != 1)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Cannot bind input attachment to array of descriptors.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (resource_kind != DXIL::ResourceKind::Texture2D && resource_kind != DXIL::ResourceKind::Texture2DMS)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Can only bind Texture2D and Texture2DMS to input attachments.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\ttype_id =\n\t\t\t\t\tbuilder.makeImageType(sampled_type_id, spv::DimSubpassData, false, false,\n\t\t\t\t\t\t\t\t\t\t  image_dimension_is_multisampled(resource_kind), 2, spv::ImageFormatUnknown);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttype_id =\n\t\t\t\t    builder.makeImageType(sampled_type_id, image_dimension_from_resource_kind(resource_kind), false,\n\t\t\t\t                          image_dimension_is_arrayed(resource_kind),\n\t\t\t\t                          image_dimension_is_multisampled(resource_kind), 1, spv::ImageFormatUnknown);\n\t\t\t\tif (range_size != 1)\n\t\t\t\t{\n\t\t\t\t\tif (range_size == ~0u)\n\t\t\t\t\t\ttype_id = builder.makeRuntimeArray(type_id);\n\t\t\t\t\telse\n\t\t\t\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(range_size), 0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tauto &ref = srv_index_to_reference[index];\n\n\t\t\tif (type_id)\n\t\t\t\tref.var_id = create_variable(storage, type_id, name.empty() ? nullptr : name.c_str());\n\t\t\telse if (aliased_access.requires_alias_decoration)\n\t\t\t\tref.var_alias_group = create_raw_ssbo_variable_alias_group(aliased_access.raw_declarations, range_size, name);\n\t\t\telse\n\t\t\t{\n\t\t\t\tassert(aliased_access.raw_declarations.size() == 1);\n\t\t\t\tref.var_id = create_raw_ssbo_variable(aliased_access.raw_declarations.front(), range_size, name);\n\t\t\t}\n\n\t\t\tif (actual_component_type != effective_component_type && component_type_is_16bit(actual_component_type))\n\t\t\t\tbuilder.addDecoration(ref.var_id, spv::DecorationRelaxedPrecision);\n\n\t\t\tconst auto decorate_variable = [&](spv::Id id) {\n\t\t\t\tbuilder.addDecoration(id, spv::DecorationDescriptorSet, vulkan_binding.buffer_binding.descriptor_set);\n\t\t\t\tbuilder.addDecoration(id, spv::DecorationBinding, vulkan_binding.buffer_binding.binding);\n\t\t\t\tif (vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t\t{\n\t\t\t\t\t// Make it crystal clear this is a read-only SSBO which cannot observe changed from other SSBO writes.\n\t\t\t\t\t// Do not emit Aliased here even for type aliases\n\t\t\t\t\t// since we cannot observe writes from other descriptors anyways.\n\t\t\t\t\tbuilder.addDecoration(id, spv::DecorationNonWritable);\n\t\t\t\t\tbuilder.addDecoration(id, spv::DecorationRestrict);\n\t\t\t\t}\n\t\t\t\telse if (vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::InputAttachment &&\n\t\t\t\t         vulkan_binding.buffer_binding.input_attachment_index != -1u)\n\t\t\t\t{\n\t\t\t\t\tbuilder.addDecoration(id, spv::DecorationInputAttachmentIndex,\n\t\t\t\t\t                      int(vulkan_binding.buffer_binding.input_attachment_index));\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tif (ref.var_id)\n\t\t\t\tdecorate_variable(ref.var_id);\n\t\t\tfor (auto &var : ref.var_alias_group)\n\t\t\t\tdecorate_variable(var.var_id);\n\n\t\t\tref.aliased = aliased_access.requires_alias_decoration;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.stride = stride;\n\t\t\tref.resource_kind = resource_kind;\n\n\t\t\t// Counteract any offsets.\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\tref.base_offset = -bind_register;\n\n\t\t\tif (ref.var_id)\n\t\t\t{\n\t\t\t\tauto &meta = handle_to_resource_meta[ref.var_id];\n\t\t\t\tmeta = {};\n\t\t\t\tmeta.kind = resource_kind;\n\t\t\t\tmeta.stride = stride;\n\t\t\t\tmeta.var_id = ref.var_id;\n\t\t\t\tmeta.storage = storage;\n\t\t\t\tmeta.component_type = actual_component_type;\n\n\t\t\t\tif (aliased_access.override_primary_component_types)\n\t\t\t\t{\n\t\t\t\t\tmeta.component_type = aliased_access.primary_component_type;\n\t\t\t\t\tmeta.raw_component_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (auto &var : ref.var_alias_group)\n\t\t\t{\n\t\t\t\tauto &meta = handle_to_resource_meta[var.var_id];\n\t\t\t\tmeta = {};\n\t\t\t\tmeta.kind = resource_kind;\n\t\t\t\tmeta.component_type = raw_width_to_component_type(var.declaration.type, var.declaration.width);\n\t\t\t\tmeta.raw_component_vecsize = var.declaration.vecsize;\n\t\t\t\tmeta.stride = stride;\n\t\t\t\tmeta.var_id = var.var_id;\n\t\t\t\tmeta.storage = storage;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::get_ssbo_offset_buffer_id(spv::Id &buffer_id,\n                                                const VulkanBinding &buffer_binding,\n                                                const VulkanBinding &offset_binding,\n                                                DXIL::ResourceKind kind, unsigned alignment)\n{\n\tbuffer_id = 0;\n\n\tbool is_buffer_type = kind == DXIL::ResourceKind::StructuredBuffer ||\n\t                      kind == DXIL::ResourceKind::RawBuffer ||\n\t                      kind == DXIL::ResourceKind::TypedBuffer;\n\tif (!is_buffer_type)\n\t\treturn true;\n\n\tbool use_offsets = false;\n\n\t// If we're emitting an SSBO where we expect small alignment, we'll need to carry forward an \"offset\".\n\tif (buffer_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t{\n\t\tif (kind != DXIL::ResourceKind::TypedBuffer && (alignment & (options.ssbo_alignment - 1)) != 0)\n\t\t{\n\t\t\tif (!buffer_binding.bindless.use_heap)\n\t\t\t{\n\t\t\t\tLOGE(\"SSBO offset is only supported for bindless SSBOs.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (offset_binding.bindless.use_heap)\n\t\t\t{\n\t\t\t\tLOGE(\"SSBO offset buffer must be a bindless buffer.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tuse_offsets = true;\n\t\t}\n\t}\n\telse if (options.bindless_typed_buffer_offsets && buffer_binding.bindless.use_heap)\n\t{\n\t\tuse_offsets = true;\n\t}\n\n\tif (use_offsets)\n\t{\n\t\tBindlessInfo bindless_info = {};\n\t\tbindless_info.descriptor_type = VulkanDescriptorType::SSBO;\n\t\tbindless_info.type = DXIL::ResourceType::SRV;\n\t\tbindless_info.offsets = true;\n\t\tbindless_info.desc_set = offset_binding.descriptor_set;\n\t\tbindless_info.binding = offset_binding.binding;\n\t\tbindless_info.component = DXIL::ComponentType::U32;\n\t\tbindless_info.kind = DXIL::ResourceKind::RawBuffer;\n\t\tbuffer_id = create_bindless_heap_variable(bindless_info);\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::get_uav_image_format(DXIL::ResourceKind resource_kind,\n                                           DXIL::ComponentType actual_component_type,\n                                           const AccessTracking &access_meta,\n                                           spv::ImageFormat &format)\n{\n\tif (resource_kind == DXIL::ResourceKind::FeedbackTexture2D ||\n\t    resource_kind == DXIL::ResourceKind::FeedbackTexture2DArray)\n\t{\n\t\tformat = spv::ImageFormatR64ui;\n\t\tbuilder().addExtension(\"SPV_EXT_shader_image_int64\");\n\t\tbuilder().addCapability(spv::CapabilityInt64ImageEXT);\n\t\treturn true;\n\t}\n\telse if (resource_kind != DXIL::ResourceKind::RawBuffer &&\n\t         resource_kind != DXIL::ResourceKind::StructuredBuffer)\n\t{\n\t\t// For any typed resource, we need to check if the resource is being read.\n\t\t// To avoid StorageReadWithoutFormat, we emit a format based on the component type.\n\t\tif (access_meta.has_read)\n\t\t{\n\t\t\tif (options.typed_uav_read_without_format && !access_meta.has_atomic)\n\t\t\t{\n\t\t\t\tbuilder().addCapability(spv::CapabilityStorageImageReadWithoutFormat);\n\t\t\t\tformat = spv::ImageFormatUnknown;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tswitch (actual_component_type)\n\t\t\t\t{\n\t\t\t\tcase DXIL::ComponentType::U32:\n\t\t\t\t\tformat = spv::ImageFormatR32ui;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL::ComponentType::I32:\n\t\t\t\t\tformat = spv::ImageFormatR32i;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL::ComponentType::F32:\n\t\t\t\t\tformat = spv::ImageFormatR32f;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL::ComponentType::U64:\n\t\t\t\t\tformat = spv::ImageFormatR64ui;\n\t\t\t\t\tbuilder().addExtension(\"SPV_EXT_shader_image_int64\");\n\t\t\t\t\tbuilder().addCapability(spv::CapabilityInt64ImageEXT);\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tLOGE(\"Reading from UAV, but component type does not conform to U32, I32, F32 or U64. \"\n\t\t\t\t\t     \"typed_uav_read_without_format option must be enabled.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_uavs(const llvm::MDNode *uavs, const llvm::MDNode *refl)\n{\n\tauto &builder = spirv_module.get_builder();\n\tunsigned num_uavs = uavs->getNumOperands();\n\n\tfor (unsigned i = 0; i < num_uavs; i++)\n\t{\n\t\tauto *uav = llvm::cast<llvm::MDNode>(uavs->getOperand(i));\n\n\t\tauto var_meta = get_resource_variable_meta(uav);\n\t\tif (!var_meta.is_active)\n\t\t\tcontinue;\n\n\t\tunsigned index = get_constant_metadata(uav, 0);\n\t\tauto name = get_resource_name_metadata(uav, refl);\n\t\tunsigned bind_space = get_constant_metadata(uav, 3);\n\t\tunsigned bind_register = get_constant_metadata(uav, 4);\n\t\tunsigned range_size = get_constant_metadata(uav, 5);\n\n\t\tif (bind_register == UINT32_MAX && bind_space == UINT32_MAX)\n\t\t{\n\t\t\t// This seems to be possible in RT shaders when explicit register() is missing?\n\t\t\tLOGE(\"Nonsensical UAV binding detected.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto resource_kind = static_cast<DXIL::ResourceKind>(get_constant_metadata(uav, 6));\n\n\t\t// Magic resource that does not actually exist.\n\t\tif (index == ags.uav_magic_resource_type_index || index == nvapi.uav_magic_resource_type_index)\n\t\t\tcontinue;\n\n\t\tbool has_counter = get_constant_metadata(uav, 8) != 0;\n\t\tbool is_rov = get_constant_metadata(uav, 9) != 0;\n\n\t\t// ROV implies coherent in Vulkan memory models.\n\t\tbool globally_coherent = get_constant_metadata(uav, 7) != 0 || is_rov;\n\n\t\tllvm::MDNode *tags = nullptr;\n\t\tif (uav->getNumOperands() >= 11 && uav->getOperand(10))\n\t\t\ttags = llvm::dyn_cast<llvm::MDNode>(uav->getOperand(10));\n\n\t\tunsigned stride = 0;\n\t\tspv::ImageFormat format = spv::ImageFormatUnknown;\n\n\t\tauto actual_component_type = DXIL::ComponentType::U32;\n\t\tauto effective_component_type = actual_component_type;\n\n\t\tauto &access_meta = uav_access_tracking[index];\n\t\tif (globally_coherent)\n\t\t\texecution_mode_meta.declares_globallycoherent_uav = true;\n\t\tif (is_rov)\n\t\t\texecution_mode_meta.declares_rov = true;\n\n\t\t// We shouldn't need this, but dxilconv is broken.\n\t\tif (access_meta.has_counter)\n\t\t\thas_counter = true;\n\n\t\t// If the shader has device-memory memory barriers, we need to support this.\n\t\t// GLSL450 memory model does not do this for us by default.\n\t\t//   coherent: memory variable where reads and writes are coherent with reads and\n\t\t//             writes from other shader invocations\n\t\t// We have two options:\n\t\t// - slap Coherent on it.\n\t\t// - Use Vulkan memory model and make use of MakeVisibleKHR/MakeAvailableKHR flags in a OpMemoryBarrier.\n\t\t//   This would flush and invalidate any incoherent caches as necessary.\n\t\t// For now, slapping coherent on all UAVs is good enough.\n\t\t// When we move to full Vulkan memory model we can do a slightly better job.\n\t\t// If no UAV actually needs globallycoherent we can demote any barriers to workgroup barriers,\n\t\t// which is hopefully more optimal if the compiler understands the intent ...\n\t\t// Only promote resources which actually need some kind of coherence.\n\t\tif (shader_analysis.require_uav_thread_group_coherence &&\n\t\t    access_meta.has_written && access_meta.has_read &&\n\t\t    execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\t{\n\t\t\tglobally_coherent = true;\n\t\t}\n\n\t\tif (resource_kind == DXIL::ResourceKind::FeedbackTexture2D ||\n\t\t    resource_kind == DXIL::ResourceKind::FeedbackTexture2DArray)\n\t\t{\n\t\t\t// 64-bit atomics make things a bit nicer.\n\t\t\tactual_component_type = DXIL::ComponentType::U64;\n\t\t\teffective_component_type = get_effective_typed_resource_type(actual_component_type);\n\t\t}\n\t\telse if (tags && get_constant_metadata(tags, 0) == 0)\n\t\t{\n\t\t\t// Sampled format.\n\t\t\tactual_component_type = normalize_component_type(static_cast<DXIL::ComponentType>(get_constant_metadata(tags, 1)));\n\t\t\tif (access_meta.has_atomic_64bit)\n\t\t\t{\n\t\t\t\t// The component type in DXIL is u32, even if the resource itself is u64 in meta reflection data ...\n\t\t\t\t// This is also the case for signed components. Always use R64UI here.\n\t\t\t\tactual_component_type = DXIL::ComponentType::U64;\n\t\t\t}\n\t\t\teffective_component_type = get_effective_typed_resource_type(actual_component_type);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Structured/Raw buffers, just use uint for good measure, we'll bitcast as needed.\n\t\t\t// Field 1 is stride, but we don't care about that unless we will support an SSBO path.\n\t\t\tformat = spv::ImageFormatR32ui;\n\t\t\tif (tags)\n\t\t\t\tstride = get_constant_metadata(tags, 1);\n\t\t}\n\n\t\tunsigned alignment = resource_kind == DXIL::ResourceKind::RawBuffer ? 16 : (stride & -int(stride));\n\n\t\tif (!get_uav_image_format(resource_kind, actual_component_type, access_meta, format))\n\t\t\treturn false;\n\n\t\tDescriptorTableEntry local_table_entry = {};\n\t\tint local_root_signature_entry = get_local_root_signature_entry(\n\t\t    ResourceClass::UAV, bind_space, bind_register, local_table_entry);\n\t\tbool need_resource_remapping = local_root_signature_entry < 0 ||\n\t\t                               local_root_signature[local_root_signature_entry].type == LocalRootSignatureType::Table;\n\n\t\tD3DUAVBinding d3d_binding = {};\n\t\td3d_binding.counter = has_counter;\n\t\td3d_binding.binding = {\n\t\t\tget_remapping_stage(execution_model), resource_kind, index, bind_space, bind_register, range_size, alignment\n\t\t};\n\t\tVulkanUAVBinding vulkan_binding = { { bind_space, bind_register }, { bind_space + 1, bind_register }, {} };\n\t\tif (need_resource_remapping && resource_mapping_iface &&\n\t\t    !resource_mapping_iface->remap_uav(d3d_binding, vulkan_binding))\n\t\t{\n\t\t\t// We may be rejected if the unbound range has 1 non-bindless descriptor.\n\t\t\tbool retry = d3d_binding.binding.range_size == UINT32_MAX;\n\t\t\tif (retry)\n\t\t\t{\n\t\t\t\td3d_binding.binding.range_size = 1;\n\t\t\t\trange_size = 1;\n\t\t\t}\n\n\t\t\tif (!retry || !resource_mapping_iface->remap_uav(d3d_binding, vulkan_binding))\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to remap UAV %u:%u.\\n\", bind_space, bind_register);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tAliasedAccess aliased_access;\n\t\tif (!analyze_aliased_access(access_meta,\n\t\t                            need_resource_remapping ?\n\t\t                            vulkan_binding.buffer_binding.descriptor_type :\n\t\t                            VulkanDescriptorType::BufferDeviceAddress, aliased_access))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tuav_index_to_reference.resize(std::max(uav_index_to_reference.size(), size_t(index + 1)));\n\t\tuav_index_to_counter.resize(std::max(uav_index_to_counter.size(), size_t(index + 1)));\n\t\tuav_index_to_offset.resize(std::max(uav_index_to_offset.size(), size_t(index + 1)));\n\n\t\tif (!get_ssbo_offset_buffer_id(uav_index_to_offset[index], vulkan_binding.buffer_binding,\n\t\t                               vulkan_binding.offset_binding, resource_kind, alignment))\n\t\t\treturn false;\n\n\t\tif (range_size != 1)\n\t\t{\n\t\t\tif (range_size == ~0u)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);\n\t\t\t}\n\n\t\t\tif (has_counter)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t\tif (vulkan_binding.counter_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityStorageBufferArrayDynamicIndexing);\n\t\t\t\telse\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT);\n\t\t\t}\n\n\t\t\tif ((resource_kind == DXIL::ResourceKind::StructuredBuffer ||\n\t\t\t     resource_kind == DXIL::ResourceKind::RawBuffer) &&\n\t\t\t    vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t{\n\t\t\t\tbuilder.addCapability(spv::CapabilityStorageBufferArrayDynamicIndexing);\n\t\t\t}\n\t\t\telse if (resource_kind == DXIL::ResourceKind::StructuredBuffer ||\n\t\t\t         resource_kind == DXIL::ResourceKind::RawBuffer ||\n\t\t\t         resource_kind == DXIL::ResourceKind::TypedBuffer)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT);\n\t\t\t}\n\t\t\telse\n\t\t\t\tbuilder.addCapability(spv::CapabilityStorageImageArrayDynamicIndexing);\n\t\t}\n\n\t\tBindlessInfo bindless_info = {};\n\t\tbindless_info.type = DXIL::ResourceType::UAV;\n\t\tbindless_info.component = effective_component_type;\n\t\tbindless_info.kind = resource_kind;\n\t\tbindless_info.desc_set = vulkan_binding.buffer_binding.descriptor_set;\n\t\tbindless_info.binding = vulkan_binding.buffer_binding.binding;\n\t\tbindless_info.format = format;\n\t\tbindless_info.uav_read = access_meta.has_read;\n\t\tbindless_info.uav_written = access_meta.has_written;\n\t\tbindless_info.uav_coherent = globally_coherent;\n\t\tbindless_info.descriptor_type = vulkan_binding.buffer_binding.descriptor_type;\n\t\tbindless_info.relaxed_precision = actual_component_type != effective_component_type &&\n\t\t                                  component_type_is_16bit(actual_component_type);\n\t\tbindless_info.debug.stride = stride;\n\n\t\t// If we emit two SSBOs which both access the same buffer, we must emit Aliased decoration to be safe.\n\t\tbindless_info.aliased = aliased_access.requires_alias_decoration;\n\n\t\tBindlessInfo counter_info = {};\n\n\t\tcounter_info.type = DXIL::ResourceType::UAV;\n\t\tcounter_info.component = DXIL::ComponentType::U32;\n\t\tcounter_info.desc_set = vulkan_binding.counter_binding.descriptor_set;\n\t\tcounter_info.binding = vulkan_binding.counter_binding.binding;\n\n\t\tif (vulkan_binding.counter_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t{\n\t\t\tcounter_info.kind = DXIL::ResourceKind::RawBuffer;\n\t\t\tcounter_info.counters = true;\n\t\t}\n\t\telse if (options.physical_storage_buffer &&\n\t\t         vulkan_binding.counter_binding.descriptor_type != VulkanDescriptorType::TexelBuffer)\n\t\t{\n\t\t\tcounter_info.kind = DXIL::ResourceKind::Invalid;\n\t\t\tcounter_info.counters = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcounter_info.kind = DXIL::ResourceKind::TypedBuffer;\n\t\t\tcounter_info.uav_read = true;\n\t\t\tcounter_info.uav_written = true;\n\t\t\tcounter_info.uav_coherent = globally_coherent;\n\t\t\tcounter_info.format = spv::ImageFormatR32ui;\n\t\t}\n\n\t\tReferenceVkMemoryModel vkmm = {};\n\n\t\tif (execution_mode_meta.memory_model == spv::MemoryModelVulkan)\n\t\t{\n\t\t\t// For UAV we just slap it on everything.\n\t\t\tvkmm.non_private = true;\n\t\t\tvkmm.auto_visibility = globally_coherent || is_rov;\n\t\t}\n\n\t\tif (local_root_signature_entry >= 0)\n\t\t{\n\t\t\tauto &entry = local_root_signature[local_root_signature_entry];\n\t\t\tif (entry.type == LocalRootSignatureType::Table)\n\t\t\t{\n\t\t\t\tif (!vulkan_binding.buffer_binding.bindless.use_heap)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Table SBT entries must be bindless.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (!var_meta.is_lib_variable)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Local root signature requires global lib variables.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tuint32_t heap_offset = local_table_entry.offset_in_heap;\n\t\t\t\theap_offset += bind_register - local_table_entry.register_index;\n\n\t\t\t\tauto &ref = uav_index_to_reference[index];\n\t\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t\t{\n\t\t\t\t\tref.var_alias_group = create_bindless_heap_variable_alias_group(\n\t\t\t\t\t\tbindless_info, aliased_access.raw_declarations);\n\t\t\t\t}\n\t\t\t\telse if (aliased_access.override_primary_component_types)\n\t\t\t\t{\n\t\t\t\t\tauto tmp_info = bindless_info;\n\t\t\t\t\ttmp_info.component = aliased_access.primary_component_type;\n\t\t\t\t\ttmp_info.raw_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\t\t\tref.var_id = create_bindless_heap_variable(tmp_info);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tref.var_id = create_bindless_heap_variable(bindless_info);\n\t\t\t\t}\n\n\t\t\t\tref.aliased = aliased_access.requires_alias_decoration;\n\t\t\t\tref.base_offset = heap_offset;\n\t\t\t\tref.stride = stride;\n\t\t\t\tref.bindless = true;\n\t\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\t\tref.local_root_signature_entry = local_root_signature_entry;\n\t\t\t\tref.resource_kind = resource_kind;\n\t\t\t\tref.vkmm = vkmm;\n\n\t\t\t\tif (has_counter)\n\t\t\t\t{\n\t\t\t\t\tif (!vulkan_binding.counter_binding.bindless.use_heap)\n\t\t\t\t\t{\n\t\t\t\t\t\tLOGE(\"Table SBT entries must be bindless.\\n\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\theap_offset = local_table_entry.offset_in_heap;\n\t\t\t\t\theap_offset += bind_register - local_table_entry.register_index;\n\t\t\t\t\tspv::Id counter_var_id = create_bindless_heap_variable(counter_info);\n\n\t\t\t\t\tauto &counter_ref = uav_index_to_counter[index];\n\t\t\t\t\tcounter_ref.var_id = counter_var_id;\n\t\t\t\t\tcounter_ref.base_offset = heap_offset;\n\t\t\t\t\tcounter_ref.stride = 4;\n\t\t\t\t\tcounter_ref.bindless = true;\n\t\t\t\t\tcounter_ref.base_resource_is_array = range_size != 1;\n\t\t\t\t\tcounter_ref.local_root_signature_entry = local_root_signature_entry;\n\t\t\t\t\t// Signals the underlying type of the counter buffer.\n\t\t\t\t\tcounter_ref.resource_kind =\n\t\t\t\t\t\tcounter_info.counters ? DXIL::ResourceKind::RawBuffer : DXIL::ResourceKind::TypedBuffer;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Otherwise, we simply refer to the SBT directly to obtain a pointer.\n\t\t\t\tif (resource_kind != DXIL::ResourceKind::RawBuffer &&\n\t\t\t\t    resource_kind != DXIL::ResourceKind::StructuredBuffer)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"UAV SBT root descriptors must be raw buffers or structures buffers.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tauto &ref = uav_index_to_reference[index];\n\t\t\t\tref.var_id = shader_record_buffer_id;\n\t\t\t\tref.stride = stride;\n\t\t\t\tref.local_root_signature_entry = local_root_signature_entry;\n\t\t\t\tref.resource_kind = resource_kind;\n\t\t\t\tref.vkmm = vkmm;\n\n\t\t\t\tif (range_size != 1)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Cannot use descriptor array for root descriptors.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::BufferDeviceAddress)\n\t\t{\n\t\t\tif (resource_kind != DXIL::ResourceKind::RawBuffer &&\n\t\t\t    resource_kind != DXIL::ResourceKind::StructuredBuffer)\n\t\t\t{\n\t\t\t\tLOGE(\"BDA root descriptors must be raw buffers or structured buffers.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tauto &ref = uav_index_to_reference[index];\n\t\t\tref.var_id = root_constant_id;\n\t\t\tref.root_descriptor = true;\n\t\t\tref.push_constant_member = vulkan_binding.buffer_binding.root_constant_index;\n\t\t\tref.coherent = globally_coherent;\n\t\t\tref.rov = is_rov;\n\t\t\tref.stride = stride;\n\t\t\tref.resource_kind = resource_kind;\n\t\t\tref.vkmm = vkmm;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t\temit_root_parameter_index_from_push_index(\"UAV\", ref.push_constant_member, 8, true);\n\n\t\t\tif (range_size != 1)\n\t\t\t{\n\t\t\t\tLOGE(\"Cannot use descriptor array for root descriptors.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse if (vulkan_binding.buffer_binding.bindless.use_heap)\n\t\t{\n\t\t\t// DXIL already applies the t# register offset to any dynamic index, so counteract that here.\n\t\t\t// The exception is with lib_* where we access resources by variable, not through\n\t\t\t// createResource() >_____<.\n\t\t\tuint32_t heap_offset = vulkan_binding.buffer_binding.bindless.heap_root_offset;\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\theap_offset -= bind_register;\n\n\t\t\tauto &ref = uav_index_to_reference[index];\n\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t{\n\t\t\t\tref.var_alias_group = create_bindless_heap_variable_alias_group(\n\t\t\t\t\tbindless_info, aliased_access.raw_declarations);\n\t\t\t}\n\t\t\telse if (aliased_access.override_primary_component_types)\n\t\t\t{\n\t\t\t\tauto tmp_info = bindless_info;\n\t\t\t\ttmp_info.component = aliased_access.primary_component_type;\n\t\t\t\ttmp_info.raw_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\t\tref.var_id = create_bindless_heap_variable(tmp_info);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tref.var_id = create_bindless_heap_variable(bindless_info);\n\t\t\t}\n\n\t\t\tref.aliased = aliased_access.requires_alias_decoration;\n\t\t\tref.push_constant_member = vulkan_binding.buffer_binding.root_constant_index + root_descriptor_count;\n\t\t\tref.base_offset = heap_offset;\n\t\t\tref.stride = stride;\n\t\t\tref.bindless = true;\n\t\t\tref.coherent = globally_coherent;\n\t\t\tref.rov = is_rov;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.resource_kind = resource_kind;\n\t\t\tref.vkmm = vkmm;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t{\n\t\t\t\temit_root_parameter_index_from_push_index(\n\t\t\t\t\t\"ResourceTable\", vulkan_binding.buffer_binding.root_constant_index, 4, false);\n\t\t\t}\n\n\t\t\tif (has_counter)\n\t\t\t{\n\t\t\t\tif (vulkan_binding.counter_binding.bindless.use_heap)\n\t\t\t\t{\n\t\t\t\t\tspv::Id counter_var_id = create_bindless_heap_variable(counter_info);\n\n\t\t\t\t\theap_offset = vulkan_binding.counter_binding.bindless.heap_root_offset;\n\t\t\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\t\t\theap_offset -= bind_register;\n\n\t\t\t\t\tauto &counter_ref = uav_index_to_counter[index];\n\t\t\t\t\tcounter_ref.var_id = counter_var_id;\n\t\t\t\t\tcounter_ref.push_constant_member = vulkan_binding.counter_binding.root_constant_index + root_descriptor_count;\n\t\t\t\t\tcounter_ref.base_offset = heap_offset;\n\t\t\t\t\tcounter_ref.stride = 4;\n\t\t\t\t\tcounter_ref.bindless = true;\n\t\t\t\t\tcounter_ref.base_resource_is_array = range_size != 1;\n\n\t\t\t\t\t// Signals the underlying type of the counter buffer.\n\t\t\t\t\tcounter_ref.resource_kind = counter_info.kind;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"If base UAV uses bindless heap, UAV counter must also do so.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tspv::Id var_id = 0;\n\t\t\tVector<RawDeclarationVariable> var_alias_group;\n\t\t\tspv::StorageClass storage;\n\n\t\t\tif (vulkan_binding.buffer_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t{\n\t\t\t\t// TODO: Consider implementing aliased buffers which all refer to the same buffer,\n\t\t\t\t// but which can exploit alignment per-instruction.\n\t\t\t\t// This is impractical, since BufferLoad/Store in DXIL does not have alignment (4 bytes is assumed),\n\t\t\t\t// so just unroll.\n\t\t\t\t// To make good use of this, we'll need apps to use SM 6.2 RawBufferLoad/Store, which does have explicit alignment.\n\t\t\t\t// We'll likely need to mess around with Aliased decoration as well, which might have other effects ...\n\n\t\t\t\tstorage = spv::StorageClassStorageBuffer;\n\n\t\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t\t\tvar_alias_group = create_raw_ssbo_variable_alias_group(aliased_access.raw_declarations, range_size, name);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tassert(aliased_access.raw_declarations.size() == 1);\n\t\t\t\t\tvar_id = create_raw_ssbo_variable(aliased_access.raw_declarations.front(), range_size, name);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Treat default as texel buffer, as it's the more compatible way of implementing buffer types in DXIL.\n\t\t\t\tauto element_type_id = get_type_id(effective_component_type, 1, 1);\n\n\t\t\t\tspv::Id type_id =\n\t\t\t\t    builder.makeImageType(element_type_id, image_dimension_from_resource_kind(resource_kind), false,\n\t\t\t\t                          image_dimension_is_arrayed(resource_kind),\n\t\t\t\t                          image_dimension_is_multisampled(resource_kind), 2, format);\n\n\t\t\t\tif (range_size != 1)\n\t\t\t\t{\n\t\t\t\t\tif (range_size == ~0u)\n\t\t\t\t\t\ttype_id = builder.makeRuntimeArray(type_id);\n\t\t\t\t\telse\n\t\t\t\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(range_size), 0);\n\t\t\t\t}\n\n\t\t\t\tstorage = spv::StorageClassUniformConstant;\n\t\t\t\tvar_id = create_variable(storage, type_id,\n\t\t\t\t                         name.empty() ? nullptr : name.c_str());\n\n\t\t\t\tif (actual_component_type != effective_component_type && component_type_is_16bit(actual_component_type))\n\t\t\t\t\tbuilder.addDecoration(var_id, spv::DecorationRelaxedPrecision);\n\t\t\t}\n\n\t\t\tauto &ref = uav_index_to_reference[index];\n\t\t\tref.var_id = var_id;\n\t\t\tref.var_alias_group = std::move(var_alias_group);\n\t\t\tref.aliased = aliased_access.requires_alias_decoration;\n\t\t\tref.stride = stride;\n\t\t\tref.coherent = globally_coherent;\n\t\t\tref.rov = is_rov;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.resource_kind = resource_kind;\n\t\t\tref.vkmm = vkmm;\n\n\t\t\t// Counteract any offsets.\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\tref.base_offset = -bind_register;\n\n\t\t\tconst auto decorate_variable = [&](spv::Id id) {\n\t\t\t\tbuilder.addDecoration(id, spv::DecorationDescriptorSet, vulkan_binding.buffer_binding.descriptor_set);\n\t\t\t\tbuilder.addDecoration(id, spv::DecorationBinding, vulkan_binding.buffer_binding.binding);\n\t\t\t\tif (!access_meta.has_read)\n\t\t\t\t\tbuilder.addDecoration(id, spv::DecorationNonReadable);\n\t\t\t\tif (!access_meta.has_written)\n\t\t\t\t\tbuilder.addDecoration(id, spv::DecorationNonWritable);\n\t\t\t\tif (globally_coherent && execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\t\t\t\tbuilder.addDecoration(id, spv::DecorationCoherent);\n\t\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t\t\tbuilder.addDecoration(id, spv::DecorationAliased);\n\t\t\t};\n\n\t\t\tif (var_id)\n\t\t\t\tdecorate_variable(var_id);\n\t\t\tfor (auto &var : ref.var_alias_group)\n\t\t\t\tdecorate_variable(var.var_id);\n\n\t\t\tspv::Id counter_var_id = 0;\n\t\t\tif (has_counter)\n\t\t\t{\n\t\t\t\tif (vulkan_binding.counter_binding.bindless.use_heap)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Cannot use bindless UAV counters along with non-bindless UAVs.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tspv::StorageClass counter_storage;\n\t\t\t\tspv::Id type_id;\n\n\t\t\t\tif (vulkan_binding.counter_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t\t{\n\t\t\t\t\tspv::Id uint_type = builder.makeUintType(32);\n\t\t\t\t\ttype_id = builder.makeStructType({ uint_type }, \"AtomicCounterSSBO\");\n\t\t\t\t\tbuilder.addDecoration(type_id, spv::DecorationBlock);\n\t\t\t\t\tbuilder.addMemberName(type_id, 0, \"counter\");\n\t\t\t\t\tbuilder.addMemberDecoration(type_id, 0, spv::DecorationOffset, 0);\n\t\t\t\t\tcounter_storage = spv::StorageClassStorageBuffer;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Treat default as texel buffer, as it's the more compatible way of implementing buffer types in DXIL.\n\t\t\t\t\tauto element_type_id = get_type_id(DXIL::ComponentType::U32, 1, 1);\n\t\t\t\t\ttype_id = builder.makeImageType(\n\t\t\t\t\t\telement_type_id, spv::DimBuffer, false, false, false, 2, format);\n\t\t\t\t\tcounter_storage = spv::StorageClassUniformConstant;\n\t\t\t\t}\n\n\t\t\t\tif (range_size != 1)\n\t\t\t\t{\n\t\t\t\t\tif (range_size == ~0u)\n\t\t\t\t\t\ttype_id = builder.makeRuntimeArray(type_id);\n\t\t\t\t\telse\n\t\t\t\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(range_size), 0);\n\t\t\t\t}\n\n\t\t\t\tcounter_var_id = create_variable(counter_storage, type_id, name.empty() ? nullptr : (name + \"Counter\").c_str());\n\n\t\t\t\tbuilder.addDecoration(counter_var_id, spv::DecorationDescriptorSet,\n\t\t\t\t                      vulkan_binding.counter_binding.descriptor_set);\n\t\t\t\tbuilder.addDecoration(counter_var_id, spv::DecorationBinding, vulkan_binding.counter_binding.binding);\n\n\t\t\t\tauto &counter_ref = uav_index_to_counter[index];\n\t\t\t\tcounter_ref.var_id = counter_var_id;\n\t\t\t\tcounter_ref.stride = 4;\n\t\t\t\tcounter_ref.base_resource_is_array = range_size != 1;\n\t\t\t\tcounter_ref.resource_kind = counter_storage == spv::StorageClassStorageBuffer ?\n\t\t\t\t\tDXIL::ResourceKind::RawBuffer : DXIL::ResourceKind::TypedBuffer;\n\t\t\t}\n\n\t\t\tif (var_id)\n\t\t\t{\n\t\t\t\tauto &meta = handle_to_resource_meta[var_id];\n\t\t\t\tmeta = {};\n\t\t\t\tmeta.kind = resource_kind;\n\t\t\t\tmeta.stride = stride;\n\t\t\t\tmeta.var_id = var_id;\n\t\t\t\tmeta.storage = storage;\n\t\t\t\tmeta.component_type = actual_component_type;\n\t\t\t\tmeta.vkmm = vkmm;\n\n\t\t\t\tif (aliased_access.override_primary_component_types)\n\t\t\t\t{\n\t\t\t\t\tmeta.component_type = aliased_access.primary_component_type;\n\t\t\t\t\tmeta.raw_component_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (auto &var : ref.var_alias_group)\n\t\t\t{\n\t\t\t\tauto &meta = handle_to_resource_meta[var.var_id];\n\t\t\t\tmeta = {};\n\t\t\t\tmeta.kind = resource_kind;\n\t\t\t\tmeta.stride = stride;\n\t\t\t\tmeta.var_id = var.var_id;\n\t\t\t\tmeta.storage = storage;\n\t\t\t\tmeta.component_type = raw_width_to_component_type(var.declaration.type, var.declaration.width);\n\t\t\t\tmeta.raw_component_vecsize = var.declaration.vecsize;\n\t\t\t\tmeta.vkmm = vkmm;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_cbvs(const llvm::MDNode *cbvs, const llvm::MDNode *refl)\n{\n\tauto &builder = spirv_module.get_builder();\n\tunsigned num_cbvs = cbvs->getNumOperands();\n\n\tfor (unsigned i = 0; i < num_cbvs; i++)\n\t{\n\t\tauto *cbv = llvm::cast<llvm::MDNode>(cbvs->getOperand(i));\n\t\tauto var_meta = get_resource_variable_meta(cbv);\n\t\tif (!var_meta.is_active)\n\t\t\tcontinue;\n\n\t\tunsigned index = get_constant_metadata(cbv, 0);\n\t\tauto name = get_resource_name_metadata(cbv, refl);\n\t\tunsigned bind_space = get_constant_metadata(cbv, 3);\n\t\tunsigned bind_register = get_constant_metadata(cbv, 4);\n\t\tunsigned range_size = get_constant_metadata(cbv, 5);\n\t\tunsigned cbv_size = get_constant_metadata(cbv, 6);\n\n\t\tif (bind_register == UINT32_MAX && bind_space == UINT32_MAX)\n\t\t{\n\t\t\t// This seems to be possible in RT shaders when explicit register() is missing?\n\t\t\tLOGE(\"Nonsensical CBV binding detected.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tDescriptorTableEntry local_table_entry = {};\n\t\tint local_root_signature_entry = get_local_root_signature_entry(\n\t\t    ResourceClass::CBV, bind_space, bind_register, local_table_entry);\n\t\tbool need_resource_remapping = local_root_signature_entry < 0 ||\n\t\t                               local_root_signature[local_root_signature_entry].type == LocalRootSignatureType::Table;\n\n\t\tD3DBinding d3d_binding = { get_remapping_stage(execution_model),\n\t\t\t                       DXIL::ResourceKind::CBuffer,\n\t\t\t                       index,\n\t\t\t                       bind_space,\n\t\t\t                       bind_register,\n\t\t\t                       range_size, 0 };\n\t\tVulkanCBVBinding vulkan_binding = {};\n\t\tvulkan_binding.buffer = { bind_space, bind_register };\n\t\tif (need_resource_remapping && resource_mapping_iface &&\n\t\t    !resource_mapping_iface->remap_cbv(d3d_binding, vulkan_binding))\n\t\t{\n\t\t\t// We may be rejected if the unbound range has 1 non-bindless descriptor.\n\t\t\tbool retry = d3d_binding.range_size == UINT32_MAX;\n\t\t\tif (retry)\n\t\t\t{\n\t\t\t\td3d_binding.range_size = 1;\n\t\t\t\trange_size = 1;\n\t\t\t}\n\n\t\t\tif (!retry || !resource_mapping_iface->remap_cbv(d3d_binding, vulkan_binding))\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to remap CBV %u:%u.\\n\", bind_space, bind_register);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tauto &access_meta = cbv_access_tracking[index];\n\t\tAliasedAccess aliased_access;\n\t\tif (!analyze_aliased_access(access_meta, VulkanDescriptorType::UBO, aliased_access))\n\t\t\treturn false;\n\n\t\tcbv_index_to_reference.resize(std::max(cbv_index_to_reference.size(), size_t(index + 1)));\n\n\t\tif (range_size != 1)\n\t\t{\n\t\t\tif (range_size == ~0u)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);\n\t\t\t}\n\n\t\t\tif (vulkan_binding.buffer.bindless.use_heap && options.bindless_cbv_ssbo_emulation)\n\t\t\t\tbuilder.addCapability(spv::CapabilityStorageBufferArrayDynamicIndexing);\n\t\t\telse\n\t\t\t\tbuilder.addCapability(spv::CapabilityUniformBufferArrayDynamicIndexing);\n\t\t}\n\n\t\tBindlessInfo bindless_info = {};\n\t\tbindless_info.type = DXIL::ResourceType::CBV;\n\t\tbindless_info.kind = DXIL::ResourceKind::CBuffer;\n\t\tbindless_info.desc_set = vulkan_binding.buffer.descriptor_set;\n\t\tbindless_info.binding = vulkan_binding.buffer.binding;\n\t\tbindless_info.component = aliased_access.primary_component_type;\n\t\tbindless_info.raw_vecsize = aliased_access.primary_raw_vecsize;\n\n\t\tif (local_root_signature_entry >= 0)\n\t\t{\n\t\t\tauto &entry = local_root_signature[local_root_signature_entry];\n\t\t\tif (entry.type == LocalRootSignatureType::Table)\n\t\t\t{\n\t\t\t\tif (!vulkan_binding.buffer.bindless.use_heap)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Table SBT entries must be bindless.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tuint32_t heap_offset = local_table_entry.offset_in_heap;\n\t\t\t\theap_offset += bind_register - local_table_entry.register_index;\n\n\t\t\t\tif (!var_meta.is_lib_variable)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Local root signature requires global lib variables.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tauto &ref = cbv_index_to_reference[index];\n\n\t\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t\t{\n\t\t\t\t\tref.var_alias_group = create_bindless_heap_variable_alias_group(\n\t\t\t\t\t\t\tbindless_info, aliased_access.raw_declarations);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tref.var_id = create_bindless_heap_variable(bindless_info);\n\t\t\t\t}\n\n\t\t\t\tref.base_offset = heap_offset;\n\t\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\t\tref.bindless = true;\n\t\t\t\tref.local_root_signature_entry = local_root_signature_entry;\n\t\t\t\tref.resource_kind = DXIL::ResourceKind::CBuffer;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto &ref = cbv_index_to_reference[index];\n\t\t\t\tref.var_id = shader_record_buffer_id;\n\t\t\t\tref.local_root_signature_entry = local_root_signature_entry;\n\t\t\t\tref.resource_kind = DXIL::ResourceKind::CBuffer;\n\n\t\t\t\tif (range_size != 1)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Cannot use descriptor array for root descriptors.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (vulkan_binding.push_constant)\n\t\t{\n\t\t\tif (root_constant_id == 0)\n\t\t\t{\n\t\t\t\tLOGE(\"Must have setup push constant block to use root constant path.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tauto &ref = cbv_index_to_reference[index];\n\t\t\tref.var_id = root_constant_id;\n\t\t\tref.push_constant_member = vulkan_binding.push.offset_in_words + root_descriptor_count;\n\t\t\tref.resource_kind = DXIL::ResourceKind::CBuffer;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t\temit_root_parameter_index_from_push_index(\"Constant\", vulkan_binding.push.offset_in_words, cbv_size, false);\n\t\t}\n\t\telse if (vulkan_binding.buffer.descriptor_type == VulkanDescriptorType::BufferDeviceAddress)\n\t\t{\n\t\t\tauto &ref = cbv_index_to_reference[index];\n\t\t\tref.var_id = root_constant_id;\n\t\t\tref.root_descriptor = true;\n\t\t\tref.push_constant_member = vulkan_binding.buffer.root_constant_index;\n\t\t\tref.resource_kind = DXIL::ResourceKind::CBuffer;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t\temit_root_parameter_index_from_push_index(\"CBV\", ref.push_constant_member, 8, true);\n\n\t\t\tif (range_size != 1)\n\t\t\t{\n\t\t\t\tLOGE(\"Cannot use descriptor array for root descriptors.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse if (vulkan_binding.buffer.bindless.use_heap)\n\t\t{\n\t\t\t// DXIL already applies the t# register offset to any dynamic index, so counteract that here.\n\t\t\t// The exception is with lib_* where we access resources by variable, not through\n\t\t\t// createResource() >_____<.\n\t\t\tuint32_t heap_offset = vulkan_binding.buffer.bindless.heap_root_offset;\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\theap_offset -= bind_register;\n\n\t\t\tauto &ref = cbv_index_to_reference[index];\n\n\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t{\n\t\t\t\tref.var_alias_group = create_bindless_heap_variable_alias_group(\n\t\t\t\t\t\tbindless_info, aliased_access.raw_declarations);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tref.var_id = create_bindless_heap_variable(bindless_info);\n\t\t\t}\n\n\t\t\tref.push_constant_member = vulkan_binding.buffer.root_constant_index + root_descriptor_count;\n\t\t\tref.base_offset = heap_offset;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.bindless = true;\n\t\t\tref.resource_kind = DXIL::ResourceKind::CBuffer;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t\temit_root_parameter_index_from_push_index(\"ResourceTable\", vulkan_binding.buffer.root_constant_index, 4, false);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto &ref = cbv_index_to_reference[index];\n\n\t\t\tif (aliased_access.requires_alias_decoration)\n\t\t\t{\n\t\t\t\tref.var_alias_group = create_ubo_variable_alias_group(\n\t\t\t\t\t\taliased_access.raw_declarations, range_size, name, cbv_size);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tassert(aliased_access.raw_declarations.size() == 1);\n\t\t\t\tref.var_id = create_ubo_variable(aliased_access.raw_declarations.front(), range_size, name, cbv_size);\n\t\t\t}\n\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.resource_kind = DXIL::ResourceKind::CBuffer;\n\n\t\t\t// Counteract any offsets.\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\tref.base_offset = -bind_register;\n\n\t\t\tif (ref.var_id)\n\t\t\t{\n\t\t\t\tauto &meta = handle_to_resource_meta[ref.var_id];\n\t\t\t\tmeta = {};\n\t\t\t\tmeta.kind = ref.resource_kind;\n\t\t\t\tmeta.var_id = ref.var_id;\n\t\t\t\tmeta.storage = spv::StorageClassUniform;\n\t\t\t\tmeta.component_type = aliased_access.primary_component_type;\n\t\t\t\tmeta.raw_component_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\t\tbuilder.addDecoration(meta.var_id, spv::DecorationDescriptorSet, vulkan_binding.buffer.descriptor_set);\n\t\t\t\tbuilder.addDecoration(meta.var_id, spv::DecorationBinding, vulkan_binding.buffer.binding);\n\t\t\t}\n\n\t\t\tfor (auto &var : ref.var_alias_group)\n\t\t\t{\n\t\t\t\tauto &meta = handle_to_resource_meta[var.var_id];\n\t\t\t\tmeta = {};\n\t\t\t\tmeta.kind = ref.resource_kind;\n\t\t\t\tmeta.var_id = var.var_id;\n\t\t\t\tmeta.storage = spv::StorageClassUniform;\n\t\t\t\tmeta.component_type = raw_width_to_component_type(var.declaration.type, var.declaration.width);\n\t\t\t\tmeta.raw_component_vecsize = var.declaration.vecsize;\n\t\t\t\tbuilder.addDecoration(meta.var_id, spv::DecorationDescriptorSet, vulkan_binding.buffer.descriptor_set);\n\t\t\t\tbuilder.addDecoration(meta.var_id, spv::DecorationBinding, vulkan_binding.buffer.binding);\n\t\t\t}\n\n            if (options.extended_non_semantic_info)\n            {\n                emit_root_parameter_index_from_push_index(\"PushCBV\",\n                        Converter::pack_desc_set_binding_to_virtual_offset(\n                                vulkan_binding.buffer.descriptor_set, vulkan_binding.buffer.binding), 0, false);\n            }\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_samplers(const llvm::MDNode *samplers, const llvm::MDNode *refl)\n{\n\tauto &builder = spirv_module.get_builder();\n\tunsigned num_samplers = samplers->getNumOperands();\n\n\tfor (unsigned i = 0; i < num_samplers; i++)\n\t{\n\t\tauto *sampler = llvm::cast<llvm::MDNode>(samplers->getOperand(i));\n\n\t\tauto var_meta = get_resource_variable_meta(sampler);\n\t\tif (!var_meta.is_active)\n\t\t\tcontinue;\n\n\t\tunsigned index = get_constant_metadata(sampler, 0);\n\t\tauto name = get_resource_name_metadata(sampler, refl);\n\t\tunsigned bind_space = get_constant_metadata(sampler, 3);\n\t\tunsigned bind_register = get_constant_metadata(sampler, 4);\n\t\tunsigned range_size = get_constant_metadata(sampler, 5);\n\n\t\tif (bind_register == UINT32_MAX && bind_space == UINT32_MAX)\n\t\t{\n\t\t\t// This seems to be possible in RT shaders when explicit register() is missing?\n\t\t\tLOGE(\"Nonsensical Sampler binding detected.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (range_size != 1)\n\t\t{\n\t\t\tif (range_size == ~0u)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);\n\t\t\t}\n\n\t\t\t// This capability also covers samplers.\n\t\t\tbuilder.addCapability(spv::CapabilitySampledImageArrayDynamicIndexing);\n\t\t}\n\n\t\tDescriptorTableEntry local_table_entry = {};\n\t\tint local_root_signature_entry = get_local_root_signature_entry(\n\t\t\tResourceClass::Sampler, bind_space, bind_register, local_table_entry);\n\t\tbool need_resource_remapping = local_root_signature_entry < 0 ||\n\t\t                               local_root_signature[local_root_signature_entry].type == LocalRootSignatureType::Table;\n\n\t\tD3DBinding d3d_binding = { get_remapping_stage(execution_model),\n\t\t\t                       DXIL::ResourceKind::Sampler,\n\t\t\t                       index,\n\t\t\t                       bind_space,\n\t\t\t                       bind_register,\n\t\t\t                       range_size, 0 };\n\t\tVulkanBinding vulkan_binding = { bind_space, bind_register };\n\t\tif (need_resource_remapping && resource_mapping_iface &&\n\t\t    !resource_mapping_iface->remap_sampler(d3d_binding, vulkan_binding))\n\t\t{\n\t\t\t// We may be rejected if the unbound range has 1 non-bindless descriptor.\n\t\t\tbool retry = d3d_binding.range_size == UINT32_MAX;\n\t\t\tif (retry)\n\t\t\t{\n\t\t\t\td3d_binding.range_size = 1;\n\t\t\t\trange_size = 1;\n\t\t\t}\n\n\t\t\tif (!retry || !resource_mapping_iface->remap_sampler(d3d_binding, vulkan_binding))\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to remap sampler %u:%u.\\n\", bind_space, bind_register);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tsampler_index_to_reference.resize(std::max(sampler_index_to_reference.size(), size_t(index + 1)));\n\n\t\tBindlessInfo bindless_info = {};\n\t\tbindless_info.type = DXIL::ResourceType::Sampler;\n\t\tbindless_info.kind = DXIL::ResourceKind::Sampler;\n\t\tbindless_info.desc_set = vulkan_binding.descriptor_set;\n\t\tbindless_info.binding = vulkan_binding.binding;\n\n\t\tif (local_root_signature_entry >= 0)\n\t\t{\n\t\t\t// Samplers can only live in table entries.\n\t\t\tif (!vulkan_binding.bindless.use_heap)\n\t\t\t{\n\t\t\t\tLOGE(\"Table SBT entries must be bindless.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tspv::Id var_id = create_bindless_heap_variable(bindless_info);\n\n\t\t\tuint32_t heap_offset = local_table_entry.offset_in_heap;\n\t\t\theap_offset += bind_register - local_table_entry.register_index;\n\n\t\t\tif (!var_meta.is_lib_variable)\n\t\t\t{\n\t\t\t\tLOGE(\"Local root signature requires global lib variables.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tauto &ref = sampler_index_to_reference[index];\n\t\t\tref.var_id = var_id;\n\t\t\tref.base_offset = heap_offset;\n\t\t\tref.bindless = true;\n\t\t\tref.local_root_signature_entry = local_root_signature_entry;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.resource_kind = DXIL::ResourceKind::Sampler;\n\t\t}\n\t\telse if (vulkan_binding.bindless.use_heap)\n\t\t{\n\t\t\tspv::Id var_id = create_bindless_heap_variable(bindless_info);\n\n\t\t\t// DXIL already applies the t# register offset to any dynamic index, so counteract that here.\n\t\t\t// The exception is with lib_* where we access resources by variable, not through\n\t\t\t// createResource() >_____<.\n\t\t\tuint32_t heap_offset = vulkan_binding.bindless.heap_root_offset;\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\theap_offset -= bind_register;\n\n\t\t\tauto &ref = sampler_index_to_reference[index];\n\t\t\tref.var_id = var_id;\n\t\t\tref.push_constant_member = vulkan_binding.root_constant_index + root_descriptor_count;\n\t\t\tref.base_offset = heap_offset;\n\t\t\tref.bindless = true;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.resource_kind = DXIL::ResourceKind::Sampler;\n\n\t\t\tif (options.extended_non_semantic_info)\n\t\t\t\temit_root_parameter_index_from_push_index(\"SamplerTable\", vulkan_binding.root_constant_index, 4, false);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tspv::Id type_id = builder.makeSamplerType();\n\n\t\t\tif (range_size != 1)\n\t\t\t{\n\t\t\t\tif (range_size == ~0u)\n\t\t\t\t\ttype_id = builder.makeRuntimeArray(type_id);\n\t\t\t\telse\n\t\t\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(range_size), 0);\n\t\t\t}\n\n\t\t\tspv::Id var_id = create_variable(spv::StorageClassUniformConstant, type_id, name.empty() ? nullptr : name.c_str());\n\n\t\t\tbuilder.addDecoration(var_id, spv::DecorationDescriptorSet, vulkan_binding.descriptor_set);\n\t\t\tbuilder.addDecoration(var_id, spv::DecorationBinding, vulkan_binding.binding);\n\n\t\t\tauto &ref = sampler_index_to_reference[index];\n\t\t\tref.var_id = var_id;\n\t\t\tref.base_resource_is_array = range_size != 1;\n\t\t\tref.resource_kind = DXIL::ResourceKind::Sampler;\n\n\t\t\t// Counteract any offsets.\n\t\t\tif (range_size != 1 && !var_meta.is_lib_variable)\n\t\t\t\tref.base_offset = -bind_register;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::scan_srvs(ResourceRemappingInterface *iface, const llvm::MDNode *srvs, ShaderStage stage)\n{\n\tunsigned num_srvs = srvs->getNumOperands();\n\tfor (unsigned i = 0; i < num_srvs; i++)\n\t{\n\t\tauto *srv = llvm::cast<llvm::MDNode>(srvs->getOperand(i));\n\t\tunsigned index = get_constant_metadata(srv, 0);\n\t\tunsigned bind_space = get_constant_metadata(srv, 3);\n\t\tunsigned bind_register = get_constant_metadata(srv, 4);\n\t\tunsigned range_size = get_constant_metadata(srv, 5);\n\t\tauto resource_kind = static_cast<DXIL::ResourceKind>(get_constant_metadata(srv, 6));\n\n\t\tD3DBinding d3d_binding = { stage, resource_kind, index, bind_space, bind_register, range_size };\n\t\tVulkanSRVBinding vulkan_binding = {};\n\t\tif (iface && !iface->remap_srv(d3d_binding, vulkan_binding))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::scan_samplers(ResourceRemappingInterface *iface, const llvm::MDNode *samplers, ShaderStage stage)\n{\n\tunsigned num_samplers = samplers->getNumOperands();\n\tfor (unsigned i = 0; i < num_samplers; i++)\n\t{\n\t\tauto *sampler = llvm::cast<llvm::MDNode>(samplers->getOperand(i));\n\t\tunsigned index = get_constant_metadata(sampler, 0);\n\t\tunsigned bind_space = get_constant_metadata(sampler, 3);\n\t\tunsigned bind_register = get_constant_metadata(sampler, 4);\n\t\tunsigned range_size = get_constant_metadata(sampler, 5);\n\n\t\tD3DBinding d3d_binding = { stage, DXIL::ResourceKind::Sampler, index, bind_space, bind_register, range_size };\n\t\tVulkanBinding vulkan_binding = {};\n\t\tif (iface && !iface->remap_sampler(d3d_binding, vulkan_binding))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::scan_cbvs(ResourceRemappingInterface *iface, const llvm::MDNode *cbvs, ShaderStage stage)\n{\n\tunsigned num_cbvs = cbvs->getNumOperands();\n\tfor (unsigned i = 0; i < num_cbvs; i++)\n\t{\n\t\tauto *cbv = llvm::cast<llvm::MDNode>(cbvs->getOperand(i));\n\t\tunsigned index = get_constant_metadata(cbv, 0);\n\t\tunsigned bind_space = get_constant_metadata(cbv, 3);\n\t\tunsigned bind_register = get_constant_metadata(cbv, 4);\n\t\tunsigned range_size = get_constant_metadata(cbv, 5);\n\n\t\tD3DBinding d3d_binding = { stage, DXIL::ResourceKind::CBuffer, index, bind_space, bind_register, range_size };\n\t\tVulkanCBVBinding vulkan_binding = {};\n\t\tif (iface && !iface->remap_cbv(d3d_binding, vulkan_binding))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::scan_uavs(ResourceRemappingInterface *iface, const llvm::MDNode *uavs, ShaderStage stage)\n{\n\tunsigned num_uavs = uavs->getNumOperands();\n\tfor (unsigned i = 0; i < num_uavs; i++)\n\t{\n\t\tauto *uav = llvm::cast<llvm::MDNode>(uavs->getOperand(i));\n\t\tunsigned index = get_constant_metadata(uav, 0);\n\t\tunsigned bind_space = get_constant_metadata(uav, 3);\n\t\tunsigned bind_register = get_constant_metadata(uav, 4);\n\t\tunsigned range_size = get_constant_metadata(uav, 5);\n\t\tauto resource_kind = static_cast<DXIL::ResourceKind>(get_constant_metadata(uav, 6));\n\t\tbool has_counter = get_constant_metadata(uav, 8) != 0;\n\n\t\tD3DUAVBinding d3d_binding = { { stage, resource_kind, index, bind_space, bind_register, range_size },\n\t\t\t                          has_counter };\n\t\tVulkanUAVBinding vulkan_binding = {};\n\t\tif (iface && !iface->remap_uav(d3d_binding, vulkan_binding))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::require_arrayed_root_constants() const\n{\n\tif (!resource_mapping_iface)\n\t\treturn false;\n\n\tauto &module = bitcode_parser.get_module();\n\tauto *resource_meta = module.getNamedMetadata(\"dx.resources\");\n\tif (!resource_meta)\n\t\treturn false;\n\n\tauto *metas = resource_meta->getOperand(0);\n\tif (!metas->getOperand(2))\n\t\treturn false;\n\n\tauto *cbvs = llvm::dyn_cast<llvm::MDNode>(metas->getOperand(2));\n\tif (!cbvs)\n\t\treturn false;\n\n\tunsigned num_cbvs = cbvs->getNumOperands();\n\tfor (unsigned i = 0; i < num_cbvs; i++)\n\t{\n\t\tauto *cbv = llvm::cast<llvm::MDNode>(cbvs->getOperand(i));\n\t\tauto var_meta = get_resource_variable_meta(cbv);\n\t\tif (!var_meta.is_active)\n\t\t\tcontinue;\n\n\t\tunsigned index = get_constant_metadata(cbv, 0);\n\n\t\tauto itr = cbv_access_tracking.find(index);\n\t\tif (itr == cbv_access_tracking.end())\n\t\t\tcontinue;\n\n\t\tunsigned bind_space = get_constant_metadata(cbv, 3);\n\t\tunsigned bind_register = get_constant_metadata(cbv, 4);\n\n\t\tDescriptorTableEntry local_table_entry = {};\n\t\tint local_root_signature_entry = get_local_root_signature_entry(\n\t\t    ResourceClass::CBV, bind_space, bind_register, local_table_entry);\n\t\tif (local_root_signature_entry >= 0)\n\t\t\tcontinue;\n\n\t\tD3DBinding d3d_binding = { get_remapping_stage(execution_model),\n\t\t\t                       DXIL::ResourceKind::CBuffer,\n\t\t\t                       index,\n\t\t\t                       bind_space,\n\t\t\t                       bind_register,\n\t\t\t                       UINT32_MAX, 0 };\n\t\tVulkanCBVBinding vulkan_binding = {};\n\t\tvulkan_binding.buffer = { bind_space, bind_register };\n\t\tif (!resource_mapping_iface->remap_cbv(d3d_binding, vulkan_binding))\n\t\t\tcontinue;\n\t\tif (!vulkan_binding.push_constant)\n\t\t\tcontinue;\n\n\t\tif (itr->second.dynamically_indexed_cbv)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nvoid Converter::Impl::emit_root_constants(unsigned num_descriptors, unsigned num_constant_words)\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tbool array_root_constants = require_arrayed_root_constants();\n\n\t// Root constants cannot be dynamically indexed in DXIL, so emit them as members.\n\tVector<spv::Id> members((array_root_constants ? 1 : num_constant_words) + num_descriptors);\n\n\t// Emit root descriptors as u32x2 to work around missing SGPR promotion on RADV.\n\tfor (unsigned i = 0; i < num_descriptors; i++)\n\t\tmembers[i] = builder.makeVectorType(builder.makeUintType(32), 2);\n\n\tif (array_root_constants)\n\t{\n\t\tspv::Id type_id = builder.makeUintType(32);\n\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(num_constant_words), 4);\n\t\tbuilder.addDecoration(type_id, spv::DecorationArrayStride, 4);\n\t\tmembers[num_descriptors] = type_id;\n\t}\n\telse\n\t{\n\t\tfor (unsigned i = 0; i < num_constant_words; i++)\n\t\t\tmembers[i + num_descriptors] = builder.makeUintType(32);\n\t}\n\n\tspv::Id type_id = get_struct_type(members, 0, \"RootConstants\");\n\tbuilder.addDecoration(type_id, spv::DecorationBlock);\n\n\tfor (unsigned i = 0; i < num_descriptors; i++)\n\t\tbuilder.addMemberDecoration(type_id, i, spv::DecorationOffset, sizeof(uint64_t) * i);\n\n\tfor (unsigned i = 0; i < (array_root_constants ? 1 : num_constant_words); i++)\n\t{\n\t\tbuilder.addMemberDecoration(type_id, i + num_descriptors, spv::DecorationOffset,\n\t\t                            sizeof(uint64_t) * num_descriptors + sizeof(uint32_t) * i);\n\t}\n\n\tif (array_root_constants)\n\t\tbuilder.addMemberName(type_id, num_descriptors, \"root_constants_and_tables\");\n\n\tif (options.inline_ubo_enable)\n\t{\n\t\troot_constant_id = create_variable(spv::StorageClassUniform, type_id, \"registers\");\n\t\tbuilder.addDecoration(root_constant_id, spv::DecorationDescriptorSet, options.inline_ubo_descriptor_set);\n\t\tbuilder.addDecoration(root_constant_id, spv::DecorationBinding, options.inline_ubo_descriptor_binding);\n\t}\n\telse\n\t\troot_constant_id = create_variable(spv::StorageClassPushConstant, type_id, \"registers\");\n\n\troot_descriptor_count = num_descriptors;\n\troot_constant_num_words = num_constant_words;\n\troot_constant_arrayed = array_root_constants;\n}\n\nstatic bool execution_model_is_ray_tracing(spv::ExecutionModel model)\n{\n\tswitch (model)\n\t{\n\tcase spv::ExecutionModelRayGenerationKHR:\n\tcase spv::ExecutionModelCallableKHR:\n\tcase spv::ExecutionModelIntersectionKHR:\n\tcase spv::ExecutionModelMissKHR:\n\tcase spv::ExecutionModelClosestHitKHR:\n\tcase spv::ExecutionModelAnyHitKHR:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nspv::Id Converter::Impl::emit_shader_record_buffer_block_type(bool physical_storage)\n{\n\tif (local_root_signature.empty())\n\t\treturn 0;\n\n\tauto &builder = spirv_module.get_builder();\n\n\tspv::Id type_id;\n\tVector<spv::Id> member_types;\n\tVector<uint32_t> offsets;\n\tmember_types.reserve(local_root_signature.size());\n\toffsets.reserve(local_root_signature.size());\n\tshader_record_buffer_types.reserve(local_root_signature.size());\n\n\tuint32_t current_offset = 0;\n\tfor (auto &elem : local_root_signature)\n\t{\n\t\tswitch (elem.type)\n\t\t{\n\t\tcase LocalRootSignatureType::Constants:\n\t\t{\n\t\t\tspv::Id array_size_id = builder.makeUintConstant(elem.constants.num_words);\n\t\t\tspv::Id u32_type = builder.makeUintType(32);\n\t\t\tspv::Id member_type_id =\n\t\t\t    builder.makeArrayType(u32_type, array_size_id, 4);\n\t\t\tbuilder.addDecoration(member_type_id, spv::DecorationArrayStride, 4);\n\t\t\tmember_types.push_back(member_type_id);\n\t\t\toffsets.push_back(current_offset);\n\t\t\tcurrent_offset += 4 * elem.constants.num_words;\n\t\t\tshader_record_buffer_types.push_back(member_type_id);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase LocalRootSignatureType::Descriptor:\n\t\t{\n\t\t\t// A 64-bit integer which we will bitcast to a physical storage buffer later.\n\t\t\t// Emit it as u32x2 as otherwise we don't get SGPR promotion on ACO as of right now.\n\t\t\tspv::Id member_type_id = builder.makeVectorType(builder.makeUintType(32), 2);\n\t\t\tmember_types.push_back(member_type_id);\n\t\t\tcurrent_offset = (current_offset + 7) & ~7;\n\t\t\toffsets.push_back(current_offset);\n\t\t\tcurrent_offset += 8;\n\t\t\tshader_record_buffer_types.push_back(member_type_id);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase LocalRootSignatureType::Table:\n\t\t{\n\t\t\tspv::Id member_type_id = builder.makeVectorType(builder.makeUintType(32), 2);\n\t\t\tmember_types.push_back(member_type_id);\n\t\t\tcurrent_offset = (current_offset + 7) & ~7;\n\t\t\toffsets.push_back(current_offset);\n\t\t\tcurrent_offset += 8;\n\t\t\tshader_record_buffer_types.push_back(member_type_id);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n\n\ttype_id = get_struct_type(member_types, 0, \"SBTBlock\");\n\tbuilder.addDecoration(type_id, spv::DecorationBlock);\n\n\tfor (size_t i = 0; i < local_root_signature.size(); i++)\n\t{\n\t\tbuilder.addMemberDecoration(type_id, i, spv::DecorationOffset, offsets[i]);\n\t\tif (physical_storage)\n\t\t\tbuilder.addMemberDecoration(type_id, i, spv::DecorationNonWritable);\n\t}\n\n\treturn type_id;\n}\n\nbool Converter::Impl::emit_shader_record_buffer()\n{\n\tspv::Id type_id = emit_shader_record_buffer_block_type(false);\n\tif (type_id)\n\t\tshader_record_buffer_id = create_variable(spv::StorageClassShaderRecordBufferKHR, type_id, \"SBT\");\n\treturn true;\n}\n\nstatic bool local_root_signature_matches(const LocalRootSignatureEntry &entry,\n                                         ResourceClass resource_class,\n                                         uint32_t space, uint32_t binding,\n                                         DescriptorTableEntry &local_table_entry)\n{\n\tswitch (entry.type)\n\t{\n\tcase LocalRootSignatureType::Constants:\n\t\treturn resource_class == ResourceClass::CBV &&\n\t\t       entry.constants.register_space == space &&\n\t\t       entry.constants.register_index == binding;\n\n\tcase LocalRootSignatureType::Descriptor:\n\t\treturn entry.descriptor.type == resource_class &&\n\t\t       entry.descriptor.register_space == space &&\n\t\t       entry.descriptor.register_index == binding;\n\n\tcase LocalRootSignatureType::Table:\n\t\tfor (auto &table_entry : entry.table_entries)\n\t\t{\n\t\t\tif (table_entry.type == resource_class && table_entry.register_space == space &&\n\t\t\t    table_entry.register_index <= binding &&\n\t\t\t    ((table_entry.num_descriptors_in_range == ~0u) ||\n\t\t\t     ((binding - table_entry.register_index) < table_entry.num_descriptors_in_range)))\n\t\t\t{\n\t\t\t\tlocal_table_entry = table_entry;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nint Converter::Impl::get_local_root_signature_entry(ResourceClass resource_class, uint32_t space, uint32_t binding,\n                                                    DescriptorTableEntry &local_table_entry) const\n{\n\tauto itr = std::find_if(local_root_signature.begin(), local_root_signature.end(), [&](const LocalRootSignatureEntry &entry) {\n\t\treturn local_root_signature_matches(entry, resource_class, space, binding, local_table_entry);\n\t});\n\n\tif (itr != local_root_signature.end())\n\t\treturn int(itr - local_root_signature.begin());\n\telse\n\t\treturn -1;\n}\n\nbool Converter::Impl::emit_resources_global_mapping()\n{\n\tauto &module = bitcode_parser.get_module();\n\tauto *resource_meta = module.getNamedMetadata(\"dx.resources\");\n\tif (!resource_meta)\n\t\treturn true;\n\n\tauto *metas = resource_meta->getOperand(0);\n\n\tif (metas->getOperand(0))\n\t\tif (!emit_resources_global_mapping(DXIL::ResourceType::SRV, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(0))))\n\t\t\treturn false;\n\tif (metas->getOperand(1))\n\t\tif (!emit_resources_global_mapping(DXIL::ResourceType::UAV, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(1))))\n\t\t\treturn false;\n\tif (metas->getOperand(2))\n\t\tif (!emit_resources_global_mapping(DXIL::ResourceType::CBV, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(2))))\n\t\t\treturn false;\n\tif (metas->getOperand(3))\n\t\tif (!emit_resources_global_mapping(DXIL::ResourceType::Sampler, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(3))))\n\t\t\treturn false;\n\n\treturn true;\n}\n\nvoid Converter::Impl::get_shader_model(const llvm::Module &module, String *model, uint32_t *major, uint32_t *minor)\n{\n\tauto *resource_meta = module.getNamedMetadata(\"dx.shaderModel\");\n\tif (!resource_meta)\n\t{\n\t\tif (major)\n\t\t\t*major = 6;\n\t\tif (minor)\n\t\t\t*minor = 0;\n\t\tif (model)\n\t\t\tmodel->clear();\n\t}\n\telse\n\t{\n\t\tauto *meta = resource_meta->getOperand(0);\n\n\t\tif (model)\n\t\t\t*model = get_string_metadata(meta, 0);\n\t\tif (major)\n\t\t\t*major = get_constant_metadata(meta, 1);\n\t\tif (minor)\n\t\t\t*minor = get_constant_metadata(meta, 2);\n\t}\n}\n\nConverter::Impl::RawBufferMeta\nConverter::Impl::get_raw_buffer_meta(DXIL::ResourceType resource_type, unsigned meta_index)\n{\n\tauto &module = bitcode_parser.get_module();\n\tauto *resource_meta = module.getNamedMetadata(\"dx.resources\");\n\tif (!resource_meta)\n\t\treturn { DXIL::ResourceKind::Invalid, 0 };\n\n\tauto *metas = resource_meta->getOperand(0);\n\tauto &resource_list = metas->getOperand(uint32_t(resource_type));\n\tif (!resource_list)\n\t\treturn { DXIL::ResourceKind::Invalid, 0 };\n\n\tauto *entries = llvm::cast<llvm::MDNode>(resource_list);\n\tunsigned num_entries = entries->getNumOperands();\n\tfor (unsigned i = 0; i < num_entries; i++)\n\t{\n\t\tauto *entry = llvm::cast<llvm::MDNode>(entries->getOperand(i));\n\t\tif (get_constant_metadata(entry, 0) == meta_index)\n\t\t{\n\t\t\tRawBufferMeta meta = {};\n\t\t\tmeta.kind = DXIL::ResourceKind(get_constant_metadata(entry, 6));\n\n\t\t\tunsigned tag_index = resource_type == DXIL::ResourceType::SRV ? 8 : 10;\n\n\t\t\tllvm::MDNode *tags = nullptr;\n\t\t\tif (entry->getNumOperands() > tag_index && entry->getOperand(tag_index))\n\t\t\t\ttags = llvm::dyn_cast<llvm::MDNode>(entry->getOperand(tag_index));\n\t\t\tif (tags)\n\t\t\t\tmeta.stride = get_constant_metadata(tags, 1);\n\t\t\treturn meta;\n\t\t}\n\t}\n\n\treturn { DXIL::ResourceKind::Invalid, 0 };\n}\n\nuint32_t Converter::Impl::find_binding_meta_index(uint32_t binding_range_lo, uint32_t binding_range_hi,\n                                                  uint32_t binding_space, DXIL::ResourceType resource_type)\n{\n\tauto &module = bitcode_parser.get_module();\n\tauto *resource_meta = module.getNamedMetadata(\"dx.resources\");\n\tif (!resource_meta)\n\t\treturn UINT32_MAX;\n\n\tauto *metas = resource_meta->getOperand(0);\n\tauto &resource_list = metas->getOperand(uint32_t(resource_type));\n\tif (!resource_list)\n\t\treturn UINT32_MAX;\n\n\tauto *entries = llvm::cast<llvm::MDNode>(resource_list);\n\tunsigned num_entries = entries->getNumOperands();\n\tfor (unsigned i = 0; i < num_entries; i++)\n\t{\n\t\tauto *entry = llvm::cast<llvm::MDNode>(entries->getOperand(i));\n\t\tuint32_t index = get_constant_metadata(entry, 0);\n\t\tuint32_t bind_space = get_constant_metadata(entry, 3);\n\t\tuint32_t bind_register = get_constant_metadata(entry, 4);\n\t\tuint32_t range_size = get_constant_metadata(entry, 5);\n\n\t\tif (binding_space != bind_space)\n\t\t\tcontinue;\n\n\t\tif (binding_range_lo >= bind_register &&\n\t\t    (range_size == UINT32_MAX || (binding_range_hi < bind_register + range_size)))\n\t\t{\n\t\t\treturn index;\n\t\t}\n\t}\n\n\treturn UINT32_MAX;\n}\n\nbool Converter::Impl::emit_descriptor_heap_size_ubo()\n{\n\tspv::Id u32_type = builder().makeUintType(32);\n\tspv::Id block_type = builder().makeStructType({ u32_type }, \"DescriptorHeapSizeUBO\");\n\tbuilder().addMemberName(block_type, 0, \"count\");\n\tbuilder().addDecoration(block_type, spv::DecorationBlock);\n\tbuilder().addMemberDecoration(block_type, 0, spv::DecorationOffset, 0);\n\n\tauto &mapping = options.meta_descriptor_mappings[int(MetaDescriptor::ResourceDescriptorHeapSize)];\n\tspv::Id var_id = create_variable(spv::StorageClassUniform, block_type, \"DescriptorHeapSize\");\n\tbuilder().addDecoration(var_id, spv::DecorationDescriptorSet, mapping.desc_set);\n\tbuilder().addDecoration(var_id, spv::DecorationBinding, mapping.desc_binding);\n\n\tinstrumentation.descriptor_heap_size_var_id = var_id;\n\treturn true;\n}\n\nbool Converter::Impl::emit_descriptor_heap_introspection_buffer()\n{\n\tif (instrumentation.descriptor_heap_introspection_var_id != 0)\n\t\treturn true;\n\n\t// We need to know the size of the descriptor heap. Rather than passing this\n\t// through a separate descriptor, we can just query the SSBO size of the\n\t// side-band SSBO. It is designed to have a size equal to the descriptor heap.\n\t// Somewhat hacky is that we can ask for a global heap of RTAS, which gets us this descriptor.\n\tVulkanSRVBinding vulkan_binding = {};\n\n\tauto &mapping = options.meta_descriptor_mappings[int(MetaDescriptor::RawDescriptorHeapView)];\n\n\tif (mapping.kind != MetaDescriptorKind::ReadonlySSBO &&\n\t    mapping.kind != MetaDescriptorKind::UBOContainingBDA &&\n\t    mapping.kind != MetaDescriptorKind::Invalid)\n\t\treturn false;\n\n\tbool use_full_descriptor = mapping.kind != MetaDescriptorKind::UBOContainingBDA;\n\n\tif (mapping.kind == MetaDescriptorKind::Invalid)\n\t{\n\t\t// Legacy proxy. The RTAS heap does what we want in the legacy model.\n\t\tD3DBinding d3d_binding = {\n\t\t\tget_remapping_stage(execution_model),\n\t\t\tDXIL::ResourceKind::RTAccelerationStructure,\n\t\t\t0,\n\t\t\tUINT32_MAX,\n\t\t\tUINT32_MAX,\n\t\t\tUINT32_MAX,\n\t\t\t0,\n\t\t};\n\n\t\tif (!resource_mapping_iface->remap_srv(d3d_binding, vulkan_binding))\n\t\t\treturn false;\n\n\t\tif (vulkan_binding.buffer_binding.descriptor_type != VulkanDescriptorType::SSBO &&\n\t\t    vulkan_binding.buffer_binding.descriptor_type != VulkanDescriptorType::Identity)\n\t\t{\n\t\t\tLOGE(\"Dummy SSBO must be an SSBO.\\n\");\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tvulkan_binding.buffer_binding.descriptor_set = mapping.desc_set;\n\t\tvulkan_binding.buffer_binding.binding = mapping.desc_binding;\n\t}\n\n\tif (options.physical_address_descriptor_stride == 0)\n\t{\n\t\tLOGE(\"physical_address_descriptor_stride must be set.\\n\");\n\t\treturn false;\n\t}\n\n\tspv::Id u32_type = builder().makeUintType(32);\n\tuint32_t elems = options.physical_address_descriptor_stride;\n\n\tif (options.instruction_instrumentation.enabled || !use_full_descriptor)\n\t\tu32_type = builder().makeVectorType(u32_type, 2);\n\telse\n\t\telems *= 2;\n\n\tspv::Id u32_array_type = builder().makeArrayType(u32_type, builder().makeUintConstant(elems), 0);\n\tbuilder().addDecoration(u32_array_type, spv::DecorationArrayStride,\n\t                        options.instruction_instrumentation.enabled || !use_full_descriptor ? 8 : 4);\n\n\tspv::Id inner_struct_type = get_struct_type({ u32_array_type }, 0, \"DescriptorHeapRawPayload\");\n\tbuilder().addMemberDecoration(inner_struct_type, 0, spv::DecorationOffset, 0);\n\n\tspv::Id inner_struct_array_type = builder().makeRuntimeArray(inner_struct_type);\n\tbuilder().addDecoration(inner_struct_array_type, spv::DecorationArrayStride,\n\t                        8u * options.physical_address_descriptor_stride);\n\n\tbool sync_val =\n\t\toptions.instruction_instrumentation.enabled &&\n\t\toptions.instruction_instrumentation.type == InstructionInstrumentationType::BufferSynchronizationValidation;\n\n\tspv::Id block_type_id = get_struct_type(\n\t\t{ inner_struct_array_type }, 0, use_full_descriptor ? \"DescriptorHeapRobustnessSSBO\" : \"DescriptorHeapRawBlock\");\n\tbuilder().addDecoration(block_type_id, spv::DecorationBlock);\n\tbuilder().addMemberDecoration(block_type_id, 0, spv::DecorationOffset, 0);\n\tif (!sync_val)\n\t{\n\t\tbuilder().addMemberDecoration(block_type_id, 0, spv::DecorationNonWritable);\n\t\tif (use_full_descriptor)\n\t\t\tbuilder().addMemberDecoration(block_type_id, 0, spv::DecorationNonReadable);\n\t}\n\tbuilder().addMemberName(block_type_id, 0, \"descriptors\");\n\n\tspv::Id var_id;\n\tif (use_full_descriptor)\n\t{\n\t\tvar_id = create_variable(spv::StorageClassStorageBuffer, block_type_id, \"DescriptorHeapRobustness\");\n\t}\n\telse\n\t{\n\t\t// Wrap the descriptor as a plain BDA.\n\t\tspv::Id ptr_type = builder().makePointer(spv::StorageClassPhysicalStorageBuffer, block_type_id);\n\t\tspv::Id ubo_block_type = builder().makeStructType({ ptr_type }, \"DescriptorHeapRawPayloadPtr\");\n\t\tbuilder().addMemberName(ubo_block_type, 0, \"ptr\");\n\t\tbuilder().addMemberDecoration(ubo_block_type, 0, spv::DecorationOffset, 0);\n\t\tbuilder().addDecoration(ubo_block_type, spv::DecorationBlock);\n\n\t\tvar_id = create_variable(spv::StorageClassUniform, ubo_block_type, \"DescriptorHeapRaw\");\n\t\tinstrumentation.descriptor_heap_introspection_block_ptr_type_id = ptr_type;\n\t}\n\n\tbuilder().addDecoration(var_id, spv::DecorationDescriptorSet, vulkan_binding.buffer_binding.descriptor_set);\n\tbuilder().addDecoration(var_id, spv::DecorationBinding, vulkan_binding.buffer_binding.binding);\n\n\tinstrumentation.descriptor_heap_introspection_var_id = var_id;\n\tinstrumentation.descriptor_heap_introspection_is_bda = !use_full_descriptor;\n\n\tif (sync_val)\n\t{\n\t\tinstrumentation.invocation_id_var_id =\n\t\t\tcreate_variable(spv::StorageClassPrivate, builder().makeUintType(32), \"InvocationID\");\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_global_heaps()\n{\n\tVector<AnnotateHandleReference *> annotations;\n\tfor (auto &use : llvm_annotate_handle_uses)\n\t\tannotations.push_back(&use.second);\n\n\t// Ensure reproducible codegen since we iterate over an unordered map.\n\tstd::sort(annotations.begin(), annotations.end(),\n\t          [](const AnnotateHandleReference *a, const AnnotateHandleReference *b) {\n\t              return a->ordinal < b->ordinal;\n\t          });\n\n\tfor (auto *annotation : annotations)\n\t{\n\t\tBindlessInfo info = {};\n\n\t\tauto actual_component_type = DXIL::ComponentType::U32;\n\t\tinfo.format = spv::ImageFormatUnknown;\n\t\tif (annotation->resource_type != DXIL::ResourceType::CBV &&\n\t\t    annotation->resource_kind != DXIL::ResourceKind::RawBuffer &&\n\t\t    annotation->resource_kind != DXIL::ResourceKind::StructuredBuffer)\n\t\t{\n\t\t\tactual_component_type = normalize_component_type(annotation->component_type);\n\t\t\tif (annotation->tracking.has_atomic_64bit)\n\t\t\t{\n\t\t\t\t// The component type in DXIL is u32, even if the resource itself is u64 in meta reflection data ...\n\t\t\t\t// This is also the case for signed components. Always use R64UI here.\n\t\t\t\tactual_component_type = DXIL::ComponentType::U64;\n\t\t\t}\n\t\t}\n\t\telse if (annotation->resource_type == DXIL::ResourceType::UAV)\n\t\t{\n\t\t\tinfo.format = spv::ImageFormatR32ui;\n\t\t}\n\n\t\tauto effective_component_type = get_effective_typed_resource_type(actual_component_type);\n\n\t\tinfo.type = annotation->resource_type;\n\t\tinfo.component = effective_component_type;\n\t\tinfo.kind = annotation->resource_kind;\n\t\tinfo.relaxed_precision = actual_component_type != effective_component_type &&\n\t\t                         component_type_is_16bit(actual_component_type);\n\n\t\tif (info.type == DXIL::ResourceType::UAV)\n\t\t{\n\t\t\t// See emit_uavs() for details around coherent and memory model shenanigans ...\n\t\t\tif (annotation->coherent)\n\t\t\t\texecution_mode_meta.declares_globallycoherent_uav = true;\n\t\t\tif (annotation->rov)\n\t\t\t\texecution_mode_meta.declares_rov = true;\n\n\t\t\t// Do not attempt to track read and write here to figure out if this resource in particular needs to be coherent.\n\t\t\t// It's plausible that the write and read can happen across\n\t\t\t// two different accesses to ResourceDescriptorHeap[]. Don't take any chances here ...\n\t\t\tif (shader_analysis.require_uav_thread_group_coherence &&\n\t\t\t    execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\t\t{\n\t\t\t\tannotation->coherent = true;\n\t\t\t}\n\n\t\t\tif (annotation->resource_kind == DXIL::ResourceKind::StructuredBuffer ||\n\t\t\t    annotation->resource_kind == DXIL::ResourceKind::RawBuffer)\n\t\t\t{\n\t\t\t\t// In case there is aliasing through different declarations,\n\t\t\t\t// we cannot emit NonWritable or NonReadable safely. Assume full read-write.\n\t\t\t\t// Be a bit careful with typed resources since it's not always supported with read-write + typed.\n\t\t\t\tannotation->tracking.has_read = true;\n\t\t\t\tannotation->tracking.has_written = true;\n\t\t\t}\n\n\t\t\tinfo.uav_coherent = annotation->coherent || annotation->rov;\n\t\t\tinfo.uav_read = annotation->tracking.has_read;\n\t\t\tinfo.uav_written = annotation->tracking.has_written;\n\t\t\tif (!get_uav_image_format(annotation->resource_kind, actual_component_type,\n\t\t\t                          annotation->tracking, info.format))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tunsigned stride = annotation->stride;\n\t\tunsigned alignment = info.kind == DXIL::ResourceKind::RawBuffer ? 16 : (stride & -int(stride));\n\t\tD3DBinding d3d_binding = {\n\t\t\tget_remapping_stage(execution_model), info.kind, 0,\n\t\t\tUINT32_MAX, UINT32_MAX, UINT32_MAX, alignment,\n\t\t};\n\t\tVulkanBinding vulkan_binding = {};\n\n\t\tbool remap_success = false;\n\t\tif (resource_mapping_iface)\n\t\t{\n\t\t\tswitch (info.type)\n\t\t\t{\n\t\t\tcase DXIL::ResourceType::SRV:\n\t\t\t{\n\t\t\t\tVulkanSRVBinding vulkan_srv_binding = {};\n\t\t\t\tremap_success = resource_mapping_iface->remap_srv(d3d_binding, vulkan_srv_binding);\n\t\t\t\tvulkan_binding = vulkan_srv_binding.buffer_binding;\n\t\t\t\tif (!get_ssbo_offset_buffer_id(annotation->offset_buffer_id, vulkan_srv_binding.buffer_binding,\n\t\t\t\t                               vulkan_srv_binding.offset_binding, annotation->resource_kind, alignment))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase DXIL::ResourceType::UAV:\n\t\t\t{\n\t\t\t\tVulkanUAVBinding vulkan_uav_binding = {};\n\t\t\t\tD3DUAVBinding d3d_uav_binding = {};\n\n\t\t\t\td3d_uav_binding.binding = d3d_binding;\n\t\t\t\td3d_uav_binding.counter = annotation->counter;\n\n\t\t\t\tremap_success = resource_mapping_iface->remap_uav(d3d_uav_binding, vulkan_uav_binding);\n\t\t\t\tvulkan_binding = vulkan_uav_binding.buffer_binding;\n\t\t\t\tif (!get_ssbo_offset_buffer_id(annotation->offset_buffer_id, vulkan_uav_binding.buffer_binding,\n\t\t\t\t\t\t\t\t\t\t\t   vulkan_uav_binding.offset_binding, annotation->resource_kind, alignment))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (annotation->counter)\n\t\t\t\t{\n\t\t\t\t\tauto &counter_binding = vulkan_uav_binding.counter_binding;\n\t\t\t\t\tBindlessInfo counter_info = {};\n\n\t\t\t\t\tannotation->counter_reference.base_resource_is_array = true;\n\t\t\t\t\tannotation->counter_reference.push_constant_member = UINT32_MAX;\n\t\t\t\t\tannotation->counter_reference.stride = 4;\n\t\t\t\t\tannotation->counter_reference.bindless = true;\n\n\t\t\t\t\tcounter_info.type = DXIL::ResourceType::UAV;\n\t\t\t\t\tcounter_info.component = DXIL::ComponentType::U32;\n\t\t\t\t\tcounter_info.desc_set = counter_binding.descriptor_set;\n\t\t\t\t\tcounter_info.binding = counter_binding.binding;\n\n\t\t\t\t\tif (counter_binding.descriptor_type == VulkanDescriptorType::SSBO)\n\t\t\t\t\t{\n\t\t\t\t\t\tcounter_info.kind = DXIL::ResourceKind::RawBuffer;\n\t\t\t\t\t\tcounter_info.counters = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (options.physical_storage_buffer &&\n\t\t\t\t\t         counter_binding.descriptor_type != VulkanDescriptorType::TexelBuffer)\n\t\t\t\t\t{\n\t\t\t\t\t\tcounter_info.kind = DXIL::ResourceKind::Invalid;\n\t\t\t\t\t\tcounter_info.counters = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcounter_info.kind = DXIL::ResourceKind::TypedBuffer;\n\t\t\t\t\t\tcounter_info.uav_read = true;\n\t\t\t\t\t\tcounter_info.uav_written = true;\n\t\t\t\t\t\tcounter_info.uav_coherent = false;\n\t\t\t\t\t\tcounter_info.format = spv::ImageFormatR32ui;\n\t\t\t\t\t}\n\n\t\t\t\t\tannotation->counter_reference.resource_kind = counter_info.kind;\n\t\t\t\t\tannotation->counter_reference.var_id = create_bindless_heap_variable(counter_info);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase DXIL::ResourceType::CBV:\n\t\t\t{\n\t\t\t\tVulkanCBVBinding vulkan_cbv_binding = {};\n\t\t\t\tremap_success = resource_mapping_iface->remap_cbv(d3d_binding, vulkan_cbv_binding);\n\t\t\t\tif (vulkan_cbv_binding.push_constant)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Cannot use push constants for SM 6.6 bindless.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tvulkan_binding = vulkan_cbv_binding.buffer;\n\t\t\t\tvulkan_binding.descriptor_type = VulkanDescriptorType::UBO;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase DXIL::ResourceType::Sampler:\n\t\t\t\tremap_success = resource_mapping_iface->remap_sampler(d3d_binding, vulkan_binding);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!remap_success)\n\t\t\treturn false;\n\n\t\tif (!vulkan_binding.bindless.use_heap)\n\t\t{\n\t\t\tLOGE(\"SM 6.6 bindless references must be bindless.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tAliasedAccess aliased_access;\n\t\tif (!analyze_aliased_access(annotation->tracking, vulkan_binding.descriptor_type, aliased_access))\n\t\t\treturn false;\n\n\t\tinfo.desc_set = vulkan_binding.descriptor_set;\n\t\tinfo.binding = vulkan_binding.binding;\n\t\tinfo.descriptor_type = vulkan_binding.descriptor_type;\n\t\tinfo.aliased = aliased_access.requires_alias_decoration;\n\t\tinfo.debug.stride = annotation->stride;\n\n\t\tannotation->reference.bindless = true;\n\t\tannotation->reference.base_resource_is_array = true;\n\t\tannotation->reference.push_constant_member = UINT32_MAX;\n\t\tannotation->reference.stride = annotation->stride;\n\t\tannotation->reference.resource_kind = annotation->resource_kind;\n\t\tannotation->reference.coherent = annotation->coherent || annotation->rov;\n\t\tannotation->reference.rov = annotation->rov;\n\n\t\tif (execution_mode_meta.memory_model == spv::MemoryModelVulkan)\n\t\t{\n\t\t\tannotation->reference.vkmm.non_private = info.type == DXIL::ResourceType::UAV;\n\t\t\tannotation->reference.vkmm.auto_visibility = annotation->coherent || annotation->rov;\n\t\t}\n\n\t\tif (aliased_access.requires_alias_decoration)\n\t\t{\n\t\t\tannotation->reference.var_alias_group = create_bindless_heap_variable_alias_group(\n\t\t\t    info, aliased_access.raw_declarations);\n\t\t}\n\t\telse if (aliased_access.override_primary_component_types)\n\t\t{\n\t\t\tauto tmp_info = info;\n\t\t\ttmp_info.component = aliased_access.primary_component_type;\n\t\t\ttmp_info.raw_vecsize = aliased_access.primary_raw_vecsize;\n\t\t\tannotation->reference.var_id = create_bindless_heap_variable(tmp_info);\n\t\t}\n\t\telse\n\t\t\tannotation->reference.var_id = create_bindless_heap_variable(info);\n\n\t\tannotation->reference.aliased = aliased_access.requires_alias_decoration;\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_ray_query_globals()\n{\n\tif (shader_analysis.ray_query.uses_non_direct_indexing)\n\t{\n\t\tauto &b = builder();\n\t\tspv::Id type_id = b.makeRayQueryType();\n\t\tif (shader_analysis.ray_query.uses_divergent_handles)\n\t\t{\n\t\t\ttype_id = b.makeArrayType(\n\t\t\t\ttype_id, b.makeUintConstant(shader_analysis.ray_query.num_ray_query_alloca), 0);\n\t\t}\n\n\t\tray_query.global_query_objects_id = create_variable(spv::StorageClassPrivate, type_id, \"RayQueryHeap\");\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_resources()\n{\n\tunsigned num_root_descriptors = 0;\n\tunsigned num_root_constant_words = 0;\n\n\tif (resource_mapping_iface)\n\t{\n\t\tnum_root_descriptors = resource_mapping_iface->get_root_descriptor_count();\n\t\tnum_root_constant_words = resource_mapping_iface->get_root_constant_word_count();\n\t}\n\n\tif (num_root_constant_words != 0 || num_root_descriptors != 0)\n\t\temit_root_constants(num_root_descriptors, num_root_constant_words);\n\n\tif (execution_model_is_ray_tracing(execution_model))\n\t\tif (!emit_shader_record_buffer())\n\t\t\treturn false;\n\n\tif (!emit_global_heaps())\n\t\treturn false;\n\n\tif (options.descriptor_heap_robustness)\n\t{\n\t\tauto &mapping = options.meta_descriptor_mappings[int(MetaDescriptor::ResourceDescriptorHeapSize)];\n\t\tif (mapping.kind == MetaDescriptorKind::UBOContainingConstant)\n\t\t{\n\t\t\t// Use legacy path.\n\t\t\tif (!emit_descriptor_heap_size_ubo())\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!emit_descriptor_heap_introspection_buffer())\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (options.instruction_instrumentation.enabled &&\n\t    (options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume ||\n\t     options.instruction_instrumentation.type == InstructionInstrumentationType::BufferSynchronizationValidation))\n\t{\n\t\t// Failure is not a big deal.\n\t\temit_descriptor_heap_introspection_buffer();\n\t}\n\n\tauto &module = bitcode_parser.get_module();\n\tauto *resource_meta = module.getNamedMetadata(\"dx.resources\");\n\tif (!resource_meta)\n\t\treturn true;\n\n\tauto *metas = resource_meta->getOperand(0);\n\n\tllvm::MDNode *reflection_metas = nullptr;\n\tif (bitcode_reflection_parser)\n\t{\n\t\tauto &reflection_module = bitcode_reflection_parser->get_module();\n\t\tauto *reflection_resource_meta = reflection_module.getNamedMetadata(\"dx.resources\");\n\t\tif (reflection_resource_meta)\n\t\t\treflection_metas = reflection_resource_meta->getOperand(0);\n\t}\n\n\tconst llvm::MDNode *reflection_type_metas[4] = {};\n\tconst llvm::MDNode *type_metas[4] = {};\n\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\tif (metas->getOperand(i))\n\t\t{\n\t\t\ttype_metas[i] = llvm::dyn_cast<llvm::MDNode>(metas->getOperand(i));\n\t\t\tif (reflection_metas)\n\t\t\t\treflection_type_metas[i] = llvm::dyn_cast<llvm::MDNode>(reflection_metas->getOperand(i));\n\t\t}\n\t}\n\n\tif (type_metas[0])\n\t\tif (!emit_srvs(type_metas[0], reflection_type_metas[0]))\n\t\t\treturn false;\n\tif (type_metas[1])\n\t\tif (!emit_uavs(type_metas[1], reflection_type_metas[1]))\n\t\t\treturn false;\n\tif (type_metas[2])\n\t\tif (!emit_cbvs(type_metas[2], reflection_type_metas[2]))\n\t\t\treturn false;\n\tif (type_metas[3])\n\t\tif (!emit_samplers(type_metas[3], reflection_type_metas[3]))\n\t\t\treturn false;\n\n\tfor (auto &alloc : alloca_tracking)\n\t{\n\t\t// Now that we have emitted resources, we can determine which alloca -> CBV punchthroughs to accept.\n\t\tif (!analyze_alloca_cbv_forwarding_post_resource_emit(*this, alloc.second))\n\t\t\treturn false;\n\t}\n\n\tif (!emit_ray_query_globals())\n\t\treturn false;\n\n\treturn true;\n}\n\nvoid Converter::Impl::scan_resources(ResourceRemappingInterface *iface, const LLVMBCParser &bitcode_parser)\n{\n\tauto &module = bitcode_parser.get_module();\n\tauto *resource_meta = module.getNamedMetadata(\"dx.resources\");\n\tif (!resource_meta)\n\t\treturn;\n\n\tauto *metas = resource_meta->getOperand(0);\n\tauto stage = get_shader_stage(bitcode_parser);\n\n\tif (metas->getOperand(0))\n\t\tif (!scan_srvs(iface, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(0)), stage))\n\t\t\treturn;\n\tif (metas->getOperand(1))\n\t\tif (!scan_uavs(iface, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(1)), stage))\n\t\t\treturn;\n\tif (metas->getOperand(2))\n\t\tif (!scan_cbvs(iface, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(2)), stage))\n\t\t\treturn;\n\tif (metas->getOperand(3))\n\t\tif (!scan_samplers(iface, llvm::dyn_cast<llvm::MDNode>(metas->getOperand(3)), stage))\n\t\t\treturn;\n}\n\nShaderStage Converter::Impl::get_remapping_stage(spv::ExecutionModel execution_model)\n{\n\tswitch (execution_model)\n\t{\n\tcase spv::ExecutionModelVertex:\n\t\treturn ShaderStage::Vertex;\n\tcase spv::ExecutionModelTessellationControl:\n\t\treturn ShaderStage::Hull;\n\tcase spv::ExecutionModelTessellationEvaluation:\n\t\treturn ShaderStage::Domain;\n\tcase spv::ExecutionModelGeometry:\n\t\treturn ShaderStage::Geometry;\n\tcase spv::ExecutionModelFragment:\n\t\treturn ShaderStage::Pixel;\n\tcase spv::ExecutionModelGLCompute:\n\t\treturn ShaderStage::Compute;\n\tcase spv::ExecutionModelIntersectionKHR:\n\t\treturn ShaderStage::Intersection;\n\tcase spv::ExecutionModelClosestHitKHR:\n\t\treturn ShaderStage::ClosestHit;\n\tcase spv::ExecutionModelMissKHR:\n\t\treturn ShaderStage::Miss;\n\tcase spv::ExecutionModelAnyHitKHR:\n\t\treturn ShaderStage::AnyHit;\n\tcase spv::ExecutionModelRayGenerationKHR:\n\t\treturn ShaderStage::RayGeneration;\n\tcase spv::ExecutionModelCallableKHR:\n\t\treturn ShaderStage::Callable;\n\tcase spv::ExecutionModelTaskEXT:\n\t\treturn ShaderStage::Amplification;\n\tcase spv::ExecutionModelMeshEXT:\n\t\treturn ShaderStage::Mesh;\n\tdefault:\n\t\treturn ShaderStage::Unknown;\n\t}\n}\n\nstatic inline float half_to_float(uint16_t u16_value)\n{\n\t// Based on the GLM implementation.\n\tint s = (u16_value >> 15) & 0x1;\n\tint e = (u16_value >> 10) & 0x1f;\n\tint m = (u16_value >> 0) & 0x3ff;\n\n\tunion {\n\t\tfloat f32;\n\t\tuint32_t u32;\n\t} u;\n\n\tif (e == 0)\n\t{\n\t\tif (m == 0)\n\t\t{\n\t\t\tu.u32 = uint32_t(s) << 31;\n\t\t\treturn u.f32;\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile ((m & 0x400) == 0)\n\t\t\t{\n\t\t\t\tm <<= 1;\n\t\t\t\te--;\n\t\t\t}\n\n\t\t\te++;\n\t\t\tm &= ~0x400;\n\t\t}\n\t}\n\telse if (e == 31)\n\t{\n\t\tif (m == 0)\n\t\t{\n\t\t\tu.u32 = (uint32_t(s) << 31) | 0x7f800000u;\n\t\t\treturn u.f32;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tu.u32 = (uint32_t(s) << 31) | 0x7f800000u | (m << 13);\n\t\t\treturn u.f32;\n\t\t}\n\t}\n\n\te += 127 - 15;\n\tm <<= 13;\n\tu.u32 = (uint32_t(s) << 31) | (e << 23) | m;\n\treturn u.f32;\n}\n\nspv::Id Converter::Impl::get_padded_constant_array(spv::Id padded_type_id, const llvm::Constant *constant)\n{\n\tauto &builder = spirv_module.get_builder();\n\tassert(constant->getType()->getTypeID() == llvm::Type::TypeID::ArrayTyID);\n\tVector<spv::Id> constituents;\n\n\tif (llvm::isa<llvm::ConstantAggregateZero>(constant))\n\t{\n\t\treturn builder.makeNullConstant(padded_type_id);\n\t}\n\telse if (auto *agg = llvm::dyn_cast<llvm::ConstantAggregate>(constant))\n\t{\n\t\tconstituents.reserve(agg->getNumOperands() + 1);\n\t\tfor (unsigned i = 0; i < agg->getNumOperands(); i++)\n\t\t{\n\t\t\tllvm::Constant *c = agg->getOperand(i);\n\t\t\tif (const auto *undef = llvm::dyn_cast<llvm::UndefValue>(c))\n\t\t\t\tconstituents.push_back(get_id_for_undef_constant(undef));\n\t\t\telse\n\t\t\t\tconstituents.push_back(get_id_for_constant(c, 0));\n\t\t}\n\t}\n\telse if (auto *array = llvm::dyn_cast<llvm::ConstantDataArray>(constant))\n\t{\n\t\tconstituents.reserve(array->getType()->getArrayNumElements() + 1);\n\t\tfor (unsigned i = 0; i < array->getNumElements(); i++)\n\t\t{\n\t\t\tllvm::Constant *c = array->getElementAsConstant(i);\n\t\t\tif (const auto *undef = llvm::dyn_cast<llvm::UndefValue>(c))\n\t\t\t\tconstituents.push_back(get_id_for_undef_constant(undef));\n\t\t\telse\n\t\t\t\tconstituents.push_back(get_id_for_constant(c, 0));\n\t\t}\n\t}\n\telse\n\t\treturn 0;\n\n\tconstituents.push_back(builder.makeNullConstant(get_type_id(constant->getType()->getArrayElementType())));\n\treturn builder.makeCompositeConstant(padded_type_id, constituents);\n}\n\nspv::Id Converter::Impl::get_id_for_constant(const llvm::Constant *constant, unsigned forced_width)\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tswitch (constant->getType()->getTypeID())\n\t{\n\tcase llvm::Type::TypeID::HalfTyID:\n\t{\n\t\tauto *fp = llvm::cast<llvm::ConstantFP>(constant);\n\t\tauto f16 = uint16_t(fp->getValueAPF().bitcastToAPInt().getZExtValue());\n\n\t\tif (support_native_fp16_operations())\n\t\t\treturn builder.makeFloat16Constant(f16);\n\t\telse\n\t\t\treturn builder.makeFloatConstant(half_to_float(f16));\n\t}\n\n\tcase llvm::Type::TypeID::FloatTyID:\n\t{\n\t\tauto *fp = llvm::cast<llvm::ConstantFP>(constant);\n\t\treturn builder.makeFloatConstant(fp->getValueAPF().convertToFloat());\n\t}\n\n\tcase llvm::Type::TypeID::DoubleTyID:\n\t{\n\t\tauto *fp = llvm::cast<llvm::ConstantFP>(constant);\n\t\treturn builder.makeDoubleConstant(fp->getValueAPF().convertToDouble());\n\t}\n\n\tcase llvm::Type::TypeID::IntegerTyID:\n\t{\n\t\tunsigned integer_width = forced_width ? forced_width : constant->getType()->getIntegerBitWidth();\n\t\tint physical_width = physical_integer_bit_width(integer_width);\n\t\tswitch (physical_width)\n\t\t{\n\t\tcase 1:\n\t\t\treturn builder.makeBoolConstant(constant->getUniqueInteger().getZExtValue() != 0);\n\n\t\tcase 16:\n\t\t\treturn builder.makeUint16Constant(constant->getUniqueInteger().getZExtValue());\n\n\t\tcase 32:\n\t\t\treturn builder.makeUintConstant(constant->getUniqueInteger().getZExtValue());\n\n\t\tcase 64:\n\t\t\treturn builder.makeUint64Constant(constant->getUniqueInteger().getZExtValue());\n\n\t\tdefault:\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tcase llvm::Type::TypeID::VectorTyID:\n\tcase llvm::Type::TypeID::ArrayTyID:\n\tcase llvm::Type::TypeID::StructTyID:\n\t{\n\t\tVector<spv::Id> constituents;\n\t\tspv::Id type_id = get_type_id(constant->getType());\n\n\t\tif (llvm::isa<llvm::ConstantAggregateZero>(constant))\n\t\t{\n\t\t\treturn builder.makeNullConstant(type_id);\n\t\t}\n\t\telse if (auto *agg = llvm::dyn_cast<llvm::ConstantAggregate>(constant))\n\t\t{\n\t\t\tconstituents.reserve(agg->getNumOperands());\n\t\t\tfor (unsigned i = 0; i < agg->getNumOperands(); i++)\n\t\t\t{\n\t\t\t\tllvm::Constant *c = agg->getOperand(i);\n\t\t\t\tif (const auto *undef = llvm::dyn_cast<llvm::UndefValue>(c))\n\t\t\t\t\tconstituents.push_back(get_id_for_undef_constant(undef));\n\t\t\t\telse\n\t\t\t\t\tconstituents.push_back(get_id_for_constant(c, 0));\n\t\t\t}\n\t\t}\n\t\telse if (auto *array = llvm::dyn_cast<llvm::ConstantDataArray>(constant))\n\t\t{\n\t\t\tconstituents.reserve(array->getType()->getArrayNumElements());\n\t\t\tfor (unsigned i = 0; i < array->getNumElements(); i++)\n\t\t\t{\n\t\t\t\tllvm::Constant *c = array->getElementAsConstant(i);\n\t\t\t\tif (const auto *undef = llvm::dyn_cast<llvm::UndefValue>(c))\n\t\t\t\t\tconstituents.push_back(get_id_for_undef_constant(undef));\n\t\t\t\telse\n\t\t\t\t\tconstituents.push_back(get_id_for_constant(c, 0));\n\t\t\t}\n\t\t}\n\t\telse if (auto *vec = llvm::dyn_cast<llvm::ConstantDataVector>(constant))\n\t\t{\n\t\t\tconstituents.reserve(vec->getType()->getVectorNumElements());\n\t\t\tfor (unsigned i = 0; i < vec->getNumElements(); i++)\n\t\t\t{\n\t\t\t\tllvm::Constant *c = vec->getElementAsConstant(i);\n\t\t\t\tif (const auto *undef = llvm::dyn_cast<llvm::UndefValue>(c))\n\t\t\t\t\tconstituents.push_back(get_id_for_undef_constant(undef));\n\t\t\t\telse\n\t\t\t\t\tconstituents.push_back(get_id_for_constant(c, 0));\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\treturn 0;\n\n\t\treturn builder.makeCompositeConstant(type_id, constituents);\n\t}\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nspv::Id Converter::Impl::get_id_for_undef(const llvm::UndefValue *undef)\n{\n\tauto &builder = spirv_module.get_builder();\n\tif (shader_analysis.global_undefs)\n\t\treturn builder.createUndefinedConstant(get_type_id(undef->getType()));\n\telse\n\t\treturn builder.createUndefined(get_type_id(undef->getType()));\n}\n\nspv::Id Converter::Impl::get_id_for_undef_constant(const llvm::UndefValue *undef)\n{\n\tauto &builder = spirv_module.get_builder();\n\treturn builder.createUndefinedConstant(get_type_id(undef->getType()));\n}\n\nspv::Id Converter::Impl::get_id_for_value(const llvm::Value *value, unsigned forced_width)\n{\n\tassert(value);\n\n\t// Constant expressions must be stamped out every place it is used,\n\t// since it technically lives at global scope.\n\t// Do not cache this value in the value map.\n\tif (auto *cexpr = llvm::dyn_cast<llvm::ConstantExpr>(value))\n\t\treturn build_constant_expression(*this, cexpr);\n\n\tauto itr = value_map.find(value);\n\tif (itr != value_map.end())\n\t\treturn itr->second;\n\n\tspv::Id ret;\n\tif (auto *undef = llvm::dyn_cast<llvm::UndefValue>(value))\n\t\tret = get_id_for_undef(undef);\n\telse if (auto *constant = llvm::dyn_cast<llvm::Constant>(value))\n\t\tret = get_id_for_constant(constant, forced_width);\n\telse\n\t\tret = spirv_module.allocate_id();\n\n\tvalue_map[value] = ret;\n\treturn ret;\n}\n\nstatic llvm::MDNode *get_entry_point_meta(const llvm::Module &module, const char *entry)\n{\n\tauto *ep_meta = module.getNamedMetadata(\"dx.entryPoints\");\n\tunsigned num_entry_points = ep_meta->getNumOperands();\n\tfor (unsigned i = 0; i < num_entry_points; i++)\n\t{\n\t\tauto *node = ep_meta->getOperand(i);\n\t\tif (node)\n\t\t{\n\t\t\tauto &func_node = node->getOperand(0);\n\t\t\tif (func_node)\n\t\t\t\tif (!entry || (Converter::entry_point_matches(get_string_metadata(node, 1), entry)))\n\t\t\t\t\treturn node;\n\t\t}\n\t}\n\n\t// dxilconv can emit null hull shader with non-null patch constant function ... *shrug*\n\t// I suppose we need to deal with that too.\n\tif (!entry && num_entry_points)\n\t{\n\t\tauto *node = ep_meta->getOperand(0);\n\t\tif (node)\n\t\t\treturn node;\n\t}\n\n\treturn nullptr;\n}\n\nstatic llvm::MDNode *get_null_entry_point_meta(const llvm::Module &module)\n{\n\t// In DXR, a dummy entry point with null function pointer owns the shader flags for whatever reason ...\n\tauto *ep_meta = module.getNamedMetadata(\"dx.entryPoints\");\n\tunsigned num_entry_points = ep_meta->getNumOperands();\n\tfor (unsigned i = 0; i < num_entry_points; i++)\n\t{\n\t\tauto *node = ep_meta->getOperand(i);\n\t\tif (node)\n\t\t{\n\t\t\tauto &func_node = node->getOperand(0);\n\t\t\tif (!func_node)\n\t\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn nullptr;\n}\n\nVector<String> Converter::get_entry_points(const LLVMBCParser &parser)\n{\n\tVector<String> result;\n\tauto &module = parser.get_module();\n\tauto *ep_meta = module.getNamedMetadata(\"dx.entryPoints\");\n\n\tunsigned num_entry_points = ep_meta->getNumOperands();\n\tresult.reserve(num_entry_points);\n\n\tfor (unsigned i = 0; i < num_entry_points; i++)\n\t{\n\t\tauto *node = ep_meta->getOperand(i);\n\t\tif (node)\n\t\t{\n\t\t\tauto &func_node = node->getOperand(0);\n\t\t\tif (func_node)\n\t\t\t\tresult.push_back(get_string_metadata(node, 1));\n\t\t}\n\t}\n\n\treturn result;\n}\n\nbool Converter::entry_point_matches(const String &mangled, const char *user)\n{\n\tif (is_mangled_entry_point(user))\n\t\treturn mangled == user;\n\telse\n\t\treturn demangle_entry_point(mangled) == user;\n}\n\nstatic String get_entry_point_name(llvm::MDNode *node)\n{\n\tif (!node)\n\t\treturn {};\n\n\tauto &name_node = node->getOperand(1);\n\n\tif (name_node)\n\t{\n\t\tauto *str_node = llvm::dyn_cast<llvm::MDString>(name_node);\n\t\tif (str_node)\n\t\t\treturn get_string_metadata(node, 1);\n\t}\n\n\treturn {};\n}\n\nstatic llvm::Function *get_entry_point_function(llvm::MDNode *node)\n{\n\tif (!node)\n\t\treturn nullptr;\n\n\tauto &func_node = node->getOperand(0);\n\n\tif (func_node)\n\t\treturn llvm::dyn_cast<llvm::Function>(llvm::cast<llvm::ConstantAsMetadata>(func_node)->getValue());\n\telse\n\t\treturn nullptr;\n}\n\nstatic const llvm::MDOperand *get_shader_property_tag(const llvm::MDNode *func_meta, DXIL::ShaderPropertyTag tag)\n{\n\tif (func_meta && func_meta->getNumOperands() >= 5 && func_meta->getOperand(4))\n\t{\n\t\tauto *tag_values = llvm::dyn_cast<llvm::MDNode>(func_meta->getOperand(4));\n\t\tunsigned num_pairs = tag_values->getNumOperands() / 2;\n\t\tfor (unsigned i = 0; i < num_pairs; i++)\n\t\t\tif (tag == static_cast<DXIL::ShaderPropertyTag>(get_constant_metadata(tag_values, 2 * i)))\n\t\t\t\treturn &tag_values->getOperand(2 * i + 1);\n\t}\n\n\treturn nullptr;\n}\n\nstatic bool get_execution_model_lib_target(const llvm::Module &module, llvm::MDNode *entry_point_meta)\n{\n\tString model;\n\tConverter::Impl::get_shader_model(module, &model, nullptr, nullptr);\n\treturn model == \"lib\";\n}\n\nstatic spv::ExecutionModel get_execution_model(const llvm::Module &module, llvm::MDNode *entry_point_meta)\n{\n\tif (auto *tag = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::ShaderKind))\n\t{\n\t\tif (!tag)\n\t\t\treturn spv::ExecutionModelMax;\n\n\t\tauto shader_kind = static_cast<DXIL::ShaderKind>(\n\t\t    llvm::cast<llvm::ConstantAsMetadata>(*tag)->getValue()->getUniqueInteger().getZExtValue());\n\t\tswitch (shader_kind)\n\t\t{\n\t\tcase DXIL::ShaderKind::Pixel:\n\t\t\treturn spv::ExecutionModelFragment;\n\t\tcase DXIL::ShaderKind::Vertex:\n\t\t\treturn spv::ExecutionModelVertex;\n\t\tcase DXIL::ShaderKind::Hull:\n\t\t\treturn spv::ExecutionModelTessellationControl;\n\t\tcase DXIL::ShaderKind::Domain:\n\t\t\treturn spv::ExecutionModelTessellationEvaluation;\n\t\tcase DXIL::ShaderKind::Geometry:\n\t\t\treturn spv::ExecutionModelGeometry;\n\t\tcase DXIL::ShaderKind::Compute:\n\t\tcase DXIL::ShaderKind::Node:\n\t\t\treturn spv::ExecutionModelGLCompute;\n\t\tcase DXIL::ShaderKind::Amplification:\n\t\t\treturn spv::ExecutionModelTaskEXT;\n\t\tcase DXIL::ShaderKind::Mesh:\n\t\t\treturn spv::ExecutionModelMeshEXT;\n\t\tcase DXIL::ShaderKind::RayGeneration:\n\t\t\treturn spv::ExecutionModelRayGenerationKHR;\n\t\tcase DXIL::ShaderKind::Miss:\n\t\t\treturn spv::ExecutionModelMissKHR;\n\t\tcase DXIL::ShaderKind::ClosestHit:\n\t\t\treturn spv::ExecutionModelClosestHitKHR;\n\t\tcase DXIL::ShaderKind::Callable:\n\t\t\treturn spv::ExecutionModelCallableKHR;\n\t\tcase DXIL::ShaderKind::AnyHit:\n\t\t\treturn spv::ExecutionModelAnyHitKHR;\n\t\tcase DXIL::ShaderKind::Intersection:\n\t\t\treturn spv::ExecutionModelIntersectionKHR;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// Non-RT shaders tend to rely on having the shader model set in the shaderModel meta node.\n\t\tString model;\n\t\tConverter::Impl::get_shader_model(module, &model, nullptr, nullptr);\n\n\t\tif (model == \"vs\")\n\t\t\treturn spv::ExecutionModelVertex;\n\t\telse if (model == \"ps\")\n\t\t\treturn spv::ExecutionModelFragment;\n\t\telse if (model == \"hs\")\n\t\t\treturn spv::ExecutionModelTessellationControl;\n\t\telse if (model == \"ds\")\n\t\t\treturn spv::ExecutionModelTessellationEvaluation;\n\t\telse if (model == \"gs\")\n\t\t\treturn spv::ExecutionModelGeometry;\n\t\telse if (model == \"cs\")\n\t\t\treturn spv::ExecutionModelGLCompute;\n\t\telse if (model == \"as\")\n\t\t\treturn spv::ExecutionModelTaskEXT;\n\t\telse if (model == \"ms\")\n\t\t\treturn spv::ExecutionModelMeshEXT;\n\t}\n\n\treturn spv::ExecutionModelMax;\n}\n\nspv::Id Converter::Impl::get_type_id(const llvm::Type *type, TypeLayoutFlags flags)\n{\n\tauto &builder = spirv_module.get_builder();\n\tswitch (type->getTypeID())\n\t{\n\tcase llvm::Type::TypeID::HalfTyID:\n\t\treturn builder.makeFloatType(support_native_fp16_operations() ? 16 : 32);\n\tcase llvm::Type::TypeID::FloatTyID:\n\t\treturn builder.makeFloatType(32);\n\tcase llvm::Type::TypeID::DoubleTyID:\n\t\treturn builder.makeFloatType(64);\n\n\tcase llvm::Type::TypeID::IntegerTyID:\n\t\tif (type->getIntegerBitWidth() == 1)\n\t\t\treturn builder.makeBoolType();\n\t\telse\n\t\t{\n\t\t\tauto width = physical_integer_bit_width(type->getIntegerBitWidth());\n\t\t\treturn builder.makeIntegerType(width, false);\n\t\t}\n\n\tcase llvm::Type::TypeID::PointerTyID:\n\t{\n\t\tif (DXIL::AddressSpace(type->getPointerAddressSpace()) != DXIL::AddressSpace::PhysicalNodeIO ||\n\t\t    (flags & TYPE_LAYOUT_PHYSICAL_BIT) == 0)\n\t\t{\n\t\t\t// Have to deal with this from the outside. Should only be relevant for getelementptr and instructions like that.\n\t\t\tLOGE(\"Cannot reliably convert LLVM pointer type, we cannot differentiate between Function and Private.\\n\");\n\t\t\tstd::terminate();\n\t\t}\n\n\t\t// This is free-flowing BDA in DXIL. We'll deal with it as-is.\n\t\t// Main complication is that we have to emit Offset information ourselves.\n\t\tspv::Id pointee_type = get_type_id(type->getPointerElementType(), flags);\n\t\treturn builder.makePointer(spv::StorageClassPhysicalStorageBuffer, pointee_type);\n\t}\n\n\tcase llvm::Type::TypeID::ArrayTyID:\n\t{\n\t\tif (type->getArrayNumElements() == 0)\n\t\t\treturn 0;\n\n\t\tspv::Id array_size_id;\n\t\tspv::Id element_type_id;\n\n\t\t// dxbc2dxil emits broken code for TGSM. It's an array of i8 which is absolute nonsense.\n\t\t// It then bitcasts the pointer to i32, which isn't legal either.\n\t\tif ((flags & TYPE_LAYOUT_PHYSICAL_BIT) == 0 &&\n\t\t    type->getArrayElementType()->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t\t    type->getArrayElementType()->getIntegerBitWidth() == 8 &&\n\t\t    type->getArrayNumElements() % 4 == 0)\n\t\t{\n\t\t\tarray_size_id = builder.makeUintConstant(type->getArrayNumElements() / 4);\n\t\t\telement_type_id = builder.makeUintType(32);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tarray_size_id = builder.makeUintConstant(type->getArrayNumElements());\n\t\t\telement_type_id = get_type_id(type->getArrayElementType(), flags & ~TYPE_LAYOUT_BLOCK_BIT);\n\t\t}\n\n\t\tif ((flags & TYPE_LAYOUT_PHYSICAL_BIT) != 0)\n\t\t{\n\t\t\tauto size_stride = get_physical_size_for_type(element_type_id);\n\t\t\tuint32_t stride = size_stride.size;\n\n\t\t\t// We always use scalar layout.\n\t\t\tfor (auto &cached_type : cached_physical_array_types)\n\t\t\t\tif (cached_type.element_type_id == element_type_id && cached_type.array_size_id == array_size_id)\n\t\t\t\t\treturn cached_type.id;\n\n\t\t\tspv::Id array_type_id = builder.makeArrayType(element_type_id, array_size_id, stride);\n\t\t\tbuilder.addDecoration(array_type_id, spv::DecorationArrayStride, stride);\n\t\t\tcached_physical_array_types.push_back({ array_type_id, element_type_id, array_size_id });\n\t\t\treturn array_type_id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// glslang emitter deduplicates.\n\t\t\treturn builder.makeArrayType(element_type_id, array_size_id, 0);\n\t\t}\n\t}\n\n\tcase llvm::Type::TypeID::StructTyID:\n\t{\n\t\tauto *struct_type = llvm::cast<llvm::StructType>(type);\n\t\tVector<spv::Id> member_types;\n\t\tmember_types.reserve(struct_type->getStructNumElements());\n\t\tfor (unsigned i = 0; i < struct_type->getStructNumElements(); i++)\n\t\t\tmember_types.push_back(get_type_id(struct_type->getStructElementType(i), flags & ~TYPE_LAYOUT_BLOCK_BIT));\n\t\treturn get_struct_type(member_types, flags, \"\");\n\t}\n\n\tcase llvm::Type::TypeID::VectorTyID:\n\t{\n\t\tauto *vec_type = llvm::cast<llvm::VectorType>(type);\n\t\treturn builder.makeVectorType(get_type_id(vec_type->getElementType()), vec_type->getVectorNumElements());\n\t}\n\n\tcase llvm::Type::TypeID::VoidTyID:\n\t\treturn builder.makeVoidType();\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nConverter::Impl::SizeAlignment Converter::Impl::get_physical_size_for_type(spv::Id type_id)\n{\n\tSizeAlignment res = {};\n\n\tif (builder().isScalarType(type_id))\n\t{\n\t\tres.size = builder().getScalarTypeWidth(type_id) / 8;\n\t\tres.alignment = res.size;\n\t}\n\telse if (builder().isVectorType(type_id))\n\t{\n\t\tres = get_physical_size_for_type(builder().getContainedTypeId(type_id));\n\t\tres.size *= builder().getNumComponents(type_id);\n\t}\n\telse if (builder().isArrayType(type_id))\n\t{\n\t\tres = get_physical_size_for_type(builder().getContainedTypeId(type_id));\n\t\tuint32_t array_size = builder().getNumTypeConstituents(type_id);\n\t\t// Alignment is inherited from constituent, we do scalar block layout here.\n\t\tres.size *= array_size;\n\t}\n\telse if (builder().isStructType(type_id))\n\t{\n\t\tint num_members = builder().getNumTypeConstituents(type_id);\n\t\tfor (int i = 0; i < num_members; i++)\n\t\t{\n\t\t\tuint32_t member_type_id = builder().getContainedTypeId(type_id, i);\n\t\t\tauto member_res = get_physical_size_for_type(member_type_id);\n\t\t\tres.size = (res.size + member_res.alignment - 1) & ~(member_res.alignment - 1);\n\t\t\tres.size += member_res.size;\n\t\t\tres.alignment = std::max<uint32_t>(res.alignment, member_res.alignment);\n\t\t}\n\t\tres.size = (res.size + res.alignment - 1) & ~(res.alignment - 1);\n\t}\n\telse if (builder().isPointerType(type_id))\n\t{\n\t\tres.size = sizeof(uint64_t);\n\t\tres.alignment = sizeof(uint64_t);\n\t}\n\n\treturn res;\n}\n\nvoid Converter::Impl::decorate_physical_offsets(spv::Id struct_type_id, const Vector<spv::Id> &type_ids)\n{\n\tuint32_t offset = 0;\n\tint member_index = 0;\n\tfor (auto &type_id : type_ids)\n\t{\n\t\t// DXIL seems to imply scalar alignment for node payload.\n\t\t// It's simple and easy, so just roll with that.\n\t\tauto size_alignment = get_physical_size_for_type(type_id);\n\t\tassert(size_alignment.size != 0);\n\t\toffset = (offset + size_alignment.alignment - 1) & ~(size_alignment.alignment - 1);\n\t\tbuilder().addMemberDecoration(struct_type_id, member_index, spv::DecorationOffset, offset);\n\t\toffset += size_alignment.size;\n\t\tmember_index++;\n\t}\n}\n\nspv::Id Converter::Impl::get_struct_type(const Vector<spv::Id> &type_ids, TypeLayoutFlags flags, const char *name)\n{\n\tauto itr = std::find_if(cached_struct_types.begin(), cached_struct_types.end(), [&](const StructTypeEntry &entry) -> bool {\n\t\tif (type_ids.size() != entry.subtypes.size())\n\t\t\treturn false;\n\t\tif (flags != entry.flags)\n\t\t\treturn false;\n\t\tif ((!name && !entry.name.empty()) || (entry.name != name))\n\t\t\treturn false;\n\n\t\tfor (unsigned i = 0; i < type_ids.size(); i++)\n\t\t\tif (type_ids[i] != entry.subtypes[i])\n\t\t\t\treturn false;\n\n\t\treturn true;\n\t});\n\n\tif (itr == cached_struct_types.end())\n\t{\n\t\tStructTypeEntry entry;\n\t\tentry.subtypes = type_ids;\n\t\tentry.name = name ? name : \"\";\n\n\t\tif ((flags & TYPE_LAYOUT_BLOCK_BIT) != 0)\n\t\t{\n\t\t\tconstexpr TypeLayoutFlags block_flags = TYPE_LAYOUT_BLOCK_BIT |\n\t\t\t                                        TYPE_LAYOUT_COHERENT_BIT |\n\t\t\t                                        TYPE_LAYOUT_READ_ONLY_BIT;\n\t\t\tspv::Id struct_type_id = get_struct_type(type_ids, flags & ~block_flags, entry.name.c_str());\n\t\t\tentry.id = builder().makeStructType({ struct_type_id }, entry.name.c_str());\n\t\t\tbuilder().addDecoration(entry.id, spv::DecorationBlock);\n\t\t\tbuilder().addMemberDecoration(entry.id, 0, spv::DecorationOffset, 0);\n\t\t\tif ((flags & TYPE_LAYOUT_COHERENT_BIT) != 0 && execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\t\t\tbuilder().addMemberDecoration(entry.id, 0, spv::DecorationCoherent);\n\t\t\tif ((flags & TYPE_LAYOUT_READ_ONLY_BIT) != 0)\n\t\t\t\tbuilder().addMemberDecoration(entry.id, 0, spv::DecorationNonWritable);\n\t\t\tbuilder().addMemberName(entry.id, 0, \"data\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tentry.id = builder().makeStructType(type_ids, entry.name.c_str());\n\t\t\tif ((flags & TYPE_LAYOUT_PHYSICAL_BIT) != 0)\n\t\t\t\tdecorate_physical_offsets(entry.id, type_ids);\n\t\t}\n\n\t\tentry.flags = flags;\n\t\tspv::Id id = entry.id;\n\t\tcached_struct_types.push_back(std::move(entry));\n\t\treturn id;\n\t}\n\telse\n\t\treturn itr->id;\n}\n\nspv::Id Converter::Impl::get_type_id(DXIL::ComponentType element_type, unsigned rows, unsigned cols, bool force_array)\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tspv::Id component_type;\n\tswitch (element_type)\n\t{\n\tcase DXIL::ComponentType::I1:\n\t\t// Cannot have bools in I/O interfaces, these are emitted as 32-bit integers.\n\t\tcomponent_type = builder.makeUintType(32);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::I16:\n\t\tcomponent_type = builder.makeIntegerType(16, true);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::U16:\n\t\tcomponent_type = builder.makeIntegerType(16, false);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::I32:\n\t\tcomponent_type = builder.makeIntegerType(32, true);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::U32:\n\t\tcomponent_type = builder.makeIntegerType(32, false);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::I64:\n\t\tcomponent_type = builder.makeIntegerType(64, true);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::U64:\n\t\tcomponent_type = builder.makeIntegerType(64, false);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::F16:\n\t\tcomponent_type = builder.makeFloatType(16);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::F32:\n\t\tcomponent_type = builder.makeFloatType(32);\n\t\tbreak;\n\n\tcase DXIL::ComponentType::F64:\n\t\tcomponent_type = builder.makeFloatType(64);\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unknown component type.\\n\");\n\t\treturn 0;\n\t}\n\n\tif (cols > 1)\n\t\tcomponent_type = builder.makeVectorType(component_type, cols);\n\tif (rows > 1 || force_array)\n\t\tcomponent_type = builder.makeArrayType(component_type, builder.makeUintConstant(rows), 0);\n\treturn component_type;\n}\n\nspv::Id Converter::Impl::get_type_id(spv::Id id) const\n{\n\tauto itr = id_to_type.find(id);\n\tif (itr == id_to_type.end())\n\t\treturn 0;\n\telse\n\t\treturn itr->second;\n}\n\nstatic bool module_is_ident(llvm::Module &module, const char *ident)\n{\n\tauto *ident_meta = module.getNamedMetadata(\"llvm.ident\");\n\tif (ident_meta)\n\t\tif (auto *arg0 = ident_meta->getOperand(0))\n\t\t\tif (auto *str = llvm::dyn_cast<llvm::MDString>(arg0->getOperand(0)))\n\t\t\t\tif (str->getString().find(ident) != std::string::npos)\n\t\t\t\t\treturn true;\n\n\treturn false;\n}\n\nstatic bool module_is_dxilconv(llvm::Module &module)\n{\n\treturn module_is_ident(module, \"dxbc2dxil\");\n}\n\nstatic bool module_is_dxbc_spirv(llvm::Module &module)\n{\n\treturn module_is_ident(module, \"dxbc-spirv\");\n}\n\nbool Converter::Impl::emit_patch_variables()\n{\n\tauto *node = entry_point_meta;\n\n\tif (!node->getOperand(2))\n\t\treturn true;\n\n\tauto &signature = node->getOperand(2);\n\tauto *signature_node = llvm::cast<llvm::MDNode>(signature);\n\tauto &patch_variables = signature_node->getOperand(2);\n\tif (!patch_variables)\n\t\treturn true;\n\n\t// There are no control points, and there's no explicit parameter, so force 0.\n\tif (patch_location_offset == ~0u)\n\t\tpatch_location_offset = 0;\n\n\t// dxilconv is broken and emits patch the fork phase in a way that is non-sensical.\n\t// It assumes that you can write outside the bounds of a signature element.\n\t// To make this work, we need to lower the patch constant variables from Private variables instead.\n\tbool broken_patch_variables = false;\n\tif (execution_model == spv::ExecutionModelTessellationControl)\n\t\tbroken_patch_variables = module_is_dxilconv(bitcode_parser.get_module());\n\n\tauto *patch_node = llvm::dyn_cast<llvm::MDNode>(patch_variables);\n\n\tauto &builder = spirv_module.get_builder();\n\n\tspv::StorageClass storage =\n\t    execution_model == spv::ExecutionModelTessellationEvaluation ? spv::StorageClassInput : spv::StorageClassOutput;\n\n\tunsigned num_broken_user_rows = 0;\n\n\tfor (unsigned i = 0; i < patch_node->getNumOperands(); i++)\n\t{\n\t\tauto *patch = llvm::cast<llvm::MDNode>(patch_node->getOperand(i));\n\t\tauto element_id = get_constant_metadata(patch, 0);\n\t\tauto semantic_name = get_string_metadata(patch, 1);\n\t\tauto actual_element_type = normalize_component_type(static_cast<DXIL::ComponentType>(get_constant_metadata(patch, 2)));\n\t\tauto effective_element_type = get_effective_input_output_type(actual_element_type);\n\t\tauto system_value = static_cast<DXIL::Semantic>(get_constant_metadata(patch, 3));\n\n\t\tunsigned semantic_index = 0;\n\t\tif (patch->getOperand(4))\n\t\t\tsemantic_index = get_constant_metadata(llvm::cast<llvm::MDNode>(patch->getOperand(4)), 0);\n\n\t\tauto rows = get_constant_metadata(patch, 6);\n\t\tauto cols = get_constant_metadata(patch, 7);\n\n\t\tauto start_row = get_constant_metadata(patch, 8);\n\t\tauto start_col = get_constant_metadata(patch, 9);\n\n\t\tif (system_value == DXIL::Semantic::TessFactor)\n\t\t\trows = 4;\n\t\telse if (system_value == DXIL::Semantic::InsideTessFactor)\n\t\t\trows = 2;\n\n\t\tif (broken_patch_variables && system_value == DXIL::Semantic::User)\n\t\t\tnum_broken_user_rows = std::max<unsigned>(num_broken_user_rows, start_row + rows);\n\n\t\tauto &meta = patch_elements_meta[element_id];\n\t\tmeta.semantic = system_value;\n\n\t\t// Handle case where shader declares the tess factors twice at different offsets.\n\t\tunsigned semantic_offset = 0;\n\t\tif (system_value == DXIL::Semantic::TessFactor || system_value == DXIL::Semantic::InsideTessFactor)\n\t\t{\n\t\t\tauto builtin = system_value == DXIL::Semantic::TessFactor ?\n\t\t\t               spv::BuiltInTessLevelOuter : spv::BuiltInTessLevelInner;\n\t\t\tif (spirv_module.has_builtin_shader_input(builtin))\n\t\t\t{\n\t\t\t\tmeta = {};\n\t\t\t\tmeta.id = spirv_module.get_builtin_shader_input(builtin);\n\t\t\t\tmeta.component_type = actual_element_type;\n\t\t\t\tmeta.semantic_offset = start_row;\n\t\t\t\tmeta.semantic = system_value;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Application can emit these in ViewInstancing, in which case it's just an offset.\n\t\tif (options.multiview.enable && execution_model == spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\tif (system_value == DXIL::Semantic::RenderTargetArrayIndex)\n\t\t\t\tmultiview.custom_layer_index = true;\n\t\t\tif (system_value == DXIL::Semantic::ViewPortArrayIndex)\n\t\t\t\tmultiview.custom_viewport_index = true;\n\t\t}\n\n\t\tspv::Id type_id;\n\n\t\tif (system_value == DXIL::Semantic::CullPrimitive)\n\t\t\ttype_id = builder.makeBoolType();\n\t\telse\n\t\t\ttype_id = get_type_id(effective_element_type, rows, cols);\n\n\t\tif (execution_model == spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\ttype_id = builder.makeArrayType(\n\t\t\t\ttype_id, builder.makeUintConstant(execution_mode_meta.stage_output_num_primitive, false), 0);\n\t\t}\n\n\t\tauto variable_name = semantic_name;\n\t\tif (semantic_index != 0)\n\t\t{\n\t\t\tvariable_name += \"_\";\n\t\t\tvariable_name += dxil_spv::to_string(semantic_index);\n\t\t}\n\n\t\tspv::Id variable_id = create_variable(storage, type_id, variable_name.c_str());\n\t\tmeta.id = variable_id;\n\t\tmeta.component_type = actual_element_type;\n\t\tmeta.semantic_offset = semantic_offset;\n\t\tmeta.start_row = start_row;\n\t\tmeta.start_col = start_col;\n\t\tmeta.lowering = broken_patch_variables && system_value == DXIL::Semantic::User;\n\n\t\tif (system_value != DXIL::Semantic::User)\n\t\t{\n\t\t\temit_builtin_decoration(variable_id, system_value, storage);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Patch constants are packed together with control point variables,\n\t\t\t// so we need to apply an offset to make this work in SPIR-V.\n\t\t\t// The offset is deduced from the control point I/O signature.\n\t\t\t// TODO: If it's possible to omit trailing CP members in domain shader, we will need to pass this offset\n\t\t\t// into the compiler.\n\t\t\tVulkanStageIO vk_io = { start_row + patch_location_offset, start_col, true };\n\n\t\t\tif (resource_mapping_iface)\n\t\t\t{\n\t\t\t\tD3DStageIO d3d_io = { semantic_name.c_str(), semantic_index, start_row, rows };\n\n\t\t\t\tif (execution_model == spv::ExecutionModelTessellationEvaluation)\n\t\t\t\t{\n\t\t\t\t\tif (!resource_mapping_iface->remap_stage_input(d3d_io, vk_io))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (!resource_mapping_iface->remap_stage_output(d3d_io, vk_io))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbuilder.addDecoration(variable_id, spv::DecorationLocation, vk_io.location);\n\t\t\tif (vk_io.component != 0)\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationComponent, vk_io.component);\n\t\t}\n\n\t\tbuilder.addDecoration(variable_id, execution_model == spv::ExecutionModelMeshEXT\n\t\t                                   ? spv::DecorationPerPrimitiveEXT : spv::DecorationPatch);\n\t}\n\n\tif (num_broken_user_rows)\n\t{\n\t\tspv::Id type_id = builder.makeArrayType(builder.makeVectorType(builder.makeUintType(32), 4),\n\t\t                                        builder.makeUintConstant(num_broken_user_rows), 0);\n\t\texecution_mode_meta.patch_lowering_array_var_id =\n\t\t\tcreate_variable_with_initializer(spv::StorageClassPrivate, type_id,\n\t\t\t                                 builder.makeNullConstant(type_id),\n\t\t\t                                 \"PatchLoweringRows\");\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_other_variables()\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tif (execution_model == spv::ExecutionModelMeshEXT && execution_mode_meta.stage_output_num_primitive)\n\t{\n\t\tunsigned index_dim = execution_mode_meta.primitive_index_dimension;\n\n\t\tif (index_dim)\n\t\t{\n\t\t\tspv::Id type_id = builder.makeArrayType(\n\t\t\t\tget_type_id(DXIL::ComponentType::U32, 1, index_dim),\n\t\t\t\tbuilder.makeUintConstant(execution_mode_meta.stage_output_num_primitive, false), 0);\n\t\t\tprimitive_index_array_id = create_variable(spv::StorageClassOutput, type_id, \"indices\");\n\n\t\t\tspv::BuiltIn builtin_id =\n\t\t\t    index_dim == 3 ? spv::BuiltInPrimitiveTriangleIndicesEXT : spv::BuiltInPrimitiveLineIndicesEXT;\n\t\t\tbuilder.addDecoration(primitive_index_array_id, spv::DecorationBuiltIn, builtin_id);\n\t\t\tspirv_module.register_builtin_shader_output(primitive_index_array_id, builtin_id);\n\t\t}\n\t}\n\n\treturn true;\n}\n\nstatic unsigned get_geometry_shader_stream_index(const llvm::MDNode *node)\n{\n\tif (node->getNumOperands() >= 11 && node->getOperand(10))\n\t{\n\t\tauto *attr = llvm::dyn_cast<llvm::MDNode>(node->getOperand(10));\n\t\tif (!attr)\n\t\t\treturn 0;\n\n\t\tunsigned num_pairs = attr->getNumOperands() / 2;\n\t\tfor (unsigned i = 0; i < num_pairs; i++)\n\t\t{\n\t\t\tif (static_cast<DXIL::GSStageOutTags>(get_constant_metadata(attr, 2 * i + 0)) == DXIL::GSStageOutTags::Stream)\n\t\t\t\treturn get_constant_metadata(attr, 2 * i + 1);\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic void build_geometry_stream_row_offsets(unsigned offsets[4], const llvm::MDNode *outputs_node)\n{\n\tunsigned row_count_for_geometry_stream[4] = {};\n\tfor (unsigned i = 0; i < outputs_node->getNumOperands(); i++)\n\t{\n\t\tauto *output = llvm::cast<llvm::MDNode>(outputs_node->getOperand(i));\n\t\tunsigned geometry_stream = get_geometry_shader_stream_index(output);\n\t\tif (geometry_stream < 4)\n\t\t{\n\t\t\tauto start_row = get_constant_metadata(output, 8);\n\t\t\tauto rows = get_constant_metadata(output, 6);\n\t\t\tauto end_rows = rows + start_row;\n\t\t\tif (end_rows > row_count_for_geometry_stream[geometry_stream])\n\t\t\t\trow_count_for_geometry_stream[geometry_stream] = end_rows;\n\t\t}\n\t}\n\n\tfor (unsigned row = 0; row < 4; row++)\n\t\tfor (unsigned i = 0; i < row; i++)\n\t\t\toffsets[row] += row_count_for_geometry_stream[i];\n}\n\nbool Converter::Impl::emit_stage_output_variables()\n{\n\tauto *node = entry_point_meta;\n\tif (!node->getOperand(2))\n\t\treturn true;\n\n\tauto &signature = node->getOperand(2);\n\tauto *signature_node = llvm::cast<llvm::MDNode>(signature);\n\tauto &outputs = signature_node->getOperand(1);\n\tif (!outputs)\n\t\treturn true;\n\n\tauto *outputs_node = llvm::dyn_cast<llvm::MDNode>(outputs);\n\n\tauto &builder = spirv_module.get_builder();\n\n\tunsigned clip_distance_count = 0;\n\tunsigned cull_distance_count = 0;\n\tbool auto_patch_location = patch_location_offset == ~0u &&\n\t                           (execution_model == spv::ExecutionModelTessellationControl ||\n\t                            execution_model == spv::ExecutionModelMeshEXT);\n\tif (auto_patch_location)\n\t\tpatch_location_offset = 0;\n\n\t// If we have multiple geometry streams, need to hallucinate locations.\n\t// This is okay since we're not going to support multi-stream rasterization anyways.\n\tunsigned start_row_for_geometry_stream[4] = {};\n\tif (execution_model == spv::ExecutionModelGeometry)\n\t\tbuild_geometry_stream_row_offsets(start_row_for_geometry_stream, outputs_node);\n\n\tfor (unsigned i = 0; i < outputs_node->getNumOperands(); i++)\n\t{\n\t\tauto *output = llvm::cast<llvm::MDNode>(outputs_node->getOperand(i));\n\t\tauto element_id = get_constant_metadata(output, 0);\n\t\tauto semantic_name = get_string_metadata(output, 1);\n\t\tauto actual_element_type = normalize_component_type(static_cast<DXIL::ComponentType>(get_constant_metadata(output, 2)));\n\t\tauto effective_element_type = get_effective_input_output_type(actual_element_type);\n\t\tauto system_value = static_cast<DXIL::Semantic>(get_constant_metadata(output, 3));\n\n\t\tunsigned semantic_index = 0;\n\t\tif (output->getOperand(4))\n\t\t\tsemantic_index = get_constant_metadata(llvm::cast<llvm::MDNode>(output->getOperand(4)), 0);\n\n\t\tauto interpolation = static_cast<DXIL::InterpolationMode>(get_constant_metadata(output, 5));\n\t\tauto rows = get_constant_metadata(output, 6);\n\t\tauto cols = get_constant_metadata(output, 7);\n\n\t\tauto start_row = get_constant_metadata(output, 8);\n\t\tauto start_col = get_constant_metadata(output, 9);\n\t\tbool masked_output = false;\n\n\t\tif (options.dual_source_blending && start_row >= 2)\n\t\t{\n\t\t\t// Mask out writes to unused higher RTs when using dual source blending.\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (auto_patch_location)\n\t\t\tpatch_location_offset = std::max(patch_location_offset, start_row + rows);\n\n\t\tspv::Id type_id = get_type_id(effective_element_type, rows, cols);\n\n\t\tif (options.quirks.ignore_primitive_shading_rate && system_value == DXIL::Semantic::ShadingRate)\n\t\t{\n\t\t\tmasked_output = true;\n\t\t}\n\t\telse if (execution_model == spv::ExecutionModelTessellationControl ||\n\t\t         (execution_model == spv::ExecutionModelTessellationEvaluation &&\n\t\t          system_value == DXIL::Semantic::ShadingRate))\n\t\t{\n\t\t\t// For HS <-> DS, ignore system values.\n\t\t\t// Shading rate is also ignored in DS. RE4 hits this case. Just treat it as a normal user varying.\n\t\t\tsystem_value = DXIL::Semantic::User;\n\t\t}\n\n\t\tif (system_value == DXIL::Semantic::Position)\n\t\t{\n\t\t\ttype_id = get_type_id(effective_element_type, rows, 4);\n\t\t}\n\t\telse if (system_value == DXIL::Semantic::Coverage)\n\t\t{\n\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(1), 0);\n\t\t}\n\t\telse if (system_value == DXIL::Semantic::ClipDistance)\n\t\t{\n\t\t\t// DX is rather weird here and you can declare clip distance either as a vector or array, or both!\n\t\t\toutput_clip_cull_meta[element_id] = { clip_distance_count, cols, spv::BuiltInClipDistance };\n\t\t\toutput_elements_meta[element_id] = { 0, actual_element_type, 0, system_value };\n\t\t\tclip_distance_count += rows * cols;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (system_value == DXIL::Semantic::CullDistance)\n\t\t{\n\t\t\t// DX is rather weird here and you can declare clip distance either as a vector or array, or both!\n\t\t\toutput_clip_cull_meta[element_id] = { cull_distance_count, cols, spv::BuiltInCullDistance };\n\t\t\toutput_elements_meta[element_id] = { 0, actual_element_type, 0, system_value };\n\t\t\tcull_distance_count += rows * cols;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Application can emit these in ViewInstancing, in which case it's just an offset.\n\t\tif (options.multiview.enable)\n\t\t{\n\t\t\tif (system_value == DXIL::Semantic::RenderTargetArrayIndex)\n\t\t\t\tmultiview.custom_layer_index = true;\n\t\t\tif (system_value == DXIL::Semantic::ViewPortArrayIndex)\n\t\t\t\tmultiview.custom_viewport_index = true;\n\t\t}\n\n\t\tif (execution_model == spv::ExecutionModelTessellationControl || execution_model == spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\ttype_id = builder.makeArrayType(\n\t\t\t    type_id, builder.makeUintConstant(execution_mode_meta.stage_output_num_vertex, false), 0);\n\t\t}\n\n\t\tauto variable_name = semantic_name;\n\t\tif (semantic_index != 0)\n\t\t{\n\t\t\tvariable_name += \"_\";\n\t\t\tvariable_name += dxil_spv::to_string(semantic_index);\n\t\t}\n\n\t\tspv::Id variable_id = create_variable(\n\t\t\tmasked_output ? spv::StorageClassPrivate : spv::StorageClassOutput, type_id, variable_name.c_str());\n\t\toutput_elements_meta[element_id] = { variable_id, actual_element_type, 0, system_value };\n\n\t\tif (effective_element_type != actual_element_type && component_type_is_16bit(actual_element_type))\n\t\t\tbuilder.addDecoration(variable_id, spv::DecorationRelaxedPrecision);\n\n\t\tif (execution_model == spv::ExecutionModelVertex || execution_model == spv::ExecutionModelGeometry ||\n\t\t    execution_model == spv::ExecutionModelTessellationEvaluation)\n\t\t{\n\t\t\tif (resource_mapping_iface)\n\t\t\t{\n\t\t\t\tVulkanStreamOutput vk_output = {};\n\t\t\t\tif (!resource_mapping_iface->remap_stream_output({ semantic_name.c_str(), semantic_index }, vk_output))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (vk_output.enable)\n\t\t\t\t{\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityTransformFeedback);\n\t\t\t\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeXfb);\n\t\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationOffset, vk_output.offset);\n\t\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationXfbStride, vk_output.stride);\n\t\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationXfbBuffer, vk_output.buffer_index);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tunsigned geometry_stream = 0;\n\t\tif (execution_model == spv::ExecutionModelGeometry)\n\t\t{\n\t\t\tgeometry_stream = get_geometry_shader_stream_index(output);\n\t\t\tif (geometry_stream != 0)\n\t\t\t{\n\t\t\t\tbuilder.addCapability(spv::CapabilityGeometryStreams);\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationStream, geometry_stream);\n\t\t\t}\n\t\t}\n\n\t\tif (system_value == DXIL::Semantic::Target)\n\t\t{\n\t\t\tif (options.dual_source_blending)\n\t\t\t{\n\t\t\t\tassert(start_row == 0 || start_row == 1);\n\t\t\t\tif (rows != 1)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"For dual source blending, number of rows must be 1.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationLocation, 0);\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationIndex, start_row);\n\t\t\t\toutput_elements_meta[element_id].semantic_offset = 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationLocation, start_row);\n\t\t\t\toutput_elements_meta[element_id].semantic_offset = start_row;\n\t\t\t}\n\n\t\t\tif (start_col != 0)\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationComponent, start_col);\n\t\t}\n\t\telse if (system_value != DXIL::Semantic::User)\n\t\t{\n\t\t\temit_builtin_decoration(variable_id, system_value, spv::StorageClassOutput);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (execution_model == spv::ExecutionModelVertex ||\n\t\t\t    execution_model == spv::ExecutionModelTessellationEvaluation ||\n\t\t\t    execution_model == spv::ExecutionModelGeometry ||\n\t\t\t    execution_model == spv::ExecutionModelMeshEXT)\n\t\t\t{\n\t\t\t\temit_interpolation_decorations(variable_id, interpolation);\n\t\t\t}\n\n\t\t\tVulkanStageIO vk_output = { start_row, start_col };\n\n\t\t\tif (execution_model == spv::ExecutionModelGeometry && geometry_stream < 4)\n\t\t\t\tvk_output.location += start_row_for_geometry_stream[geometry_stream];\n\n\t\t\tif (resource_mapping_iface)\n\t\t\t{\n\t\t\t\tD3DStageIO d3d_output = { semantic_name.c_str(), semantic_index, start_row, rows };\n\t\t\t\tif (!resource_mapping_iface->remap_stage_output(d3d_output, vk_output))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbuilder.addDecoration(variable_id, spv::DecorationLocation, vk_output.location);\n\t\t\tif (vk_output.component != 0)\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationComponent, vk_output.component);\n\t\t}\n\t}\n\n\tif (clip_distance_count)\n\t{\n\t\tspv::Id type_id = get_type_id(DXIL::ComponentType::F32, clip_distance_count, 1, true);\n\t\tif (execution_model == spv::ExecutionModelTessellationControl || execution_model == spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\ttype_id = builder.makeArrayType(\n\t\t\t    type_id, builder.makeUintConstant(execution_mode_meta.stage_output_num_vertex, false), 0);\n\t\t}\n\n\t\tspv::Id variable_id = create_variable(spv::StorageClassOutput, type_id);\n\t\temit_builtin_decoration(variable_id, DXIL::Semantic::ClipDistance, spv::StorageClassOutput);\n\t\tspirv_module.register_builtin_shader_output(variable_id, spv::BuiltInClipDistance);\n\t}\n\n\tif (cull_distance_count)\n\t{\n\t\tspv::Id type_id = get_type_id(DXIL::ComponentType::F32, cull_distance_count, 1, true);\n\t\tif (execution_model == spv::ExecutionModelTessellationControl || execution_model == spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\ttype_id = builder.makeArrayType(\n\t\t\t    type_id, builder.makeUintConstant(execution_mode_meta.stage_output_num_vertex, false), 0);\n\t\t}\n\n\t\tspv::Id variable_id = create_variable(spv::StorageClassOutput, type_id);\n\t\temit_builtin_decoration(variable_id, DXIL::Semantic::CullDistance, spv::StorageClassOutput);\n\t\tspirv_module.register_builtin_shader_output(variable_id, spv::BuiltInCullDistance);\n\t}\n\n\treturn true;\n}\n\nvoid Converter::Impl::emit_builtin_interpolation_decorations(spv::Id variable_id,\n                                                             DXIL::Semantic semantic,\n                                                             DXIL::InterpolationMode mode)\n{\n\tswitch (semantic)\n\t{\n\tcase DXIL::Semantic::Barycentrics:\n\tcase DXIL::Semantic::InternalBarycentricsNoPerspective:\n\t\temit_interpolation_decorations(variable_id, mode);\n\t\tbreak;\n\n\tcase DXIL::Semantic::Position:\n\t\t// DXIL emits NoPerspective here, but seems weird to emit that since it's kinda implied.\n\t\t// Normalize the interpolate mode first, then emit.\n\t\tif (mode == DXIL::InterpolationMode::LinearNoperspective)\n\t\t\tmode = DXIL::InterpolationMode::Linear;\n\t\telse if (mode == DXIL::InterpolationMode::LinearNoperspectiveCentroid)\n\t\t\tmode = DXIL::InterpolationMode::LinearCentroid;\n\t\telse if (mode == DXIL::InterpolationMode::LinearNoperspectiveSample)\n\t\t\tmode = DXIL::InterpolationMode::LinearSample;\n\t\temit_interpolation_decorations(variable_id, mode);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nvoid Converter::Impl::emit_interpolation_decorations(spv::Id variable_id, DXIL::InterpolationMode mode)\n{\n\tauto &builder = spirv_module.get_builder();\n\tswitch (mode)\n\t{\n\tcase DXIL::InterpolationMode::Constant:\n\t\tbuilder.addDecoration(variable_id, spv::DecorationFlat);\n\t\tbreak;\n\n\tcase DXIL::InterpolationMode::LinearCentroid:\n\t\tbuilder.addDecoration(variable_id, spv::DecorationCentroid);\n\t\tbreak;\n\n\tcase DXIL::InterpolationMode::LinearSample:\n\t\tbuilder.addDecoration(variable_id, spv::DecorationSample);\n\t\tbuilder.addCapability(spv::CapabilitySampleRateShading);\n\t\texecution_mode_meta.per_sample_shading = true;\n\t\tbreak;\n\n\tcase DXIL::InterpolationMode::LinearNoperspective:\n\t\tbuilder.addDecoration(variable_id, spv::DecorationNoPerspective);\n\t\tbreak;\n\n\tcase DXIL::InterpolationMode::LinearNoperspectiveCentroid:\n\t\tbuilder.addDecoration(variable_id, spv::DecorationNoPerspective);\n\t\tbuilder.addDecoration(variable_id, spv::DecorationCentroid);\n\t\tbreak;\n\n\tcase DXIL::InterpolationMode::LinearNoperspectiveSample:\n\t\tbuilder.addDecoration(variable_id, spv::DecorationNoPerspective);\n\t\tbuilder.addDecoration(variable_id, spv::DecorationSample);\n\t\tbuilder.addCapability(spv::CapabilitySampleRateShading);\n\t\texecution_mode_meta.per_sample_shading = true;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nvoid Converter::Impl::emit_builtin_decoration(spv::Id id, DXIL::Semantic semantic, spv::StorageClass storage)\n{\n\tauto &builder = spirv_module.get_builder();\n\tbool requires_flat_input = false;\n\tswitch (semantic)\n\t{\n\tcase DXIL::Semantic::Position:\n\t\tif (execution_model == spv::ExecutionModelFragment)\n\t\t{\n\t\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInFragCoord);\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInFragCoord);\n\t\t}\n\t\telse if (storage == spv::StorageClassInput)\n\t\t{\n\t\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInPosition);\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInPosition);\n\t\t}\n\t\telse if (storage == spv::StorageClassOutput)\n\t\t{\n\t\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInPosition);\n\t\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInPosition);\n\t\t\tif (options.invariant_position)\n\t\t\t\tbuilder.addDecoration(id, spv::DecorationInvariant);\n\t\t}\n\t\tbreak;\n\n\tcase DXIL::Semantic::SampleIndex:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInSampleId);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInSampleId);\n\t\tbuilder.addCapability(spv::CapabilitySampleRateShading);\n\t\texecution_mode_meta.per_sample_shading = true;\n\t\trequires_flat_input = true;\n\t\tbreak;\n\n\tcase DXIL::Semantic::VertexID:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInVertexIndex);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInVertexIndex);\n\t\tbreak;\n\n\tcase DXIL::Semantic::InstanceID:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInInstanceIndex);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInInstanceIndex);\n\t\tbreak;\n\n\tcase DXIL::Semantic::InsideTessFactor:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInTessLevelInner);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInTessLevelInner);\n\t\tbreak;\n\n\tcase DXIL::Semantic::TessFactor:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInTessLevelOuter);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInTessLevelOuter);\n\t\tbreak;\n\n\tcase DXIL::Semantic::Coverage:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInSampleMask);\n\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInSampleMask);\n\t\tbreak;\n\n\tcase DXIL::Semantic::Depth:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInFragDepth);\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDepthReplacing);\n\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInFragDepth);\n\t\tbreak;\n\n\tcase DXIL::Semantic::StencilRef:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInFragStencilRefEXT);\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeStencilRefReplacingEXT);\n\t\tbuilder.addExtension(\"SPV_EXT_shader_stencil_export\");\n\t\tbuilder.addCapability(spv::CapabilityStencilExportEXT);\n\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInFragStencilRefEXT);\n\t\tbreak;\n\n\tcase DXIL::Semantic::DepthLessEqual:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInFragDepth);\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDepthReplacing);\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDepthLess);\n\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInFragDepth);\n\t\tbreak;\n\n\tcase DXIL::Semantic::DepthGreaterEqual:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInFragDepth);\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDepthReplacing);\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDepthGreater);\n\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInFragDepth);\n\t\tbreak;\n\n\tcase DXIL::Semantic::IsFrontFace:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInFrontFacing);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInFrontFacing);\n\t\tbreak;\n\n\tcase DXIL::Semantic::ClipDistance:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInClipDistance);\n\t\tbuilder.addCapability(spv::CapabilityClipDistance);\n\t\tif (storage == spv::StorageClassOutput)\n\t\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInClipDistance);\n\t\telse if (storage == spv::StorageClassInput)\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInClipDistance);\n\t\tbreak;\n\n\tcase DXIL::Semantic::CullDistance:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInCullDistance);\n\t\tbuilder.addCapability(spv::CapabilityCullDistance);\n\t\tif (storage == spv::StorageClassOutput)\n\t\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInCullDistance);\n\t\telse if (storage == spv::StorageClassInput)\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInCullDistance);\n\t\tbreak;\n\n\tcase DXIL::Semantic::RenderTargetArrayIndex:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInLayer);\n\t\tif (storage == spv::StorageClassOutput)\n\t\t{\n\t\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInLayer);\n\t\t\tif (execution_model != spv::ExecutionModelGeometry)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_shader_viewport_index_layer\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInLayer);\n\t\t\trequires_flat_input = true;\n\t\t}\n\t\tbuilder.addCapability(spv::CapabilityGeometry);\n\t\tbreak;\n\n\tcase DXIL::Semantic::ViewPortArrayIndex:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInViewportIndex);\n\t\tif (storage == spv::StorageClassOutput)\n\t\t{\n\t\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInViewportIndex);\n\t\t\tif (execution_model != spv::ExecutionModelGeometry)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_shader_viewport_index_layer\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInViewportIndex);\n\t\t\trequires_flat_input = true;\n\t\t}\n\t\tbuilder.addCapability(spv::CapabilityMultiViewport);\n\t\tbreak;\n\n\tcase DXIL::Semantic::PrimitiveID:\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInPrimitiveId);\n\t\tif (storage == spv::StorageClassOutput)\n\t\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInPrimitiveId);\n\t\telse\n\t\t{\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInPrimitiveId);\n\t\t\trequires_flat_input = true;\n\t\t}\n\t\tbuilder.addCapability(spv::CapabilityGeometry);\n\t\tbreak;\n\n\tcase DXIL::Semantic::ShadingRate:\n\t\tif (storage == spv::StorageClassOutput)\n\t\t{\n\t\t\tif (!options.quirks.ignore_primitive_shading_rate)\n\t\t\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInPrimitiveShadingRateKHR);\n\t\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInPrimitiveShadingRateKHR);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!options.quirks.ignore_primitive_shading_rate)\n\t\t\t{\n\t\t\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInShadingRateKHR);\n\t\t\t\trequires_flat_input = true;\n\t\t\t}\n\t\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInShadingRateKHR);\n\t\t}\n\t\tbuilder.addExtension(\"SPV_KHR_fragment_shading_rate\");\n\t\tbuilder.addCapability(spv::CapabilityFragmentShadingRateKHR);\n\t\tbreak;\n\n\tcase DXIL::Semantic::Barycentrics:\n\tcase DXIL::Semantic::InternalBarycentricsNoPerspective:\n\t{\n\t\tif (options.khr_barycentrics_enabled)\n\t\t{\n\t\t\tauto builtin =\n\t\t\t    semantic == DXIL::Semantic::Barycentrics ? spv::BuiltInBaryCoordKHR : spv::BuiltInBaryCoordNoPerspKHR;\n\n\t\t\tbuilder.addExtension(\"SPV_KHR_fragment_shader_barycentric\");\n\t\t\tbuilder.addCapability(spv::CapabilityFragmentBarycentricKHR);\n\t\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, builtin);\n\t\t\tspirv_module.register_builtin_shader_input(id, builtin);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// TODO: We're not dealing with centroid vs per-sample decorations here.\n\t\t\tauto builtin =\n\t\t\t    semantic == DXIL::Semantic::Barycentrics ? spv::BuiltInBaryCoordSmoothAMD : spv::BuiltInBaryCoordNoPerspAMD;\n\n\t\t\tbuilder.addExtension(\"SPV_AMD_shader_explicit_vertex_parameter\");\n\t\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, builtin);\n\t\t\tspirv_module.register_builtin_shader_input(id, builtin);\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase DXIL::Semantic::CullPrimitive:\n\t{\n\t\tbuilder.addExtension(\"SPV_EXT_mesh_shader\");\n\t\tbuilder.addCapability(spv::CapabilityMeshShadingEXT);\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInCullPrimitiveEXT);\n\t\tspirv_module.register_builtin_shader_output(id, spv::BuiltInCullPrimitiveEXT);\n\t\tbreak;\n\t}\n\n\tcase DXIL::Semantic::DomainLocation:\n\t\t// This is normally an opcode in DXIL, but custom IR likes it to be a semantic,\n\t\t// and it's easier to just treat it like a normal builtin input.\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInTessCoord);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInTessCoord);\n\t\tbreak;\n\n\tcase DXIL::Semantic::DispatchThreadID:\n\t\t// This is normally an opcode in DXIL, but custom IR likes it to be a semantic.\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInGlobalInvocationId);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInGlobalInvocationId);\n\t\tbreak;\n\n\tcase DXIL::Semantic::GroupThreadID:\n\t\t// This is normally an opcode in DXIL, but custom IR likes it to be a semantic.\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInLocalInvocationId);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInLocalInvocationId);\n\t\tbreak;\n\n\tcase DXIL::Semantic::GroupID:\n\t\t// This is normally an opcode in DXIL, but custom IR likes it to be a semantic.\n\t\tbuilder.addDecoration(id, spv::DecorationBuiltIn, spv::BuiltInWorkgroupId);\n\t\tspirv_module.register_builtin_shader_input(id, spv::BuiltInWorkgroupId);\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unknown DXIL semantic.\\n\");\n\t\tbreak;\n\t}\n\n\t// VUID-StandaloneSpirv-Flat-04744\n\tif (requires_flat_input && execution_model == spv::ExecutionModelFragment)\n\t\tbuilder.addDecoration(id, spv::DecorationFlat);\n}\n\nstatic bool execution_model_has_incoming_payload(spv::ExecutionModel model)\n{\n\treturn model != spv::ExecutionModelRayGenerationKHR && execution_model_is_ray_tracing(model);\n}\n\nstatic bool execution_model_has_hit_attribute(spv::ExecutionModel model)\n{\n\tswitch (model)\n\t{\n\tcase spv::ExecutionModelAnyHitKHR:\n\tcase spv::ExecutionModelClosestHitKHR:\n\tcase spv::ExecutionModelIntersectionKHR:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool Converter::Impl::emit_incoming_payload()\n{\n\tauto *func = get_entry_point_function(entry_point_meta);\n\n\t// The first argument to a RT entry point is always a pointer to payload.\n\tif (func->arg_end() - func->arg_begin() >= 1)\n\t{\n\t\tauto &arg = *func->arg_begin();\n\t\tif (!llvm::isa<llvm::PointerType>(arg.getType()))\n\t\t\treturn false;\n\t\tauto *elem_type = arg.getType()->getPointerElementType();\n\n\t\tspv::StorageClass storage;\n\t\tif (execution_model == spv::ExecutionModelCallableKHR)\n\t\t\tstorage = spv::StorageClassIncomingCallableDataKHR;\n\t\telse\n\t\t\tstorage = spv::StorageClassIncomingRayPayloadKHR;\n\n\t\t// This is a POD. We'll emit that as a block containing the payload type.\n\t\tspv::Id payload_var = create_variable(storage, get_type_id(elem_type), \"payload\");\n\t\thandle_to_storage_class[&arg] = storage;\n\t\trewrite_value(&arg, payload_var);\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_hit_attribute()\n{\n\tauto *func = get_entry_point_function(entry_point_meta);\n\n\t// The second argument to a RT entry point is always a pointer to hit attribute.\n\tif (func->arg_end() - func->arg_begin() >= 2)\n\t{\n\t\tauto args = func->arg_begin();\n\t\t++args;\n\t\tauto &arg = *args;\n\t\tif (!llvm::isa<llvm::PointerType>(arg.getType()))\n\t\t\treturn false;\n\t\tauto *elem_type = arg.getType()->getPointerElementType();\n\n\t\tspv::Id hit_attribute_var = create_variable(spv::StorageClassHitAttributeKHR, get_type_id(elem_type), \"hit\");\n\t\thandle_to_storage_class[&arg] = spv::StorageClassHitAttributeKHR;\n\t\trewrite_value(&arg, hit_attribute_var);\n\t}\n\telse if (execution_model == spv::ExecutionModelIntersectionKHR && llvm_hit_attribute_output_type)\n\t{\n\t\tauto *elem_type = llvm_hit_attribute_output_type->getPointerElementType();\n\t\tllvm_hit_attribute_output_value = create_variable(spv::StorageClassHitAttributeKHR,\n\t\t                                                  get_type_id(elem_type), \"hit\");\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_global_variables()\n{\n\tauto &module = bitcode_parser.get_module();\n\n\tif (execution_model_has_incoming_payload(execution_model))\n\t\tif (!emit_incoming_payload())\n\t\t\treturn false;\n\n\tif (execution_model_has_hit_attribute(execution_model))\n\t\tif (!emit_hit_attribute())\n\t\t\treturn false;\n\n\tfor (auto itr = module.global_begin(); itr != module.global_end(); ++itr)\n\t{\n\t\tllvm::GlobalVariable &global = *itr;\n\n\t\tauto address_space = static_cast<DXIL::AddressSpace>(global.getType()->getAddressSpace());\n\n\t\t// Workarounds for DXR. RT resources tend to be declared with external linkage + structs.\n\t\t// Groupshared is also declared with external linkage, even if that is bogus.\n\t\t// Make sure we declare global internal struct LUTs at the very least ...\n\t\tif (global.getLinkage() == llvm::GlobalVariable::ExternalLinkage &&\n\t\t    address_space != DXIL::AddressSpace::GroupShared)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore @llvm.global_ctors(). Only observed once with dummy ctor.\n\t\t// It probably is not intended to work.\n\t\tif (global.getLinkage() == llvm::GlobalVariable::AppendingLinkage)\n\t\t\tcontinue;\n\n\t\tspv::Id pointee_type_id = 0;\n\t\tspv::Id scalar_type_id = 0;\n\t\tbool padded_composite = false;\n\t\tbool complex_composite = false;\n\n\t\tif (address_space == DXIL::AddressSpace::Thread &&\n\t\t    options.extended_robustness.constant_lut &&\n\t\t    global.hasInitializer() &&\n\t\t    global.isConstant())\n\t\t{\n\t\t\tif (auto *array_type = llvm::dyn_cast<llvm::ArrayType>(global.getType()->getPointerElementType()))\n\t\t\t{\n\t\t\t\tscalar_type_id = get_type_id(array_type->getArrayElementType());\n\t\t\t\tpointee_type_id = builder().makeArrayType(\n\t\t\t\t\tscalar_type_id, builder().makeUintConstant(array_type->getArrayNumElements() + 1), false);\n\t\t\t\tpadded_composite = true;\n\t\t\t}\n\t\t}\n\t\telse if (address_space == DXIL::AddressSpace::GroupShared &&\n\t\t         shader_analysis.require_wmma)\n\t\t{\n\t\t\t// Workaround for bugged WMMA shaders.\n\t\t\t// The shaders rely on AMD aligning LDS size to 512 bytes.\n\t\t\t// This avoids overflow spilling into LDSTranspose area by mistake, which breaks some shaders.\n\t\t\tif (auto *array_type = llvm::dyn_cast<llvm::ArrayType>(global.getType()->getPointerElementType()))\n\t\t\t{\n\t\t\t\tscalar_type_id = get_type_id(array_type->getArrayElementType());\n\t\t\t\tuint32_t elem_count = array_type->getArrayNumElements();\n\t\t\t\tuint32_t alignment = (512 * 8) / array_type->getArrayElementType()->getIntegerBitWidth();\n\t\t\t\telem_count = (elem_count + alignment - 1) & ~(alignment - 1);\n\t\t\t\tpointee_type_id = builder().makeArrayType(\n\t\t\t\t\tscalar_type_id, builder().makeUintConstant(elem_count), false);\n\t\t\t}\n\t\t}\n\t\telse if (shader_analysis.require_wmma)\n\t\t{\n\t\t\tif (ags_alloca_or_global_filter(*this, &global, pointee_type_id))\n\t\t\t\tcomplex_composite = true;\n\t\t}\n\n\t\tif (!pointee_type_id)\n\t\t\tpointee_type_id = get_type_id(global.getType()->getPointerElementType());\n\n\t\t// Happens for some global variables in DXR for some reason, benign.\n\t\tif (pointee_type_id == 0)\n\t\t\tcontinue;\n\n\t\tspv::Id initializer_id = 0;\n\n\t\tllvm::Constant *initializer = nullptr;\n\t\tif (global.hasInitializer())\n\t\t\tinitializer = global.getInitializer();\n\t\tif (initializer && llvm::isa<llvm::UndefValue>(initializer))\n\t\t\tinitializer = nullptr;\n\n\t\tif (address_space == DXIL::AddressSpace::GroupShared)\n\t\t{\n\t\t\tif (initializer)\n\t\t\t{\n\t\t\t\t// FIXME: Is this even legal DXIL?\n\t\t\t\tLOGW(\"Global variable address space cannot have initializer! Ignoring ...\\n\");\n\t\t\t\tinitializer = nullptr;\n\t\t\t}\n\t\t}\n\n\t\tif (initializer)\n\t\t{\n\t\t\tif (complex_composite)\n\t\t\t{\n\t\t\t\tif (!llvm::isa<llvm::ConstantAggregateZero>(initializer))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"WMMA initializer must be all zero.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tinitializer_id = builder().makeNullConstant(pointee_type_id);\n\t\t\t}\n\t\t\telse if (padded_composite)\n\t\t\t\tinitializer_id = get_padded_constant_array(pointee_type_id, initializer);\n\t\t\telse\n\t\t\t\tinitializer_id = get_id_for_constant(initializer, 0);\n\t\t}\n\n\t\tspv::StorageClass storage_class = address_space == DXIL::AddressSpace::GroupShared\n\t\t                                  ? spv::StorageClassWorkgroup : spv::StorageClassPrivate;\n\t\tspv::Id var_id = create_variable_with_initializer(\n\t\t\tget_effective_storage_class(&global, storage_class),\n\t\t\tpointee_type_id, initializer_id);\n\n\t\tdecorate_relaxed_precision(global.getType()->getPointerElementType(), var_id, false);\n\t\trewrite_value(&global, var_id);\n\t}\n\n\treturn true;\n}\n\nstatic void adjust_system_value(DXIL::Semantic &semantic, DXIL::InterpolationMode &interpolation)\n{\n\tif (semantic == DXIL::Semantic::Barycentrics)\n\t{\n\t\tswitch (interpolation)\n\t\t{\n\t\tcase DXIL::InterpolationMode::LinearNoperspective:\n\t\t\tsemantic = DXIL::Semantic::InternalBarycentricsNoPerspective;\n\t\t\tinterpolation = DXIL::InterpolationMode::Linear;\n\t\t\tbreak;\n\n\t\tcase DXIL::InterpolationMode::LinearNoperspectiveCentroid:\n\t\t\tsemantic = DXIL::Semantic::InternalBarycentricsNoPerspective;\n\t\t\tinterpolation = DXIL::InterpolationMode::LinearCentroid;\n\t\t\tbreak;\n\n\t\tcase DXIL::InterpolationMode::LinearNoperspectiveSample:\n\t\t\tsemantic = DXIL::Semantic::InternalBarycentricsNoPerspective;\n\t\t\tinterpolation = DXIL::InterpolationMode::LinearSample;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nbool Converter::Impl::emit_stage_input_variables()\n{\n\tauto *node = entry_point_meta;\n\tif (!node->getOperand(2))\n\t\treturn true;\n\n\tauto &signature = node->getOperand(2);\n\tauto *signature_node = llvm::cast<llvm::MDNode>(signature);\n\tauto &inputs = signature_node->getOperand(0);\n\tif (!inputs)\n\t\treturn true;\n\n\tbool stage_arrayed_inputs = execution_model == spv::ExecutionModelGeometry ||\n\t                            execution_model == spv::ExecutionModelTessellationControl ||\n\t                            execution_model == spv::ExecutionModelTessellationEvaluation;\n\n\tuint32_t stage_input_vertices = execution_mode_meta.stage_input_num_vertex;\n\tif (execution_model == spv::ExecutionModelTessellationControl)\n\t{\n\t\t// The control point input arrays are effectively unsized. We have to give it something, so use upper bound.\n\t\tconstexpr uint32_t MaxControlPoints = 32;\n\t\tstage_input_vertices = MaxControlPoints;\n\t}\n\n\tauto *inputs_node = llvm::dyn_cast<llvm::MDNode>(inputs);\n\n\tauto &builder = spirv_module.get_builder();\n\n\tunsigned clip_distance_count = 0;\n\tunsigned cull_distance_count = 0;\n\tbool auto_patch_location = patch_location_offset == ~0u &&\n\t                           execution_model == spv::ExecutionModelTessellationEvaluation;\n\tif (auto_patch_location)\n\t\tpatch_location_offset = 0;\n\n\tfor (unsigned i = 0; i < inputs_node->getNumOperands(); i++)\n\t{\n\t\tbool arrayed_input = stage_arrayed_inputs;\n\t\tauto *input = llvm::cast<llvm::MDNode>(inputs_node->getOperand(i));\n\t\tauto element_id = get_constant_metadata(input, 0);\n\t\tauto semantic_name = get_string_metadata(input, 1);\n\t\tauto actual_element_type = normalize_component_type(static_cast<DXIL::ComponentType>(get_constant_metadata(input, 2)));\n\t\tauto effective_element_type = get_effective_input_output_type(actual_element_type);\n\t\tauto system_value = static_cast<DXIL::Semantic>(get_constant_metadata(input, 3));\n\n\t\tunsigned semantic_index = 0;\n\t\tif (input->getOperand(4))\n\t\t\tsemantic_index = get_constant_metadata(llvm::cast<llvm::MDNode>(input->getOperand(4)), 0);\n\n\t\tauto interpolation = static_cast<DXIL::InterpolationMode>(get_constant_metadata(input, 5));\n\t\tadjust_system_value(system_value, interpolation);\n\n\t\tauto rows = get_constant_metadata(input, 6);\n\t\tauto cols = get_constant_metadata(input, 7);\n\n\t\tauto start_row = get_constant_metadata(input, 8);\n\t\tauto start_col = get_constant_metadata(input, 9);\n\n\t\tif (auto_patch_location)\n\t\t\tpatch_location_offset = std::max(patch_location_offset, start_row + rows);\n\n\t\t// For HS <-> DS, ignore system values.\n\t\t// Allow certain system values that are synthesized however.\n\t\tif (execution_model == spv::ExecutionModelTessellationEvaluation && system_value != DXIL::Semantic::DomainLocation)\n\t\t\tsystem_value = DXIL::Semantic::User;\n\n\t\tbool masked_input = false;\n\t\tif (system_value == DXIL::Semantic::ShadingRate && options.quirks.ignore_primitive_shading_rate)\n\t\t\tmasked_input = true;\n\n\t\tif (!options.khr_barycentrics_enabled)\n\t\t{\n\t\t\tif (system_value == DXIL::Semantic::Barycentrics ||\n\t\t\t\tsystem_value == DXIL::Semantic::InternalBarycentricsNoPerspective)\n\t\t\t{\n\t\t\t\tcols = 2;\n\t\t\t}\n\t\t}\n\n\t\tspv::Id type_id = get_type_id(effective_element_type, rows, cols);\n\t\tif (system_value == DXIL::Semantic::Position)\n\t\t{\n\t\t\ttype_id = get_type_id(effective_element_type, rows, 4);\n\t\t}\n\t\telse if (system_value == DXIL::Semantic::IsFrontFace)\n\t\t{\n\t\t\t// Need to cast this to uint when loading the semantic input.\n\t\t\ttype_id = builder.makeBoolType();\n\t\t}\n\t\telse if (system_value == DXIL::Semantic::ClipDistance)\n\t\t{\n\t\t\t// DX is rather weird here and you can declare clip distance either as a vector or array, or both!\n\t\t\tinput_clip_cull_meta[element_id] = { clip_distance_count, cols, spv::BuiltInClipDistance };\n\t\t\tinput_elements_meta[element_id] = { 0, actual_element_type, 0, system_value };\n\t\t\tclip_distance_count += rows * cols;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (system_value == DXIL::Semantic::CullDistance)\n\t\t{\n\t\t\t// DX is rather weird here and you can declare clip distance either as a vector or array, or both!\n\t\t\tinput_clip_cull_meta[element_id] = { cull_distance_count, cols, spv::BuiltInCullDistance };\n\t\t\tinput_elements_meta[element_id] = { 0, actual_element_type, 0, system_value };\n\t\t\tcull_distance_count += rows * cols;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (system_value == DXIL::Semantic::PrimitiveID ||\n\t\t         system_value == DXIL::Semantic::ShadingRate ||\n\t\t         system_value == DXIL::Semantic::DomainLocation)\n\t\t{\n\t\t\tarrayed_input = false;\n\t\t}\n\n\t\tbool per_vertex = llvm_attribute_at_vertex_indices.count(element_id) != 0;\n\n\t\tif (arrayed_input)\n\t\t{\n\t\t\ttype_id =\n\t\t\t    builder.makeArrayType(type_id, builder.makeUintConstant(stage_input_vertices), 0);\n\t\t}\n\t\telse if (per_vertex && options.khr_barycentrics_enabled)\n\t\t{\n\t\t\t// TODO: Does this change for barycentrics with lines?\n\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(3), 0);\n\t\t\t// Default. We should emit PerVertex instead of flat. Linear here is the default, don't emit anything.\n\t\t\tinterpolation = DXIL::InterpolationMode::Linear;\n\t\t}\n\n\t\tauto variable_name = semantic_name;\n\t\tif (semantic_index != 0)\n\t\t{\n\t\t\tvariable_name += \"_\";\n\t\t\tvariable_name += dxil_spv::to_string(semantic_index);\n\t\t}\n\n\t\tspv::Id variable_id = create_variable(masked_input ? spv::StorageClassPrivate : spv::StorageClassInput, type_id,\n\t\t                                      variable_name.c_str());\n\t\tinput_elements_meta[element_id] = { variable_id, actual_element_type, system_value != DXIL::Semantic::User ? start_row : 0, system_value };\n\n\t\tif (per_vertex)\n\t\t{\n\t\t\tif (options.khr_barycentrics_enabled)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_KHR_fragment_shader_barycentric\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityFragmentBarycentricKHR);\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationPerVertexKHR);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_AMD_shader_explicit_vertex_parameter\");\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationExplicitInterpAMD);\n\t\t\t}\n\t\t}\n\n\t\tif (effective_element_type != actual_element_type && component_type_is_16bit(actual_element_type))\n\t\t\tbuilder.addDecoration(variable_id, spv::DecorationRelaxedPrecision);\n\n\t\tif (system_value != DXIL::Semantic::User)\n\t\t{\n\t\t\temit_builtin_decoration(variable_id, system_value, spv::StorageClassInput);\n\t\t\tif (execution_model == spv::ExecutionModelFragment)\n\t\t\t\temit_builtin_interpolation_decorations(variable_id, system_value, interpolation);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (execution_model == spv::ExecutionModelFragment)\n\t\t\t\temit_interpolation_decorations(variable_id, interpolation);\n\n\t\t\tVulkanStageIO vk_input = { start_row, start_col };\n\n\t\t\tif (resource_mapping_iface)\n\t\t\t{\n\t\t\t\tD3DStageIO d3d_input = { semantic_name.c_str(), semantic_index, start_row, rows };\n\n\t\t\t\tif (execution_model == spv::ExecutionModelVertex)\n\t\t\t\t{\n\t\t\t\t\tif (!resource_mapping_iface->remap_vertex_input(d3d_input, vk_input))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (!resource_mapping_iface->remap_stage_input(d3d_input, vk_input))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbuilder.addDecoration(variable_id, spv::DecorationLocation, vk_input.location);\n\n\t\t\tif (execution_model != spv::ExecutionModelVertex && vk_input.component != 0)\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationComponent, vk_input.component);\n\n\t\t\tif (execution_model == spv::ExecutionModelFragment && (vk_input.flags & STAGE_IO_PER_PRIMITIVE))\n\t\t\t{\n\t\t\t\tbuilder.addDecoration(variable_id, spv::DecorationPerPrimitiveEXT);\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_mesh_shader\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityMeshShadingEXT);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (clip_distance_count)\n\t{\n\t\tspv::Id type_id = get_type_id(DXIL::ComponentType::F32, clip_distance_count, 1, true);\n\t\tif (stage_arrayed_inputs)\n\t\t{\n\t\t\ttype_id = builder.makeArrayType(\n\t\t\t    type_id, builder.makeUintConstant(stage_input_vertices, false), 0);\n\t\t}\n\n\t\tspv::Id variable_id = create_variable(spv::StorageClassInput, type_id);\n\t\temit_builtin_decoration(variable_id, DXIL::Semantic::ClipDistance, spv::StorageClassInput);\n\t\tspirv_module.register_builtin_shader_input(variable_id, spv::BuiltInClipDistance);\n\t}\n\n\tif (cull_distance_count)\n\t{\n\t\tspv::Id type_id = get_type_id(DXIL::ComponentType::F32, cull_distance_count, 1, true);\n\t\tif (stage_arrayed_inputs)\n\t\t{\n\t\t\ttype_id = builder.makeArrayType(\n\t\t\t    type_id, builder.makeUintConstant(stage_input_vertices, false), 0);\n\t\t}\n\n\t\tspv::Id variable_id = create_variable(spv::StorageClassInput, type_id);\n\t\temit_builtin_decoration(variable_id, DXIL::Semantic::CullDistance, spv::StorageClassInput);\n\t\tspirv_module.register_builtin_shader_input(variable_id, spv::BuiltInCullDistance);\n\t}\n\n\treturn true;\n}\n\nspv::Id Converter::Impl::build_sampled_image(spv::Id image_id, spv::Id sampler_id, bool comparison)\n{\n\tbool is_non_uniform =\n\t    handle_to_resource_meta[image_id].non_uniform || handle_to_resource_meta[sampler_id].non_uniform;\n\n\tauto itr = std::find_if(combined_image_sampler_cache.begin(), combined_image_sampler_cache.end(),\n\t                        [&](const CombinedImageSampler &combined) {\n\t\t                        return combined.image_id == image_id && combined.sampler_id == sampler_id &&\n\t\t                               combined.non_uniform == is_non_uniform;\n\t                        });\n\n\tif (itr != combined_image_sampler_cache.end())\n\t\treturn itr->combined_id;\n\n\tauto &builder = spirv_module.get_builder();\n\tspv::Id image_type_id = get_type_id(image_id);\n\tspv::Dim dim = builder.getTypeDimensionality(image_type_id);\n\tbool arrayed = builder.isArrayedImageType(image_type_id);\n\tbool multisampled = builder.isMultisampledImageType(image_type_id);\n\tspv::Id sampled_format = builder.getImageComponentType(image_type_id);\n\n\timage_type_id =\n\t    builder.makeImageType(sampled_format, dim, comparison, arrayed, multisampled, 1, spv::ImageFormatUnknown);\n\n\tOperation *op = allocate(spv::OpSampledImage, builder.makeSampledImageType(image_type_id));\n\top->add_ids({ image_id, sampler_id });\n\tadd(op);\n\n\tif (is_non_uniform)\n\t{\n\t\tbuilder.addDecoration(op->id, spv::DecorationNonUniformEXT);\n\t\top->flags |= Operation::SinkableBit;\n\t}\n\n\tcombined_image_sampler_cache.push_back({ image_id, sampler_id, op->id, is_non_uniform });\n\treturn op->id;\n}\n\nspv::Id Converter::Impl::build_vector_type(spv::Id element_type, unsigned count)\n{\n\tauto &builder = spirv_module.get_builder();\n\tif (count == 1)\n\t\treturn element_type;\n\telse\n\t\treturn builder.makeVectorType(element_type, count);\n}\n\nspv::Id Converter::Impl::build_vector(spv::Id element_type, const spv::Id *elements, unsigned count)\n{\n\tif (count == 1)\n\t\treturn elements[0];\n\n\tauto &builder = spirv_module.get_builder();\n\n\tOperation *op = allocate(spv::OpCompositeConstruct, builder.makeVectorType(element_type, count));\n\tfor (unsigned i = 0; i < count; i++)\n\t\top->add_id(elements[i]);\n\n\tadd(op);\n\treturn op->id;\n}\n\nspv::Id Converter::Impl::build_constant_vector(spv::Id element_type, const spv::Id *elements, unsigned count)\n{\n\tif (count == 1)\n\t\treturn elements[0];\n\n\tauto &builder = spirv_module.get_builder();\n\treturn builder.makeCompositeConstant(builder.makeVectorType(element_type, count), { elements, elements + count });\n}\n\nspv::Id Converter::Impl::build_splat_constant_vector(spv::Id element_type, spv::Id value, unsigned count)\n{\n\tspv::Id ids[4];\n\tfor (unsigned i = 0; i < count; i++)\n\t\tids[i] = value;\n\treturn build_constant_vector(element_type, ids, count);\n}\n\nspv::Id Converter::Impl::build_offset(spv::Id value, unsigned offset)\n{\n\tif (offset == 0)\n\t\treturn value;\n\n\tauto &builder = spirv_module.get_builder();\n\n\tOperation *op = allocate(spv::OpIAdd, builder.makeUintType(32));\n\top->add_ids({ value, builder.makeUintConstant(offset) });\n\n\tadd(op);\n\treturn op->id;\n}\n\nvoid Converter::Impl::repack_sparse_feedback(DXIL::ComponentType component_type, unsigned num_components, const llvm::Value *value,\n                                             const llvm::Type *target_type, spv::Id override_value)\n{\n\tauto *code_id = allocate(spv::OpCompositeExtract, builder().makeUintType(32));\n\tcode_id->add_id(get_id_for_value(value));\n\tcode_id->add_literal(0);\n\tadd(code_id);\n\n\tauto effective_component_type = get_effective_typed_resource_type(component_type);\n\tspv::Id texel_id;\n\n\tif (override_value)\n\t{\n\t\ttexel_id = override_value;\n\t}\n\telse\n\t{\n\t\tauto *texel = allocate(spv::OpCompositeExtract, get_type_id(effective_component_type, 1, num_components));\n\t\ttexel->add_id(get_id_for_value(value));\n\t\ttexel->add_literal(1);\n\t\tadd(texel);\n\t\ttexel_id = texel->id;\n\t}\n\n\tfixup_load_type_typed(component_type, num_components, texel_id, target_type);\n\n\tspv::Id components[5];\n\n\tif (num_components > 1)\n\t{\n\t\tfor (unsigned i = 0; i < num_components; i++)\n\t\t{\n\t\t\tauto *extract_op = allocate(spv::OpCompositeExtract, get_type_id(component_type, 1, 1));\n\t\t\textract_op->add_id(texel_id);\n\t\t\textract_op->add_literal(i);\n\t\t\tadd(extract_op);\n\t\t\tcomponents[i] = extract_op->id;\n\t\t}\n\t}\n\telse\n\t{\n\t\tfor (auto &comp : components)\n\t\t\tcomp = texel_id;\n\t\tnum_components = 4;\n\t}\n\n\tcomponents[num_components] = code_id->id;\n\n\tauto *repack_op = allocate(spv::OpCompositeConstruct, get_type_id(value->getType()));\n\tfor (auto &comp : components)\n\t\trepack_op->add_id(comp);\n\tadd(repack_op);\n\trewrite_value(value, repack_op->id);\n}\n\nbool Converter::Impl::support_native_fp16_operations() const\n{\n\treturn execution_mode_meta.native_16bit_operations || options.min_precision_prefer_native_16bit;\n}\n\nspv::Id Converter::Impl::build_value_cast(spv::Id value_id,\n                                          DXIL::ComponentType input_type,\n                                          DXIL::ComponentType output_type,\n                                          unsigned components)\n{\n\t// This path only hits for bitcasts or 16-bit <-> 32-bit casts.\n\tbool output_16bit = component_type_is_16bit(output_type);\n\tbool input_16bit = component_type_is_16bit(input_type);\n\n\tspv::Op opcode = spv::OpBitcast;\n\n\tif (output_16bit != input_16bit)\n\t{\n\t\tswitch (input_type)\n\t\t{\n\t\tcase DXIL::ComponentType::F16:\n\t\tcase DXIL::ComponentType::F32:\n\t\t\topcode = spv::OpFConvert;\n\t\t\tbreak;\n\n\t\tcase DXIL::ComponentType::I16:\n\t\tcase DXIL::ComponentType::I32:\n\t\t\topcode = spv::OpSConvert;\n\t\t\tbreak;\n\n\t\tcase DXIL::ComponentType::U16:\n\t\tcase DXIL::ComponentType::U32:\n\t\t\topcode = spv::OpUConvert;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\t// OpUConvert is not allowed on integer outputs.\n\t\t// We also need SConvert if we're doing 16 -> I32,\n\t\t// since what we actually want is I16 -> I32.\n\t\tswitch (output_type)\n\t\t{\n\t\tcase DXIL::ComponentType::I16:\n\t\tcase DXIL::ComponentType::I32:\n\t\t\topcode = spv::OpSConvert;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tOperation *op = allocate(opcode, get_type_id(output_type, 1, components));\n\top->add_id(value_id);\n\tadd(op);\n\treturn op->id;\n}\n\nvoid Converter::Impl::fixup_load_type_io(DXIL::ComponentType component_type, unsigned components, const llvm::Value *value)\n{\n\tauto output_component_type = component_type;\n\tauto input_component_type = component_type;\n\n\tbool promote_fp16 = input_component_type == DXIL::ComponentType::F16 && !support_native_fp16_operations();\n\n\tif (!options.storage_16bit_input_output || promote_fp16)\n\t\tinput_component_type = convert_16bit_component_to_32bit(input_component_type);\n\tif (promote_fp16)\n\t\toutput_component_type = convert_16bit_component_to_32bit(output_component_type);\n\n\toutput_component_type = convert_component_to_unsigned(output_component_type);\n\n\tif (output_component_type != input_component_type)\n\t{\n\t\trewrite_value(value, build_value_cast(get_id_for_value(value), input_component_type,\n\t\t                                      output_component_type, components));\n\t}\n}\n\nvoid Converter::Impl::fixup_load_type_atomic(DXIL::ComponentType component_type, unsigned components, const llvm::Value *value)\n{\n\tauto output_component_type = component_type;\n\tauto input_component_type = component_type;\n\n\toutput_component_type = convert_component_to_unsigned(output_component_type);\n\n\tif (output_component_type != input_component_type)\n\t{\n\t\trewrite_value(value, build_value_cast(get_id_for_value(value), input_component_type,\n\t\t                                      output_component_type, components));\n\t}\n}\n\nvoid Converter::Impl::fixup_load_type_typed(DXIL::ComponentType &component_type, unsigned components, spv::Id &value_id,\n                                            const llvm::Type *target_type)\n{\n\tauto output_component_type = component_type;\n\tauto input_component_type = get_effective_typed_resource_type(component_type);\n\n\tif (output_component_type == DXIL::ComponentType::U64 && target_type->getIntegerBitWidth() == 32)\n\t{\n\t\t// If the component type is U64 it's used for atomics, but load/store interface is still 32-bit.\n\t\t// Bit-cast rather than value cast.\n\t\tauto *bitcast_op = allocate(spv::OpCompositeExtract, builder().makeUintType(64));\n\t\tbitcast_op->add_id(value_id);\n\t\tbitcast_op->add_literal(0);\n\t\tadd(bitcast_op);\n\n\t\tauto *u32_cast_op = allocate(spv::OpBitcast, builder().makeVectorType(builder().makeUintType(32), 2));\n\t\tu32_cast_op->add_id(bitcast_op->id);\n\t\tadd(u32_cast_op);\n\t\toutput_component_type = DXIL::ComponentType::U32;\n\n\t\tif (components > 2)\n\t\t{\n\t\t\tauto *composite_op =\n\t\t\t\tallocate(spv::OpCompositeConstruct,\n\t\t\t\t         builder().makeVectorType(builder().makeUintType(32), components));\n\t\t\tcomposite_op->add_id(u32_cast_op->id);\n\t\t\tfor (unsigned i = 2; i < components; i++)\n\t\t\t\tcomposite_op->add_id(builder().makeUintConstant(0));\n\t\t\tadd(composite_op);\n\t\t\tvalue_id = composite_op->id;\n\t\t}\n\t\telse if (components == 1)\n\t\t{\n\t\t\tauto *extract_op = allocate(spv::OpCompositeExtract, builder().makeUintType(32));\n\t\t\textract_op->add_id(u32_cast_op->id);\n\t\t\textract_op->add_literal(0);\n\t\t\tadd(extract_op);\n\t\t\tvalue_id = extract_op->id;\n\t\t}\n\t\telse\n\t\t\tvalue_id = u32_cast_op->id;\n\t}\n\telse\n\t{\n\t\tif (output_component_type == DXIL::ComponentType::F16 && !support_native_fp16_operations())\n\t\t\toutput_component_type = convert_16bit_component_to_32bit(output_component_type);\n\t\telse if (target_type->getTypeID() == llvm::Type::TypeID::FloatTyID)\n\t\t{\n\t\t\t// Only convert if we actually want half here.\n\t\t\t// Certain operations always return float even if the resource type is half for some silly reason.\n\t\t\toutput_component_type = DXIL::ComponentType::F32;\n\t\t}\n\n\t\toutput_component_type = convert_component_to_unsigned(output_component_type);\n\n\t\tif (output_component_type != input_component_type)\n\t\t\tvalue_id = build_value_cast(value_id, input_component_type, output_component_type, components);\n\t\tcomponent_type = output_component_type;\n\t}\n}\n\nvoid Converter::Impl::fixup_load_type_typed(DXIL::ComponentType component_type, unsigned components,\n                                            const llvm::Value *value, const llvm::Type *target_type)\n{\n\tspv::Id value_id = get_id_for_value(value);\n\tspv::Id new_value_id = value_id;\n\tfixup_load_type_typed(component_type, components, new_value_id, target_type);\n\tif (new_value_id != value_id)\n\t\trewrite_value(value, new_value_id);\n}\n\nspv::Id Converter::Impl::fixup_store_type_io(DXIL::ComponentType component_type, unsigned components, spv::Id value)\n{\n\tauto output_component_type = component_type;\n\tauto input_component_type = component_type;\n\n\tif (!options.storage_16bit_input_output ||\n\t    (output_component_type == DXIL::ComponentType::F16 && !support_native_fp16_operations()))\n\t{\n\t\toutput_component_type = convert_16bit_component_to_32bit(output_component_type);\n\t}\n\n\tif (input_component_type == DXIL::ComponentType::F16 && !support_native_fp16_operations())\n\t\tinput_component_type = convert_16bit_component_to_32bit(input_component_type);\n\n\tinput_component_type = convert_component_to_unsigned(input_component_type);\n\n\tif (output_component_type != input_component_type)\n\t\tvalue = build_value_cast(value, input_component_type, output_component_type, components);\n\treturn value;\n}\n\nspv::Id Converter::Impl::fixup_store_type_atomic(DXIL::ComponentType component_type, unsigned components, spv::Id value)\n{\n\tauto output_component_type = component_type;\n\tauto input_component_type = component_type;\n\n\tinput_component_type = convert_component_to_unsigned(input_component_type);\n\n\tif (output_component_type != input_component_type)\n\t\tvalue = build_value_cast(value, input_component_type, output_component_type, components);\n\treturn value;\n}\n\nspv::Id Converter::Impl::fixup_store_type_typed(DXIL::ComponentType component_type, unsigned components, spv::Id value)\n{\n\tif (component_type == DXIL::ComponentType::U64)\n\t{\n\t\t// If the component type is U64 it's used for atomics, but load/store interface is still 32-bit.\n\t\t// Bit-cast rather than value cast.\n\t\tspv::Id u64_ids[4] = {};\n\t\tfor (unsigned i = 0; i < components / 2; i++)\n\t\t{\n\t\t\tauto *shuffle_op = allocate(spv::OpVectorShuffle, builder().makeVectorType(builder().makeUintType(32), 2));\n\t\t\tshuffle_op->add_id(value);\n\t\t\tshuffle_op->add_id(value);\n\t\t\tshuffle_op->add_literal(2 * i + 0);\n\t\t\tshuffle_op->add_literal(2 * i + 1);\n\t\t\tadd(shuffle_op);\n\n\t\t\tauto *cast_op = allocate(spv::OpBitcast, builder().makeUintType(64));\n\t\t\tcast_op->add_id(shuffle_op->id);\n\t\t\tadd(cast_op);\n\t\t\tu64_ids[i] = cast_op->id;\n\t\t}\n\n\t\tfor (unsigned i = components / 2; i < components; i++)\n\t\t\tu64_ids[i] = builder().makeUint64Constant(0);\n\n\t\tvalue = build_vector(builder().makeUintType(64), u64_ids, components);\n\t}\n\telse\n\t{\n\t\tauto output_component_type = get_effective_typed_resource_type(component_type);\n\t\tauto input_component_type = component_type;\n\n\t\tif (input_component_type == DXIL::ComponentType::F16 && !support_native_fp16_operations())\n\t\t\tinput_component_type = convert_16bit_component_to_32bit(input_component_type);\n\t\tinput_component_type = convert_component_to_unsigned(input_component_type);\n\n\t\tif (output_component_type != input_component_type)\n\t\t\tvalue = build_value_cast(value, input_component_type, output_component_type, components);\n\t}\n\n\treturn value;\n}\n\nbool Converter::Impl::emit_phi_instruction(CFGNode *block, const llvm::PHINode &instruction)\n{\n\tunsigned count = instruction.getNumIncomingValues();\n\tspv::Id override_type = 0;\n\n\tif (ags_filter_phi(*this, instruction, override_type))\n\t\treturn true;\n\n\tif (count == 1)\n\t{\n\t\t// Degenerate PHI. Seems to happen in some bizarre cases with lcssa passes?\n\t\tauto *value = instruction.getIncomingValue(0);\n\t\trewrite_value(&instruction, get_id_for_value(value));\n\n\t\t// This PHI node can actually be pointer or descriptor for whatever reason,\n\t\t// so inherit any such mappings.\n\t\t{\n\t\t\tauto itr = handle_to_storage_class.find(value);\n\t\t\tif (itr != handle_to_storage_class.end())\n\t\t\t\thandle_to_storage_class[&instruction] = itr->second;\n\t\t}\n\n\t\t{\n\t\t\tauto itr = handle_to_root_member_offset.find(value);\n\t\t\tif (itr != handle_to_root_member_offset.end())\n\t\t\t\thandle_to_root_member_offset[&instruction] = itr->second;\n\t\t}\n\t}\n\telse\n\t{\n\t\tPHI phi;\n\t\tphi.id = get_id_for_value(&instruction);\n\n\t\tauto itr = llvm_composite_meta.find(&instruction);\n\n\t\tif (itr != llvm_composite_meta.end() && itr->second.components <= 4 && (itr->second.access_mask & ~0xfu) == 0 &&\n\t\t    std::find(llvm_dxil_op_fake_struct_types.begin(), llvm_dxil_op_fake_struct_types.end(), instruction.getType()) !=\n\t\t    llvm_dxil_op_fake_struct_types.end())\n\t\t{\n\t\t\t// Using PHI as a composite is exceedingly quirky, but it does come up.\n\t\t\t// FIXME: This could go wrong if one incoming value uses different components\n\t\t\t// from the others, but this scenario has only ever been observed from single-incoming\n\t\t\t// values, so this code path shouldn't really be taken at all.\n\t\t\tphi.type_id = get_type_id(instruction.getType()->getStructElementType(0));\n\t\t\tif (itr->second.components > 1)\n\t\t\t\tphi.type_id = builder().makeVectorType(phi.type_id, itr->second.components);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tphi.type_id = override_type ? override_type : get_type_id(instruction.getType());\n\t\t}\n\n\t\tphi.relaxed = type_can_relax_precision(instruction.getType(), false);\n\n\t\tfor (unsigned i = 0; i < count; i++)\n\t\t{\n\t\t\tIncomingValue incoming = {};\n\t\t\tauto bb_itr = bb_map.find(instruction.getIncomingBlock(i));\n\n\t\t\t// If the block was statically eliminated, it might not exist.\n\t\t\tif (bb_itr != bb_map.end())\n\t\t\t{\n\t\t\t\tincoming.block = bb_itr->second->node;\n\t\t\t\tauto *value = instruction.getIncomingValue(i);\n\t\t\t\tincoming.id = get_id_for_value(value);\n\t\t\t\tphi.incoming.push_back(incoming);\n\t\t\t}\n\t\t}\n\n\t\tif (phi.incoming.empty())\n\t\t{\n\t\t\tLOGE(\"PHI instruction has zero incoming blocks.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (phi.incoming.size() > 1)\n\t\t\tblock->ir.phi.push_back(std::move(phi));\n\t\telse\n\t\t\trewrite_value(&instruction, phi.incoming.front().id);\n\t}\n\n\treturn true;\n}\n\nstatic bool instruction_has_side_effects(const llvm::Instruction &instruction)\n{\n\tif (llvm::isa<llvm::StoreInst>(&instruction) ||\n\t    llvm::isa<llvm::AtomicCmpXchgInst>(&instruction) ||\n\t    llvm::isa<llvm::AtomicRMWInst>(&instruction))\n\t{\n\t\treturn true;\n\t}\n\n\tif (auto *call_inst = llvm::dyn_cast<llvm::CallInst>(&instruction))\n\t{\n\t\tauto *called_function = call_inst->getCalledFunction();\n\t\tif (strncmp(called_function->getName().data(), \"dx.op\", 5) == 0)\n\t\t\treturn dxil_instruction_has_side_effects(call_inst);\n\t\telse\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool Converter::Impl::emit_instruction(CFGNode *block, const llvm::Instruction &instruction)\n{\n\tif (instruction.isTerminator())\n\t\treturn true;\n\n\t// We really shouldn't have to do this, but DXC misses some dead SSA ops.\n\t// Helps sanitize repro suite output in some cases.\n\tif (options.eliminate_dead_code &&\n\t    !instruction_has_side_effects(instruction) &&\n\t    llvm_used_ssa_values.count(&instruction) == 0)\n\t{\n\t\treturn true;\n\t}\n\n\tcurrent_block = &block->ir.operations;\n\n\tif (auto *call_inst = llvm::dyn_cast<llvm::CallInst>(&instruction))\n\t{\n\t\tauto *called_function = call_inst->getCalledFunction();\n\t\tif (strncmp(called_function->getName().data(), \"dx.op\", 5) == 0)\n\t\t{\n\t\t\treturn emit_dxil_instruction(*this, call_inst);\n\t\t}\n\t\telse if (strncmp(called_function->getName().data(), \"llvm.\", 5) == 0)\n\t\t{\n\t\t\t// lib_6_6 sometimes emits llvm.lifetime.begin/end for some bizarre reason.\n\t\t\t// Just ignore ...\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn emit_call_instruction(*this, *call_inst);\n\t\t}\n\t}\n\telse if (auto *phi_inst = llvm::dyn_cast<llvm::PHINode>(&instruction))\n\t\treturn emit_phi_instruction(block, *phi_inst);\n\telse\n\t\treturn emit_llvm_instruction(*this, instruction);\n\n\tcurrent_block = nullptr;\n\treturn false;\n}\n\nbool Converter::Impl::emit_execution_modes_node_output(llvm::MDNode *output)\n{\n\tNodeOutputMeta output_meta = {};\n\n\tbool is_rw_sharing;\n\toutput_meta.payload_stride = node_parse_payload_stride(output, is_rw_sharing);\n\toutput_meta.spec_constant_node_index = builder().makeUintConstant(0, true);\n\tbuilder().addDecoration(output_meta.spec_constant_node_index, spv::DecorationSpecId,\n\t                        int(NodeSpecIdOutputBase + node_outputs.size()));\n\n\tuint32_t num_ops = output->getNumOperands();\n\tfor (uint32_t i = 0; i < num_ops; i += 2)\n\t{\n\t\tauto tag = DXIL::NodeMetadataTag(get_constant_metadata(output, i));\n\t\tif (tag == DXIL::NodeMetadataTag::NodeOutputID)\n\t\t{\n\t\t\tauto *output_node = llvm::cast<llvm::MDNode>(output->getOperand(i + 1));\n\t\t\tString name = get_string_metadata(output_node, 0);\n\t\t\tbuilder().addName(output_meta.spec_constant_node_index, name.c_str());\n\n\t\t\t// FIXME: This is probably not accurate for arrayed nodes.\n\t\t\t// Can recursive nodes be arrayed? Seems very spicy ...\n\t\t\toutput_meta.is_recursive =\n\t\t\t\tname == node_input.node_id &&\n\t\t\t\tnode_input.node_array_index == get_constant_metadata(output_node, 1);\n\t\t}\n\t}\n\n\tnode_outputs.push_back(output_meta);\n\treturn true;\n}\n\nNodeDispatchGrid Converter::Impl::node_parse_dispatch_grid(llvm::MDNode *node_meta)\n{\n\tuint32_t num_ops = node_meta->getNumOperands();\n\tfor (uint32_t i = 0; i < num_ops; i += 2)\n\t{\n\t\tauto tag = DXIL::NodeMetadataTag(get_constant_metadata(node_meta, i));\n\t\tif (tag == DXIL::NodeMetadataTag::NodeRecordType)\n\t\t{\n\t\t\tauto *node_record_type = llvm::cast<llvm::MDNode>(node_meta->getOperand(i + 1));\n\t\t\tfor (uint32_t j = 0; j < node_record_type->getNumOperands(); j += 2)\n\t\t\t{\n\t\t\t\tif (get_constant_metadata(node_record_type, j) == 1)\n\t\t\t\t{\n\t\t\t\t\tauto *dispatch_info = llvm::cast<llvm::MDNode>(node_record_type->getOperand(j + 1));\n\t\t\t\t\tuint32_t byte_offset = get_constant_metadata(dispatch_info, 0);\n\t\t\t\t\tauto component_type = DXIL::ComponentType(get_constant_metadata(dispatch_info, 1));\n\t\t\t\t\tuint32_t num_components = get_constant_metadata(dispatch_info, 2);\n\t\t\t\t\treturn { byte_offset, component_type, num_components };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {};\n}\n\nuint32_t Converter::Impl::node_parse_payload_stride(llvm::MDNode *node_meta, bool &is_rw_sharing)\n{\n\tuint32_t num_ops = node_meta->getNumOperands();\n\tuint32_t payload_stride = 0;\n\tis_rw_sharing = false;\n\n\tfor (uint32_t i = 0; i < num_ops; i += 2)\n\t{\n\t\tauto tag = DXIL::NodeMetadataTag(get_constant_metadata(node_meta, i));\n\t\tif (tag == DXIL::NodeMetadataTag::NodeIOFlags)\n\t\t{\n\t\t\tuint32_t node_io_flags = get_constant_metadata(node_meta, i + 1);\n\t\t\tif ((node_io_flags & DXIL::NodeIOEmptyRecordBit) != 0)\n\t\t\t\treturn 0;\n\t\t\tif ((node_io_flags & DXIL::NodeIOTrackRWInputSharingBit) != 0)\n\t\t\t\tis_rw_sharing = true;\n\t\t}\n\t\telse if (tag == DXIL::NodeMetadataTag::NodeRecordType)\n\t\t{\n\t\t\tauto *node_record_type = llvm::cast<llvm::MDNode>(node_meta->getOperand(i + 1));\n\t\t\tfor (uint32_t j = 0; j < node_record_type->getNumOperands(); j += 2)\n\t\t\t{\n\t\t\t\tif (get_constant_metadata(node_record_type, j) == 0)\n\t\t\t\t{\n\t\t\t\t\tuint32_t input_node_size = get_constant_metadata(node_record_type, j + 1);\n\t\t\t\t\tpayload_stride = input_node_size;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (is_rw_sharing)\n\t{\n\t\t// DXIL metadata does not account for the implied u32 used for group sharing.\n\t\t// In case the last member is u16, align to u32.\n\t\tpayload_stride = (payload_stride + 3u) & ~3u;\n\t\t// Allocate space for magic word.\n\t\tpayload_stride += 4;\n\t}\n\n\treturn payload_stride;\n}\n\nbool Converter::Impl::emit_execution_modes_node_input()\n{\n\tspv::Id u32_type_id = builder().makeUintType(32);\n\tspv::Id uvec2_type_id = builder().makeVectorType(u32_type_id, 2);\n\tspv::Id u64_type_id = builder().makeUintType(64);\n\n\tif (node_input.payload_stride)\n\t{\n\t\tnode_input.private_bda_var_id = create_variable(\n\t\t\tspv::StorageClassPrivate, u64_type_id, \"NodeInputPayloadBDA\");\n\t\tnode_input.private_stride_var_id = create_variable(\n\t\t\tspv::StorageClassPrivate, u32_type_id, \"NodeInputStride\");\n\t}\n\n\t// We have to rewrite global IDs. Local invocation should remain intact.\n\tspv::Id uvec3_type = builder().makeVectorType(u32_type_id, 3);\n\tspv::Id workgroup_id = create_variable(spv::StorageClassPrivate, uvec3_type, \"WorkgroupID\");\n\tspv::Id global_invocation_id = create_variable(spv::StorageClassPrivate, uvec3_type, \"GlobalInvocationID\");\n\tspirv_module.register_builtin_shader_input(workgroup_id, spv::BuiltInWorkgroupId);\n\tspirv_module.register_builtin_shader_input(global_invocation_id, spv::BuiltInGlobalInvocationId);\n\n\t// Emit binding model.\n\t// Push constants are our only option.\n\tif (!options.inline_ubo_enable)\n\t{\n\t\tLOGE(\"When compiling for nodes, inline UBO path must be enabled for root parameters.\\n\");\n\t\treturn false;\n\t}\n\n\tnode_input.shader_record_block_type_id = emit_shader_record_buffer_block_type(true);\n\tspv::Id ptr_shader_record_block_type_id = 0;\n\tif (node_input.shader_record_block_type_id)\n\t{\n\t\tptr_shader_record_block_type_id =\n\t\t\tbuilder().makePointer(spv::StorageClassPhysicalStorageBuffer,\n\t\t\t                      node_input.shader_record_block_type_id);\n\t}\n\telse\n\t{\n\t\t// Dummy type\n\t\tptr_shader_record_block_type_id = builder().makeVectorType(builder().makeUintType(32), 2);\n\t}\n\n\t// Declare the ABI for dispatching a node. This will change depending on the dispatch mode,\n\t// and style of execution (indirect pull or array).\n\n\tspv::Id u32_array_type_id = builder().makeRuntimeArray(u32_type_id);\n\tbuilder().addDecoration(u32_array_type_id, spv::DecorationArrayStride, 4);\n\n\tspv::Id u32_struct_type_id = builder().makeStructType({ u32_type_id }, \"NodeReadonlyU32Ptr\");\n\tbuilder().addDecoration(u32_struct_type_id, spv::DecorationBlock);\n\tbuilder().addMemberDecoration(u32_struct_type_id, 0, spv::DecorationOffset, 0);\n\tbuilder().addMemberDecoration(u32_struct_type_id, 0, spv::DecorationNonWritable);\n\tbuilder().addMemberName(u32_struct_type_id, 0, \"value\");\n\tspv::Id u32_ptr_type_id = builder().makePointer(spv::StorageClassPhysicalStorageBuffer, u32_struct_type_id);\n\n\tspv::Id u32_array_struct_type_id = builder().makeStructType({ u32_array_type_id }, \"NodeReadonlyU32ArrayPtr\");\n\tbuilder().addDecoration(u32_array_struct_type_id, spv::DecorationBlock);\n\tbuilder().addMemberDecoration(u32_array_struct_type_id, 0, spv::DecorationOffset, 0);\n\tbuilder().addMemberDecoration(u32_array_struct_type_id, 0, spv::DecorationNonWritable);\n\tbuilder().addMemberName(u32_array_struct_type_id, 0, \"offsets\");\n\tspv::Id u32_array_ptr_type_id = builder().makePointer(spv::StorageClassPhysicalStorageBuffer, u32_array_struct_type_id);\n\n\tconst Vector<spv::Id> members = {\n\t\tu64_type_id,\n\t\tu32_ptr_type_id,\n\t\tu32_ptr_type_id,\n\t\tuvec2_type_id,\n\t\tu64_type_id,\n\t\tu64_type_id,\n\t\tptr_shader_record_block_type_id,\n\t\tu32_type_id,\n\t\tu32_type_id,\n\t};\n\n\tspv::Id type_id = builder().makeStructType(members, \"NodeDispatchRegisters\");\n\tbuilder().addMemberDecoration(type_id, NodePayloadBDA, spv::DecorationOffset, 0);\n\tbuilder().addMemberDecoration(type_id, NodeLinearOffsetBDA, spv::DecorationOffset, 8);\n\tbuilder().addMemberDecoration(type_id, NodeEndNodesBDA, spv::DecorationOffset, 16);\n\tbuilder().addMemberDecoration(type_id, NodePayloadStrideOrOffsetsBDA, spv::DecorationOffset, 24);\n\tbuilder().addMemberDecoration(type_id, NodePayloadOutputBDA, spv::DecorationOffset, 32);\n\tbuilder().addMemberDecoration(type_id, NodePayloadOutputAtomicBDA, spv::DecorationOffset, 40);\n\tbuilder().addMemberDecoration(type_id, NodeLocalRootSignatureBDA, spv::DecorationOffset, 48);\n\tbuilder().addMemberDecoration(type_id, NodePayloadOutputOffset, spv::DecorationOffset, 56);\n\tbuilder().addMemberDecoration(type_id, NodeRemainingRecursionLevels, spv::DecorationOffset, 60);\n\n\t// For linear node layout (entry point).\n\t// Node payload is found at PayloadLinearBDA + NodeIndex * PayloadStride.\n\tbuilder().addMemberName(type_id, NodePayloadBDA, \"PayloadLinearBDA\");\n\t// With packed workgroup layout, need to apply an offset.\n\tbuilder().addMemberName(type_id, NodeLinearOffsetBDA, \"NodeLinearOffsetBDA\");\n\t// For thread and coalesce, need to know total number of threads to mask execution on edge.\n\tbuilder().addMemberName(type_id, NodeEndNodesBDA, \"NodeEndNodesBDA\");\n\tbuilder().addMemberName(type_id, NodePayloadStrideOrOffsetsBDA, \"NodePayloadStrideOrOffsetsBDA\");\n\tbuilder().addMemberName(type_id, NodePayloadOutputBDA, \"NodePayloadOutputBDA\");\n\tbuilder().addMemberName(type_id, NodePayloadOutputAtomicBDA, \"NodePayloadOutputAtomicBDA\");\n\tbuilder().addMemberName(type_id, NodeLocalRootSignatureBDA, \"NodeLocalRootSignatureBDA\");\n\t// For broadcast nodes. Need to instance multiple times.\n\t// Becomes WorkGroupID and affects GlobalInvocationID.\n\tbuilder().addMemberName(type_id, NodePayloadOutputOffset, \"NodePayloadOutputOffset\");\n\tbuilder().addMemberName(type_id, NodeRemainingRecursionLevels, \"NodeRemainingRecursionLevels\");\n\tbuilder().addDecoration(type_id, spv::DecorationBlock);\n\tnode_input.node_dispatch_push_id =\n\t    create_variable(spv::StorageClassPushConstant, type_id, \"NodeDispatch\");\n\tbuilder().addDecoration(node_input.node_dispatch_push_id, spv::DecorationRestrictPointer);\n\n\tnode_input.private_coalesce_offset_id =\n\t\tcreate_variable(spv::StorageClassPrivate, u32_type_id, \"NodeCoalesceOffset\");\n\tnode_input.private_coalesce_count_id =\n\t\tcreate_variable(spv::StorageClassPrivate, u32_type_id, \"NodeCoalesceCount\");\n\n\tnode_input.u32_ptr_type_id = u32_ptr_type_id;\n\tnode_input.u32_array_ptr_type_id = u32_array_ptr_type_id;\n\n\tspv::Id u64_struct_type_id = builder().makeStructType({ u64_type_id }, \"NodeReadonlyU64Ptr\");\n\tbuilder().addDecoration(u64_struct_type_id, spv::DecorationBlock);\n\tbuilder().addMemberDecoration(u64_struct_type_id, 0, spv::DecorationOffset, 0);\n\tbuilder().addMemberDecoration(u64_struct_type_id, 0, spv::DecorationNonWritable);\n\tbuilder().addMemberName(u64_struct_type_id, 0, \"value\");\n\tnode_input.u64_ptr_type_id = builder().makePointer(spv::StorageClassPhysicalStorageBuffer, u64_struct_type_id);\n\n\treturn true;\n}\n\nNodeOutputData Converter::Impl::get_node_output(llvm::MDNode *output)\n{\n\tNodeOutputData data = {};\n\n\tuint32_t num_ops = output->getNumOperands();\n\tfor (uint32_t i = 0; i < num_ops; i += 2)\n\t{\n\t\tauto tag = DXIL::NodeMetadataTag(get_constant_metadata(output, i));\n\t\tif (tag == DXIL::NodeMetadataTag::NodeOutputID)\n\t\t{\n\t\t\tauto *output_node = llvm::cast<llvm::MDNode>(output->getOperand(i + 1));\n\t\t\tdata.node_id = get_string_metadata(output_node, 0);\n\t\t\tdata.node_array_index = get_constant_metadata(output_node, 1);\n\t\t}\n\t\telse if (tag == DXIL::NodeMetadataTag::NodeAllowSparseNodes)\n\t\t\tdata.sparse_array = get_constant_metadata(output, i + 1) != 0;\n\t\telse if (tag == DXIL::NodeMetadataTag::NodeOutputArraySize)\n\t\t\tdata.node_array_size = get_constant_metadata(output, i + 1);\n\t\telse if (tag == DXIL::NodeMetadataTag::NodeMaxRecords)\n\t\t\tdata.max_records = get_constant_metadata(output, i + 1);\n\t}\n\n\treturn data;\n}\n\nNodeInputData Converter::Impl::get_node_input(llvm::MDNode *meta)\n{\n\tNodeInputData node = {};\n\n\tauto *launch_type_node = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeLaunchType);\n\tif (!launch_type_node)\n\t\treturn {};\n\n\tnode.launch_type = DXIL::NodeLaunchType(\n\t    llvm::cast<llvm::ConstantAsMetadata>(*launch_type_node)->getValue()->getUniqueInteger().getZExtValue());\n\n\tif (node.launch_type == DXIL::NodeLaunchType::Invalid)\n\t\treturn {};\n\n\tauto *is_program_entry_node = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeIsProgramEntry);\n\tif (is_program_entry_node)\n\t{\n\t\tnode.is_program_entry =\n\t\t    llvm::cast<llvm::ConstantAsMetadata>(*is_program_entry_node)->getValue()->getUniqueInteger().getZExtValue() != 0;\n\t}\n\n\tnode.is_indirect_bda_stride_program_entry_spec_id = NodeSpecIdIndirectPayloadStride;\n\tnode.is_entry_point_spec_id = NodeSpecIdIsEntryPoint;\n\n\tif (node.launch_type == DXIL::NodeLaunchType::Broadcasting)\n\t{\n\t\tnode.dispatch_grid_is_upper_bound_spec_id = NodeSpecIdDispatchGridIsUpperBound;\n\t\tnode.is_static_broadcast_node_spec_id = NodeSpecIdIsStaticBroadcastNode;\n\t\tnode.max_broadcast_grid_spec_id[0] = NodeSpecIdMaxBroadcastGridX;\n\t\tnode.max_broadcast_grid_spec_id[1] = NodeSpecIdMaxBroadcastGridY;\n\t\tnode.max_broadcast_grid_spec_id[2] = NodeSpecIdMaxBroadcastGridZ;\n\t}\n\telse\n\t{\n\t\tnode.dispatch_grid_is_upper_bound_spec_id = UINT32_MAX;\n\t\tnode.is_static_broadcast_node_spec_id = UINT32_MAX;\n\t\tfor (auto &spec_id : node.max_broadcast_grid_spec_id)\n\t\t\tspec_id = UINT32_MAX;\n\t}\n\n\tauto *recursion_node = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeMaxRecursionDepth);\n\tif (recursion_node)\n\t{\n\t\tnode.recursion_factor =\n\t\t\tllvm::cast<llvm::ConstantAsMetadata>(*recursion_node)->getValue()->getUniqueInteger().getZExtValue();\n\t}\n\n\tif (node.launch_type == DXIL::NodeLaunchType::Broadcasting)\n\t{\n\t\tauto *max_grid = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeMaxDispatchGrid);\n\t\tconst llvm::MDOperand *fixed_grid;\n\n\t\tif (max_grid)\n\t\t{\n\t\t\tnode.dispatch_grid_is_upper_bound = true;\n\t\t\tfixed_grid = max_grid;\n\t\t}\n\t\telse\n\t\t\tfixed_grid = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeDispatchGrid);\n\n\t\tif (!fixed_grid)\n\t\t\treturn {};\n\n\t\tfor (uint32_t i = 0; i < 3; i++)\n\t\t\tnode.broadcast_grid[i] = get_constant_metadata(llvm::cast<llvm::MDNode>(*fixed_grid), i);\n\t}\n\n\tnode.thread_group_size_spec_id[0] = NodeSpecIdGroupSizeX;\n\tnode.thread_group_size_spec_id[1] = NodeSpecIdGroupSizeY;\n\tnode.thread_group_size_spec_id[2] = NodeSpecIdGroupSizeZ;\n\n\tauto *name_node = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeID);\n\n\tif (name_node)\n\t{\n\t\tauto *name_id = llvm::cast<llvm::MDNode>(*name_node);\n\t\tnode.node_id = get_string_metadata(name_id, 0);\n\t\tnode.node_array_index = get_constant_metadata(name_id, 1);\n\t}\n\n\tauto *inputs_node = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeInputs);\n\n\tllvm::MDNode *input = nullptr;\n\tif (inputs_node)\n\t{\n\t\tauto *inputs = llvm::cast<llvm::MDNode>(*inputs_node);\n\t\t// Current spec only allows one input node.\n\t\tif (inputs->getNumOperands() != 1)\n\t\t\treturn {};\n\t\tinput = llvm::cast<llvm::MDNode>(inputs->getOperand(0));\n\t}\n\n\tif (input)\n\t{\n\t\tuint32_t num_ops = input->getNumOperands();\n\n\t\tnode.grid_buffer = node_parse_dispatch_grid(input);\n\t\tnode.payload_stride = node_parse_payload_stride(input, node.node_track_rw_input_sharing);\n\n\t\tfor (uint32_t i = 0; i < num_ops; i += 2)\n\t\t{\n\t\t\tauto tag = DXIL::NodeMetadataTag(get_constant_metadata(input, i));\n\t\t\tif (tag == DXIL::NodeMetadataTag::NodeMaxRecords)\n\t\t\t\tnode.coalesce_factor = get_constant_metadata(input, i + 1);\n\t\t}\n\n        // We seem to need a sensible default.\n        if (node.coalesce_factor == 0 && node.launch_type == DXIL::NodeLaunchType::Coalescing)\n            node.coalesce_factor = 1;\n\t}\n\n\tauto *share_input_node = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeShareInputOf);\n\tif (share_input_node)\n\t{\n\t\tauto *share_input = llvm::cast<llvm::MDNode>(*share_input_node);\n\t\tnode.node_share_input_id = get_string_metadata(share_input, 0);\n\t\tnode.node_share_input_array_index = get_constant_metadata(share_input, 1);\n\t}\n\n\tauto *local_argument_node = get_shader_property_tag(meta, DXIL::ShaderPropertyTag::NodeLocalRootArgumentsTableIndex);\n\tif (local_argument_node)\n\t{\n\t\tnode.local_root_arguments_table_index =\n\t\t    llvm::cast<llvm::ConstantAsMetadata>(*local_argument_node)->getValue()->getUniqueInteger().getZExtValue();\n\t}\n\telse\n\t\tnode.local_root_arguments_table_index = UINT32_MAX;\n\n\treturn node;\n}\n\nNodeInputData Converter::get_node_input(const LLVMBCParser &parser, const char *entry)\n{\n\tauto *entry_point_meta = get_entry_point_meta(parser.get_module(), entry);\n\tif (!entry_point_meta)\n\t\treturn {};\n\treturn Impl::get_node_input(entry_point_meta);\n}\n\nVector<NodeOutputData> Converter::get_node_outputs(const LLVMBCParser &parser, const char *entry)\n{\n\tVector<NodeOutputData> output_data;\n\tauto *entry_point_meta = get_entry_point_meta(parser.get_module(), entry);\n\tif (!entry_point_meta)\n\t\treturn {};\n\n\tauto *outputs_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::NodeOutputs);\n\tif (outputs_node)\n\t{\n\t\tauto *outputs = llvm::cast<llvm::MDNode>(*outputs_node);\n\t\tfor (unsigned i = 0; i < outputs->getNumOperands(); i++)\n\t\t{\n\t\t\tauto *output = llvm::cast<llvm::MDNode>(outputs->getOperand(i));\n\t\t\toutput_data.push_back(Impl::get_node_output(output));\n\t\t}\n\t}\n\n\t// Spec constant IDs are allowed incrementally.\n\t// Spec constant ID 0 is reserved for workgroup size spec constant.\n\tuint32_t spec_constant_id = NodeSpecIdOutputBase;\n\tfor (auto &output : output_data)\n\t{\n\t\toutput.node_index_spec_constant_id = spec_constant_id;\n\t\tspec_constant_id++;\n\t}\n\n\treturn output_data;\n}\n\nString Converter::get_analysis_warnings() const\n{\n\tString str;\n\n\tif (impl->shader_analysis.needs_auto_group_shared_barriers)\n\t{\n\t\t// This is a case that might just happen to work if the game assumes lock-step execution.\n\t\t// If the group size is larger, it's extremely unlikely the game works by chance on native drivers.\n\t\t// Some shaders seem to use groupshared as a sort of \"scratch space\" per thread, which\n\t\t// is a valid use case and does not require barriers to be correct.\n\t\tstr += \"- Has group shared access, but no group shared barrier anywhere.\\n\";\n\t}\n\n\treturn str;\n}\n\nbool Converter::Impl::emit_execution_modes_node()\n{\n\t// It will be necessary to override all this metadata through some API.\n\t// Not really needed to support this until we've implemented everything.\n\tNodeInputData node = get_node_input(entry_point_meta);\n\tif (node.launch_type == DXIL::NodeLaunchType::Invalid)\n\t\treturn false;\n\n\tnode_input.node_id = node.node_id;\n\tnode_input.node_array_index = node.node_array_index;\n\tnode_input.launch_type = node.launch_type;\n\tnode_input.dispatch_grid = node.grid_buffer;\n\tnode_input.payload_stride = node.payload_stride;\n\tnode_input.coalesce_stride = node.coalesce_factor;\n\n\tif (!emit_execution_modes_node_input())\n\t\treturn false;\n\n\tauto *outputs_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::NodeOutputs);\n\tif (outputs_node)\n\t{\n\t\tauto *outputs = llvm::cast<llvm::MDNode>(*outputs_node);\n\n\t\tfor (unsigned i = 0; i < outputs->getNumOperands(); i++)\n\t\t{\n\t\t\tauto *output = llvm::cast<llvm::MDNode>(outputs->getOperand(i));\n\t\t\tif (!emit_execution_modes_node_output(output))\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\tnode_input.is_indirect_payload_stride_id = builder().makeBoolConstant(false, true);\n\tbuilder().addDecoration(node_input.is_indirect_payload_stride_id, spv::DecorationSpecId,\n\t                        int(node.is_indirect_bda_stride_program_entry_spec_id));\n\tbuilder().addName(node_input.is_indirect_payload_stride_id, \"NodeEntryIndirectPayloadStride\");\n\n\tnode_input.is_entry_point_id = builder().makeBoolConstant(node.is_program_entry, true);\n\tbuilder().addDecoration(node_input.is_entry_point_id, spv::DecorationSpecId,\n\t                        int(node.is_entry_point_spec_id));\n\tbuilder().addName(node_input.is_entry_point_id, \"NodeIsProgramEntry\");\n\n\tif (node_input.launch_type == DXIL::NodeLaunchType::Broadcasting)\n\t{\n\t\tnode_input.broadcast_has_max_grid_id = builder().makeBoolConstant(node.dispatch_grid_is_upper_bound, true);\n\t\tbuilder().addDecoration(node_input.broadcast_has_max_grid_id, spv::DecorationSpecId,\n\t\t                        int(node.dispatch_grid_is_upper_bound_spec_id));\n\t\tbuilder().addName(node_input.broadcast_has_max_grid_id, \"DispatchGridIsUpperBound\");\n\n\t\tnode_input.is_static_broadcast_node_id = builder().makeBoolConstant(false, true);\n\t\tbuilder().addDecoration(node_input.is_static_broadcast_node_id, spv::DecorationSpecId,\n\t\t                        int(node.is_static_broadcast_node_spec_id));\n\t\tbuilder().addName(node_input.is_static_broadcast_node_id, \"DispatchStaticPayload\");\n\n\t\tspv::Id u32_type = builder().makeUintType(32);\n\n\t\tfor (uint32_t i = 0; i < 3; i++)\n\t\t{\n\t\t\tnode_input.max_broadcast_grid_id[i] = builder().makeUintConstant(node.broadcast_grid[i], true);\n\t\t\tbuilder().addDecoration(node_input.max_broadcast_grid_id[i], spv::DecorationSpecId,\n\t\t\t                        int(node.max_broadcast_grid_spec_id[i]));\n\t\t\tstatic const char *names[] = { \"MaxBroadcastGridX\", \"MaxBroadcastGridY\", \"MaxBroadcastGridZ\" };\n\t\t\tbuilder().addName(node_input.max_broadcast_grid_id[i], names[i]);\n\n\t\t\tnode_input.max_broadcast_grid_minus_1_id[i] = builder().createSpecConstantOp(\n\t\t\t    spv::OpISub, u32_type, { node_input.max_broadcast_grid_id[i], builder().makeUintConstant(1) }, {});\n\t\t\tstatic const char *sub_names[] = { \"GridXMinus1\", \"GridYMinus1\", \"GridZMinus1\" };\n\t\t\tbuilder().addName(node_input.max_broadcast_grid_minus_1_id[i], sub_names[i]);\n\t\t}\n\t}\n\n\treturn emit_execution_modes_compute();\n}\n\nbool Converter::Impl::emit_execution_modes_compute()\n{\n\tauto *num_threads_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::NumThreads);\n\tif (num_threads_node)\n\t{\n\t\tauto *num_threads = llvm::cast<llvm::MDNode>(*num_threads_node);\n\t\treturn emit_execution_modes_thread_wave_properties(num_threads);\n\t}\n\telse\n\t\treturn false;\n}\n\nstatic bool entry_point_modifies_sample_mask(const llvm::MDNode *node)\n{\n\tif (!node->getOperand(2))\n\t\treturn false;\n\tauto &signature = node->getOperand(2);\n\tauto *signature_node = llvm::cast<llvm::MDNode>(signature);\n\tauto &outputs = signature_node->getOperand(1);\n\tif (!outputs)\n\t\treturn false;\n\n\tauto *outputs_node = llvm::dyn_cast<llvm::MDNode>(outputs);\n\tfor (unsigned i = 0; i < outputs_node->getNumOperands(); i++)\n\t{\n\t\tauto *output = llvm::cast<llvm::MDNode>(outputs_node->getOperand(i));\n\t\tauto system_value = static_cast<DXIL::Semantic>(get_constant_metadata(output, 3));\n\t\tif (system_value == DXIL::Semantic::Depth ||\n\t\t    system_value == DXIL::Semantic::DepthLessEqual ||\n\t\t    system_value == DXIL::Semantic::DepthGreaterEqual ||\n\t\t    system_value == DXIL::Semantic::StencilRef ||\n\t\t    system_value == DXIL::Semantic::Coverage)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic uint64_t get_shader_flags(const llvm::MDNode *entry_point_meta)\n{\n\tauto *flags_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::ShaderFlags);\n\tif (flags_node)\n\t\treturn llvm::cast<llvm::ConstantAsMetadata>(*flags_node)->getValue()->getUniqueInteger().getZExtValue();\n\telse\n\t\treturn 0;\n}\n\nbool Converter::Impl::emit_execution_modes_pixel_late()\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tif (execution_mode_meta.declares_rov)\n\t{\n\t\tbuilder.addExtension(\"SPV_EXT_fragment_shader_interlock\");\n\t\tif (execution_mode_meta.per_sample_shading)\n\t\t{\n\t\t\tbuilder.addCapability(spv::CapabilityFragmentShaderSampleInterlockEXT);\n\t\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeSampleInterlockOrderedEXT);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbuilder.addCapability(spv::CapabilityFragmentShaderPixelInterlockEXT);\n\t\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModePixelInterlockOrderedEXT);\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_execution_modes_pixel()\n{\n\tauto &builder = spirv_module.get_builder();\n\tauto flags = get_shader_flags(entry_point_meta);\n\tbool early_depth_stencil = (flags & DXIL::ShaderFlagEarlyDepthStencil) != 0;\n\n\tif (options.descriptor_qa_enabled || options.instruction_instrumentation.enabled)\n\t{\n\t\t// If we have descriptor QA enabled, we will have side effects when running fragment shaders.\n\t\t// This forces late-Z which can trigger some horrible performance issues.\n\t\t// Make sure to enable early depth-stencil if nothing in the shader is early/late sensitive.\n\t\tif (!entry_point_modifies_sample_mask(entry_point_meta) &&\n\t\t    !shader_analysis.has_side_effects && !shader_analysis.discards)\n\t\t{\n\t\t\tearly_depth_stencil = true;\n\t\t}\n\t}\n\n\tif (early_depth_stencil)\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeEarlyFragmentTests);\n\n\t// Avoid masking helper lanes when strict_helper_lane_waveops is used.\n\t// Execution modes to enable correct Vulkan behaviour are set up later.\n\tauto *func = get_entry_point_function(entry_point_meta);\n\texecution_mode_meta.waveops_include_helper_lanes =\n\t    func->hasFnAttribute(\"waveops-include-helper-lanes\");\n\n\t// If helper lanes don't exist, don't bother trying to mask them out,\n\t// it will just confuse the compiler.\n\tspirv_module.set_helper_lanes_participate_in_wave_ops(\n\t\t!options.strict_helper_lane_waveops ||\n\t    execution_model != spv::ExecutionModelFragment ||\n\t\texecution_mode_meta.waveops_include_helper_lanes);\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_execution_modes_domain()\n{\n\tauto &builder = spirv_module.get_builder();\n\tbuilder.addCapability(spv::CapabilityTessellation);\n\n\tauto *ds_state_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::DSState);\n\tif (ds_state_node)\n\t{\n\t\tauto *arguments = llvm::cast<llvm::MDNode>(*ds_state_node);\n\t\tauto domain = static_cast<DXIL::TessellatorDomain>(get_constant_metadata(arguments, 0));\n\t\tauto *func = spirv_module.get_entry_function();\n\n\t\tswitch (domain)\n\t\t{\n\t\tcase DXIL::TessellatorDomain::IsoLine:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeIsolines);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorDomain::Tri:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeTriangles);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorDomain::Quad:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeQuads);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unknown tessellator domain!\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tunsigned input_control_points = get_constant_metadata(arguments, 1);\n\t\texecution_mode_meta.stage_input_num_vertex = input_control_points;\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nbool Converter::Impl::emit_execution_modes_hull()\n{\n\tauto &builder = spirv_module.get_builder();\n\tbuilder.addCapability(spv::CapabilityTessellation);\n\tauto *hs_state_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::HSState);\n\n\tif (hs_state_node)\n\t{\n\t\tauto *arguments = llvm::cast<llvm::MDNode>(*hs_state_node);\n\n\t\tauto *patch_constant = llvm::cast<llvm::ConstantAsMetadata>(arguments->getOperand(0));\n\t\tauto *patch_constant_value = patch_constant->getValue();\n\t\texecution_mode_meta.patch_constant_function = llvm::cast<llvm::Function>(patch_constant_value);\n\n\t\tunsigned input_control_points = get_constant_metadata(arguments, 1);\n\t\tunsigned output_control_points = get_constant_metadata(arguments, 2);\n\t\tauto domain = static_cast<DXIL::TessellatorDomain>(get_constant_metadata(arguments, 3));\n\t\tauto partitioning = static_cast<DXIL::TessellatorPartitioning>(get_constant_metadata(arguments, 4));\n\t\tauto primitive = static_cast<DXIL::TessellatorOutputPrimitive>(get_constant_metadata(arguments, 5));\n\n\t\tauto *func = spirv_module.get_entry_function();\n\n\t\tswitch (domain)\n\t\t{\n\t\tcase DXIL::TessellatorDomain::IsoLine:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeIsolines);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorDomain::Tri:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeTriangles);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorDomain::Quad:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeQuads);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unknown tessellator domain!\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tswitch (partitioning)\n\t\t{\n\t\tcase DXIL::TessellatorPartitioning::Integer:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeSpacingEqual);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorPartitioning::Pow2:\n\t\t\tLOGE(\"Emulating Pow2 spacing as Integer.\\n\");\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeSpacingEqual);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorPartitioning::FractionalEven:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeSpacingFractionalEven);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorPartitioning::FractionalOdd:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeSpacingFractionalOdd);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unknown tessellator partitioning.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tswitch (primitive)\n\t\t{\n\t\tcase DXIL::TessellatorOutputPrimitive::TriangleCCW:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeVertexOrderCcw);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorOutputPrimitive::TriangleCW:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeVertexOrderCw);\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorOutputPrimitive::Point:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModePointMode);\n\t\t\t// TODO: Do we have to specify CCW/CW in point mode?\n\t\t\tbreak;\n\n\t\tcase DXIL::TessellatorOutputPrimitive::Line:\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unknown tessellator primitive.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputVertices, output_control_points);\n\n\t\texecution_mode_meta.stage_input_num_vertex = input_control_points;\n\t\texecution_mode_meta.stage_output_num_vertex = output_control_points;\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nbool Converter::Impl::emit_execution_modes_geometry()\n{\n\tauto &builder = spirv_module.get_builder();\n\tbuilder.addCapability(spv::CapabilityGeometry);\n\tauto *gs_state_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::GSState);\n\n\tif (gs_state_node)\n\t{\n\t\tauto *arguments = llvm::cast<llvm::MDNode>(*gs_state_node);\n\n\t\tauto input_primitive = static_cast<DXIL::InputPrimitive>(get_constant_metadata(arguments, 0));\n\t\tunsigned max_vertex_count = get_constant_metadata(arguments, 1);\n\n\t\tauto *func = spirv_module.get_entry_function();\n\n\t\tauto topology = static_cast<DXIL::PrimitiveTopology>(get_constant_metadata(arguments, 3));\n\t\tunsigned gs_instances = get_constant_metadata(arguments, 4);\n\n\t\texecution_mode_meta.gs_stream_active_mask = get_constant_metadata(arguments, 2);\n\n\t\tbuilder.addExecutionMode(func, spv::ExecutionModeInvocations, gs_instances);\n\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputVertices, max_vertex_count);\n\n\t\tswitch (input_primitive)\n\t\t{\n\t\tcase DXIL::InputPrimitive::Point:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeInputPoints);\n\t\t\texecution_mode_meta.stage_input_num_vertex = 1;\n\t\t\tbreak;\n\n\t\tcase DXIL::InputPrimitive::Line:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeInputLines);\n\t\t\texecution_mode_meta.stage_input_num_vertex = 2;\n\t\t\tbreak;\n\n\t\tcase DXIL::InputPrimitive::LineWithAdjacency:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeInputLinesAdjacency);\n\t\t\texecution_mode_meta.stage_input_num_vertex = 4;\n\t\t\tbreak;\n\n\t\tcase DXIL::InputPrimitive::Triangle:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeTriangles);\n\t\t\texecution_mode_meta.stage_input_num_vertex = 3;\n\t\t\tbreak;\n\n\t\tcase DXIL::InputPrimitive::TriangleWithAdjaceny:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeInputTrianglesAdjacency);\n\t\t\texecution_mode_meta.stage_input_num_vertex = 6;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unexpected input primitive (%u).\\n\", unsigned(input_primitive));\n\t\t\treturn false;\n\t\t}\n\n\t\tswitch (topology)\n\t\t{\n\t\tcase DXIL::PrimitiveTopology::PointList:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputPoints);\n\t\t\tbreak;\n\n\t\tcase DXIL::PrimitiveTopology::LineStrip:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputLineStrip);\n\t\t\tbreak;\n\n\t\tcase DXIL::PrimitiveTopology::TriangleStrip:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputTriangleStrip);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unexpected output primitive topology (%u).\\n\", unsigned(topology));\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nbool Converter::Impl::emit_execution_modes_ray_tracing(spv::ExecutionModel model)\n{\n\tauto &builder = spirv_module.get_builder();\n\tbuilder.addCapability(spv::CapabilityRayTracingKHR);\n\tif (options.ray_tracing_primitive_culling_enabled && shader_analysis.can_require_primitive_culling)\n\t\tbuilder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);\n\tif (options.opacity_micromap_enabled && shader_analysis.can_require_opacity_micromap)\n\t{\n\t\tbuilder.addCapability(spv::CapabilityRayTracingOpacityMicromapEXT);\n\t\tbuilder.addExtension(\"SPV_EXT_opacity_micromap\");\n\t}\n\tbuilder.addExtension(\"SPV_KHR_ray_tracing\");\n\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\n\t// For DXR, we'll need full bindless.\n\tbuilder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);\n\n\tbuilder.addCapability(spv::CapabilitySampledImageArrayDynamicIndexing);\n\tbuilder.addCapability(spv::CapabilitySampledImageArrayNonUniformIndexing);\n\tbuilder.addCapability(spv::CapabilityStorageImageArrayDynamicIndexing);\n\tbuilder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexing);\n\tbuilder.addCapability(spv::CapabilityStorageBufferArrayDynamicIndexing);\n\tbuilder.addCapability(spv::CapabilityStorageBufferArrayNonUniformIndexing);\n\tbuilder.addCapability(spv::CapabilityUniformBufferArrayDynamicIndexing);\n\tbuilder.addCapability(spv::CapabilityUniformBufferArrayNonUniformIndexing);\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_execution_modes_thread_wave_properties(const llvm::MDNode *num_threads)\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tif (options.force_wave_size_enable && options.force_subgroup_size)\n\t{\n\t\texecution_mode_meta.wave_size_min = options.force_subgroup_size;\n\t\texecution_mode_meta.wave_size_max = 0;\n\t\texecution_mode_meta.wave_size_preferred = 0;\n\t}\n\telse\n\t{\n\t\tauto *wave_size_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::WaveSize);\n\t\tauto *wave_size_range_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::RangedWaveSize);\n\n\t\tif (wave_size_range_node)\n\t\t{\n\t\t\tauto *wave_size = llvm::cast<llvm::MDNode>(*wave_size_range_node);\n\t\t\texecution_mode_meta.wave_size_min = get_constant_metadata(wave_size, 0);\n\t\t\texecution_mode_meta.wave_size_max = get_constant_metadata(wave_size, 1);\n\t\t\texecution_mode_meta.wave_size_preferred = get_constant_metadata(wave_size, 2);\n\t\t}\n\t\telse if (wave_size_node)\n\t\t{\n\t\t\tauto *wave_size = llvm::cast<llvm::MDNode>(*wave_size_node);\n\t\t\texecution_mode_meta.wave_size_min = get_constant_metadata(wave_size, 0);\n\t\t\texecution_mode_meta.wave_size_max = 0;\n\t\t\texecution_mode_meta.wave_size_preferred = 0;\n\t\t}\n\t}\n\n\tunsigned threads[3];\n\tfor (unsigned dim = 0; dim < 3; dim++)\n\t\tthreads[dim] = get_constant_metadata(num_threads, dim);\n\tunsigned total_workgroup_threads = threads[0] * threads[1] * threads[2];\n\n\tif (execution_model == spv::ExecutionModelGLCompute)\n\t{\n\t\tif ((total_workgroup_threads <= 32 && shader_analysis.require_subgroups) ||\n\t\t    (shader_analysis.subgroup_ballot_reads_first && !shader_analysis.subgroup_ballot_reads_upper))\n\t\t{\n\t\t\t// Common game bug. Only reading the first scalar of a ballot probably means\n\t\t\t// the shader relies on WaveSize <= 32.\n\t\t\tsuggest_maximum_wave_size(32);\n\t\t}\n\t}\n\n\tif (shader_analysis.require_compute_shader_derivatives)\n\t{\n\t\tif (execution_model != spv::ExecutionModelGLCompute &&\n\t\t    execution_model != spv::ExecutionModelTaskEXT &&\n\t\t    execution_model != spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\tLOGE(\"Derivatives only supported in compute, task and mesh shaders.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// For sanity, verify that dimensions align sufficiently.\n\t\t// Spec says that product of workgroup size must align with 4.\n\t\tif (total_workgroup_threads % 4 == 0)\n\t\t{\n\t\t\tbool derivatives_2d = (threads[0] % 2 == 0) && (threads[1] % 2 == 0);\n\t\t\tif (options.compute_shader_derivatives)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(options.compute_shader_derivatives_khr\n\t\t\t\t\t? \"SPV_KHR_compute_shader_derivatives\" : \"SPV_NV_compute_shader_derivatives\");\n\n\t\t\t\tif (derivatives_2d && options.compute_shader_derivatives_quad)\n\t\t\t\t{\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsKHR);\n\n\t\t\t\t\t// It is technically not in spec to just assume this since subgroup lane mapping to local invocation index\n\t\t\t\t\t// is not defined without this. In practice on NV, this holds based on our testing.\n\t\t\t\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDerivativeGroupQuadsKHR);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityComputeDerivativeGroupLinearKHR);\n\n\t\t\t\t\t// It is technically not in spec to just assume this since subgroup lane mapping to local invocation index\n\t\t\t\t\t// is not defined without this. In practice on NV, this holds based on our testing.\n\t\t\t\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDerivativeGroupLinearKHR);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the X and Y dimensions align with 2,\n\t\t\t// we need to assume that any quad op works on a 2D dispatch.\n\t\t\texecution_mode_meta.synthesize_2d_quad_dispatch = !options.compute_shader_derivatives_quad && derivatives_2d;\n\t\t\tif (execution_mode_meta.synthesize_2d_quad_dispatch)\n\t\t\t{\n\t\t\t\tthreads[0] *= 2;\n\t\t\t\tthreads[1] /= 2;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// DXC is robust against this case.\n\t\t\t// Derivatives become meaningless now, so we have to fake the results.\n\t\t\texecution_mode_meta.synthesize_dummy_derivatives = true;\n\t\t\tLOGW(\"Invalid use of compute shader derivatives detected. Falling back to robust results.\\n\");\n\t\t}\n\t}\n\n\tfor (unsigned dim = 0; dim < 3; dim++)\n\t\texecution_mode_meta.workgroup_threads[dim] = threads[dim];\n\n\tif (execution_model_lib_target)\n\t{\n\t\tthreads[0] = builder.makeUintConstant(threads[0], true);\n\t\tthreads[1] = builder.makeUintConstant(threads[1], true);\n\t\tthreads[2] = builder.makeUintConstant(threads[2], true);\n\t\tbuilder.addDecoration(threads[0], spv::DecorationSpecId, NodeSpecIdGroupSizeX);\n\t\tbuilder.addDecoration(threads[1], spv::DecorationSpecId, NodeSpecIdGroupSizeY);\n\t\tbuilder.addDecoration(threads[2], spv::DecorationSpecId, NodeSpecIdGroupSizeZ);\n\t\tbuilder.addExecutionModeId(spirv_module.get_entry_function(),\n\t\t                           spv::ExecutionModeLocalSizeId,\n\t\t                           threads[0], threads[1], threads[2]);\n\n\t\tnode_input.thread_group_size_id =\n\t\t\tbuilder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3),\n\t\t\t                              { threads[0], threads[1], threads[2] }, true);\n\t\tbuilder.addName(node_input.thread_group_size_id, \"ThreadGroupSize\");\n\t}\n\telse\n\t{\n\t\tbuilder.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeLocalSize,\n\t\t                         threads[0], threads[1], threads[2]);\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_execution_modes_amplification()\n{\n\tauto &builder = spirv_module.get_builder();\n\n\tbuilder.addExtension(\"SPV_EXT_mesh_shader\");\n\tbuilder.addCapability(spv::CapabilityMeshShadingEXT);\n\n\tauto *as_state_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::ASState);\n\n\tif (as_state_node)\n\t{\n\t\tauto *arguments = llvm::cast<llvm::MDNode>(*as_state_node);\n\t\tauto *num_threads = llvm::cast<llvm::MDNode>(arguments->getOperand(0));\n\t\treturn emit_execution_modes_thread_wave_properties(num_threads);\n\t}\n\telse\n\t\treturn false;\n}\n\nbool Converter::Impl::emit_execution_modes_mesh()\n{\n\tauto &builder = spirv_module.get_builder();\n\tauto *func = spirv_module.get_entry_function();\n\n\tbuilder.addExtension(\"SPV_EXT_mesh_shader\");\n\tbuilder.addCapability(spv::CapabilityMeshShadingEXT);\n\n\tauto *ms_state_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::MSState);\n\n\tif (ms_state_node)\n\t{\n\t\tauto *arguments = llvm::cast<llvm::MDNode>(*ms_state_node);\n\t\tunsigned max_vertex_count = get_constant_metadata(arguments, 1);\n\t\tunsigned max_primitive_count = get_constant_metadata(arguments, 2);\n\t\tauto topology = static_cast<DXIL::MeshOutputTopology>(get_constant_metadata(arguments, 3));\n\t\tunsigned index_count;\n\n\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputVertices, std::max<int>(1, max_vertex_count));\n\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputPrimitivesEXT, std::max<int>(1, max_primitive_count));\n\n\t\tswitch (topology)\n\t\t{\n\t\tcase DXIL::MeshOutputTopology::Undefined:\n\t\t\tindex_count = 0;\n\t\t\tbreak;\n\n\t\tcase DXIL::MeshOutputTopology::Line:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputLinesEXT);\n\t\t\tindex_count = 2;\n\t\t\tbreak;\n\n\t\tcase DXIL::MeshOutputTopology::Triangle:\n\t\t\tbuilder.addExecutionMode(func, spv::ExecutionModeOutputTrianglesEXT);\n\t\t\tindex_count = 3;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOGE(\"Unexpected mesh output topology (%u).\\n\", unsigned(topology));\n\t\t\treturn false;\n\t\t}\n\n\t\texecution_mode_meta.stage_output_num_vertex = max_vertex_count;\n\t\texecution_mode_meta.stage_output_num_primitive = max_primitive_count;\n\t\texecution_mode_meta.primitive_index_dimension = index_count;\n\n\t\tauto *num_threads = llvm::cast<llvm::MDNode>(arguments->getOperand(0));\n\t\treturn emit_execution_modes_thread_wave_properties(num_threads);\n\t}\n\telse\n\t\treturn false;\n}\n\nbool Converter::Impl::emit_execution_modes_fp_denorm_rounding()\n{\n\t// Check for SM 6.2 denorm handling. Only applies to FP32.\n\tauto *func = get_entry_point_function(entry_point_meta);\n\tif (!func)\n\t\treturn true;\n\n\t// NVIDIA hack. The way the driver exposes float controls is very unfortunate.\n\t// If only partial denorm support is enabled, assume we cannot freely control FP32 behavior either.\n\t// However, for SM 6.2+, we have to force it on NVIDIA, even if driver doesn't actually expose it.\n\tbool supports_full_denorm_control_fp32 =\n\t\toptions.supports_float16_denorm_preserve &&\n\t\toptions.supports_float64_denorm_preserve;\n\n\t// Plain DXIL only supports fp32-denorm-mode, the rest are internal extensions.\n\tconst struct\n\t{\n\t\tconst char *tag;\n\t\tint bits;\n\t\tbool supported;\n\t} denorms[] = {\n\t\t{ \"dxbc-fp16-denorm-mode\", 16, options.supports_float16_denorm_preserve },\n\t\t{ \"dxbc-fp32-denorm-mode\", 32, supports_full_denorm_control_fp32 },\n\t\t{ \"dxbc-fp64-denorm-mode\", 64, options.supports_float64_denorm_preserve },\n\t\t{ \"fp32-denorm-mode\", 32, true },\n\t};\n\n\t// For whatever reason, NVIDIA loses a tremendous amount of performance from setting rounding modes.\n\t// Just ignore it since it's always RTE in practice anyway.\n#if 0\n\tstatic const struct\n\t{\n\t\tconst char *tag;\n\t\tint bits;\n\t} rounding[] = {\n\t\t{ \"dxbc-fp16-round-mode\", 16 },\n\t\t{ \"dxbc-fp32-round-mode\", 32 },\n\t\t{ \"dxbc-fp64-round-mode\", 64 },\n\t};\n#endif\n\n\tfor (auto &d : denorms)\n\t{\n\t\tif (!d.supported)\n\t\t\tcontinue;\n\n\t\tauto attr = func->getFnAttribute(d.tag);\n\t\tauto str = attr.getValueAsString();\n\t\tif (str == \"ftz\")\n\t\t{\n\t\t\tbuilder().addExtension(\"SPV_KHR_float_controls\");\n\t\t\tbuilder().addCapability(spv::CapabilityDenormFlushToZero);\n\t\t\tbuilder().addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDenormFlushToZero, d.bits);\n\t\t}\n\t\telse if (str == \"preserve\")\n\t\t{\n\t\t\tbuilder().addExtension(\"SPV_KHR_float_controls\");\n\t\t\tbuilder().addCapability(spv::CapabilityDenormPreserve);\n\t\t\tbuilder().addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDenormPreserve, d.bits);\n\t\t}\n\t}\n\n#if 0\n\tfor (auto &r : rounding)\n\t{\n\t\tauto attr = func->getFnAttribute(r.tag);\n\t\tauto str = attr.getValueAsString();\n\t\tif (str == \"rtz\")\n\t\t{\n\t\t\tbuilder().addExtension(\"SPV_KHR_float_controls\");\n\t\t\tbuilder().addCapability(spv::CapabilityRoundingModeRTZ);\n\t\t\tbuilder().addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeRoundingModeRTZ, r.bits);\n\t\t}\n\t\telse if (str == \"rte\")\n\t\t{\n\t\t\tbuilder().addExtension(\"SPV_KHR_float_controls\");\n\t\t\tbuilder().addCapability(spv::CapabilityRoundingModeRTE);\n\t\t\tbuilder().addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeRoundingModeRTE, r.bits);\n\t\t}\n\t}\n#endif\n\n\tif (shader_analysis.require_wmma && GlobalConfiguration::get().wmma_rdna3_workaround)\n\t{\n\t\t// FP16 RTZ allows faster conversions on AMD.\n\t\t// This hack only makes sense on RDNA3.\n\t\tbuilder().addExtension(\"SPV_KHR_float_controls\");\n\t\tbuilder().addCapability(spv::CapabilityRoundingModeRTZ);\n\t\tbuilder().addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeRoundingModeRTZ, 16);\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::analyze_execution_modes_meta()\n{\n\tauto *meta = entry_point_meta;\n\n\tif (execution_model_lib_target)\n\t\tif (auto *null_meta = get_null_entry_point_meta(bitcode_parser.get_module()))\n\t\t\tmeta = null_meta;\n\n\tauto flags = get_shader_flags(meta);\n\texecution_mode_meta.native_16bit_operations = (flags & DXIL::ShaderFlagNativeLowPrecision) != 0;\n\treturn true;\n}\n\nvoid Converter::Impl::emit_execution_modes_post_code_generation()\n{\n\tauto &b = builder();\n\n\tif (module_is_dxilconv(bitcode_parser.get_module()))\n\t{\n\t\t// We should use these globally, but don't want to invalidate all Fossilize archives just yet.\n\t\t// Shader instrumentation may declare its own preservation modes, so only declare execution modes\n\t\t// if we haven't done anything.\n\t\tif (!builder().hasCapability(spv::CapabilitySignedZeroInfNanPreserve))\n\t\t{\n\t\t\tb.addExtension(\"SPV_KHR_float_controls\");\n\t\t\tb.addCapability(spv::CapabilitySignedZeroInfNanPreserve);\n\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeSignedZeroInfNanPreserve, 32);\n\t\t\tif (b.hasCapability(spv::CapabilityFloat64))\n\t\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeSignedZeroInfNanPreserve, 64);\n\t\t}\n\n\t\t// DXBC assumes flush-to-zero, but dxilconv doesn't explicitly emit that, since it's not in SM 6.0.\n\t\tif (!b.hasCapability(spv::CapabilityDenormFlushToZero) && !b.hasCapability(spv::CapabilityDenormPreserve))\n\t\t{\n\t\t\tb.addExtension(\"SPV_KHR_float_controls\");\n\t\t\tb.addCapability(spv::CapabilityDenormFlushToZero);\n\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDenormFlushToZero, 32);\n\t\t}\n\t}\n\n\t// Custom IR is expected to set this with extended attributes.\n\tif (!module_is_dxbc_spirv(bitcode_parser.get_module()))\n\t{\n\t\t// Float16 and Float64 require denorms to be preserved in D3D12.\n\t\tif (b.hasCapability(spv::CapabilityFloat16) && options.supports_float16_denorm_preserve)\n\t\t{\n\t\t\tb.addExtension(\"SPV_KHR_float_controls\");\n\t\t\tb.addCapability(spv::CapabilityDenormPreserve);\n\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDenormPreserve, 16);\n\t\t}\n\n\t\tif (b.hasCapability(spv::CapabilityFloat64) && options.supports_float64_denorm_preserve)\n\t\t{\n\t\t\tb.addExtension(\"SPV_KHR_float_controls\");\n\t\t\tb.addCapability(spv::CapabilityDenormPreserve);\n\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeDenormPreserve, 64);\n\t\t}\n\t}\n\telse\n\t{\n\t\t// If instrumentation didn't add these already.\n\t\tif (!builder().hasCapability(spv::CapabilitySignedZeroInfNanPreserve))\n\t\t{\n\t\t\t// Set SignedZeroInfNanPreserve by default for new IR.\n\t\t\t// We should use these globally, but don't want to invalidate all Fossilize archives just yet.\n\t\t\tb.addExtension(\"SPV_KHR_float_controls\");\n\t\t\tb.addCapability(spv::CapabilitySignedZeroInfNanPreserve);\n\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeSignedZeroInfNanPreserve, 32);\n\t\t\tif (b.hasCapability(spv::CapabilityFloat16))\n\t\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeSignedZeroInfNanPreserve, 16);\n\t\t\tif (b.hasCapability(spv::CapabilityFloat64))\n\t\t\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeSignedZeroInfNanPreserve, 64);\n\t\t}\n\t}\n\n\t// Opt into quad derivatives and maximal reconvergence for fragment shaders using\n\t// QuadAll/QuadAny intrinsics to get meaningful behaviour for quad-uniform control\n\t// flow, other quad ops are ignored for now.\n\tif (options.supports_quad_control && execution_model == spv::ExecutionModelFragment &&\n\t    execution_mode_meta.needs_quad_derivatives)\n\t{\n\t\tb.addExtension(\"SPV_KHR_quad_control\");\n\t\tb.addCapability(spv::CapabilityQuadControlKHR);\n\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeRequireFullQuadsKHR);\n\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeQuadDerivativesKHR);\n\t}\n\n\tif (options.supports_maximal_reconvergence &&\n\t    (options.force_maximal_reconvergence ||\n\t     execution_mode_meta.waveops_include_helper_lanes ||\n\t     execution_mode_meta.needs_quad_derivatives ||\n\t     shader_analysis.need_maximal_reconvergence_helper_call))\n\t{\n\t\tb.addExtension(\"SPV_KHR_maximal_reconvergence\");\n\t\tb.addExecutionMode(spirv_module.get_entry_function(), spv::ExecutionModeMaximallyReconvergesKHR);\n\t}\n}\n\nbool Converter::Impl::emit_execution_modes_late()\n{\n\tswitch (execution_model)\n\t{\n\tcase spv::ExecutionModelFragment:\n\t\tif (!emit_execution_modes_pixel_late())\n\t\t\treturn false;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn true;\n}\n\nbool Converter::Impl::emit_execution_modes()\n{\n\tswitch (execution_model)\n\t{\n\tcase spv::ExecutionModelGLCompute:\n\t\tif (execution_model_lib_target)\n\t\t{\n\t\t\tif (!emit_execution_modes_node())\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!emit_execution_modes_compute())\n\t\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\n\tcase spv::ExecutionModelGeometry:\n\t\tif (!emit_execution_modes_geometry())\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase spv::ExecutionModelTessellationControl:\n\t\tif (!emit_execution_modes_hull())\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase spv::ExecutionModelTessellationEvaluation:\n\t\tif (!emit_execution_modes_domain())\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase spv::ExecutionModelFragment:\n\t\tif (!emit_execution_modes_pixel())\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase spv::ExecutionModelRayGenerationKHR:\n\tcase spv::ExecutionModelMissKHR:\n\tcase spv::ExecutionModelIntersectionKHR:\n\tcase spv::ExecutionModelAnyHitKHR:\n\tcase spv::ExecutionModelCallableKHR:\n\tcase spv::ExecutionModelClosestHitKHR:\n\t\tif (!emit_execution_modes_ray_tracing(execution_model))\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase spv::ExecutionModelTaskEXT:\n\t\tif (!emit_execution_modes_amplification())\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase spv::ExecutionModelMeshEXT:\n\t\tif (!emit_execution_modes_mesh())\n\t\t\treturn false;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (!emit_execution_modes_fp_denorm_rounding())\n\t\treturn false;\n\n\treturn true;\n}\n\nConvertedFunction::Function\nConverter::Impl::build_rov_main(const Vector<llvm::BasicBlock *> &visit_order,\n                                CFGNodePool &pool,\n                                Vector<ConvertedFunction::Function> &leaves)\n{\n\tauto *code_main = convert_function(visit_order, true);\n\n\t// Need to figure out if our ROV use is trivial. If not, we will wrap the entire function in ROV pairs.\n\tCFGStructurizer cfg{code_main, pool, spirv_module};\n\tbool trivial_rewrite = cfg.rewrite_rov_lock_region();\n\n\tif (trivial_rewrite)\n\t\treturn { code_main, spirv_module.get_entry_function() };\n\n\t// If we need to fallback we need a wrapper function. Replace the entry point.\n\n\tspv::Block *code_entry;\n\tauto *code_func =\n\t    builder().makeFunctionEntry(spv::NoPrecision, builder().makeVoidType(), \"code_main\", {}, {}, &code_entry);\n\n\tcode_func->moveLocalDeclarationsFrom(spirv_module.get_entry_function());\n\n\tauto *entry = pool.create_node();\n\tentry->ir.operations.push_back(allocate(spv::OpBeginInvocationInterlockEXT));\n\tauto *call_op = allocate(spv::OpFunctionCall, builder().makeVoidType());\n\tcall_op->add_id(code_func->getId());\n\tentry->ir.operations.push_back(call_op);\n\tentry->ir.operations.push_back(allocate(spv::OpEndInvocationInterlockEXT));\n\tentry->ir.terminator.type = Terminator::Type::Return;\n\tleaves.push_back({ code_main, code_func });\n\treturn { entry, spirv_module.get_entry_function() };\n}\n\n\nConvertedFunction::Function\nConverter::Impl::build_node_main(const Vector<llvm::BasicBlock *> &visit_order,\n                                 CFGNodePool &pool,\n                                 Vector<ConvertedFunction::Function> &leaves)\n{\n\tspv::Block *node_entry;\n\tauto *node_func =\n\t\tbuilder().makeFunctionEntry(spv::NoPrecision, builder().makeVoidType(),\n\t\t                            \"node_main\", {}, {}, &node_entry);\n\n\t// Set build point so alloca() functions can create variables correctly.\n\tbuilder().setBuildPoint(node_entry);\n\tauto *node_main = convert_function(visit_order, true);\n\tleaves.push_back({ node_main, node_func });\n\n\tauto *entry = pool.create_node();\n\tcurrent_block = &entry->ir.operations;\n\tentry->ir.terminator.type = Terminator::Type::Return;\n\n\tif (!emit_workgraph_dispatcher(*this, pool, entry, node_func->getId()))\n\t\treturn {};\n\n\treturn { entry, spirv_module.get_entry_function() };\n}\n\nvoid Converter::Impl::emit_patch_output_lowering(CFGNode *bb)\n{\n\tauto *node = entry_point_meta;\n\tcurrent_block = &bb->ir.operations;\n\tassert(node->getOperand(2));\n\n\tauto &signature = node->getOperand(2);\n\tauto *signature_node = llvm::cast<llvm::MDNode>(signature);\n\tauto &patch_variables = signature_node->getOperand(2);\n\tif (!patch_variables)\n\t\treturn;\n\n\tauto *patch_node = llvm::dyn_cast<llvm::MDNode>(patch_variables);\n\n\tspv::Id u32_type = builder().makeUintType(32);\n\tspv::Id uvec4_type = builder().makeVectorType(u32_type, 4);\n\n\tfor (unsigned i = 0; i < patch_node->getNumOperands(); i++)\n\t{\n\t\tauto *patch = llvm::cast<llvm::MDNode>(patch_node->getOperand(i));\n\t\tauto element_id = get_constant_metadata(patch, 0);\n\t\tauto actual_element_type = normalize_component_type(static_cast<DXIL::ComponentType>(get_constant_metadata(patch, 2)));\n\t\tauto system_value = static_cast<DXIL::Semantic>(get_constant_metadata(patch, 3));\n\n\t\tif (system_value != DXIL::Semantic::User)\n\t\t\tcontinue;\n\n\t\tauto rows = get_constant_metadata(patch, 6);\n\t\tauto cols = get_constant_metadata(patch, 7);\n\t\tauto start_row = get_constant_metadata(patch, 8);\n\t\tauto start_col = get_constant_metadata(patch, 9);\n\n\t\tauto &meta = patch_elements_meta[element_id];\n\t\tassert(meta.id);\n\n\t\tfor (unsigned row = 0; row < rows; row++)\n\t\t{\n\t\t\tauto *chain = allocate(spv::OpAccessChain, builder().makePointer(spv::StorageClassPrivate, uvec4_type));\n\t\t\tchain->add_id(execution_mode_meta.patch_lowering_array_var_id);\n\t\t\tchain->add_id(builder().makeUintConstant(row + start_row));\n\t\t\tadd(chain);\n\n\t\t\tauto *load_op = allocate(spv::OpLoad, uvec4_type);\n\t\t\tload_op->add_id(chain->id);\n\t\t\tadd(load_op);\n\n\t\t\tspv::Id store_id;\n\n\t\t\tif (cols == 4)\n\t\t\t{\n\t\t\t\tstore_id = load_op->id;\n\t\t\t}\n\t\t\telse if (cols > 1)\n\t\t\t{\n\t\t\t\tauto *shuffle_op = allocate(spv::OpVectorShuffle, get_type_id(DXIL::ComponentType::U32, 1, cols));\n\t\t\t\tshuffle_op->add_id(load_op->id);\n\t\t\t\tshuffle_op->add_id(load_op->id);\n\t\t\t\tfor (unsigned c = 0; c < cols; c++)\n\t\t\t\t\tshuffle_op->add_literal(c + start_col);\n\t\t\t\tadd(shuffle_op);\n\t\t\t\tstore_id = shuffle_op->id;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto *extract_op = allocate(spv::OpCompositeExtract, u32_type);\n\t\t\t\textract_op->add_id(load_op->id);\n\t\t\t\textract_op->add_literal(start_col);\n\t\t\t\tadd(extract_op);\n\t\t\t\tstore_id = extract_op->id;\n\t\t\t}\n\n\t\t\tif (actual_element_type != DXIL::ComponentType::U32)\n\t\t\t{\n\t\t\t\tauto *cast = allocate(spv::OpBitcast, get_type_id(actual_element_type, 1, cols));\n\t\t\t\tcast->add_id(store_id);\n\t\t\t\tadd(cast);\n\t\t\t\tstore_id = cast->id;\n\t\t\t}\n\n\t\t\tauto *store_op = allocate(spv::OpStore);\n\n\t\t\tif (rows > 1)\n\t\t\t{\n\t\t\t\tauto *store_chain = allocate(\n\t\t\t\t\tspv::OpAccessChain,\n\t\t\t\t\tbuilder().makePointer(spv::StorageClassOutput,\n\t\t\t\t\t                      get_type_id(actual_element_type, 1, cols)));\n\n\t\t\t\tstore_chain->add_id(meta.id);\n\t\t\t\tstore_chain->add_id(builder().makeUintConstant(row));\n\t\t\t\tadd(store_chain);\n\n\t\t\t\tstore_op->add_id(store_chain->id);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstore_op->add_id(meta.id);\n\t\t\t}\n\n\t\t\tstore_op->add_id(store_id);\n\t\t\tadd(store_op);\n\t\t}\n\t}\n}\n\nCFGNode *Converter::Impl::build_hull_passthrough_function(CFGNodePool &pool)\n{\n\t// Hull shader may have a null main entry, which indicates a default passthrough function should be invoked to copy\n\t// all inputs to corresponding outputs\n\tauto *entry = pool.create_node();\n\n\tauto &signature = entry_point_meta->getOperand(2);\n\tif (!signature)\n\t\treturn {};\n\tauto *signature_node = llvm::cast<llvm::MDNode>(signature);\n\n\tauto &inputs = signature_node->getOperand(0);\n\tif (!inputs)\n\t\treturn {};\n\tauto *inputs_node = llvm::dyn_cast<llvm::MDNode>(inputs);\n\n\tauto &outputs = signature_node->getOperand(1);\n\tif (!outputs)\n\t\treturn {};\n\tauto *outputs_node = llvm::dyn_cast<llvm::MDNode>(outputs);\n\n\tif (!inputs_node || !outputs_node)\n\t\treturn {};\n\n\tauto &builder = spirv_module.get_builder();\n\n\t// InvocationId is the control point ID used to index into the input arrays.\n\tauto *load_cipd_op = allocate(spv::OpLoad, builder.makeUintType(32));\n\tload_cipd_op->add_id(spirv_module.get_builtin_shader_input(spv::BuiltInInvocationId));\n\tentry->ir.operations.push_back(load_cipd_op);\n\n\tunsigned num_entries = std::min<uint32_t>(inputs_node->getNumOperands(), outputs_node->getNumOperands());\n\n\t// It's a little unclear if match by meta entry order, or by row/col.\n\t// Without any test to prove otherwise, keep it simple.\n\tfor (unsigned i = 0; i < num_entries; i++)\n\t{\n\t\tauto *input = llvm::cast<llvm::MDNode>(inputs_node->getOperand(i));\n\t\tauto element_id = get_constant_metadata(input, 0);\n\t\tauto actual_element_type = normalize_component_type(static_cast<DXIL::ComponentType>(get_constant_metadata(input, 2)));\n\t\tauto effective_element_type = get_effective_input_output_type(actual_element_type);\n\n\t\tauto rows = get_constant_metadata(input, 6);\n\t\tauto cols = get_constant_metadata(input, 7);\n\n\t\tauto type_id = get_type_id(effective_element_type, rows, cols);\n\n\t\tauto *input_chain = allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassInput, type_id));\n\t\tinput_chain->add_id(input_elements_meta[element_id].id);\n\t\tinput_chain->add_id(load_cipd_op->id);\n\t\tentry->ir.operations.push_back(input_chain);\n\n\t\tauto *load_op = allocate(spv::OpLoad, type_id);\n\t\tload_op->add_id(input_chain->id);\n\t\tentry->ir.operations.push_back(load_op);\n\n\t\tauto *output = llvm::cast<llvm::MDNode>(outputs_node->getOperand(i));\n\t\telement_id = get_constant_metadata(output, 0);\n\n\t\tauto *output_chain = allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassOutput, type_id));\n\t\toutput_chain->add_id(output_elements_meta[element_id].id);\n\t\toutput_chain->add_id(load_cipd_op->id);\n\t\tentry->ir.operations.push_back(output_chain);\n\n\t\tauto *store_op = allocate(spv::OpStore);\n\t\tstore_op->add_id(output_chain->id);\n\t\tstore_op->add_id(load_op->id);\n\t\tentry->ir.operations.push_back(store_op);\n\t}\n\n\tentry->ir.terminator.type = Terminator::Type::Return;\n\n\treturn entry;\n}\n\nConvertedFunction::Function\nConverter::Impl::build_hull_main(const Vector<llvm::BasicBlock *> &visit_order,\n                                 const Vector<llvm::BasicBlock *> &patch_visit_order,\n                                 CFGNodePool &pool,\n                                 Vector<ConvertedFunction::Function> &leaves)\n{\n\t// Just make sure there is an entry block already created.\n\tspv::Block *hull_entry = nullptr, *patch_entry = nullptr;\n\tauto *hull_func =\n\t\tbuilder().makeFunctionEntry(spv::NoPrecision, builder().makeVoidType(), \"hull_main\", {}, {}, &hull_entry);\n\n\tauto *patch_func =\n\t    builder().makeFunctionEntry(spv::NoPrecision, builder().makeVoidType(), \"patch_main\", {}, {}, &patch_entry);\n\n\t// Set build point so alloca() functions can create variables correctly.\n\tif (hull_entry)\n\t\tbuilder().setBuildPoint(hull_entry);\n\tCFGNode *hull_main = nullptr;\n\tif (!visit_order.empty())\n\t\thull_main = convert_function(visit_order, true);\n\telse\n\t\thull_main = build_hull_passthrough_function(pool);\n\n\tbuilder().setBuildPoint(patch_entry);\n\tauto *patch_main = convert_function(patch_visit_order, false);\n\tbuilder().setBuildPoint(spirv_module.get_entry_function()->getEntryBlock());\n\n\tif (hull_main)\n\t\tleaves.push_back({ hull_main, hull_func });\n\tleaves.push_back({ patch_main, patch_func });\n\n\tauto *entry = pool.create_node();\n\n\tOperation *call_op;\n\tif (hull_func)\n\t{\n\t\tcall_op = allocate(spv::OpFunctionCall, builder().makeVoidType());\n\t\tcall_op->add_id(hull_func->getId());\n\t\tentry->ir.operations.push_back(call_op);\n\t}\n\n\tif (execution_mode_meta.stage_output_num_vertex > 1)\n\t{\n\t\tauto *load_op = allocate(spv::OpLoad, builder().makeUintType(32));\n\t\tload_op->add_id(spirv_module.get_builtin_shader_input(spv::BuiltInInvocationId));\n\t\tentry->ir.operations.push_back(load_op);\n\n\t\tauto *cmp_op = allocate(spv::OpIEqual, builder().makeBoolType());\n\t\tcmp_op->add_ids({ load_op->id, builder().makeUintConstant(0) });\n\t\tentry->ir.operations.push_back(cmp_op);\n\n\t\tif (hull_main)\n\t\t{\n\t\t\tauto *barrier_op = allocate(spv::OpControlBarrier);\n\t\t\t// Not 100% sure what to emit here. Just do what glslang does.\n\t\t\tbarrier_op->add_id(builder().makeUintConstant(spv::ScopeWorkgroup));\n\n\t\t\tif (execution_mode_meta.memory_model == spv::MemoryModelVulkan)\n\t\t\t{\n\t\t\t\tbarrier_op->add_id(builder().makeUintConstant(spv::ScopeWorkgroup));\n\t\t\t\tbarrier_op->add_id(builder().makeUintConstant(\n\t\t\t\t    spv::MemorySemanticsOutputMemoryMask | spv::MemorySemanticsAcquireReleaseMask));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbarrier_op->add_id(builder().makeUintConstant(spv::ScopeInvocation));\n\t\t\t\tbarrier_op->add_id(builder().makeUintConstant(0));\n\t\t\t}\n\n\t\t\tentry->ir.operations.push_back(barrier_op);\n\t\t}\n\n\t\tauto *patch_block = pool.create_node();\n\t\tauto *merge_block = pool.create_node();\n\n\t\tentry->add_branch(patch_block);\n\t\tentry->add_branch(merge_block);\n\t\tpatch_block->add_branch(merge_block);\n\n\t\tentry->ir.terminator.type = Terminator::Type::Condition;\n\t\tentry->ir.terminator.true_block = patch_block;\n\t\tentry->ir.terminator.false_block = merge_block;\n\t\tentry->ir.terminator.conditional_id = cmp_op->id;\n\n\t\tpatch_block->ir.terminator.type = Terminator::Type::Branch;\n\t\tpatch_block->ir.terminator.direct_block = merge_block;\n\n\t\tcall_op = allocate(spv::OpFunctionCall, builder().makeVoidType());\n\t\tcall_op->add_id(patch_func->getId());\n\t\tpatch_block->ir.operations.push_back(call_op);\n\t\tif (execution_mode_meta.patch_lowering_array_var_id)\n\t\t\temit_patch_output_lowering(patch_block);\n\n\t\tmerge_block->ir.terminator.type = Terminator::Type::Return;\n\t}\n\telse\n\t{\n\t\tcall_op = allocate(spv::OpFunctionCall, builder().makeVoidType());\n\t\tcall_op->add_id(patch_func->getId());\n\t\tentry->ir.operations.push_back(call_op);\n\t\tentry->ir.terminator.type = Terminator::Type::Return;\n\t\tif (execution_mode_meta.patch_lowering_array_var_id)\n\t\t\temit_patch_output_lowering(entry);\n\t}\n\n\treturn { entry, spirv_module.get_entry_function() };\n}\n\nvoid Converter::Impl::build_function_bb_visit_order_inner_analysis(\n\tVector<llvm::BasicBlock *> &bbs, UnorderedSet<llvm::BasicBlock *> &visited,\n\tllvm::BasicBlock *bb)\n{\n\tif (visited.count(bb))\n\t\treturn;\n\tvisited.insert(bb);\n\n\t// Check for special case where we optimize to direct branch.\n\tauto *term = bb->getTerminator();\n\tif (auto *inst = llvm::dyn_cast<llvm::BranchInst>(term))\n\t{\n\t\tif (inst->isConditional())\n\t\t{\n\t\t\tbool cond_value;\n\t\t\tif (can_optimize_conditional_branch_to_static(*this, inst->getCondition(), cond_value))\n\t\t\t{\n\t\t\t\tauto *succ = inst->getSuccessor(cond_value ? 0 : 1);\n\t\t\t\tbuild_function_bb_visit_order_inner_analysis(bbs, visited, succ);\n\t\t\t\tbbs.push_back(bb);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (auto itr = llvm::succ_begin(bb); itr != llvm::succ_end(bb); ++itr)\n\t{\n\t\tauto *succ = *itr;\n\t\tbuild_function_bb_visit_order_inner_analysis(bbs, visited, succ);\n\t}\n\n\tbbs.push_back(bb);\n}\n\nVector<llvm::BasicBlock *> Converter::Impl::build_function_bb_visit_order_analysis(llvm::Function *func)\n{\n\tif (!func)\n\t\treturn {};\n\n\tUnorderedSet<llvm::BasicBlock *> visited;\n\tVector<llvm::BasicBlock *> visit_order;\n\tauto *entry = &func->getEntryBlock();\n\tbuild_function_bb_visit_order_inner_analysis(visit_order, visited, entry);\n\t// Get natural traverse order, input is post-traversal order.\n\tstd::reverse(visit_order.begin(), visit_order.end());\n\treturn visit_order;\n}\n\nvoid Converter::Impl::build_function_bb_visit_register(llvm::BasicBlock *bb, CFGNodePool &pool, String tag)\n{\n\tauto entry_meta = std::make_unique<BlockMeta>(bb);\n\tbb_map[bb] = entry_meta.get();\n\tauto *entry_node = pool.create_node();\n\tbb_map[bb]->node = entry_node;\n\tentry_node->name = std::move(tag);\n\tmetas.push_back(std::move(entry_meta));\n}\n\n// This only exists so that we can avoid nuking all existing Fossilize caches with completely new shaders.\n// This traversal order is not a perfect reverse post-traversal,\n// so we cannot use it for analysis with alloca() -> CBV forwarding checks.\n// Once we are ready to consider doing large scale SPIR-V changes that invalidate all caches anyway,\n// we might as well get rid of this path in the same update and use the common analysis path.\nVector<llvm::BasicBlock *> Converter::Impl::build_function_bb_visit_order_legacy(\n    llvm::Function *func, CFGNodePool &pool)\n{\n\tif (!func)\n\t\treturn {};\n\n\tauto *entry = &func->getEntryBlock();\n\tbuild_function_bb_visit_register(entry, pool, \".entry\");\n\n\tVector<llvm::BasicBlock *> to_process;\n\tVector<llvm::BasicBlock *> processing;\n\tto_process.push_back(entry);\n\tVector<llvm::BasicBlock *> visit_order;\n\n\tunsigned fake_label_id = 0;\n\n\tconst auto queue_visit_succ = [&](llvm::BasicBlock *block, llvm::BasicBlock *succ) {\n\t\tif (!bb_map.count(succ))\n\t\t{\n\t\t\tto_process.push_back(succ);\n\t\t\tbuild_function_bb_visit_register(succ, pool, dxil_spv::to_string(++fake_label_id));\n\t\t}\n\n\t\tbb_map[block]->node->add_branch(bb_map[succ]->node);\n\t};\n\n\t// Traverse the CFG and register all blocks in the pool.\n\twhile (!to_process.empty())\n\t{\n\t\tstd::swap(to_process, processing);\n\t\tfor (auto *block : processing)\n\t\t{\n\t\t\tvisit_order.push_back(block);\n\n\t\t\tauto *term = block->getTerminator();\n\t\t\tif (auto *inst = llvm::dyn_cast<llvm::BranchInst>(term))\n\t\t\t{\n\t\t\t\tif (inst->isConditional())\n\t\t\t\t{\n\t\t\t\t\tbool cond_value;\n\t\t\t\t\tif (can_optimize_conditional_branch_to_static(*this, inst->getCondition(), cond_value))\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *succ = inst->getSuccessor(cond_value ? 0 : 1);\n\t\t\t\t\t\tqueue_visit_succ(block, succ);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (auto itr = llvm::succ_begin(block); itr != llvm::succ_end(block); ++itr)\n\t\t\t\tqueue_visit_succ(block, *itr);\n\t\t}\n\t\tprocessing.clear();\n\t}\n\n\treturn visit_order;\n}\n\nvoid Converter::Impl::emit_write_instrumentation_invocation_id(CFGNode *node)\n{\n\tcurrent_block = &node->ir.operations;\n\n\tspv::Id alloc_id = spirv_module.get_helper_call_id(HelperCall::AllocateInvocationID);\n\n\tauto *call = allocate(spv::OpFunctionCall, builder().makeUintType(32));\n\tcall->add_id(alloc_id);\n\tadd(call);\n\n\tauto *store = allocate(spv::OpStore);\n\tstore->add_id(instrumentation.invocation_id_var_id);\n\tstore->add_id(call->id);\n\tadd(store);\n}\n\nvoid Converter::Impl::gather_function_dependencies(llvm::Function *caller, Vector<llvm::Function *> &funcs)\n{\n\tif (std::find(funcs.begin(), funcs.end(), caller) != funcs.end())\n\t\treturn;\n\n\t// Avoid exponential explosion while traversing.\n\tfuncs.push_back(caller);\n\n\tfor (auto &bb : *caller)\n\t{\n\t\tfor (auto &inst : bb)\n\t\t{\n\t\t\tif (const auto *call_inst = llvm::dyn_cast<llvm::CallInst>(&inst))\n\t\t\t{\n\t\t\t\tauto *fn = call_inst->getCalledFunction();\n\t\t\t\tif (strncmp(fn->getName().data(), \"dx.op\", 5) != 0 &&\n\t\t\t\t    strncmp(fn->getName().data(), \"llvm.\", 5) != 0)\n\t\t\t\t{\n\t\t\t\t\tgather_function_dependencies(fn, funcs);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Ensure leaves come before their caller.\n\tfuncs.erase(std::find(funcs.begin(), funcs.end(), caller));\n\tfuncs.push_back(caller);\n}\n\nbool Converter::Impl::build_callee_functions(CFGNodePool &pool,\n                                             const Vector<llvm::Function *> &callees,\n                                             Vector<ConvertedFunction::Function> &leaves)\n{\n\tllvm::Function *func = get_entry_point_function(entry_point_meta);\n\n\tfor (auto *leaf_func : callees)\n\t{\n\t\tif (leaf_func == func || leaf_func == execution_mode_meta.patch_constant_function)\n\t\t\tcontinue;\n\n\t\tVector<spv::Id> arg_types;\n\t\tspv::Block *spv_entry;\n\n\t\t// Cannot safely use function-local undefs now.\n\t\tshader_analysis.global_undefs = true;\n\n\t\targ_types.reserve(leaf_func->getFunctionType()->getNumParams());\n\t\tfor (uint32_t i = 0; i < leaf_func->getFunctionType()->getNumParams(); i++)\n\t\t\targ_types.push_back(get_type_id(leaf_func->getFunctionType()->getParamType(i)));\n\n\t\tauto *spv_func =\n\t\t    builder().makeFunctionEntry(spv::NoPrecision, get_type_id(leaf_func->getFunctionType()->getReturnType()),\n#ifdef HAVE_LLVMBC\n\t\t                                leaf_func->getName().c_str(),\n#else\n\t\t                                leaf_func->getName().str().c_str(),\n#endif\n\t\t                                arg_types, {}, &spv_entry);\n\n\t\trewrite_value(leaf_func, spv_func->getId());\n\n\t\tauto arg_iter = leaf_func->arg_begin();\n\t\tfor (uint32_t i = 0, n = leaf_func->getFunctionType()->getNumParams(); i < n; i++, ++arg_iter)\n\t\t\trewrite_value(&*arg_iter, spv_func->getParamId(i));\n\n\t\tauto visit_order = build_function_bb_visit_order_analysis(leaf_func);\n\n\t\tfor (auto *bb : visit_order)\n\t\t\tbuild_function_bb_visit_register(bb, pool, \"\");\n\n\t\tfor (auto *bb : visit_order)\n\t\t\tfor (auto itr = llvm::succ_begin(bb); itr != llvm::succ_end(bb); ++itr)\n\t\t\t\tbb_map[bb]->node->add_branch(bb_map[*itr]->node);\n\n\t\tbuilder().setBuildPoint(spv_entry);\n\t\tauto *entry = convert_function(visit_order, false);\n\t\tif (!entry)\n\t\t\treturn false;\n\n\t\tleaves.push_back({ entry, spv_func });\n\t}\n\n\tbuilder().setBuildPoint(spirv_module.get_entry_function()->getEntryBlock());\n\n\treturn true;\n}\n\nCFGNode *Converter::Impl::convert_function(const Vector<llvm::BasicBlock *> &visit_order, bool primary_code)\n{\n\tbool has_partial_unroll = false;\n\n\tfor (auto *bb : visit_order)\n\t{\n\t\tauto *meta = bb_map[bb];\n\t\tCFGNode *node = meta->node;\n\t\tcombined_image_sampler_cache.clear();\n\t\tpeephole_transformation_cache.clear();\n\t\tmemoized = {};\n\n\t\tif (bb == visit_order.front())\n\t\t{\n\t\t\tcurrent_block = &node->ir.operations;\n\t\t\tif (!emit_view_masking(*this))\n\t\t\t\treturn {};\n\t\t\tif (!emit_view_instancing_fixed_layer_viewport(*this, true))\n\t\t\t\treturn {};\n\t\t\tif (instrumentation.invocation_id_var_id && primary_code)\n\t\t\t\temit_write_instrumentation_invocation_id(node);\n\t\t}\n\n\t\tauto sink_itr = bb_to_sinks.find(bb);\n\t\tif (sink_itr != bb_to_sinks.end())\n\t\t{\n\t\t\tfor (auto *instruction : sink_itr->second)\n\t\t\t{\n\t\t\t\tauto itr = value_map.find(instruction);\n\t\t\t\tif (itr != value_map.end())\n\t\t\t\t\tvalue_map.erase(itr);\n\n\t\t\t\tif (!emit_instruction(node, *instruction))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to emit instruction.\\n\");\n\t\t\t\t\treturn {};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Scan opcodes.\n\t\tfor (auto &instruction : *bb)\n\t\t{\n\t\t\tif (!emit_instruction(node, instruction))\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to emit instruction.\\n\");\n\t\t\t\treturn {};\n\t\t\t}\n\t\t}\n\n\t\tags.reset();\n\t\tnvapi.reset();\n\n\t\t// We don't know if the block is a loop yet, so just tag every BB.\n\t\t// CFG will propagate the information as necessary.\n\t\tnode->ir.terminator.force_flatten = options.branch_control.force_flatten;\n\t\tnode->ir.terminator.force_branch = options.branch_control.force_branch;\n\t\tnode->ir.terminator.force_unroll = options.branch_control.force_unroll;\n\t\tnode->ir.terminator.force_loop = options.branch_control.force_loop;\n\n\t\tauto *instruction = bb->getTerminator();\n\n\t\tif (auto *inst = llvm::dyn_cast<llvm::BranchInst>(instruction))\n\t\t{\n\t\t\t// Loop information is attached to the back edge in LLVM.\n\t\t\t// Continue blocks can be direct branches or conditional ones, so make it generic.\n\t\t\tauto *loop_meta = instruction->getMetadata(\"llvm.loop\");\n\t\t\tif (loop_meta && loop_meta->getNumOperands() >= 2)\n\t\t\t{\n\t\t\t\tauto *meta_node = llvm::dyn_cast<llvm::MDNode>(loop_meta->getOperand(1));\n\t\t\t\tif (meta_node)\n\t\t\t\t{\n\t\t\t\t\tauto *meta_name = llvm::dyn_cast<llvm::MDString>(meta_node->getOperand(0));\n\t\t\t\t\tif (meta_name)\n\t\t\t\t\t{\n#ifdef HAVE_LLVMBC\n\t\t\t\t\t\tauto &str = meta_name->getString();\n#else\n\t\t\t\t\t\tauto str = meta_name->getString();\n#endif\n\n\t\t\t\t\t\tif (options.branch_control.use_shader_metadata)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (str == \"llvm.loop.unroll.disable\")\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_loop = true;\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_unroll = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (str == \"llvm.loop.unroll.full\")\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_unroll = true;\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_loop = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (str == \"llvm.loop.unroll.count\")\n\t\t\t\t\t\t\thas_partial_unroll = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (inst->isConditional())\n\t\t\t{\n\t\t\t\t// Works around some pathological unrolling scenarios where games may unroll based on WaveGetLaneCount().\n\t\t\t\tbool cond_value;\n\t\t\t\tif (can_optimize_conditional_branch_to_static(*this, inst->getCondition(), cond_value))\n\t\t\t\t{\n\t\t\t\t\tnode->ir.terminator.type = Terminator::Type::Branch;\n\t\t\t\t\tnode->ir.terminator.direct_block = bb_map[inst->getSuccessor(cond_value ? 0 : 1)]->node;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnode->ir.terminator.type = Terminator::Type::Condition;\n\t\t\t\t\tnode->ir.terminator.conditional_id = get_id_for_value(inst->getCondition());\n\t\t\t\t\tassert(inst->getNumSuccessors() == 2);\n\t\t\t\t\tnode->ir.terminator.true_block = bb_map[inst->getSuccessor(0)]->node;\n\t\t\t\t\tnode->ir.terminator.false_block = bb_map[inst->getSuccessor(1)]->node;\n\n\t\t\t\t\tif (options.branch_control.use_shader_metadata)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *branch_meta = inst->getMetadata(\"dx.controlflow.hints\");\n\t\t\t\t\t\tif (branch_meta && branch_meta->getNumOperands() >= 3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (get_constant_metadata(branch_meta, 2) == 1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_branch = true;\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_flatten = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (get_constant_metadata(branch_meta, 2) == 2)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_flatten = true;\n\t\t\t\t\t\t\t\tnode->ir.terminator.force_branch = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnode->ir.terminator.type = Terminator::Type::Branch;\n\t\t\t\tassert(inst->getNumSuccessors() == 1);\n\t\t\t\tnode->ir.terminator.direct_block = bb_map[inst->getSuccessor(0)]->node;\n\n\t\t\t\t// If the shader uses partial unrolling, but we see loops anyway,\n\t\t\t\t// it's very likely we really want this to be a loop.\n\t\t\t\t// This is somewhat of a hack heuristic to work around a Mesa bug in Lords of the Fallen,\n\t\t\t\t// but it makes at least some sense ...\n\t\t\t\tif (has_partial_unroll)\n\t\t\t\t\tnode->ir.terminator.force_loop = true;\n\t\t\t}\n\t\t}\n\t\telse if (auto *inst = llvm::dyn_cast<llvm::SwitchInst>(instruction))\n\t\t{\n\t\t\tnode->ir.terminator.type = Terminator::Type::Switch;\n\n\t\t\tTerminator::Case default_case = {};\n\t\t\tdefault_case.is_default = true;\n\t\t\tdefault_case.node = bb_map[inst->getDefaultDest()]->node;\n\t\t\tnode->ir.terminator.cases.push_back(default_case);\n\n\t\t\tnode->ir.terminator.conditional_id = get_id_for_value(inst->getCondition());\n\t\t\tfor (auto itr = inst->case_begin(); itr != inst->case_end(); ++itr)\n\t\t\t{\n\t\t\t\tTerminator::Case switch_case = {};\n\t\t\t\tswitch_case.node = bb_map[itr->getCaseSuccessor()]->node;\n\t\t\t\tswitch_case.value = uint32_t(itr->getCaseValue()->getUniqueInteger().getZExtValue());\n\t\t\t\tnode->ir.terminator.cases.push_back(switch_case);\n\t\t\t}\n\t\t}\n\t\telse if (auto *inst = llvm::dyn_cast<llvm::ReturnInst>(instruction))\n\t\t{\n\t\t\tnode->ir.terminator.type = Terminator::Type::Return;\n\t\t\tif (inst->getReturnValue())\n\t\t\t\tnode->ir.terminator.return_value = get_id_for_value(inst->getReturnValue());\n\t\t}\n\t\telse if (llvm::isa<llvm::UnreachableInst>(instruction))\n\t\t{\n\t\t\tnode->ir.terminator.type = Terminator::Type::Unreachable;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tLOGE(\"Unsupported terminator ...\\n\");\n\t\t\treturn {};\n\t\t}\n\n#ifdef HAVE_LLVMBC\n\t\t// Forward structured control flow.\n\t\tif (bb->get_merge() == llvm::BasicBlock::Merge::Selection)\n\t\t{\n\t\t\tnode->ir.merge_info.merge_type = MergeType::Selection;\n\n\t\t\t// Assume both paths can return or break, leaving the merge unreachable.\n\t\t\tif (bb->get_merge_bb() && bb_map.count(bb->get_merge_bb()))\n\t\t\t\tnode->ir.merge_info.merge_block = bb_map[bb->get_merge_bb()]->node;\n\t\t}\n\t\telse if (bb->get_merge() == llvm::BasicBlock::Merge::Loop)\n\t\t{\n\t\t\tnode->ir.merge_info.merge_type = MergeType::Loop;\n\n\t\t\t// In infinite loops, merge block may be unreachable.\n\t\t\tif (bb->get_merge_bb() && bb_map.count(bb->get_merge_bb()))\n\t\t\t\tnode->ir.merge_info.merge_block = bb_map[bb->get_merge_bb()]->node;\n\n\t\t\t// If back-edge is not reachable, we'll resolve that later.\n\t\t\tif (bb->get_continue_bb() && bb_map.count(bb->get_continue_bb()))\n\t\t\t\tnode->ir.merge_info.continue_block = bb_map[bb->get_continue_bb()]->node;\n\t\t}\n#endif\n\t}\n\n\t// Rewrite PHI incoming values if we have to.\n\tif (!phi_incoming_rewrite.empty())\n\t{\n\t\tfor (auto *bb : visit_order)\n\t\t{\n\t\t\tCFGNode *node = bb_map[bb]->node;\n\t\t\tfor (auto &phi : node->ir.phi)\n\t\t\t{\n\t\t\t\tfor (auto &incoming : phi.incoming)\n\t\t\t\t{\n\t\t\t\t\tauto itr = phi_incoming_rewrite.find(incoming.id);\n\t\t\t\t\tif (itr != phi_incoming_rewrite.end())\n\t\t\t\t\t\tincoming.id = itr->second;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn bb_map[visit_order.front()]->node;\n}\n\nvoid Converter::Impl::mark_used_value(const llvm::Value *value)\n{\n\tif (!llvm::isa<llvm::Constant>(value))\n\t{\n\t\t// Technically, we won't be able to eliminate a chain of SSA expressions\n\t\t// which are unused this way, but eeeeeeh. DXC really should handle that.\n\t\t// This is to deal with odd-ball edge cases where random single SSA instructions\n\t\t// were not eliminated for whatever reason.\n\t\tllvm_used_ssa_values.insert(value);\n\t}\n}\n\nvoid Converter::Impl::mark_used_values(const llvm::Instruction *instruction)\n{\n\tif (auto *phi_inst = llvm::dyn_cast<llvm::PHINode>(instruction))\n\t{\n\t\tfor (unsigned i = 0, n = phi_inst->getNumIncomingValues(); i < n; i++)\n\t\t{\n\t\t\tauto *incoming = phi_inst->getIncomingValue(i);\n\t\t\t// Ignore self-referential PHI. Someone else need to refer to us.\n\t\t\tif (incoming != phi_inst)\n\t\t\t\tmark_used_value(incoming);\n\t\t}\n\t}\n\telse if (const auto *ret_inst = llvm::dyn_cast<llvm::ReturnInst>(instruction))\n\t{\n\t\tif (ret_inst->getReturnValue())\n\t\t\tmark_used_value(ret_inst->getReturnValue());\n\t}\n\telse if (const auto *cond_inst = llvm::dyn_cast<llvm::BranchInst>(instruction))\n\t{\n\t\tif (cond_inst->isConditional())\n\t\t\tmark_used_value(cond_inst->getCondition());\n\t}\n\telse if (const auto *switch_inst = llvm::dyn_cast<llvm::SwitchInst>(instruction))\n\t{\n\t\tmark_used_value(switch_inst->getCondition());\n\t}\n\telse\n\t{\n\t\tfor (unsigned i = 0, n = instruction->getNumOperands(); i < n; i++)\n\t\t\tmark_used_value(instruction->getOperand(i));\n\t}\n}\n\nstatic bool instruction_is_precise_sensitive(const llvm::Instruction *value)\n{\n\tif (auto *binary_op = llvm::dyn_cast<llvm::BinaryOperator>(value))\n\t{\n\t\tauto opcode = binary_op->getOpcode();\n\t\tswitch (opcode)\n\t\t{\n\t\tcase llvm::BinaryOperator::BinaryOps::FAdd:\n\t\tcase llvm::BinaryOperator::BinaryOps::FSub:\n\t\tcase llvm::BinaryOperator::BinaryOps::FMul:\n\t\tcase llvm::BinaryOperator::BinaryOps::FDiv:\n\t\tcase llvm::BinaryOperator::BinaryOps::FRem:\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\telse if (value_is_dx_op_instrinsic(value, DXIL::Op::FMad) ||\n\t         value_is_dx_op_instrinsic(value, DXIL::Op::Dot2) ||\n\t         value_is_dx_op_instrinsic(value, DXIL::Op::Dot2AddHalf) ||\n\t         value_is_dx_op_instrinsic(value, DXIL::Op::Dot3) ||\n\t         value_is_dx_op_instrinsic(value, DXIL::Op::Dot4))\n\t{\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic bool instruction_requires_no_contraction(const llvm::Instruction *value)\n{\n\tif (instruction_is_precise_sensitive(value))\n\t{\n\t\tif (auto *binary_op = llvm::dyn_cast<llvm::BinaryOperator>(value))\n\t\t\treturn !binary_op->isFast();\n\t\telse\n\t\t\treturn llvm::cast<llvm::CallInst>(value)->hasMetadata(\"dx.precise\");\n\t}\n\n\treturn false;\n}\n\nstatic void propagate_precise(UnorderedSet<const llvm::Instruction *> &cache, const llvm::Instruction *value);\n\nstatic void mark_precise(UnorderedSet<const llvm::Instruction *> &cache, const llvm::Value *value)\n{\n\t// Stop propagating when we hit something not an instruction, i.e. a constant or variable (alloca is very rare).\n\tif (auto *inst = llvm::dyn_cast<llvm::Instruction>(value))\n\t{\n\t\tif (instruction_is_precise_sensitive(inst) && !instruction_requires_no_contraction(inst))\n\t\t{\n\t\t\tif (auto *call_inst = llvm::dyn_cast<llvm::CallInst>(inst))\n\t\t\t\tconst_cast<llvm::CallInst *>(call_inst)->setMetadata(\"dx.precise\", nullptr);\n\t\t\telse if (auto *binary_op = llvm::dyn_cast<llvm::BinaryOperator>(inst))\n\t\t\t\tconst_cast<llvm::BinaryOperator *>(binary_op)->setFast(false);\n\t\t}\n\n\t\tpropagate_precise(cache, inst);\n\t}\n}\n\nstatic void propagate_precise(UnorderedSet<const llvm::Instruction *> &cache, const llvm::Instruction *value)\n{\n\tif (cache.count(value) != 0)\n\t\treturn;\n\tcache.insert(value);\n\n\tif (const auto *phi = llvm::dyn_cast<llvm::PHINode>(value))\n\t{\n\t\tfor (unsigned i = 0, n = phi->getNumIncomingValues(); i < n; i++)\n\t\t\tmark_precise(cache, phi->getIncomingValue(i));\n\t}\n\telse\n\t{\n\t\tfor (unsigned i = 0, n = value->getNumOperands(); i < n; i++)\n\t\t\tmark_precise(cache, value->getOperand(i));\n\t}\n}\n\nstatic void propagate_precise(llvm::Function *func)\n{\n\tVector<const llvm::Instruction *> precise_instructions;\n\tfor (auto &bb : *func)\n\t\tfor (auto &inst : bb)\n\t\t\tif (instruction_requires_no_contraction(&inst))\n\t\t\t\tprecise_instructions.push_back(&inst);\n\n\tUnorderedSet<const llvm::Instruction *> visitation_cache;\n\tfor (auto *inst : precise_instructions)\n\t\tpropagate_precise(visitation_cache, inst);\n}\n\nvoid Converter::Impl::analyze_instructions_post_execution_modes()\n{\n\tif ((options.quirks.group_shared_auto_barrier || !shader_analysis.has_group_shared_barrier) &&\n\t     shader_analysis.has_group_shared_access)\n\t{\n\t\tunsigned num_threads = execution_mode_meta.workgroup_threads[0] *\n\t\t                       execution_mode_meta.workgroup_threads[1] *\n\t\t                       execution_mode_meta.workgroup_threads[2];\n\n\t\tif (options.quirks.group_shared_auto_barrier || (num_threads <= 32 && num_threads > 1))\n\t\t{\n\t\t\t// This is a case that might just happen to work if the game assumes lock-step execution on NV + AMD (rip Intel).\n\t\t\t// If the group size is larger, it's extremely unlikely the game \"just works\" by chance on native drivers.\n\t\t\t// Some shaders seem to use groupshared as a sort of \"scratch space\" per thread, which\n\t\t\t// is a valid use case and does not require barriers to be correct.\n\t\t\tshader_analysis.needs_auto_group_shared_barriers = true;\n\t\t}\n\t}\n}\n\nbool Converter::Impl::analyze_instructions(llvm::Function *func)\n{\n\t// Need to analyze this in two stages.\n\t// In the first stage, we need to analyze:\n\t// - Load/GetElementPtr to handle lib global variables\n\t// - CreateHandle family to build LLVM access handles\n\t// - ExtractValue to track which components are used for BufferLoad.\n\t// In the second phase we analyze the buffer loads and stores and figure out\n\t// alignments of the loads and stores. This lets us build up a list of SSBO declarations we need to\n\t// optimally implement the loads and stores. We need to do this late, because we depend on results\n\t// of ExtractValue analysis.\n\n\tif (func && options.propagate_precise && !options.force_precise)\n\t\tpropagate_precise(func);\n\n\tauto visit_order = build_function_bb_visit_order_analysis(func);\n\n\tfor (auto *bb : visit_order)\n\t{\n\t\tif (options.eliminate_dead_code)\n\t\t\tmark_used_values(bb->getTerminator());\n\n\t\tfor (auto &inst : *bb)\n\t\t{\n\t\t\tif (options.eliminate_dead_code)\n\t\t\t\tmark_used_values(&inst);\n\n\t\t\tif (auto *load_inst = llvm::dyn_cast<llvm::LoadInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_load_instruction(*this, load_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *store_inst = llvm::dyn_cast<llvm::StoreInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_store_instruction(*this, store_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *phi_inst = llvm::dyn_cast<llvm::PHINode>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_phi_instruction(*this, phi_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *atomicrmw_inst = llvm::dyn_cast<llvm::AtomicRMWInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_atomicrmw_instruction(*this, atomicrmw_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *cmpxchg_inst = llvm::dyn_cast<llvm::AtomicCmpXchgInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_cmpxchg_instruction(*this, cmpxchg_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *alloca_inst = llvm::dyn_cast<llvm::AllocaInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_alloca_instruction(*this, alloca_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *getelementptr_inst = llvm::dyn_cast<llvm::GetElementPtrInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_getelementptr_instruction(*this, getelementptr_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *extractvalue_inst = llvm::dyn_cast<llvm::ExtractValueInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_extractvalue_instruction(*this, extractvalue_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *cmp_inst = llvm::dyn_cast<llvm::CmpInst>(&inst))\n\t\t\t{\n\t\t\t\tif (!analyze_compare_instruction(*this, cmp_inst))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (auto *call_inst = llvm::dyn_cast<llvm::CallInst>(&inst))\n\t\t\t{\n\t\t\t\tauto *called_function = call_inst->getCalledFunction();\n\t\t\t\tif (strncmp(called_function->getName().data(), \"dx.op\", 5) == 0)\n\t\t\t\t{\n\t\t\t\t\tif (!analyze_dxil_instruction_primary_pass(*this, call_inst, bb))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Reset vendor tracking for every BB.\n\t\tags.reset();\n\t\tnvapi.reset();\n\t}\n\n\tfor (auto *bb : visit_order)\n\t{\n\t\tfor (auto &inst : *bb)\n\t\t{\n\t\t\tif (auto *call_inst = llvm::dyn_cast<llvm::CallInst>(&inst))\n\t\t\t{\n\t\t\t\tauto *called_function = call_inst->getCalledFunction();\n\t\t\t\tif (strncmp(called_function->getName().data(), \"dx.op\", 5) == 0)\n\t\t\t\t{\n\t\t\t\t\tif (!analyze_dxil_instruction_secondary_pass(*this, call_inst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Reset vendor tracking for every BB.\n\t\tags.reset();\n\t\tnvapi.reset();\n\t}\n\n\tfor (auto &alloc : alloca_tracking)\n\t{\n\t\t// Mark required resource aliases before we emit resources. Defer some work until after resource creation.\n\t\tconst auto *scalar_type =\n\t\t    alloc.first->getType()->getPointerElementType()->getArrayElementType();\n\t\tif (!analyze_alloca_cbv_forwarding_pre_resource_emit(*this, scalar_type, alloc.second))\n\t\t\treturn false;\n\t}\n\n\tags.reset_analysis();\n\tnvapi.reset_analysis();\n\n\tif (shader_analysis.require_wmma)\n\t\texecution_mode_meta.memory_model = spv::MemoryModelVulkan;\n\n\treturn true;\n}\n\nbool Converter::Impl::composite_is_accessed(const llvm::Value *composite) const\n{\n\treturn llvm_composite_meta.find(composite) != llvm_composite_meta.end();\n}\n\nConvertedFunction Converter::Impl::convert_entry_point()\n{\n\tConvertedFunction result = {};\n\n\tauto &module = bitcode_parser.get_module();\n\tentry_point_meta = get_entry_point_meta(module, options.entry_point.empty() ? nullptr : options.entry_point.c_str());\n\texecution_model = get_execution_model(module, entry_point_meta);\n\texecution_model_lib_target = get_execution_model_lib_target(module, entry_point_meta);\n\n\tif (execution_model_lib_target && execution_model == spv::ExecutionModelGLCompute)\n\t{\n\t\t// Might as well go with SPIR-V 1.6. Then we get subgroup size control semantics for \"free\".\n\t\t// When we're willing to do a clean break with Fossilize all shaders should target SPIR-V 1.6.\n\t\tspirv_module.set_override_spirv_version(0x10600);\n\t}\n\telse if (execution_model == spv::ExecutionModelFragment &&\n\t         resource_mapping_iface && resource_mapping_iface->has_nontrivial_stage_input_remapping())\n\t{\n\t\t// Force SPIR-V 1.4 for fragment shaders if we might end up requiring mesh shader capabilities.\n\t\t// Non-trivial stage input remapping may require PerPrimitiveEXT decoration.\n\t\tspirv_module.set_override_spirv_version(0x10400);\n\t}\n\n\tif (!entry_point_meta)\n\t{\n\t\tif (!options.entry_point.empty())\n\t\t\tLOGE(\"Could not find entry point \\\"%s\\\".\\n\", options.entry_point.c_str());\n\t\telse\n\t\t\tLOGE(\"Could not find any entry point.\\n\");\n\t\treturn result;\n\t}\n\n\tif (!options.shader_source_file.empty())\n\t{\n\t\tauto &builder = spirv_module.get_builder();\n\t\tuint32_t sm_major = 0, sm_minor = 0;\n\t\tget_shader_model(module, nullptr, &sm_major, &sm_minor);\n\t\tbuilder.setSource(spv::SourceLanguageUnknown, sm_major * 100 + sm_minor);\n\t\tbuilder.setSourceFile(options.shader_source_file);\n\t}\n\n\tresult.node_pool = std::make_unique<CFGNodePool>();\n\tauto &pool = *result.node_pool;\n\n\tbool need_bda =\n\t\toptions.physical_storage_buffer ||\n\t\t(execution_model_lib_target &&\n\t\t execution_model == spv::ExecutionModelGLCompute);\n\n\tspirv_module.set_descriptor_qa_info(options.descriptor_qa);\n\toptions.instruction_instrumentation.fp16 =\n\t    options.min_precision_prefer_native_16bit || execution_mode_meta.native_16bit_operations;\n\tspirv_module.set_instruction_instrumentation_info(options.instruction_instrumentation);\n\n\tllvm::Function *func = get_entry_point_function(entry_point_meta);\n\tauto visit_order = build_function_bb_visit_order_legacy(func, pool);\n\tVector<llvm::BasicBlock *> patch_visit_order;\n\n\t// dxilconv emits somewhat broken code for min16float for resource access.\n\t// Just use FP32 here since that's what we've tested and avoids lots of awkward workarounds.\n\tif (module_is_dxilconv(module))\n\t\toptions.min_precision_prefer_native_16bit = false;\n\n\tif (module_is_dxbc_spirv(module))\n\t{\n\t\tbackend.skip_non_uniform_promotion = true;\n\t\t// This is new code, might as well exercise it.\n\t\texecution_mode_meta.memory_model = spv::MemoryModelVulkan;\n\t}\n\n\t// Need to analyze some execution modes early which affect opcode analysis later.\n\tif (!analyze_execution_modes_meta())\n\t\treturn result;\n\tif (!emit_resources_global_mapping())\n\t\treturn result;\n\tif (!analyze_instructions(func))\n\t\treturn result;\n\n\tspirv_module.emit_entry_point(get_execution_model(module, entry_point_meta), \"main\", need_bda,\n\t                              execution_mode_meta.memory_model);\n\n\tif (!emit_execution_modes())\n\t\treturn result;\n\n\tif (execution_mode_meta.patch_constant_function)\n\t\tpatch_visit_order = build_function_bb_visit_order_legacy(execution_mode_meta.patch_constant_function, pool);\n\n\tVector<llvm::Function *> callees;\n\tif (func)\n\t\tgather_function_dependencies(func, callees);\n\tif (execution_mode_meta.patch_constant_function)\n\t\tgather_function_dependencies(execution_mode_meta.patch_constant_function, callees);\n\n\t// Analyze all leaf functions.\n\tfor (auto *leaf_func : callees)\n\t\tif (leaf_func != func && !analyze_instructions(leaf_func))\n\t\t\treturn result;\n\n\tif (!emit_resources())\n\t\treturn result;\n\tif (!emit_stage_input_variables())\n\t\treturn result;\n\tif (!emit_stage_output_variables())\n\t\treturn result;\n\tif (!emit_patch_variables())\n\t\treturn result;\n\tif (!emit_other_variables())\n\t\treturn result;\n\tif (!emit_global_variables())\n\t\treturn result;\n\n\tif (options.extended_non_semantic_info)\n\t\tfor (auto &info : non_semantic_debug_info)\n\t\t\temit_non_semantic_debug_info(info);\n\n\t// Some execution modes depend on other execution modes, so handle that here.\n\tif (!emit_execution_modes_late())\n\t\treturn result;\n\n\tanalyze_instructions_post_execution_modes();\n\n\texecution_mode_meta.entry_point_name = get_entry_point_name(entry_point_meta);\n\n\tif (!build_callee_functions(pool, callees, result.leaf_functions))\n\t\treturn result;\n\n\tif (execution_model == spv::ExecutionModelTessellationControl)\n\t\tresult.entry = build_hull_main(visit_order, patch_visit_order, pool, result.leaf_functions);\n\telse if (execution_mode_meta.declares_rov)\n\t\tresult.entry = build_rov_main(visit_order, pool, result.leaf_functions);\n\telse if (execution_model_lib_target && execution_model == spv::ExecutionModelGLCompute)\n\t\tresult.entry = build_node_main(visit_order, pool, result.leaf_functions);\n\telse\n\t{\n\t\tresult.entry.entry = convert_function(visit_order, true);\n\t\tif (shader_analysis.needs_auto_group_shared_barriers && options.quirks.group_shared_auto_barrier)\n\t\t{\n\t\t\tCFGStructurizer cfg{result.entry.entry, pool, spirv_module};\n\t\t\tcfg.rewrite_auto_group_shared_barrier();\n\t\t}\n\n\t\tif (shader_analysis.require_subgroup_shuffles)\n\t\t{\n\t\t\tCFGStructurizer cfg{result.entry.entry, pool, spirv_module};\n\t\t\tcfg.flatten_subgroup_shuffles();\n\t\t}\n\n\t\tif (options.quirks.fixup_loop_header_undef_phis)\n\t\t{\n\t\t\tCFGStructurizer cfg{result.entry.entry, pool, spirv_module};\n\t\t\tcfg.fixup_loop_header_undef_phis();\n\t\t}\n\n\t\tresult.entry.func = spirv_module.get_entry_function();\n\t}\n\n#ifdef HAVE_LLVMBC\n\tif (func && func->get_structured_control_flow())\n\t{\n\t\t// For TESC, the entry is a custom dispatch function.\n\t\tresult.entry.is_structured = execution_model != spv::ExecutionModelTessellationControl;\n\t\tfor (auto &leaf : result.leaf_functions)\n\t\t\tleaf.is_structured = true;\n\t}\n#endif\n\n\t// Some execution modes depend on code generation, handle that here.\n\temit_execution_modes_post_code_generation();\n\n\treturn result;\n}\n\nOperation *Converter::Impl::allocate(spv::Op op)\n{\n\treturn spirv_module.allocate_op(op);\n}\n\nOperation *Converter::Impl::allocate(spv::Op op, spv::Id id, spv::Id type_id)\n{\n\tassert(type_id != 0);\n\tassert(id != 0);\n\treturn spirv_module.allocate_op(op, id, type_id);\n}\n\nOperation *Converter::Impl::allocate(spv::Op op, spv::Id type_id)\n{\n\tassert(type_id != 0);\n\treturn spirv_module.allocate_op(op, spirv_module.allocate_id(), type_id);\n}\n\nOperation *Converter::Impl::allocate(spv::Op op, const llvm::Value *value)\n{\n\t// Constant expressions cannot have an associated opcode ID to them.\n\tassert(!llvm::isa<llvm::ConstantExpr>(value));\n\treturn spirv_module.allocate_op(op, get_id_for_value(value), get_type_id(value->getType()));\n}\n\nOperation *Converter::Impl::allocate(spv::Op op, const llvm::Value *value, spv::Id type_id)\n{\n\t// Constant expressions cannot have an associated opcode ID to them.\n\tassert(!llvm::isa<llvm::ConstantExpr>(value));\n\tassert(type_id != 0);\n\treturn spirv_module.allocate_op(op, get_id_for_value(value), type_id);\n}\n\nvoid Converter::Impl::rewrite_value(const llvm::Value *value, spv::Id id)\n{\n\tauto value_itr = value_map.find(value);\n\tif (value_itr != value_map.end())\n\t{\n\t\tif (value_itr->second != id)\n\t\t{\n\t\t\t// If a PHI node previously accessed the value ID map, it will now refer to a dead\n\t\t\t// ID. Remember to rewrite PHI incoming nodes as necessary.\n\t\t\tphi_incoming_rewrite[value_itr->second] = id;\n\t\t\tvalue_itr->second = id;\n\t\t}\n\t}\n\telse\n\t\tvalue_map[value] = id;\n}\n\nvoid Converter::Impl::add(Operation *op, bool is_rov)\n{\n\tassert(current_block);\n\tif (is_rov)\n\t\tcurrent_block->push_back(allocate(spv::OpBeginInvocationInterlockEXT));\n\tcurrent_block->push_back(op);\n\tif (is_rov)\n\t\tcurrent_block->push_back(allocate(spv::OpEndInvocationInterlockEXT));\n}\n\nvoid Converter::Impl::register_externally_visible_write(const llvm::Value *value)\n{\n\tif (!options.instruction_instrumentation.enabled ||\n\t    options.instruction_instrumentation.type != InstructionInstrumentationType::ExternallyVisibleWriteNanInf)\n\t\treturn;\n\n\t// Ignore undefs and intentional nan/inf writes.\n\tif (llvm::isa<llvm::Constant>(value))\n\t\treturn;\n\n\t// Punch through any bitcasts.\n\t// Sometimes, shaders want to store floats as uints for practical reasons.\n\twhile (llvm::isa<llvm::CastInst>(value))\n\t{\n\t\tauto *cast = llvm::cast<llvm::CastInst>(value);\n\t\tif (cast->getOpcode() == llvm::CastInst::CastOps::BitCast)\n\t\t\tvalue = cast->getOperand(0);\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tswitch (value->getType()->getTypeID())\n\t{\n\tcase llvm::Type::TypeID::HalfTyID:\n\tcase llvm::Type::TypeID::FloatTyID:\n\tcase llvm::Type::TypeID::DoubleTyID:\n\t{\n\t\tauto *op = allocate(spv::PseudoOpInstrumentExternallyVisibleStore);\n\t\top->add_id(get_id_for_value(value));\n\t\tadd(op);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nspv::Builder &Converter::Impl::builder()\n{\n\treturn spirv_module.get_builder();\n}\n\nspv::Id Converter::Impl::create_variable(spv::StorageClass storage, spv::Id type_id, const char *name)\n{\n\treturn spirv_module.create_variable(storage, type_id, name);\n}\n\nspv::Id Converter::Impl::create_variable_with_initializer(spv::StorageClass storage, spv::Id type_id,\n                                                          spv::Id initializer, const char *name)\n{\n\treturn spirv_module.create_variable_with_initializer(storage, type_id, initializer, name);\n}\n\nspv::StorageClass Converter::Impl::get_effective_storage_class(const llvm::Value *value, spv::StorageClass fallback) const\n{\n\tauto itr = handle_to_storage_class.find(value);\n\tif (itr != handle_to_storage_class.end())\n\t\treturn itr->second;\n\telse\n\t\treturn fallback;\n}\n\nbool Converter::Impl::get_needs_temp_storage_copy(const llvm::Value *value) const\n{\n\t// We always need a temp storage copy if this isn't\n\t// directly the result of an alloca instruction.\n\tif (!llvm::dyn_cast<llvm::AllocaInst>(value))\n\t\treturn true;\n\n\t// We'll also need a temp storage copy if this\n\t// alloca is directly referenced by\n\t// a TraceRay AND a CallShader.\n\treturn needs_temp_storage_copy.count(value) != 0;\n}\n\nspv::Id Converter::Impl::get_temp_payload(spv::Id type, spv::StorageClass storage)\n{\n\tfor (const auto &temp_payload : temp_payloads)\n\t{\n\t\tif (temp_payload.type == type && temp_payload.storage == storage)\n\t\t\treturn temp_payload.id;\n\t}\n\n\tspv::Id var_id = create_variable(storage, type);\n\n\ttemp_payloads.push_back(TempPayloadEntry{ type, storage, var_id });\n\treturn var_id;\n}\n\nDXIL::ComponentType Converter::Impl::get_effective_typed_resource_type(DXIL::ComponentType type)\n{\n\t// Expand/contract on load/store.\n\t// DXIL can emit half textures for example,\n\t// but we need to contract or expand instead.\n\treturn convert_16bit_component_to_32bit(type);\n}\n\nDXIL::ComponentType Converter::Impl::get_effective_input_output_type(DXIL::ComponentType type)\n{\n\tbool supports_narrow_arith_type = type != DXIL::ComponentType::F16 || support_native_fp16_operations();\n\tif (options.storage_16bit_input_output && supports_narrow_arith_type)\n\t{\n\t\tif (component_type_is_16bit(type))\n\t\t\tbuilder().addCapability(spv::CapabilityStorageInputOutput16);\n\t}\n\telse\n\t{\n\t\t// Expand/contract on load/store.\n\t\t// The only reasonable way this can break is if application relies on\n\t\t// lower precision in interpolation, but I don't think you can rely on that\n\t\t// kind of implementation detail ...\n\t\ttype = convert_16bit_component_to_32bit(type);\n\t}\n\n\treturn type;\n}\n\nspv::Id Converter::Impl::get_effective_input_output_type_id(DXIL::ComponentType type)\n{\n\treturn get_type_id(get_effective_input_output_type(type), 1, 1);\n}\n\nbool Converter::Impl::type_can_relax_precision(const llvm::Type *type, bool known_integer_sign) const\n{\n\tif (!options.arithmetic_relaxed_precision)\n\t\treturn false;\n\n\tif (type->getTypeID() == llvm::Type::TypeID::ArrayTyID)\n\t\ttype = llvm::cast<llvm::ArrayType>(type)->getArrayElementType();\n\tif (type->getTypeID() == llvm::Type::TypeID::VectorTyID)\n\t\ttype = llvm::cast<llvm::VectorType>(type)->getElementType();\n\n\treturn (!execution_mode_meta.native_16bit_operations && !options.min_precision_prefer_native_16bit) &&\n\t       (type->getTypeID() == llvm::Type::TypeID::HalfTyID ||\n\t        (type->getTypeID() == llvm::Type::TypeID::IntegerTyID && type->getIntegerBitWidth() == 16 &&\n\t         known_integer_sign));\n}\n\nvoid Converter::Impl::decorate_relaxed_precision(const llvm::Type *type, spv::Id id, bool known_integer_sign)\n{\n\t// Ignore RelaxedPrecision for integers since they are untyped in LLVM for the most part.\n\t// For texture loading operations and similar, we load in the appropriate sign, so it's safe to use RelaxedPrecision,\n\t// since RelaxedPrecision may sign-extend based on the OpTypeInt's signage.\n\t// DXIL is kinda broken in this regard since min16int and min16uint lower to the same i16 type ... :(\n\tif (type_can_relax_precision(type, known_integer_sign))\n\t\tbuilder().addDecoration(id, spv::DecorationRelaxedPrecision);\n}\n\nvoid Converter::Impl::set_option(const OptionBase &cap)\n{\n\tswitch (cap.type)\n\t{\n\tcase Option::ShaderDemoteToHelper:\n\t\toptions.shader_demote = static_cast<const OptionShaderDemoteToHelper &>(cap).supported;\n\t\tbreak;\n\n\tcase Option::DualSourceBlending:\n\t\toptions.dual_source_blending = static_cast<const OptionDualSourceBlending &>(cap).enabled;\n\t\tbreak;\n\n\tcase Option::OutputSwizzle:\n\t{\n\t\tauto &swiz = static_cast<const OptionOutputSwizzle &>(cap);\n\t\toptions.output_swizzles.clear();\n\t\toptions.output_swizzles.insert(options.output_swizzles.end(), swiz.swizzles,\n\t\t                               swiz.swizzles + swiz.swizzle_count);\n\t\tbreak;\n\t}\n\n\tcase Option::RasterizerSampleCount:\n\t{\n\t\tauto &count = static_cast<const OptionRasterizerSampleCount &>(cap);\n\t\toptions.rasterizer_sample_count = count.count;\n\t\toptions.rasterizer_sample_count_spec_constant = count.spec_constant;\n\t\tbreak;\n\t}\n\n\tcase Option::RootConstantInlineUniformBlock:\n\t{\n\t\tauto &ubo = static_cast<const OptionRootConstantInlineUniformBlock &>(cap);\n\t\toptions.inline_ubo_descriptor_set = ubo.desc_set;\n\t\toptions.inline_ubo_descriptor_binding = ubo.binding;\n\t\toptions.inline_ubo_enable = ubo.enable;\n\t\tbreak;\n\t}\n\n\tcase Option::BindlessCBVSSBOEmulation:\n\t{\n\t\tauto &bindless = static_cast<const OptionBindlessCBVSSBOEmulation &>(cap);\n\t\toptions.bindless_cbv_ssbo_emulation = bindless.enable;\n\t\tbreak;\n\t}\n\n\tcase Option::PhysicalStorageBuffer:\n\t{\n\t\tauto &psb = static_cast<const OptionPhysicalStorageBuffer &>(cap);\n\t\toptions.physical_storage_buffer = psb.enable;\n\t\tbreak;\n\t}\n\n\tcase Option::SBTDescriptorSizeLog2:\n\t{\n\t\tauto &sbt = static_cast<const OptionSBTDescriptorSizeLog2 &>(cap);\n\t\toptions.sbt_descriptor_size_srv_uav_cbv_log2 = sbt.size_log2_srv_uav_cbv;\n\t\toptions.sbt_descriptor_size_sampler_log2 = sbt.size_log2_sampler;\n\t\tbreak;\n\t}\n\n\tcase Option::SSBOAlignment:\n\t{\n\t\tauto &align = static_cast<const OptionSSBOAlignment &>(cap);\n\t\toptions.ssbo_alignment = align.alignment;\n\t\tbreak;\n\t}\n\n\tcase Option::TypedUAVReadWithoutFormat:\n\t{\n\t\tauto &uav = static_cast<const OptionTypedUAVReadWithoutFormat &>(cap);\n\t\toptions.typed_uav_read_without_format = uav.supported;\n\t\tbreak;\n\t}\n\n\tcase Option::ShaderSourceFile:\n\t{\n\t\tauto &file = static_cast<const OptionShaderSourceFile &>(cap);\n\t\tif (!file.name.empty())\n\t\t\toptions.shader_source_file = file.name;\n\t\telse\n\t\t\toptions.shader_source_file.clear();\n\t\tbreak;\n\t}\n\n\tcase Option::BindlessTypedBufferOffsets:\n\t{\n\t\tauto &off = static_cast<const OptionBindlessTypedBufferOffsets &>(cap);\n\t\toptions.bindless_typed_buffer_offsets = off.enable;\n\t\tbreak;\n\t}\n\n\tcase Option::BindlessOffsetBufferLayout:\n\t{\n\t\tauto &off = static_cast<const OptionBindlessOffsetBufferLayout &>(cap);\n\t\toptions.offset_buffer_layout = { off.untyped_offset, off.typed_offset, off.stride };\n\t\tbreak;\n\t}\n\n\tcase Option::StorageInputOutput16:\n\t{\n\t\tauto &storage = static_cast<const OptionStorageInputOutput16 &>(cap);\n\t\toptions.storage_16bit_input_output = storage.supported;\n\t\tbreak;\n\t}\n\n\tcase Option::DescriptorQA:\n\t{\n\t\tauto &qa = static_cast<const OptionDescriptorQA &>(cap);\n\t\toptions.descriptor_qa_enabled = qa.enabled;\n\t\toptions.descriptor_qa.version = qa.version;\n\t\toptions.descriptor_qa.shader_hash = qa.shader_hash;\n\t\toptions.descriptor_qa.global_desc_set = qa.global_desc_set;\n\t\toptions.descriptor_qa.global_binding = qa.global_binding;\n\t\toptions.descriptor_qa.heap_desc_set = qa.heap_desc_set;\n\t\toptions.descriptor_qa.heap_binding = qa.heap_binding;\n\t\tbreak;\n\t}\n\n\tcase Option::MinPrecisionNative16Bit:\n\t{\n\t\tauto &minprec = static_cast<const OptionMinPrecisionNative16Bit &>(cap);\n\t\toptions.min_precision_prefer_native_16bit = minprec.enabled;\n\t\tbreak;\n\t}\n\n\tcase Option::ShaderI8Dot:\n\t\toptions.shader_i8_dot_enabled = static_cast<const OptionShaderI8Dot &>(cap).supported;\n\t\tbreak;\n\n\tcase Option::ShaderRayTracingPrimitiveCulling:\n\t\toptions.ray_tracing_primitive_culling_enabled =\n\t\t    static_cast<const OptionShaderRayTracingPrimitiveCulling &>(cap).supported;\n\t\tbreak;\n\n\tcase Option::InvariantPosition:\n\t\toptions.invariant_position = static_cast<const OptionInvariantPosition &>(cap).enabled;\n\t\tbreak;\n\n\tcase Option::ScalarBlockLayout:\n\t\toptions.scalar_block_layout =\n\t\t    static_cast<const OptionScalarBlockLayout &>(cap).supported;\n\t\toptions.supports_per_component_robustness =\n\t\t    static_cast<const OptionScalarBlockLayout &>(cap).supports_per_component_robustness;\n\t\tbreak;\n\n\tcase Option::BarycentricKHR:\n\t\toptions.khr_barycentrics_enabled = static_cast<const OptionBarycentricKHR &>(cap).supported;\n\t\tbreak;\n\n\tcase Option::RobustPhysicalCBVLoad:\n\t\t// Obsolete option, use normal quirks instead.\n\t\toptions.quirks.robust_physical_cbv = static_cast<const OptionRobustPhysicalCBVLoad &>(cap).enabled;\n\t\tbreak;\n\n\tcase Option::ArithmeticRelaxedPrecision:\n\t\toptions.arithmetic_relaxed_precision = static_cast<const OptionArithmeticRelaxedPrecision &>(cap).enabled;\n\t\tbreak;\n\n\tcase Option::PhysicalAddressDescriptorIndexing:\n\t\toptions.physical_address_descriptor_stride =\n\t\t    static_cast<const OptionPhysicalAddressDescriptorIndexing &>(cap).element_stride;\n\t\toptions.physical_address_descriptor_offset =\n\t\t\tstatic_cast<const OptionPhysicalAddressDescriptorIndexing &>(cap).element_offset;\n\t\tbreak;\n\n\tcase Option::ForceSubgroupSize:\n\t\toptions.force_subgroup_size =\n\t\t\tstatic_cast<const OptionForceSubgroupSize &>(cap).forced_value;\n\t\toptions.force_wave_size_enable =\n\t\t\tstatic_cast<const OptionForceSubgroupSize &>(cap).wave_size_enable;\n\t\tbreak;\n\n\tcase Option::DenormPreserveSupport:\n\t\toptions.supports_float16_denorm_preserve =\n\t\t    static_cast<const OptionDenormPreserveSupport &>(cap).support_float16_denorm_preserve;\n\t\toptions.supports_float64_denorm_preserve =\n\t\t    static_cast<const OptionDenormPreserveSupport &>(cap).support_float64_denorm_preserve;\n\t\tbreak;\n\n\tcase Option::StrictHelperLaneWaveOps:\n\t\toptions.strict_helper_lane_waveops =\n\t\t    static_cast<const OptionStrictHelperLaneWaveOps &>(cap).enable;\n\t\tbreak;\n\n\tcase Option::SubgroupPartitionedNV:\n\t\toptions.nv_subgroup_partition_enabled =\n\t\t    static_cast<const OptionSubgroupPartitionedNV &>(cap).supported;\n\t\tbreak;\n\n\tcase Option::DeadCodeEliminate:\n\t\toptions.eliminate_dead_code =\n\t\t\tstatic_cast<const OptionDeadCodeEliminate &>(cap).enabled;\n\t\tbreak;\n\n\tcase Option::PreciseControl:\n\t\toptions.propagate_precise =\n\t\t    static_cast<const OptionPreciseControl &>(cap).propagate_precise;\n\t\toptions.force_precise =\n\t\t    static_cast<const OptionPreciseControl &>(cap).force_precise;\n\t\tbreak;\n\n\tcase Option::SampleGradOptimizationControl:\n\t\toptions.grad_opt.enabled =\n\t\t    static_cast<const OptionSampleGradOptimizationControl &>(cap).enabled;\n\t\toptions.grad_opt.assume_uniform_scale =\n\t\t\tstatic_cast<const OptionSampleGradOptimizationControl &>(cap).assume_uniform_scale;\n\t\tbreak;\n\n\tcase Option::OpacityMicromap:\n\t\toptions.opacity_micromap_enabled =\n\t\t    static_cast<const OptionOpacityMicromap &>(cap).enabled;\n\t\tbreak;\n\n\tcase Option::BranchControl:\n\t{\n\t\tauto &c = static_cast<const OptionBranchControl &>(cap);\n\t\toptions.branch_control.use_shader_metadata = c.use_shader_metadata;\n\t\toptions.branch_control.force_branch = c.force_branch;\n\t\toptions.branch_control.force_unroll = c.force_unroll;\n\t\toptions.branch_control.force_loop = c.force_loop;\n\t\toptions.branch_control.force_flatten = c.force_flatten;\n\t\tbreak;\n\t}\n\n\tcase Option::SubgroupProperties:\n\t{\n\t\tauto &c = static_cast<const OptionSubgroupProperties &>(cap);\n\t\toptions.subgroup_size.implementation_minimum = c.minimum_size;\n\t\toptions.subgroup_size.implementation_maximum = c.maximum_size;\n\t\tbreak;\n\t}\n\n\tcase Option::DescriptorHeapRobustness:\n\t{\n\t\tauto &c = static_cast<const OptionDescriptorHeapRobustness &>(cap);\n\t\toptions.descriptor_heap_robustness = c.enabled;\n\t\tbreak;\n\t}\n\n\tcase Option::ComputeShaderDerivativesNV:\n\t{\n\t\tauto &c = static_cast<const OptionComputeShaderDerivativesNV &>(cap);\n\t\toptions.compute_shader_derivatives = c.supported;\n\t\tbreak;\n\t}\n\n\tcase Option::QuadControlReconvergence:\n\t{\n\t\tauto &c = static_cast<const OptionQuadControlReconvergence &>(cap);\n\t\toptions.supports_quad_control = c.supports_quad_control;\n\t\toptions.supports_maximal_reconvergence = c.supports_maximal_reconvergence;\n\t\toptions.force_maximal_reconvergence = c.force_maximal_reconvergence;\n\t\tbreak;\n\t}\n\n\tcase Option::RawAccessChainsNV:\n\t{\n\t\tauto &c = static_cast<const OptionRawAccessChainsNV &>(cap);\n\t\toptions.nv_raw_access_chains = c.supported;\n\t\tbreak;\n\t}\n\n\tcase Option::DriverVersion:\n\t{\n\t\tauto &c = static_cast<const OptionDriverVersion &>(cap);\n\t\toptions.driver_id = c.driver_id;\n\t\toptions.driver_version = c.driver_version;\n\t\tbreak;\n\t}\n\n\tcase Option::ComputeShaderDerivatives:\n\t{\n\t\tauto &c = static_cast<const OptionComputeShaderDerivatives &>(cap);\n\t\toptions.compute_shader_derivatives = c.supports_nv || c.supports_khr;\n\t\toptions.compute_shader_derivatives_khr = c.supports_khr;\n\t\tbreak;\n\t}\n\n\tcase Option::InstructionInstrumentation:\n\t{\n\t\tauto &qa = static_cast<const OptionInstructionInstrumentation &>(cap);\n\t\toptions.instruction_instrumentation.enabled = qa.enabled;\n\t\toptions.instruction_instrumentation.version = qa.version;\n\t\toptions.instruction_instrumentation.shader_hash = qa.shader_hash;\n\t\toptions.instruction_instrumentation.fp16 = false;\n\t\toptions.instruction_instrumentation.fp32 = true;\n\t\toptions.instruction_instrumentation.fp64 = true;\n\t\toptions.instruction_instrumentation.type = qa.type;\n\t\toptions.instruction_instrumentation.control_desc_set = qa.control_desc_set;\n\t\toptions.instruction_instrumentation.control_binding = qa.control_binding;\n\t\toptions.instruction_instrumentation.payload_desc_set = qa.payload_desc_set;\n\t\toptions.instruction_instrumentation.payload_binding = qa.payload_binding;\n\t\tbreak;\n\t}\n\n\tcase Option::ShaderQuirk:\n\t{\n\t\tauto &quirk = static_cast<const OptionShaderQuirk &>(cap);\n\t\tswitch (quirk.quirk)\n\t\t{\n\t\tcase ShaderQuirk::ForceDeviceMemoryBarriersThreadGroupCoherence:\n\t\t\t// Dragon Age: Veilguard workaround.\n\t\t\toptions.quirks.force_device_memory_barriers_thread_group_coherence = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::AssumeBrokenSub8x8CubeMips:\n\t\t\t// The First Descendant workaround. Importance sampling pass is broken since only mips down to 8x8\n\t\t\t// are populated with valid data.\n\t\t\toptions.quirks.assume_broken_sub_8x8_cube_mips = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::RobustPhysicalCBVForwarding:\n\t\t\t// Gray Zone Warfare workaround. Does CBV forwarding with out of bounds access on the local array <_<.\n\t\t\t// Can trip page faults.\n\t\t\toptions.quirks.robust_physical_cbv_forwarding = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::MeshOutputRobustness:\n\t\t\toptions.quirks.mesh_outputs_bounds_check = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::AggressiveNonUniform:\n\t\t\t// Starfield workaround. Some shaders should have used nonuniform,\n\t\t\t// but the general pattern to detect it is quite complicated.\n\t\t\toptions.quirks.aggressive_nonuniform = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::RobustPhysicalCBV:\n\t\t\toptions.quirks.robust_physical_cbv = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::PromoteGroupToDeviceMemoryBarrier:\n\t\t\toptions.quirks.promote_group_to_device_memory_barrier = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::GroupSharedAutoBarrier:\n\t\t\toptions.quirks.group_shared_auto_barrier = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::FixupLoopHeaderUndefPhis:\n\t\t\toptions.quirks.fixup_loop_header_undef_phis = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::FixupRsqrtInfNan:\n\t\t\toptions.quirks.fixup_rsqrt = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::IgnorePrimitiveShadingRate:\n\t\t\toptions.quirks.ignore_primitive_shading_rate = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::RobustComputeQuadBroadcast:\n\t\t\toptions.quirks.robust_compute_quad_broadcast = true;\n\t\t\tbreak;\n\n\t\tcase ShaderQuirk::PreciseFMA:\n\t\t\toptions.quirks.precise_fma = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase Option::ExtendedRobustness:\n\t{\n\t\tauto &robust = static_cast<const OptionExtendedRobustness &>(cap);\n\t\toptions.extended_robustness.alloca = robust.robust_alloca;\n\t\toptions.extended_robustness.constant_lut = robust.robust_constant_lut;\n\t\toptions.extended_robustness.group_shared = robust.robust_group_shared;\n\t\tbreak;\n\t}\n\n\tcase Option::MaxTessFactor:\n\t{\n\t\tauto &tess_factor = static_cast<const OptionMaxTessFactor &>(cap);\n\t\toptions.max_tess_factor = tess_factor.max_tess_factor;\n\t\tbreak;\n\t}\n\n\tcase Option::VulkanMemoryModel:\n\t{\n\t\tauto &vmm = static_cast<const OptionVulkanMemoryModel &>(cap);\n\t\texecution_mode_meta.memory_model = vmm.enabled ? spv::MemoryModelVulkan : spv::MemoryModelGLSL450;\n\t\tbreak;\n\t}\n\n\tcase Option::Float8Support:\n\t{\n\t\tauto &float8 = static_cast<const OptionFloat8Support &>(cap);\n\t\toptions.wmma_fp8 = float8.wmma_fp8;\n\t\toptions.nv_cooperative_matrix2_conversions = float8.nv_cooperative_matrix2_conversions;\n\t\tbreak;\n\t}\n\n\tcase Option::NvAPI:\n\t{\n\t\tauto &nv = static_cast<const OptionNvAPI &>(cap);\n\t\toptions.nvapi.enabled = nv.enabled;\n\t\toptions.nvapi.register_index = nv.register_index;\n\t\toptions.nvapi.register_space = nv.register_space;\n\t\tbreak;\n\t}\n\n\tcase Option::ExtendedNonSemantic:\n\t{\n\t\tauto &sem = static_cast<const OptionExtendedNonSemantic &>(cap);\n\t\toptions.extended_non_semantic_info = sem.enabled;\n\t\tbreak;\n\t}\n\n\tcase Option::ViewInstancing:\n\t{\n\t\tauto &inst = static_cast<const OptionViewInstancing &>(cap);\n\t\toptions.multiview.enable = inst.enabled;\n\t\toptions.multiview.last_pre_rasterization_stage = inst.last_pre_rasterization_stage;\n\t\toptions.multiview.view_index_to_view_instance_spec_id = inst.view_index_to_view_instance_spec_id;\n\t\toptions.multiview.view_instance_to_viewport_spec_id = inst.view_instance_to_viewport_spec_id;\n\t\tbreak;\n\t}\n\n\tcase Option::MixedDotProduct:\n\t{\n\t\tauto &dot = static_cast<const OptionMixedDotProduct &>(cap);\n\t\toptions.mixed_dot_product_fp16_fp16_fp32 = dot.fp16_fp16_fp32;\n\t\tbreak;\n\t}\n\n\tcase Option::ComputeShaderDerivativesQuad:\n\t{\n\t\tauto &c = static_cast<const OptionComputeShaderDerivativesQuad &>(cap);\n\t\toptions.compute_shader_derivatives_quad = c.supports_quad;\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nvoid Converter::Impl::suggest_maximum_wave_size(unsigned wave_size)\n{\n\tif ((execution_mode_meta.heuristic_max_wave_size == 0 ||\n\t     execution_mode_meta.heuristic_max_wave_size > wave_size) &&\n\t    options.force_subgroup_size == 0)\n\t{\n\t\texecution_mode_meta.heuristic_max_wave_size = wave_size;\n\t}\n}\n\nvoid Converter::Impl::suggest_minimum_wave_size(unsigned wave_size)\n{\n\tif ((execution_mode_meta.heuristic_min_wave_size == 0 ||\n\t     execution_mode_meta.heuristic_min_wave_size < wave_size) &&\n\t    options.force_subgroup_size == 0)\n\t{\n\t\texecution_mode_meta.heuristic_min_wave_size = wave_size;\n\t}\n}\n\nvoid Converter::set_resource_remapping_interface(ResourceRemappingInterface *iface)\n{\n\timpl->resource_mapping_iface = iface;\n}\n\nvoid Converter::set_meta_descriptor(MetaDescriptor desc, MetaDescriptorKind kind, uint32_t desc_set, uint32_t binding)\n{\n\tif (int(desc) >= int(MetaDescriptor::Count))\n\t\treturn;\n\timpl->options.meta_descriptor_mappings[int(desc)] = { kind, desc_set, binding };\n}\n\nShaderStage Converter::get_shader_stage(const LLVMBCParser &bitcode_parser, const char *entry)\n{\n\tauto &module = bitcode_parser.get_module();\n\treturn Impl::get_remapping_stage(get_execution_model(module, get_entry_point_meta(module, entry)));\n}\n\nvoid Converter::scan_resources(ResourceRemappingInterface *iface, const LLVMBCParser &bitcode_parser)\n{\n\tImpl::scan_resources(iface, bitcode_parser);\n}\n\nvoid Converter::add_option(const OptionBase &cap)\n{\n\timpl->set_option(cap);\n}\n\nbool Converter::recognizes_option(Option cap)\n{\n\treturn unsigned(cap) < unsigned(Option::Count);\n}\n\nvoid Converter::set_entry_point(const char *entry)\n{\n\timpl->options.entry_point = entry;\n}\n\nvoid Converter::add_root_parameter_mapping(uint32_t root_parameter_index, uint32_t offset)\n{\n\timpl->root_parameter_mappings.push_back({ root_parameter_index, offset });\n}\n\nuint32_t Converter::pack_desc_set_binding_to_virtual_offset(uint32_t desc_set, uint32_t binding)\n{\n    return 0x80000000u | (desc_set << 24) | binding;\n}\n\nvoid Converter::add_non_semantic_debug_info(const NonSemanticDebugInfo &info)\n{\n\timpl->non_semantic_debug_info.push_back(info);\n}\n\nconst String &Converter::get_compiled_entry_point() const\n{\n\treturn impl->execution_mode_meta.entry_point_name;\n}\n\nconst GlobalConfiguration &GlobalConfiguration::get()\n{\n\tstatic GlobalConfiguration config;\n\treturn config;\n}\n\nGlobalConfiguration::GlobalConfiguration()\n{\n\tconst char *env = getenv(\"DXIL_SPIRV_CONFIG\");\n\tif (env)\n\t{\n\t\tif (strcmp(env, \"wmma_rdna3_workaround\") == 0)\n\t\t\twmma_rdna3_workaround = true;\n\t\telse if (strcmp(env, \"wmma_conv_hack\") == 0)\n\t\t\twmma_conv_hack = true;\n\t}\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "dxil_converter.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"cfg_structurizer.hpp\"\n#include \"dxil_parser.hpp\"\n#include \"llvm_bitcode_parser.hpp\"\n#include \"node_pool.hpp\"\n#include \"spirv_module.hpp\"\n#include <memory>\n\nnamespace spv\n{\nclass Function;\n}\n\nnamespace dxil_spv\n{\nstruct ConvertedFunction\n{\n\tstruct Function\n\t{\n\t\tCFGNode *entry;\n\t\tspv::Function *func;\n\t\tbool is_structured;\n\t};\n\tFunction entry = {};\n\tVector<Function> leaf_functions;\n\tstd::unique_ptr<CFGNodePool> node_pool;\n};\n\nenum class ShaderStage : unsigned\n{\n\tUnknown = 0,\n\tVertex = 1,\n\tHull = 2,\n\tDomain = 3,\n\tGeometry = 4,\n\tPixel = 5,\n\tCompute = 6,\n\tIntersection = 7,\n\tClosestHit = 8,\n\tMiss = 9,\n\tAnyHit = 10,\n\tRayGeneration = 11,\n\tCallable = 12,\n\tAmplification = 13,\n\tMesh = 14,\n};\n\nstruct D3DBinding\n{\n\tShaderStage stage;\n\tDXIL::ResourceKind kind;\n\n\t// The index in which the resource was declared in the module.\n\t// Range is [0, N), where N is number of resources.\n\tunsigned resource_index;\n\n\t// : register(N, spaceM)\n\t// If register(UINT32_MAX, UINT32_MAX) with range_size = UINT32_MAX is used, this is treated\n\t// as a binding of the global descriptor heap.\n\tunsigned register_space;\n\tunsigned register_index;\n\n\t// -1 -> unsized, 1 means non-arrayed resource.\n\tunsigned range_size;\n\n\t// For raw buffers, this is equal to 16, for structured buffers this is equal to the stride of the elements.\n\t// Otherwise, 0.\n\tunsigned alignment;\n};\n\nenum class VulkanDescriptorType : unsigned\n{\n\tIdentity = 0,\n\tSSBO = 1,\n\tTexelBuffer = 2,\n\tBufferDeviceAddress = 3,\n\tUBO = 4,\n\tInputAttachment = 5\n};\n\nstruct VulkanBinding\n{\n\tunsigned descriptor_set;\n\tunsigned binding;\n\n\t// For bindless, refers to the Nth root constant.\n\t// For buffer device address, refers to the Nth root descriptor.\n\tunion\n\t{\n\t\tunsigned root_constant_index;\n\t\tunsigned input_attachment_index;\n\t};\n\n\tstruct\n\t{\n\t\tunsigned heap_root_offset;\n\n\t\t// If true, the resource is accessed directly from a descriptor heap in way which emulates D3D12 closely.\n\t\t// layout(set = descriptor_set, binding = binding) uniform Type HEAP[];\n\t\t// HEAP[shader_index + heap_offset + registers.u32s[push_constant_member]].\n\t\tbool use_heap;\n\t} bindless;\n\n\tVulkanDescriptorType descriptor_type;\n};\n\nstruct D3DUAVBinding\n{\n\tD3DBinding binding;\n\tbool counter;\n};\n\nstruct VulkanSRVBinding\n{\n\tVulkanBinding buffer_binding;\n\tVulkanBinding offset_binding;\n};\n\nstruct VulkanUAVBinding\n{\n\tVulkanBinding buffer_binding;\n\tVulkanBinding counter_binding;\n\tVulkanBinding offset_binding;\n};\n\nstruct VulkanPushConstantBinding\n{\n\tunsigned offset_in_words;\n};\n\nstruct VulkanCBVBinding\n{\n\tunion\n\t{\n\t\tVulkanBinding buffer;\n\t\tVulkanPushConstantBinding push;\n\t};\n\n\t// Select if the CBV should fetch constants from push constants, or regular UBO.\n\tbool push_constant;\n};\n\nstruct D3DStageIO\n{\n\tconst char *semantic;\n\tunsigned semantic_index;\n\tunsigned start_row;\n\tunsigned rows;\n};\n\nenum VulkanStageIoFlagBits\n{\n\tSTAGE_IO_NONE = 0u,\n\tSTAGE_IO_PER_PRIMITIVE = 0x1u,\n};\n\nusing VulkanStageIoFlags = unsigned;\n\nstruct VulkanStageIO\n{\n\tunsigned location;\n\tunsigned component;\n\tVulkanStageIoFlags flags;\n};\n\nstruct D3DStreamOutput\n{\n\tconst char *semantic;\n\tunsigned semantic_index;\n};\n\nstruct VulkanStreamOutput\n{\n\tunsigned offset;\n\tunsigned stride;\n\tunsigned buffer_index;\n\tbool enable;\n};\n\nclass ResourceRemappingInterface\n{\npublic:\n\tvirtual ~ResourceRemappingInterface() = default;\n\tvirtual bool remap_srv(const D3DBinding &d3d_binding, VulkanSRVBinding &vulkan_binding) = 0;\n\tvirtual bool remap_sampler(const D3DBinding &d3d_binding, VulkanBinding &vulkan_binding) = 0;\n\tvirtual bool remap_uav(const D3DUAVBinding &d3d_binding, VulkanUAVBinding &vulkan_binding) = 0;\n\tvirtual bool remap_cbv(const D3DBinding &d3d_binding, VulkanCBVBinding &vulkan_binding) = 0;\n\tvirtual bool remap_vertex_input(const D3DStageIO &d3d_input, VulkanStageIO &vulkan_location) = 0;\n\tvirtual bool remap_stream_output(const D3DStreamOutput &d3d_output, VulkanStreamOutput &vulkan_output) = 0;\n\tvirtual bool remap_stage_input(const D3DStageIO &d3d_input, VulkanStageIO &vk_input) = 0;\n\tvirtual bool remap_stage_output(const D3DStageIO &d3d_output, VulkanStageIO &vk_output) = 0;\n\tvirtual unsigned get_root_constant_word_count() = 0;\n\tvirtual unsigned get_root_descriptor_count() = 0;\n\tvirtual bool has_nontrivial_stage_input_remapping() = 0;\n};\n\nenum class Option : uint32_t\n{\n\tInvalid = 0,\n\tShaderDemoteToHelper = 1,\n\tDualSourceBlending = 2,\n\tOutputSwizzle = 3,\n\tRasterizerSampleCount = 4,\n\tRootConstantInlineUniformBlock = 5,\n\tBindlessCBVSSBOEmulation = 6,\n\tPhysicalStorageBuffer = 7,\n\tSBTDescriptorSizeLog2 = 8,\n\tSSBOAlignment = 9,\n\tTypedUAVReadWithoutFormat = 10,\n\tShaderSourceFile = 11,\n\tBindlessTypedBufferOffsets = 12,\n\tBindlessOffsetBufferLayout = 13,\n\tStorageInputOutput16 = 14,\n\tDescriptorQA = 15,\n\tMinPrecisionNative16Bit = 16,\n\tShaderI8Dot = 17,\n\tShaderRayTracingPrimitiveCulling = 18,\n\tInvariantPosition = 19,\n\tScalarBlockLayout = 20,\n\tBarycentricKHR = 21,\n\tRobustPhysicalCBVLoad = 22,\n\tArithmeticRelaxedPrecision = 23,\n\tPhysicalAddressDescriptorIndexing = 24,\n\tForceSubgroupSize = 25,\n\tDenormPreserveSupport = 26,\n\tStrictHelperLaneWaveOps = 27,\n\tSubgroupPartitionedNV = 28,\n\tDeadCodeEliminate = 29,\n\tPreciseControl = 30,\n\tSampleGradOptimizationControl = 31,\n\tOpacityMicromap = 32,\n\tBranchControl = 33,\n\tSubgroupProperties = 34,\n\tDescriptorHeapRobustness = 35,\n\tComputeShaderDerivativesNV = 36,\n\tQuadControlReconvergence = 37,\n\tRawAccessChainsNV = 38,\n\tDriverVersion = 39,\n\tComputeShaderDerivatives = 40,\n\tInstructionInstrumentation = 41,\n\tShaderQuirk = 42,\n\tExtendedRobustness = 43,\n\tMaxTessFactor = 44,\n\tVulkanMemoryModel = 45,\n\tFloat8Support = 46,\n\tNvAPI = 47,\n\tExtendedNonSemantic = 48,\n\tViewInstancing = 49,\n\tMixedDotProduct = 50,\n\tComputeShaderDerivativesQuad = 51,\n\tCount\n};\n\nenum class ResourceClass : uint32_t\n{\n\tSRV = 0,\n\tUAV = 1,\n\tCBV = 2,\n\tSampler = 3\n};\n\nstruct OptionBase\n{\n\texplicit OptionBase(Option cap)\n\t    : type(cap)\n\t{\n\t}\n\n\tOption type;\n\tDXIL_SPV_OVERRIDE_NEW_DELETE\n};\n\nstruct OptionShaderDemoteToHelper : OptionBase\n{\n\tOptionShaderDemoteToHelper()\n\t    : OptionBase(Option::ShaderDemoteToHelper)\n\t{\n\t}\n\tbool supported = false;\n};\n\nstruct OptionDualSourceBlending : OptionBase\n{\n\tOptionDualSourceBlending()\n\t    : OptionBase(Option::DualSourceBlending)\n\t{\n\t}\n\tbool enabled = false;\n};\n\nstruct OptionOutputSwizzle : OptionBase\n{\n\tOptionOutputSwizzle()\n\t    : OptionBase(Option::OutputSwizzle)\n\t{\n\t}\n\tconst unsigned *swizzles = nullptr;\n\tunsigned swizzle_count = 0;\n};\n\nstruct OptionRasterizerSampleCount : OptionBase\n{\n\tOptionRasterizerSampleCount()\n\t    : OptionBase(Option::RasterizerSampleCount)\n\t{\n\t}\n\tunsigned count = 0;\n\tbool spec_constant = false;\n};\n\nstruct OptionRootConstantInlineUniformBlock : OptionBase\n{\n\tOptionRootConstantInlineUniformBlock()\n\t    : OptionBase(Option::RootConstantInlineUniformBlock)\n\t{\n\t}\n\tunsigned desc_set = 0;\n\tunsigned binding = 0;\n\tbool enable = false;\n};\n\nstruct OptionBindlessCBVSSBOEmulation : OptionBase\n{\n\tOptionBindlessCBVSSBOEmulation()\n\t    : OptionBase(Option::BindlessCBVSSBOEmulation)\n\t{\n\t}\n\tbool enable = false;\n};\n\nstruct OptionPhysicalStorageBuffer : OptionBase\n{\n\tOptionPhysicalStorageBuffer()\n\t    : OptionBase(Option::PhysicalStorageBuffer)\n\t{\n\t}\n\tbool enable = false;\n};\n\nstruct OptionSBTDescriptorSizeLog2 : OptionBase\n{\n\tOptionSBTDescriptorSizeLog2()\n\t\t: OptionBase(Option::SBTDescriptorSizeLog2)\n\t{\n\t}\n\tunsigned size_log2_srv_uav_cbv = 0;\n\tunsigned size_log2_sampler = 0;\n};\n\nstruct OptionSSBOAlignment : OptionBase\n{\n\tOptionSSBOAlignment()\n\t\t: OptionBase(Option::SSBOAlignment)\n\t{\n\t}\n\tunsigned alignment = 1;\n};\n\nstruct OptionTypedUAVReadWithoutFormat : OptionBase\n{\n\tOptionTypedUAVReadWithoutFormat()\n\t\t: OptionBase(Option::TypedUAVReadWithoutFormat)\n\t{\n\t}\n\tbool supported = false;\n};\n\nstruct OptionShaderSourceFile : OptionBase\n{\n\tOptionShaderSourceFile()\n\t\t: OptionBase(Option::ShaderSourceFile)\n\t{\n\t}\n\tString name;\n};\n\nstruct OptionBindlessTypedBufferOffsets : OptionBase\n{\n\tOptionBindlessTypedBufferOffsets()\n\t\t: OptionBase(Option::BindlessTypedBufferOffsets)\n\t{\n\t}\n\tbool enable = false;\n};\n\nstruct OptionBindlessOffsetBufferLayout : OptionBase\n{\n\tOptionBindlessOffsetBufferLayout()\n\t\t: OptionBase(Option::BindlessOffsetBufferLayout)\n\t{\n\t}\n\n\tunsigned untyped_offset = 0;\n\tunsigned typed_offset = 0;\n\tunsigned stride = 1;\n};\n\nstruct OptionStorageInputOutput16 : OptionBase\n{\n\tOptionStorageInputOutput16()\n\t\t: OptionBase(Option::StorageInputOutput16)\n\t{\n\t}\n\n\tbool supported = true;\n};\n\nstruct OptionDescriptorQA : OptionBase\n{\n\tOptionDescriptorQA()\n\t\t: OptionBase(Option::DescriptorQA)\n\t{\n\t}\n\n\tenum { DefaultVersion = 1 };\n\n\tbool enabled = false;\n\tuint32_t version = DefaultVersion;\n\tuint32_t global_desc_set = 0;\n\tuint32_t global_binding = 0;\n\tuint32_t heap_desc_set = 0;\n\tuint32_t heap_binding = 0;\n\tuint64_t shader_hash = 0;\n};\n\nstruct OptionMinPrecisionNative16Bit : OptionBase\n{\n\tOptionMinPrecisionNative16Bit()\n\t\t: OptionBase(Option::MinPrecisionNative16Bit)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionShaderI8Dot : OptionBase\n{\n\tOptionShaderI8Dot()\n\t\t: OptionBase(Option::ShaderI8Dot)\n\t{\n\t}\n\n\tbool supported = false;\n};\n\nstruct OptionShaderRayTracingPrimitiveCulling : OptionBase\n{\n\tOptionShaderRayTracingPrimitiveCulling()\n\t\t: OptionBase(Option::ShaderRayTracingPrimitiveCulling)\n\t{\n\t}\n\n\tbool supported = false;\n};\n\nstruct OptionInvariantPosition : OptionBase\n{\n\tOptionInvariantPosition()\n\t\t: OptionBase(Option::InvariantPosition)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionScalarBlockLayout : OptionBase\n{\n\tOptionScalarBlockLayout()\n\t\t: OptionBase(Option::ScalarBlockLayout)\n\t{\n\t}\n\n\tbool supported = false;\n\tbool supports_per_component_robustness = false;\n};\n\nstruct OptionBarycentricKHR : OptionBase\n{\n\tOptionBarycentricKHR()\n\t\t: OptionBase(Option::BarycentricKHR)\n\t{\n\t}\n\n\tbool supported = false;\n};\n\nstruct OptionRobustPhysicalCBVLoad : OptionBase\n{\n\tOptionRobustPhysicalCBVLoad()\n\t\t: OptionBase(Option::RobustPhysicalCBVLoad)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionArithmeticRelaxedPrecision : OptionBase\n{\n\tOptionArithmeticRelaxedPrecision()\n\t\t: OptionBase(Option::ArithmeticRelaxedPrecision)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionPhysicalAddressDescriptorIndexing : OptionBase\n{\n\tOptionPhysicalAddressDescriptorIndexing()\n\t    : OptionBase(Option::PhysicalAddressDescriptorIndexing)\n\t{\n\t}\n\n\t// In units of uint64_t addresses.\n\t// Used for scenarios where a descriptor buffer is bound directly as an SSBO\n\t// and raw VAs might not longer be tightly packed in memory.\n\tunsigned element_stride = 1;\n\tunsigned element_offset = 0;\n};\n\nstruct OptionForceSubgroupSize : OptionBase\n{\n\tOptionForceSubgroupSize()\n\t    : OptionBase(Option::ForceSubgroupSize)\n\t{\n\t}\n\n\t// If not 0, forces WaveGetLaneCount() to return a fixed value.\n\t// Can be used to force a shader to avoid buggy code paths.\n\tunsigned forced_value = 0;\n\t// If true and forced_value is not 0,\n\t// pretends that the shader exposes SM 6.6 WaveSize equal to forced_value.\n\t// Intended use case:\n\t// - false: Workaround and avoid bad subgroup code paths by setting forced_value to something meaningless.\n\t// - true: Performance tweaks. Force e.g. wave32 vs wave64 on RDNA.\n\tbool wave_size_enable = false;\n};\n\nstruct OptionDenormPreserveSupport : OptionBase\n{\n\tOptionDenormPreserveSupport()\n\t\t: OptionBase(Option::DenormPreserveSupport)\n\t{\n\t}\n\n\t// Should always be set to true if supported.\n\t// If not supported, rely on implementation to default to the right thing.\n\tbool support_float16_denorm_preserve = false;\n\tbool support_float64_denorm_preserve = false;\n};\n\nstruct OptionStrictHelperLaneWaveOps : OptionBase\n{\n\tOptionStrictHelperLaneWaveOps()\n\t    : OptionBase(Option::StrictHelperLaneWaveOps)\n\t{\n\t}\n\n\t// If true, and WaveOpsIncludeHelperLanes is not set,\n\t// helper lanes explicitly do not participate in wave ops.\n\tbool enable = true;\n};\n\nstruct OptionSubgroupPartitionedNV : OptionBase\n{\n\tOptionSubgroupPartitionedNV()\n\t\t: OptionBase(Option::SubgroupPartitionedNV)\n\t{\n\t}\n\n\tbool supported = false;\n};\n\nstruct OptionDeadCodeEliminate : OptionBase\n{\n\tOptionDeadCodeEliminate()\n\t\t: OptionBase(Option::DeadCodeEliminate)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionPreciseControl : OptionBase\n{\n\tOptionPreciseControl()\n\t\t: OptionBase(Option::PreciseControl)\n\t{\n\t}\n\n\tbool force_precise = false;\n\tbool propagate_precise = false;\n};\n\nstruct OptionSampleGradOptimizationControl : OptionBase\n{\n\tOptionSampleGradOptimizationControl()\n\t    : OptionBase(Option::SampleGradOptimizationControl)\n\t{\n\t}\n\n\tbool enabled = false;\n\tbool assume_uniform_scale = false;\n};\n\nstruct OptionOpacityMicromap : OptionBase\n{\n\tOptionOpacityMicromap()\n\t\t: OptionBase(Option::OpacityMicromap)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionBranchControl : OptionBase\n{\n\tOptionBranchControl()\n\t\t: OptionBase(Option::BranchControl)\n\t{\n\t}\n\n\tbool use_shader_metadata = false;\n\tbool force_unroll = false;\n\tbool force_loop = false;\n\tbool force_flatten = false;\n\tbool force_branch = false;\n};\n\nstruct OptionSubgroupProperties : OptionBase\n{\n\tOptionSubgroupProperties()\n\t\t: OptionBase(Option::SubgroupProperties)\n\t{\n\t}\n\n\tunsigned minimum_size = 4;\n\tunsigned maximum_size = 128;\n};\n\nstruct OptionDescriptorHeapRobustness : OptionBase\n{\n\tOptionDescriptorHeapRobustness()\n\t\t: OptionBase(Option::DescriptorHeapRobustness)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionComputeShaderDerivativesNV : OptionBase\n{\n\tOptionComputeShaderDerivativesNV()\n\t\t: OptionBase(Option::ComputeShaderDerivativesNV)\n\t{\n\t}\n\n\t// Before adding this option, we assumed that by default.\n\tbool supported = true;\n};\n\nstruct OptionQuadControlReconvergence : OptionBase\n{\n\tOptionQuadControlReconvergence()\n\t\t: OptionBase(Option::QuadControlReconvergence)\n\t{\n\t}\n\n\tbool supports_quad_control = false;\n\tbool supports_maximal_reconvergence = false;\n\tbool force_maximal_reconvergence = false;\n};\n\nstruct OptionRawAccessChainsNV : OptionBase\n{\n\tOptionRawAccessChainsNV()\n\t\t: OptionBase(Option::RawAccessChainsNV)\n\t{\n\t}\n\n\tbool supported = false;\n};\n\nstruct OptionDriverVersion : OptionBase\n{\n\tOptionDriverVersion()\n\t\t: OptionBase(Option::DriverVersion)\n\t{\n\t}\n\n\tuint32_t driver_id = 0; // Vulkan12Properties::driverID\n\tuint32_t driver_version = 0; // PhysicalDeviceProperties::driverVersion\n};\n\nstruct OptionComputeShaderDerivatives : OptionBase\n{\n\tOptionComputeShaderDerivatives()\n\t\t: OptionBase(Option::ComputeShaderDerivatives)\n\t{\n\t}\n\n\tbool supports_nv = false;\n\tbool supports_khr = false;\n};\n\nstruct OptionInstructionInstrumentation : OptionBase\n{\n\tOptionInstructionInstrumentation()\n\t    : OptionBase(Option::InstructionInstrumentation)\n\t{\n\t}\n\n\tenum { DefaultVersion = 1 };\n\n\tbool enabled = false;\n\tuint32_t version = DefaultVersion;\n\tuint32_t control_desc_set = 0;\n\tuint32_t control_binding = 0;\n\tuint32_t payload_desc_set = 0;\n\tuint32_t payload_binding = 0;\n\tuint64_t shader_hash = 0;\n\tInstructionInstrumentationType type = {};\n};\n\nenum class ShaderQuirk : uint32_t\n{\n\tNone = 0,\n\tForceDeviceMemoryBarriersThreadGroupCoherence,\n\tAssumeBrokenSub8x8CubeMips,\n\tRobustPhysicalCBVForwarding,\n\tMeshOutputRobustness,\n\tAggressiveNonUniform,\n\tRobustPhysicalCBV,\n\tPromoteGroupToDeviceMemoryBarrier,\n\tGroupSharedAutoBarrier,\n\tFixupLoopHeaderUndefPhis,\n\tFixupRsqrtInfNan,\n\tIgnorePrimitiveShadingRate,\n\tRobustComputeQuadBroadcast,\n\tPreciseFMA\n};\n\nstruct OptionShaderQuirk : OptionBase\n{\n\tOptionShaderQuirk()\n\t    : OptionBase(Option::ShaderQuirk)\n\t{\n\t}\n\n\tShaderQuirk quirk = ShaderQuirk::None;\n};\n\nstruct OptionExtendedRobustness : OptionBase\n{\n\tOptionExtendedRobustness()\n\t\t: OptionBase(Option::ExtendedRobustness)\n\t{\n\t}\n\n\tbool robust_group_shared = false;\n\tbool robust_alloca = false;\n\tbool robust_constant_lut = false;\n};\n\nstruct OptionMaxTessFactor : OptionBase\n{\n\tOptionMaxTessFactor()\n\t\t: OptionBase(Option::MaxTessFactor)\n\t{\n\t}\n\n\tunsigned max_tess_factor = 0;\n};\n\nstruct OptionVulkanMemoryModel : OptionBase\n{\n\tOptionVulkanMemoryModel()\n\t    : OptionBase(Option::VulkanMemoryModel)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionFloat8Support : OptionBase\n{\n\tOptionFloat8Support()\n\t    : OptionBase(Option::Float8Support)\n\t{\n\t}\n\n\tbool wmma_fp8 = false;\n\tbool nv_cooperative_matrix2_conversions = false;\n};\n\nstruct OptionNvAPI : OptionBase\n{\n\tOptionNvAPI()\n\t\t: OptionBase(Option::NvAPI)\n\t{\n\t}\n\n\tbool enabled = false;\n\tunsigned register_index = 0;\n\tunsigned register_space = 0;\n};\n\nstruct OptionExtendedNonSemantic : OptionBase\n{\n\tOptionExtendedNonSemantic()\n\t\t: OptionBase(Option::ExtendedNonSemantic)\n\t{\n\t}\n\n\tbool enabled = false;\n};\n\nstruct OptionViewInstancing : OptionBase\n{\n\tOptionViewInstancing()\n\t\t: OptionBase(Option::ViewInstancing)\n\t{\n\t}\n\n\tbool enabled = false;\n\tbool implicit_viewport_offset = false;\n\tbool last_pre_rasterization_stage = false;\n\tuint32_t view_index_to_view_instance_spec_id = UINT32_MAX;\n\tuint32_t view_instance_to_viewport_spec_id = UINT32_MAX;\n};\n\nstruct OptionMixedDotProduct : OptionBase\n{\n\tOptionMixedDotProduct()\n\t\t: OptionBase(Option::MixedDotProduct)\n\t{\n\t}\n\n\tbool fp16_fp16_fp32 = false;\n};\n\nstruct OptionComputeShaderDerivativesQuad : OptionBase\n{\n\tOptionComputeShaderDerivativesQuad()\n\t\t: OptionBase(Option::ComputeShaderDerivativesQuad)\n\t{\n\t}\n\n\tbool supports_quad = false;\n};\n\nstruct DescriptorTableEntry\n{\n\tResourceClass type;\n\tuint32_t register_space;\n\tuint32_t register_index;\n\tuint32_t num_descriptors_in_range;\n\tuint32_t offset_in_heap;\n};\n\nstruct NodeDispatchGrid\n{\n\tuint32_t offset;\n\tDXIL::ComponentType component_type;\n\tuint32_t count;\n};\n\nstruct NodeInputData\n{\n\tString node_id;\n\tuint32_t payload_stride;\n\tDXIL::NodeLaunchType launch_type;\n\tuint32_t node_array_index;\n\tNodeDispatchGrid grid_buffer;\n\tuint32_t broadcast_grid[3];\n\tuint32_t thread_group_size_spec_id[3];\n\tuint32_t max_broadcast_grid_spec_id[3];\n\tuint32_t recursion_factor;\n\tuint32_t coalesce_factor;\n\tString node_share_input_id;\n\tuint32_t node_share_input_array_index;\n\tuint32_t local_root_arguments_table_index;\n\tuint32_t is_indirect_bda_stride_program_entry_spec_id;\n\tuint32_t is_entry_point_spec_id;\n\tuint32_t dispatch_grid_is_upper_bound_spec_id;\n\tuint32_t is_static_broadcast_node_spec_id;\n\tbool dispatch_grid_is_upper_bound;\n\tbool node_track_rw_input_sharing;\n\tbool is_program_entry;\n};\n\nstruct NodeOutputData\n{\n\tString node_id;\n\tuint32_t node_array_index;\n\tuint32_t node_array_size;\n\tuint32_t node_index_spec_constant_id;\n\tuint32_t max_records;\n\tbool sparse_array;\n};\n\nstruct NonSemanticDebugInfo\n{\n\tconst char *tag;\n\tconst void *data;\n\tsize_t size;\n};\n\nenum class ShaderFeature\n{\n\tNative16BitOperations = 0,\n\tCount\n};\n\nenum class MetaDescriptor\n{\n\t// u32 containing number of descriptors in CBV_SRV_UAV heap.\n\t// Must be UBOContainingConstant.\n\tResourceDescriptorHeapSize = 0,\n\t// A BDA pointing to first descriptor payload in resource heap.\n\t// May point to real descriptors, or only UAV counters depending on driver needs.\n\t// Stride / offset of pointer is determined by Option::PhysicalAddressDescriptorIndexing.\n\t// Must be UBOContainingBDA or ReadonlySSBO.\n\tRawDescriptorHeapView = 1,\n\t// - u16 ViewID;\n\t// - u16 LayerOffset;\n\t// Packed into one u32.\n\t// Must be UBOContainingConstant.\n\tDynamicViewInstancingOffsets = 2,\n\t// - u32 ActiveViewIDMask\n\t// Must be UBOContainingConstant.\n\tDynamicViewInstancingMask = 3,\n\tCount\n};\n\nenum class MetaDescriptorKind\n{\n\tInvalid,\n\n\t// Currently unused, could be extended as needed.\n\tPushConstant,\n\tPushBDA,\n\n\t// An UBO containing plain constants.\n\t// May not be backed by a real descriptor, and be hoisted through some special mechanism.\n\tUBOContainingConstant,\n\t// An UBO containing a BDA. May not be backed by a real descriptor.\n\t// May not be backed by a real descriptor, and be hoisted through some special mechanism.\n\tUBOContainingBDA,\n\n\t// An SSBO backed by a real descriptor, i.e. OpArrayLength is valid.\n\tReadonlySSBO\n};\n\nclass Converter\n{\npublic:\n\tConverter(LLVMBCParser &bitcode_parser, LLVMBCParser *bitcode_reflection_parser, SPIRVModule &module);\n\t~Converter();\n\tConvertedFunction convert_entry_point();\n\tvoid set_resource_remapping_interface(ResourceRemappingInterface *iface);\n\n\tstatic ShaderStage get_shader_stage(const LLVMBCParser &bitcode_parser, const char *entry = nullptr);\n\tstatic void scan_resources(ResourceRemappingInterface *iface, const LLVMBCParser &bitcode_parser);\n\n\tstatic Vector<String> get_entry_points(const LLVMBCParser &parser);\n\tstatic bool entry_point_matches(const String &mangled, const char *user);\n\tvoid set_entry_point(const char *entry);\n\tconst String &get_compiled_entry_point() const;\n\n\tvoid add_option(const OptionBase &cap);\n\tstatic bool recognizes_option(Option cap);\n\n\t// These are declared separately since we need to declare a concrete physical buffer layout\n\t// for local root signature elements which depends on the entire local root signature.\n\t// It would get somewhat awkward to shoehorn this into the resource \"pull\" API for normal resources.\n\n\tvoid add_local_root_constants(uint32_t register_space, uint32_t register_index, uint32_t num_words);\n\tvoid add_local_root_descriptor(ResourceClass type, uint32_t register_space, uint32_t register_index);\n\n\t// Local root descriptor tables are special. They must be constructed in such a way that\n\t// the MSB 32 bits can be ignored and the LSB 32 bits are encoded as Index << SBTDescriptorSizeLog2.\n\t// Thus, we translate GPU VA to index by a simple shift on the lower 32-bit value.\n\tvoid add_local_root_descriptor_table(Vector<DescriptorTableEntry> entries);\n\tvoid add_local_root_descriptor_table(const DescriptorTableEntry *entries, size_t count);\n\n\t// For debug purposes. Makes it possible to map a computed push constant offset\n\t// back to corresponding root parameter index.\n\t// Not needed by codegen, but is used by extended debug info.\n\tvoid add_root_parameter_mapping(uint32_t root_parameter_index, uint32_t offset);\n    static uint32_t pack_desc_set_binding_to_virtual_offset(uint32_t desc_set, uint32_t binding);\n\n\t// For debug purposes. Emits arbitrary data with NonSemantic.dxil-spirv.*.\n\t// Pointers are owned by application and must remain valid until compilation is done.\n\tvoid add_non_semantic_debug_info(const NonSemanticDebugInfo &info);\n\n\tvoid set_patch_location_offset(uint32_t offset);\n\n\t// After compilation, query CS workgroup size.\n\tvoid get_workgroup_dimensions(uint32_t &x, uint32_t &y, uint32_t &z) const;\n\t// After compilation, query expected patch size.\n\tuint32_t get_patch_vertex_count() const;\n\tuint32_t get_patch_location_offset() const;\n\t// If any of these are non-zero, a CS may have to be compiled for a specific wave size.\n\tvoid get_compute_wave_size_range(uint32_t &min, uint32_t &max, uint32_t &preferred) const;\n\t// If non-zero, similar to required, but can be ignored. Used as a workaround hint or performance hint.\n\tuint32_t get_compute_heuristic_min_wave_size() const;\n\tuint32_t get_compute_heuristic_max_wave_size() const;\n\n\t// Returns true if view instancing is enabled and the result can be lowered directly to Vulkan.\n\tbool is_multiview_compatible() const;\n\n\tbool shader_requires_feature(ShaderFeature feature) const;\n\n\t// For esoteric CFG workarounds.\n\tbool get_driver_version(uint32_t &driver_id, uint32_t &driver_version) const;\n\n\tstatic NodeInputData get_node_input(const LLVMBCParser &parser, const char *entry);\n\tstatic Vector<NodeOutputData> get_node_outputs(const LLVMBCParser &parser, const char *entry);\n\n\tString get_analysis_warnings() const;\n\n\tvoid set_meta_descriptor(MetaDescriptor desc, MetaDescriptorKind kind,\n\t                         uint32_t desc_set, uint32_t binding_or_push_index);\n\n\tstruct Impl;\n\nprivate:\n\tstd::unique_ptr<Impl> impl;\n};\n} // namespace dxil_spv\n"
  },
  {
    "path": "dxil_extract.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"cli_parser.hpp\"\n#include \"dxil_spirv_c.h\"\n#include \"logging.hpp\"\n#include <stdint.h>\n#include <stdio.h>\n#include <vector>\n\nusing namespace dxil_spv;\n\nstatic void print_help()\n{\n\tLOGE(\"dxil-extract <DXIL blob> [--output file.bc] [--reflection] [--verbose]\\n\");\n}\n\nstatic std::vector<uint8_t> read_file(const char *path)\n{\n\tFILE *file = fopen(path, \"rb\");\n\tif (!file)\n\t\treturn {};\n\n\tfseek(file, 0, SEEK_END);\n\tauto len = ftell(file);\n\trewind(file);\n\tstd::vector<uint8_t> result(len);\n\tif (fread(result.data(), 1, len, file) != size_t(len))\n\t{\n\t\tfclose(file);\n\t\treturn {};\n\t}\n\n\tfclose(file);\n\treturn result;\n}\n\nstatic bool write_file(const char *path, const void *data, size_t size)\n{\n\tbool ret = true;\n\n\tFILE *file = fopen(path, \"wb\");\n\tif (!file)\n\t\treturn false;\n\n\tif (fwrite(data, 1, size, file) != size)\n\t{\n\t\tLOGE(\"Failed to write LLVM BC.\\n\");\n\t\tret = false;\n\t}\n\tfclose(file);\n\treturn ret;\n}\n\nstatic uint64_t vkd3d_proton_hash_fnv1(const void *data_, size_t size)\n{\n\tauto *data = static_cast<const uint8_t *>(data_);\n\tuint64_t h = 0xcbf29ce484222325ull;\n\n\tfor (size_t i = 0; i < size; i++)\n\t\th = (h * 0x100000001b3ull) ^ data[i];\n\n\treturn h;\n}\n\nint main(int argc, char **argv)\n{\n\tstd::string input, output;\n\tbool reflection = false;\n\tbool verbose = false;\n\n\tCLICallbacks cbs;\n\tcbs.add(\"--help\", [](CLIParser &parser) {\n\t\tprint_help();\n\t\tparser.end();\n\t});\n\tcbs.add(\"--output\", [&](CLIParser &parser) { output = parser.next_string(); });\n\tcbs.add(\"--reflection\", [&](CLIParser &) { reflection = true; });\n\tcbs.add(\"--verbose\", [&](CLIParser &) { verbose = true; });\n\tcbs.default_handler = [&](const char *arg) { input = arg; };\n\tCLIParser parser(std::move(cbs), argc - 1, argv + 1);\n\n\tif (!parser.parse())\n\t\treturn EXIT_FAILURE;\n\telse if (parser.is_ended_state())\n\t\treturn EXIT_SUCCESS;\n\n\tif (input.empty())\n\t{\n\t\tLOGE(\"Need input file.\\n\");\n\t\treturn EXIT_FAILURE;\n\t}\n\n\tauto input_file = read_file(input.c_str());\n\tif (input_file.empty())\n\t{\n\t\tLOGE(\"Failed to read file %s.\\n\", input.c_str());\n\t\treturn EXIT_FAILURE;\n\t}\n\n\tdxil_spv_parsed_blob blob;\n\tif (reflection)\n\t{\n\t\tdxil_spv_result result;\n\t\tif ((result = dxil_spv_parse_reflection_dxil_blob(input_file.data(), input_file.size(), &blob)) != DXIL_SPV_SUCCESS)\n\t\t{\n\t\t\t// Fallback in case there is no STAT block.\n\t\t\tif (result == DXIL_SPV_ERROR_NO_DATA)\n\t\t\t{\n\t\t\t\tLOGW(\"There is no STAT block, falling back to normal DXIL block.\\n\");\n\t\t\t\tresult = dxil_spv_parse_dxil_blob(input_file.data(), input_file.size(), &blob);\n\t\t\t}\n\n\t\t\tif (result != DXIL_SPV_SUCCESS)\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to parse blob.\\n\");\n\t\t\t\treturn EXIT_FAILURE;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (dxil_spv_parse_dxil_blob(input_file.data(), input_file.size(), &blob) != DXIL_SPV_SUCCESS)\n\t\t{\n\t\t\tLOGE(\"Failed to parse blob.\\n\");\n\t\t\treturn EXIT_FAILURE;\n\t\t}\n\t}\n\n\tif (verbose)\n\t{\n\t\tprintf(\"=== %s ===\\n\", input.c_str());\n\t\tunsigned entry_point_count = 0;\n\t\tdxil_spv_parsed_blob_get_num_entry_points(blob, &entry_point_count);\n\t\tfor (unsigned i = 0; i < entry_point_count; i++)\n\t\t{\n\t\t\tconst char *demangled = nullptr;\n\t\t\tdxil_spv_parsed_blob_get_entry_point_demangled_name(blob, i, &demangled);\n\t\t\tprintf(\"  %s\\n\", demangled);\n\t\t}\n\t\tprintf(\"vkd3d-proton hash: %016llx\\n\",\n\t\t       static_cast<unsigned long long>(vkd3d_proton_hash_fnv1(input_file.data(), input_file.size())));\n\t\tprintf(\"==================\\n\");\n\t}\n\n\tconst void *ir_data;\n\tsize_t ir_size;\n\n\tif (dxil_spv_parsed_blob_get_raw_ir(blob, &ir_data, &ir_size) != DXIL_SPV_SUCCESS)\n\t{\n\t\tLOGE(\"Failed to extract raw IR.\\n\");\n\t\treturn EXIT_FAILURE;\n\t}\n\n\tif (output.empty())\n\t{\n\t\tdxil_spv_parsed_blob_dump_llvm_ir(blob);\n\t\tdxil_spv_parsed_blob_free(blob);\n\t\treturn EXIT_SUCCESS;\n\t}\n\n\tif (!write_file(output.c_str(), ir_data, ir_size))\n\t{\n\t\tLOGE(\"Failed to write IR to %s.\\n\", output.c_str());\n\t\treturn EXIT_FAILURE;\n\t}\n\tdxil_spv_parsed_blob_free(blob);\n}\n"
  },
  {
    "path": "dxil_parser.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_parser.hpp\"\n#include \"dxil.hpp\"\n#include \"memory_stream.hpp\"\n#include \"logging.hpp\"\n#include <stdio.h>\n#include <string.h>\n#include <vector>\n\nnamespace dxil_spv\n{\nbool is_mangled_entry_point(const char *user)\n{\n\t// The mangling algorithm is intentionally left undefined in spec.\n\t// However, the mangling scheme clearly follows MSVC here.\n\t// The format we're looking for is:\n\t// <blah>?<identifier>@<suffix>.\n\t// http://www.agner.org/optimize/calling_conventions.pdf (section 8.1).\n\t// DXC also seems to start with '\\01', but we can ignore that.\n\tconst char *mangle_begin = strchr(user, '?');\n\tif (!mangle_begin)\n\t\treturn false;\n\n\tconst char *mangle_end = strchr(mangle_begin + 1, '@');\n\treturn mangle_end != nullptr;\n}\n\nString demangle_entry_point(const String &entry)\n{\n\tauto start_idx = entry.find_first_of('?');\n\tif (start_idx == std::string::npos)\n\t\treturn entry;\n\n\tstart_idx++;\n\n\tauto end_idx = entry.find_first_of('@', start_idx);\n\tif (end_idx == std::string::npos)\n\t\treturn entry;\n\n\treturn entry.substr(start_idx, end_idx - start_idx);\n}\n\nVector<uint8_t> &DXILContainerParser::get_blob()\n{\n\treturn dxil_blob;\n}\n\nVector<RDATSubobject> &DXILContainerParser::get_rdat_subobjects()\n{\n\treturn rdat_subobjects;\n}\n\nbool DXILContainerParser::parse_dxil(MemoryStream &stream)\n{\n\tDXIL::ProgramHeader program_header;\n\tif (!stream.read(program_header))\n\t\treturn false;\n\n\tif (static_cast<DXIL::FourCC>(program_header.dxil_magic) != DXIL::FourCC::DXIL)\n\t\treturn false;\n\n\tconstexpr uint32_t DxilMagicPad = sizeof(DXIL::ProgramHeader) - offsetof(DXIL::ProgramHeader, dxil_magic);\n\n\tif (program_header.bitcode_offset < DxilMagicPad)\n\t\treturn false;\n\n\tauto substream = stream.create_substream_bitcode_size(\n\t\tstream.get_offset() + program_header.bitcode_offset - DxilMagicPad,\n\t\tprogram_header.bitcode_size);\n\n\tdxil_blob.resize(substream.get_size());\n\tif (!substream.read(dxil_blob.data(), substream.get_size()))\n\t\treturn false;\n\n\treturn true;\n}\n\nbool DXILContainerParser::parse_iosg1(MemoryStream &stream, Vector<DXIL::IOElement> &elements)\n{\n\tuint32_t element_count;\n\tif (!stream.read(element_count))\n\t\treturn false;\n\n\tif (!stream.skip(sizeof(uint32_t)))\n\t\treturn false;\n\n\telements.resize(element_count);\n\tfor (uint32_t i = 0; i < element_count; i++)\n\t{\n\t\tif (!stream.read(elements[i].stream_index))\n\t\t\treturn false;\n\n\t\tuint32_t string_offset;\n\t\tif (!stream.read(string_offset))\n\t\t\treturn false;\n\n\t\tif (!stream.read(elements[i].semantic_index))\n\t\t\treturn false;\n\t\tif (!stream.read(elements[i].system_value_semantic))\n\t\t\treturn false;\n\t\tif (!stream.read(elements[i].component_type))\n\t\t\treturn false;\n\t\tif (!stream.read(elements[i].register_index))\n\t\t\treturn false;\n\t\tif (!stream.read(elements[i].mask))\n\t\t\treturn false;\n\t\tif (!stream.read(elements[i].min_precision))\n\t\t\treturn false;\n\n\t\tsize_t offset = stream.get_offset();\n\t\tif (!stream.seek(string_offset))\n\t\t\treturn false;\n\n\t\tconst char *semantic_name;\n\t\tif (!stream.map_string_iterate(semantic_name))\n\t\t\treturn false;\n\t\telements[i].semantic_name = semantic_name;\n\t\tif (!stream.seek(offset))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool DXILContainerParser::parse_rdat(MemoryStream &stream)\n{\n\tuint32_t version, part_count;\n\tif (!stream.read(version))\n\t\treturn false;\n\tif (!stream.read(part_count))\n\t\treturn false;\n\n\tconstexpr uint32_t RDAT_Version = 0x10;\n\tif (version != RDAT_Version)\n\t\treturn false;\n\n\tVector<uint32_t> offsets(part_count);\n\tfor (uint32_t i = 0; i < part_count; i++)\n\t\tif (!stream.read(offsets[i]))\n\t\t\treturn false;\n\n\tMemoryStream string_buffer;\n\tMemoryStream index_buffer;\n\tMemoryStream raw_bytes;\n\n\tfor (uint32_t i = 0; i < part_count; i++)\n\t{\n\t\tif (offsets[i] + 2 * sizeof(uint32_t) > stream.get_size())\n\t\t\treturn false;\n\n\t\tuint32_t part_size = i + 1 < part_count ?\n\t\t                     (offsets[i + 1] - offsets[i]) :\n\t\t                     uint32_t(stream.get_size() - offsets[i]);\n\t\tauto substream = stream.create_substream(offsets[i], part_size);\n\n\t\tDXIL::RuntimeDataPartType type;\n\t\tif (!substream.read(type))\n\t\t\treturn false;\n\t\tuint32_t subpart_length;\n\t\tif (!substream.read(subpart_length))\n\t\t\treturn false;\n\t\tif (subpart_length + 2 * sizeof(uint32_t) > substream.get_size())\n\t\t\treturn false;\n\n\t\tswitch (type)\n\t\t{\n\t\tcase DXIL::RuntimeDataPartType::StringBuffer:\n\t\t{\n\t\t\tstring_buffer = substream.create_substream(substream.get_offset(), subpart_length);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::RuntimeDataPartType::IndexArrays:\n\t\t{\n\t\t\tindex_buffer = substream.create_substream(substream.get_offset(), subpart_length);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::RuntimeDataPartType::RawBytes:\n\t\t{\n\t\t\traw_bytes = substream.create_substream(substream.get_offset(), subpart_length);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::RuntimeDataPartType::SubobjectTable:\n\t\t{\n\t\t\tuint32_t record_count;\n\t\t\tuint32_t record_stride;\n\t\t\tif (!substream.read(record_count))\n\t\t\t\treturn false;\n\t\t\tif (!substream.read(record_stride))\n\t\t\t\treturn false;\n\n\t\t\tfor (unsigned record = 0; record < record_count; record++)\n\t\t\t{\n\t\t\t\tauto record_stream =\n\t\t\t\t\t\tsubstream.create_substream(substream.get_offset() + record * record_stride, record_stride);\n\n\t\t\t\tDXIL::SubobjectKind kind;\n\t\t\t\tif (!record_stream.read(kind))\n\t\t\t\t\treturn false;\n\n\t\t\t\tswitch (kind)\n\t\t\t\t{\n\t\t\t\tcase DXIL::SubobjectKind::StateObjectConfig:\n\t\t\t\t{\n\t\t\t\t\tuint32_t name_offset;\n\t\t\t\t\tif (!record_stream.read(name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tconst char *str = nullptr;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(str, name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tuint32_t flag;\n\t\t\t\t\tif (!record_stream.read(flag))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tRDATSubobject elem = {};\n\t\t\t\t\telem.kind = kind;\n\t\t\t\t\telem.subobject_name = str;\n\t\t\t\t\telem.args[0] = flag;\n\t\t\t\t\trdat_subobjects.push_back(std::move(elem));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase DXIL::SubobjectKind::RaytracingShaderConfig:\n\t\t\t\t{\n\t\t\t\t\tuint32_t name_offset;\n\t\t\t\t\tif (!record_stream.read(name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tconst char *str;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(str, name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tuint32_t max_payload_size, max_attribute_size;\n\t\t\t\t\tif (!record_stream.read(max_payload_size))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!record_stream.read(max_attribute_size))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tRDATSubobject elem = {};\n\t\t\t\t\telem.kind = kind;\n\t\t\t\t\telem.subobject_name = str;\n\t\t\t\t\telem.args[0] = max_payload_size;\n\t\t\t\t\telem.args[1] = max_attribute_size;\n\t\t\t\t\trdat_subobjects.push_back(std::move(elem));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase DXIL::SubobjectKind::RaytracingPipelineConfig:\n\t\t\t\tcase DXIL::SubobjectKind::RaytracingPipelineConfig1:\n\t\t\t\t{\n\t\t\t\t\tuint32_t name_offset;\n\t\t\t\t\tif (!record_stream.read(name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tconst char *str;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(str, name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tuint32_t max_recursion_depth;\n\t\t\t\t\tuint32_t flags = 0;\n\n\t\t\t\t\tif (!record_stream.read(max_recursion_depth))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tif (kind == DXIL::SubobjectKind::RaytracingPipelineConfig1)\n\t\t\t\t\t\tif (!record_stream.read(flags))\n\t\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tRDATSubobject elem = {};\n\t\t\t\t\telem.kind = kind;\n\t\t\t\t\telem.subobject_name = str;\n\t\t\t\t\telem.args[0] = max_recursion_depth;\n\t\t\t\t\telem.args[1] = flags;\n\t\t\t\t\trdat_subobjects.push_back(std::move(elem));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase DXIL::SubobjectKind::HitGroup:\n\t\t\t\t{\n\t\t\t\t\tuint32_t name_offset;\n\t\t\t\t\tif (!record_stream.read(name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tconst char *hg_name;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(hg_name, name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tDXIL::HitGroupType hit_group_type;\n\t\t\t\t\tif (!record_stream.read(hit_group_type))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tuint32_t ahit_name_offset, chit_name_offset, intersection_name_offset;\n\t\t\t\t\tif (!record_stream.read(ahit_name_offset))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!record_stream.read(chit_name_offset))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!record_stream.read(intersection_name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tconst char *ahit, *chit, *intersection;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(ahit, ahit_name_offset))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(chit, chit_name_offset))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(intersection, intersection_name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tRDATSubobject elem = {};\n\t\t\t\t\telem.kind = kind;\n\t\t\t\t\telem.subobject_name = hg_name;\n\t\t\t\t\telem.hit_group_type = hit_group_type;\n\t\t\t\t\telem.exports = { ahit, chit, intersection };\n\t\t\t\t\trdat_subobjects.push_back(std::move(elem));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase DXIL::SubobjectKind::SubobjectToExportsAssociation:\n\t\t\t\t{\n\t\t\t\t\tRDATSubobject elem = {};\n\t\t\t\t\telem.kind = kind;\n\t\t\t\t\tuint32_t name_offset;\n\n\t\t\t\t\tif (!record_stream.read(name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tconst char *name;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(name, name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\telem.subobject_name = name;\n\n\t\t\t\t\tif (!record_stream.read(name_offset))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tconst char *object_name;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(object_name, name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\telem.exports.push_back(object_name);\n\n\t\t\t\t\tuint32_t index_offset;\n\t\t\t\t\tif (!record_stream.read(index_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tauto index_substream = index_buffer.create_substream(sizeof(uint32_t) * index_offset);\n\t\t\t\t\tuint32_t count;\n\t\t\t\t\tif (!index_substream.read(count))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tfor (uint32_t export_index = 0; export_index < count; export_index++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!index_substream.read(name_offset))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!string_buffer.map_string_absolute(object_name, name_offset))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\telem.exports.push_back(object_name);\n\t\t\t\t\t}\n\n\t\t\t\t\trdat_subobjects.push_back(std::move(elem));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase DXIL::SubobjectKind::GlobalRootSignature:\n\t\t\t\tcase DXIL::SubobjectKind::LocalRootSignature:\n\t\t\t\t{\n\t\t\t\t\tuint32_t name_offset;\n\n\t\t\t\t\tif (!record_stream.read(name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tconst char *name;\n\t\t\t\t\tif (!string_buffer.map_string_absolute(name, name_offset))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tuint32_t byte_offset;\n\t\t\t\t\tuint32_t byte_size;\n\t\t\t\t\tif (!record_stream.read(byte_offset))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!record_stream.read(byte_size))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tauto name_substream = raw_bytes.create_substream(byte_offset, byte_size);\n\t\t\t\t\tauto *data = name_substream.map_read<uint8_t>(byte_size);\n\n\t\t\t\t\tRDATSubobject elem = {};\n\t\t\t\t\telem.kind = kind;\n\t\t\t\t\telem.subobject_name = name;\n\t\t\t\t\telem.payload = data;\n\t\t\t\t\telem.payload_size = byte_size;\n\t\t\t\t\trdat_subobjects.push_back(std::move(elem));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool DXILContainerParser::parse_container(const void *data, size_t size, bool reflection)\n{\n\tMemoryStream stream(data, size);\n\n\tDXIL::ContainerHeader container_header;\n\tif (!stream.read(container_header))\n\t\treturn false;\n\n\tif (static_cast<DXIL::FourCC>(container_header.header_fourcc) != DXIL::FourCC::Container)\n\t\treturn false;\n\tif (container_header.container_size_in_bytes > size)\n\t\treturn false;\n\n\tVector<uint32_t> parts(container_header.part_count);\n\tfor (uint32_t i = 0; i < container_header.part_count; i++)\n\t{\n\t\tif (!stream.read(parts[i]))\n\t\t\treturn false;\n\t}\n\n\tfor (auto &part_offset : parts)\n\t{\n\t\tif (!stream.seek(part_offset))\n\t\t\treturn false;\n\n\t\tDXIL::PartHeader part_header;\n\t\tif (!stream.read(part_header))\n\t\t\treturn false;\n\n\t\tauto fourcc = static_cast<DXIL::FourCC>(part_header.part_fourcc);\n\n\t\tif (fourcc == DXIL::FourCC::SHDR || fourcc == DXIL::FourCC::SHEX)\n\t\t\tdxbc_binary = true;\n\t}\n\n\tfor (auto &part_offset : parts)\n\t{\n\t\tif (!stream.seek(part_offset))\n\t\t\treturn false;\n\n\t\tDXIL::PartHeader part_header;\n\t\tif (!stream.read(part_header))\n\t\t\treturn false;\n\n\t\tauto fourcc = static_cast<DXIL::FourCC>(part_header.part_fourcc);\n\t\tswitch (fourcc)\n\t\t{\n\t\tcase DXIL::FourCC::DXIL:\n\t\tcase DXIL::FourCC::ShaderStatistics:\n\t\t{\n\t\t\tDXIL::FourCC expected = reflection ? DXIL::FourCC::ShaderStatistics : DXIL::FourCC::DXIL;\n\t\t\tif (expected != fourcc || dxbc_binary)\n\t\t\t\tbreak;\n\n\t\t\t// The STAT block includes a DXIL blob that is literally the same DXIL IR\n\t\t\t// minus code + string names in the metadata chunks ... <__________________________________<\n\t\t\tauto substream = stream.create_substream(stream.get_offset(), part_header.part_size);\n\t\t\tif (!parse_dxil(substream))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::FourCC::FeatureInfo:\n\t\t\tbreak;\n\n\t\tcase DXIL::FourCC::InputSignature:\n\t\t{\n\t\t\tauto substream = stream.create_substream(stream.get_offset(), part_header.part_size);\n\t\t\tif (!parse_iosg1(substream, input_elements))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::FourCC::OutputSignature:\n\t\t{\n\t\t\tauto substream = stream.create_substream(stream.get_offset(), part_header.part_size);\n\t\t\tif (!parse_iosg1(substream, output_elements))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DXIL::FourCC::PatchConstantSignature:\n\t\t\tbreak;\n\n\t\tcase DXIL::FourCC::PrivateData:\n\t\t\tbreak;\n\n\t\tcase DXIL::FourCC::RootSignature:\n\t\t\tbreak;\n\n\t\tcase DXIL::FourCC::PipelineStateValidation:\n\t\t\tbreak;\n\n\t\tcase DXIL::FourCC::ResourceDef:\n\t\t\tbreak;\n\n\t\tcase DXIL::FourCC::ShaderHash:\n\t\t\tbreak;\n\n\t\tcase DXIL::FourCC::RuntimeData:\n\t\t{\n\t\t\tauto substream = stream.create_substream(stream.get_offset(), part_header.part_size);\n\t\t\tif (!parse_rdat(substream))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "dxil_parser.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"dxil.hpp\"\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace dxil_spv\n{\nclass MemoryStream;\n\nstruct RDATSubobject\n{\n\t// All strings point directly to the DXBC blob and the pointers are not owned.\n\tDXIL::SubobjectKind kind;\n\n\t// All subobjects have a variable name as declared in the shader.\n\tconst char *subobject_name;\n\n\t// All exports.\n\t// For hit groups, 3 strings: AnyHit, ClosestHit, Intersection. Strings may be empty if not used.\n\t// For SubobjectToExportsAssociation: N strings. exports[0] is associated with the following exports.\n\tDXIL::HitGroupType hit_group_type;\n\tVector<const char *> exports;\n\n\t// For StateObjectConfig, RaytracingShaderConfig, RaytracingPipelineConfig(1).\n\t// Each element is in struct order.\n\tuint32_t args[2];\n\n\t// For Global/Local Root Signatures.\n\tconst uint8_t *payload;\n\tsize_t payload_size;\n};\n\nclass DXILContainerParser\n{\npublic:\n\tbool parse_container(const void *data, size_t size, bool reflection);\n\tVector<uint8_t> &get_blob();\n\tVector<RDATSubobject> &get_rdat_subobjects();\n\tbool is_dxbc_binary() const { return dxbc_binary; }\n\nprivate:\n\tVector<uint8_t> dxil_blob;\n\tVector<DXIL::IOElement> input_elements;\n\tVector<DXIL::IOElement> output_elements;\n\tVector<RDATSubobject> rdat_subobjects;\n\n\tbool dxbc_binary = false;\n\n\tbool parse_dxil(MemoryStream &stream);\n\tbool parse_iosg1(MemoryStream &stream, Vector<DXIL::IOElement> &elements);\n\tbool parse_rdat(MemoryStream &stream);\n};\n\nbool is_mangled_entry_point(const char *user);\nString demangle_entry_point(const String &entry);\n} // namespace dxil_spv\n"
  },
  {
    "path": "dxil_spirv.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include <algorithm>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <vector>\n\n#define DXIL_SPV_ENABLE_EXPERIMENTAL_MULTIVIEW\n#include \"dxil_spirv_c.h\"\n\n#include \"cli_parser.hpp\"\n#include \"logging.hpp\"\n#include \"spirv-tools/libspirv.hpp\"\n#include \"spirv_cross_c.h\"\n\nusing namespace dxil_spv;\n\nstatic std::string convert_to_asm(const void *code, size_t size)\n{\n\tspvtools::SpirvTools tools(SPV_ENV_VULKAN_1_3);\n\ttools.SetMessageConsumer([](spv_message_level_t, const char *, const spv_position_t &, const char *message) {\n\t\tLOGE(\"SPIRV-Tools message: %s\\n\", message);\n\t});\n\n\tstd::string str;\n\tif (!tools.Disassemble(static_cast<const uint32_t *>(code), size / sizeof(uint32_t), &str, 0))\n\t\treturn \"\";\n\telse\n\t\treturn str;\n}\n\nstatic bool validate_spirv(const void *code, size_t size)\n{\n\tspvtools::SpirvTools tools(SPV_ENV_VULKAN_1_3);\n\tbool expected_failure = false;\n\tbool unexpected_failure = false;\n\n\ttools.SetMessageConsumer([&](spv_message_level_t, const char *, const spv_position_t &, const char *message) {\n\t\tif (strstr(message, \"08721\") || strstr(message, \"08722\"))\n\t\t{\n\t\t\tLOGW(\"SPIRV-Tools message expected failure: %s\\n\", message);\n\t\t\texpected_failure = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tLOGE(\"SPIRV-Tools message: %s\\n\", message);\n\t\t\tunexpected_failure = true;\n\t\t}\n\t});\n\tspvtools::ValidatorOptions opts;\n\topts.SetScalarBlockLayout(true);\n\treturn tools.Validate(static_cast<const uint32_t *>(code), size / sizeof(uint32_t), opts) ||\n\t       (expected_failure && !unexpected_failure);\n}\n\nstatic std::string convert_to_glsl(const void *code, size_t size)\n{\n\tstd::string ret;\n\tspvc_context context;\n\tif (spvc_context_create(&context) != SPVC_SUCCESS)\n\t\treturn ret;\n\n\tspvc_parsed_ir ir;\n\tif (spvc_context_parse_spirv(context, static_cast<const SpvId *>(code), size / sizeof(uint32_t), &ir) !=\n\t    SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler compiler;\n\tif (spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler) !=\n\t    SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler_options opts;\n\tif (spvc_compiler_create_compiler_options(compiler, &opts) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler_options_set_bool(opts, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_FALSE);\n\tspvc_compiler_options_set_uint(opts, SPVC_COMPILER_OPTION_GLSL_VERSION, 460);\n\tspvc_compiler_options_set_bool(opts, SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS, SPVC_TRUE);\n\tspvc_compiler_install_compiler_options(compiler, opts);\n\n\tconst char *source;\n\tif (spvc_compiler_compile(compiler, &source) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tret = source;\n\ncleanup:\n\tspvc_context_destroy(context);\n\treturn ret;\n}\n\nstatic std::vector<uint8_t> read_file(const char *path)\n{\n\tFILE *file = fopen(path, \"rb\");\n\tif (!file)\n\t\treturn {};\n\n\tfseek(file, 0, SEEK_END);\n\tauto len = ftell(file);\n\trewind(file);\n\tstd::vector<uint8_t> result(len);\n\tif (fread(result.data(), 1, len, file) != size_t(len))\n\t{\n\t\tfclose(file);\n\t\treturn {};\n\t}\n\n\tfclose(file);\n\treturn result;\n}\n\nstatic void print_help()\n{\n\tLOGE(\"Usage: dxil-spirv <input path>\\n\"\n\t     \"\\t[--output <path>]\\n\"\n\t     \"\\t[--glsl]\\n\"\n\t     \"\\t[--asm]\\n\"\n\t     \"\\t[--validate]\\n\"\n\t     \"\\t[--entry name]\\n\"\n\t     \"\\t[--debug-all-entry-points]\\n\"\n\t     \"\\t[--root-constant space binding word_offset word_count]\\n\"\n\t     \"\\t[--root-constant-inline-ubo set binding]\\n\"\n\t     \"\\t[--vertex-input semantic location]\\n\"\n\t     \"\\t[--stream-output semantic index offset stride buffer-index]\\n\"\n\t     \"\\t[--enable-shader-demote]\\n\"\n\t     \"\\t[--enable-shader-i8-dot]\\n\"\n\t     \"\\t[--enable-dual-source-blending]\\n\"\n\t     \"\\t[--bindless]\\n\"\n\t     \"\\t[--no-bda]\\n\"\n\t     \"\\t[--local-root-signature]\\n\"\n\t     \"\\t[--uav-counter-force-texel-buffer]\\n\"\n\t     \"\\t[--uav-counter-force-ssbo]\\n\"\n\t     \"\\t[--bindless-cbv-as-ssbo]\\n\"\n\t     \"\\t[--ssbo-uav]\\n\"\n\t     \"\\t[--ssbo-srv]\\n\"\n\t     \"\\t[--ssbo-rtas]\\n\"\n\t     \"\\t[--input-attachments]\\n\"\n\t     \"\\t[--ssbo-alignment <align>]\\n\"\n\t     \"\\t[--typed-uav-read-without-format]\\n\"\n\t     \"\\t[--bindless-typed-buffer-offsets]\\n\"\n\t     \"\\t[--output-rt-swizzle index xyzw]\\n\"\n\t     \"\\t[--bindless-offset-buffer-layout <untyped offset> <typed offset> <stride>]\\n\"\n\t     \"\\t[--storage-input-output-16bit]\\n\"\n\t     \"\\t[--root-descriptor <cbv/uav/srv> <space> <register>]\\n\"\n\t     \"\\t[--descriptor-qa <set> <binding base> <shader hash>]\\n\"\n\t     \"\\t[--instruction-instrumentation <type> <set> <binding base> <shader hash>]\\n\"\n\t     \"\\t[--min-precision-native-16bit]\\n\"\n\t     \"\\t[--raw-llvm]\\n\"\n\t     \"\\t[--use-reflection-names]\\n\"\n\t     \"\\t[--invariant-position]\\n\"\n\t     \"\\t[--robust-physical-cbv-load]\\n\"\n\t     \"\\t[--allow-arithmetic-relaxed-precision]\\n\"\n\t     \"\\t[--physical-address-descriptor-indexing <element stride> <element offset>]\\n\"\n\t     \"\\t[--nvapi <register index> <register space>]\\n\"\n\t     \"\\t[--subgroup-partitioned-nv]\\n\"\n\t     \"\\t[--dead-code-eliminate]\\n\"\n\t     \"\\t[--propagate-precise]\\n\"\n\t     \"\\t[--force-precise]\\n\"\n\t     \"\\t[--force-flatten]\\n\"\n\t     \"\\t[--force-loop]\\n\"\n\t     \"\\t[--force-branch]\\n\"\n\t     \"\\t[--force-unroll]\\n\"\n\t     \"\\t[--subgroup-size minimum maximum]\\n\"\n\t     \"\\t[--descriptor-heap-robustness]\\n\"\n\t     \"\\t[--no-compute-shader-derivatives]\\n\"\n\t     \"\\t[--quad-control-maximal-reconvergence]\\n\"\n\t     \"\\t[--force-maximal-reconvergence]\\n\"\n\t     \"\\t[--raw-access-chains-nv]\\n\"\n\t     \"\\t[--extended-robustness]\\n\"\n\t     \"\\t[--vkmm]\\n\"\n\t     \"\\t[--full-wmma <fp8> <nv-coopmat2>]\\n\"\n\t     \"\\t[--shader-quirk <index>]\\n\"\n\t     \"\\t[--non-semantic]\\n\"\n\t     \"\\t[--mixed-float-dot-product]\\n\"\n\t     \"\\t[--view-instancing]\\n\"\n\t     \"\\t[--view-instancing-last-pre-rasterization-stage]\\n\"\n\t     \"\\t[--view-instance-to-viewport-spec-id <id>]\\n\"\n\t     \"\\t[--view-index-to-view-instance-spec-id <id>]\\n\"\n\t     \"\\t[--meta-descriptor descriptor kind set binding]\\n\");\n}\n\nstruct MetaDescriptor\n{\n\tdxil_spv_meta_descriptor meta;\n\tdxil_spv_meta_descriptor_kind kind;\n\tuint32_t desc_set;\n\tuint32_t desc_binding;\n};\n\nstruct Arguments\n{\n\tstd::string input_path;\n\tstd::string output_path;\n\tstd::string entry_point;\n\tbool dump_module = false;\n\tbool glsl = false;\n\tbool emit_asm = false;\n\tbool validate = false;\n\tbool shader_demote = false;\n\tbool shader_i8_dot = false;\n\tbool dual_source_blending = false;\n\tbool debug_all_entry_points = false;\n\tbool storage_input_output_16bit = false;\n\tstd::vector<unsigned> swizzles;\n\n\tunsigned root_constant_inline_ubo_desc_set = 0;\n\tunsigned root_constant_inline_ubo_binding = 0;\n\tbool root_constant_inline_ubo = false;\n\tbool bindless_cbv_as_ssbo = false;\n\tbool typed_uav_read_without_format = false;\n\tbool bindless_typed_buffer_offsets = false;\n\tbool min_precision_native_16bit = false;\n\tbool raw_llvm = false;\n\tbool use_reflection_names = false;\n\tbool invariant_position = false;\n\tbool robust_physical_cbv_load = false;\n\tbool allow_arithmetic_relaxed_precision = false;\n\tbool subgroup_partitioned_nv = false;\n\tbool dead_code_eliminate = false;\n\tbool propagate_precise = false;\n\tbool force_precise = false;\n\tbool opacity_micromap = false;\n\tbool force_flatten = false;\n\tbool force_loop = false;\n\tbool force_branch = false;\n\tbool force_unroll = false;\n\tbool descriptor_heap_robustness = false;\n\tbool compute_shader_derivatives = true;\n\tbool quad_control_maximal_reconvergence = false;\n\tbool force_maximal_reconvergence = false;\n\tbool raw_access_chains_nv = false;\n\tbool extended_robustness = false;\n\tbool vkmm = false;\n\tbool wmma_fp8 = false;\n\tbool wmma_nv_coopmat2 = false;\n\tbool non_semantic = false;\n\tbool mixed_float_dot_product = false;\n\tstd::vector<dxil_spv_shader_quirk> quirks;\n\n\tunsigned ssbo_alignment = 1;\n\tunsigned physical_address_indexing_stride = 1;\n\tunsigned physical_address_indexing_offset = 0;\n\tunsigned subgroup_size_minimum = 4;\n\tunsigned subgroup_size_maximum = 128;\n\n\tbool descriptor_qa = false;\n\tuint32_t descriptor_qa_set = 0;\n\tuint32_t descriptor_qa_binding = 0;\n\n\tbool nvapi = false;\n\tunsigned nvapi_register_index = 0;\n\tunsigned nvapi_register_space = 0;\n\n\tbool instruction_instrumentation = false;\n\tuint32_t instruction_instrumentation_set = 0;\n\tuint32_t instruction_instrumentation_binding = 0;\n\tdxil_spv_instruction_instrumentation_type instruction_instrumentation_type = {};\n\n\tuint64_t shader_hash = 0;\n\n\tdxil_spv_option_bindless_offset_buffer_layout offset_buffer_layout;\n\n\tstd::vector<MetaDescriptor> meta_descriptors;\n\n\tbool view_instancing = false;\n\tbool view_instancing_last_pre_rasterization_stage = false;\n\tuint32_t view_index_to_view_instance_spec_id = UINT32_MAX;\n\tuint32_t view_instance_to_viewport_spec_id = UINT32_MAX;\n};\n\nstruct Remapper\n{\n\tstruct RootConstant\n\t{\n\t\tunsigned register_space;\n\t\tunsigned register_index;\n\t\tunsigned word_offset;\n\t};\n\n\tstruct RootDescriptor\n\t{\n\t\tdxil_spv_resource_class resource_class;\n\t\tuint32_t space;\n\t\tuint32_t register_index;\n\t};\n\n\tstd::vector<RootConstant> root_constants;\n\tunsigned root_constant_word_count = 0;\n\n\tstd::vector<RootDescriptor> root_descriptors;\n\n\tstruct VertexInput\n\t{\n\t\tstd::string semantic;\n\t\tunsigned index;\n\t};\n\tstd::vector<VertexInput> vertex_inputs;\n\n\tstruct StreamOutput\n\t{\n\t\tstd::string semantic;\n\t\tunsigned index;\n\n\t\tunsigned offset;\n\t\tunsigned stride;\n\t\tunsigned buffer_index;\n\t};\n\tstd::vector<StreamOutput> stream_outputs;\n\tbool bindless = false;\n\tbool bda = true;\n\tbool uav_counter_force_texel_buffer = false;\n\tbool uav_counter_force_ssbo = false;\n\n\tbool ssbo_uav = false;\n\tbool ssbo_srv = false;\n\tbool ssbo_rtas = false;\n\tbool input_attachments = false;\n};\n\nstatic bool kind_is_buffer(dxil_spv_resource_kind kind)\n{\n\treturn kind == DXIL_SPV_RESOURCE_KIND_RAW_BUFFER || kind == DXIL_SPV_RESOURCE_KIND_STRUCTURED_BUFFER ||\n\t       kind == DXIL_SPV_RESOURCE_KIND_TYPED_BUFFER;\n}\n\nstatic int32_t find_root_descriptor_index(const Remapper *remapper, const dxil_spv_d3d_binding *binding,\n                                          dxil_spv_resource_class resource_class)\n{\n\tauto itr = std::find_if(remapper->root_descriptors.begin(), remapper->root_descriptors.end(),\n\t                        [&](const Remapper::RootDescriptor &desc)\n\t                        {\n\t                          return desc.resource_class == resource_class &&\n\t                                 desc.space == binding->register_space &&\n\t                                 desc.register_index == binding->register_index;\n\t                        });\n\n\tif (itr != remapper->root_descriptors.end())\n\t\treturn int32_t(itr - remapper->root_descriptors.begin());\n\telse\n\t\treturn -1;\n}\n\nstatic bool d3d_binding_is_global_heap(const dxil_spv_d3d_binding &binding)\n{\n\treturn binding.register_index == UINT32_MAX &&\n\t       binding.register_space == UINT32_MAX &&\n\t       binding.range_size == UINT32_MAX;\n}\n\nstatic dxil_spv_bool remap_srv(void *userdata, const dxil_spv_d3d_binding *binding, dxil_spv_srv_vulkan_binding *vk_binding)\n{\n\tauto *remapper = static_cast<Remapper *>(userdata);\n\t*vk_binding = {};\n\n\tint32_t desc_index = find_root_descriptor_index(remapper, binding, DXIL_SPV_RESOURCE_CLASS_SRV);\n\tif (desc_index >= 0)\n\t{\n\t\tvk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_BUFFER_DEVICE_ADDRESS;\n\t\tvk_binding->buffer_binding.root_constant_index = uint32_t(desc_index);\n\t}\n\telse\n\t{\n\t\tbool is_global_heap = d3d_binding_is_global_heap(*binding);\n\n\t\tif (is_global_heap)\n\t\t{\n\t\t\tvk_binding->buffer_binding.bindless.use_heap = DXIL_SPV_TRUE;\n\t\t\tvk_binding->buffer_binding.set = 0;\n\t\t\tvk_binding->buffer_binding.binding = 0;\n\t\t}\n\t\telse if (remapper->bindless)\n\t\t{\n\t\t\tvk_binding->buffer_binding.bindless.use_heap = DXIL_SPV_TRUE;\n\t\t\tvk_binding->buffer_binding.bindless.heap_root_offset = binding->register_index;\n\t\t\tvk_binding->buffer_binding.root_constant_index = kind_is_buffer(binding->kind) ? 1 : 0;\n\t\t\tvk_binding->buffer_binding.set = kind_is_buffer(binding->kind) ? 1 : 0;\n\t\t\tvk_binding->buffer_binding.binding = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvk_binding->buffer_binding.bindless.use_heap = DXIL_SPV_FALSE;\n\t\t\tvk_binding->buffer_binding.set = binding->register_space;\n\t\t\tvk_binding->buffer_binding.binding = binding->register_index;\n\t\t}\n\n\t\tif (binding->kind == DXIL_SPV_RESOURCE_KIND_RT_ACCELERATION_STRUCTURE)\n\t\t\tif ((remapper->bindless || is_global_heap) && remapper->ssbo_rtas)\n\t\t\t\tvk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_SSBO;\n\n\t\tif (remapper->input_attachments &&\n\t\t\t(binding->register_space == 1000 || binding->register_space == 1001) &&\n\t\t    (binding->kind == DXIL_SPV_RESOURCE_KIND_TEXTURE_2D ||\n\t\t     binding->kind == DXIL_SPV_RESOURCE_KIND_TEXTURE_2DMS))\n\t\t{\n\t\t\tvk_binding->buffer_binding.bindless.use_heap = DXIL_SPV_FALSE;\n\t\t\tvk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;\n\t\t\tvk_binding->buffer_binding.input_attachment_index =\n\t\t\t    binding->register_space == 1000 ? binding->register_index : -1u;\n\t\t}\n\n\t\tif (remapper->ssbo_srv)\n\t\t{\n\t\t\tif (binding->kind == DXIL_SPV_RESOURCE_KIND_STRUCTURED_BUFFER ||\n\t\t\t    binding->kind == DXIL_SPV_RESOURCE_KIND_RAW_BUFFER)\n\t\t\t{\n\t\t\t\tvk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_SSBO;\n\t\t\t}\n\t\t}\n\n\t\t// In case it's needed, place offset buffer here.\n\t\tvk_binding->offset_binding.set = 15;\n\t\tvk_binding->offset_binding.binding = 0;\n\t}\n\n\treturn DXIL_SPV_TRUE;\n}\n\nstatic dxil_spv_bool remap_sampler(void *userdata, const dxil_spv_d3d_binding *binding,\n                                   dxil_spv_vulkan_binding *vk_binding)\n{\n\tauto *remapper = static_cast<Remapper *>(userdata);\n\t*vk_binding = {};\n\n\tif (d3d_binding_is_global_heap(*binding))\n\t{\n\t\tvk_binding->bindless.use_heap = DXIL_SPV_TRUE;\n\t\tvk_binding->set = 0;\n\t\tvk_binding->binding = 0;\n\t}\n\telse if (remapper->bindless)\n\t{\n\t\tvk_binding->bindless.use_heap = DXIL_SPV_TRUE;\n\t\tvk_binding->bindless.heap_root_offset = binding->register_index;\n\t\tvk_binding->root_constant_index = 2;\n\t\tvk_binding->set = 2;\n\t\tvk_binding->binding = 0;\n\t}\n\telse\n\t{\n\t\tvk_binding->bindless.use_heap = DXIL_SPV_FALSE;\n\t\tvk_binding->set = binding->register_space;\n\t\tvk_binding->binding = binding->register_index;\n\t}\n\treturn DXIL_SPV_TRUE;\n}\n\nstatic dxil_spv_bool remap_uav(void *userdata, const dxil_spv_uav_d3d_binding *binding,\n                               dxil_spv_uav_vulkan_binding *vk_binding)\n{\n\tauto *remapper = static_cast<Remapper *>(userdata);\n\t*vk_binding = {};\n\n\tint32_t desc_index = find_root_descriptor_index(remapper, &binding->d3d_binding, DXIL_SPV_RESOURCE_CLASS_UAV);\n\tif (desc_index >= 0)\n\t{\n\t\tvk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_BUFFER_DEVICE_ADDRESS;\n\t\tvk_binding->buffer_binding.root_constant_index = uint32_t(desc_index);\n\t}\n\telse\n\t{\n\t\tbool binding_is_global_heap = d3d_binding_is_global_heap(binding->d3d_binding);\n\n\t\tif (binding_is_global_heap)\n\t\t{\n\t\t\tvk_binding->buffer_binding.bindless.use_heap = DXIL_SPV_TRUE;\n\t\t\tvk_binding->buffer_binding.set = 0;\n\t\t\tvk_binding->buffer_binding.binding = 0;\n\t\t}\n\t\telse if (remapper->bindless)\n\t\t{\n\t\t\tvk_binding->buffer_binding.bindless.use_heap = DXIL_SPV_TRUE;\n\t\t\tvk_binding->buffer_binding.bindless.heap_root_offset = binding->d3d_binding.register_index;\n\t\t\tvk_binding->buffer_binding.root_constant_index = kind_is_buffer(binding->d3d_binding.kind) ? 4 : 3;\n\t\t\tvk_binding->buffer_binding.set = kind_is_buffer(binding->d3d_binding.kind) ? 4 : 3;\n\t\t\tvk_binding->buffer_binding.binding = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvk_binding->buffer_binding.bindless.use_heap = DXIL_SPV_FALSE;\n\t\t\tvk_binding->buffer_binding.set = binding->d3d_binding.register_space;\n\t\t\tvk_binding->buffer_binding.binding = binding->d3d_binding.register_index;\n\t\t}\n\n\t\tif (remapper->ssbo_uav)\n\t\t{\n\t\t\tif (binding->d3d_binding.kind == DXIL_SPV_RESOURCE_KIND_STRUCTURED_BUFFER ||\n\t\t\t    binding->d3d_binding.kind == DXIL_SPV_RESOURCE_KIND_RAW_BUFFER)\n\t\t\t{\n\t\t\t\tvk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_SSBO;\n\t\t\t}\n\t\t}\n\n\t\tvk_binding->offset_binding.set = 15;\n\t\tvk_binding->offset_binding.binding = 0;\n\n\t\tif (binding->has_counter)\n\t\t{\n\t\t\tif (remapper->bindless || binding_is_global_heap)\n\t\t\t{\n\t\t\t\tvk_binding->counter_binding.bindless.use_heap = DXIL_SPV_TRUE;\n\t\t\t\tvk_binding->counter_binding.root_constant_index = 4;\n\t\t\t\tvk_binding->counter_binding.bindless.heap_root_offset = binding->d3d_binding.register_index;\n\t\t\t\tvk_binding->counter_binding.set = 7;\n\t\t\t\tvk_binding->counter_binding.binding = 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvk_binding->counter_binding.bindless.use_heap = DXIL_SPV_FALSE;\n\t\t\t\tvk_binding->counter_binding.set = 7;\n\t\t\t\tvk_binding->counter_binding.binding = binding->d3d_binding.resource_index;\n\t\t\t}\n\n\t\t\tif (remapper->uav_counter_force_texel_buffer)\n\t\t\t\tvk_binding->counter_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_TEXEL_BUFFER;\n\t\t\telse if (remapper->uav_counter_force_ssbo)\n\t\t\t\tvk_binding->counter_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_SSBO;\n\t\t}\n\t}\n\n\treturn DXIL_SPV_TRUE;\n}\n\nstatic dxil_spv_bool remap_cbv(void *userdata, const dxil_spv_d3d_binding *binding,\n                               dxil_spv_cbv_vulkan_binding *vk_binding)\n{\n\tauto *remapper = static_cast<Remapper *>(userdata);\n\t*vk_binding = {};\n\n\tint32_t desc_index = find_root_descriptor_index(remapper, binding, DXIL_SPV_RESOURCE_CLASS_CBV);\n\tif (desc_index >= 0)\n\t{\n\t\tvk_binding->push_constant = DXIL_SPV_FALSE;\n\t\tvk_binding->vulkan.uniform_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_BUFFER_DEVICE_ADDRESS;\n\t\tvk_binding->vulkan.uniform_binding.root_constant_index = uint32_t(desc_index);\n\t}\n\telse\n\t{\n\t\tauto itr = std::find_if(\n\t\t    remapper->root_constants.begin(), remapper->root_constants.end(), [&](const Remapper::RootConstant &root) {\n\t\t\t    return root.register_space == binding->register_space && root.register_index == binding->register_index;\n\t\t    });\n\n\t\tif (itr != remapper->root_constants.end())\n\t\t{\n\t\t\tvk_binding->push_constant = DXIL_SPV_TRUE;\n\t\t\tvk_binding->vulkan.push_constant.offset_in_words = itr->word_offset;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (d3d_binding_is_global_heap(*binding))\n\t\t\t{\n\t\t\t\tvk_binding->vulkan.uniform_binding.bindless.use_heap = DXIL_SPV_TRUE;\n\t\t\t\tvk_binding->vulkan.uniform_binding.set = 0;\n\t\t\t\tvk_binding->vulkan.uniform_binding.binding = 0;\n\t\t\t}\n\t\t\telse if (remapper->bindless)\n\t\t\t{\n\t\t\t\tvk_binding->vulkan.uniform_binding.bindless.use_heap = DXIL_SPV_TRUE;\n\t\t\t\tvk_binding->vulkan.uniform_binding.bindless.heap_root_offset = binding->register_index;\n\t\t\t\tvk_binding->vulkan.uniform_binding.root_constant_index = 5;\n\t\t\t\tvk_binding->vulkan.uniform_binding.set = 5;\n\t\t\t\tvk_binding->vulkan.uniform_binding.binding = 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvk_binding->vulkan.uniform_binding.bindless.use_heap = DXIL_SPV_FALSE;\n\t\t\t\tvk_binding->vulkan.uniform_binding.set = binding->register_space;\n\t\t\t\tvk_binding->vulkan.uniform_binding.binding = binding->register_index;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn DXIL_SPV_TRUE;\n}\n\nstatic dxil_spv_bool remap_vertex_input(void *userdata, const dxil_spv_d3d_vertex_input *d3d_input,\n                                        dxil_spv_vulkan_vertex_input *vk_input)\n{\n\tauto *remapper = static_cast<Remapper *>(userdata);\n\n\tauto itr = std::find_if(remapper->vertex_inputs.begin(), remapper->vertex_inputs.end(),\n\t                        [&](const Remapper::VertexInput &vin) { return vin.semantic == d3d_input->semantic; });\n\n\tif (itr != remapper->vertex_inputs.end())\n\t{\n\t\tvk_input->location = itr->index + d3d_input->semantic_index;\n\t}\n\telse\n\t{\n\t\tvk_input->location = d3d_input->start_row;\n\t}\n\n\treturn DXIL_SPV_TRUE;\n}\n\n#ifdef _MSC_VER\n#define strcasecmp _stricmp\n#endif\n\nstatic dxil_spv_bool remap_stream_output(void *userdata, const dxil_spv_d3d_stream_output *d3d_output,\n                                         dxil_spv_vulkan_stream_output *vk_output)\n{\n\tauto *remapper = static_cast<Remapper *>(userdata);\n\n\tauto itr = std::find_if(remapper->stream_outputs.begin(), remapper->stream_outputs.end(),\n\t                        [&](const Remapper::StreamOutput &vin) {\n\t\t                        return strcasecmp(vin.semantic.c_str(), d3d_output->semantic) == 0 &&\n\t\t                               vin.index == d3d_output->semantic_index;\n\t                        });\n\n\tif (itr != remapper->stream_outputs.end())\n\t{\n\t\tvk_output->enable = DXIL_SPV_TRUE;\n\t\tvk_output->offset = itr->offset;\n\t\tvk_output->stride = itr->stride;\n\t\tvk_output->buffer_index = itr->buffer_index;\n\t}\n\telse\n\t{\n\t\t*vk_output = {};\n\t}\n\n\treturn DXIL_SPV_TRUE;\n}\n\nint main(int argc, char **argv)\n{\n\tArguments args;\n\tRemapper remapper;\n\tbool local_root_signature = false;\n\tdxil_spv_begin_thread_allocator_context();\n\n\targs.offset_buffer_layout.base.type = DXIL_SPV_OPTION_BINDLESS_OFFSET_BUFFER_LAYOUT;\n\targs.offset_buffer_layout.untyped_offset = 0;\n\targs.offset_buffer_layout.typed_offset = 0;\n\targs.offset_buffer_layout.stride = 1;\n\n\t// Begin with identity swizzles.\n\targs.swizzles.resize(8, 0 | (1 << 2) | (2 << 4) | (3 << 6));\n\n\tCLICallbacks cbs;\n\tcbs.add(\"--help\", [](CLIParser &parser) {\n\t\tprint_help();\n\t\tparser.end();\n\t});\n\tcbs.add(\"--dump-module\", [&](CLIParser &) { args.dump_module = true; });\n\tcbs.add(\"--glsl\", [&](CLIParser &) { args.glsl = true; });\n\tcbs.add(\"--asm\", [&](CLIParser &) { args.emit_asm = true; });\n\tcbs.add(\"--validate\", [&](CLIParser &) { args.validate = true; });\n\tcbs.add(\"--output\", [&](CLIParser &parser) { args.output_path = parser.next_string(); });\n\tcbs.add(\"--root-constant\", [&](CLIParser &parser) {\n\t\tRemapper::RootConstant root = {};\n\t\troot.register_space = parser.next_uint();\n\t\troot.register_index = parser.next_uint();\n\t\troot.word_offset = parser.next_uint();\n\t\tunsigned word_count = parser.next_uint();\n\t\tremapper.root_constant_word_count = std::max(remapper.root_constant_word_count, word_count + root.word_offset);\n\t\tremapper.root_constants.push_back(root);\n\t});\n\tcbs.add(\"--vertex-input\", [&](CLIParser &parser) {\n\t\tconst char *sem = parser.next_string();\n\t\tunsigned loc = parser.next_uint();\n\t\tremapper.vertex_inputs.push_back({ std::string(sem), loc });\n\t});\n\tcbs.add(\"--stream-output\", [&](CLIParser &parser) {\n\t\tconst char *sem = parser.next_string();\n\t\tunsigned index = parser.next_uint();\n\n\t\tunsigned offset = parser.next_uint();\n\t\tunsigned stride = parser.next_uint();\n\t\tunsigned buffer_index = parser.next_uint();\n\t\tremapper.stream_outputs.push_back({ std::string(sem), index, offset, stride, buffer_index });\n\t});\n\tcbs.add(\"--enable-shader-demote\", [&](CLIParser &) { args.shader_demote = true; });\n\tcbs.add(\"--enable-shader-i8-dot\", [&](CLIParser &parser) { args.shader_i8_dot = true; });\n\tcbs.add(\"--enable-dual-source-blending\", [&](CLIParser &) { args.dual_source_blending = true; });\n\tcbs.add(\"--bindless\", [&](CLIParser &) {\n\t\tremapper.bindless = true;\n\t\tremapper.root_constant_word_count = std::max(remapper.root_constant_word_count, 8u);\n\t});\n\tcbs.add(\"--no-bda\", [&](CLIParser &) {\n\t\tremapper.bda = false;\n\t});\n\tcbs.add(\"--uav-counter-force-texel-buffer\", [&](CLIParser &) {\n\t\tremapper.uav_counter_force_texel_buffer = true;\n\t});\n\tcbs.add(\"--uav-counter-force-ssbo\", [&](CLIParser &) {\n\t\tremapper.uav_counter_force_ssbo = true;\n\t});\n\tcbs.add(\"--local-root-signature\", [&](CLIParser &) {\n\t\tlocal_root_signature = true;\n\t});\n\tcbs.add(\"--root-descriptor\", [&](CLIParser &parser) {\n\t\tconst char *tag = parser.next_string();\n\t\tuint32_t space = parser.next_uint();\n\t\tuint32_t register_index = parser.next_uint();\n\t\tdxil_spv_resource_class resource_class;\n\t\tif (!strcmp(tag, \"cbv\"))\n\t\t\tresource_class = DXIL_SPV_RESOURCE_CLASS_CBV;\n\t\telse if (!strcmp(tag, \"uav\"))\n\t\t\tresource_class = DXIL_SPV_RESOURCE_CLASS_UAV;\n\t\telse if (!strcmp(tag, \"srv\"))\n\t\t\tresource_class = DXIL_SPV_RESOURCE_CLASS_SRV;\n\t\telse\n\t\t{\n\t\t\tLOGE(\"Invalid resource class %s, ignoring.\\n\", tag);\n\t\t\treturn;\n\t\t}\n\n\t\tremapper.root_descriptors.push_back({ resource_class, space, register_index });\n\t});\n\tcbs.add(\"--output-rt-swizzle\", [&](CLIParser &parser) {\n\t\tunsigned index = parser.next_uint();\n\t\tif (index >= args.swizzles.size())\n\t\t{\n\t\t\tLOGE(\"RT index out of range.\\n\");\n\t\t\tprint_help();\n\t\t\tparser.end();\n\t\t\treturn;\n\t\t}\n\n\t\tconst char *arg = parser.next_string();\n\t\tif (strlen(arg) != 4)\n\t\t{\n\t\t\tLOGE(\"RT swizzle must be 4 characters (x, y, z, w).\\n\");\n\t\t\tprint_help();\n\t\t\tparser.end();\n\t\t\treturn;\n\t\t}\n\n\t\tauto &swiz = args.swizzles[index];\n\t\tswiz = 0;\n\n\t\tfor (unsigned c = 0; c < 4; c++)\n\t\t{\n\t\t\tswitch (arg[c])\n\t\t\t{\n\t\t\tcase 'x':\n\t\t\tcase 'X':\n\t\t\tcase 'r':\n\t\t\tcase 'R':\n\t\t\t\tswiz |= 0 << (2 * c);\n\t\t\t\tbreak;\n\n\t\t\tcase 'y':\n\t\t\tcase 'Y':\n\t\t\tcase 'g':\n\t\t\tcase 'G':\n\t\t\t\tswiz |= 1 << (2 * c);\n\t\t\t\tbreak;\n\n\t\t\tcase 'z':\n\t\t\tcase 'Z':\n\t\t\tcase 'b':\n\t\t\tcase 'B':\n\t\t\t\tswiz |= 2 << (2 * c);\n\t\t\t\tbreak;\n\n\t\t\tcase 'w':\n\t\t\tcase 'W':\n\t\t\tcase 'a':\n\t\t\tcase 'A':\n\t\t\t\tswiz |= 3 << (2 * c);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOGE(\"Invalid swizzle character %c.\\n\", arg[c]);\n\t\t\t\tprint_help();\n\t\t\t\tparser.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\tcbs.add(\"--root-constant-inline-ubo\", [&](CLIParser &parser) {\n\t\targs.root_constant_inline_ubo_desc_set = parser.next_uint();\n\t\targs.root_constant_inline_ubo_binding = parser.next_uint();\n\t\targs.root_constant_inline_ubo = true;\n\t});\n\tcbs.add(\"--bindless-cbv-as-ssbo\", [&](CLIParser &) { args.bindless_cbv_as_ssbo = true; });\n\tcbs.add(\"--ssbo-uav\", [&](CLIParser &) { remapper.ssbo_uav = true; });\n\tcbs.add(\"--ssbo-srv\", [&](CLIParser &) { remapper.ssbo_srv = true; });\n\tcbs.add(\"--ssbo-rtas\", [&](CLIParser &) { remapper.ssbo_rtas = true; });\n\tcbs.add(\"--input-attachments\", [&](CLIParser &) { remapper.input_attachments = true; });\n\tcbs.add(\"--ssbo-alignment\", [&](CLIParser &parser) { args.ssbo_alignment = parser.next_uint(); });\n\tcbs.add(\"--typed-uav-read-without-format\", [&](CLIParser &) { args.typed_uav_read_without_format = true; });\n\tcbs.add(\"--bindless-typed-buffer-offsets\", [&](CLIParser &) { args.bindless_typed_buffer_offsets = true; });\n\tcbs.add(\"--bindless-offset-buffer-layout\", [&](CLIParser &parser) {\n\t\targs.offset_buffer_layout.untyped_offset = parser.next_uint();\n\t\targs.offset_buffer_layout.typed_offset = parser.next_uint();\n\t\targs.offset_buffer_layout.stride = parser.next_uint();\n\t});\n\tcbs.add(\"--entry\", [&](CLIParser &parser) { args.entry_point = parser.next_string(); });\n\tcbs.add(\"--debug-all-entry-points\", [&](CLIParser &parser) { args.debug_all_entry_points = true; });\n\tcbs.add(\"--storage-input-output-16bit\", [&](CLIParser &parser) { args.storage_input_output_16bit = true; });\n\tcbs.add(\"--descriptor-qa\", [&](CLIParser &parser) {\n\t\targs.descriptor_qa = true;\n\t\targs.descriptor_qa_set = parser.next_uint();\n\t\targs.descriptor_qa_binding = parser.next_uint();\n\t\targs.shader_hash = uint64_t(strtoull(parser.next_string(), nullptr, 16));\n\t});\n\tcbs.add(\"--instruction-instrumentation\", [&](CLIParser &parser) {\n\t\targs.instruction_instrumentation = true;\n\t\targs.instruction_instrumentation_type = dxil_spv_instruction_instrumentation_type(parser.next_uint());\n\t\targs.instruction_instrumentation_set = parser.next_uint();\n\t\targs.instruction_instrumentation_binding = parser.next_uint();\n\t\targs.shader_hash = uint64_t(strtoull(parser.next_string(), nullptr, 16));\n\t});\n\tcbs.add(\"--min-precision-native-16bit\", [&](CLIParser &) { args.min_precision_native_16bit = true; });\n\tcbs.add(\"--raw-llvm\", [&](CLIParser &) { args.raw_llvm = true; });\n\tcbs.add(\"--use-reflection-names\", [&](CLIParser &) { args.use_reflection_names = true; });\n\tcbs.add(\"--invariant-position\", [&](CLIParser &) { args.invariant_position = true; });\n\tcbs.add(\"--robust-physical-cbv-load\", [&](CLIParser &) { args.robust_physical_cbv_load = true; });\n\tcbs.add(\"--allow-arithmetic-relaxed-precision\", [&](CLIParser &) { args.allow_arithmetic_relaxed_precision = true; });\n\tcbs.add(\"--physical-address-descriptor-indexing\", [&](CLIParser &parser) {\n\t\targs.physical_address_indexing_stride = parser.next_uint();\n\t\targs.physical_address_indexing_offset = parser.next_uint();\n\t});\n\tcbs.add(\"--nvapi\", [&](CLIParser &parser) {\n\t\targs.nvapi = true;\n\t\targs.nvapi_register_index = parser.next_uint();\n\t\targs.nvapi_register_space = parser.next_uint();\n\t});\n\tcbs.add(\"--subgroup-partitioned-nv\", [&](CLIParser &) {\n\t\targs.subgroup_partitioned_nv = true;\n\t});\n\tcbs.add(\"--dead-code-eliminate\", [&](CLIParser &) {\n\t\targs.dead_code_eliminate = true;\n\t});\n\tcbs.add(\"--propagate-precise\", [&](CLIParser &) {\n\t\targs.propagate_precise = true;\n\t});\n\tcbs.add(\"--force-precise\", [&](CLIParser &) {\n\t\targs.force_precise = true;\n\t});\n\tcbs.add(\"--opacity-micromap\", [&](CLIParser &) {\n\t\targs.opacity_micromap = true;\n\t});\n\tcbs.add(\"--force-flatten\", [&](CLIParser &) {\n\t\targs.force_flatten = true;\n\t});\n\tcbs.add(\"--force-loop\", [&](CLIParser &) {\n\t\targs.force_loop = true;\n\t});\n\tcbs.add(\"--force-unroll\", [&](CLIParser &) {\n\t\targs.force_unroll = true;\n\t});\n\tcbs.add(\"--force-branch\", [&](CLIParser &) {\n\t\targs.force_branch = true;\n\t});\n\tcbs.add(\"--subgroup-size\", [&](CLIParser &parser) {\n\t\targs.subgroup_size_minimum = parser.next_uint();\n\t\targs.subgroup_size_maximum = parser.next_uint();\n\t});\n\tcbs.add(\"--descriptor-heap-robustness\", [&](CLIParser &) {\n\t\targs.descriptor_heap_robustness = true;\n\t});\n\tcbs.add(\"--no-compute-shader-derivatives\", [&](CLIParser &) {\n\t\targs.compute_shader_derivatives = false;\n\t});\n\tcbs.add(\"--quad-control-maximal-reconvergence\", [&](CLIParser &) {\n\t\targs.quad_control_maximal_reconvergence = true;\n\t});\n\tcbs.add(\"--force-maximal-reconvergence\", [&](CLIParser &) {\n\t\targs.force_maximal_reconvergence = true;\n\t});\n\tcbs.add(\"--raw-access-chains-nv\", [&](CLIParser &) {\n\t\targs.raw_access_chains_nv = true;\n\t});\n\tcbs.add(\"--extended-robustness\", [&](CLIParser &) {\n\t\targs.extended_robustness = true;\n\t});\n\tcbs.add(\"--vkmm\", [&](CLIParser &) {\n\t\targs.vkmm = true;\n\t});\n\tcbs.add(\"--full-wmma\", [&](CLIParser &parser) {\n\t\targs.wmma_fp8 = parser.next_uint() != 0;\n\t\targs.wmma_nv_coopmat2 = parser.next_uint() != 0;\n\t});\n\tcbs.add(\"--shader-quirk\", [&](CLIParser &parser) {\n\t\targs.quirks.push_back(dxil_spv_shader_quirk(parser.next_uint()));\n\t});\n\tcbs.add(\"--non-semantic\", [&](CLIParser &) { args.non_semantic = true; });\n\tcbs.add(\"--mixed-float-dot-product\", [&](CLIParser &) { args.mixed_float_dot_product = true; });\n\tcbs.add(\"--meta-descriptor\", [&](CLIParser &parser) {\n\t\tMetaDescriptor meta = {};\n\t\tmeta.meta = dxil_spv_meta_descriptor(parser.next_uint());\n\t\tmeta.kind = dxil_spv_meta_descriptor_kind(parser.next_uint());\n\t\tmeta.desc_set = parser.next_uint();\n\t\tmeta.desc_binding = parser.next_uint();\n\t\targs.meta_descriptors.push_back(meta);\n\t});\n\tcbs.add(\"--view-instancing\", [&](CLIParser &parser) {\n\t\targs.view_instancing = true;\n\t});\n\tcbs.add(\"--view-instancing-last-pre-rasterization-stage\", [&](CLIParser &parser) {\n\t\targs.view_instancing_last_pre_rasterization_stage = true;\n\t});\n\tcbs.add(\"--view-instance-to-viewport-spec-id\", [&](CLIParser &parser) {\n\t\targs.view_instance_to_viewport_spec_id = parser.next_uint();\n\t});\n\tcbs.add(\"--view-index-to-view-instance-spec-id\", [&](CLIParser &parser) {\n\t\targs.view_index_to_view_instance_spec_id = parser.next_uint();\n\t});\n\tcbs.error_handler = [] { print_help(); };\n\tcbs.default_handler = [&](const char *arg) { args.input_path = arg; };\n\tCLIParser cli_parser(std::move(cbs), argc - 1, argv + 1);\n\tif (!cli_parser.parse())\n\t\treturn EXIT_FAILURE;\n\telse if (cli_parser.is_ended_state())\n\t\treturn EXIT_SUCCESS;\n\n\tif (args.input_path.empty())\n\t{\n\t\tLOGE(\"No input file.\\n\");\n\t\tprint_help();\n\t\treturn EXIT_FAILURE;\n\t}\n\n\tauto binary = read_file(args.input_path.c_str());\n\tif (binary.empty())\n\t{\n\t\tLOGE(\"Failed to load file: %s\\n\", args.input_path.c_str());\n\t\treturn EXIT_FAILURE;\n\t}\n\n\tdxil_spv_parsed_blob reflection_blob = nullptr;\n\tdxil_spv_parsed_blob blob;\n\n\tif (args.raw_llvm)\n\t{\n\t\tif (dxil_spv_parse_dxil(binary.data(), binary.size(), &blob) != DXIL_SPV_SUCCESS)\n\t\t{\n\t\t\tLOGE(\"Failed to parse raw LLVM blob.\\n\");\n\t\t\treturn EXIT_FAILURE;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (dxil_spv_parse_dxil_blob(binary.data(), binary.size(), &blob) != DXIL_SPV_SUCCESS)\n\t\t{\n\t\t\tLOGE(\"Failed to parse blob.\\n\");\n\t\t\treturn EXIT_FAILURE;\n\t\t}\n\t}\n\n\tif (args.use_reflection_names)\n\t{\n\t\tauto result = dxil_spv_parse_reflection_dxil_blob(binary.data(), binary.size(), &reflection_blob);\n\t\tif (result != DXIL_SPV_SUCCESS && result != DXIL_SPV_ERROR_NO_DATA)\n\t\t{\n\t\t\tLOGE(\"Failed to parse blob.\\n\");\n\t\t\treturn EXIT_FAILURE;\n\t\t}\n\t\telse if (result == DXIL_SPV_ERROR_NO_DATA)\n\t\t{\n\t\t\tLOGW(\"No STAT block found in DXIL blob.\\n\");\n\t\t\treflection_blob = nullptr;\n\t\t}\n\t}\n\n\tif (args.dump_module)\n\t\tdxil_spv_parsed_blob_dump_llvm_ir(blob);\n\n\tdxil_spv_converter converter;\n\tif (dxil_spv_create_converter_with_reflection(blob, reflection_blob, &converter) != DXIL_SPV_SUCCESS)\n\t\treturn EXIT_FAILURE;\n\n\tdxil_spv_converter_set_srv_remapper(converter, remap_srv, &remapper);\n\tdxil_spv_converter_set_sampler_remapper(converter, remap_sampler, &remapper);\n\tdxil_spv_converter_set_uav_remapper(converter, remap_uav, &remapper);\n\tdxil_spv_converter_set_cbv_remapper(converter, remap_cbv, &remapper);\n\n\tdxil_spv_converter_set_vertex_input_remapper(converter, remap_vertex_input, &remapper);\n\tdxil_spv_converter_set_stream_output_remapper(converter, remap_stream_output, &remapper);\n\tdxil_spv_converter_set_root_constant_word_count(converter, remapper.root_constant_word_count);\n\tdxil_spv_converter_set_root_descriptor_count(converter, remapper.root_descriptors.size());\n\n\tif (local_root_signature)\n\t{\n\t\tdxil_spv_converter_add_local_root_constants(converter, 15, 0, 5);\n\t\tdxil_spv_converter_add_local_root_constants(converter, 15, 1, 6);\n\t\tdxil_spv_converter_add_local_root_descriptor(converter, DXIL_SPV_RESOURCE_CLASS_SRV, 15, 1);\n\t\tdxil_spv_converter_add_local_root_descriptor(converter, DXIL_SPV_RESOURCE_CLASS_UAV, 15, 1);\n\t\tdxil_spv_converter_add_local_root_descriptor(converter, DXIL_SPV_RESOURCE_CLASS_SRV, 15, 2);\n\t\tdxil_spv_converter_add_local_root_descriptor(converter, DXIL_SPV_RESOURCE_CLASS_UAV, 15, 2);\n\t\tdxil_spv_converter_add_local_root_descriptor(converter, DXIL_SPV_RESOURCE_CLASS_CBV, 15, 2);\n\t\tdxil_spv_converter_add_local_root_descriptor_table(converter, DXIL_SPV_RESOURCE_CLASS_SRV, 15, 3, ~0u, 10);\n\t\tdxil_spv_converter_add_local_root_descriptor_table(converter, DXIL_SPV_RESOURCE_CLASS_UAV, 15, 3, ~0u, 11);\n\t\tdxil_spv_converter_add_local_root_descriptor_table(converter, DXIL_SPV_RESOURCE_CLASS_CBV, 15, 3, ~0u, 12);\n\t\tdxil_spv_converter_add_local_root_descriptor_table(converter, DXIL_SPV_RESOURCE_CLASS_SAMPLER, 15, 3, ~0u, 13);\n\n\t\tdxil_spv_option_sbt_descriptor_size_log2 desc_size =\n\t\t\t{ { DXIL_SPV_OPTION_SBT_DESCRIPTOR_SIZE_LOG2 }, 6, 5 };\n\t\tdxil_spv_converter_add_option(converter, &desc_size.base);\n\t}\n\n\tif (remapper.bindless)\n\t{\n\t\t// Dummy mappings.\n\t\tfor (uint32_t i = 0; i < 64; i++)\n\t\t\tdxil_spv_converter_add_root_parameter_mapping(converter, i, 4 * i);\n\t}\n\n\tif (args.shader_demote)\n\t{\n\t\tconst dxil_spv_option_shader_demote_to_helper helper = { { DXIL_SPV_OPTION_SHADER_DEMOTE_TO_HELPER },\n\t\t\t                                                     DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &helper.base);\n\t}\n\n\tif (args.shader_i8_dot)\n\t{\n\t\tconst dxil_spv_option_shader_i8_dot helper = { { DXIL_SPV_OPTION_SHADER_I8_DOT },\n\t\t                                               DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &helper.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_shader_ray_tracing_primitive_culling helper =\n\t\t\t{ { DXIL_SPV_OPTION_SHADER_RAY_TRACING_PRIMITIVE_CULLING },\n\t\t\t  DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &helper.base);\n\t}\n\n\tif (args.dual_source_blending)\n\t{\n\t\tconst dxil_spv_option_dual_source_blending helper = { { DXIL_SPV_OPTION_DUAL_SOURCE_BLENDING }, DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &helper.base);\n\t}\n\n\tconst dxil_spv_option_output_swizzle swizzle = { { DXIL_SPV_OPTION_OUTPUT_SWIZZLE },\n\t\t                                             args.swizzles.data(),\n\t\t                                             unsigned(args.swizzles.size()) };\n\tdxil_spv_converter_add_option(converter, &swizzle.base);\n\n\tif (args.root_constant_inline_ubo)\n\t{\n\t\tconst dxil_spv_option_root_constant_inline_uniform_block inline_block = {\n\t\t\t{ DXIL_SPV_OPTION_ROOT_CONSTANT_INLINE_UNIFORM_BLOCK },\n\t\t\targs.root_constant_inline_ubo_desc_set,\n\t\t\targs.root_constant_inline_ubo_binding,\n\t\t\tDXIL_SPV_TRUE\n\t\t};\n\t\tdxil_spv_converter_add_option(converter, &inline_block.base);\n\t}\n\n\tif (args.bindless_cbv_as_ssbo)\n\t{\n\t\tconst dxil_spv_option_bindless_cbv_ssbo_emulation cbv = { { DXIL_SPV_OPTION_BINDLESS_CBV_SSBO_EMULATION },\n\t\t\t                                                      DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &cbv.base);\n\t}\n\n\tif (remapper.bindless || !remapper.root_descriptors.empty() || local_root_signature)\n\t{\n\t\tconst dxil_spv_option_physical_storage_buffer phys = { { DXIL_SPV_OPTION_PHYSICAL_STORAGE_BUFFER },\n\t\t\t                                                   remapper.bda ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &phys.base);\n\t}\n\n\t{\n\t\tdxil_spv_option_ssbo_alignment align = { { DXIL_SPV_OPTION_SSBO_ALIGNMENT }, args.ssbo_alignment };\n\t\tdxil_spv_converter_add_option(converter, &align.base);\n\t}\n\n\t{\n\t\tdxil_spv_option_typed_uav_read_without_format support = { { DXIL_SPV_OPTION_TYPED_UAV_READ_WITHOUT_FORMAT },\n\t\t                                                          args.typed_uav_read_without_format };\n\t\tdxil_spv_converter_add_option(converter, &support.base);\n\t}\n\n\t{\n\t\tdxil_spv_option_bindless_typed_buffer_offsets offsets = { { DXIL_SPV_OPTION_BINDLESS_TYPED_BUFFER_OFFSETS },\n\t\t\t                                                      args.bindless_typed_buffer_offsets ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &offsets.base);\n\t}\n\n\t{\n\t\tdxil_spv_option_storage_input_output_16bit storage = { { DXIL_SPV_OPTION_STORAGE_INPUT_OUTPUT_16BIT },\n\t\t                                                       args.storage_input_output_16bit ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &storage.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_descriptor_qa qa = { { DXIL_SPV_OPTION_DESCRIPTOR_QA },\n\t\t                                           args.descriptor_qa ? DXIL_SPV_TRUE : DXIL_SPV_FALSE,\n\t\t                                           DXIL_SPV_DESCRIPTOR_QA_INTERFACE_VERSION,\n\t\t                                           args.descriptor_qa_set, args.descriptor_qa_binding,\n\t\t                                           args.descriptor_qa_set, args.descriptor_qa_binding + 1,\n\t\t                                           args.shader_hash };\n\t\tdxil_spv_converter_add_option(converter, &qa.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_instruction_instrumentation inst = {\n\t\t\t{ DXIL_SPV_OPTION_INSTRUCTION_INSTRUMENTATION },\n\t\t\targs.instruction_instrumentation ? DXIL_SPV_TRUE : DXIL_SPV_FALSE,\n\t\t\tDXIL_SPV_INSTRUCTION_INSTRUMENTATION_INTERFACE_VERSION,\n\t\t\targs.instruction_instrumentation_set, args.instruction_instrumentation_binding,\n\t\t\targs.instruction_instrumentation_set, args.instruction_instrumentation_binding + 1,\n\t\t\targs.shader_hash,\n\t\t\targs.instruction_instrumentation_type,\n\t\t};\n\t\tdxil_spv_converter_add_option(converter, &inst.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_min_precision_native_16bit minprec = { { DXIL_SPV_OPTION_MIN_PRECISION_NATIVE_16BIT },\n\t\t                                                             args.min_precision_native_16bit ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &minprec.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_invariant_position invariant = { { DXIL_SPV_OPTION_INVARIANT_POSITION },\n\t\t                                                       args.invariant_position ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &invariant.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_scalar_block_layout scalar = { { DXIL_SPV_OPTION_SCALAR_BLOCK_LAYOUT },\n\t\t\t                                                 DXIL_SPV_TRUE, DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &scalar.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_barycentric_khr bary = { { DXIL_SPV_OPTION_BARYCENTRIC_KHR },\n\t\t\t\t\t\t\t\t\t\t\t\t\t   DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &bary.base);\n\t}\n\n\tif (args.robust_physical_cbv_load)\n\t{\n\t\tconst dxil_spv_option_robust_physical_cbv_load cbv = { { DXIL_SPV_OPTION_ROBUST_PHYSICAL_CBV_LOAD },\n\t\t                                                       DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &cbv.base);\n\t}\n\n\tif (args.allow_arithmetic_relaxed_precision)\n\t{\n\t\tconst dxil_spv_option_arithmetic_relaxed_precision relaxed = { { DXIL_SPV_OPTION_ARITHMETIC_RELAXED_PRECISION },\n\t\t                                                               DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &relaxed.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_physical_address_descriptor_indexing indexing = { { DXIL_SPV_OPTION_PHYSICAL_ADDRESS_DESCRIPTOR_INDEXING },\n\t\t                                                                        args.physical_address_indexing_stride,\n\t\t                                                                        args.physical_address_indexing_offset };\n\t\tdxil_spv_converter_add_option(converter, &indexing.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_denorm_preserve_support denorm = { { DXIL_SPV_OPTION_DENORM_PRESERVE_SUPPORT },\n\t\t                                                         DXIL_SPV_TRUE, DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &denorm.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_subgroup_partitioned_nv partitioned = { { DXIL_SPV_OPTION_SUBGROUP_PARTITIONED_NV },\n\t\t                                                              args.subgroup_partitioned_nv ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &partitioned.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_dead_code_eliminate eliminate = { { DXIL_SPV_OPTION_DEAD_CODE_ELIMINATE },\n\t\t                                                        args.dead_code_eliminate ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &eliminate.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_precise_control precise = { { DXIL_SPV_OPTION_PRECISE_CONTROL },\n\t\t                                                  args.force_precise ? DXIL_SPV_TRUE : DXIL_SPV_FALSE,\n\t\t                                                  args.propagate_precise ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &precise.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_opacity_micromap omm = { { DXIL_SPV_OPTION_OPACITY_MICROMAP },\n\t\t                                               args.opacity_micromap ? DXIL_SPV_TRUE : DXIL_SPV_FALSE };\n\t\tdxil_spv_converter_add_option(converter, &omm.base);\n\t}\n\n\t{\n\t\tdxil_spv_option_branch_control branch = { { DXIL_SPV_OPTION_BRANCH_CONTROL } };\n\t\tbranch.force_flatten = args.force_flatten ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\t\tbranch.force_loop = args.force_loop ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\t\tbranch.force_unroll = args.force_unroll ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\t\tbranch.force_branch = args.force_branch ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\t\tdxil_spv_converter_add_option(converter, &branch.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_subgroup_properties props = { { DXIL_SPV_OPTION_SUBGROUP_PROPERTIES },\n\t\t                                                    args.subgroup_size_minimum, args.subgroup_size_maximum };\n\t\tdxil_spv_converter_add_option(converter, &props.base);\n\t}\n\n\tif (args.descriptor_heap_robustness)\n\t{\n\t\tconst dxil_spv_option_descriptor_heap_robustness robustness = { { DXIL_SPV_OPTION_DESCRIPTOR_HEAP_ROBUSTNESS },\n\t\t\t                                                            DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &robustness.base);\n\t}\n\n\t{\n\t\tconst dxil_spv_option_compute_shader_derivatives derivs = {\n\t\t\t{ DXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES },\n\t\t\targs.compute_shader_derivatives ? DXIL_SPV_TRUE : DXIL_SPV_FALSE,\n\t\t\targs.compute_shader_derivatives ? DXIL_SPV_TRUE : DXIL_SPV_FALSE,\n\t\t};\n\t\tdxil_spv_converter_add_option(converter, &derivs.base);\n\n\t\tif (args.compute_shader_derivatives)\n\t\t{\n\t\t\tconst dxil_spv_option_compute_shader_derivatives_quad quad = {\n\t\t\t\t{ DXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES_QUAD }, DXIL_SPV_TRUE,\n\t\t\t};\n\t\t\tdxil_spv_converter_add_option(converter, &quad.base);\n\t\t}\n\t}\n\n\t{\n\t\tdxil_spv_option_quad_control_reconvergence reconv = {\n\t\t\t{ DXIL_SPV_OPTION_QUAD_CONTROL_RECONVERGENCE } };\n\n\t\treconv.force_maximal_reconvergence = args.force_maximal_reconvergence ?\n\t\t                                     DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\t\treconv.supports_maximal_reconvergence =\n\t\t    (args.quad_control_maximal_reconvergence || args.force_maximal_reconvergence) ?\n\t\t        DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\t\treconv.supports_quad_control = args.quad_control_maximal_reconvergence;\n\t\tdxil_spv_converter_add_option(converter, &reconv.base);\n\t}\n\n\tif (args.raw_access_chains_nv)\n\t{\n\t\tconst dxil_spv_option_raw_access_chains_nv chain = {\n\t\t\t{ DXIL_SPV_OPTION_RAW_ACCESS_CHAINS_NV }, DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &chain.base);\n\t}\n\n\tif (args.extended_robustness)\n\t{\n\t\tdxil_spv_option_extended_robustness robust = {\n\t\t\t{ DXIL_SPV_OPTION_EXTENDED_ROBUSTNESS } };\n\t\trobust.robust_constant_lut = DXIL_SPV_TRUE;\n\t\trobust.robust_alloca = DXIL_SPV_TRUE;\n\t\tdxil_spv_converter_add_option(converter, &robust.base);\n\t}\n\n\tif (args.vkmm)\n\t{\n\t\tdxil_spv_option_extended_robustness vkmm = {\n\t\t\t{ DXIL_SPV_OPTION_VULKAN_MEMORY_MODEL }, DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &vkmm.base);\n\t}\n\n\tif (args.wmma_fp8 || args.wmma_nv_coopmat2)\n\t{\n\t\tdxil_spv_option_float8_support wmma = {\n\t\t\t{ DXIL_SPV_OPTION_FLOAT8_SUPPORT }, args.wmma_fp8, args.wmma_nv_coopmat2};\n\t\tdxil_spv_converter_add_option(converter, &wmma.base);\n\t}\n\n\tif (args.nvapi)\n\t{\n\t\tdxil_spv_option_nvapi extn = {{ DXIL_SPV_OPTION_NVAPI }};\n\t\textn.enabled = DXIL_SPV_TRUE;\n\t\textn.register_index = args.nvapi_register_index;\n\t\textn.register_space = args.nvapi_register_space;\n\t\tdxil_spv_converter_add_option(converter, &extn.base);\n\t}\n\n\tif (args.non_semantic)\n\t{\n\t\tdxil_spv_option_extended_non_semantic sem = {{ DXIL_SPV_OPTION_EXTENDED_NON_SEMANTIC }, DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &sem.base);\n\t}\n\n\tif (args.mixed_float_dot_product)\n\t{\n\t\tdxil_spv_option_mixed_float_dot_product mixed = {{ DXIL_SPV_OPTION_MIXED_FLOAT_DOT_PRODUCT }, DXIL_SPV_TRUE };\n\t\tdxil_spv_converter_add_option(converter, &mixed.base);\n\t}\n\n\tif (args.view_instancing)\n\t{\n\t\tdxil_spv_option_view_instancing inst = {{ DXIL_SPV_OPTION_VIEW_INSTANCING }};\n\t\tinst.enabled = DXIL_SPV_TRUE;\n\t\tinst.last_pre_rasterization_stage = args.view_instancing_last_pre_rasterization_stage;\n\t\tinst.view_index_to_view_instance_spec_id = args.view_index_to_view_instance_spec_id;\n\t\tinst.view_instance_to_viewport_spec_id = args.view_instance_to_viewport_spec_id;\n\t\tdxil_spv_converter_add_option(converter, &inst.base);\n\t}\n\n\tfor (auto &quirk : args.quirks)\n\t{\n\t\tdxil_spv_option_shader_quirk helper = {\n\t\t\t{ DXIL_SPV_OPTION_SHADER_QUIRK }, quirk };\n\t\tdxil_spv_converter_add_option(converter, &helper.base);\n\t}\n\n\tfor (auto &meta : args.meta_descriptors)\n\t\tdxil_spv_converter_set_meta_descriptor(converter, meta.meta, meta.kind, meta.desc_set, meta.desc_binding);\n\n\tdxil_spv_converter_add_option(converter, &args.offset_buffer_layout.base);\n\n\tunsigned num_entry_points = 1;\n\tif (args.debug_all_entry_points)\n\t\tdxil_spv_parsed_blob_get_num_entry_points(blob, &num_entry_points);\n\n\tstd::string final_output;\n\n\tfor (unsigned entry_point = 0; entry_point < num_entry_points; entry_point++)\n\t{\n\t\tconst char *demangled_entry = nullptr;\n\t\tif (args.debug_all_entry_points)\n\t\t{\n\t\t\tdxil_spv_parsed_blob_get_entry_point_demangled_name(blob, entry_point, &demangled_entry);\n\t\t\tdxil_spv_converter_set_entry_point(converter, demangled_entry);\n\t\t}\n\t\telse if (!args.entry_point.empty())\n\t\t\tdxil_spv_converter_set_entry_point(converter, args.entry_point.c_str());\n\n\t\tif (dxil_spv_converter_run(converter) != DXIL_SPV_SUCCESS)\n\t\t{\n\t\t\tLOGE(\"Failed to convert DXIL to SPIR-V.\\n\");\n\t\t\treturn EXIT_FAILURE;\n\t\t}\n\n\t\tdxil_spv_compiled_spirv compiled;\n\t\tif (dxil_spv_converter_get_compiled_spirv(converter, &compiled) != DXIL_SPV_SUCCESS)\n\t\t\treturn EXIT_FAILURE;\n\n\t\tunsigned heuristic_min_wave_size = 0;\n\t\tunsigned heuristic_max_wave_size = 0;\n\t\tunsigned wave_size_min = 0;\n\t\tunsigned wave_size_max = 0;\n\t\tunsigned wave_size_preferred = 0;\n\t\tdxil_spv_converter_get_compute_wave_size_range(converter, &wave_size_min, &wave_size_max, &wave_size_preferred);\n\t\tdxil_spv_converter_get_compute_heuristic_min_wave_size(converter, &heuristic_min_wave_size);\n\t\tdxil_spv_converter_get_compute_heuristic_max_wave_size(converter, &heuristic_max_wave_size);\n\n\t\tif (args.validate)\n\t\t{\n\t\t\tif (!validate_spirv(compiled.data, compiled.size))\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to validate SPIR-V.\\n\");\n\t\t\t\treturn EXIT_FAILURE;\n\t\t\t}\n\t\t}\n\n\t\tstd::string spirv_asm_string;\n\n\t\tif (args.emit_asm || (!args.glsl && args.output_path.empty()))\n\t\t{\n\t\t\tif (wave_size_min)\n\t\t\t{\n\t\t\t\tspirv_asm_string += \"// WaveSize(\";\n\t\t\t\tspirv_asm_string += std::to_string(wave_size_min);\n\t\t\t\tif (wave_size_max || wave_size_preferred)\n\t\t\t\t\tspirv_asm_string += \",\" + std::to_string(wave_size_max ? wave_size_max : wave_size_min);\n\t\t\t\tif (wave_size_preferred)\n\t\t\t\t\tspirv_asm_string += \",\" + std::to_string(wave_size_preferred);\n\t\t\t\tspirv_asm_string += \")\\n\";\n\t\t\t}\n\n\t\t\tif (heuristic_min_wave_size)\n\t\t\t{\n\t\t\t\tspirv_asm_string += \"// HeuristicWaveSizeMin(\";\n\t\t\t\tspirv_asm_string += std::to_string(heuristic_min_wave_size);\n\t\t\t\tspirv_asm_string += \")\\n\";\n\t\t\t}\n\n\t\t\tif (heuristic_max_wave_size)\n\t\t\t{\n\t\t\t\tspirv_asm_string += \"// HeuristicWaveSize(\";\n\t\t\t\tspirv_asm_string += std::to_string(heuristic_max_wave_size);\n\t\t\t\tspirv_asm_string += \")\\n\";\n\t\t\t}\n\n\t\t\tdxil_spv_bool compat;\n\t\t\tif (dxil_spv_converter_is_multiview_compatible(converter, &compat) == DXIL_SPV_SUCCESS && compat)\n\t\t\t\tspirv_asm_string += \"// MultiviewCompatible\\n\";\n\n\t\t\tif (demangled_entry && !args.glsl)\n\t\t\t{\n\t\t\t\tspirv_asm_string += \"// ========== \";\n\t\t\t\tspirv_asm_string += demangled_entry;\n\t\t\t\tspirv_asm_string += \" ==========\\n\";\n\t\t\t}\n\t\t\tspirv_asm_string += convert_to_asm(compiled.data, compiled.size);\n\t\t\tif (demangled_entry && !args.glsl)\n\t\t\t\tspirv_asm_string += \"// ==================\\n\";\n\t\t}\n\n\t\tif (args.glsl)\n\t\t{\n\t\t\tauto compiled_glsl = convert_to_glsl(compiled.data, compiled.size);\n\n\t\t\tif (compiled_glsl.empty())\n\t\t\t{\n\t\t\t\tLOGE(\"Failed to convert to GLSL.\\n\");\n\t\t\t\treturn EXIT_FAILURE;\n\t\t\t}\n\n\t\t\tconst char *warn = dxil_spv_converter_get_analysis_warnings(converter);\n\t\t\tif (warn && *warn != '\\0')\n\t\t\t{\n\t\t\t\tcompiled_glsl += \"/* WARNINGS:\\n\";\n\t\t\t\tcompiled_glsl += warn;\n\t\t\t\tcompiled_glsl += \"*/\\n\\n\";\n\t\t\t}\n\n\t\t\tif (!spirv_asm_string.empty())\n\t\t\t{\n\t\t\t\tcompiled_glsl += \"\\n#if 0\\n\";\n\t\t\t\tcompiled_glsl += \"// SPIR-V disassembly\\n\";\n\t\t\t\tcompiled_glsl += spirv_asm_string;\n\t\t\t\tcompiled_glsl += \"#endif\";\n\t\t\t}\n\n\t\t\tstd::string output;\n\t\t\tif (demangled_entry)\n\t\t\t{\n\t\t\t\toutput += \"// ========= \";\n\t\t\t\toutput += demangled_entry;\n\t\t\t\toutput += \" =========\\n\";\n\t\t\t\toutput += compiled_glsl;\n\t\t\t\toutput += \"\\n// =================\\n\";\n\t\t\t}\n\t\t\telse\n\t\t\t\toutput = std::move(compiled_glsl);\n\n\t\t\tfinal_output += output;\n\t\t}\n\t\telse if (args.emit_asm || args.output_path.empty())\n\t\t{\n\t\t\tfinal_output += spirv_asm_string;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (demangled_entry)\n\t\t\t{\n\t\t\t\tLOGE(\"Cannot emit binary output when using debug-all-entry-points.\\n\");\n\t\t\t\treturn EXIT_FAILURE;\n\t\t\t}\n\n\t\t\tFILE *file = fopen(args.output_path.c_str(), \"wb\");\n\t\t\tif (file)\n\t\t\t{\n\t\t\t\tif (fwrite(compiled.data, 1, compiled.size, file) != compiled.size)\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to write SPIR-V.\\n\");\n\t\t\t\t\treturn EXIT_FAILURE;\n\t\t\t\t}\n\t\t\t\tfclose(file);\n\t\t\t}\n\t\t\telse\n\t\t\t\tLOGE(\"Failed to open %s.\\n\", args.output_path.c_str());\n\t\t}\n\t}\n\n\t// Dump debug output of RDAT objects if we have them.\n\tif (args.glsl || args.emit_asm)\n\t{\n\t\tunsigned num_subobjects = dxil_spv_parsed_blob_get_num_rdat_subobjects(blob);\n\t\tif (num_subobjects > 0)\n\t\t{\n\t\t\tfinal_output += \"\\n#if 0\\n==== RDAT ====\\n\";\n\t\t\tfor (unsigned i = 0; i < num_subobjects; i++)\n\t\t\t{\n\t\t\t\tdxil_spv_rdat_subobject obj;\n\t\t\t\tdxil_spv_parsed_blob_get_rdat_subobject(blob, i, &obj);\n\t\t\t\tswitch (obj.kind)\n\t\t\t\t{\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_STATE_OBJECT_CONFIG:\n\t\t\t\t\tfinal_output += \"ShaderConfig \";\n\t\t\t\t\tfinal_output += obj.subobject_name;\n\t\t\t\t\tfinal_output += \" = { flags = \";\n\t\t\t\t\tfinal_output += std::to_string(obj.args[0]);\n\t\t\t\t\tfinal_output += \" };\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_SHADER_CONFIG:\n\t\t\t\t\tfinal_output += \"ShaderConfig \";\n\t\t\t\t\tfinal_output += obj.subobject_name;\n\t\t\t\t\tfinal_output += \" = { maxPayloadSize = \";\n\t\t\t\t\tfinal_output += std::to_string(obj.args[0]);\n\t\t\t\t\tfinal_output += \", maxAttributeSize = \";\n\t\t\t\t\tfinal_output += std::to_string(obj.args[1]);\n\t\t\t\t\tfinal_output += \" };\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG:\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1:\n\t\t\t\t\tfinal_output += \"RaytracingPipelineConfig1 \";\n\t\t\t\t\tfinal_output += obj.subobject_name;\n\t\t\t\t\tfinal_output += \" = { maxRecursion = \";\n\t\t\t\t\tfinal_output += std::to_string(obj.args[0]);\n\t\t\t\t\tfinal_output += \", flags = \";\n\t\t\t\t\tfinal_output += std::to_string(obj.args[1]);\n\t\t\t\t\tfinal_output += \" };\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE:\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_LOCAL_ROOT_SIGNATURE:\n\t\t\t\t\tfinal_output += obj.kind == DXIL_SPV_RDAT_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE ?\n\t\t\t\t\t\t\t\"GlobalRootSignature \" : \"LocalRootSignature \";\n\t\t\t\t\tfinal_output += obj.subobject_name;\n\t\t\t\t\tfinal_output += \" = { \";\n\t\t\t\t\tfinal_output += std::to_string(obj.payload_size);\n\t\t\t\t\tfinal_output += \" bytes };\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_HIT_GROUP:\n\t\t\t\t\tfinal_output += obj.hit_group_type == DXIL_SPV_HIT_GROUP_TYPE_TRIANGLE ?\n\t\t\t\t\t\t\t\"TriangleHitGroup \" : \"ProceduralHitGroup \";\n\t\t\t\t\tfinal_output += obj.subobject_name;\n\t\t\t\t\tassert(obj.num_exports == 3);\n\t\t\t\t\tfinal_output += \" = { ahit = \\\"\";\n\t\t\t\t\tfinal_output += obj.exports[0];\n\t\t\t\t\tfinal_output += \"\\\", chit = \\\"\";\n\t\t\t\t\tfinal_output += obj.exports[1];\n\t\t\t\t\tfinal_output += \"\\\", intersection = \\\"\";\n\t\t\t\t\tfinal_output += obj.exports[2];\n\t\t\t\t\tfinal_output += \"\\\" };\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase DXIL_SPV_RDAT_SUBOBJECT_KIND_SUBOBJECT_TO_EXPORTS_ASSOCIATION:\n\t\t\t\t\tfinal_output += \"SubobjectToExportsAssociation \";\n\t\t\t\t\tfinal_output += obj.subobject_name;\n\t\t\t\t\tfinal_output += \" = { \";\n\t\t\t\t\tassert(obj.num_exports >= 1);\n\t\t\t\t\tfinal_output += obj.exports[0];\n\t\t\t\t\tfinal_output += \", { \";\n\t\t\t\t\tfor (unsigned j = 1; j < obj.num_exports; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal_output += obj.exports[j];\n\t\t\t\t\t\tif (j + 1 < obj.num_exports)\n\t\t\t\t\t\t\tfinal_output += \", \";\n\t\t\t\t\t}\n\t\t\t\t\tfinal_output += \" } };\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinal_output += \"============\\n#endif\";\n\t\t}\n\t}\n\n\tif (args.output_path.empty())\n\t{\n\t\tprintf(\"%s\\n\", final_output.c_str());\n\t}\n\telse if (!final_output.empty())\n\t{\n\t\tFILE *file = fopen(args.output_path.c_str(), \"w\");\n\t\tif (!file)\n\t\t{\n\t\t\tLOGE(\"Failed to open %s for writing.\\n\", args.output_path.c_str());\n\t\t\treturn EXIT_FAILURE;\n\t\t}\n\t\tfprintf(file, \"%s\\n\", final_output.c_str());\n\t\tfclose(file);\n\t}\n\n\tdxil_spv_converter_free(converter);\n\tdxil_spv_parsed_blob_free(blob);\n\tif (reflection_blob)\n\t\tdxil_spv_parsed_blob_free(reflection_blob);\n\tdxil_spv_end_thread_allocator_context();\n\treturn EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "dxil_spirv_c.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#define DXIL_SPV_ENABLE_EXPERIMENTAL_WORKGRAPHS\n#define DXIL_SPV_ENABLE_EXPERIMENTAL_MULTIVIEW\n#include \"thread_local_allocator.hpp\"\n#include \"dxil_spirv_c.h\"\n#include \"dxil_converter.hpp\"\n#include \"dxil_parser.hpp\"\n#include \"llvm_bitcode_parser.hpp\"\n#include \"logging.hpp\"\n#include \"spirv_module.hpp\"\n#include <string.h>\n#include <new>\n\nusing namespace dxil_spv;\n\nvoid dxil_spv_get_version(unsigned *major, unsigned *minor, unsigned *patch)\n{\n\t*major = DXIL_SPV_API_VERSION_MAJOR;\n\t*minor = DXIL_SPV_API_VERSION_MINOR;\n\t*patch = DXIL_SPV_API_VERSION_PATCH;\n}\n\nstruct dxil_spv_parsed_blob_s\n{\n\tLLVMBCParser bc;\n#ifdef HAVE_LLVMBC\n\tString disasm;\n#else\n\tstd::string disasm;\n#endif\n\tVector<uint8_t> dxil_blob;\n\tVector<RDATSubobject> rdat_subobjects;\n\n\tstruct EntryPoint\n\t{\n\t\tString mangled;\n\t\tString demangled;\n\t\tNodeInputData node_input;\n\t\tVector<NodeOutputData> node_outputs;\n\t};\n\tVector<EntryPoint> entry_points;\n};\n\nstruct Remapper : ResourceRemappingInterface\n{\n\tstatic void copy_buffer_binding(VulkanBinding &vk_binding, const dxil_spv_vulkan_binding &c_vk_binding)\n\t{\n\t\tvk_binding.descriptor_set = c_vk_binding.set;\n\t\tvk_binding.binding = c_vk_binding.binding;\n\t\tvk_binding.root_constant_index = c_vk_binding.root_constant_index;\n\t\tvk_binding.bindless.use_heap = bool(c_vk_binding.bindless.use_heap);\n\t\tvk_binding.bindless.heap_root_offset = c_vk_binding.bindless.heap_root_offset;\n\t\tvk_binding.descriptor_type = static_cast<VulkanDescriptorType>(c_vk_binding.descriptor_type);\n\t}\n\n\tbool remap_srv(const D3DBinding &binding, VulkanSRVBinding &vk_binding) override\n\t{\n\t\tif (srv_remapper)\n\t\t{\n\t\t\tconst dxil_spv_d3d_binding c_binding = { static_cast<dxil_spv_shader_stage>(binding.stage),\n\t\t\t\t                                     static_cast<dxil_spv_resource_kind>(binding.kind),\n\t\t\t\t                                     binding.resource_index,\n\t\t\t\t                                     binding.register_space,\n\t\t\t\t                                     binding.register_index,\n\t\t\t\t                                     binding.range_size,\n\t\t\t\t                                     binding.alignment };\n\n\t\t\tdxil_spv_srv_vulkan_binding c_vk_binding = {};\n\t\t\tif (srv_remapper(srv_userdata, &c_binding, &c_vk_binding) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tcopy_buffer_binding(vk_binding.buffer_binding, c_vk_binding.buffer_binding);\n\t\t\t\tcopy_buffer_binding(vk_binding.offset_binding, c_vk_binding.offset_binding);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvk_binding.buffer_binding.bindless.use_heap = false;\n\t\t\tvk_binding.buffer_binding.descriptor_set = binding.register_space;\n\t\t\tvk_binding.buffer_binding.binding = binding.register_index;\n\t\t\tvk_binding.buffer_binding.descriptor_type = VulkanDescriptorType::Identity;\n\t\t\tvk_binding.offset_binding = {};\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tbool remap_sampler(const D3DBinding &binding, VulkanBinding &vk_binding) override\n\t{\n\t\tif (sampler_remapper)\n\t\t{\n\t\t\tconst dxil_spv_d3d_binding c_binding = { static_cast<dxil_spv_shader_stage>(binding.stage),\n\t\t\t\t                                     static_cast<dxil_spv_resource_kind>(binding.kind),\n\t\t\t\t                                     binding.resource_index,\n\t\t\t\t                                     binding.register_space,\n\t\t\t\t                                     binding.register_index,\n\t\t\t\t                                     binding.range_size,\n\t\t\t\t                                     binding.alignment };\n\n\t\t\tdxil_spv_vulkan_binding c_vk_binding = {};\n\t\t\tif (sampler_remapper(sampler_userdata, &c_binding, &c_vk_binding) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tcopy_buffer_binding(vk_binding, c_vk_binding);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvk_binding.bindless.use_heap = false;\n\t\t\tvk_binding.descriptor_set = binding.register_space;\n\t\t\tvk_binding.binding = binding.register_index;\n\t\t\tvk_binding.descriptor_type = VulkanDescriptorType::Identity;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tbool remap_uav(const D3DUAVBinding &binding, VulkanUAVBinding &vk_binding) override\n\t{\n\t\tif (uav_remapper)\n\t\t{\n\t\t\tconst dxil_spv_uav_d3d_binding c_binding = {\n\t\t\t\t{ static_cast<dxil_spv_shader_stage>(binding.binding.stage),\n\t\t\t\t  static_cast<dxil_spv_resource_kind>(binding.binding.kind), binding.binding.resource_index,\n\t\t\t\t  binding.binding.register_space, binding.binding.register_index, binding.binding.range_size,\n\t\t\t\t  binding.binding.alignment },\n\t\t\t\tbinding.counter ? DXIL_SPV_TRUE : DXIL_SPV_FALSE\n\t\t\t};\n\n\t\t\tdxil_spv_uav_vulkan_binding c_vk_binding = {};\n\t\t\tif (uav_remapper(uav_userdata, &c_binding, &c_vk_binding) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tcopy_buffer_binding(vk_binding.buffer_binding, c_vk_binding.buffer_binding);\n\t\t\t\tcopy_buffer_binding(vk_binding.counter_binding, c_vk_binding.counter_binding);\n\t\t\t\tcopy_buffer_binding(vk_binding.offset_binding, c_vk_binding.offset_binding);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvk_binding.buffer_binding.bindless.use_heap = false;\n\t\t\tvk_binding.counter_binding.bindless.use_heap = false;\n\t\t\tvk_binding.buffer_binding.descriptor_set = binding.binding.register_space;\n\t\t\tvk_binding.buffer_binding.binding = binding.binding.register_index;\n\t\t\tvk_binding.counter_binding.descriptor_set = binding.binding.register_space + 1;\n\t\t\tvk_binding.counter_binding.binding = binding.binding.register_index;\n\t\t\tvk_binding.buffer_binding.descriptor_type = VulkanDescriptorType::Identity;\n\t\t\tvk_binding.counter_binding.descriptor_type = VulkanDescriptorType::Identity;\n\t\t\tvk_binding.offset_binding = {};\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tbool remap_cbv(const D3DBinding &binding, VulkanCBVBinding &vk_binding) override\n\t{\n\t\tif (cbv_remapper)\n\t\t{\n\t\t\tconst dxil_spv_d3d_binding c_binding = { static_cast<dxil_spv_shader_stage>(binding.stage),\n\t\t\t\t                                     static_cast<dxil_spv_resource_kind>(binding.kind),\n\t\t\t\t                                     binding.resource_index,\n\t\t\t\t                                     binding.register_space,\n\t\t\t\t                                     binding.register_index,\n\t\t\t\t                                     binding.range_size,\n\t\t\t\t                                     binding.alignment };\n\n\t\t\tdxil_spv_cbv_vulkan_binding c_vk_binding = {};\n\t\t\tif (cbv_remapper(cbv_userdata, &c_binding, &c_vk_binding) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tvk_binding.push_constant = c_vk_binding.push_constant;\n\t\t\t\tif (vk_binding.push_constant)\n\t\t\t\t\tvk_binding.push.offset_in_words = c_vk_binding.vulkan.push_constant.offset_in_words;\n\t\t\t\telse\n\t\t\t\t\tcopy_buffer_binding(vk_binding.buffer, c_vk_binding.vulkan.uniform_binding);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvk_binding.buffer.bindless.use_heap = false;\n\t\t\tvk_binding.buffer.descriptor_set = binding.register_space;\n\t\t\tvk_binding.buffer.binding = binding.register_index;\n\t\t\tvk_binding.buffer.descriptor_type = VulkanDescriptorType::Identity;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tbool remap_vertex_input(const D3DStageIO &d3d_input, VulkanStageIO &vk_input) override\n\t{\n\t\tdxil_spv_d3d_vertex_input c_input = { d3d_input.semantic, d3d_input.semantic_index, d3d_input.start_row,\n\t\t\t                                  d3d_input.rows };\n\t\tdxil_spv_vulkan_vertex_input c_vk_input = {};\n\n\t\tif (input_remapper)\n\t\t{\n\t\t\tif (input_remapper(input_userdata, &c_input, &c_vk_input) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tvk_input.location = c_vk_input.location;\n\t\t\t\tvk_input.component = 0;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvk_input.location = d3d_input.start_row;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tbool remap_stream_output(const D3DStreamOutput &d3d_output, VulkanStreamOutput &vk_output) override\n\t{\n\t\tdxil_spv_d3d_stream_output c_output = { d3d_output.semantic, d3d_output.semantic_index };\n\t\tdxil_spv_vulkan_stream_output c_vk_output = {};\n\n\t\tif (output_remapper)\n\t\t{\n\t\t\tif (output_remapper(output_userdata, &c_output, &c_vk_output) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tvk_output.enable = bool(c_vk_output.enable);\n\t\t\t\tvk_output.offset = c_vk_output.offset;\n\t\t\t\tvk_output.stride = c_vk_output.stride;\n\t\t\t\tvk_output.buffer_index = c_vk_output.buffer_index;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tbool remap_stage_input(const D3DStageIO &d3d_input, VulkanStageIO &vk_input) override\n\t{\n\t\tdxil_spv_d3d_shader_stage_io c_input = { d3d_input.semantic, d3d_input.semantic_index };\n\t\tdxil_spv_vulkan_shader_stage_io c_vk_input = { vk_input.location, vk_input.component, vk_input.flags };\n\n\t\tif (stage_input_remapper)\n\t\t{\n\t\t\tif (stage_input_remapper(stage_input_userdata, &c_input, &c_vk_input) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tvk_input.location = c_vk_input.location;\n\t\t\t\tvk_input.component = c_vk_input.component;\n\t\t\t\tvk_input.flags = c_vk_input.flags;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tbool has_nontrivial_stage_input_remapping() override\n\t{\n\t\treturn stage_input_remapper != nullptr;\n\t}\n\n\tbool remap_stage_output(const D3DStageIO &d3d_output, VulkanStageIO &vk_output) override\n\t{\n\t\tdxil_spv_d3d_shader_stage_io c_output = { d3d_output.semantic, d3d_output.semantic_index };\n\t\tdxil_spv_vulkan_shader_stage_io c_vk_output = { vk_output.location, vk_output.component, vk_output.flags };\n\n\t\tif (stage_output_remapper)\n\t\t{\n\t\t\tif (stage_output_remapper(stage_output_userdata, &c_output, &c_vk_output) == DXIL_SPV_TRUE)\n\t\t\t{\n\t\t\t\tvk_output.location = c_vk_output.location;\n\t\t\t\tvk_output.component = c_vk_output.component;\n\t\t\t\tvk_output.flags = c_vk_output.flags;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tunsigned get_root_constant_word_count() override\n\t{\n\t\treturn root_constant_word_count;\n\t}\n\n\tunsigned get_root_descriptor_count() override\n\t{\n\t\treturn root_descriptor_count;\n\t}\n\n\tdxil_spv_srv_remapper_cb srv_remapper = nullptr;\n\tvoid *srv_userdata = nullptr;\n\n\tdxil_spv_sampler_remapper_cb sampler_remapper = nullptr;\n\tvoid *sampler_userdata = nullptr;\n\n\tdxil_spv_uav_remapper_cb uav_remapper = nullptr;\n\tvoid *uav_userdata = nullptr;\n\n\tdxil_spv_cbv_remapper_cb cbv_remapper = nullptr;\n\tvoid *cbv_userdata = nullptr;\n\n\tdxil_spv_vertex_input_remapper_cb input_remapper = nullptr;\n\tvoid *input_userdata = nullptr;\n\n\tdxil_spv_stream_output_remapper_cb output_remapper = nullptr;\n\tvoid *output_userdata = nullptr;\n\n\tdxil_spv_shader_stage_io_remapper_cb stage_input_remapper = nullptr;\n\tvoid *stage_input_userdata = nullptr;\n\n\tdxil_spv_shader_stage_io_remapper_cb stage_output_remapper = nullptr;\n\tvoid *stage_output_userdata = nullptr;\n\n\tunsigned root_constant_word_count = 0;\n\tunsigned root_descriptor_count = 0;\n};\n\nenum class LocalRootParameterType\n{\n\tConstants,\n\tDescriptor,\n\tTable\n};\n\nstruct LocalConstants\n{\n\tunsigned register_space;\n\tunsigned register_index;\n\tunsigned num_words;\n};\n\nstruct LocalDescriptor\n{\n\tResourceClass resource_class;\n\tunsigned register_space;\n\tunsigned register_index;\n};\n\nstruct LocalRootParameter\n{\n\tLocalRootParameterType type;\n\tLocalConstants local_constants;\n\tLocalDescriptor local_descriptor;\n\tVector<DescriptorTableEntry> table_entries;\n};\n\nstruct dxil_spv_converter_s\n{\n\tdxil_spv_converter_s(LLVMBCParser &bc_parser_, LLVMBCParser *bc_reflection_parser_)\n\t\t: bc_parser(bc_parser_), bc_reflection_parser(bc_reflection_parser_)\n\t{\n\t}\n\n\tLLVMBCParser &bc_parser;\n\tLLVMBCParser *bc_reflection_parser;\n\tVector<uint32_t> spirv;\n\tString entry_point;\n\tString compiled_entry_point;\n\tString analysis_warnings;\n\tRemapper remapper;\n\n\tVector<LocalRootParameter> local_root_parameters;\n\n\tVector<std::unique_ptr<OptionBase>> options;\n\n\tstruct MetaDescriptorMapping\n\t{\n\t\tMetaDescriptor meta;\n\t\tMetaDescriptorKind kind;\n\t\tuint32_t desc_set;\n\t\tuint32_t desc_binding;\n\t};\n\tVector<MetaDescriptorMapping> meta_mappings;\n\n\tVector<DescriptorTableEntry> local_entries;\n\tbool active_table = false;\n\tbool uses_subgroup_size = false;\n\tbool is_multiview_compatible = false;\n\tuint32_t workgroup_size[3] = {};\n\tuint32_t patch_vertex_count = 0;\n    uint32_t patch_location_offset = UINT32_MAX;\n\tuint32_t wave_size_min = 0;\n\tuint32_t wave_size_max = 0;\n\tuint32_t wave_size_preferred = 0;\n\tuint32_t heuristic_min_wave_size = 0;\n\tuint32_t heuristic_max_wave_size = 0;\n\tVector<std::pair<unsigned, unsigned>> root_parameter_mappings;\n\tVector<NonSemanticDebugInfo> non_semantic_debug_info;\n\tbool shader_feature_used[unsigned(ShaderFeature::Count)] = {};\n};\n\ndxil_spv_result dxil_spv_parse_dxil_blob(const void *data, size_t size, dxil_spv_parsed_blob *blob)\n{\n\tauto *parsed = new (std::nothrow) dxil_spv_parsed_blob_s;\n\tif (!parsed)\n\t\treturn DXIL_SPV_ERROR_OUT_OF_MEMORY;\n\n\tDXILContainerParser parser;\n\tif (!parser.parse_container(data, size, false))\n\t{\n\t\tdelete parsed;\n\t\treturn DXIL_SPV_ERROR_PARSER;\n\t}\n\n\tparsed->dxil_blob = std::move(parser.get_blob());\n\tparsed->rdat_subobjects = std::move(parser.get_rdat_subobjects());\n\n\tbool success;\n\n\tif (parser.is_dxbc_binary())\n\t\tsuccess = parsed->bc.parseDXBCBinary(data, size);\n\telse\n\t\tsuccess = parsed->bc.parse(parsed->dxil_blob.data(), parsed->dxil_blob.size());\n\n\tif (!success)\n\t{\n\t\tdelete parsed;\n\t\treturn DXIL_SPV_ERROR_PARSER;\n\t}\n\n\tauto names = Converter::get_entry_points(parsed->bc);\n\tfor (auto &name : names)\n\t{\n\t\tparsed->entry_points.push_back({\n\t\t\tname, demangle_entry_point(name),\n\t\t\tConverter::get_node_input(parsed->bc, name.c_str()),\n\t\t\tConverter::get_node_outputs(parsed->bc, name.c_str())\n\t\t});\n\t}\n\n\t*blob = parsed;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parse_reflection_dxil_blob(const void *data, size_t size, dxil_spv_parsed_blob *blob)\n{\n\tauto *parsed = new (std::nothrow) dxil_spv_parsed_blob_s;\n\tif (!parsed)\n\t\treturn DXIL_SPV_ERROR_OUT_OF_MEMORY;\n\n\tDXILContainerParser parser;\n\tif (!parser.parse_container(data, size, true))\n\t{\n\t\tdelete parsed;\n\t\treturn DXIL_SPV_ERROR_PARSER;\n\t}\n\n\tif (parser.get_blob().empty())\n\t{\n\t\tdelete parsed;\n\t\treturn DXIL_SPV_ERROR_NO_DATA;\n\t}\n\n\tparsed->dxil_blob = std::move(parser.get_blob());\n\n\tif (!parsed->bc.parse(parsed->dxil_blob.data(), parsed->dxil_blob.size()))\n\t{\n\t\tdelete parsed;\n\t\treturn DXIL_SPV_ERROR_PARSER;\n\t}\n\n\t*blob = parsed;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parse_dxil(const void *data, size_t size, dxil_spv_parsed_blob *blob)\n{\n\tauto *parsed = new (std::nothrow) dxil_spv_parsed_blob_s;\n\tif (!parsed)\n\t\treturn DXIL_SPV_ERROR_OUT_OF_MEMORY;\n\n\tif (!parsed->bc.parse(data, size))\n\t{\n\t\tdelete parsed;\n\t\treturn DXIL_SPV_ERROR_PARSER;\n\t}\n\n\tauto names = Converter::get_entry_points(parsed->bc);\n\tfor (auto &name : names)\n\t{\n\t\tparsed->entry_points.push_back({\n\t\t\tname, demangle_entry_point(name),\n\t\t\tConverter::get_node_input(parsed->bc, name.c_str()),\n\t\t\tConverter::get_node_outputs(parsed->bc, name.c_str())\n\t\t});\n\t}\n\n\t*blob = parsed;\n\treturn DXIL_SPV_SUCCESS;\n}\n\nvoid dxil_spv_parsed_blob_dump_llvm_ir(dxil_spv_parsed_blob blob)\n{\n\tauto &module = blob->bc.get_module();\n#ifdef HAVE_LLVMBC\n\tString str;\n\tif (llvm::disassemble(module, str))\n\t\tfprintf(stderr, \"%s\\n\", str.c_str());\n\telse\n\t\tfprintf(stderr, \"Failed to disassemble LLVM IR!\\n\");\n#else\n\tmodule.print(llvm::errs(), nullptr);\n#endif\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_disassembled_ir(dxil_spv_parsed_blob blob, const char **str)\n{\n\tblob->disasm.clear();\n\n\tauto *module = &blob->bc.get_module();\n#ifdef HAVE_LLVMBC\n\tif (!llvm::disassemble(*module, blob->disasm))\n\t\treturn DXIL_SPV_ERROR_GENERIC;\n#else\n\tllvm::raw_string_ostream ostr(blob->disasm);\n\tmodule->print(ostr, nullptr);\n#endif\n\t*str = blob->disasm.c_str();\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_raw_ir(dxil_spv_parsed_blob blob, const void **data, size_t *size)\n{\n\tif (blob->dxil_blob.empty())\n\t\treturn DXIL_SPV_ERROR_GENERIC;\n\n\t*data = blob->dxil_blob.data();\n\t*size = blob->dxil_blob.size();\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_shader_stage dxil_spv_parsed_blob_get_shader_stage(dxil_spv_parsed_blob blob)\n{\n\treturn static_cast<dxil_spv_shader_stage>(Converter::get_shader_stage(blob->bc));\n}\n\ndxil_spv_shader_stage dxil_spv_parsed_blob_get_shader_stage_for_entry(dxil_spv_parsed_blob blob, const char *entry)\n{\n\treturn static_cast<dxil_spv_shader_stage>(Converter::get_shader_stage(blob->bc, entry));\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_entry_index_by_name(dxil_spv_parsed_blob blob,\n                                                             const char *entry,\n                                                             unsigned *index)\n{\n    for (size_t i = 0, n = blob->entry_points.size(); i < n; i++)\n    {\n        if (blob->entry_points[i].demangled == entry || blob->entry_points[i].mangled == entry)\n        {\n            *index = unsigned(i);\n            return DXIL_SPV_SUCCESS;\n        }\n    }\n\n    return DXIL_SPV_ERROR_GENERIC;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_num_entry_points(dxil_spv_parsed_blob blob, unsigned *count)\n{\n\t*count = unsigned(blob->entry_points.size());\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_entry_point_name(dxil_spv_parsed_blob blob,\n                                                          unsigned index,\n                                                          const char **mangled_entry)\n{\n\tif (index >= blob->entry_points.size())\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\t*mangled_entry = blob->entry_points[index].mangled.c_str();\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_entry_point_demangled_name(dxil_spv_parsed_blob blob,\n                                                                    unsigned index,\n                                                                    const char **demangled_entry)\n{\n\tif (index >= blob->entry_points.size())\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\t*demangled_entry = blob->entry_points[index].demangled.c_str();\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_entry_point_node_input(\n    dxil_spv_parsed_blob blob, unsigned index, dxil_spv_node_input_data *data)\n{\n\tif (index >= blob->entry_points.size())\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\n\tauto &input = blob->entry_points[index].node_input;\n\tdata->node_id = input.node_id.c_str();\n\tdata->payload_stride = input.payload_stride;\n\tdata->launch_type = dxil_spv_node_launch_type(input.launch_type);\n\tdata->node_array_index = input.node_array_index;\n\tdata->dispatch_grid_offset = input.grid_buffer.offset;\n\tdata->dispatch_grid_type_bits = input.grid_buffer.component_type == DXIL::ComponentType::U32 ? 32 : 16;\n\tdata->dispatch_grid_components = input.grid_buffer.count;\n\tfor (int i = 0; i < 3; i++)\n\t{\n\t\tdata->broadcast_grid[i] = input.broadcast_grid[i];\n\t\tdata->thread_group_size_spec_id[i] = input.thread_group_size_spec_id[i];\n\t\tdata->max_broadcast_grid_spec_id[i] = input.max_broadcast_grid_spec_id[i];\n\t}\n\tdata->recursion_factor = input.recursion_factor;\n\tdata->coalesce_factor = input.coalesce_factor;\n\tdata->node_share_input_id = input.node_share_input_id.c_str();\n\tdata->node_share_input_array_index = input.node_share_input_array_index;\n\tdata->local_root_arguments_table_index = input.local_root_arguments_table_index;\n\tdata->is_indirect_bda_stride_program_entry_spec_id = input.is_indirect_bda_stride_program_entry_spec_id;\n\tdata->is_entry_point_spec_id = input.is_entry_point_spec_id;\n\tdata->dispatch_grid_is_upper_bound = input.dispatch_grid_is_upper_bound ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\tdata->dispatch_grid_is_upper_bound_spec_id = input.dispatch_grid_is_upper_bound_spec_id;\n\tdata->is_static_broadcast_node_spec_id = input.is_static_broadcast_node_spec_id;\n\tdata->node_track_rw_input_sharing = input.node_track_rw_input_sharing ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\tdata->is_program_entry = input.is_program_entry ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_entry_point_num_node_outputs(\n    dxil_spv_parsed_blob blob, unsigned index, unsigned *num_outputs)\n{\n\tif (index >= blob->entry_points.size())\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\n\t*num_outputs = unsigned(blob->entry_points[index].node_outputs.size());\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_get_entry_point_node_output(\n    dxil_spv_parsed_blob blob, unsigned index, unsigned output_index, dxil_spv_node_output_data *data)\n{\n\tif (index >= blob->entry_points.size())\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\n\tauto &entry = blob->entry_points[index];\n\tif (output_index >= entry.node_outputs.size())\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\n\tauto &output = entry.node_outputs[output_index];\n\n\tdata->node_id = output.node_id.c_str();\n\tdata->node_array_index = output.node_array_index;\n\tdata->node_array_size = output.node_array_size;\n\tdata->sparse_array = output.sparse_array;\n\tdata->max_records = output.max_records;\n\tdata->node_index_spec_constant_id = output.node_index_spec_constant_id;\n\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_parsed_blob_scan_resources(dxil_spv_parsed_blob blob,\n                                                    dxil_spv_srv_remapper_cb srv_remapper,\n                                                    dxil_spv_sampler_remapper_cb sampler_remapper,\n                                                    dxil_spv_cbv_remapper_cb cbv_remapper,\n                                                    dxil_spv_uav_remapper_cb uav_remapper, void *userdata)\n{\n\tRemapper remapper;\n\tremapper.srv_remapper = srv_remapper;\n\tremapper.srv_userdata = userdata;\n\tremapper.sampler_remapper = sampler_remapper;\n\tremapper.sampler_userdata = userdata;\n\tremapper.cbv_remapper = cbv_remapper;\n\tremapper.cbv_userdata = userdata;\n\tremapper.uav_remapper = uav_remapper;\n\tremapper.uav_userdata = userdata;\n\n\tConverter::scan_resources(&remapper, blob->bc);\n\treturn DXIL_SPV_SUCCESS;\n}\n\nvoid dxil_spv_parsed_blob_free(dxil_spv_parsed_blob blob)\n{\n\tdelete blob;\n}\n\ndxil_spv_result dxil_spv_create_converter_with_reflection(dxil_spv_parsed_blob blob,\n                                                          dxil_spv_parsed_blob reflection_blob,\n                                                          dxil_spv_converter *converter)\n{\n\tauto *conv = new (std::nothrow) dxil_spv_converter_s(blob->bc, reflection_blob ? &reflection_blob->bc : nullptr);\n\tif (!conv)\n\t\treturn DXIL_SPV_ERROR_OUT_OF_MEMORY;\n\n\t*converter = conv;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_create_converter(dxil_spv_parsed_blob blob, dxil_spv_converter *converter)\n{\n\treturn dxil_spv_create_converter_with_reflection(blob, nullptr, converter);\n}\n\nvoid dxil_spv_converter_free(dxil_spv_converter converter)\n{\n\tdelete converter;\n}\n\nvoid dxil_spv_converter_set_entry_point(dxil_spv_converter converter, const char *entry_point)\n{\n\tif (entry_point)\n\t\tconverter->entry_point = entry_point;\n\telse\n\t\tconverter->entry_point.clear();\n}\n\ndxil_spv_result dxil_spv_converter_run(dxil_spv_converter converter)\n{\n\tSPIRVModule module;\n\tConverter dxil_converter(converter->bc_parser, converter->bc_reflection_parser, module);\n\n\tif (!converter->entry_point.empty())\n\t\tdxil_converter.set_entry_point(converter->entry_point.c_str());\n\tdxil_converter.set_resource_remapping_interface(&converter->remapper);\n\tfor (auto &opt : converter->options)\n\t\tdxil_converter.add_option(*opt);\n\n\tif (converter->patch_location_offset != UINT32_MAX)\n\t\tdxil_converter.set_patch_location_offset(converter->patch_location_offset);\n\n\tfor (auto &mapping : converter->root_parameter_mappings)\n\t\tdxil_converter.add_root_parameter_mapping(mapping.first, mapping.second);\n\n\tfor (auto &info : converter->non_semantic_debug_info)\n\t\tdxil_converter.add_non_semantic_debug_info(info);\n\n\tfor (auto &mapping : converter->meta_mappings)\n\t\tdxil_converter.set_meta_descriptor(mapping.meta, mapping.kind, mapping.desc_set, mapping.desc_binding);\n\n\tfor (auto &local_param : converter->local_root_parameters)\n\t{\n\t\tswitch (local_param.type)\n\t\t{\n\t\tcase LocalRootParameterType::Constants:\n\t\t\tdxil_converter.add_local_root_constants(local_param.local_constants.register_space,\n\t\t\t                                        local_param.local_constants.register_index,\n\t\t\t                                        local_param.local_constants.num_words);\n\t\t\tbreak;\n\n\t\tcase LocalRootParameterType::Descriptor:\n\t\t\tdxil_converter.add_local_root_descriptor(local_param.local_descriptor.resource_class,\n\t\t\t                                         local_param.local_descriptor.register_space,\n\t\t\t                                         local_param.local_descriptor.register_index);\n\t\t\tbreak;\n\n\t\tcase LocalRootParameterType::Table:\n\t\t\tdxil_converter.add_local_root_descriptor_table(local_param.table_entries);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tauto entry_point = dxil_converter.convert_entry_point();\n\n\tif (entry_point.entry.entry == nullptr)\n\t{\n\t\tLOGE(\"Failed to convert function.\\n\");\n\t\treturn DXIL_SPV_ERROR_GENERIC;\n\t}\n\n\t{\n\t\tdxil_spv::CFGStructurizer structurizer(entry_point.entry.entry, *entry_point.node_pool, module);\n\n\t\tmodule.set_entry_build_point(entry_point.entry.func);\n\n\t\tif (entry_point.entry.is_structured)\n\t\t\tstructurizer.run_trivial();\n\t\telse\n\t\t\tstructurizer.run();\n\n\t\tmodule.emit_entry_point_function_body(structurizer);\n\t}\n\n\tfor (auto &leaf : entry_point.leaf_functions)\n\t{\n\t\tif (!leaf.entry)\n\t\t{\n\t\t\tLOGE(\"Leaf function is nullptr!\\n\");\n\t\t\treturn DXIL_SPV_ERROR_GENERIC;\n\t\t}\n\t\tdxil_spv::CFGStructurizer structurizer(leaf.entry, *entry_point.node_pool, module);\n\t\tmodule.set_entry_build_point(leaf.func);\n\n\t\tif (leaf.is_structured)\n\t\t\tstructurizer.run_trivial();\n\t\telse\n\t\t\tstructurizer.run();\n\n\t\tmodule.emit_leaf_function_body(leaf.func, structurizer);\n\t}\n\n\tif (!module.finalize_spirv(converter->spirv))\n\t{\n\t\tLOGE(\"Failed to finalize SPIR-V.\\n\");\n\t\treturn DXIL_SPV_ERROR_GENERIC;\n\t}\n\n\tconverter->compiled_entry_point = dxil_converter.get_compiled_entry_point();\n\tconverter->uses_subgroup_size = module.has_builtin_shader_input(spv::BuiltInSubgroupSize);\n\tconverter->is_multiview_compatible = dxil_converter.is_multiview_compatible();\n\tdxil_converter.get_workgroup_dimensions(converter->workgroup_size[0],\n\t                                        converter->workgroup_size[1],\n\t                                        converter->workgroup_size[2]);\n\tdxil_converter.get_compute_wave_size_range(converter->wave_size_min, converter->wave_size_max, converter->wave_size_preferred);\n\tconverter->heuristic_min_wave_size = dxil_converter.get_compute_heuristic_min_wave_size();\n\tconverter->heuristic_max_wave_size = dxil_converter.get_compute_heuristic_max_wave_size();\n\tconverter->patch_vertex_count = dxil_converter.get_patch_vertex_count();\n\tconverter->patch_location_offset = dxil_converter.get_patch_location_offset();\n\tfor (int i = 0; i < int(ShaderFeature::Count); i++)\n\t\tconverter->shader_feature_used[i] = dxil_converter.shader_requires_feature(ShaderFeature(i));\n\tconverter->analysis_warnings = dxil_converter.get_analysis_warnings();\n\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_compiled_spirv(dxil_spv_converter converter, dxil_spv_compiled_spirv *compiled)\n{\n\tif (converter->spirv.empty())\n\t\treturn DXIL_SPV_ERROR_GENERIC;\n\n\tcompiled->data = converter->spirv.data();\n\tcompiled->size = converter->spirv.size() * sizeof(uint32_t);\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_compiled_entry_point(dxil_spv_converter converter,\n                                                            const char **entry_point)\n{\n\tif (converter->spirv.empty())\n\t\treturn DXIL_SPV_ERROR_GENERIC;\n\n\t*entry_point = converter->compiled_entry_point.c_str();\n\treturn DXIL_SPV_SUCCESS;\n}\n\nvoid dxil_spv_converter_set_srv_remapper(dxil_spv_converter converter, dxil_spv_srv_remapper_cb remapper,\n                                         void *userdata)\n{\n\tconverter->remapper.srv_remapper = remapper;\n\tconverter->remapper.srv_userdata = userdata;\n}\n\nvoid dxil_spv_converter_set_sampler_remapper(dxil_spv_converter converter, dxil_spv_sampler_remapper_cb remapper,\n                                             void *userdata)\n{\n\tconverter->remapper.sampler_remapper = remapper;\n\tconverter->remapper.sampler_userdata = userdata;\n}\n\nvoid dxil_spv_converter_set_root_constant_word_count(dxil_spv_converter converter, unsigned num_words)\n{\n\tconverter->remapper.root_constant_word_count = num_words;\n}\n\nvoid dxil_spv_converter_set_root_descriptor_count(dxil_spv_converter converter, unsigned count)\n{\n\tconverter->remapper.root_descriptor_count = count;\n}\n\nvoid dxil_spv_converter_set_uav_remapper(dxil_spv_converter converter, dxil_spv_uav_remapper_cb remapper,\n                                         void *userdata)\n{\n\tconverter->remapper.uav_remapper = remapper;\n\tconverter->remapper.uav_userdata = userdata;\n}\n\nvoid dxil_spv_converter_set_cbv_remapper(dxil_spv_converter converter, dxil_spv_cbv_remapper_cb remapper,\n                                         void *userdata)\n{\n\tconverter->remapper.cbv_remapper = remapper;\n\tconverter->remapper.cbv_userdata = userdata;\n}\n\nvoid dxil_spv_converter_set_stage_input_remapper(dxil_spv_converter converter,\n                                                 dxil_spv_shader_stage_io_remapper_cb remapper, void *userdata)\n{\n\tconverter->remapper.stage_input_remapper = remapper;\n\tconverter->remapper.stage_input_userdata = userdata;\n}\n\nvoid dxil_spv_converter_set_stage_output_remapper(dxil_spv_converter converter,\n                                                  dxil_spv_shader_stage_io_remapper_cb remapper, void *userdata)\n{\n\tconverter->remapper.stage_output_remapper = remapper;\n\tconverter->remapper.stage_output_userdata = userdata;\n}\n\nvoid dxil_spv_converter_set_vertex_input_remapper(dxil_spv_converter converter,\n                                                  dxil_spv_vertex_input_remapper_cb remapper, void *userdata)\n{\n\tconverter->remapper.input_remapper = remapper;\n\tconverter->remapper.input_userdata = userdata;\n}\n\nvoid dxil_spv_converter_set_stream_output_remapper(dxil_spv_converter converter,\n                                                   dxil_spv_stream_output_remapper_cb remapper, void *userdata)\n{\n\tconverter->remapper.output_remapper = remapper;\n\tconverter->remapper.output_userdata = userdata;\n}\n\n/* Useful to check if the implementation recognizes a particular capability for ABI compatibility. */\ndxil_spv_bool dxil_spv_converter_supports_option(dxil_spv_option cap)\n{\n\treturn Converter::recognizes_option(static_cast<Option>(cap)) ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n}\n\ntemplate <typename T>\nstatic std::unique_ptr<T> duplicate(const T &value)\n{\n\treturn std::unique_ptr<T>(new T(value));\n}\n\ndxil_spv_result dxil_spv_converter_add_option(dxil_spv_converter converter, const dxil_spv_option_base *option)\n{\n\tif (!dxil_spv_converter_supports_option(option->type))\n\t\treturn DXIL_SPV_ERROR_UNSUPPORTED_FEATURE;\n\n\tswitch (option->type)\n\t{\n\tcase DXIL_SPV_OPTION_SHADER_DEMOTE_TO_HELPER:\n\t{\n\t\tOptionShaderDemoteToHelper helper;\n\t\thelper.supported = bool(reinterpret_cast<const dxil_spv_option_shader_demote_to_helper *>(option)->supported);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_DUAL_SOURCE_BLENDING:\n\t{\n\t\tOptionDualSourceBlending helper;\n\t\thelper.enabled = bool(reinterpret_cast<const dxil_spv_option_dual_source_blending *>(option)->enabled);\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_OUTPUT_SWIZZLE:\n\t{\n\t\tOptionOutputSwizzle helper;\n\t\tconst auto *input = reinterpret_cast<const dxil_spv_option_output_swizzle *>(option);\n\t\thelper.swizzles = input->swizzles;\n\t\thelper.swizzle_count = input->swizzle_count;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_RASTERIZER_SAMPLE_COUNT:\n\t{\n\t\tOptionRasterizerSampleCount helper;\n\t\tconst auto *count = reinterpret_cast<const dxil_spv_option_rasterizer_sample_count *>(option);\n\t\thelper.count = count->sample_count;\n\t\thelper.spec_constant = bool(count->spec_constant);\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_ROOT_CONSTANT_INLINE_UNIFORM_BLOCK:\n\t{\n\t\tOptionRootConstantInlineUniformBlock helper;\n\t\tconst auto *ubo = reinterpret_cast<const dxil_spv_option_root_constant_inline_uniform_block *>(option);\n\t\thelper.desc_set = ubo->desc_set;\n\t\thelper.binding = ubo->binding;\n\t\thelper.enable = ubo->enable == DXIL_SPV_TRUE;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_BINDLESS_CBV_SSBO_EMULATION:\n\t{\n\t\tOptionBindlessCBVSSBOEmulation helper;\n\t\thelper.enable =\n\t\t    reinterpret_cast<const dxil_spv_option_bindless_cbv_ssbo_emulation *>(option)->enable == DXIL_SPV_TRUE;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_PHYSICAL_STORAGE_BUFFER:\n\t{\n\t\tOptionPhysicalStorageBuffer helper;\n\t\thelper.enable =\n\t\t    reinterpret_cast<const dxil_spv_option_physical_storage_buffer *>(option)->enable == DXIL_SPV_TRUE;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SBT_DESCRIPTOR_SIZE_LOG2:\n\t{\n\t\tOptionSBTDescriptorSizeLog2 helper;\n\t\thelper.size_log2_srv_uav_cbv = reinterpret_cast<const dxil_spv_option_sbt_descriptor_size_log2 *>(option)->size_log2_srv_uav_cbv;\n\t\thelper.size_log2_sampler = reinterpret_cast<const dxil_spv_option_sbt_descriptor_size_log2 *>(option)->size_log2_sampler;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SSBO_ALIGNMENT:\n\t{\n\t\tOptionSSBOAlignment helper;\n\t\thelper.alignment = reinterpret_cast<const dxil_spv_option_ssbo_alignment *>(option)->alignment;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_TYPED_UAV_READ_WITHOUT_FORMAT:\n\t{\n\t\tOptionTypedUAVReadWithoutFormat helper;\n\t\thelper.supported = reinterpret_cast<const dxil_spv_option_typed_uav_read_without_format *>(option)->supported == DXIL_SPV_TRUE;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SHADER_SOURCE_FILE:\n\t{\n\t\tOptionShaderSourceFile helper;\n\t\tconst char *name = reinterpret_cast<const dxil_spv_option_shader_source_file *>(option)->name;\n\t\tif (name)\n\t\t\thelper.name = name;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_BINDLESS_TYPED_BUFFER_OFFSETS:\n\t{\n\t\tOptionBindlessTypedBufferOffsets helper;\n\t\thelper.enable = reinterpret_cast<const dxil_spv_option_bindless_typed_buffer_offsets *>(option)->enable;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_BINDLESS_OFFSET_BUFFER_LAYOUT:\n\t{\n\t\tOptionBindlessOffsetBufferLayout helper;\n\t\tauto *opt = reinterpret_cast<const dxil_spv_option_bindless_offset_buffer_layout *>(option);\n\t\thelper.untyped_offset = opt->untyped_offset;\n\t\thelper.typed_offset = opt->typed_offset;\n\t\thelper.stride = opt->stride;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_STORAGE_INPUT_OUTPUT_16BIT:\n\t{\n\t\tOptionStorageInputOutput16 helper;\n\t\thelper.supported =\n\t\t    reinterpret_cast<const dxil_spv_option_storage_input_output_16bit *>(option)->supported == DXIL_SPV_TRUE;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_DESCRIPTOR_QA:\n\t{\n\t\tOptionDescriptorQA helper;\n\t\tauto *qa = reinterpret_cast<const dxil_spv_option_descriptor_qa *>(option);\n\t\thelper.enabled = qa->enabled == DXIL_SPV_TRUE;\n\t\thelper.shader_hash = qa->shader_hash;\n\t\thelper.global_desc_set = qa->global_desc_set;\n\t\thelper.global_binding = qa->global_binding;\n\t\thelper.heap_desc_set = qa->heap_desc_set;\n\t\thelper.heap_binding = qa->heap_binding;\n\t\thelper.version = qa->version;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_MIN_PRECISION_NATIVE_16BIT:\n\t{\n\t\tOptionMinPrecisionNative16Bit helper;\n\t\tauto *minprec = reinterpret_cast<const dxil_spv_option_min_precision_native_16bit *>(option);\n\t\thelper.enabled = minprec->enabled == DXIL_SPV_TRUE;\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SHADER_I8_DOT:\n\t{\n\t\tOptionShaderI8Dot helper;\n\t\thelper.supported = bool(reinterpret_cast<const dxil_spv_option_shader_i8_dot *>(option)->supported);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SHADER_RAY_TRACING_PRIMITIVE_CULLING:\n\t{\n\t\tOptionShaderRayTracingPrimitiveCulling helper;\n\t\thelper.supported = bool(reinterpret_cast<const dxil_spv_option_shader_ray_tracing_primitive_culling *>(option)->supported);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_INVARIANT_POSITION:\n\t{\n\t\tOptionInvariantPosition helper;\n\t\thelper.enabled = bool(reinterpret_cast<const dxil_spv_option_invariant_position *>(option)->enabled);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SCALAR_BLOCK_LAYOUT:\n\t{\n\t\tOptionScalarBlockLayout helper;\n\t\tauto *opt = reinterpret_cast<const dxil_spv_option_scalar_block_layout *>(option);\n\t\thelper.supported = bool(opt->supported);\n\t\thelper.supports_per_component_robustness = bool(opt->supports_per_component_robustness);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_BARYCENTRIC_KHR:\n\t{\n\t\tOptionBarycentricKHR helper;\n\t\tauto *opt = reinterpret_cast<const dxil_spv_option_barycentric_khr *>(option);\n\t\thelper.supported = bool(opt->supported);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_ROBUST_PHYSICAL_CBV_LOAD:\n\t{\n\t\tOptionRobustPhysicalCBVLoad helper;\n\t\tauto *robust = reinterpret_cast<const dxil_spv_option_robust_physical_cbv_load *>(option);\n\t\thelper.enabled = bool(robust->enabled);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_ARITHMETIC_RELAXED_PRECISION:\n\t{\n\t\tOptionArithmeticRelaxedPrecision helper;\n\t\tauto *robust = reinterpret_cast<const dxil_spv_option_arithmetic_relaxed_precision *>(option);\n\t\thelper.enabled = bool(robust->enabled);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_PHYSICAL_ADDRESS_DESCRIPTOR_INDEXING:\n\t{\n\t\tOptionPhysicalAddressDescriptorIndexing helper;\n\t\tauto *indexing = reinterpret_cast<const dxil_spv_option_physical_address_descriptor_indexing *>(option);\n\t\thelper.element_stride = indexing->element_stride;\n\t\thelper.element_offset = indexing->element_offset;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_FORCE_SUBGROUP_SIZE:\n\t{\n\t\tOptionForceSubgroupSize helper;\n\t\tauto *subgroup = reinterpret_cast<const dxil_spv_option_force_subgroup_size *>(option);\n\t\thelper.forced_value = subgroup->forced_value;\n\t\thelper.wave_size_enable = subgroup->wave_size_enable;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_DENORM_PRESERVE_SUPPORT:\n\t{\n\t\tOptionDenormPreserveSupport helper;\n\t\tauto *denorm = reinterpret_cast<const dxil_spv_option_denorm_preserve_support *>(option);\n\t\thelper.support_float16_denorm_preserve = bool(denorm->supports_float16_denorm_preserve);\n\t\thelper.support_float64_denorm_preserve = bool(denorm->supports_float64_denorm_preserve);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_STRICT_HELPER_LANE_WAVE_OPS:\n\t{\n\t\tOptionStrictHelperLaneWaveOps helper;\n\t\tauto *strict = reinterpret_cast<const dxil_spv_option_strict_helper_lane_wave_ops *>(option);\n\t\thelper.enable = strict->enable;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SUBGROUP_PARTITIONED_NV:\n\t{\n\t\tOptionSubgroupPartitionedNV helper;\n\t\tauto *partitioned = reinterpret_cast<const dxil_spv_option_subgroup_partitioned_nv *>(option);\n\t\thelper.supported = partitioned->supported;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_DEAD_CODE_ELIMINATE:\n\t{\n\t\tOptionDeadCodeEliminate helper;\n\t\tauto *eliminate = reinterpret_cast<const dxil_spv_option_dead_code_eliminate *>(option);\n\t\thelper.enabled = eliminate->enabled;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_PRECISE_CONTROL:\n\t{\n\t\tOptionPreciseControl helper;\n\t\tauto *precise = reinterpret_cast<const dxil_spv_option_precise_control *>(option);\n\t\thelper.force_precise = precise->force_precise;\n\t\thelper.propagate_precise = precise->propagate_precise;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SAMPLE_GRAD_OPTIMIZATION_CONTROL:\n\t{\n\t\tOptionSampleGradOptimizationControl helper;\n\t\tauto *precise = reinterpret_cast<const dxil_spv_option_sample_grad_optimization_control *>(option);\n\t\thelper.enabled = precise->enabled;\n\t\thelper.assume_uniform_scale = precise->assume_uniform_scale;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_OPACITY_MICROMAP:\n\t{\n\t\tOptionOpacityMicromap helper;\n\t\tauto *omm = reinterpret_cast<const dxil_spv_option_opacity_micromap *>(option);\n\t\thelper.enabled = omm->enabled;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_BRANCH_CONTROL:\n\t{\n\t\tOptionBranchControl helper;\n\t\tauto *branch = reinterpret_cast<const dxil_spv_option_branch_control *>(option);\n\t\thelper.use_shader_metadata = branch->use_shader_metadata;\n\t\thelper.force_branch = branch->force_branch;\n\t\thelper.force_loop = branch->force_loop;\n\t\thelper.force_unroll = branch->force_unroll;\n\t\thelper.force_flatten = branch->force_flatten;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SUBGROUP_PROPERTIES:\n\t{\n\t\tOptionSubgroupProperties helper;\n\t\tauto *sub = reinterpret_cast<const dxil_spv_option_subgroup_properties *>(option);\n\t\thelper.minimum_size = sub->minimum_size;\n\t\thelper.maximum_size = sub->maximum_size;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_DESCRIPTOR_HEAP_ROBUSTNESS:\n\t{\n\t\tOptionDescriptorHeapRobustness helper;\n\t\tauto *rob = reinterpret_cast<const dxil_spv_option_descriptor_heap_robustness *>(option);\n\t\thelper.enabled = rob->enabled;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES_NV:\n\t{\n\t\tOptionComputeShaderDerivativesNV helper;\n\t\tauto *deriv = reinterpret_cast<const dxil_spv_option_compute_shader_derivatives_nv *>(option);\n\t\thelper.supported = deriv->supported;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_QUAD_CONTROL_RECONVERGENCE:\n\t{\n\t\tOptionQuadControlReconvergence helper;\n\t\tauto *quad = reinterpret_cast<const dxil_spv_option_quad_control_reconvergence *>(option);\n\t\thelper.supports_quad_control = quad->supports_quad_control;\n\t\thelper.supports_maximal_reconvergence = quad->supports_maximal_reconvergence;\n\t\thelper.force_maximal_reconvergence = quad->force_maximal_reconvergence;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_RAW_ACCESS_CHAINS_NV:\n\t{\n\t\tOptionRawAccessChainsNV helper;\n\t\tauto *chain = reinterpret_cast<const dxil_spv_option_raw_access_chains_nv *>(option);\n\t\thelper.supported = chain->supported;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_DRIVER_VERSION:\n\t{\n\t\tOptionDriverVersion helper;\n\t\tauto *ver = reinterpret_cast<const dxil_spv_option_driver_version *>(option);\n\t\thelper.driver_id = ver->driver_id;\n\t\thelper.driver_version = ver->driver_version;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES:\n\t{\n\t\tOptionComputeShaderDerivatives helper;\n\t\tauto *deriv = reinterpret_cast<const dxil_spv_option_compute_shader_derivatives *>(option);\n\t\thelper.supports_nv = deriv->supports_nv;\n\t\thelper.supports_khr = deriv->supports_khr;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_INSTRUCTION_INSTRUMENTATION:\n\t{\n\t\tOptionInstructionInstrumentation helper;\n\t\tauto *inst = reinterpret_cast<const dxil_spv_option_instruction_instrumentation *>(option);\n\t\thelper.enabled = inst->enabled;\n\t\thelper.version = inst->version;\n\t\thelper.control_desc_set = inst->control_desc_set;\n\t\thelper.control_binding = inst->control_binding;\n\t\thelper.payload_desc_set = inst->payload_desc_set;\n\t\thelper.payload_binding = inst->payload_binding;\n\t\thelper.shader_hash = inst->shader_hash;\n\t\thelper.type = InstructionInstrumentationType(inst->type);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_SHADER_QUIRK:\n\t{\n\t\tOptionShaderQuirk helper;\n\t\tauto *quirk = reinterpret_cast<const dxil_spv_option_shader_quirk *>(option);\n\t\thelper.quirk = static_cast<ShaderQuirk>(quirk->quirk);\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_EXTENDED_ROBUSTNESS:\n\t{\n\t\tOptionExtendedRobustness helper;\n\t\tauto *robust = reinterpret_cast<const dxil_spv_option_extended_robustness *>(option);\n\t\thelper.robust_group_shared = robust->robust_group_shared;\n\t\thelper.robust_alloca = robust->robust_alloca;\n\t\thelper.robust_constant_lut = robust->robust_constant_lut;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_MAX_TESS_FACTOR:\n\t{\n\t\tOptionMaxTessFactor helper;\n\t\tauto *tess_factor = reinterpret_cast<const dxil_spv_option_max_tess_factor *>(option);\n\t\thelper.max_tess_factor = tess_factor->max_tess_factor;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_VULKAN_MEMORY_MODEL:\n\t{\n\t\tOptionVulkanMemoryModel helper;\n\t\tauto *vkmm = reinterpret_cast<const dxil_spv_option_vulkan_memory_model *>(option);\n\t\thelper.enabled = vkmm->enabled;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_FLOAT8_SUPPORT:\n\t{\n\t\tOptionFloat8Support helper;\n\t\tauto *float8 = reinterpret_cast<const dxil_spv_option_float8_support *>(option);\n\t\thelper.wmma_fp8 = float8->wmma_fp8;\n\t\thelper.nv_cooperative_matrix2_conversions = float8->nv_cooperative_matrix2_conversions;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_NVAPI:\n\t{\n\t\tOptionNvAPI helper;\n\t\tauto *nvapi = reinterpret_cast<const dxil_spv_option_nvapi *>(option);\n\t\thelper.enabled = nvapi->enabled;\n\t\thelper.register_index = nvapi->register_index;\n\t\thelper.register_space = nvapi->register_space;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_EXTENDED_NON_SEMANTIC:\n\t{\n\t\tOptionExtendedNonSemantic helper;\n\t\tauto *sem = reinterpret_cast<const dxil_spv_option_extended_non_semantic *>(option);\n\t\thelper.enabled = sem->enabled;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_VIEW_INSTANCING:\n\t{\n\t\tOptionViewInstancing helper;\n\t\tauto *inst = reinterpret_cast<const dxil_spv_option_view_instancing *>(option);\n\t\thelper.enabled = inst->enabled == DXIL_SPV_TRUE;\n\t\thelper.last_pre_rasterization_stage = inst->last_pre_rasterization_stage == DXIL_SPV_TRUE;\n\t\thelper.view_index_to_view_instance_spec_id = inst->view_index_to_view_instance_spec_id;\n\t\thelper.view_instance_to_viewport_spec_id = inst->view_instance_to_viewport_spec_id;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_MIXED_FLOAT_DOT_PRODUCT:\n\t{\n\t\tOptionMixedDotProduct helper;\n\t\tauto *dot = reinterpret_cast<const dxil_spv_option_mixed_float_dot_product *>(option);\n\t\thelper.fp16_fp16_fp32 = dot->fp16_fp16_fp32;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tcase DXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES_QUAD:\n\t{\n\t\tOptionComputeShaderDerivativesQuad helper;\n\t\tauto *deriv = reinterpret_cast<const dxil_spv_option_compute_shader_derivatives_quad *>(option);\n\t\thelper.supports_quad = deriv->supports_quad == DXIL_SPV_TRUE;\n\n\t\tconverter->options.emplace_back(duplicate(helper));\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\treturn DXIL_SPV_ERROR_UNSUPPORTED_FEATURE;\n\t}\n\n\treturn DXIL_SPV_SUCCESS;\n}\n\nvoid dxil_spv_converter_add_local_root_constants(dxil_spv_converter converter,\n                                                 unsigned register_space,\n                                                 unsigned register_index,\n                                                 unsigned num_words)\n{\n\tLocalRootParameter param = {};\n\tparam.type = LocalRootParameterType::Constants;\n\tparam.local_constants = { register_space, register_index, num_words };\n\tconverter->local_root_parameters.push_back(std::move(param));\n}\n\nvoid dxil_spv_converter_add_local_root_descriptor(dxil_spv_converter converter,\n                                                  dxil_spv_resource_class resource_class,\n                                                  unsigned register_space,\n                                                  unsigned register_index)\n{\n\tLocalRootParameter param = {};\n\tparam.type = LocalRootParameterType::Descriptor;\n\tparam.local_descriptor = { ResourceClass(resource_class), register_space, register_index };\n\tconverter->local_root_parameters.push_back(std::move(param));\n}\n\nvoid dxil_spv_converter_add_local_root_descriptor_table(dxil_spv_converter converter,\n                                                        dxil_spv_resource_class resource_class,\n                                                        unsigned register_space,\n                                                        unsigned register_index,\n                                                        unsigned num_descriptors_in_range,\n                                                        unsigned offset_in_heap)\n{\n\tDescriptorTableEntry entry = {};\n\tentry.type = ResourceClass(resource_class);\n\tentry.register_space = register_space;\n\tentry.register_index = register_index;\n\tentry.num_descriptors_in_range = num_descriptors_in_range;\n\tentry.offset_in_heap = offset_in_heap;\n\n\tif (converter->active_table)\n\t\tconverter->local_entries.push_back(entry);\n\telse\n\t{\n\t\tLocalRootParameter param = {};\n\t\tparam.type = LocalRootParameterType::Table;\n\t\tparam.table_entries = { entry };\n\t\tconverter->local_root_parameters.push_back(std::move(param));\n\t}\n}\n\ndxil_spv_result dxil_spv_converter_begin_local_root_descriptor_table(\n\tdxil_spv_converter converter)\n{\n\tif (converter->active_table)\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\n\tconverter->local_entries = {};\n\tconverter->active_table = true;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_end_local_root_descriptor_table(\n\tdxil_spv_converter converter)\n{\n\tif (!converter->active_table || converter->local_entries.empty())\n\t\treturn DXIL_SPV_ERROR_INVALID_ARGUMENT;\n\n\tLocalRootParameter param = {};\n\tparam.type = LocalRootParameterType::Table;\n\tstd::swap(param.table_entries, converter->local_entries);\n\tconverter->local_root_parameters.push_back(std::move(param));\n\n\tconverter->active_table = false;\n\treturn DXIL_SPV_SUCCESS;\n}\n\nvoid dxil_spv_converter_add_root_parameter_mapping(\n\tdxil_spv_converter converter, unsigned root_parameter_index, unsigned offset)\n{\n\tconverter->root_parameter_mappings.emplace_back(root_parameter_index, offset);\n}\n\nvoid dxil_spv_converter_add_root_descriptor_mapping(\n    dxil_spv_converter converter, unsigned root_parameter_index,\n    unsigned desc_set, unsigned binding)\n{\n    converter->root_parameter_mappings.emplace_back(\n            root_parameter_index,\n            Converter::pack_desc_set_binding_to_virtual_offset(desc_set, binding));\n}\n\nvoid dxil_spv_converter_add_non_semantic_debug_info(\n\tdxil_spv_converter converter, const char *tag, const void *data, size_t size)\n{\n\tconverter->non_semantic_debug_info.push_back({ tag, data, size });\n}\n\nvoid dxil_spv_converter_set_patch_location_offset(\n\t\tdxil_spv_converter converter, unsigned offset)\n{\n\tconverter->patch_location_offset = offset;\n}\n\nunsigned dxil_spv_parsed_blob_get_num_rdat_subobjects(dxil_spv_parsed_blob blob)\n{\n\treturn unsigned(blob->rdat_subobjects.size());\n}\n\nvoid dxil_spv_parsed_blob_get_rdat_subobject(\n\t\tdxil_spv_parsed_blob blob, unsigned index, dxil_spv_rdat_subobject *subobject)\n{\n\tauto &sub = blob->rdat_subobjects[index];\n\tsubobject->kind = static_cast<dxil_spv_rdat_subobject_kind>(sub.kind);\n\tsubobject->subobject_name = sub.subobject_name;\n\tsubobject->exports = sub.exports.data();\n\tsubobject->num_exports = unsigned(sub.exports.size());\n\tsubobject->payload = sub.payload;\n\tsubobject->payload_size = sub.payload_size;\n\tsubobject->hit_group_type = static_cast<dxil_spv_hit_group_type>(sub.hit_group_type);\n\tstatic_assert(sizeof(subobject->args) == sizeof(sub.args), \"Mismatch is args size.\");\n\tmemcpy(subobject->args, sub.args, sizeof(sub.args));\n}\n\ndxil_spv_bool dxil_spv_converter_uses_subgroup_size(dxil_spv_converter converter)\n{\n\treturn converter->uses_subgroup_size ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n}\n\ndxil_spv_result dxil_spv_converter_get_compute_workgroup_dimensions(\n\tdxil_spv_converter converter,\n\tunsigned *x, unsigned *y, unsigned *z)\n{\n\t*x = converter->workgroup_size[0];\n\t*y = converter->workgroup_size[1];\n\t*z = converter->workgroup_size[2];\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_compute_required_wave_size(\n\tdxil_spv_converter converter, unsigned *wave_size)\n{\n\t/* This API cannot express ranged subgroup sizes */\n\tif (converter->wave_size_max && converter->wave_size_min != converter->wave_size_max)\n\t\treturn DXIL_SPV_ERROR_GENERIC;\n\n\t*wave_size = converter->wave_size_min;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_compute_wave_size_range(\n\tdxil_spv_converter converter, unsigned *wave_size_min, unsigned *wave_size_max, unsigned *wave_size_preferred)\n{\n\t*wave_size_min = converter->wave_size_min;\n\t*wave_size_max = converter->wave_size_max;\n\t*wave_size_preferred = converter->wave_size_preferred;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_compute_heuristic_max_wave_size(\n    dxil_spv_converter converter, unsigned *wave_size)\n{\n\t*wave_size = converter->heuristic_max_wave_size;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_compute_heuristic_min_wave_size(\n    dxil_spv_converter converter, unsigned *wave_size)\n{\n\t*wave_size = converter->heuristic_min_wave_size;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_patch_vertex_count(\n\t\tdxil_spv_converter converter, unsigned *patch_vertices)\n{\n\t*patch_vertices = converter->patch_vertex_count;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_get_patch_location_offset(\n\t\tdxil_spv_converter converter, unsigned *patch_location_offset)\n{\n\t*patch_location_offset = converter->patch_location_offset;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_bool dxil_spv_converter_uses_shader_feature(\n\t\tdxil_spv_converter converter, dxil_spv_shader_feature feature)\n{\n\tif (feature < int(ShaderFeature::Count))\n\t\treturn converter->shader_feature_used[feature] ? DXIL_SPV_TRUE : DXIL_SPV_FALSE;\n\telse\n\t\treturn DXIL_SPV_FALSE;\n}\n\ndxil_spv_result dxil_spv_converter_is_multiview_compatible(\n\t\tdxil_spv_converter converter, dxil_spv_bool *result)\n{\n\t*result = converter->is_multiview_compatible;\n\treturn DXIL_SPV_SUCCESS;\n}\n\ndxil_spv_result dxil_spv_converter_set_meta_descriptor(\n\t\tdxil_spv_converter converter, dxil_spv_meta_descriptor meta,\n\t\tdxil_spv_meta_descriptor_kind kind, unsigned desc_set, unsigned binding_or_push_index)\n{\n\tconverter->meta_mappings.push_back({ MetaDescriptor(meta), MetaDescriptorKind(kind), desc_set, binding_or_push_index });\n\treturn DXIL_SPV_SUCCESS;\n}\n\nconst char *dxil_spv_converter_get_analysis_warnings(dxil_spv_converter converter)\n{\n\tif (converter->analysis_warnings.empty())\n\t\treturn nullptr;\n\treturn converter->analysis_warnings.c_str();\n}\n\nvoid dxil_spv_begin_thread_allocator_context(void)\n{\n\tbegin_thread_allocator_context();\n}\n\nvoid dxil_spv_end_thread_allocator_context(void)\n{\n\tend_thread_allocator_context();\n}\n\nvoid dxil_spv_reset_thread_allocator_context(void)\n{\n\treset_thread_allocator_context();\n}\n\nstatic thread_local dxil_spv_log_cb c_callback_wrapper;\nstatic void c_callback_wrapper_trampoline(void *userdata, dxil_spv::LogLevel level, const char *msg)\n{\n\tif (c_callback_wrapper)\n\t\tc_callback_wrapper(userdata, dxil_spv_log_level(level), msg);\n}\n\nvoid dxil_spv_set_thread_log_callback(dxil_spv_log_cb callback, void *userdata)\n{\n\tc_callback_wrapper = callback;\n\tdxil_spv::set_thread_log_callback(c_callback_wrapper_trampoline, userdata);\n}\n"
  },
  {
    "path": "dxil_spirv_c.h",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef DXIL_SPV_C_API_H\n#define DXIL_SPV_C_API_H\n\n#include <stddef.h>\n\n/* C89-compatible wrapper for dxil_spv. */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define DXIL_SPV_API_VERSION_MAJOR 2\n#define DXIL_SPV_API_VERSION_MINOR 66\n#define DXIL_SPV_API_VERSION_PATCH 0\n\n#define DXIL_SPV_DESCRIPTOR_QA_INTERFACE_VERSION 2\n#define DXIL_SPV_INSTRUCTION_INSTRUMENTATION_INTERFACE_VERSION 2\n\n#if !defined(DXIL_SPV_PUBLIC_API)\n#if defined(DXIL_SPV_EXPORT_SYMBOLS)\n#if defined(__GNUC__)\n#define DXIL_SPV_PUBLIC_API __attribute__((visibility(\"default\")))\n#elif defined(_MSC_VER)\n#define DXIL_SPV_PUBLIC_API __declspec(dllexport)\n#else\n#define DXIL_SPV_PUBLIC_API\n#endif\n#else\n#define DXIL_SPV_PUBLIC_API\n#endif\n#else\n#define DXIL_SPV_PUBLIC_API\n#endif\n\n/* C89 does not have bool type. */\ntypedef unsigned char dxil_spv_bool;\n#define DXIL_SPV_TRUE ((dxil_spv_bool)1)\n#define DXIL_SPV_FALSE ((dxil_spv_bool)0)\n\ntypedef enum dxil_spv_result\n{\n\tDXIL_SPV_SUCCESS = 0,\n\tDXIL_SPV_ERROR_OUT_OF_MEMORY = -1,\n\tDXIL_SPV_ERROR_GENERIC = -2,\n\tDXIL_SPV_ERROR_UNSUPPORTED_FEATURE = -3,\n\tDXIL_SPV_ERROR_PARSER = -4,\n\tDXIL_SPV_ERROR_FAILED_VALIDATION = -5,\n\tDXIL_SPV_ERROR_INVALID_ARGUMENT = -6,\n\tDXIL_SPV_ERROR_NO_DATA = -7,\n\tDXIL_SPV_RESULT_INT_MAX = 0x7fffffff\n} dxil_spv_result;\n\ntypedef enum dxil_spv_shader_stage\n{\n\tDXIL_SPV_STAGE_UNKNOWN = 0,\n\tDXIL_SPV_STAGE_VERTEX = 1,\n\tDXIL_SPV_STAGE_HULL = 2,\n\tDXIL_SPV_STAGE_DOMAIN = 3,\n\tDXIL_SPV_STAGE_GEOMETRY = 4,\n\tDXIL_SPV_STAGE_PIXEL = 5,\n\tDXIL_SPV_STAGE_COMPUTE = 6,\n\tDXIL_SPV_STAGE_INTERSECTION = 7,\n\tDXIL_SPV_STAGE_CLOSEST_HIT = 8,\n\tDXIL_SPV_STAGE_MISS = 9,\n\tDXIL_SPV_STAGE_ANY_HIT = 10,\n\tDXIL_SPV_STAGE_RAY_GENERATION = 11,\n\tDXIL_SPV_STAGE_CALLABLE = 12,\n\tDXIL_SPV_STAGE_AMPLIFICATION = 13,\n\tDXIL_SPV_STAGE_MESH = 14,\n\tDXIL_SPV_STAGE_INT_MAX = 0x7fffffff\n} dxil_spv_shader_stage;\n\n/* Remaps input attribute to desired location. */\ntypedef struct dxil_spv_d3d_vertex_input\n{\n\tconst char *semantic;\n\tunsigned semantic_index;\n\tunsigned start_row;\n\tunsigned rows;\n} dxil_spv_d3d_vertex_input;\n\ntypedef struct dxil_spv_vulkan_vertex_input\n{\n\tunsigned location;\n} dxil_spv_vulkan_vertex_input;\ntypedef dxil_spv_bool (*dxil_spv_vertex_input_remapper_cb)(void *userdata, const dxil_spv_d3d_vertex_input *d3d_input,\n                                                           dxil_spv_vulkan_vertex_input *vulkan_input);\n\ntypedef struct dxil_spv_d3d_stream_output\n{\n\tconst char *semantic;\n\tunsigned semantic_index;\n} dxil_spv_d3d_stream_output;\n\ntypedef struct dxil_spv_vulkan_stream_output\n{\n\tunsigned offset;\n\tunsigned stride;\n\tunsigned buffer_index;\n\tdxil_spv_bool enable;\n} dxil_spv_vulkan_stream_output;\n\ntypedef dxil_spv_bool (*dxil_spv_stream_output_remapper_cb)(void *userdata, const dxil_spv_d3d_stream_output *d3d_output,\n                                                            dxil_spv_vulkan_stream_output *vulkan_output);\n\ntypedef struct dxil_spv_d3d_shader_stage_io\n{\n\tconst char *semantic;\n\tunsigned semantic_index;\n\tunsigned start_row;\n\tunsigned rows;\n} dxil_spv_d3d_shader_stage_io;\n\nenum dxil_spv_vulkan_shader_stage_io_flags\n{\n\tDXIL_SPV_SHADER_STAGE_IO_NONE = 0u,\n\tDXIL_SPV_SHADER_STAGE_IO_PER_PRIMITIVE = 0x1u,\n};\n\ntypedef struct dxil_spv_vulkan_shader_stage_io\n{\n\tunsigned location;\n\tunsigned component;\n\tunsigned flags;\n} dxil_spv_vulkan_shader_stage_io;\n\ntypedef dxil_spv_bool (*dxil_spv_shader_stage_io_remapper_cb)(void *userdata, const dxil_spv_d3d_shader_stage_io *d3d_input,\n                                                              dxil_spv_vulkan_shader_stage_io *vulkan_variable);\n\n/* Matches DXIL enum */\ntypedef enum dxil_spv_resource_kind\n{\n\tDXIL_SPV_RESOURCE_KIND_INVALID = 0,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_1D = 1,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_2D = 2,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_2DMS = 3,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_3D = 4,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_CUBE = 5,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_1D_ARRAY = 6,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_2D_ARRAY = 7,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_2D_MS_ARRAY = 8,\n\tDXIL_SPV_RESOURCE_KIND_TEXTURE_CUBE_ARRAY = 9,\n\tDXIL_SPV_RESOURCE_KIND_TYPED_BUFFER = 10,\n\tDXIL_SPV_RESOURCE_KIND_RAW_BUFFER = 11,\n\tDXIL_SPV_RESOURCE_KIND_STRUCTURED_BUFFER = 12,\n\tDXIL_SPV_RESOURCE_KIND_CONSTANT_BUFFER = 13,\n\tDXIL_SPV_RESOURCE_KIND_SAMPLER = 14,\n\tDXIL_SPV_RESOURCE_KIND_TBUFFER = 15,\n\tDXIL_SPV_RESOURCE_KIND_RT_ACCELERATION_STRUCTURE = 16,\n\tDXIL_SPV_RESOURCE_KIND_FEEDBACK_TEXTURE_2D = 17,\n\tDXIL_SPV_RESOURCE_KIND_FEEDBACK_TEXTURE_2D_ARRAY = 18,\n\tDXIL_SPV_RESOURCE_KIND_INT_MAX = 0x7fffffff\n} dxil_spv_resource_kind;\n\ntypedef enum dxil_spv_resource_class\n{\n\tDXIL_SPV_RESOURCE_CLASS_SRV = 0,\n\tDXIL_SPV_RESOURCE_CLASS_UAV = 1,\n\tDXIL_SPV_RESOURCE_CLASS_CBV = 2,\n\tDXIL_SPV_RESOURCE_CLASS_SAMPLER = 3,\n\tDXIL_SPV_RESOURCE_CLASS_INT_MAX = 0x7fffffff\n} dxil_spv_resource_class;\n\ntypedef enum dxil_spv_vulkan_descriptor_type\n{\n\t/* Use the descriptor type we expect, textures, typed buffers,\n\t * CBV or samplers only have one target type. */\n\tDXIL_SPV_VULKAN_DESCRIPTOR_TYPE_IDENTITY = 0,\n\t/* For untyped buffer types, we can select whether to use an SSBO implementation or texel buffer one. */\n\tDXIL_SPV_VULKAN_DESCRIPTOR_TYPE_SSBO = 1,\n\tDXIL_SPV_VULKAN_DESCRIPTOR_TYPE_TEXEL_BUFFER = 2,\n\tDXIL_SPV_VULKAN_DESCRIPTOR_TYPE_BUFFER_DEVICE_ADDRESS = 3,\n\tDXIL_SPV_VULKAN_DESCRIPTOR_TYPE_UBO = 4,\n\t/* Special magic for tilers. Does not map to anything directly in D3D12 API. */\n\tDXIL_SPV_VULKAN_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 5,\n\tDXIL_SPV_VULKAN_DESCRIPTOR_TYPE_INT_MAX = 0x7fffffff\n} dxil_spv_vulkan_descriptor_type;\n\ntypedef enum dxil_spv_rdat_subobject_kind\n{\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_STATE_OBJECT_CONFIG = 0,\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE = 1,\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_LOCAL_ROOT_SIGNATURE = 2,\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_SUBOBJECT_TO_EXPORTS_ASSOCIATION = 8,\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_SHADER_CONFIG = 9,\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG = 10,\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_HIT_GROUP = 11,\n\tDXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1 = 12,\n\tDXIL_SPV_RDAT_SUBOBJECT_TYPE_INT_MAX = 0x7fffffff\n} dxil_spv_rdat_subobject_kind;\n\ntypedef enum dxil_spv_hit_group_type\n{\n\tDXIL_SPV_HIT_GROUP_TYPE_TRIANGLE = 0,\n\tDXIL_SPV_HIT_GROUP_TYPE_PROCEDURAL = 1,\n\tDXIL_SPV_HIT_GROUP_TYPE_INT_MAX = 0x7fffffff\n} dxil_spv_hit_group_type;\n\ntypedef enum dxil_spv_shader_quirk\n{\n\tDXIL_SPV_SHADER_QUIRK_NONE = 0,\n\t/* This is softer and only applies to shaders that uses thread group coherence at least once.\n\t * If that is the case, promotes all other uses too. Intended to be suitable for a game-global workaround. */\n\tDXIL_SPV_SHADER_QUIRK_FORCE_DEVICE_MEMORY_BARRIERS_THREAD_GROUP_COHERENCE = 1,\n\tDXIL_SPV_SHADER_QUIRK_ASSUME_BROKEN_SUB_8x8_CUBE_MIPS = 2,\n\tDXIL_SPV_SHADER_QUIRK_ROBUST_PHYSICAL_CBV_FORWARDING = 3,\n\tDXIL_SPV_SHADER_QUIRK_MESH_OUTPUTS_ROBUSTNESS = 4,\n\tDXIL_SPV_SHADER_QUIRK_AGGRESSIVE_NONUNIFORM = 5,\n\tDXIL_SPV_SHADER_QUIRK_ROBUST_PHYSICAL_CBV = 6,\n\t/* This is a harder workaround which forces UAV barriers even if shader does not use anything like that.\n\t * Intended to be used with specific shaders since it's not feasible to detect the race condition algorithmically. */\n\tDXIL_SPV_SHADER_QUIRK_PROMOTE_GROUP_TO_DEVICE_MEMORY_BARRIER = 7,\n\tDXIL_SPV_SHADER_QUIRK_GROUP_SHARED_AUTO_BARRIER = 8,\n\tDXIL_SPV_SHADER_QUIRK_FIXUP_LOOP_HEADER_UNDEF_PHIS = 9,\n\tDXIL_SPV_SHADER_QUIRK_FIXUP_RSQRT_INF_NAN = 10,\n\tDXIL_SPV_SHADER_QUIRK_IGNORE_PRIMITIVE_SHADING_RATE = 11,\n\tDXIL_SPV_SHADER_QUIRK_ROBUST_COMPUTE_QUAD_BROADCAST = 12,\n\tDXIL_SPV_SHADER_QUIRK_PRECISE_FMA = 13,\n\tDXIL_SPV_SHADER_QUIRK_INT_MAX = 0x7fffffff\n} dxil_spv_shader_quirk;\n\ntypedef enum dxil_spv_meta_descriptor\n{\n\tDXIL_SPV_META_DESCRIPTOR_RESOURCE_DESCRIPTOR_HEAP_SIZE = 0,\n\tDXIL_SPV_META_DESCRIPTOR_RAW_DESCRIPTOR_HEAP_VIEW = 1,\n\tDXIL_SPV_META_DESCRIPTOR_DYNAMIC_VIEW_INSTANCING_OFFSETS = 2,\n\tDXIL_SPV_META_DESCRIPTOR_DYNAMIC_VIEW_INSTANCING_MASK = 3,\n\tDXIL_SPV_META_DESCRIPTOR_INT_MAX = 0x7fffffff\n} dxil_spv_meta_descriptor;\n\ntypedef enum dxil_spv_meta_descriptor_kind\n{\n\tDXIL_SPV_META_DESCRIPTOR_KIND_INVALID = 0,\n\tDXIL_SPV_META_DESCRIPTOR_KIND_PUSH_CONSTANT,\n\tDXIL_SPV_META_DESCRIPTOR_KIND_PUSH_BDA,\n\tDXIL_SPV_META_DESCRIPTOR_KIND_UBO_CONTAINING_CONSTANT,\n\tDXIL_SPV_META_DESCRIPTOR_KIND_UBO_CONTAINING_BDA,\n\tDXIL_SPV_META_DESCRIPTOR_KIND_READONLY_SSBO,\n\tDXIL_SPV_META_DESCRIPTOR_KIND_INT_MAX = 0x7fffffff\n} dxil_spv_meta_descriptor_kind;\n\n#ifdef DXIL_SPV_ENABLE_EXPERIMENTAL_WORKGRAPHS\ntypedef enum dxil_spv_node_launch_type\n{\n\tDXIL_SPV_NODE_LAUNCH_TYPE_INVALID = 0,\n\tDXIL_SPV_NODE_LAUNCH_TYPE_BROADCASTING = 1,\n\tDXIL_SPV_NODE_LAUNCH_TYPE_COALESCING = 2,\n\tDXIL_SPV_NODE_LAUNCH_TYPE_THREAD = 3,\n\tDXIL_SPV_NODE_LAUNCH_TYPE_INT_MAX = 0x7fffffff\n} dxil_spv_node_launch_type;\n#endif\n\ntypedef struct dxil_spv_d3d_binding\n{\n\tdxil_spv_shader_stage stage;\n\tdxil_spv_resource_kind kind;\n\tunsigned resource_index;\n\tunsigned register_space;\n\tunsigned register_index;\n\tunsigned range_size;\n\t/* For raw buffers, this is equal to 16, for structured buffers this is equal to the stride of the elements.\n\t * This can be used by the implementation to select an appropriate descriptor type.\n\t * Otherwise, 0. */\n\tunsigned alignment;\n} dxil_spv_d3d_binding;\n\ntypedef struct dxil_spv_vulkan_binding\n{\n\tunsigned set;\n\tunsigned binding;\n\n\tunion\n\t{\n\t\t/* For bindless, refers to the Nth root constant.\n\t\t * For buffer device address, refers to the Nth root descriptor.\n\t\t */\n\t\tunsigned root_constant_index;\n\n\t\t/* For input attachments, refers to the input_attachment_index.\n\t\t* -1u maps to depth-stencil attachment and anything else maps to color attachment index. */\n\t\tunsigned input_attachment_index;\n\t};\n\n\tstruct\n\t{\n\t\tunsigned heap_root_offset;\n\t\tdxil_spv_bool use_heap;\n\t} bindless;\n\tdxil_spv_vulkan_descriptor_type descriptor_type;\n} dxil_spv_vulkan_binding;\n\n/* Remaps UAVs to desired binding points. */\ntypedef struct dxil_spv_uav_d3d_binding\n{\n\tdxil_spv_d3d_binding d3d_binding;\n\tdxil_spv_bool has_counter;\n} dxil_spv_uav_d3d_binding;\n\ntypedef struct dxil_spv_srv_vulkan_binding\n{\n\tdxil_spv_vulkan_binding buffer_binding;\n\tdxil_spv_vulkan_binding offset_binding;\n} dxil_spv_srv_vulkan_binding;\n\ntypedef struct dxil_spv_uav_vulkan_binding\n{\n\tdxil_spv_vulkan_binding buffer_binding;\n\tdxil_spv_vulkan_binding counter_binding;\n\tdxil_spv_vulkan_binding offset_binding;\n} dxil_spv_uav_vulkan_binding;\n\ntypedef struct dxil_spv_push_constant_mapping\n{\n\tunsigned offset_in_words;\n} dxil_spv_push_constant_mapping;\n\ntypedef struct dxil_spv_cbv_vulkan_binding\n{\n\tunion\n\t{\n\t\tdxil_spv_vulkan_binding uniform_binding;\n\t\tdxil_spv_push_constant_mapping push_constant;\n\t} vulkan;\n\tdxil_spv_bool push_constant;\n} dxil_spv_cbv_vulkan_binding;\n\ntypedef struct dxil_spv_compiled_spirv\n{\n\tconst void *data;\n\tsize_t size;\n} dxil_spv_compiled_spirv;\n\ntypedef dxil_spv_bool (*dxil_spv_srv_remapper_cb)(void *userdata,\n                                                  const dxil_spv_d3d_binding *d3d_binding,\n                                                  dxil_spv_srv_vulkan_binding *vulkan_binding);\ntypedef dxil_spv_bool (*dxil_spv_sampler_remapper_cb)(void *userdata,\n                                                      const dxil_spv_d3d_binding *d3d_binding,\n                                                      dxil_spv_vulkan_binding *vulkan_binding);\ntypedef dxil_spv_bool (*dxil_spv_uav_remapper_cb)(void *userdata,\n                                                  const dxil_spv_uav_d3d_binding *d3d_uav_binding,\n                                                  dxil_spv_uav_vulkan_binding *vulkan_uav_binding);\ntypedef dxil_spv_bool (*dxil_spv_cbv_remapper_cb)(void *userdata,\n                                                  const dxil_spv_d3d_binding *d3d_uav_binding,\n                                                  dxil_spv_cbv_vulkan_binding *vulkan_uav_binding);\n\ntypedef struct dxil_spv_rdat_subobject\n{\n\t// See dxil_parser.hpp for details.\n\tdxil_spv_rdat_subobject_kind kind;\n\tconst char *subobject_name;\n\tdxil_spv_hit_group_type hit_group_type;\n\tconst char * const *exports;\n\tunsigned num_exports;\n\tunsigned args[2];\n\tconst void *payload;\n\tsize_t payload_size;\n} dxil_spv_rdat_subobject;\n\n#ifdef DXIL_SPV_ENABLE_EXPERIMENTAL_WORKGRAPHS\ntypedef struct dxil_spv_node_input_data\n{\n\tconst char *node_id; /* This is often same as entry point name, but does not have to be. */\n\tunsigned payload_stride; /* If 0, there is no input payload, i.e. EmptyNode. */\n\tdxil_spv_node_launch_type launch_type;\n\tunsigned node_array_index;\n\tunsigned dispatch_grid_offset;\n\tunsigned dispatch_grid_type_bits;\n\tunsigned dispatch_grid_components;\n\tunsigned broadcast_grid[3]; /* For broadcast nodes. */\n\tunsigned thread_group_size_spec_id[3];\n\tunsigned max_broadcast_grid_spec_id[3];\n\tunsigned recursion_factor; /* [NodeMaxRecursionDepth] */\n\tunsigned coalesce_factor;\n\tconst char *node_share_input_id;\n\tunsigned node_share_input_array_index;\n\tunsigned local_root_arguments_table_index;\n\tunsigned is_indirect_bda_stride_program_entry_spec_id;\n\tunsigned is_entry_point_spec_id;\n\tunsigned dispatch_grid_is_upper_bound_spec_id;\n\tunsigned is_static_broadcast_node_spec_id;\n\tdxil_spv_bool dispatch_grid_is_upper_bound; /* [NodeMaxDispatchGrid] if true. */\n\tdxil_spv_bool node_track_rw_input_sharing; /* Payload is tagged with [NodeTrackRWInputSharing]. */\n\tdxil_spv_bool is_program_entry; /* [NodeIsProgramEntry] */\n} dxil_spv_node_input_data;\n\ntypedef struct dxil_spv_node_output_data\n{\n\tconst char *node_id;\n\tunsigned node_array_index;\n\tunsigned node_array_size; /* If UINT32_MAX, it's unbounded. */\n\tunsigned node_index_spec_constant_id;\n\tunsigned max_records;\n\tdxil_spv_bool sparse_array;\n\t/* We get the rest of the information from the target entry point's input data.\n\t * Output data is only for determining linkage. */\n} dxil_spv_node_output_data;\n#endif\n\ntypedef enum dxil_spv_log_level\n{\n\tDXIL_SPV_LOG_LEVEL_DEBUG,\n\tDXIL_SPV_LOG_LEVEL_WARN,\n\tDXIL_SPV_LOG_LEVEL_ERROR,\n\tDXIL_SPV_LOG_LEVEL_INT_MAX = 0x7fffffff\n} dxil_spv_log_level;\n\ntypedef void (*dxil_spv_log_cb)(void *userdata, dxil_spv_log_level, const char *);\n\ntypedef enum dxil_spv_option\n{\n\tDXIL_SPV_OPTION_INVALID = 0,\n\tDXIL_SPV_OPTION_SHADER_DEMOTE_TO_HELPER = 1,\n\tDXIL_SPV_OPTION_DUAL_SOURCE_BLENDING = 2,\n\tDXIL_SPV_OPTION_OUTPUT_SWIZZLE = 3,\n\tDXIL_SPV_OPTION_RASTERIZER_SAMPLE_COUNT = 4,\n\tDXIL_SPV_OPTION_ROOT_CONSTANT_INLINE_UNIFORM_BLOCK = 5,\n\tDXIL_SPV_OPTION_BINDLESS_CBV_SSBO_EMULATION = 6,\n\tDXIL_SPV_OPTION_PHYSICAL_STORAGE_BUFFER = 7,\n\tDXIL_SPV_OPTION_SBT_DESCRIPTOR_SIZE_LOG2 = 8,\n\tDXIL_SPV_OPTION_SSBO_ALIGNMENT = 9,\n\tDXIL_SPV_OPTION_TYPED_UAV_READ_WITHOUT_FORMAT = 10,\n\tDXIL_SPV_OPTION_SHADER_SOURCE_FILE = 11,\n\tDXIL_SPV_OPTION_BINDLESS_TYPED_BUFFER_OFFSETS = 12,\n\tDXIL_SPV_OPTION_BINDLESS_OFFSET_BUFFER_LAYOUT = 13,\n\tDXIL_SPV_OPTION_STORAGE_INPUT_OUTPUT_16BIT = 14,\n\tDXIL_SPV_OPTION_DESCRIPTOR_QA = 15,\n\tDXIL_SPV_OPTION_MIN_PRECISION_NATIVE_16BIT = 16,\n\tDXIL_SPV_OPTION_SHADER_I8_DOT = 17,\n\tDXIL_SPV_OPTION_SHADER_RAY_TRACING_PRIMITIVE_CULLING = 18,\n\tDXIL_SPV_OPTION_INVARIANT_POSITION = 19,\n\tDXIL_SPV_OPTION_SCALAR_BLOCK_LAYOUT = 20,\n\tDXIL_SPV_OPTION_BARYCENTRIC_KHR = 21,\n\tDXIL_SPV_OPTION_ROBUST_PHYSICAL_CBV_LOAD = 22,\n\tDXIL_SPV_OPTION_ARITHMETIC_RELAXED_PRECISION = 23,\n\tDXIL_SPV_OPTION_PHYSICAL_ADDRESS_DESCRIPTOR_INDEXING = 24,\n\tDXIL_SPV_OPTION_FORCE_SUBGROUP_SIZE = 25,\n\tDXIL_SPV_OPTION_DENORM_PRESERVE_SUPPORT = 26,\n\tDXIL_SPV_OPTION_STRICT_HELPER_LANE_WAVE_OPS = 27,\n\tDXIL_SPV_OPTION_SUBGROUP_PARTITIONED_NV = 28,\n\tDXIL_SPV_OPTION_DEAD_CODE_ELIMINATE = 29,\n\tDXIL_SPV_OPTION_PRECISE_CONTROL = 30,\n\tDXIL_SPV_OPTION_SAMPLE_GRAD_OPTIMIZATION_CONTROL = 31,\n\tDXIL_SPV_OPTION_OPACITY_MICROMAP = 32,\n\tDXIL_SPV_OPTION_BRANCH_CONTROL = 33,\n\tDXIL_SPV_OPTION_SUBGROUP_PROPERTIES = 34,\n\tDXIL_SPV_OPTION_DESCRIPTOR_HEAP_ROBUSTNESS = 35,\n\tDXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES_NV = 36,\n\tDXIL_SPV_OPTION_QUAD_CONTROL_RECONVERGENCE = 37,\n\tDXIL_SPV_OPTION_RAW_ACCESS_CHAINS_NV = 38,\n\tDXIL_SPV_OPTION_DRIVER_VERSION = 39,\n\tDXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES = 40,\n\tDXIL_SPV_OPTION_INSTRUCTION_INSTRUMENTATION = 41,\n\tDXIL_SPV_OPTION_SHADER_QUIRK = 42,\n\tDXIL_SPV_OPTION_EXTENDED_ROBUSTNESS = 43,\n\tDXIL_SPV_OPTION_MAX_TESS_FACTOR = 44,\n\tDXIL_SPV_OPTION_VULKAN_MEMORY_MODEL = 45,\n\tDXIL_SPV_OPTION_FLOAT8_SUPPORT = 46,\n\tDXIL_SPV_OPTION_NVAPI = 47,\n\tDXIL_SPV_OPTION_EXTENDED_NON_SEMANTIC = 48,\n\tDXIL_SPV_OPTION_VIEW_INSTANCING = 49,\n\tDXIL_SPV_OPTION_MIXED_FLOAT_DOT_PRODUCT = 50,\n\tDXIL_SPV_OPTION_COMPUTE_SHADER_DERIVATIVES_QUAD = 51,\n\tDXIL_SPV_OPTION_INT_MAX = 0x7fffffff\n} dxil_spv_option;\n\ntypedef enum dxil_spv_shader_feature\n{\n\tDXIL_SPV_SHADER_FEATURE_NATIVE_16BIT_OPERATIONS = 0,\n\tDXIL_SPV_SHADER_FEATURE_INT_MAX = 0x7fffffff\n} dxil_spv_shader_feature;\n\ntypedef enum dxil_spv_instruction_instrumentation_type\n{\n\tDXIL_SPV_INSTRUCTION_INSTRUMENTATION_TYPE_FULL_NAN_INF = 0,\n\tDXIL_SPV_INSTRUCTION_INSTRUMENTATION_TYPE_EXTERNALLY_VISIBLE_WRITE_NAN_INF = 1,\n\tDXIL_SPV_INSTRUCTION_INSTRUMENTATION_TYPE_FLUSH_NAN_TO_ZERO = 2,\n\tDXIL_SPV_INSTRUCTION_INSTRUMENTATION_TYPE_EXPECT_ASSUME = 3,\n\tDXIL_SPV_INSTRUCTION_INSTRUMENTATION_TYPE_BUFFER_SYNCHRONIZATION_VALIDATION = 4,\n\tDXIL_SPV_INSTRUCTION_INSTRUMENTATION_INT_MAX = 0x7fffffff\n} dxil_spv_instruction_instrumentation_type;\n\ntypedef struct dxil_spv_option_base\n{\n\tdxil_spv_option type;\n} dxil_spv_option_base;\n\ntypedef struct dxil_spv_option_shader_demote_to_helper\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_shader_demote_to_helper;\n\ntypedef struct dxil_spv_option_dual_source_blending\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_dual_source_blending;\n\ntypedef struct dxil_spv_option_output_swizzle\n{\n\tdxil_spv_option_base base;\n\t/* Each element represents one SV_Target location in a pixel shader.\n\t * Bits [0:1] represent which output component to emit in R.\n\t * Bits [2:3] represent which output component to emit in G.\n\t * Bits [4:5] represent which output component to emit in B.\n\t * Bits [6:7] represent which output component to emit in A.\n\t * There must exist a 1:1 mapping between input and output, i.e. all components must be used\n\t * an an input to exactly one output component.\n\t */\n\tconst unsigned *swizzles;\n\tunsigned swizzle_count;\n} dxil_spv_option_output_swizzle;\n\ntypedef struct dxil_spv_option_rasterizer_sample_count\n{\n\tdxil_spv_option_base base;\n\tunsigned sample_count;\n\tdxil_spv_bool spec_constant;\n} dxil_spv_option_rasterizer_sample_count;\n\ntypedef struct dxil_spv_option_root_constant_inline_uniform_block\n{\n\tdxil_spv_option_base base;\n\tunsigned desc_set;\n\tunsigned binding;\n\tdxil_spv_bool enable;\n} dxil_spv_option_root_constant_inline_uniform_block;\n\ntypedef struct dxil_spv_option_bindless_cbv_ssbo_emulation\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enable;\n} dxil_spv_option_bindless_cbv_ssbo_emulation;\n\ntypedef struct dxil_spv_option_physical_storage_buffer\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enable;\n} dxil_spv_option_physical_storage_buffer;\n\ntypedef struct dxil_spv_option_sbt_descriptor_size_log2\n{\n\tdxil_spv_option_base base;\n\tunsigned size_log2_srv_uav_cbv;\n\tunsigned size_log2_sampler;\n} dxil_spv_option_sbt_descriptor_size_log2;\n\ntypedef struct dxil_spv_option_ssbo_alignment\n{\n\tdxil_spv_option_base base;\n\tunsigned alignment;\n} dxil_spv_option_ssbo_alignment;\n\ntypedef struct dxil_spv_option_typed_uav_read_without_format\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_typed_uav_read_without_format;\n\ntypedef struct dxil_spv_option_shader_source_file\n{\n\tdxil_spv_option_base base;\n\tconst char *name; /* String constants will be copied. */\n} dxil_spv_option_shader_source_file;\n\ntypedef struct dxil_spv_option_bindless_typed_buffer_offsets\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enable;\n} dxil_spv_option_bindless_typed_buffer_offsets;\n\ntypedef struct dxil_spv_option_bindless_offset_buffer_layout\n{\n\tdxil_spv_option_base base;\n\tunsigned untyped_offset;\n\tunsigned typed_offset;\n\tunsigned stride;\n} dxil_spv_option_bindless_offset_buffer_layout;\n\ntypedef struct dxil_spv_option_storage_input_output_16bit\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_storage_input_output_16bit;\n\ntypedef struct dxil_spv_option_descriptor_qa\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n\tunsigned version;\n\tunsigned global_desc_set;\n\tunsigned global_binding;\n\tunsigned heap_desc_set;\n\tunsigned heap_binding;\n\tunsigned long long shader_hash;\n} dxil_spv_option_descriptor_qa;\n\ntypedef struct dxil_spv_option_min_precision_native_16bit\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_min_precision_native_16bit;\n\ntypedef struct dxil_spv_option_shader_i8_dot\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_shader_i8_dot;\n\ntypedef struct dxil_spv_option_shader_ray_tracing_primitive_culling\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_shader_ray_tracing_primitive_culling;\n\ntypedef struct dxil_spv_option_invariant_position\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_invariant_position;\n\ntypedef struct dxil_spv_option_scalar_block_layout\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n\tdxil_spv_bool supports_per_component_robustness;\n} dxil_spv_option_scalar_block_layout;\n\ntypedef struct dxil_spv_option_barycentric_khr\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_barycentric_khr;\n\n/* Obsolete. Use the shader quirk version of this instead. */\ntypedef struct dxil_spv_option_robust_physical_cbv_load\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_robust_physical_cbv_load;\n\ntypedef struct dxil_spv_option_arithmetic_relaxed_precision\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_arithmetic_relaxed_precision;\n\ntypedef struct dxil_spv_option_physical_address_descriptor_indexing\n{\n\tdxil_spv_option_base base;\n\tunsigned element_stride;\n\tunsigned element_offset;\n} dxil_spv_option_physical_address_descriptor_indexing;\n\ntypedef struct dxil_spv_option_force_subgroup_size\n{\n\tdxil_spv_option_base base;\n\tunsigned forced_value;\n\tdxil_spv_bool wave_size_enable;\n} dxil_spv_option_force_subgroup_size;\n\ntypedef struct dxil_spv_option_denorm_preserve_support\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supports_float16_denorm_preserve;\n\tdxil_spv_bool supports_float64_denorm_preserve;\n} dxil_spv_option_denorm_preserve_support;\n\ntypedef struct dxil_spv_option_strict_helper_lane_wave_ops\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enable;\n} dxil_spv_option_strict_helper_lane_wave_ops;\n\ntypedef struct dxil_spv_option_subgroup_partitioned_nv\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_subgroup_partitioned_nv;\n\ntypedef struct dxil_spv_option_dead_code_eliminate\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_dead_code_eliminate;\n\ntypedef struct dxil_spv_option_precise_control\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool force_precise;\n\tdxil_spv_bool propagate_precise;\n} dxil_spv_option_precise_control;\n\ntypedef struct dxil_spv_option_sample_grad_optimization_control\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n\tdxil_spv_bool assume_uniform_scale;\n} dxil_spv_option_sample_grad_optimization_control;\n\ntypedef struct dxil_spv_option_opacity_micromap\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_opacity_micromap;\n\ntypedef struct dxil_spv_option_branch_control\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool use_shader_metadata;\n\tdxil_spv_bool force_unroll;\n\tdxil_spv_bool force_loop;\n\tdxil_spv_bool force_flatten;\n\tdxil_spv_bool force_branch;\n} dxil_spv_option_branch_control;\n\ntypedef struct dxil_spv_option_subgroup_properties\n{\n\tdxil_spv_option_base base;\n\tunsigned minimum_size;\n\tunsigned maximum_size;\n} dxil_spv_option_subgroup_properties;\n\ntypedef struct dxil_spv_option_descriptor_heap_robustness\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_descriptor_heap_robustness;\n\ntypedef struct dxil_spv_option_compute_shader_derivatives_nv\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_compute_shader_derivatives_nv;\n\ntypedef struct dxil_spv_option_quad_control_reconvergence\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supports_quad_control;\n\tdxil_spv_bool supports_maximal_reconvergence;\n\tdxil_spv_bool force_maximal_reconvergence;\n} dxil_spv_option_quad_control_reconvergence;\n\ntypedef struct dxil_spv_option_raw_access_chains_nv\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supported;\n} dxil_spv_option_raw_access_chains_nv;\n\ntypedef struct dxil_spv_option_driver_version\n{\n\tdxil_spv_option_base base;\n\tunsigned driver_id;\n\tunsigned driver_version;\n} dxil_spv_option_driver_version;\n\ntypedef struct dxil_spv_option_compute_shader_derivatives\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supports_nv;\n\tdxil_spv_bool supports_khr;\n} dxil_spv_option_compute_shader_derivatives;\n\ntypedef struct dxil_spv_option_instruction_instrumentation\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n\tunsigned version;\n\tunsigned control_desc_set;\n\tunsigned control_binding;\n\tunsigned payload_desc_set;\n\tunsigned payload_binding;\n\tunsigned long long shader_hash;\n\tdxil_spv_instruction_instrumentation_type type;\n} dxil_spv_option_instruction_instrumentation;\n\ntypedef struct dxil_spv_option_shader_quirk\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_shader_quirk quirk;\n} dxil_spv_option_shader_quirk;\n\ntypedef struct dxil_spv_option_extended_robustness\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool robust_group_shared;\n\tdxil_spv_bool robust_alloca;\n\tdxil_spv_bool robust_constant_lut;\n} dxil_spv_option_extended_robustness;\n\ntypedef struct dxil_spv_option_max_tess_factor\n{\n\tdxil_spv_option_base base;\n\tunsigned max_tess_factor;\n} dxil_spv_option_max_tess_factor;\n\ntypedef struct dxil_spv_option_vulkan_memory_model\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_vulkan_memory_model;\n\ntypedef struct dxil_spv_option_float8_support\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool wmma_fp8;\n\tdxil_spv_bool nv_cooperative_matrix2_conversions;\n} dxil_spv_option_float8_support;\n\ntypedef struct dxil_spv_option_nvapi\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n\tunsigned register_index;\n\tunsigned register_space;\n} dxil_spv_option_nvapi;\n\ntypedef struct dxil_spv_option_extended_non_semantic\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n} dxil_spv_option_extended_non_semantic;\n\n#ifdef DXIL_SPV_ENABLE_EXPERIMENTAL_MULTIVIEW\ntypedef struct dxil_spv_option_view_instancing\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool enabled;\n\tdxil_spv_bool last_pre_rasterization_stage;\n\tunsigned view_index_to_view_instance_spec_id;\n\tunsigned view_instance_to_viewport_spec_id;\n} dxil_spv_option_view_instancing;\n#endif\n\ntypedef struct dxil_spv_option_mixed_float_dot_product\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool fp16_fp16_fp32;\n\tdxil_spv_bool reserved[4]; /* 4 unique features in the extension + reserved for hypothetical promoted EXT to avoid revving ABI again. */\n} dxil_spv_option_mixed_float_dot_product;\n\ntypedef struct dxil_spv_option_compute_shader_derivatives_quad\n{\n\tdxil_spv_option_base base;\n\tdxil_spv_bool supports_quad;\n} dxil_spv_option_compute_shader_derivatives_quad;\n\n/* Gets the ABI version used to build this library. Used to detect API/ABI mismatches. */\nDXIL_SPV_PUBLIC_API void dxil_spv_get_version(unsigned *major, unsigned *minor, unsigned *patch);\n\n/* Parsing API */\n/* Parses and frees a DXBC blob. */\ntypedef struct dxil_spv_parsed_blob_s *dxil_spv_parsed_blob;\n\n/* Parses a DXBC archive as is passed into CreatePipeline, which contains a DXIL blob. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parse_dxil_blob(const void *data, size_t size, dxil_spv_parsed_blob *blob);\n/* A variant that attempts to read the STAT block instead. The STAT block contains DXIL that is only used for reflection. (?!?!) */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parse_reflection_dxil_blob(const void *data, size_t size, dxil_spv_parsed_blob *blob);\n\n/* Parses raw DXIL (LLVM BC). */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parse_dxil(const void *data, size_t size, dxil_spv_parsed_blob *blob);\n\n/* Dumps the LLVM IR representation to console. For debugging. */\nDXIL_SPV_PUBLIC_API void dxil_spv_parsed_blob_dump_llvm_ir(dxil_spv_parsed_blob blob);\n\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_disassembled_ir(dxil_spv_parsed_blob blob, const char **str);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_raw_ir(dxil_spv_parsed_blob blob, const void **data, size_t *size);\n\nDXIL_SPV_PUBLIC_API dxil_spv_shader_stage dxil_spv_parsed_blob_get_shader_stage(dxil_spv_parsed_blob blob);\nDXIL_SPV_PUBLIC_API dxil_spv_shader_stage dxil_spv_parsed_blob_get_shader_stage_for_entry(dxil_spv_parsed_blob blob, const char *entry);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_entry_index_by_name(dxil_spv_parsed_blob blob,\n                                                                                 const char *entry,\n                                                                                 unsigned *index);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_num_entry_points(dxil_spv_parsed_blob blob, unsigned *count);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_entry_point_name(dxil_spv_parsed_blob blob,\n                                                                              unsigned index,\n                                                                              const char **mangled_entry);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_entry_point_demangled_name(dxil_spv_parsed_blob blob,\n                                                                                        unsigned index,\n                                                                                        const char **demangled_entry);\n\n#ifdef DXIL_SPV_ENABLE_EXPERIMENTAL_WORKGRAPHS\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_entry_point_node_input(\n\tdxil_spv_parsed_blob blob, unsigned index, dxil_spv_node_input_data *data);\n\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_entry_point_num_node_outputs(\n\tdxil_spv_parsed_blob blob, unsigned index, unsigned *num_outputs);\n\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_get_entry_point_node_output(\n\tdxil_spv_parsed_blob blob, unsigned index, unsigned output_index, dxil_spv_node_output_data *data);\n#endif\n\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_parsed_blob_scan_resources(\n\t\tdxil_spv_parsed_blob blob,\n\t\tdxil_spv_srv_remapper_cb srv_remapper,\n\t\tdxil_spv_sampler_remapper_cb sampler_remapper,\n\t\tdxil_spv_cbv_remapper_cb cbv_remapper,\n\t\tdxil_spv_uav_remapper_cb uav_remapper,\n\t\tvoid *userdata);\n\n/* For DXR, API subobjects can be embedded inside the blob. */\nDXIL_SPV_PUBLIC_API unsigned dxil_spv_parsed_blob_get_num_rdat_subobjects(\n\t\tdxil_spv_parsed_blob blob);\nDXIL_SPV_PUBLIC_API void dxil_spv_parsed_blob_get_rdat_subobject(\n\t\tdxil_spv_parsed_blob blob, unsigned index, dxil_spv_rdat_subobject *subobject);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_parsed_blob_free(dxil_spv_parsed_blob blob);\n/* Parsing API */\n\n/* Sets per thread global state. */\nDXIL_SPV_PUBLIC_API void dxil_spv_set_thread_log_callback(dxil_spv_log_cb callback, void *userdata);\n\n/* Converter API */\n\ntypedef struct dxil_spv_converter_s *dxil_spv_converter;\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_create_converter(dxil_spv_parsed_blob blob, dxil_spv_converter *converter);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_create_converter_with_reflection(dxil_spv_parsed_blob blob,\n                                                                              dxil_spv_parsed_blob reflection_blob,\n                                                                              dxil_spv_converter *converter);\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_free(dxil_spv_converter converter);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_entry_point(dxil_spv_converter converter, const char *entry_point);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_stage_input_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_shader_stage_io_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_stage_output_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_shader_stage_io_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_vertex_input_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_vertex_input_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_stream_output_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_stream_output_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_srv_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_srv_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_sampler_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_sampler_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_root_constant_word_count(dxil_spv_converter converter,\n                                                                         unsigned num_words);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_root_descriptor_count(dxil_spv_converter converter,\n                                                                      unsigned count);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_uav_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_uav_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_cbv_remapper(\n\t\tdxil_spv_converter converter,\n\t\tdxil_spv_cbv_remapper_cb remapper,\n\t\tvoid *userdata);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_add_local_root_constants(\n\tdxil_spv_converter converter,\n\tunsigned register_space,\n\tunsigned register_index,\n\tunsigned num_words);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_add_local_root_descriptor(\n\tdxil_spv_converter converter,\n\tdxil_spv_resource_class resource_class,\n\tunsigned register_space,\n\tunsigned register_index);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_add_local_root_descriptor_table(\n\tdxil_spv_converter converter,\n\tdxil_spv_resource_class resource_class,\n\tunsigned register_space,\n\tunsigned register_index,\n\tunsigned num_descriptors_in_range,\n\tunsigned offset_in_heap);\n\n/* For multiple table entries per local root parameter, call begin, at least one add_local, and then end\n * will commit that local root parameter. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_begin_local_root_descriptor_table(\n\tdxil_spv_converter converter);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_end_local_root_descriptor_table(\n\tdxil_spv_converter converter);\n\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_add_root_parameter_mapping(\n\tdxil_spv_converter converter, unsigned root_parameter_index, unsigned offset);\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_add_root_descriptor_mapping(\n        dxil_spv_converter converter, unsigned root_parameter_index,\n        unsigned desc_set, unsigned binding);\n\n/* Pointer is owned by application. Must remain valid until compile() is called. */\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_add_non_semantic_debug_info(\n\tdxil_spv_converter converter, const char *tag, const void *data, size_t size);\n\n/* For domain shader, when linking with hull shader. */\nDXIL_SPV_PUBLIC_API void dxil_spv_converter_set_patch_location_offset(\n\tdxil_spv_converter converter, unsigned offset);\n\n/* After setting up converter, runs the converted to SPIR-V. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_run(dxil_spv_converter converter);\n\n/* Obtain final SPIR-V. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_compiled_spirv(dxil_spv_converter converter,\n                                                                          dxil_spv_compiled_spirv *compiled);\n\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_compiled_entry_point(dxil_spv_converter converter,\n                                                                                const char **entry_point);\n\n/* Useful to check if the implementation recognizes a particular option for ABI compatibility. */\nDXIL_SPV_PUBLIC_API dxil_spv_bool dxil_spv_converter_supports_option(dxil_spv_option option);\n/* Adds a generic option to the implementation which allows it to generate more advanced code or change codegen if desired.\n * Baseline assumed feature set is Vulkan 1.1 / SPIR-V 1.3. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_add_option(dxil_spv_converter converter,\n                                                                  const dxil_spv_option_base *option);\n\n/* After compilation. Queries if SubgroupSize builtin was emitted, which requires ALLOW_VARYING_SUBGROUP_SIZE\n * in Vulkan. */\nDXIL_SPV_PUBLIC_API dxil_spv_bool dxil_spv_converter_uses_subgroup_size(dxil_spv_converter converter);\n\n/* After compilation. Queries CS workgroup dimensions used.\n * Can be relevant for some subgroup_size_control workarounds. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_compute_workgroup_dimensions(\n\tdxil_spv_converter converter,\n\tunsigned *x, unsigned *y, unsigned *z);\n\n/* After compilation. Queries CS required wave size.\n * If *wave_size is non-zero, maps to requiredSubgroupSize, otherwise, VARYING_SUBGROUP_SIZE. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_compute_required_wave_size(\n\tdxil_spv_converter converter, unsigned *wave_size);\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_compute_wave_size_range(\n\tdxil_spv_converter converter, unsigned *wave_size, unsigned *wave_size_max, unsigned *wave_size_preferred);\n\n/* After compilation. Queries suggested maximum wave size. The behavior here depends on heuristics\n * and can be ignored, but is often used for workarounds and identifying dubious shader code.\n * If *wave_size is non-zero, could map to requiredSubgroupSize. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_compute_heuristic_max_wave_size(\n\tdxil_spv_converter converter, unsigned *wave_size);\n\n/* After compilation. Queries suggested minimum wave size. The behavior here depends on heuristics\n * and can be ignored, but is often used for workarounds and identifying dubious shader code.\n * If *wave_size is non-zero, could map to requiredSubgroupSize. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_compute_heuristic_min_wave_size(\n\tdxil_spv_converter converter, unsigned *wave_size);\n\n/* After compilation, queries num vertices for HS. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_patch_vertex_count(\n\tdxil_spv_converter converter, unsigned *patch_vertices);\n\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_get_patch_location_offset(\n        dxil_spv_converter converter, unsigned *patch_location_offset);\n\n/* After compilation, queries if shader feature is used.\n * Designed to map closely to D3D12 feature checks.\n * NOTE: This is obsolete now, and replaced with a simple SPIR-V scan in vkd3d-proton. */\nDXIL_SPV_PUBLIC_API dxil_spv_bool dxil_spv_converter_uses_shader_feature(\n\tdxil_spv_converter converter, dxil_spv_shader_feature feature);\n\n#ifdef DXIL_SPV_ENABLE_EXPERIMENTAL_MULTIVIEW\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_is_multiview_compatible(\n\tdxil_spv_converter converter, dxil_spv_bool *result);\n#endif\n\n/* Intended to be added to the GLSL output in repro suite.\n * Attempts to analyze the DXIL for potential out of spec behavior that needs another pair of eyes.\n * Lifetime of string is only as long as converter is alive.\n * Returns NULL when there are no warnings. */\nDXIL_SPV_PUBLIC_API const char *dxil_spv_converter_get_analysis_warnings(dxil_spv_converter converter);\n\n/* Adds explicit mapping for system descriptors. */\nDXIL_SPV_PUBLIC_API dxil_spv_result dxil_spv_converter_set_meta_descriptor(\n\t\tdxil_spv_converter converter, dxil_spv_meta_descriptor meta,\n\t\tdxil_spv_meta_descriptor_kind kind, unsigned desc_set, unsigned binding_or_push_index);\n\n/* Use an optimized allocation scheme.\n * Call begin before allocating any dxil_spv objects,\n * and end after all dxil_spv created by this thread is destroyed.\n * Reset is an optimized variant of end() -> begin(). Useful if compiling multiple shaders one after another. */\nDXIL_SPV_PUBLIC_API void dxil_spv_begin_thread_allocator_context(void);\nDXIL_SPV_PUBLIC_API void dxil_spv_end_thread_allocator_context(void);\nDXIL_SPV_PUBLIC_API void dxil_spv_reset_thread_allocator_context(void);\n\n/* Converter API */\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "external/CMakeLists.txt",
    "content": "if (DXIL_SPIRV_NATIVE_LLVM)\n\tmessage(STATUS \"Building Native LLVM.\")\n\n    # Disable everything we can.\n    set(LLVM_TARGETS_TO_BUILD \"\" CACHE INTERNAL \"\")\n    set(LLVM_BUILD_RUNTIME OFF)\n    set(LLVM_BUILD_TOOLS OFF)\n    set(LLVM_INCLUDE_BENCHMARKS OFF)\n    set(LLVM_INCLUDE_DOCS OFF)\n    set(LLVM_INCLUDE_EXAMPLES OFF)\n    set(LLVM_INCLUDE_TESTS OFF)\n    set(LLVM_INCLUDE_TOOLS OFF)\n    set(LLVM_INCLUDE_UTILS OFF)\n    set(LLVM_ENABLE_OCAMLDOC OFF)\n    set(LLVM_ENABLE_BINDINGS OFF)\n    set(LLVM_ENABLE_THREADS OFF)\n    set(LLVM_ENABLE_LIBPFM OFF)\n    set(LLVM_ENABLE_TERMINFO OFF)\n    set(LLVM_ENABLE_WARNINGS OFF)\n    set(LLVM_ENABLE_PEDANTIC OFF)\n    set(LLVM_POLLY_LINK_INTO_TOOLS OFF)\n    set(LLVM_POLLY_BUILD OFF)\n    set(WITH_POLLY OFF)\n    set(LLVM_ENABLE_Z3_SOLVER OFF)\n\n    # Need to build out-of-tree.\n    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/llvm ${CMAKE_CURRENT_BINARY_DIR}/llvm_build EXCLUDE_FROM_ALL)\n\n    set(LLVM_DIR \"${CMAKE_CURRENT_BINARY_DIR}/llvm_build/lib/cmake/llvm/\")\n\n    find_package(LLVM CONFIG)\n    if (NOT LLVM_FOUND)\n        message(FATAL_ERROR \"Could not build LLVM from the submodule. Run `git submodule update --init` first.\")\n    endif()\n\n    llvm_map_components_to_libnames(third_party_llvm_libs Core IRReader Support)\n    add_library(third_party_llvm INTERFACE)\n    target_link_libraries(third_party_llvm INTERFACE ${third_party_llvm_libs})\n    target_include_directories(third_party_llvm INTERFACE ${LLVM_INCLUDE_DIRS})\n    target_compile_definitions(third_party_llvm INTERFACE ${LLVM_DEFINITIONS})\n    add_library(external::llvm ALIAS third_party_llvm)\nelse()\n    message(STATUS \"Using builtin LLVM C++ API replacement.\")\n    add_library(external::llvm ALIAS llvm-bc)\nendif()\n"
  },
  {
    "path": "format_all.sh",
    "content": "#!/bin/bash\n\nfor file in *.{cpp,hpp} debug/*.hpp opcodes/*.{cpp,hpp} opcodes/dxil/*.{cpp,hpp} bc/*.{cpp,hpp}\ndo\n    echo \"Formatting file: $file ...\"\n    clang-format -style=file -i $file\ndone\n"
  },
  {
    "path": "ir.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"spirv.hpp\"\n#include <assert.h>\n#include <initializer_list>\n#include <stdint.h>\n\n// A simple IR representation which allows the CFGStructurizer to do some simple rewrites of blocks,\n// PHI nodes in particular.\n\nnamespace dxil_spv\n{\nenum class MergeType\n{\n\tNone,\n\tLoop,\n\tSelection\n};\n\nstruct CFGNode;\nstruct MergeInfo\n{\n\tMergeType merge_type = MergeType::None;\n\tCFGNode *merge_block = nullptr;\n\tCFGNode *continue_block = nullptr;\n\tspv::LoopControlMask loop_control_mask = spv::LoopControlMaskNone;\n\tspv::SelectionControlMask selection_control_mask = spv::SelectionControlMaskNone;\n};\n\nstruct IncomingValue\n{\n\tCFGNode *block = nullptr;\n\tuint32_t id = 0;\n};\n\nstruct PHI\n{\n\tuint32_t id = 0;\n\tuint32_t type_id = 0;\n\tbool relaxed = false;\n\tVector<IncomingValue> incoming;\n};\n\nstruct IDArgument\n{\n\texplicit IDArgument(spv::Id id_)\n\t    : id(id_)\n\t{\n\t}\n\n\tspv::Id id;\n};\n\nstruct LiteralArgument\n{\n\texplicit LiteralArgument(uint32_t lit_)\n\t    : lit(lit_)\n\t{\n\t}\n\n\tuint32_t lit;\n};\n\nstruct Operation\n{\n\tenum\n\t{\n\t\tMaxArguments = 13\n\t};\n\n\tOperation() = default;\n\n\texplicit Operation(spv::Op op_)\n\t    : op(op_)\n\t{\n\t}\n\n\tOperation(spv::Op op_, spv::Id id_, spv::Id type_id_)\n\t    : op(op_)\n\t    , id(id_)\n\t    , type_id(type_id_)\n\t{\n\t}\n\n\tvoid add_id(spv::Id arg)\n\t{\n\t\tassert(num_arguments < MaxArguments);\n\t\tassert(arg != 0);\n\t\targuments[num_arguments++] = arg;\n\t}\n\n\tvoid add_ids(const std::initializer_list<spv::Id> &args)\n\t{\n\t\tfor (auto &arg : args)\n\t\t{\n\t\t\tassert(arg != 0);\n\t\t\tadd_id(arg);\n\t\t}\n\t}\n\n\tvoid add_literal(uint32_t lit)\n\t{\n\t\tassert(num_arguments < MaxArguments);\n\t\tliteral_mask |= 1u << num_arguments;\n\t\targuments[num_arguments++] = lit;\n\t}\n\n\tconst spv::Id *begin() const\n\t{\n\t\treturn arguments;\n\t}\n\n\tconst spv::Id *end() const\n\t{\n\t\treturn arguments + num_arguments;\n\t}\n\n\tuint8_t get_literal_mask() const\n\t{\n\t\treturn literal_mask;\n\t}\n\n\tspv::Op op = spv::OpNop;\n\tspv::Id id = 0;\n\tspv::Id type_id = 0;\n\n\tspv::Id arguments[MaxArguments];\n\tunsigned num_arguments = 0;\n\tuint8_t literal_mask = 0;\n\n\tenum : uint8_t\n\t{\n\t\tSinkableBit = 1 << 0,\n\t\tDependencySinkableBit = 1 << 1,\n\t\tAutoGroupSharedBarrier = 1 << 2,\n\t\t// Inserted after analysis passes are done.\n\t\tSubgroupSyncPre = 1 << 3,\n\t\tSubgroupSyncPost = 1 << 4\n\t};\n\tuint8_t flags = 0;\n};\n\nstruct Terminator\n{\n\tenum class Type\n\t{\n\t\tUnreachable,\n\t\tBranch,\n\t\tCondition,\n\t\tSwitch,\n\t\tReturn,\n\t\tKill\n\t};\n\n\tuint32_t conditional_id = 0;\n\tType type = Type::Unreachable;\n\tCFGNode *direct_block = nullptr;\n\tCFGNode *true_block = nullptr;\n\tCFGNode *false_block = nullptr;\n\n\tstruct Case\n\t{\n\t\tCFGNode *node = nullptr;\n\t\tuint64_t global_order = 0;\n\t\tuint32_t value = 0;\n\t\tbool is_default = false;\n\t};\n\tVector<Case> cases;\n\tuint32_t return_value = 0;\n\n\tbool force_unroll = false;\n\tbool force_loop = false;\n\tbool force_flatten = false;\n\tbool force_branch = false;\n};\n\nstruct IRBlock\n{\n\tVector<PHI> phi;\n\tVector<Operation *> operations;\n\tMergeInfo merge_info;\n\tTerminator terminator;\n};\n\n} // namespace dxil_spv\n"
  },
  {
    "path": "link.T",
    "content": "{\n\tglobal: dxil_spv_*;\n\tlocal: *;\n};\n"
  },
  {
    "path": "llvm_bitcode_parser.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"llvm_bitcode_parser.hpp\"\n\n#ifdef HAVE_LLVMBC\n#include \"context.hpp\"\n#include \"module.hpp\"\n#else\n#include <llvm/IRReader/IRReader.h>\n#include <llvm/Support/SourceMgr.h>\n#endif\n\nnamespace dxil_spv\n{\nstruct LLVMBCParser::Impl\n{\n\tllvm::LLVMContext context;\n#ifdef HAVE_LLVMBC\n\tllvm::Module *module = nullptr;\n#else\n\tstd::unique_ptr<llvm::Module> module;\n#endif\n};\n\nLLVMBCParser::LLVMBCParser()\n{\n\timpl.reset(new Impl);\n}\n\nLLVMBCParser::~LLVMBCParser()\n{\n}\n\nbool LLVMBCParser::parse(const void *data, size_t size)\n{\n#ifdef HAVE_LLVMBC\n\timpl->module = llvm::parseIR(impl->context, data, size);\n\tif (!impl->module)\n\t\treturn false;\n#else\n\tauto memory = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(size);\n\tmemcpy(memory->getBufferStart(), data, size);\n\n\tllvm::SMDiagnostic error;\n\timpl->module = llvm::parseIR(*memory, error, impl->context);\n\tif (!impl->module)\n\t{\n\t\terror.print(\"DXIL\", llvm::errs());\n\t\treturn false;\n\t}\n#endif\n\n\treturn true;\n}\n\nbool LLVMBCParser::parseDXBCBinary(const void *data, size_t size)\n{\n#ifdef HAVE_LLVMBC\n\timpl->module = llvm::parseDXBCBinary(impl->context, data, size);\n\treturn impl->module != nullptr;\n#else\n\t(void)data;\n\t(void)size;\n\treturn false;\n#endif\n}\n\nbool LLVMBCParser::parseDXBC(dxbc_spv::ir::Builder &builder)\n{\n#ifdef HAVE_LLVMBC\n\timpl->module = llvm::parseDXBCIR(impl->context, builder);\n\treturn impl->module != nullptr;\n#else\n\t(void)builder;\n\treturn false;\n#endif\n}\n\nllvm::Module &LLVMBCParser::get_module()\n{\n\treturn *impl->module;\n}\n\nconst llvm::Module &LLVMBCParser::get_module() const\n{\n\treturn *impl->module;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "llvm_bitcode_parser.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#ifdef HAVE_LLVMBC\n#include \"module.hpp\"\n#else\n#include <llvm/IR/LLVMContext.h>\n#include <llvm/IR/Module.h>\n#endif\n\n#include <memory>\n#include <stddef.h>\n\nnamespace dxbc_spv\n{\nnamespace ir\n{\nclass Builder;\n}\n}\n\nnamespace dxil_spv\n{\nclass LLVMBCParser\n{\npublic:\n\tLLVMBCParser();\n\t~LLVMBCParser();\n\tbool parse(const void *data, size_t size);\n\tbool parseDXBCBinary(const void *data, size_t size);\n\tbool parseDXBC(dxbc_spv::ir::Builder &builder);\n\tllvm::Module &get_module();\n\tconst llvm::Module &get_module() const;\n\nprivate:\n\tstruct Impl;\n\tstd::unique_ptr<Impl> impl;\n};\n} // namespace dxil_spv\n"
  },
  {
    "path": "memory_stream.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"memory_stream.hpp\"\n#include <string.h>\n\nnamespace dxil_spv\n{\nMemoryStream::MemoryStream(const void *blob_, size_t size)\n    : blob(static_cast<const uint8_t *>(blob_))\n    , blob_size(size)\n{\n}\n\nvoid MemoryStream::reset()\n{\n\tblob_offset = 0;\n}\n\nbool MemoryStream::read(void *buffer, size_t size)\n{\n\tif (blob_offset + size > blob_size)\n\t\treturn false;\n\n\tmemcpy(buffer, blob + blob_offset, size);\n\tblob_offset += size;\n\treturn true;\n}\n\nconst void *MemoryStream::map_read(size_t size)\n{\n\tif (blob_offset + size > blob_size)\n\t\treturn nullptr;\n\n\tconst void *mapped = blob + blob_offset;\n\tblob_offset += size;\n\treturn mapped;\n}\n\nbool MemoryStream::map_string_iterate(const char *&str)\n{\n\t// Strings are C strings and can be mapped 1:1.\n\t// Just need to verify they terminate properly.\n\tstr = reinterpret_cast<const char *>(blob + blob_offset);\n\tchar c;\n\n\tdo\n\t{\n\t\tif (!read(c))\n\t\t\treturn false;\n\t\telse if (c == '\\0')\n\t\t\tbreak;\n\t} while (c != '\\0');\n\n\treturn true;\n}\n\nbool MemoryStream::map_string_absolute(const char *&str, size_t offset) const\n{\n\tauto substream = create_substream(offset);\n\treturn substream.map_string_iterate(str);\n}\n\nbool MemoryStream::seek(size_t new_offset)\n{\n\tif (new_offset > blob_size)\n\t\treturn false;\n\n\tblob_offset = new_offset;\n\treturn true;\n}\n\nbool MemoryStream::skip(size_t count)\n{\n\treturn seek(blob_offset + count);\n}\n\nMemoryStream MemoryStream::create_substream(size_t offset, size_t size) const\n{\n\tif (offset >= blob_size || offset + size > blob_size)\n\t\treturn { nullptr, 0 };\n\telse\n\t\treturn { blob + offset, size };\n}\n\nMemoryStream MemoryStream::create_substream(size_t offset) const\n{\n\tif (offset >= blob_size)\n\t\treturn { nullptr, 0 };\n\telse\n\t\treturn { blob + offset, blob_size - offset };\n}\n\nMemoryStream MemoryStream::create_substream_bitcode_size(size_t offset, size_t bitcode_size) const\n{\n\tif (offset + bitcode_size > blob_size)\n\t\treturn { nullptr, 0 };\n\telse\n\t\treturn { blob + offset, bitcode_size };\n}\n\nsize_t MemoryStream::get_offset() const\n{\n\treturn blob_offset;\n}\n\nsize_t MemoryStream::get_size() const\n{\n\treturn blob_size;\n}\n\n} // namespace dxil_spv\n"
  },
  {
    "path": "memory_stream.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace dxil_spv\n{\nclass MemoryStream\n{\npublic:\n\tMemoryStream(const void *blob, size_t size);\n\tMemoryStream() = default;\n\n\tvoid reset();\n\n\ttemplate <typename T>\n\tbool read(T &buffer)\n\t{\n\t\treturn read(&buffer, sizeof(T));\n\t}\n\n\tconst void *map_read(size_t byte_size);\n\n\ttemplate <typename T>\n\tconst T *map_read(size_t byte_size)\n\t{\n\t\treturn static_cast<const T *>(map_read(byte_size));\n\t}\n\n\tbool read(void *buffer, size_t size);\n\tbool map_string_iterate(const char *&str);\n\tbool map_string_absolute(const char *&str, size_t offset) const;\n\tbool seek(size_t offset);\n\tbool skip(size_t count);\n\n\tsize_t get_offset() const;\n\tsize_t get_size() const;\n\tMemoryStream create_substream(size_t offset, size_t size) const;\n\tMemoryStream create_substream(size_t offset) const;\n\tMemoryStream create_substream_bitcode_size(size_t offset, size_t bitcode_size) const;\n\nprivate:\n\tconst uint8_t *blob = nullptr;\n\tsize_t blob_size = 0;\n\tsize_t blob_offset = 0;\n};\n} // namespace dxil_spv\n"
  },
  {
    "path": "meson.build",
    "content": "project('dxil-spirv', ['cpp'], version : '0.0', meson_version : '>= 0.49', default_options : ['b_ndebug=if-release'])\n\ndxil_spirv_compiler      = meson.get_compiler('cpp')\ndxil_spirv_cpp_std       = 'c++14'\ndxil_spirv_warning_level = '2' # Equivelant of -Wall -Wextra\n\nadd_project_arguments('-DAMD_EXTENSIONS',          language : 'cpp')\nadd_project_arguments('-DHAVE_LLVMBC',             language : 'cpp')\nadd_project_arguments('-DNOMINMAX',                language : 'cpp')\n\ndxil_spirv_include_dirs = include_directories([\n  'bc',\n  'debug',\n  'util',\n  'third_party/bc-decoder',\n  'third_party/glslang-spirv',\n  'third_party/spirv-headers/include/spirv/unified1',\n])\n\nadd_project_arguments(dxil_spirv_compiler.get_supported_arguments([\n    '-Wno-missing-field-initializers',\n    '-Wno-empty-body',\n    '-Wno-unused-parameter',\n    '-fno-exceptions',\n    '-fvisibility=hidden',\n    '/wd4267',   # Narrowing conversions\n    '/wd4244',   # Narrowing conversions\n    '/wd4996']), # Secure no warnings\n  language : 'cpp')\n\ndxil_spirv_src = [\n  # dxil-spirv-c\n  'dxil_spirv_c.cpp',\n\n  # bc-decoder\n  'third_party/bc-decoder/llvm_decoder.cpp',\n\n  # glslang-spirv-builder\n  'third_party/glslang-spirv/Logger.cpp',\n  'third_party/glslang-spirv/InReadableOrder.cpp',\n  'third_party/glslang-spirv/SpvBuilder.cpp',\n\n  # llvm-bc\n  'bc/value.cpp',\n  'bc/instruction.cpp',\n  'bc/function.cpp',\n  'bc/context.cpp',\n  'bc/type.cpp',\n  'bc/module.cpp',\n  'bc/metadata.cpp',\n  'bc/disassembler.cpp',\n\n  # spirv-module\n  'spirv_module.cpp',\n  'descriptor_qa.cpp',\n  'spirv_module_instrumentation.cpp',\n\n  # dxil-converter\n  'memory_stream.cpp',\n  'llvm_bitcode_parser.cpp',\n\n  'dxil_converter.cpp',\n  'cfg_structurizer.cpp',\n  'node_pool.cpp',\n  'node.cpp',\n  'dxil_parser.cpp',\n\n  'opcodes/dxil/dxil_ags.cpp',\n  'opcodes/dxil/dxil_nvapi.cpp',\n  'opcodes/dxil/dxil_common.cpp',\n  'opcodes/dxil/dxil_resources.cpp',\n  'opcodes/dxil/dxil_compute.cpp',\n  'opcodes/dxil/dxil_arithmetic.cpp',\n  'opcodes/dxil/dxil_pixel_ops.cpp',\n  'opcodes/dxil/dxil_geometry.cpp',\n  'opcodes/dxil/dxil_tessellation.cpp',\n  'opcodes/dxil/dxil_waveops.cpp',\n  'opcodes/dxil/dxil_sampling.cpp',\n  'opcodes/dxil/dxil_buffer.cpp',\n  'opcodes/dxil/dxil_ray_tracing.cpp',\n  'opcodes/dxil/dxil_mesh.cpp',\n  'opcodes/dxil/dxil_workgraph.cpp',\n  'opcodes/opcodes_llvm_builtins.cpp',\n  'opcodes/opcodes_dxil_builtins.cpp',\n\n  # dxil-utils\n  'util/thread_local_allocator.cpp',\n\n  # debug\n  'debug/logging.cpp',\n]\n\ndxbc_spirv = subproject('dxbc-spirv')\n\ndxbc_spirv_include_dirs = include_directories([\n  'subprojects/dxbc-spirv'\n])\n\ndxbc_spirv_dep = dependency('dxbc-spirv',\n  fallback        : [ 'dxbc-spirv', 'dxbc_spv_dep' ],\n  default_options : [ 'cpp_std=c++17' ])\n\ndxbc_spv_module = static_library('dxbc_spv_module', files('bc/module_dxbc_ir.cpp'),\n  include_directories : [ dxil_spirv_include_dirs ],\n  dependencies        : [ dxbc_spirv_dep ],\n  override_options    : [ 'cpp_std=c++17' ])\n\ndxil_spirv_lib = static_library('dxil-spirv', dxil_spirv_src,\n  include_directories : [ dxil_spirv_include_dirs ],\n  link_with           : [ dxbc_spv_module ],\n  override_options    : [\n    'cpp_std='       + dxil_spirv_cpp_std,\n    'warning_level=' + dxil_spirv_warning_level\n  ])\n\ndxil_spirv_dep = declare_dependency(\n  include_directories : include_directories('.'),\n  link_with           : [ dxil_spirv_lib ])\n"
  },
  {
    "path": "misc/structurize_test.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"cfg_structurizer.hpp\"\n#include \"node.hpp\"\n#include \"node_pool.hpp\"\n#include \"spirv_module.hpp\"\n#include \"SpvBuilder.h\"\n#include <stdio.h>\n#include <string.h>\n#include <string>\n#include <unordered_map>\n\n#include \"logging.hpp\"\n#include \"spirv-tools/libspirv.hpp\"\n#include \"spirv_cross_c.h\"\n\nusing namespace dxil_spv;\n\nstruct Emitter : BlockEmissionInterface\n{\n\tvoid emit_basic_block(CFGNode *node) override;\n\tvoid register_block(CFGNode *node) override\n\t{\n\t\tif (node->id == 0)\n\t\t\tnode->id = module.allocate_id();\n\t}\n\n\tSPIRVModule module;\n};\n\nvoid Emitter::emit_basic_block(CFGNode *node)\n{\n\tauto &info = node->ir.merge_info;\n\tLOGE(\"%u (%s):\\n\", node->id, node->name.c_str());\n\n\t// Emit opcodes here ...\n\n\tswitch (info.merge_type)\n\t{\n\tcase MergeType::Selection:\n\t\tLOGE(\"    SelectionMerge -> %s\\n\", info.merge_block ? info.merge_block->name.c_str() : \"Unreachable\");\n\t\tbreak;\n\n\tcase MergeType::Loop:\n\t\tLOGE(\"    LoopMerge -> %s, Continue <- %s\\n\", info.merge_block ? info.merge_block->name.c_str() : \"Unreachable\",\n\t\t     info.continue_block ? info.continue_block->name.c_str() : \"Unreachable\");\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tswitch (node->ir.terminator.type)\n\t{\n\tcase Terminator::Type::Branch:\n\t\tLOGE(\"  Direct -> %s\\n\", node->ir.terminator.direct_block->name.c_str());\n\t\tbreak;\n\n\tcase Terminator::Type::Condition:\n\t\tLOGE(\"  Selection -> %s : %s\\n\", node->ir.terminator.true_block->name.c_str(),\n\t\t     node->ir.terminator.false_block->name.c_str());\n\t\tbreak;\n\n\tcase Terminator::Type::Return:\n\t\tLOGE(\"  Return\\n\");\n\t\tbreak;\n\n\tcase Terminator::Type::Unreachable:\n\t\tLOGE(\"  Unreachable\\n\");\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nstatic void print_spirv_assembly(const Vector<uint32_t> &code)\n{\n\tspvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);\n\tstd::string str;\n\tif (!tools.Disassemble(code.data(), code.size(), &str, SPV_BINARY_TO_TEXT_OPTION_INDENT))\n\t\tLOGE(\"Failed to disassemble SPIR-V.\\n\");\n\telse\n\t\tLOGE(\"\\nSPIR-V:\\n%s\\n\", str.c_str());\n}\n\nstatic void print_glsl(const Vector<uint32_t> &code)\n{\n\tspvc_context context;\n\tif (spvc_context_create(&context) != SPVC_SUCCESS)\n\t\treturn;\n\n\tspvc_parsed_ir ir;\n\tif (spvc_context_parse_spirv(context, code.data(), code.size(), &ir) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler compiler;\n\tif (spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler) !=\n\t    SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler_options opts;\n\tif (spvc_compiler_create_compiler_options(compiler, &opts) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tspvc_compiler_options_set_bool(opts, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_FALSE);\n\tspvc_compiler_options_set_uint(opts, SPVC_COMPILER_OPTION_GLSL_VERSION, 460);\n\tspvc_compiler_options_set_bool(opts, SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS, SPVC_TRUE);\n\tspvc_compiler_install_compiler_options(compiler, opts);\n\n\tconst char *source;\n\tif (spvc_compiler_compile(compiler, &source) != SPVC_SUCCESS)\n\t\tgoto cleanup;\n\n\tLOGI(\"==== GLSL ====\\n\");\n\tfputs(source, stderr);\n\tLOGI(\"====\\n\");\n\ncleanup:\n\tspvc_context_destroy(context);\n}\n\nstatic void validate_spirv(const Vector<uint32_t> &code)\n{\n\tspvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);\n\ttools.SetMessageConsumer([](spv_message_level_t, const char *, const spv_position_t &, const char *message) {\n\t\tLOGE(\"Message: %s\\n\", message);\n\t});\n\tif (!tools.Validate(code.data(), code.size()))\n\t\tLOGE(\"Validation error.\\n\");\n\telse\n\t\tLOGE(\"Validated successfully!\\n\");\n}\n\nstatic Vector<String> tokenize(char *line_buffer)\n{\n\tVector<String> tokens;\n\n\tchar *saveptr;\n\tchar *first = strtok_r(line_buffer, \" \", &saveptr);\n\tif (first)\n\t\ttokens.push_back(first);\n\telse\n\t\treturn tokens;\n\twhile (char *token = strtok_r(nullptr, \" \", &saveptr))\n\t\ttokens.push_back(token);\n\n\tfor (auto &token : tokens)\n\t\twhile (!token.empty() && token.back() == '\\n')\n\t\t\ttoken.pop_back();\n\n\treturn tokens;\n}\n\nint main(int argc, char **argv)\n{\n\tif (argc != 2)\n\t{\n\t\tfprintf(stderr, \"Usage: structurize-test <input test>\\n\");\n\t\treturn EXIT_FAILURE;\n\t}\n\n\tstd::unordered_map<String, CFGNode *> block_metas;\n\tEmitter emitter;\n\tCFGNodePool pool;\n\n\tconst auto get = [&](const String &name) -> CFGNode * {\n\t\tauto itr = block_metas.find(name);\n\t\tif (itr == block_metas.end())\n\t\t{\n\t\t\tauto &new_entry = block_metas[name];\n\t\t\tauto *node = pool.create_node();\n\t\t\tnode->ir.terminator.type = Terminator::Type::Return;\n\t\t\tnode->name = name;\n\t\t\tnew_entry = node;\n\t\t\treturn node;\n\t\t}\n\t\telse\n\t\t\treturn itr->second;\n\t};\n\n\tconst auto add_branch = [&](const char *from, const char *to) {\n\t\tauto *f = get(from);\n\t\tauto *t = get(to);\n\t\tf->add_branch(t);\n\t\tf->ir.terminator.type = Terminator::Type::Branch;\n\t\tf->ir.terminator.direct_block = t;\n\t};\n\n\tconst auto add_selection = [&](const char *from, const char *to0, const char *to1) {\n\t\tauto *f = get(from);\n\t\tauto *t0 = get(to0);\n\t\tauto *t1 = get(to1);\n\t\tf->add_branch(t0);\n\t\tf->add_branch(t1);\n\t\tf->ir.terminator.type = Terminator::Type::Condition;\n\t\tf->ir.terminator.true_block = t0;\n\t\tf->ir.terminator.false_block = t1;\n\t\tf->ir.terminator.conditional_id = emitter.module.get_builder().makeBoolConstant(true, true);\n\t\temitter.module.get_builder().addName(f->ir.terminator.conditional_id, (std::string(from) + \"_sel\").c_str());\n\t};\n\n\tconst auto add_switch = [&](const char *from, const String *nodes, size_t num_nodes) {\n\t\tauto *f = get(from);\n\t\tf->ir.terminator.type = Terminator::Type::Switch;\n\t\tf->ir.terminator.conditional_id = emitter.module.get_builder().makeUintConstant(0, true);\n\t\tfor (size_t i = 0; i < num_nodes; i++)\n\t\t{\n\t\t\tauto *t = get(nodes[i]);\n\t\t\tf->add_branch(t);\n\t\t\tTerminator::Case case_label = {};\n\t\t\tcase_label.node = t;\n\t\t\tcase_label.global_order = i;\n\t\t\tcase_label.is_default = i == 0;\n\t\t\tf->ir.terminator.cases.push_back(case_label);\n\t\t}\n\t};\n\n\tconst auto add_phi = [&](const char *phi, const Vector<const char *> &from_nodes) {\n\t\tauto *p = get(phi);\n\t\tp->ir.phi.emplace_back();\n\t\tauto &phi_node = p->ir.phi.back();\n\t\tphi_node.type_id = emitter.module.get_builder().makeUintType(32);\n\t\tphi_node.id = emitter.module.allocate_id();\n\t\temitter.module.get_builder().addName(phi_node.id, phi);\n\n\t\tfor (auto &from : from_nodes)\n\t\t{\n\t\t\tIncomingValue value = {};\n\t\t\tvalue.block = get(from);\n\t\t\tvalue.id = emitter.module.get_builder().makeUintConstant(uint32_t(std::hash<std::string>()(from)), true);\n\t\t\temitter.module.get_builder().addName(value.id, (std::string(\"incoming_value_\") + from).c_str());\n\t\t\tphi_node.incoming.push_back(value);\n\t\t}\n\t};\n\n\tconst auto add_sideeffect = [&](const char *block) {\n\t\tauto *b = get(block);\n\t\tauto &builder = emitter.module.get_builder();\n\t\tspv::Id var_id = builder.createVariable(spv::StorageClassFunction, builder.makeUintType(32));\n\n\t\tauto *op = emitter.module.allocate_op(spv::OpStore);\n\t\top->add_id(var_id);\n\t\top->add_id(builder.makeUintConstant(0));\n\t\tb->ir.operations.push_back(op);\n\t};\n\n\temitter.module.emit_entry_point(spv::ExecutionModelVertex, \"main\", false, spv::MemoryModelGLSL450);\n\n\tFILE *file = fopen(argv[1], \"r\");\n\tif (!file)\n\t{\n\t\tfprintf(stderr, \"Failed to open input file: %s.\\n\", argv[1]);\n\t\treturn EXIT_FAILURE;\n\t}\n\n\tchar line_buffer[1024];\n\twhile (fgets(line_buffer, sizeof(line_buffer), file))\n\t{\n\t\tauto tokens = tokenize(line_buffer);\n\t\tif (tokens.empty())\n\t\t\tcontinue;\n\n\t\tif (tokens.front() == \"b\")\n\t\t{\n\t\t\tif (tokens.size() != 3)\n\t\t\t{\n\t\t\t\tLOGE(\"b token needs 3 elements.\\n\");\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tadd_branch(tokens[1].c_str(), tokens[2].c_str());\n\t\t}\n\t\telse if (tokens.front() == \"c\")\n\t\t{\n\t\t\tif (tokens.size() != 4)\n\t\t\t{\n\t\t\t\tLOGE(\"c token needs 4 elements.\\n\");\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tadd_selection(tokens[1].c_str(), tokens[2].c_str(), tokens[3].c_str());\n\t\t}\n\t\telse if (tokens.front() == \"switch\")\n\t\t{\n\t\t\tif (tokens.size() < 3)\n\t\t\t{\n\t\t\t\tLOGE(\"switch token needs at least.\\n\");\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tadd_switch(tokens[1].c_str(), tokens.data() + 2, tokens.size() - 2);\n\t\t}\n\t\telse if (tokens.front() == \"phi\")\n\t\t{\n\t\t\tif (tokens.size() < 3)\n\t\t\t{\n\t\t\t\tLOGE(\"phi token needs at least 3 elements.\\n\");\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tVector<const char *> src_blocks;\n\t\t\tfor (auto itr = tokens.begin() + 2; itr != tokens.end(); ++itr)\n\t\t\t\tsrc_blocks.push_back(itr->c_str());\n\t\t\tadd_phi(tokens[1].c_str(), src_blocks);\n\t\t}\n\t\telse if (tokens.front() == \"sideeffect\")\n\t\t{\n\t\t\tif (tokens.size() != 2)\n\t\t\t{\n\t\t\t\tLOGE(\"sideeffects token needs 2 elements.\\n\");\n\t\t\t\tcontinue;;\n\t\t\t}\n\t\t\tadd_sideeffect(tokens[1].c_str());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tLOGE(\"Unknown token %s.\\n\", tokens.front().c_str());\n\t\t}\n\t}\n\n\tCFGStructurizer traverser(get(\"entry\"), pool, emitter.module);\n\ttraverser.run();\n\ttraverser.traverse(emitter);\n\n\tpool.for_each_node([](CFGNode &node) {\n\t\tnode.userdata = nullptr;\n\t\tnode.id = 0;\n\t});\n\n\temitter.module.emit_entry_point_function_body(traverser);\n\tVector<uint32_t> code;\n\temitter.module.finalize_spirv(code);\n\n\tprint_glsl(code);\n\tprint_spirv_assembly(code);\n\tvalidate_spirv(code);\n}\n"
  },
  {
    "path": "node.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"node.hpp\"\n#include \"node_pool.hpp\"\n#include \"logging.hpp\"\n\n#include <algorithm>\n#include <assert.h>\n\nnamespace dxil_spv\n{\nCFGNode::CFGNode(CFGNodePool &pool_)\n\t: pool(pool_)\n{\n}\n\nvoid CFGNode::add_unique_pred(CFGNode *node)\n{\n\tauto itr = std::find(pred.begin(), pred.end(), node);\n\tif (itr == pred.end())\n\t\tpred.push_back(node);\n}\n\nvoid CFGNode::add_unique_fake_pred(CFGNode *node)\n{\n\tauto itr = std::find(fake_pred.begin(), fake_pred.end(), node);\n\tif (itr == fake_pred.end())\n\t\tfake_pred.push_back(node);\n}\n\nvoid CFGNode::add_unique_header(CFGNode *node)\n{\n\tauto itr = std::find(headers.begin(), headers.end(), node);\n\tif (itr == headers.end())\n\t\theaders.push_back(node);\n}\n\nvoid CFGNode::add_branch(CFGNode *to)\n{\n\tadd_unique_succ(to);\n\tto->add_unique_pred(this);\n}\n\nvoid CFGNode::clear_branches()\n{\n\tfor (auto *s : succ)\n\t{\n\t\tauto itr = std::find(s->pred.begin(), s->pred.end(), this);\n\t\t// We might have become stale during rewrites. In this case we might have a succ\n\t\t// with no corresponding pred. Ignore that.\n\t\tif (itr != s->pred.end())\n\t\t\ts->pred.erase(itr);\n\t}\n\tsucc.clear();\n}\n\nvoid CFGNode::add_fake_branch(CFGNode *to)\n{\n\tif (std::find(succ.begin(), succ.end(), to) != succ.end())\n\t\treturn;\n\n\tadd_unique_fake_succ(to);\n\tto->add_unique_fake_pred(this);\n}\n\nvoid CFGNode::add_unique_succ(CFGNode *node)\n{\n\tassert(std::find(fake_succ.begin(), fake_succ.end(), node) == fake_succ.end());\n\tauto itr = std::find(succ.begin(), succ.end(), node);\n\tif (itr == succ.end())\n\t\tsucc.push_back(node);\n}\n\nvoid CFGNode::add_unique_fake_succ(CFGNode *node)\n{\n\tauto itr = std::find(fake_succ.begin(), fake_succ.end(), node);\n\tif (itr == fake_succ.end())\n\t\tfake_succ.push_back(node);\n}\n\nunsigned CFGNode::num_forward_preds() const\n{\n\treturn unsigned(pred.size());\n}\n\nbool CFGNode::has_pred_back_edges() const\n{\n\treturn pred_back_edge != nullptr;\n}\n\nbool CFGNode::reaches_domination_frontier_before_merge(const CFGNode *merge) const\n{\n\tfor (auto *frontier : dominance_frontier)\n\t\tif (merge != frontier && merge->post_dominates(frontier))\n\t\t\treturn true;\n\treturn false;\n}\n\nbool CFGNode::dominates_outer_continue(const CFGNode *loop_header) const\n{\n\tif (loop_header->pred.empty())\n\t\treturn false;\n\n\tloop_header = loop_header->immediate_dominator;\n\twhile (loop_header)\n\t{\n\t\tif (loop_header->pred_back_edge && dominates(loop_header->pred_back_edge))\n\t\t\treturn true;\n\n\t\tif (loop_header->pred.empty())\n\t\t\tbreak;\n\t\tloop_header = loop_header->immediate_dominator;\n\t}\n\n\treturn false;\n}\n\nbool CFGNode::dominates(const CFGNode *other) const\n{\n\t// Follow immediate dominator graph. Either we end up at this, or entry block.\n\twhile (this != other)\n\t{\n\t\tif (!other->immediate_dominator || other == other->immediate_dominator)\n\t\t\tbreak;\n\t\tother = other->immediate_dominator;\n\t}\n\n\treturn this == other;\n}\n\nbool CFGNode::can_loop_merge_to(const CFGNode *other) const\n{\n\tif (!dominates(other))\n\t\treturn false;\n\n\tauto *c = pred_back_edge;\n\n\tif (c && !c->succ.empty())\n\t{\n\t\t// If the continue block branches to something which is not the loop header,\n\t\t// it must be the merge block we're after, i.e., it must be a clean break (or we are kind of screwed).\n\t\t// Detect a \"fake\" merge branch here.\n\t\t// E.g., we have a fake merge branch if an escaping edge is branching to one block beyond the real merge block.\n\t\t// This can happen after split_merge_scopes() transform where inner loop\n\t\t// tries to break out of multiple loops and multiple selection scopes at the same time.\n\t\t// We can still dominate this escape target, but it's still an escape which must be resolved some other way with ladders.\n\t\tif (std::find(c->succ.begin(), c->succ.end(), other) == c->succ.end())\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool CFGNode::can_backtrace_to(const CFGNode *parent, UnorderedSet<const CFGNode *> &node_cache) const\n{\n\tif (node_cache.count(this))\n\t\treturn false;\n\tnode_cache.insert(this);\n\n\tfor (auto *p : pred)\n\t\tif (p == parent || p->can_backtrace_to(parent, node_cache))\n\t\t\treturn true;\n\n\treturn false;\n}\n\nbool CFGNode::can_backtrace_to_with_blockers(const CFGNode *parent, const Vector<CFGNode *> &block_nodes,\n                                             UnorderedSet<const CFGNode *> &node_cache) const\n{\n\tif (node_cache.count(this))\n\t\treturn false;\n\tnode_cache.insert(this);\n\n\tif (std::find(block_nodes.begin(), block_nodes.end(), this) != block_nodes.end())\n\t\treturn false;\n\n\tfor (auto *p : pred)\n\t\tif (p == parent || p->can_backtrace_to_with_blockers(parent, block_nodes, node_cache))\n\t\t\treturn true;\n\n\treturn false;\n}\n\nbool CFGNode::can_backtrace_to(const CFGNode *parent) const\n{\n\t// If parent can branch to this, then post_order(parent) must be greater than post_order(this).\n\tif (parent->forward_post_visit_order < forward_post_visit_order)\n\t\treturn false;\n\n\tUnorderedSet<const CFGNode *> node_cache;\n\treturn can_backtrace_to(parent, node_cache);\n}\n\nbool CFGNode::can_backtrace_to_with_blockers(const CFGNode *parent, const Vector<CFGNode *> &block_nodes) const\n{\n\t// If parent can branch to this, then post_order(parent) must be greater than post_order(this).\n\tif (parent->forward_post_visit_order < forward_post_visit_order)\n\t\treturn false;\n\n\tUnorderedSet<const CFGNode *> node_cache;\n\treturn can_backtrace_to_with_blockers(parent, block_nodes, node_cache);\n}\n\nbool CFGNode::post_dominates_any_work(const CFGNode *parent, UnorderedSet<const CFGNode *> &node_cache) const\n{\n\t// If we reached this node before and didn't terminate, it must have returned false.\n\tif (node_cache.count(parent))\n\t\treturn false;\n\tnode_cache.insert(parent);\n\n\t// This is not a dummy block, we have an answer.\n\tif (!parent->ir.operations.empty() || !parent->ir.phi.empty())\n\t\treturn post_dominates(parent);\n\n\tfor (auto *p : parent->pred)\n\t\tif (post_dominates_any_work(p, node_cache))\n\t\t\treturn true;\n\n\treturn false;\n}\n\nunsigned CFGNode::count_post_dominates_work_from_incoming_preds() const\n{\n\tauto *start_node = this;\n\t// Trivial back-trace as far as we can go.\n\twhile (start_node->pred.size() == 1 &&\n\t       start_node->ir.operations.empty() && start_node->ir.phi.empty() &&\n\t       start_node->post_dominates(start_node->pred.front()))\n\t{\n\t\tstart_node = start_node->pred.front();\n\t}\n\n\tif (!start_node->ir.operations.empty() || !start_node->ir.phi.empty())\n\t\treturn true;\n\n\tunsigned num_post_dominated_preds = 0;\n\tUnorderedSet<const CFGNode *> node_cache;\n\n\tfor (auto *p : start_node->pred)\n\t\tif (start_node->post_dominates_any_work(p, node_cache))\n\t\t\tnum_post_dominated_preds++;\n\treturn num_post_dominated_preds;\n}\n\nbool CFGNode::post_dominates_any_work() const\n{\n\treturn count_post_dominates_work_from_incoming_preds() != 0;\n}\n\nbool CFGNode::post_dominates(const CFGNode *start_node) const\n{\n\twhile (start_node != this)\n\t{\n\t\t// Reached exit node.\n\t\tif (!start_node->immediate_post_dominator || start_node == start_node->immediate_post_dominator)\n\t\t\tbreak;\n\t\tstart_node = start_node->immediate_post_dominator;\n\t}\n\n\treturn this == start_node;\n}\n\nbool CFGNode::post_dominates_perfect_structured_construct() const\n{\n\tif (!post_dominates(immediate_dominator))\n\t\treturn false;\n\n\tfor (auto *p : pred)\n\t\tif (!post_dominates(p))\n\t\t\treturn false;\n\treturn true;\n}\n\nbool CFGNode::dominates_all_reachable_exits(UnorderedSet<const CFGNode *> &completed, const CFGNode &header) const\n{\n\tif (!completed.count(this))\n\t{\n\t\tcompleted.insert(this);\n\t\tif (succ_back_edge && !header.dominates(succ_back_edge))\n\t\t\treturn false;\n\n\t\tfor (auto *node : succ)\n\t\t\tif (!header.dominates(node) || !node->dominates_all_reachable_exits(completed, header))\n\t\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool CFGNode::dominates_all_reachable_exits() const\n{\n\tUnorderedSet<const CFGNode *> completed;\n\treturn dominates_all_reachable_exits(completed, *this);\n}\n\nCFGNode *CFGNode::find_common_post_dominator(CFGNode *a, CFGNode *b)\n{\n\tassert(a);\n\tassert(b);\n\n\twhile (a != b)\n\t{\n\t\tif (!a->immediate_post_dominator)\n\t\t{\n\t\t\tfor (auto *p : a->succ)\n\t\t\t\tp->recompute_immediate_post_dominator();\n\t\t\ta->recompute_immediate_post_dominator();\n\t\t}\n\n\t\tif (!b->immediate_post_dominator)\n\t\t{\n\t\t\tfor (auto *p : b->succ)\n\t\t\t\tp->recompute_immediate_post_dominator();\n\t\t\tb->recompute_immediate_post_dominator();\n\t\t}\n\n\t\tif (a->backward_post_visit_order == b->backward_post_visit_order)\n\t\t{\n\t\t\t// Should not normally happen, but when we insert ladder blocks,\n\t\t\t// we might have assigned temporary visit orders which can alias with\n\t\t\t// other nodes in some cases. Fixing this up requires a full traversal of the entire CFG,\n\t\t\t// so as a fallback we can do direct reachability and domination analysis.\n\t\t\tif (b->post_dominates(a))\n\t\t\t\treturn b;\n\t\t\telse if (a->post_dominates(b))\n\t\t\t\treturn a;\n\n\t\t\t// If there is no clear domination relationship, then we need to iterate both a and b.\n\t\t\t// This is fine as we now know that neither a nor b can be the common node.\n\t\t\tassert(a->immediate_post_dominator);\n\t\t\tassert(b->immediate_post_dominator);\n\t\t\ta = a->immediate_post_dominator;\n\t\t\tb = b->immediate_post_dominator;\n\t\t}\n\t\telse if (a->backward_post_visit_order < b->backward_post_visit_order)\n\t\t{\n\t\t\tassert(a->immediate_post_dominator);\n\t\t\ta = a->immediate_post_dominator;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tassert(b->immediate_post_dominator);\n\t\t\tb = b->immediate_post_dominator;\n\t\t}\n\t}\n\n\treturn a;\n}\n\nCFGNode *CFGNode::find_common_dominator(CFGNode *a, CFGNode *b)\n{\n\tassert(a);\n\tassert(b);\n\n\twhile (a != b)\n\t{\n\t\tif (!a->immediate_dominator)\n\t\t{\n\t\t\tfor (auto *p : a->pred)\n\t\t\t\tp->recompute_immediate_dominator();\n\t\t\ta->recompute_immediate_dominator();\n\t\t}\n\n\t\tif (!b->immediate_dominator)\n\t\t{\n\t\t\tfor (auto *p : b->pred)\n\t\t\t\tp->recompute_immediate_dominator();\n\t\t\tb->recompute_immediate_dominator();\n\t\t}\n\n\t\tif (a->forward_post_visit_order == b->forward_post_visit_order)\n\t\t{\n\t\t\t// Should not normally happen, but when we insert ladder blocks,\n\t\t\t// we might have assigned temporary visit orders which can alias with\n\t\t\t// other nodes in some cases. Fixing this up requires a full traversal of the entire CFG,\n\t\t\t// so as a fallback we can do direct reachability and domination analysis.\n\t\t\tif (b->dominates(a))\n\t\t\t\treturn const_cast<CFGNode *>(b);\n\t\t\telse if (a->dominates(b))\n\t\t\t\treturn const_cast<CFGNode *>(a);\n\n\t\t\t// If there is no clear domination relationship, then we need to iterate both a and b.\n\t\t\t// This is fine as we now know that neither a nor b can be the common node.\n\t\t\tassert(a->immediate_dominator);\n\t\t\tassert(b->immediate_dominator);\n\t\t\tif (a == a->immediate_dominator)\n\t\t\t\treturn b;\n\t\t\telse if (b == b->immediate_dominator)\n\t\t\t\treturn a;\n\t\t\ta = a->immediate_dominator;\n\t\t\tb = b->immediate_dominator;\n\t\t}\n\t\telse if (a->forward_post_visit_order < b->forward_post_visit_order)\n\t\t{\n\t\t\t// Awkward case which can happen when nodes are unreachable in the CFG.\n\t\t\t// Can occur with the dummy blocks we create.\n\t\t\tif (a == a->immediate_dominator)\n\t\t\t\treturn b;\n\t\t\ta = a->immediate_dominator;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Awkward case which can happen when nodes are unreachable in the CFG.\n\t\t\t// Can occur with the dummy blocks we create.\n\t\t\tif (b == b->immediate_dominator)\n\t\t\t\treturn a;\n\n\t\t\tb = b->immediate_dominator;\n\t\t}\n\t}\n\treturn const_cast<CFGNode *>(a);\n}\n\nCFGNode *CFGNode::get_immediate_dominator_loop_header()\n{\n\tassert(immediate_dominator);\n\tauto *node = this;\n\twhile (!node->pred_back_edge)\n\t{\n\t\tif (node->pred.empty())\n\t\t\treturn nullptr;\n\n\t\tassert(node->immediate_dominator);\n\t\tnode = node->immediate_dominator;\n\t}\n\n\treturn node;\n}\n\nCFGNode *CFGNode::rewrite_branch_through_intermediate_node(CFGNode *to_prev, CFGNode *to_next)\n{\n\tassert(std::find(succ.begin(), succ.end(), to_next) != succ.end());\n\n\tauto *intermediate = pool.create_node();\n\tintermediate->name = name + \".intermediate.\" + to_next->name;\n\tintermediate->ir.terminator.type = Terminator::Type::Branch;\n\tintermediate->ir.terminator.direct_block = to_next;\n\tintermediate->add_branch(to_next);\n\tintermediate->immediate_post_dominator = to_next;\n\tintermediate->immediate_dominator = this;\n\tintermediate->forward_post_visit_order = forward_post_visit_order;\n\tintermediate->backward_post_visit_order = backward_post_visit_order;\n\tretarget_branch(to_prev, intermediate);\n\tto_next->recompute_immediate_dominator();\n\n\treturn intermediate;\n}\n\nvoid CFGNode::retarget_branch_with_intermediate_node(CFGNode *to_prev, CFGNode *to_next)\n{\n\t// If there is no duplication, just go ahead.\n\tif (std::find(succ.begin(), succ.end(), to_next) == succ.end())\n\t\tretarget_branch(to_prev, to_next);\n\telse\n\t\trewrite_branch_through_intermediate_node(to_prev, to_next);\n}\n\nvoid CFGNode::retarget_branch_pre_traversal(CFGNode *to_prev, CFGNode *to_next)\n{\n\t//LOGI(\"Retargeting branch for %s: %s -> %s\\n\", name.c_str(), to_prev->name.c_str(), to_next->name.c_str());\n\n\tassert(std::find(succ.begin(), succ.end(), to_prev) != succ.end());\n\tassert(std::find(to_prev->pred.begin(), to_prev->pred.end(), this) != to_prev->pred.end());\n\tassert(std::find(succ.begin(), succ.end(), to_next) == succ.end());\n\tassert(std::find(to_next->pred.begin(), to_next->pred.end(), this) == to_next->pred.end());\n\n\tto_prev->pred.erase(std::find(to_prev->pred.begin(), to_prev->pred.end(), this));\n\n\t// Modify succ in place so we don't invalidate iterator in traverse_dominated_blocks_and_rewrite_branch.\n\t*std::find(succ.begin(), succ.end(), to_prev) = to_next;\n\n\tauto replace_itr = std::find(to_next->pred.begin(), to_next->pred.end(), to_prev);\n\t// If to_prev now becomes unreachable, just replace pred in-place to avoid a stale pred.\n\t// The stale pred will be cleaned up later when recomputing CFG.\n\tif (to_prev->pred.empty() && !to_prev->pred_back_edge && replace_itr != to_next->pred.end())\n\t\t*replace_itr = this;\n\telse\n\t\tto_next->add_unique_pred(this);\n\n\tif (ir.terminator.direct_block == to_prev)\n\t\tir.terminator.direct_block = to_next;\n\tif (ir.terminator.true_block == to_prev)\n\t\tir.terminator.true_block = to_next;\n\tif (ir.terminator.false_block == to_prev)\n\t\tir.terminator.false_block = to_next;\n\tfor (auto &c : ir.terminator.cases)\n\t\tif (c.node == to_prev)\n\t\t\tc.node = to_next;\n}\n\nvoid CFGNode::retarget_branch(CFGNode *to_prev, CFGNode *to_next)\n{\n\tretarget_branch_pre_traversal(to_prev, to_next);\n\n\t// Branch targets have changed, so recompute immediate dominators.\n\tif (to_prev->forward_post_visit_order > to_next->forward_post_visit_order)\n\t{\n\t\tto_prev->recompute_immediate_dominator();\n\t\tto_next->recompute_immediate_dominator();\n\t}\n\telse\n\t{\n\t\tto_next->recompute_immediate_dominator();\n\t\tto_prev->recompute_immediate_dominator();\n\t}\n\n\t// ... and post dominator for ourself.\n\t// I am not sure if it's technically possible that we have to recompute the entire post domination graph now?\n\trecompute_immediate_post_dominator();\n}\n\nvoid CFGNode::retarget_fake_succ(CFGNode *to_prev, CFGNode *to_next)\n{\n\tassert(std::find(to_prev->fake_pred.begin(), to_prev->fake_pred.end(), this) != to_prev->fake_pred.end());\n\tauto succ_itr = std::find(fake_succ.begin(), fake_succ.end(), to_next);\n\tauto prev_itr = std::find(fake_succ.begin(), fake_succ.end(), to_prev);\n\tassert(prev_itr != fake_succ.end());\n\n\t// It is valid to rewrite a fake succ to an existing one.\n\t// It's possible that we need to rewrite from one loop exit to another.\n\n\tif (succ_itr == fake_succ.end())\n\t{\n\t\t*prev_itr = to_next;\n\t\tassert(std::find(to_next->fake_pred.begin(), to_next->fake_pred.end(), this) == to_next->fake_pred.end());\n\t}\n\telse\n\t{\n\t\t// We can invalidate iterators since we break out immediately when rewriting a fake succ.\n\t\tfake_succ.erase(prev_itr);\n\t}\n\n\tto_next->add_unique_fake_pred(this);\n\trecompute_immediate_post_dominator();\n}\n\nvoid CFGNode::fixup_merge_info_after_branch_rewrite(CFGNode *from, CFGNode *to)\n{\n\t// If we end up re-seating merge sites, make sure we add it to headers in the target block, since we might have\n\t// to keep splitting merge scopes in innermost scopes.\n\tif (std::find(from->headers.begin(), from->headers.end(), this) != from->headers.end())\n\t{\n\t\tif (std::find(to->headers.begin(), to->headers.end(), this) == to->headers.end())\n\t\t\tto->headers.push_back(this);\n\t\tif (selection_merge_block == from)\n\t\t\tselection_merge_block = to;\n\t\tif (loop_merge_block == from)\n\t\t\tloop_merge_block = to;\n\t\tif (loop_ladder_block == from)\n\t\t\tloop_ladder_block = to;\n\t}\n}\n\nvoid CFGNode::recompute_immediate_dominator()\n{\n\tif (pred.empty())\n\t{\n\t\t// For entry block only.\n\t\timmediate_dominator = this;\n\t}\n\telse\n\t{\n\t\timmediate_dominator = nullptr;\n\n\t\tfor (auto *edge : pred)\n\t\t{\n\t\t\tif (immediate_dominator)\n\t\t\t\timmediate_dominator = CFGNode::find_common_dominator(immediate_dominator, edge);\n\t\t\telse\n\t\t\t\timmediate_dominator = edge;\n\t\t}\n\t}\n}\n\nvoid CFGNode::recompute_immediate_post_dominator()\n{\n\tif (!succ.empty() || !fake_succ.empty())\n\t{\n\t\t// For non-leaf blocks only. The immediate post dominator is already set up to be the exit node in leaf nodes.\n\t\timmediate_post_dominator = nullptr;\n\t\tfor (auto *edge : succ)\n\t\t{\n\t\t\tif (immediate_post_dominator)\n\t\t\t\timmediate_post_dominator = CFGNode::find_common_post_dominator(immediate_post_dominator, edge);\n\t\t\telse\n\t\t\t\timmediate_post_dominator = edge;\n\t\t}\n\n\t\tfor (auto *edge : fake_succ)\n\t\t{\n\t\t\tif (immediate_post_dominator)\n\t\t\t\timmediate_post_dominator = CFGNode::find_common_post_dominator(immediate_post_dominator, edge);\n\t\t\telse\n\t\t\t\timmediate_post_dominator = edge;\n\t\t}\n\t}\n}\n\nCFGNode *CFGNode::get_outer_selection_dominator()\n{\n\tassert(immediate_dominator);\n\tauto *node = immediate_dominator;\n\n\t// We need to find an immediate dominator which we do not post-dominate.\n\t// That first idom is considered the outer selection header.\n\twhile (node->ir.terminator.type != Terminator::Type::Switch && post_dominates(node))\n\t{\n\t\tif (node->pred.empty())\n\t\t\tbreak;\n\n\t\t// Skip from merge block to header.\n\t\twhile (std::find(node->headers.begin(), node->headers.end(), node->immediate_dominator) != node->headers.end())\n\t\t\tnode = node->immediate_dominator;\n\n\t\tif (post_dominates(node))\n\t\t{\n\t\t\tassert(node->immediate_dominator);\n\t\t\tnode = node->immediate_dominator;\n\t\t}\n\t}\n\n\treturn node;\n}\n\nCFGNode *CFGNode::get_outer_header_dominator()\n{\n\tassert(immediate_dominator);\n\tauto *node = immediate_dominator;\n\twhile (node->succ.size() == 1 && node->ir.terminator.type != Terminator::Type::Switch && !node->pred_back_edge)\n\t{\n\t\tif (node->pred.empty())\n\t\t\tbreak;\n\n\t\tassert(node->immediate_dominator);\n\t\tnode = node->immediate_dominator;\n\t}\n\n\treturn node;\n}\n\nbool CFGNode::block_is_jump_thread_ladder() const\n{\n\tif (!ir.operations.empty() || ir.terminator.type != Terminator::Type::Condition || ir.phi.size() != 1)\n\t\treturn false;\n\n\tauto &phi = ir.phi.front();\n\n\t// Detect a jump thread block. If the branch target directly depends on the incoming blocks,\n\t// we have this scenario.\n\treturn ir.terminator.conditional_id == phi.id;\n}\n\nbool CFGNode::reaches_backward_visited_node(UnorderedSet<const dxil_spv::CFGNode *> &completed) const\n{\n\tif (completed.count(this))\n\t\treturn false;\n\tcompleted.insert(this);\n\n\tif (backward_visited)\n\t\treturn true;\n\n\tfor (auto *node : succ)\n\t\tif (node->reaches_backward_visited_node(completed))\n\t\t\treturn true;\n\n\tfor (auto *node : fake_succ)\n\t\tif (node->reaches_backward_visited_node(completed))\n\t\t\treturn true;\n\n\treturn false;\n}\n\nbool CFGNode::reaches_backward_visited_node() const\n{\n\tUnorderedSet<const CFGNode *> visit;\n\treturn reaches_backward_visited_node(visit);\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "node.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"ir.hpp\"\n\n#include <algorithm>\n#include <stdint.h>\n\nnamespace dxil_spv\n{\nclass CFGNodePool;\n\nstruct CFGNode\n{\npublic:\n\tString name;\n\tuint32_t id = 0;\n\tvoid *userdata = nullptr;\n\tIRBlock ir;\n\n\tvoid add_branch(CFGNode *to);\n\tvoid add_fake_branch(CFGNode *to);\n\tvoid clear_branches();\n\n\tDXIL_SPV_OVERRIDE_NEW_DELETE\n\nprivate:\n\tfriend class CFGNodePool;\n\tfriend class CFGStructurizer;\n\tfriend struct LoopBacktracer;\n\tfriend struct LoopMergeTracer;\n\texplicit CFGNode(CFGNodePool &pool);\n\n\tCFGNodePool &pool;\n\tuint32_t forward_post_visit_order = 0;\n\tuint32_t backward_post_visit_order = 0;\n\tbool visited = false;\n\tbool backward_visited = false;\n\tbool traversing = false;\n\tbool freeze_structured_analysis = false;\n\tbool is_pseudo_back_edge = false;\n\n\tMergeType merge = MergeType::None;\n\tCFGNode *loop_merge_block = nullptr;\n\tCFGNode *loop_ladder_block = nullptr;\n\tCFGNode *selection_merge_block = nullptr;\n\tVector<CFGNode *> headers;\n\n\tCFGNode *immediate_dominator = nullptr;\n\tCFGNode *immediate_post_dominator = nullptr;\n\tVector<CFGNode *> succ;\n\tVector<CFGNode *> pred;\n\n\t// Fake successors and predecessors which only serve to make the flipped CFG reducible.\n\t// This makes post-domination analysis not strictly correct in all cases, but it is\n\t// fine for the purposes we need post-domination analysis for.\n\t// If a continue block is not reachable in the flipped CFG, we will\n\t// add fake successors from the continue block.\n\tVector<CFGNode *> fake_succ;\n\tVector<CFGNode *> fake_pred;\n\n\tCFGNode *pred_back_edge = nullptr;\n\tCFGNode *succ_back_edge = nullptr;\n\n\tvoid add_unique_succ(CFGNode *node);\n\tvoid add_unique_pred(CFGNode *node);\n\tvoid add_unique_fake_succ(CFGNode *node);\n\tvoid add_unique_fake_pred(CFGNode *node);\n\tvoid add_unique_header(CFGNode *node);\n\tunsigned num_forward_preds() const;\n\tbool has_pred_back_edges() const;\n\tbool dominates(const CFGNode *other) const;\n\tbool reaches_domination_frontier_before_merge(const CFGNode *merge) const;\n\tbool dominates_outer_continue(const CFGNode *loop_header) const;\n\tbool can_loop_merge_to(const CFGNode *other) const;\n\tbool post_dominates(const CFGNode *other) const;\n\tbool post_dominates_perfect_structured_construct() const;\n\tbool dominates_all_reachable_exits() const;\n\tstatic CFGNode *find_common_dominator(CFGNode *a, CFGNode *b);\n\tstatic CFGNode *find_common_post_dominator(CFGNode *a, CFGNode *b);\n\tCFGNode *get_immediate_dominator_loop_header();\n\tbool can_backtrace_to(const CFGNode *parent) const;\n\tbool can_backtrace_to_with_blockers(const CFGNode *parent, const Vector<CFGNode *> &block_nodes) const;\n\tbool can_backtrace_to(const CFGNode *parent, UnorderedSet<const CFGNode *> &node_cache) const;\n\tbool can_backtrace_to_with_blockers(const CFGNode *parent, const Vector<CFGNode *> &block_nodes,\n\t                                    UnorderedSet<const CFGNode *> &node_cache) const;\n\tbool post_dominates_any_work() const;\n\tunsigned count_post_dominates_work_from_incoming_preds() const;\n\tbool post_dominates_any_work(const CFGNode *parent, UnorderedSet<const CFGNode *> &node_cache) const;\n\tbool reaches_backward_visited_node() const;\n\n\tvoid retarget_branch(CFGNode *to_prev, CFGNode *to_next);\n\tvoid retarget_branch_pre_traversal(CFGNode *to_prev, CFGNode *to_next);\n\tvoid retarget_branch_with_intermediate_node(CFGNode *to_prev, CFGNode *to_next);\n\tCFGNode *rewrite_branch_through_intermediate_node(CFGNode *to_prev, CFGNode *to_next);\n\n\tvoid fixup_merge_info_after_branch_rewrite(CFGNode *from, CFGNode *to);\n\n\ttemplate <typename Op>\n\tvoid walk_cfg_from(const Op &op) const;\n\n\tvoid recompute_immediate_dominator();\n\tvoid recompute_immediate_post_dominator();\n\n\ttemplate <typename Op>\n\tvoid traverse_dominated_blocks(const Op &op) const;\n\n\tCFGNode *get_outer_selection_dominator();\n\tCFGNode *get_outer_header_dominator();\n\n\tVector<CFGNode *> dominance_frontier;\n\tVector<CFGNode *> post_dominance_frontier;\n\n\tbool block_is_jump_thread_ladder() const;\n\nprivate:\n\tbool dominates_all_reachable_exits(UnorderedSet<const CFGNode *>& completed, const CFGNode &header) const;\n\n\ttemplate <typename Op>\n\tvoid traverse_dominated_blocks(UnorderedSet<const CFGNode *> &completed,\n\t                                    const CFGNode &header, const Op &op) const;\n\n\tvoid retarget_fake_succ(CFGNode *from, CFGNode *to);\n\tbool reaches_backward_visited_node(UnorderedSet<const CFGNode *> &completed) const;\n};\n\ntemplate <typename Op>\nvoid CFGNode::walk_cfg_from(const Op &op) const\n{\n\tif (!op(this))\n\t\treturn;\n\n\tfor (auto *s : succ)\n\t\ts->walk_cfg_from(op);\n}\n\ntemplate <typename Op>\nvoid CFGNode::traverse_dominated_blocks(UnorderedSet<const CFGNode *> &completed,\n                                        const CFGNode &header, const Op &op) const\n{\n\tfor (auto *node : succ)\n\t{\n\t\tbool can_visit = completed.count(node) == 0;\n\t\tif (can_visit)\n\t\t\tcompleted.insert(node);\n\n\t\tif (can_visit && header.dominates(node))\n\t\t{\n\t\t\tif (op(node))\n\t\t\t\tnode->traverse_dominated_blocks(completed, header, op);\n\t\t}\n\t}\n}\n\ntemplate <typename Op>\nvoid CFGNode::traverse_dominated_blocks(const Op &op) const\n{\n\tUnorderedSet<const CFGNode *> completed;\n\ttraverse_dominated_blocks(completed, *this, op);\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "node_pool.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"node_pool.hpp\"\n#include \"node.hpp\"\n#include <utility>\n\nnamespace dxil_spv\n{\nCFGNodePool::CFGNodePool()\n{\n}\n\nCFGNodePool::~CFGNodePool()\n{\n}\n\nCFGNode *CFGNodePool::create_node()\n{\n\tauto node = std::unique_ptr<CFGNode>(new CFGNode(*this));\n\tauto *ret = node.get();\n\tnodes.push_back(std::move(node));\n\treturn ret;\n}\n\n} // namespace dxil_spv\n"
  },
  {
    "path": "node_pool.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include <memory>\n\nnamespace dxil_spv\n{\nstruct CFGNode;\n\nclass CFGNodePool\n{\npublic:\n\tDXIL_SPV_OVERRIDE_NEW_DELETE\n\n\tCFGNodePool();\n\t~CFGNodePool();\n\n\tCFGNode *create_node();\n\n\ttemplate <typename Op>\n\tvoid for_each_node(const Op &op)\n\t{\n\t\tfor (auto &node : nodes)\n\t\t\top(*node);\n\t}\n\nprivate:\n\tVector<std::unique_ptr<CFGNode>> nodes;\n};\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/converter_impl.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"SpvBuilder.h\"\n#include \"cfg_structurizer.hpp\"\n#include \"dxil_converter.hpp\"\n#include \"scratch_pool.hpp\"\n#include \"descriptor_qa.hpp\"\n#include \"opcodes.hpp\"\n#include \"dxil/dxil_ags.hpp\"\n#include \"dxil/dxil_nvapi.hpp\"\n\n#include \"GLSL.std.450.h\"\n\n#ifdef HAVE_LLVMBC\n#include \"function.hpp\"\n#include \"instruction.hpp\"\n#include \"module.hpp\"\n#include \"value.hpp\"\n#include \"metadata.hpp\"\n#else\n#include <llvm/IR/BasicBlock.h>\n#include <llvm/IR/CFG.h>\n#include <llvm/IR/Instructions.h>\n#endif\n\n#include <stdlib.h>\n#include <string.h>\n\nnamespace dxil_spv\n{\nenum class LocalRootSignatureType\n{\n\tConstants,\n\tDescriptor,\n\tTable\n};\n\nstruct LocalRootSignatureConstants\n{\n\tuint32_t register_space;\n\tuint32_t register_index;\n\tuint32_t num_words;\n};\n\nstruct LocalRootSignatureDescriptor\n{\n\tResourceClass type;\n\tuint32_t register_space;\n\tuint32_t register_index;\n};\n\nstruct LocalRootSignatureEntry\n{\n\tLocalRootSignatureType type;\n\tunion\n\t{\n\t\tLocalRootSignatureConstants constants;\n\t\tLocalRootSignatureDescriptor descriptor;\n\t};\n\tVector<DescriptorTableEntry> table_entries;\n};\n\nstruct ReferenceVkMemoryModel\n{\n\tbool non_private = false;\n\tbool auto_visibility = false;\n};\n\nstatic inline DXIL::ComponentType raw_width_to_component_type(RawType type, RawWidth raw_width)\n{\n\tswitch (raw_width)\n\t{\n\tcase RawWidth::B8:\n\t\treturn DXIL::ComponentType::InternalU8;\n\tcase RawWidth::B16:\n\t\treturn type == RawType::Float ? DXIL::ComponentType::F16 : DXIL::ComponentType::U16;\n\tcase RawWidth::B64:\n\t\treturn type == RawType::Float ? DXIL::ComponentType::F64 : DXIL::ComponentType::U64;\n\tdefault:\n\t\treturn type == RawType::Float ? DXIL::ComponentType::F32 : DXIL::ComponentType::U32;\n\t}\n}\n\nstatic inline unsigned raw_vecsize_to_vecsize(RawVecSize raw_vecsize)\n{\n\treturn unsigned(raw_vecsize) + 1;\n}\n\nstatic inline unsigned raw_component_type_to_bits(DXIL::ComponentType type)\n{\n\tswitch (type)\n\t{\n\tcase DXIL::ComponentType::InternalU8:\n\t\treturn 8;\n\tcase DXIL::ComponentType::U16:\n\tcase DXIL::ComponentType::F16:\n\t\treturn 16;\n\tcase DXIL::ComponentType::U32:\n\tcase DXIL::ComponentType::F32:\n\t\treturn 32;\n\tcase DXIL::ComponentType::U64:\n\tcase DXIL::ComponentType::F64:\n\t\treturn 64;\n\tdefault:\n\t\tassert(0 && \"Invalid component type.\");\n\t\treturn 0;\n\t}\n}\n\nstatic inline RawType raw_component_type_to_type(DXIL::ComponentType type)\n{\n\tswitch (type)\n\t{\n\tcase DXIL::ComponentType::InternalU8:\n\tcase DXIL::ComponentType::U16:\n\tcase DXIL::ComponentType::U32:\n\tcase DXIL::ComponentType::U64:\n\t\treturn RawType::Integer;\n\tcase DXIL::ComponentType::F16:\n\tcase DXIL::ComponentType::F32:\n\tcase DXIL::ComponentType::F64:\n\t\treturn RawType::Float;\n\tdefault:\n\t\tassert(0 && \"Invalid component type.\");\n\t\treturn RawType::Count;\n\t}\n}\n\nstatic inline unsigned raw_width_to_bits(RawWidth raw_width)\n{\n\treturn raw_component_type_to_bits(raw_width_to_component_type(RawType::Integer, raw_width));\n}\n\n// Track patterns where shader copies CBV arrays into a local array.\n// DXC does not seem to optimize this in all cases that games run into.\nstruct AllocaCBVForwardingTracking\n{\n\tconst llvm::Value *cbv_handle = nullptr;\n\tuint32_t scalar_index_offset = 0;\n\tuint32_t stride = 0;\n\tuint32_t highest_store_index = 0;\n\tuint32_t min_highest_store_index = 0;\n\tbool has_load = false;\n};\n\nclass GlobalConfiguration\n{\npublic:\n\t// Only used for temporary hackery and testing.\n\tstatic const GlobalConfiguration &get();\n\tbool wmma_rdna3_workaround = false;\n\tbool wmma_conv_hack = false;\n\nprivate:\n\tGlobalConfiguration();\n};\n\nstruct AccessTracking\n{\n\tbool has_read = false;\n\tbool has_written = false;\n\tbool has_atomic = false;\n\tbool has_atomic_64bit = false;\n\tbool has_counter = false;\n\tbool dynamically_indexed_cbv = false;\n\tbool raw_access_buffer_declarations[unsigned(RawType::Count)][unsigned(RawWidth::Count)][unsigned(RawVecSize::Count)] = {};\n};\n\nstruct Converter::Impl\n{\n\tDXIL_SPV_OVERRIDE_NEW_DELETE\n\n\tImpl(LLVMBCParser &bitcode_parser_, LLVMBCParser *bitcode_reflection_parser_, SPIRVModule &module_)\n\t    : bitcode_parser(bitcode_parser_)\n\t    , bitcode_reflection_parser(bitcode_reflection_parser_)\n\t    , spirv_module(module_)\n\t{\n\t}\n\n\tLLVMBCParser &bitcode_parser;\n\tLLVMBCParser *bitcode_reflection_parser;\n\tSPIRVModule &spirv_module;\n\n\tstruct BlockMeta\n\t{\n\t\texplicit BlockMeta(llvm::BasicBlock *bb_)\n\t\t    : bb(bb_)\n\t\t{\n\t\t}\n\n\t\tllvm::BasicBlock *bb;\n\t\tCFGNode *node = nullptr;\n\n\t\tDXIL_SPV_OVERRIDE_NEW_DELETE\n\t};\n\tVector<std::unique_ptr<BlockMeta>> metas;\n\tUnorderedMap<const llvm::BasicBlock *, BlockMeta *> bb_map;\n\tUnorderedMap<const llvm::Value *, spv::Id> value_map;\n\tUnorderedMap<spv::Id, spv::Id> phi_incoming_rewrite;\n\n\tConvertedFunction convert_entry_point();\n\tCFGNode *convert_function(const Vector<llvm::BasicBlock *> &bbs, bool primary_code);\n\tCFGNode *build_hull_passthrough_function(CFGNodePool &pool);\n\tConvertedFunction::Function build_hull_main(const Vector<llvm::BasicBlock *> &bbs,\n\t                                            const Vector<llvm::BasicBlock *> &patch_bbs,\n\t                                            CFGNodePool &pool,\n\t                                            Vector<ConvertedFunction::Function> &leaves);\n\tConvertedFunction::Function build_rov_main(const Vector<llvm::BasicBlock *> &bbs,\n\t                                           CFGNodePool &pool,\n\t                                           Vector<ConvertedFunction::Function> &leaves);\n\tConvertedFunction::Function build_node_main(const Vector<llvm::BasicBlock *> &bbs,\n\t                                            CFGNodePool &pool,\n\t                                            Vector<ConvertedFunction::Function> &leaves);\n\tvoid gather_function_dependencies(llvm::Function *caller, Vector<llvm::Function *> &funcs);\n\tbool build_callee_functions(CFGNodePool &pool, const Vector<llvm::Function *> &callees,\n\t                            Vector<ConvertedFunction::Function> &leaves);\n\tspv::Id get_id_for_value(const llvm::Value *value, unsigned forced_integer_width = 0);\n\tspv::Id get_id_for_constant(const llvm::Constant *constant, unsigned forced_width);\n\tspv::Id get_padded_constant_array(spv::Id padded_type_id, const llvm::Constant *constant);\n\tspv::Id get_id_for_undef(const llvm::UndefValue *undef);\n\tspv::Id get_id_for_undef_constant(const llvm::UndefValue *undef);\n\tvoid emit_patch_output_lowering(CFGNode *node);\n\n\tVector<llvm::BasicBlock *> build_function_bb_visit_order_legacy(llvm::Function *func, CFGNodePool &pool);\n\tVector<llvm::BasicBlock *> build_function_bb_visit_order_analysis(llvm::Function *func);\n\tvoid build_function_bb_visit_order_inner_analysis(Vector<llvm::BasicBlock *> &bbs,\n\t                                                  UnorderedSet<llvm::BasicBlock *> &visited,\n\t                                                  llvm::BasicBlock *bb);\n\tvoid build_function_bb_visit_register(llvm::BasicBlock *bb, CFGNodePool &pool, String tag);\n\n\tbool emit_stage_input_variables();\n\tbool emit_stage_output_variables();\n\tbool emit_patch_variables();\n\tbool emit_other_variables();\n\tbool emit_global_variables();\n\tbool emit_incoming_payload();\n\tbool emit_hit_attribute();\n\tvoid emit_interpolation_decorations(spv::Id variable_id, DXIL::InterpolationMode mode);\n\tvoid emit_builtin_interpolation_decorations(spv::Id variable_id, DXIL::Semantic semantic, DXIL::InterpolationMode mode);\n\n\tspv::ExecutionModel execution_model = spv::ExecutionModelMax;\n\tbool execution_model_lib_target = false;\n\tbool emit_execution_modes();\n\tbool emit_execution_modes_late();\n\tvoid emit_execution_modes_post_code_generation();\n\tbool analyze_execution_modes_meta();\n\tbool emit_execution_modes_compute();\n\tbool emit_execution_modes_node();\n\n\tstatic NodeDispatchGrid node_parse_dispatch_grid(llvm::MDNode *node_meta);\n\tstatic uint32_t node_parse_payload_stride(llvm::MDNode *node_meta, bool &is_rw_sharing);\n\tbool emit_execution_modes_node_input();\n\tbool emit_execution_modes_node_output(llvm::MDNode *input);\n\tbool emit_execution_modes_geometry();\n\tbool emit_execution_modes_hull();\n\tbool emit_execution_modes_domain();\n\tbool emit_execution_modes_pixel();\n\tbool emit_execution_modes_pixel_late();\n\tbool emit_execution_modes_ray_tracing(spv::ExecutionModel model);\n\tbool emit_execution_modes_amplification();\n\tbool emit_execution_modes_mesh();\n\tbool emit_execution_modes_fp_denorm_rounding();\n\tbool emit_execution_modes_thread_wave_properties(const llvm::MDNode *num_threads);\n\n\tbool analyze_instructions(llvm::Function *func);\n\tvoid analyze_instructions_post_execution_modes();\n\tvoid mark_used_values(const llvm::Instruction *instruction);\n\tvoid mark_used_value(const llvm::Value *value);\n\n\tstruct RawDeclaration\n\t{\n\t\tRawType type;\n\t\tRawWidth width;\n\t\tRawVecSize vecsize;\n\t};\n\n\tUnorderedMap<uint32_t, AccessTracking> cbv_access_tracking;\n\tUnorderedMap<uint32_t, AccessTracking> srv_access_tracking;\n\tUnorderedMap<uint32_t, AccessTracking> uav_access_tracking;\n\tUnorderedMap<const llvm::Value *, uint32_t> llvm_value_to_cbv_resource_index_map;\n\tUnorderedMap<const llvm::Value *, uint32_t> llvm_value_to_srv_resource_index_map;\n\tUnorderedMap<const llvm::Value *, uint32_t> llvm_value_to_uav_resource_index_map;\n\tUnorderedSet<const llvm::Value *> llvm_values_using_update_counter;\n\tUnorderedMap<const llvm::Value *, spv::Id> llvm_value_actual_type;\n\tUnorderedSet<uint32_t> llvm_attribute_at_vertex_indices;\n\n\tAGSState ags;\n\tNVAPIState nvapi;\n\n\t// DXIL has no storage class concept for hit/callable/payload types.\n\tconst llvm::Type *llvm_hit_attribute_output_type = nullptr;\n\tspv::Id llvm_hit_attribute_output_value = 0;\n\n\tstruct CompositeMeta\n\t{\n\t\t// Keeps track of which elements of a struct composite type are statically accessed.\n\t\t// This is required to eliminate dead loads when we're unrolling and also needed to keep\n\t\t// track of if opcodes should use sparse residency or not.\n\t\tunsigned access_mask = 0;\n\t\t// Effectively findMSB(access_mask) + 1\n\t\tunsigned components = 0;\n\t\t// If true, the composite was loaded as a vector, i.e. typed buffer or texture read.\n\t\tbool forced_composite = true;\n\t};\n\tUnorderedMap<const llvm::Value *, CompositeMeta> llvm_composite_meta;\n\tVector<const llvm::Type *> llvm_dxil_op_fake_struct_types;\n\n\tbool composite_is_accessed(const llvm::Value *composite) const;\n\n\tstruct ResourceMetaReference\n\t{\n\t\tDXIL::ResourceType type;\n\t\tunsigned meta_index;\n\t\tllvm::Value *offset;\n\t\tconst llvm::GlobalVariable *variable;\n\t\tbool non_uniform;\n\t};\n\tUnorderedMap<const llvm::Value *, ResourceMetaReference> llvm_global_variable_to_resource_mapping;\n\tUnorderedSet<const llvm::GlobalVariable *> llvm_active_global_resource_variables;\n\n\tstruct ResourceVariableMeta\n\t{\n\t\tbool is_lib_variable;\n\t\tbool is_active;\n\t};\n\tResourceVariableMeta get_resource_variable_meta(const llvm::MDNode *resource) const;\n\n\tstruct ExecutionModeMeta\n\t{\n\t\tunsigned stage_input_num_vertex = 0;\n\t\tunsigned stage_output_num_vertex = 0;\n\t\tunsigned stage_output_num_primitive = 0;\n\t\tunsigned primitive_index_dimension = 0;\n\t\tunsigned gs_stream_active_mask = 0;\n\t\tllvm::Function *patch_constant_function = nullptr;\n\t\tspv::Id patch_lowering_array_var_id = 0;\n\t\tunsigned workgroup_threads[3] = {};\n\t\tbool native_16bit_operations = false;\n\t\tbool synthesize_2d_quad_dispatch = false;\n\t\tbool synthesize_dummy_derivatives = false;\n\t\tunsigned wave_size_min = 0;\n\t\tunsigned wave_size_max = 0;\n\t\tunsigned wave_size_preferred = 0;\n\t\tunsigned heuristic_min_wave_size = 0;\n\t\tunsigned heuristic_max_wave_size = 0;\n\t\tbool declares_globallycoherent_uav = false;\n\t\tbool declares_rov = false;\n\t\tbool per_sample_shading = false;\n\t\tbool waveops_include_helper_lanes = false;\n\t\tbool needs_quad_derivatives = false;\n\t\tString entry_point_name;\n\n\t\t// Eventually, we should use Vulkan memory model across the board,\n\t\t// but don't want to invalidate all Foz caches.\n\t\tspv::MemoryModel memory_model = spv::MemoryModelGLSL450;\n\t} execution_mode_meta;\n\n\tstatic ShaderStage get_remapping_stage(spv::ExecutionModel model);\n\n\tllvm::MDNode *entry_point_meta = nullptr;\n\tbool emit_resources_global_mapping();\n\tbool emit_resources_global_mapping(DXIL::ResourceType type, const llvm::MDNode *node);\n\tbool emit_resources();\n\tbool emit_global_heaps();\n\tbool emit_descriptor_heap_introspection_buffer();\n\tbool emit_descriptor_heap_size_ubo();\n\tbool emit_srvs(const llvm::MDNode *srvs, const llvm::MDNode *refl);\n\tbool emit_uavs(const llvm::MDNode *uavs, const llvm::MDNode *refl);\n\tbool emit_cbvs(const llvm::MDNode *cbvs, const llvm::MDNode *refl);\n\tbool emit_samplers(const llvm::MDNode *samplers, const llvm::MDNode *refl);\n\tbool emit_shader_record_buffer();\n\tspv::Id emit_shader_record_buffer_block_type(bool physical_storage);\n\tvoid register_resource_meta_reference(const llvm::MDOperand &operand, DXIL::ResourceType type, unsigned index);\n\tvoid emit_root_constants(unsigned num_descriptors, unsigned num_constant_words);\n\tbool require_arrayed_root_constants() const;\n\tstatic void scan_resources(ResourceRemappingInterface *iface, const LLVMBCParser &parser);\n\tstatic bool scan_srvs(ResourceRemappingInterface *iface, const llvm::MDNode *srvs, ShaderStage stage);\n\tstatic bool scan_uavs(ResourceRemappingInterface *iface, const llvm::MDNode *uavs, ShaderStage stage);\n\tstatic bool scan_cbvs(ResourceRemappingInterface *iface, const llvm::MDNode *cbvs, ShaderStage stage);\n\tstatic bool scan_samplers(ResourceRemappingInterface *iface, const llvm::MDNode *samplers, ShaderStage stage);\n\tbool get_ssbo_offset_buffer_id(spv::Id &buffer_id, const VulkanBinding &buffer_binding, const VulkanBinding &offset_binding,\n\t                               DXIL::ResourceKind kind, unsigned alignment);\n\n\tVector<LocalRootSignatureEntry> local_root_signature;\n\tint get_local_root_signature_entry(ResourceClass resource_class, uint32_t space, uint32_t binding,\n\t                                   DescriptorTableEntry &local_table_entry) const;\n\n\tvoid emit_root_parameter_index_from_push_index(const char *tag, uint32_t index, uint32_t size, bool bda);\n\tuint64_t root_parameter_emit_mask = 0;\n\n\tstruct RawDeclarationVariable\n\t{\n\t\tRawDeclaration declaration;\n\t\tspv::Id var_id;\n\t};\n\n\tstruct ResourceReference\n\t{\n\t\tspv::Id var_id = 0;\n\t\tVector<RawDeclarationVariable> var_alias_group;\n\t\tbool aliased = false;\n\n\t\tuint32_t push_constant_member = 0;\n\t\tuint32_t base_offset = 0;\n\t\tunsigned stride = 0;\n\t\tbool bindless = false;\n\t\tbool base_resource_is_array = false;\n\t\tbool root_descriptor = false;\n\t\tbool coherent = false;\n\t\tbool rov = false;\n\t\tDXIL::ResourceKind resource_kind = DXIL::ResourceKind::Invalid;\n\t\tint local_root_signature_entry = -1;\n\t\tReferenceVkMemoryModel vkmm;\n\t};\n\n\t// Collects all unique calls to annotateHandle (SM 6.6),\n\t// we use this to build the various bindless variables as necessary.\n\tstruct AnnotateHandleReference\n\t{\n\t\tunsigned ordinal; // Important for reproducible codegen later.\n\t\tDXIL::ResourceKind resource_kind;\n\t\tDXIL::ResourceType resource_type;\n\t\tDXIL::ComponentType component_type;\n\t\tAccessTracking tracking;\n\t\tunsigned stride;\n\t\tbool coherent;\n\t\tbool rov;\n\t\tbool counter;\n\t\tResourceReference reference;\n\t\tResourceReference counter_reference;\n\t\tspv::Id offset_buffer_id;\n\t};\n\tUnorderedMap<const llvm::Value *, AnnotateHandleReference> llvm_annotate_handle_uses;\n\tUnorderedSet<const llvm::Value *> llvm_annotate_handle_lib_uses;\n\tVector<const llvm::Value *> llvm_vkmm_coherent_ptrs;\n\n\tVector<ResourceReference> srv_index_to_reference;\n\tVector<spv::Id> srv_index_to_offset;\n\tVector<ResourceReference> sampler_index_to_reference;\n\tVector<ResourceReference> cbv_index_to_reference;\n\tVector<ResourceReference> uav_index_to_reference;\n\tVector<ResourceReference> uav_index_to_counter;\n\tVector<spv::Id> uav_index_to_offset;\n\tspv::Id root_constant_id = 0;\n\tunsigned root_descriptor_count = 0;\n\tunsigned root_constant_num_words = 0;\n\tbool root_constant_arrayed = false;\n\tunsigned patch_location_offset = ~0u;\n\tunsigned descriptor_qa_counter = 0;\n\tspv::Id primitive_index_array_id = 0;\n\n\tstruct\n\t{\n\t\tspv::Id descriptor_heap_size_var_id;\n\t\tspv::Id descriptor_heap_introspection_var_id;\n\t\tspv::Id descriptor_heap_introspection_block_ptr_type_id;\n\t\tspv::Id invocation_id_var_id;\n\t\tbool descriptor_heap_introspection_is_bda;\n\t} instrumentation = {};\n\tvoid emit_write_instrumentation_invocation_id(CFGNode *node);\n\n\tstruct PhysicalPointerMeta\n\t{\n\t\tbool nonwritable;\n\t\tbool nonreadable;\n\t\tbool coherent;\n\t\tbool rov;\n\t\tuint8_t stride;\n\t\tuint32_t size;\n\t};\n\n\tstruct ResourceMetaInstrumentation\n\t{\n\t\tspv::Id bda_id;\n\t\tspv::Id elem_size_id;\n\t\tspv::Id resource_size_id;\n\t};\n\n\tstruct ResourceMeta\n\t{\n\t\tDXIL::ResourceKind kind;\n\t\tDXIL::ComponentType component_type;\n\t\tRawVecSize raw_component_vecsize;\n\t\tunsigned stride;\n\n\t\tspv::Id var_id;\n\t\tVector<RawDeclarationVariable> var_alias_group;\n\t\tbool aliased;\n\t\tbool non_uniform;\n\t\tbool rov;\n\t\tReferenceVkMemoryModel vkmm;\n\n\t\tspv::StorageClass storage;\n\t\tspv::StorageClass counter_storage;\n\n\t\tspv::Id counter_var_id;\n\t\tPhysicalPointerMeta physical_pointer_meta;\n\t\tspv::Id index_offset_id;\n\t\tResourceMetaInstrumentation instrumentation;\n\t};\n\tUnorderedMap<spv::Id, ResourceMeta> handle_to_resource_meta;\n\tUnorderedMap<spv::Id, spv::Id> id_to_type;\n\tUnorderedMap<const llvm::Value *, unsigned> handle_to_root_member_offset;\n\tUnorderedMap<const llvm::Value *, spv::StorageClass> handle_to_storage_class;\n\tUnorderedMap<const llvm::Value *, spv::Id> handle_to_robustness;\n\tUnorderedSet<const llvm::Value *> needs_temp_storage_copy;\n\n\tstruct TempPayloadEntry\n\t{\n\t\tspv::Id type;\n\t\tspv::StorageClass storage;\n\t\tspv::Id id;\n\t};\n\tVector<TempPayloadEntry> temp_payloads;\n\n\tspv::StorageClass get_effective_storage_class(const llvm::Value *value, spv::StorageClass fallback) const;\n\tbool get_needs_temp_storage_copy(const llvm::Value *value) const;\n\tspv::Id get_temp_payload(spv::Id type, spv::StorageClass storage);\n\n\tspv::Id get_type_id(DXIL::ComponentType element_type, unsigned rows, unsigned cols, bool force_array = false);\n\n\tenum TypeLayoutFlagBits\n\t{\n\t\tTYPE_LAYOUT_PHYSICAL_BIT = 0x1,\n\t\tTYPE_LAYOUT_READ_ONLY_BIT = 0x2,\n\t\tTYPE_LAYOUT_COHERENT_BIT = 0x4,\n\t\tTYPE_LAYOUT_BLOCK_BIT = 0x8,\n\t};\n\tusing TypeLayoutFlags = uint32_t;\n\n\tspv::Id get_type_id(const llvm::Type *type, TypeLayoutFlags flags = 0);\n\tspv::Id get_type_id(spv::Id id) const;\n\n\tstruct ElementMeta\n\t{\n\t\tspv::Id id;\n\t\tDXIL::ComponentType component_type;\n\t\tunsigned semantic_offset;\n\t\tDXIL::Semantic semantic;\n\t};\n\n\tstruct ElementPatchMeta : ElementMeta\n\t{\n\t\tspv::Id start_row;\n\t\tspv::Id start_col;\n\t\tbool lowering;\n\t};\n\n\tstruct ClipCullMeta\n\t{\n\t\tunsigned offset;\n\t\tunsigned row_stride;\n\t\tspv::BuiltIn builtin;\n\t};\n\tUnorderedMap<uint32_t, ElementMeta> input_elements_meta;\n\tUnorderedMap<uint32_t, ElementMeta> output_elements_meta;\n\tUnorderedMap<uint32_t, ElementPatchMeta> patch_elements_meta;\n\tUnorderedMap<uint32_t, ClipCullMeta> input_clip_cull_meta;\n\tUnorderedMap<uint32_t, ClipCullMeta> output_clip_cull_meta;\n\tvoid emit_builtin_decoration(spv::Id id, DXIL::Semantic semantic, spv::StorageClass storage);\n\n\tstruct NodeInputMeta\n\t{\n\t\tString node_id;\n\t\tuint32_t node_array_index;\n\t\tspv::Id private_bda_var_id; // Private variable which holds a BDA to the node, set by the main() dispatcher.\n\t\tspv::Id private_stride_var_id; // Private variable which holds stride for entry point nodes, set by the main() dispatcher.\n\t\tspv::Id private_coalesce_offset_id; // Private variable which holds the linear input index.\n\t\tspv::Id private_coalesce_count_id; // Private variable which holds the input count.\n\t\tspv::Id node_dispatch_push_id; // PushConstant ABI for dispatching.\n\t\tspv::Id shader_record_block_type_id;\n\t\t// Stride for the payload. This is recorded in metadata, but we may have to allocate SV_DispatchGrid.\n\t\tuint32_t payload_stride;\n\t\tuint32_t coalesce_stride; // Coalesce width.\n\t\tspv::Id u32_ptr_type_id;\n\t\tspv::Id u64_ptr_type_id;\n\t\tspv::Id u32_array_ptr_type_id;\n\t\tspv::Id is_indirect_payload_stride_id;\n\t\tspv::Id is_entry_point_id;\n\t\tspv::Id broadcast_has_max_grid_id;\n\t\tspv::Id thread_group_size_id;\n\t\tspv::Id is_static_broadcast_node_id;\n\t\tspv::Id max_broadcast_grid_id[3];\n\t\tspv::Id max_broadcast_grid_minus_1_id[3];\n\t\tspv::Id real_workgroup_id;\n\t\tspv::Id real_global_invocation_id;\n\t\tDXIL::NodeLaunchType launch_type;\n\t\tNodeDispatchGrid dispatch_grid;\n\t};\n\n\tstruct NodeOutputMeta\n\t{\n\t\tspv::Id spec_constant_node_index;\n\t\t// Stride for the payload. This is recorded in metadata, but we may have to allocate SV_DispatchGrid.\n\t\tuint32_t payload_stride;\n\t\tbool is_recursive;\n\t};\n\n\tNodeInputMeta node_input = {};\n\tVector<NodeOutputMeta> node_outputs;\n\n\tbool emit_instruction(CFGNode *block, const llvm::Instruction &instruction);\n\tbool emit_phi_instruction(CFGNode *block, const llvm::PHINode &instruction);\n\n\tspv::Id build_sampled_image(spv::Id image_id, spv::Id sampler_id, bool comparison);\n\tspv::Id build_vector(spv::Id element_type, const spv::Id *elements, unsigned count);\n\tspv::Id build_vector_type(spv::Id element_type, unsigned count);\n\tspv::Id build_constant_vector(spv::Id element_type, const spv::Id *elements, unsigned count);\n\tspv::Id build_splat_constant_vector(spv::Id element_type, spv::Id value, unsigned count);\n\tspv::Id build_offset(spv::Id value, unsigned offset);\n\tvoid fixup_load_type_io(DXIL::ComponentType component_type, unsigned components, const llvm::Value *value);\n\tvoid fixup_load_type_atomic(DXIL::ComponentType component_type, unsigned components, const llvm::Value *value);\n\tvoid fixup_load_type_typed(DXIL::ComponentType component_type, unsigned components, const llvm::Value *value,\n\t                           const llvm::Type *target_type);\n\tvoid fixup_load_type_typed(DXIL::ComponentType &component_type, unsigned components, spv::Id &value_id,\n\t                           const llvm::Type *target_type);\n\tvoid repack_sparse_feedback(DXIL::ComponentType component_type, unsigned components, const llvm::Value *value,\n\t                            const llvm::Type *target_type, spv::Id override_value = 0);\n\tspv::Id fixup_store_type_io(DXIL::ComponentType component_type, unsigned components, spv::Id value);\n\tspv::Id fixup_store_type_atomic(DXIL::ComponentType component_type, unsigned components, spv::Id value);\n\tspv::Id fixup_store_type_typed(DXIL::ComponentType component_type, unsigned components, spv::Id value);\n\tspv::Id build_value_cast(spv::Id value_id, DXIL::ComponentType input_type, DXIL::ComponentType output_type,\n\t                         unsigned components);\n\tbool support_native_fp16_operations() const;\n\n\tVector<Operation *> *current_block = nullptr;\n\tvoid add(Operation *op, bool is_rov = false);\n\tOperation *allocate(spv::Op op);\n\tOperation *allocate(spv::Op op, const llvm::Value *value);\n\tOperation *allocate(spv::Op op, spv::Id type_id);\n\tOperation *allocate(spv::Op op, const llvm::Value *value, spv::Id type_id);\n\tOperation *allocate(spv::Op op, spv::Id id, spv::Id type_id);\n\tvoid register_externally_visible_write(const llvm::Value *value);\n\tvoid rewrite_value(const llvm::Value *value, spv::Id id);\n\tspv::Builder &builder();\n\tspv::Id create_variable(spv::StorageClass storage, spv::Id type_id, const char *name = nullptr);\n\tspv::Id create_variable_with_initializer(spv::StorageClass storage, spv::Id type_id,\n\t                                         spv::Id initializer, const char *name = nullptr);\n\n\tspv::Id glsl_std450_ext = 0;\n\tspv::Id texture_sample_pos_lut_id = 0;\n\tspv::Id rasterizer_sample_count_id = 0;\n\tspv::Id shader_record_buffer_id = 0;\n\tVector<spv::Id> shader_record_buffer_types;\n\n\tResourceRemappingInterface *resource_mapping_iface = nullptr;\n\n\tstruct StructTypeEntry\n\t{\n\t\tspv::Id id;\n\t\tString name;\n\t\tVector<spv::Id> subtypes;\n\t\tTypeLayoutFlags flags;\n\t};\n\n\tstruct ArrayTypeEntry\n\t{\n\t\tspv::Id id;\n\t\tuint32_t element_type_id;\n\t\tuint32_t array_size_id;\n\t};\n\tVector<StructTypeEntry> cached_struct_types;\n\tVector<ArrayTypeEntry> cached_physical_array_types;\n\tspv::Id get_struct_type(const Vector<spv::Id> &type_ids, TypeLayoutFlags flags, const char *name);\n\tvoid decorate_physical_offsets(spv::Id struct_type_id, const Vector<spv::Id> &type_ids);\n\n\tstruct SizeAlignment\n\t{\n\t\tuint32_t size;\n\t\tuint32_t alignment;\n\t};\n\tSizeAlignment get_physical_size_for_type(spv::Id type_id);\n\n\tvoid set_option(const OptionBase &cap);\n\tstruct\n\t{\n\t\tbool shader_demote = false;\n\t\tbool dual_source_blending = false;\n\t\tunsigned rasterizer_sample_count = 0;\n\t\tbool rasterizer_sample_count_spec_constant = true;\n\t\tVector<unsigned> output_swizzles;\n\t\tString shader_source_file;\n\t\tString entry_point;\n\n\t\tunsigned inline_ubo_descriptor_set = 0;\n\t\tunsigned inline_ubo_descriptor_binding = 0;\n\t\tbool inline_ubo_enable = false;\n\t\tbool bindless_cbv_ssbo_emulation = false;\n\t\tbool physical_storage_buffer = false;\n\n\t\tunsigned sbt_descriptor_size_srv_uav_cbv_log2 = 0;\n\t\tunsigned sbt_descriptor_size_sampler_log2 = 0;\n\t\tunsigned ssbo_alignment = 16;\n\t\tbool typed_uav_read_without_format = false;\n\t\tbool bindless_typed_buffer_offsets = false;\n\t\tbool storage_16bit_input_output = false;\n\n\t\tstruct\n\t\t{\n\t\t\tunsigned untyped_offset = 0;\n\t\t\tunsigned typed_offset = 0;\n\t\t\tunsigned stride = 1;\n\t\t} offset_buffer_layout;\n\n\t\tDescriptorQAInfo descriptor_qa;\n\t\tInstructionInstrumentationInfo instruction_instrumentation;\n\t\tbool descriptor_qa_enabled = false;\n\t\tbool descriptor_qa_sink_handles = true;\n\t\tbool min_precision_prefer_native_16bit = false;\n\t\tbool shader_i8_dot_enabled = false;\n\t\tbool ray_tracing_primitive_culling_enabled = false;\n\t\tbool invariant_position = false;\n\t\tbool scalar_block_layout = false;\n\t\tbool supports_per_component_robustness = false;\n\t\tbool khr_barycentrics_enabled = false;\n\t\tbool arithmetic_relaxed_precision = false;\n\t\tbool force_wave_size_enable = false;\n\t\tbool supports_float16_denorm_preserve = false;\n\t\tbool supports_float64_denorm_preserve = false;\n\t\tbool strict_helper_lane_waveops = true;\n\t\tbool nv_subgroup_partition_enabled = false;\n\t\t// Assumed by default in earlier code, so avoid surprises if dxil-spirv\n\t\t// is updated on its own.\n\t\tbool compute_shader_derivatives = true;\n\t\tbool compute_shader_derivatives_khr = false;\n\t\tbool compute_shader_derivatives_quad = false;\n\t\tbool eliminate_dead_code = false;\n\t\tbool propagate_precise = false;\n\t\tbool force_precise = false;\n\t\tbool descriptor_heap_robustness = false;\n\t\tbool supports_quad_control = false;\n\t\tbool supports_maximal_reconvergence = false;\n\t\tbool force_maximal_reconvergence = false;\n\t\tbool nv_raw_access_chains = false;\n\t\tbool wmma_fp8 = false;\n\t\tbool nv_cooperative_matrix2_conversions = false;\n\t\tstruct\n\t\t{\n\t\t\tbool enabled = false;\n\t\t\tbool assume_uniform_scale = false;\n\t\t} grad_opt;\n\t\tbool opacity_micromap_enabled = false;\n\t\tunsigned physical_address_descriptor_stride = 1;\n\t\tunsigned physical_address_descriptor_offset = 0;\n\t\tunsigned force_subgroup_size = 0;\n\n\t\tstruct\n\t\t{\n\t\t\tbool use_shader_metadata = false;\n\t\t\tbool force_unroll = false;\n\t\t\tbool force_loop = false;\n\t\t\tbool force_flatten = false;\n\t\t\tbool force_branch = false;\n\t\t} branch_control;\n\n\t\tstruct\n\t\t{\n\t\t\tunsigned implementation_minimum = 4;\n\t\t\tunsigned implementation_maximum = 128;\n\t\t} subgroup_size;\n\n\t\tuint32_t driver_id = 0;\n\t\tuint32_t driver_version = 0;\n\n\t\tstruct\n\t\t{\n\t\t\tbool force_device_memory_barriers_thread_group_coherence = false;\n\t\t\tbool assume_broken_sub_8x8_cube_mips = false;\n\t\t\tbool robust_physical_cbv_forwarding = false;\n\t\t\tbool robust_physical_cbv = false;\n\t\t\tbool mesh_outputs_bounds_check = false;\n\t\t\tbool aggressive_nonuniform = false;\n\t\t\tbool promote_group_to_device_memory_barrier = false;\n\t\t\tbool group_shared_auto_barrier = false;\n\t\t\tbool fixup_loop_header_undef_phis = false;\n\t\t\tbool fixup_rsqrt = false;\n\t\t\tbool ignore_primitive_shading_rate = false;\n\t\t\tbool robust_compute_quad_broadcast = false;\n\t\t\tbool precise_fma = false;\n\t\t} quirks;\n\n\t\tstruct\n\t\t{\n\t\t\tbool group_shared = false;\n\t\t\tbool constant_lut = false;\n\t\t\tbool alloca = false;\n\t\t} extended_robustness;\n\n\t\tunsigned max_tess_factor = 0;\n\n\t\tstruct\n\t\t{\n\t\t\tbool enabled = false;\n\t\t\tunsigned register_index = 0;\n\t\t\tunsigned register_space = 0;\n\t\t} nvapi;\n\n\t\tbool extended_non_semantic_info = false;\n\t\tbool mixed_dot_product_fp16_fp16_fp32 = false;\n\n\t\tstruct\n\t\t{\n\t\t\tMetaDescriptorKind kind = MetaDescriptorKind::Invalid;\n\t\t\tuint32_t desc_set = UINT32_MAX;\n\t\t\tuint32_t desc_binding = UINT32_MAX;\n\t\t} meta_descriptor_mappings[int(MetaDescriptor::Count)];\n\n\t\tstruct\n\t\t{\n\t\t\t// If view instancing is enabled at all.\n\t\t\t// If not, ViewID will just return constant 0.\n\t\t\tbool enable = false;\n\n\t\t\t// If false and multiview is enabled, it only means we're interested in ViewID potentially ...\n\t\t\tbool last_pre_rasterization_stage = false;\n\n\t\t\t// One u32 spec constant mapping 16 ViewIndices back to ViewID.\n\t\t\t// If this is not set, it's implied we always the ViewID and layer offset from a constant.\n\t\t\t// If the shader exports Layer offset, this is ignored,\n\t\t\t// and we must fall back to draw level instancing.\n\t\t\tuint32_t view_index_to_view_instance_spec_id = UINT32_MAX;\n\n\t\t\t// If not UINT32_MAX, implies view instancing needs to apply a non-zero offset to output ViewportIndex.\n\t\t\tuint32_t view_instance_to_viewport_spec_id = UINT32_MAX;\n\t\t} multiview;\n\t} options;\n\n\tstruct\n\t{\n\t\tspv::Id view_index_to_view_instance_id = 0;\n\t\tspv::Id view_instance_to_viewport_id = 0;\n\t\tbool custom_layer_index = false;\n\t\tbool custom_viewport_index = false;\n\t} multiview;\n\n\tstruct BindlessInfo\n\t{\n\t\tDXIL::ResourceType type;\n\t\tDXIL::ComponentType component;\n\t\tRawVecSize raw_vecsize;\n\t\tDXIL::ResourceKind kind;\n\t\tspv::ImageFormat format;\n\t\tVulkanDescriptorType descriptor_type;\n\t\tbool uav_read;\n\t\tbool uav_written;\n\t\tbool uav_coherent;\n\t\tbool counters;\n\t\tbool offsets;\n\t\tbool aliased;\n\t\tbool relaxed_precision;\n\t\tuint32_t desc_set;\n\t\tuint32_t binding;\n\t\tstruct\n\t\t{\n\t\t\tuint32_t stride;\n\t\t} debug;\n\t};\n\n\tspv::Id create_bindless_heap_variable(const BindlessInfo &info);\n\tVector<RawDeclarationVariable> create_bindless_heap_variable_alias_group(\n\t\t\tconst BindlessInfo &base_info, const Vector<RawDeclaration> &raw_decls);\n\tVector<RawDeclarationVariable> create_raw_ssbo_variable_alias_group(\n\t\t\tconst Vector<RawDeclaration> &raw_decls,\n\t\t\tuint32_t range_size, const String &name);\n\tVector<RawDeclarationVariable> create_ubo_variable_alias_group(\n\t\t\tconst Vector<RawDeclaration> &raw_decls,\n\t\t\tuint32_t range_size, const String &name, unsigned cbv_size);\n\tspv::Id create_raw_ssbo_variable(const RawDeclaration &raw_decl, uint32_t range_size, const String &name);\n\tspv::Id create_ubo_variable(const RawDeclaration &raw_decl, uint32_t range_size, const String &name, unsigned cbv_size);\n\n\tstruct BindlessResource\n\t{\n\t\tBindlessInfo info;\n\t\tuint32_t var_id;\n\t};\n\tVector<BindlessResource> bindless_resources;\n\n\tstruct CombinedImageSampler\n\t{\n\t\tspv::Id image_id;\n\t\tspv::Id sampler_id;\n\t\tspv::Id combined_id;\n\t\tbool non_uniform;\n\t};\n\tVector<CombinedImageSampler> combined_image_sampler_cache;\n\n\tstruct PeepholeTransformation\n\t{\n\t\tspv::Id input_id;\n\t\tspv::Id result_id;\n\t\tuint64_t key; // Depends on the transform. Extend to something more sophisticated if needed.\n\t};\n\tVector<PeepholeTransformation> peephole_transformation_cache;\n\n\t// For quirk workarounds which need to check if a lane is active or not.\n\tstruct\n\t{\n\t\tspv::Id current_ballot_value_id;\n\t\tspv::Id current_subgroup_quad_index_id;\n\t\tspv::Id current_quad_lane_active_id[4];\n\t\tbool current_quad_uniform_checked;\n\t} memoized = {};\n\n\tstruct PhysicalPointerEntry\n\t{\n\t\tspv::Id ptr_type_id;\n\t\tspv::Id base_type_id;\n\t\tPhysicalPointerMeta meta;\n\t};\n\tVector<PhysicalPointerEntry> physical_pointer_entries;\n\tspv::Id get_physical_pointer_block_type(spv::Id base_type_id, const PhysicalPointerMeta &meta);\n\n\tDXIL::ComponentType get_effective_input_output_type(DXIL::ComponentType type);\n\tstatic DXIL::ComponentType get_effective_typed_resource_type(DXIL::ComponentType type);\n\tspv::Id get_effective_input_output_type_id(DXIL::ComponentType type);\n\tbool get_uav_image_format(DXIL::ResourceKind resource_kind,\n\t                          DXIL::ComponentType actual_component_type,\n\t                          const AccessTracking &access_meta,\n\t                          spv::ImageFormat &format);\n\n\tuint32_t find_binding_meta_index(uint32_t binding_range_lo, uint32_t binding_range_hi,\n\t                                 uint32_t binding_space, DXIL::ResourceType resource_type);\n\n\tstruct RawBufferMeta\n\t{\n\t\tDXIL::ResourceKind kind;\n\t\tunsigned stride;\n\t};\n\tRawBufferMeta get_raw_buffer_meta(DXIL::ResourceType resource_type, unsigned meta_index);\n\n\tstatic void get_shader_model(const llvm::Module &module, String *model, uint32_t *major, uint32_t *minor);\n\n\tstruct AliasedAccess\n\t{\n\t\tVector<RawDeclaration> raw_declarations;\n\t\tbool requires_alias_decoration = false;\n\t\tbool override_primary_component_types = false;\n\t\tDXIL::ComponentType primary_component_type = DXIL::ComponentType::Invalid;\n\t\tRawVecSize primary_raw_vecsize = RawVecSize::V1;\n\t};\n\tbool analyze_aliased_access(const AccessTracking &tracking,\n\t                            VulkanDescriptorType descriptor_type,\n\t                            AliasedAccess &aliased_access) const;\n\n\tstruct\n\t{\n\t\t// Only relevant for fragment shaders, and some other misc uses.\n\t\tbool has_side_effects = false;\n\t\tbool discards = false;\n\t\tbool can_require_primitive_culling = false;\n\t\tbool require_compute_shader_derivatives = false;\n\t\tbool precise_f16_to_f32_observed = false;\n\t\tbool require_uav_thread_group_coherence = false;\n\t\tbool require_node_output_group_coherence = false;\n\t\tbool require_node_input_group_coherence = false;\n\t\tbool require_subgroups = false;\n\t\tbool require_subgroup_shuffles = false;\n\t\tbool subgroup_ballot_reads_upper = false;\n\t\tbool subgroup_ballot_reads_first = false;\n\t\tbool can_require_opacity_micromap = false;\n\t\tbool need_maximal_reconvergence_helper_call = false;\n\t\tbool has_group_shared_barrier = false;\n\t\tbool has_group_shared_access = false;\n\t\tbool needs_auto_group_shared_barriers = false;\n\t\tbool require_wmma = false;\n\t\t// Should just do this always, but don't want to nuke FOZ caches needlessly.\n\t\tbool global_undefs = false;\n\n\t\tstruct\n\t\t{\n\t\t\tbool uses_non_direct_indexing = false;\n\n\t\t\t// If every instance of ray query uses the same handle IDs,\n\t\t\t// we can conveniently ignore any weird Phis, etc.\n\t\t\t// This might get somewhat spicy when considering loops,\n\t\t\t// but if the loop always starts with a resetting TraceInlineRay,\n\t\t\t// there cannot be cases where multiple instances of the loop body\n\t\t\t// refers to different objects each time.\n\t\t\tconst llvm::Value *reference_handle_value = nullptr;\n\t\t\tbool uses_divergent_handles = false;\n\n\t\t\t// If we need to treat ray query objects as pure index into global table.\n\t\t\tuint32_t num_ray_query_alloca = 0;\n\n\t\t\tstruct Mapping\n\t\t\t{\n\t\t\t\tconst llvm::AllocaInst *alloca;\n\t\t\t\tuint32_t ray_query_flags;\n\t\t\t};\n\t\t\tVector<Mapping> alloca_mappings;\n\t\t} ray_query;\n\t} shader_analysis;\n\n\tstruct\n\t{\n\t\tbool skip_non_uniform_promotion = false;\n\t} backend;\n\n\t// For descriptor QA, we need to rewrite how resource handles are emitted.\n\tUnorderedMap<const llvm::CallInst *, const llvm::BasicBlock *> resource_handle_to_block;\n\tUnorderedSet<const llvm::CallInst *> resource_handles_needing_sink;\n\tUnorderedSet<const llvm::CallInst *> resource_handle_is_conservative;\n\tUnorderedMap<const llvm::BasicBlock *, Vector<const llvm::Instruction *>> bb_to_sinks;\n\tUnorderedSet<const llvm::CallInst *> wave_op_forced_helper_lanes;\n\n\tUnorderedSet<const llvm::Value *> llvm_used_ssa_values;\n\tUnorderedMap<const llvm::AllocaInst *, AllocaCBVForwardingTracking> alloca_tracking;\n\tUnorderedSet<const llvm::GetElementPtrInst *> masked_alloca_forward_gep;\n\n\tstruct\n\t{\n\t\tspv::Id global_query_objects_id = 0;\n\t\tuint32_t ray_query_index = 0;\n\t} ray_query;\n\n\tbool emit_ray_query_globals();\n\n\tstruct RootParameterMapping\n\t{\n\t\tuint32_t root_parameter_index;\n\t\tuint32_t offset;\n\t};\n\tVector<RootParameterMapping> root_parameter_mappings;\n\tVector<NonSemanticDebugInfo> non_semantic_debug_info;\n\tvoid emit_non_semantic_debug_info(const NonSemanticDebugInfo &info);\n\n\tbool type_can_relax_precision(const llvm::Type *type, bool known_integer_sign) const;\n\tvoid decorate_relaxed_precision(const llvm::Type *type, spv::Id id, bool known_integer_sign);\n\n\tvoid suggest_minimum_wave_size(unsigned wave_size);\n\tvoid suggest_maximum_wave_size(unsigned wave_size);\n\n\tstatic NodeInputData get_node_input(llvm::MDNode *meta);\n\tstatic NodeOutputData get_node_output(llvm::MDNode *meta);\n};\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_ags.cpp",
    "content": "/* Copyright (c) 2019-2025 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"opcodes/opcodes.hpp\"\n#include \"dxil_ags.hpp\"\n#include \"spirv_module.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"dxil_common.hpp\"\n#include \"dxil_sampling.hpp\"\n#include \"dxil_buffer.hpp\"\n#include \"logging.hpp\"\n#include <limits>\n\nnamespace dxil_spv\n{\nstatic bool emit_magic_ags_atomic_u64(Converter::Impl &impl, spv::Id image_id,\n                                      spv::Op atomic_opcode, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilityInt64Atomics);\n\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tspv::Id coords[3] = {};\n\tuint32_t num_coords_full = 0, num_coords = 0;\n\n\tif (meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t\tLOGE(\"RWStructuredBuffer not supported for AGS u64 atomics.\\n\");\n\telse if (meta.kind == DXIL::ResourceKind::TypedBuffer)\n\t\tLOGE(\"RWBuffer not supported for AGS u64 atomics.\\n\");\n\n\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t{\n\t\t// AGS header only supports BAB.\n\t\tcoords[0] = build_index_divider(impl, impl.ags.backdoor_instructions[0]->getOperand(5), 3, 1);\n\t\tnum_coords = 1;\n\t\tnum_coords_full = 1;\n\t}\n\telse\n\t{\n\t\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\t\treturn false;\n\n\t\tif (num_coords_full > 3)\n\t\t\treturn false;\n\n\t\t// The actual coordinates are stored in the backdoor instructions.\n\t\tfor (uint32_t i = 0; i < num_coords_full; i++)\n\t\t{\n\t\t\tauto *coord_value = impl.ags.backdoor_instructions[i / 2]->getOperand(5 + (i & 1));\n\t\t\tcoords[i] = impl.get_id_for_value(coord_value);\n\t\t}\n\t}\n\n\tspv::Id coord = impl.build_vector(builder.makeUintType(32), coords, num_coords_full);\n\n\tDXIL::ComponentType component_type;\n\tspv::Id counter_ptr_id = emit_atomic_access_chain(impl, meta, RawWidth::B64, image_id, coord, component_type);\n\n\tspv::Id u32s[2];\n\tu32s[0] = impl.get_id_for_value(impl.ags.backdoor_instructions[1]->getOperand(6));\n\tu32s[1] = impl.get_id_for_value(impl.ags.backdoor_instructions[2]->getOperand(5));\n\tspv::Id u32_vec = impl.build_vector(builder.makeUintType(32), u32s, 2);\n\n\tauto *bitcast_op = impl.allocate(spv::OpBitcast, impl.get_type_id(DXIL::ComponentType::U64, 1, 1));\n\tbitcast_op->add_id(u32_vec);\n\timpl.add(bitcast_op);\n\n\tauto *atomic_op = impl.allocate(atomic_opcode, impl.get_type_id(DXIL::ComponentType::U64, 1, 1));\n\n\tatomic_op->add_id(counter_ptr_id);\n\tatomic_op->add_id(builder.getAtomicDeviceScopeId());\n\tatomic_op->add_id(builder.makeUintConstant(0));\n\tatomic_op->add_id(bitcast_op->id);\n\timpl.add(atomic_op);\n\n\tbitcast_op = impl.allocate(spv::OpBitcast, impl.get_type_id(DXIL::ComponentType::U32, 1, 2));\n\tbitcast_op->add_id(atomic_op->id);\n\timpl.add(bitcast_op);\n\n\tfor (unsigned i = 0; i < 2; i++)\n\t{\n\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, impl.get_type_id(DXIL::ComponentType::U32, 1, 1));\n\t\textract_op->add_id(bitcast_op->id);\n\t\textract_op->add_literal(i);\n\t\timpl.add(extract_op);\n\t\tu32s[i] = extract_op->id;\n\t}\n\n\t// The backdoor instructions end up with the final result.\n\timpl.rewrite_value(impl.ags.backdoor_instructions[0], u32s[0]);\n\timpl.rewrite_value(impl.ags.backdoor_instructions[2], u32s[1]);\n\timpl.rewrite_value(instruction, u32s[1]);\n\treturn true;\n}\n\nstatic spv::Id make_fp8_type(Converter::Impl &impl, bool load_store)\n{\n\tif (impl.options.wmma_fp8)\n\t\treturn impl.builder().makeFloatType(8, spv::FPEncodingFloat8E4M3EXT);\n\telse if (load_store)\n\t\treturn impl.builder().makeUintType(8);\n\telse\n\t\treturn impl.builder().makeFloatType(16);\n}\n\nstatic inline uint32_t get_type_data_format(uint32_t imm)\n{\n\treturn (imm >> AmdExtD3DShaderIntrinsicsWaveMatrixModifier_DataFormatFlagShift) &\n\t       AmdExtD3DShaderIntrinsicsWaveMatrixModifier_DataFormatFlagMask;\n}\n\nstatic inline uint32_t get_matrix_type(uint32_t imm)\n{\n\treturn (imm >> AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagShift) &\n\t       AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagMask;\n}\n\nstatic inline uint32_t get_matrix_shape(uint32_t imm)\n{\n\treturn (imm >> AmdExtD3DShaderIntrinsicsWaveMatrixModifier_ShapeShift) &\n\t       AmdExtD3DShaderIntrinsicsWaveMatrixModifier_ShapeMask;\n}\n\nstatic bool validate_convert_compatibility(uint32_t imm_a, uint32_t imm_b)\n{\n\t// AGS opcodes allow conversion between types + transpositions.\n\t// Horrifying :(\n\tuint32_t shape_a = get_matrix_shape(imm_a);\n\tuint32_t shape_b = get_matrix_shape(imm_b);\n\treturn shape_a == shape_b;\n}\n\nstatic spv::CooperativeMatrixUse convert_matrix_use(uint32_t use)\n{\n\tswitch (use)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixType_A:\n\t\treturn spv::CooperativeMatrixUseMatrixAKHR;\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixType_B:\n\t\treturn spv::CooperativeMatrixUseMatrixBKHR;\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixType_Accumulator:\n\t\treturn spv::CooperativeMatrixUseMatrixAccumulatorKHR;\n\tdefault:\n\t\treturn spv::CooperativeMatrixUseMax;\n\t}\n}\n\nstatic spv::Id build_coopmat_type(Converter::Impl &impl, uint32_t immediate, bool load_store)\n{\n\tauto &builder = impl.builder();\n\n\tuint32_t fmt = get_type_data_format(immediate);\n\tuint32_t type = get_matrix_type(immediate);\n\tuint32_t shape = get_matrix_shape(immediate);\n\n\tif (shape != AmdExtD3DShaderIntrinsicsWaveMatrixShape_16X16)\n\t\treturn 0;\n\n\tspv::Id use;\n\tspv::Id scalar_type;\n\tauto spv_use = convert_matrix_use(type);\n\n\tswitch (fmt)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\tif (spv_use != spv::CooperativeMatrixUseMatrixAccumulatorKHR)\n\t\t\treturn 0;\n\t\tscalar_type = builder.makeFloatType(32);\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\tscalar_type = builder.makeFloatType(16);\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\tscalar_type = make_fp8_type(impl, load_store);\n\t\tbreak;\n\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tuse = builder.makeUintConstant(spv_use);\n\tspv::Id rows_cols = builder.makeUintConstant(16);\n\treturn builder.makeCooperativeMatrixType(scalar_type, rows_cols, rows_cols, use);\n}\n\nstatic inline uint32_t get_matrix_io_channel(uint32_t imm)\n{\n\treturn (imm >> AmdExtD3DShaderIntrinsicsWaveMatrixInOut_ChannelShift) &\n\t       AmdExtD3DShaderIntrinsicsWaveMatrixInOut_ChannelMask;\n}\n\nstatic inline uint32_t get_matrix_io_register(uint32_t imm)\n{\n\treturn (imm >> AmdExtD3DShaderIntrinsicsWaveMatrixInOut_SecondRegFlagShift) &\n\t       AmdExtD3DShaderIntrinsicsWaveMatrixInOut_SecondRegFlagMask;\n}\n\nstatic inline uint32_t get_matrix_io_type(uint32_t imm)\n{\n\treturn (imm >> AmdExtD3DShaderIntrinsicsWaveMatrixInOut_MatRegTypeFlagShift) &\n\t       AmdExtD3DShaderIntrinsicsWaveMatrixInOut_MatRegTypeFlagMask;\n}\n\nstatic bool validate_wmma_io_registers(Converter::Impl &impl, uint32_t base_argument,\n                                       AmdExtD3DShaderIntrinsicsWaveMatrixRegType reg_type,\n                                       uint32_t phase, bool input_validation)\n{\n\tif (reg_type == AmdExtD3DShaderIntrinsicsWaveMatrixRegType_RetVal_Reg && !input_validation)\n\t{\n\t\t// 8 outputs\n\t\tfor (uint32_t i = 0; i < 8; i++)\n\t\t{\n\t\t\tuint32_t inst_index = base_argument + i;\n\t\t\tuint32_t imm = impl.ags.instructions[inst_index].immediate;\n\t\t\tuint32_t channel = get_matrix_io_channel(imm);\n\t\t\tuint32_t reg = get_matrix_io_register(imm);\n\t\t\tuint32_t type = get_matrix_io_type(imm);\n\n\t\t\tif (impl.ags.instructions[inst_index].phase != phase)\n\t\t\t\treturn false;\n\n\t\t\t// Check for unexpected cases.\n\t\t\tif ((imm >> AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTileShift) != 0)\n\t\t\t\treturn false;\n\t\t\tif (type != reg_type)\n\t\t\t\treturn false;\n\t\t\tif (channel != i % 4 || reg != i / 4)\n\t\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tspv::Id coopmat_id = impl.get_id_for_value(impl.ags.backdoor_instructions[base_argument]->getOperand(5));\n\n\t\t// If the matrix is PHI or loaded from alloca, we only check component mapping.\n\t\tbool all_phi_or_load = true;\n\t\tfor (uint32_t i = 0; i < 4 && all_phi_or_load; i++)\n\t\t{\n\t\t\tuint32_t inst_index = base_argument + i;\n\t\t\tconst auto *value0 = impl.ags.backdoor_instructions[inst_index]->getOperand(5);\n\t\t\tconst auto *value1 = impl.ags.backdoor_instructions[inst_index]->getOperand(6);\n\t\t\tall_phi_or_load =\n\t\t\t\t(llvm::isa<llvm::PHINode>(value0) || llvm::isa<llvm::LoadInst>(value0)) &&\n\t\t\t\t(llvm::isa<llvm::PHINode>(value1) || llvm::isa<llvm::LoadInst>(value1));\n\t\t}\n\n\t\t// 4x2 inputs.\n\t\tfor (uint32_t i = 0; i < 4; i++)\n\t\t{\n\t\t\tuint32_t inst_index = base_argument + i;\n\t\t\tconst auto *value0 = impl.ags.backdoor_instructions[inst_index]->getOperand(5);\n\t\t\tconst auto *value1 = impl.ags.backdoor_instructions[inst_index]->getOperand(6);\n\t\t\tauto itr0 = impl.ags.coopmat_component_mapping.find(value0);\n\t\t\tauto itr1 = impl.ags.coopmat_component_mapping.find(value1);\n\n\t\t\tif (impl.ags.instructions[inst_index].phase != phase)\n\t\t\t\treturn false;\n\n\t\t\t// Don't accept any weird shuffle.\n\t\t\tif (itr0 == impl.ags.coopmat_component_mapping.end() || itr0->second.component != 2 * i + 0 ||\n\t\t\t    (!all_phi_or_load && impl.get_id_for_value(value0) != coopmat_id))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (itr1 == impl.ags.coopmat_component_mapping.end() || itr1->second.component != 2 * i + 1 ||\n\t\t\t    (!all_phi_or_load && impl.get_id_for_value(value1) != coopmat_id))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tuint32_t imm = impl.ags.instructions[inst_index].immediate;\n\n\t\t\tuint32_t channel = get_matrix_io_channel(imm);\n\t\t\tuint32_t reg = get_matrix_io_register(imm);\n\t\t\tuint32_t type = get_matrix_io_type(imm);\n\n\t\t\t// Check for unexpected cases.\n\t\t\tif ((imm >> AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTileShift) != 0)\n\t\t\t\treturn false;\n\t\t\tif (type != reg_type)\n\t\t\t\treturn false;\n\t\t\tif (channel != i % 2 || reg != i / 2)\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nstatic bool emit_wmma_return_values(Converter::Impl &impl, spv::Id type_id, spv::Id id, uint32_t phase)\n{\n\tif (!validate_wmma_io_registers(impl, impl.ags.num_instructions - 8,\n\t                                AmdExtD3DShaderIntrinsicsWaveMatrixRegType_RetVal_Reg,\n\t                                phase, false))\n\t{\n\t\treturn false;\n\t}\n\n\t// Validate output register assignment.\n\tfor (uint32_t i = 0; i < 8; i++)\n\t{\n\t\tuint32_t inst_index = impl.ags.num_instructions - 8 + i;\n\t\tauto *inst = impl.ags.backdoor_instructions[inst_index];\n\t\tif (id)\n\t\t\timpl.rewrite_value(inst, id);\n\t\timpl.ags.coopmat_component_mapping[inst] = { type_id, i };\n\t}\n\n\treturn true;\n}\n\nstatic spv::Id emit_coopmat_transfer(Converter::Impl &impl, spv::Id v, uint32_t input_imm, uint32_t output_imm)\n{\n\tspv::Id input_type = build_coopmat_type(impl, input_imm, false);\n\tspv::Id output_type = build_coopmat_type(impl, output_imm, false);\n\n\tspv::Id aux_types[3] = { input_type, output_type };\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::CoopMatTransfer, aux_types, 2);\n\n\t// RADV workaround. Should pass as value, but NIR aborts.\n\tspv::Id param = impl.create_variable(spv::StorageClassFunction, input_type);\n\tauto *store = impl.allocate(spv::OpStore);\n\tstore->add_id(param);\n\tstore->add_id(v);\n\timpl.add(store);\n\n\tauto *call = impl.allocate(spv::OpFunctionCall, output_type);\n\tcall->add_id(call_id);\n\tcall->add_id(param);\n\timpl.add(call);\n\n\treturn call->id;\n}\n\nstatic spv::Id emit_coopmat_broken_saturation_fixup(Converter::Impl &impl, spv::Id v, spv::Id type_id)\n{\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::CoopMatSaturationFixup, type_id);\n\n\t// RADV workaround. Should pass as value, but NIR aborts.\n\tspv::Id param = impl.create_variable(spv::StorageClassFunction, type_id);\n\tauto *store = impl.allocate(spv::OpStore);\n\tstore->add_id(param);\n\tstore->add_id(v);\n\timpl.add(store);\n\n\tauto *call = impl.allocate(spv::OpFunctionCall, type_id);\n\tcall->add_id(call_id);\n\tcall->add_id(param);\n\timpl.add(call);\n\n\treturn call->id;\n}\n\nstatic spv::Id emit_coopmat_saturate_fp8(Converter::Impl &impl, spv::Id v, spv::Id type_id)\n{\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::CoopMatSaturateFP8, type_id);\n\n\t// RADV workaround. Should pass as value, but NIR aborts.\n\tspv::Id param = impl.create_variable(spv::StorageClassFunction, type_id);\n\tauto *store = impl.allocate(spv::OpStore);\n\tstore->add_id(param);\n\tstore->add_id(v);\n\timpl.add(store);\n\n\tauto *call = impl.allocate(spv::OpFunctionCall, type_id);\n\tcall->add_id(call_id);\n\tcall->add_id(param);\n\timpl.add(call);\n\n\treturn call->id;\n}\n\nstatic spv::Id emit_coopmat_transpose_with_convert(\n    Converter::Impl &impl, spv::Id v, uint32_t input_imm, uint32_t output_imm, bool saturating)\n{\n\tauto &builder = impl.builder();\n\n\tbool can_convert_use;\n\tif (GlobalConfiguration::get().wmma_conv_hack || GlobalConfiguration::get().wmma_rdna3_workaround)\n\t{\n\t\t// Go out of spec if we explicitly enable that.\n\t\tcan_convert_use = get_matrix_type(input_imm) != get_matrix_type(output_imm);\n\t}\n\telse\n\t{\n\t\tcan_convert_use = get_matrix_type(input_imm) == AmdExtD3DShaderIntrinsicsWaveMatrixType_Accumulator &&\n\t\t                  get_matrix_type(output_imm) != AmdExtD3DShaderIntrinsicsWaveMatrixType_Accumulator;\n\t}\n\n\tif (impl.options.nv_cooperative_matrix2_conversions && can_convert_use)\n\t{\n\t\t// We can only go from accumulator to non-accumulator in this path.\n\t\t// NV extension allows us to convert between matrix types without extra fuzz.\n\t\t// However, it \"just werks\" on RADV for now (with wmma_conv_hack enabled),\n\t\t// so skirt around the issue.\n\t\tspv::Op opcode;\n\n\t\tauto effective_input_fmt = get_type_data_format(input_imm);\n\t\tauto effective_output_fmt = get_type_data_format(output_imm);\n\n\t\t// On RDNA3, it's better to do any per-element operation in C matrix rather than A or B.\n\t\tif (!impl.options.wmma_fp8 &&\n\t\t    effective_output_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8 &&\n\t\t    effective_input_fmt != AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8 && saturating &&\n\t\t    get_matrix_type(input_imm) == AmdExtD3DShaderIntrinsicsWaveMatrixType_Accumulator &&\n\t\t    get_matrix_type(output_imm) != AmdExtD3DShaderIntrinsicsWaveMatrixType_Accumulator)\n\t\t{\n\t\t\tuint32_t output_accum_imm = output_imm;\n\t\t\toutput_accum_imm &= ~(\n\t\t\t\tAmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagMask <<\n\t\t\t\tAmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagShift);\n\t\t\toutput_accum_imm |= AmdExtD3DShaderIntrinsicsWaveMatrixType_Accumulator <<\n\t\t\t                    AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagShift;\n\n\t\t\tauto *conv = impl.allocate(spv::OpFConvert, build_coopmat_type(impl, output_accum_imm, false));\n\t\t\tconv->add_id(v);\n\t\t\timpl.add(conv);\n\n\t\t\tv = emit_coopmat_saturate_fp8(impl, conv->id, build_coopmat_type(impl, output_accum_imm, false));\n\n\t\t\teffective_input_fmt = effective_output_fmt;\n\t\t\tsaturating = false;\n\t\t}\n\n\t\tif (!impl.options.wmma_fp8)\n\t\t{\n\t\t\tif (effective_input_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\t\t\teffective_input_fmt = AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16;\n\t\t\tif (effective_output_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\t\t\teffective_output_fmt = AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16;\n\t\t}\n\n\t\tif (effective_input_fmt != effective_output_fmt)\n\t\t{\n\t\t\tswitch (effective_input_fmt)\n\t\t\t{\n\t\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// FSR4 only needs FP, don't care about all possible combinations yet.\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tswitch (effective_output_fmt)\n\t\t\t{\n\t\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// FSR4 only needs FP, don't care about all possible combinations yet.\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\topcode = spv::OpFConvert;\n\t\t}\n\t\telse\n\t\t{\n\t\t\topcode = spv::OpCooperativeMatrixConvertNV;\n\t\t}\n\n\t\tbuilder.addExtension(\"SPV_NV_cooperative_matrix2\");\n\t\tbuilder.addCapability(spv::CapabilityCooperativeMatrixConversionsNV);\n\n\t\tauto *conv = impl.allocate(opcode, build_coopmat_type(impl, output_imm, false));\n\t\tconv->add_id(v);\n\t\timpl.add(conv);\n\n\t\tspv::Id id = conv->id;\n\n\t\tif (saturating)\n\t\t{\n\t\t\tif (impl.options.wmma_fp8 && opcode == spv::OpFConvert &&\n\t\t\t    get_type_data_format(output_imm) == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\t\t{\n\t\t\t\timpl.builder().addDecoration(id, spv::DecorationSaturatedToLargestFloat8NormalConversionEXT);\n\t\t\t}\n\t\t\telse if (get_type_data_format(output_imm) == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8 &&\n\t\t\t         get_type_data_format(input_imm) != AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8 &&\n\t\t\t         !impl.options.wmma_fp8)\n\t\t\t{\n\t\t\t\tid = emit_coopmat_saturate_fp8(impl, id, build_coopmat_type(impl, output_imm, false));\n\t\t\t}\n\t\t}\n\n\t\treturn id;\n\t}\n\n\treturn 0;\n}\n\nstatic spv::Id emit_coopmat_transpose(Converter::Impl &impl, spv::Id v, uint32_t input_imm, uint32_t output_imm)\n{\n\tauto &builder = impl.builder();\n\n\tif (impl.options.wmma_fp8)\n\t{\n\t\tif (get_matrix_type(input_imm) != AmdExtD3DShaderIntrinsicsWaveMatrixType_A &&\n\t\t    get_matrix_type(output_imm) != AmdExtD3DShaderIntrinsicsWaveMatrixType_A &&\n\t\t    get_type_data_format(input_imm) == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\t{\n\t\t\t// It appears that in the cases we care about, layout of B and C are the same.\n\t\t\t// Just do element-wise copy here to avoid the bad roundtrip.\n\t\t\t// This assumption only seems to hold for FP8, but that's the only case we care about.\n\t\t\treturn emit_coopmat_transfer(impl, v, input_imm, output_imm);\n\t\t}\n\t}\n\n\tif (!impl.ags.coopmat_transpose_scratch)\n\t{\n\t\tspv::Id lds_type_id = builder.makeUintType(32);\n\t\tuint32_t num_elements = 16 * 16;\n\n\t\t// Assume that the workgroup is aligned.\n\t\tuint32_t max_num_workgroups = impl.execution_mode_meta.workgroup_threads[0] *\n\t\t                              impl.execution_mode_meta.workgroup_threads[1] *\n\t\t                              impl.execution_mode_meta.workgroup_threads[2];\n\n\t\tif (impl.execution_mode_meta.wave_size_min)\n\t\t\tmax_num_workgroups /= impl.execution_mode_meta.wave_size_min;\n\t\telse if (impl.options.subgroup_size.implementation_minimum)\n\t\t\tmax_num_workgroups /= impl.options.subgroup_size.implementation_minimum;\n\t\telse\n\t\t{\n\t\t\tLOGE(\"Need LDS transpose, but there is no estimate for how large the LDS buffer needs to be.\\n\");\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (!max_num_workgroups)\n\t\t{\n\t\t\tLOGE(\"Invalid workgroup size.\\n\");\n\t\t\treturn 0;\n\t\t}\n\n\t\tnum_elements *= max_num_workgroups;\n\n\t\tlds_type_id = builder.makeArrayType(lds_type_id, builder.makeUintConstant(num_elements), 0);\n\t\timpl.ags.coopmat_transpose_scratch =\n\t\t    impl.create_variable(spv::StorageClassWorkgroup, lds_type_id, \"LDSTransposeScratch\");\n\t}\n\n\tif (get_type_data_format(input_imm) != get_type_data_format(output_imm))\n\t\treturn 0;\n\tif (get_type_data_format(input_imm) == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32)\n\t\treturn 0;\n\n\tspv::Id subgroup_id_var = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSubgroupId);\n\tauto *subgroup_id = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\tsubgroup_id->add_id(subgroup_id_var);\n\timpl.add(subgroup_id);\n\n\tauto *index = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\tindex->add_id(subgroup_id->id);\n\tindex->add_id(builder.makeUintConstant(16 * 16));\n\timpl.add(index);\n\n\tauto *chain = impl.allocate(spv::OpInBoundsAccessChain,\n\t                            builder.makePointer(spv::StorageClassWorkgroup, builder.makeUintType(32)));\n\tchain->add_id(impl.ags.coopmat_transpose_scratch);\n\tchain->add_id(index->id);\n\timpl.add(chain);\n\n\tauto *barrier = impl.allocate(spv::OpControlBarrier);\n\tbarrier->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbarrier->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbarrier->add_id(builder.getWorkgroupBarrierSemanticsId());\n\timpl.add(barrier);\n\n\tauto *store = impl.allocate(spv::OpCooperativeMatrixStoreKHR);\n\tstore->add_id(chain->id);\n\tstore->add_id(v);\n\tstore->add_id(builder.makeUintConstant(spv::CooperativeMatrixLayoutColumnMajorKHR));\n\tstore->add_id(builder.makeUintConstant(16));\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan)\n\t\tstore->add_literal(spv::MemoryAccessNonPrivatePointerMask);\n\n\timpl.add(store);\n\n\tbarrier = impl.allocate(spv::OpControlBarrier);\n\tbarrier->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbarrier->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbarrier->add_id(builder.getWorkgroupBarrierSemanticsId());\n\timpl.add(barrier);\n\n\tspv::Id output_type = build_coopmat_type(impl, output_imm, false);\n\tif (!output_type)\n\t\treturn 0;\n\n\tauto *load = impl.allocate(spv::OpCooperativeMatrixLoadKHR, output_type);\n\tload->add_id(chain->id);\n\tload->add_id(builder.makeUintConstant(spv::CooperativeMatrixLayoutColumnMajorKHR));\n\tload->add_id(builder.makeUintConstant(16));\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan)\n\t\tload->add_literal(spv::MemoryAccessNonPrivatePointerMask);\n\timpl.add(load);\n\n\treturn load->id;\n}\n\nstatic spv::Id emit_fp8_to_fp16_coopmat(Converter::Impl &impl, spv::Id v, spv::CooperativeMatrixUse use)\n{\n\tauto &builder = impl.builder();\n\tspv::Id rows_cols = builder.makeUintConstant(16);\n\tspv::Id u8_type = builder.makeCooperativeMatrixType(\n\t\tbuilder.makeUintType(8), rows_cols, rows_cols, builder.makeUintConstant(use));\n\tspv::Id f16_type = builder.makeCooperativeMatrixType(\n\t\tbuilder.makeFloatType(16), rows_cols, rows_cols, builder.makeUintConstant(use));\n\n\tspv::Id aux_types[2] = { u8_type, f16_type };\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::CoopMatFP8toFP16, aux_types, 2);\n\n\t// RADV workaround. Should pass as value, but NIR aborts.\n\tspv::Id param = impl.create_variable(spv::StorageClassFunction, u8_type);\n\tauto *store = impl.allocate(spv::OpStore);\n\tstore->add_id(param);\n\tstore->add_id(v);\n\timpl.add(store);\n\n\tauto *call = impl.allocate(spv::OpFunctionCall, f16_type);\n\tcall->add_id(call_id);\n\tcall->add_id(param);\n\timpl.add(call);\n\n\treturn call->id;\n}\n\nstatic spv::Id emit_fp16_to_fp8_coopmat(Converter::Impl &impl, spv::Id v, spv::CooperativeMatrixUse use)\n{\n\tauto &builder = impl.builder();\n\tspv::Id rows_cols = builder.makeUintConstant(16);\n\tspv::Id u8_type = builder.makeCooperativeMatrixType(\n\t    builder.makeUintType(8), rows_cols, rows_cols, builder.makeUintConstant(use));\n\tspv::Id f16_type = builder.makeCooperativeMatrixType(\n\t    builder.makeFloatType(16), rows_cols, rows_cols, builder.makeUintConstant(use));\n\n\tspv::Id aux_types[2] = { u8_type, f16_type };\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::CoopMatFP16toFP8, aux_types, 2);\n\n\t// RADV workaround. Should pass as value, but NIR aborts.\n\tspv::Id param = impl.create_variable(spv::StorageClassFunction, f16_type);\n\tauto *store = impl.allocate(spv::OpStore);\n\tstore->add_id(param);\n\tstore->add_id(v);\n\timpl.add(store);\n\n\tauto *call = impl.allocate(spv::OpFunctionCall, u8_type);\n\tcall->add_id(call_id);\n\tcall->add_id(param);\n\timpl.add(call);\n\n\treturn call->id;\n}\n\nstatic bool emit_wmma_length(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tuint32_t type_imm = impl.ags.instructions[0].immediate;\n\tuint32_t fmt = get_type_data_format(type_imm);\n\n\tspv::Id type_id = build_coopmat_type(impl, type_imm, false);\n\tif (type_id == 0)\n\t\treturn false;\n\n\tspv::Id id = 0;\n\n\tauto *len = impl.allocate(spv::OpCooperativeMatrixLengthKHR, builder.makeUintType(32));\n\tlen->add_id(type_id);\n\timpl.add(len);\n\tid = len->id;\n\n\tif (fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t{\n\t\t// FP8 is tightly packed.\n\t\tauto *div = impl.allocate(spv::OpUDiv, builder.makeUintType(32));\n\t\tdiv->add_id(id);\n\t\tdiv->add_id(builder.makeUintConstant(4));\n\t\timpl.add(div);\n\t\tid = div->id;\n\t}\n\n\timpl.rewrite_value(impl.ags.backdoor_instructions[0], id);\n\treturn true;\n}\n\nstatic spv::Id build_packed_fp8_to_fp16_vec4(Converter::Impl &impl, spv::Id packed_id)\n{\n\tauto &builder = impl.builder();\n\tspv::Id u8_type = builder.makeUintType(8);\n\tspv::Id u8vec4_type = builder.makeVectorType(u8_type, 4);\n\tspv::Id i16_type = builder.makeIntType(16);\n\tspv::Id i16vec4_type = builder.makeVectorType(i16_type, 4);\n\tspv::Id f16_type = builder.makeFloatType(16);\n\tspv::Id f16vec4_type = builder.makeVectorType(f16_type, 4);\n\n\tauto *cast = impl.allocate(spv::OpBitcast, u8vec4_type);\n\tcast->add_id(packed_id);\n\timpl.add(cast);\n\n\tauto *sext = impl.allocate(spv::OpSConvert, i16vec4_type);\n\tsext->add_id(cast->id);\n\timpl.add(sext);\n\n\tauto *shift = impl.allocate(spv::OpShiftLeftLogical, i16vec4_type);\n\tshift->add_id(sext->id);\n\tshift->add_id(impl.build_splat_constant_vector(i16_type, builder.makeInt16Constant(7), 4));\n\timpl.add(shift);\n\n\tauto *mask = impl.allocate(spv::OpBitwiseAnd, i16vec4_type);\n\tmask->add_id(shift->id);\n\tmask->add_id(impl.build_splat_constant_vector(i16_type, builder.makeInt16Constant(int16_t(0xffff ^ 0x4000)), 4));\n\timpl.add(mask);\n\n\tauto *bitcast = impl.allocate(spv::OpBitcast, f16vec4_type);\n\tbitcast->add_id(mask->id);\n\timpl.add(bitcast);\n\n\t// Need post-scale to correctly deal with denorms.\n\tauto *mul = impl.allocate(spv::OpVectorTimesScalar, f16vec4_type);\n\tmul->add_id(bitcast->id);\n\tmul->add_id(builder.makeFloat16Constant(0x5c00 /* 256.0 */));\n\timpl.add(mul);\n\n\treturn mul->id;\n}\n\nstatic bool emit_wmma_element_insert(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tif (!validate_wmma_io_registers(impl, 0, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_RetVal_Reg, 0, true))\n\t\treturn false;\n\n\tuint32_t type_imm = impl.ags.instructions[4].immediate;\n\tuint32_t fmt = get_type_data_format(type_imm);\n\tspv::Id coop_type = build_coopmat_type(impl, type_imm, false);\n\tif (!coop_type)\n\t\treturn false;\n\n\tconst llvm::Value *elem = impl.ags.backdoor_instructions[4]->getOperand(5);\n\tspv::Id data_id = impl.get_id_for_value(impl.ags.backdoor_instructions[4]->getOperand(6));\n\tspv::Id id = 0;\n\tif (!impl.options.wmma_fp8 && fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\tdata_id = build_packed_fp8_to_fp16_vec4(impl, data_id);\n\n\tif (const auto *const_e = llvm::dyn_cast<llvm::ConstantInt>(elem))\n\t{\n\t\tswitch (fmt)\n\t\t{\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t{\n\t\t\t// 8-bit elements are packed in AGS for some reason ...\n\t\t\tid = impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5));\n\n\t\t\tspv::Id cast_id = 0;\n\t\t\tif (impl.options.wmma_fp8)\n\t\t\t{\n\t\t\t\tauto *cast = impl.allocate(spv::OpBitcast, builder.makeVectorType(builder.makeUintType(8), 4));\n\t\t\t\tcast->add_id(data_id);\n\t\t\t\timpl.add(cast);\n\t\t\t\tcast_id = cast->id;\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tauto *ext = impl.allocate(spv::OpCompositeExtract,\n\t\t\t\t                          impl.options.wmma_fp8 ? builder.makeUintType(8) : builder.makeFloatType(16));\n\t\t\t\text->add_id(cast_id ? cast_id : data_id);\n\t\t\t\text->add_literal(i);\n\t\t\t\timpl.add(ext);\n\n\t\t\t\tif (impl.options.wmma_fp8)\n\t\t\t\t{\n\t\t\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, make_fp8_type(impl, false));\n\t\t\t\t\tbitcast->add_id(ext->id);\n\t\t\t\t\timpl.add(bitcast);\n\t\t\t\t\text = bitcast;\n\t\t\t\t}\n\n\t\t\t\tauto *insert = impl.allocate(spv::OpCompositeInsert, coop_type);\n\t\t\t\tinsert->add_id(ext->id);\n\t\t\t\tinsert->add_id(id);\n\t\t\t\tinsert->add_literal(4 * const_e->getUniqueInteger().getZExtValue() + i);\n\t\t\t\timpl.add(insert);\n\t\t\t\tid = insert->id;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t{\n\t\t\tauto *downcast = impl.allocate(spv::OpUConvert, builder.makeUintType(16));\n\t\t\tdowncast->add_id(data_id);\n\t\t\timpl.add(downcast);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeFloatType(16));\n\t\t\tbitcast->add_id(downcast->id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tauto *insert = impl.allocate(spv::OpCompositeInsert, coop_type);\n\t\t\tinsert->add_id(bitcast->id);\n\t\t\tinsert->add_id(impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5)));\n\t\t\tinsert->add_literal(const_e->getUniqueInteger().getZExtValue());\n\t\t\timpl.add(insert);\n\n\t\t\tid = insert->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t{\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeFloatType(16));\n\t\t\tbitcast->add_id(data_id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tauto *insert = impl.allocate(spv::OpCompositeInsert, coop_type);\n\t\t\tinsert->add_id(bitcast->id);\n\t\t\tinsert->add_id(impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5)));\n\t\t\tinsert->add_literal(const_e->getUniqueInteger().getZExtValue());\n\t\t\timpl.add(insert);\n\n\t\t\tid = insert->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tLOGE(\"Unexpected type for element extract.\\n\");\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tspv::Id local_var = impl.create_variable(spv::StorageClassFunction, coop_type);\n\t\tauto *store = impl.allocate(spv::OpStore);\n\t\tstore->add_id(local_var);\n\t\tstore->add_id(impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5)));\n\t\timpl.add(store);\n\n\t\tswitch (fmt)\n\t\t{\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t{\n\t\t\t// 8-bit elements are packed in AGS for some reason ...\n\t\t\tspv::Id cast_id = 0;\n\n\t\t\tif (impl.options.wmma_fp8)\n\t\t\t{\n\t\t\t\tauto *cast = impl.allocate(spv::OpBitcast, builder.makeVectorType(builder.makeUintType(8), 4));\n\t\t\t\tcast->add_id(data_id);\n\t\t\t\timpl.add(cast);\n\t\t\t\tcast_id = cast->id;\n\t\t\t}\n\n\t\t\tauto *index4 = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tindex4->add_id(impl.get_id_for_value(elem));\n\t\t\tindex4->add_id(builder.makeUintConstant(4));\n\t\t\timpl.add(index4);\n\n\t\t\tfor (int i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tauto *ext = impl.allocate(spv::OpCompositeExtract,\n\t\t\t\t                          impl.options.wmma_fp8 ? builder.makeUintType(8) : builder.makeFloatType(16));\n\t\t\t\text->add_id(cast_id ? cast_id : data_id);\n\t\t\t\text->add_literal(i);\n\t\t\t\timpl.add(ext);\n\n\t\t\t\tif (impl.options.wmma_fp8)\n\t\t\t\t{\n\t\t\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, make_fp8_type(impl, false));\n\t\t\t\t\tbitcast->add_id(ext->id);\n\t\t\t\t\timpl.add(bitcast);\n\t\t\t\t\text = bitcast;\n\t\t\t\t}\n\n\t\t\t\tauto *index = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\t\tindex->add_id(index4->id);\n\t\t\t\tindex->add_id(builder.makeUintConstant(i));\n\t\t\t\timpl.add(index);\n\n\t\t\t\tauto *chain = impl.allocate(spv::OpInBoundsAccessChain,\n\t\t\t\t                            builder.makePointer(spv::StorageClassFunction, make_fp8_type(impl, false)));\n\t\t\t\tchain->add_id(local_var);\n\t\t\t\tchain->add_id(index->id);\n\t\t\t\timpl.add(chain);\n\n\t\t\t\tauto *store_elem = impl.allocate(spv::OpStore);\n\t\t\t\tstore_elem->add_id(chain->id);\n\t\t\t\tstore_elem->add_id(ext->id);\n\t\t\t\timpl.add(store_elem);\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t{\n\t\t\tauto *downcast = impl.allocate(spv::OpUConvert, builder.makeUintType(16));\n\t\t\tdowncast->add_id(data_id);\n\t\t\timpl.add(downcast);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeFloatType(16));\n\t\t\tbitcast->add_id(downcast->id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tauto *chain = impl.allocate(spv::OpInBoundsAccessChain,\n\t\t\t                            builder.makePointer(spv::StorageClassFunction, builder.makeFloatType(16)));\n\t\t\tchain->add_id(local_var);\n\t\t\tchain->add_id(impl.get_id_for_value(elem));\n\t\t\timpl.add(chain);\n\n\t\t\tauto *store_elem = impl.allocate(spv::OpStore);\n\t\t\tstore_elem->add_id(chain->id);\n\t\t\tstore_elem->add_id(bitcast->id);\n\t\t\timpl.add(store_elem);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t{\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeFloatType(32));\n\t\t\tbitcast->add_id(data_id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tauto *chain = impl.allocate(spv::OpInBoundsAccessChain,\n\t\t\t                            builder.makePointer(spv::StorageClassFunction, builder.makeFloatType(32)));\n\t\t\tchain->add_id(local_var);\n\t\t\tchain->add_id(impl.get_id_for_value(elem));\n\t\t\timpl.add(chain);\n\n\t\t\tauto *store_elem = impl.allocate(spv::OpStore);\n\t\t\tstore_elem->add_id(chain->id);\n\t\t\tstore_elem->add_id(bitcast->id);\n\t\t\timpl.add(store_elem);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tLOGE(\"Unexpected type for element extract.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto *load = impl.allocate(spv::OpLoad, coop_type);\n\t\tload->add_id(local_var);\n\t\timpl.add(load);\n\t\tid = load->id;\n\t}\n\n\treturn emit_wmma_return_values(impl, coop_type, id, 2);\n}\n\nstatic bool emit_wmma_element_extract(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tif (!validate_wmma_io_registers(impl, 0, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_RetVal_Reg, 0, true))\n\t\treturn false;\n\n\tuint32_t type_imm = impl.ags.instructions[4].immediate;\n\tuint32_t fmt = get_type_data_format(type_imm);\n\n\tspv::Id coop_vec_id = impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5));\n\tconst llvm::Value *elem = impl.ags.backdoor_instructions[4]->getOperand(5);\n\tspv::Id id = 0;\n\n\t// FSR4 doesn't need this, just don't bother if we emulate FP8 as FP16.\n\tif (!impl.options.wmma_fp8 && fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\treturn false;\n\n\tif (const auto *const_e = llvm::dyn_cast<llvm::ConstantInt>(elem))\n\t{\n\t\tswitch (fmt)\n\t\t{\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t{\n\t\t\t// 8-bit elements are packed in AGS for some reason ...\n\t\t\tspv::Id elements[4];\n\n\t\t\tfor (int i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tauto *extract = impl.allocate(spv::OpCompositeExtract, make_fp8_type(impl, false));\n\t\t\t\textract->add_id(coop_vec_id);\n\t\t\t\textract->add_literal(4 * const_e->getUniqueInteger().getZExtValue() + i);\n\t\t\t\timpl.add(extract);\n\t\t\t\telements[i] = extract->id;\n\t\t\t}\n\n\t\t\tspv::Id vec = impl.build_vector(make_fp8_type(impl, false), elements, 4);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(32));\n\t\t\tbitcast->add_id(vec);\n\t\t\timpl.add(bitcast);\n\n\t\t\tid = bitcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t{\n\t\t\tauto *extract = impl.allocate(spv::OpCompositeExtract, builder.makeFloatType(16));\n\t\t\textract->add_id(coop_vec_id);\n\t\t\textract->add_literal(const_e->getUniqueInteger().getZExtValue());\n\t\t\timpl.add(extract);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(16));\n\t\t\tbitcast->add_id(extract->id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tauto *upcast = impl.allocate(spv::OpUConvert, builder.makeUintType(32));\n\t\t\tupcast->add_id(bitcast->id);\n\t\t\timpl.add(upcast);\n\n\t\t\tid = upcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t{\n\t\t\tauto *extract = impl.allocate(spv::OpCompositeExtract, builder.makeFloatType(32));\n\t\t\textract->add_id(coop_vec_id);\n\t\t\textract->add_literal(const_e->getUniqueInteger().getZExtValue());\n\t\t\timpl.add(extract);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(32));\n\t\t\tbitcast->add_id(extract->id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tid = bitcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tLOGE(\"Unexpected type for element extract.\\n\");\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tspv::Id type_id = build_coopmat_type(impl, type_imm, false);\n\t\tif (!type_id)\n\t\t\treturn false;\n\n\t\tspv::Id local_var = impl.create_variable(spv::StorageClassFunction, type_id);\n\n\t\tauto *store = impl.allocate(spv::OpStore);\n\t\tstore->add_id(local_var);\n\t\tstore->add_id(coop_vec_id);\n\t\timpl.add(store);\n\n\t\tswitch (fmt)\n\t\t{\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t{\n\t\t\t// 8-bit elements are packed in AGS for some reason ...\n\t\t\tspv::Id elements[4];\n\n\t\t\tauto *index4 = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tindex4->add_id(impl.get_id_for_value(elem));\n\t\t\tindex4->add_id(builder.makeUintConstant(4));\n\t\t\timpl.add(index4);\n\n\t\t\tfor (int i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tauto *index = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\t\tindex->add_id(index4->id);\n\t\t\t\tindex->add_id(builder.makeUintConstant(i));\n\t\t\t\timpl.add(index);\n\n\t\t\t\tauto *chain = impl.allocate(\n\t\t\t\t\tspv::OpInBoundsAccessChain,\n\t\t\t\t\tbuilder.makePointer(spv::StorageClassFunction, make_fp8_type(impl, false)));\n\t\t\t\tchain->add_id(local_var);\n\t\t\t\tchain->add_id(index->id);\n\t\t\t\timpl.add(chain);\n\n\t\t\t\tauto *load = impl.allocate(spv::OpLoad, make_fp8_type(impl, false));\n\t\t\t\tload->add_id(chain->id);\n\t\t\t\timpl.add(load);\n\n\t\t\t\telements[i] = load->id;\n\t\t\t}\n\n\t\t\tspv::Id vec = impl.build_vector(make_fp8_type(impl, false), elements, 4);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(32));\n\t\t\tbitcast->add_id(vec);\n\t\t\timpl.add(bitcast);\n\n\t\t\tid = bitcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t{\n\t\t\tauto *chain = impl.allocate(\n\t\t\t\tspv::OpInBoundsAccessChain,\n\t\t\t\tbuilder.makePointer(spv::StorageClassFunction, builder.makeFloatType(16)));\n\t\t\tchain->add_id(local_var);\n\t\t\tchain->add_id(impl.get_id_for_value(elem));\n\t\t\timpl.add(chain);\n\n\t\t\tauto *load = impl.allocate(spv::OpLoad, builder.makeFloatType(16));\n\t\t\tload->add_id(chain->id);\n\t\t\timpl.add(load);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(16));\n\t\t\tbitcast->add_id(load->id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tauto *upcast = impl.allocate(spv::OpUConvert, builder.makeUintType(32));\n\t\t\tupcast->add_id(bitcast->id);\n\t\t\timpl.add(upcast);\n\n\t\t\tid = upcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t{\n\t\t\tauto *chain = impl.allocate(\n\t\t\t\tspv::OpInBoundsAccessChain,\n\t\t\t\tbuilder.makePointer(spv::StorageClassFunction, builder.makeFloatType(32)));\n\t\t\tchain->add_id(local_var);\n\t\t\tchain->add_id(impl.get_id_for_value(elem));\n\t\t\timpl.add(chain);\n\n\t\t\tauto *load = impl.allocate(spv::OpLoad, builder.makeFloatType(32));\n\t\t\tload->add_id(chain->id);\n\t\t\timpl.add(load);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(32));\n\t\t\tbitcast->add_id(load->id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tid = bitcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tLOGE(\"Unexpected type for element extract.\\n\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\timpl.rewrite_value(impl.ags.backdoor_instructions[4], id);\n\treturn true;\n}\n\nstatic bool emit_wmma_fill(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tconst auto *v = impl.ags.backdoor_instructions[0]->getOperand(5);\n\n\tuint32_t type_imm = impl.ags.instructions[0].immediate;\n\tuint32_t fmt = get_type_data_format(type_imm);\n\tspv::Id type = build_coopmat_type(impl, type_imm, false);\n\tspv::Id id;\n\n\tif (const auto *const_v = llvm::dyn_cast<llvm::ConstantInt>(v))\n\t{\n\t\tswitch (fmt)\n\t\t{\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t\tif (impl.options.wmma_fp8)\n\t\t\t{\n\t\t\t\tid = builder.makeFloat8Constant(const_v->getUniqueInteger().getZExtValue(),\n\t\t\t\t                                spv::FPEncodingFloat8E4M3EXT);\n\t\t\t}\n\t\t\telse if (const_v->getUniqueInteger().getZExtValue() == 0)\n\t\t\t{\n\t\t\t\t// Trivial\n\t\t\t\tid = builder.makeFloat16Constant(0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Not needed by FSR4.\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t\tid = builder.makeFloat16Constant(const_v->getUniqueInteger().getZExtValue());\n\t\t\tbreak;\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t{\n\t\t\tunion { float f32; uint32_t u32; } u;\n\t\t\tu.u32 = const_v->getUniqueInteger().getZExtValue();\n\t\t\tid = builder.makeFloatConstant(u.f32);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tLOGE(\"Unsupported WMMA Fill format.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tid = builder.makeCompositeConstant(type, { id });\n\t}\n\telse\n\t{\n\t\tid = impl.get_id_for_value(v);\n\n\t\tswitch (fmt)\n\t\t{\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8:\n\t\t{\n\t\t\tauto *narrow = impl.allocate(spv::OpUConvert, builder.makeUintType(8));\n\t\t\tnarrow->add_id(id);\n\t\t\timpl.add(narrow);\n\t\t\tid = narrow->id;\n\n\t\t\tif (impl.options.wmma_fp8)\n\t\t\t{\n\t\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, make_fp8_type(impl, false));\n\t\t\t\tbitcast->add_id(id);\n\t\t\t\timpl.add(bitcast);\n\t\t\t\tid = bitcast->id;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Not needed by FSR4.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16:\n\t\t{\n\t\t\tauto *narrow = impl.allocate(spv::OpUConvert, builder.makeUintType(16));\n\t\t\tnarrow->add_id(id);\n\t\t\timpl.add(narrow);\n\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeFloatType(16));\n\t\t\tbitcast->add_id(narrow->id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tid = bitcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32:\n\t\t{\n\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeFloatType(32));\n\t\t\tbitcast->add_id(id);\n\t\t\timpl.add(bitcast);\n\n\t\t\tid = bitcast->id;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tLOGE(\"Unsupported WMMA Fill format.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// Cooperative matrices are implicitly splatted.\n\t\tauto *splat = impl.allocate(spv::OpCompositeConstruct, type);\n\t\tsplat->add_id(id);\n\t\timpl.add(splat);\n\n\t\tid = splat->id;\n\t}\n\n\tif (!emit_wmma_return_values(impl, type, id, 1))\n\t{\n\t\tLOGE(\"Failed to emit WMMA return values.\\n\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstatic bool emit_wmma_element_wise_arith(Converter::Impl &impl)\n{\n\tif (impl.ags.instructions[8].phase != 1)\n\t\treturn false;\n\n\tif (!validate_wmma_io_registers(impl, 0, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_A_TempReg, 0, true))\n\t\treturn false;\n\tif (!validate_wmma_io_registers(impl, 4, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_B_TempReg, 0, true))\n\t\treturn false;\n\n\tuint32_t type_imm = impl.ags.instructions[8].immediate;\n\tspv::Id type = build_coopmat_type(impl, type_imm, false);\n\n\tspv::Id a = impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5));\n\tspv::Id b = impl.get_id_for_value(impl.ags.backdoor_instructions[4]->getOperand(5));\n\tspv::Op op;\n\n\tuint32_t float_op = 0;\n\n\tif (!get_constant_operand(impl.ags.backdoor_instructions[8], 6, &float_op) || float_op != 0)\n\t\treturn false;\n\n\tif (!get_constant_operand(impl.ags.backdoor_instructions[8], 5, &float_op))\n\t\treturn false;\n\n\tswitch (float_op)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Add:\n\t\top = spv::OpFAdd;\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Sub:\n\t\top = spv::OpFSub;\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Mul:\n\t\top = spv::OpFMul;\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Div:\n\t\top = spv::OpFDiv;\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Times:\n\t\t// AMD implements this as constant 0 apparently.\n\t\t// It's not used, so just implement it as we'd expect.\n\t\top = spv::OpFMul;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tauto *arith_op = impl.allocate(op, type);\n\tarith_op->add_id(a);\n\tarith_op->add_id(b);\n\timpl.add(arith_op);\n\n\tif (!emit_wmma_return_values(impl, type, arith_op->id, 2))\n\t{\n\t\tLOGE(\"Failed to emit WMMA return values.\\n\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstatic bool emit_float8_conversion(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tauto convert_op = AmdExtD3DShaderIntrinsicsFloat8CvtOp(impl.ags.instructions[0].immediate &\n\t                                                       AmdExtD3DShaderIntrinsicsFloat8Conversion_CvtOpMask);\n\tbool saturate = ((impl.ags.instructions[0].immediate >> AmdExtD3DShaderIntrinsicsFloat8Conversion_SatShift) &\n\t                 AmdExtD3DShaderIntrinsicsFloat8Conversion_SatMask) != 0;\n\n\tbuilder.addExtension(\"SPV_EXT_float8\");\n\tbuilder.addCapability(spv::CapabilityFloat8EXT);\n\tbuilder.addCapability(spv::CapabilityInt8);\n\tbool is_bfloat = false;\n\n\tuint32_t dummy_value;\n\tif (!get_constant_operand(impl.ags.backdoor_instructions[0], 6, &dummy_value) || dummy_value != 0)\n\t\treturn false;\n\n\tswitch (convert_op)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsFloat8CvtOp_F32_2_BF8:\n\t\tis_bfloat = true;\n\t\t// fallthrough\n\tcase AmdExtD3DShaderIntrinsicsFloat8CvtOp_F32_2_FP8:\n\t{\n\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeFloatType(32));\n\t\tbitcast->add_id(impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5)));\n\t\timpl.add(bitcast);\n\n#if 0\n\t\t// Native implementation seems to correctly treat saturated inf in this case.\n\t\tif (saturate && !is_bfloat)\n\t\t{\n\t\t\t// Fixup for RDNA4 HW compat.\n\t\t\tauto *is_inf = impl.allocate(spv::OpIsInf, builder.makeBoolType());\n\t\t\tis_inf->add_id(bitcast->id);\n\t\t\timpl.add(is_inf);\n\n\t\t\tauto *select = impl.allocate(spv::OpSelect, builder.makeFloatType(32));\n\t\t\tselect->add_id(is_inf->id);\n\t\t\tselect->add_id(builder.makeFloatConstant(std::numeric_limits<float>::quiet_NaN()));\n\t\t\tselect->add_id(bitcast->id);\n\t\t\timpl.add(select);\n\n\t\t\tbitcast = select;\n\t\t}\n#endif\n\n\t\tauto *conv = impl.allocate(spv::OpFConvert, builder.makeFloatType(8, is_bfloat ? spv::FPEncodingFloat8E5M2EXT :\n\t\t                                                                                 spv::FPEncodingFloat8E4M3EXT));\n\t\tconv->add_id(bitcast->id);\n\t\timpl.add(conv);\n\n\t\tif (saturate)\n\t\t\tbuilder.addDecoration(conv->id, spv::DecorationSaturatedToLargestFloat8NormalConversionEXT);\n\n\t\tbitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(8));\n\t\tbitcast->add_id(conv->id);\n\t\timpl.add(bitcast);\n\n\t\tauto *ext = impl.allocate(spv::OpUConvert, impl.ags.backdoor_instructions[0]);\n\t\text->add_id(bitcast->id);\n\t\timpl.add(ext);\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsFloat8CvtOp_BF8_2_F32:\n\t\tis_bfloat = true;\n\t\t// fallthrough\n\tcase AmdExtD3DShaderIntrinsicsFloat8CvtOp_FP8_2_F32:\n\t{\n\t\tauto *trunc = impl.allocate(spv::OpUConvert, builder.makeUintType(8));\n\t\ttrunc->add_id(impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5)));\n\t\timpl.add(trunc);\n\n\t\tauto *bitcast =\n\t\t    impl.allocate(spv::OpBitcast, builder.makeFloatType(8, is_bfloat ? spv::FPEncodingFloat8E5M2EXT :\n\t\t                                                                       spv::FPEncodingFloat8E4M3EXT));\n\t\tbitcast->add_id(trunc->id);\n\t\timpl.add(bitcast);\n\n\t\tauto *conv = impl.allocate(spv::OpFConvert, builder.makeFloatType(32));\n\t\tconv->add_id(bitcast->id);\n\t\timpl.add(conv);\n\n\t\tbitcast = impl.allocate(spv::OpBitcast, impl.ags.backdoor_instructions[0]);\n\t\tbitcast->add_id(conv->id);\n\t\timpl.add(bitcast);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstatic spv::Id get_matmul_result_type(Converter::Impl &impl, uint32_t opcode)\n{\n\tauto &builder = impl.builder();\n\tspv::Id rows_cols = builder.makeUintConstant(16);\n\tspv::Id use = builder.makeUintConstant(spv::CooperativeMatrixUseMatrixAccumulatorKHR);\n\tspv::Id scalar_type;\n\n\tswitch (opcode)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_FP8_FP8:\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_F16:\n\t\tscalar_type = builder.makeFloatType(32);\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F16_16X16X16_F16:\n\t\tscalar_type = builder.makeFloatType(16);\n\t\tbreak;\n\n\tdefault:\n\t\treturn 0;\n\t}\n\n\treturn builder.makeCooperativeMatrixType(scalar_type, rows_cols, rows_cols, use);\n}\n\nstatic bool emit_wmma_muladd(Converter::Impl &impl)\n{\n\tif (!validate_wmma_io_registers(impl, 0, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_A_TempReg, 0, true))\n\t\treturn false;\n\tif (!validate_wmma_io_registers(impl, 4, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_B_TempReg, 0, true))\n\t\treturn false;\n\tif (!validate_wmma_io_registers(impl, 8, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_Accumulator_TempReg, 0, true))\n\t\treturn false;\n\n\tif (impl.ags.instructions[12].phase != 1)\n\t\treturn false;\n\n\tauto opcode = (impl.ags.instructions[12].immediate >> AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_OpsShift) &\n\t              AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_OpsMask;\n\n\tspv::Id type = get_matmul_result_type(impl, opcode);\n\tif (!type)\n\t\treturn false;\n\n\tauto *muladd = impl.allocate(spv::OpCooperativeMatrixMulAddKHR, type);\n\n\tspv::Id a = impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5));\n\tspv::Id b = impl.get_id_for_value(impl.ags.backdoor_instructions[4]->getOperand(5));\n\tspv::Id c = impl.get_id_for_value(impl.ags.backdoor_instructions[8]->getOperand(5));\n\n\tmuladd->add_id(a);\n\tmuladd->add_id(b);\n\tmuladd->add_id(c);\n\timpl.add(muladd);\n\n\tif (!emit_wmma_return_values(impl, type, muladd->id, 2))\n\t{\n\t\tLOGE(\"Failed to emit WMMA return values.\\n\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstatic spv::Id emit_wmma_complex_convert(Converter::Impl &impl, spv::Id coopmat,\n                                         uint32_t type_imm, uint32_t output_immediate,\n                                         bool saturating)\n{\n\tuint32_t input_fmt = get_type_data_format(type_imm);\n\tuint32_t output_fmt = get_type_data_format(output_immediate);\n\n\tif (impl.options.wmma_fp8 &&\n\t    output_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8 &&\n\t    (input_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16 ||\n\t     input_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32) &&\n\t    saturating)\n\t{\n\t\t// Works around broken RDNA4 HW behavior.\n\t\t// Even when saturating, +/- inf becomes NaN.\n\t\t// To allow RADV to emit optimal code we have to explicitly \"emulate\" this HW bug.\n\t\t// Only do this fixup if we have native FP8, otherwise the compiler will not understand it\n\t\t// and likely emit worse code.\n\t\tcoopmat = emit_coopmat_broken_saturation_fixup(impl, coopmat, build_coopmat_type(impl, type_imm, false));\n\t}\n\n\t// If this is supported, we can do everything in one go.\n\tspv::Id res_id = emit_coopmat_transpose_with_convert(impl, coopmat, type_imm, output_immediate, saturating);\n\tif (res_id != 0)\n\t\treturn res_id;\n\n\tuint32_t input_use = get_matrix_type(type_imm);\n\tuint32_t output_use = get_matrix_type(output_immediate);\n\tauto in_use = convert_matrix_use(input_use);\n\tauto out_use = convert_matrix_use(output_use);\n\n\tspv::Id output_type = build_coopmat_type(impl, output_immediate, false);\n\n\tconstexpr uint32_t FormatMask =\n\t\tAmdExtD3DShaderIntrinsicsWaveMatrixModifier_DataFormatFlagMask <<\n\t\tAmdExtD3DShaderIntrinsicsWaveMatrixModifier_DataFormatFlagShift;\n\n\tconstexpr uint32_t TypeMask =\n\t\tAmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagMask <<\n\t\tAmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagShift;\n\n\t// Transpose in input format, convert later.\n\tuint32_t output_type_input_use_imm = output_immediate;\n\toutput_type_input_use_imm &= ~TypeMask;\n\toutput_type_input_use_imm |= impl.ags.instructions[4].immediate & TypeMask;\n\tspv::Id output_type_input_use = build_coopmat_type(impl, output_type_input_use_imm, false);\n\n\tuint32_t output_type_input_fmt_imm = output_immediate;\n\toutput_type_input_fmt_imm &= ~FormatMask;\n\toutput_type_input_fmt_imm |= impl.ags.instructions[4].immediate & FormatMask;\n\tspv::Id output_type_input_fmt = build_coopmat_type(impl, output_type_input_fmt_imm, false);\n\n\tif (!output_type || (!output_type_input_use && !output_type_input_fmt))\n\t\treturn 0;\n\n\t// Transpose early if the target format does not support the input use.\n\tif (in_use != out_use && !output_type_input_use)\n\t{\n\t\tcoopmat = emit_coopmat_transpose(impl, coopmat, type_imm, output_type_input_fmt_imm);\n\t\tif (!coopmat)\n\t\t\treturn 0;\n\t\tin_use = out_use;\n\t\toutput_type_input_use = output_type;\n\t}\n\n\tauto effective_input_fmt = input_fmt;\n\tauto effective_output_fmt = output_fmt;\n\tif (!impl.options.wmma_fp8)\n\t{\n\t\tif (effective_input_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\t\teffective_input_fmt = AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16;\n\t\tif (effective_output_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\t\teffective_output_fmt = AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16;\n\t}\n\n\tif (effective_input_fmt != effective_output_fmt)\n\t{\n\t\tauto *conv = impl.allocate(spv::OpFConvert, output_type_input_use);\n\t\tconv->add_id(coopmat);\n\t\timpl.add(conv);\n\t\tcoopmat = conv->id;\n\n\t\tif (impl.options.wmma_fp8 && saturating &&\n\t\t    output_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t\t{\n\t\t\timpl.builder().addDecoration(\n\t\t\t\tcoopmat, spv::DecorationSaturatedToLargestFloat8NormalConversionEXT);\n\t\t}\n\t}\n\n\tif (output_fmt == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8 && !impl.options.wmma_fp8)\n\t\tcoopmat = emit_coopmat_saturate_fp8(impl, coopmat, output_type_input_use);\n\n\tif (in_use != out_use)\n\t{\n\t\tcoopmat = emit_coopmat_transpose(impl, coopmat, output_type_input_use_imm, output_immediate);\n\t\tif (!coopmat)\n\t\t\treturn 0;\n\t}\n\n\treturn coopmat;\n}\n\nstatic bool emit_wmma_convert(Converter::Impl &impl)\n{\n\tif (!validate_wmma_io_registers(impl, 0, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_RetVal_Reg, 0, true))\n\t\treturn false;\n\n\tif (impl.ags.instructions[4].phase != 1)\n\t\treturn false;\n\n\tuint32_t output_immediate = 0;\n\tif (!get_constant_operand(impl.ags.backdoor_instructions[4], 5, &output_immediate))\n\t\treturn false;\n\n\tuint32_t saturating = 0;\n\tif (!get_constant_operand(impl.ags.backdoor_instructions[4], 6, &saturating))\n\t\treturn false;\n\n\tif (!validate_convert_compatibility(impl.ags.instructions[4].immediate, output_immediate))\n\t\treturn false;\n\n\tspv::Id output_type = build_coopmat_type(impl, output_immediate, false);\n\n\tspv::Id res_id;\n\n\tif (impl.ags.instructions[4].immediate == output_immediate)\n\t{\n\t\tres_id = impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5));\n\t}\n\telse\n\t{\n\t\tspv::Id coopmat = impl.get_id_for_value(impl.ags.backdoor_instructions[0]->getOperand(5));\n\t\tres_id = emit_wmma_complex_convert(impl, coopmat, impl.ags.instructions[4].immediate,\n\t\t                                   output_immediate, saturating != 0);\n\t\tif (!res_id)\n\t\t\treturn false;\n\t}\n\n\tif (!emit_wmma_return_values(impl, output_type, res_id, 2))\n\t{\n\t\tLOGE(\"Failed to emit WMMA return values.\\n\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstruct WMMAAccessChain\n{\n\tspv::Id chain_id;\n\tspv::Id stride_id;\n\tuint32_t alignment;\n};\n\nstatic WMMAAccessChain build_wmma_access_chain(\n\tConverter::Impl &impl, const llvm::Value *offset, const llvm::Value *stride)\n{\n\tWMMAAccessChain ret = {};\n\tauto &builder = impl.builder();\n\n\tif (impl.ags.active_uav_op == DXIL::Op::AtomicBinOp)\n\t{\n\t\t// LDS access chains are in terms of u32 elements for whatever reason ...\n\t\t// This is convenient for us however, since SPIR-V is defined the same way.\n\t\t// TODO: Unsure what happens if the LDS pointer is u16, but FSR4 doesn't use that, so whatever.\n\t\tauto *chain = impl.allocate(spv::OpAccessChain,\n\t\t                            builder.makePointer(spv::StorageClassWorkgroup, builder.makeUintType(32)));\n\t\tchain->add_id(impl.ags.active_uav_ptr);\n\t\tchain->add_id(impl.get_id_for_value(offset));\n\n\t\timpl.add(chain);\n\t\tret.chain_id = chain->id;\n\t\tret.stride_id = impl.get_id_for_value(stride);\n\t\treturn ret;\n\t}\n\n\t// Build the actual load.\n\tconst auto &meta = impl.handle_to_resource_meta[impl.ags.active_uav_ptr];\n\n\tif (meta.storage == spv::StorageClassStorageBuffer || impl.ags.active_uav_op == DXIL::Op::AtomicBinOp)\n\t{\n\t\tspv::Id buffer_id = get_buffer_alias_handle(\n\t\t\timpl, meta, impl.ags.active_uav_ptr, RawType::Integer, RawWidth::B8, RawVecSize::V1);\n\n\t\tif (!buffer_id)\n\t\t{\n\t\t\tLOGE(\"Failed to get buffer alias.\\n\");\n\t\t\treturn ret;\n\t\t}\n\n\t\t// Cooperative matrix is in terms of elements of the value type, not bytes.\n\t\t// We could use 8-bit storage, but that means adding a lot of extra cruft ...\n\t\tauto *chain = impl.allocate(spv::OpAccessChain,\n\t\t                            builder.makePointer(spv::StorageClassStorageBuffer, builder.makeUintType(8)));\n\t\tchain->add_id(buffer_id);\n\t\tchain->add_id(builder.makeUintConstant(0));\n\t\tchain->add_id(impl.get_id_for_value(offset));\n\n\t\timpl.add(chain);\n\t\tret.chain_id = chain->id;\n\t\tret.stride_id = impl.get_id_for_value(stride);\n\t}\n\telse if (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\tif (!impl.ags.u8_array_bda_type)\n\t\t{\n\t\t\timpl.ags.u8_array_bda_type = builder.makeRuntimeArray(builder.makeUintType(8));\n\t\t\tbuilder.addDecoration(impl.ags.u8_array_bda_type, spv::DecorationArrayStride, 1);\n\t\t}\n\n\t\tauto *cast = impl.allocate(spv::OpBitcast,\n\t\t                           builder.makePointer(spv::StorageClassPhysicalStorageBuffer, impl.ags.u8_array_bda_type));\n\n\t\tcast->add_id(impl.ags.active_uav_ptr);\n\t\timpl.add(cast);\n\n\t\tauto *chain = impl.allocate(spv::OpAccessChain,\n\t\t                            builder.makePointer(spv::StorageClassPhysicalStorageBuffer, builder.makeUintType(8)));\n\t\tchain->add_id(cast->id);\n\t\tchain->add_id(impl.get_id_for_value(offset));\n\t\timpl.add(chain);\n\n\t\tret.chain_id = chain->id;\n\t\tret.stride_id = impl.get_id_for_value(stride);\n\t\tret.alignment = 16; // Unsure what requirements are here. Just do the simple thing.\n\t}\n\telse\n\t{\n\t\tLOGE(\"Expected BDA or SSBO for WMMA load-store.\\n\");\n\t}\n\n\treturn ret;\n}\n\nstatic bool emit_wmma_store(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\t// Sanity check that we're reading from the hooked read opcode.\n\tif (impl.ags.backdoor_instructions[5]->getOperand(5) != impl.ags.active_read_backdoor)\n\t\treturn false;\n\n\tif (impl.ags.instructions[0].phase != 0)\n\t\treturn false;\n\tif (impl.ags.instructions[5].phase != 2)\n\t\treturn false;\n\n\tif (!validate_wmma_io_registers(impl, 1, AmdExtD3DShaderIntrinsicsWaveMatrixRegType_RetVal_Reg, 1, true))\n\t\treturn false;\n\n\tuint32_t type_immediate = impl.ags.instructions[5].immediate;\n\tbool column_major = ((type_immediate >> AmdExtD3DShaderIntrinsicsWaveMatrixModifier_LayoutFlagShift) &\n\t                     AmdExtD3DShaderIntrinsicsWaveMatrixModifier_LayoutFlagMask) != 0;\n\n\tauto chain = build_wmma_access_chain(impl, impl.ags.backdoor_instructions[0]->getOperand(5),\n\t                                     impl.ags.backdoor_instructions[0]->getOperand(6));\n\n\tif (chain.chain_id == 0)\n\t\treturn false;\n\n\tspv::Id store_id = impl.get_id_for_value(impl.ags.backdoor_instructions[1]->getOperand(5));\n\n\tif (!impl.options.wmma_fp8 &&\n\t    get_type_data_format(type_immediate) == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t{\n\t\tauto spv_use = convert_matrix_use(get_matrix_type(type_immediate));\n\t\t// Until we have proper FP8 support, we'll need to downconvert on store.\n\t\tstore_id = emit_fp16_to_fp8_coopmat(impl, store_id, spv_use);\n\t}\n\n\tauto *store = impl.allocate(spv::OpCooperativeMatrixStoreKHR);\n\tstore->add_id(chain.chain_id);\n\tstore->add_id(store_id);\n\tstore->add_id(builder.makeUintConstant(\n\t\tcolumn_major ? spv::CooperativeMatrixLayoutColumnMajorKHR : spv::CooperativeMatrixLayoutRowMajorKHR));\n\tstore->add_id(chain.stride_id);\n\n\tbool non_private = impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan;\n\n\tif (chain.alignment)\n\t{\n\t\tstore->add_literal(spv::MemoryAccessAlignedMask);\n\t\tstore->add_literal(chain.alignment);\n\t}\n\n\tadd_vkmm_access_qualifiers(impl, store, { non_private });\n\n\timpl.add(store);\n\n\treturn true;\n}\n\nstatic void emit_subgroup_barrier(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tauto *barrier = impl.allocate(spv::OpControlBarrier);\n\tbarrier->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbarrier->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbarrier->add_id(builder.getWorkgroupBarrierSemanticsId());\n\timpl.add(barrier);\n}\n\nstatic bool emit_wmma_load(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\t// Sanity check that we're reading from the hooked read opcode.\n\tif (impl.ags.backdoor_instructions[1]->getOperand(5) != impl.ags.active_read_backdoor)\n\t\treturn false;\n\n\tif (impl.ags.instructions[0].phase != 0)\n\t\treturn false;\n\tif (impl.ags.instructions[1].phase != 1)\n\t\treturn false;\n\n\tuint32_t type_immediate = impl.ags.instructions[1].immediate;\n\tspv::Id type_id = build_coopmat_type(impl, type_immediate, true);\n\n\tif (!type_id)\n\t{\n\t\tLOGE(\"Failed to create coopmat type.\\n\");\n\t\treturn false;\n\t}\n\n\tauto chain = build_wmma_access_chain(impl, impl.ags.backdoor_instructions[0]->getOperand(5),\n\t                                     impl.ags.backdoor_instructions[0]->getOperand(6));\n\n\tif (chain.chain_id == 0)\n\t\treturn false;\n\n\tbool column_major = ((type_immediate >> AmdExtD3DShaderIntrinsicsWaveMatrixModifier_LayoutFlagShift) &\n\t                     AmdExtD3DShaderIntrinsicsWaveMatrixModifier_LayoutFlagMask) != 0;\n\n\t// Workaround AGS omitting barriers.\n\tif (impl.ags.active_uav_op == DXIL::Op::AtomicBinOp)\n\t\temit_subgroup_barrier(impl);\n\n\tauto *load = impl.allocate(spv::OpCooperativeMatrixLoadKHR, type_id);\n\tload->add_id(chain.chain_id);\n\tload->add_id(builder.makeUintConstant(\n\t\tcolumn_major ? spv::CooperativeMatrixLayoutColumnMajorKHR : spv::CooperativeMatrixLayoutRowMajorKHR));\n\tload->add_id(chain.stride_id);\n\n\tbool non_private = impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan;\n\n\tif (chain.alignment)\n\t{\n\t\tload->add_literal(spv::MemoryAccessAlignedMask);\n\t\tload->add_literal(chain.alignment);\n\t}\n\n\tadd_vkmm_access_qualifiers(impl, load, { non_private });\n\n\timpl.add(load);\n\n\t// Workaround AGS omitting barriers.\n\tif (impl.ags.active_uav_op == DXIL::Op::AtomicBinOp)\n\t\temit_subgroup_barrier(impl);\n\n\tspv::Id id = load->id;\n\n\tif (!impl.options.wmma_fp8 &&\n\t    get_type_data_format(type_immediate) == AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8)\n\t{\n\t\tauto spv_use = convert_matrix_use(get_matrix_type(type_immediate));\n\t\t// Until we have proper FP8 support, we'll need to upconvert.\n\t\tid = emit_fp8_to_fp16_coopmat(impl, id, spv_use);\n\t}\n\n\ttype_id = build_coopmat_type(impl, type_immediate, false);\n\n\tif (!emit_wmma_return_values(impl, type_id, id, 2))\n\t{\n\t\tLOGE(\"Failed to emit WMMA return values.\\n\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool wmma_store_is_masked(Converter::Impl &impl, const llvm::StoreInst *inst)\n{\n\tauto itr = impl.ags.coopmat_component_mapping.find(inst->getOperand(0));\n\tif (itr == impl.ags.coopmat_component_mapping.end() || itr->second.component == 0)\n\t\treturn false;\n\n\titr = impl.ags.coopmat_component_mapping.find(inst->getOperand(1));\n\tif (itr == impl.ags.coopmat_component_mapping.end() || itr->second.component == 0)\n\t\treturn false;\n\n\treturn true;\n}\n\nstatic spv::Id rewrite_gep_rdna3(Converter::Impl &impl, const llvm::Value *value, spv::Id id)\n{\n\tif (impl.ags.column_oriented_allocas_or_globals.count(value) == 0)\n\t\treturn id;\n\n\tauto &builder = impl.builder();\n\tauto *shift = impl.allocate(spv::OpShiftLeftLogical, builder.makeUintType(32));\n\tshift->add_id(id);\n\tshift->add_id(builder.makeUintConstant(1));\n\timpl.add(shift);\n\n\tauto *mask = impl.allocate(spv::OpBitwiseAnd, builder.makeUintType(32));\n\tmask->add_id(shift->id);\n\tmask->add_id(builder.makeUintConstant(7));\n\timpl.add(mask);\n\n\tspv::Id local_id_var = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSubgroupLocalInvocationId);\n\tauto *load = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\tload->add_id(local_id_var);\n\timpl.add(load);\n\n\tauto *shift_down = impl.allocate(spv::OpShiftRightLogical, builder.makeUintType(32));\n\tshift_down->add_id(load->id);\n\tshift_down->add_id(builder.makeUintConstant(4));\n\timpl.add(shift_down);\n\n\tauto *add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\tadd->add_id(mask->id);\n\tadd->add_id(shift_down->id);\n\timpl.add(add);\n\n\treturn add->id;\n}\n\nstatic const llvm::Value *get_underlying_gep_array(const llvm::GetElementPtrInst *gep)\n{\n\tif (!gep)\n\t\treturn nullptr;\n\n\tauto *source_variable = gep->getOperand(0);\n\tif (const auto *alloca = llvm::dyn_cast<llvm::AllocaInst>(source_variable))\n\t\treturn alloca;\n\telse if (const auto *global = llvm::dyn_cast<llvm::GlobalVariable>(source_variable))\n\t\treturn global;\n\treturn nullptr;\n}\n\nstatic const llvm::Value *get_underlying_gep_array(const llvm::ConstantExpr *cexpr)\n{\n\tif (!cexpr)\n\t\treturn nullptr;\n\n\tif (cexpr->getOpcode() != llvm::Instruction::GetElementPtr)\n\t\treturn nullptr;\n\n\t// Not possible to constexpr-gep into alloca, since alloca isn't constant expression.\n\tauto *source_variable = cexpr->getOperand(0);\n\tif (const auto *global = llvm::dyn_cast<llvm::GlobalVariable>(source_variable))\n\t\treturn global;\n\treturn nullptr;\n}\n\nspv::Id rewrite_alloca_gep_index(Converter::Impl &impl, const llvm::GetElementPtrInst *gep, spv::Id id)\n{\n\tauto *value = get_underlying_gep_array(gep);\n\tif (!value)\n\t\treturn id;\n\n\tif (!llvm::isa<llvm::Constant>(gep->getOperand(2)))\n\t{\n\t\tspv::Id rdna3_gep_id = rewrite_gep_rdna3(impl, value, id);\n\t\tif (rdna3_gep_id != id)\n\t\t\treturn rdna3_gep_id;\n\t}\n\n\tauto itr = impl.ags.alloca_or_global_tracking.find(value);\n\tif (itr == impl.ags.alloca_or_global_tracking.end())\n\t\treturn id;\n\n\tif (itr->second.override_element_type && itr->second.override_element_stride)\n\t{\n\t\tauto split = split_index_scale_bias(gep->getOperand(2));\n\t\tif (!split.stride)\n\t\t\treturn 0;\n\t\tif (split.stride != UINT32_MAX && split.stride != itr->second.override_element_stride)\n\t\t\treturn 0;\n\n\t\tuint32_t const_index = 0;\n\n\t\tif (split.stride == UINT32_MAX && itr->second.override_element_stride && !split.index)\n\t\t{\n\t\t\tconst_index = split.elem / itr->second.override_element_stride;\n\t\t\tsplit.elem -= const_index * itr->second.override_element_stride;\n\t\t}\n\n\t\timpl.ags.coopmat_component_mapping[gep] =\n\t\t    { itr->second.override_element_type, split.elem };\n\n\t\t// If we're writing anything other than the first element, skip the actual write.\n\t\tif (split.elem != 0)\n\t\t\treturn UINT32_MAX;\n\n\t\tif (split.index)\n\t\t\tid = impl.get_id_for_value(split.index);\n\t\telse\n\t\t\tid = impl.builder().makeUintConstant(const_index);\n\t}\n\n\treturn id;\n}\n\nstatic bool is_gep_instruction(const llvm::Value *value)\n{\n\tif (llvm::isa<llvm::GetElementPtrInst>(value))\n\t\treturn true;\n\telse if (const auto *cexpr = llvm::dyn_cast<llvm::ConstantExpr>(value))\n\t\treturn cexpr->getOpcode() == llvm::Instruction::GetElementPtr;\n\telse\n\t\treturn false;\n}\n\nbool analyze_ags_wmma_store(Converter::Impl &impl, const llvm::StoreInst *store)\n{\n\tauto itr = impl.ags.coopmat_component_mapping.find(store->getOperand(0));\n\tif (itr == impl.ags.coopmat_component_mapping.end())\n\t\treturn true;\n\n\tauto *store_ptr = store->getOperand(1);\n\n\tif (!is_gep_instruction(store_ptr))\n\t{\n\t\tLOGE(\"Trying to store a WMMA matrix without GEP.\\n\");\n\t\treturn false;\n\t}\n\n\tauto *gep = llvm::dyn_cast<llvm::GetElementPtrInst>(store_ptr);\n\tauto *cexpr = llvm::dyn_cast<llvm::ConstantExpr>(store_ptr);\n\tconst llvm::Value *value = nullptr;\n\tif (gep)\n\t\tvalue = get_underlying_gep_array(gep);\n\telse if (cexpr)\n\t\tvalue = get_underlying_gep_array(cexpr);\n\n\tif (!value || (gep ? gep->getNumOperands() : cexpr->getNumOperands()) < 3)\n\t{\n\t\tLOGE(\"Trying to store WMMA to something not Alloca or global array.\\n\");\n\t\treturn false;\n\t}\n\n\tconst auto *index = gep ? gep->getOperand(2) : cexpr->getOperand(2);\n\tauto split = split_index_scale_bias(index);\n\tif (!split.stride)\n\t\treturn false;\n\n\tauto &tracking = impl.ags.alloca_or_global_tracking[value];\n\tif (tracking.override_element_stride &&\n\t    tracking.override_element_stride != split.stride &&\n\t    split.stride != UINT32_MAX)\n\t{\n\t\tLOGE(\"Mismatch WMMA stride.\\n\");\n\t\treturn false;\n\t}\n\n\tif (tracking.override_element_type && tracking.override_element_type != itr->second.type_id)\n\t{\n\t\tLOGE(\"Mismatch WMMA type.\\n\");\n\t\treturn false;\n\t}\n\n\tif (split.stride == UINT32_MAX)\n\t{\n\t\t// Somewhat hacky, but this is the AGS assumption.\n\t\ttracking.override_element_stride = 8;\n\n#if 0\n\t\t// This breaks in some cases.\n\t\tif (split.elem > itr->second.component)\n\t\t{\n\t\t\tif (tracking.override_element_stride == 0)\n\t\t\t{\n\t\t\t\t// We can deduce stride from this.\n\t\t\t\ttracking.override_element_stride = split.elem - itr->second.component;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// This isn't perfect if there are gaps in the writes, but we can assume that's not the case.\n\t\t\t\ttracking.override_element_stride =\n\t\t\t\t\tstd::min<uint32_t>(split.elem - itr->second.component,\n\t\t\t\t\t\t\t\t\t   tracking.override_element_stride);\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tif (split.stride == UINT32_MAX && tracking.override_element_stride)\n\t{\n\t\tsplit.stride = tracking.override_element_stride;\n\t\tsplit.elem %= split.stride;\n\t}\n\n\t// If we have constant indices we don't know how the mapping works yet.\n\tif (split.elem != itr->second.component)\n\t{\n\t\tLOGE(\"Unexpected component mapping in WMMA store.\\n\");\n\t\treturn false;\n\t}\n\n\tif (split.stride != UINT32_MAX)\n\t\ttracking.override_element_stride = split.stride;\n\ttracking.override_element_type = itr->second.type_id;\n\treturn true;\n}\n\nstatic void analyze_dubious_implementation_defined_column_behavior(\n\tConverter::Impl &impl, const llvm::Value *value)\n{\n\t// Try to figure out if the inserted element depends on manually adding elements from alloca().\n\t// This has different results on RDNA4 and RDNA3 and we can detect\n\t// this very specific case and rewrite the GEP to hack around it.\n\n\tif (!GlobalConfiguration::get().wmma_rdna3_workaround)\n\t\treturn;\n\n\tif (const auto *binop = llvm::dyn_cast<llvm::BinaryOperator>(value))\n\t{\n\t\tanalyze_dubious_implementation_defined_column_behavior(impl, binop->getOperand(0));\n\t\tanalyze_dubious_implementation_defined_column_behavior(impl, binop->getOperand(1));\n\t}\n\telse if (const auto *cast = llvm::dyn_cast<llvm::CastInst>(value))\n\t{\n\t\tanalyze_dubious_implementation_defined_column_behavior(impl, cast->getOperand(0));\n\t}\n\telse if (const auto *load = llvm::dyn_cast<llvm::LoadInst>(value))\n\t{\n\t\tauto *ptr = load->getPointerOperand();\n\t\tif (const auto *gep = llvm::dyn_cast<llvm::GetElementPtrInst>(ptr))\n\t\t{\n\t\t\tif (const auto *alloca = llvm::dyn_cast<llvm::AllocaInst>(gep->getOperand(0)))\n\t\t\t{\n\t\t\t\tauto *type = alloca->getType()->getPointerElementType();\n\t\t\t\tif (type->getTypeID() == llvm::Type::TypeID::ArrayTyID && type->getArrayNumElements() == 8)\n\t\t\t\t{\n\t\t\t\t\timpl.ags.column_oriented_allocas_or_globals.insert(alloca);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool analyze_magic_ags_instruction(Converter::Impl &impl)\n{\n\tif (impl.ags.num_instructions == 0)\n\t\treturn true;\n\n\tbool has_wmma_return_values = false;\n\tspv::Id type_id = 0;\n\tuint32_t phase = 0;\n\n\tswitch (impl.ags.instructions[0].opcode)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavLoad:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLdsLoad:\n\t\thas_wmma_return_values = impl.ags.num_instructions == 10;\n\t\tif (has_wmma_return_values)\n\t\t{\n\t\t\ttype_id = build_coopmat_type(impl, impl.ags.instructions[1].immediate, false);\n\t\t\tphase = 2;\n\t\t}\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixCopy:\n\t\tif (impl.ags.current_phase == 1)\n\t\t{\n\t\t\tif (impl.ags.num_instructions > 5)\n\t\t\t{\n\t\t\t\t// Apparently some shaders encode dummy inputs? Shift away useless stuff either way.\n\t\t\t\tmemmove(impl.ags.instructions, impl.ags.instructions + (impl.ags.num_instructions - 5),\n\t\t\t\t        5 * sizeof(impl.ags.instructions[0]));\n\t\t\t\tmemmove(impl.ags.backdoor_instructions, impl.ags.backdoor_instructions + (impl.ags.num_instructions - 5),\n\t\t\t\t        5 * sizeof(impl.ags.backdoor_instructions[0]));\n\t\t\t\timpl.ags.num_instructions = 5;\n\t\t\t}\n\t\t}\n\t\thas_wmma_return_values = impl.ags.num_instructions == 13;\n\t\tif (has_wmma_return_values)\n\t\t{\n\t\t\tuint32_t output_immediate = 0;\n\t\t\tif (!get_constant_operand(impl.ags.backdoor_instructions[4], 5, &output_immediate))\n\t\t\t\treturn false;\n\t\t\ttype_id = build_coopmat_type(impl, output_immediate, false);\n\t\t\tphase = 2;\n\t\t}\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixMulAcc:\n\t\thas_wmma_return_values = impl.ags.num_instructions == 21;\n\t\tif (has_wmma_return_values)\n\t\t{\n\t\t\tauto opcode = (impl.ags.instructions[12].immediate >> AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_OpsShift) &\n\t\t\t              AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_OpsMask;\n\t\t\ttype_id = get_matmul_result_type(impl, opcode);\n\t\t\tphase = 2;\n\t\t}\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixFill:\n\t\thas_wmma_return_values = impl.ags.num_instructions == 9;\n\t\tif (has_wmma_return_values)\n\t\t{\n\t\t\ttype_id = build_coopmat_type(impl, impl.ags.instructions[0].immediate, false);\n\t\t\tphase = 1;\n\t\t}\n\t\tbreak;\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixElementFill:\n\t\t has_wmma_return_values = impl.ags.num_instructions == 13;\n\t\t if (has_wmma_return_values)\n\t\t {\n\t\t\t type_id = build_coopmat_type(impl, impl.ags.instructions[4].immediate, false);\n\t\t\t // FSR4 workaround for RDNA3.\n\t\t\t analyze_dubious_implementation_defined_column_behavior(\n\t\t\t     impl, impl.ags.backdoor_instructions[4]->getOperand(6));\n\t\t\t phase = 2;\n\t\t }\n\t\t break;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (has_wmma_return_values)\n\t\treturn emit_wmma_return_values(impl, type_id, 0, phase);\n\telse\n\t\treturn true;\n}\n\nbool emit_magic_ags_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tpush_ags_instruction(impl, instruction);\n\n\t// We might be able to retire an instruction now.\n\t// Only support exactly what we need to support. Anything else will fail compilation.\n\tif (impl.ags.num_instructions == 0)\n\t\treturn true;\n\n\tswitch (impl.ags.instructions[0].opcode)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsOpcode_Readfirstlane:\n\t{\n\t\t// Don't bother with all the weird special cases.\n\t\tauto *op = impl.allocate(spv::OpGroupNonUniformBroadcastFirst, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(5)));\n\n\t\timpl.add(op);\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t\timpl.ags.num_instructions = 0;\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_Readlane:\n\t{\n\t\tauto *op = impl.allocate(spv::OpGroupNonUniformBroadcast, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(5)));\n\t\top->add_id(builder.makeUintConstant(impl.ags.instructions[0].immediate));\n\n\t\timpl.add(op);\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t\timpl.ags.num_instructions = 0;\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_LaneId:\n\t{\n\t\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSubgroupLocalInvocationId);\n\t\tauto *load_op = impl.allocate(spv::OpLoad, instruction);\n\t\tload_op->add_id(var_id);\n\t\timpl.add(load_op);\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\t\timpl.ags.num_instructions = 0;\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_DrawIndex:\n\t{\n\t\tspv::Id draw_index_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInDrawIndex);\n\t\tbuilder.addCapability(spv::CapabilityDrawParameters);\n\n\t\tauto *op = impl.allocate(spv::OpLoad, instruction);\n\t\top->add_id(draw_index_id);\n\t\timpl.add(op);\n\t\timpl.ags.num_instructions = 0;\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_AtomicU64:\n\t{\n\t\tspv::Op atomic_op = spv::OpNop;\n\t\tif (impl.ags.num_instructions == 3)\n\t\t{\n\t\t\tswitch (impl.ags.instructions[0].immediate)\n\t\t\t{\n\t\t\tcase AmdExtD3DShaderIntrinsicsAtomicOp_MaxU64:\n\t\t\t\tatomic_op = spv::OpAtomicUMax;\n\t\t\t\tbreak;\n\t\t\tcase AmdExtD3DShaderIntrinsicsAtomicOp_MinU64:\n\t\t\t\tatomic_op = spv::OpAtomicUMin;\n\t\t\t\tbreak;\n\t\t\tcase AmdExtD3DShaderIntrinsicsAtomicOp_AddU64:\n\t\t\t\tatomic_op = spv::OpAtomicIAdd;\n\t\t\t\tbreak;\n\t\t\tcase AmdExtD3DShaderIntrinsicsAtomicOp_XorU64:\n\t\t\t\tatomic_op = spv::OpAtomicXor;\n\t\t\t\tbreak;\n\t\t\tcase AmdExtD3DShaderIntrinsicsAtomicOp_OrU64:\n\t\t\t\tatomic_op = spv::OpAtomicOr;\n\t\t\t\tbreak;\n\t\t\tcase AmdExtD3DShaderIntrinsicsAtomicOp_AndU64:\n\t\t\t\tatomic_op = spv::OpAtomicAnd;\n\t\t\t\tbreak;\n\t\t\tcase AmdExtD3DShaderIntrinsicsAtomicOp_XchgU64:\n\t\t\t\tatomic_op = spv::OpAtomicExchange;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// CmpXchg isn't hard to support, just need to modify the impl a bit, but only care if we have to.\n\t\t\t\tLOGE(\"Unsupported AGS AtomicU64 variant: immediate %u.\\n\", impl.ags.instructions[0].immediate);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool ret = false;\n\n\t\t\t// Magic 64-bit image atomics.\n\t\t\tif ((impl.ags.active_uav_op == DXIL::Op::TextureStore ||\n\t\t\t     impl.ags.active_uav_op == DXIL::Op::BufferStore) && impl.ags.active_uav_ptr)\n\t\t\t{\n\t\t\t\tret = emit_magic_ags_atomic_u64(impl, impl.ags.active_uav_ptr, atomic_op, instruction);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tLOGE(\"Attempting to use AGS U64 atomic on unknown resource type.\\n\");\n\t\t\t}\n\n\t\t\timpl.ags.num_instructions = 0;\n\t\t\treturn ret;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavLoad:\n\t{\n\t\tif (impl.ags.num_instructions == 10)\n\t\t{\n\t\t\tif (!emit_wmma_load(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavStore:\n\t{\n\t\tif (impl.ags.num_instructions == 6)\n\t\t{\n\t\t\tif (!emit_wmma_store(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixCopy:\n\t{\n\t\tif (impl.ags.current_phase == 1)\n\t\t{\n\t\t\tif (impl.ags.num_instructions > 5)\n\t\t\t{\n\t\t\t\t// Apparently some shaders encode dummy inputs? Shift away useless stuff either way.\n\t\t\t\tmemmove(impl.ags.instructions, impl.ags.instructions + (impl.ags.num_instructions - 5),\n\t\t\t\t        5 * sizeof(impl.ags.instructions[0]));\n\t\t\t\tmemmove(impl.ags.backdoor_instructions, impl.ags.backdoor_instructions + (impl.ags.num_instructions - 5),\n\t\t\t\t        5 * sizeof(impl.ags.backdoor_instructions[0]));\n\t\t\t\timpl.ags.num_instructions = 5;\n\t\t\t}\n\t\t}\n\n\t\tif (impl.ags.num_instructions == 13)\n\t\t{\n\t\t\tif (!emit_wmma_convert(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLdsLoad:\n\t{\n\t\tif (impl.ags.num_instructions == 10)\n\t\t{\n\t\t\tif (!emit_wmma_load(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLdsStore:\n\t{\n\t\tif (impl.ags.num_instructions == 6)\n\t\t{\n\t\t\tif (!emit_wmma_store(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixMulAcc:\n\t{\n\t\tif (impl.ags.num_instructions == 21)\n\t\t{\n\t\t\tif (!emit_wmma_muladd(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixFill:\n\t{\n\t\tif (impl.ags.num_instructions == 9)\n\t\t{\n\t\t\tif (!emit_wmma_fill(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixElementFill:\n\t{\n\t\tif (impl.ags.num_instructions == 13)\n\t\t{\n\t\t\tif (!emit_wmma_element_insert(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLength:\n\t{\n\t\tif (!emit_wmma_length(impl))\n\t\t\treturn false;\n\t\timpl.ags.num_instructions = 0;\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixElementExtract:\n\t{\n\t\tif (impl.ags.num_instructions == 5)\n\t\t{\n\t\t\tif (!emit_wmma_element_extract(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_MatrixElementWiseArithmetic:\n\t{\n\t\tif (impl.ags.num_instructions == 17)\n\t\t{\n\t\t\tif (!emit_wmma_element_wise_arith(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase AmdExtD3DShaderIntrinsicsOpcode_Float8Conversion:\n\t{\n\t\tif (impl.ags.num_instructions == 1)\n\t\t{\n\t\t\tif (!emit_float8_conversion(impl))\n\t\t\t\treturn false;\n\t\t\timpl.ags.num_instructions = 0;\n\t\t}\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tLOGE(\"Unsupported AGS magic instruction 0x%x (immediate %u).\\n\",\n\t\t     impl.ags.instructions[0].opcode,\n\t\t     impl.ags.instructions[0].immediate);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nvoid push_ags_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tuint32_t op = 0;\n\tif (!get_constant_operand(instruction, 2, &op))\n\t\treturn;\n\n\tif (!is_ags_magic(op))\n\t\treturn;\n\n\tauto inst = decode_ags_instruction(op);\n\n\tswitch (inst.opcode)\n\t{\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavLoad:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavStore:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixCopy:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLdsLoad:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLdsStore:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixMulAcc:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixFill:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixElementFill:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLength:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixElementExtract:\n\tcase AmdExtD3DShaderIntrinsicsOpcode_MatrixElementWiseArithmetic:\n\t\timpl.shader_analysis.require_subgroups = true;\n\t\timpl.shader_analysis.require_wmma = true;\n\t\tbreak;\n\t}\n\n\tauto &ags = impl.ags;\n\n\t// Reset if we're beginning a new instruction sequence.\n\t// New instruction type, reset.\n\tif (inst.phase < ags.current_phase ||\n\t    (ags.num_instructions && inst.opcode != ags.instructions[0].opcode))\n\t{\n\t\tags.reset();\n\t}\n\n\tif ((inst.phase == ags.current_phase || (inst.phase == ags.current_phase + 1)) &&\n\t    inst.phase <= ags.num_instructions &&\n\t    ags.num_instructions < AgsInstruction::MaxInstructions)\n\t{\n\t\tags.instructions[ags.num_instructions] = inst;\n\t\tags.backdoor_instructions[ags.num_instructions] = instruction;\n\t\tags.num_instructions++;\n\t\tags.current_phase = inst.phase;\n\t}\n}\n\n// This is done early to keep track of which resources are supposed to be redirected to AGS\n// when dealing with buffer stores, etc.\nbool analyze_prepass_ags_dxil_atomic_op(Converter::Impl &impl, const llvm::CallInst *instruction, uint32_t resource_index)\n{\n\t// Special magic.\n\tif (resource_index == impl.ags.uav_magic_resource_type_index &&\n\t    value_is_dx_op_instrinsic(instruction, DXIL::Op::AtomicCompareExchange))\n\t{\n\t\tpush_ags_instruction(impl, instruction);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// This is done later where we do a more complex analysis.\nbool analyze_ags_dxil_cmpxchg_op(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t{\n\t\t// Special magic.\n\t\tif (itr->second == impl.ags.uav_magic_resource_type_index &&\n\t\t    value_is_dx_op_instrinsic(instruction, DXIL::Op::AtomicCompareExchange))\n\t\t{\n\t\t\tpush_ags_instruction(impl, instruction);\n\t\t\tif (!analyze_magic_ags_instruction(impl))\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool analyze_ags_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, AccessTracking *tracking)\n{\n\tif (impl.ags.num_instructions == 1)\n\t{\n\t\tif (instruction->getOperand(2) == impl.ags.backdoor_instructions[0])\n\t\t{\n\t\t\tswitch (impl.ags.instructions[0].opcode)\n\t\t\t{\n\t\t\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavStore:\n\t\t\t\ttracking->has_written = true;\n\t\t\t\tbreak;\n\n\t\t\tcase AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavLoad:\n\t\t\t\ttracking->has_read = true;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Be byte oriented.\n\t\t\ttracking->raw_access_buffer_declarations[int(RawType::Integer)][int(RawWidth::B8)][int(RawVecSize::V1)] = true;\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid analyze_ags_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction,\n                              AccessTracking *tracking, DXIL::Op opcode)\n{\n\t// Detect 64-bit atomics.\n\tif (impl.ags.num_instructions == 2 && impl.ags.backdoor_instructions[0] == instruction->getOperand(2))\n\t{\n\t\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\t\ttracking->has_atomic = true;\n\t\ttracking->has_read = true;\n\t\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t\t{\n\t\t\timpl.ags.active_uav_index = itr->second;\n\t\t\timpl.ags.active_uav_op = opcode;\n\t\t}\n\n\t\t// Mark 64-bit usage.\n\t\tif (opcode != DXIL::Op::TextureStore && opcode != DXIL::Op::TextureStoreSample)\n\t\t\ttracking->raw_access_buffer_declarations[int(RawType::Integer)][int(RawWidth::B64)][int(RawVecSize::V1)] = true;\n\t\telse\n\t\t\ttracking->has_atomic_64bit = true;\n\t}\n}\n\nbool emit_ags_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, DXIL::Op opcode)\n{\n\tif (impl.ags.num_instructions == 1)\n\t{\n\t\tif (instruction->getOperand(2) == impl.ags.backdoor_instructions[0])\n\t\t{\n\t\t\timpl.ags.active_uav_ptr = impl.get_id_for_value(instruction->getOperand(1));\n\t\t\timpl.ags.active_uav_op = opcode;\n\t\t\timpl.ags.active_read_backdoor = instruction;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool emit_ags_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id)\n{\n\t// Deferred 64-bit atomic. Resolve in a later AGS atomic.\n\tif (impl.ags.num_instructions == 2 && impl.ags.backdoor_instructions[0] == instruction->getOperand(2))\n\t{\n\t\timpl.ags.active_uav_ptr = id;\n\t\timpl.ags.active_uav_op = DXIL::Op::BufferStore;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_ags_texture_store(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id, bool multi_sampled)\n{\n\tif (impl.ags.num_instructions == 2 &&\n\t    impl.ags.backdoor_instructions[0] == instruction->getOperand(2) && !multi_sampled)\n\t{\n\t\timpl.ags.active_uav_ptr = id;\n\t\timpl.ags.active_uav_op = DXIL::Op::TextureStore;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_ags_resource_uav_handle(Converter::Impl &impl, const llvm::CallInst *instruction, uint32_t resource_range)\n{\n\tif (resource_range == impl.ags.uav_magic_resource_type_index)\n\t{\n\t\t// Resources tied to constant uints are considered \"magic\".\n\t\tif (impl.ags.magic_ptr_id == 0)\n\t\t{\n\t\t\tspv::Id dummy_value = impl.spirv_module.allocate_id();\n\t\t\timpl.ags.magic_ptr_id = dummy_value;\n\t\t}\n\n\t\timpl.rewrite_value(instruction, impl.ags.magic_ptr_id);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool ags_llvm_load_filter(Converter::Impl &impl, Operation *op, const llvm::LoadInst *instruction)\n{\n\t// Only load if it's the first element.\n\tauto component_itr = impl.ags.coopmat_component_mapping.find(instruction->getPointerOperand());\n\tif (component_itr != impl.ags.coopmat_component_mapping.end())\n\t{\n\t\top->type_id = component_itr->second.type_id;\n\t\timpl.ags.coopmat_component_mapping[instruction] = component_itr->second;\n\t\tif (component_itr->second.component != 0)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_ags_extract_value(Converter::Impl &impl, const llvm::ExtractValueInst *instruction)\n{\n\tif (instruction->getAggregateOperand() == impl.ags.active_read_backdoor)\n\t{\n\t\timpl.ags.active_read_backdoor = instruction;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool ags_alloca_or_global_filter(Converter::Impl &impl, const llvm::Value *value, spv::Id &pointee_type_id)\n{\n\tauto ags_itr = impl.ags.alloca_or_global_tracking.find(value);\n\n\tif (ags_itr != impl.ags.alloca_or_global_tracking.end() && ags_itr->second.override_element_type)\n\t{\n\t\tauto *element_type = value->getType()->getPointerElementType();\n\t\tuint32_t elems = element_type->getArrayNumElements();\n\t\tif (ags_itr->second.override_element_stride == 0)\n\t\t{\n\t\t\tLOGE(\"Element stride is currently unknown. Something must have been missed during analysis.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tpointee_type_id = impl.builder().makeArrayType(\n\t\t    ags_itr->second.override_element_type,\n\t\t    impl.builder().makeUintConstant(elems / ags_itr->second.override_element_stride), 0);\n\t}\n\n\treturn pointee_type_id != 0;\n}\n\nbool emit_ags_atomicrmw(Converter::Impl &impl, const llvm::AtomicRMWInst *instruction)\n{\n\tif (instruction->getPointerOperand() == impl.ags.active_read_backdoor)\n\t{\n\t\timpl.ags.active_read_backdoor = instruction;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_ags_getelementptr(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction)\n{\n\tif (impl.ags.num_instructions == 1)\n\t{\n\t\tif (instruction->getOperand(2) == impl.ags.backdoor_instructions[0] &&\n\t\t    DXIL::AddressSpace(instruction->getOperand(0)->getType()->getPointerAddressSpace()) ==\n\t\t    DXIL::AddressSpace::GroupShared)\n\t\t{\n\t\t\timpl.ags.active_uav_ptr = impl.get_id_for_value(instruction->getOperand(0));\n\t\t\t// Dummy, signal LDS operation.\n\t\t\timpl.ags.active_uav_op = DXIL::Op::AtomicBinOp;\n\t\t\timpl.ags.active_read_backdoor = instruction;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid ags_getelementptr_filter(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction, spv::Id &type_id)\n{\n\tif (const auto *value = get_underlying_gep_array(instruction))\n\t{\n\t\tauto override_itr = impl.ags.alloca_or_global_tracking.find(value);\n\t\tif (override_itr != impl.ags.alloca_or_global_tracking.end() && override_itr->second.override_element_type)\n\t\t\ttype_id = override_itr->second.override_element_type;\n\t}\n}\n\nstatic spv::Id ags_build_cexpr_gep(Converter::Impl &impl, const llvm::Value *load_store_pointer, spv::Id &type_id,\n                                   uint32_t &split_elem)\n{\n\tif (auto *value = get_underlying_gep_array(llvm::dyn_cast<llvm::ConstantExpr>(load_store_pointer)))\n\t{\n\t\tauto itr = impl.ags.alloca_or_global_tracking.find(value);\n\t\tif (itr != impl.ags.alloca_or_global_tracking.end() && itr->second.override_element_type)\n\t\t{\n\t\t\tauto &builder = impl.builder();\n\n\t\t\ttype_id = itr->second.override_element_type;\n\t\t\tauto *cexpr = llvm::cast<llvm::ConstantExpr>(load_store_pointer);\n\n\t\t\tauto split = split_index_scale_bias(cexpr->getOperand(2));\n\t\t\tif (!split.stride)\n\t\t\t\treturn 0;\n\t\t\tif (split.stride != UINT32_MAX && split.stride != itr->second.override_element_stride)\n\t\t\t\treturn 0;\n\n\t\t\tuint32_t const_index = 0;\n\n\t\t\tif (split.stride == UINT32_MAX && itr->second.override_element_stride && !split.index)\n\t\t\t{\n\t\t\t\tconst_index = split.elem / itr->second.override_element_stride;\n\t\t\t\tsplit.elem -= const_index * itr->second.override_element_stride;\n\t\t\t}\n\n\t\t\tsplit_elem = split.elem;\n\n\t\t\t// If we're writing anything other than the first element, skip the actual write.\n\t\t\tif (split.elem != 0)\n\t\t\t\treturn UINT32_MAX;\n\n\t\t\tspv::Id index_id = 0;\n\n\t\t\tif (split.index)\n\t\t\t\tindex_id = impl.get_id_for_value(split.index);\n\t\t\telse\n\t\t\t\tindex_id = impl.builder().makeUintConstant(const_index);\n\n\t\t\tauto *chain = impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassPrivate, type_id));\n\t\t\tchain->add_id(impl.get_id_for_value(cexpr->getOperand(0)));\n\t\t\tchain->add_id(index_id);\n\t\t\timpl.add(chain);\n\t\t\treturn chain->id;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nbool ags_llvm_load_filter_cexpr(Converter::Impl &impl, const llvm::LoadInst *instruction)\n{\n\tif (!impl.shader_analysis.require_wmma)\n\t\treturn false;\n\n\tuint32_t split_elem = 0;\n\tspv::Id type_id = 0;\n\tspv::Id ptr_id = ags_build_cexpr_gep(impl, instruction->getPointerOperand(), type_id, split_elem);\n\n\tif (ptr_id != 0)\n\t\timpl.ags.coopmat_component_mapping[instruction] = { type_id, split_elem };\n\n\tif (ptr_id != 0 && ptr_id != UINT32_MAX)\n\t{\n\t\tauto *load = impl.allocate(spv::OpLoad, instruction, type_id);\n\t\tload->add_id(ptr_id);\n\t\timpl.add(load);\n\t}\n\n\treturn ptr_id != 0;\n}\n\nbool ags_store_filter(Converter::Impl &impl, const llvm::StoreInst *instruction)\n{\n\tif (!impl.shader_analysis.require_wmma)\n\t\treturn false;\n\n\tuint32_t split_elem = 0;\n\tspv::Id type_id = 0;\n\tspv::Id ptr_id = ags_build_cexpr_gep(impl, instruction->getOperand(1), type_id, split_elem);\n\n\tif (ptr_id != 0 && ptr_id != UINT32_MAX)\n\t{\n\t\tauto *store = impl.allocate(spv::OpStore);\n\t\tstore->add_id(ptr_id);\n\t\tstore->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\t\timpl.add(store);\n\t}\n\n\treturn ptr_id != 0;\n}\n\nbool ags_filter_phi(Converter::Impl &impl, const llvm::PHINode &instruction, spv::Id &override_type)\n{\n\tfor (uint32_t i = 0; i < instruction.getNumIncomingValues() && override_type == 0; i++)\n\t{\n\t\tauto *incoming = instruction.getIncomingValue(i);\n\t\tauto itr = impl.ags.coopmat_component_mapping.find(incoming);\n\t\tif (itr != impl.ags.coopmat_component_mapping.end())\n\t\t{\n\t\t\toverride_type = itr->second.type_id;\n\t\t\timpl.ags.coopmat_component_mapping[&instruction] = { override_type, itr->second.component };\n\t\t\tif (itr->second.component != 0)\n\t\t\t{\n\t\t\t\t// Dummy value, will not actually emit a PHI. Just need to forward the mapping.\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n}\n"
  },
  {
    "path": "opcodes/dxil/dxil_ags.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n*\n* SPDX-License-Identifier: MIT\n*\n* Permission is hereby granted, free of charge, to any person obtaining\n* a copy of this software and associated documentation files (the\n* \"Software\"), to deal in the Software without restriction, including\n* without limitation the rights to use, copy, modify, merge, publish,\n* distribute, sublicense, and/or sell copies of the Software, and to\n* permit persons to whom the Software is furnished to do so, subject to\n* the following conditions:\n*\n* The above copyright notice and this permission notice shall be\n* included in all copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#pragma once\n\n#include <stdint.h>\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\n// From https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/blob/master/ags_lib/hlsl/ags_shader_intrinsics_dx12.hlsl\n\n//\n// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n\nstatic constexpr uint32_t AgsUAVMagicRegisterSpace = 2147420894;\n\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_MagicCodeShift   = 28;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_MagicCodeMask    = 0xf;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_OpcodePhaseShift = 24;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_OpcodePhaseMask  = 0x3;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_DataShift        = 8;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_DataMask         = 0xffff;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_OpcodeShift      = 0;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_OpcodeMask       = 0xff;\n\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsics_MagicCode        = 0x5;\n\n\n/**\n***********************************************************************************************************************\n*   Intrinsic opcodes.\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Readfirstlane          = 0x01;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Readlane               = 0x02;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_LaneId                 = 0x03;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Swizzle                = 0x04;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Ballot                 = 0x05;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_MBCnt                  = 0x06;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Min3U                  = 0x07;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Min3F                  = 0x08;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Med3U                  = 0x09;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Med3F                  = 0x0a;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Max3U                  = 0x0b;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Max3F                  = 0x0c;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_BaryCoord              = 0x0d;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_VtxParam               = 0x0e;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Reserved1              = 0x0f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Reserved2              = 0x10;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Reserved3              = 0x11;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveReduce             = 0x12;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveScan               = 0x13;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_LoadDwAtAddr           = 0x14;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_DrawIndex              = 0x17;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_AtomicU64              = 0x18;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_GetWaveSize            = 0x19;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_BaseInstance           = 0x1a;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_BaseVertex             = 0x1b;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_FloatConversion        = 0x1c;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_ReadlaneAt             = 0x1d;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_ShaderClock            = 0x1f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_ShaderRealtimeClock    = 0x20;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Halt                   = 0x21;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_IntersectBvhNode            = 0x22;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_BufferStoreByte             = 0x23;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_BufferStoreShort            = 0x24;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_ShaderMarker                = 0x25;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_FloatOpWithRoundMode        = 0x26;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Reserved5                   = 0x27;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixMulAcc            = 0x28;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavLoad           = 0x29;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixUavStore          = 0x2a;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixGlobalLoad        = 0x2b;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixGlobalStore       = 0x2c;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLdsLoad           = 0x2d;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLdsStore          = 0x2e;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixElementFill       = 0x2f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixElementExtract    = 0x30;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixLength            = 0x31;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixCopy              = 0x32;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_WaveMatrixFill              = 0x33;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_MatrixSparsityIndexLoad     = 0x34;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_MatrixElementWiseArithmetic = 0x35;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_Float8Conversion            = 0x36;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_BuiltIn1                    = 0x37;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_BuiltInArg                  = 0x38;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcode_LastValidOpcode             = 0x38;\n/**\n***********************************************************************************************************************\n*   Intrinsic opcode phases.\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcodePhase_0   = 0x0;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcodePhase_1   = 0x1;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcodePhase_2   = 0x2;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsOpcodePhase_3   = 0x3;\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsWaveOp defines for supported operations. Can be used as the parameter for the\n*   AmdExtD3DShaderIntrinsicsOpcode_WaveOp intrinsic.\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_AddF = 0x01;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_AddI = 0x02;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_AddU = 0x03;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MulF = 0x04;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MulI = 0x05;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MulU = 0x06;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MinF = 0x07;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MinI = 0x08;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MinU = 0x09;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MaxF = 0x0a;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MaxI = 0x0b;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_MaxU = 0x0c;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_And  = 0x0d;    // Reduction only\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_Or   = 0x0e;    // Reduction only\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_Xor  = 0x0f;    // Reduction only\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsWaveOp masks and shifts for opcode and flags\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift = 0;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_OpcodeMask  = 0xff;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_FlagShift   = 8;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_FlagMask    = 0xff;\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsWaveOp flags for use with AmdExtD3DShaderIntrinsicsOpcode_WaveScan.\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_Inclusive  = 0x01;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsWaveOp_Exclusive  = 0x02;\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsSwizzle defines for common swizzles.  Can be used as the operation parameter for the\n*   AmdExtD3DShaderIntrinsics_Swizzle intrinsic.\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_SwapX1     = 0x041f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_SwapX2     = 0x081f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_SwapX4     = 0x101f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_SwapX8     = 0x201f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_SwapX16    = 0x401f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_ReverseX2  = 0x041f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_ReverseX4  = 0x0c1f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_ReverseX8  = 0x1c1f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_ReverseX16 = 0x3c1f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_ReverseX32 = 0x7c1f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_BCastX2    = 0x003e;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_BCastX4    = 0x003c;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_BCastX8    = 0x0038;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_BCastX16   = 0x0030;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsSwizzle_BCastX32   = 0x0020;\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsBarycentric defines for barycentric interpolation mode.  To be used with\n*   AmdExtD3DShaderIntrinsicsOpcode_IjBarycentricCoords to specify the interpolation mode.\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_LinearCenter   = 0x1;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_LinearCentroid = 0x2;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_LinearSample   = 0x3;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_PerspCenter    = 0x4;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_PerspCentroid  = 0x5;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_PerspSample    = 0x6;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_PerspPullModel = 0x7;\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsBarycentric defines for specifying vertex and parameter indices.  To be used as inputs to\n*   the AmdExtD3DShaderIntrinsicsOpcode_VertexParameter function\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Vertex0       = 0x0;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Vertex1       = 0x1;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Vertex2       = 0x2;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param0        = 0x00;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param1        = 0x01;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param2        = 0x02;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param3        = 0x03;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param4        = 0x04;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param5        = 0x05;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param6        = 0x06;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param7        = 0x07;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param8        = 0x08;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param9        = 0x09;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param10       = 0x0a;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param11       = 0x0b;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param12       = 0x0c;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param13       = 0x0d;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param14       = 0x0e;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param15       = 0x0f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param16       = 0x10;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param17       = 0x11;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param18       = 0x12;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param19       = 0x13;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param20       = 0x14;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param21       = 0x15;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param22       = 0x16;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param23       = 0x17;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param24       = 0x18;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param25       = 0x19;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param26       = 0x1a;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param27       = 0x1b;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param28       = 0x1c;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param29       = 0x1d;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param30       = 0x1e;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_Param31       = 0x1f;\n\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ComponentX     = 0x0;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ComponentY     = 0x1;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ComponentZ     = 0x2;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ComponentW     = 0x3;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ParamShift     = 0;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ParamMask      = 0x1f;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_VtxShift       = 0x5;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_VtxMask        = 0x3;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ComponentShift = 0x7;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsBarycentric_ComponentMask  = 0x3;\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsAtomic defines for supported operations. Can be used as the parameter for the\n*   AmdExtD3DShaderIntrinsicsOpcode_AtomicU64 intrinsic.\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_MinU64     = 0x01;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_MaxU64     = 0x02;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_AndU64     = 0x03;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_OrU64      = 0x04;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_XorU64     = 0x05;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_AddU64     = 0x06;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_XchgU64    = 0x07;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsAtomicOp_CmpXchgU64 = 0x08;\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsFloatConversion defines for supported rounding modes from float to float16 conversions.\n*   To be used as an input AmdExtD3DShaderIntrinsicsOpcode_FloatConversion instruction\n***********************************************************************************************************************\n*/\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16Near    = 0x01;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16NegInf  = 0x02;\nstatic constexpr uint32_t AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16PlusInf = 0x03;\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsFloat8CvtOp enumeration to specify the conversion operation\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsFloat8CvtOp\n{\n\tAmdExtD3DShaderIntrinsicsFloat8CvtOp_FP8_2_F32 = 0x0,\n\tAmdExtD3DShaderIntrinsicsFloat8CvtOp_BF8_2_F32 = 0x1,\n\tAmdExtD3DShaderIntrinsicsFloat8CvtOp_F32_2_FP8 = 0x2,\n\tAmdExtD3DShaderIntrinsicsFloat8CvtOp_F32_2_BF8 = 0x3,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    Shifts and masks for the arguments required for AmdExtD3DShaderIntrinsicsFloat8Conversion\n***********************************************************************************************************************\n*/\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsFloat8Conversion_CvtOpShift = 0;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsFloat8Conversion_CvtOpMask  = 0xff;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsFloat8Conversion_SatShift   = 8;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsFloat8Conversion_SatMask    = 0x1;\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsWaveMatrixDataFormat enumeration for supported matrix element data format.\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsWaveMatrixOpDataFormat\n{\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_I4   = 0x0,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_U4   = 0x1,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_I8   = 0x2,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_U8   = 0x3,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F16  = 0x4,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_BF16 = 0x5,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_F32  = 0x6,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_I32  = 0x7,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_U32  = 0x8,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_BF8  = 0x9,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixDataFormat_FP8  = 0xa,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsWaveMatrixType enumeration for supported wave matrix type.\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsWaveMatrixOpMatrixType\n{\n\tAmdExtD3DShaderIntrinsicsWaveMatrixType_A            = 0x0,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixType_B            = 0x1,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixType_Accumulator  = 0x2,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsWaveMatrixMatrixShape enumeration for supported wave matrix shape.\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsWaveMatrixOpMatrixShape\n{\n\tAmdExtD3DShaderIntrinsicsWaveMatrixShape_16X16 = 0x0,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixShape_32X16 = 0x1,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixShape_16X32 = 0x2,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixShape_64X16 = 0x3,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsWaveMatrixOpcode enumeration to specify the wmma inst opcode.\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsWaveMatrixOpcode\n{\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_BF16_16X16X16_BF16     = 0x0,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F16_16X16X16_F16       = 0x1,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_BF16      = 0x2,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_BF8_BF8   = 0x3,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_BF8_FP8   = 0x4,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_F16       = 0x5,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_FP8_BF8   = 0x6,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_F32_16X16X16_FP8_FP8   = 0x7,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_I4        = 0x8,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_U4        = 0x9,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_IU4       = 0xa,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_UI4       = 0xb,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_I8        = 0xc,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_U8        = 0xd,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_IU8       = 0xe,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X16_UI8       = 0xf,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X32_I4        = 0x10,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X32_U4        = 0x11,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X32_IU4       = 0x12,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_WMMA_I32_16X16X32_UI4       = 0x13,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_BF16_16X16X32_BF16    = 0x14,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_F16_16X16X32_F16      = 0x15,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_F32_16X16X32_BF16     = 0x16,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_F32_16X16X32_BF8_BF8  = 0x17,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_F32_16X16X32_BF8_FP8  = 0x18,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_F32_16X16X32_F16      = 0x19,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_F32_16X16X32_FP8_BF8  = 0x1a,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_F32_16X16X32_FP8_FP8  = 0x1b,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_I4       = 0x1c,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_U4       = 0x1d,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_IU4      = 0x1e,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_UI4      = 0x1f,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_I8       = 0x20,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_U8       = 0x21,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_IU8      = 0x22,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X32_UI8      = 0x23,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X64_I4       = 0x24,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X64_U4       = 0x25,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X64_IU4      = 0x26,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixOpcode_SWMMA_I32_16X16X64_UI4      = 0x27,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsWaveMatrixRegType enumeration to specify the temp register.\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsWaveMatrixRegType\n{\n\tAmdExtD3DShaderIntrinsicsWaveMatrixRegType_RetVal_Reg          = 0x0,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixRegType_A_TempReg           = 0x1,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixRegType_B_TempReg           = 0x2,\n\tAmdExtD3DShaderIntrinsicsWaveMatrixRegType_Accumulator_TempReg = 0x3,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsMatrixElementWiseOp enumeration to specify the element-wise operation\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsMatrixElementWiseOp\n{\n\tAmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Add   = 0x1,\n\tAmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Sub   = 0x2,\n\tAmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Mul   = 0x3,\n\tAmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Div   = 0x4,\n\tAmdExtD3DShaderIntrinsicsMatrixElementWiseOp_Times = 0x5,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsSparsityIndexMem enumeration is used to specify where to read sparsity indexes.\n***********************************************************************************************************************\n*/\nenum AmdExtD3DShaderIntrinsicsSparsityIndexMem\n{\n\tAmdExtD3DShaderIntrinsicsSparsityIndexMem_UavBuffer    = 0x0,\n\tAmdExtD3DShaderIntrinsicsSparsityIndexMem_GroupShared  = 0x1,\n\tAmdExtD3DShaderIntrinsicsSparsityIndexMem_GlobalBuffer = 0x2,\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    Shifts and masks for the arguments required for AmdExtD3DShaderIntrinsicsWaveMatrixOpcode\n***********************************************************************************************************************\n*/\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_OpsShift  = 0;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_OpsMask   = 0x7f;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_FlagShift = 15;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixOpcode_FlagMask  = 0x1;\n\n/**\n***********************************************************************************************************************\n* @brief\n*    Shifts and masks for the arguments required for AmdExtD3DShaderIntrinsicsWaveMatrixOpInOut\n***********************************************************************************************************************\n*/\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixInOut_ChannelShift        = 0;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixInOut_ChannelMask         = 0xf;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixInOut_SecondRegFlagShift  = 4;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixInOut_SecondRegFlagMask   = 0xf;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixInOut_MatRegTypeFlagShift = 8;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixInOut_MatRegTypeFlagMask  = 0xff;\n\n/**\n***********************************************************************************************************************\n* @brief\n*    Shifts and masks for the arguments required for AmdExtD3DShaderIntrinsicsWaveMatrixModifier\n***********************************************************************************************************************\n*/\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_DataFormatFlagShift = 0;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_DataFormatFlagMask  = 0xf;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagShift = 4;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTypeFlagMask  = 0x7;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_LayoutFlagShift     = 7;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_LayoutFlagMask      = 0x1;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_ShapeShift          = 8;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_ShapeMask           = 0x7;\n// Following flags only apply to AmdExtD3DShaderIntrinsicsOpcode_WaveMatrix*Load\n// and AmdExtD3DShaderIntrinsicsOpcode_WaveMatrix*Store\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTileShift     = 11;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_MatrixTileMask      = 0x1;\n// Following flags only apply to AmdExtD3DShaderIntrinsicsOpcode_MatrixSparsityIndexLoad\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_IndexMemTypeShift   = 14;\nconstexpr unsigned int AmdExtD3DShaderIntrinsicsWaveMatrixModifier_IndexMemTypeMask    = 0x3;\n\nstatic inline bool is_ags_magic(uint32_t v)\n{\n\treturn (v >> AmdExtD3DShaderIntrinsics_MagicCodeShift) == AmdExtD3DShaderIntrinsics_MagicCode;\n}\n\nstatic inline AgsInstruction decode_ags_instruction(uint32_t v)\n{\n\tAgsInstruction inst = {};\n\n\tinst.opcode = (v >> AmdExtD3DShaderIntrinsics_OpcodeShift) & AmdExtD3DShaderIntrinsics_OpcodeMask;\n\tinst.phase = (v >> AmdExtD3DShaderIntrinsics_OpcodePhaseShift) & AmdExtD3DShaderIntrinsics_OpcodePhaseMask;\n\tinst.immediate = (v >> AmdExtD3DShaderIntrinsics_DataShift) & AmdExtD3DShaderIntrinsics_DataMask;\n\n\treturn inst;\n}\n\nbool emit_magic_ags_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool analyze_magic_ags_instruction(Converter::Impl &impl);\nbool analyze_ags_wmma_store(Converter::Impl &impl, const llvm::StoreInst *store);\nspv::Id rewrite_alloca_gep_index(Converter::Impl &impl, const llvm::GetElementPtrInst *gep, spv::Id id);\nbool wmma_store_is_masked(Converter::Impl &impl, const llvm::StoreInst *inst);\n\nvoid push_ags_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool analyze_prepass_ags_dxil_atomic_op(Converter::Impl &impl, const llvm::CallInst *instruction, uint32_t resource_index);\nbool analyze_ags_dxil_cmpxchg_op(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nstruct AccessTracking;\nbool analyze_ags_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, AccessTracking *tracking);\nvoid analyze_ags_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction, AccessTracking *tracking, DXIL::Op opcode);\n\nbool emit_ags_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, DXIL::Op opcode);\nbool emit_ags_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id);\nbool emit_ags_texture_store(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id, bool multi_sampled);\n\nbool emit_ags_resource_uav_handle(Converter::Impl &impl, const llvm::CallInst *instruction, uint32_t resource_range);\n\nbool ags_llvm_load_filter(Converter::Impl &impl, Operation *op, const llvm::LoadInst *instruction);\nbool ags_llvm_load_filter_cexpr(Converter::Impl &impl, const llvm::LoadInst *instruction);\nbool emit_ags_extract_value(Converter::Impl &impl, const llvm::ExtractValueInst *instruction);\nbool emit_ags_atomicrmw(Converter::Impl &impl, const llvm::AtomicRMWInst *instruction);\nbool emit_ags_getelementptr(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction);\nbool ags_store_filter(Converter::Impl &impl, const llvm::StoreInst *instruction);\nbool ags_alloca_or_global_filter(Converter::Impl &impl, const llvm::Value *value, spv::Id &pointee_type_id);\nvoid ags_getelementptr_filter(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction, spv::Id &type_id);\n\nbool ags_filter_phi(Converter::Impl &impl, const llvm::PHINode &instruction, spv::Id &override_type);\n\nstruct AGSCoopMatMapping\n{\n\tspv::Id type_id;\n\tuint32_t component;\n};\n\nstruct AllocaAGSForwardingTracking\n{\n\t// For AGS WMMA rewrites.\n\tspv::Id override_element_type = 0;\n\tuint32_t override_element_stride = 0;\n};\n\nstruct AGSState\n{\n\t// For magic resource types, assume there is one globally declared dummy resource.\n\t// Don't conflict with sentinel index for SM 6.6 heap.\n\tuint32_t uav_magic_resource_type_index = UINT32_MAX - 1;\n\tspv::Id magic_ptr_id = 0;\n\tuint32_t active_uav_index = 0;\n\tspv::Id active_uav_ptr = 0;\n\tDXIL::Op active_uav_op;\n\tAgsInstruction instructions[AgsInstruction::MaxInstructions];\n\tconst llvm::CallInst *backdoor_instructions[AgsInstruction::MaxInstructions];\n\tunsigned current_phase = 0;\n\tunsigned num_instructions = 0;\n\tspv::Id debug_var_id = 0;\n\tconst llvm::Value *active_read_backdoor = nullptr;\n\tUnorderedMap<const llvm::Value *, AGSCoopMatMapping> coopmat_component_mapping;\n\tUnorderedSet<const llvm::Value *> column_oriented_allocas_or_globals;\n\tUnorderedMap<const llvm::Value *, AllocaAGSForwardingTracking> alloca_or_global_tracking;\n\tspv::Id u8_array_bda_type = 0;\n\tspv::Id coopmat_transpose_scratch = 0;\n\n\tvoid reset()\n\t{\n\t\tcurrent_phase = 0;\n\t\tnum_instructions = 0;\n\t\tactive_read_backdoor = nullptr;\n\t}\n\n\tvoid reset_analysis()\n\t{\n\t\tcoopmat_component_mapping.clear();\n\t}\n};\n}"
  },
  {
    "path": "opcodes/dxil/dxil_arithmetic.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_arithmetic.hpp\"\n#include \"dxil_resources.hpp\"\n#include \"dxil_common.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"opcodes/opcodes_llvm_builtins.hpp\"\n#include <limits>\n\nnamespace dxil_spv\n{\nbool emit_imad_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// FIXME: Do we need to deal with intermediate mul overflow here somehow?\n\n\tOperation *mul = impl.allocate(spv::OpIMul, impl.get_type_id(instruction->getType()));\n\tmul->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\tmul->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\timpl.add(mul);\n\n\tOperation *add = impl.allocate(spv::OpIAdd, instruction);\n\tadd->add_id(mul->id);\n\tadd->add_id(impl.get_id_for_value(instruction->getOperand(3)));\n\timpl.add(add);\n\treturn true;\n}\n\nbool emit_fmad_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id result_id;\n\n\tbool is_precise = instruction->hasMetadata(\"dx.precise\") || impl.options.force_precise;\n\n\tif (!impl.options.quirks.precise_fma && is_precise)\n\t{\n\t\t// DXIL docs says to split the expression explicitly.\n\t\t// HLSL docs says it just has to be invariant.\n\t\t// These conflict since we could have used NoContract FMA instead,\n\t\t// but at least Big Navi splits fmac into mul + add when doing nocontract fma(), so ...\n\t\tspv::Id type_id = impl.get_type_id(instruction->getType());\n\t\tOperation *mul_op = impl.allocate(spv::OpFMul, type_id);\n\t\tmul_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\tmul_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\timpl.add(mul_op);\n\t\tbuilder.addDecoration(mul_op->id, spv::DecorationNoContraction);\n\n\t\timpl.decorate_relaxed_precision(instruction->getType(), mul_op->id, false);\n\n\t\tOperation *add_op = impl.allocate(spv::OpFAdd, instruction);\n\t\tadd_op->add_id(mul_op->id);\n\t\tadd_op->add_id(impl.get_id_for_value(instruction->getOperand(3)));\n\t\timpl.add(add_op);\n\t\tbuilder.addDecoration(add_op->id, spv::DecorationNoContraction);\n\n\t\tresult_id = add_op->id;\n\t}\n\telse\n\t{\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\t\top->add_id(impl.glsl_std450_ext);\n\t\top->add_literal(GLSLstd450Fma);\n\t\tfor (unsigned i = 1; i < 4; i++)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(i)));\n\t\timpl.add(op);\n\n\t\tif (is_precise)\n\t\t\tbuilder.addDecoration(op->id, spv::DecorationNoContraction);\n\n\t\tresult_id = op->id;\n\t}\n\n\timpl.decorate_relaxed_precision(instruction->getType(), result_id, false);\n\treturn true;\n}\n\nbool emit_isfinite_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\t// There is an OpIsFinite instruction, but it's only supported in kernel mode, so we have to decompose here.\n\n\tOperation *nan_op = impl.allocate(spv::OpIsNan, builder.makeBoolType());\n\tOperation *inf_op = impl.allocate(spv::OpIsInf, builder.makeBoolType());\n\tnan_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\tinf_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\n\timpl.add(nan_op);\n\timpl.add(inf_op);\n\n\tOperation *non_finite_op = impl.allocate(spv::OpLogicalOr, builder.makeBoolType());\n\tnon_finite_op->add_ids({ nan_op->id, inf_op->id });\n\timpl.add(non_finite_op);\n\n\tOperation *op = impl.allocate(spv::OpLogicalNot, instruction);\n\top->add_id(non_finite_op->id);\n\timpl.add(op);\n\treturn true;\n}\n\nspv::Id emit_native_bitscan(GLSLstd450 opcode, Converter::Impl &impl,\n                            const llvm::Instruction *instruction, const llvm::Value *value)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tOperation *op;\n\n\t// Vulkan currently does not allow 16/64-bit for these ... :(\n\tif (value->getType()->getIntegerBitWidth() == 16)\n\t{\n\t\tauto *extend = impl.allocate(\n\t\t    opcode == GLSLstd450FindSMsb ? spv::OpSConvert : spv::OpUConvert, builder.makeUintType(32));\n\n\t\textend->add_id(impl.get_id_for_value(value));\n\t\timpl.add(extend);\n\n\t\tif (instruction)\n\t\t\top = impl.allocate(spv::OpExtInst, instruction);\n\t\telse\n\t\t\top = impl.allocate(spv::OpExtInst, builder.makeUintType(32));\n\n\t\top->add_id(impl.glsl_std450_ext);\n\t\top->add_literal(opcode);\n\t\top->add_id(extend->id);\n\t}\n\telse if (value->getType()->getIntegerBitWidth() == 64)\n\t{\n\t\tspv::Id uint_type = builder.makeUintType(32);\n\t\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\n\t\tauto *bitcast = impl.allocate(spv::OpBitcast, uvec2_type);\n\t\tbitcast->add_id(impl.get_id_for_value(value));\n\t\timpl.add(bitcast);\n\n\t\tif (opcode == GLSLstd450FindSMsb)\n\t\t{\n\t\t\tauto *ext = impl.allocate(spv::OpCompositeExtract, uint_type);\n\t\t\text->add_id(bitcast->id);\n\t\t\text->add_literal(1);\n\t\t\timpl.add(ext);\n\n\t\t\tspv::Id int_type = builder.makeIntType(32);\n\t\t\tauto *shifted = impl.allocate(spv::OpShiftRightArithmetic, int_type);\n\t\t\tshifted->add_id(ext->id);\n\t\t\tshifted->add_id(builder.makeIntConstant(31));\n\t\t\timpl.add(shifted);\n\n\t\t\tconst spv::Id elems[] = { shifted->id, shifted->id };\n\n\t\t\tauto *xored = impl.allocate(spv::OpBitwiseXor, uvec2_type);\n\t\t\txored->add_id(bitcast->id);\n\t\t\txored->add_id(impl.build_vector(int_type, elems, 2));\n\t\t\timpl.add(xored);\n\n\t\t\tbitcast = xored;\n\t\t\topcode = GLSLstd450FindUMsb;\n\t\t}\n\n\t\tauto *ilsb = impl.allocate(spv::OpExtInst, uvec2_type);\n\t\tilsb->add_id(impl.glsl_std450_ext);\n\t\tilsb->add_literal(opcode);\n\t\tilsb->add_id(bitcast->id);\n\t\timpl.add(ilsb);\n\n\t\tspv::Id scalars[2];\n\t\tfor (int i = 0; i < 2; i++)\n\t\t{\n\t\t\tauto *ext = impl.allocate(spv::OpCompositeExtract, uint_type);\n\t\t\text->add_id(ilsb->id);\n\t\t\text->add_literal(i);\n\t\t\timpl.add(ext);\n\t\t\tscalars[i] = ext->id;\n\t\t}\n\n\t\tauto *or32 = impl.allocate(spv::OpBitwiseOr, uint_type);\n\t\tor32->add_id(scalars[1]);\n\t\tor32->add_id(builder.makeUintConstant(32));\n\t\timpl.add(or32);\n\t\tscalars[1] = or32->id;\n\n\t\tauto merge_op = opcode == GLSLstd450FindILsb ? GLSLstd450UMin : GLSLstd450SMax;\n\n\t\tif (instruction)\n\t\t\top = impl.allocate(spv::OpExtInst, instruction);\n\t\telse\n\t\t\top = impl.allocate(spv::OpExtInst, uint_type);\n\n\t\top->add_id(impl.glsl_std450_ext);\n\t\top->add_literal(merge_op);\n\t\top->add_id(scalars[0]);\n\t\top->add_id(scalars[1]);\n\t}\n\telse\n\t{\n\t\tif (instruction)\n\t\t\top = impl.allocate(spv::OpExtInst, instruction);\n\t\telse\n\t\t\top = impl.allocate(spv::OpExtInst, builder.makeUintType(32));\n\n\t\top->add_id(impl.glsl_std450_ext);\n\t\top->add_literal(opcode);\n\t\top->add_id(impl.get_id_for_value(value));\n\t}\n\n\timpl.add(op);\n\treturn op->id;\n}\n\nbool emit_find_low_bit_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\temit_native_bitscan(GLSLstd450FindILsb, impl, instruction, instruction->getOperand(1));\n\treturn true;\n}\n\nbool emit_find_high_bit_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\t// This is actually CLZ, and not FindMSB.\n\tauto *value = instruction->getOperand(1);\n\tspv::Id msb_id = emit_native_bitscan(opcode, impl, nullptr, value);\n\n\tOperation *eq_neg1_op = impl.allocate(spv::OpIEqual, builder.makeBoolType());\n\t{\n\t\teq_neg1_op->add_ids({ msb_id, builder.makeUintConstant(~0u) });\n\t\timpl.add(eq_neg1_op);\n\t}\n\n\tOperation *msb_sub_op = impl.allocate(spv::OpISub, impl.get_type_id(instruction->getType()));\n\t{\n\t\tmsb_sub_op->add_ids({\n\t\t    builder.makeUintConstant(value->getType()->getIntegerBitWidth() - 1),\n\t\t    msb_id\n\t\t});\n\t\timpl.add(msb_sub_op);\n\t}\n\n\tOperation *op = impl.allocate(spv::OpSelect, instruction);\n\top->add_ids({ eq_neg1_op->id, builder.makeUintConstant(~0u), msb_sub_op->id });\n\timpl.add(op);\n\treturn true;\n}\n\nstatic bool emit_dxil_peephole_iabs(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (opcode != GLSLstd450SMax)\n\t\treturn false;\n\n\tconst auto *binop0 = llvm::dyn_cast<llvm::BinaryOperator>(instruction->getOperand(1));\n\tconst auto *binop1 = llvm::dyn_cast<llvm::BinaryOperator>(instruction->getOperand(2));\n\n\tbool peephole0 = binop0 && can_optimize_to_snegate(binop0) && binop0->getOperand(1) == instruction->getOperand(2);\n\tbool peephole1 = binop1 && can_optimize_to_snegate(binop1) && binop1->getOperand(1) == instruction->getOperand(1);\n\n\tif (peephole0 || peephole1)\n\t{\n\t\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\t\top->add_id(impl.glsl_std450_ext);\n\t\top->add_literal(GLSLstd450SAbs);\n\n\t\tif (peephole0)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\telse\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\n\t\timpl.add(op);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_dxil_std450_binary_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tif (emit_dxil_peephole_iabs(opcode, impl, instruction))\n\t\treturn true;\n\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(opcode);\n\tfor (unsigned i = 1; i < 3; i++)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(i)));\n\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\treturn true;\n}\n\nbool emit_dxil_wide_arith_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction,\n                                      bool spirv_semantics)\n{\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tif ((opcode == spv::OpSMulExtended || opcode == spv::OpUMulExtended) && !spirv_semantics)\n\t{\n\t\t// Demote to plain multiply.\n\t\tauto composite_itr = impl.llvm_composite_meta.find(instruction);\n\t\tif (composite_itr != impl.llvm_composite_meta.end() && composite_itr->second.access_mask == 0x2)\n\t\t{\n\t\t\tOperation *mul_op = impl.allocate(spv::OpIMul, instruction, u32_type);\n\t\t\tmul_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\t\tmul_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\t\timpl.add(mul_op);\n\t\t\tcomposite_itr->second.components = 1;\n\t\t\tcomposite_itr->second.forced_composite = false;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tspv::Id type_id;\n\n\tif (spirv_semantics)\n\t{\n\t\ttype_id = impl.get_type_id(llvm::cast<llvm::VectorType>(instruction->getType())->getElementType());\n\t\ttype_id = impl.get_struct_type({ type_id, type_id }, 0, \"WideArithResult\");\n\t}\n\telse\n\t{\n\t\ttype_id = impl.get_type_id(instruction->getType());\n\t}\n\n\tOperation *mul_op = impl.allocate(opcode, type_id);\n\tmul_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\tmul_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\timpl.add(mul_op);\n\n\tspv::Id extracted_values[2];\n\tfor (uint32_t i = 0; i < 2; i++)\n\t{\n\t\tauto *ext_op = impl.allocate(spv::OpCompositeExtract, u32_type);\n\t\text_op->add_id(mul_op->id);\n\t\text_op->add_literal(i);\n\t\timpl.add(ext_op);\n\n\t\tif (spirv_semantics)\n\t\t\textracted_values[i] = ext_op->id;\n\t\telse\n\t\t\textracted_values[1 - i] = ext_op->id;\n\t}\n\n\tspv::Id result = impl.build_vector(u32_type, extracted_values, 2);\n\timpl.rewrite_value(instruction, result);\n\n\treturn true;\n}\n\nbool emit_dxbc_udiv_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id id0 = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id id1 = impl.get_id_for_value(instruction->getOperand(2));\n\n\tauto *div_op = impl.allocate(spv::OpUDiv, builder.makeUintType(32));\n\tdiv_op->add_id(id0);\n\tdiv_op->add_id(id1);\n\timpl.add(div_op);\n\n\tauto *mod_op = impl.allocate(spv::OpUMod, builder.makeUintType(32));\n\tmod_op->add_id(id0);\n\tmod_op->add_id(id1);\n\timpl.add(mod_op);\n\n\tauto *is_zero_divider = impl.allocate(spv::OpIEqual, builder.makeBoolType());\n\tis_zero_divider->add_id(id1);\n\tis_zero_divider->add_id(builder.makeUintConstant(0));\n\timpl.add(is_zero_divider);\n\n\tauto *quot_select = impl.allocate(spv::OpSelect, builder.makeUintType(32));\n\tquot_select->add_id(is_zero_divider->id);\n\tquot_select->add_id(builder.makeUintConstant(UINT32_MAX));\n\tquot_select->add_id(div_op->id);\n\timpl.add(quot_select);\n\n\tauto *rem_select = impl.allocate(spv::OpSelect, builder.makeUintType(32));\n\trem_select->add_id(is_zero_divider->id);\n\trem_select->add_id(builder.makeUintConstant(UINT32_MAX));\n\trem_select->add_id(mod_op->id);\n\timpl.add(rem_select);\n\n\tspv::Id elems[2] = { quot_select->id, rem_select->id };\n\timpl.rewrite_value(instruction, impl.build_vector(builder.makeUintType(32), elems, 2));\n\treturn true;\n}\n\nbool emit_dxil_std450_trinary_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(opcode);\n\n\tfor (unsigned i = 1; i < 4; i++)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(i)));\n\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\treturn true;\n}\n\nstatic bool value_is_length_squared(const llvm::Value *value)\n{\n\tint components = 0;\n\tif (value_is_dx_op_instrinsic(value, DXIL::Op::Dot2))\n\t\tcomponents = 2;\n\telse if (value_is_dx_op_instrinsic(value, DXIL::Op::Dot3))\n\t\tcomponents = 3;\n\telse if (value_is_dx_op_instrinsic(value, DXIL::Op::Dot4))\n\t\tcomponents = 4;\n\telse\n\t\treturn false;\n\n\tauto *dot = llvm::cast<llvm::CallInst>(value);\n\tfor (int i = 0; i < components; i++)\n\t\tif (dot->getOperand(1 + i) != dot->getOperand(i + 1 + components))\n\t\t\treturn false;\n\n\treturn true;\n}\n\nstatic bool is_canonically_normalizing_value(const llvm::Value *value)\n{\n\treturn value_is_dx_op_instrinsic(value, DXIL::Op::Rsqrt) &&\n\t       value_is_length_squared(llvm::cast<llvm::CallInst>(value)->getOperand(1));\n}\n\nstatic std::pair<const llvm::Value *, double> split_constant_multipliers(const llvm::Value *value)\n{\n\tif (const auto *fp = llvm::dyn_cast<llvm::ConstantFP>(value))\n\t{\n\t\treturn { nullptr, fp->getValueAPF().convertToDouble() };\n\t}\n\telse if (const auto *bin_op = llvm::dyn_cast<llvm::BinaryOperator>(value))\n\t{\n\t\tif (bin_op->getOpcode() != llvm::BinaryOperator::BinaryOps::FMul)\n\t\t\treturn { value, 1.0 };\n\n\t\tauto split0 = split_constant_multipliers(bin_op->getOperand(0));\n\t\tauto split1 = split_constant_multipliers(bin_op->getOperand(1));\n\n\t\tif (split0.first && split1.first)\n\t\t\treturn { value, 1.0 };\n\t\telse if (split0.first)\n\t\t\treturn { split0.first, split0.second * split1.second };\n\t\telse if (split1.first)\n\t\t\treturn { split1.first, split0.second * split1.second };\n\t\telse\n\t\t\treturn { nullptr, split0.second * split1.second };\n\t}\n\n\treturn { value, 1.0 };\n}\n\nstatic bool get_expression_upper_bound(const llvm::Value *value, double &boundary_value)\n{\n\tauto overall_split = split_constant_multipliers(value);\n\tvalue = overall_split.first;\n\tif (!overall_split.first)\n\t{\n\t\tboundary_value = overall_split.second;\n\t\treturn true;\n\t}\n\n\t// Simple analysis to find what we want to see.\n\tif (auto *bin_op = llvm::dyn_cast<llvm::BinaryOperator>(value))\n\t{\n\t\tif (bin_op->getOpcode() != llvm::BinaryOperator::BinaryOps::FMul)\n\t\t\treturn false;\n\n\t\tconst llvm::Value *op0 = bin_op->getOperand(0);\n\t\tconst llvm::Value *op1 = bin_op->getOperand(1);\n\n\t\tauto split0 = split_constant_multipliers(op0);\n\t\tauto split1 = split_constant_multipliers(op1);\n\n\t\t// Don't want to deal with any negative numbers here since the definition of max and min flip.\n\t\tif (split0.second < 0.0 || split1.second < 0.0)\n\t\t\treturn false;\n\n\t\tif (split0.first)\n\t\t\top0 = split0.first;\n\t\tif (split1.first)\n\t\t\top1 = split1.first;\n\n\t\tbool is_normalizing0 = is_canonically_normalizing_value(split0.first);\n\t\tbool is_normalizing1 = is_canonically_normalizing_value(split1.first);\n\n\t\tif (is_normalizing0 || is_normalizing1)\n\t\t{\n\t\t\tconst llvm::Value *mul_value = is_normalizing0 ? op1 : op0;\n\t\t\tauto *rsqrt = llvm::cast<llvm::CallInst>(is_normalizing0 ? op0 : op1);\n\t\t\tauto *dot = llvm::cast<llvm::CallInst>(rsqrt->getOperand(1));\n\t\t\tfor (unsigned i = 1; i < dot->getNumOperands(); i++)\n\t\t\t{\n\t\t\t\tif (dot->getOperand(i) == mul_value)\n\t\t\t\t{\n\t\t\t\t\tboundary_value = overall_split.second * split0.second * split1.second;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic spv::Id build_clamped_non_negative_sqrt(Converter::Impl &impl, spv::Id id, const llvm::Value *value)\n{\n\t// Try to detect a pattern that can manifest in some shaders in the wild where 1 ULP causes\n\t// A tiny negative value to occur, leading to NaN. This is a workaround, obviously.\n\tauto *bin_op = llvm::dyn_cast<llvm::BinaryOperator>(value);\n\tif (!bin_op || bin_op->getOpcode() != llvm::BinaryOperator::BinaryOps::FSub || !bin_op->isFast())\n\t\treturn id;\n\n\tauto *const0 = llvm::dyn_cast<llvm::ConstantFP>(bin_op->getOperand(0));\n\tif (!const0)\n\t\treturn id;\n\n\tdouble bound = 0.0;\n\tif (!get_expression_upper_bound(bin_op->getOperand(1), bound) ||\n\t    const0->getValueAPF().convertToDouble() != bound || bound == 0.0)\n\t\treturn id;\n\n\tauto *lower = impl.allocate(spv::OpExtInst, impl.get_type_id(value->getType()));\n\tlower->add_id(impl.glsl_std450_ext);\n\tlower->add_literal(GLSLstd450FMax);\n\tlower->add_id(id);\n\tlower->add_id(impl.builder().makeNullConstant(lower->type_id));\n\timpl.add(lower);\n\treturn lower->id;\n}\n\nbool emit_dxil_std450_unary_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\t// Games rely on this peephole, since DXC doesn't do it for us.\n\tif (opcode == GLSLstd450Exp2 || opcode == GLSLstd450Log2)\n\t{\n\t\tbool precise = instruction->hasMetadata(\"dx.precise\") || impl.options.force_precise;\n\t\tif (!precise)\n\t\t{\n\t\t\tif ((opcode == GLSLstd450Exp2 && value_is_dx_op_instrinsic(instruction->getOperand(1), DXIL::Op::Log)) ||\n\t\t\t    (value_is_dx_op_instrinsic(instruction->getOperand(1), DXIL::Op::Exp)))\n\t\t\t{\n\t\t\t\tauto *base_value = llvm::cast<llvm::CallInst>(instruction->getOperand(1))->getOperand(1);\n\t\t\t\timpl.rewrite_value(instruction, impl.get_id_for_value(base_value));\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(opcode);\n\n\tspv::Id id = impl.get_id_for_value(instruction->getOperand(1));\n\tif (opcode == GLSLstd450Sqrt)\n\t\tid = build_clamped_non_negative_sqrt(impl, id, instruction->getOperand(1));\n\n\top->add_id(id);\n\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\n\tif (opcode == GLSLstd450InverseSqrt && impl.options.quirks.fixup_rsqrt &&\n\t    instruction->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID)\n\t{\n\t\t// Only consider normal FP32 floats for simplicity since this is just a workaround.\n\t\tauto *clamp = impl.allocate(spv::OpExtInst, impl.get_type_id(instruction->getType()));\n\t\tclamp->add_id(impl.glsl_std450_ext);\n\t\tclamp->add_literal(GLSLstd450NMin);\n\t\tclamp->add_id(op->id);\n\t\tclamp->add_id(impl.builder().makeFloatConstant(std::numeric_limits<float>::max()));\n\t\timpl.add(clamp);\n\t\timpl.rewrite_value(instruction, clamp->id);\n\t}\n\n\treturn true;\n}\n\nbool emit_dxil_unary_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tOperation *op = impl.allocate(opcode, instruction);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\treturn true;\n}\n\nbool emit_saturate_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tspv::Id constant_0, constant_1;\n\n\tswitch (instruction->getType()->getTypeID())\n\t{\n\tcase llvm::Type::TypeID::HalfTyID:\n\t\tif (impl.support_native_fp16_operations())\n\t\t{\n\t\t\tconstant_0 = builder.makeFloat16Constant(0);\n\t\t\tconstant_1 = builder.makeFloat16Constant(0x3c00);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconstant_0 = builder.makeFloatConstant(0.0f);\n\t\t\tconstant_1 = builder.makeFloatConstant(1.0f);\n\t\t}\n\t\tbreak;\n\n\tcase llvm::Type::TypeID::FloatTyID:\n\t\tconstant_0 = builder.makeFloatConstant(0.0f);\n\t\tconstant_1 = builder.makeFloatConstant(1.0f);\n\t\tbreak;\n\n\tcase llvm::Type::TypeID::DoubleTyID:\n\t\tconstant_0 = builder.makeDoubleConstant(0.0);\n\t\tconstant_1 = builder.makeDoubleConstant(1.0);\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(GLSLstd450NClamp);\n\top->add_ids({ impl.get_id_for_value(instruction->getOperand(1)),\n\t              constant_0, constant_1 });\n\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\treturn true;\n}\n\nbool emit_dot_instruction(unsigned dimensions, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tOperation *op = impl.allocate(spv::OpDot, instruction);\n\n\tspv::Id vec0_args[4] = {};\n\tspv::Id vec1_args[4] = {};\n\tfor (unsigned i = 0; i < dimensions; i++)\n\t\tvec0_args[i] = impl.get_id_for_value(instruction->getOperand(1 + i));\n\tfor (unsigned i = 0; i < dimensions; i++)\n\t\tvec1_args[i] = impl.get_id_for_value(instruction->getOperand(1 + i + dimensions));\n\n\tspv::Id vec0 = impl.build_vector(op->type_id, vec0_args, dimensions);\n\tspv::Id vec1 = impl.build_vector(op->type_id, vec1_args, dimensions);\n\n\top->add_ids({ vec0, vec1 });\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\n\tbool precise = instruction->hasMetadata(\"dx.precise\") || impl.options.force_precise;\n\tif (precise)\n\t\timpl.builder().addDecoration(op->id, spv::DecorationNoContraction);\n\n\treturn true;\n}\n\nstatic spv::Id clamp_bitfield_width(Converter::Impl &impl, spv::Id offset, spv::Id width)\n{\n\tauto &builder = impl.builder();\n\t// D3D has well-defined behavior when width + offset overflows in bitfield instructions.\n\t// To get similar behavior, we just need to clamp width.\n\tauto *max_width_op = impl.allocate(spv::OpISub, builder.makeUintType(32));\n\tmax_width_op->add_id(builder.makeUintConstant(32));\n\tmax_width_op->add_id(offset);\n\timpl.add(max_width_op);\n\n\tauto *clamp_op = impl.allocate(spv::OpExtInst, builder.makeUintType(32));\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\tclamp_op->add_id(impl.glsl_std450_ext);\n\tclamp_op->add_literal(GLSLstd450UMin);\n\tclamp_op->add_id(width);\n\tclamp_op->add_id(max_width_op->id);\n\timpl.add(clamp_op);\n\treturn clamp_op->id;\n}\n\nstatic spv::Id mask_input(Converter::Impl &impl, const llvm::Value *value)\n{\n\tOperation *op = impl.allocate(spv::OpBitwiseAnd, impl.get_type_id(value->getType()));\n\top->add_id(impl.get_id_for_value(value));\n\top->add_id(impl.builder().makeUintConstant(31));\n\timpl.add(op);\n\treturn op->id;\n}\n\nbool emit_bfe_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction, bool spirv_semantics)\n{\n\tif (spirv_semantics)\n\t{\n\t\tOperation *op = impl.allocate(opcode, instruction);\n\t\tfor (unsigned i = 0; i < 3; i++)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(i + 1)));\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\t// SPIR-V spec doesn't say anything about masking inputs, but Ibfe/Ubfe do, so ...\n\t\tspv::Id masked_width_id = mask_input(impl, instruction->getOperand(1));\n\t\tspv::Id masked_offset_id = mask_input(impl, instruction->getOperand(2));\n\t\tmasked_width_id = clamp_bitfield_width(impl, masked_offset_id, masked_width_id);\n\n\t\tOperation *op = impl.allocate(opcode, instruction);\n\t\top->add_ids({ impl.get_id_for_value(instruction->getOperand(3)), masked_offset_id, masked_width_id });\n\t\timpl.add(op);\n\t}\n\treturn true;\n}\n\nbool emit_bfi_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool spirv_semantics)\n{\n\tif (spirv_semantics)\n\t{\n\t\tOperation *op = impl.allocate(spv::OpBitFieldInsert, instruction);\n\t\tfor (unsigned i = 0; i < 4; i++)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(i + 1)));\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\tspv::Id masked_width_id = mask_input(impl, instruction->getOperand(1));\n\t\tspv::Id masked_offset_id = mask_input(impl, instruction->getOperand(2));\n\t\tmasked_width_id = clamp_bitfield_width(impl, masked_offset_id, masked_width_id);\n\n\t\tspv::Id src_id = impl.get_id_for_value(instruction->getOperand(3));\n\t\tspv::Id dst_id = impl.get_id_for_value(instruction->getOperand(4));\n\n\t\tOperation *op = impl.allocate(spv::OpBitFieldInsert, instruction);\n\t\top->add_ids({ dst_id, src_id, masked_offset_id, masked_width_id });\n\t\timpl.add(op);\n\t}\n\n\treturn true;\n}\n\nbool emit_make_double_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(GLSLstd450PackDouble2x32);\n\n\tspv::Id inputs[2];\n\tfor (unsigned i = 0; i < 2; i++)\n\t\tinputs[i] = impl.get_id_for_value(instruction->getOperand(1 + i));\n\top->add_id(impl.build_vector(builder.makeUintType(32), inputs, 2));\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_split_double_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction, builder.makeVectorType(builder.makeUintType(32), 2));\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(GLSLstd450UnpackDouble2x32);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_legacy_f16_to_f32_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tOperation *unpack_op = impl.allocate(spv::OpExtInst, builder.makeVectorType(builder.makeFloatType(32), 2));\n\tunpack_op->add_id(impl.glsl_std450_ext);\n\tunpack_op->add_literal(GLSLstd450UnpackHalf2x16);\n\tunpack_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(unpack_op);\n\n\t// By construction, these are relaxed precision, but spams lots of unrelated shader changes,\n\t// and doesn't make too much sense to add ...\n\t//builder.addDecoration(unpack_op->id, spv::DecorationRelaxedPrecision);\n\n\tOperation *op = impl.allocate(spv::OpCompositeExtract, instruction);\n\top->add_id(unpack_op->id);\n\top->add_literal(0);\n\timpl.add(op);\n\n\t// By construction, these are relaxed precision, but spams lots of unrelated shader changes,\n\t// and doesn't make too much sense to add ...\n\t//builder.addDecoration(op->id, spv::DecorationRelaxedPrecision);\n\n\treturn true;\n}\n\nbool emit_legacy_f32_to_f16_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (impl.support_native_fp16_operations() && emit_bypass_fp16_trunc(impl, instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t// According to D3D11 functional spec (and implementations), this is required to be RTZ.\n\t// We have no obvious way of getting this behavior on a per-instruction basis,\n\t// and it is too expensive/complicated to implement this behavior exactly.\n\t// In practice, we have observed cases where this matters in HZD, but we don't really need RTZ, we just\n\t// need invariance to be preserved for an FP16 write and the following unpack of that expression.\n\t// QuantizeToFP16 ensures a baseline which works for the time being on the affected implementations.\n\t// - Polaris / Vega: RTZ rounding can be optimized to RTE rounding with just plain packHalf, which breaks invariance.\n\t// - NV: packHalf / unpackHalf pairs are optimized away, leaving full FP32 precision.\n\t// Ideally we'd have a PackHalf variant which takes rounding mode / denorm mode to be correct, but alas ...\n\t// Only do this hack when heuristics deduce it to be necessary.\n\tspv::Id input_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\tif (impl.shader_analysis.precise_f16_to_f32_observed)\n\t{\n\t\tauto *quant_op = impl.allocate(spv::OpQuantizeToF16, builder.makeFloatType(32));\n\t\tquant_op->add_id(input_id);\n\t\timpl.add(quant_op);\n\t\tinput_id = quant_op->id;\n\t}\n\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction);\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(GLSLstd450PackHalf2x16);\n\n\tspv::Id inputs[2] = { input_id, builder.makeFloatConstant(0.0f) };\n\top->add_id(impl.build_vector(builder.makeFloatType(32), inputs, 2));\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\treturn true;\n}\n\nbool emit_bitcast_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto *op = impl.allocate(spv::OpBitcast, instruction);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(op);\n\treturn true;\n}\n\nstatic spv::Id build_bfe(Converter::Impl &impl, spv::Id value_id, unsigned offset, unsigned bits, bool sign_extend)\n{\n\tauto &builder = impl.builder();\n\tauto *op = impl.allocate(sign_extend ? spv::OpBitFieldSExtract : spv::OpBitFieldUExtract, builder.makeUintType(32));\n\top->add_id(value_id);\n\top->add_id(builder.makeUintConstant(offset));\n\top->add_id(builder.makeUintConstant(bits));\n\timpl.add(op);\n\treturn op->id;\n}\n\nbool emit_i8_dot_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool sign_extend)\n{\n\tauto &builder = impl.builder();\n\tspv::Id acc = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id a = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id b = impl.get_id_for_value(instruction->getOperand(3));\n\n\tif (impl.options.shader_i8_dot_enabled)\n\t{\n\t\tbuilder.addExtension(\"SPV_KHR_integer_dot_product\");\n\t\tbuilder.addCapability(spv::CapabilityDotProductKHR);\n\t\tbuilder.addCapability(spv::CapabilityDotProductInput4x8BitPackedKHR);\n\n\t\t// Not supposed to saturate.\n\t\tauto *dot_op = impl.allocate(sign_extend ? spv::OpSDotKHR : spv::OpUDotKHR, builder.makeUintType(32));\n\t\tdot_op->add_id(a);\n\t\tdot_op->add_id(b);\n\t\tdot_op->add_literal(spv::PackedVectorFormatPackedVectorFormat4x8BitKHR);\n\t\timpl.add(dot_op);\n\n\t\tauto *acc_op = impl.allocate(spv::OpIAdd, instruction);\n\t\tacc_op->add_id(acc);\n\t\tacc_op->add_id(dot_op->id);\n\t\timpl.add(acc_op);\n\t}\n\telse\n\t{\n\t\tfor (unsigned i = 0; i < 4; i++)\n\t\t{\n\t\t\tspv::Id a_component = build_bfe(impl, a, 8 * i, 8, sign_extend);\n\t\t\tspv::Id b_component = build_bfe(impl, b, 8 * i, 8, sign_extend);\n\t\t\tauto *mul_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tmul_op->add_id(a_component);\n\t\t\tmul_op->add_id(b_component);\n\t\t\timpl.add(mul_op);\n\n\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\tadd_op->add_id(acc);\n\t\t\tadd_op->add_id(mul_op->id);\n\t\t\tacc = add_op->id;\n\t\t\timpl.add(add_op);\n\t\t}\n\n\t\timpl.rewrite_value(instruction, acc);\n\t}\n\n\treturn true;\n}\n\nbool emit_dot2_add_half_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id as[2], bs[2];\n\tas[0] = impl.get_id_for_value(instruction->getOperand(2));\n\tas[1] = impl.get_id_for_value(instruction->getOperand(3));\n\tbs[0] = impl.get_id_for_value(instruction->getOperand(4));\n\tbs[1] = impl.get_id_for_value(instruction->getOperand(5));\n\n\tbool precise = instruction->hasMetadata(\"dx.precise\") || impl.options.force_precise;\n\n\t// V_DOT2C_F32_F16 is emitted on native drivers, and based on some reversing, the behavior is\n\t// acc = (float(a.x * b.x) + float(a.y * b.y)) + acc\n\t// - MUL in FP16\n\t// - FEXT to FP32\n\t// - FADD dot results\n\t// - FADD to acc\n\tspv::Id half_type_id = builder.makeFloatType(16);\n\tspv::Id float_type_id = builder.makeFloatType(32);\n\tspv::Id a = impl.build_vector(half_type_id, as, 2);\n\tspv::Id b = impl.build_vector(half_type_id, bs, 2);\n\n\tif (impl.options.mixed_dot_product_fp16_fp16_fp32)\n\t{\n\t\tbuilder.addExtension(\"SPV_VALVE_mixed_float_dot_product\");\n\t\tbuilder.addCapability(spv::CapabilityDotProductFloat16AccFloat32VALVE);\n\n\t\tauto *acc_op = impl.allocate(spv::OpFDot2MixAcc32VALVE, instruction);\n\t\tacc_op->add_id(a);\n\t\tacc_op->add_id(b);\n\t\tacc_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(acc_op);\n\t\treturn true;\n\t}\n\n\tauto *dot_op = impl.allocate(spv::OpFMul, builder.makeVectorType(half_type_id, 2));\n\tdot_op->add_id(a);\n\tdot_op->add_id(b);\n\timpl.add(dot_op);\n\tif (precise)\n\t\tbuilder.addDecoration(dot_op->id, spv::DecorationNoContraction);\n\n\tspv::Id expanded_input = dot_op->id;\n\tif (impl.support_native_fp16_operations())\n\t{\n\t\tauto *extend_op = impl.allocate(spv::OpFConvert, builder.makeVectorType(float_type_id, 2));\n\t\textend_op->add_id(expanded_input);\n\t\timpl.add(extend_op);\n\t\texpanded_input = extend_op->id;\n\t}\n\n\tspv::Id components[2];\n\tfor (unsigned i = 0; i < 2; i++)\n\t{\n\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, float_type_id);\n\t\textract_op->add_id(expanded_input);\n\t\textract_op->add_literal(i);\n\t\timpl.add(extract_op);\n\t\tcomponents[i] = extract_op->id;\n\t}\n\n\tauto *dot_sum = impl.allocate(spv::OpFAdd, float_type_id);\n\tdot_sum->add_id(components[0]);\n\tdot_sum->add_id(components[1]);\n\timpl.add(dot_sum);\n\tif (precise)\n\t\tbuilder.addDecoration(dot_sum->id, spv::DecorationNoContraction);\n\n\tauto *acc_op = impl.allocate(spv::OpFAdd, instruction);\n\tacc_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\tacc_op->add_id(dot_sum->id);\n\timpl.add(acc_op);\n\tif (precise)\n\t\tbuilder.addDecoration(acc_op->id, spv::DecorationNoContraction);\n\n\t// This opcode requires native FP16, so RelaxedPrecision is useless.\n\n\treturn true;\n}\n\nbool emit_unpack4x8_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilityInt8);\n\n\tauto *bitcast_op = impl.allocate(spv::OpBitcast, builder.makeVectorType(builder.makeUintType(8), 4));\n\tbitcast_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\timpl.add(bitcast_op);\n\n\tuint32_t signed_expand;\n\tif (!get_constant_operand(instruction, 1, &signed_expand))\n\t\treturn false;\n\n\tauto *element_type = get_composite_element_type(instruction->getType());\n\tspv::Id result_type = builder.makeVectorType(impl.get_type_id(element_type), 4);\n\n\tauto *expand_op = impl.allocate(signed_expand ? spv::OpSConvert : spv::OpUConvert,\n\t                                instruction, result_type);\n\texpand_op->add_id(bitcast_op->id);\n\timpl.add(expand_op);\n\n\treturn true;\n}\n\nbool emit_pack4x8_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilityInt8);\n\n\tauto *element_type = instruction->getOperand(2)->getType();\n\tspv::Id uint_type = impl.get_type_id(element_type);\n\n\tuint32_t clamp_op_literal;\n\tif (!get_constant_operand(instruction, 1, &clamp_op_literal))\n\t\treturn false;\n\n\tspv::Id elements[4];\n\tfor (unsigned i = 0; i < 4; i++)\n\t\telements[i] = impl.get_id_for_value(instruction->getOperand(2 + i));\n\n\tspv::Id vec_id = impl.build_vector(uint_type, elements, 4);\n\tif (clamp_op_literal != 0)\n\t{\n\t\t// Signed saturate with u8 range or s8 range.\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\tspv::Id lo_id, hi_id;\n\t\tif (element_type->getIntegerBitWidth() == 16)\n\t\t{\n\t\t\tlo_id = builder.makeInt16Constant(clamp_op_literal == 1 ? 0 : -128);\n\t\t\thi_id = builder.makeInt16Constant(clamp_op_literal == 1 ? 255 : 127);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlo_id = builder.makeIntConstant(clamp_op_literal == 1 ? 0 : -128);\n\t\t\thi_id = builder.makeIntConstant(clamp_op_literal == 1 ? 255 : 127);\n\t\t}\n\n\t\tVector<spv::Id> lo_ids = { lo_id, lo_id, lo_id, lo_id };\n\t\tVector<spv::Id> hi_ids = { hi_id, hi_id, hi_id, hi_id };\n\n\t\tspv::Id int_type = builder.makeIntType(element_type->getIntegerBitWidth());\n\t\tspv::Id int4_type = builder.makeVectorType(int_type, 4);\n\t\tlo_id = builder.makeCompositeConstant(int4_type, lo_ids);\n\t\thi_id = builder.makeCompositeConstant(int4_type, hi_ids);\n\n\t\tauto *clamp_op = impl.allocate(spv::OpExtInst, int4_type);\n\t\tclamp_op->add_id(impl.glsl_std450_ext);\n\t\tclamp_op->add_literal(GLSLstd450SClamp);\n\t\tclamp_op->add_id(vec_id);\n\t\tclamp_op->add_id(lo_id);\n\t\tclamp_op->add_id(hi_id);\n\t\timpl.add(clamp_op);\n\t\tvec_id = clamp_op->id;\n\t}\n\n\tauto *narrow_op = impl.allocate(spv::OpUConvert, builder.makeVectorType(builder.makeUintType(8), 4));\n\tnarrow_op->add_id(vec_id);\n\timpl.add(narrow_op);\n\n\tauto *bitcast_op = impl.allocate(spv::OpBitcast, instruction);\n\tbitcast_op->add_id(narrow_op->id);\n\timpl.add(bitcast_op);\n\n\treturn true;\n}\n\nbool emit_msad_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t// Don't modify this implementation since compilers pattern match this.\n\n\tspv::Id uint32_scalar_type = builder.makeUintType(32);\n\tspv::Id uint32_vector_type = builder.makeVectorType(uint32_scalar_type, 4);\n\tspv::Id bool_type = builder.makeVectorType(builder.makeBoolType(), 4);\n\n\tVector<spv::Id> ref_byte_ids = { 0, 0, 0, 0 };\n\tVector<spv::Id> src_byte_ids = { 0, 0, 0, 0 };\n\n\tfor (uint32_t i = 0; i < 4; i++)\n\t{\n\t\tauto *ref_bfe_op = impl.allocate(spv::OpBitFieldUExtract, uint32_scalar_type);\n\t\tref_bfe_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\tref_bfe_op->add_id(builder.makeUintConstant(8 * i));\n\t\tref_bfe_op->add_id(builder.makeUintConstant(8));\n\t\timpl.add(ref_bfe_op);\n\n\t\tauto *src_bfe_op = impl.allocate(spv::OpBitFieldUExtract, uint32_scalar_type);\n\t\tsrc_bfe_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\tsrc_bfe_op->add_id(builder.makeUintConstant(8 * i));\n\t\tsrc_bfe_op->add_id(builder.makeUintConstant(8));\n\t\timpl.add(src_bfe_op);\n\n\t\tref_byte_ids[i] = ref_bfe_op->id;\n\t\tsrc_byte_ids[i] = src_bfe_op->id;\n\t}\n\n\tauto *ref_composite_op = impl.allocate(spv::OpCompositeConstruct, uint32_vector_type);\n\tfor (uint32_t i = 0; i < 4; i++)\n\t\tref_composite_op->add_id(ref_byte_ids[i]);\n\timpl.add(ref_composite_op);\n\n\tauto *src_composite_op = impl.allocate(spv::OpCompositeConstruct, uint32_vector_type);\n\tfor (uint32_t i = 0; i < 4; i++)\n\t\tsrc_composite_op->add_id(src_byte_ids[i]);\n\timpl.add(src_composite_op);\n\n\tspv::Id zero_vector = builder.makeNullConstant(uint32_vector_type);\n\n\tauto *compare_ref_zero_op = impl.allocate(spv::OpIEqual, bool_type);\n\tcompare_ref_zero_op->add_id(ref_composite_op->id);\n\tcompare_ref_zero_op->add_id(zero_vector);\n\timpl.add(compare_ref_zero_op);\n\n\tauto *ref_src_diff_op = impl.allocate(spv::OpISub, uint32_vector_type);\n\tref_src_diff_op->add_id(ref_composite_op->id);\n\tref_src_diff_op->add_id(src_composite_op->id);\n\timpl.add(ref_src_diff_op);\n\n\tauto *abs_diff_op = impl.allocate(spv::OpExtInst, uint32_vector_type);\n\tabs_diff_op->add_id(impl.glsl_std450_ext);\n\tabs_diff_op->add_literal(GLSLstd450SAbs);\n\tabs_diff_op->add_id(ref_src_diff_op->id);\n\timpl.add(abs_diff_op);\n\n\tauto *masked_diff_op = impl.allocate(spv::OpSelect, uint32_vector_type);\n\tmasked_diff_op->add_id(compare_ref_zero_op->id);\n\tmasked_diff_op->add_id(zero_vector);\n\tmasked_diff_op->add_id(abs_diff_op->id);\n\timpl.add(masked_diff_op);\n\n\tspv::Id sum_id = 0;\n\n\tfor (uint32_t i = 0; i < 4; i++)\n\t{\n\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, uint32_scalar_type);\n\t\textract_op->add_id(masked_diff_op->id);\n\t\textract_op->add_literal(i);\n\t\timpl.add(extract_op);\n\n\t\tif (sum_id)\n\t\t{\n\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, uint32_scalar_type);\n\t\t\tadd_op->add_id(sum_id);\n\t\t\tadd_op->add_id(extract_op->id);\n\t\t\timpl.add(add_op);\n\n\t\t\tsum_id = add_op->id;\n\t\t}\n\t\telse\n\t\t\tsum_id = extract_op->id;\n\t}\n\n\t/* DXIL docs say that the addition should saturate on overflow,\n\t * but but drivers don't seem to do that. */\n\tauto *add_op = impl.allocate(spv::OpIAdd, instruction);\n\tadd_op->add_id(impl.get_id_for_value(instruction->getOperand(3)));\n\tadd_op->add_id(sum_id);\n\timpl.add(add_op);\n\n\treturn true;\n}\n\nbool emit_bit_reverse_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tauto int_width = instruction->getType()->getIntegerBitWidth();\n\n\tif (int_width == 32)\n\t{\n\t\tauto *op = impl.allocate(spv::OpBitReverse, instruction);\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(op);\n\t\treturn true;\n\t}\n\telse if (int_width == 16)\n\t{\n\t\tspv::Id uint_type = builder.makeUintType(32);\n\t\tspv::Id u16_type = builder.makeUintType(16);\n\t\tspv::Id u16vec2_type = builder.makeVectorType(u16_type, 2);\n\n\t\tauto *conv_op = impl.allocate(spv::OpUConvert, uint_type);\n\t\tconv_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(conv_op);\n\n\t\tauto *reverse_op = impl.allocate(spv::OpBitReverse, uint_type);\n\t\treverse_op->add_id(conv_op->id);\n\t\timpl.add(reverse_op);\n\n\t\tauto *cast_op = impl.allocate(spv::OpBitcast, u16vec2_type);\n\t\tcast_op->add_id(reverse_op->id);\n\t\timpl.add(cast_op);\n\n\t\tauto *ext1 = impl.allocate(spv::OpCompositeExtract, instruction);\n\t\text1->add_id(cast_op->id);\n\t\text1->add_literal(1);\n\t\timpl.add(ext1);\n\t\treturn true;\n\t}\n\telse if (int_width == 64)\n\t{\n\t\tspv::Id uint_type = builder.makeUintType(32);\n\t\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\n\t\tauto *conv_op = impl.allocate(spv::OpBitcast, uvec2_type);\n\t\tconv_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(conv_op);\n\n\t\tauto *reverse_op = impl.allocate(spv::OpBitReverse, uvec2_type);\n\t\treverse_op->add_id(conv_op->id);\n\t\timpl.add(reverse_op);\n\n\t\tauto *shuf_op = impl.allocate(spv::OpVectorShuffle, uvec2_type);\n\t\tshuf_op->add_id(reverse_op->id);\n\t\tshuf_op->add_id(reverse_op->id);\n\t\tshuf_op->add_literal(1);\n\t\tshuf_op->add_literal(0);\n\t\timpl.add(shuf_op);\n\n\t\tauto *cast_op = impl.allocate(spv::OpBitcast, instruction);\n\t\tcast_op->add_id(shuf_op->id);\n\t\timpl.add(cast_op);\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_bit_count_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// Vulkan only allows 32-bit types here for whatever reason ...\n\tauto &builder = impl.builder();\n\tauto int_width = instruction->getOperand(1)->getType()->getIntegerBitWidth();\n\n\tif (int_width == 32)\n\t{\n\t\tauto *op = impl.allocate(spv::OpBitCount, instruction);\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(op);\n\t\treturn true;\n\t}\n\telse if (int_width == 16)\n\t{\n\t\tauto *conv_op = impl.allocate(spv::OpUConvert, builder.makeUintType(32));\n\t\tconv_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(conv_op);\n\n\t\tauto *op = impl.allocate(spv::OpBitCount, instruction);\n\t\top->add_id(conv_op->id);\n\t\timpl.add(op);\n\t\treturn true;\n\t}\n\telse if (int_width == 64)\n\t{\n\t\tspv::Id uint_type = builder.makeUintType(32);\n\t\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\n\t\tauto *conv_op = impl.allocate(spv::OpBitcast, uvec2_type);\n\t\tconv_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(conv_op);\n\n\t\tauto *count_op = impl.allocate(spv::OpBitCount, uvec2_type);\n\t\tcount_op->add_id(conv_op->id);\n\t\timpl.add(count_op);\n\n\t\tauto *ext0 = impl.allocate(spv::OpCompositeExtract, uint_type);\n\t\text0->add_id(count_op->id);\n\t\text0->add_literal(0);\n\t\timpl.add(ext0);\n\n\t\tauto *ext1 = impl.allocate(spv::OpCompositeExtract, uint_type);\n\t\text1->add_id(count_op->id);\n\t\text1->add_literal(1);\n\t\timpl.add(ext1);\n\n\t\tauto *add_op = impl.allocate(spv::OpIAdd, instruction);\n\t\tadd_op->add_id(ext0->id);\n\t\tadd_op->add_id(ext1->id);\n\t\timpl.add(add_op);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_legacy_double_conv_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id input_value = impl.get_id_for_value(instruction->getOperand(1));\n\n\t// We probably need round-to-zero semantics here, but w/e.\n\tif (opcode != spv::OpFConvert)\n\t{\n\t\tauto &builder = impl.builder();\n\t\t// Clamp to target range.\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\tauto *clamp_op = impl.allocate(spv::OpExtInst, builder.makeFloatType(64));\n\t\tclamp_op->add_id(impl.glsl_std450_ext);\n\t\tclamp_op->add_literal(GLSLstd450NClamp);\n\t\tclamp_op->add_id(input_value);\n\t\tclamp_op->add_id(builder.makeDoubleConstant(opcode == spv::OpConvertFToU ? 0.0 : double(INT32_MIN)));\n\t\tclamp_op->add_id(builder.makeDoubleConstant(opcode == spv::OpConvertFToU ? double(UINT32_MAX) : double(INT32_MAX)));\n\n\t\timpl.add(clamp_op);\n\t\tinput_value = clamp_op->id;\n\t}\n\n\tauto *op = impl.allocate(opcode, instruction);\n\top->add_id(input_value);\n\timpl.add(op);\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_arithmetic.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"GLSL.std.450.h\"\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_imad_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_fmad_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_isfinite_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_saturate_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_find_high_bit_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_dxil_unary_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dxil_std450_unary_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dxil_std450_binary_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dxil_std450_trinary_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dxil_wide_arith_instruction(spv::Op op, Converter::Impl &impl, const llvm::CallInst *instruction, bool spirv_semantics);\nbool emit_dxbc_udiv_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_dot_instruction(unsigned dimensions, Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_bfe_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction, bool spirv_semantics);\nbool emit_bfi_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool spirv_semantics);\n\ntemplate <bool spirv_semantics>\nstatic inline bool emit_bfi_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_bfi_instruction(impl, instruction, spirv_semantics);\n}\n\nbool emit_make_double_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_split_double_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_legacy_f16_to_f32_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_legacy_f32_to_f16_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_bitcast_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nspv::Id emit_native_bitscan(GLSLstd450 opcode, Converter::Impl &impl,\n                            const llvm::Instruction *instruction, const llvm::Value *value);\nbool emit_find_low_bit_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\ntemplate <GLSLstd450 opcode>\nstatic inline bool emit_find_high_bit_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_find_high_bit_instruction(opcode, impl, instruction);\n}\n\ntemplate <GLSLstd450 opcode>\nstatic inline bool std450_trinary_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_dxil_std450_trinary_instruction(opcode, impl, instruction);\n}\n\ntemplate <GLSLstd450 opcode>\nstatic inline bool std450_binary_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_dxil_std450_binary_instruction(opcode, impl, instruction);\n}\n\ntemplate <GLSLstd450 opcode>\nstatic inline bool std450_unary_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_dxil_std450_unary_instruction(opcode, impl, instruction);\n}\n\ntemplate <spv::Op opcode>\nstatic inline bool unary_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_dxil_unary_instruction(opcode, impl, instruction);\n}\n\ntemplate <spv::Op opcode, bool spirv_semantics>\nstatic inline bool wide_arith_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_dxil_wide_arith_instruction(opcode, impl, instruction, spirv_semantics);\n}\n\ntemplate <unsigned Dim>\nstatic inline bool emit_dot_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_dot_instruction(Dim, impl, instruction);\n}\n\ntemplate <spv::Op opcode, bool spirv_semantics>\nstatic inline bool emit_bfe_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_bfe_instruction(opcode, impl, instruction, spirv_semantics);\n}\n\nbool emit_i8_dot_instruction(Converter::Impl &Impl, const llvm::CallInst *instruction, bool sign_extend);\ntemplate <bool sign_extend>\nstatic inline bool emit_i8_dot_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_i8_dot_instruction(impl, instruction, sign_extend);\n}\n\nbool emit_dot2_add_half_instruction(Converter::Impl &Impl, const llvm::CallInst *instruction);\nbool emit_unpack4x8_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_pack4x8_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_msad_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_bit_reverse_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_bit_count_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_legacy_double_conv_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\n\ntemplate <spv::Op opcode>\nstatic inline bool emit_legacy_double_conv_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_legacy_double_conv_instruction(opcode, impl, instruction);\n}\n\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_buffer.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_buffer.hpp\"\n#include \"dxil_common.hpp\"\n#include \"dxil_sampling.hpp\"\n#include \"dxil_ags.hpp\"\n#include \"dxil_resources.hpp\"\n#include \"logging.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n\nnamespace dxil_spv\n{\nstatic RawWidth get_buffer_access_bits_per_component(\n\tConverter::Impl &impl, spv::StorageClass storage, const llvm::Type *element_type)\n{\n    if (impl.execution_mode_meta.native_16bit_operations &&\n            (storage == spv::StorageClassPhysicalStorageBuffer || storage == spv::StorageClassStorageBuffer) &&\n            type_is_16bit(element_type))\n\t{\n\t\treturn RawWidth::B16;\n\t}\n\telse if (type_is_64bit(element_type))\n\t\treturn RawWidth::B64;\n\telse\n\t\treturn RawWidth::B32;\n}\n\nvoid emit_buffer_synchronization_validation(Converter::Impl &impl,\n                                            const llvm::CallInst *instruction,\n                                            BDAOperation bda_operation)\n{\n\tif (!impl.options.instruction_instrumentation.enabled ||\n\t    impl.options.instruction_instrumentation.type != InstructionInstrumentationType::BufferSynchronizationValidation)\n\t{\n\t\treturn;\n\t}\n\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tif (meta.storage != spv::StorageClassPhysicalStorageBuffer && meta.instrumentation.bda_id == 0)\n\t\treturn;\n\n\tauto &builder = impl.builder();\n\tspv::Id stride_id = 0;\n\tspv::Id offset_id = 0;\n\tspv::Id elem_id = 0;\n\tspv::Id len_id = 0;\n\n\tif (bda_operation == BDAOperation::Store || bda_operation == BDAOperation::Load)\n\t{\n\t\tconst llvm::Type *element_type;\n\t\tif (bda_operation == BDAOperation::Store)\n\t\t\telement_type = instruction->getOperand(4)->getType();\n\t\telse\n\t\t\telement_type = get_composite_element_type(instruction->getType());\n\n\t\tif (meta.kind == DXIL::ResourceKind::RawBuffer || meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t{\n\t\t\tunsigned mask;\n\n\t\t\tif (bda_operation == BDAOperation::Load)\n\t\t\t{\n\t\t\t\tauto &access_meta = impl.llvm_composite_meta[instruction];\n\t\t\t\tmask = access_meta.access_mask & 0xf;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmask = llvm::cast<llvm::ConstantInt>(instruction->getOperand(8))->getUniqueInteger().getZExtValue();\n\t\t\t}\n\n\t\t\tunsigned width = raw_width_to_bits(get_buffer_access_bits_per_component(impl, meta.storage, element_type));\n\n\t\t\tunsigned num_elems = 0;\n\t\t\tfor (unsigned i = 0; i < 4; i++)\n\t\t\t\tif ((mask & (1u << i)) != 0)\n\t\t\t\t\tnum_elems = i + 1;\n\n\t\t\tlen_id = builder.makeUintConstant(num_elems * width / 8);\n\t\t}\n\n\t\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t\t{\n\t\t\toffset_id = impl.get_id_for_value(instruction->getOperand(2));\n\t\t}\n\t\telse if (meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t{\n\t\t\telem_id = impl.get_id_for_value(instruction->getOperand(2));\n\t\t\tif (!llvm::isa<llvm::UndefValue>(instruction->getOperand(3)))\n\t\t\t\toffset_id = impl.get_id_for_value(instruction->getOperand(3));\n\t\t\tstride_id = builder.makeUintConstant(meta.stride);\n\t\t}\n\t\telse if (meta.kind == DXIL::ResourceKind::TypedBuffer)\n\t\t{\n\t\t\telem_id = impl.get_id_for_value(instruction->getOperand(2));\n\t\t\tstride_id = meta.instrumentation.elem_size_id;\n\t\t\tlen_id = meta.instrumentation.elem_size_id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\telem_id = impl.get_id_for_value(instruction->getOperand(2));\n\t\t\tstride_id = builder.makeUintConstant(16);\n\t\t\tlen_id = stride_id;\n\t\t}\n\t}\n\telse\n\t{\n\t\tunsigned elem_index;\n\n\t\tif (value_is_dx_op_instrinsic(instruction, DXIL::Op::AtomicCompareExchange))\n\t\t\telem_index = 2;\n\t\telse\n\t\t\telem_index = 3;\n\n\t\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t\t{\n\t\t\toffset_id = impl.get_id_for_value(instruction->getOperand(elem_index));\n\t\t}\n\t\telse if (meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t{\n\t\t\telem_id = impl.get_id_for_value(instruction->getOperand(elem_index));\n\t\t\tif (!llvm::isa<llvm::UndefValue>(instruction->getOperand(elem_index + 1)))\n\t\t\t\toffset_id = impl.get_id_for_value(instruction->getOperand(elem_index + 1));\n\t\t\tstride_id = builder.makeUintConstant(meta.stride);\n\t\t}\n\t\telse if (meta.kind == DXIL::ResourceKind::TypedBuffer)\n\t\t{\n\t\t\telem_id = impl.get_id_for_value(instruction->getOperand(elem_index));\n\t\t\tstride_id = meta.instrumentation.elem_size_id;\n\t\t}\n\n\t\tlen_id = builder.makeUintConstant(instruction->getType()->getIntegerBitWidth() / 8);\n\t}\n\n\tspv::Id total_offset_id = 0;\n\n\tif (elem_id != 0)\n\t{\n\t\tauto *mul = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tmul->add_id(elem_id);\n\t\tmul->add_id(stride_id);\n\t\timpl.add(mul);\n\t\ttotal_offset_id = mul->id;\n\t}\n\n\tif (!total_offset_id)\n\t{\n\t\ttotal_offset_id = offset_id;\n\t}\n\telse if (offset_id != 0)\n\t{\n\t\tauto *add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd->add_id(total_offset_id);\n\t\tadd->add_id(offset_id);\n\t\timpl.add(add);\n\t\ttotal_offset_id = add->id;\n\t}\n\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::ValidateBDALoadStore);\n\tauto *call = impl.allocate(spv::OpFunctionCall, builder.makeBoolType());\n\tcall->add_id(call_id);\n\tcall->add_id(meta.instrumentation.bda_id ? meta.instrumentation.bda_id : impl.get_id_for_value(instruction->getOperand(1)));\n\tcall->add_id(total_offset_id);\n\tcall->add_id(len_id);\n\tcall->add_id(builder.makeUintConstant(unsigned(bda_operation)));\n\n\tauto *load_invocation_id = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\tload_invocation_id->add_id(impl.instrumentation.invocation_id_var_id);\n\timpl.add(load_invocation_id);\n\n\tcall->add_id(load_invocation_id->id);\n\n\tif (meta.instrumentation.resource_size_id)\n\t{\n\t\tauto *in_bounds = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\n\t\tif (meta.kind == DXIL::ResourceKind::TypedBuffer)\n\t\t\tin_bounds->add_id(elem_id);\n\t\telse\n\t\t\tin_bounds->add_id(total_offset_id);\n\t\tin_bounds->add_id(meta.instrumentation.resource_size_id);\n\n\t\timpl.add(in_bounds);\n\t\tcall->add_id(in_bounds->id);\n\t}\n\telse\n\t{\n\t\tcall->add_id(builder.makeBoolConstant(true));\n\t}\n\n\timpl.add(call);\n\n\tauto *expect_true = impl.allocate(spv::OpAssumeTrueKHR);\n\texpect_true->add_id(call->id);\n\timpl.add(expect_true);\n}\n\nbool raw_access_byte_address_can_vectorize(Converter::Impl &impl, const llvm::Type *type,\n                                           const llvm::Value *byte_offset,\n                                           unsigned vecsize)\n{\n\t// vec3 vectorization requires scalar block layout always.\n\t// For byte address buffers, robustness must be checked per component, and a vectorized vec3 load\n\t// can straddle the boundary. If the hardware is known not to support per-component robustness correctly,\n\t// avoid vectorizing this case.\n\tif ((!impl.options.scalar_block_layout || !impl.options.supports_per_component_robustness) && vecsize == 3)\n\t\treturn false;\n\n\tif (impl.options.ssbo_alignment > 16 && vecsize == 3)\n\t\treturn false;\n\n\t// The rules for raw BAB vectorization are pretty simple.\n\t// If the offset % element_size == 0, we can translate that load to a clean vectorized load-store.\n\t// vec3 is the special case due to robustness, but robustness2 will generally have 16 byte alignment here,\n\t// so it should be fine.\n\tunsigned addr_shift_log2 = raw_buffer_data_type_to_addr_shift_log2(impl, type);\n\n\tRawBufferAccessSplit split = {};\n\t// If we achieve a successful split, we can vectorize.\n\treturn extract_raw_buffer_access_split(byte_offset, 1, addr_shift_log2, vecsize, split);\n}\n\nbool raw_access_structured_can_vectorize(\n\t\tConverter::Impl &impl, const llvm::Type *type,\n\t\tconst llvm::Value *index, unsigned stride,\n\t\tconst llvm::Value *byte_offset,\n\t\tunsigned vecsize)\n{\n\t// vec3 vectorization requires scalar block layout always.\n\tif (!impl.options.scalar_block_layout && vecsize == 3)\n\t\treturn false;\n\n\tunsigned addr_shift_log2 = raw_buffer_data_type_to_addr_shift_log2(impl, type);\n\tunsigned element_size = (1u << addr_shift_log2) * vecsize;\n\tunsigned alignment = element_size & -int(element_size);\n\n\t// A hypothetical offset buffer must be able to cleanly divide by element_size.\n\t// If stride aligns properly, we know we will never need offset buffers.\n\tif ((stride & (impl.options.ssbo_alignment - 1)) != 0)\n\t{\n\t\t// Mostly relevant for vec3 here, where the binding alignment is smaller than element size divider.\n\t\tif (element_size > alignment)\n\t\t\treturn false;\n\t}\n\n\tRawBufferAccessSplit split = {};\n\treturn extract_raw_buffer_access_split(index, stride, addr_shift_log2, vecsize, split) &&\n\t       extract_raw_buffer_access_split(byte_offset, 1, addr_shift_log2, vecsize, split);\n}\n\nRawVecSize raw_access_byte_address_vectorize(\n\tConverter::Impl &impl, const llvm::Type *type,\n    const llvm::Value *byte_offset, uint32_t mask)\n{\n\tif (mask == 0xfu && raw_access_byte_address_can_vectorize(impl, type, byte_offset, 4))\n\t\treturn RawVecSize::V4;\n\telse if (mask == 0x7u && raw_access_byte_address_can_vectorize(impl, type, byte_offset, 3))\n\t\treturn RawVecSize::V3;\n\telse if (mask == 0x3u && raw_access_byte_address_can_vectorize(impl, type, byte_offset, 2))\n\t\treturn RawVecSize::V2;\n\telse\n\t\treturn RawVecSize::V1;\n}\n\nRawVecSize raw_access_structured_vectorize(\n\tConverter::Impl &impl, const llvm::Type *type,\n\tconst llvm::Value *index,\n\tunsigned stride,\n    const llvm::Value *byte_offset,\n\tuint32_t mask)\n{\n\tif (mask == 0xfu && raw_access_structured_can_vectorize(impl, type, index, stride, byte_offset, 4))\n\t\treturn RawVecSize::V4;\n\telse if (mask == 0x7u && raw_access_structured_can_vectorize(impl, type, index, stride, byte_offset, 3))\n\t\treturn RawVecSize::V3;\n\telse if (mask == 0x3u && raw_access_structured_can_vectorize(impl, type, index, stride, byte_offset, 2))\n\t\treturn RawVecSize::V2;\n\telse\n\t\treturn RawVecSize::V1;\n}\n\nstatic spv::Id build_accumulate_offsets(Converter::Impl &impl, const spv::Id *ids, unsigned count)\n{\n\tspv::Id accumulated_id = 0;\n\tfor (unsigned i = 0; i < count; i++)\n\t{\n\t\tif (!ids[i])\n\t\t\tcontinue;\n\n\t\tif (!accumulated_id)\n\t\t{\n\t\t\taccumulated_id = ids[i];\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, impl.builder().makeUintType(32));\n\t\t\tadd_op->add_id(accumulated_id);\n\t\t\tadd_op->add_id(ids[i]);\n\t\t\timpl.add(add_op);\n\t\t\taccumulated_id = add_op->id;\n\t\t}\n\t}\n\n\tif (!accumulated_id)\n\t\taccumulated_id = impl.builder().makeUintConstant(0);\n\n\treturn accumulated_id;\n}\n\nstatic spv::Id build_structured_index(Converter::Impl &impl, const llvm::Value *index,\n                                      unsigned stride,\n                                      const llvm::Value *byte_offset,\n                                      unsigned addr_shift_log2,\n                                      unsigned vecsize)\n{\n\tauto &builder = impl.builder();\n\tRawBufferAccessSplit stride_split = {};\n\tRawBufferAccessSplit byte_split = {};\n\tif (extract_raw_buffer_access_split(index, stride, addr_shift_log2, vecsize, stride_split) &&\n\t    extract_raw_buffer_access_split(byte_offset, 1, addr_shift_log2, vecsize, byte_split))\n\t{\n\t\tstride_split.bias += byte_split.bias;\n\t\tbyte_split.bias = 0;\n\n\t\tspv::Id offsets_id[3] = {};\n\n\t\tif (stride_split.dynamic_index)\n\t\t{\n\t\t\tif (stride_split.scale != 1)\n\t\t\t{\n\t\t\t\tauto *scale_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\t\tscale_op->add_id(impl.get_id_for_value(stride_split.dynamic_index));\n\t\t\t\tscale_op->add_id(builder.makeUintConstant(stride_split.scale));\n\t\t\t\timpl.add(scale_op);\n\t\t\t\toffsets_id[0] = scale_op->id;\n\t\t\t}\n\t\t\telse\n\t\t\t\toffsets_id[0] = impl.get_id_for_value(stride_split.dynamic_index);\n\t\t}\n\n\t\tif (byte_split.dynamic_index)\n\t\t{\n\t\t\tif (byte_split.scale != 1)\n\t\t\t{\n\t\t\t\tauto *scale_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\t\tscale_op->add_id(builder.makeUintConstant(byte_split.scale));\n\t\t\t\tscale_op->add_id(impl.get_id_for_value(byte_split.dynamic_index));\n\t\t\t\timpl.add(scale_op);\n\t\t\t\toffsets_id[1] = scale_op->id;\n\t\t\t}\n\t\t\telse\n\t\t\t\toffsets_id[1] = impl.get_id_for_value(byte_split.dynamic_index);\n\t\t}\n\n\t\tif (stride_split.bias)\n\t\t\toffsets_id[2] = builder.makeUintConstant(stride_split.bias);\n\n\t\t// byte_split bias is folded.\n\n\t\treturn build_accumulate_offsets(impl, offsets_id, 3);\n\t}\n\telse\n\t{\n\t\tassert(vecsize == 1);\n\t\tspv::Id offsets_id[2] = {};\n\n\t\t// Do it the conservative way.\n\t\tif (stride != (1u << addr_shift_log2))\n\t\t{\n\t\t\tauto *scale_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tscale_op->add_id(impl.get_id_for_value(index));\n\t\t\tscale_op->add_id(builder.makeUintConstant(stride / (1u << addr_shift_log2)));\n\t\t\timpl.add(scale_op);\n\t\t\toffsets_id[0] = scale_op->id;\n\t\t}\n\t\telse\n\t\t\toffsets_id[0] = impl.get_id_for_value(index);\n\n\t\toffsets_id[1] = build_index_divider(impl, byte_offset, addr_shift_log2, 1);\n\n\t\treturn build_accumulate_offsets(impl, offsets_id, 2);\n\t}\n}\n\nunsigned raw_buffer_data_type_to_addr_shift_log2(Converter::Impl &impl, const llvm::Type *data_type)\n{\n\t// A 16-bit raw load is only actually 16-bit if native 16-bit operations are enabled.\n\tif (impl.execution_mode_meta.native_16bit_operations && type_is_16bit(data_type))\n\t\treturn 1;\n\telse if (type_is_64bit(data_type))\n\t\treturn 3;\n\telse\n\t\treturn 2;\n}\n\nstatic BufferAccessInfo build_buffer_access(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                            unsigned operand_offset,\n                                            spv::Id index_offset_id,\n                                            const llvm::Type *data_type,\n                                            uint32_t access_mask)\n{\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tspv::Id index_id = 0;\n\tRawVecSize raw_vecsize = RawVecSize::V1;\n\tunsigned addr_shift_log2 = raw_buffer_data_type_to_addr_shift_log2(impl, data_type);\n\n\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t{\n\t\t// For raw buffers, the index is in bytes.\n\t\traw_vecsize = raw_access_byte_address_vectorize(impl, data_type, instruction->getOperand(2 + operand_offset), access_mask);\n\t\tindex_id = build_index_divider(impl, instruction->getOperand(2 + operand_offset), addr_shift_log2, raw_vecsize_to_vecsize(raw_vecsize));\n\t}\n\telse if (meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t{\n\t\traw_vecsize = raw_access_structured_vectorize(\n\t\t\timpl, data_type,\n\t\t\tinstruction->getOperand(2 + operand_offset),\n\t\t    meta.stride,\n\t\t\tinstruction->getOperand(3 + operand_offset),\n\t\t\taccess_mask);\n\n\t\tindex_id = build_structured_index(\n\t\t\timpl,\n\t\t\tinstruction->getOperand(2 + operand_offset),\n\t\t\tmeta.stride,\n\t\t\tinstruction->getOperand(3 + operand_offset),\n\t\t\taddr_shift_log2,\n\t\t\traw_vecsize_to_vecsize(raw_vecsize));\n\t}\n\telse\n\t\tindex_id = impl.get_id_for_value(instruction->getOperand(2 + operand_offset));\n\n\tif (index_offset_id)\n\t{\n\t\tunsigned vectorized_addr_shift_log2 = addr_shift_log2;\n\n\t\tswitch (raw_vecsize)\n\t\t{\n\t\tcase RawVecSize::V2:\n\t\t\tvectorized_addr_shift_log2 += 1;\n\t\t\tbreak;\n\n\t\tcase RawVecSize::V4:\n\t\t\tvectorized_addr_shift_log2 += 2;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\t// If we need offset buffers, we should never hit this case.\n\t\t\tassert(raw_vecsize != RawVecSize::V3);\n\t\t\tbreak;\n\t\t}\n\n\t\t// Need to shift the offset buffer last minute instead.\n\t\tif (meta.aliased)\n\t\t{\n\t\t\tspv::Id vec_type = builder.makeVectorType(builder.makeUintType(32), 2);\n\t\t\tOperation *shift_op = impl.allocate(spv::OpShiftRightLogical, vec_type);\n\t\t\tshift_op->add_id(index_offset_id);\n\n\t\t\tspv::Id shamt[2];\n\t\t\tshamt[0] = shamt[1] = builder.makeUintConstant(vectorized_addr_shift_log2);\n\t\t\tspv::Id const_vec = impl.build_constant_vector(builder.makeUintType(32), shamt, 2);\n\n\t\t\tshift_op->add_id(const_vec);\n\t\t\timpl.add(shift_op);\n\n\t\t\tindex_offset_id = shift_op->id;\n\t\t}\n\n\t\tOperation *extract_offset = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\t\textract_offset->add_id(index_offset_id);\n\t\textract_offset->add_literal(0);\n\t\timpl.add(extract_offset);\n\n\t\tOperation *extract_len = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\t\textract_len->add_id(index_offset_id);\n\t\textract_len->add_literal(1);\n\t\timpl.add(extract_len);\n\n\t\tOperation *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd_op->add_ids({ index_id, extract_offset->id });\n\t\timpl.add(add_op);\n\n\t\tOperation *compare_op = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\t\tcompare_op->add_ids({ index_id, extract_len->id });\n\t\timpl.add(compare_op);\n\n\t\t// If we have an offset ID, it also means we cannot rely on accurate robustness.\n\t\t// To handle this, we will range check and fabricate an invalid index, which is guaranteed to trip OOB.\n\t\t// This avoids us having to inject branches.\n\t\t// Choose 0x3ffffffc since it is the largest index (for 32-bit) that won't overflow 4GB offset (will break some drivers),\n\t\t// and we potentially need to write 4 elements.\n\t\t// If the allocation in question was really 4GB, then we will never trigger OOB check anyways.\n\t\t// For typed buffers, there is no address computation in the shader, so we should be able to do UINT_MAX.\n\n\t\tOperation *select_op = impl.allocate(spv::OpSelect, builder.makeUintType(32));\n\n\t\tuint32_t oob_index;\n\t\tif (meta.kind == DXIL::ResourceKind::TypedBuffer)\n\t\t\toob_index = 0xffffffffu;\n\t\telse if (raw_vecsize != RawVecSize::V1)\n\t\t\toob_index = 0xffffffffu >> vectorized_addr_shift_log2;\n\t\telse\n\t\t\toob_index = (0xffffffffu >> addr_shift_log2) - 3u;\n\n\t\tselect_op->add_ids({ compare_op->id, add_op->id, builder.makeUintConstant(oob_index) });\n\t\timpl.add(select_op);\n\n\t\tindex_id = select_op->id;\n\t}\n\n\treturn { index_id, raw_vecsize };\n}\n\nstatic spv::Id build_physical_pointer_address_for_raw_load_store(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\tconst auto &meta = impl.handle_to_resource_meta[ptr_id];\n\n\tspv::Id index_id = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id element_offset = 0;\n\tif (meta.stride != 0)\n\t\telement_offset = impl.get_id_for_value(instruction->getOperand(3));\n\n\tspv::Id byte_offset_id = 0;\n\tif (meta.stride)\n\t{\n\t\tauto *stride_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tstride_op->add_id(index_id);\n\t\tstride_op->add_id(builder.makeUintConstant(meta.stride));\n\t\timpl.add(stride_op);\n\n\t\tauto *offset_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\toffset_op->add_id(stride_op->id);\n\t\toffset_op->add_id(element_offset);\n\t\timpl.add(offset_op);\n\n\t\tbyte_offset_id = offset_op->id;\n\t}\n\telse\n\t{\n\t\tbyte_offset_id = index_id;\n\t}\n\n\treturn emit_u32x2_u32_add(impl, ptr_id, byte_offset_id);\n}\n\nstatic spv::Id build_vectorized_physical_load_store_access(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                           unsigned vecsize, const llvm::Type *element_type)\n{\n\tspv::Id ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\tconst auto &meta = impl.handle_to_resource_meta[ptr_id];\n\tunsigned mask = (1u << vecsize) - 1u;\n\n\t// If we can express this as a plain access chain, do so for clarity and ideally better perf.\n\t// If we cannot do it trivially, fallback to raw pointer arithmetic.\n\tbool can_vectorize = false;\n\n\tif (meta.stride)\n\t{\n\t\tif (raw_access_structured_can_vectorize(impl, element_type,\n\t\t                                        instruction->getOperand(2), meta.stride,\n\t\t                                        instruction->getOperand(3), vecsize))\n\t\t{\n\t\t\tcan_vectorize = true;\n\t\t}\n\t}\n\telse if (raw_access_byte_address_can_vectorize(impl, element_type,\n\t                                               instruction->getOperand(2), vecsize))\n\t{\n\t\tcan_vectorize = true;\n\t}\n\n\tif (can_vectorize)\n\t{\n\t\tauto access = build_buffer_access(impl, instruction, 0, 0, element_type, mask);\n\t\treturn access.index_id;\n\t}\n\telse\n\t\treturn 0;\n}\n\nstatic bool emit_physical_buffer_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                  const Converter::Impl::PhysicalPointerMeta &ptr_meta,\n                                                  const ReferenceVkMemoryModel &vkmm,\n                                                  uint32_t mask = 0, uint32_t alignment = 0)\n{\n\tauto &builder = impl.builder();\n\n\tif (mask == 0 && !get_constant_operand(instruction, 4, &mask))\n\t\treturn false;\n\tif (alignment == 0 && !get_constant_operand(instruction, 5, &alignment))\n\t\treturn false;\n\n\tunsigned vecsize = 0;\n\tif (mask == 1)\n\t\tvecsize = 1;\n\telse if (mask == 3)\n\t\tvecsize = 2;\n\telse if (mask == 7)\n\t\tvecsize = 3;\n\telse if (mask == 15)\n\t\tvecsize = 4;\n\telse\n\t{\n\t\tLOGE(\"Unexpected mask for RawBufferLoad = %u.\\n\", mask);\n\t\treturn false;\n\t}\n\n\tauto *element_type = get_composite_element_type(instruction->getType());\n\t// If we can express this as a plain access chain, do so for clarity and ideally better perf.\n\t// If we cannot do it trivially, fallback to raw pointer arithmetic.\n\tspv::Id array_id = build_vectorized_physical_load_store_access(impl, instruction, vecsize, element_type);\n\n\tspv::Id physical_type_id;\n\tspv::Op value_cast_op;\n\tget_physical_load_store_cast_info(impl, element_type, physical_type_id, value_cast_op);\n\n\tif (vecsize > 1)\n\t\tphysical_type_id = builder.makeVectorType(physical_type_id, vecsize);\n\n\tauto scalar_alignment = get_type_scalar_alignment(impl, element_type);\n\t// Fixup broken DXIL.\n\talignment = std::max<uint32_t>(alignment, scalar_alignment);\n\n\tauto tmp_ptr_meta = ptr_meta;\n\ttmp_ptr_meta.stride = array_id ? vecsize * scalar_alignment : 0;\n\tspv::Id ptr_type_id = impl.get_physical_pointer_block_type(physical_type_id, tmp_ptr_meta);\n\n\tif (tmp_ptr_meta.stride && (tmp_ptr_meta.stride & (tmp_ptr_meta.stride - 1)) == 0)\n\t{\n\t\talignment = std::max<uint32_t>(alignment, tmp_ptr_meta.stride);\n\t\talignment = std::min<uint32_t>(alignment, 16);\n\t}\n\n\tspv::Id u64_ptr_id;\n\tif (array_id)\n\t\tu64_ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\telse\n\t\tu64_ptr_id = build_physical_pointer_address_for_raw_load_store(impl, instruction);\n\n\temit_buffer_synchronization_validation(impl, instruction, BDAOperation::Load);\n\n\tauto *ptr_bitcast_op = impl.allocate(spv::OpBitcast, ptr_type_id);\n\tptr_bitcast_op->add_id(u64_ptr_id);\n\timpl.add(ptr_bitcast_op);\n\n\tauto *chain_op = impl.allocate(spv::OpInBoundsAccessChain,\n\t\t\t\t\t\t\t\t   builder.makePointer(spv::StorageClassPhysicalStorageBuffer, physical_type_id));\n\tchain_op->add_id(ptr_bitcast_op->id);\n\tchain_op->add_id(builder.makeUintConstant(0));\n\tif (array_id)\n\t\tchain_op->add_id(array_id);\n\timpl.add(chain_op);\n\n\tauto *load_op = impl.allocate(spv::OpLoad, physical_type_id);\n\tload_op->add_id(chain_op->id);\n\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\tload_op->add_literal(alignment);\n\tadd_vkmm_access_qualifiers(impl, load_op, vkmm);\n\n\timpl.add(load_op, ptr_meta.rov);\n\n\tspv::Id loaded_id = load_op->id;\n\n\tif (value_cast_op != spv::OpNop)\n\t{\n\t\tspv::Id type_id = impl.get_type_id(element_type);\n\t\tif (vecsize > 1)\n\t\t\ttype_id = builder.makeVectorType(type_id, vecsize);\n\t\tauto *cast_op = impl.allocate(value_cast_op, type_id);\n\t\tcast_op->add_id(loaded_id);\n\t\timpl.add(cast_op);\n\t\tloaded_id = cast_op->id;\n\t}\n\n\timpl.rewrite_value(instruction, loaded_id);\n\n\tif (vecsize == 1)\n\t\timpl.llvm_composite_meta[instruction].forced_composite = false;\n\n\treturn true;\n}\n\nstruct RawAccessChain\n{\n    spv::Id ptr_id;\n    spv::Id component_type_id;\n    spv::Id vector_type_id;\n    unsigned alignment;\n};\n\nstatic bool buffer_access_is_raw_access_chain(Converter::Impl &impl, const Converter::Impl::ResourceMeta &meta)\n{\n    return impl.options.nv_raw_access_chains &&\n            (meta.storage == spv::StorageClassStorageBuffer || meta.storage == spv::StorageClassPhysicalStorageBuffer);\n}\n\nstatic RawAccessChain emit_raw_access_chain(Converter::Impl &impl, const Converter::Impl::ResourceMeta &meta,\n                                            const llvm::CallInst *inst, const llvm::Type *element_type, unsigned vecsize)\n{\n\tauto &builder = impl.builder();\n\tspv::Id raw_component_type_id;\n\tRawAccessChain raw = {};\n\n\t// If we're storing to min16 types and we use native 16-bit in arithmetic,\n\t// we have to expand to 32-bit before storing :(\n\t// This will probably fall over with int vs uint, since we don't know how to sign-extend.\n\tif (!impl.execution_mode_meta.native_16bit_operations &&\n\t    impl.options.min_precision_prefer_native_16bit &&\n\t    type_is_16bit(element_type))\n\t{\n\t\tif (element_type->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\t\traw_component_type_id = builder.makeFloatType(32);\n\t\telse\n\t\t\traw_component_type_id = builder.makeUintType(32);\n\t}\n\telse\n\t\traw_component_type_id = impl.get_type_id(element_type);\n\n\tspv::Id vec_type = vecsize > 1 ? builder.makeVectorType(raw_component_type_id, vecsize) : raw_component_type_id;\n\tspv::Id ptr_vec_type = builder.makePointer(spv::StorageClassStorageBuffer, vec_type);\n\n\tbuilder.addCapability(spv::CapabilityRawAccessChainsNV);\n\tbuilder.addExtension(\"SPV_NV_raw_access_chains\");\n\n\tauto *op = impl.allocate(spv::OpRawAccessChainNV, ptr_vec_type);\n\top->add_id(impl.get_id_for_value(inst->getOperand(1)));\n\n\tunsigned scalar_size = builder.getScalarTypeWidth(raw_component_type_id) / 8;\n\n\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t{\n\t\tunsigned addr_shift_log2 = raw_buffer_data_type_to_addr_shift_log2(impl, element_type);\n\n\t\tif (raw_access_byte_address_can_vectorize(impl, element_type, inst->getOperand(2), 4))\n\t\t\traw.alignment = 4;\n\t\telse if (raw_access_byte_address_can_vectorize(impl, element_type, inst->getOperand(2), 2))\n\t\t\traw.alignment = 2;\n\t\telse\n\t\t\traw.alignment = 1;\n\n\t\tif (raw.alignment != 1 && raw.alignment * scalar_size <= 16 && vecsize <= raw.alignment)\n\t\t{\n\t\t\t// If we can prove vectorization, we can treat this as a structured buffer instead.\n\t\t\t// That way we needlessly avoid per-component robustness.\n\t\t\t// BAB descriptor range is aligned to 16 bytes, so we cannot use PerElementMask if the load\n\t\t\t// can straddle a 16 byte boundary.\n\t\t\t// If we care enough, we can split this load into two, and use per-element on both, but that's overkill.\n\n\t\t\tspv::Id element_id = build_index_divider(impl, inst->getOperand(2), addr_shift_log2, raw.alignment);\n\t\t\top->add_id(builder.makeUintConstant(raw.alignment * scalar_size));\n\t\t\top->add_id(element_id);\n\t\t\top->add_id(builder.makeUintConstant(0));\n\t\t\top->add_literal(spv::RawAccessChainOperandsRobustnessPerElementNVMask);\n\t\t}\n\t\telse\n\t\t{\n\t\t\top->add_id(builder.makeUintConstant(0));\n\t\t\top->add_id(builder.makeUintConstant(0));\n\t\t\top->add_id(impl.get_id_for_value(inst->getOperand(2)));\n\t\t\top->add_literal(spv::RawAccessChainOperandsRobustnessPerComponentNVMask);\n\t\t}\n\t}\n\telse\n\t{\n\t\top->add_id(builder.makeUintConstant(meta.stride));\n\t\top->add_id(impl.get_id_for_value(inst->getOperand(2)));\n\t\top->add_id(impl.get_id_for_value(inst->getOperand(3)));\n\t\top->add_literal(spv::RawAccessChainOperandsRobustnessPerElementNVMask);\n\n\t\t// Need extra check for stride alignment since we can normally \"vectorize\" vec3 structured buffers\n\t\t// if SSBO alignment is 4. However, we also need to make sure the alignment is correct before accepting.\n\t\tif ((meta.stride & (scalar_size * 4 - 1)) == 0 &&\n\t\t    raw_access_structured_can_vectorize(\n\t\t\t    impl, element_type,\n\t\t\t    inst->getOperand(2), meta.stride, inst->getOperand(3), 4))\n\t\t{\n\t\t\traw.alignment = 4;\n\t\t}\n\t\telse if ((meta.stride & (scalar_size * 2 - 1)) == 0 &&\n\t\t         raw_access_structured_can_vectorize(\n\t\t\t         impl, element_type,\n\t\t\t         inst->getOperand(2), meta.stride,\n\t\t\t         inst->getOperand(3), 2))\n\t\t{\n\t\t\traw.alignment = 2;\n\t\t}\n\t\telse\n\t\t\traw.alignment = 1;\n\t}\n\n\traw.alignment *= scalar_size;\n\traw.component_type_id = raw_component_type_id;\n\traw.vector_type_id = vec_type;\n\traw.ptr_id = op->id;\n\n\timpl.add(op);\n\n\tif (meta.non_uniform)\n\t\tbuilder.addDecoration(op->id, spv::DecorationNonUniform);\n\n\tif (meta.physical_pointer_meta.nonwritable)\n\t\tbuilder.addDecoration(op->id, spv::DecorationNonWritable);\n\tif (meta.physical_pointer_meta.coherent && impl.execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\tbuilder.addDecoration(op->id, spv::DecorationCoherent);\n\n\treturn raw;\n}\n\nstatic bool emit_buffer_load_raw_chain_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                   const Converter::Impl::ResourceMeta &meta,\n                                                   Converter::Impl::CompositeMeta &access_meta)\n{\n\tauto *result_type = instruction->getType();\n\tauto *target_type = get_composite_element_type(result_type);\n\n\tunsigned num_elements = 1;\n\tfor (unsigned i = 0; i < 4; i++)\n\t\tif ((access_meta.access_mask & (1u << i)) != 0)\n\t\t\tnum_elements = i + 1;\n\tauto raw = emit_raw_access_chain(impl, meta, instruction, target_type, num_elements);\n\n\tauto *load_op = impl.allocate(spv::OpLoad, instruction, raw.vector_type_id);\n\tload_op->add_id(raw.ptr_id);\n\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\tload_op->add_literal(raw.alignment);\n\tadd_vkmm_access_qualifiers(impl, load_op, meta.vkmm);\n\timpl.add(load_op);\n\n\tif (type_is_16bit(target_type) &&\n\t    !impl.execution_mode_meta.native_16bit_operations &&\n\t    impl.options.min_precision_prefer_native_16bit)\n\t{\n\t\tOperation *narrow_op;\n\n\t\tif (target_type->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\t{\n\t\t\tnarrow_op = impl.allocate(\n\t\t\t\tspv::OpFConvert,\n\t\t\t\timpl.get_type_id(DXIL::ComponentType::F16, 1, num_elements));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tnarrow_op = impl.allocate(\n\t\t\t\tspv::OpUConvert,\n\t\t\t\timpl.get_type_id(DXIL::ComponentType::U16, 1, num_elements));\n\t\t}\n\n\t\tnarrow_op->add_id(load_op->id);\n\t\timpl.add(narrow_op);\n\t\timpl.rewrite_value(instruction, narrow_op->id);\n\t}\n\n\taccess_meta.forced_composite = false;\n\treturn true;\n}\n\nbool emit_buffer_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (emit_ags_buffer_load(impl, instruction, DXIL::Op::BufferLoad))\n\t\treturn true;\n\tif (emit_nvapi_buffer_load(impl, instruction, DXIL::Op::BufferLoad))\n\t\treturn true;\n\n\t// Elide dead loads.\n\tif (!impl.composite_is_accessed(instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id image_type_id = impl.get_type_id(image_id);\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tauto &access_meta = impl.llvm_composite_meta[instruction];\n\tbool sparse = (access_meta.access_mask & (1u << 4)) != 0;\n\n\t// Leave no gaps in the access mask to aid vectorization.\n\t// For reads, we can safely read components we not strictly need to read.\n\tuint32_t smeared_access_mask;\n\n\tif (meta.storage != spv::StorageClassUniformConstant)\n\t{\n\t\tsmeared_access_mask = access_meta.access_mask & 0xfu;\n\t\tsmeared_access_mask |= smeared_access_mask >> 1u;\n\t\tsmeared_access_mask |= smeared_access_mask >> 2u;\n\t}\n\telse\n\t\tsmeared_access_mask = 1;\n\n\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\tif (sparse)\n\t\t{\n\t\t\tLOGE(\"Cannot use BDA and sparse feedback. >:(\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// We don't know more about alignment in SM 5.1 BufferStore.\n\t\t// We know the type must be 32-bit however ...\n\t\t// Might be possible to do some fancy analysis to deduce a better alignment.\n\n\t\treturn emit_physical_buffer_load_instruction(impl, instruction, meta.physical_pointer_meta, meta.vkmm,\n\t\t                                             smeared_access_mask, 4);\n\t}\n\n\temit_buffer_synchronization_validation(impl, instruction, BDAOperation::Load);\n\n\tbool raw_access_chain = buffer_access_is_raw_access_chain(impl, meta) && !sparse;\n\tif (raw_access_chain)\n\t\treturn emit_buffer_load_raw_chain_instruction(impl, instruction, meta, access_meta);\n\n\tauto *result_type = instruction->getType();\n\tauto *target_type = get_composite_element_type(result_type);\n\n\tbool is_typed = meta.kind == DXIL::ResourceKind::TypedBuffer;\n\tauto access = build_buffer_access(impl, instruction, 0, meta.index_offset_id,\n\t                                  get_composite_element_type(result_type),\n\t                                  smeared_access_mask);\n\n\tauto width = get_buffer_access_bits_per_component(impl, meta.storage, target_type);\n\tRawType raw_type = target_type->getTypeID() == llvm::Type::TypeID::DoubleTyID ?\n\t                   RawType::Float : RawType::Integer;\n\n\timage_id = get_buffer_alias_handle(impl, meta, image_id, raw_type, width, access.raw_vec_size);\n\tbool vectorized_load = access.raw_vec_size != RawVecSize::V1;\n\n\t// Sparse information is stored in the 5th component.\n\tif (sparse)\n\t\tbuilder.addCapability(spv::CapabilitySparseResidency);\n\n\tif (!is_typed)\n\t{\n\t\t// Unroll up to 4 loads. Ideally, we'd probably use physical_storage_buffer here, but unfortunately we have no indication\n\t\t// how many components we need to load here, and the number of components we load is not necessarily constant,\n\t\t// so we cannot reliably encode this information in the SRV.\n\t\t// The best we can do is to infer it from stride if we can.\n\t\t//unsigned conservative_num_elements = std::min(access.num_components, std::min(4u, access_meta.components));\n\t\tunsigned conservative_num_elements = 0;\n\t\tunsigned vecsize = raw_vecsize_to_vecsize(access.raw_vec_size);\n\n\t\tif (vectorized_load)\n\t\t\tconservative_num_elements = vecsize;\n\t\telse\n\t\t{\n\t\t\tfor (unsigned i = 0; i < 4; i++)\n\t\t\t\tif ((access_meta.access_mask & (1u << i)) != 0)\n\t\t\t\t\tconservative_num_elements = i + 1;\n\t\t}\n\n\t\tspv::Id component_ids[4] = {};\n\n\t\tspv::Id extracted_id_type = raw_type == RawType::Integer ?\n\t\t                            builder.makeUintType(raw_width_to_bits(width)) :\n\t\t                            builder.makeFloatType(raw_width_to_bits(width));\n\n\t\tif (vectorized_load)\n\t\t\textracted_id_type = builder.makeVectorType(extracted_id_type, vecsize);\n\n\t\tspv::Id constructed_id = 0;\n\t\tbool ssbo = meta.storage == spv::StorageClassStorageBuffer;\n\n\t\tauto *element_type = get_composite_element_type(result_type);\n\t\tbool need_cast = (element_type->getTypeID() != llvm::Type::TypeID::IntegerTyID) ||\n\t\t                 (type_is_16bit(element_type) && !impl.execution_mode_meta.native_16bit_operations &&\n\t\t                  impl.options.min_precision_prefer_native_16bit);\n\n\t\t// FP64 is handled directly.\n\t\tif (target_type->getTypeID() == llvm::Type::TypeID::DoubleTyID)\n\t\t\tneed_cast = false;\n\n\t\tif (ssbo && sparse)\n\t\t{\n\t\t\tLOGE(\"Cannot use SSBOs and sparse feedback. >:(\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (ssbo)\n\t\t{\n\t\t\tspv::Id ptr_type = builder.makePointer(spv::StorageClassStorageBuffer, extracted_id_type);\n\t\t\tfor (unsigned i = 0; i < (vectorized_load ? 1 : conservative_num_elements); i++)\n\t\t\t{\n\t\t\t\tif (vectorized_load || (access_meta.access_mask & (1u << i)) != 0)\n\t\t\t\t{\n\t\t\t\t\tauto *chain_op = impl.allocate(spv::OpAccessChain, ptr_type);\n\t\t\t\t\tchain_op->add_id(image_id);\n\t\t\t\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\t\t\t\tchain_op->add_id(impl.build_offset(access.index_id, i));\n\t\t\t\t\timpl.add(chain_op);\n\n\t\t\t\t\tif (meta.non_uniform)\n\t\t\t\t\t\tbuilder.addDecoration(chain_op->id, spv::DecorationNonUniform);\n\n\t\t\t\t\tauto *load_op = impl.allocate(spv::OpLoad, extracted_id_type);\n\t\t\t\t\tload_op->add_id(chain_op->id);\n\n\t\t\t\t\tadd_vkmm_access_qualifiers(impl, load_op, meta.vkmm);\n\t\t\t\t\timpl.add(load_op, meta.rov);\n\t\t\t\t\tcomponent_ids[i] = load_op->id;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcomponent_ids[i] = builder.createUndefined(extracted_id_type);\n\t\t\t}\n\n\t\t\tif (vectorized_load)\n\t\t\t\tconstructed_id = component_ids[0];\n\t\t\telse\n\t\t\t\tconstructed_id = impl.build_vector(extracted_id_type, component_ids, conservative_num_elements);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbool is_uav = builder.isStorageImageType(image_type_id);\n\n\t\t\tspv::Id loaded_id_type = builder.makeVectorType(extracted_id_type, 4);\n\t\t\tspv::Id sparse_code_id = 0;\n\t\t\tspv::Id sparse_loaded_id_type = 0;\n\t\t\tif (sparse)\n\t\t\t\tsparse_loaded_id_type = impl.get_struct_type({ extracted_id_type, loaded_id_type }, 0, \"SparseTexel\");\n\n\t\t\tbool first_load = true;\n\t\t\tfor (unsigned i = 0; i < conservative_num_elements; i++)\n\t\t\t{\n\t\t\t\tif (access_meta.access_mask & (1u << i))\n\t\t\t\t{\n\t\t\t\t\t// There is no sane way to combine sparse feedback code, since it's completely opaque to application.\n\t\t\t\t\t// We could hypothetically return a vector of status code and deal with it magically, but let's not go there ...\n\t\t\t\t\tspv::Op opcode;\n\t\t\t\t\tif (is_uav)\n\t\t\t\t\t\topcode = (sparse && first_load) ? spv::OpImageSparseRead : spv::OpImageRead;\n\t\t\t\t\telse\n\t\t\t\t\t\topcode = (sparse && first_load) ? spv::OpImageSparseFetch : spv::OpImageFetch;\n\n\t\t\t\t\tOperation *loaded_op =\n\t\t\t\t\t    impl.allocate(opcode, (sparse && first_load) ? sparse_loaded_id_type : loaded_id_type);\n\t\t\t\t\tloaded_op->add_ids({ image_id, impl.build_offset(access.index_id, i) });\n\n\t\t\t\t\tadd_vkmm_access_qualifiers(impl, loaded_op, meta.vkmm);\n\t\t\t\t\timpl.add(loaded_op, meta.rov);\n\n\t\t\t\t\tif (sparse && first_load)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *code_extract_op = impl.allocate(spv::OpCompositeExtract, extracted_id_type);\n\t\t\t\t\t\tcode_extract_op->add_id(loaded_op->id);\n\t\t\t\t\t\tcode_extract_op->add_literal(0);\n\t\t\t\t\t\timpl.add(code_extract_op);\n\t\t\t\t\t\tsparse_code_id = code_extract_op->id;\n\n\t\t\t\t\t\tOperation *extracted_op = impl.allocate(spv::OpCompositeExtract, extracted_id_type);\n\t\t\t\t\t\textracted_op->add_id(loaded_op->id);\n\t\t\t\t\t\textracted_op->add_literal(1);\n\t\t\t\t\t\textracted_op->add_literal(0);\n\t\t\t\t\t\timpl.add(extracted_op);\n\t\t\t\t\t\tcomponent_ids[i] = extracted_op->id;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tOperation *extracted_op = impl.allocate(spv::OpCompositeExtract, extracted_id_type);\n\t\t\t\t\t\textracted_op->add_id(loaded_op->id);\n\t\t\t\t\t\textracted_op->add_literal(0);\n\t\t\t\t\t\timpl.add(extracted_op);\n\t\t\t\t\t\tcomponent_ids[i] = extracted_op->id;\n\t\t\t\t\t}\n\t\t\t\t\tfirst_load = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcomponent_ids[i] = builder.createUndefined(builder.makeUintType(32));\n\t\t\t}\n\n\t\t\tif (sparse)\n\t\t\t{\n\t\t\t\tOperation *op = impl.allocate(spv::OpCompositeConstruct, instruction);\n\n\t\t\t\tif (need_cast)\n\t\t\t\t{\n\t\t\t\t\tfor (unsigned i = 0; i < conservative_num_elements; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *bitcast_op =\n\t\t\t\t\t\t    impl.allocate(spv::OpBitcast, impl.get_type_id(element_type));\n\t\t\t\t\t\tbitcast_op->add_id(component_ids[i]);\n\t\t\t\t\t\timpl.add(bitcast_op);\n\t\t\t\t\t\tcomponent_ids[i] = bitcast_op->id;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (unsigned i = 0; i < conservative_num_elements; i++)\n\t\t\t\t\top->add_id(component_ids[i]);\n\t\t\t\tfor (unsigned i = conservative_num_elements; i < 4; i++)\n\t\t\t\t\top->add_id(builder.createUndefined(impl.get_type_id(element_type)));\n\t\t\t\top->add_id(sparse_code_id);\n\t\t\t\timpl.add(op);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconstructed_id = impl.build_vector(extracted_id_type, component_ids, conservative_num_elements);\n\t\t\t}\n\t\t}\n\n\t\tif (!sparse)\n\t\t{\n\t\t\tif (need_cast)\n\t\t\t{\n\t\t\t\tspv::Id casted_id;\n\n\t\t\t\tif (type_is_16bit(element_type) &&\n\t\t\t\t    !impl.execution_mode_meta.native_16bit_operations &&\n\t\t\t\t    impl.options.min_precision_prefer_native_16bit)\n\t\t\t\t{\n\t\t\t\t\tif (element_type->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\t\t\t\t{\n\t\t\t\t\t\tOperation *bitcast_op = impl.allocate(\n\t\t\t\t\t\t\tspv::OpBitcast,\n\t\t\t\t\t\t\timpl.get_type_id(DXIL::ComponentType::F32, 1, conservative_num_elements));\n\t\t\t\t\t\tbitcast_op->add_id(constructed_id);\n\t\t\t\t\t\timpl.add(bitcast_op);\n\t\t\t\t\t\tcasted_id = bitcast_op->id;\n\n\t\t\t\t\t\tOperation *narrow_op = impl.allocate(\n\t\t\t\t\t\t\tspv::OpFConvert,\n\t\t\t\t\t\t\timpl.get_type_id(DXIL::ComponentType::F16, 1, conservative_num_elements));\n\t\t\t\t\t\tnarrow_op->add_id(casted_id);\n\t\t\t\t\t\timpl.add(narrow_op);\n\t\t\t\t\t\tcasted_id = narrow_op->id;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tOperation *narrow_op = impl.allocate(\n\t\t\t\t\t\t\tspv::OpUConvert,\n\t\t\t\t\t\t\timpl.get_type_id(DXIL::ComponentType::U16, 1, conservative_num_elements));\n\t\t\t\t\t\tnarrow_op->add_id(constructed_id);\n\t\t\t\t\t\timpl.add(narrow_op);\n\t\t\t\t\t\tcasted_id = narrow_op->id;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tOperation *op = impl.allocate(\n\t\t\t\t\t\tspv::OpBitcast, impl.build_vector_type(impl.get_type_id(element_type), conservative_num_elements));\n\t\t\t\t\top->add_id(constructed_id);\n\t\t\t\t\timpl.add(op);\n\t\t\t\t\tcasted_id = op->id;\n\t\t\t\t}\n\n\t\t\t\timpl.rewrite_value(instruction, casted_id);\n\t\t\t}\n\t\t\telse\n\t\t\t\timpl.rewrite_value(instruction, constructed_id);\n\t\t}\n\n\t\taccess_meta.forced_composite = false;\n\t}\n\telse\n\t{\n\t\tbool is_uav = builder.isStorageImageType(image_type_id);\n\n\t\tauto effective_component_type = Converter::Impl::get_effective_typed_resource_type(meta.component_type);\n\t\tspv::Id texel_type = impl.get_type_id(effective_component_type, 1, 4);\n\t\tspv::Id sample_type;\n\n\t\tif (sparse)\n\t\t\tsample_type = impl.get_struct_type({ builder.makeUintType(32), texel_type }, 0, \"SparseTexel\");\n\t\telse\n\t\t\tsample_type = texel_type;\n\n\t\tspv::Op opcode;\n\t\tif (is_uav)\n\t\t\topcode = sparse ? spv::OpImageSparseRead : spv::OpImageRead;\n\t\telse\n\t\t\topcode = sparse ? spv::OpImageSparseFetch : spv::OpImageFetch;\n\n\t\tOperation *op = impl.allocate(opcode, instruction, sample_type);\n\n\t\tif (!sparse)\n\t\t\timpl.decorate_relaxed_precision(get_composite_element_type(instruction->getType()), op->id, true);\n\n\t\top->add_ids({ image_id, access.index_id });\n\t\tadd_vkmm_access_qualifiers(impl, op, meta.vkmm);\n\t\timpl.add(op, meta.rov);\n\n\t\tif (sparse)\n\t\t\timpl.repack_sparse_feedback(meta.component_type, 4, instruction, target_type);\n\t\telse\n\t\t\timpl.fixup_load_type_typed(meta.component_type, 4, instruction, target_type);\n\t}\n\n\treturn true;\n}\n\nstatic bool emit_physical_buffer_store_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                   const Converter::Impl::PhysicalPointerMeta &ptr_meta,\n                                                   const ReferenceVkMemoryModel &vkmm,\n                                                   uint32_t alignment = 0)\n{\n\tauto &builder = impl.builder();\n\n\tuint32_t mask = 0;\n\tif (!get_constant_operand(instruction, 8, &mask))\n\t\treturn false;\n\n\tif (alignment == 0 && !get_constant_operand(instruction, 9, &alignment))\n\t\treturn false;\n\n\tunsigned vecsize = 0;\n\tif (mask == 1)\n\t\tvecsize = 1;\n\telse if (mask == 3)\n\t\tvecsize = 2;\n\telse if (mask == 7)\n\t\tvecsize = 3;\n\telse if (mask == 15)\n\t\tvecsize = 4;\n\telse\n\t{\n\t\tLOGE(\"Unexpected mask for RawBufferStore = %u.\\n\", mask);\n\t\treturn false;\n\t}\n\n\tauto *element_type = instruction->getOperand(4)->getType();\n\n\t// If we can express this as a plain access chain, do so for clarity and ideally better perf.\n\t// If we cannot do it trivially, fallback to raw pointer arithmetic.\n\tspv::Id array_id = build_vectorized_physical_load_store_access(impl, instruction, vecsize, element_type);\n\n\tspv::Id physical_type_id;\n\tspv::Op value_cast_op;\n\tget_physical_load_store_cast_info(impl, element_type, physical_type_id, value_cast_op);\n\n\tspv::Id vec_type_id = physical_type_id;\n\tif (vecsize > 1)\n\t\tvec_type_id = builder.makeVectorType(physical_type_id, vecsize);\n\n\tauto scalar_alignment = get_type_scalar_alignment(impl, element_type);\n\t// Fixup broken DXIL.\n\talignment = std::max<uint32_t>(alignment, scalar_alignment);\n\n\tauto tmp_ptr_meta = ptr_meta;\n\ttmp_ptr_meta.stride = array_id ? vecsize * scalar_alignment : 0;\n\tspv::Id ptr_type_id = impl.get_physical_pointer_block_type(vec_type_id, tmp_ptr_meta);\n\n\tif (tmp_ptr_meta.stride && (tmp_ptr_meta.stride & (tmp_ptr_meta.stride - 1)) == 0)\n\t{\n\t\talignment = std::max<uint32_t>(alignment, tmp_ptr_meta.stride);\n\t\talignment = std::min<uint32_t>(alignment, 16);\n\t}\n\n\tspv::Id u64_ptr_id;\n\tif (array_id)\n\t\tu64_ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\telse\n\t\tu64_ptr_id = build_physical_pointer_address_for_raw_load_store(impl, instruction);\n\n\temit_buffer_synchronization_validation(impl, instruction, BDAOperation::Store);\n\n\tauto *ptr_bitcast_op = impl.allocate(spv::OpBitcast, ptr_type_id);\n\tptr_bitcast_op->add_id(u64_ptr_id);\n\timpl.add(ptr_bitcast_op);\n\n\tauto *chain_op = impl.allocate(spv::OpInBoundsAccessChain,\n\t\t\t\t\t\t\t\t   builder.makePointer(spv::StorageClassPhysicalStorageBuffer, vec_type_id));\n\tchain_op->add_id(ptr_bitcast_op->id);\n\tchain_op->add_id(builder.makeUintConstant(0));\n\tif (array_id)\n\t\tchain_op->add_id(array_id);\n\timpl.add(chain_op);\n\n\tspv::Id elems[4] = {};\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\timpl.register_externally_visible_write(instruction->getOperand(4 + i));\n\t\telems[i] = impl.get_id_for_value(instruction->getOperand(4 + i));\n\t}\n\n\tauto *store_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(chain_op->id);\n\n\tspv::Id vec_id = impl.build_vector(physical_type_id, elems, vecsize);\n\tif (value_cast_op != spv::OpNop)\n\t{\n\t\tauto *op = impl.allocate(value_cast_op, vec_type_id);\n\t\top->add_id(vec_id);\n\t\timpl.add(op);\n\t\tvec_id = op->id;\n\t}\n\n\tstore_op->add_id(vec_id);\n\tstore_op->add_literal(spv::MemoryAccessAlignedMask);\n\tstore_op->add_literal(alignment);\n\tadd_vkmm_access_qualifiers(impl, store_op, vkmm);\n\n\timpl.add(store_op, ptr_meta.rov);\n\n\treturn true;\n}\n\nbool emit_raw_buffer_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (emit_ags_buffer_load(impl, instruction, DXIL::Op::RawBufferLoad))\n\t\treturn true;\n\tif (emit_nvapi_buffer_load(impl, instruction, DXIL::Op::RawBufferLoad))\n\t\treturn true;\n\n\tif (!impl.composite_is_accessed(instruction))\n\t\treturn true;\n\n\tspv::Id ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\tconst auto &meta = impl.handle_to_resource_meta[ptr_id];\n\n\tif (meta.storage != spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\tauto *ret_component = get_composite_element_type(instruction->getType());\n\t\tif (ret_component->getTypeID() != llvm::Type::TypeID::FloatTyID &&\n\t\t    !(ret_component->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t\t      ret_component->getIntegerBitWidth() == 32) &&\n\t\t    meta.storage != spv::StorageClassStorageBuffer)\n\t\t{\n\t\t\tLOGE(\"16 or 64-bit RawBufferLoad on descriptors is only supported for SSBOs.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// Ignore the mask. We'll read too much, but robustness should take care of any OOB.\n\t\treturn emit_buffer_load_instruction(impl, instruction);\n\t}\n\telse\n\t\treturn emit_physical_buffer_load_instruction(impl, instruction, meta.physical_pointer_meta, meta.vkmm);\n}\n\nstatic unsigned emit_buffer_store_values_bitcast(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                 spv::Id *store_values, unsigned write_mask,\n                                                 RawWidth raw_width,\n                                                 bool is_typed, bool ignore_bitcast)\n{\n\tauto *element_type = instruction->getOperand(4)->getType();\n\tauto &builder = impl.builder();\n\tunsigned raw_vecsize = 0;\n\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\tif ((write_mask & (1u << i)) != 0)\n\t\t{\n\t\t\timpl.register_externally_visible_write(instruction->getOperand(4 + i));\n\t\t\tstore_values[i] = impl.get_id_for_value(instruction->getOperand(4 + i));\n\t\t\tif (!is_typed)\n\t\t\t{\n\t\t\t\t// If we're storing to min16 types and we use native 16-bit in arithmetic,\n\t\t\t\t// we have to expand to 32-bit before storing :(\n\t\t\t\t// This will probably fall over with int vs uint, since we don't know how to sign-extend.\n\t\t\t\tif (!impl.execution_mode_meta.native_16bit_operations &&\n\t\t\t\t    impl.options.min_precision_prefer_native_16bit &&\n\t\t\t\t    type_is_16bit(element_type))\n\t\t\t\t{\n\t\t\t\t\tif (element_type->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\t\t\t\t{\n\t\t\t\t\t\tOperation *op = impl.allocate(spv::OpFConvert, builder.makeFloatType(32));\n\t\t\t\t\t\top->add_id(store_values[i]);\n\t\t\t\t\t\tstore_values[i] = op->id;\n\t\t\t\t\t\timpl.add(op);\n\n\t\t\t\t\t\tif (!ignore_bitcast)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tOperation *bitcast_op = impl.allocate(spv::OpBitcast, builder.makeUintType(32));\n\t\t\t\t\t\t\tbitcast_op->add_id(store_values[i]);\n\t\t\t\t\t\t\timpl.add(bitcast_op);\n\t\t\t\t\t\t\tstore_values[i] = bitcast_op->id;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// SConvert or UConvert, who knows. :)\n\t\t\t\t\t\tOperation *op = impl.allocate(spv::OpUConvert, builder.makeUintType(32));\n\t\t\t\t\t\top->add_id(store_values[i]);\n\t\t\t\t\t\tstore_values[i] = op->id;\n\t\t\t\t\t\timpl.add(op);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (!ignore_bitcast &&\n\t\t\t\t         element_type->getTypeID() != llvm::Type::TypeID::DoubleTyID &&\n\t\t\t\t         element_type->getTypeID() != llvm::Type::TypeID::IntegerTyID)\n\t\t\t\t{\n\t\t\t\t\tOperation *op = impl.allocate(spv::OpBitcast, builder.makeUintType(raw_width_to_bits(raw_width)));\n\t\t\t\t\top->add_id(store_values[i]);\n\t\t\t\t\tstore_values[i] = op->id;\n\t\t\t\t\timpl.add(op);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\traw_vecsize = i + 1;\n\t\t}\n\t}\n\n\treturn raw_vecsize;\n}\n\nbool emit_buffer_store_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\tif (emit_ags_buffer_store(impl, instruction, image_id))\n\t\treturn true;\n\tif (emit_nvapi_buffer_store(impl, instruction, image_id))\n\t\treturn true;\n\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\t// We don't more about alignment in SM 5.1 BufferStore.\n\t\t// We know the type must be 32-bit however ...\n\t\t// Might be possible to do some fancy analysis to deduce a better alignment.\n\t\treturn emit_physical_buffer_store_instruction(impl, instruction, meta.physical_pointer_meta, meta.vkmm, 4);\n\t}\n\n\temit_buffer_synchronization_validation(impl, instruction, BDAOperation::Store);\n\n\tauto *element_type = instruction->getOperand(4)->getType();\n\n\t// SSBO operations with min16* types are actually 32-bit.\n\t// We only get native 16-bit load-store with native_16bit_operations.\n\tbool is_typed = meta.kind == DXIL::ResourceKind::TypedBuffer;\n\tunsigned mask = llvm::cast<llvm::ConstantInt>(instruction->getOperand(8))->getUniqueInteger().getZExtValue();\n\tauto width = get_buffer_access_bits_per_component(impl, meta.storage, element_type);\n\n\tbool raw_access_chain = buffer_access_is_raw_access_chain(impl, meta);\n\tspv::Id store_values[4] = {};\n\n\tif (raw_access_chain)\n\t{\n\t\tauto raw_vecsize = emit_buffer_store_values_bitcast(impl, instruction, store_values, mask, width, false, true);\n\t\tauto raw = emit_raw_access_chain(impl, meta, instruction, element_type, raw_vecsize);\n\t\tspv::Id vector_value_id = impl.build_vector(raw.component_type_id, store_values, raw_vecsize);\n\n\t\tauto *store_op = impl.allocate(spv::OpStore);\n\t\tstore_op->add_id(raw.ptr_id);\n\t\tstore_op->add_id(vector_value_id);\n\t\tstore_op->add_literal(spv::MemoryAccessAlignedMask);\n\t\tstore_op->add_literal(raw.alignment);\n\t\tadd_vkmm_access_qualifiers(impl, store_op, meta.vkmm);\n\n\t\timpl.add(store_op);\n\t\treturn true;\n\t}\n\n\tauto access = build_buffer_access(impl, instruction, 0, meta.index_offset_id,\n\t                                  instruction->getOperand(4)->getType(),\n\t                                  meta.storage != spv::StorageClassUniformConstant ? mask : 1u);\n\n\tRawType raw_type = element_type->getTypeID() == llvm::Type::TypeID::DoubleTyID ?\n\t                   RawType::Float : RawType::Integer;\n\n\timage_id = get_buffer_alias_handle(impl, meta, image_id, raw_type, width, access.raw_vec_size);\n\tbool vectorized_store = access.raw_vec_size != RawVecSize::V1;\n\n\t// We could hoist the call to emit_buffer_store_values_bitcast,\n\t// but causes too much churn on shader deltas.\n\temit_buffer_store_values_bitcast(impl, instruction, store_values, mask, width, is_typed, false);\n\n\tif (is_typed)\n\t{\n\t\tspv::Id element_type_id = impl.get_type_id(instruction->getOperand(4)->getType());\n\n\t\t// Deal with signed resource store.\n\t\tOperation *op = impl.allocate(spv::OpImageWrite);\n\t\top->add_ids(\n\t\t    { image_id, access.index_id,\n\t\t      impl.fixup_store_type_typed(meta.component_type, 4, impl.build_vector(element_type_id, store_values, 4)) });\n\n\t\tadd_vkmm_access_qualifiers(impl, op, meta.vkmm);\n\t\timpl.add(op, meta.rov);\n\t}\n\telse if (meta.storage == spv::StorageClassStorageBuffer)\n\t{\n\t\tif (vectorized_store)\n\t\t{\n\t\t\tspv::Id elem_type_id = raw_type == RawType::Integer ?\n\t\t\t                       builder.makeUintType(raw_width_to_bits(width)) :\n\t\t\t                       builder.makeFloatType(raw_width_to_bits(width));\n\n\t\t\tunsigned vecsize = raw_vecsize_to_vecsize(access.raw_vec_size);\n\t\t\tspv::Id vec_type_id = builder.makeVectorType(elem_type_id, vecsize);\n\t\t\tspv::Id vector_value_id = impl.build_vector(elem_type_id, store_values, vecsize);\n\t\t\tOperation *chain_op = impl.allocate(\n\t\t\t\tspv::OpAccessChain, builder.makePointer(spv::StorageClassStorageBuffer, vec_type_id));\n\n\t\t\tchain_op->add_id(image_id);\n\t\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\t\tchain_op->add_id(access.index_id);\n\t\t\timpl.add(chain_op);\n\n\t\t\tif (meta.non_uniform)\n\t\t\t\tbuilder.addDecoration(chain_op->id, spv::DecorationNonUniform);\n\n\t\t\tOperation *store_op = impl.allocate(spv::OpStore);\n\t\t\tstore_op->add_id(chain_op->id);\n\t\t\tstore_op->add_id(vector_value_id);\n\t\t\tadd_vkmm_access_qualifiers(impl, store_op, meta.vkmm);\n\n\t\t\timpl.add(store_op, meta.rov);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (unsigned i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tif (mask & (1u << i))\n\t\t\t\t{\n\t\t\t\t\tspv::Id elem_type_id = raw_type == RawType::Integer ?\n\t\t\t\t\t                       builder.makeUintType(raw_width_to_bits(width)) :\n\t\t\t\t\t                       builder.makeFloatType(raw_width_to_bits(width));\n\n\t\t\t\t\tOperation *chain_op = impl.allocate(\n\t\t\t\t\t    spv::OpAccessChain, builder.makePointer(spv::StorageClassStorageBuffer, elem_type_id));\n\t\t\t\t\tchain_op->add_id(image_id);\n\t\t\t\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\t\t\t\tchain_op->add_id(impl.build_offset(access.index_id, i));\n\t\t\t\t\timpl.add(chain_op);\n\n\t\t\t\t\tif (meta.non_uniform)\n\t\t\t\t\t\tbuilder.addDecoration(chain_op->id, spv::DecorationNonUniform);\n\n\t\t\t\t\tOperation *store_op = impl.allocate(spv::OpStore);\n\t\t\t\t\tstore_op->add_id(chain_op->id);\n\t\t\t\t\tstore_op->add_id(store_values[i]);\n\n\t\t\t\t\tadd_vkmm_access_qualifiers(impl, store_op, meta.vkmm);\n\t\t\t\t\timpl.add(store_op, meta.rov);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tspv::Id splat_type_id = builder.makeVectorType(builder.makeUintType(32), 4);\n\t\tfor (unsigned i = 0; i < 4; i++)\n\t\t{\n\t\t\tif (mask & (1u << i))\n\t\t\t{\n\t\t\t\tOperation *splat_op = impl.allocate(spv::OpCompositeConstruct, splat_type_id);\n\t\t\t\tsplat_op->add_ids({ store_values[i], store_values[i], store_values[i], store_values[i] });\n\t\t\t\timpl.add(splat_op);\n\n\t\t\t\tOperation *op = impl.allocate(spv::OpImageWrite);\n\t\t\t\top->add_ids({\n\t\t\t\t    image_id,\n\t\t\t\t    impl.build_offset(access.index_id, i),\n\t\t\t\t    splat_op->id,\n\t\t\t\t});\n\n\t\t\t\tadd_vkmm_access_qualifiers(impl, op, meta.vkmm);\n\t\t\t\timpl.add(op, meta.rov);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (is_typed)\n\t\tbuilder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);\n\n\treturn true;\n}\n\nbool emit_raw_buffer_store_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\tif (emit_ags_buffer_store(impl, instruction, ptr_id))\n\t\treturn true;\n\tif (emit_nvapi_buffer_store(impl, instruction, ptr_id))\n\t\treturn true;\n\n\tconst auto &meta = impl.handle_to_resource_meta[ptr_id];\n\n\tif (meta.storage != spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\tauto *store_type = instruction->getOperand(4)->getType();\n\t\tif (store_type->getTypeID() != llvm::Type::TypeID::FloatTyID &&\n\t\t    !(store_type->getTypeID() == llvm::Type::TypeID::IntegerTyID && store_type->getIntegerBitWidth() == 32) &&\n\t\t    meta.storage != spv::StorageClassStorageBuffer)\n\t\t{\n\t\t\tLOGE(\"16 or 64-bit RawBufferStore on descriptors is only supported for SSBOs.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\treturn emit_buffer_store_instruction(impl, instruction);\n\t}\n\telse\n\t\treturn emit_physical_buffer_store_instruction(impl, instruction, meta.physical_pointer_meta, meta.vkmm);\n}\n\nspv::Id emit_atomic_access_chain(Converter::Impl &impl,\n                                 const Converter::Impl::ResourceMeta &meta,\n                                 RawWidth width, spv::Id image_id, spv::Id coord,\n                                 DXIL::ComponentType &component_type)\n{\n\tauto &builder = impl.builder();\n\tOperation *counter_ptr_op = nullptr;\n\tcomponent_type = raw_width_to_component_type(RawType::Integer, width);\n\tspv::Id var_id = get_buffer_alias_handle(impl, meta, meta.var_id, RawType::Integer, width, RawVecSize::V1);\n\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\tspv::Id uint_type = builder.makeUintType(raw_width_to_bits(width));\n\t\tauto physical_pointer_meta = meta.physical_pointer_meta;\n\t\tphysical_pointer_meta.stride = raw_width_to_bits(width) / 8;\n\t\tspv::Id ptr_type_id =\n\t\t    impl.get_physical_pointer_block_type(uint_type, physical_pointer_meta);\n\n\t\tauto *ptr_bitcast_op = impl.allocate(spv::OpBitcast, ptr_type_id);\n\t\tptr_bitcast_op->add_id(image_id);\n\t\timpl.add(ptr_bitcast_op);\n\n\t\tcounter_ptr_op = impl.allocate(spv::OpAccessChain,\n\t\t                               builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type));\n\t\tcounter_ptr_op->add_ids({ ptr_bitcast_op->id, builder.makeUintConstant(0), coord });\n\t}\n\telse if (meta.storage == spv::StorageClassStorageBuffer)\n\t{\n\t\tcounter_ptr_op =\n\t\t    impl.allocate(spv::OpAccessChain,\n\t\t                  builder.makePointer(spv::StorageClassStorageBuffer,\n\t\t                                      builder.makeUintType(raw_width_to_bits(width))));\n\t\tcounter_ptr_op->add_ids({ var_id, builder.makeUintConstant(0), coord });\n\t}\n\telse\n\t{\n\t\tcounter_ptr_op =\n\t\t    impl.allocate(spv::OpImageTexelPointer,\n\t\t                  builder.makePointer(spv::StorageClassImage, impl.get_type_id(meta.component_type, 1, 1)));\n\t\tcounter_ptr_op->add_ids({ var_id, coord, builder.makeUintConstant(0) });\n\t\tcomponent_type = meta.component_type;\n\t}\n\timpl.add(counter_ptr_op);\n\n\treturn counter_ptr_op->id;\n}\n\nbool emit_atomic_binop_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\tauto binop = static_cast<DXIL::AtomicBinOp>(\n\t    llvm::cast<llvm::ConstantInt>(instruction->getOperand(2))->getUniqueInteger().getZExtValue());\n\n\temit_buffer_synchronization_validation(impl, instruction, BDAOperation::AtomicRMW);\n\n\tspv::Id coords[3] = {};\n\tuint32_t num_coords_full = 0, num_coords = 0;\n\n\tif (meta.kind == DXIL::ResourceKind::StructuredBuffer || meta.kind == DXIL::ResourceKind::RawBuffer ||\n\t    meta.kind == DXIL::ResourceKind::TypedBuffer)\n\t{\n\t\tauto access = build_buffer_access(impl, instruction, 1, meta.index_offset_id, instruction->getType(), 1);\n\t\tcoords[0] = access.index_id;\n\t\tnum_coords = 1;\n\t\tnum_coords_full = 1;\n\t}\n\telse\n\t{\n\t\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\t\treturn false;\n\n\t\tif (num_coords_full > 3)\n\t\t\treturn false;\n\n\t\tfor (uint32_t i = 0; i < num_coords_full; i++)\n\t\t\tcoords[i] = impl.get_id_for_value(instruction->getOperand(3 + i));\n\t}\n\tspv::Id coord = impl.build_vector(builder.makeUintType(32), coords, num_coords_full);\n\n\tauto width = get_buffer_access_bits_per_component(impl, meta.storage, instruction->getType());\n\tif (width == RawWidth::B64)\n\t\tbuilder.addCapability(spv::CapabilityInt64Atomics);\n\n\tDXIL::ComponentType component_type;\n\tspv::Id counter_ptr_id = emit_atomic_access_chain(impl, meta, width, image_id, coord, component_type);\n\n\tif (meta.non_uniform)\n\t\tbuilder.addDecoration(counter_ptr_id, spv::DecorationNonUniformEXT);\n\n\tspv::Op opcode;\n\n\tswitch (binop)\n\t{\n\tcase DXIL::AtomicBinOp::Exchange:\n\t\topcode = spv::OpAtomicExchange;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::IAdd:\n\t\topcode = spv::OpAtomicIAdd;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::And:\n\t\topcode = spv::OpAtomicAnd;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::Or:\n\t\topcode = spv::OpAtomicOr;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::Xor:\n\t\topcode = spv::OpAtomicXor;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::IMin:\n\t\topcode = spv::OpAtomicSMin;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::IMax:\n\t\topcode = spv::OpAtomicSMax;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::UMin:\n\t\topcode = spv::OpAtomicUMin;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::UMax:\n\t\topcode = spv::OpAtomicUMax;\n\t\tbreak;\n\n\t// Internal extensions.\n\tcase DXIL::AtomicBinOp::Load:\n\t\topcode = spv::OpAtomicLoad;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::Store:\n\t\topcode = spv::OpAtomicStore;\n\t\tbreak;\n\n\tcase DXIL::AtomicBinOp::Sub:\n\t\topcode = spv::OpAtomicISub;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tOperation *op;\n\n\tif (opcode != spv::OpAtomicStore)\n\t\top = impl.allocate(opcode, instruction, impl.get_type_id(component_type, 1, 1));\n\telse\n\t\top = impl.allocate(opcode);\n\n\top->add_id(counter_ptr_id);\n\top->add_id(builder.getAtomicDeviceScopeId());\n\top->add_id(builder.makeUintConstant(0));\n\n\tif (opcode != spv::OpAtomicLoad)\n\t\top->add_id(impl.fixup_store_type_atomic(component_type, 1, impl.get_id_for_value(instruction->getOperand(6))));\n\n\timpl.add(op, meta.rov);\n\n\timpl.fixup_load_type_atomic(component_type, 1, instruction);\n\treturn true;\n}\n\nbool emit_atomic_cmpxchg_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\tif (image_id == impl.ags.magic_ptr_id)\n\t\treturn emit_magic_ags_instruction(impl, instruction);\n\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\temit_buffer_synchronization_validation(impl, instruction, BDAOperation::AtomicRMW);\n\n\tspv::Id coords[3] = {};\n\tuint32_t num_coords_full = 0, num_coords = 0;\n\n\tif (meta.kind == DXIL::ResourceKind::StructuredBuffer ||\n\t    meta.kind == DXIL::ResourceKind::RawBuffer ||\n\t    meta.kind == DXIL::ResourceKind::TypedBuffer)\n\t{\n\t\tauto access = build_buffer_access(impl, instruction, 0, meta.index_offset_id, instruction->getType(), 1);\n\t\tcoords[0] = access.index_id;\n\t\tnum_coords = 1;\n\t\tnum_coords_full = 1;\n\t}\n\telse\n\t{\n\t\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\t\treturn false;\n\n\t\tif (num_coords_full > 3)\n\t\t\treturn false;\n\n\t\tfor (uint32_t i = 0; i < num_coords_full; i++)\n\t\t\tcoords[i] = impl.get_id_for_value(instruction->getOperand(2 + i));\n\t}\n\n\tspv::Id coord = impl.build_vector(builder.makeUintType(32), coords, num_coords_full);\n\n\tauto width = get_buffer_access_bits_per_component(impl, meta.storage, instruction->getType());\n\tif (width == RawWidth::B64)\n\t\tbuilder.addCapability(spv::CapabilityInt64Atomics);\n\n\tDXIL::ComponentType component_type;\n\tspv::Id counter_ptr_id = emit_atomic_access_chain(impl, meta, width, image_id, coord, component_type);\n\n\tif (meta.non_uniform)\n\t\tbuilder.addDecoration(counter_ptr_id, spv::DecorationNonUniformEXT);\n\n\tOperation *op =\n\t    impl.allocate(spv::OpAtomicCompareExchange, instruction, impl.get_type_id(component_type, 1, 1));\n\n\tspv::Id comparison_id = impl.get_id_for_value(instruction->getOperand(5));\n\tspv::Id new_value_id = impl.get_id_for_value(instruction->getOperand(6));\n\tcomparison_id = impl.fixup_store_type_atomic(component_type, 1, comparison_id);\n\tnew_value_id = impl.fixup_store_type_atomic(component_type, 1, new_value_id);\n\n\top->add_id(counter_ptr_id);\n\top->add_id(builder.getAtomicDeviceScopeId());\n\top->add_id(builder.makeUintConstant(0));\n\top->add_id(builder.makeUintConstant(0));\n\top->add_id(new_value_id);\n\top->add_id(comparison_id);\n\timpl.add(op, meta.rov);\n\timpl.fixup_load_type_atomic(component_type, 1, instruction);\n\treturn true;\n}\n\nbool emit_buffer_update_counter_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\tif (emit_nvapi_buffer_update_counter(impl, instruction, image_id))\n\t\treturn true;\n\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\tint direction = llvm::cast<llvm::ConstantInt>(instruction->getOperand(2))->getUniqueInteger().getSExtValue();\n\n\tif (meta.counter_storage == spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\tspv::Id func_id = impl.spirv_module.get_helper_call_id(HelperCall::RobustAtomicCounter);\n\t\tauto *op = impl.allocate(spv::OpFunctionCall, instruction);\n\t\top->add_id(func_id);\n\t\top->add_id(meta.counter_var_id);\n\t\top->add_id(builder.makeUintConstant(direction));\n\t\top->add_id(builder.makeUintConstant(direction < 0 ? -1u : 0u));\n\t\timpl.add(op, meta.rov);\n\t}\n\telse\n\t{\n\t\tspv::Id ptr_id;\n\n\t\tif (meta.counter_storage == spv::StorageClassUniformConstant)\n\t\t{\n\t\t\tauto *counter_ptr_op = impl.allocate(spv::OpImageTexelPointer,\n\t\t\t                                     builder.makePointer(spv::StorageClassImage, builder.makeUintType(32)));\n\n\t\t\tcounter_ptr_op->add_id(meta.counter_var_id);\n\t\t\tcounter_ptr_op->add_id(builder.makeUintConstant(0));\n\t\t\tcounter_ptr_op->add_id(builder.makeUintConstant(0));\n\n\t\t\tif (meta.non_uniform)\n\t\t\t\tbuilder.addDecoration(counter_ptr_op->id, spv::DecorationNonUniformEXT);\n\t\t\timpl.add(counter_ptr_op);\n\t\t\tptr_id = counter_ptr_op->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tptr_id = meta.counter_var_id;\n\t\t}\n\n\t\tauto *op = impl.allocate(spv::OpAtomicIAdd, instruction);\n\n\t\top->add_id(ptr_id);\n\t\top->add_id(builder.getAtomicDeviceScopeId());\n\t\top->add_id(builder.makeUintConstant(0));\n\t\top->add_id(builder.makeUintConstant(direction));\n\t\timpl.add(op, meta.rov);\n\n\t\tspv::Id result_id = op->id;\n\n\t\tif (direction < 0)\n\t\t{\n\t\t\top = impl.allocate(spv::OpISub, builder.makeUintType(32));\n\t\t\top->add_ids({ result_id, builder.makeUintConstant(1) });\n\t\t\timpl.add(op);\n\t\t\timpl.rewrite_value(instruction, op->id);\n\t\t}\n\t}\n\n\treturn true;\n}\n\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_buffer.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n\nnamespace dxil_spv\n{\nstruct BufferAccessInfo\n{\n\tspv::Id index_id;\n\tRawVecSize raw_vec_size;\n};\n\nbool emit_buffer_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_raw_buffer_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_buffer_store_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_raw_buffer_store_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_atomic_binop_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_atomic_cmpxchg_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_buffer_update_counter_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nunsigned raw_buffer_data_type_to_addr_shift_log2(Converter::Impl &impl, const llvm::Type *data_type);\n\nbool raw_access_byte_address_can_vectorize(Converter::Impl &impl, const llvm::Type *type,\n                                           const llvm::Value *byte_offset, unsigned vecsize);\n\nbool raw_access_structured_can_vectorize(Converter::Impl &impl, const llvm::Type *type,\n                                         const llvm::Value *index,\n                                         unsigned stride,\n                                         const llvm::Value *byte_offset,\n                                         unsigned vecsize);\n\nRawVecSize raw_access_byte_address_vectorize(Converter::Impl &impl, const llvm::Type *type,\n                                             const llvm::Value *byte_offset, uint32_t mask);\n\nRawVecSize raw_access_structured_vectorize(Converter::Impl &impl, const llvm::Type *type,\n                                           const llvm::Value *index,\n                                           unsigned stride,\n                                           const llvm::Value *byte_offset,\n                                           uint32_t mask);\n\nvoid emit_buffer_synchronization_validation(Converter::Impl &impl, const llvm::CallInst *instruction, BDAOperation bda_operation);\n\nspv::Id emit_atomic_access_chain(Converter::Impl &impl,\n                                 const Converter::Impl::ResourceMeta &meta,\n                                 RawWidth width, spv::Id image_id, spv::Id coord,\n                                 DXIL::ComponentType &component_type);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_common.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_common.hpp\"\n#include \"logging.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n\nnamespace dxil_spv\n{\nbool get_constant_operand(const llvm::Instruction *value, unsigned index, uint32_t *operand)\n{\n\tif (index >= value->getNumOperands())\n\t{\n\t\tLOGE(\"Operand index out of range.\\n\");\n\t\treturn false;\n\t}\n\n\tauto *constant = llvm::dyn_cast<llvm::ConstantInt>(value->getOperand(index));\n\tif (!constant)\n\t\treturn false;\n\n\t*operand = uint32_t(constant->getUniqueInteger().getZExtValue());\n\treturn true;\n}\n\nspv::Id emit_u32x2_u32_add(Converter::Impl &impl, spv::Id u32x2_value, spv::Id u32_value)\n{\n\tauto &builder = impl.builder();\n\tspv::Id uint_type = builder.makeUintType(32);\n\n\tauto *base_addr_lo = impl.allocate(spv::OpCompositeExtract, uint_type);\n\tbase_addr_lo->add_id(u32x2_value);\n\tbase_addr_lo->add_literal(0);\n\timpl.add(base_addr_lo);\n\n\tauto *base_addr_hi = impl.allocate(spv::OpCompositeExtract, uint_type);\n\tbase_addr_hi->add_id(u32x2_value);\n\tbase_addr_hi->add_literal(1);\n\timpl.add(base_addr_hi);\n\n\tauto *add_op = impl.allocate(spv::OpIAddCarry, impl.get_struct_type({ uint_type, uint_type }, 0, \"AddCarry\"));\n\tadd_op->add_ids({ base_addr_lo->id, u32_value });\n\timpl.add(add_op);\n\n\tauto *lo_op = impl.allocate(spv::OpCompositeExtract, uint_type);\n\tlo_op->add_id(add_op->id);\n\tlo_op->add_literal(0);\n\timpl.add(lo_op);\n\n\tauto *carry_op = impl.allocate(spv::OpCompositeExtract, uint_type);\n\tcarry_op->add_id(add_op->id);\n\tcarry_op->add_literal(1);\n\timpl.add(carry_op);\n\n\tauto *hi_op = impl.allocate(spv::OpIAdd, uint_type);\n\thi_op->add_id(base_addr_hi->id);\n\thi_op->add_id(carry_op->id);\n\timpl.add(hi_op);\n\n\tspv::Id addr_elems[2] = { lo_op->id, hi_op->id };\n\tspv::Id addr_vec = impl.build_vector(uint_type, addr_elems, 2);\n\treturn addr_vec;\n}\n\nunsigned get_type_scalar_alignment(Converter::Impl &impl, const llvm::Type *type)\n{\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t\ttype = vec->getElementType();\n\n\tunsigned scalar_alignment;\n\tswitch (type->getTypeID())\n\t{\n\tcase llvm::Type::TypeID::IntegerTyID:\n\t\tscalar_alignment = type->getIntegerBitWidth() / 8;\n\t\tbreak;\n\tcase llvm::Type::TypeID::HalfTyID:\n\t\tscalar_alignment = 2;\n\t\tbreak;\n\tcase llvm::Type::TypeID::FloatTyID:\n\t\tscalar_alignment = 4;\n\t\tbreak;\n\tcase llvm::Type::TypeID::DoubleTyID:\n\t\tscalar_alignment = 8;\n\t\tbreak;\n\tdefault:\n\t\tLOGE(\"Invalid type for scalar alignment query.\\n\");\n\t\treturn 1;\n\t}\n\n\tif (!impl.execution_mode_meta.native_16bit_operations && scalar_alignment == 2)\n\t\tscalar_alignment = 4;\n\n\treturn scalar_alignment;\n}\n\nspv::Id get_buffer_alias_handle(Converter::Impl &impl, const Converter::Impl::ResourceMeta &meta,\n                                spv::Id default_id, RawType type, RawWidth width, RawVecSize vecsize)\n{\n\tfor (auto &alias : meta.var_alias_group)\n\t{\n\t\tif (alias.declaration.type == type &&\n\t\t    alias.declaration.width == width &&\n\t\t    alias.declaration.vecsize == vecsize)\n\t\t{\n\t\t\tdefault_id = alias.var_id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn default_id;\n}\n\nbool type_is_16bit(const llvm::Type *data_type)\n{\n\treturn data_type->getTypeID() == llvm::Type::TypeID::HalfTyID ||\n\t       (data_type->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t        data_type->getIntegerBitWidth() == 16);\n}\n\nbool type_is_64bit(const llvm::Type *data_type)\n{\n\treturn data_type->getTypeID() == llvm::Type::TypeID::DoubleTyID ||\n\t       (data_type->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t        data_type->getIntegerBitWidth() == 64);\n}\n\nvoid get_physical_load_store_cast_info(Converter::Impl &impl, const llvm::Type *element_type,\n                                       spv::Id &physical_type_id, spv::Op &value_cast_op)\n{\n\tbool using_native_16bit_arith =\n\t\ttype_is_16bit(element_type) &&\n\t\t(element_type->getTypeID() == llvm::Type::TypeID::IntegerTyID || impl.support_native_fp16_operations());\n\n\tif (!impl.execution_mode_meta.native_16bit_operations && using_native_16bit_arith)\n\t{\n\t\tif (element_type->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\t{\n\t\t\tphysical_type_id = impl.get_type_id(DXIL::ComponentType::F32, 1, 1);\n\t\t\tvalue_cast_op = spv::OpFConvert;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tphysical_type_id = impl.get_type_id(DXIL::ComponentType::U32, 1, 1);\n\t\t\tvalue_cast_op = spv::OpUConvert;\n\t\t}\n\t}\n\telse\n\t{\n\t\tphysical_type_id = impl.get_type_id(element_type);\n\t\tvalue_cast_op = spv::OpNop;\n\t}\n}\n\nstatic spv::Id build_index_divider_fallback(Converter::Impl &impl, const llvm::Value *offset, unsigned addr_shift_log2)\n{\n\tauto &builder = impl.builder();\n\tOperation *op = impl.allocate(spv::OpShiftRightLogical, builder.makeUintType(32));\n\top->add_id(impl.get_id_for_value(offset));\n\top->add_id(builder.makeUintConstant(addr_shift_log2));\n\timpl.add(op);\n\treturn op->id;\n}\n\nbool extract_raw_buffer_access_split(const llvm::Value *index, unsigned stride,\n                                     uint32_t addr_shift_log2, unsigned vecsize,\n                                     RawBufferAccessSplit &split)\n{\n\tunsigned element_size = (1u << addr_shift_log2) * vecsize;\n\n\t// Base case first, a constant value.\n\tif (const auto *const_addr = llvm::dyn_cast<llvm::ConstantInt>(index))\n\t{\n\t\tint64_t constant_offset = const_addr->getUniqueInteger().getSExtValue();\n\t\tconstant_offset *= stride;\n\n\t\t// Always pass scalar constant dividers through.\n\t\t// Building a fallback divider helps nothing.\n\t\tif (vecsize == 1 || constant_offset % int(element_size) == 0)\n\t\t{\n\t\t\tsplit = {};\n\t\t\tsplit.bias = constant_offset / element_size;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tconst llvm::ConstantInt *scale = nullptr;\n\tconst llvm::ConstantInt *bias = nullptr;\n\tbool scale_log2 = false;\n\tbool bias_is_add = false;\n\tbool bias_negate = false;\n\n\twhile (!scale && llvm::isa<llvm::BinaryOperator>(index))\n\t{\n\t\tauto *binop = llvm::cast<llvm::BinaryOperator>(index);\n\t\tauto *lhs = binop->getOperand(0);\n\t\tauto *rhs = binop->getOperand(1);\n\t\tif (!bias && (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Add ||\n\t\t              binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Sub ||\n\t\t              binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Or ||\n\t\t              binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Xor))\n\t\t{\n\t\t\tif (const auto *const_lhs = llvm::dyn_cast<llvm::ConstantInt>(lhs))\n\t\t\t{\n\t\t\t\tbias = const_lhs;\n\t\t\t\tindex = rhs;\n\t\t\t}\n\t\t\telse if (const auto *const_rhs = llvm::dyn_cast<llvm::ConstantInt>(rhs))\n\t\t\t{\n\t\t\t\tbias = const_rhs;\n\t\t\t\tindex = lhs;\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\n\t\t\t// DXC tends to be emit shift + or in some cases.\n\t\t\t// We can turn this back into mul + add in most cases.\n\t\t\tbias_negate = binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Sub;\n\t\t\tbias_is_add =\n\t\t\t\t\tbinop->getOpcode() == llvm::BinaryOperator::BinaryOps::Add ||\n\t\t\t\t\tbias_negate;\n\t\t}\n\t\telse if (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Shl)\n\t\t{\n\t\t\tif (const auto *const_rhs = llvm::dyn_cast<llvm::ConstantInt>(rhs))\n\t\t\t{\n\t\t\t\tscale = const_rhs;\n\t\t\t\tindex = lhs;\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\n\t\t\tscale_log2 = true;\n\t\t}\n\t\telse if (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Mul)\n\t\t{\n\t\t\tif (const auto *const_lhs = llvm::dyn_cast<llvm::ConstantInt>(lhs))\n\t\t\t{\n\t\t\t\tscale = const_lhs;\n\t\t\t\tindex = rhs;\n\t\t\t}\n\t\t\telse if (const auto *const_rhs = llvm::dyn_cast<llvm::ConstantInt>(rhs))\n\t\t\t{\n\t\t\t\tscale = const_rhs;\n\t\t\t\tindex = lhs;\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\n\t\t\tscale_log2 = false;\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tif (!scale && !bias)\n\t{\n\t\t// We cannot split anything, but we might be able to vectorize if the stride alone carries us.\n\t\tif (stride % element_size == 0)\n\t\t{\n\t\t\tsplit = {};\n\t\t\tsplit.scale = stride / element_size;\n\t\t\tsplit.dynamic_index = index;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tuint64_t scale_factor = 1;\n\tif (scale)\n\t\tscale_factor = scale->getUniqueInteger().getZExtValue();\n\tif (scale_log2)\n\t\tscale_factor = 1ull << scale_factor;\n\n\tint64_t bias_factor = 0;\n\tif (bias)\n\t\tbias_factor = bias->getUniqueInteger().getSExtValue();\n\tif (bias_negate)\n\t\tbias_factor = -bias_factor;\n\n\t// If there is no bit overlap between scale_factor and bias_factor\n\t// then the bitwise OR is equivalent to add.\n\tif (!bias_is_add && (scale_factor & bias_factor) != 0)\n\t\treturn false;\n\n\tscale_factor *= stride;\n\tbias_factor *= stride;\n\n\tif (scale_factor % element_size == 0 && bias_factor % element_size == 0 && index)\n\t{\n\t\tsplit.scale = scale_factor / element_size;\n\t\tsplit.bias = bias_factor / int(element_size);\n\t\tsplit.dynamic_index = index;\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nspv::Id build_index_divider(Converter::Impl &impl, const llvm::Value *offset,\n                            unsigned addr_shift_log2, unsigned vecsize)\n{\n\tauto &builder = impl.builder();\n\t// Attempt to do trivial constant folding to make output a little more sensible to read.\n\t// Try to find an expression for offset which is \"constant0 * offset + constant1\",\n\t// where constant0 and constant1 are aligned with addr_shift_log2.\n\n\tspv::Id index_id;\n\tRawBufferAccessSplit split = {};\n\n\tif (extract_raw_buffer_access_split(offset, 1, addr_shift_log2, vecsize, split))\n\t{\n\t\tif (!split.dynamic_index)\n\t\t\treturn builder.makeUintConstant(split.bias);\n\n\t\tspv::Op bias_opcode = split.bias > 0 ? spv::OpIAdd : spv::OpISub;\n\t\tif (bias_opcode == spv::OpISub)\n\t\t\tsplit.bias = -split.bias;\n\n\t\tspv::Id scaled_id;\n\t\tif (split.scale != 1)\n\t\t{\n\t\t\tOperation *scale_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tscale_op->add_id(impl.get_id_for_value(split.dynamic_index));\n\t\t\tscale_op->add_id(builder.makeUintConstant(split.scale));\n\t\t\timpl.add(scale_op);\n\t\t\tscaled_id = scale_op->id;\n\t\t}\n\t\telse\n\t\t\tscaled_id = impl.get_id_for_value(split.dynamic_index);\n\n\t\tspv::Id bias_id;\n\t\tif (split.bias != 0)\n\t\t{\n\t\t\tOperation *bias_op = impl.allocate(bias_opcode, builder.makeUintType(32));\n\t\t\tbias_op->add_id(scaled_id);\n\t\t\tbias_op->add_id(builder.makeUintConstant(split.bias));\n\t\t\timpl.add(bias_op);\n\t\t\tbias_id = bias_op->id;\n\t\t}\n\t\telse\n\t\t\tbias_id = scaled_id;\n\n\t\tindex_id = bias_id;\n\t}\n\telse\n\t{\n\t\tassert(vecsize == 1);\n\t\tindex_id = build_index_divider_fallback(impl, offset, addr_shift_log2);\n\t}\n\n\treturn index_id;\n}\n\nspv::Id build_load_invocation_id(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInInvocationId);\n\n\tOperation *op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\top->add_id(var_id);\n\n\timpl.add(op);\n\treturn op->id;\n}\n\nspv::Id get_clip_cull_distance_access_chain(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                            const Converter::Impl::ClipCullMeta &meta, spv::StorageClass storage)\n{\n\tauto &builder = impl.builder();\n\tuint32_t var_id = storage == spv::StorageClassOutput ? impl.spirv_module.get_builtin_shader_output(meta.builtin) :\n\t                  impl.spirv_module.get_builtin_shader_input(meta.builtin);\n\n\tOperation *op = impl.allocate(spv::OpAccessChain, builder.makePointer(storage, builder.makeFloatType(32)));\n\top->add_id(var_id);\n\n\tif (instruction->getNumOperands() >= 6 &&\n\t    storage == spv::StorageClassOutput &&\n\t    impl.execution_model == spv::ExecutionModelMeshEXT)\n\t{\n\t\t// Mesh shaders, need to index into per-vertex array.\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(5)));\n\t}\n\n\tif (storage == spv::StorageClassInput)\n\t{\n\t\tif (impl.execution_model == spv::ExecutionModelGeometry ||\n\t\t    impl.execution_model == spv::ExecutionModelTessellationControl ||\n\t\t    impl.execution_model == spv::ExecutionModelTessellationEvaluation)\n\t\t{\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(4)));\n\t\t}\n\t}\n\telse if (storage == spv::StorageClassOutput && impl.execution_model == spv::ExecutionModelTessellationControl)\n\t{\n\t\top->add_id(build_load_invocation_id(impl));\n\t}\n\n\tauto *row = instruction->getOperand(2);\n\tauto *row_const = llvm::dyn_cast<llvm::ConstantInt>(row);\n\n\tuint32_t constant_col;\n\tif (!get_constant_operand(instruction, 3, &constant_col))\n\t\treturn false;\n\n\tunsigned stride = meta.row_stride;\n\n\tif (row_const)\n\t{\n\t\top->add_id(builder.makeUintConstant(row_const->getUniqueInteger().getZExtValue() * stride + constant_col +\n\t\t                                    meta.offset));\n\t}\n\telse if (stride == 1 && meta.offset == 0)\n\t{\n\t\t// Simple case, can just index directly into ClipDistance array.\n\t\top->add_id(impl.get_id_for_value(row));\n\t}\n\telse if (stride == 1)\n\t{\n\t\tOperation *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd_op->add_id(impl.get_id_for_value(row));\n\t\tadd_op->add_id(builder.makeUintConstant(meta.offset));\n\t\timpl.add(add_op);\n\n\t\top->add_id(add_op->id);\n\t}\n\telse\n\t{\n\t\t// A more annoying case, flatten 2D to 1D.\n\t\tOperation *mul_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tmul_op->add_id(impl.get_id_for_value(row));\n\t\tmul_op->add_id(builder.makeUintConstant(stride));\n\t\timpl.add(mul_op);\n\n\t\tOperation *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd_op->add_id(mul_op->id);\n\t\tadd_op->add_id(builder.makeUintConstant(constant_col + meta.offset));\n\t\timpl.add(add_op);\n\n\t\top->add_id(add_op->id);\n\t}\n\n\timpl.add(op);\n\treturn op->id;\n}\n\nbool emit_store_clip_cull_distance(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                   const Converter::Impl::ClipCullMeta &meta)\n{\n\tspv::Id ptr_id = get_clip_cull_distance_access_chain(impl, instruction, meta, spv::StorageClassOutput);\n\n\timpl.register_externally_visible_write(instruction->getOperand(4));\n\tspv::Id store_value = impl.get_id_for_value(instruction->getOperand(4));\n\tOperation *store_op = impl.allocate(spv::OpStore);\n\tstore_op->add_ids({ ptr_id, store_value });\n\timpl.add(store_op);\n\treturn true;\n}\n\nConverter::Impl::ClipCullMeta *output_clip_cull_distance_meta(Converter::Impl &impl, unsigned index)\n{\n\tauto itr = impl.output_clip_cull_meta.find(index);\n\tif (itr != impl.output_clip_cull_meta.end())\n\t\treturn &itr->second;\n\telse\n\t\treturn nullptr;\n}\n\nbool value_is_dx_op_instrinsic(const llvm::Value *value, DXIL::Op op)\n{\n\tauto *call = llvm::dyn_cast<llvm::CallInst>(value);\n\tif (!call)\n\t\treturn false;\n\n\tauto *func = call->getCalledFunction();\n\tif (strncmp(func->getName().data(), \"dx.op\", 5) != 0)\n\t\treturn false;\n\n\t// The opcode is encoded as a constant integer.\n\tuint32_t opcode;\n\tif (!get_constant_operand(call, 0, &opcode))\n\t\treturn false;\n\n\treturn op == DXIL::Op(opcode);\n}\n\nvoid emit_expect_assume_quad_uniform(Converter::Impl &impl)\n{\n\tif (impl.options.instruction_instrumentation.enabled &&\n\t    impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume &&\n\t    !impl.memoized.current_quad_uniform_checked)\n\t{\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::IsQuadUniformControlFlow);\n\t\tauto *call = impl.allocate(spv::OpFunctionCall, impl.builder().makeBoolType());\n\t\tcall->add_id(call_id);\n\t\timpl.add(call);\n\n\t\tauto *assert_uniform = impl.allocate(spv::OpAssumeTrueKHR);\n\t\tassert_uniform->add_id(call->id);\n\t\timpl.add(assert_uniform);\n\n\t\timpl.memoized.current_quad_uniform_checked = true;\n\t}\n}\n\nSplitScaleBias split_index_scale_bias(const llvm::Value *value)\n{\n\tconst auto *cint = llvm::dyn_cast<llvm::ConstantInt>(value);\n\t// Return UINT32_MAX as stride since we cannot reasonably know yet.\n\tif (cint)\n\t\treturn { UINT32_MAX, nullptr, uint32_t(cint->getUniqueInteger().getZExtValue()) };\n\n\tconst auto *binop = llvm::dyn_cast<llvm::BinaryOperator>(value);\n\tif (!binop)\n\t\treturn {};\n\n\tif (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Add)\n\t{\n\t\tconst auto *const0 = llvm::dyn_cast<llvm::ConstantInt>(binop->getOperand(0));\n\t\tconst auto *const1 = llvm::dyn_cast<llvm::ConstantInt>(binop->getOperand(1));\n\t\tif (const0 && !const1)\n\t\t{\n\t\t\tauto split = split_index_scale_bias(binop->getOperand(1));\n\t\t\tsplit.elem += const0->getUniqueInteger().getZExtValue();\n\t\t\treturn split;\n\t\t}\n\t\telse if (!const0 && const1)\n\t\t{\n\t\t\tauto split = split_index_scale_bias(binop->getOperand(0));\n\t\t\tsplit.elem += const1->getUniqueInteger().getZExtValue();\n\t\t\treturn split;\n\t\t}\n\t}\n\telse if (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Mul)\n\t{\n\t\tconst auto *const0 = llvm::dyn_cast<llvm::ConstantInt>(binop->getOperand(0));\n\t\tconst auto *const1 = llvm::dyn_cast<llvm::ConstantInt>(binop->getOperand(1));\n\t\tif (const0 && !const1)\n\t\t\treturn { uint32_t(const0->getUniqueInteger().getZExtValue()), binop->getOperand(1), 0 };\n\t\telse if (!const0 && const1)\n\t\t\treturn { uint32_t(const1->getUniqueInteger().getZExtValue()), binop->getOperand(0), 0 };\n\t}\n\n\treturn {};\n}\n\nvoid add_vkmm_access_qualifiers(Converter::Impl &impl, Operation *op, const ReferenceVkMemoryModel &vkmm)\n{\n\tif (impl.execution_mode_meta.memory_model != spv::MemoryModelVulkan)\n\t\treturn;\n\n\tuint32_t mm_argument_index = 0;\n\tuint32_t mm_flags = 0;\n\n\tswitch (op->op)\n\t{\n\tcase spv::OpLoad:\n\t\tif (vkmm.non_private)\n\t\t\tmm_flags |= spv::MemoryAccessNonPrivatePointerMask;\n\t\tif (vkmm.auto_visibility)\n\t\t\tmm_flags |= spv::MemoryAccessMakePointerVisibleMask;\n\t\tmm_argument_index = 1;\n\t\tbreak;\n\n\tcase spv::OpStore:\n\t\tif (vkmm.non_private)\n\t\t\tmm_flags |= spv::MemoryAccessNonPrivatePointerMask;\n\t\tif (vkmm.auto_visibility)\n\t\t\tmm_flags |= spv::MemoryAccessMakePointerAvailableMask;\n\t\tmm_argument_index = 2;\n\t\tbreak;\n\n\tcase spv::OpCooperativeMatrixLoadKHR:\n\t\tif (vkmm.non_private)\n\t\t\tmm_flags |= spv::MemoryAccessNonPrivatePointerMask;\n\t\tif (vkmm.auto_visibility)\n\t\t\tmm_flags |= spv::MemoryAccessMakePointerVisibleMask;\n\t\tmm_argument_index = 3;\n\t\tbreak;\n\n\tcase spv::OpCooperativeMatrixStoreKHR:\n\t\tif (vkmm.non_private)\n\t\t\tmm_flags |= spv::MemoryAccessNonPrivatePointerMask;\n\t\tif (vkmm.auto_visibility)\n\t\t\tmm_flags |= spv::MemoryAccessMakePointerAvailableMask;\n\t\tmm_argument_index = 4;\n\t\tbreak;\n\n\tcase spv::OpImageRead:\n\tcase spv::OpImageSparseRead:\n\t\tif (vkmm.non_private)\n\t\t\tmm_flags |= spv::ImageOperandsNonPrivateTexelMask;\n\t\tif (vkmm.auto_visibility)\n\t\t\tmm_flags |= spv::ImageOperandsMakeTexelVisibleMask;\n\t\tmm_argument_index = 2;\n\t\tbreak;\n\n\tcase spv::OpImageWrite:\n\t\tif (vkmm.non_private)\n\t\t\tmm_flags |= spv::ImageOperandsNonPrivateTexelMask;\n\t\tif (vkmm.auto_visibility)\n\t\t\tmm_flags |= spv::ImageOperandsMakeTexelAvailableMask;\n\t\tmm_argument_index = 3;\n\t\tbreak;\n\n\tdefault:\n\t\treturn;\n\t}\n\n\tif (mm_flags)\n\t{\n\t\tif (op->num_arguments > mm_argument_index)\n\t\t\top->arguments[mm_argument_index] |= mm_flags;\n\t\telse\n\t\t\top->add_literal(mm_flags);\n\n\t\tif (vkmm.auto_visibility)\n\t\t\top->add_id(impl.builder().makeUintConstant(spv::ScopeQueueFamily));\n\t}\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_common.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"SpvBuilder.h\"\n#include \"opcodes/opcodes.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n\nnamespace dxil_spv\n{\nbool get_constant_operand(const llvm::Instruction *value, unsigned index, uint32_t *operand);\nspv::Id emit_u32x2_u32_add(Converter::Impl &impl, spv::Id u32x2_value, spv::Id u32_value);\nunsigned get_type_scalar_alignment(Converter::Impl &impl, const llvm::Type *type);\n\nspv::Id get_buffer_alias_handle(Converter::Impl &impl, const Converter::Impl::ResourceMeta &meta,\n                                spv::Id default_id, RawType type, RawWidth width, RawVecSize vecsize);\n\nbool type_is_16bit(const llvm::Type *data_type);\nbool type_is_64bit(const llvm::Type *data_type);\n\nvoid get_physical_load_store_cast_info(Converter::Impl &impl, const llvm::Type *element_type,\n                                       spv::Id &physical_type_id, spv::Op &value_cast_op);\n\nstruct RawBufferAccessSplit\n{\n\tuint64_t scale;\n\tint64_t bias;\n\tconst llvm::Value *dynamic_index;\n};\n\nbool extract_raw_buffer_access_split(const llvm::Value *index, unsigned stride,\n\t\t\t\t\t\t\t\t\t uint32_t addr_shift_log2, unsigned vecsize,\n\t\t\t\t\t\t\t\t\t RawBufferAccessSplit &split);\n\nspv::Id build_index_divider(Converter::Impl &impl, const llvm::Value *offset,\n                            unsigned addr_shift_log2, unsigned vecsize);\n\n// Clip-cull distance munging.\nspv::Id get_clip_cull_distance_access_chain(\n\tConverter::Impl &impl, const llvm::CallInst *instruction,\n\tconst Converter::Impl::ClipCullMeta &meta, spv::StorageClass storage);\nConverter::Impl::ClipCullMeta *output_clip_cull_distance_meta(\n\tConverter::Impl &impl, unsigned index);\nbool emit_store_clip_cull_distance(\n\tConverter::Impl &impl, const llvm::CallInst *instruction,\n\tconst Converter::Impl::ClipCullMeta &meta);\n\nbool value_is_dx_op_instrinsic(const llvm::Value *value, DXIL::Op op);\n\nspv::Id build_load_invocation_id(Converter::Impl &impl);\n\nvoid emit_expect_assume_quad_uniform(Converter::Impl &impl);\n\nstruct SplitScaleBias\n{\n\tuint32_t stride;\n\tconst llvm::Value *index;\n\tuint32_t elem;\n};\n\nSplitScaleBias split_index_scale_bias(const llvm::Value *value);\n\nstruct ReferenceVkMemoryModel;\nvoid add_vkmm_access_qualifiers(Converter::Impl &impl, Operation *op, const ReferenceVkMemoryModel &vkmm);\n}\n"
  },
  {
    "path": "opcodes/dxil/dxil_compute.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_compute.hpp\"\n#include \"dxil_common.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_barrier_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tuint32_t operation;\n\tif (!get_constant_operand(instruction, 1, &operation))\n\t\treturn false;\n\n\t// Match DXC SPIR-V output here.\n\tbool is_sync = (operation & DXIL::SyncThreadGroup) != 0;\n\tauto *op = impl.allocate(is_sync ? spv::OpControlBarrier : spv::OpMemoryBarrier);\n\n\tif (is_sync)\n\t\top->add_id(builder.makeUintConstant(spv::ScopeWorkgroup));\n\n\t// We might only need to ensure coherency within the workgroup, in which case we can narrow the scope.\n\t// DXC emits AccessUAVGlobal all the time, so try to demote to UAVThreadGroup when appropriate.\n\tspv::Scope memory_scope = spv::ScopeWorkgroup;\n\n\tbool needs_device_scope_uav =\n\t    (operation & DXIL::AccessUAVGlobal) != 0 && impl.execution_mode_meta.declares_globallycoherent_uav;\n\n\t// We only ever need explicit Vis/Avail in workgroup scope for VkMM.\n\t// globallycoherent is handled per-operation,\n\t// and we only need acquire release to ensure ordering.\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelGLSL450 && needs_device_scope_uav)\n\t\tmemory_scope = spv::ScopeDevice;\n\n\top->add_id(builder.makeUintConstant(memory_scope));\n\n\t// AcquireReleaseMask doesn't care about scope.\n\tuint32_t semantics = spv::MemorySemanticsAcquireReleaseMask;\n\n\t// Game workaround. Sometimes a game might forget to insert device memory barrier in the proper place ._.\n\tconst bool force_device_memory_barriers =\n\t\tis_sync &&\n\t\t(impl.options.quirks.force_device_memory_barriers_thread_group_coherence ||\n\t\t impl.options.quirks.promote_group_to_device_memory_barrier);\n\n\tbool has_uav_barrier = (operation & (DXIL::AccessUAVGlobal | DXIL::AccessUAVThreadGroup)) != 0 ||\n\t                       (force_device_memory_barriers && impl.shader_analysis.require_uav_thread_group_coherence);\n\n\tif (has_uav_barrier)\n\t\tsemantics |= spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsUniformMemoryMask;\n\n\tif ((operation & DXIL::AccessGroupShared) != 0)\n\t\tsemantics |= spv::MemorySemanticsWorkgroupMemoryMask;\n\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan)\n\t\tsemantics |= spv::MemorySemanticsMakeAvailableMask | spv::MemorySemanticsMakeVisibleMask;\n\n\top->add_id(builder.makeUintConstant(semantics));\n\n\timpl.add(op);\n\treturn true;\n}\n\nstatic spv::StorageClass get_compute_builtin_storage_class(Converter::Impl &impl, spv::BuiltIn builtin)\n{\n\tif (!impl.execution_model_lib_target || impl.execution_model != spv::ExecutionModelGLCompute)\n\t\treturn spv::StorageClassInput;\n\n\treturn builtin == spv::BuiltInWorkgroupId || builtin == spv::BuiltInGlobalInvocationId ?\n\t       spv::StorageClassPrivate : spv::StorageClassInput;\n}\n\nstatic bool emit_thread_2d_quad_fixup_instruction(spv::BuiltIn builtin, Converter::Impl &impl,\n                                                  const llvm::CallInst *instruction, uint32_t component)\n{\n\t// We have to compute everything from scratch. Sigh ... <_>\n\tauto &builder = impl.builder();\n\tspv::Id local_thread_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInLocalInvocationId);\n\n\t{\n\t\tauto *load_op = impl.allocate(spv::OpLoad, builder.makeVectorType(builder.makeUintType(32), 3));\n\t\tload_op->add_id(local_thread_id);\n\t\timpl.add(load_op);\n\t\tlocal_thread_id = load_op->id;\n\t}\n\n\tspv::Id comp_ids[3] = {};\n\tconst bool require[3] = {\n\t\ttrue,\n\t\tcomponent >= 1 || builtin == spv::BuiltInLocalInvocationIndex,\n\t\tbuiltin == spv::BuiltInLocalInvocationIndex\n\t};\n\n\tfor (unsigned i = 0; i < 3; i++)\n\t{\n\t\tif (require[i])\n\t\t{\n\t\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\t\t\textract_op->add_id(local_thread_id);\n\t\t\textract_op->add_literal(i);\n\t\t\timpl.add(extract_op);\n\t\t\tcomp_ids[i] = extract_op->id;\n\t\t}\n\t}\n\n\tif (require[1])\n\t{\n\t\t// Y * 2 + ((X >> 1) & 1).\n\t\tauto *x_part = impl.allocate(spv::OpBitFieldUExtract, builder.makeUintType(32));\n\t\tx_part->add_id(comp_ids[0]);\n\t\tx_part->add_id(builder.makeUintConstant(1));\n\t\tx_part->add_id(builder.makeUintConstant(1));\n\t\timpl.add(x_part);\n\n\t\tauto *y_part = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\ty_part->add_id(comp_ids[1]);\n\t\ty_part->add_id(builder.makeUintConstant(2));\n\t\timpl.add(y_part);\n\n\t\tauto *add_part = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd_part->add_id(x_part->id);\n\t\tadd_part->add_id(y_part->id);\n\t\timpl.add(add_part);\n\t\tcomp_ids[1] = add_part->id;\n\t}\n\n\t{\n\t\t// Reconstruct X. In a group of 4 threads, we should see [0, 1, 0, 1], but for different Ys.\n\t\tauto *and_op = impl.allocate(spv::OpBitwiseAnd, builder.makeUintType(32));\n\t\tand_op->add_id(comp_ids[0]);\n\t\tand_op->add_id(builder.makeUintConstant(1));\n\t\timpl.add(and_op);\n\n\t\tauto *shift_down = impl.allocate(spv::OpShiftRightLogical, builder.makeUintType(32));\n\t\tshift_down->add_id(comp_ids[0]);\n\t\tshift_down->add_id(builder.makeUintConstant(2));\n\t\timpl.add(shift_down);\n\n\t\tauto *shift_up = impl.allocate(spv::OpShiftLeftLogical, builder.makeUintType(32));\n\t\tshift_up->add_id(shift_down->id);\n\t\tshift_up->add_id(builder.makeUintConstant(1));\n\t\timpl.add(shift_up);\n\n\t\tauto *or_op = impl.allocate(spv::OpBitwiseOr, builder.makeUintType(32));\n\t\tor_op->add_id(and_op->id);\n\t\tor_op->add_id(shift_up->id);\n\t\timpl.add(or_op);\n\n\t\tcomp_ids[0] = or_op->id;\n\t}\n\n\t// Reconstruct the flattened index.\n\tif (builtin == spv::BuiltInLocalInvocationIndex)\n\t{\n\t\tauto *y_base_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\ty_base_op->add_id(comp_ids[1]);\n\t\ty_base_op->add_id(builder.makeUintConstant(impl.execution_mode_meta.workgroup_threads[0] / 2));\n\t\timpl.add(y_base_op);\n\n\t\tauto *z_base_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tz_base_op->add_id(comp_ids[2]);\n\t\tz_base_op->add_id(builder.makeUintConstant(\n\t\t\timpl.execution_mode_meta.workgroup_threads[0] * impl.execution_mode_meta.workgroup_threads[1]));\n\t\timpl.add(z_base_op);\n\n\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd_op->add_id(y_base_op->id);\n\t\tadd_op->add_id(z_base_op->id);\n\t\timpl.add(add_op);\n\n\t\tauto *final_add_op = impl.allocate(spv::OpIAdd, instruction);\n\t\tfinal_add_op->add_id(add_op->id);\n\t\tfinal_add_op->add_id(comp_ids[0]);\n\t\timpl.add(final_add_op);\n\t}\n\telse if (builtin == spv::BuiltInLocalInvocationId)\n\t{\n\t\timpl.rewrite_value(instruction, comp_ids[component]);\n\t}\n\telse\n\t{\n\t\tspv::Id wg_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInWorkgroupId);\n\t\tauto *ptr_wg = impl.allocate(spv::OpAccessChain, builder.makePointer(\n\t\t\tget_compute_builtin_storage_class(impl, spv::BuiltInWorkgroupId),\n\t\t\tbuilder.makeUintType(32)));\n\n\t\tptr_wg->add_id(wg_id);\n\t\tptr_wg->add_id(builder.makeUintConstant(component));\n\t\timpl.add(ptr_wg);\n\n\t\tauto *load_wg = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\tload_wg->add_id(ptr_wg->id);\n\t\timpl.add(load_wg);\n\n\t\tauto *base_thread = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tbase_thread->add_id(load_wg->id);\n\n\t\tif (component == 0)\n\t\t\tbase_thread->add_id(builder.makeUintConstant(impl.execution_mode_meta.workgroup_threads[component] / 2));\n\t\telse // if (component == 1)\n\t\t\tbase_thread->add_id(builder.makeUintConstant(impl.execution_mode_meta.workgroup_threads[component] * 2));\n\n\t\timpl.add(base_thread);\n\n\t\tauto *final_add = impl.allocate(spv::OpIAdd, instruction);\n\t\tfinal_add->add_id(base_thread->id);\n\t\tfinal_add->add_id(comp_ids[component]);\n\t\timpl.add(final_add);\n\t}\n\n\treturn true;\n}\n\nbool emit_thread_id_load_instruction(spv::BuiltIn builtin, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// This appears to always be constant, not unlike all other input loading instructions.\n\t// Any attempt to dynamically index forces alloca.\n\tuint32_t component = 0;\n\tif (builtin != spv::BuiltInLocalInvocationIndex && !get_constant_operand(instruction, 1, &component))\n\t\treturn false;\n\n\t// Querying Z component for ThreadId or ThreadIdInGroup doesn't change with 2D quad fixup, just use normal path.\n\t// Need to consider ThreadId.xy, ThreadIdInGroup.xy and FlattenedThreadIdInGroup.\n\tif (builtin != spv::BuiltInWorkgroupId && impl.execution_mode_meta.synthesize_2d_quad_dispatch && component <= 1)\n\t\treturn emit_thread_2d_quad_fixup_instruction(builtin, impl, instruction, component);\n\n\t// Awkward NVIDIA workaround. If loading LocalInvocationId, check if we can return constant 0.\n\t// This is key to avoid some particular shader compiler bugs.\n\tif (builtin == spv::BuiltInLocalInvocationId)\n\t{\n\t\tif (component <= 2 && impl.execution_mode_meta.workgroup_threads[component] == 1)\n\t\t{\n\t\t\tspv::Id const_zero = impl.builder().makeUintConstant(0);\n\t\t\timpl.rewrite_value(instruction, const_zero);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(builtin);\n\n\tif (builtin != spv::BuiltInLocalInvocationIndex)\n\t{\n\t\tOperation *op =\n\t\t\timpl.allocate(spv::OpAccessChain, impl.builder().makePointer(\n\t\t\t\tget_compute_builtin_storage_class(impl, builtin), impl.get_type_id(instruction->getType())));\n\n\t\top->add_id(var_id);\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(op);\n\t\tvar_id = op->id;\n\t}\n\n\tOperation *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\timpl.add(op);\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_compute.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_barrier_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_thread_id_load_instruction(spv::BuiltIn builtin, Converter::Impl &impl, const llvm::CallInst *instruction);\n\ntemplate <spv::BuiltIn builtin>\nstatic inline bool emit_thread_id_load_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_thread_id_load_instruction(builtin, impl, instruction);\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_geometry.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_geometry.hpp\"\n#include \"logging.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_stream_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// If view instancing, need to emit these every time.\n\tif (!emit_view_instancing_fixed_layer_viewport(impl, false))\n\t\treturn false;\n\n\tOperation *op;\n\tauto &builder = impl.builder();\n\n\tif (impl.execution_mode_meta.gs_stream_active_mask != 1)\n\t{\n\t\top = impl.allocate(spv::OpEmitStreamVertex);\n\n\t\tauto *constant = llvm::dyn_cast<llvm::ConstantInt>(instruction->getOperand(1));\n\t\tif (!constant)\n\t\t{\n\t\t\tLOGE(\"Argument to emitStream must be a constant.\\n\");\n\t\t\treturn false;\n\t\t}\n\t\top->add_id(builder.makeUintConstant(constant->getUniqueInteger().getZExtValue()));\n\t\tbuilder.addCapability(spv::CapabilityGeometryStreams);\n\t}\n\telse\n\t\top = impl.allocate(spv::OpEmitVertex);\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_cut_stream_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tOperation *op;\n\tauto &builder = impl.builder();\n\n\tif (impl.execution_mode_meta.gs_stream_active_mask != 1)\n\t{\n\t\top = impl.allocate(spv::OpEndStreamPrimitive);\n\n\t\tauto *constant = llvm::dyn_cast<llvm::ConstantInt>(instruction->getOperand(1));\n\t\tif (!constant)\n\t\t{\n\t\t\tLOGE(\"Argument to emitStream must be a constant.\\n\");\n\t\t\treturn false;\n\t\t}\n\t\top->add_id(builder.makeUintConstant(constant->getUniqueInteger().getZExtValue()));\n\t\tbuilder.addCapability(spv::CapabilityGeometryStreams);\n\t}\n\telse\n\t\top = impl.allocate(spv::OpEndPrimitive);\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_then_cut_stream_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (!emit_stream_instruction(impl, instruction))\n\t\treturn false;\n\treturn emit_cut_stream_instruction(impl, instruction);\n}\n\nbool emit_gs_instance_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInInvocationId);\n\tOperation *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_primitive_id_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInPrimitiveId);\n\tOperation *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\timpl.add(op);\n\n\tif (impl.execution_model == spv::ExecutionModelFragment)\n\t\timpl.builder().addCapability(spv::CapabilityGeometry);\n\n\treturn true;\n}\n\nstatic bool emit_view_instance_ubo(Converter::Impl &impl)\n{\n\tif (impl.multiview.view_index_to_view_instance_id)\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tauto &mapping = impl.options.meta_descriptor_mappings[int(MetaDescriptor::DynamicViewInstancingOffsets)];\n\tif (mapping.kind != MetaDescriptorKind::UBOContainingConstant)\n\t{\n\t\tLOGE(\"If using dynamic view instancing, must provide a UBO with offsets.\\n\");\n\t\treturn false;\n\t}\n\n\tspv::Id type_id = builder.makeStructType({ u32_type }, \"ViewInstancingOffsetsUBO\");\n\tbuilder.addDecoration(type_id, spv::DecorationBlock);\n\tbuilder.addMemberDecoration(type_id, 0, spv::DecorationOffset, 0);\n\tbuilder.addMemberName(type_id, 0, \"ViewID_Layer\");\n\n\timpl.multiview.view_index_to_view_instance_id =\n\t    impl.create_variable(spv::StorageClassUniform, type_id, \"ViewInstancingOffsets\");\n\n\tbuilder.addDecoration(impl.multiview.view_index_to_view_instance_id,\n\t                      spv::DecorationDescriptorSet, mapping.desc_set);\n\tbuilder.addDecoration(impl.multiview.view_index_to_view_instance_id,\n\t                      spv::DecorationBinding, mapping.desc_binding);\n\n\treturn true;\n}\n\nspv::Id build_layer_offset_id(Converter::Impl &impl)\n{\n\tif (!impl.options.multiview.enable)\n\t\treturn 0;\n\n\tauto &mapping = impl.options.meta_descriptor_mappings[int(MetaDescriptor::DynamicViewInstancingOffsets)];\n\tif (mapping.kind == MetaDescriptorKind::Invalid)\n\t\treturn 0;\n\n\tif (!emit_view_instance_ubo(impl))\n\t\treturn 0;\n\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tauto *chain = impl.allocate(\n\t    spv::OpAccessChain, builder.makePointer(spv::StorageClassUniform, u32_type));\n\tchain->add_id(impl.multiview.view_index_to_view_instance_id);\n\tchain->add_id(builder.makeUintConstant(0));\n\timpl.add(chain);\n\n\tauto *load = impl.allocate(spv::OpLoad, u32_type);\n\tload->add_id(chain->id);\n\timpl.add(load);\n\n\tauto *ext = impl.allocate(spv::OpBitFieldUExtract, u32_type);\n\text->add_id(load->id);\n\text->add_id(builder.makeUintConstant(16));\n\text->add_id(builder.makeUintConstant(16));\n\timpl.add(ext);\n\n\treturn ext->id;\n}\n\nstatic bool should_emit_view_instancing_fixed_layer_viewport(Converter::Impl &impl, bool entry_point)\n{\n\treturn impl.execution_model == spv::ExecutionModelVertex ||\n\t       impl.execution_model == spv::ExecutionModelTessellationEvaluation ||\n\t       (impl.execution_model == spv::ExecutionModelGeometry && !entry_point) ||\n\t       (impl.execution_model == spv::ExecutionModelMeshEXT && !entry_point);\n}\n\nstatic void emit_workgroup_unrolled_array_store(Converter::Impl &impl,\n                                                spv::Id var_id, spv::Id value_id, spv::Id limit_id)\n{\n\tauto &builder = impl.builder();\n\n\tunsigned num_threads = impl.execution_mode_meta.workgroup_threads[0] *\n\t                       impl.execution_mode_meta.workgroup_threads[1] *\n\t                       impl.execution_mode_meta.workgroup_threads[2];\n\n\tspv::Id local_index = impl.spirv_module.get_builtin_shader_input(spv::BuiltInLocalInvocationIndex);\n\tauto *load = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\tload->add_id(local_index);\n\timpl.add(load);\n\n\t// Statically unroll. Simplifies the implementation.\n\tfor (unsigned i = 0; i < impl.execution_mode_meta.stage_output_num_primitive; i += num_threads)\n\t{\n\t\tauto *offset = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\toffset->add_id(load->id);\n\t\toffset->add_id(builder.makeUintConstant(i));\n\t\timpl.add(offset);\n\n\t\tauto *in_bounds = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\t\tin_bounds->add_id(offset->id);\n\t\tin_bounds->add_id(limit_id);\n\t\timpl.add(in_bounds);\n\n\t\tauto *chain = impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassOutput, builder.makeUintType(32)));\n\t\tchain->add_id(var_id);\n\t\tchain->add_id(offset->id);\n\t\timpl.add(chain);\n\n\t\tauto *store = impl.allocate(spv::PseudoOpMaskedStore);\n\t\tstore->add_id(chain->id);\n\t\tstore->add_id(value_id);\n\t\tstore->add_id(in_bounds->id);\n\t\timpl.add(store);\n\t}\n}\n\nstatic bool emit_view_instancing_fixed_layer(Converter::Impl &impl, bool entry_point, spv::Id limit_id)\n{\n\tif (!impl.options.multiview.enable || impl.multiview.custom_layer_index ||\n\t    !impl.options.multiview.last_pre_rasterization_stage ||\n\t    impl.options.multiview.view_index_to_view_instance_spec_id != UINT32_MAX ||\n\t    !should_emit_view_instancing_fixed_layer_viewport(impl, entry_point))\n\t\treturn true;\n\n\tauto &mapping = impl.options.meta_descriptor_mappings[int(MetaDescriptor::DynamicViewInstancingOffsets)];\n\tif (mapping.kind == MetaDescriptorKind::Invalid)\n\t\treturn true;\n\n\tspv::Id layer_offset_id = build_layer_offset_id(impl);\n\tif (!layer_offset_id)\n\t\treturn false;\n\n\tspv::Id layer_id = impl.spirv_module.get_builtin_shader_output(spv::BuiltInLayer);\n\tauto &builder = impl.builder();\n\n\tif (!layer_id)\n\t{\n\t\tspv::Id type_id = builder.makeUintType(32);\n\t\tif (impl.execution_model == spv::ExecutionModelMeshEXT)\n\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(impl.execution_mode_meta.stage_output_num_primitive), 0);\n\t\tlayer_id = impl.create_variable(spv::StorageClassOutput, type_id);\n\n\t\timpl.spirv_module.register_builtin_shader_output(layer_id, spv::BuiltInLayer);\n\t\timpl.emit_builtin_decoration(layer_id, DXIL::Semantic::RenderTargetArrayIndex, spv::StorageClassOutput);\n\n\t\tif (impl.execution_model == spv::ExecutionModelMeshEXT)\n\t\t\tbuilder.addDecoration(layer_id, spv::DecorationPerPrimitiveEXT);\n\t}\n\n\tif (impl.execution_model == spv::ExecutionModelMeshEXT)\n\t{\n\t\temit_workgroup_unrolled_array_store(impl, layer_id, layer_offset_id, limit_id);\n\t}\n\telse\n\t{\n\t\tauto *store = impl.allocate(spv::OpStore);\n\t\tstore->add_id(layer_id);\n\t\tstore->add_id(layer_offset_id);\n\t\timpl.add(store);\n\t}\n\n\treturn true;\n}\n\nspv::Id build_viewport_offset_id(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tif (impl.options.multiview.view_instance_to_viewport_spec_id == UINT32_MAX)\n\t{\n\t\tLOGE(\"Need to set view instance to viewport spec id.\\n\");\n\t\treturn 0;\n\t}\n\n\tspv::Id view_instance_id = build_view_instance_id(impl);\n\n\tif (!impl.multiview.view_instance_to_viewport_id)\n\t{\n\t\timpl.multiview.view_instance_to_viewport_id = builder.makeUintConstant(0, true);\n\t\tbuilder.addName(impl.multiview.view_instance_to_viewport_id, \"ViewIDToViewport\");\n\t\tbuilder.addDecoration(impl.multiview.view_instance_to_viewport_id,\n\t\t                      spv::DecorationSpecId, impl.options.multiview.view_instance_to_viewport_spec_id);\n\t}\n\n\tspv::Id u32_type = builder.makeUintType(32);\n\tauto *mul = impl.allocate(spv::OpIMul, u32_type);\n\tmul->add_id(view_instance_id);\n\tmul->add_id(builder.makeUintConstant(8));\n\timpl.add(mul);\n\n\tauto *mask = impl.allocate(spv::OpBitFieldUExtract, u32_type);\n\tmask->add_id(impl.multiview.view_instance_to_viewport_id);\n\tmask->add_id(mul->id);\n\tmask->add_id(builder.makeUintConstant(8));\n\timpl.add(mask);\n\n\treturn mask->id;\n}\n\nstatic bool emit_view_instancing_fixed_viewport(Converter::Impl &impl, bool entry_point, spv::Id limit_id)\n{\n\tif (!impl.options.multiview.enable || impl.multiview.custom_viewport_index ||\n\t    !impl.options.multiview.last_pre_rasterization_stage ||\n\t    impl.options.multiview.view_instance_to_viewport_spec_id == UINT32_MAX ||\n\t    !should_emit_view_instancing_fixed_layer_viewport(impl, entry_point))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\n\tspv::Id viewport_id = build_viewport_offset_id(impl);\n\tspv::Id vp_id = impl.spirv_module.get_builtin_shader_output(spv::BuiltInViewportIndex);\n\n\tif (!vp_id)\n\t{\n\t\tspv::Id type_id = builder.makeUintType(32);\n\t\tif (impl.execution_model == spv::ExecutionModelMeshEXT)\n\t\t\ttype_id = builder.makeArrayType(type_id, builder.makeUintConstant(impl.execution_mode_meta.stage_output_num_primitive), 0);\n\n\t\tvp_id = impl.create_variable(spv::StorageClassOutput, type_id);\n\t\timpl.spirv_module.register_builtin_shader_output(vp_id, spv::BuiltInViewportIndex);\n\t\timpl.emit_builtin_decoration(vp_id, DXIL::Semantic::ViewPortArrayIndex, spv::StorageClassOutput);\n\n\t\tif (impl.execution_model == spv::ExecutionModelMeshEXT)\n\t\t\tbuilder.addDecoration(vp_id, spv::DecorationPerPrimitiveEXT);\n\t}\n\n\tif (impl.execution_model == spv::ExecutionModelMeshEXT)\n\t{\n\t\temit_workgroup_unrolled_array_store(impl, vp_id, viewport_id, limit_id);\n\t}\n\telse\n\t{\n\t\tauto *store = impl.allocate(spv::OpStore);\n\t\tstore->add_id(vp_id);\n\t\tstore->add_id(viewport_id);\n\t\timpl.add(store);\n\t}\n\n\treturn true;\n}\n\nbool emit_view_instancing_fixed_layer_viewport(Converter::Impl &impl, bool entry_point, spv::Id limit_id)\n{\n\tif (!emit_view_instancing_fixed_layer(impl, entry_point, limit_id))\n\t\treturn false;\n\tif (!emit_view_instancing_fixed_viewport(impl, entry_point, limit_id))\n\t\treturn false;\n\n\treturn true;\n}\n\nbool emit_view_masking(Converter::Impl &impl)\n{\n\tif (!impl.options.multiview.enable || !impl.options.multiview.last_pre_rasterization_stage)\n\t\treturn true;\n\n\tauto &mapping = impl.options.meta_descriptor_mappings[int(MetaDescriptor::DynamicViewInstancingMask)];\n\tif (mapping.kind == MetaDescriptorKind::Invalid)\n\t\treturn true;\n\n\tif (mapping.kind != MetaDescriptorKind::UBOContainingConstant)\n\t{\n\t\tLOGE(\"DynamicViewMasking must be UBO containing constant.\\n\");\n\t\treturn false;\n\t}\n\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tspv::Id type_id = builder.makeStructType({ u32_type }, \"ViewInstanceMaskUBO\");\n\tbuilder.addDecoration(type_id, spv::DecorationBlock);\n\tbuilder.addMemberDecoration(type_id, 0, spv::DecorationOffset, 0);\n\tbuilder.addMemberName(type_id, 0, \"Mask\");\n\n\tspv::Id view_mask_id = impl.create_variable(spv::StorageClassUniform, type_id, \"ViewInstanceMask\");\n\tbuilder.addDecoration(view_mask_id, spv::DecorationDescriptorSet, mapping.desc_set);\n\tbuilder.addDecoration(view_mask_id, spv::DecorationBinding, mapping.desc_binding);\n\n\tspv::Id view_id = build_view_instance_id(impl);\n\n\tauto *chain = impl.allocate(\n\t    spv::OpAccessChain, builder.makePointer(spv::StorageClassUniform, u32_type));\n\tchain->add_id(view_mask_id);\n\tchain->add_id(builder.makeUintConstant(0));\n\timpl.add(chain);\n\n\tauto *load = impl.allocate(spv::OpLoad, u32_type);\n\tload->add_id(chain->id);\n\timpl.add(load);\n\n\tauto *mask = impl.allocate(spv::OpBitFieldUExtract, u32_type);\n\tmask->add_id(load->id);\n\tmask->add_id(view_id);\n\tmask->add_id(builder.makeUintConstant(1));\n\timpl.add(mask);\n\n\tauto *eq = impl.allocate(spv::OpIEqual, builder.makeBoolType());\n\teq->add_id(mask->id);\n\teq->add_id(builder.makeUintConstant(0));\n\timpl.add(eq);\n\n\t// In geometry shaders and mesh shaders, we can simply just return early, nothing will be emitted.\n\t// Make sure to write a dummy invalid position on other targets.\n\t// TODO: Could optimize for hull shaders by forcing invalid tess factors early,\n\t// but might screw up phase constant phase if there are side effects, so ...\n\tif (impl.execution_model == spv::ExecutionModelVertex ||\n\t    impl.execution_model == spv::ExecutionModelTessellationEvaluation)\n\t{\n\t\tspv::Id pos_id = impl.spirv_module.get_builtin_shader_output(spv::BuiltInPosition);\n\t\tauto *write_degen = impl.allocate(spv::OpStore);\n\t\twrite_degen->add_id(pos_id);\n\t\twrite_degen->add_id(impl.build_splat_constant_vector(\n\t\t    builder.makeFloatType(32), builder.makeFloatConstant(-1.0f), 4));\n\t\timpl.add(write_degen);\n\t}\n\n\tauto *retcond = impl.allocate(spv::PseudoOpReturnCond);\n\tretcond->add_id(eq->id);\n\timpl.add(retcond);\n\n\treturn true;\n}\n\nspv::Id build_view_instance_id(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tif (!impl.multiview.custom_layer_index &&\n\t    impl.options.multiview.view_index_to_view_instance_spec_id != UINT32_MAX)\n\t{\n\t\t// We're using proper multiview.\n\t\tif (!impl.multiview.view_index_to_view_instance_id)\n\t\t{\n\t\t\timpl.multiview.view_index_to_view_instance_id = builder.makeUintConstant(0, true);\n\t\t\tbuilder.addDecoration(impl.multiview.view_index_to_view_instance_id,\n\t\t\t                      spv::DecorationSpecId, impl.options.multiview.view_index_to_view_instance_spec_id);\n\t\t\tbuilder.addName(impl.multiview.view_index_to_view_instance_id, \"ViewIndexToViewInstanceMap\");\n\t\t}\n\n\t\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInViewIndex);\n\t\tOperation *op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\top->add_id(var_id);\n\t\timpl.add(op);\n\t\tbuilder.addCapability(spv::CapabilityMultiView);\n\n\t\tauto *mul = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tmul->add_id(op->id);\n\t\tmul->add_id(builder.makeUintConstant(2));\n\t\timpl.add(mul);\n\n\t\tauto *extract = impl.allocate(spv::OpBitFieldUExtract, builder.makeUintType(32));\n\t\textract->add_id(impl.multiview.view_index_to_view_instance_id);\n\t\textract->add_id(mul->id);\n\t\textract->add_id(builder.makeUintConstant(2));\n\t\timpl.add(extract);\n\n\t\treturn extract->id;\n\t}\n\telse\n\t{\n\t\tspv::Id u32_type = builder.makeUintType(32);\n\n\t\tif (!emit_view_instance_ubo(impl))\n\t\t\treturn 0;\n\n\t\tauto *chain = impl.allocate(\n\t\t\tspv::OpAccessChain, builder.makePointer(spv::StorageClassUniform, u32_type));\n\t\tchain->add_id(impl.multiview.view_index_to_view_instance_id);\n\t\tchain->add_id(builder.makeUintConstant(0));\n\t\timpl.add(chain);\n\n\t\tauto *load = impl.allocate(spv::OpLoad, u32_type);\n\t\tload->add_id(chain->id);\n\t\timpl.add(load);\n\n\t\tauto *ext = impl.allocate(spv::OpBitFieldUExtract, u32_type);\n\t\text->add_id(load->id);\n\t\text->add_id(builder.makeUintConstant(0));\n\t\text->add_id(builder.makeUintConstant(16));\n\t\timpl.add(ext);\n\n\t\treturn ext->id;\n\t}\n}\n\nbool emit_view_id_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tif (!impl.options.multiview.enable)\n\t\timpl.rewrite_value(instruction, builder.makeUintConstant(0));\n\telse\n\t\timpl.rewrite_value(instruction, build_view_instance_id(impl));\n\n\treturn true;\n}\n\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_geometry.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_stream_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_cut_stream_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_then_cut_stream_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_gs_instance_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_primitive_id_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_view_id_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nspv::Id build_view_instance_id(Converter::Impl &impl);\nspv::Id build_viewport_offset_id(Converter::Impl &impl);\nspv::Id build_layer_offset_id(Converter::Impl &impl);\nbool emit_view_masking(Converter::Impl &impl);\nbool emit_view_instancing_fixed_layer_viewport(Converter::Impl &impl, bool entry_point, spv::Id limit_id = 0);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_mesh.cpp",
    "content": "/*\n * Copyright 2022 Philip Rebohle for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_mesh.hpp\"\n#include \"dxil_common.hpp\"\n#include \"logging.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n#include \"dxil_geometry.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_set_mesh_output_counts_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tOperation *op = impl.allocate(spv::OpSetMeshOutputsEXT);\n\n\tspv::Id num_vertex_id, num_prim_id;\n\n\t// If we have a degenerate case where either of these is 0, we have to declare 0 as max output.\n\tif (impl.execution_mode_meta.stage_output_num_vertex == 0)\n\t\tnum_vertex_id = impl.builder().makeUintConstant(0);\n\telse\n\t\tnum_vertex_id = impl.get_id_for_value(instruction->getOperand(1));\n\top->add_id(num_vertex_id);\n\n\tif (impl.execution_mode_meta.stage_output_num_primitive == 0)\n\t\tnum_prim_id = impl.builder().makeUintConstant(0);\n\telse\n\t\tnum_prim_id = impl.get_id_for_value(instruction->getOperand(2));\n\top->add_id(num_prim_id);\n\n\tif (impl.options.quirks.mesh_outputs_bounds_check)\n\t{\n\t\t// Technically the first thread wins so we need to broadcast the results,\n\t\t// but in all cases where we care about this quirk, the inputs are threadgroup uniform, so this is fine.\n\t\tauto *assert_vertex = impl.allocate(spv::OpUGreaterThan, impl.builder().makeBoolType());\n\t\tassert_vertex->add_id(num_vertex_id);\n\t\tassert_vertex->add_id(impl.builder().makeUintConstant(impl.execution_mode_meta.stage_output_num_vertex));\n\n\t\tauto *assert_prim = impl.allocate(spv::OpUGreaterThan, impl.builder().makeBoolType());\n\t\tassert_prim->add_id(num_prim_id);\n\t\tassert_prim->add_id(impl.builder().makeUintConstant(impl.execution_mode_meta.stage_output_num_primitive));\n\n\t\tauto *should_exit = impl.allocate(spv::OpLogicalOr, impl.builder().makeBoolType());\n\t\tshould_exit->add_id(assert_vertex->id);\n\t\tshould_exit->add_id(assert_prim->id);\n\n\t\timpl.add(assert_vertex);\n\t\timpl.add(assert_prim);\n\t\timpl.add(should_exit);\n\n\t\tauto *return_op = impl.allocate(spv::PseudoOpReturnCond);\n\t\treturn_op->add_id(should_exit->id);\n\t\timpl.add(return_op);\n\n\t\t// OpSampledImage must be consumed in same block.\n\t\t// We'll split blocks here, so just recreate the combined sampler image if needed.\n\t\timpl.combined_image_sampler_cache.clear();\n\t}\n\n\tif (impl.options.instruction_instrumentation.enabled &&\n\t    impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume)\n\t{\n\t\tauto *assert_vertex = impl.allocate(spv::OpULessThanEqual, impl.builder().makeBoolType());\n\t\tassert_vertex->add_id(num_vertex_id);\n\t\tassert_vertex->add_id(impl.builder().makeUintConstant(impl.execution_mode_meta.stage_output_num_vertex));\n\t\tauto *assume_vertex = impl.allocate(spv::OpAssumeTrueKHR);\n\t\tassume_vertex->add_id(assert_vertex->id);\n\n\t\tauto *assert_prim = impl.allocate(spv::OpULessThanEqual, impl.builder().makeBoolType());\n\t\tassert_prim->add_id(num_prim_id);\n\t\tassert_prim->add_id(impl.builder().makeUintConstant(impl.execution_mode_meta.stage_output_num_primitive));\n\t\tauto *assume_prim = impl.allocate(spv::OpAssumeTrueKHR);\n\t\tassume_prim->add_id(assert_prim->id);\n\n\t\timpl.add(assert_vertex);\n\t\timpl.add(assume_vertex);\n\t\timpl.add(assert_prim);\n\t\timpl.add(assume_prim);\n\t}\n\n\timpl.add(op);\n\n\t// Workaround shader compiler bugs by emitting a conditional return.\n\tif (!impl.shader_analysis.has_side_effects)\n\t{\n\t\tauto &builder = impl.builder();\n\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t\tspv::Id num_ids = impl.spirv_module.get_builtin_shader_input(spv::BuiltInNumSubgroups);\n\t\tauto *load_op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\tload_op->add_id(num_ids);\n\t\timpl.add(load_op);\n\n\t\tauto *one_subgroup = impl.allocate(spv::OpIEqual, builder.makeBoolType());\n\t\tone_subgroup->add_id(load_op->id);\n\t\tone_subgroup->add_id(builder.makeUintConstant(1));\n\t\timpl.add(one_subgroup);\n\n\t\tauto *broadcast_vert = impl.allocate(spv::OpGroupNonUniformBroadcastFirst, builder.makeUintType(32));\n\t\tbroadcast_vert->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tbroadcast_vert->add_id(num_vertex_id);\n\t\timpl.add(broadcast_vert);\n\n\t\tauto *broadcast_prim = impl.allocate(spv::OpGroupNonUniformBroadcastFirst, builder.makeUintType(32));\n\t\tbroadcast_prim->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tbroadcast_prim->add_id(num_prim_id);\n\t\timpl.add(broadcast_prim);\n\n\t\tauto *vert_zero = impl.allocate(spv::OpIEqual, builder.makeBoolType());\n\t\tvert_zero->add_id(broadcast_vert->id);\n\t\tvert_zero->add_id(builder.makeUintConstant(0));\n\t\timpl.add(vert_zero);\n\n\t\tauto *prim_zero = impl.allocate(spv::OpIEqual, builder.makeBoolType());\n\t\tprim_zero->add_id(broadcast_prim->id);\n\t\tprim_zero->add_id(builder.makeUintConstant(0));\n\t\timpl.add(prim_zero);\n\n\t\tauto *degenerate_meshlet = impl.allocate(spv::OpLogicalOr, builder.makeBoolType());\n\t\tdegenerate_meshlet->add_id(vert_zero->id);\n\t\tdegenerate_meshlet->add_id(prim_zero->id);\n\t\timpl.add(degenerate_meshlet);\n\n\t\tauto *early_return = impl.allocate(spv::OpLogicalAnd, builder.makeBoolType());\n\t\tearly_return->add_id(one_subgroup->id);\n\t\tearly_return->add_id(degenerate_meshlet->id);\n\t\timpl.add(early_return);\n\n\t\t// This may also be useful in some cases if application does misc shader work after SetMeshOutputsEXT.\n\t\t// Use a pseudo-op (arbitrarily chosen as OpLifetimeStop as the name is convenient) for conditional return\n\t\t// since we have no easy way of introducing additional control flow\n\t\t// in the LLVM -> SPIR-V emitter.\n\t\t// This gets resolved during final SPIR-V lowering.\n\t\tauto *cond_ret = impl.allocate(spv::PseudoOpReturnCond);\n\t\tcond_ret->add_id(early_return->id);\n\t\timpl.add(cond_ret);\n\t}\n\n\temit_view_instancing_fixed_layer_viewport(impl, false, num_prim_id);\n\n\treturn true;\n}\n\nbool emit_emit_indices_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\t// If we for some reason have max primitives 0 in the execution mode,\n\t// just ignore any access to index buffer.\n\tif (!impl.primitive_index_array_id || impl.execution_mode_meta.stage_output_num_primitive == 0)\n\t\treturn true;\n\n\tunsigned index_dim = impl.execution_mode_meta.primitive_index_dimension;\n\tspv::Id index_type_id = impl.get_type_id(DXIL::ComponentType::U32, 1, index_dim);\n\tspv::Id index_scalar_type_id = impl.get_type_id(DXIL::ComponentType::U32, 1, 1);\n\n\tspv::Id components[3];\n\tfor (unsigned i = 0; i < index_dim; i++)\n\t\tcomponents[i] = impl.get_id_for_value(instruction->getOperand(2 + i));\n\tspv::Id index_id = impl.build_vector(index_scalar_type_id, components, index_dim);\n\n\tOperation *op = impl.allocate(spv::OpAccessChain,\n\t                              builder.makePointer(spv::StorageClassOutput, index_type_id));\n\tspv::Id ptr_id = op->id;\n\n\top->add_id(impl.primitive_index_array_id);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(op);\n\n\top = impl.allocate(spv::OpStore);\n\top->add_ids({ ptr_id, index_id });\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_store_vertex_output_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// If we for some reason have max vertices 0 in the execution mode,\n\t// just ignore any access to vertex output.\n\tif (impl.execution_mode_meta.stage_output_num_vertex == 0)\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tuint32_t output_element_index;\n\tif (!get_constant_operand(instruction, 1, &output_element_index))\n\t\treturn false;\n\n\t// Need special handling for clip distance.\n\tauto *clip_cull_meta = output_clip_cull_distance_meta(impl, output_element_index);\n\tif (clip_cull_meta)\n\t\treturn emit_store_clip_cull_distance(impl, instruction, *clip_cull_meta);\n\n\tconst auto &meta = impl.output_elements_meta[output_element_index];\n\n\tuint32_t var_id = meta.id;\n\tuint32_t ptr_id;\n\n\tspv::Id output_type_id = builder.getContainedTypeId(builder.getDerefTypeId(var_id));\n\n\tbool row_index = false;\n\tif (builder.isArrayType(output_type_id))\n\t{\n\t\trow_index = true;\n\t\toutput_type_id = builder.getContainedTypeId(output_type_id);\n\t}\n\tuint32_t num_cols = builder.getNumTypeComponents(output_type_id);\n\n\tOperation *op = impl.allocate(\n\t\t\tspv::OpAccessChain, builder.makePointer(spv::StorageClassOutput, builder.getScalarTypeId(output_type_id)));\n\tptr_id = op->id;\n\n\top->add_id(var_id);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(5)));\n\tif (row_index)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\tif (num_cols > 1)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(3), 32));\n\n\timpl.add(op);\n\n\timpl.register_externally_visible_write(instruction->getOperand(4));\n\tspv::Id store_value = impl.get_id_for_value(instruction->getOperand(4));\n\n\top = impl.allocate(spv::OpStore);\n\top->add_ids({ ptr_id, impl.fixup_store_type_io(meta.component_type, 1, store_value) });\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_store_primitive_output_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// If we for some reason have max primitives 0 in the execution mode,\n\t// just ignore any access to primitive output.\n\tif (impl.execution_mode_meta.stage_output_num_primitive == 0)\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tuint32_t output_element_index;\n\tif (!get_constant_operand(instruction, 1, &output_element_index))\n\t\treturn false;\n\n\tconst auto &meta = impl.patch_elements_meta[output_element_index];\n\tuint32_t var_id = meta.id;\n\tspv::Id ptr_id;\n\n\tspv::Id output_type_id = builder.getContainedTypeId(builder.getDerefTypeId(var_id));\n\n\tbool row_index = false;\n\tif (builder.isArrayType(output_type_id))\n\t{\n\t\trow_index = true;\n\t\toutput_type_id = builder.getContainedTypeId(output_type_id);\n\t}\n\tuint32_t num_cols = builder.getNumTypeComponents(output_type_id);\n\n\timpl.register_externally_visible_write(instruction->getOperand(4));\n\tspv::Id store_value = impl.fixup_store_type_io(meta.component_type, 1,\n\t                                               impl.get_id_for_value(instruction->getOperand(4)));\n\n\tOperation *op;\n\tspv::BuiltIn builtin;\n\tif (impl.spirv_module.query_builtin_shader_output(var_id, &builtin) && builtin == spv::BuiltInCullPrimitiveEXT)\n\t{\n\t\t// Special case where the output variable is bool, but the value we get is uint32\n\t\top = impl.allocate(spv::OpINotEqual, builder.makeBoolType());\n\t\top->add_id(store_value);\n\t\top->add_id(builder.makeUintConstant(0));\n\t\timpl.add(op);\n\t\tstore_value = op->id;\n\t}\n\n\tif (impl.options.multiview.enable && impl.options.multiview.last_pre_rasterization_stage)\n\t{\n\t\tif (meta.semantic == DXIL::Semantic::RenderTargetArrayIndex)\n\t\t{\n\t\t\tauto *add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\tadd->add_id(store_value);\n\t\t\tadd->add_id(build_layer_offset_id(impl));\n\t\t\timpl.add(add);\n\n\t\t\tstore_value = add->id;\n\t\t}\n\t\telse if (meta.semantic == DXIL::Semantic::ViewPortArrayIndex &&\n\t\t         impl.options.multiview.view_instance_to_viewport_spec_id != UINT32_MAX)\n\t\t{\n\t\t\tauto *add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\tadd->add_id(store_value);\n\t\t\tadd->add_id(build_viewport_offset_id(impl));\n\t\t\timpl.add(add);\n\n\t\t\tstore_value = add->id;\n\t\t}\n\t}\n\n\top = impl.allocate(spv::OpAccessChain,\n\t                   builder.makePointer(spv::StorageClassOutput, builder.getScalarTypeId(output_type_id)));\n\tptr_id = op->id;\n\top->add_id(var_id);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(5)));\n\tif (row_index)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\tif (num_cols > 1)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(3), 32));\n\n\timpl.add(op);\n\n\top = impl.allocate(spv::OpStore);\n\top->add_ids({ ptr_id, store_value });\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_dispatch_mesh_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tOperation *op = impl.allocate(spv::OpEmitMeshTasksEXT);\n\n\tfor (unsigned i = 1; i <= 4; i++)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(i)));\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_get_mesh_payload_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// GetMeshPayload can only be called once per shader\n\tspv::Id type_id = impl.get_type_id(instruction->getType()->getPointerElementType());\n\tspv::Id var_id = impl.create_variable(spv::StorageClassTaskPayloadWorkgroupEXT, type_id);\n\n\timpl.rewrite_value(instruction, var_id);\n\treturn true;\n}\n\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_mesh.hpp",
    "content": "/*\n * Copyright 2022 Philip Rebohle for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_set_mesh_output_counts_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_emit_indices_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_store_vertex_output_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_store_primitive_output_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dispatch_mesh_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_get_mesh_payload_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_nvapi.cpp",
    "content": "/* Copyright (c) 2025 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n */\n\n#include \"dxil_nvapi.hpp\"\n#include \"dxil_common.hpp\"\n#include \"dxil_ray_tracing.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"logging.hpp\"\n\nnamespace dxil_spv\n{\nenum NVExtnOp\n{\n\tNV_EXTN_OP_SHFL = 1,\n\tNV_EXTN_OP_SHFL_UP = 2,\n\tNV_EXTN_OP_SHFL_DOWN = 3,\n\tNV_EXTN_OP_SHFL_XOR = 4,\n\tNV_EXTN_OP_VOTE_ALL = 5,\n\tNV_EXTN_OP_VOTE_ANY = 6,\n\tNV_EXTN_OP_VOTE_BALLOT = 7,\n\tNV_EXTN_OP_GET_LANE_ID = 8,\n\tNV_EXTN_OP_FP16_ATOMIC = 12,\n\tNV_EXTN_OP_FP32_ATOMIC = 13,\n\tNV_EXTN_OP_GET_SPECIAL = 19,\n\tNV_EXTN_OP_UINT64_ATOMIC = 20,\n\tNV_EXTN_OP_MATCH_ANY = 21,\n\tNV_EXTN_OP_FOOTPRINT = 28,\n\tNV_EXTN_OP_FOOTPRINT_BIAS = 29,\n\tNV_EXTN_OP_GET_SHADING_RATE = 30,\n\tNV_EXTN_OP_FOOTPRINT_LEVEL = 31,\n\tNV_EXTN_OP_FOOTPRINT_GRAD = 32,\n\tNV_EXTN_OP_SHFL_GENERIC = 33,\n\tNV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE = 51,\n\tNV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED = 52,\n\tNV_EXTN_OP_HIT_OBJECT_TRACE_RAY = 67,\n\tNV_EXTN_OP_HIT_OBJECT_MAKE_HIT = 68,\n\tNV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX  = 69,\n\tNV_EXTN_OP_HIT_OBJECT_MAKE_MISS = 70,\n\tNV_EXTN_OP_HIT_OBJECT_REORDER_THREAD = 71,\n\tNV_EXTN_OP_HIT_OBJECT_INVOKE = 72,\n\tNV_EXTN_OP_HIT_OBJECT_IS_MISS = 73,\n\tNV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_ID = 74,\n\tNV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_INDEX = 75,\n\tNV_EXTN_OP_HIT_OBJECT_GET_PRIMITIVE_INDEX = 76,\n\tNV_EXTN_OP_HIT_OBJECT_GET_GEOMETRY_INDEX = 77,\n\tNV_EXTN_OP_HIT_OBJECT_GET_HIT_KIND = 78,\n\tNV_EXTN_OP_HIT_OBJECT_GET_RAY_DESC = 79,\n\tNV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES = 80,\n\tNV_EXTN_OP_HIT_OBJECT_GET_SHADER_TABLE_INDEX = 81,\n\tNV_EXTN_OP_HIT_OBJECT_LOAD_LOCAL_ROOT_TABLE_CONSTANT = 82,\n\tNV_EXTN_OP_HIT_OBJECT_IS_HIT = 83,\n\tNV_EXTN_OP_HIT_OBJECT_IS_NOP = 84,\n\tNV_EXTN_OP_HIT_OBJECT_MAKE_NOP = 85,\n\tNV_EXTN_OP_RT_TRIANGLE_OBJECT_POSITIONS = 86,\n\tNV_EXTN_OP_RT_MICRO_TRIANGLE_OBJECT_POSITIONS = 87,\n\tNV_EXTN_OP_RT_MICRO_TRIANGLE_BARYCENTRICS = 88,\n\tNV_EXTN_OP_RT_IS_MICRO_TRIANGLE_HIT = 89,\n\tNV_EXTN_OP_RT_IS_BACK_FACING = 90,\n\tNV_EXTN_OP_RT_MICRO_VERTEX_OBJECT_POSITION = 91,\n\tNV_EXTN_OP_RT_MICRO_VERTEX_BARYCENTRICS = 92,\n\tNV_EXTN_OP_RT_GET_CLUSTER_ID = 93,\n\tNV_EXTN_OP_RT_GET_CANDIDATE_CLUSTER_ID = 94,\n\tNV_EXTN_OP_RT_GET_COMMITTED_CLUSTER_ID = 95,\n\tNV_EXTN_OP_HIT_OBJECT_GET_CLUSTER_ID = 96,\n\tNV_EXTN_OP_RT_CANDIDATE_TRIANGLE_OBJECT_POSITIONS = 97,\n\tNV_EXTN_OP_RT_COMMITTED_TRIANGLE_OBJECT_POSITIONS = 98,\n\tNV_EXTN_OP_HIT_OBJECT_GET_TRIANGLE_OBJECT_POSITIONS = 99,\n\tNV_EXTN_OP_RT_SPHERE_OBJECT_POSITION_AND_RADIUS = 100,\n\tNV_EXTN_OP_RT_CANDIDATE_SPHERE_OBJECT_POSITION_AND_RADIUS = 101,\n\tNV_EXTN_OP_RT_COMMITTED_SPHERE_OBJECT_POSITION_AND_RADIUS = 102,\n\tNV_EXTN_OP_HIT_OBJECT_GET_SPHERE_OBJECT_POSITION_AND_RADIUS = 103,\n\tNV_EXTN_OP_RT_LSS_OBJECT_POSITIONS_AND_RADII = 104,\n\tNV_EXTN_OP_RT_CANDIDATE_LSS_OBJECT_POSITIONS_AND_RADII = 105,\n\tNV_EXTN_OP_RT_COMMITTED_LSS_OBJECT_POSITIONS_AND_RADII = 106,\n\tNV_EXTN_OP_HIT_OBJECT_GET_LSS_OBJECT_POSITIONS_AND_RADII = 107,\n\tNV_EXTN_OP_RT_IS_SPHERE_HIT = 108,\n\tNV_EXTN_OP_RT_CANDIDATE_IS_NONOPAQUE_SPHERE = 109,\n\tNV_EXTN_OP_RT_COMMITTED_IS_SPHERE = 110,\n\tNV_EXTN_OP_HIT_OBJECT_IS_SPHERE_HIT = 111,\n\tNV_EXTN_OP_RT_IS_LSS_HIT = 112,\n\tNV_EXTN_OP_RT_CANDIDATE_IS_NONOPAQUE_LSS = 113,\n\tNV_EXTN_OP_RT_COMMITTED_IS_LSS = 114,\n\tNV_EXTN_OP_HIT_OBJECT_IS_LSS_HIT = 115,\n\tNV_EXTN_OP_RT_CANDIDATE_LSS_HIT_PARAMETER = 116,\n\tNV_EXTN_OP_RT_COMMITTED_LSS_HIT_PARAMETER = 117,\n\tNV_EXTN_OP_RT_CANDIDATE_BUILTIN_PRIMITIVE_RAY_T = 118,\n\tNV_EXTN_OP_RT_COMMIT_NONOPAQUE_BUILTIN_PRIMITIVE_HIT = 119\n};\n\nenum NVSpecialOp\n{\n\tNV_SPECIALOP_THREADLTMASK = 4,\n\tNV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED = 5,\n\tNV_SPECIALOP_GLOBAL_TIMER_LO = 9,\n\tNV_SPECIALOP_GLOBAL_TIMER_HI = 10\n};\n\nvoid NVAPIState::reset()\n{\n\tfor (auto &input : fake_doorbell_inputs)\n\t\tinput = nullptr;\n\tfor (auto &intermediate : fake_doorbell_intermediates)\n\t\tintermediate = nullptr;\n\tfor (auto &output : fake_doorbell_outputs)\n\t\toutput = 0;\n\n\tdoorbell = nullptr;\n\tdeferred_opcode = 0;\n\tclock_output_index = 0;\n\tnum_expected_clock_outputs = 0;\n\t// The marked UAV persists.\n}\n\nvoid NVAPIState::notify_doorbell(Converter::Impl &impl, const llvm::CallInst *instruction, bool analysis)\n{\n\t// IncrementCounter is used for either starting an intrinsic or sometimes clocking out values from it.\n\tif (num_expected_clock_outputs == 0)\n\t{\n\t\treset();\n\n\t\t// When the dummy structured buffer is being written to,\n\t\t// the structure index comes from this counter value.\n\t\tdoorbell = instruction;\n\t}\n\telse\n\t{\n\t\t// We're clocking out arguments.\n\t\t// We either clock out arguments by IncrementCounter() or reading the magic UAV.\n\n\t\tif (clock_output_index < num_expected_clock_outputs)\n\t\t{\n\t\t\t// Deferred instructions will consume the outputs, emitting SPIR-V and rewriting\n\t\t\t// values as needed when the last fake CallShader/TraceRay call is encountered\n\t\t\tif (deferred_opcode)\n\t\t\t\tfake_doorbell_intermediates[clock_output_index] = instruction;\n\t\t\telse if (!analysis)\n\t\t\t\timpl.rewrite_value(instruction, impl.nvapi.fake_doorbell_outputs[clock_output_index]);\n\t\t\tclock_output_index++;\n\t\t}\n\n\t\tif (clock_output_index >= num_expected_clock_outputs && !deferred_opcode)\n\t\t{\n\t\t\t// We're done consuming the opcode. The next IncrementCounter starts a new opcode.\n\t\t\treset();\n\t\t}\n\t}\n}\n\nstatic spv::Id get_argument(Converter::Impl &impl, uint32_t offset)\n{\n\treturn impl.get_id_for_value(impl.nvapi.fake_doorbell_inputs[offset]);\n}\n\nstatic spv::Id get_argument_as_float(Converter::Impl &impl, uint32_t offset)\n{\n\tauto *op = impl.nvapi.fake_doorbell_inputs[offset];\n\tauto *cast_inst = llvm::dyn_cast<llvm::CastInst>(op);\n\n\tif (cast_inst != nullptr && cast_inst->getOpcode() == llvm::Instruction::BitCast)\n\t{\n\t\top = cast_inst->getOperand(0);\n\n\t\tif (op->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID)\n\t\t\treturn impl.get_id_for_value(op);\n\t}\n\n\tauto *bitcast_op = impl.allocate(spv::OpBitcast, impl.builder().makeFloatType(32));\n\tbitcast_op->add_id(impl.get_id_for_value(op));\n\timpl.add(bitcast_op);\n\n\treturn bitcast_op->id;\n}\n\nstatic bool emit_nvapi_extn_op_shuffle(Converter::Impl &impl)\n{\n\t// Dummy throwaway implementation.\n\tspv::Id val = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\tspv::Id lane = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 1);\n\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformShuffle);\n\n\tauto *op = impl.allocate(spv::OpGroupNonUniformShuffle, builder.makeUintType(32));\n\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\top->add_id(val);\n\top->add_id(lane);\n\timpl.add(op);\n\n\timpl.nvapi.fake_doorbell_outputs[0] = op->id;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_fp16x2_atomic(Converter::Impl &impl)\n{\n\tif (!impl.nvapi.marked_uav)\n\t\treturn false;\n\n\t// Dummy throwaway implementation to demonstrate UAV reference plumbing.\n\tspv::Id addr = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\tspv::Id val = get_argument(impl, NVAPI_ARGUMENT_SRC1U + 0);\n\tspv::Id type = get_argument(impl, NVAPI_ARGUMENT_SRC2U + 0);\n\t(void)type;\n\n\tauto &builder = impl.builder();\n\n\tspv::Id id = impl.get_id_for_value(impl.nvapi.marked_uav);\n\tconst auto &meta = impl.handle_to_resource_meta[id];\n\n\tif (meta.storage == spv::StorageClassStorageBuffer)\n\t{\n\t\tspv::Id ssbo_id = get_buffer_alias_handle(impl, meta, id, RawType::Integer, RawWidth::B32, RawVecSize::V1);\n\n\t\tauto *chain = impl.allocate(spv::OpAccessChain,\n\t\t                            builder.makePointer(spv::StorageClassStorageBuffer, builder.makeUintType(32)));\n\t\tchain->add_id(ssbo_id);\n\t\tchain->add_id(builder.makeUintConstant(0));\n\t\tchain->add_id(addr);\n\t\timpl.add(chain);\n\n\t\tauto *atomic = impl.allocate(spv::OpAtomicIAdd, builder.makeUintType(32));\n\t\tatomic->add_id(chain->id);\n\t\tatomic->add_id(builder.makeUintConstant(spv::ScopeDevice));\n\t\tatomic->add_id(builder.makeUintConstant(0));\n\t\tatomic->add_id(val);\n\t\timpl.add(atomic);\n\n\t\timpl.nvapi.fake_doorbell_outputs[NVAPI_ARGUMENT_DST0U + 0] = atomic->id;\n\t}\n\telse if (meta.storage == spv::StorageClassUniformConstant)\n\t{\n\t\tauto *ptr = impl.allocate(spv::OpImageWrite);\n\t\tptr->add_id(id);\n\t\tptr->add_id(addr);\n\t\tptr->add_id(impl.build_splat_constant_vector(builder.makeFloatType(32), builder.makeFloatConstant(2.0f), 4));\n\t\timpl.add(ptr);\n\n\t\tbuilder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);\n\t\timpl.nvapi.fake_doorbell_outputs[NVAPI_ARGUMENT_DST0U + 0] = builder.makeUintConstant(42);\n\t}\n\n\timpl.nvapi.marked_uav = nullptr;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_get_special(Converter::Impl &impl)\n{\n\tauto *c = llvm::dyn_cast<llvm::ConstantInt>(impl.nvapi.fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0]);\n\tif (c != nullptr)\n\t{\n\t\tauto subopcode = uint32_t(c->getUniqueInteger().getZExtValue());\n\t\tauto &builder = impl.builder();\n\n\t\tswitch (subopcode)\n\t\t{\n\t\tcase NV_SPECIALOP_GLOBAL_TIMER_LO:\n\t\tcase NV_SPECIALOP_GLOBAL_TIMER_HI:\n\t\t{\n\t\t\tbuilder.addExtension(\"SPV_KHR_shader_clock\");\n\t\t\tbuilder.addCapability(spv::CapabilityShaderClockKHR);\n\n\t\t\tauto *read_op = impl.allocate(spv::OpReadClockKHR, builder.makeVectorType(builder.makeUintType(32), 2));\n\t\t\tread_op->add_id(builder.makeUintConstant(1));\n\t\t\timpl.add(read_op);\n\n\t\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\t\t\textract_op->add_id(read_op->id);\n\t\t\textract_op->add_literal(subopcode - NV_SPECIALOP_GLOBAL_TIMER_LO);\n\t\t\timpl.add(extract_op);\n\n\t\t\timpl.nvapi.fake_doorbell_outputs[0] = extract_op->id;\n\t\t\treturn true;\n\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_trace_ray(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id miss_index = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\n\tauto *hit_object = impl.nvapi.fake_doorbell_intermediates[NVAPI_INTERMEDIATE_HANDLE_0];\n\n\tauto &builder = impl.builder();\n\n\tbuilder.addExtension(\"SPV_NV_shader_invocation_reorder\");\n\tbuilder.addCapability(spv::CapabilityShaderInvocationReorderNV);\n\n\tspv::Id acceleration_structure = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id ray_flags = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id instance_inclusion_mask = impl.get_id_for_value(instruction->getOperand(3));\n\tspv::Id ray_contribution_to_hit_group = impl.get_id_for_value(instruction->getOperand(4));\n\tspv::Id multiplier_for_geometry = impl.get_id_for_value(instruction->getOperand(5));\n\n\tspv::Id ray_origin[3];\n\tspv::Id ray_dir[3];\n\n\tfor (unsigned i = 0; i < 3; i++)\n\t{\n\t\tray_origin[i] = impl.get_id_for_value(instruction->getOperand(7 + i));\n\t\tray_dir[i] = impl.get_id_for_value(instruction->getOperand(11 + i));\n\t}\n\n\tspv::Id tmin = impl.get_id_for_value(instruction->getOperand(10));\n\tspv::Id tmax = impl.get_id_for_value(instruction->getOperand(14));\n\n\tspv::Id float32 = builder.makeFloatType(32);\n\tspv::Id ray_origin_vec = impl.build_vector(float32, ray_origin, 3);\n\tspv::Id ray_dir_vec = impl.build_vector(float32, ray_dir, 3);\n\n\tauto *ray_payload = instruction->getOperand(15);\n\n\tbool needs_temp_copy = impl.get_needs_temp_storage_copy(ray_payload);\n\tspv::Id ray_payload_var_id = needs_temp_copy\n\t\t? emit_temp_storage_copy(impl, ray_payload, spv::StorageClassRayPayloadKHR)\n\t\t: impl.get_id_for_value(ray_payload);\n\n\tspv::Id variable = impl.create_variable(spv::StorageClassFunction, builder.makeHitObjectNVType());\n\n\tauto op = impl.allocate(spv::OpHitObjectTraceRayNV);\n\top->add_id(variable);\n\top->add_id(acceleration_structure);\n\top->add_id(ray_flags);\n\top->add_id(instance_inclusion_mask);\n\top->add_id(ray_contribution_to_hit_group);\n\top->add_id(multiplier_for_geometry);\n\top->add_id(miss_index);\n\top->add_id(ray_origin_vec);\n\top->add_id(tmin);\n\top->add_id(ray_dir_vec);\n\top->add_id(tmax);\n\top->add_id(ray_payload_var_id);\n\timpl.add(op);\n\n\tif (needs_temp_copy)\n\t\temit_temp_storage_resolve(impl, ray_payload, ray_payload_var_id);\n\n\timpl.rewrite_value(hit_object, variable);\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_make_hit(Converter::Impl &impl, const llvm::CallInst *instruction, bool with_index)\n{\n\tspv::Id instance_index = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\tspv::Id geometry_index = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 1);\n\tspv::Id primitive_index = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 2);\n\tspv::Id hit_kind = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 3);\n\t\n\tspv::Id hit_group_record_index;\n\tspv::Id ray_contribution_to_hit_group_index;\n\tspv::Id multiplier_for_geometry_contribution_to_hit_group_index;\n\n\tif (with_index)\n\t\thit_group_record_index = get_argument(impl, NVAPI_ARGUMENT_SRC1U + 0);\n\telse\n\t{\n\t\tray_contribution_to_hit_group_index = get_argument(impl, NVAPI_ARGUMENT_SRC1U + 0);\n\t\tmultiplier_for_geometry_contribution_to_hit_group_index = get_argument(impl, NVAPI_ARGUMENT_SRC1U + 1);\n\t}\n\n\tauto *hit_object = impl.nvapi.fake_doorbell_intermediates[NVAPI_INTERMEDIATE_HANDLE_0];\n\tauto *attributes = impl.nvapi.fake_doorbell_intermediates[NVAPI_INTERMEDIATE_ATTRIBUTES];\n\n\tauto &builder = impl.builder();\n\n\tbuilder.addExtension(\"SPV_NV_shader_invocation_reorder\");\n\tbuilder.addCapability(spv::CapabilityShaderInvocationReorderNV);\n\n\tspv::Id acceleration_structure = impl.get_id_for_value(instruction->getOperand(1));\n\n\tspv::Id ray_origin[3];\n\tspv::Id ray_dir[3];\n\n\tfor (unsigned i = 0; i < 3; i++)\n\t{\n\t\tray_origin[i] = impl.get_id_for_value(instruction->getOperand(7 + i));\n\t\tray_dir[i] = impl.get_id_for_value(instruction->getOperand(11 + i));\n\t}\n\n\tspv::Id tmin = impl.get_id_for_value(instruction->getOperand(10));\n\tspv::Id tmax = impl.get_id_for_value(instruction->getOperand(14));\n\n\tspv::Id float32 = builder.makeFloatType(32);\n\tspv::Id ray_origin_vec = impl.build_vector(float32, ray_origin, 3);\n\tspv::Id ray_dir_vec = impl.build_vector(float32, ray_dir, 3);\n\n\tbool needs_temp_copy = impl.get_needs_temp_storage_copy(attributes);\n\tspv::Id attribute_var_id = needs_temp_copy\n\t\t? emit_temp_storage_copy(impl, attributes, spv::StorageClassHitObjectAttributeNV)\n\t\t: impl.get_id_for_value(attributes);\n\n\tspv::Id variable = impl.create_variable(spv::StorageClassFunction, builder.makeHitObjectNVType());\n\n\tauto op = impl.allocate(with_index ? spv::OpHitObjectRecordHitWithIndexNV : spv::OpHitObjectRecordHitNV);\n\top->add_id(variable);\n\top->add_id(acceleration_structure);\n\top->add_id(instance_index);\n\top->add_id(primitive_index);\n\top->add_id(geometry_index);\n\top->add_id(hit_kind);\n\n\tif (with_index)\n\t\top->add_id(hit_group_record_index);\n\telse\n\t{\n\t\top->add_id(ray_contribution_to_hit_group_index);\n\t\top->add_id(multiplier_for_geometry_contribution_to_hit_group_index);\n\t}\n\n\top->add_id(ray_origin_vec);\n\top->add_id(tmin);\n\top->add_id(ray_dir_vec);\n\top->add_id(tmax);\n\top->add_id(attribute_var_id);\n\timpl.add(op);\n\n\timpl.rewrite_value(hit_object, variable);\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_make_miss(Converter::Impl &impl)\n{\n\tspv::Id index = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\tspv::Id tmin = get_argument_as_float(impl, NVAPI_ARGUMENT_SRC0U + 1);\n\tspv::Id tmax = get_argument_as_float(impl, NVAPI_ARGUMENT_SRC0U + 2);\n\n\tspv::Id ray_origin[3];\n\tspv::Id ray_dir[3];\n\n\tfor (unsigned i = 0; i < 3; i++)\n\t{\n\t\tray_origin[i] = get_argument_as_float(impl, NVAPI_ARGUMENT_SRC1U + i);\n\t\tray_dir[i] = get_argument_as_float(impl, NVAPI_ARGUMENT_SRC2U + i);\n\t}\n\n\tauto &builder = impl.builder();\n\n\tbuilder.addExtension(\"SPV_NV_shader_invocation_reorder\");\n\tbuilder.addCapability(spv::CapabilityShaderInvocationReorderNV);\n\n\tspv::Id float32 = builder.makeFloatType(32);\n\tspv::Id ray_origin_vec = impl.build_vector(float32, ray_origin, 3);\n\tspv::Id ray_dir_vec = impl.build_vector(float32, ray_dir, 3);\n\n\tspv::Id variable = impl.create_variable(spv::StorageClassFunction, builder.makeHitObjectNVType());\n\n\tauto op = impl.allocate(spv::OpHitObjectRecordMissNV);\n\top->add_id(variable);\n\top->add_id(index);\n\top->add_id(ray_origin_vec);\n\top->add_id(tmin);\n\top->add_id(ray_dir_vec);\n\top->add_id(tmax);\n\timpl.add(op);\n\n\timpl.nvapi.fake_doorbell_outputs[0] = variable;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_reorder_thread(Converter::Impl &impl)\n{\n\tauto *c = llvm::dyn_cast<llvm::ConstantInt>(impl.nvapi.fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0]);\n\tif (c != nullptr)\n\t{\n\t\tspv::Id hit_object = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 1);\n\t\tspv::Id hint = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 2);\n\t\tspv::Id bits = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 3);\n\n\t\tauto &builder = impl.builder();\n\n\t\tbuilder.addExtension(\"SPV_NV_shader_invocation_reorder\");\n\t\tbuilder.addCapability(spv::CapabilityShaderInvocationReorderNV);\n\n\t\tOperation *op;\n\n\t\tif (c->getUniqueInteger().getZExtValue())\n\t\t{\n\t\t\top = impl.allocate(spv::OpReorderThreadWithHitObjectNV);\n\t\t\top->add_id(hit_object);\n\t\t}\n\t\telse\n\t\t\top = impl.allocate(spv::OpReorderThreadWithHintNV);\n\n\t\top->add_id(hint);\n\t\top->add_id(bits);\n\t\timpl.add(op);\n\n\t\timpl.nvapi.fake_doorbell_outputs[0] = op->id;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_invoke(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id hit_object = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\n\tauto *ray_payload = instruction->getOperand(15);\n\n\tbool needs_temp_copy = impl.get_needs_temp_storage_copy(ray_payload);\n\tspv::Id ray_payload_var_id = needs_temp_copy\n\t\t? emit_temp_storage_copy(impl, ray_payload, spv::StorageClassRayPayloadKHR)\n\t\t: impl.get_id_for_value(ray_payload);\n\n\tauto *op = impl.allocate(spv::Op::OpHitObjectExecuteShaderNV);\n\top->add_id(hit_object);\n\top->add_id(ray_payload_var_id);\n\timpl.add(op);\n\n\tif (needs_temp_copy)\n\t\temit_temp_storage_resolve(impl, ray_payload, ray_payload_var_id);\n\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_get_bool(Converter::Impl &impl, uint32_t opcode)\n{\n\tspv::Id hit_object = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\n\tauto &builder = impl.builder();\n\tspv::Op op;\n\n\tswitch (opcode)\n\t{\n\tcase NV_EXTN_OP_HIT_OBJECT_IS_MISS:\n\t\top = spv::OpHitObjectIsMissNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_IS_HIT:\n\t\top = spv::OpHitObjectIsHitNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_IS_NOP:\n\t\top = spv::OpHitObjectIsEmptyNV;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tauto *is_op = impl.allocate(op, builder.makeBoolType());\n\tis_op->add_id(hit_object);\n\timpl.add(is_op);\n\n\tauto *select_op = impl.allocate(spv::OpSelect, builder.makeUintType(32));\n\tselect_op->add_id(is_op->id);\n\tselect_op->add_id(builder.makeUintConstant(1));\n\tselect_op->add_id(builder.makeUintConstant(0));\n\timpl.add(select_op);\n\n\timpl.nvapi.fake_doorbell_outputs[0] = select_op->id;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_get_uint(Converter::Impl &impl, uint32_t opcode)\n{\n\tspv::Id hit_object = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\n\tauto &builder = impl.builder();\n\tspv::Op op;\n\n\tswitch (opcode)\n\t{\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_ID:\n\t\top = spv::OpHitObjectGetInstanceIdNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_INDEX:\n\t\top = spv::OpHitObjectGetInstanceCustomIndexNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_PRIMITIVE_INDEX:\n\t\top = spv::OpHitObjectGetPrimitiveIndexNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_GEOMETRY_INDEX:\n\t\top = spv::OpHitObjectGetGeometryIndexNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_HIT_KIND:\n\t\top = spv::OpHitObjectGetHitKindNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_SHADER_TABLE_INDEX:\n\t\top = spv::OpHitObjectGetShaderBindingTableRecordIndexNV;\n\t\tbreak;\n\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_CLUSTER_ID:\n\t\tbuilder.addExtension(\"SPV_NV_cluster_acceleration_structure\");\n\t\tbuilder.addCapability(spv::CapabilityRayTracingClusterAccelerationStructureNV);\n\t\top = spv::OpHitObjectGetClusterIdNV;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tauto *get_op = impl.allocate(op, builder.makeUintType(32));\n\tget_op->add_id(hit_object);\n\timpl.add(get_op);\n\n\timpl.nvapi.fake_doorbell_outputs[0] = get_op->id;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_get_ray_desc(Converter::Impl &impl)\n{\n\tspv::Id hit_object = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\n\tauto &builder = impl.builder();\n\n\tauto uint32 = builder.makeUintType(32);\n\tauto float32 = builder.makeFloatType(32);\n\tauto vec3float32 = builder.makeVectorType(float32, 3);\n\n\tauto o = 0;\n\n\tfor (auto op : { spv::OpHitObjectGetRayTMinNV, spv::OpHitObjectGetRayTMaxNV })\n\t{\n\t\tauto *get_op = impl.allocate(op, float32);\n\t\tget_op->add_id(hit_object);\n\t\timpl.add(get_op);\n\n\t\tauto *bitcast_op = impl.allocate(spv::OpBitcast, uint32);\n\t\tbitcast_op->add_id(get_op->id);\n\t\timpl.add(bitcast_op);\n\n\t\timpl.nvapi.fake_doorbell_outputs[o++] = bitcast_op->id;\n\t}\n\n\tfor (auto op : { spv::OpHitObjectGetWorldRayOriginNV, spv::OpHitObjectGetWorldRayDirectionNV })\n\t{\n\t\tauto *get_op = impl.allocate(op, vec3float32);\n\t\tget_op->add_id(hit_object);\n\t\timpl.add(get_op);\n\n\t\tfor (unsigned i = 0; i < 3; i++)\n\t\t{\n\t\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, float32);\n\t\t\textract_op->add_id(get_op->id);\n\t\t\textract_op->add_literal(i);\n\t\t\timpl.add(extract_op);\n\n\t\t\tauto *bitcast_op = impl.allocate(spv::OpBitcast, uint32);\n\t\t\tbitcast_op->add_id(extract_op->id);\n\t\t\timpl.add(bitcast_op);\n\n\t\t\timpl.nvapi.fake_doorbell_outputs[o++] = bitcast_op->id;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_get_attributes(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id hit_object = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\n\tauto *attributes = instruction->getOperand(2);\n\n\tbool needs_temp_copy = impl.get_needs_temp_storage_copy(attributes);\n\tspv::Id attributes_var_id = needs_temp_copy\n\t\t? emit_temp_storage_copy(impl, attributes, spv::StorageClassHitObjectAttributeNV)\n\t\t: impl.get_id_for_value(attributes);\n\n\tauto op = impl.allocate(spv::OpHitObjectGetAttributesNV);\n\top->add_id(hit_object);\n\top->add_id(attributes_var_id);\n\timpl.add(op);\n\n\tif (needs_temp_copy)\n\t\temit_temp_storage_resolve(impl, attributes, attributes_var_id);\n\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_load_local_root_table_constant(Converter::Impl &impl)\n{\n\tspv::Id hit_object = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 0);\n\tspv::Id offset = get_argument(impl, NVAPI_ARGUMENT_SRC0U + 1);\n\n\tauto &builder = impl.builder();\n\n\tspv::Id uint32 = builder.makeUintType(32);\n\tspv::Id uint64 = builder.makeUintType(64);\n\n\tif (!impl.nvapi.hit_object_srb_ptr)\n\t{\n\t\tspv::Id srb_struct = builder.makeStructType({ uint32 }, \"HitObjectSRB\");\n\n\t\tbuilder.addDecoration(srb_struct, spv::DecorationBlock);\n\t\tbuilder.addDecoration(srb_struct, spv::DecorationHitObjectShaderRecordBufferNV);\n\n\t\tbuilder.addMemberDecoration(srb_struct, 0, spv::DecorationOffset, 0);\n\t\tbuilder.addMemberDecoration(srb_struct, 0, spv::DecorationNonWritable);\n\n\t\timpl.nvapi.hit_object_srb_ptr = builder.makePointer(spv::StorageClassPhysicalStorageBuffer, srb_struct);\n\t\timpl.nvapi.hit_object_srb_member_ptr = builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint32);\n\t}\n\n\tauto *op = impl.allocate(spv::OpHitObjectGetShaderRecordBufferHandleNV, builder.makeVectorType(uint32, 2));\n\top->add_id(hit_object);\n\timpl.add(op);\n\n\tauto *cast_op = impl.allocate(spv::OpBitcast, uint64);\n\tcast_op->add_id(op->id);\n\timpl.add(cast_op);\n\n\tauto *convert_op = impl.allocate(spv::OpUConvert, uint64);\n\tconvert_op->add_id(offset);\n\timpl.add(convert_op);\n\n\tauto *add_op = impl.allocate(spv::OpIAdd, uint64);\n\tadd_op->add_id(cast_op->id);\n\tadd_op->add_id(convert_op->id);\n\timpl.add(add_op);\n\n\tconvert_op = impl.allocate(spv::OpConvertUToPtr, impl.nvapi.hit_object_srb_ptr);\n\tconvert_op->add_id(add_op->id);\n\timpl.add(convert_op);\n\n\tauto *chain_op = impl.allocate(spv::OpAccessChain, impl.nvapi.hit_object_srb_member_ptr);\n\tchain_op->add_id(convert_op->id);\n\tchain_op->add_id(builder.makeUintConstant(0));\n\timpl.add(chain_op);\n\n\tauto *load_op = impl.allocate(spv::OpLoad, uint32);\n\tload_op->add_id(chain_op->id);\n\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\tload_op->add_literal(sizeof(uint32_t));\n\timpl.add(load_op);\n\n\timpl.nvapi.fake_doorbell_outputs[0] = load_op->id;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_hit_object_make_nop(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tbuilder.addExtension(\"SPV_NV_shader_invocation_reorder\");\n\tbuilder.addCapability(spv::CapabilityShaderInvocationReorderNV);\n\n\tspv::Id variable = impl.create_variable(spv::StorageClassFunction, builder.makeHitObjectNVType());\n\n\tauto op = impl.allocate(spv::OpHitObjectRecordEmptyNV);\n\top->add_id(variable);\n\timpl.add(op);\n\n\timpl.nvapi.fake_doorbell_outputs[0] = variable;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_rt_get_cluster_id(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tbuilder.addExtension(\"SPV_NV_cluster_acceleration_structure\");\n\tbuilder.addCapability(spv::CapabilityRayTracingClusterAccelerationStructureNV);\n\n\tspv::Id id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInClusterIDNV);\n\tauto *op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\top->add_id(id);\n\timpl.add(op);\n\n\timpl.nvapi.fake_doorbell_outputs[0] = op->id;\n\treturn true;\n}\n\nstatic bool emit_nvapi_extn_op_rt_get_intersection_cluster_id(Converter::Impl &impl, spv::RayQueryIntersection intersection)\n{\n\tauto *ray_flags = llvm::dyn_cast<llvm::CallInst>(impl.nvapi.fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0]);\n\tif (ray_flags != nullptr)\n\t{\n\t\tauto &builder = impl.builder();\n\t\tspv::Id ray_object_id = 0;\n\t\tif (!build_ray_query_object(impl, ray_flags->getOperand(1), ray_object_id))\n\t\t\treturn false;\n\n\t\tbuilder.addExtension(\"SPV_NV_cluster_acceleration_structure\");\n\t\tbuilder.addCapability(spv::CapabilityRayTracingClusterAccelerationStructureNV);\n\n\t\tauto *op = impl.allocate(spv::OpRayQueryGetClusterIdNV, builder.makeUintType(32));\n\t\top->add_id(ray_object_id);\n\t\top->add_id(builder.makeUintConstant(intersection));\n\t\timpl.add(op);\n\n\t\timpl.nvapi.fake_doorbell_outputs[0] = op->id;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool NVAPIState::can_commit_opcode()\n{\n\tif (!fake_doorbell_inputs[NVAPI_ARGUMENT_OPCODE])\n\t\treturn false;\n\n\tauto *c = llvm::dyn_cast<llvm::ConstantInt>(fake_doorbell_inputs[NVAPI_ARGUMENT_OPCODE]);\n\tif (c != nullptr)\n\t{\n\t\tauto opcode = uint32_t(c->getUniqueInteger().getZExtValue());\n\t\tswitch (opcode)\n\t\t{\n\t\tcase NV_EXTN_OP_SHFL:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 1] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 2] != nullptr;\n\n\t\tcase NV_EXTN_OP_FP16_ATOMIC:\n\t\t\treturn marked_uav &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC1U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC2U + 0] != nullptr;\n\n\t\tcase NV_EXTN_OP_GET_SPECIAL:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_TRACE_RAY:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_NUM_OUTPUTS_FOR_INC_COUNTER] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_NUM_OUTPUTS_FOR_INC_COUNTER] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 1] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 2] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 3] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC1U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC1U + 1] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_NUM_OUTPUTS_FOR_INC_COUNTER] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 1] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 2] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 3] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC1U + 0] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_MISS:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 1] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 2] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC1U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC1U + 1] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC1U + 2] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC2U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC2U + 1] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC2U + 2] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_REORDER_THREAD:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 1] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 2] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 3] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_INVOKE:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_IS_MISS:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_IS_HIT:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_IS_NOP:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_ID:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_PRIMITIVE_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_GEOMETRY_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_HIT_KIND:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_RAY_DESC:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_SHADER_TABLE_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_CLUSTER_ID:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_LOAD_LOCAL_ROOT_TABLE_CONSTANT:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr &&\n\t\t\t       fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 1] != nullptr;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_NOP:\n\t\tcase NV_EXTN_OP_RT_GET_CLUSTER_ID:\n\t\t\treturn true;\n\n\t\tcase NV_EXTN_OP_RT_GET_CANDIDATE_CLUSTER_ID:\n\t\tcase NV_EXTN_OP_RT_GET_COMMITTED_CLUSTER_ID:\n\t\t\treturn fake_doorbell_inputs[NVAPI_ARGUMENT_SRC0U + 0] != nullptr;\n\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t\treturn false;\n}\n\nbool NVAPIState::commit_opcode(Converter::Impl &impl, bool analysis)\n{\n\tif (!fake_doorbell_inputs[NVAPI_ARGUMENT_OPCODE])\n\t\treturn false;\n\n\tauto *c = llvm::dyn_cast<llvm::ConstantInt>(fake_doorbell_inputs[NVAPI_ARGUMENT_OPCODE]);\n\tif (c != nullptr)\n\t{\n\t\tauto opcode = uint32_t(c->getUniqueInteger().getZExtValue());\n\t\tswitch (opcode)\n\t\t{\n\t\tcase NV_EXTN_OP_SHFL:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_shuffle(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_FP16_ATOMIC:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 0;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_fp16x2_atomic(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_GET_SPECIAL:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_get_special(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_TRACE_RAY:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX:\n\t\t\timpl.spirv_module.set_override_spirv_version(0x10400);\n\t\t\timpl.nvapi.num_expected_clock_outputs = 2;\n\t\t\timpl.nvapi.deferred_opcode = opcode;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_MISS:\n\t\t\timpl.spirv_module.set_override_spirv_version(0x10400);\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_hit_object_make_miss(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_REORDER_THREAD:\n\t\t\timpl.spirv_module.set_override_spirv_version(0x10400);\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_hit_object_reorder_thread(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_INVOKE:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\timpl.nvapi.deferred_opcode = opcode;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_IS_MISS:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_IS_HIT:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_IS_NOP:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_hit_object_get_bool(impl, opcode))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_ID:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_PRIMITIVE_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_GEOMETRY_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_HIT_KIND:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_SHADER_TABLE_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_CLUSTER_ID:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_hit_object_get_uint(impl, opcode))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_RAY_DESC:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 8;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_hit_object_get_ray_desc(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_LOAD_LOCAL_ROOT_TABLE_CONSTANT:\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_hit_object_load_local_root_table_constant(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_NOP:\n\t\t\timpl.spirv_module.set_override_spirv_version(0x10400);\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_hit_object_make_nop(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_RT_GET_CLUSTER_ID:\n\t\t\timpl.spirv_module.set_override_spirv_version(0x10400);\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_rt_get_cluster_id(impl))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_RT_GET_CANDIDATE_CLUSTER_ID:\n\t\t\timpl.spirv_module.set_override_spirv_version(0x10400);\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_rt_get_intersection_cluster_id(impl, spv::RayQueryIntersectionRayQueryCandidateIntersectionKHR))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tcase NV_EXTN_OP_RT_GET_COMMITTED_CLUSTER_ID:\n\t\t\timpl.spirv_module.set_override_spirv_version(0x10400);\n\t\t\timpl.nvapi.num_expected_clock_outputs = 1;\n\t\t\tif (!analysis && !emit_nvapi_extn_op_rt_get_intersection_cluster_id(impl, spv::RayQueryIntersectionRayQueryCommittedIntersectionKHR))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nbool emit_nvapi_buffer_update_counter(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id)\n{\n\tif (id == impl.nvapi.magic_ptr_id)\n\t{\n\t\timpl.nvapi.notify_doorbell(impl, instruction, false);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool analyze_nvapi_buffer_update_counter(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (impl.options.nvapi.enabled)\n\t{\n\t\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\t\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t\t{\n\t\t\tif (itr->second == impl.nvapi.uav_magic_resource_type_index)\n\t\t\t{\n\t\t\t\timpl.nvapi.notify_doorbell(impl, instruction, true);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool nvapi_buffer_update_counter_filter(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (impl.options.nvapi.enabled)\n\t{\n\t\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\t\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t\t\tif (itr->second == impl.nvapi.uav_magic_resource_type_index)\n\t\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic const llvm::Value *get_nvapi_trace_handle(Converter::Impl &impl)\n{\n\tswitch (impl.nvapi.deferred_opcode)\n\t{\n\tcase NV_EXTN_OP_HIT_OBJECT_TRACE_RAY:\n\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT:\n\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX:\n\t\treturn impl.nvapi.fake_doorbell_intermediates[NVAPI_INTERMEDIATE_HANDLE_1];\n\tcase NV_EXTN_OP_HIT_OBJECT_INVOKE:\n\tcase NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES:\n\t\treturn impl.nvapi.fake_doorbell_intermediates[NVAPI_INTERMEDIATE_HANDLE_0];\n\tdefault:\n\t\treturn nullptr;\n\t}\n}\n\nstatic void mark_alloca_variable(Converter::Impl &impl, const llvm::Value *variable, spv::StorageClass storage_class)\n{\n\tconst auto *alloca_inst = llvm::dyn_cast<llvm::AllocaInst>(variable);\n\tif (alloca_inst != nullptr)\n\t{\n\t\tauto storage = impl.get_effective_storage_class(alloca_inst, spv::StorageClassFunction);\n\t\tif (storage != spv::StorageClassFunction && storage != storage_class)\n\t\t{\n\t\t\timpl.handle_to_storage_class[alloca_inst] = spv::StorageClassFunction;\n\t\t\tif (!impl.get_needs_temp_storage_copy(alloca_inst))\n\t\t\t\timpl.needs_temp_storage_copy.insert(alloca_inst);\n\t\t}\n\t\telse if (!impl.get_needs_temp_storage_copy(alloca_inst))\n\t\t{\n\t\t\timpl.handle_to_storage_class[alloca_inst] = storage_class;\n\t\t}\n\t}\n}\n\nbool analyze_nvapi_call_shader(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto *handle = get_nvapi_trace_handle(impl);\n\tif (handle != nullptr && handle == instruction->getOperand(1))\n\t{\n\t\tswitch (impl.nvapi.deferred_opcode)\n\t\t{\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX:\n\t\t\tmark_alloca_variable(impl, instruction->getOperand(2), spv::StorageClassHitObjectAttributeNV);\n\t\t\treturn true;\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES:\n\t\t\tmark_alloca_variable(impl, instruction->getOperand(2), spv::StorageClassHitObjectAttributeNV);\n\t\t\timpl.nvapi.reset();\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool analyze_nvapi_trace_ray(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto *handle = get_nvapi_trace_handle(impl);\n\tif (handle != nullptr && handle == instruction->getOperand(6))\n\t{\n\t\tswitch (impl.nvapi.deferred_opcode)\n\t\t{\n\t\tcase NV_EXTN_OP_HIT_OBJECT_TRACE_RAY:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_INVOKE:\n\t\t\tmark_alloca_variable(impl, instruction->getOperand(15), spv::StorageClassRayPayloadKHR);\n\t\t\timpl.nvapi.reset();\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool emit_nvapi_call_shader(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto *handle = get_nvapi_trace_handle(impl);\n\tif (handle != nullptr && handle == instruction->getOperand(1))\n\t{\n\t\tswitch (impl.nvapi.deferred_opcode)\n\t\t{\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT:\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX:\n\t\t\timpl.nvapi.fake_doorbell_intermediates[NVAPI_INTERMEDIATE_ATTRIBUTES] = instruction->getOperand(2);\n\t\t\treturn true;\n\t\tcase NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES:\n\t\t\tif (!emit_nvapi_extn_op_hit_object_get_attributes(impl, instruction))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\n\t\timpl.nvapi.reset();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_nvapi_trace_ray(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto *handle = get_nvapi_trace_handle(impl);\n\tif (handle != nullptr && handle == instruction->getOperand(6))\n\t{\n\t\tswitch (impl.nvapi.deferred_opcode)\n\t\t{\n\t\tcase NV_EXTN_OP_HIT_OBJECT_TRACE_RAY:\n\t\t\tif (!emit_nvapi_extn_op_hit_object_trace_ray(impl, instruction))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT:\n\t\t\tif (!emit_nvapi_extn_op_hit_object_make_hit(impl, instruction, false))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\tcase NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX:\n\t\t\tif (!emit_nvapi_extn_op_hit_object_make_hit(impl, instruction, true))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\tcase NV_EXTN_OP_HIT_OBJECT_INVOKE:\n\t\t\tif (!emit_nvapi_extn_op_hit_object_invoke(impl, instruction))\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\n\t\timpl.nvapi.reset();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_nvapi_resource_uav_handle(Converter::Impl &impl, const llvm::CallInst *instruction, uint32_t resource_range)\n{\n\tif (resource_range == impl.nvapi.uav_magic_resource_type_index)\n\t{\n\t\t// Resources tied to constant uints are considered \"magic\".\n\t\tif (impl.nvapi.magic_ptr_id == 0)\n\t\t{\n\t\t\tspv::Id dummy_value = impl.spirv_module.allocate_id();\n\t\t\timpl.nvapi.magic_ptr_id = dummy_value;\n\t\t}\n\n\t\timpl.rewrite_value(instruction, impl.nvapi.magic_ptr_id);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool analyze_nvapi_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, AccessTracking *)\n{\n\tif (impl.options.nvapi.enabled &&\n\t    impl.nvapi.uav_magic_resource_type_index != NVAPI_MAGIC_RESOURCE_SENTINEL &&\n\t    instruction->getOperand(2) == impl.nvapi.doorbell)\n\t{\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nvoid analyze_nvapi_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                AccessTracking *, DXIL::Op)\n{\n\t// We don't have the magic_ptr_id yet, but if we write with the doorbell value, we're very sure.\n\tif (impl.options.nvapi.enabled &&\n\t    impl.nvapi.uav_magic_resource_type_index != NVAPI_MAGIC_RESOURCE_SENTINEL &&\n\t    instruction->getOperand(2) == impl.nvapi.doorbell)\n\t{\n\t\tif (!impl.nvapi.mark_uav_write(instruction))\n\t\t\timpl.nvapi.write_arguments_from_store(impl, instruction, true);\n\t}\n}\n\nbool emit_nvapi_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, DXIL::Op)\n{\n\t// This can clock out arguments.\n\tif (impl.get_id_for_value(instruction->getOperand(1)) == impl.nvapi.magic_ptr_id &&\n\t    instruction->getOperand(2) == impl.nvapi.doorbell)\n\t{\n\t\tuint32_t offset;\n\t\tif (!get_constant_operand(instruction, 3, &offset))\n\t\t\treturn false;\n\n\t\tif (offset & 3)\n\t\t{\n\t\t\tLOGE(\"NVAPI offset is not aligned by 4 bytes.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\toffset /= 4;\n\n\t\tif (offset >= NVAPI_ARGUMENT_COUNT)\n\t\t{\n\t\t\tLOGE(\"NVAPI offset is too large.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (impl.nvapi.fake_doorbell_outputs[offset] == 0)\n\t\t{\n\t\t\tLOGE(\"Output argument is empty.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\timpl.rewrite_value(instruction, impl.nvapi.fake_doorbell_outputs[offset]);\n\t\t// TODO\n\t\timpl.llvm_composite_meta[instruction].components = 1;\n\t\timpl.llvm_composite_meta[instruction].forced_composite = false;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool NVAPIState::mark_uav_write(const llvm::CallInst *instruction)\n{\n\tauto *mark = fake_doorbell_inputs[NVAPI_ARGUMENT_MARK_UAV_REF];\n\tif (mark != nullptr)\n\t{\n\t\tconst auto *c = llvm::dyn_cast<llvm::ConstantInt>(mark);\n\t\tif (c != nullptr)\n\t\t{\n\t\t\tif (c->getUniqueInteger().getZExtValue() == 1)\n\t\t\t{\n\t\t\t\t// This completes an operation.\n\t\t\t\tmarked_uav = instruction->getOperand(1);\n\t\t\t\treset();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool NVAPIState::write_arguments_from_store(Converter::Impl &impl, const llvm::CallInst *instruction, bool analysis)\n{\n\tuint32_t offset;\n\tif (!get_constant_operand(instruction, 3, &offset))\n\t\treturn false;\n\n\tuint32_t mask;\n\tif (!get_constant_operand(instruction, 8, &mask))\n\t\treturn false;\n\n\tif (offset & 3)\n\t{\n\t\tLOGE(\"NVAPI offset is not aligned by 4 bytes.\\n\");\n\t\treturn false;\n\t}\n\n\toffset /= 4;\n\n\tif (offset >= NVAPI_ARGUMENT_COUNT)\n\t{\n\t\tLOGE(\"NVAPI offset is too large.\\n\");\n\t\treturn false;\n\t}\n\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\tif (mask & (1u << i))\n\t\t\tfake_doorbell_inputs[offset + i] = instruction->getOperand(4 + i);\n\t}\n\n\tif (can_commit_opcode())\n\t\tcommit_opcode(impl, analysis);\n\n\treturn true;\n}\n\nbool emit_nvapi_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id)\n{\n\tif (instruction->getOperand(2) == impl.nvapi.doorbell)\n\t{\n\t\tif (id == impl.nvapi.magic_ptr_id)\n\t\t\treturn impl.nvapi.write_arguments_from_store(impl, instruction, false);\n\t\telse\n\t\t\treturn impl.nvapi.mark_uav_write(instruction);\n\t}\n\n\treturn false;\n}\n}"
  },
  {
    "path": "opcodes/dxil/dxil_nvapi.hpp",
    "content": "/* Copyright (c) 2025 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nenum\n{\n\tNVAPI_ARGUMENT_OPCODE = 0,\n\tNVAPI_ARGUMENT_RID = 1,\n\tNVAPI_ARGUMENT_SID = 2,\n\tNVAPI_ARGUMENT_DST1U = 3,\n\tNVAPI_ARGUMENT_SRC3U = 7,\n\tNVAPI_ARGUMENT_SRC4U = 11,\n\tNVAPI_ARGUMENT_SRC5U = 15,\n\tNVAPI_ARGUMENT_SRC0U = 19,\n\tNVAPI_ARGUMENT_SRC1U = 23,\n\tNVAPI_ARGUMENT_SRC2U = 27,\n\tNVAPI_ARGUMENT_DST0U = 31,\n\tNVAPI_ARGUMENT_MARK_UAV_REF = 35,\n\tNVAPI_ARGUMENT_NUM_OUTPUTS_FOR_INC_COUNTER = 36,\n\tNVAPI_ARGUMENT_COUNT\n};\n\nenum\n{\n\tNVAPI_INTERMEDIATE_HANDLE_0 = 0,\n\tNVAPI_INTERMEDIATE_HANDLE_1 = 1,\n\tNVAPI_INTERMEDIATE_ATTRIBUTES = 2,\n\tNVAPI_INTERMEDIATE_COUNT\n};\n\n// Don't conflict with sentinel index for SM 6.6 heap.\nstatic constexpr uint32_t NVAPI_MAGIC_RESOURCE_SENTINEL = UINT32_MAX - 1;\n\nstruct NVAPIState\n{\n\tspv::Id magic_ptr_id = 0;\n\tconst llvm::Value *doorbell = nullptr;\n\tunsigned uav_magic_resource_type_index = NVAPI_MAGIC_RESOURCE_SENTINEL;\n\n\tconst llvm::Value *fake_doorbell_inputs[NVAPI_ARGUMENT_COUNT] = {};\n\tconst llvm::Value *fake_doorbell_intermediates[NVAPI_INTERMEDIATE_COUNT] = {};\n\tspv::Id fake_doorbell_outputs[NVAPI_ARGUMENT_COUNT] = {};\n\tconst llvm::Value *marked_uav = nullptr;\n\n\tspv::Id hit_object_srb_ptr = 0;\n\tspv::Id hit_object_srb_member_ptr = 0;\n\n\tunsigned deferred_opcode = 0;\n\n\tvoid reset();\n\tvoid reset_analysis() {}\n\tvoid notify_doorbell(Converter::Impl &impl, const llvm::CallInst *instruction, bool analysis);\n\tbool can_commit_opcode();\n\tbool commit_opcode(Converter::Impl &impl, bool analysis);\n\n\t// Some opcodes expect to read outputs by iteratively calling IncrementCounter().\n\tunsigned clock_output_index = 0;\n\tunsigned num_expected_clock_outputs = 0;\n\n\tbool write_arguments_from_store(Converter::Impl &impl, const llvm::CallInst *instruction, bool analysis);\n\tbool mark_uav_write(const llvm::CallInst *instruction);\n};\n\n// IncrementCounter is the doorbell opcode for NVAPI.\nbool analyze_nvapi_buffer_update_counter(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool nvapi_buffer_update_counter_filter(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_nvapi_buffer_update_counter(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id);\n\nbool analyze_nvapi_call_shader(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool analyze_nvapi_trace_ray(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_nvapi_call_shader(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_nvapi_trace_ray(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nstruct AccessTracking;\nbool analyze_nvapi_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, AccessTracking *tracking);\nvoid analyze_nvapi_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction, AccessTracking *tracking, DXIL::Op opcode);\n\nbool emit_nvapi_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, DXIL::Op opcode);\nbool emit_nvapi_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id id);\n\nbool emit_nvapi_resource_uav_handle(Converter::Impl &impl, const llvm::CallInst *instruction, uint32_t resource_range);\n}"
  },
  {
    "path": "opcodes/dxil/dxil_pixel_ops.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_pixel_ops.hpp\"\n#include \"dxil_common.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n#include \"dxil_waveops.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_discard_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto *cond = instruction->getOperand(1);\n\tbool has_condition = false;\n\tif (const auto *constant_int = llvm::dyn_cast<llvm::ConstantInt>(cond))\n\t{\n\t\tif (!constant_int->getUniqueInteger().getZExtValue())\n\t\t\treturn true;\n\t}\n\telse\n\t\thas_condition = true;\n\n\tOperation *op = impl.allocate(spv::OpDemoteToHelperInvocationEXT);\n\tif (has_condition)\n\t\top->add_id(impl.get_id_for_value(cond));\n\timpl.add(op);\n\timpl.spirv_module.enable_shader_discard(impl.options.shader_demote);\n\treturn true;\n}\n\nstatic bool emit_derivative_instruction_quad_coarse(\n    spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\temit_expect_assume_quad_uniform(impl);\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\n\tspv::Id type_id = impl.get_type_id(instruction->getType());\n\n\tauto *base = impl.allocate(spv::OpGroupNonUniformQuadBroadcast, type_id);\n\tbase->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbase->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\tbase->add_id(builder.makeUintConstant(0));\n\n\tauto *flip = impl.allocate(spv::OpGroupNonUniformQuadBroadcast, type_id);\n\tflip->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tflip->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\tflip->add_id(builder.makeUintConstant(opcode == spv::OpDPdyCoarse ? 2 : 1));\n\n\tauto *sub = impl.allocate(spv::OpFSub, instruction);\n\tsub->add_id(flip->id);\n\tsub->add_id(base->id);\n\n\timpl.add(base);\n\timpl.add(flip);\n\timpl.add(sub);\n\n\treturn true;\n}\n\nstatic bool emit_derivative_instruction_quad_fine(\n\tspv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\temit_expect_assume_quad_uniform(impl);\n\tauto &builder = impl.builder();\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\n\tspv::Id type_id = impl.get_type_id(instruction->getType());\n\n\tauto *flip = impl.allocate(spv::OpGroupNonUniformQuadSwap, type_id);\n\tflip->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tflip->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\tflip->add_id(builder.makeUintConstant(opcode == spv::OpDPdyFine ? 1 : 0));\n\timpl.add(flip);\n\n\tauto *sub = impl.allocate(spv::OpFSub, type_id);\n\tsub->add_id(flip->id);\n\tsub->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(sub);\n\n\tauto *flip_result = impl.allocate(spv::OpGroupNonUniformQuadSwap, type_id);\n\tflip_result->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tflip_result->add_id(sub->id);\n\tflip_result->add_id(builder.makeUintConstant(opcode == spv::OpDPdyFine ? 1 : 0));\n\timpl.add(flip_result);\n\n\tspv::Id local_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSubgroupLocalInvocationId);\n\tauto *load_local = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\tload_local->add_id(local_id);\n\timpl.add(load_local);\n\n\tauto *mask_op = impl.allocate(spv::OpBitwiseAnd, builder.makeUintType(32));\n\tmask_op->add_id(load_local->id);\n\tmask_op->add_id(builder.makeUintConstant(opcode == spv::OpDPdyFine ? 2 : 1));\n\timpl.add(mask_op);\n\n\tauto *should_flip = impl.allocate(spv::OpINotEqual, builder.makeBoolType());\n\tshould_flip->add_id(mask_op->id);\n\tshould_flip->add_id(builder.makeUintConstant(0));\n\timpl.add(should_flip);\n\n\tauto *sel = impl.allocate(spv::OpSelect, instruction);\n\tsel->add_id(should_flip->id);\n\tsel->add_id(flip_result->id);\n\tsel->add_id(sub->id);\n\timpl.add(sel);\n\n\treturn true;\n}\n\nstatic bool emit_derivative_instruction_quad(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\temit_expect_assume_quad_uniform(impl);\n\n\tswitch (opcode)\n\t{\n\tcase spv::OpDPdxCoarse:\n\tcase spv::OpDPdyCoarse:\n\t\treturn emit_derivative_instruction_quad_coarse(opcode, impl, instruction);\n\n\tcase spv::OpDPdxFine:\n\tcase spv::OpDPdyFine:\n\t\treturn emit_derivative_instruction_quad_fine(opcode, impl, instruction);\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool emit_extended_derivative_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\temit_expect_assume_quad_uniform(impl);\n\n\tuint32_t dim, mode;\n\tif (!get_constant_operand(instruction, 2, &dim))\n\t\treturn false;\n\tif (!get_constant_operand(instruction, 3, &mode))\n\t\treturn false;\n\n\tspv::Op opcode;\n\n\tif (dim == 0 && mode == 0)\n\t\topcode = spv::OpDPdx;\n\telse if (dim == 0 && mode == 1)\n\t\topcode = spv::OpDPdxCoarse;\n\telse if (dim == 0 && mode == 2)\n\t\topcode = spv::OpDPdxFine;\n\telse if (dim == 1 && mode == 0)\n\t\topcode = spv::OpDPdy;\n\telse if (dim == 1 && mode == 1)\n\t\topcode = spv::OpDPdyCoarse;\n\telse if (dim == 1 && mode == 2)\n\t\topcode = spv::OpDPdyFine;\n\telse\n\t\treturn false;\n\n\tauto *op = impl.allocate(opcode, instruction);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(op);\n\timpl.builder().addCapability(spv::CapabilityDerivativeControl);\n\treturn true;\n}\n\nbool emit_derivative_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\temit_expect_assume_quad_uniform(impl);\n\n\tif (impl.execution_mode_meta.synthesize_dummy_derivatives)\n\t{\n\t\tspv::Id constant_0;\n\t\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID &&\n\t\t    impl.support_native_fp16_operations())\n\t\t{\n\t\t\tconstant_0 = builder.makeFloat16Constant(0);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconstant_0 = builder.makeFloatConstant(0.0f);\n\t\t}\n\n\t\timpl.rewrite_value(instruction, constant_0);\n\t\treturn true;\n\t}\n\n\tif (impl.execution_model != spv::ExecutionModelFragment &&\n\t    !impl.options.compute_shader_derivatives)\n\t{\n\t\treturn emit_derivative_instruction_quad(opcode, impl, instruction);\n\t}\n\n\tbool relax_precision = false;\n\tspv::Id input_id;\n\n\t// SPIR-V only supports 32-bit derivatives.\n\tbool fp32 = instruction->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID;\n\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID &&\n\t    !impl.support_native_fp16_operations())\n\t{\n\t\tfp32 = true;\n\t\trelax_precision = true;\n\t}\n\n\tOperation *op;\n\tif (fp32)\n\t{\n\t\top = impl.allocate(opcode, instruction);\n\t\t// Somewhat redundant, but avoid changing reference output\n\t\t// for all shaders that use derivatives with constants.\n\t\tinput_id = impl.get_id_for_value(instruction->getOperand(1));\n\t}\n\telse\n\t{\n\t\tspv::Id fp32_type = builder.makeFloatType(32);\n\t\tauto *cast_op = impl.allocate(spv::OpFConvert, fp32_type);\n\t\tcast_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(cast_op);\n\t\tinput_id = cast_op->id;\n\n\t\top = impl.allocate(opcode, fp32_type);\n\t}\n\n\top->add_id(input_id);\n\timpl.add(op);\n\n\tif (relax_precision)\n\t\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\n\tif (!fp32)\n\t{\n\t\tauto *cast_op = impl.allocate(spv::OpFConvert, instruction);\n\t\tcast_op->add_id(op->id);\n\t\timpl.add(cast_op);\n\t\top = cast_op;\n\t}\n\n\tif (impl.execution_model == spv::ExecutionModelGLCompute && impl.options.quirks.robust_compute_quad_broadcast &&\n\t\t(opcode == spv::OpDPdxCoarse || opcode == spv::OpDPdyCoarse))\n\t{\n\t\t// Could implement for Fine too, but it gets a little more complicated.\n\t\tspv::Id base_active_id = emit_current_quad_lane_active(impl, 0);\n\t\tspv::Id other_active_id = emit_current_quad_lane_active(impl, opcode == spv::OpDPdxCoarse ? 1 : 2);\n\n\t\tauto *both_active = impl.allocate(spv::OpLogicalAnd, builder.makeBoolType());\n\t\tboth_active->add_id(base_active_id);\n\t\tboth_active->add_id(other_active_id);\n\t\timpl.add(both_active);\n\n\t\tauto *sel = impl.allocate(spv::OpSelect, impl.get_type_id(instruction->getType()));\n\t\tsel->add_id(both_active->id);\n\t\tsel->add_id(op->id);\n\t\tsel->add_id(builder.makeNullConstant(impl.get_type_id(instruction->getType())));\n\t\timpl.add(sel);\n\n\t\timpl.rewrite_value(instruction, sel->id);\n\t}\n\n\timpl.builder().addCapability(spv::CapabilityDerivativeControl);\n\treturn true;\n}\n\nbool emit_sample_index_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSampleId);\n\tOperation *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\timpl.add(op);\n\timpl.builder().addCapability(spv::CapabilitySampleRateShading);\n\treturn true;\n}\n\nbool emit_coverage_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSampleMask);\n\n\tOperation *ptr_op =\n\t    impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassInput, builder.makeUintType(32)));\n\tptr_op->add_id(var_id);\n\tptr_op->add_id(builder.makeUintConstant(0));\n\timpl.add(ptr_op);\n\n\tOperation *load_op = impl.allocate(spv::OpLoad, instruction);\n\tload_op->add_id(ptr_op->id);\n\timpl.add(load_op);\n\treturn true;\n}\n\nbool emit_inner_coverage_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInFullyCoveredEXT);\n\n\tbuilder.addCapability(spv::CapabilityFragmentFullyCoveredEXT);\n\tbuilder.addExtension(\"SPV_EXT_fragment_fully_covered\");\n\n\tOperation *load_op = impl.allocate(spv::OpLoad, builder.makeBoolType());\n\tload_op->add_id(var_id);\n\timpl.add(load_op);\n\n\tauto *type = instruction->getType();\n\n\tif (type->getIntegerBitWidth() == 1)\n\t{\n\t\timpl.rewrite_value(instruction, load_op->id);\n\t}\n\telse\n\t{\n\t\tauto *select_op = impl.allocate(spv::OpSelect, instruction);\n\t\tselect_op->add_id(load_op->id);\n\t\tselect_op->add_id(builder.makeUintConstant(1));\n\t\tselect_op->add_id(builder.makeUintConstant(0));\n\t\timpl.add(select_op);\n\t}\n\n\treturn true;\n}\n\nbool emit_is_helper_lane_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto *op = impl.allocate(spv::OpIsHelperInvocationEXT, instruction);\n\timpl.add(op);\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_pixel_ops.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_discard_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_is_helper_lane_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_sample_index_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_coverage_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_inner_coverage_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_derivative_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\n\ntemplate <spv::Op opcode>\nstatic inline bool emit_derivative_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_derivative_instruction(opcode, impl, instruction);\n}\n\nbool emit_extended_derivative_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_ray_tracing.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"opcodes/opcodes.hpp\"\n#include \"dxil_common.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n#include \"logging.hpp\"\n\nnamespace dxil_spv\n{\nspv::Id emit_temp_storage_copy(Converter::Impl &impl, const llvm::Value *value, spv::StorageClass storage)\n{\n\t// Make a new temporary variable for the ray payload/callable data.\n\tauto *pointer_type = llvm::cast<llvm::PointerType>(value->getType());\n\tauto *pointee_type = pointer_type->getPointerElementType();\n\tspv::Id type_id = impl.get_type_id(pointee_type);\n\tspv::Id var_id = impl.get_temp_payload(type_id, storage);\n\n\t// Load the alloca'ed value\n\tauto *load_op = impl.allocate(spv::OpLoad, type_id);\n\tload_op->add_id(impl.get_id_for_value(value));\n\timpl.add(load_op);\n\n\t// Store the alloca'ed value to our data in the right storage type\n\tauto *store_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(var_id);\n\tstore_op->add_id(load_op->id);\n\timpl.add(store_op);\n\n\treturn var_id;\n}\n\nvoid emit_temp_storage_resolve(Converter::Impl &impl, const llvm::Value *real_value, spv::Id temp_storage)\n{\n\tauto *pointer_type = llvm::cast<llvm::PointerType>(real_value->getType());\n\tauto *pointee_type = pointer_type->getPointerElementType();\n\tspv::Id type_id = impl.get_type_id(pointee_type);\n\n\t// Load the result from the temp\n\tauto *load_op = impl.allocate(spv::OpLoad, type_id);\n\tload_op->add_id(temp_storage);\n\timpl.add(load_op);\n\n\t// Store the result in the alloca'ed value\n\tauto *store_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(impl.get_id_for_value(real_value));\n\tstore_op->add_id(load_op->id);\n\timpl.add(store_op);\n}\n\nbool emit_trace_ray_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tif (emit_nvapi_trace_ray(impl, inst))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Id acceleration_structure = impl.get_id_for_value(inst->getOperand(1));\n\tspv::Id ray_flags = impl.get_id_for_value(inst->getOperand(2));\n\tspv::Id instance_inclusion_mask = impl.get_id_for_value(inst->getOperand(3));\n\tspv::Id ray_contribution_to_hit_group = impl.get_id_for_value(inst->getOperand(4));\n\tspv::Id multiplier_for_geometry = impl.get_id_for_value(inst->getOperand(5));\n\tspv::Id miss_shader_index = impl.get_id_for_value(inst->getOperand(6));\n\n\tspv::Id ray_origin[3];\n\tspv::Id ray_dir[3];\n\n\tfor (unsigned i = 0; i < 3; i++)\n\t{\n\t\tray_origin[i] = impl.get_id_for_value(inst->getOperand(7 + i));\n\t\tray_dir[i] = impl.get_id_for_value(inst->getOperand(11 + i));\n\t}\n\n\tspv::Id tmin = impl.get_id_for_value(inst->getOperand(10));\n\tspv::Id tmax = impl.get_id_for_value(inst->getOperand(14));\n\n\tspv::Id ray_origin_vec = impl.build_vector(builder.makeFloatType(32), ray_origin, 3);\n\tspv::Id ray_dir_vec = impl.build_vector(builder.makeFloatType(32), ray_dir, 3);\n\n\tauto *ray_payload = inst->getOperand(15);\n\n\tbool needs_temp_copy = impl.get_needs_temp_storage_copy(ray_payload);\n\tspv::Id ray_payload_var_id = needs_temp_copy\n\t\t? emit_temp_storage_copy(impl, ray_payload, spv::StorageClassRayPayloadKHR)\n\t\t: impl.get_id_for_value(ray_payload);\n\n\tauto *op = impl.allocate(spv::OpTraceRayKHR);\n\top->add_ids({\n\t    acceleration_structure,\n\t    ray_flags,\n\t    instance_inclusion_mask,\n\t    ray_contribution_to_hit_group,\n\t    multiplier_for_geometry,\n\t    miss_shader_index,\n\t    ray_origin_vec,\n\t    tmin,\n\t    ray_dir_vec,\n\t    tmax,\n\t    ray_payload_var_id\n\t});\n\timpl.add(op);\n\n\t// In this instance, the ray_payload_var_id is our temp.\n\tif (needs_temp_copy)\n\t\temit_temp_storage_resolve(impl, ray_payload, ray_payload_var_id);\n\n\treturn true;\n}\n\nbool emit_ray_tracing_builtin_load_instruction(Converter::Impl &impl, const llvm::CallInst *inst,\n                                               spv::BuiltIn builtin, spv::Id scalar_type)\n{\n\tauto &builder = impl.builder();\n\tspv::Id input = impl.spirv_module.get_builtin_shader_input(builtin);\n\n\tauto *access_chain = impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassInput, scalar_type));\n\taccess_chain->add_id(input);\n\taccess_chain->add_id(impl.get_id_for_value(inst->getOperand(1), 32));\n\timpl.add(access_chain);\n\n\tauto *load = impl.allocate(spv::OpLoad, inst);\n\tload->add_id(access_chain->id);\n\timpl.add(load);\n\treturn true;\n}\n\nbool emit_dispatch_rays_index_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_builtin_load_instruction(impl, inst, spv::BuiltInLaunchIdKHR,\n\t                                                 impl.builder().makeUintType(32));\n}\n\nbool emit_dispatch_rays_dimensions_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_builtin_load_instruction(impl, inst, spv::BuiltInLaunchSizeKHR,\n\t                                                 impl.builder().makeUintType(32));\n}\n\nbool emit_object_ray_origin_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_builtin_load_instruction(impl, inst, spv::BuiltInObjectRayOriginKHR,\n\t                                                 impl.builder().makeFloatType(32));\n}\n\nbool emit_world_ray_origin_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_builtin_load_instruction(impl, inst, spv::BuiltInWorldRayOriginKHR,\n\t                                                 impl.builder().makeFloatType(32));\n}\n\nbool emit_object_ray_direction_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_builtin_load_instruction(impl, inst, spv::BuiltInObjectRayDirectionKHR,\n\t                                                 impl.builder().makeFloatType(32));\n}\n\nbool emit_world_ray_direction_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_builtin_load_instruction(impl, inst, spv::BuiltInWorldRayDirectionKHR,\n\t                                                 impl.builder().makeFloatType(32));\n}\n\nbool emit_ray_t_min_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tspv::Id id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInRayTminKHR);\n\tauto *op = impl.allocate(spv::OpLoad, inst);\n\top->add_id(id);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_t_current_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tspv::Id id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInRayTmaxKHR);\n\tauto *op = impl.allocate(spv::OpLoad, inst);\n\top->add_id(id);\n\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan &&\n\t    impl.spirv_module.builtin_requires_volatile(spv::BuiltInRayTmaxKHR))\n\t{\n\t\top->add_literal(spv::MemoryAccessVolatileMask);\n\t}\n\n\timpl.add(op);\n\treturn true;\n}\n\nstatic bool emit_ray_tracing_matrix_load(Converter::Impl &impl, const llvm::CallInst *inst, spv::BuiltIn builtin)\n{\n\tauto &builder = impl.builder();\n\tspv::Id matrix_id = impl.spirv_module.get_builtin_shader_input(builtin);\n\tauto *chain_op = impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassInput, builder.makeFloatType(32)));\n\tchain_op->add_id(matrix_id);\n\n\t// Transpose here.\n\tchain_op->add_id(impl.get_id_for_value(inst->getOperand(2), 32));\n\tchain_op->add_id(impl.get_id_for_value(inst->getOperand(1)));\n\n\timpl.add(chain_op);\n\n\tauto *load_op = impl.allocate(spv::OpLoad, inst);\n\tload_op->add_id(chain_op->id);\n\timpl.add(load_op);\n\treturn true;\n}\n\nbool emit_ray_tracing_report_hit(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\t// We only have one global HitAttributeKHR per shader, so we'll need to copy from argument into that.\n\tauto *load_op = impl.allocate(spv::OpLoad, impl.get_type_id(impl.llvm_hit_attribute_output_type->getPointerElementType()));\n\tload_op->add_id(impl.get_id_for_value(inst->getOperand(3)));\n\timpl.add(load_op);\n\n\tauto *store_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(impl.llvm_hit_attribute_output_value);\n\tstore_op->add_id(load_op->id);\n\timpl.add(store_op);\n\n\tauto *op = impl.allocate(spv::OpReportIntersectionKHR, inst);\n\top->add_id(impl.get_id_for_value(inst->getOperand(1)));\n\top->add_id(impl.get_id_for_value(inst->getOperand(2)));\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_tracing_accept_hit_and_end_search(Converter::Impl &impl, const llvm::CallInst *)\n{\n\tauto *op = impl.allocate(spv::OpTerminateRayKHR);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_tracing_ignore_hit(Converter::Impl &impl, const llvm::CallInst *)\n{\n\tauto *op = impl.allocate(spv::OpIgnoreIntersectionKHR);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_tracing_call_shader(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tif (emit_nvapi_call_shader(impl, inst))\n\t\treturn true;\n\n\tauto *callable_data = inst->getOperand(2);\n\n\tbool needs_temp_copy = impl.get_needs_temp_storage_copy(callable_data);\n\tspv::Id callable_data_var_id = impl.get_needs_temp_storage_copy(callable_data)\n\t\t? emit_temp_storage_copy(impl, callable_data, spv::StorageClassCallableDataKHR)\n\t\t: impl.get_id_for_value(callable_data);\n\n\tauto *op = impl.allocate(spv::OpExecuteCallableKHR);\n\top->add_id(impl.get_id_for_value(inst->getOperand(1)));\n\top->add_id(callable_data_var_id);\n\timpl.add(op);\n\n\t// In this instance, the callable_data_var_id is our temp.\n\tif (needs_temp_copy)\n\t\temit_temp_storage_resolve(impl, callable_data, callable_data_var_id);\n\n\treturn true;\n}\n\nbool emit_world_to_object_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_matrix_load(impl, inst, spv::BuiltInWorldToObjectKHR);\n}\n\nbool emit_object_to_world_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_matrix_load(impl, inst, spv::BuiltInObjectToWorldKHR);\n}\n\nstatic bool emit_ray_tracing_load_uint(Converter::Impl &impl, const llvm::CallInst *inst, spv::BuiltIn builtin)\n{\n\tspv::Id index_id = impl.spirv_module.get_builtin_shader_input(builtin);\n\tauto *op = impl.allocate(spv::OpLoad, inst);\n\top->add_id(index_id);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_tracing_instance_id_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_load_uint(impl, inst, spv::BuiltInInstanceCustomIndexKHR);\n}\n\nbool emit_ray_tracing_instance_index_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_load_uint(impl, inst, spv::BuiltInInstanceId);\n}\n\nbool emit_ray_tracing_geometry_index_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_load_uint(impl, inst, spv::BuiltInRayGeometryIndexKHR);\n}\n\nbool emit_ray_tracing_primitive_index_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_load_uint(impl, inst, spv::BuiltInPrimitiveId);\n}\n\nbool emit_ray_tracing_ray_flags_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_load_uint(impl, inst, spv::BuiltInIncomingRayFlagsKHR);\n}\n\nbool emit_ray_tracing_hit_kind_instruction(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn emit_ray_tracing_load_uint(impl, inst, spv::BuiltInHitKindKHR);\n}\n\nstatic void emit_ray_query_capabilities(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tbuilder.addExtension(\"SPV_KHR_ray_query\");\n\tbuilder.addCapability(spv::CapabilityRayQueryKHR);\n\tbuilder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);\n\tif (impl.options.opacity_micromap_enabled)\n\t{\n\t\tbuilder.addExtension(\"SPV_EXT_opacity_micromap\");\n\t\tbuilder.addCapability(spv::CapabilityRayTracingOpacityMicromapEXT);\n\t}\n}\n\nbool emit_allocate_ray_query(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tauto &builder = impl.builder();\n\n\tif (impl.ray_query.global_query_objects_id)\n\t{\n\t\tuint32_t index;\n\t\tif (impl.shader_analysis.ray_query.uses_divergent_handles)\n\t\t\tindex = impl.ray_query.ray_query_index++;\n\t\telse\n\t\t\tindex = 0;\n\n\t\timpl.rewrite_value(inst, builder.makeUintConstant(index));\n\t}\n\telse\n\t{\n\t\tspv::Id var_id = impl.spirv_module.create_variable(spv::StorageClassPrivate, builder.makeRayQueryType());\n\t\timpl.rewrite_value(inst, var_id);\n\t\timpl.handle_to_storage_class[inst] = spv::StorageClassPrivate;\n\t}\n\n\temit_ray_query_capabilities(impl);\n\treturn true;\n}\n\nstatic bool get_representative_ray_query_flags(Converter::Impl &impl, const llvm::Value *operand,\n                                               uint32_t &ray_query_flags)\n{\n\tif (value_is_dx_op_instrinsic(operand, DXIL::Op::AllocateRayQuery))\n\t{\n\t\treturn get_constant_operand(llvm::cast<llvm::CallInst>(operand), 1, &ray_query_flags);\n\t}\n\telse if (const auto *phi = llvm::dyn_cast<llvm::PHINode>(operand))\n\t{\n\t\t// HLSL expectation is that all ray query flags are the same, so pick the static flags from first incoming.\n\t\treturn get_representative_ray_query_flags(impl, phi->getIncomingValue(0), ray_query_flags);\n\t}\n\telse if (const auto *select = llvm::dyn_cast<llvm::SelectInst>(operand))\n\t{\n\t\treturn get_representative_ray_query_flags(impl, select->getOperand(1), ray_query_flags);\n\t}\n\telse if (const auto *load = llvm::dyn_cast<llvm::LoadInst>(operand))\n\t{\n\t\treturn get_representative_ray_query_flags(impl, load->getPointerOperand(), ray_query_flags);\n\t}\n\telse if (const auto *gep = llvm::dyn_cast<llvm::GetElementPtrInst>(operand))\n\t{\n\t\treturn get_representative_ray_query_flags(impl, gep->getOperand(0), ray_query_flags);\n\t}\n\telse if (const auto *alloca = llvm::dyn_cast<llvm::AllocaInst>(operand))\n\t{\n\t\tfor (auto &mapping : impl.shader_analysis.ray_query.alloca_mappings)\n\t\t{\n\t\t\tif (mapping.alloca == alloca)\n\t\t\t{\n\t\t\t\tray_query_flags = mapping.ray_query_flags;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tLOGE(\"Cannot find ray query flags mapping.\\n\");\n\t\treturn false;\n\t}\n\n\t// No idea ...\n\tLOGE(\"Cannot find representative ray query flags.\\n\");\n\treturn false;\n}\n\nbool build_ray_query_object(Converter::Impl &impl, const llvm::Value *operand,\n                            spv::Id &object_id, uint32_t *ray_query_flags = nullptr)\n{\n\tif (impl.ray_query.global_query_objects_id)\n\t{\n\t\tauto &builder = impl.builder();\n\n\t\tif (impl.shader_analysis.ray_query.uses_divergent_handles)\n\t\t{\n\t\t\t// Painful case.\n\t\t\tauto *chain = impl.allocate(spv::OpInBoundsAccessChain,\n\t\t\t                            builder.makePointer(spv::StorageClassPrivate, builder.makeRayQueryType()));\n\t\t\tchain->add_id(impl.ray_query.global_query_objects_id);\n\t\t\tchain->add_id(impl.get_id_for_value(operand));\n\t\t\timpl.add(chain);\n\n\t\t\tobject_id = chain->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Trivial case.\n\t\t\tobject_id = impl.ray_query.global_query_objects_id;\n\t\t}\n\n\t\t// Need to deduce the flags for the allocation.\n\t\t// This must be statically deducible from an HLSL point of view.\n\t\t// If we fail this check, fail compilation.\n\t\tif (ray_query_flags && !get_representative_ray_query_flags(impl, operand, *ray_query_flags))\n\t\t\treturn false;\n\t}\n\telse\n\t{\n\t\tobject_id = impl.get_id_for_value(operand);\n\t\tauto *ray_object = llvm::cast<llvm::CallInst>(operand);\n\t\tif (ray_query_flags && !get_constant_operand(ray_object, 1, ray_query_flags))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool emit_ray_query_trace_ray_inline_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tauto *init_op = impl.allocate(spv::OpRayQueryInitializeKHR);\n\n\tspv::Id ray_object_id = 0;\n\tuint32_t ray_query_flags = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id, &ray_query_flags))\n\t\treturn false;\n\n\tinit_op->add_id(ray_object_id);\n\tinit_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\n\t// The template type of the ray query object is embedded in the object itself, we must OR in the constant flags.\n\tif (auto *const_flags = llvm::dyn_cast<llvm::ConstantInt>(instruction->getOperand(3)))\n\t{\n\t\tray_query_flags |= const_flags->getUniqueInteger().getZExtValue();\n\t\tinit_op->add_id(builder.makeUintConstant(ray_query_flags));\n\t}\n\telse if (ray_query_flags == 0)\n\t{\n\t\tinit_op->add_id(impl.get_id_for_value(instruction->getOperand(3)));\n\t}\n\telse\n\t{\n\t\tauto *or_op = impl.allocate(spv::OpBitwiseOr, builder.makeUintType(32));\n\t\tor_op->add_id(impl.get_id_for_value(instruction->getOperand(3)));\n\t\tor_op->add_id(builder.makeUintConstant(ray_query_flags));\n\t\timpl.add(or_op);\n\t\tinit_op->add_id(or_op->id);\n\t}\n\n\tinit_op->add_id(impl.get_id_for_value(instruction->getOperand(4)));\n\n\tspv::Id origin[3], direction[3];\n\tfor (unsigned i = 0; i < 3; i++)\n\t{\n\t\torigin[i] = impl.get_id_for_value(instruction->getOperand(5 + i));\n\t\tdirection[i] = impl.get_id_for_value(instruction->getOperand(9 + i));\n\t}\n\tinit_op->add_id(impl.build_vector(builder.makeFloatType(32), origin, 3));\n\tinit_op->add_id(impl.get_id_for_value(instruction->getOperand(8)));\n\tinit_op->add_id(impl.build_vector(builder.makeFloatType(32), direction, 3));\n\tinit_op->add_id(impl.get_id_for_value(instruction->getOperand(12)));\n\n\timpl.add(init_op);\n\n\treturn true;\n}\n\nbool emit_ray_query_proceed_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tauto *op = impl.allocate(spv::OpRayQueryProceedKHR, instruction);\n\top->add_id(ray_object_id);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_query_abort_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tauto *op = impl.allocate(spv::OpRayQueryTerminateKHR);\n\top->add_id(ray_object_id);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_query_intersection_type_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                  spv::RayQueryIntersection intersection)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tauto *op = impl.allocate(spv::OpRayQueryGetIntersectionTypeKHR, instruction);\n\top->add_id(ray_object_id);\n\top->add_id(builder.makeUintConstant(intersection));\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_query_system_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                             spv::Op opcode, uint32_t vecsize)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tif (vecsize == 1)\n\t{\n\t\tauto *op = impl.allocate(opcode, instruction);\n\t\top->add_id(ray_object_id);\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\tauto *op = impl.allocate(opcode, builder.makeVectorType(impl.get_type_id(instruction->getType()), vecsize));\n\t\top->add_id(ray_object_id);\n\t\timpl.add(op);\n\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, instruction);\n\t\textract_op->add_id(op->id);\n\n\t\tuint32_t index = 0;\n\t\tif (!get_constant_operand(instruction, 2, &index))\n\t\t\treturn false;\n\t\textract_op->add_literal(index);\n\t\timpl.add(extract_op);\n\t}\n\treturn true;\n}\n\nbool emit_ray_query_get_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                          spv::Op opcode, uint32_t vecsize, spv::RayQueryIntersection intersection)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tif (vecsize == 1)\n\t{\n\t\tauto *op = impl.allocate(opcode, instruction);\n\t\top->add_id(ray_object_id);\n\t\top->add_id(builder.makeUintConstant(intersection));\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\tauto *op = impl.allocate(opcode, builder.makeVectorType(impl.get_type_id(instruction->getType()), vecsize));\n\t\top->add_id(ray_object_id);\n\t\top->add_id(builder.makeUintConstant(intersection));\n\t\timpl.add(op);\n\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, instruction);\n\t\textract_op->add_id(op->id);\n\n\t\tuint32_t index = 0;\n\t\tif (!get_constant_operand(instruction, 2, &index))\n\t\t\treturn false;\n\t\textract_op->add_literal(index);\n\t\timpl.add(extract_op);\n\t}\n\treturn true;\n}\n\nbool emit_ray_query_get_matrix_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                 spv::Op opcode, spv::RayQueryIntersection intersection)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tauto *op = impl.allocate(opcode, builder.makeMatrixType(impl.get_type_id(instruction->getType()), 4, 3));\n\top->add_id(ray_object_id);\n\top->add_id(builder.makeUintConstant(intersection));\n\timpl.add(op);\n\n\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, instruction);\n\tuint32_t row = 0, col = 0;\n\tif (!get_constant_operand(instruction, 2, &row))\n\t\treturn false;\n\tif (!get_constant_operand(instruction, 3, &col))\n\t\treturn false;\n\textract_op->add_id(op->id);\n\textract_op->add_literal(col);\n\textract_op->add_literal(row);\n\timpl.add(extract_op);\n\treturn true;\n}\n\nbool emit_ray_query_commit_non_opaque_triangle_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tauto *op = impl.allocate(spv::OpRayQueryConfirmIntersectionKHR);\n\top->add_id(ray_object_id);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_query_commit_procedural_primitive_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tauto *op = impl.allocate(spv::OpRayQueryGenerateIntersectionKHR);\n\top->add_id(ray_object_id);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_ray_query_candidate_procedural_primitive_non_opaque_instruction(Converter::Impl &impl,\n                                                                          const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ray_object_id = 0;\n\tif (!build_ray_query_object(impl, instruction->getOperand(1), ray_object_id))\n\t\treturn false;\n\n\tauto *op = impl.allocate(spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, builder.makeBoolType());\n\top->add_id(ray_object_id);\n\timpl.add(op);\n\n\tauto *not_op = impl.allocate(spv::OpLogicalNot, instruction);\n\tnot_op->add_id(op->id);\n\timpl.add(not_op);\n\treturn true;\n}\n}\n"
  },
  {
    "path": "opcodes/dxil/dxil_ray_tracing.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nspv::Id emit_temp_storage_copy(Converter::Impl &impl, const llvm::Value *value, spv::StorageClass storage);\nvoid emit_temp_storage_resolve(Converter::Impl &impl, const llvm::Value *real_value, spv::Id temp_storage);\nbool emit_trace_ray_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dispatch_rays_index_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dispatch_rays_dimensions_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_object_ray_origin_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_world_ray_origin_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_object_ray_direction_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_world_ray_direction_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_t_min_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_t_current_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_world_to_object_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_object_to_world_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_instance_id_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_instance_index_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_geometry_index_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_primitive_index_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_ray_flags_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_hit_kind_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_report_hit(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_accept_hit_and_end_search(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_ignore_hit(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_tracing_call_shader(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_allocate_ray_query(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool build_ray_query_object(Converter::Impl &impl, const llvm::Value *operand, \n                            spv::Id &object_id, uint32_t *ray_query_flags = nullptr);\nbool emit_ray_query_trace_ray_inline_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_query_proceed_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_query_abort_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_ray_query_commit_non_opaque_triangle_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_query_commit_procedural_primitive_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_ray_query_candidate_procedural_primitive_non_opaque_instruction(Converter::Impl &impl,\n                                                                          const llvm::CallInst *instruction);\n\nbool emit_ray_query_intersection_type_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                  spv::RayQueryIntersection intersection);\ntemplate <spv::RayQueryIntersection intersection>\nbool emit_ray_query_intersection_type_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_ray_query_intersection_type_instruction(impl, instruction, intersection);\n}\n\nbool emit_ray_query_system_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                             spv::Op op, uint32_t vecsize);\ntemplate <spv::Op opcode, uint32_t vecsize>\ninline bool emit_ray_query_system_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_ray_query_system_value_instruction(impl, instruction, opcode, vecsize);\n}\n\nbool emit_ray_query_get_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                          spv::Op opcode, uint32_t vecsize, spv::RayQueryIntersection intersection);\ntemplate <spv::Op opcode, uint32_t vecsize, spv::RayQueryIntersection intersection>\ninline bool emit_ray_query_get_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_ray_query_get_value_instruction(impl, instruction, opcode, vecsize, intersection);\n}\n\nbool emit_ray_query_get_matrix_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                 spv::Op opcode, spv::RayQueryIntersection intersection);\ntemplate <spv::Op opcode, spv::RayQueryIntersection intersection>\ninline bool emit_ray_query_get_matrix_value_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_ray_query_get_matrix_value_instruction(impl, instruction, opcode, intersection);\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_resources.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_resources.hpp\"\n#include \"dxil_common.hpp\"\n#include \"logging.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n#include \"dxil_buffer.hpp\"\n#include \"dxil_workgraph.hpp\"\n#include \"dxil_waveops.hpp\"\n#include \"dxil_ags.hpp\"\n#include \"dxil_geometry.hpp\"\n\nnamespace dxil_spv\n{\nstatic Converter::Impl::ClipCullMeta *input_clip_cull_distance_meta(Converter::Impl &impl, unsigned index)\n{\n\tauto itr = impl.input_clip_cull_meta.find(index);\n\tif (itr != impl.input_clip_cull_meta.end())\n\t\treturn &itr->second;\n\telse\n\t\treturn nullptr;\n}\n\nstatic bool emit_load_clip_cull_distance(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                         const Converter::Impl::ClipCullMeta &meta)\n{\n\tspv::Id ptr_id = get_clip_cull_distance_access_chain(impl, instruction, meta, spv::StorageClassInput);\n\n\tOperation *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(ptr_id);\n\timpl.add(op);\n\treturn true;\n}\n\nstatic void fixup_builtin_load(Converter::Impl &impl, spv::Id var_id, const llvm::CallInst *instruction,\n                               bool spirv_semantics)\n{\n\tauto &builder = impl.builder();\n\tspv::BuiltIn builtin;\n\tif (impl.spirv_module.query_builtin_shader_input(var_id, &builtin))\n\t{\n\t\tif (builtin == spv::BuiltInInstanceIndex || builtin == spv::BuiltInVertexIndex)\n\t\t{\n\t\t\t// Need to shift down to 0-base.\n\t\t\tspv::Id base_id = impl.spirv_module.get_builtin_shader_input(\n\t\t\t    builtin == spv::BuiltInInstanceIndex ? spv::BuiltInBaseInstance : spv::BuiltInBaseVertex);\n\t\t\t{\n\t\t\t\tOperation *op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\t\t\top->add_id(base_id);\n\t\t\t\tbase_id = op->id;\n\t\t\t\timpl.add(op);\n\t\t\t}\n\n\t\t\tOperation *sub_op = impl.allocate(spv::OpISub, builder.makeUintType(32));\n\t\t\tsub_op->add_ids({ impl.get_id_for_value(instruction), base_id });\n\t\t\timpl.add(sub_op);\n\t\t\timpl.rewrite_value(instruction, sub_op->id);\n\t\t\tbuilder.addCapability(spv::CapabilityDrawParameters);\n\t\t}\n\t\telse if (builtin == spv::BuiltInFrontFacing && instruction->getType()->getIntegerBitWidth() != 1)\n\t\t{\n\t\t\tOperation *cast_op = impl.allocate(spv::OpSelect, builder.makeUintType(32));\n\t\t\tcast_op->add_id(impl.get_id_for_value(instruction));\n\t\t\tcast_op->add_id(builder.makeUintConstant(~0u));\n\t\t\tcast_op->add_id(builder.makeUintConstant(0));\n\t\t\timpl.add(cast_op);\n\t\t\timpl.rewrite_value(instruction, cast_op->id);\n\t\t}\n\t\telse if (builtin == spv::BuiltInFragCoord && !spirv_semantics)\n\t\t{\n\t\t\tauto *col = llvm::cast<llvm::ConstantInt>(instruction->getOperand(3));\n\t\t\tif (col->getUniqueInteger().getZExtValue() == 3)\n\t\t\t{\n\t\t\t\t// FragCoord.w is inverted in DX.\n\t\t\t\tOperation *op = impl.allocate(spv::OpFDiv, builder.makeFloatType(32));\n\t\t\t\top->add_id(builder.makeFloatConstant(1.0f));\n\t\t\t\top->add_id(impl.get_id_for_value(instruction));\n\t\t\t\timpl.add(op);\n\t\t\t\timpl.rewrite_value(instruction, op->id);\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic spv::Id get_builtin_load_type(Converter::Impl &impl, const Converter::Impl::ElementMeta &meta)\n{\n\tspv::BuiltIn builtin;\n\tif (impl.spirv_module.query_builtin_shader_input(meta.id, &builtin) && builtin == spv::BuiltInFrontFacing)\n\t\treturn impl.builder().makeBoolType();\n\telse\n\t\treturn impl.get_effective_input_output_type_id(meta.component_type);\n}\n\nstatic bool emit_amd_bary_coord_load(Converter::Impl &impl, const llvm::CallInst *instruction, spv::Id var_id)\n{\n\tauto &builder = impl.builder();\n\n\tuint32_t col = 0;\n\tif (!get_constant_operand(instruction, 3, &col) || col > 2)\n\t{\n\t\tLOGE(\"Bary coord index must be constant {0, 1, 2}.\\n\");\n\t\treturn false;\n\t}\n\n\t/* Need to swizzle the bary coord appropriately. */\n\tauto *bary = impl.allocate(spv::OpLoad, builder.makeVectorType(builder.makeFloatType(32), 2));\n\tbary->add_id(var_id);\n\timpl.add(bary);\n\n\tif (col >= 1)\n\t{\n\t\tauto *ext = impl.allocate(spv::OpCompositeExtract, instruction);\n\t\text->add_id(bary->id);\n\t\text->add_literal(col - 1);\n\t\timpl.add(ext);\n\t}\n\telse\n\t{\n\t\tauto *bary_i = impl.allocate(spv::OpCompositeExtract, builder.makeFloatType(32));\n\t\tbary_i->add_id(bary->id);\n\t\tbary_i->add_literal(0);\n\t\timpl.add(bary_i);\n\n\t\tauto *bary_j = impl.allocate(spv::OpCompositeExtract, builder.makeFloatType(32));\n\t\tbary_j->add_id(bary->id);\n\t\tbary_j->add_literal(1);\n\t\timpl.add(bary_j);\n\n\t\tauto *sub_i = impl.allocate(spv::OpFSub, builder.makeFloatType(32));\n\t\tsub_i->add_id(builder.makeFloatConstant(1.0f));\n\t\tsub_i->add_id(bary_i->id);\n\t\timpl.add(sub_i);\n\n\t\tauto *sub_j = impl.allocate(spv::OpFSub, instruction);\n\t\tsub_j->add_id(sub_i->id);\n\t\tsub_j->add_id(bary_j->id);\n\t\timpl.add(sub_j);\n\t}\n\n\treturn true;\n}\n\nbool emit_load_input_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool spirv_semantics)\n{\n\tauto &builder = impl.builder();\n\tuint32_t input_element_index;\n\tif (!get_constant_operand(instruction, 1, &input_element_index))\n\t\treturn false;\n\n\t// Need special handling for clip distance.\n\tauto *clip_cull_meta = input_clip_cull_distance_meta(impl, input_element_index);\n\tif (clip_cull_meta)\n\t\treturn emit_load_clip_cull_distance(impl, instruction, *clip_cull_meta);\n\n\tconst auto &meta = impl.input_elements_meta[input_element_index];\n\tuint32_t var_id = meta.id;\n\tuint32_t ptr_id;\n\n\tif (impl.options.quirks.ignore_primitive_shading_rate && meta.semantic == DXIL::Semantic::ShadingRate)\n\t{\n\t\timpl.rewrite_value(instruction, builder.makeUintConstant(0));\n\t\treturn true;\n\t}\n\telse if ((meta.semantic == DXIL::Semantic::Barycentrics ||\n\t          meta.semantic == DXIL::Semantic::InternalBarycentricsNoPerspective) &&\n\t         !impl.options.khr_barycentrics_enabled)\n\t{\n\t\treturn emit_amd_bary_coord_load(impl, instruction, var_id);\n\t}\n\n\tspv::Id input_type_id = builder.getDerefTypeId(var_id);\n\n\tbool array_index = false;\n\n\t// Deal with custom IR routing through this function.\n\t// In plain DXIL, this check is not necessary.\n\tif (builder.isArrayType(input_type_id))\n\t{\n\t\tif (impl.execution_model == spv::ExecutionModelTessellationControl ||\n\t\t    impl.execution_model == spv::ExecutionModelGeometry ||\n\t\t    impl.execution_model == spv::ExecutionModelTessellationEvaluation ||\n\t\t    (impl.llvm_attribute_at_vertex_indices.count(input_element_index) != 0 &&\n\t\t     impl.options.khr_barycentrics_enabled))\n\t\t{\n\t\t\tinput_type_id = builder.getContainedTypeId(input_type_id);\n\t\t\tarray_index = true;\n\t\t}\n\t}\n\n\tbool row_index = false;\n\tif (builder.isArrayType(input_type_id))\n\t{\n\t\trow_index = true;\n\t\tinput_type_id = builder.getContainedTypeId(input_type_id);\n\t}\n\n\tuint32_t num_cols = builder.getNumTypeComponents(input_type_id);\n\n\tif (num_cols > 1 || row_index || array_index)\n\t{\n\t\t// Need to deal with signed vs unsigned here.\n\t\tOperation *op =\n\t\t\timpl.allocate(spv::OpAccessChain,\n\t\t\t              builder.makePointer(spv::StorageClassInput,\n\t\t\t                                  impl.get_effective_input_output_type_id(meta.component_type)));\n\t\tptr_id = op->id;\n\n\t\top->add_id(var_id);\n\t\t// Vertex array index for GS/DS/HS or barycentrics.\n\t\tif (array_index)\n\t\t{\n\t\t\tauto *index = instruction->getOperand(4);\n\t\t\tif (llvm::isa<llvm::UndefValue>(index))\n\t\t\t{\n\t\t\t\t// If we loadInput on a barycentric input, we get nointerpolation,\n\t\t\t\t// i.e. flat, i.e. provoking vertex, i.e. vertex 0.\n\t\t\t\top->add_id(builder.makeUintConstant(0));\n\t\t\t}\n\t\t\telse\n\t\t\t\top->add_id(impl.get_id_for_value(index));\n\t\t}\n\t\tif (row_index)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\tif (num_cols > 1)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(3), 32));\n\n\t\timpl.add(op);\n\t}\n\telse\n\t\tptr_id = var_id;\n\n\t// Need to deal with signed vs unsigned here.\n\tspv::Id load_type = get_builtin_load_type(impl, meta);\n\n\tif (impl.llvm_attribute_at_vertex_indices.count(input_element_index) != 0 &&\n\t\t!impl.options.khr_barycentrics_enabled)\n\t{\n\t\tbuilder.addCapability(spv::CapabilityInterpolationFunction);\n\t\tconstexpr uint32_t InterpolateAtVertexAMD = 1;\n\t\tspv::Id ext_id = builder.import(\"SPV_AMD_shader_explicit_vertex_parameter\");\n\t\tauto *op = impl.allocate(spv::OpExtInst, instruction, load_type);\n\t\top->add_id(ext_id);\n\t\top->add_literal(InterpolateAtVertexAMD);\n\t\top->add_id(ptr_id);\n\n\t\tuint32_t vid = 0;\n\t\tif (!llvm::isa<llvm::UndefValue>(instruction->getOperand(4)) &&\n\t\t    (!get_constant_operand(instruction, 4, &vid) || vid > 2))\n\t\t{\n\t\t\tLOGE(\"InterpolateAtVertexAMD only takes constant vid {0, 1, 2}.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\top->add_id(builder.makeUintConstant(vid));\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\tauto *op = impl.allocate(spv::OpLoad, instruction, load_type);\n\t\top->add_id(ptr_id);\n\t\timpl.add(op);\n\t}\n\n\tfixup_builtin_load(impl, var_id, instruction, spirv_semantics);\n\n\t// Need to bitcast after we load.\n\timpl.fixup_load_type_io(meta.component_type, 1, instruction);\n\treturn true;\n}\n\nstatic spv::Id build_attribute_offset(spv::Id id, Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\t{\n\t\tOperation *op = impl.allocate(spv::OpBitFieldSExtract, builder.makeUintType(32));\n\t\top->add_id(id);\n\t\top->add_id(builder.makeUintConstant(0));\n\t\top->add_id(builder.makeUintConstant(4));\n\t\tid = op->id;\n\t\timpl.add(op);\n\t}\n\n\t{\n\t\tOperation *op = impl.allocate(spv::OpConvertSToF, builder.makeFloatType(32));\n\t\top->add_id(id);\n\t\tid = op->id;\n\t\timpl.add(op);\n\t}\n\n\t{\n\t\tOperation *op = impl.allocate(spv::OpFMul, builder.makeFloatType(32));\n\t\top->add_ids({ id, builder.makeFloatConstant(1.0f / 16.0f) });\n\t\tid = op->id;\n\t\timpl.add(op);\n\t}\n\n\treturn id;\n}\n\nbool emit_interpolate_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction, bool extended)\n{\n\tauto &builder = impl.builder();\n\tuint32_t input_element_index;\n\tif (!get_constant_operand(instruction, 1, &input_element_index))\n\t\treturn false;\n\n\tconst auto &meta = impl.input_elements_meta[input_element_index];\n\tuint32_t var_id = meta.id;\n\tuint32_t ptr_id;\n\n\tspv::Id input_type_id = builder.getDerefTypeId(var_id);\n\n\tbool row_index = false;\n\tif (builder.isArrayType(input_type_id))\n\t{\n\t\trow_index = true;\n\t\tinput_type_id = builder.getContainedTypeId(input_type_id);\n\t}\n\n\tuint32_t num_cols = builder.getNumTypeComponents(input_type_id);\n\n\tif (num_cols > 1 || row_index)\n\t{\n\t\t// Need to deal with signed vs unsigned here.\n\t\tOperation *op =\n\t\t\timpl.allocate(spv::OpAccessChain,\n\t\t\t              builder.makePointer(spv::StorageClassInput,\n\t\t\t                                  impl.get_effective_input_output_type_id(meta.component_type)));\n\n\t\top->add_id(var_id);\n\n\t\tif (row_index)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\tif (num_cols > 1)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(3), 32));\n\n\t\timpl.add(op);\n\t\tptr_id = op->id;\n\t}\n\telse\n\t\tptr_id = var_id;\n\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tspv::Id aux_id = 0;\n\n\tif (opcode == GLSLstd450InterpolateAtOffset && !extended)\n\t{\n\t\tspv::Id offsets[2] = {};\n\t\tbool is_non_const = false;\n\t\tfor (unsigned i = 0; i < 2; i++)\n\t\t{\n\t\t\tauto *operand = instruction->getOperand(4 + i);\n\t\t\tauto *constant_operand = llvm::dyn_cast<llvm::ConstantInt>(operand);\n\n\t\t\t// Need to do it the tedious way, extracting bits and converting to float ...\n\t\t\tif (!constant_operand)\n\t\t\t{\n\t\t\t\toffsets[i] = impl.get_id_for_value(instruction->getOperand(4 + i));\n\t\t\t\toffsets[i] = build_attribute_offset(offsets[i], impl);\n\t\t\t\tis_non_const = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfloat off = float(constant_operand->getUniqueInteger().getSExtValue()) / 16.0f;\n\t\t\t\toffsets[i] = builder.makeFloatConstant(off);\n\t\t\t}\n\t\t}\n\n\t\tif (is_non_const)\n\t\t\taux_id = impl.build_vector(builder.makeFloatType(32), offsets, 2);\n\t\telse\n\t\t\taux_id = impl.build_constant_vector(builder.makeFloatType(32), offsets, 2);\n\t}\n\telse if (opcode == GLSLstd450InterpolateAtSample || opcode == GLSLstd450InterpolateAtOffset)\n\t\taux_id = impl.get_id_for_value(instruction->getOperand(4));\n\n\t// Need to deal with signed vs unsigned here.\n\tOperation *op = impl.allocate(spv::OpExtInst, instruction,\n\t                              impl.get_effective_input_output_type_id(meta.component_type));\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(opcode);\n\top->add_id(ptr_id);\n\n\tif (aux_id)\n\t\top->add_id(aux_id);\n\n\timpl.add(op);\n\n\t// Need to bitcast after we load.\n\timpl.fixup_load_type_io(meta.component_type, 1, instruction);\n\tbuilder.addCapability(spv::CapabilityInterpolationFunction);\n\treturn true;\n}\n\nbool emit_store_output_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tuint32_t output_element_index;\n\tif (!get_constant_operand(instruction, 1, &output_element_index))\n\t\treturn false;\n\n\t// Need special handling for clip distance.\n\tauto *clip_cull_meta = output_clip_cull_distance_meta(impl, output_element_index);\n\tif (clip_cull_meta)\n\t\treturn emit_store_clip_cull_distance(impl, instruction, *clip_cull_meta);\n\n\tif (impl.options.dual_source_blending)\n\t{\n\t\t// Mask out writes to unused higher RTs when using dual source blending.\n\t\tif (impl.output_elements_meta.count(output_element_index) == 0)\n\t\t\treturn true;\n\t}\n\n\tconst auto &meta = impl.output_elements_meta[output_element_index];\n\n\tuint32_t var_id = meta.id;\n\tuint32_t ptr_id;\n\n\tspv::Id output_type_id = builder.getDerefTypeId(var_id);\n\tbool is_control_point_output = impl.execution_model == spv::ExecutionModelTessellationControl;\n\tif (is_control_point_output)\n\t\toutput_type_id = builder.getContainedTypeId(output_type_id);\n\n\tbool row_index = false;\n\tif (builder.isArrayType(output_type_id))\n\t{\n\t\trow_index = true;\n\t\toutput_type_id = builder.getContainedTypeId(output_type_id);\n\t}\n\tuint32_t num_cols = builder.getNumTypeComponents(output_type_id);\n\n\tif (num_cols > 1 || row_index || is_control_point_output)\n\t{\n\t\tOperation *op = impl.allocate(\n\t\t    spv::OpAccessChain, builder.makePointer(spv::StorageClassOutput, builder.getScalarTypeId(output_type_id)));\n\t\tptr_id = op->id;\n\n\t\top->add_id(var_id);\n\t\tif (is_control_point_output)\n\t\t\top->add_id(build_load_invocation_id(impl));\n\n\t\tif (row_index)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\n\t\tif (num_cols > 1)\n\t\t{\n\t\t\tunsigned col;\n\t\t\tif (!get_constant_operand(instruction, 3, &col))\n\t\t\t{\n\t\t\t\tLOGE(\"Column index to StoreOutput must be a constant.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// If we need to swizzle fragment shader outputs, do it here.\n\t\t\tif (impl.execution_model == spv::ExecutionModelFragment &&\n\t\t\t    meta.semantic_offset < impl.options.output_swizzles.size())\n\t\t\t{\n\t\t\t\t// Assume a 1:1 reversible mapping, so we don't need to splat the write or something like that.\n\t\t\t\tunsigned swiz = impl.options.output_swizzles[meta.semantic_offset];\n\t\t\t\tfor (unsigned output_component = 0; output_component < 4; output_component++)\n\t\t\t\t{\n\t\t\t\t\tif (((swiz >> (2u * output_component)) & 3u) == col)\n\t\t\t\t\t{\n\t\t\t\t\t\tcol = output_component;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\top->add_id(builder.makeUintConstant(col));\n\t\t}\n\n\t\timpl.add(op);\n\t}\n\telse\n\t\tptr_id = var_id;\n\n\timpl.register_externally_visible_write(instruction->getOperand(4));\n\tspv::Id store_value = impl.get_id_for_value(instruction->getOperand(4));\n\n\tif (impl.options.multiview.enable && impl.options.multiview.last_pre_rasterization_stage)\n\t{\n\t\tif (meta.semantic == DXIL::Semantic::RenderTargetArrayIndex)\n\t\t{\n\t\t\tauto *add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\tadd->add_id(store_value);\n\t\t\tadd->add_id(build_layer_offset_id(impl));\n\t\t\timpl.add(add);\n\n\t\t\tstore_value = add->id;\n\t\t}\n\t\telse if (meta.semantic == DXIL::Semantic::ViewPortArrayIndex &&\n\t\t         impl.options.multiview.view_instance_to_viewport_spec_id != UINT32_MAX)\n\t\t{\n\t\t\tauto *add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\tadd->add_id(store_value);\n\t\t\tadd->add_id(build_viewport_offset_id(impl));\n\t\t\timpl.add(add);\n\n\t\t\tstore_value = add->id;\n\t\t}\n\t}\n\n\tOperation *op = impl.allocate(spv::OpStore);\n\top->add_ids({ ptr_id, impl.fixup_store_type_io(meta.component_type, 1, store_value) });\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_load_draw_parameter_instruction(spv::BuiltIn builtin, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(builtin);\n\n\tOperation *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\timpl.add(op);\n\n\tbuilder.addCapability(spv::CapabilityDrawParameters);\n\treturn true;\n}\n\nbool emit_load_control_point_count_in(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInPatchVertices);\n\tOperation *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\timpl.add(op);\n\treturn true;\n}\n\nstatic spv::Id build_bindless_heap_offset(Converter::Impl &impl,\n                                          spv::Id table_index_id,\n                                          uint32_t base_offset,\n                                          const llvm::Value *dynamic_offset)\n{\n\tauto &builder = impl.builder();\n\n\tif (base_offset != 0 && dynamic_offset)\n\t{\n\t\t// Try to constant fold the offsets.\n\t\t// Works around some driver issues in some cases and makes the code neater.\n\t\t// It's very common for bindless to get counteracting - and + here, turning base_offset into 0 ...\n\t\tif (const auto *bin_op = llvm::dyn_cast<llvm::BinaryOperator>(dynamic_offset))\n\t\t{\n\t\t\tif (bin_op->getOpcode() == llvm::BinaryOperator::BinaryOps::Add)\n\t\t\t{\n\t\t\t\tauto *a = bin_op->getOperand(0);\n\t\t\t\tauto *b = bin_op->getOperand(1);\n\t\t\t\tif (const auto *a_const = llvm::dyn_cast<llvm::ConstantInt>(a))\n\t\t\t\t{\n\t\t\t\t\tbase_offset += uint32_t(a_const->getUniqueInteger().getZExtValue());\n\t\t\t\t\tdynamic_offset = b;\n\t\t\t\t}\n\t\t\t\telse if (const auto *b_const = llvm::dyn_cast<llvm::ConstantInt>(b))\n\t\t\t\t{\n\t\t\t\t\tbase_offset += uint32_t(b_const->getUniqueInteger().getZExtValue());\n\t\t\t\t\tdynamic_offset = a;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (const auto *cint = llvm::dyn_cast<llvm::ConstantInt>(dynamic_offset))\n\t\t{\n\t\t\tbase_offset += uint32_t(cint->getUniqueInteger().getZExtValue());\n\t\t\tdynamic_offset = nullptr;\n\t\t}\n\t}\n\n\tif (base_offset != 0)\n\t{\n\t\tif (table_index_id)\n\t\t{\n\t\t\tauto *heap_offset = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\theap_offset->add_id(table_index_id);\n\t\t\theap_offset->add_id(builder.makeUintConstant(base_offset));\n\t\t\timpl.add(heap_offset);\n\t\t\ttable_index_id = heap_offset->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttable_index_id = builder.makeUintConstant(base_offset);\n\t\t}\n\t}\n\n\tif (dynamic_offset)\n\t{\n\t\tif (table_index_id)\n\t\t{\n\t\t\tauto *offset = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\toffset->add_id(table_index_id);\n\t\t\toffset->add_id(impl.get_id_for_value(dynamic_offset));\n\t\t\timpl.add(offset);\n\t\t\ttable_index_id = offset->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttable_index_id = impl.get_id_for_value(dynamic_offset);\n\t\t}\n\t}\n\n\tif (!table_index_id)\n\t\ttable_index_id = builder.makeUintConstant(0);\n\n\treturn table_index_id;\n}\n\nstatic spv::Id build_adjusted_descriptor_indexing(Converter::Impl &impl,\n                                                  uint32_t base_offset,\n                                                  const llvm::Value *dynamic_offset)\n{\n\treturn build_bindless_heap_offset(impl, 0, base_offset, dynamic_offset);\n}\n\nstatic spv::Id build_bindless_heap_offset_shader_record(Converter::Impl &impl, const Converter::Impl::ResourceReference &reference,\n                                                        const llvm::Value *dynamic_offset)\n{\n\tauto &builder = impl.builder();\n\n\tOperation *descriptor_table;\n\n\tif (impl.node_input.node_dispatch_push_id)\n\t{\n\t\t// Nodes\n\t\tspv::Id shader_record_buffer_id = emit_load_node_input_push_parameter(\n\t\t    impl, NodeLocalRootSignatureBDA,\n\t\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer,\n\t\t                        impl.node_input.shader_record_block_type_id));\n\n\t\tdescriptor_table = impl.allocate(\n\t\t\tspv::OpAccessChain, builder.makePointer(spv::StorageClassPhysicalStorageBuffer, builder.makeUintType(32)));\n\t\tdescriptor_table->add_id(shader_record_buffer_id);\n\t}\n\telse\n\t{\n\t\tdescriptor_table = impl.allocate(\n\t\t    spv::OpAccessChain, builder.makePointer(spv::StorageClassShaderRecordBufferKHR, builder.makeUintType(32)));\n\t\tdescriptor_table->add_id(impl.shader_record_buffer_id);\n\t}\n\n\tdescriptor_table->add_id(builder.makeUintConstant(reference.local_root_signature_entry));\n\tdescriptor_table->add_id(builder.makeUintConstant(0));\n\timpl.add(descriptor_table);\n\n\tauto *loaded_word = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\tloaded_word->add_id(descriptor_table->id);\n\tif (impl.node_input.node_dispatch_push_id)\n\t{\n\t\tloaded_word->add_literal(spv::MemoryAccessAlignedMask);\n\t\tloaded_word->add_literal(8);\n\t}\n\timpl.add(loaded_word);\n\n\tauto *shifted_word = impl.allocate(spv::OpShiftRightLogical, builder.makeUintType(32));\n\tshifted_word->add_id(loaded_word->id);\n\n\t// Need to translate fake GPU VA to index.\n\tunsigned shamt = reference.resource_kind == DXIL::ResourceKind::Sampler ?\n\t    impl.options.sbt_descriptor_size_sampler_log2 : impl.options.sbt_descriptor_size_srv_uav_cbv_log2;\n\tshifted_word->add_id(builder.makeUintConstant(shamt));\n\timpl.add(shifted_word);\n\tloaded_word = shifted_word;\n\n\treturn build_bindless_heap_offset(impl, loaded_word->id, reference.base_offset, dynamic_offset);\n}\n\nstatic spv::Id build_bindless_heap_offset_push_constant(Converter::Impl &impl, const Converter::Impl::ResourceReference &reference,\n                                                        const llvm::Value *dynamic_offset)\n{\n\tauto &builder = impl.builder();\n\tif (reference.push_constant_member >= (impl.root_constant_num_words + impl.root_descriptor_count) ||\n\t    reference.push_constant_member < impl.root_descriptor_count ||\n\t    impl.root_constant_id == 0)\n\t{\n\t\tLOGE(\"Descriptor table offset is out of push constant range.\\n\");\n\t\treturn 0;\n\t}\n\n\tauto *descriptor_table = impl.allocate(\n\t\tspv::OpAccessChain,\n\t\tbuilder.makePointer(impl.options.inline_ubo_enable ? spv::StorageClassUniform : spv::StorageClassPushConstant,\n\t\t                    builder.makeUintType(32)));\n\tdescriptor_table->add_id(impl.root_constant_id);\n\n\tif (impl.root_constant_arrayed)\n\t{\n\t\tdescriptor_table->add_id(builder.makeUintConstant(impl.root_descriptor_count));\n\t\tdescriptor_table->add_id(builder.makeUintConstant(reference.push_constant_member - impl.root_descriptor_count));\n\t}\n\telse\n\t{\n\t\tdescriptor_table->add_id(builder.makeUintConstant(reference.push_constant_member));\n\t}\n\n\timpl.add(descriptor_table);\n\n\tauto *loaded_word = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\tloaded_word->add_id(descriptor_table->id);\n\timpl.add(loaded_word);\n\n\treturn build_bindless_heap_offset(impl, loaded_word->id, reference.base_offset, dynamic_offset);\n}\n\nstatic spv::Id build_descriptor_qa_check(Converter::Impl &impl, spv::Id offset_id,\n                                         DescriptorQATypeFlags type)\n{\n\t// Only implemented for CBV_SRV_UAV heap.\n\tif (type == DESCRIPTOR_QA_TYPE_SAMPLER_BIT)\n\t\treturn offset_id;\n\n\tif (impl.options.descriptor_qa.version != Version)\n\t{\n\t\tLOGE(\"Descriptor QA version is not %u.\\n\", Version);\n\t\treturn offset_id;\n\t}\n\n\tauto &builder = impl.builder();\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, builder.makeUintType(32));\n\tcall_op->add_id(impl.spirv_module.get_helper_call_id(HelperCall::DescriptorQACheck));\n\tcall_op->add_id(offset_id);\n\tcall_op->add_id(builder.makeUintConstant(type));\n\tcall_op->add_id(builder.makeUintConstant(++impl.descriptor_qa_counter));\n\timpl.add(call_op);\n\treturn call_op->id;\n}\n\nstatic spv::Id build_descriptor_heap_robustness(Converter::Impl &impl, spv::Id offset_id)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id size_id;\n\n\tif (impl.instrumentation.descriptor_heap_size_var_id)\n\t{\n\t\tauto *chain = impl.allocate(spv::OpAccessChain,\n\t\t                            builder.makePointer(spv::StorageClassUniform, builder.makeUintType(32)));\n\t\tchain->add_id(impl.instrumentation.descriptor_heap_size_var_id);\n\t\tchain->add_id(builder.makeUintConstant(0));\n\t\timpl.add(chain);\n\n\t\tauto *load = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\tload->add_id(chain->id);\n\t\timpl.add(load);\n\n\t\tsize_id = load->id;\n\t}\n\telse\n\t{\n\t\tauto *op = impl.allocate(spv::OpArrayLength, builder.makeUintType(32));\n\t\top->add_id(impl.instrumentation.descriptor_heap_introspection_var_id);\n\t\top->add_literal(0);\n\t\timpl.add(op);\n\n\t\tsize_id = op->id;\n\t}\n\n    if (impl.options.instruction_instrumentation.enabled &&\n            impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume)\n    {\n        // If we can just assert instead, go for that.\n        auto *less_than = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n        less_than->add_id(offset_id);\n        less_than->add_id(size_id);\n        impl.add(less_than);\n\n        auto *assert_in_bounds = impl.allocate(spv::OpAssumeTrueKHR);\n        assert_in_bounds->add_id(less_than->id);\n        impl.add(assert_in_bounds);\n    }\n\n    if (impl.options.descriptor_heap_robustness)\n    {\n        if (!impl.glsl_std450_ext)\n            impl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n        auto *clamp_op = impl.allocate(spv::OpExtInst, builder.makeUintType(32));\n        clamp_op->add_id(impl.glsl_std450_ext);\n        clamp_op->add_literal(GLSLstd450UMin);\n        clamp_op->add_id(offset_id);\n        clamp_op->add_id(size_id);\n        impl.add(clamp_op);\n        return clamp_op->id;\n    }\n\n    return offset_id;\n}\n\nstatic spv::Id build_bindless_heap_offset(Converter::Impl &impl,\n                                          const Converter::Impl::ResourceReference &reference,\n                                          DescriptorQATypeFlags type,\n                                          const llvm::Value *dynamic_offset)\n{\n\tspv::Id offset_id;\n\tif (reference.local_root_signature_entry >= 0)\n\t\toffset_id = build_bindless_heap_offset_shader_record(impl, reference, dynamic_offset);\n\telse if (reference.push_constant_member != UINT32_MAX)\n\t\toffset_id = build_bindless_heap_offset_push_constant(impl, reference, dynamic_offset);\n\telse\n\t{\n\t\tif (reference.base_offset != 0)\n\t\t{\n\t\t\tLOGE(\"For SM 6.6 heaps, no constant offset can be applied.\\n\");\n\t\t\treturn 0;\n\t\t}\n\t\toffset_id = impl.get_id_for_value(dynamic_offset);\n\t}\n\n\tbool need_heap_robustness_check =\n\t    impl.options.descriptor_heap_robustness ||\n\t    (impl.options.instruction_instrumentation.enabled &&\n\t     impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume);\n\n\tif (impl.options.descriptor_qa_enabled)\n\t{\n\t\toffset_id = build_descriptor_qa_check(impl, offset_id, type);\n\t}\n\telse if (need_heap_robustness_check && type != DESCRIPTOR_QA_TYPE_SAMPLER_BIT && dynamic_offset &&\n\t         (impl.instrumentation.descriptor_heap_introspection_var_id ||\n\t          impl.instrumentation.descriptor_heap_size_var_id))\n\t{\n\t\toffset_id = build_descriptor_heap_robustness(impl, offset_id);\n\t}\n\n\treturn offset_id;\n}\n\nstatic spv::Id build_physical_address_indexing_from_ssbo(Converter::Impl &impl, spv::Id offset_id)\n{\n\tauto &builder = impl.builder();\n\n\tif (impl.options.physical_address_descriptor_stride != 1)\n\t{\n\t\tauto *mul_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tmul_op->add_id(builder.makeUintConstant(impl.options.physical_address_descriptor_stride));\n\t\tmul_op->add_id(offset_id);\n\t\timpl.add(mul_op);\n\t\toffset_id = mul_op->id;\n\t}\n\n\tif (impl.options.physical_address_descriptor_offset != 0)\n\t{\n\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd_op->add_id(offset_id);\n\t\tadd_op->add_id(builder.makeUintConstant(impl.options.physical_address_descriptor_offset));\n\t\timpl.add(add_op);\n\t\toffset_id = add_op->id;\n\t}\n\n\treturn offset_id;\n}\n\nstatic spv::Id build_load_physical_uav_counter(Converter::Impl &impl, const Converter::Impl::ResourceReference &counter,\n                                               const llvm::Value *offset, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\tspv::Id ptr_id;\n\n\tif (impl.instrumentation.descriptor_heap_introspection_var_id == counter.var_id)\n\t{\n\t\tif (!impl.instrumentation.descriptor_heap_introspection_is_bda)\n\t\t{\n\t\t\tLOGE(\"When using introspection variable for UAV counter mapping, it must be BDA based.\\n\");\n\t\t\treturn 0;\n\t\t}\n\n\t\tauto *chain_op =\n\t\t\timpl.allocate(spv::OpAccessChain, builder.makePointer(\n\t\t\t\tspv::StorageClassUniform,\n\t\t\t\timpl.instrumentation.descriptor_heap_introspection_block_ptr_type_id));\n\n\t\tchain_op->add_id(impl.instrumentation.descriptor_heap_introspection_var_id);\n\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\timpl.add(chain_op);\n\n\t\tauto *load_ptr = impl.allocate(\n\t\t    spv::OpLoad, impl.instrumentation.descriptor_heap_introspection_block_ptr_type_id);\n\t\tload_ptr->add_id(chain_op->id);\n\t\timpl.add(load_ptr);\n\n        chain_op = impl.allocate(spv::OpInBoundsAccessChain,\n                builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uvec2_type));\n\t\tchain_op->add_id(load_ptr->id);\n\t\tchain_op->add_id(builder.makeUintConstant(0));\n\n\t\tspv::Id offset_id = build_bindless_heap_offset(impl, counter, DESCRIPTOR_QA_TYPE_RAW_VA_BIT,\n\t\t                                               counter.base_resource_is_array ? offset : nullptr);\n\t\tchain_op->add_id(offset_id);\n\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\tchain_op->add_id(builder.makeUintConstant(impl.options.physical_address_descriptor_offset));\n\t\timpl.add(chain_op);\n\n\t\tptr_id = chain_op->id;\n\t}\n\telse\n\t{\n\t\tauto *chain_op =\n\t\t    impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassStorageBuffer, uvec2_type));\n\t\tchain_op->add_id(counter.var_id);\n\t\tchain_op->add_id(builder.makeUintConstant(0));\n\n\t\tspv::Id offset_id = build_bindless_heap_offset(impl, counter, DESCRIPTOR_QA_TYPE_RAW_VA_BIT,\n\t\t                                               counter.base_resource_is_array ? offset : nullptr);\n\t\toffset_id = build_physical_address_indexing_from_ssbo(impl, offset_id);\n\n\t\tchain_op->add_id(offset_id);\n\t\timpl.add(chain_op);\n\n\t\tptr_id = chain_op->id;\n\t}\n\n\tauto *load_op = impl.allocate(spv::OpLoad, uvec2_type);\n\tload_op->add_id(ptr_id);\n\n\tif (impl.instrumentation.descriptor_heap_introspection_var_id == counter.var_id)\n\t{\n\t\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\t\tload_op->add_literal(8);\n\t}\n\n\timpl.add(load_op);\n\treturn load_op->id;\n}\n\nstatic spv::StorageClass get_resource_storage_class(Converter::Impl &impl, spv::Id base_resource_id)\n{\n\tauto meta_itr = impl.handle_to_resource_meta.find(base_resource_id);\n\tauto storage = spv::StorageClassUniformConstant;\n\tif (meta_itr != impl.handle_to_resource_meta.end())\n\t\tstorage = meta_itr->second.storage;\n\n\treturn storage;\n}\n\nstatic void build_resource_bda_instrumentation(Converter::Impl &impl, spv::Id offset_id,\n                                               Converter::Impl::ResourceMetaInstrumentation &instrumentation)\n{\n\tif (!impl.options.instruction_instrumentation.enabled ||\n\t    impl.options.instruction_instrumentation.type != InstructionInstrumentationType::BufferSynchronizationValidation)\n\t\treturn;\n\n\tif (instrumentation.bda_id != 0 || impl.instrumentation.descriptor_heap_introspection_var_id == 0)\n\t\treturn;\n\n\tauto &builder = impl.builder();\n\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\tauto *chain = impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassStorageBuffer, uvec2_type));\n\tchain->add_id(impl.instrumentation.descriptor_heap_introspection_var_id);\n\tchain->add_id(builder.makeUintConstant(0));\n\tchain->add_id(offset_id);\n\tchain->add_id(builder.makeUintConstant(0));\n\tchain->add_id(builder.makeUintConstant(0));\n\timpl.add(chain);\n\n\tauto *loaded = impl.allocate(spv::OpLoad, uvec2_type);\n\tloaded->add_id(chain->id);\n\timpl.add(loaded);\n\tinstrumentation.bda_id = loaded->id;\n\n\tauto *extract = impl.allocate(spv::OpCompositeExtract, uint_type);\n\textract->add_id(loaded->id);\n\textract->add_literal(1);\n\timpl.add(extract);\n\n\tauto *shifted = impl.allocate(spv::OpShiftRightLogical, uint_type);\n\tshifted->add_id(extract->id);\n\tshifted->add_id(builder.makeUintConstant(16));\n\timpl.add(shifted);\n\n\tinstrumentation.elem_size_id = shifted->id;\n}\n\nstatic spv::Id build_instrumentation_size_query(Converter::Impl &impl,\n                                                spv::Id resource_id, spv::Id type_id,\n                                                const Converter::Impl::ResourceReference &reference,\n                                                spv::StorageClass storage)\n{\n\tauto &builder = impl.builder();\n\tbool is_raw = reference.resource_kind == DXIL::ResourceKind::RawBuffer ||\n\t              reference.resource_kind == DXIL::ResourceKind::StructuredBuffer;\n\n\tif (reference.resource_kind == DXIL::ResourceKind::CBuffer)\n\t{\n\t\t// We cannot query size of a CBV, but those are read-only anyway, and we can assume a 64 KiB limit to\n\t\t// catch blatant OOB.\n\t\treturn builder.makeUintConstant(64 * 1024);\n\t}\n\telse if (reference.resource_kind == DXIL::ResourceKind::TypedBuffer ||\n\t         (is_raw && storage == spv::StorageClassUniformConstant))\n\t{\n\t\tauto *num_elems = impl.allocate(spv::OpImageQuerySize, builder.makeUintType(32));\n\t\tnum_elems->add_id(resource_id);\n\t\timpl.add(num_elems);\n\t\tbuilder.addCapability(spv::CapabilityImageQuery);\n\n\t\tif (is_raw)\n\t\t{\n\t\t\tauto *mul = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tmul->add_id(num_elems->id);\n\t\t\tmul->add_id(builder.makeUintConstant(4));\n\t\t\timpl.add(mul);\n\t\t\treturn mul->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn num_elems->id;\n\t\t}\n\t}\n\telse if (is_raw)\n\t{\n\t\t// This is a little questionable for unaligned vectors like vec3, but it'll be good enough in practice.\n\t\tauto *array_len = impl.allocate(spv::OpArrayLength, builder.makeUintType(32));\n\t\tarray_len->add_id(resource_id);\n\t\tarray_len->add_literal(0);\n\t\timpl.add(array_len);\n\n\t\tspv::Id member_type_id = builder.getContainedTypeId(builder.getContainedTypeId(type_id, 0));\n\t\tuint32_t vec_size = 1;\n\n\t\tif (!builder.isScalarType(member_type_id))\n\t\t{\n\t\t\tvec_size = builder.getNumTypeComponents(member_type_id);\n\t\t\tmember_type_id = builder.getContainedTypeId(member_type_id);\n\t\t}\n\n\t\tuint32_t scalar_width = builder.getScalarTypeWidth(member_type_id) / 8;\n\n\t\tauto *mul = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tmul->add_id(array_len->id);\n\t\tmul->add_id(builder.makeUintConstant(scalar_width * vec_size));\n\t\timpl.add(mul);\n\n\t\treturn mul->id;\n\t}\n\n\treturn 0;\n}\n\nstatic bool build_load_resource_handle(Converter::Impl &impl, spv::Id base_resource_id,\n                                       const Converter::Impl::ResourceReference &reference,\n                                       DescriptorQATypeFlagBits descriptor_type,\n                                       const llvm::CallInst *instruction,\n                                       llvm::Value *instruction_offset_value, bool instruction_is_non_uniform,\n                                       bool &is_non_uniform,\n                                       spv::Id *ptr_id, spv::Id *value_id, spv::Id *bindless_offset_id,\n                                       Converter::Impl::ResourceMetaInstrumentation *instrumentation)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id resource_id = base_resource_id;\n\tspv::Id type_id = builder.getDerefTypeId(resource_id);\n\n\tauto storage = get_resource_storage_class(impl, base_resource_id);\n\tis_non_uniform = false;\n\n\t// If we index based on SBT, we must assume non-uniform, even for resources\n\t// which are not arrayed, since in theory, the dispatch can process different SBTs concurrently,\n\t// perhaps even within same subgroup, so have to be defensive.\n\tif (reference.local_root_signature_entry >= 0)\n\t\tis_non_uniform = true;\n\n\tif (reference.base_resource_is_array || reference.bindless)\n\t{\n\t\tif (reference.base_resource_is_array && instruction_offset_value && instruction_is_non_uniform)\n\t\t\tis_non_uniform = true;\n\n\t\ttype_id = builder.getContainedTypeId(type_id);\n\t\tOperation *op =\n\t\t    impl.allocate(spv::OpAccessChain, builder.makePointer(storage, type_id));\n\t\top->add_id(resource_id);\n\n\t\tspv::Id offset_id;\n\n\t\tif (reference.bindless)\n\t\t{\n\t\t\toffset_id = build_bindless_heap_offset(\n\t\t\t    impl, reference, descriptor_type, reference.base_resource_is_array ? instruction_offset_value : nullptr);\n\n\t\t\tif (offset_id == 0)\n\t\t\t\treturn false;\n\n\t\t\tif (bindless_offset_id)\n\t\t\t\t*bindless_offset_id = offset_id;\n\n\t\t\tif (instrumentation &&\n\t\t\t    (reference.resource_kind == DXIL::ResourceKind::CBuffer ||\n\t\t\t     reference.resource_kind == DXIL::ResourceKind::StructuredBuffer ||\n\t\t\t     reference.resource_kind == DXIL::ResourceKind::TypedBuffer ||\n\t\t\t     reference.resource_kind == DXIL::ResourceKind::RawBuffer))\n\t\t\t{\n\t\t\t\tbuild_resource_bda_instrumentation(impl, offset_id, *instrumentation);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\toffset_id = build_adjusted_descriptor_indexing(\n\t\t\t\timpl, reference.base_offset,\n\t\t\t\treference.base_resource_is_array ? instruction_offset_value : nullptr);\n\n\t\t\tif (bindless_offset_id)\n\t\t\t\t*bindless_offset_id = 0;\n\t\t}\n\n\t\top->add_id(offset_id);\n\n\t\t// Some compilers require the index to be marked as NonUniformEXT, even if it not required by Vulkan spec.\n\t\t// Avoid SPIR-V validation error if same index is used for multiple resources.\n\t\tif (is_non_uniform && instruction_offset_value)\n\t\t{\n\t\t\tbuilder.addUniqueDecoration(offset_id, spv::DecorationNonUniformEXT);\n\n\t\t\t// Mark this operation as a sink candidate.\n\t\t\t// We have observed some really nasty bugs in the wild where a resource is loaded from,\n\t\t\t// but not actually needed before a branch. That branch will guard invalid usage.\n\t\t\top->flags |= Operation::SinkableBit;\n\t\t}\n\n\t\tif (!is_non_uniform && instruction_offset_value &&\n\t\t    ((reference.resource_kind == DXIL::ResourceKind::CBuffer || impl.options.quirks.aggressive_nonuniform) &&\n\t\t     !impl.backend.skip_non_uniform_promotion &&\n\t\t     value_is_likely_non_uniform(impl, instruction_offset_value)))\n\t\t{\n\t\t\t// Native drivers seems to apply hacks and workarounds to workaround bugged games.\n\t\t\t// Only apply this for bindless CBV for now, unless we opt in to more aggressive checks.\n\t\t\t// I have not been able to prove this effect for other resource types so far.\n\t\t\tis_non_uniform = true;\n\t\t}\n\n\t\tif (impl.options.instruction_instrumentation.enabled &&\n\t\t    impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume &&\n\t\t    !is_non_uniform && reference.base_resource_is_array &&\n\t\t    instruction_offset_value &&\n\t\t    !value_is_statically_wave_uniform(impl, instruction_offset_value))\n\t\t{\n\t\t\t// Assert that the index is wave uniform.\n\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformVote);\n\n\t\t\tauto *is_valid = impl.allocate(spv::OpGroupNonUniformAllEqual, builder.makeBoolType());\n\t\t\tis_valid->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tis_valid->add_id(offset_id);\n\t\t\timpl.add(is_valid);\n\n\t\t\tauto *assert_op = impl.allocate(spv::OpAssumeTrueKHR);\n\t\t\tassert_op->add_id(is_valid->id);\n\t\t\timpl.add(assert_op);\n\t\t}\n\n\t\timpl.add(op);\n\t\tresource_id = op->id;\n\t}\n\n\tif (ptr_id)\n\t\t*ptr_id = resource_id;\n\n\tif (value_id)\n\t{\n\t\tif (storage == spv::StorageClassUniformConstant)\n\t\t{\n\t\t\tOperation *op = impl.allocate(spv::OpLoad, instruction, type_id);\n\t\t\top->add_id(resource_id);\n\t\t\timpl.id_to_type[op->id] = type_id;\n\t\t\timpl.add(op);\n\t\t\tif (is_non_uniform)\n\t\t\t\tbuilder.addDecoration(op->id, spv::DecorationNonUniformEXT);\n\t\t\t*value_id = op->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*value_id = resource_id;\n\t\t\timpl.rewrite_value(instruction, resource_id);\n\n\t\t\t// Generally, we want to add NonUniformEXT after access chain for UBO/SSBO,\n\t\t\t// but there is a special case in non-uniform OpArrayLength, where we will use this pointer\n\t\t\t// directly, so mark it as non-uniform here.\n\t\t\tif (is_non_uniform)\n\t\t\t\tbuilder.addDecoration(resource_id, spv::DecorationNonUniformEXT);\n\t\t}\n\n\t\tif (instrumentation && instrumentation->bda_id && !instrumentation->resource_size_id)\n\t\t\tinstrumentation->resource_size_id = build_instrumentation_size_query(impl, *value_id, type_id, reference, storage);\n\t}\n\n\treturn true;\n}\n\nstatic spv::Id build_shader_record_access_chain(Converter::Impl &impl, unsigned local_root_signature_entry)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id array_type_id = impl.shader_record_buffer_types[local_root_signature_entry];\n\tOperation *access_chain;\n\n\tif (impl.node_input.node_dispatch_push_id)\n\t{\n\t\t// Nodes\n\t\tspv::Id shader_record_buffer_id = emit_load_node_input_push_parameter(\n\t\t\timpl, NodeLocalRootSignatureBDA,\n\t\t\tbuilder.makePointer(spv::StorageClassPhysicalStorageBuffer,\n\t\t\t                    impl.node_input.shader_record_block_type_id));\n\n\t\tspv::Id ptr_array_type_id = builder.makePointer(spv::StorageClassPhysicalStorageBuffer, array_type_id);\n\t\taccess_chain = impl.allocate(spv::OpAccessChain, ptr_array_type_id);\n\t\taccess_chain->add_id(shader_record_buffer_id);\n\t}\n\telse\n\t{\n\t\t// RayTracing with ShaderRecordBufferKHR.\n\t\tspv::Id ptr_array_type_id = builder.makePointer(spv::StorageClassShaderRecordBufferKHR, array_type_id);\n\t\taccess_chain = impl.allocate(spv::OpAccessChain, ptr_array_type_id);\n\t\taccess_chain->add_id(impl.shader_record_buffer_id);\n\t}\n\n\taccess_chain->add_id(builder.makeUintConstant(local_root_signature_entry));\n\timpl.add(access_chain);\n\treturn access_chain->id;\n}\n\nstatic spv::Id build_root_descriptor_access_chain(Converter::Impl &impl, unsigned member_index)\n{\n\tauto &builder = impl.builder();\n\n\tauto storage = impl.options.inline_ubo_enable ? spv::StorageClassUniform : spv::StorageClassPushConstant;\n\n\tspv::Id ptr_type_id = builder.makePointer(storage, builder.makeVectorType(builder.makeUintType(32), 2));\n\tauto *access_chain = impl.allocate(spv::OpAccessChain, ptr_type_id);\n\taccess_chain->add_id(impl.root_constant_id);\n\taccess_chain->add_id(builder.makeUintConstant(member_index));\n\timpl.add(access_chain);\n\n\treturn access_chain->id;\n}\n\nstatic spv::Id build_root_descriptor_load_physical_pointer(Converter::Impl &impl,\n                                                           const Converter::Impl::ResourceReference &reference)\n{\n\tauto &builder = impl.builder();\n\tint local_root_signature_entry = reference.local_root_signature_entry;\n\n\tspv::Id ptr_id;\n\tif (local_root_signature_entry >= 0)\n\t\tptr_id = build_shader_record_access_chain(impl, local_root_signature_entry);\n\telse\n\t\tptr_id = build_root_descriptor_access_chain(impl, reference.push_constant_member);\n\n\tauto *load_ptr = impl.allocate(spv::OpLoad, builder.makeVectorType(builder.makeUintType(32), 2));\n\tload_ptr->add_id(ptr_id);\n\n\tif (local_root_signature_entry >= 0 && impl.node_input.shader_record_block_type_id != 0)\n\t{\n\t\tload_ptr->add_literal(spv::MemoryAccessAlignedMask);\n\t\tload_ptr->add_literal(8);\n\t}\n\n\timpl.add(load_ptr);\n\treturn load_ptr->id;\n}\n\nstatic spv::Id build_load_physical_rtas(Converter::Impl &impl, const Converter::Impl::ResourceReference &reference,\n                                        const llvm::Value *offset, bool non_uniform)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ptr_id;\n\n\tif (builder.getStorageClass(reference.var_id) == spv::StorageClassStorageBuffer)\n\t{\n\t\tspv::Id offset_id = build_bindless_heap_offset(impl, reference,\n\t\t                                               DESCRIPTOR_QA_TYPE_RT_ACCELERATION_STRUCTURE_BIT |\n\t\t                                               DESCRIPTOR_QA_TYPE_RAW_VA_BIT,\n\t\t                                               reference.base_resource_is_array ? offset : nullptr);\n\n\t\tif (!non_uniform)\n\t\t{\n\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t\t\tauto *broadcast_op = impl.allocate(spv::OpGroupNonUniformBroadcastFirst, builder.makeUintType(32));\n\t\t\tbroadcast_op->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tbroadcast_op->add_id(offset_id);\n\t\t\timpl.add(broadcast_op);\n\t\t\toffset_id = broadcast_op->id;\n\t\t}\n\n\t\toffset_id = build_physical_address_indexing_from_ssbo(impl, offset_id);\n\n\t\tspv::Id uvec2_type = builder.makeVectorType(builder.makeUintType(32), 2);\n\t\tauto *chain_op =\n\t\t    impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassStorageBuffer, uvec2_type));\n\t\tchain_op->add_id(reference.var_id);\n\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\tchain_op->add_id(offset_id);\n\t\timpl.add(chain_op);\n\n\t\tauto *load_op = impl.allocate(spv::OpLoad, uvec2_type);\n\t\tload_op->add_id(chain_op->id);\n\t\timpl.add(load_op);\n\t\tptr_id = load_op->id;\n\t}\n\telse\n\t{\n\t\tptr_id = build_root_descriptor_load_physical_pointer(impl, reference);\n\t}\n\n\tauto *convert_op = impl.allocate(spv::OpConvertUToAccelerationStructureKHR, builder.makeAccelerationStructureType());\n\tconvert_op->add_id(ptr_id);\n\timpl.add(convert_op);\n\treturn convert_op->id;\n}\n\nstatic bool resource_is_physical_rtas(Converter::Impl &impl, const Converter::Impl::ResourceReference &reference)\n{\n\tif (reference.resource_kind != DXIL::ResourceKind::RTAccelerationStructure)\n\t\treturn false;\n\n\tbool physical_pointer_heap = impl.builder().getStorageClass(reference.var_id) == spv::StorageClassStorageBuffer;\n\tif (physical_pointer_heap)\n\t\treturn true;\n\n\tif (reference.local_root_signature_entry >= 0)\n\t\treturn impl.local_root_signature[reference.local_root_signature_entry].type == LocalRootSignatureType::Descriptor;\n\telse\n\t\treturn reference.root_descriptor;\n}\n\nstatic bool resource_is_physical_pointer(Converter::Impl &impl, const Converter::Impl::ResourceReference &reference)\n{\n\tif (reference.local_root_signature_entry >= 0)\n\t\treturn impl.local_root_signature[reference.local_root_signature_entry].type == LocalRootSignatureType::Descriptor;\n\telse\n\t\treturn reference.root_descriptor;\n}\n\nstatic spv::Id build_load_buffer_offset(Converter::Impl &impl, Converter::Impl::ResourceReference &reference,\n                                        Converter::Impl::ResourceMeta &meta,\n                                        spv::Id offset_ssbo_id, spv::Id bindless_offset_id, bool non_uniform)\n{\n\tauto &builder = impl.builder();\n\n\tif (!non_uniform)\n\t{\n\t\t// Allow scalar load of the offset if possible.\n\t\tOperation *scalar_op = impl.allocate(spv::OpGroupNonUniformBroadcastFirst, builder.makeUintType(32));\n\t\tscalar_op->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tscalar_op->add_id(bindless_offset_id);\n\t\timpl.add(scalar_op);\n\t\tbindless_offset_id = scalar_op->id;\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t}\n\n\tbool untyped_buffer = meta.storage != spv::StorageClassUniformConstant &&\n\t                      meta.kind != DXIL::ResourceKind::TypedBuffer;\n\tunsigned layout_offset = untyped_buffer ? impl.options.offset_buffer_layout.untyped_offset :\n\t                         impl.options.offset_buffer_layout.typed_offset;\n\n\tif (impl.options.offset_buffer_layout.stride != 1)\n\t{\n\t\tOperation *scale_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tscale_op->add_id(bindless_offset_id);\n\t\tscale_op->add_id(builder.makeUintConstant(impl.options.offset_buffer_layout.stride));\n\t\timpl.add(scale_op);\n\t\tbindless_offset_id = scale_op->id;\n\t}\n\n\tif (layout_offset)\n\t{\n\t\tOperation *bias_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tbias_op->add_id(bindless_offset_id);\n\t\tbias_op->add_id(builder.makeUintConstant(layout_offset));\n\t\timpl.add(bias_op);\n\t\tbindless_offset_id = bias_op->id;\n\t}\n\n\tspv::Id vec_type = builder.makeVectorType(builder.makeUintType(32), 2);\n\n\tOperation *chain_op = impl.allocate(spv::OpAccessChain,\n\t                                    builder.makePointer(spv::StorageClassStorageBuffer,\n\t                                                        vec_type));\n\tchain_op->add_id(offset_ssbo_id);\n\tchain_op->add_id(builder.makeUintConstant(0));\n\tchain_op->add_id(bindless_offset_id);\n\timpl.add(chain_op);\n\n\tOperation *load_op = impl.allocate(spv::OpLoad, vec_type);\n\tload_op->add_id(chain_op->id);\n\timpl.add(load_op);\n\n\tspv::Id offset_id = load_op->id;\n\n\t// Shift the offset buffer once if we can get away with it.\n\tif (untyped_buffer && !reference.aliased)\n\t{\n\t\tOperation *shift_op = impl.allocate(spv::OpShiftRightLogical, vec_type);\n\t\tshift_op->add_id(offset_id);\n\n\t\tunsigned ssbo_element_size =\n\t\t\traw_vecsize_to_vecsize(meta.raw_component_vecsize) *\n\t\t\traw_component_type_to_bits(meta.component_type) / 8;\n\n\t\tunsigned shamt = 0;\n\t\twhile (ssbo_element_size > 1)\n\t\t{\n\t\t\tshamt++;\n\t\t\tssbo_element_size >>= 1;\n\t\t}\n\n\t\tspv::Id const_2[2];\n\t\tconst_2[0] = const_2[1] = builder.makeUintConstant(shamt);\n\t\tspv::Id const_vec = impl.build_constant_vector(builder.makeUintType(32), const_2, 2);\n\n\t\tshift_op->add_id(const_vec);\n\t\timpl.add(shift_op);\n\n\t\toffset_id = shift_op->id;\n\t}\n\n\treturn offset_id;\n}\n\nstatic bool resource_kind_is_buffer(DXIL::ResourceKind kind)\n{\n\tswitch (kind)\n\t{\n\tcase DXIL::ResourceKind::RawBuffer:\n\tcase DXIL::ResourceKind::StructuredBuffer:\n\tcase DXIL::ResourceKind::TypedBuffer:\n\tcase DXIL::ResourceKind::CBuffer:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstatic Converter::Impl::ResourceReference &get_resource_counter_reference(\n\tConverter::Impl &impl, const llvm::CallInst *instruction, unsigned resource_range)\n{\n\tif (resource_range == UINT32_MAX)\n\t\treturn impl.llvm_annotate_handle_uses[instruction].counter_reference;\n\telse\n\t\treturn impl.uav_index_to_counter[resource_range];\n}\n\nstatic Converter::Impl::ResourceReference &get_resource_reference(\n\t\tConverter::Impl &impl, DXIL::ResourceType resource_type,\n\t\tconst llvm::CallInst *instruction, unsigned resource_range)\n{\n\tif (resource_range == UINT32_MAX)\n\t{\n\t\treturn impl.llvm_annotate_handle_uses[instruction].reference;\n\t}\n\telse\n\t{\n\t\tswitch (resource_type)\n\t\t{\n\t\tdefault:\n\t\tcase DXIL::ResourceType::SRV:\n\t\t\treturn impl.srv_index_to_reference[resource_range];\n\t\tcase DXIL::ResourceType::UAV:\n\t\t\treturn impl.uav_index_to_reference[resource_range];\n\t\tcase DXIL::ResourceType::CBV:\n\t\t\treturn impl.cbv_index_to_reference[resource_range];\n\t\tcase DXIL::ResourceType::Sampler:\n\t\t\treturn impl.sampler_index_to_reference[resource_range];\n\t\t}\n\t}\n}\n\nstatic spv::Id get_offset_buffer_variable(\n\t\tConverter::Impl &impl, DXIL::ResourceType resource_type,\n\t\tconst llvm::CallInst *instruction, unsigned resource_range)\n{\n\tif (resource_range == UINT32_MAX)\n\t\treturn impl.llvm_annotate_handle_uses[instruction].offset_buffer_id;\n\telse if (resource_type == DXIL::ResourceType::SRV)\n\t\treturn impl.srv_index_to_offset[resource_range];\n\telse\n\t\treturn impl.uav_index_to_offset[resource_range];\n}\n\nstatic bool emit_create_handle(Converter::Impl &impl, const llvm::CallInst *instruction,\n                               DXIL::ResourceType resource_type, unsigned resource_range,\n                               llvm::Value *instruction_offset, bool non_uniform)\n{\n\tauto &builder = impl.builder();\n\tswitch (resource_type)\n\t{\n\tcase DXIL::ResourceType::SRV:\n\t{\n\t\tauto &reference = get_resource_reference(impl, resource_type, instruction, resource_range);\n\n\t\tif (resource_is_physical_rtas(impl, reference))\n\t\t{\n\t\t\tspv::Id ptr_id = build_load_physical_rtas(impl, reference, instruction_offset, non_uniform);\n\t\t\timpl.rewrite_value(instruction, ptr_id);\n\t\t\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\t\t\tmeta = {};\n\t\t\tmeta.storage = spv::StorageClassGeneric;\n\t\t\tmeta.kind = DXIL::ResourceKind::RTAccelerationStructure;\n\t\t}\n\t\telse if (resource_is_physical_pointer(impl, reference))\n\t\t{\n\t\t\tspv::Id ptr_id = build_root_descriptor_load_physical_pointer(impl, reference);\n\t\t\timpl.rewrite_value(instruction, ptr_id);\n\t\t\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\t\t\tmeta = {};\n\t\t\tmeta.stride = reference.stride;\n\t\t\tmeta.storage = spv::StorageClassPhysicalStorageBuffer;\n\t\t\tmeta.physical_pointer_meta.nonwritable = true;\n\t\t\tmeta.kind = reference.resource_kind;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbool is_non_uniform = false;\n\n\t\t\tspv::Id representative_var_id = reference.var_id;\n\t\t\tif (!representative_var_id && !reference.var_alias_group.empty())\n\t\t\t\trepresentative_var_id = reference.var_alias_group.front().var_id;\n\t\t\tauto storage = get_resource_storage_class(impl, representative_var_id);\n\n\t\t\tDescriptorQATypeFlagBits descriptor_type;\n\t\t\tif (storage == spv::StorageClassStorageBuffer)\n\t\t\t\tdescriptor_type = DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT;\n\t\t\telse if (resource_kind_is_buffer(reference.resource_kind))\n\t\t\t\tdescriptor_type = DESCRIPTOR_QA_TYPE_UNIFORM_TEXEL_BUFFER_BIT;\n\t\t\telse if (reference.resource_kind == DXIL::ResourceKind::RTAccelerationStructure)\n\t\t\t\tdescriptor_type = DESCRIPTOR_QA_TYPE_RT_ACCELERATION_STRUCTURE_BIT;\n\t\t\telse\n\t\t\t\tdescriptor_type = DESCRIPTOR_QA_TYPE_SAMPLED_IMAGE_BIT;\n\n\t\t\tVector<Converter::Impl::RawDeclarationVariable> raw_declarations;\n\t\t\tspv::Id loaded_id = 0;\n\t\t\tspv::Id offset_id = 0;\n\t\t\tspv::Id resource_id = 0;\n\t\t\traw_declarations.reserve(reference.var_alias_group.size());\n\n\t\t\tConverter::Impl::ResourceMetaInstrumentation instrumentation = {};\n\n\t\t\tif (reference.var_id)\n\t\t\t{\n\t\t\t\tresource_id = reference.var_id;\n\t\t\t\tif (!build_load_resource_handle(impl, resource_id, reference, descriptor_type, instruction,\n\t\t\t\t\t\t\t\t\t\t\t\tinstruction_offset, non_uniform, is_non_uniform,\n\t\t\t\t\t\t\t\t\t\t\t\tnullptr, &loaded_id, &offset_id, &instrumentation))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to load SRV resource handle.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (auto &alias : reference.var_alias_group)\n\t\t\t{\n\t\t\t\tresource_id = alias.var_id;\n\t\t\t\tif (!build_load_resource_handle(impl, resource_id, reference, descriptor_type,\n\t\t\t\t\t\t\t\t\t\t\t\tinstruction, instruction_offset, non_uniform, is_non_uniform,\n\t\t\t\t\t\t\t\t\t\t\t\tnullptr, &loaded_id, &offset_id, &instrumentation))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to load SRV resource handle.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\traw_declarations.push_back({ alias.declaration, loaded_id });\n\t\t\t}\n\n\t\t\tauto &incoming_meta = impl.handle_to_resource_meta[resource_id];\n\n\t\t\tspv::Id offset_buffer_id = get_offset_buffer_variable(impl, resource_type, instruction, resource_range);\n\t\t\tif (offset_buffer_id)\n\t\t\t{\n\t\t\t\toffset_id = build_load_buffer_offset(impl, reference, incoming_meta,\n\t\t\t\t                                     offset_buffer_id, offset_id, non_uniform);\n\t\t\t}\n\t\t\telse\n\t\t\t\toffset_id = 0;\n\n\t\t\tauto &meta = impl.handle_to_resource_meta[loaded_id];\n\t\t\tmeta = incoming_meta;\n\t\t\tmeta.non_uniform = is_non_uniform;\n\t\t\tmeta.index_offset_id = offset_id;\n\t\t\tmeta.var_alias_group = std::move(raw_declarations);\n\t\t\tmeta.aliased = reference.aliased;\n\t\t\tmeta.physical_pointer_meta.nonwritable = true;\n\t\t\tmeta.instrumentation = instrumentation;\n\n\t\t\t// The base array variable does not know what the stride is, promote that state here.\n\t\t\tif (reference.bindless)\n\t\t\t\tmeta.stride = reference.stride;\n\n\t\t\tif (is_non_uniform)\n\t\t\t{\n\t\t\t\tspv::Id type_id = builder.getDerefTypeId(resource_id);\n\t\t\t\ttype_id = builder.getContainedTypeId(type_id);\n\n\t\t\t\tif (builder.getTypeClass(type_id) != spv::OpTypeAccelerationStructureKHR)\n\t\t\t\t{\n\t\t\t\t\tif (meta.storage == spv::StorageClassStorageBuffer)\n\t\t\t\t\t\tbuilder.addCapability(spv::CapabilityStorageBufferArrayNonUniformIndexing);\n\t\t\t\t\telse if (builder.getTypeDimensionality(type_id) == spv::DimBuffer)\n\t\t\t\t\t\tbuilder.addCapability(spv::CapabilityUniformTexelBufferArrayNonUniformIndexing);\n\t\t\t\t\telse\n\t\t\t\t\t\tbuilder.addCapability(spv::CapabilitySampledImageArrayNonUniformIndexingEXT);\n\t\t\t\t}\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase DXIL::ResourceType::UAV:\n\t{\n\t\tif (emit_ags_resource_uav_handle(impl, instruction, resource_range))\n\t\t\tbreak;\n\t\tif (emit_nvapi_resource_uav_handle(impl, instruction, resource_range))\n\t\t\tbreak;\n\n\t\tauto &reference = get_resource_reference(impl, resource_type, instruction, resource_range);\n\n\t\tif (resource_is_physical_pointer(impl, reference))\n\t\t{\n\t\t\tspv::Id ptr_id = build_root_descriptor_load_physical_pointer(impl, reference);\n\t\t\timpl.rewrite_value(instruction, ptr_id);\n\t\t\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\t\t\tmeta = {};\n\t\t\tmeta.stride = reference.stride;\n\t\t\tmeta.storage = spv::StorageClassPhysicalStorageBuffer;\n\t\t\tmeta.physical_pointer_meta.coherent = reference.coherent;\n\t\t\tmeta.physical_pointer_meta.rov = reference.rov;\n\t\t\tmeta.kind = reference.resource_kind;\n\t\t\tmeta.rov = reference.rov;\n\t\t\tmeta.vkmm = reference.vkmm;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbool is_non_uniform = false;\n\n\t\t\tspv::Id representative_var_id = reference.var_id;\n\t\t\tif (!representative_var_id && !reference.var_alias_group.empty())\n\t\t\t\trepresentative_var_id = reference.var_alias_group.front().var_id;\n\t\t\tauto storage = get_resource_storage_class(impl, representative_var_id);\n\n\t\t\tDescriptorQATypeFlagBits descriptor_type;\n\t\t\tif (storage == spv::StorageClassStorageBuffer)\n\t\t\t\tdescriptor_type = DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT;\n\t\t\telse if (resource_kind_is_buffer(reference.resource_kind))\n\t\t\t\tdescriptor_type = DESCRIPTOR_QA_TYPE_STORAGE_TEXEL_BUFFER_BIT;\n\t\t\telse\n\t\t\t\tdescriptor_type = DESCRIPTOR_QA_TYPE_STORAGE_IMAGE_BIT;\n\n\t\t\tVector<Converter::Impl::RawDeclarationVariable> raw_declarations;\n\t\t\tspv::Id loaded_id = 0;\n\t\t\tspv::Id offset_id = 0;\n\t\t\tspv::Id resource_id = 0;\n\t\t\tspv::Id resource_ptr_id = 0;\n\t\t\traw_declarations.reserve(reference.var_alias_group.size());\n\n\t\t\tConverter::Impl::ResourceMetaInstrumentation instrumentation = {};\n\n\t\t\tif (reference.var_id)\n\t\t\t{\n\t\t\t\tresource_id = reference.var_id;\n\t\t\t\tif (!build_load_resource_handle(impl, resource_id, reference, descriptor_type, instruction,\n\t\t\t\t                                instruction_offset, non_uniform, is_non_uniform, &resource_ptr_id,\n\t\t\t\t                                &loaded_id, &offset_id, &instrumentation))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to load UAV resource handle.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (auto &alias : reference.var_alias_group)\n\t\t\t{\n\t\t\t\tresource_id = alias.var_id;\n\t\t\t\tif (!build_load_resource_handle(impl, resource_id, reference, descriptor_type,\n\t\t\t\t\t\t\t\t\t\t\t\tinstruction, instruction_offset, non_uniform, is_non_uniform,\n\t\t\t\t\t\t\t\t\t\t\t\tnullptr, &loaded_id, &offset_id, &instrumentation))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to load UAV resource handle.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\traw_declarations.push_back({ alias.declaration, loaded_id });\n\t\t\t}\n\n\t\t\tauto &incoming_meta = impl.handle_to_resource_meta[resource_id];\n\n\t\t\tspv::Id offset_buffer_id = get_offset_buffer_variable(impl, resource_type, instruction, resource_range);\n\t\t\tif (offset_buffer_id)\n\t\t\t{\n\t\t\t\toffset_id = build_load_buffer_offset(impl, reference, incoming_meta,\n\t\t\t\t                                     offset_buffer_id, offset_id, non_uniform);\n\t\t\t}\n\t\t\telse\n\t\t\t\toffset_id = 0;\n\n\t\t\tauto &meta = impl.handle_to_resource_meta[loaded_id];\n\t\t\tmeta = incoming_meta;\n\t\t\tmeta.non_uniform = is_non_uniform;\n\t\t\tmeta.index_offset_id = offset_id;\n\t\t\tmeta.var_alias_group = std::move(raw_declarations);\n\t\t\tmeta.aliased = reference.aliased;\n\t\t\tmeta.rov = reference.rov;\n\t\t\tmeta.vkmm = reference.vkmm;\n\t\t\tmeta.physical_pointer_meta.coherent = reference.coherent;\n\t\t\tmeta.instrumentation = instrumentation;\n\n\t\t\t// Image atomics requires the pointer to image and not OpTypeImage directly.\n\t\t\tmeta.var_id = resource_ptr_id;\n\n\t\t\t// The base array variable does not know what the stride is, promote that state here.\n\t\t\tif (reference.bindless)\n\t\t\t\tmeta.stride = reference.stride;\n\n\t\t\tif (is_non_uniform)\n\t\t\t{\n\t\t\t\tspv::Id type_id = builder.getDerefTypeId(resource_id);\n\t\t\t\ttype_id = builder.getContainedTypeId(type_id);\n\n\t\t\t\tif (meta.storage == spv::StorageClassStorageBuffer)\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityStorageBufferArrayNonUniformIndexing);\n\t\t\t\telse if (builder.getTypeDimensionality(type_id) == spv::DimBuffer)\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityStorageTexelBufferArrayNonUniformIndexing);\n\t\t\t\telse\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexing);\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t}\n\n\t\t\tif (impl.llvm_values_using_update_counter.count(instruction) != 0)\n\t\t\t{\n\t\t\t\tauto &counter_reference = get_resource_counter_reference(impl, instruction, resource_range);\n\t\t\t\tmeta.counter_storage = counter_reference.resource_kind == DXIL::ResourceKind::RawBuffer ?\n\t\t\t\t                       spv::StorageClassStorageBuffer : spv::StorageClassUniformConstant;\n\n\t\t\t\tif (counter_reference.bindless)\n\t\t\t\t{\n\t\t\t\t\tif (counter_reference.resource_kind == DXIL::ResourceKind::Invalid)\n\t\t\t\t\t{\n\t\t\t\t\t\tmeta.counter_var_id =\n\t\t\t\t\t\t    build_load_physical_uav_counter(impl, counter_reference, instruction_offset, instruction);\n\t\t\t\t\t\tmeta.counter_storage = spv::StorageClassPhysicalStorageBuffer;\n\t\t\t\t\t\t// Don't support this since the physical pointer we get from heap is actually the counter.\n\t\t\t\t\t\tmeta.instrumentation = {};\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!build_load_resource_handle(impl, counter_reference.var_id, reference,\n\t\t\t\t\t\t                                DESCRIPTOR_QA_TYPE_RAW_VA_BIT,\n\t\t\t\t\t\t                                instruction, instruction_offset, non_uniform,\n\t\t\t\t\t\t                                is_non_uniform, &meta.counter_var_id, nullptr, nullptr, nullptr))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLOGE(\"Failed to load UAV counter pointer.\\n\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (counter_reference.resource_kind == DXIL::ResourceKind::RawBuffer)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto *chain = impl.allocate(\n\t\t\t\t\t\t\t    spv::OpAccessChain,\n\t\t\t\t\t\t\t    builder.makePointer(spv::StorageClassStorageBuffer, builder.makeUintType(32)));\n\t\t\t\t\t\t\tchain->add_id(meta.counter_var_id);\n\t\t\t\t\t\t\tchain->add_id(builder.makeUintConstant(0));\n\t\t\t\t\t\t\timpl.add(chain);\n\t\t\t\t\t\t\tmeta.counter_var_id = chain->id;\n\t\t\t\t\t\t\tif (meta.non_uniform)\n\t\t\t\t\t\t\t\tbuilder.addDecoration(meta.counter_var_id, spv::DecorationNonUniformEXT);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmeta.counter_var_id = counter_reference.var_id;\n\t\t\t\t\tif (counter_reference.base_resource_is_array)\n\t\t\t\t\t{\n\t\t\t\t\t\toffset_id = build_adjusted_descriptor_indexing(impl, reference.base_offset, instruction_offset);\n\t\t\t\t\t\tif (counter_reference.resource_kind == DXIL::ResourceKind::TypedBuffer)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tspv::Id image_type_id = builder.getContainedTypeId(builder.getDerefTypeId(meta.counter_var_id));\n\t\t\t\t\t\t\tauto *chain = impl.allocate(\n\t\t\t\t\t\t\t\tspv::OpAccessChain,\n\t\t\t\t\t\t\t\tbuilder.makePointer(spv::StorageClassUniformConstant, image_type_id));\n\t\t\t\t\t\t\tchain->add_id(meta.counter_var_id);\n\t\t\t\t\t\t\tchain->add_id(offset_id);\n\t\t\t\t\t\t\timpl.add(chain);\n\t\t\t\t\t\t\tmeta.counter_var_id = chain->id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto *chain = impl.allocate(\n\t\t\t\t\t\t\t    spv::OpAccessChain,\n\t\t\t\t\t\t\t    builder.makePointer(spv::StorageClassStorageBuffer, builder.makeUintType(32)));\n\t\t\t\t\t\t\tchain->add_id(meta.counter_var_id);\n\t\t\t\t\t\t\tchain->add_id(offset_id);\n\t\t\t\t\t\t\tchain->add_id(builder.makeUintConstant(0));\n\t\t\t\t\t\t\timpl.add(chain);\n\t\t\t\t\t\t\tmeta.counter_var_id = chain->id;\n\t\t\t\t\t\t\tif (meta.non_uniform)\n\t\t\t\t\t\t\t\tbuilder.addDecoration(meta.counter_var_id, spv::DecorationNonUniformEXT);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (counter_reference.resource_kind == DXIL::ResourceKind::RawBuffer)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *chain = impl.allocate(\n\t\t\t\t\t\t\tspv::OpAccessChain,\n\t\t\t\t\t\tbuilder.makePointer(spv::StorageClassStorageBuffer, builder.makeUintType(32)));\n\t\t\t\t\t\tchain->add_id(meta.counter_var_id);\n\t\t\t\t\t\tchain->add_id(builder.makeUintConstant(0));\n\t\t\t\t\t\timpl.add(chain);\n\t\t\t\t\t\tmeta.counter_var_id = chain->id;\n\t\t\t\t\t\tif (meta.non_uniform)\n\t\t\t\t\t\t\tbuilder.addDecoration(meta.counter_var_id, spv::DecorationNonUniformEXT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase DXIL::ResourceType::CBV:\n\t{\n\t\tauto &reference = get_resource_reference(impl, resource_type, instruction, resource_range);\n\t\tconst LocalRootSignatureEntry *local_root_signature_entry = nullptr;\n\t\tif (reference.local_root_signature_entry >= 0)\n\t\t\tlocal_root_signature_entry = &impl.local_root_signature[reference.local_root_signature_entry];\n\n\t\t// Special case root constants since these resources point directly to\n\t\t// the push constant block or SBT and not to any concrete resource,\n\t\t// so we cannot deduce storage classes properly.\n\n\t\tif (resource_is_physical_pointer(impl, reference))\n\t\t{\n\t\t\tspv::Id ptr_id = build_root_descriptor_load_physical_pointer(impl, reference);\n\t\t\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\t\t\tmeta = {};\n\t\t\tmeta.stride = reference.stride;\n\t\t\tmeta.storage = spv::StorageClassPhysicalStorageBuffer;\n\t\t\tmeta.physical_pointer_meta.nonwritable = true;\n\t\t\tmeta.kind = reference.resource_kind;\n\t\t\timpl.rewrite_value(instruction, ptr_id);\n\t\t}\n\t\telse if (reference.var_id != 0 && reference.var_id == impl.root_constant_id)\n\t\t{\n\t\t\t// Point directly to root constants.\n\t\t\timpl.rewrite_value(instruction, reference.var_id);\n\t\t\tunsigned member_offset = reference.push_constant_member;\n\t\t\timpl.handle_to_root_member_offset[instruction] = member_offset;\n\t\t}\n\t\telse if (local_root_signature_entry && local_root_signature_entry->type == LocalRootSignatureType::Constants)\n\t\t{\n\t\t\t// Access chain into the desired member once.\n\t\t\tspv::Id id = build_shader_record_access_chain(impl, reference.local_root_signature_entry);\n\n\t\t\tauto &meta = impl.handle_to_resource_meta[id];\n\t\t\tmeta = {};\n\t\t\tmeta.storage = spv::StorageClassShaderRecordBufferKHR;\n\t\t\tmeta.kind = DXIL::ResourceKind::CBuffer;\n\t\t\timpl.handle_to_root_member_offset[instruction] = reference.local_root_signature_entry;\n\t\t\timpl.rewrite_value(instruction, id);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbool is_non_uniform = false;\n\n\t\t\tbool ssbo = reference.bindless && impl.options.bindless_cbv_ssbo_emulation;\n\t\t\tauto storage = ssbo ? spv::StorageClassStorageBuffer : spv::StorageClassUniform;\n\t\t\tauto descriptor_type = ssbo ? DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT : DESCRIPTOR_QA_TYPE_UNIFORM_BUFFER_BIT;\n\n\t\t\tVector<Converter::Impl::RawDeclarationVariable> raw_declarations;\n\t\t\tspv::Id loaded_id = 0;\n\t\t\tspv::Id resource_id = 0;\n\t\t\traw_declarations.reserve(reference.var_alias_group.size());\n\n\t\t\tConverter::Impl::ResourceMetaInstrumentation instrumentation = {};\n\n\t\t\tif (reference.var_id)\n\t\t\t{\n\t\t\t\tresource_id = reference.var_id;\n\t\t\t\tif (!build_load_resource_handle(impl, resource_id, reference, descriptor_type, instruction,\n\t\t\t\t\t\t\t\t\t\t\t\tinstruction_offset, non_uniform, is_non_uniform,\n\t\t\t\t\t\t\t\t\t\t\t\tnullptr, &loaded_id, nullptr, &instrumentation))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to load CBV resource handle.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (auto &alias : reference.var_alias_group)\n\t\t\t{\n\t\t\t\tresource_id = alias.var_id;\n\t\t\t\tif (!build_load_resource_handle(impl, resource_id, reference, descriptor_type,\n\t\t\t\t\t\t\t\t\t\t\t\tinstruction, instruction_offset, non_uniform, is_non_uniform,\n\t\t\t\t\t\t\t\t\t\t\t\tnullptr, &loaded_id, nullptr, &instrumentation))\n\t\t\t\t{\n\t\t\t\t\tLOGE(\"Failed to load CBV resource handle.\\n\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\traw_declarations.push_back({ alias.declaration, loaded_id });\n\t\t\t}\n\n\t\t\tauto &incoming_meta = impl.handle_to_resource_meta[resource_id];\n\n\t\t\tauto &meta = impl.handle_to_resource_meta[loaded_id];\n\t\t\tmeta = incoming_meta;\n\t\t\tmeta.non_uniform = is_non_uniform;\n\t\t\tmeta.storage = storage;\n\t\t\tmeta.var_alias_group = std::move(raw_declarations);\n\t\t\tmeta.kind = DXIL::ResourceKind::CBuffer;\n\t\t\tmeta.instrumentation = instrumentation;\n\n\t\t\tif (is_non_uniform)\n\t\t\t{\n\t\t\t\tif (ssbo)\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityStorageBufferArrayNonUniformIndexingEXT);\n\t\t\t\telse\n\t\t\t\t\tbuilder.addCapability(spv::CapabilityUniformBufferArrayNonUniformIndexingEXT);\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase DXIL::ResourceType::Sampler:\n\t{\n\t\tauto &reference = get_resource_reference(impl, resource_type, instruction, resource_range);\n\t\tspv::Id base_sampler_id = reference.var_id;\n\n\t\tbool is_non_uniform = false;\n\t\tspv::Id loaded_id = 0;\n\t\tif (!build_load_resource_handle(impl, base_sampler_id, reference, DESCRIPTOR_QA_TYPE_SAMPLER_BIT, instruction,\n\t\t                                instruction_offset, non_uniform, is_non_uniform, nullptr, &loaded_id, nullptr, nullptr))\n\t\t{\n\t\t\tLOGE(\"Failed to load Sampler resource handle.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tauto &meta = impl.handle_to_resource_meta[loaded_id];\n\t\tmeta = impl.handle_to_resource_meta[base_sampler_id];\n\t\tmeta.non_uniform = is_non_uniform;\n\n\t\tif (is_non_uniform)\n\t\t{\n\t\t\tbuilder.addCapability(spv::CapabilitySampledImageArrayNonUniformIndexingEXT);\n\t\t\tbuilder.addExtension(\"SPV_EXT_descriptor_indexing\");\n\t\t}\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstatic bool resource_handle_needs_sink(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn impl.options.descriptor_qa_enabled &&\n\t       impl.options.descriptor_qa_sink_handles &&\n\t       impl.resource_handles_needing_sink.count(instruction);\n}\n\nbool emit_create_handle_for_lib_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// Defer creating any handles since annotateHandle is actually going to do it.\n\tif (impl.llvm_annotate_handle_lib_uses.count(instruction))\n\t\treturn true;\n\n\tif (resource_handle_needs_sink(impl, instruction))\n\t{\n\t\timpl.resource_handles_needing_sink.erase(impl.resource_handles_needing_sink.find(instruction));\n\t\treturn true;\n\t}\n\n\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(instruction->getOperand(1));\n\tif (itr == impl.llvm_global_variable_to_resource_mapping.end())\n\t\treturn false;\n\n\treturn emit_create_handle(impl, instruction, itr->second.type,\n\t                          itr->second.meta_index, itr->second.offset, itr->second.non_uniform);\n}\n\nbool emit_create_handle_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (resource_handle_needs_sink(impl, instruction))\n\t{\n\t\timpl.resource_handles_needing_sink.erase(impl.resource_handles_needing_sink.find(instruction));\n\t\treturn true;\n\t}\n\n\tuint32_t resource_type_operand, resource_range;\n\n\tif (!get_constant_operand(instruction, 1, &resource_type_operand))\n\t\treturn false;\n\tif (!get_constant_operand(instruction, 2, &resource_range))\n\t\treturn false;\n\n\tuint32_t non_uniform = 0;\n\tget_constant_operand(instruction, 4, &non_uniform);\n\n\tauto resource_type = static_cast<DXIL::ResourceType>(resource_type_operand);\n\treturn emit_create_handle(impl, instruction, resource_type, resource_range,\n\t                          instruction->getOperand(3), non_uniform != 0);\n}\n\nbool emit_create_handle_from_heap_instruction(Converter::Impl &, const llvm::CallInst *)\n{\n\t// Do nothing here. We cannot emit code before annotateHandle.\n\treturn true;\n}\n\nbool emit_create_handle_from_binding_instruction(Converter::Impl &, const llvm::CallInst *)\n{\n\t// Do nothing here. We cannot emit code before annotateHandle.\n\treturn true;\n}\n\nbool get_annotate_handle_meta(Converter::Impl &impl, const llvm::CallInst *instruction,\n                              AnnotateHandleMeta &meta)\n{\n\tauto *handle = llvm::dyn_cast<llvm::CallInst>(instruction->getOperand(1));\n\tif (!handle)\n\t\treturn false;\n\n\tuint32_t opcode;\n\tif (!get_constant_operand(handle, 0, &opcode))\n\t\treturn false;\n\n\tmeta.resource_op = DXIL::Op(opcode);\n\tuint32_t non_uniform_int = 0;\n\n\tif (meta.resource_op == DXIL::Op::CreateHandleFromHeap)\n\t{\n\t\tauto &annotation = impl.llvm_annotate_handle_uses[instruction];\n\t\tmeta.resource_type = annotation.resource_type;\n\t\tmeta.binding_index = UINT32_MAX; // Direct heap access.\n\n\t\tmeta.offset = handle->getOperand(1);\n\n\t\tif (!get_constant_operand(handle, 3, &non_uniform_int))\n\t\t\treturn false;\n\t}\n\telse if (meta.resource_op == DXIL::Op::CreateHandleFromBinding)\n\t{\n\t\tmeta.offset = handle->getOperand(2);\n\n\t\tif (!get_constant_operand(handle, 3, &non_uniform_int))\n\t\t\treturn false;\n\n\t\tif (auto *res_type = llvm::dyn_cast<llvm::ConstantAggregate>(handle->getOperand(1)))\n\t\t{\n\t\t\tif (res_type->getNumOperands() != 4)\n\t\t\t\treturn false;\n\n\t\t\tuint32_t binding_range_lo = res_type->getOperand(0)->getUniqueInteger().getZExtValue();\n\t\t\tuint32_t binding_range_hi = res_type->getOperand(1)->getUniqueInteger().getZExtValue();\n\t\t\tuint32_t binding_space = res_type->getOperand(2)->getUniqueInteger().getZExtValue();\n\t\t\tmeta.resource_type = DXIL::ResourceType(res_type->getOperand(3)->getUniqueInteger().getZExtValue());\n\t\t\tmeta.binding_index = impl.find_binding_meta_index(\n\t\t\t\tbinding_range_lo, binding_range_hi,\n\t\t\t\tbinding_space, meta.resource_type);\n\n\t\t\tif (meta.binding_index == UINT32_MAX)\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (llvm::isa<llvm::ConstantAggregateZero>(handle->getOperand(1)))\n\t\t{\n\t\t\tmeta.resource_type = DXIL::ResourceType(0);\n\t\t\tmeta.binding_index = impl.find_binding_meta_index(0, 0, 0, meta.resource_type);\n\t\t\tif (meta.binding_index == UINT32_MAX)\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\telse if (meta.resource_op == DXIL::Op::CreateHandleForLib)\n\t{\n\t\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(handle->getOperand(1));\n\t\tif (itr == impl.llvm_global_variable_to_resource_mapping.end())\n\t\t\treturn false;\n\n\t\t// Marks that the CreateHandleForLib is a dummy and should not actually emit a resource handle.\n\t\timpl.llvm_annotate_handle_lib_uses.insert(instruction->getOperand(1));\n\n\t\tmeta.resource_type = itr->second.type;\n\t\tmeta.binding_index = itr->second.meta_index;\n\t\tmeta.offset = itr->second.offset;\n\t\tnon_uniform_int = uint32_t(itr->second.non_uniform);\n\t}\n\telse\n\t\treturn false;\n\n\tmeta.non_uniform = non_uniform_int != 0;\n\treturn true;\n}\n\nbool emit_annotate_handle_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (resource_handle_needs_sink(impl, instruction))\n\t{\n\t\timpl.resource_handles_needing_sink.erase(impl.resource_handles_needing_sink.find(instruction));\n\t\treturn true;\n\t}\n\n\tAnnotateHandleMeta meta = {};\n\tif (!get_annotate_handle_meta(impl, instruction, meta))\n\t\treturn false;\n\n\treturn emit_create_handle(impl, instruction, meta.resource_type,\n\t                          meta.binding_index, meta.offset, meta.non_uniform);\n}\n\nstatic bool build_bitcast_32x4_to_16x8_composite(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                 spv::Id loaded_id)\n{\n\tauto &builder = impl.builder();\n\n\tVector<spv::Id> member_types(8);\n\tspv::Id type_id = impl.get_type_id(get_composite_element_type(instruction->getType()));\n\tfor (auto &type : member_types)\n\t\ttype = type_id;\n\n\tspv::Id vec2_type_id = builder.makeVectorType(type_id, 2);\n\n\tspv::Id u32_composites[4];\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, builder.makeFloatType(32));\n\t\textract_op->add_id(loaded_id);\n\t\textract_op->add_literal(i);\n\t\timpl.add(extract_op);\n\t\tu32_composites[i] = extract_op->id;\n\t}\n\n\tspv::Id u16_composites[8];\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\tauto *bitcast_op = impl.allocate(spv::OpBitcast, vec2_type_id);\n\t\tbitcast_op->add_id(u32_composites[i]);\n\t\timpl.add(bitcast_op);\n\n\t\tfor (unsigned j = 0; j < 2; j++)\n\t\t{\n\t\t\tauto *extract = impl.allocate(spv::OpCompositeExtract, type_id);\n\t\t\textract->add_id(bitcast_op->id);\n\t\t\textract->add_literal(j);\n\t\t\timpl.add(extract);\n\t\t\tu16_composites[2 * i + j] = extract->id;\n\t\t}\n\t}\n\n\tspv::Id struct_type_id = impl.get_struct_type(member_types, 0, \"CBVComposite16x8\");\n\tauto *composite = impl.allocate(spv::OpCompositeConstruct, struct_type_id);\n\tfor (auto &comp : u16_composites)\n\t\tcomposite->add_id(comp);\n\timpl.add(composite);\n\timpl.rewrite_value(instruction, composite->id);\n\treturn true;\n}\n\nstatic bool emit_cbuffer_load_physical_pointer(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tbool scalar_load = !type_is_composite_return_value(instruction->getType());\n\tunsigned scalar_alignment;\n\tuint32_t alignment;\n\n\tconst llvm::Type *result_component_type;\n\n\tif (!scalar_load)\n\t{\n\t\tresult_component_type = get_composite_element_type(instruction->getType());\n\t\tscalar_alignment = get_type_scalar_alignment(impl, result_component_type);\n\t\talignment = 16;\n\t}\n\telse\n\t{\n\t\t// DXIL emits the alignment, but we cannot trust it, DXC is completely buggy here and emits\n\t\t// obviously bogus alignment values.\n\t\t// Use scalar alignment.\n\t\tresult_component_type = instruction->getType();\n\t\talignment = get_type_scalar_alignment(impl, instruction->getType());\n\t\tscalar_alignment = alignment;\n\t}\n\n\t// Handle min16float where we want FP16 value, but FP32 physical.\n\tspv::Op value_cast_op = spv::OpNop;\n\tspv::Id physical_type_id = 0;\n\tget_physical_load_store_cast_info(impl, result_component_type, physical_type_id, value_cast_op);\n\n\tspv::Id index_id;\n\n\tif (!scalar_load)\n\t{\n\t\tindex_id = impl.get_id_for_value(instruction->getOperand(2));\n\t}\n\telse\n\t{\n\t\tunsigned addr_shift_log2 = raw_buffer_data_type_to_addr_shift_log2(impl, instruction->getType());\n\t\tindex_id = build_index_divider(impl, instruction->getOperand(2), addr_shift_log2, 1);\n\t}\n\n\tauto *result_type = instruction->getType();\n\tunsigned physical_vecsize;\n\tspv::Id result_type_id;\n\n\tif (scalar_load)\n\t{\n\t\tresult_type_id = impl.get_type_id(result_type);\n\t\tphysical_vecsize = 1;\n\t}\n\telse\n\t{\n\t\tif (scalar_alignment != 2)\n\t\t{\n\t\t\tphysical_vecsize = 16 / scalar_alignment;\n\t\t\tresult_type_id = builder.makeVectorType(physical_type_id, physical_vecsize);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tresult_type_id = builder.makeVectorType(builder.makeFloatType(32), 4);\n\t\t\tphysical_vecsize = 4;\n\t\t}\n\t}\n\n\tConverter::Impl::PhysicalPointerMeta ptr_meta = {};\n\tptr_meta.nonwritable = true;\n\tptr_meta.stride = alignment;\n\tptr_meta.size = 64 * 1024;\n\tspv::Id ptr_type_id = impl.get_physical_pointer_block_type(result_type_id, ptr_meta);\n\n\tspv::Id loaded_id;\n\n\tif (impl.options.instruction_instrumentation.enabled &&\n\t    impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume &&\n\t    !llvm::isa<llvm::ConstantInt>(instruction->getOperand(2)))\n\t{\n\t\tauto *is_in_bounds = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\t\tis_in_bounds->add_id(index_id);\n\t\tis_in_bounds->add_id(builder.makeUintConstant(ptr_meta.size / alignment));\n\t\timpl.add(is_in_bounds);\n\n\t\tauto *assert_that = impl.allocate(spv::OpAssumeTrueKHR);\n\t\tassert_that->add_id(is_in_bounds->id);\n\t\timpl.add(assert_that);\n\t}\n\n\tif (impl.options.quirks.robust_physical_cbv && !llvm::isa<llvm::ConstantInt>(instruction->getOperand(2)))\n\t{\n\t\tspv::Id call_id = impl.spirv_module.get_robust_physical_cbv_load_call_id(result_type_id, ptr_type_id, alignment);\n\t\tauto *call_op = impl.allocate(spv::OpFunctionCall, result_type_id);\n\t\tcall_op->add_id(call_id);\n\t\tcall_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\tcall_op->add_id(index_id);\n\t\timpl.add(call_op);\n\t\tloaded_id = call_op->id;\n\t\timpl.rewrite_value(instruction, loaded_id);\n\t}\n\telse\n\t{\n\t\tauto *ptr_bitcast_op = impl.allocate(spv::OpBitcast, ptr_type_id);\n\t\tptr_bitcast_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(ptr_bitcast_op);\n\n\t\t// Out of bounds is undefined behavior for root descriptors.\n\t\t// Allows a compiler to assume that the index is unsigned and multiplying by stride does not overflow 32-bit space.\n\t\tauto *chain_op = impl.allocate(spv::OpInBoundsAccessChain,\n\t\t                               builder.makePointer(spv::StorageClassPhysicalStorageBuffer, result_type_id));\n\t\tchain_op->add_id(ptr_bitcast_op->id);\n\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\tchain_op->add_id(index_id);\n\t\timpl.add(chain_op);\n\n\t\tauto *load_op = impl.allocate(spv::OpLoad, instruction, result_type_id);\n\t\tload_op->add_id(chain_op->id);\n\t\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\t\tload_op->add_literal(alignment);\n\t\timpl.add(load_op);\n\t\tloaded_id = load_op->id;\n\t}\n\n\t// Handle f16x8 loads.\n\tif (!scalar_load && scalar_alignment == 2)\n\t\treturn build_bitcast_32x4_to_16x8_composite(impl, instruction, loaded_id);\n\telse if (value_cast_op != spv::OpNop)\n\t{\n\t\tspv::Id type_id = impl.get_type_id(result_component_type);\n\t\tif (physical_vecsize != 1)\n\t\t\ttype_id = builder.makeVectorType(type_id, physical_vecsize);\n\t\tauto *cast_op = impl.allocate(value_cast_op, type_id);\n\t\tcast_op->add_id(impl.get_id_for_value(instruction));\n\t\timpl.add(cast_op);\n\t\timpl.rewrite_value(instruction, cast_op->id);\n\t}\n\n\treturn true;\n}\n\nstatic bool emit_cbuffer_load_from_uints(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                         spv::Id base_ptr,\n                                         spv::StorageClass storage,\n                                         unsigned index_offset, unsigned num_elements)\n{\n\tauto &builder = impl.builder();\n\n\t// For shader record buffers and workgraph local root signature, we are more flexible.\n\tbool is_physical = storage == spv::StorageClassShaderRecordBufferKHR ||\n\t                   storage == spv::StorageClassPhysicalStorageBuffer;\n\n\tauto *constant_int = llvm::dyn_cast<llvm::ConstantInt>(instruction->getOperand(2));\n\n\t// It's UB code to get here anyway.\n#if 0\n\tif (!constant_int)\n\t{\n\t\tif (!is_physical && !value_is_statically_wave_uniform(impl, instruction->getOperand(2)))\n\t\t{\n\t\t\tLOGE(\"Cannot dynamically index into push constants unless we prove dynamically uniform requirement.\\n\");\n\t\t\treturn false;\n\t\t}\n\t}\n#endif\n\n\t// CBufferLoad vs CBufferLoadLegacy\n\tbool scalar_load = !type_is_composite_return_value(instruction->getType());\n\tunsigned member_index = UINT32_MAX;\n\tspv::Id dynamic_member_index = 0;\n\n\tif (constant_int)\n\t\tmember_index = unsigned(constant_int->getUniqueInteger().getZExtValue());\n\telse\n\t\tdynamic_member_index = impl.get_id_for_value(instruction->getOperand(2));\n\n\t// In scalar load, we index by byte offset. Ignore alignment, we read from registers.\n\tif (scalar_load)\n\t{\n\t\tif (dynamic_member_index)\n\t\t{\n\t\t\tauto *shr = impl.allocate(spv::OpShiftRightLogical, builder.makeUintType(32));\n\t\t\tshr->add_id(dynamic_member_index);\n\t\t\tshr->add_id(builder.makeUintConstant(2));\n\t\t\timpl.add(shr);\n\t\t\tdynamic_member_index = shr->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (member_index % 4)\n\t\t\t{\n\t\t\t\tLOGE(\"Scalar CBufferLoad on root constant buffer is not aligned to 4 bytes.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tmember_index /= 4;\n\t\t}\n\n\t\tif (get_type_scalar_alignment(impl, instruction->getType()) != 4)\n\t\t{\n\t\t\tLOGE(\"Attempting to use root constant buffer with non-32bit type.\\n\");\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// In legacy load, we index in terms of float4[]s.\n\t\tif (!dynamic_member_index)\n\t\t{\n\t\t\tmember_index *= 4;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *mul4 = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tmul4->add_id(builder.makeUintConstant(4));\n\t\t\tmul4->add_id(dynamic_member_index);\n\t\t\timpl.add(mul4);\n\n\t\t\tdynamic_member_index = mul4->id;\n\t\t}\n\n\t\tif (get_type_scalar_alignment(impl, get_composite_element_type(instruction->getType())) != 4)\n\t\t{\n\t\t\tLOGE(\"Attempting to use root constant buffer with non-32bit type.\\n\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (!dynamic_member_index)\n\t{\n\t\tmember_index += index_offset;\n\n\t\tif (member_index >= num_elements)\n\t\t{\n\t\t\tLOGE(\"Root constant CBV is accessed out of bounds. (%u > %u).\\n\", member_index, num_elements);\n\t\t\treturn false;\n\t\t}\n\t}\n\telse if (!is_physical && index_offset != impl.root_descriptor_count)\n\t{\n\t\tauto *dyn_offset = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tdyn_offset->add_id(dynamic_member_index);\n\t\tdyn_offset->add_id(builder.makeUintConstant(index_offset - impl.root_descriptor_count));\n\t\timpl.add(dyn_offset);\n\t\tdynamic_member_index = dyn_offset->id;\n\t}\n\n\tunsigned num_words = std::min(scalar_load ? 1u : 4u, dynamic_member_index ? UINT32_MAX : num_elements - member_index);\n\n\tauto *result_scalar_type = instruction->getType();\n\tif (!scalar_load)\n\t\tresult_scalar_type = get_composite_element_type(result_scalar_type);\n\n\t// Root constants are emitted as uints as they are typically used as indices.\n\tbool need_bitcast = result_scalar_type->getTypeID() != llvm::Type::TypeID::IntegerTyID;\n\n\tspv::Id elements[4];\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\tif (i < num_words)\n\t\t{\n\t\t\tauto *op = impl.allocate(\n\t\t\t\tstorage == spv::StorageClassPhysicalStorageBuffer ? spv::OpInBoundsAccessChain : spv::OpAccessChain,\n\t\t\t\tbuilder.makePointer(storage == spv::StorageClassPushConstant && impl.options.inline_ubo_enable ?\n\t\t\t\t                    spv::StorageClassUniform : storage,\n\t\t\t\t                    builder.makeUintType(32)));\n\n\t\t\top->add_id(base_ptr);\n\n\t\t\tif (impl.root_constant_arrayed && !is_physical)\n\t\t\t\top->add_id(builder.makeUintConstant(impl.root_descriptor_count));\n\n\t\t\tif (constant_int)\n\t\t\t{\n\t\t\t\tif (impl.root_constant_arrayed && !is_physical)\n\t\t\t\t\top->add_id(builder.makeUintConstant(member_index + i - impl.root_descriptor_count));\n\t\t\t\telse\n\t\t\t\t\top->add_id(builder.makeUintConstant(member_index + i));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto *index_add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\t\tindex_add->add_id(dynamic_member_index);\n\t\t\t\tindex_add->add_id(builder.makeUintConstant(i));\n\t\t\t\timpl.add(index_add);\n\n\t\t\t\tif (!impl.glsl_std450_ext)\n\t\t\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\t\t\t// Robustness. This is illegal D3D12 code, so we don't really care if it's slow.\n\t\t\t\tauto *clamp = impl.allocate(spv::OpExtInst, builder.makeUintType(32));\n\t\t\t\tclamp->add_id(impl.glsl_std450_ext);\n\t\t\t\tclamp->add_literal(GLSLstd450UMin);\n\t\t\t\tclamp->add_id(index_add->id);\n\n\t\t\t\tif (is_physical)\n\t\t\t\t\tclamp->add_id(builder.makeUintConstant(num_elements - 1));\n\t\t\t\telse\n\t\t\t\t\tclamp->add_id(builder.makeUintConstant(impl.root_constant_num_words - 1));\n\t\t\t\timpl.add(clamp);\n\n\t\t\t\top->add_id(clamp->id);\n\t\t\t}\n\n\t\t\timpl.add(op);\n\n\t\t\tauto *load_op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\t\tload_op->add_id(op->id);\n\n\t\t\tif (storage == spv::StorageClassPhysicalStorageBuffer)\n\t\t\t{\n\t\t\t\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\t\t\t\tload_op->add_literal(4);\n\t\t\t}\n\n\t\t\timpl.add(load_op);\n\t\t\telements[i] = load_op->id;\n\t\t}\n\t\telse if (!scalar_load)\n\t\t\telements[i] = builder.makeUintConstant(0);\n\t}\n\n\tspv::Id id;\n\n\tif (scalar_load)\n\t\tid = elements[0];\n\telse\n\t\tid = impl.build_vector(builder.makeUintType(32), elements, 4);\n\n\tspv::Op value_cast_op = spv::OpNop;\n\tspv::Id physical_type_id = 0;\n\tget_physical_load_store_cast_info(impl, result_scalar_type, physical_type_id, value_cast_op);\n\n\tif (need_bitcast)\n\t{\n\t\tspv::Id type_id = physical_type_id;\n\t\tif (!scalar_load)\n\t\t\ttype_id = builder.makeVectorType(type_id, 4);\n\n\t\tauto *op = impl.allocate(spv::OpBitcast, instruction, type_id);\n\t\top->add_id(id);\n\t\timpl.add(op);\n\t\tid = op->id;\n\t}\n\telse\n\t{\n\t\timpl.rewrite_value(instruction, id);\n\t}\n\n\t// To handle min16 types in root constants, we might have to narrow here.\n\tif (value_cast_op != spv::OpNop)\n\t{\n\t\tspv::Id type_id = impl.get_type_id(result_scalar_type);\n\t\tif (!scalar_load)\n\t\t\ttype_id = builder.makeVectorType(type_id, 4);\n\n\t\tauto *cast_op = impl.allocate(value_cast_op, type_id);\n\t\tcast_op->add_id(id);\n\t\timpl.add(cast_op);\n\t\timpl.rewrite_value(instruction, cast_op->id);\n\t}\n\n\treturn true;\n}\n\nstatic bool emit_cbuffer_load_shader_record(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                            unsigned local_root_signature_entry)\n{\n\tauto &entry = impl.local_root_signature[local_root_signature_entry];\n\treturn emit_cbuffer_load_from_uints(impl, instruction,\n\t                                    impl.get_id_for_value(instruction->getOperand(1)),\n\t                                    impl.node_input.shader_record_block_type_id ?\n\t                                    spv::StorageClassPhysicalStorageBuffer : spv::StorageClassShaderRecordBufferKHR,\n\t                                    0, entry.constants.num_words);\n}\n\nstatic bool emit_cbuffer_load_root_constant(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_cbuffer_load_from_uints(impl, instruction,\n\t                                    impl.root_constant_id,\n\t                                    spv::StorageClassPushConstant,\n\t                                    impl.handle_to_root_member_offset[instruction->getOperand(1)],\n\t                                    impl.root_constant_num_words + impl.root_descriptor_count);\n}\n\nbool cbuffer_supports_gep_punchthrough(Converter::Impl &impl, const llvm::Value *cbv_handle)\n{\n\tauto itr = impl.llvm_value_to_cbv_resource_index_map.find(cbv_handle);\n\n\t// Bindless, cannot be push constant or local root sig.\n\tif (itr == impl.llvm_value_to_cbv_resource_index_map.end())\n\t\treturn true;\n\n\tauto &ref = impl.cbv_index_to_reference[itr->second];\n\n\t// Block root constants for local root signatures as well.\n\tif (ref.local_root_signature_entry >= 0)\n\t{\n\t\tauto &entry = impl.local_root_signature[ref.local_root_signature_entry];\n\t\treturn entry.type != LocalRootSignatureType::Constants;\n\t}\n\n\tif (ref.var_id != 0 && ref.var_id == impl.root_constant_id &&\n\t    !resource_is_physical_pointer(impl, ref))\n\t{\n\t\treturn false;\n\t}\n\n\t// Root descriptor and table descriptors are fine.\n\treturn true;\n}\n\nbool emit_gep_as_cbuffer_scalar_offset(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction,\n                                       const llvm::Value *cbv_handle, uint32_t scalar_index_offset, uint32_t stride)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ptr_id = impl.get_id_for_value(cbv_handle);\n\tif (!ptr_id)\n\t\treturn false;\n\n\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\n\t// We should have guarded against this.\n\t// Guard against shader record buffer to avoid having to deal with bitcasting.\n\tif (ptr_id == impl.root_constant_id || meta.storage == spv::StorageClassShaderRecordBufferKHR)\n\t\treturn false;\n\n\tspv::Id array_index_id = impl.get_id_for_value(instruction->getOperand(2));\n\n\tbool expect_assume = impl.options.instruction_instrumentation.enabled &&\n\t                     impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume;\n\n\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer &&\n\t    (impl.options.quirks.robust_physical_cbv_forwarding || expect_assume))\n\t{\n\t\t// Clamp the index to the range of the private array.\n\t\t// Otherwise we can rely on robustness to clean things up, but here we risk page faults.\n\t\tauto *aggregate_type = instruction->getOperand(0)->getType();\n\t\tif (auto *ptr_type = llvm::dyn_cast<llvm::PointerType>(aggregate_type))\n\t\t{\n\t\t\tif (auto *array_type = llvm::dyn_cast<llvm::ArrayType>(ptr_type->getPointerElementType()))\n\t\t\t{\n\t\t\t\tunsigned num_elements = array_type->getArrayNumElements();\n\n\t\t\t\tif (expect_assume)\n\t\t\t\t{\n\t\t\t\t\tauto *is_in_bounds = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\t\t\t\t\tis_in_bounds->add_id(array_index_id);\n\t\t\t\t\tis_in_bounds->add_id(builder.makeUintConstant(num_elements));\n\t\t\t\t\timpl.add(is_in_bounds);\n\n\t\t\t\t\tauto *assert_that = impl.allocate(spv::OpAssumeTrueKHR);\n\t\t\t\t\tassert_that->add_id(is_in_bounds->id);\n\t\t\t\t\timpl.add(assert_that);\n\t\t\t\t}\n\n\t\t\t\tif (impl.options.quirks.robust_physical_cbv_forwarding)\n\t\t\t\t{\n\t\t\t\t\tif (!impl.glsl_std450_ext)\n\t\t\t\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\t\t\t\tauto *clamp_op = impl.allocate(spv::OpExtInst, builder.makeIntType(32));\n\t\t\t\t\tclamp_op->add_id(impl.glsl_std450_ext);\n\t\t\t\t\tclamp_op->add_literal(GLSLstd450SClamp);\n\t\t\t\t\tclamp_op->add_id(array_index_id);\n\t\t\t\t\tclamp_op->add_id(builder.makeIntConstant(0));\n\t\t\t\t\tclamp_op->add_id(builder.makeIntConstant(int(num_elements) - 1));\n\t\t\t\t\timpl.add(clamp_op);\n\n\t\t\t\t\tarray_index_id = clamp_op->id;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (stride != 1)\n\t{\n\t\tauto *mul_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\tmul_op->add_id(array_index_id);\n\t\tmul_op->add_id(builder.makeUintConstant(stride));\n\t\timpl.add(mul_op);\n\t\tarray_index_id = mul_op->id;\n\t}\n\n\tif (scalar_index_offset != 0)\n\t{\n\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd_op->add_id(array_index_id);\n\t\tadd_op->add_id(builder.makeUintConstant(scalar_index_offset));\n\t\timpl.add(add_op);\n\t\tarray_index_id = add_op->id;\n\t}\n\n\tconst auto *elem_type = instruction->getType()->getPointerElementType();\n\tspv::Id result_type_id = impl.get_type_id(elem_type);\n\n\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t{\n\t\tConverter::Impl::PhysicalPointerMeta ptr_meta = {};\n\t\tptr_meta.nonwritable = true;\n\t\tptr_meta.stride = 4;\n\t\tptr_meta.size = 64 * 1024;\n\t\tspv::Id ptr_type_id = impl.get_physical_pointer_block_type(result_type_id, ptr_meta);\n\n\t\tauto *ptr_bitcast_op = impl.allocate(spv::OpBitcast, ptr_type_id);\n\t\tptr_bitcast_op->add_id(ptr_id);\n\t\timpl.add(ptr_bitcast_op);\n\n\t\tauto *chain_op = impl.allocate(spv::OpInBoundsAccessChain, instruction,\n\t\t                               builder.makePointer(spv::StorageClassPhysicalStorageBuffer, result_type_id));\n\t\tchain_op->add_id(ptr_bitcast_op->id);\n\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\tchain_op->add_id(array_index_id);\n\t\timpl.add(chain_op);\n\t}\n\telse\n\t{\n\t\tRawType raw_type = elem_type->isIntegerTy() ? RawType::Integer : RawType::Float;\n\t\tptr_id = get_buffer_alias_handle(impl, meta, ptr_id, raw_type, RawWidth::B32, RawVecSize::V1);\n\n\t\tOperation *access_chain_op = impl.allocate(\n\t\t    spv::OpAccessChain, instruction, builder.makePointer(meta.storage, impl.get_type_id(elem_type)));\n\t\taccess_chain_op->add_ids({ ptr_id, builder.makeUintConstant(0), array_index_id });\n\t\timpl.add(access_chain_op);\n\t}\n\n\treturn true;\n}\n\nbool emit_cbuffer_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\t// This always returns a scalar.\n\tspv::Id ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\tif (!ptr_id)\n\t\treturn false;\n\n\tif (ptr_id == impl.root_constant_id)\n\t{\n\t\treturn emit_cbuffer_load_root_constant(impl, instruction);\n\t}\n\telse\n\t{\n\t\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\n\t\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t\t{\n\t\t\treturn emit_cbuffer_load_physical_pointer(impl, instruction);\n\t\t}\n\t\telse if (meta.storage == spv::StorageClassShaderRecordBufferKHR)\n\t\t{\n\t\t\treturn emit_cbuffer_load_shader_record(impl, instruction,\n\t\t\t\t\t\t\t\t\t\t\t\t   impl.handle_to_root_member_offset[instruction->getOperand(1)]);\n\t\t}\n\n\t\t// Handle min16float where we want FP16 value, but FP32 physical.\n\t\tspv::Op value_cast_op = spv::OpNop;\n\t\tspv::Id physical_type_id = 0;\n\t\tget_physical_load_store_cast_info(impl, instruction->getType(), physical_type_id, value_cast_op);\n\n\t\tunsigned addr_shift;\n\t\tRawWidth raw_width;\n\t\tswitch (get_type_scalar_alignment(impl, instruction->getType()))\n\t\t{\n\t\tcase 2:\n\t\t\traw_width = RawWidth::B16;\n\t\t\taddr_shift = 1;\n\t\t\tbreak;\n\n\t\tcase 4:\n\t\t\traw_width = RawWidth::B32;\n\t\t\taddr_shift = 2;\n\t\t\tbreak;\n\n\t\tcase 8:\n\t\t\traw_width = RawWidth::B64;\n\t\t\taddr_shift = 3;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\n\t\tRawType raw_type = instruction->getType()->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t\t                   raw_width == RawWidth::B64 ?\n\t\t                   RawType::Integer : RawType::Float;\n\n\t\tunsigned raw_bits = raw_width_to_bits(raw_width);\n\t\tptr_id = get_buffer_alias_handle(impl, meta, ptr_id, raw_type, raw_width, RawVecSize::V1);\n\n\t\tspv::Id array_index_id = build_index_divider(impl, instruction->getOperand(2), addr_shift, 1);\n\n\t\tspv::Id element_type_id = raw_type == RawType::Integer ?\n\t\t    builder.makeUintType(raw_bits) : builder.makeFloatType(raw_bits);\n\n\t\tOperation *access_chain_op = impl.allocate(\n\t\t\t\tspv::OpAccessChain, builder.makePointer(meta.storage, element_type_id));\n\t\taccess_chain_op->add_ids({ ptr_id, builder.makeUintConstant(0), array_index_id });\n\t\timpl.add(access_chain_op);\n\n\t\tif (meta.non_uniform)\n\t\t\tbuilder.addDecoration(access_chain_op->id, spv::DecorationNonUniformEXT);\n\n\t\tbool need_bitcast = false;\n\t\tauto *result_type = instruction->getType();\n\t\tif (result_type->getTypeID() == llvm::Type::TypeID::IntegerTyID && raw_width != RawWidth::B64)\n\t\t\tneed_bitcast = true;\n\n\t\tOperation *load_op = impl.allocate(spv::OpLoad, instruction, element_type_id);\n\t\tload_op->add_id(access_chain_op->id);\n\t\timpl.add(load_op);\n\n\t\tif (need_bitcast)\n\t\t{\n\t\t\tOperation *op = impl.allocate(spv::OpBitcast, builder.makeUintType(raw_bits));\n\t\t\top->add_id(load_op->id);\n\t\t\timpl.add(op);\n\t\t\timpl.rewrite_value(instruction, op->id);\n\t\t}\n\n\t\t// Handle min16float4 value cast scenarios.\n\t\tif (value_cast_op != spv::OpNop)\n\t\t{\n\t\t\tauto *cast_op = impl.allocate(value_cast_op, impl.get_type_id(instruction->getType()));\n\t\t\tcast_op->add_id(impl.get_id_for_value(instruction));\n\t\t\timpl.add(cast_op);\n\t\t\timpl.rewrite_value(instruction, cast_op->id);\n\t\t}\n\n\t\treturn true;\n\t}\n}\n\nbool type_is_composite_return_value(llvm::Type *type)\n{\n\treturn type->getTypeID() == llvm::Type::TypeID::StructTyID || type->getTypeID() == llvm::Type::TypeID::VectorTyID;\n}\n\nllvm::Type *get_composite_element_type(llvm::Type *type)\n{\n\tassert(type_is_composite_return_value(type));\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t\treturn vec->getElementType();\n\telse\n\t\treturn type->getStructElementType(0);\n}\n\nbool emit_cbuffer_load_legacy_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\t// This function returns a struct, but ignore that, and just return a vec4 for now.\n\t// extractvalue is used to pull out components and that works for vectors as well.\n\tspv::Id ptr_id = impl.get_id_for_value(instruction->getOperand(1));\n\tif (!ptr_id)\n\t\treturn false;\n\n\tif (ptr_id == impl.root_constant_id)\n\t{\n\t\treturn emit_cbuffer_load_root_constant(impl, instruction);\n\t}\n\telse\n\t{\n\t\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\n\t\tauto *result_type = instruction->getType();\n\n\t\tif (!type_is_composite_return_value(result_type))\n\t\t{\n\t\t\tLOGE(\"CBufferLoadLegacy: return type must be struct or vector.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\temit_buffer_synchronization_validation(impl, instruction, BDAOperation::Load);\n\n\t\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t\t{\n\t\t\treturn emit_cbuffer_load_physical_pointer(impl, instruction);\n\t\t}\n\t\telse if (meta.storage == spv::StorageClassShaderRecordBufferKHR)\n\t\t{\n\t\t\treturn emit_cbuffer_load_shader_record(impl, instruction,\n\t\t\t                                       impl.handle_to_root_member_offset[instruction->getOperand(1)]);\n\t\t}\n\n\t\t// Handle min16float where we want FP16 value, but FP32 physical.\n\t\tauto *result_component_type = get_composite_element_type(result_type);\n\t\tspv::Op value_cast_op = spv::OpNop;\n\t\tspv::Id physical_type_id = 0;\n\t\tget_physical_load_store_cast_info(impl, result_component_type, physical_type_id, value_cast_op);\n\n\t\tRawVecSize alias_vecsize;\n\t\tRawWidth alias_width;\n\t\tunsigned scalar_alignment = get_type_scalar_alignment(impl, result_component_type);\n\t\tunsigned bits, vecsize;\n\n\t\tif (scalar_alignment == 8)\n\t\t{\n\t\t\talias_width = RawWidth::B64;\n\t\t\talias_vecsize = RawVecSize::V2;\n\t\t}\n\t\telse\n\t\t{\n\t\t\talias_width = RawWidth::B32;\n\t\t\talias_vecsize = RawVecSize::V4;\n\t\t}\n\n\t\tbits = raw_width_to_bits(alias_width);\n\t\tvecsize = raw_vecsize_to_vecsize(alias_vecsize);\n\n\t\tRawType raw_type = result_component_type->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t\t                   scalar_alignment == 8 ? RawType::Integer : RawType::Float;\n\n\t\tptr_id = get_buffer_alias_handle(impl, meta, ptr_id, raw_type, alias_width, alias_vecsize);\n\n\t\tspv::Id vec4_index = impl.get_id_for_value(instruction->getOperand(2));\n\n\t\tspv::Id element_type_id = raw_type == RawType::Integer ?\n\t\t                          builder.makeUintType(bits) : builder.makeFloatType(bits);\n\n\t\tspv::Id vector_type_id = builder.makeVectorType(element_type_id, vecsize);\n\t\tOperation *access_chain_op = impl.allocate(spv::OpAccessChain, builder.makePointer(meta.storage, vector_type_id));\n\t\taccess_chain_op->add_ids({ ptr_id, builder.makeUintConstant(0), vec4_index });\n\t\timpl.add(access_chain_op);\n\n\t\tif (meta.non_uniform)\n\t\t\tbuilder.addDecoration(access_chain_op->id, spv::DecorationNonUniformEXT);\n\n\t\tbool need_bitcast = false;\n\t\tif (result_component_type->getTypeID() == llvm::Type::TypeID::IntegerTyID && scalar_alignment < 8)\n\t\t\tneed_bitcast = true;\n\n\t\tOperation *load_op = impl.allocate(spv::OpLoad, instruction, vector_type_id);\n\t\tload_op->add_id(access_chain_op->id);\n\t\timpl.add(load_op);\n\n\t\tif (scalar_alignment == 2)\n\t\t{\n\t\t\t// Special case, need to bitcast and build a struct with 8 elements instead.\n\t\t\tif (!build_bitcast_32x4_to_16x8_composite(impl, instruction, load_op->id))\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (need_bitcast)\n\t\t{\n\t\t\tspv::Id uint_vector_type_id = builder.makeVectorType(builder.makeUintType(bits), vecsize);\n\t\t\tOperation *op = impl.allocate(spv::OpBitcast, uint_vector_type_id);\n\n\t\t\top->add_id(load_op->id);\n\t\t\timpl.add(op);\n\t\t\timpl.rewrite_value(instruction, op->id);\n\t\t}\n\n\t\t// If we have min-precision loads, we might have to truncate here.\n\t\tif (value_cast_op != spv::OpNop)\n\t\t{\n\t\t\tauto *cast_op = impl.allocate(value_cast_op, builder.makeVectorType(impl.get_type_id(result_component_type), vecsize));\n\t\t\tcast_op->add_id(impl.get_id_for_value(instruction));\n\t\t\timpl.add(cast_op);\n\t\t\timpl.rewrite_value(instruction, cast_op->id);\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool resource_handle_is_uniform_readonly_descriptor(Converter::Impl &impl, const llvm::Value *value)\n{\n\tspv::Id ptr_id = impl.get_id_for_value(value);\n\tif (!ptr_id)\n\t\treturn false;\n\n\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\n\t// Root constants must be wave uniform unless waves are merged across different state calls which is ridiculous.\n\t// Anything loaded from record buffer is probably not wave uniform;\n\t// waves are merged arbitrarily, so we cannot assume anything.\n\tif (ptr_id == impl.root_constant_id)\n\t\treturn true;\n\n\t// Only consider an untyped load to be uniform.\n\t// There are reasonable use cases for scalaizing a typed load,\n\t// since those tend to never go through scalar caches.\n\tif (meta.storage != spv::StorageClassPhysicalStorageBuffer &&\n\t    meta.storage != spv::StorageClassStorageBuffer &&\n\t    meta.storage != spv::StorageClassUniform)\n\t{\n\t\treturn false;\n\t}\n\n\tauto *instruction = llvm::cast<llvm::CallInst>(value);\n\tConverter::Impl::ResourceReference *reference = nullptr;\n\tDXIL::ResourceType resource_type = {};\n\n\tif (value_is_dx_op_instrinsic(value, DXIL::Op::CreateHandle))\n\t{\n\t\tuint32_t resource_type_operand, resource_range;\n\t\tif (!get_constant_operand(instruction, 1, &resource_type_operand))\n\t\t\treturn false;\n\t\tif (!get_constant_operand(instruction, 2, &resource_range))\n\t\t\treturn false;\n\n\t\tresource_type = static_cast<DXIL::ResourceType>(resource_type_operand);\n\t\treference = &get_resource_reference(impl, resource_type, instruction, resource_range);\n\t}\n\telse if (value_is_dx_op_instrinsic(value, DXIL::Op::CreateHandleForLib))\n\t{\n\t\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(instruction->getOperand(1));\n\t\tif (itr == impl.llvm_global_variable_to_resource_mapping.end())\n\t\t\treturn false;\n\t\tresource_type = itr->second.type;\n\t\treference = &get_resource_reference(impl, itr->second.type, instruction, itr->second.meta_index);\n\t}\n\telse if (value_is_dx_op_instrinsic(value, DXIL::Op::AnnotateHandle))\n\t{\n\t\tAnnotateHandleMeta annotate_meta = {};\n\t\tif (!get_annotate_handle_meta(impl, instruction, annotate_meta))\n\t\t\treturn false;\n\t\tresource_type = annotate_meta.resource_type;\n\t\treference = &get_resource_reference(impl, annotate_meta.resource_type, instruction, annotate_meta.binding_index);\n\t}\n\n\tif (resource_type != DXIL::ResourceType::SRV && resource_type != DXIL::ResourceType::CBV)\n\t\treturn false;\n\n\tif (!reference)\n\t\treturn false;\n\n\t// Anything referencing local root signature is questionable to assume anything about.\n\tif (reference->local_root_signature_entry >= 0)\n\t\treturn false;\n\n\t// For any array, be afraid. Even if the index is dynamically uniform, it might become not wave uniform\n\t// due to multi-draw shenanigans. A constant index would work, but that's going a bit too far for\n\t// a simple peephole ...\n\tif (reference->base_resource_is_array)\n\t\treturn false;\n\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_resources.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"GLSL.std.450.h\"\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_load_input_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool spirv_semantics);\n\ntemplate <bool spirv_semantics>\nstatic bool emit_load_input_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_load_input_instruction(impl, instruction, spirv_semantics);\n}\n\nbool emit_interpolate_instruction(GLSLstd450 opcode, Converter::Impl &impl, const llvm::CallInst *instruction, bool extended);\nbool emit_store_output_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_create_handle_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_create_handle_for_lib_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_create_handle_from_heap_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_create_handle_from_binding_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_annotate_handle_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_cbuffer_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_cbuffer_load_legacy_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_gep_as_cbuffer_scalar_offset(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction,\n                                       const llvm::Value *cbv_handle, uint32_t scalar_index_offset, uint32_t stride);\nbool cbuffer_supports_gep_punchthrough(Converter::Impl &impl, const llvm::Value *cbv_handle);\nbool emit_load_draw_parameter_instruction(spv::BuiltIn builtin, Converter::Impl &impl, const llvm::CallInst *instruction);\n\ntemplate <GLSLstd450 opcode, bool extended>\nstatic inline bool emit_interpolate_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_interpolate_instruction(opcode, impl, instruction, extended);\n}\n\ntemplate <spv::BuiltIn builtin>\nstatic inline bool emit_load_draw_parameter_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_load_draw_parameter_instruction(builtin, impl, instruction);\n}\n\nbool emit_load_control_point_count_in(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nstruct AnnotateHandleMeta\n{\n\tDXIL::Op resource_op;\n\tDXIL::ResourceType resource_type;\n\tllvm::Value *offset;\n\tuint32_t binding_index;\n\tbool non_uniform;\n};\nbool get_annotate_handle_meta(Converter::Impl &impl, const llvm::CallInst *instruction, AnnotateHandleMeta &meta);\n\nbool resource_handle_is_uniform_readonly_descriptor(Converter::Impl &impl, const llvm::Value *value);\n\nbool type_is_composite_return_value(llvm::Type *type);\nllvm::Type *get_composite_element_type(llvm::Type *type);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_sampling.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_sampling.hpp\"\n#include \"dxil_common.hpp\"\n#include \"dxil_resources.hpp\"\n#include \"spirv_module.hpp\"\n#include \"logging.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"dxil_ags.hpp\"\n\nnamespace dxil_spv\n{\nbool get_image_dimensions_query_size(Converter::Impl &impl, spv::Builder &builder, spv::Id image_id,\n                                     uint32_t *num_coords)\n{\n\tspv::Id image_type_id = impl.get_type_id(image_id);\n\tspv::Dim dim = builder.getTypeDimensionality(image_type_id);\n\tbool is_array = builder.isArrayedImageType(image_type_id);\n\n\tswitch (dim)\n\t{\n\tcase spv::DimSubpassData:\n\t\t*num_coords = 0;\n\t\tbreak;\n\n\tcase spv::Dim1D:\n\tcase spv::DimBuffer:\n\t\t*num_coords = 1;\n\t\tbreak;\n\n\tcase spv::Dim2D:\n\tcase spv::DimCube:\n\t\t*num_coords = 2;\n\t\tbreak;\n\n\tcase spv::Dim3D:\n\t\t*num_coords = 3;\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unexpected sample dimensionality.\\n\");\n\t\treturn false;\n\t}\n\n\tif (is_array)\n\t\t(*num_coords)++;\n\n\treturn true;\n}\n\nbool get_image_dimensions(Converter::Impl &impl, spv::Id image_id, uint32_t *num_coords, uint32_t *num_dimensions)\n{\n\tauto &builder = impl.builder();\n\tspv::Id image_type_id = impl.get_type_id(image_id);\n\tspv::Dim dim = builder.getTypeDimensionality(image_type_id);\n\tbool arrayed = builder.isArrayedImageType(image_type_id);\n\n\tswitch (dim)\n\t{\n\tcase spv::DimSubpassData:\n\t\t*num_coords = 0;\n\t\tbreak;\n\n\tcase spv::Dim1D:\n\tcase spv::DimBuffer:\n\t\t*num_dimensions = 1;\n\t\tbreak;\n\n\tcase spv::Dim2D:\n\t\t*num_dimensions = 2;\n\t\tbreak;\n\n\tcase spv::Dim3D:\n\tcase spv::DimCube:\n\t\t*num_dimensions = 3;\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unexpected sample dimensionality.\\n\");\n\t\treturn false;\n\t}\n\n\t*num_coords = *num_dimensions + unsigned(arrayed);\n\treturn true;\n}\n\nstatic spv::Id build_texel_offset_vector(Converter::Impl &impl,\n                                         const spv::Id *offsets, unsigned num_coords,\n                                         uint32_t image_ops, bool is_gather_instruction)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id int_type = builder.makeIntegerType(32, true);\n\tspv::Id offset_vec;\n\n\tif (image_ops & spv::ImageOperandsConstOffsetMask)\n\t\toffset_vec = impl.build_constant_vector(int_type, offsets, num_coords);\n\telse\n\t\toffset_vec = impl.build_vector(int_type, offsets, num_coords);\n\n\t// Gather has a larger range for offsets,\n\t// and we shouldn't try to mask anything.\n\tif ((image_ops & spv::ImageOperandsOffsetMask) && !is_gather_instruction)\n\t{\n\t\t// SM 6.7 requires signed int wrap for the dynamic offset within range.\n\t\tspv::Id ivec_type = impl.build_vector_type(int_type, num_coords);\n\t\tauto *bfe = impl.allocate(spv::OpBitFieldSExtract, ivec_type);\n\t\tbfe->add_id(offset_vec);\n\t\tbfe->add_id(builder.makeIntConstant(0));\n\t\tbfe->add_id(builder.makeIntConstant(4));\n\t\timpl.add(bfe);\n\t\toffset_vec = bfe->id;\n\t}\n\n\treturn offset_vec;\n}\n\nstatic bool get_texel_offsets(Converter::Impl &impl, const llvm::CallInst *instruction, uint32_t &image_flags,\n                              unsigned base_operand, unsigned num_coords, spv::Id *offsets,\n                              bool instruction_is_gather)\n{\n\tauto &builder = impl.builder();\n\n\tbool is_const_offset = true;\n\tbool has_non_zero_offset = false;\n\n\tfor (unsigned i = 0; i < num_coords; i++)\n\t{\n\t\t// Treat undefined offset as 0, since we can.\n\t\tif (!llvm::isa<llvm::UndefValue>(instruction->getOperand(base_operand + i)))\n\t\t{\n\t\t\tauto *constant_arg = llvm::dyn_cast<llvm::ConstantInt>(instruction->getOperand(base_operand + i));\n\t\t\tif (constant_arg)\n\t\t\t{\n\t\t\t\tif (constant_arg->getUniqueInteger().getSExtValue() != 0)\n\t\t\t\t\thas_non_zero_offset = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbuilder.addCapability(spv::CapabilityImageGatherExtended);\n\t\t\t\tis_const_offset = false;\n\t\t\t\thas_non_zero_offset = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Don't bother emitting offset if they are all 0.\n\tif (!has_non_zero_offset)\n\t\treturn true;\n\n\tif (is_const_offset)\n\t\timage_flags |= spv::ImageOperandsConstOffsetMask;\n\telse\n\t\timage_flags |= spv::ImageOperandsOffsetMask;\n\n\tfor (unsigned i = 0; i < num_coords; i++)\n\t{\n\t\tif (!llvm::isa<llvm::UndefValue>(instruction->getOperand(base_operand + i)))\n\t\t{\n\t\t\tauto operand = instruction->getOperand(base_operand + i);\n\t\t\tif (is_const_offset)\n\t\t\t{\n\t\t\t\tauto *constant_arg = llvm::dyn_cast<llvm::ConstantInt>(operand);\n\t\t\t\toffsets[i] = builder.makeIntConstant(int(constant_arg->getUniqueInteger().getSExtValue()));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Makes sure when we build the array, it's the correct element type.\n\t\t\t\tauto *cast_op = impl.allocate(spv::OpBitcast, builder.makeIntegerType(32, true));\n\t\t\t\timpl.add(cast_op);\n\t\t\t\tcast_op->add_id(impl.get_id_for_value(operand));\n\t\t\t\toffsets[i] = cast_op->id;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\toffsets[i] = builder.makeIntConstant(0);\n\t}\n\n\treturn true;\n}\n\nstatic void build_gradient(Converter::Impl &impl, const spv::Id *coord, unsigned num_coords,\n                           spv::Id &grad_x, spv::Id &grad_y, spv::Id bias_id, uint32_t &ops)\n{\n\tauto &builder = impl.builder();\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id vec_type = builder.makeVectorType(f32_type, num_coords);\n\tspv::Id coord_vec = impl.build_vector(builder.makeFloatType(32), coord, num_coords);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\n\tauto *shuf_x = impl.allocate(spv::OpGroupNonUniformQuadSwap, vec_type);\n\tshuf_x->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tshuf_x->add_id(coord_vec);\n\tshuf_x->add_id(builder.makeUintConstant(0));\n\n\tauto *shuf_y = impl.allocate(spv::OpGroupNonUniformQuadSwap, vec_type);\n\tshuf_y->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tshuf_y->add_id(coord_vec);\n\tshuf_y->add_id(builder.makeUintConstant(1));\n\n\t// Sign does not matter here. LOD computation takes absolute values.\n\tauto *horiz_sub = impl.allocate(spv::OpFSub, vec_type);\n\tauto *vert_sub = impl.allocate(spv::OpFSub, vec_type);\n\thoriz_sub->add_id(coord_vec);\n\thoriz_sub->add_id(shuf_x->id);\n\tvert_sub->add_id(coord_vec);\n\tvert_sub->add_id(shuf_y->id);\n\n\timpl.add(shuf_x);\n\timpl.add(shuf_y);\n\timpl.add(horiz_sub);\n\timpl.add(vert_sub);\n\n\tgrad_x = horiz_sub->id;\n\tgrad_y = vert_sub->id;\n\n\tif (ops & spv::ImageOperandsBiasMask)\n\t{\n\t\tops &= ~spv::ImageOperandsBiasMask;\n\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\tauto *exp2 = impl.allocate(spv::OpExtInst, f32_type);\n\t\texp2->add_id(impl.glsl_std450_ext);\n\t\texp2->add_literal(GLSLstd450Exp2);\n\t\texp2->add_id(bias_id);\n\t\timpl.add(exp2);\n\n\t\tauto *scale_x = impl.allocate(spv::OpVectorTimesScalar, vec_type);\n\t\tauto *scale_y = impl.allocate(spv::OpVectorTimesScalar, vec_type);\n\t\tscale_x->add_id(grad_x);\n\t\tscale_x->add_id(exp2->id);\n\t\tscale_y->add_id(grad_y);\n\t\tscale_y->add_id(exp2->id);\n\n\t\timpl.add(scale_x);\n\t\timpl.add(scale_y);\n\t\tgrad_x = scale_x->id;\n\t\tgrad_y = scale_y->id;\n\t}\n\n\tops |= spv::ImageOperandsGradMask;\n}\n\nstatic spv::Id emit_workaround_clamp_cube_mips(Converter::Impl &impl, spv::Id image_id, spv::Id bias_level_argument)\n{\n\tauto &builder = impl.builder();\n\n\tif (builder.getTypeDimensionality(impl.get_type_id(image_id)) != spv::DimCube)\n\t\treturn bias_level_argument;\n\n\t// Very specific workaround where the game is only computing mips down to\n\t// 8x8 despite having all mips in the chain. Sigh ...\n\tauto *lods = impl.allocate(spv::OpImageQueryLevels, builder.makeIntType(32));\n\tlods->add_id(image_id);\n\timpl.add(lods);\n\n\tauto *sub4 = impl.allocate(spv::OpISub, builder.makeIntType(32));\n\tsub4->add_id(lods->id);\n\tsub4->add_id(builder.makeUintConstant(4));\n\timpl.add(sub4);\n\n\tauto *conv = impl.allocate(spv::OpConvertSToF, builder.makeFloatType(32));\n\tconv->add_id(sub4->id);\n\timpl.add(conv);\n\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tauto *min_op = impl.allocate(spv::OpExtInst, builder.makeFloatType(32));\n\tmin_op->add_id(impl.glsl_std450_ext);\n\tmin_op->add_literal(GLSLstd450FMin);\n\tmin_op->add_id(conv->id);\n\tmin_op->add_id(bias_level_argument);\n\timpl.add(min_op);\n\n\treturn min_op->id;\n}\n\nbool emit_sample_instruction(DXIL::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tbool comparison_sampling = opcode == DXIL::Op::SampleCmp ||\n\t                           opcode == DXIL::Op::SampleCmpLevelZero ||\n\t                           opcode == DXIL::Op::SampleCmpLevel ||\n\t                           opcode == DXIL::Op::SampleCmpBias;\n\n\tbool force_explicit_lod = impl.execution_mode_meta.synthesize_dummy_derivatives;\n\n\t// Elide dead loads.\n\tif (!comparison_sampling && !impl.composite_is_accessed(instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id sampler_id = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id combined_image_sampler_id = impl.build_sampled_image(image_id, sampler_id, comparison_sampling);\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tunsigned num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\tif (num_coords == 0)\n\t{\n\t\tLOGE(\"Cannot use sampling instructions with input attachment.\\n\");\n\t\treturn false;\n\t}\n\n\tspv::Id coord[4] = {};\n\tfor (unsigned i = 0; i < num_coords_full; i++)\n\t\tcoord[i] = impl.get_id_for_value(instruction->getOperand(i + 3));\n\n\tuint32_t image_ops = 0;\n\n\tif (force_explicit_lod)\n\t{\n\t\tif (opcode == DXIL::Op::Sample || opcode == DXIL::Op::SampleBias)\n\t\t\topcode = DXIL::Op::SampleLevel;\n\t\telse if (opcode == DXIL::Op::SampleCmp || opcode == DXIL::Op::SampleCmpBias)\n\t\t\topcode = DXIL::Op::SampleCmpLevelZero;\n\t\telse\n\t\t\tforce_explicit_lod = false;\n\t}\n\n\tif (opcode == DXIL::Op::Sample || opcode == DXIL::Op::SampleBias ||\n\t    opcode == DXIL::Op::SampleCmpBias || opcode == DXIL::Op::SampleCmp)\n\t{\n\t\temit_expect_assume_quad_uniform(impl);\n\t}\n\n\tif (opcode == DXIL::Op::SampleLevel || opcode == DXIL::Op::SampleCmpLevelZero || opcode == DXIL::Op::SampleCmpLevel)\n\t\timage_ops |= spv::ImageOperandsLodMask;\n\telse if (opcode == DXIL::Op::SampleBias || opcode == DXIL::Op::SampleCmpBias)\n\t\timage_ops |= spv::ImageOperandsBiasMask;\n\n\tspv::Id offsets[3] = {};\n\tif (!get_texel_offsets(impl, instruction, image_ops, 7, num_coords, offsets, false))\n\t\treturn false;\n\n\tspv::Id dref_id = 0;\n\n\tif (comparison_sampling)\n\t\tdref_id = impl.get_id_for_value(instruction->getOperand(10));\n\n\tspv::Id bias_level_argument = 0;\n\tspv::Id min_lod_argument = 0;\n\tunsigned bias_level_argument_index = comparison_sampling ? 11 : 10;\n\tunsigned min_lod_argument_index = 11;\n\n\tif (opcode == DXIL::Op::Sample)\n\t\tmin_lod_argument_index = 10;\n\telse if (opcode == DXIL::Op::SampleCmpBias)\n\t\tmin_lod_argument_index = 12;\n\n\tauto &access_meta = impl.llvm_composite_meta[instruction];\n\tbool sparse = (access_meta.access_mask & (1u << 4)) != 0;\n\tif (sparse)\n\t\tbuilder.addCapability(spv::CapabilitySparseResidency);\n\n\tif (opcode == DXIL::Op::Sample || opcode == DXIL::Op::SampleCmp || opcode == DXIL::Op::SampleBias || opcode == DXIL::Op::SampleCmpBias)\n\t{\n\t\tauto min_lod_argument_value = instruction->getOperand(min_lod_argument_index);\n\t\tif (llvm::isa<llvm::UndefValue>(min_lod_argument_value))\n\t\t{\n\t\t\t// No value set\n\t\t}\n\t\telse if (llvm::isa<llvm::ConstantFP>(min_lod_argument_value) && llvm::cast<llvm::ConstantFP>(min_lod_argument_value)->getValueAPF().convertToFloat() == 0)\n\t\t{\n\t\t\t// LOD values less than 0 are invalid, so this is a no-op.\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmin_lod_argument = impl.get_id_for_value(min_lod_argument_value);\n\t\t\timage_ops |= spv::ImageOperandsMinLodMask;\n\t\t\tbuilder.addCapability(spv::CapabilityMinLod);\n\t\t}\n\t}\n\n\tif (force_explicit_lod)\n\t\tbias_level_argument = builder.makeFloatConstant(0.0f);\n\telse if (opcode == DXIL::Op::SampleBias || opcode == DXIL::Op::SampleCmpBias || opcode == DXIL::Op::SampleLevel || opcode == DXIL::Op::SampleCmpLevel)\n\t\tbias_level_argument = impl.get_id_for_value(instruction->getOperand(bias_level_argument_index));\n\telse\n\t\tbias_level_argument = builder.makeFloatConstant(0.0f);\n\n\tif (!force_explicit_lod && impl.options.quirks.assume_broken_sub_8x8_cube_mips && opcode == DXIL::Op::SampleLevel)\n\t\tbias_level_argument = emit_workaround_clamp_cube_mips(impl, image_id, bias_level_argument);\n\n\tspv::Op spv_op;\n\n\tswitch (opcode)\n\t{\n\tcase DXIL::Op::SampleLevel:\n\t\tspv_op = sparse ? spv::OpImageSparseSampleExplicitLod : spv::OpImageSampleExplicitLod;\n\t\tbreak;\n\n\tcase DXIL::Op::Sample:\n\tcase DXIL::Op::SampleBias:\n\t\tspv_op = sparse ? spv::OpImageSparseSampleImplicitLod : spv::OpImageSampleImplicitLod;\n\t\tbreak;\n\n\tcase DXIL::Op::SampleCmp:\n\tcase DXIL::Op::SampleCmpBias:\n\t\tspv_op = sparse ? spv::OpImageSparseSampleDrefImplicitLod : spv::OpImageSampleDrefImplicitLod;\n\t\tbreak;\n\n\tcase DXIL::Op::SampleCmpLevel:\n\tcase DXIL::Op::SampleCmpLevelZero:\n\t\tspv_op = sparse ? spv::OpImageSparseSampleDrefExplicitLod : spv::OpImageSampleDrefExplicitLod;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tauto effective_component_type = Converter::Impl::get_effective_typed_resource_type(meta.component_type);\n\tspv::Id texel_type = impl.get_type_id(effective_component_type, 1, comparison_sampling ? 1 : 4);\n\tspv::Id grad_x = 0, grad_y = 0;\n\tspv::Id sample_type;\n\n\tif (sparse)\n\t\tsample_type = impl.get_struct_type({ builder.makeUintType(32), texel_type }, 0, \"SparseTexel\");\n\telse\n\t\tsample_type = texel_type;\n\n\tbool grad_rewrite = impl.execution_model != spv::ExecutionModelFragment &&\n\t                    !impl.options.compute_shader_derivatives;\n\n\tif (grad_rewrite)\n\t{\n\t\tswitch (spv_op)\n\t\t{\n\t\tcase spv::OpImageSampleImplicitLod:\n\t\t\tspv_op = spv::OpImageSampleExplicitLod;\n\t\t\tbreak;\n\n\t\tcase spv::OpImageSparseSampleImplicitLod:\n\t\t\tspv_op = spv::OpImageSparseSampleExplicitLod;\n\t\t\tbreak;\n\n\t\tcase spv::OpImageSampleDrefImplicitLod:\n\t\t\tspv_op = spv::OpImageSampleDrefExplicitLod;\n\t\t\tbreak;\n\n\t\tcase spv::OpImageSparseSampleDrefImplicitLod:\n\t\t\tspv_op = spv::OpImageSparseSampleDrefExplicitLod;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tgrad_rewrite = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (grad_rewrite)\n\t\tbuild_gradient(impl, coord, num_coords, grad_x, grad_y, bias_level_argument, image_ops);\n\n\t// Comparison sampling only returns a scalar, so we'll need to splat out result.\n\tOperation *op = impl.allocate(spv_op, instruction, sample_type);\n\n\tif (!sparse)\n\t\timpl.decorate_relaxed_precision(get_composite_element_type(instruction->getType()), op->id, true);\n\n\top->add_id(combined_image_sampler_id);\n\top->add_id(impl.build_vector(builder.makeFloatType(32), coord, num_coords_full));\n\n\tif (dref_id)\n\t\top->add_id(dref_id);\n\n\top->add_literal(image_ops);\n\n\tif (image_ops & (spv::ImageOperandsBiasMask | spv::ImageOperandsLodMask))\n\t\top->add_id(bias_level_argument);\n\n\tif (image_ops & spv::ImageOperandsGradMask)\n\t{\n\t\top->add_id(grad_x);\n\t\top->add_id(grad_y);\n\t}\n\n\tif (image_ops & (spv::ImageOperandsConstOffsetMask | spv::ImageOperandsOffsetMask))\n\t{\n\t\tspv::Id offset_vec = build_texel_offset_vector(impl, offsets, num_coords, image_ops, false);\n\t\top->add_id(offset_vec);\n\t}\n\n\tif (image_ops & spv::ImageOperandsMinLodMask)\n\t\top->add_id(min_lod_argument);\n\n\timpl.add(op);\n\n\tauto *target_type = get_composite_element_type(instruction->getType());\n\n\tif (sparse)\n\t{\n\t\t// Repack return arguments from { i32, Tx4 } into { T, T, T, T, i32 } which DXIL expects.\n\t\timpl.repack_sparse_feedback(meta.component_type, comparison_sampling ? 1 : 4, instruction, target_type);\n\t}\n\telse if (comparison_sampling)\n\t{\n\t\tspv::Id loaded_id = op->id;\n\t\tauto tmp = meta.component_type;\n\t\timpl.fixup_load_type_typed(tmp, 1, loaded_id, target_type);\n\t\tOperation *splat_op =\n\t\t\timpl.allocate(spv::OpCompositeConstruct, builder.makeVectorType(impl.get_type_id(target_type), 4));\n\t\tsplat_op->add_ids({ loaded_id, loaded_id, loaded_id, loaded_id });\n\t\timpl.add(splat_op);\n\t\timpl.rewrite_value(instruction, splat_op->id);\n\t}\n\telse\n\t{\n\t\timpl.fixup_load_type_typed(meta.component_type, 4, instruction, target_type);\n\t}\n\n\treturn true;\n}\n\nstatic bool binary_op_is_multiple_of_derivative(const llvm::Value *grad_value, const llvm::Value *coord_value,\n                                                DXIL::Op candidate_coarse_op, DXIL::Op candidate_fine_op,\n                                                const llvm::Value *&multiple)\n{\n\tconst auto *bin_op = llvm::dyn_cast<llvm::BinaryOperator>(grad_value);\n\tif (!bin_op)\n\t\treturn false;\n\n\tif (bin_op->getOpcode() != llvm::BinaryOperator::BinaryOps::FMul)\n\t\treturn false;\n\n\t// Play fast and loose if we can :3\n\tif (!bin_op->isFast())\n\t\treturn false;\n\n\tauto *a = bin_op->getOperand(0);\n\tauto *b = bin_op->getOperand(1);\n\n\tif ((value_is_dx_op_instrinsic(a, candidate_coarse_op) ||\n\t     value_is_dx_op_instrinsic(a, candidate_fine_op)))\n\t{\n\t\tif (llvm::cast<llvm::CallInst>(a)->getOperand(1) == coord_value)\n\t\t{\n\t\t\tmultiple = b;\n\t\t\treturn true;\n\t\t}\n\t}\n\telse if ((value_is_dx_op_instrinsic(b, candidate_coarse_op) ||\n\t          value_is_dx_op_instrinsic(b, candidate_fine_op)))\n\t{\n\t\tif (llvm::cast<llvm::CallInst>(b)->getOperand(1) == coord_value)\n\t\t{\n\t\t\tmultiple = a;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic spv::Id sample_grad_is_lod_bias(Converter::Impl &impl, const llvm::CallInst *instruction, unsigned num_coords,\n                                       unsigned grad_argument_index)\n{\n\tif (!impl.current_block)\n\t\treturn 0;\n\n\tif (!impl.options.grad_opt.enabled)\n\t\treturn 0;\n\n\tconst llvm::Value *mult_grad_x[3] = {};\n\tconst llvm::Value *mult_grad_y[3] = {};\n\n\tfor (unsigned i = 0; i < num_coords; i++)\n\t{\n\t\tauto *coord = instruction->getOperand(i + 3);\n\n\t\t// Don't bother trying to fiddle with constant expressions.\n\t\t// All derivatives are expected to constant-fold.\n\t\tif (llvm::isa<llvm::Constant>(coord))\n\t\t\treturn 0;\n\n\t\tauto *grad_x = instruction->getOperand(i + grad_argument_index);\n\t\tauto *grad_y = instruction->getOperand(i + grad_argument_index + 3);\n\n\t\t// Gradients must have been computed in this block,\n\t\t// otherwise we might introduce bugs with helper lanes being deactivated,\n\t\t// since this that scenario is the primary use case for grad in the first place ...\n\t\tspv::Id grad_x_id = impl.get_id_for_value(grad_x);\n\t\tspv::Id grad_y_id = impl.get_id_for_value(grad_y);\n\t\tif (!grad_x_id || !grad_y_id)\n\t\t\treturn 0;\n\n\t\tfor (auto &op : *impl.current_block)\n\t\t{\n\t\t\tif (op->id == grad_x_id)\n\t\t\t\tgrad_x_id = 0;\n\t\t\tif (op->id == grad_y_id)\n\t\t\t\tgrad_y_id = 0;\n\t\t}\n\n\t\tif (grad_x_id || grad_y_id)\n\t\t\treturn 0;\n\n\t\tif (!binary_op_is_multiple_of_derivative(grad_x, coord, DXIL::Op::DerivCoarseX, DXIL::Op::DerivFineX, mult_grad_x[i]) ||\n\t\t    !binary_op_is_multiple_of_derivative(grad_y, coord, DXIL::Op::DerivCoarseY, DXIL::Op::DerivFineY, mult_grad_y[i]))\n\t\t\treturn 0;\n\t}\n\n\tfor (unsigned i = 0; i < num_coords; i++)\n\t{\n\t\tif (!mult_grad_x[i] || !mult_grad_y[i])\n\t\t\treturn 0;\n\n\t\tif (i > 0)\n\t\t{\n\t\t\tif (mult_grad_x[i] != mult_grad_x[0])\n\t\t\t\treturn 0;\n\t\t\tif (mult_grad_y[i] != mult_grad_y[0])\n\t\t\t\treturn 0;\n\t\t}\n\t}\n\n\t// We can only apply uniform scale with textureBias, unless we have app-opt.\n\tif (mult_grad_x[0] != mult_grad_y[0] && !impl.options.grad_opt.assume_uniform_scale)\n\t\treturn 0;\n\n\tauto &builder = impl.builder();\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tspv::Id min_value_id;\n\n\tspv::Id fp32_type = builder.makeFloatType(32);\n\n\tOperation *abs_x_op = impl.allocate(spv::OpExtInst, fp32_type);\n\tabs_x_op->add_id(impl.glsl_std450_ext);\n\tabs_x_op->add_literal(GLSLstd450FAbs);\n\tabs_x_op->add_id(impl.get_id_for_value(mult_grad_x[0]));\n\timpl.add(abs_x_op);\n\n\tif (mult_grad_x[0] != mult_grad_y[0])\n\t{\n\t\tOperation *abs_y_op = impl.allocate(spv::OpExtInst, fp32_type);\n\t\tabs_y_op->add_id(impl.glsl_std450_ext);\n\t\tabs_y_op->add_literal(GLSLstd450FAbs);\n\t\tabs_y_op->add_id(impl.get_id_for_value(mult_grad_y[0]));\n\t\timpl.add(abs_y_op);\n\n\t\tOperation *min_op = impl.allocate(spv::OpExtInst, fp32_type);\n\t\tmin_op->add_id(impl.glsl_std450_ext);\n\t\tmin_op->add_literal(GLSLstd450FMin);\n\t\tmin_op->add_id(abs_x_op->id);\n\t\tmin_op->add_id(abs_y_op->id);\n\n\t\timpl.add(min_op);\n\t\tmin_value_id = min_op->id;\n\t}\n\telse\n\t{\n\t\tmin_value_id = abs_x_op->id;\n\t}\n\n\tOperation *op = impl.allocate(spv::OpExtInst, fp32_type);\n\top->add_id(impl.glsl_std450_ext);\n\top->add_literal(GLSLstd450Log2);\n\top->add_id(min_value_id);\n\timpl.add(op);\n\n\treturn op->id;\n}\n\nbool emit_sample_grad_instruction(DXIL::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tbool comparison_sampling = opcode == DXIL::Op::SampleCmpGrad;\n\n\t// Elide dead loads.\n\tif (!comparison_sampling && !impl.composite_is_accessed(instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id sampler_id = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id combined_image_sampler_id = impl.build_sampled_image(image_id, sampler_id, comparison_sampling);\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tunsigned num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\tif (num_coords == 0)\n\t{\n\t\tLOGE(\"Cannot use sampling instructions with input attachment.\\n\");\n\t\treturn false;\n\t}\n\n\tuint32_t image_ops = spv::ImageOperandsGradMask;\n\n\tspv::Id coord[4] = {};\n\tfor (unsigned i = 0; i < num_coords_full; i++)\n\t\tcoord[i] = impl.get_id_for_value(instruction->getOperand(i + 3));\n\n\tspv::Id offsets[3] = {};\n\tif (!get_texel_offsets(impl, instruction, image_ops, 7, num_coords, offsets, false))\n\t\treturn false;\n\n\tunsigned grad_argument_index = comparison_sampling ? 11 : 10;\n\tspv::Id bias_id = sample_grad_is_lod_bias(impl, instruction, num_coords, grad_argument_index);\n\n\tspv::Id grad_x[3] = {};\n\tspv::Id grad_y[3] = {};\n\n\tif (bias_id)\n\t{\n\t\timage_ops = spv::ImageOperandsBiasMask;\n\t}\n\telse\n\t{\n\t\tfor (unsigned i = 0; i < num_coords; i++)\n\t\t\tgrad_x[i] = impl.get_id_for_value(instruction->getOperand(i + grad_argument_index));\n\t\tfor (unsigned i = 0; i < num_coords; i++)\n\t\t\tgrad_y[i] = impl.get_id_for_value(instruction->getOperand(i + grad_argument_index + 3));\n\t}\n\n\tunsigned min_lod_argument_index = comparison_sampling ? 17 : 16;\n\tspv::Id aux_argument = 0;\n\tauto min_lod_argument_value = instruction->getOperand(min_lod_argument_index);\n\tif (llvm::isa<llvm::UndefValue>(min_lod_argument_value))\n\t{\n\t\t// No value set\n\t}\n\telse if (llvm::isa<llvm::ConstantFP>(min_lod_argument_value) && llvm::cast<llvm::ConstantFP>(min_lod_argument_value)->getValueAPF().convertToFloat() == 0)\n\t{\n\t\t// LOD values less than 0 are invalid, so this is a no-op.\n\t}\n\telse\n\t{\n\t\taux_argument = impl.get_id_for_value(min_lod_argument_value);\n\t\timage_ops |= spv::ImageOperandsMinLodMask;\n\t\tbuilder.addCapability(spv::CapabilityMinLod);\n\t}\n\n\tauto &access_meta = impl.llvm_composite_meta[instruction];\n\tbool sparse = (access_meta.access_mask & (1u << 4)) != 0;\n\tif (sparse)\n\t\tbuilder.addCapability(spv::CapabilitySparseResidency);\n\n\tauto effective_component_type = Converter::Impl::get_effective_typed_resource_type(meta.component_type);\n\tspv::Id texel_type = impl.get_type_id(effective_component_type, 1, comparison_sampling ? 1 : 4);\n\tspv::Id sample_type;\n\n\tif (sparse)\n\t\tsample_type = impl.get_struct_type({ builder.makeUintType(32), texel_type }, 0, \"SparseTexel\");\n\telse\n\t\tsample_type = texel_type;\n\n\tspv::Id dref_id = 0;\n\tspv::Op spv_op;\n\tif (comparison_sampling)\n\t{\n\t\tif (bias_id)\n\t\t\tspv_op = sparse ? spv::OpImageSparseSampleDrefImplicitLod : spv::OpImageSampleDrefImplicitLod;\n\t\telse\n\t\t\tspv_op = sparse ? spv::OpImageSparseSampleDrefExplicitLod : spv::OpImageSampleDrefExplicitLod;\n\n\t\tdref_id = impl.get_id_for_value(instruction->getOperand(10));\n\t}\n\telse\n\t{\n\t\tif (bias_id)\n\t\t\tspv_op = sparse ? spv::OpImageSparseSampleImplicitLod : spv::OpImageSampleImplicitLod;\n\t\telse\n\t\t\tspv_op = sparse ? spv::OpImageSparseSampleExplicitLod : spv::OpImageSampleExplicitLod;\n\t}\n\n\tOperation *op = impl.allocate(spv_op, instruction, sample_type);\n\n\tif (!sparse)\n\t\timpl.decorate_relaxed_precision(get_composite_element_type(instruction->getType()), op->id, true);\n\n\top->add_id(combined_image_sampler_id);\n\top->add_id(impl.build_vector(builder.makeFloatType(32), coord, num_coords_full));\n\n\tif (dref_id)\n\t\top->add_id(dref_id);\n\n\top->add_literal(image_ops);\n\n\tif (image_ops & spv::ImageOperandsGradMask)\n\t{\n\t\top->add_id(impl.build_vector(builder.makeFloatType(32), grad_x, num_coords));\n\t\top->add_id(impl.build_vector(builder.makeFloatType(32), grad_y, num_coords));\n\t}\n\telse if (image_ops & spv::ImageOperandsBiasMask)\n\t\top->add_id(bias_id);\n\n\tif (image_ops & (spv::ImageOperandsConstOffsetMask | spv::ImageOperandsOffsetMask))\n\t\top->add_id(build_texel_offset_vector(impl, offsets, num_coords, image_ops, false));\n\n\tif (image_ops & spv::ImageOperandsMinLodMask)\n\t\top->add_id(aux_argument);\n\n\timpl.add(op);\n\n\tauto *target_type = get_composite_element_type(instruction->getType());\n\n\tif (sparse)\n\t\timpl.repack_sparse_feedback(meta.component_type, comparison_sampling ? 1 : 4, instruction, target_type);\n\telse if (comparison_sampling)\n\t{\n\t\tspv::Id loaded_id = op->id;\n\t\tauto tmp = meta.component_type;\n\t\timpl.fixup_load_type_typed(tmp, 1, loaded_id, target_type);\n\t\tOperation *splat_op =\n\t\t\timpl.allocate(spv::OpCompositeConstruct, builder.makeVectorType(impl.get_type_id(target_type), 4));\n\t\tsplat_op->add_ids({ loaded_id, loaded_id, loaded_id, loaded_id });\n\t\timpl.add(splat_op);\n\t\timpl.rewrite_value(instruction, splat_op->id);\n\t}\n\telse\n\t{\n\t\timpl.fixup_load_type_typed(meta.component_type, 4, instruction, target_type);\n\t}\n\n\treturn true;\n}\n\nbool emit_texture_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// Elide dead loads.\n\tif (!impl.composite_is_accessed(instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id image_type_id = impl.get_type_id(image_id);\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tbool is_uav = builder.isStorageImageType(image_type_id);\n\tuint32_t image_ops = 0;\n\n\tspv::Id mip_or_sample = 0;\n\tif (!llvm::isa<llvm::UndefValue>(instruction->getOperand(2)))\n\t{\n\t\tmip_or_sample = impl.get_id_for_value(instruction->getOperand(2));\n\t\tif (builder.isMultisampledImageType(image_type_id))\n\t\t\timage_ops |= spv::ImageOperandsSampleMask;\n\t\telse\n\t\t\timage_ops |= spv::ImageOperandsLodMask;\n\t}\n\n\tspv::Id coord[3] = {};\n\n\tunsigned num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\t// Cubes are not supported here.\n\tif (num_coords_full > 3)\n\t\treturn false;\n\n\tfor (unsigned i = 0; i < num_coords_full; i++)\n\t\tcoord[i] = impl.get_id_for_value(instruction->getOperand(i + 3));\n\n\tspv::Id offsets[4] = {};\n\tif (num_coords != 0 && !get_texel_offsets(impl, instruction, image_ops, 6, num_coords, offsets, false))\n\t\treturn false;\n\n\tauto &access_meta = impl.llvm_composite_meta[instruction];\n\tbool sparse = (access_meta.access_mask & (1u << 4)) != 0;\n\tif (sparse)\n\t{\n\t\tif (num_coords == 0)\n\t\t{\n\t\t\tLOGE(\"InputAttachment does not support sparse residency query.\\n\");\n\t\t\treturn false;\n\t\t}\n\t\tbuilder.addCapability(spv::CapabilitySparseResidency);\n\t}\n\n\tauto effective_component_type = Converter::Impl::get_effective_typed_resource_type(meta.component_type);\n\tspv::Id texel_type = impl.get_type_id(effective_component_type, 1, 4);\n\tspv::Id sample_type;\n\n\tif (sparse)\n\t\tsample_type = impl.get_struct_type({ builder.makeUintType(32), texel_type }, 0, \"SparseTexel\");\n\telse\n\t\tsample_type = texel_type;\n\n\tspv::Op opcode;\n\tif (num_coords == 0)\n\t{\n\t\topcode = spv::OpImageRead;\n\t\timage_ops &= ~spv::ImageOperandsLodMask;\n\t}\n\telse if (is_uav)\n\t\topcode = sparse ? spv::OpImageSparseRead : spv::OpImageRead;\n\telse\n\t\topcode = sparse ? spv::OpImageSparseFetch : spv::OpImageFetch;\n\n\tOperation *op = impl.allocate(opcode, instruction, sample_type);\n\tif (!sparse)\n\t\timpl.decorate_relaxed_precision(get_composite_element_type(instruction->getType()), op->id, true);\n\n\tspv::Id coord_id;\n\tif (num_coords == 0) // SubpassInput\n\t\tcoord_id = impl.build_splat_constant_vector(builder.makeUintType(32), builder.makeUintConstant(0), 2);\n\telse\n\t\tcoord_id = impl.build_vector(builder.makeUintType(32), coord, num_coords_full);\n\n\tif (!is_uav && (image_ops & spv::ImageOperandsOffsetMask))\n\t{\n\t\t// Don't need fancy features for fetch, just do arith.\n\t\tfor (unsigned i = num_coords; i < num_coords_full; i++)\n\t\t\toffsets[i] = builder.makeIntConstant(0);\n\t\tauto *add_op = impl.allocate(spv::OpIAdd, impl.build_vector_type(builder.makeIntType(32), num_coords_full));\n\t\tadd_op->add_id(coord_id);\n\t\tadd_op->add_id(build_texel_offset_vector(impl, offsets, num_coords_full, image_ops, false));\n\t\timpl.add(add_op);\n\t\tcoord_id = add_op->id;\n\t\timage_ops &= ~spv::ImageOperandsOffsetMask;\n\t}\n\n\top->add_ids({ image_id, coord_id });\n\top->add_literal(image_ops);\n\n\tif (!is_uav)\n\t{\n\t\tif (image_ops & spv::ImageOperandsLodMask)\n\t\t\top->add_id(mip_or_sample);\n\n\t\tif (image_ops & spv::ImageOperandsConstOffsetMask)\n\t\t\top->add_id(build_texel_offset_vector(impl, offsets, num_coords, image_ops, false));\n\t}\n\n\tif (image_ops & spv::ImageOperandsSampleMask)\n\t{\n\t\top->add_id(mip_or_sample);\n\t\tif (is_uav)\n\t\t\timpl.builder().addCapability(spv::CapabilityStorageImageMultisample);\n\t}\n\n\tadd_vkmm_access_qualifiers(impl, op, meta.vkmm);\n\timpl.add(op, meta.rov);\n\n\tauto *target_type = get_composite_element_type(instruction->getType());\n\n\tif (sparse)\n\t\timpl.repack_sparse_feedback(meta.component_type, 4, instruction, target_type);\n\telse\n\t\timpl.fixup_load_type_typed(meta.component_type, 4, instruction, target_type);\n\treturn true;\n}\n\nbool emit_get_dimensions_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool extended)\n{\n\tif (!impl.composite_is_accessed(instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id image_type_id = impl.get_type_id(image_id);\n\tauto &meta = impl.handle_to_resource_meta[image_id];\n\n\tuint32_t ssbo_element_size = 4;\n\tuint32_t divider = 1;\n\n\tif (extended && !get_constant_operand(instruction, 3, &divider))\n\t\treturn false;\n\n\tOperation *levels_or_samples_op = nullptr;\n\tOperation *dimensions_op = nullptr;\n\tauto &access_meta = impl.llvm_composite_meta[instruction];\n\tuint32_t num_coords = 0;\n\tbool has_samples = false;\n\tbool has_lod = false;\n\n\tif (meta.storage == spv::StorageClassStorageBuffer)\n\t{\n\t\tif (meta.index_offset_id)\n\t\t{\n\t\t\tdimensions_op = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\t\t\tdimensions_op->add_id(meta.index_offset_id);\n\t\t\tdimensions_op->add_literal(1);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdimensions_op = impl.allocate(spv::OpArrayLength, builder.makeUintType(32));\n\t\t\tdimensions_op->add_id(image_id);\n\t\t\tdimensions_op->add_literal(0);\n\t\t}\n\n\t\tssbo_element_size = raw_vecsize_to_vecsize(meta.raw_component_vecsize) *\n\t\t                    raw_component_type_to_bits(meta.component_type) / 8;\n\n\t\timpl.add(dimensions_op);\n\t\tnum_coords = 1;\n\t}\n\telse if (meta.index_offset_id)\n\t{\n\t\tdimensions_op = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\t\tdimensions_op->add_id(meta.index_offset_id);\n\t\tdimensions_op->add_literal(1);\n\t\timpl.add(dimensions_op);\n\t\tnum_coords = 1;\n\t}\n\telse\n\t{\n\t\tif (!get_image_dimensions_query_size(impl, builder, image_id, &num_coords))\n\t\t\treturn false;\n\n\t\tbool is_uav = builder.isStorageImageType(image_type_id);\n\t\thas_samples = builder.isMultisampledImageType(image_type_id);\n\t\thas_lod = !is_uav && builder.getTypeDimensionality(image_type_id) != spv::DimBuffer && !has_samples;\n\n\t\tspv::Id dim_type_id = builder.makeUintType(32);\n\t\tif (num_coords > 1)\n\t\t\tdim_type_id = builder.makeVectorType(dim_type_id, num_coords);\n\n\t\t// 22.4.14 resinfo. Querying for mip level out of range should return 0.\n\t\tspv::Id level_in_range_id = 0;\n\n\t\tif ((access_meta.access_mask & 7) != 0)\n\t\t{\n\t\t\tdimensions_op = impl.allocate(has_lod ? spv::OpImageQuerySizeLod : spv::OpImageQuerySize, dim_type_id);\n\t\t\tdimensions_op->add_id(image_id);\n\t\t\tif (has_lod)\n\t\t\t\tdimensions_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\t\timpl.add(dimensions_op);\n\n\t\t\tif (has_lod)\n\t\t\t{\n\t\t\t\tauto *level_operand = instruction->getOperand(2);\n\t\t\t\tif (!llvm::isa<llvm::ConstantInt>(level_operand) ||\n\t\t\t\t    llvm::cast<llvm::ConstantInt>(level_operand)->getUniqueInteger().getZExtValue() != 0)\n\t\t\t\t{\n\t\t\t\t\tauto *levels = impl.allocate(spv::OpImageQueryLevels, builder.makeUintType(32));\n\t\t\t\t\tlevels->add_id(image_id);\n\t\t\t\t\timpl.add(levels);\n\n\t\t\t\t\tauto *cmp = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\t\t\t\t\tcmp->add_id(impl.get_id_for_value(level_operand));\n\t\t\t\t\tcmp->add_id(levels->id);\n\t\t\t\t\timpl.add(cmp);\n\n\t\t\t\t\tlevel_in_range_id = cmp->id;\n\n\t\t\t\t\tif (num_coords > 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Not needed in SPIR-V 1.4+, but for now we can emit SPIR-V 1.3.\n\t\t\t\t\t\tspv::Id coords_vec[4];\n\t\t\t\t\t\tfor (uint32_t i = 0; i < num_coords; i++)\n\t\t\t\t\t\t\tcoords_vec[i] = cmp->id;\n\t\t\t\t\t\tlevel_in_range_id = impl.build_vector(builder.makeBoolType(), coords_vec, num_coords);\n\t\t\t\t\t}\n\n\t\t\t\t\tauto *select = impl.allocate(spv::OpSelect, dim_type_id);\n\t\t\t\t\tselect->add_id(level_in_range_id);\n\t\t\t\t\tselect->add_id(dimensions_op->id);\n\t\t\t\t\tselect->add_id(builder.makeNullConstant(dim_type_id));\n\t\t\t\t\timpl.add(select);\n\n\t\t\t\t\tdimensions_op = select;\n\n\t\t\t\t\t// If we also need levels, no need to query twice.\n\t\t\t\t\tif ((access_meta.access_mask & (1u << 3)) != 0)\n\t\t\t\t\t\tlevels_or_samples_op = levels;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tnum_coords = 0;\n\t}\n\n\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t{\n\t\tif (divider != 1 && ssbo_element_size % divider == 0)\n\t\t{\n\t\t\t// Fold the mult/div. A compiler cannot do it since IMul may overflow in theory.\n\t\t\tssbo_element_size /= divider;\n\t\t\tdivider = 1;\n\t\t}\n\n\t\tif (ssbo_element_size != 1)\n\t\t{\n\t\t\tOperation *byte_size_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\t\t\tbyte_size_op->add_ids({ dimensions_op->id, builder.makeUintConstant(ssbo_element_size) });\n\t\t\timpl.add(byte_size_op);\n\t\t\tdimensions_op = byte_size_op;\n\t\t}\n\n\t\tif (divider != 1)\n\t\t{\n\t\t\tOperation *elements_op = impl.allocate(spv::OpUDiv, builder.makeUintType(32));\n\t\t\telements_op->add_ids({ dimensions_op->id, builder.makeUintConstant(divider) });\n\t\t\timpl.add(elements_op);\n\t\t\tdimensions_op = elements_op;\n\t\t}\n\t}\n\telse if (meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t{\n\t\tOperation *elem_count_op = impl.allocate(spv::OpUDiv, builder.makeUintType(32));\n\n\t\tif (meta.index_offset_id != 0)\n\t\t{\n\t\t\t// If the offset buffer is pre-shifted, shift the divider as well.\n\t\t\tif (!meta.aliased)\n\t\t\t\telem_count_op->add_ids({ dimensions_op->id, builder.makeUintConstant(meta.stride / ssbo_element_size) });\n\t\t\telse\n\t\t\t\telem_count_op->add_ids({ dimensions_op->id, builder.makeUintConstant(meta.stride) });\n\t\t}\n\t\telse\n\t\t\telem_count_op->add_ids({ dimensions_op->id, builder.makeUintConstant(meta.stride / ssbo_element_size) });\n\n\t\timpl.add(elem_count_op);\n\t\tdimensions_op = elem_count_op;\n\t}\n\n\tif (!levels_or_samples_op && (access_meta.access_mask & (1u << 3)) != 0)\n\t{\n\t\tif (has_lod)\n\t\t{\n\t\t\tlevels_or_samples_op = impl.allocate(spv::OpImageQueryLevels, builder.makeUintType(32));\n\t\t\tlevels_or_samples_op->add_id(image_id);\n\t\t\timpl.add(levels_or_samples_op);\n\t\t}\n\t\telse if (has_samples)\n\t\t{\n\t\t\tlevels_or_samples_op = impl.allocate(spv::OpImageQuerySamples, builder.makeUintType(32));\n\t\t\tlevels_or_samples_op->add_id(image_id);\n\t\t\timpl.add(levels_or_samples_op);\n\t\t}\n\t}\n\n\tassert(levels_or_samples_op || dimensions_op);\n\n\tif (!levels_or_samples_op && dimensions_op)\n\t{\n\t\tif (num_coords == 1)\n\t\t\taccess_meta.forced_composite = false;\n\t\timpl.rewrite_value(instruction, dimensions_op->id);\n\t}\n\telse if (dimensions_op)\n\t{\n\t\tOperation *op =\n\t\t    impl.allocate(spv::OpCompositeConstruct, instruction, builder.makeVectorType(builder.makeUintType(32), 4));\n\t\top->add_id(dimensions_op->id);\n\n\t\t// This element cannot be statically accessed if we don't have LOD, so don't bother returning anything here.\n\t\t// Otherwise, we need to pad out.\n\t\tfor (unsigned i = num_coords; i < 3; i++)\n\t\t\top->add_id(builder.createUndefined(builder.makeUintType(32)));\n\t\top->add_id(levels_or_samples_op->id);\n\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\t// Redirect any extract from this scalar to be preserved as-is.\n\t\t// Pretend this is a scalar even if Levels/Samples query is supposed to live in W.\n\t\taccess_meta.forced_composite = false;\n\t\taccess_meta.access_mask = 1;\n\t\taccess_meta.components = 1;\n\t\timpl.rewrite_value(instruction, levels_or_samples_op->id);\n\t}\n\n\tbuilder.addCapability(spv::CapabilityImageQuery);\n\treturn true;\n}\n\nbool emit_texture_store_instruction_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction, bool multi_sampled)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\t// Deferred 64-bit atomic. Resolve in a later AGS atomic.\n\tif (emit_ags_texture_store(impl, instruction, image_id, multi_sampled))\n\t\treturn true;\n\tif (emit_nvapi_buffer_store(impl, instruction, image_id))\n\t\treturn true;\n\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\tspv::Id coord[3] = {};\n\n\tunsigned num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\t// Cubes are not supported here.\n\tif (num_coords_full > 3)\n\t\treturn false;\n\n\tfor (unsigned i = 0; i < num_coords_full; i++)\n\t\tcoord[i] = impl.get_id_for_value(instruction->getOperand(i + 2));\n\n\tspv::Id write_values[4] = {};\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\timpl.register_externally_visible_write(instruction->getOperand(i + 5));\n\t\twrite_values[i] = impl.get_id_for_value(instruction->getOperand(i + 5));\n\t}\n\n\t// Ignore write mask. We cannot do anything meaningful about it.\n\t// The write mask must cover all components in the image, and there is no \"sliced write\" support for typed resources.\n\n\tOperation *op = impl.allocate(spv::OpImageWrite);\n\n\top->add_id(image_id);\n\top->add_id(impl.build_vector(builder.makeUintType(32), coord, num_coords_full));\n\n\tspv::Id store_id = impl.build_vector(impl.get_type_id(instruction->getOperand(5)->getType()), write_values, 4);\n\tstore_id = impl.fixup_store_type_typed(meta.component_type, 4, store_id);\n\top->add_id(store_id);\n\tbuilder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);\n\n\tif (multi_sampled)\n\t{\n\t\tspv::Id sample_id = impl.get_id_for_value(instruction->getOperand(10));\n\t\top->add_literal(spv::ImageOperandsSampleMask);\n\t\top->add_id(sample_id);\n\t\tbuilder.addCapability(spv::CapabilityStorageImageMultisample);\n\t}\n\n\tadd_vkmm_access_qualifiers(impl, op, meta.vkmm);\n\n\timpl.add(op, meta.rov);\n\treturn true;\n}\n\nbool emit_texture_gather_instruction(bool compare, bool raw, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// Elide dead loads.\n\tif (!impl.composite_is_accessed(instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id sampler_id = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id combined_image_sampler_id = impl.build_sampled_image(image_id, sampler_id, compare);\n\tconst auto &meta = impl.handle_to_resource_meta[image_id];\n\n\tuint32_t num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\tif (num_coords == 0)\n\t{\n\t\tLOGE(\"Cannot use gather instructions with input attachment.\\n\");\n\t\treturn false;\n\t}\n\n\tspv::Id coords[4] = {};\n\tspv::Id offsets[2] = {};\n\tuint32_t image_flags = 0;\n\n\tfor (unsigned i = 0; i < num_coords_full; i++)\n\t\tcoords[i] = impl.get_id_for_value(instruction->getOperand(3 + i));\n\tspv::Id coord_id = impl.build_vector(builder.makeFloatType(32), coords, num_coords_full);\n\n\tif (num_coords == 2 && !get_texel_offsets(impl, instruction, image_flags, 7, num_coords, offsets, true))\n\t\treturn false;\n\n\tspv::Id aux_id;\n\n\tif (!raw)\n\t{\n\t\tif (compare)\n\t\t{\n\t\t\t// TextureGatherCmp has a component here. Perhaps it is to select depth vs stencil?\n\t\t\taux_id = impl.get_id_for_value(instruction->getOperand(10));\n\t\t}\n\t\telse\n\t\t\taux_id = impl.get_id_for_value(instruction->getOperand(9));\n\t}\n\telse\n\t\taux_id = builder.makeUintConstant(0);\n\n\tauto &access_meta = impl.llvm_composite_meta[instruction];\n\tbool sparse = (access_meta.access_mask & (1u << 4)) != 0;\n\tif (sparse)\n\t\tbuilder.addCapability(spv::CapabilitySparseResidency);\n\n\tauto effective_component_type = Converter::Impl::get_effective_typed_resource_type(meta.component_type);\n\tspv::Id texel_type = impl.get_type_id(effective_component_type, 1, 4);\n\tspv::Id sample_type;\n\n\tif (sparse)\n\t\tsample_type = impl.get_struct_type({ builder.makeUintType(32), texel_type }, 0, \"SparseTexel\");\n\telse\n\t\tsample_type = texel_type;\n\n\tbool raw_gather64 = raw && get_composite_element_type(instruction->getType())->getIntegerBitWidth() == 64;\n\n\tspv::Op opcode;\n\tif (compare)\n\t\topcode = sparse ? spv::OpImageSparseDrefGather : spv::OpImageDrefGather;\n\telse\n\t\topcode = sparse ? spv::OpImageSparseGather : spv::OpImageGather;\n\n\tOperation *op = impl.allocate(opcode, instruction, sample_type);\n\tif (!sparse)\n\t\timpl.decorate_relaxed_precision(get_composite_element_type(instruction->getType()), op->id, true);\n\n\top->add_ids({ combined_image_sampler_id, coord_id, aux_id });\n\n\tspv::Id texel_offset_id = 0;\n\tif (image_flags)\n\t{\n\t\top->add_literal(image_flags);\n\t\ttexel_offset_id = build_texel_offset_vector(impl, offsets, num_coords, image_flags, true);\n\t\top->add_id(texel_offset_id);\n\t}\n\n\timpl.add(op);\n\n\tif (raw_gather64)\n\t{\n\t\tOperation *op_green = impl.allocate(spv::OpImageGather, texel_type);\n\t\top_green->add_ids({ combined_image_sampler_id, coord_id, builder.makeUintConstant(1) });\n\n\t\tif (image_flags)\n\t\t{\n\t\t\top_green->add_literal(image_flags);\n\t\t\top_green->add_id(texel_offset_id);\n\t\t}\n\n\t\timpl.add(op_green);\n\n\t\tspv::Id components64[4];\n\t\tspv::Id gather_result;\n\n\t\tif (sparse)\n\t\t{\n\t\t\tauto *extract_value = impl.allocate(spv::OpCompositeExtract, texel_type);\n\t\t\tgather_result = extract_value->id;\n\t\t\textract_value->add_id(op->id);\n\t\t\textract_value->add_literal(1);\n\t\t\timpl.add(extract_value);\n\t\t}\n\t\telse\n\t\t\tgather_result = op->id;\n\n\t\tfor (unsigned i = 0; i < 4; i++)\n\t\t{\n\t\t\tauto *extr0 = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\t\t\tauto *extr1 = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(32));\n\n\t\t\textr0->add_id(gather_result);\n\t\t\textr0->add_literal(i);\n\t\t\textr1->add_id(op_green->id);\n\t\t\textr1->add_literal(i);\n\n\t\t\timpl.add(extr0);\n\t\t\timpl.add(extr1);\n\n\t\t\tspv::Id components[2] = { extr0->id, extr1->id };\n\t\t\tspv::Id value = impl.build_vector(builder.makeUintType(32), components, 2);\n\t\t\tauto *bitcast_64 = impl.allocate(spv::OpBitcast, builder.makeUintType(64));\n\t\t\tbitcast_64->add_id(value);\n\t\t\tcomponents64[i] = bitcast_64->id;\n\n\t\t\timpl.add(bitcast_64);\n\t\t}\n\n\t\tspv::Id u64_vector = impl.build_vector(builder.makeUintType(64), components64, 4);\n\n\t\tif (sparse)\n\t\t{\n\t\t\tauto *target_type = get_composite_element_type(instruction->getType());\n\t\t\timpl.repack_sparse_feedback(DXIL::ComponentType::U64, 4, instruction, target_type, u64_vector);\n\t\t}\n\t\telse\n\t\t{\n\t\t\timpl.rewrite_value(instruction, u64_vector);\n\t\t}\n\t}\n\telse\n\t{\n\t\tauto *target_type = get_composite_element_type(instruction->getType());\n\n\t\tif (sparse)\n\t\t\timpl.repack_sparse_feedback(meta.component_type, 4, instruction, target_type);\n\t\telse\n\t\t\timpl.fixup_load_type_typed(meta.component_type, 4, instruction, target_type);\n\t}\n\n\treturn true;\n}\n\nstatic spv::Id build_lod_from_gradient(Converter::Impl &impl, spv::Id grad_x, spv::Id grad_y)\n{\n\tauto &builder = impl.builder();\n\tspv::Id f32_type = builder.makeFloatType(32);\n\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tauto *dot_x = impl.allocate(spv::OpDot, f32_type);\n\tdot_x->add_id(grad_x);\n\tdot_x->add_id(grad_x);\n\timpl.add(dot_x);\n\n\tauto *dot_y = impl.allocate(spv::OpDot, f32_type);\n\tdot_y->add_id(grad_y);\n\tdot_y->add_id(grad_y);\n\timpl.add(dot_y);\n\n\tauto *dot_max = impl.allocate(spv::OpExtInst, f32_type);\n\tdot_max->add_id(impl.glsl_std450_ext);\n\tdot_max->add_literal(GLSLstd450FMax);\n\tdot_max->add_id(dot_x->id);\n\tdot_max->add_id(dot_y->id);\n\timpl.add(dot_max);\n\n\tauto *log_op = impl.allocate(spv::OpExtInst, f32_type);\n\tlog_op->add_id(impl.glsl_std450_ext);\n\tlog_op->add_literal(GLSLstd450Log2);\n\tlog_op->add_id(dot_max->id);\n\timpl.add(log_op);\n\n\tauto *half_mul = impl.allocate(spv::OpFMul, f32_type);\n\thalf_mul->add_id(log_op->id);\n\thalf_mul->add_id(builder.makeFloatConstant(0.5f));\n\timpl.add(half_mul);\n\n\treturn half_mul->id;\n}\n\nstatic spv::Id emit_cube_extract_str(Converter::Impl &impl, spv::Id coord,\n                                     spv::Id z_major_id, spv::Id y_major_id)\n{\n\tauto &builder = impl.builder();\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id vec3_type = builder.makeVectorType(f32_type, 3);\n\n\tauto *y_major_shuffle = impl.allocate(spv::OpVectorShuffle, vec3_type);\n\ty_major_shuffle->add_id(coord);\n\ty_major_shuffle->add_id(coord);\n\ty_major_shuffle->add_literal(0);\n\ty_major_shuffle->add_literal(2);\n\ty_major_shuffle->add_literal(1);\n\timpl.add(y_major_shuffle);\n\n\tauto *x_major_shuffle = impl.allocate(spv::OpVectorShuffle, vec3_type);\n\tx_major_shuffle->add_id(coord);\n\tx_major_shuffle->add_id(coord);\n\tx_major_shuffle->add_literal(2);\n\tx_major_shuffle->add_literal(1);\n\tx_major_shuffle->add_literal(0);\n\n\timpl.add(x_major_shuffle);\n\tauto *z_major_splat3 = impl.allocate(spv::OpCompositeConstruct, builder.makeVectorType(builder.makeBoolType(), 3));\n\tfor (unsigned i = 0; i < 3; i++)\n\t\tz_major_splat3->add_id(z_major_id);\n\timpl.add(z_major_splat3);\n\n\tauto *y_major_splat4 = impl.allocate(spv::OpCompositeConstruct, builder.makeVectorType(builder.makeBoolType(), 3));\n\tfor (unsigned i = 0; i < 3; i++)\n\t\ty_major_splat4->add_id(y_major_id);\n\timpl.add(y_major_splat4);\n\n\tauto *yx_select = impl.allocate(spv::OpSelect, vec3_type);\n\tyx_select->add_id(y_major_splat4->id);\n\tyx_select->add_id(y_major_shuffle->id);\n\tyx_select->add_id(x_major_shuffle->id);\n\timpl.add(yx_select);\n\n\tauto *reordered = impl.allocate(spv::OpSelect, vec3_type);\n\treordered->add_id(z_major_splat3->id);\n\treordered->add_id(coord);\n\treordered->add_id(yx_select->id);\n\timpl.add(reordered);\n\n\treturn reordered->id;\n}\n\nstatic void emit_calculate_lod_cube_gradient_transform(Converter::Impl &impl,\n                                                       spv::Id coord_vec, spv::Id dx, spv::Id dy,\n                                                       spv::Id &out_dx, spv::Id &out_dy)\n{\n\tauto &builder = impl.builder();\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id vec2_type = builder.makeVectorType(f32_type, 2);\n\tspv::Id vec3_type = builder.makeVectorType(f32_type, 3);\n\tspv::Id vec4_type = builder.makeVectorType(f32_type, 4);\n\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tbuilder.addName(coord_vec, \"coord\");\n\tbuilder.addName(dx, \"d_coord_dx\");\n\tbuilder.addName(dy, \"d_coord_dy\");\n\n\t// See 7.18.11 of D3D11 functional spec\n\t// 16.5.6 - Cube Map Derivative Transform in Vulkan spec\n\tauto *coord_abs = impl.allocate(spv::OpExtInst, vec3_type);\n\tcoord_abs->add_id(impl.glsl_std450_ext);\n\tcoord_abs->add_literal(GLSLstd450FAbs);\n\tcoord_abs->add_id(coord_vec);\n\timpl.add(coord_abs);\n\tbuilder.addName(coord_abs->id, \"abs_uvw\");\n\n\tspv::Id max_component_id = 0;\n\tspv::Id abs_components[3];\n\tfor (unsigned i = 0; i < 3; i++)\n\t{\n\t\tauto *extract = impl.allocate(spv::OpCompositeExtract, f32_type);\n\t\textract->add_id(coord_abs->id);\n\t\textract->add_literal(i);\n\t\timpl.add(extract);\n\t\tabs_components[i] = extract->id;\n\n\t\tif (max_component_id != 0)\n\t\t{\n\t\t\tauto *max_comp = impl.allocate(spv::OpExtInst, f32_type);\n\t\t\tmax_comp->add_id(impl.glsl_std450_ext);\n\t\t\tmax_comp->add_literal(GLSLstd450FMax);\n\t\t\tmax_comp->add_id(extract->id);\n\t\t\tmax_comp->add_id(max_component_id);\n\t\t\timpl.add(max_comp);\n\t\t\tmax_component_id = max_comp->id;\n\t\t}\n\t\telse\n\t\t\tmax_component_id = extract->id;\n\t}\n\n\tbuilder.addName(max_component_id, \"max_component\");\n\n\t// Shuffle components based on major axis.\n\t// Ordering of the minor axes isn't interesting since our LOD computation is rotationally invariant and sign invariant,\n\t// and cube faces are square.\n\n\t// Z takes precedence, then Y.\n\tauto *z_major = impl.allocate(spv::OpFOrdGreaterThanEqual, builder.makeBoolType());\n\tz_major->add_id(abs_components[2]);\n\tz_major->add_id(max_component_id);\n\timpl.add(z_major);\n\tbuilder.addName(z_major->id, \"z_major\");\n\n\tauto *y_major = impl.allocate(spv::OpFOrdGreaterThanEqual, builder.makeBoolType());\n\ty_major->add_id(abs_components[1]);\n\ty_major->add_id(max_component_id);\n\timpl.add(y_major);\n\tbuilder.addName(y_major->id, \"y_major\");\n\n\tauto *r_sqr = impl.allocate(spv::OpFMul, f32_type);\n\tr_sqr->add_id(max_component_id);\n\tr_sqr->add_id(max_component_id);\n\timpl.add(r_sqr);\n\n\tauto *r_sqr_inv_half = impl.allocate(spv::OpFDiv, f32_type);\n\tr_sqr_inv_half->add_id(builder.makeFloatConstant(0.5f));\n\tr_sqr_inv_half->add_id(r_sqr->id);\n\timpl.add(r_sqr_inv_half);\n\n\t// [ dsdx, dtdx, drdx ]\n\tspv::Id d_coord_dx = emit_cube_extract_str(impl, dx, z_major->id, y_major->id);\n\t// [ dsdy, dtdy, drdy ]\n\tspv::Id d_coord_dy = emit_cube_extract_str(impl, dy, z_major->id, y_major->id);\n\t// [ s, t, r ]\n\tspv::Id coords = emit_cube_extract_str(impl, coord_vec, z_major->id, y_major->id);\n\n\tbuilder.addName(d_coord_dx, \"d_str_dx\");\n\tbuilder.addName(d_coord_dy, \"d_str_dy\");\n\tbuilder.addName(coords, \"str\");\n\n\t// [ dsdx, dtdx, dsdy, dtdy ]\n\tauto *st_gradients = impl.allocate(spv::OpVectorShuffle, vec4_type);\n\tst_gradients->add_id(d_coord_dx);\n\tst_gradients->add_id(d_coord_dy);\n\tst_gradients->add_literal(0);\n\tst_gradients->add_literal(3);\n\tst_gradients->add_literal(1);\n\tst_gradients->add_literal(4);\n\timpl.add(st_gradients);\n\n\t// [ s, s, t, t ]\n\tauto *st_coords = impl.allocate(spv::OpVectorShuffle, vec4_type);\n\tst_coords->add_id(coords);\n\tst_coords->add_id(coords);\n\tst_coords->add_literal(0);\n\tst_coords->add_literal(0);\n\tst_coords->add_literal(1);\n\tst_coords->add_literal(1);\n\timpl.add(st_coords);\n\n\t// [ drdx, drdy, drdx, drdy ]\n\tauto *r_gradients = impl.allocate(spv::OpVectorShuffle, vec4_type);\n\tr_gradients->add_id(d_coord_dx);\n\tr_gradients->add_id(d_coord_dy);\n\tr_gradients->add_literal(2);\n\tr_gradients->add_literal(5);\n\tr_gradients->add_literal(2);\n\tr_gradients->add_literal(5);\n\timpl.add(r_gradients);\n\n\t// |r_c| * [ dsdx, dtdx, dsdy, dtdy ]\n\tauto *st_gradient_times_r = impl.allocate(spv::OpVectorTimesScalar, vec4_type);\n\tst_gradient_times_r->add_id(st_gradients->id);\n\tst_gradient_times_r->add_id(max_component_id);\n\timpl.add(st_gradient_times_r);\n\n\t// [ s, s, t, t ] * [ drdx, drdy, drdx, drdy ]\n\tauto *coord_times_r_gradient = impl.allocate(spv::OpFMul, vec4_type);\n\tcoord_times_r_gradient->add_id(st_coords->id);\n\tcoord_times_r_gradient->add_id(r_gradients->id);\n\timpl.add(coord_times_r_gradient);\n\n\tauto *sub = impl.allocate(spv::OpFSub, vec4_type);\n\tsub->add_id(st_gradient_times_r->id);\n\tsub->add_id(coord_times_r_gradient->id);\n\timpl.add(sub);\n\n\tauto *mul = impl.allocate(spv::OpVectorTimesScalar, vec4_type);\n\tmul->add_id(sub->id);\n\tmul->add_id(r_sqr_inv_half->id);\n\timpl.add(mul);\n\n\tbuilder.addName(mul->id, \"cube_gradients\");\n\n\t// [ ds'dx, dt'dx ]\n\tauto *grad_x_extract = impl.allocate(spv::OpVectorShuffle, vec2_type);\n\tgrad_x_extract->add_id(mul->id);\n\tgrad_x_extract->add_id(mul->id);\n\tgrad_x_extract->add_literal(0);\n\tgrad_x_extract->add_literal(2);\n\timpl.add(grad_x_extract);\n\n\t// [ ds'dy, dt'dy ]\n\tauto *grad_y_extract = impl.allocate(spv::OpVectorShuffle, vec2_type);\n\tgrad_y_extract->add_id(mul->id);\n\tgrad_y_extract->add_id(mul->id);\n\tgrad_y_extract->add_literal(1);\n\tgrad_y_extract->add_literal(3);\n\timpl.add(grad_y_extract);\n\n\tout_dx = grad_x_extract->id;\n\tout_dy = grad_y_extract->id;\n}\n\nstatic bool emit_calculate_lod_instruction_fallback(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tLOGW(\"Emitting non-conformant CalculateLevelOfDetail. Missing NV_compute_shader_derivatives.\\n\");\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilityImageQuery);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\n\t// Best effort workaround. Extremely unlikely that this will be a real problem in practice.\n\t// Only Pascal should ever hit this path.\n\t// Assumes sampler with no LOD bias and no mip clamp + trilinear.\n\t// Same concerns as sampler feedback where we need side channel data to be conformant.\n\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\tuint32_t num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\tspv::Id coords[3] = {};\n\tfor (unsigned i = 0; i < num_coords; i++)\n\t\tcoords[i] = impl.get_id_for_value(instruction->getOperand(3 + i));\n\tspv::Id coord_vec = impl.build_vector(builder.makeFloatType(32), coords, num_coords);\n\n\tspv::Id i32_type = builder.makeIntType(32);\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id fvec_type = builder.makeVectorType(f32_type, num_coords);\n\n\tauto *swap_x = impl.allocate(spv::OpGroupNonUniformQuadSwap, fvec_type);\n\tswap_x->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tswap_x->add_id(coord_vec);\n\tswap_x->add_id(builder.makeUintConstant(0));\n\timpl.add(swap_x);\n\n\tauto *swap_y = impl.allocate(spv::OpGroupNonUniformQuadSwap, fvec_type);\n\tswap_y->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\tswap_y->add_id(coord_vec);\n\tswap_y->add_id(builder.makeUintConstant(1));\n\timpl.add(swap_y);\n\n\tauto *grad_x = impl.allocate(spv::OpFSub, fvec_type);\n\tgrad_x->add_id(swap_x->id);\n\tgrad_x->add_id(coord_vec);\n\timpl.add(grad_x);\n\n\tauto *grad_y = impl.allocate(spv::OpFSub, fvec_type);\n\tgrad_y->add_id(swap_y->id);\n\tgrad_y->add_id(coord_vec);\n\timpl.add(grad_y);\n\n\tuint32_t num_size_coords;\n\tif (!get_image_dimensions_query_size(impl, builder, image_id, &num_size_coords))\n\t\treturn false;\n\n\tspv::Id grad_x_id = grad_x->id;\n\tspv::Id grad_y_id = grad_y->id;\n\tif (builder.getTypeDimensionality(impl.get_type_id(image_id)) == spv::DimCube)\n\t{\n\t\temit_calculate_lod_cube_gradient_transform(impl, coord_vec,\n\t\t                                           grad_x->id, grad_y->id,\n\t\t                                           grad_x_id, grad_y_id);\n\n\t\t// Projected down to 2 dimensions now.\n\t\tfvec_type = builder.makeVectorType(f32_type, 2);\n\t\tnum_coords = 2;\n\t}\n\n\tauto *query_op = impl.allocate(spv::OpImageQuerySizeLod, builder.makeVectorType(i32_type, num_size_coords));\n\tquery_op->add_ids({ image_id, builder.makeIntConstant(0) });\n\timpl.add(query_op);\n\n\tif (num_coords != num_size_coords)\n\t{\n\t\tauto *shuffle_op = impl.allocate(spv::OpVectorShuffle, builder.makeVectorType(i32_type, num_coords));\n\t\tshuffle_op->add_id(query_op->id);\n\t\tshuffle_op->add_id(query_op->id);\n\t\tfor (unsigned i = 0; i < num_coords; i++)\n\t\t\tshuffle_op->add_literal(i);\n\t\timpl.add(shuffle_op);\n\n\t\tquery_op = shuffle_op;\n\t}\n\n\tauto *fconv = impl.allocate(spv::OpConvertSToF, fvec_type);\n\tfconv->add_id(query_op->id);\n\timpl.add(fconv);\n\n\tauto *scale_x = impl.allocate(spv::OpFMul, fvec_type);\n\tscale_x->add_ids({ grad_x_id, fconv->id });\n\timpl.add(scale_x);\n\n\tauto *scale_y = impl.allocate(spv::OpFMul, fvec_type);\n\tscale_y->add_ids({ grad_y_id, fconv->id });\n\timpl.add(scale_y);\n\n\tspv::Id lod = build_lod_from_gradient(impl, scale_x->id, scale_y->id);\n\n\tauto *clamped_value = llvm::cast<llvm::ConstantInt>(instruction->getOperand(6));\n\tbool clamped = clamped_value->getUniqueInteger().getZExtValue() != 0;\n\n\tif (clamped)\n\t{\n\t\tauto *levels_op = impl.allocate(spv::OpImageQueryLevels, builder.makeIntType(32));\n\t\tlevels_op->add_id(image_id);\n\t\timpl.add(levels_op);\n\n\t\tauto *f_levels = impl.allocate(spv::OpConvertSToF, f32_type);\n\t\tf_levels->add_id(levels_op->id);\n\t\timpl.add(f_levels);\n\n\t\tauto *max_level = impl.allocate(spv::OpFSub, f32_type);\n\t\tmax_level->add_id(f_levels->id);\n\t\tmax_level->add_id(builder.makeFloatConstant(-1.0f));\n\t\timpl.add(max_level);\n\n\t\t// In case of null descriptor, make sure we end up with 0, so do min, then max.\n\t\tauto *min_op = impl.allocate(spv::OpExtInst, f32_type);\n\t\tmin_op->add_id(impl.glsl_std450_ext);\n\t\tmin_op->add_literal(GLSLstd450FMin);\n\t\tmin_op->add_ids({ lod, max_level->id });\n\t\timpl.add(min_op);\n\n\t\tauto *max_op = impl.allocate(spv::OpExtInst, f32_type);\n\t\tmax_op->add_id(impl.glsl_std450_ext);\n\t\tmax_op->add_literal(GLSLstd450FMax);\n\t\tmax_op->add_ids({ min_op->id, builder.makeFloatConstant(0.0f) });\n\t\timpl.add(max_op);\n\n\t\tlod = max_op->id;\n\t}\n\telse\n\t{\n\t\t// The assumption is still fixed point,\n\t\t// and real hardware will not return -inf here. Clamp to [-128, 128] which has been observed in the wild.\n\t\tauto *clamp_op = impl.allocate(spv::OpExtInst, f32_type);\n\t\tclamp_op->add_id(impl.glsl_std450_ext);\n\t\tclamp_op->add_literal(GLSLstd450FClamp);\n\t\tclamp_op->add_id(lod);\n\t\tclamp_op->add_id(builder.makeFloatConstant(-128.0f));\n\t\tclamp_op->add_id(builder.makeFloatConstant(+128.0f));\n\t\timpl.add(clamp_op);\n\n\t\tlod = clamp_op->id;\n\t}\n\n\timpl.rewrite_value(instruction, lod);\n\treturn true;\n}\n\nbool emit_calculate_lod_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool extended)\n{\n\tauto &builder = impl.builder();\n\tif (impl.execution_mode_meta.synthesize_dummy_derivatives)\n\t{\n\t\timpl.rewrite_value(instruction, builder.makeFloatConstant(0.0f));\n\t\treturn true;\n\t}\n\n\temit_expect_assume_quad_uniform(impl);\n\n\tif (impl.execution_model != spv::ExecutionModelFragment &&\n\t    !impl.options.compute_shader_derivatives)\n\t{\n\t\treturn emit_calculate_lod_instruction_fallback(impl, instruction);\n\t}\n\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id sampler_id = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id combined_image_sampler_id = impl.build_sampled_image(image_id, sampler_id, false);\n\n\tuint32_t num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\tif (num_coords == 0)\n\t{\n\t\tLOGE(\"Cannot use calculate lod instructions with input attachment.\\n\");\n\t\treturn false;\n\t}\n\n\tspv::Id coords[3] = {};\n\tfor (unsigned i = 0; i < num_coords; i++)\n\t\tcoords[i] = impl.get_id_for_value(instruction->getOperand(3 + i));\n\n\tbool clamped = false;\n\n\t// Internal extension to better match DXBC/SPIR-V.\n\tif (!extended)\n\t{\n\t\tauto *clamped_value = llvm::cast<llvm::ConstantInt>(instruction->getOperand(6));\n\t\tclamped = clamped_value->getUniqueInteger().getZExtValue() != 0;\n\t}\n\n\tOperation *query_op = impl.allocate(spv::OpImageQueryLod, builder.makeVectorType(builder.makeFloatType(32), 2));\n\tquery_op->add_ids({ combined_image_sampler_id, impl.build_vector(builder.makeFloatType(32), coords, num_coords) });\n\timpl.add(query_op);\n\n\tif (!extended)\n\t{\n\t\tOperation *op = impl.allocate(spv::OpCompositeExtract, instruction);\n\t\top->add_id(query_op->id);\n\t\top->add_literal(clamped ? 0u : 1u);\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\timpl.rewrite_value(instruction, query_op->id);\n\t}\n\n\tbuilder.addCapability(spv::CapabilityImageQuery);\n\treturn true;\n}\n\nstatic void build_sample_position_lut(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\t// Standard sample locations from the Vulkan spec.\n\tstatic const float standard_sample_positions[][2] = {\n\t\t// 1 sample\n\t\t{ 0.0 / 16.0, 0.0 / 16.0 },\n\t\t// 2 samples\n\t\t{ 4.0 / 16.0, 4.0 / 16.0 },\n\t\t{ -4.0 / 16.0, -4.0 / 16.0 },\n\t\t// 4 samples\n\t\t{ -2.0 / 16.0, -6.0 / 16.0 },\n\t\t{ 6.0 / 16.0, -2.0 / 16.0 },\n\t\t{ -6.0 / 16.0, 2.0 / 16.0 },\n\t\t{ 2.0 / 16.0, 6.0 / 16.0 },\n\t\t// 8 samples\n\t\t{ 1.0 / 16.0, -3.0 / 16.0 },\n\t\t{ -1.0 / 16.0, 3.0 / 16.0 },\n\t\t{ 5.0 / 16.0, 1.0 / 16.0 },\n\t\t{ -3.0 / 16.0, -5.0 / 16.0 },\n\t\t{ -5.0 / 16.0, 5.0 / 16.0 },\n\t\t{ -7.0 / 16.0, -1.0 / 16.0 },\n\t\t{ 3.0 / 16.0, 7.0 / 16.0 },\n\t\t{ 7.0 / 16.0, -7.0 / 16.0 },\n\t\t// 16 samples\n\t\t{ 1.0 / 16.0, 1.0 / 16.0 },\n\t\t{ -1.0 / 16.0, -3.0 / 16.0 },\n\t\t{ -3.0 / 16.0, 2.0 / 16.0 },\n\t\t{ 4.0 / 16.0, -1.0 / 16.0 },\n\t\t{ -5.0 / 16.0, -2.0 / 16.0 },\n\t\t{ 2.0 / 16.0, 5.0 / 16.0 },\n\t\t{ 5.0 / 16.0, 3.0 / 16.0 },\n\t\t{ 3.0 / 16.0, -5.0 / 16.0 },\n\t\t{ -2.0 / 16.0, 6.0 / 16.0 },\n\t\t{ 0.0 / 16.0, -7.0 / 16.0 },\n\t\t{ -4.0 / 16.0, -6.0 / 16.0 },\n\t\t{ -6.0 / 16.0, 4.0 / 16.0 },\n\t\t{ -8.0 / 16.0, 0.0 / 16.0 },\n\t\t{ 7.0 / 16.0, -4.0 / 16.0 },\n\t\t{ 6.0 / 16.0, 7.0 / 16.0 },\n\t\t{ -7.0 / 16.0, -8.0 / 16.0 },\n\t};\n\n\tif (!impl.texture_sample_pos_lut_id)\n\t{\n\t\tspv::Id vec2_type = builder.makeVectorType(builder.makeFloatType(32), 2);\n\n\t\tconstexpr size_t num_pos = sizeof(standard_sample_positions) / sizeof(standard_sample_positions[0]);\n\t\tVector<spv::Id> constituents(num_pos);\n\t\tfor (size_t i = 0; i < num_pos; i++)\n\t\t{\n\t\t\tspv::Id elems[2];\n\t\t\tfor (unsigned j = 0; j < 2; j++)\n\t\t\t\telems[j] = builder.makeFloatConstant(standard_sample_positions[i][j]);\n\t\t\tconstituents[i] = impl.build_constant_vector(builder.makeFloatType(32), elems, 2);\n\t\t}\n\n\t\tspv::Id array_type = builder.makeArrayType(vec2_type, builder.makeUintConstant(num_pos), 0);\n\t\tspv::Id lut_id = builder.makeCompositeConstant(array_type, constituents);\n\t\timpl.texture_sample_pos_lut_id = impl.create_variable_with_initializer(spv::StorageClassPrivate, array_type,\n\t\t                                                                       lut_id, \"Texture2DMSSamplePositionLUT\");\n\t}\n}\n\nstatic spv::Id build_rasterizer_sample_count(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tif (!impl.rasterizer_sample_count_id)\n\t{\n\t\tif (impl.options.rasterizer_sample_count_spec_constant)\n\t\t{\n\t\t\timpl.rasterizer_sample_count_id = builder.makeUintConstant(1, true);\n\t\t\tbuilder.addDecoration(impl.rasterizer_sample_count_id, spv::DecorationSpecId,\n\t\t\t                      impl.options.rasterizer_sample_count);\n\t\t}\n\t\telse\n\t\t\timpl.rasterizer_sample_count_id = builder.makeUintConstant(impl.options.rasterizer_sample_count, false);\n\t}\n\treturn impl.rasterizer_sample_count_id;\n}\n\nbool emit_get_render_target_sample_count(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\timpl.rewrite_value(instruction, build_rasterizer_sample_count(impl));\n\treturn true;\n}\n\nbool emit_check_access_fully_mapped_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilitySparseResidency);\n\tauto *op = impl.allocate(spv::OpImageSparseTexelsResident, instruction);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_get_sample_position(Converter::Impl &impl, const llvm::CallInst *instruction, bool image)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id sample_count_id;\n\tif (image)\n\t{\n\t\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\t\tauto *query_samples_op = impl.allocate(spv::OpImageQuerySamples, builder.makeUintType(32));\n\t\tquery_samples_op->add_id(image_id);\n\t\timpl.add(query_samples_op);\n\t\tsample_count_id = query_samples_op->id;\n\t}\n\telse\n\t{\n\t\tsample_count_id = build_rasterizer_sample_count(impl);\n\t}\n\n\tspv::Id sample_index_id = impl.get_id_for_value(instruction->getOperand(image ? 2 : 1));\n\n\t// Build the LUT if we have to.\n\tbuild_sample_position_lut(impl);\n\n\t// Sample count is only POT, so table starts at N - 1.\n\tauto *lut_base_offset_op = impl.allocate(spv::OpISub, builder.makeUintType(32));\n\tlut_base_offset_op->add_ids({ sample_count_id, builder.makeUintConstant(1) });\n\timpl.add(lut_base_offset_op);\n\n\t// Build LUT offset.\n\tauto *lut_offset_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\tlut_offset_op->add_ids({ lut_base_offset_op->id, sample_index_id });\n\timpl.add(lut_offset_op);\n\n\t// Range check sample index against actual texture.\n\tauto *cmp0_op = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\tcmp0_op->add_ids({ sample_index_id, sample_count_id });\n\timpl.add(cmp0_op);\n\n\t// Range check sample index against max supported 16.\n\tauto *cmp1_op = impl.allocate(spv::OpULessThanEqual, builder.makeBoolType());\n\tcmp1_op->add_ids({ sample_count_id, builder.makeUintConstant(16) });\n\timpl.add(cmp1_op);\n\n\tauto *cmp_op = impl.allocate(spv::OpLogicalAnd, builder.makeBoolType());\n\tcmp_op->add_ids({ cmp0_op->id, cmp1_op->id });\n\timpl.add(cmp_op);\n\n\tauto *final_lut_index_op = impl.allocate(spv::OpSelect, builder.makeUintType(32));\n\tfinal_lut_index_op->add_ids({ cmp_op->id, lut_offset_op->id, builder.makeUintConstant(0) });\n\timpl.add(final_lut_index_op);\n\n\tspv::Id vec2_type = builder.makeVectorType(builder.makeFloatType(32), 2);\n\n\tauto *chain_op = impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassPrivate, vec2_type));\n\tchain_op->add_ids({ impl.texture_sample_pos_lut_id, final_lut_index_op->id });\n\timpl.add(chain_op);\n\n\tauto *load_op = impl.allocate(spv::OpLoad, instruction, vec2_type);\n\tload_op->add_id(chain_op->id);\n\timpl.add(load_op);\n\n\tbuilder.addCapability(spv::CapabilityImageQuery);\n\treturn true;\n}\n\nstatic spv::Id emit_query_size(Converter::Impl &impl, spv::Id image_id,\n                               bool array, spv::Id lod_id = 0)\n{\n\tauto &builder = impl.builder();\n\tspv::Id i32_type = builder.makeIntType(32);\n\n\tauto *query_size_level_zero = impl.allocate(\n\t\tlod_id ? spv::OpImageQuerySizeLod : spv::OpImageQuerySize,\n\t\tbuilder.makeVectorType(i32_type, array ? 3 : 2));\n\tquery_size_level_zero->add_id(image_id);\n\tif (lod_id)\n\t\tquery_size_level_zero->add_id(lod_id);\n\timpl.add(query_size_level_zero);\n\n\tif (array)\n\t{\n\t\tauto *extract = impl.allocate(spv::OpVectorShuffle, builder.makeVectorType(i32_type, 2));\n\t\textract->add_id(query_size_level_zero->id);\n\t\textract->add_id(query_size_level_zero->id);\n\t\textract->add_literal(0);\n\t\textract->add_literal(1);\n\t\timpl.add(extract);\n\n\t\tquery_size_level_zero = extract;\n\t}\n\n\treturn query_size_level_zero->id;\n}\n\n// A software implementation of sampler feedback is by nature quite brittle.\n// Implement a best-effort solution.\n\nstatic spv::Id emit_accessed_lod(DXIL::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction,\n                                 spv::Id image_id, spv::Id sampler_id, spv::Id coord_id, spv::Id max_level_id,\n                                 spv::Id *gradient_mod_id, bool array)\n{\n\tauto &builder = impl.builder();\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id fvec_type = builder.makeVectorType(f32_type, 2);\n\tspv::Id access_lod_id;\n\n\t*gradient_mod_id = 0;\n\n\tif (opcode == DXIL::Op::WriteSamplerFeedback || opcode == DXIL::Op::WriteSamplerFeedbackBias)\n\t{\n\t\tspv::Id combined_image_sampler_id = impl.build_sampled_image(image_id, sampler_id, false);\n\n\t\t// This is more or less correct.\n\t\t// We can also detect if tri-linear should be used by checking fractional clamped LOD.\n\t\tspv::Id modified_coord_id;\n\n\t\tif (opcode == DXIL::Op::WriteSamplerFeedbackBias)\n\t\t{\n\t\t\t// Fake a larger or smaller gradient to get effective LOD bias.\n\t\t\t// In D3D11 functional spec, out of range LOD bias is undefined, so don't bother clamping.\n\t\t\tauto *exp = impl.allocate(spv::OpExtInst, f32_type);\n\t\t\texp->add_id(impl.glsl_std450_ext);\n\t\t\texp->add_literal(GLSLstd450Exp2);\n\t\t\texp->add_id(impl.get_id_for_value(instruction->getOperand(8)));\n\t\t\timpl.add(exp);\n\n\t\t\t*gradient_mod_id = exp->id;\n\n\t\t\t// Bias can technically be unique per pixel in a quad, so we have to compute LOD 4 times,\n\t\t\t// but make the assumption that LOD bias is constant over a quad to stay sane.\n\t\t\t// The common use for LOD bias for streaming is TAA related either way.\n\t\t\t// Workaround is to QuadBroadcast(exp, i), then compute LOD 4 times, then select the appropriate LOD.\n\t\t\tauto *quad_first = impl.allocate(spv::OpGroupNonUniformQuadBroadcast, f32_type);\n\t\t\tquad_first->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tquad_first->add_id(exp->id);\n\t\t\tquad_first->add_id(builder.makeUintConstant(0));\n\t\t\timpl.add(quad_first);\n\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\n\t\t\tauto *mul = impl.allocate(spv::OpVectorTimesScalar, fvec_type);\n\t\t\tmul->add_id(coord_id);\n\t\t\tmul->add_id(quad_first->id);\n\t\t\timpl.add(mul);\n\t\t\tmodified_coord_id = mul->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmodified_coord_id = coord_id;\n\t\t}\n\n\t\tauto *query_op = impl.allocate(spv::OpImageQueryLod, builder.makeVectorType(f32_type, 2));\n\t\tquery_op->add_ids({ combined_image_sampler_id, modified_coord_id });\n\t\timpl.add(query_op);\n\n\t\tauto *extract_op = impl.allocate(spv::OpCompositeExtract, f32_type);\n\t\textract_op->add_id(query_op->id);\n\t\textract_op->add_literal(0);\n\t\timpl.add(extract_op);\n\t\taccess_lod_id = extract_op->id;\n\t}\n\telse if (opcode == DXIL::Op::WriteSamplerFeedbackLevel)\n\t{\n\t\taccess_lod_id = impl.get_id_for_value(instruction->getOperand(8));\n\t}\n\telse if (opcode == DXIL::Op::WriteSamplerFeedbackGrad)\n\t{\n\t\tauto *fp_size = impl.allocate(spv::OpConvertSToF, fvec_type);\n\t\tfp_size->add_id(emit_query_size(impl, image_id, array, builder.makeIntConstant(0)));\n\t\timpl.add(fp_size);\n\n\t\tspv::Id ddx[2];\n\t\tspv::Id ddy[2];\n\t\tfor (unsigned i = 0; i < 2; i++)\n\t\t{\n\t\t\tddx[i] = impl.get_id_for_value(instruction->getOperand(8 + i));\n\t\t\tddy[i] = impl.get_id_for_value(instruction->getOperand(11 + i));\n\t\t}\n\n\t\t// Spec is very lenient on how LOD can be computed, but choose the D3D11 spec wording.\n\t\t// Based it on maximum gradient length, which is rotationally invariant and matches\n\t\t// observed behavior on AMD and Intel. NV + aniso is ... weird and non-compliant.\n\n\t\tspv::Id ddx_id = impl.build_vector(f32_type, ddx, 2);\n\t\tspv::Id ddy_id = impl.build_vector(f32_type, ddy, 2);\n\n\t\tauto *grad_x = impl.allocate(spv::OpFMul, fvec_type);\n\t\tgrad_x->add_id(fp_size->id);\n\t\tgrad_x->add_id(ddx_id);\n\t\timpl.add(grad_x);\n\n\t\tauto *grad_y = impl.allocate(spv::OpFMul, fvec_type);\n\t\tgrad_y->add_id(fp_size->id);\n\t\tgrad_y->add_id(ddy_id);\n\t\timpl.add(grad_y);\n\n\t\taccess_lod_id = build_lod_from_gradient(impl, grad_x->id, grad_y->id);\n\t}\n\telse\n\t\treturn 0;\n\n\tif (opcode == DXIL::Op::WriteSamplerFeedbackLevel || opcode == DXIL::Op::WriteSamplerFeedbackGrad)\n\t{\n\t\tauto *max_level_fp = impl.allocate(spv::OpConvertSToF, f32_type);\n\t\tmax_level_fp->add_id(max_level_id);\n\t\timpl.add(max_level_fp);\n\n\t\t// We don't know sampler clamping here, so we'll have to assume min/maxLOD covers more than image view.\n\t\t// We also don't know about tri-linear vs bi-linear at all, so we have to assume tri-linear\n\t\t// if explicit LOD is fractional.\n\t\t// NClamp in case the gradient causes NaN for whatever reason.\n\t\tauto *clamped_lod = impl.allocate(spv::OpExtInst, f32_type);\n\t\tclamped_lod->add_id(impl.glsl_std450_ext);\n\t\tclamped_lod->add_literal(GLSLstd450NClamp);\n\t\tclamped_lod->add_id(access_lod_id);\n\t\tclamped_lod->add_id(builder.makeFloatConstant(0.0f));\n\t\tclamped_lod->add_id(max_level_fp->id);\n\t\timpl.add(clamped_lod);\n\n\t\taccess_lod_id = clamped_lod->id;\n\t}\n\n\tif (opcode != DXIL::Op::WriteSamplerFeedbackLevel)\n\t{\n\t\t// Undocumented feature in spec. There's an extra MinMipClamp operand here.\n\t\t// We cannot implement that completely accurately since we need QueryLod + MinMip, which\n\t\t// does not exist, but just YOLO it.\n\t\t// Normally, that clamp value will be integer, which should be fine.\n\t\t// This comes after [0, levels - 1] clamp, since if we clamp LOD to out of bounds of view,\n\t\t// we end up accessing OOB.\n\t\tauto *clamp_value = instruction->getOperand(instruction->getNumOperands() - 1);\n\t\tif (!llvm::isa<llvm::UndefValue>(clamp_value))\n\t\t{\n\t\t\tauto *clamp_lod = impl.allocate(spv::OpExtInst, f32_type);\n\t\t\tclamp_lod->add_id(impl.glsl_std450_ext);\n\t\t\tclamp_lod->add_literal(GLSLstd450FMax);\n\t\t\tclamp_lod->add_id(access_lod_id);\n\t\t\tclamp_lod->add_id(impl.get_id_for_value(clamp_value));\n\t\t\timpl.add(clamp_lod);\n\n\t\t\t// LOD 15 bits are reserved.\n\t\t\tauto *max_lod_clamp = impl.allocate(spv::OpExtInst, f32_type);\n\t\t\tmax_lod_clamp->add_id(impl.glsl_std450_ext);\n\t\t\tmax_lod_clamp->add_literal(GLSLstd450FMin);\n\t\t\tmax_lod_clamp->add_id(clamp_lod->id);\n\t\t\tmax_lod_clamp->add_id(builder.makeFloatConstant(14.0f));\n\t\t\timpl.add(max_lod_clamp);\n\n\t\t\taccess_lod_id = max_lod_clamp->id;\n\t\t}\n\t}\n\n\treturn access_lod_id;\n}\n\nstatic spv::Id emit_mip_region_size_log2(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                         spv::Id feedback_image_id, bool arrayed)\n{\n\tauto &builder = impl.builder();\n\tspv::Id i32_type = builder.makeIntType(32);\n\tspv::Id ivec_type = builder.makeVectorType(i32_type, 2);\n\n\tspv::Id feedback_size_id;\n\n\tif (arrayed)\n\t{\n\t\tauto *query_feedback_size = impl.allocate(spv::OpImageQuerySize, builder.makeVectorType(i32_type, 3));\n\t\tquery_feedback_size->add_id(feedback_image_id);\n\t\timpl.add(query_feedback_size);\n\n\t\tauto *extract = impl.allocate(spv::OpVectorShuffle, ivec_type);\n\t\textract->add_id(query_feedback_size->id);\n\t\textract->add_id(query_feedback_size->id);\n\t\textract->add_literal(0);\n\t\textract->add_literal(1);\n\t\timpl.add(extract);\n\n\t\tfeedback_size_id = extract->id;\n\t}\n\telse\n\t{\n\t\tauto *query_feedback_size = impl.allocate(spv::OpImageQuerySize, ivec_type);\n\t\tquery_feedback_size->add_id(feedback_image_id);\n\t\timpl.add(query_feedback_size);\n\n\t\tfeedback_size_id = query_feedback_size->id;\n\t}\n\n\tauto *masked_size = impl.allocate(spv::OpBitwiseAnd, ivec_type);\n\tmasked_size->add_id(feedback_size_id);\n\tmasked_size->add_id(impl.build_splat_constant_vector(i32_type, builder.makeIntConstant(15), 2));\n\timpl.add(masked_size);\n\n\treturn masked_size->id;\n}\n\nstruct ScalingFactors\n{\n\tspv::Id normalized_scale_id;\n\tspv::Id float_size_id;\n\tspv::Id unnormalized_exponent_id;\n};\n\nstatic ScalingFactors emit_scaling_factor_to_mip_region_space(\n\tConverter::Impl &impl, const llvm::CallInst *instruction,\n\tspv::Id image_id, spv::Id lod_id, spv::Id mip_region_size_log2, bool arrayed)\n{\n\tauto &builder = impl.builder();\n\tspv::Id i32_type = builder.makeIntType(32);\n\tspv::Id ivec_type = builder.makeVectorType(i32_type, 2);\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id fvec_type = builder.makeVectorType(f32_type, 2);\n\n\t// Query size of top-level mip we're writing to.\n\tauto *fp_size = impl.allocate(spv::OpConvertSToF, fvec_type);\n\tfp_size->add_id(emit_query_size(impl, image_id, arrayed, lod_id));\n\timpl.add(fp_size);\n\n\t// The lower 4 bits of feedback image store log2(MipRegionWidth).\n\t// X dimension for width and Y for height.\n\t// Clever hackery that avoids having to pass down an extra side buffer ... :V\n\tauto *to_mip_region_space = impl.allocate(spv::OpSNegate, ivec_type);\n\tto_mip_region_space->add_id(mip_region_size_log2);\n\timpl.add(to_mip_region_space);\n\n\t// Scale the UV coordinates into sub-pixel coordinates in mip-region space.\n\tauto *ld_exp = impl.allocate(spv::OpExtInst, fvec_type);\n\tld_exp->add_id(impl.glsl_std450_ext);\n\tld_exp->add_literal(GLSLstd450Ldexp);\n\tld_exp->add_id(fp_size->id);\n\tld_exp->add_id(to_mip_region_space->id);\n\timpl.add(ld_exp);\n\n\tScalingFactors factors = {};\n\tfactors.normalized_scale_id = ld_exp->id;\n\tfactors.float_size_id = fp_size->id;\n\tfactors.unnormalized_exponent_id = to_mip_region_space->id;\n\treturn factors;\n}\n\nstatic spv::Id emit_max_level(Converter::Impl &impl, spv::Id image_id)\n{\n\tauto &builder = impl.builder();\n\tspv::Id i32_type = builder.makeIntType(32);\n\n\tauto *query_levels = impl.allocate(spv::OpImageQueryLevels, i32_type);\n\tquery_levels->add_id(image_id);\n\timpl.add(query_levels);\n\n\tauto *max_level = impl.allocate(spv::OpISub, i32_type);\n\tmax_level->add_id(query_levels->id);\n\tmax_level->add_id(builder.makeIntConstant(1));\n\timpl.add(max_level);\n\n\treturn max_level->id;\n}\n\nstruct LodSelection\n{\n\tspv::Id fine_lod_id;\n\tspv::Id coarse_lod_id;\n\tspv::Id trilinear_enable_id;\n};\n\nstatic LodSelection emit_trilinear_lods(Converter::Impl &impl, spv::Id access_lod_id, spv::Id max_level_id)\n{\n\tLodSelection lods = {};\n\tauto &builder = impl.builder();\n\tspv::Id i32_type = builder.makeIntType(32);\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id bool_type = builder.makeBoolType();\n\n\tauto *fine_lod = impl.allocate(spv::OpConvertFToS, i32_type);\n\tfine_lod->add_id(access_lod_id);\n\timpl.add(fine_lod);\n\n\tlods.fine_lod_id = fine_lod->id;\n\n\t// Trilinear only kicks in one the fractional value hits 1 / 256.\n\t// It does not trigger on 1 / 512 from real-world testing for example.\n\t// Use mid-point between the two. Avoids subtle rounding issues in FP add.\n\tauto *coarse_bias_lod = impl.allocate(spv::OpFAdd, f32_type);\n\tcoarse_bias_lod->add_id(access_lod_id);\n\tcoarse_bias_lod->add_id(builder.makeFloatConstant(1.0f - 0.75f / 256.0f));\n\timpl.add(coarse_bias_lod);\n\n\tauto *coarse_lod = impl.allocate(spv::OpConvertFToS, i32_type);\n\tcoarse_lod->add_id(coarse_bias_lod->id);\n\timpl.add(coarse_lod);\n\n\tauto *clamped_lod = impl.allocate(spv::OpExtInst, i32_type);\n\tclamped_lod->add_id(impl.glsl_std450_ext);\n\tclamped_lod->add_literal(GLSLstd450SMin);\n\tclamped_lod->add_id(coarse_lod->id);\n\tclamped_lod->add_id(max_level_id);\n\timpl.add(clamped_lod);\n\tlods.coarse_lod_id = coarse_lod->id;\n\n\tauto *trilinear = impl.allocate(spv::OpINotEqual, bool_type);\n\ttrilinear->add_id(fine_lod->id);\n\ttrilinear->add_id(coarse_lod->id);\n\timpl.add(trilinear);\n\tlods.trilinear_enable_id = trilinear->id;\n\n\treturn lods;\n}\n\nstatic spv::Id emit_gradient_extent_normalized(Converter::Impl &impl, spv::Id coord_id, spv::Id grad_scale_id)\n{\n\tauto &builder = impl.builder();\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id fvec_type = builder.makeVectorType(f32_type, 2);\n\n\tauto *ddx = impl.allocate(spv::OpDPdx, fvec_type);\n\tddx->add_id(coord_id);\n\timpl.add(ddx);\n\n\tauto *ddy = impl.allocate(spv::OpDPdy, fvec_type);\n\tddy->add_id(coord_id);\n\timpl.add(ddy);\n\n\tauto *ddx_abs = impl.allocate(spv::OpExtInst, fvec_type);\n\tddx_abs->add_id(impl.glsl_std450_ext);\n\tddx_abs->add_literal(GLSLstd450FAbs);\n\tddx_abs->add_id(ddx->id);\n\timpl.add(ddx_abs);\n\n\tauto *ddy_abs = impl.allocate(spv::OpExtInst, fvec_type);\n\tddy_abs->add_id(impl.glsl_std450_ext);\n\tddy_abs->add_literal(GLSLstd450FAbs);\n\tddy_abs->add_id(ddy->id);\n\timpl.add(ddy_abs);\n\n\tauto *ddx_abs_0 = impl.allocate(spv::OpCompositeExtract, f32_type);\n\tddx_abs_0->add_id(ddx_abs->id);\n\tddx_abs_0->add_literal(0);\n\timpl.add(ddx_abs_0);\n\n\tauto *ddy_abs_0 = impl.allocate(spv::OpCompositeExtract, f32_type);\n\tddy_abs_0->add_id(ddy_abs->id);\n\tddy_abs_0->add_literal(0);\n\timpl.add(ddy_abs_0);\n\n\tauto *ddx_abs_1 = impl.allocate(spv::OpCompositeExtract, f32_type);\n\tddx_abs_1->add_id(ddx_abs->id);\n\tddx_abs_1->add_literal(1);\n\timpl.add(ddx_abs_1);\n\n\tauto *ddy_abs_1 = impl.allocate(spv::OpCompositeExtract, f32_type);\n\tddy_abs_1->add_id(ddy_abs->id);\n\tddy_abs_1->add_literal(1);\n\timpl.add(ddy_abs_1);\n\n\tauto *extent_x = impl.allocate(spv::OpExtInst, f32_type);\n\textent_x->add_id(impl.glsl_std450_ext);\n\textent_x->add_literal(GLSLstd450FMax);\n\textent_x->add_id(ddx_abs_0->id);\n\textent_x->add_id(ddy_abs_0->id);\n\timpl.add(extent_x);\n\n\tauto *extent_y = impl.allocate(spv::OpExtInst, f32_type);\n\textent_y->add_id(impl.glsl_std450_ext);\n\textent_y->add_literal(GLSLstd450FMax);\n\textent_y->add_id(ddx_abs_1->id);\n\textent_y->add_id(ddy_abs_1->id);\n\timpl.add(extent_y);\n\n\tspv::Id extent_ids[2] = {extent_x->id, extent_y->id};\n\tspv::Id extent = impl.build_vector(f32_type, extent_ids, 2);\n\n\t// Extremely weird behavior observed on both NV and Intel.\n\t// It seems that if you have LOD bias, the effective gradient is scaled accordingly.\n\t// This means the aniso footprint is scaled too, which is extremely weird and definitely\n\t// not accurate to spec how I understand it ...\n\t// TODO: Does sampler LOD bias affect this too?\n\tif (grad_scale_id)\n\t{\n\t\tauto *grad_mul = impl.allocate(spv::OpVectorTimesScalar, fvec_type);\n\t\tgrad_mul->add_id(extent);\n\t\tgrad_mul->add_id(grad_scale_id);\n\t\timpl.add(grad_mul);\n\t\textent = grad_mul->id;\n\t}\n\n\treturn extent;\n}\n\nbool emit_write_sampler_feedback_instruction(DXIL::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tbuilder.addCapability(spv::CapabilityImageQuery);\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tspv::Id feedback_id = impl.get_id_for_value(instruction->getOperand(1));\n\tspv::Id image_id = impl.get_id_for_value(instruction->getOperand(2));\n\tspv::Id sampler_id = impl.get_id_for_value(instruction->getOperand(3));\n\tconst auto &meta = impl.handle_to_resource_meta[feedback_id];\n\n\tuint32_t num_coords_full = 0, num_coords = 0;\n\tif (!get_image_dimensions(impl, image_id, &num_coords_full, &num_coords))\n\t\treturn false;\n\n\t// Should not happen.\n\tif (num_coords != 2)\n\t\treturn false;\n\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id i32_type = builder.makeIntType(32);\n\tspv::Id f32_type = builder.makeFloatType(32);\n\tspv::Id bvec_type = builder.makeVectorType(bool_type, 2);\n\tspv::Id ivec_type = builder.makeVectorType(i32_type, 2);\n\tspv::Id fvec_type = builder.makeVectorType(f32_type, 2);\n\n\tspv::Id int_layer_id = 0;\n\tif (num_coords_full == 3)\n\t{\n\t\t// Vulkan allows for two implementation of this rounding, either RTE or floor(v + 0.5).\n\t\t// Pick the suggested one. This matches real-world implementations.\n\t\tauto *rounded_layer = impl.allocate(spv::OpExtInst, f32_type);\n\t\trounded_layer->add_id(impl.glsl_std450_ext);\n\t\trounded_layer->add_literal(GLSLstd450RoundEven);\n\t\trounded_layer->add_id(impl.get_id_for_value(instruction->getOperand(6)));\n\t\timpl.add(rounded_layer);\n\n\t\tauto *int_layer = impl.allocate(spv::OpConvertFToS, i32_type);\n\t\tint_layer->add_id(rounded_layer->id);\n\t\timpl.add(int_layer);\n\n\t\tint_layer_id = int_layer->id;\n\t}\n\n\tspv::Id coord_ids[2];\n\tfor (uint32_t i = 0; i < 2; i++)\n\t\tcoord_ids[i] = impl.get_id_for_value(instruction->getOperand(4 + i));\n\tspv::Id coord_id = impl.build_vector(f32_type, coord_ids, 2);\n\tspv::Id mip_region_size_log2 = emit_mip_region_size_log2(impl, instruction, feedback_id, num_coords_full == 3);\n\tspv::Id max_level_id = emit_max_level(impl, image_id);\n\n\t// This part will change quite dramatically based on op-code.\n\t// Computing the actual LOD to access is quite painful.\n\t// We cannot do it properly for most interesting cases without having side band information\n\t// about sampler state. In real-world scenarios, applications will likely adhere to whatever mip level\n\t// we decide to access either way, so it shouldn't lead to serious problems.\n\tspv::Id grad_scale_id;\n\tspv::Id access_lod_id = emit_accessed_lod(opcode, impl, instruction, image_id, sampler_id, coord_id,\n\t                                          max_level_id, &grad_scale_id, num_coords_full == 3);\n\n\tauto lods = emit_trilinear_lods(impl, access_lod_id, max_level_id);\n\n\tspv::Id normalized_grad_extent = 0;\n\tif (opcode == DXIL::Op::WriteSamplerFeedback || opcode == DXIL::Op::WriteSamplerFeedbackBias)\n\t\tnormalized_grad_extent = emit_gradient_extent_normalized(impl, coord_id, grad_scale_id);\n\n\t// Assume that if we get coordinates above 1.0 we intend to WRAP.\n\t// Only WRAP and CLAMP is supported with sampler feedback (but WRAP is kinda broken on NV hardware).\n\t// After wrap, assume CLAMP semantics for purposes of filtering.\n\tauto *fract_uv_op = impl.allocate(spv::OpExtInst, fvec_type);\n\tfract_uv_op->add_id(impl.glsl_std450_ext);\n\tfract_uv_op->add_literal(GLSLstd450Fract);\n\tfract_uv_op->add_id(coord_id);\n\timpl.add(fract_uv_op);\n\n\tfor (unsigned lod_iteration = 0; lod_iteration < 2; lod_iteration++)\n\t{\n\t\tspv::Id lod_id = lod_iteration ? lods.coarse_lod_id : lods.fine_lod_id;\n\n\t\tauto scaling = emit_scaling_factor_to_mip_region_space(\n\t\t\timpl, instruction, image_id, lod_id,\n\t\t\tmip_region_size_log2, num_coords_full == 3);\n\n\t\tauto *mul_mip_region_coord = impl.allocate(spv::OpFMul, fvec_type);\n\t\tmul_mip_region_coord->add_id(fract_uv_op->id);\n\t\tmul_mip_region_coord->add_id(scaling.normalized_scale_id);\n\t\timpl.add(mul_mip_region_coord);\n\n\t\t// We have to assume the worst w.r.t. filtering / aniso.\n\t\t// Simplify this with a ton with crude, but effective approximations.\n\t\t// Compute derivatives in mip region space.\n\t\t// Based on these derivatives, we get a bounding box.\n\t\t// The size of this bounding box is then clamped to a minimum and maximum size.\n\t\t// At minimum, we have 1x aniso / bilinear. Extent is +/- 0.5 texels.\n\t\t// At maximum, we have 16x aniso. Extent is +/- 8 texels.\n\t\t// Need to look at derivatives so that we can compute conservative aniso extent.\n\n\t\t// For implicit LOD, we compute the gradient and try to recover aniso information.\n\t\tspv::Id clamped_extent_id;\n\n\t\tif (opcode == DXIL::Op::WriteSamplerFeedback || opcode == DXIL::Op::WriteSamplerFeedbackBias)\n\t\t{\n\t\t\tauto *scale_size = impl.allocate(spv::OpFMul, fvec_type);\n\t\t\tscale_size->add_id(normalized_grad_extent);\n\t\t\tscale_size->add_id(scaling.float_size_id);\n\t\t\timpl.add(scale_size);\n\n\t\t\t// For integer LODs, we will end up computing an approximate integer due to FP derivatives.\n\t\t\t// It would be very bad if we got a positive error and rounded up a full POT.\n\t\t\t// LODs tend to be snapped to fixed point, so use a sufficient threshold to avoid these errors.\n\t\t\t// This value is chosen somewhat arbitrarily, but one subtexel worth of bias seems reasonable.\n\t\t\tauto *rounding_bias = impl.allocate(spv::OpFSub, fvec_type);\n\t\t\trounding_bias->add_id(scale_size->id);\n\t\t\trounding_bias->add_id(\n\t\t\t\timpl.build_splat_constant_vector(f32_type, builder.makeFloatConstant(1.0f / 256.0f), 2));\n\t\t\timpl.add(rounding_bias);\n\n\t\t\t// With aniso factors, implementations are allowed to round up the aniso factor\n\t\t\t// to nearest supported value.\n\t\t\t// From exhaustive testing, NV and Intel have somewhat different behavior, but in general,\n\t\t\t// all POT factors behave accurately with this implementation.\n\t\t\t// Oddly enough, the extent is enlongated as well when rounding up, which is also not spec compliant ...\n\t\t\t// What we want to do is round up to next POT and round up extent similarly,\n\t\t\t// and the cutest way to do this is with frexp. The exponent represents next POT in magnitude.\n\t\t\t// We can then clamp that frexp to [unormalized_exponent_id, unnormalized_exponent_id + 4].\n\t\t\t// We're robust against NaN since the exponent is undefined, but we'll clamp that below in integer space.\n\t\t\tauto *frexp = impl.allocate(spv::OpExtInst, builder.makeStructResultType(fvec_type, ivec_type));\n\t\t\tfrexp->add_id(impl.glsl_std450_ext);\n\t\t\tfrexp->add_literal(GLSLstd450FrexpStruct);\n\t\t\tfrexp->add_id(rounding_bias->id);\n\t\t\timpl.add(frexp);\n\n\t\t\tauto *extract = impl.allocate(spv::OpCompositeExtract, ivec_type);\n\t\t\textract->add_id(frexp->id);\n\t\t\textract->add_literal(1);\n\t\t\timpl.add(extract);\n\n\t\t\tauto *sclamp = impl.allocate(spv::OpExtInst, ivec_type);\n\t\t\tsclamp->add_id(impl.glsl_std450_ext);\n\t\t\tsclamp->add_literal(GLSLstd450SClamp);\n\t\t\tsclamp->add_id(extract->id);\n\t\t\tsclamp->add_id(impl.build_splat_constant_vector(i32_type, builder.makeIntConstant(0), num_coords));\n\t\t\tsclamp->add_id(impl.build_splat_constant_vector(i32_type, builder.makeIntConstant(4), num_coords));\n\t\t\timpl.add(sclamp);\n\n\t\t\tauto *shift_exp = impl.allocate(spv::OpIAdd, ivec_type);\n\t\t\tshift_exp->add_id(sclamp->id);\n\t\t\tshift_exp->add_id(scaling.unnormalized_exponent_id);\n\t\t\timpl.add(shift_exp);\n\n\t\t\t// For aniso, the conservative filter extent is half the major length.\n\t\t\t// Halve the bounding box extents as a rough approximation.\n\t\t\t// For bilinear, the footprint can be found in [-0.5, 0.5] texels.\n\t\t\t// Fuse the multiply and exp2() here in ldexp.\n\t\t\tauto *fextent = impl.allocate(spv::OpExtInst, fvec_type);\n\t\t\tfextent->add_id(impl.glsl_std450_ext);\n\t\t\tfextent->add_literal(GLSLstd450Ldexp);\n\t\t\tfextent->add_id(impl.build_splat_constant_vector(f32_type, builder.makeFloatConstant(0.5f), num_coords));\n\t\t\tfextent->add_id(shift_exp->id);\n\t\t\timpl.add(fextent);\n\n\t\t\t// We only support signalling access for nearest neighbor.\n\t\t\t// For 16x aniso with 4x4 region, this can go wrong, but we don't really care.\n\t\t\t// Worst case, we can clamp to 16x16 region internally and upsample the region map on resolve.\n\t\t\t// Maximum +/- 0.5 regions is allowed here, this ensures that we access maximum 2x2 blocks.\n\t\t\tauto *clamped_extent = impl.allocate(spv::OpExtInst, fvec_type);\n\t\t\tclamped_extent->add_id(impl.glsl_std450_ext);\n\t\t\tclamped_extent->add_literal(GLSLstd450FMin);\n\t\t\tclamped_extent->add_id(fextent->id);\n\t\t\tclamped_extent->add_id(\n\t\t\t\timpl.build_splat_constant_vector(f32_type, builder.makeFloatConstant(0.5f), num_coords));\n\t\t\timpl.add(clamped_extent);\n\n\t\t\tclamped_extent_id = clamped_extent->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Level is incompatible with aniso, so always assume simple bilinear. Use fixed +/- 0.5 pixel footprint.\n\t\t\t// For explicit gradient, we also assume no aniso,\n\t\t\t// since computing aniso-factors can cause far too fine mips to be requested if this was not intended by app.\n\t\t\t// We have no good way to detect this, and trying to compute aniso factors\n\t\t\t// accurately to hardware is a losing game since every implementation applies heavy approximations.\n\t\t\tauto *min_extent = impl.allocate(spv::OpExtInst, fvec_type);\n\t\t\tmin_extent->add_id(impl.glsl_std450_ext);\n\t\t\tmin_extent->add_literal(GLSLstd450Ldexp);\n\t\t\tmin_extent->add_id(impl.build_splat_constant_vector(f32_type, builder.makeFloatConstant(0.5f), num_coords));\n\t\t\tmin_extent->add_id(scaling.unnormalized_exponent_id);\n\t\t\timpl.add(min_extent);\n\n\t\t\tclamped_extent_id = min_extent->id;\n\t\t}\n\n\t\tauto *lo_foot_print = impl.allocate(spv::OpFSub, fvec_type);\n\t\tlo_foot_print->add_id(mul_mip_region_coord->id);\n\t\tlo_foot_print->add_id(clamped_extent_id);\n\t\timpl.add(lo_foot_print);\n\n\t\tauto *lo_clamped = impl.allocate(spv::OpExtInst, fvec_type);\n\t\tlo_clamped->add_id(impl.glsl_std450_ext);\n\t\tlo_clamped->add_literal(GLSLstd450FMax);\n\t\tlo_clamped->add_id(lo_foot_print->id);\n\t\tlo_clamped->add_id(impl.build_splat_constant_vector(f32_type, builder.makeFloatConstant(0.0f), num_coords));\n\t\timpl.add(lo_clamped);\n\n\t\tauto *hi_foot_print = impl.allocate(spv::OpFAdd, fvec_type);\n\t\thi_foot_print->add_id(mul_mip_region_coord->id);\n\t\thi_foot_print->add_id(clamped_extent_id);\n\t\timpl.add(hi_foot_print);\n\n\t\tauto *lo_int = impl.allocate(spv::OpConvertFToS, ivec_type);\n\t\tlo_int->add_id(lo_clamped->id);\n\t\timpl.add(lo_int);\n\n\t\tauto *hi_int = impl.allocate(spv::OpConvertFToS, ivec_type);\n\t\thi_int->add_id(hi_foot_print->id);\n\t\timpl.add(hi_int);\n\n\t\tauto *not_equal = impl.allocate(spv::OpINotEqual, bvec_type);\n\t\tnot_equal->add_id(lo_int->id);\n\t\tnot_equal->add_id(hi_int->id);\n\t\timpl.add(not_equal);\n\n\t\tauto *visit_horiz = impl.allocate(spv::OpCompositeExtract, bool_type);\n\t\tvisit_horiz->add_id(not_equal->id);\n\t\tvisit_horiz->add_literal(0);\n\t\timpl.add(visit_horiz);\n\n\t\tauto *visit_vert = impl.allocate(spv::OpCompositeExtract, bool_type);\n\t\tvisit_vert->add_id(not_equal->id);\n\t\tvisit_vert->add_literal(1);\n\t\timpl.add(visit_vert);\n\n\t\tauto *visit_diag = impl.allocate(spv::OpLogicalAnd, bool_type);\n\t\tvisit_diag->add_id(visit_horiz->id);\n\t\tvisit_diag->add_id(visit_vert->id);\n\t\timpl.add(visit_diag);\n\n\t\tconst spv::Id bit_ids[3] = {visit_horiz->id, visit_vert->id, visit_diag->id};\n\t\tspv::Id merged_bit = builder.makeIntConstant(1);\n\n\t\tfor (unsigned i = 0; i < 3; i++)\n\t\t{\n\t\t\tauto *select_op = impl.allocate(spv::OpSelect, i32_type);\n\t\t\tselect_op->add_id(bit_ids[i]);\n\t\t\tselect_op->add_id(builder.makeIntConstant(2 << i));\n\t\t\tselect_op->add_id(builder.makeIntConstant(0));\n\t\t\timpl.add(select_op);\n\n\t\t\tauto *or_op = impl.allocate(spv::OpBitwiseOr, i32_type);\n\t\t\tor_op->add_id(merged_bit);\n\t\t\tor_op->add_id(select_op->id);\n\t\t\timpl.add(or_op);\n\n\t\t\tmerged_bit = or_op->id;\n\t\t}\n\n\t\tspv::Id u64_type = builder.makeUintType(64);\n\t\tauto *u64_conv = impl.allocate(spv::OpSConvert, u64_type);\n\t\tu64_conv->add_id(merged_bit);\n\t\timpl.add(u64_conv);\n\n\t\tauto *shamt = impl.allocate(spv::OpIMul, i32_type);\n\t\tshamt->add_id(lod_id);\n\t\tshamt->add_id(builder.makeIntConstant(4));\n\t\timpl.add(shamt);\n\n\t\tauto *shamt64 = impl.allocate(spv::OpSConvert, u64_type);\n\t\tshamt64->add_id(shamt->id);\n\t\timpl.add(shamt64);\n\n\t\tauto *shift_op = impl.allocate(spv::OpShiftLeftLogical, u64_type);\n\t\tshift_op->add_id(u64_conv->id);\n\t\tshift_op->add_id(shamt64->id);\n\t\timpl.add(shift_op);\n\n\t\tspv::Id comp_id;\n\t\tif (int_layer_id)\n\t\t{\n\t\t\tauto *comp = impl.allocate(spv::OpCompositeConstruct, builder.makeVectorType(i32_type, num_coords_full));\n\t\t\tcomp->add_id(lo_int->id);\n\t\t\tcomp->add_id(int_layer_id);\n\t\t\timpl.add(comp);\n\t\t\tcomp_id = comp->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcomp_id = lo_int->id;\n\t\t}\n\n\t\tspv::Id participate_id;\n\t\tif (impl.execution_model == spv::ExecutionModelFragment)\n\t\t{\n\t\t\tauto *is_helper = impl.allocate(spv::OpIsHelperInvocationEXT, bool_type);\n\t\t\timpl.add(is_helper);\n\n\t\t\tauto *not_op = impl.allocate(spv::OpLogicalNot, bool_type);\n\t\t\tnot_op->add_id(is_helper->id);\n\t\t\timpl.add(not_op);\n\n\t\t\tparticipate_id = not_op->id;\n\n\t\t\tif (lod_iteration != 0)\n\t\t\t{\n\t\t\t\tauto *trilinear_and = impl.allocate(spv::OpLogicalAnd, bool_type);\n\t\t\t\ttrilinear_and->add_id(participate_id);\n\t\t\t\ttrilinear_and->add_id(lods.trilinear_enable_id);\n\t\t\t\timpl.add(trilinear_and);\n\t\t\t\tparticipate_id = trilinear_and->id;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (lod_iteration == 0)\n\t\t\t\tparticipate_id = builder.makeBoolConstant(true);\n\t\t\telse\n\t\t\t\tparticipate_id = lods.trilinear_enable_id;\n\t\t}\n\n\t\tHelperCall helper_call;\n\t\tif (num_coords_full == 3 && meta.non_uniform)\n\t\t\thelper_call = HelperCall::AtomicImageArrayR64CompactNonUniform;\n\t\telse if (num_coords_full == 3)\n\t\t\thelper_call = HelperCall::AtomicImageArrayR64Compact;\n\t\telse if (meta.non_uniform)\n\t\t\thelper_call = HelperCall::AtomicImageR64CompactNonUniform;\n\t\telse\n\t\t\thelper_call = HelperCall::AtomicImageR64Compact;\n\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(helper_call);\n\t\tauto *call = impl.allocate(spv::OpFunctionCall, builder.makeVoidType());\n\t\tcall->add_id(call_id);\n\t\tcall->add_id(meta.var_id);\n\t\tcall->add_id(comp_id);\n\t\tcall->add_id(shift_op->id);\n\t\tcall->add_id(participate_id);\n\t\timpl.add(call);\n\t}\n\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_sampling.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool get_image_dimensions(Converter::Impl &impl, spv::Id image_id, uint32_t *num_coords, uint32_t *num_dimensions);\n\nbool emit_sample_instruction(DXIL::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_sample_grad_instruction(DXIL::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_texture_gather_instruction(bool compare, bool raw, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_texture_load_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_texture_store_instruction_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction, bool multi_sampled);\nbool emit_get_dimensions_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool extended);\n\ntemplate <bool extended>\nbool emit_get_dimensions_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_get_dimensions_instruction(impl, instruction, extended);\n}\n\nbool emit_calculate_lod_instruction(Converter::Impl &impl, const llvm::CallInst *instruction, bool extended);\n\ntemplate <bool extended>\nbool emit_calculate_lod_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_calculate_lod_instruction(impl, instruction, extended);\n}\n\nbool emit_get_sample_position(Converter::Impl &impl, const llvm::CallInst *instruction, bool image);\nbool emit_get_render_target_sample_count(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_check_access_fully_mapped_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_write_sampler_feedback_instruction(DXIL::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\n\ntemplate <DXIL::Op opcode>\nbool emit_write_sampler_feedback_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_write_sampler_feedback_instruction(opcode, impl, instruction);\n}\n\ntemplate <DXIL::Op opcode>\nstatic inline bool emit_sample_instruction_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_sample_instruction(opcode, impl, instruction);\n}\n\ntemplate <DXIL::Op opcode>\nstatic inline bool emit_sample_grad_instruction_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_sample_grad_instruction(opcode, impl, instruction);\n}\n\ntemplate <bool multi_sampled>\nstatic inline bool emit_texture_store_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_texture_store_instruction_dispatch(impl, instruction, multi_sampled);\n}\n\ntemplate <bool compare, bool raw>\nstatic inline bool emit_texture_gather_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_texture_gather_instruction(compare, raw, impl, instruction);\n}\n\ntemplate <bool image>\nstatic inline bool emit_get_sample_position_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_get_sample_position(impl, instruction, image);\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_tessellation.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_tessellation.hpp\"\n#include \"dxil_common.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n#include \"logging.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_store_patch_constant_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tuint32_t output_element_index;\n\tif (!get_constant_operand(instruction, 1, &output_element_index))\n\t\treturn false;\n\n\tconst auto &meta = impl.patch_elements_meta[output_element_index];\n\tuint32_t var_id = meta.id;\n\n\tif (meta.lowering)\n\t\tvar_id = impl.execution_mode_meta.patch_lowering_array_var_id;\n\n\tspv::Id ptr_id;\n\n\tspv::Id output_type_id = builder.getDerefTypeId(var_id);\n\n\tbool row_index = false;\n\tif (builder.isArrayType(output_type_id))\n\t{\n\t\trow_index = true;\n\t\toutput_type_id = builder.getContainedTypeId(output_type_id);\n\t}\n\tuint32_t num_cols = builder.getNumTypeComponents(output_type_id);\n\n\tif (row_index || num_cols > 1)\n\t{\n\t\tOperation *op = impl.allocate(\n\t\t\tspv::OpAccessChain, builder.makePointer(\n\t\t\t\tmeta.lowering ? spv::StorageClassPrivate : spv::StorageClassOutput,\n\t\t\t\tbuilder.getScalarTypeId(output_type_id)));\n\n\t\tptr_id = op->id;\n\t\top->add_id(var_id);\n\n\t\tif (row_index)\n\t\t{\n\t\t\tspv::Id row_id = impl.get_id_for_value(instruction->getOperand(2));\n\t\t\tif (meta.lowering && meta.start_row != 0)\n\t\t\t{\n\t\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\t\tadd_op->add_id(row_id);\n\t\t\t\tadd_op->add_id(builder.makeUintConstant(meta.start_row));\n\t\t\t\timpl.add(add_op);\n\n\t\t\t\trow_id = add_op->id;\n\t\t\t}\n\t\t\telse if (!meta.lowering && meta.semantic_offset)\n\t\t\t{\n\t\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\t\tadd_op->add_id(row_id);\n\t\t\t\tadd_op->add_id(builder.makeUintConstant(meta.semantic_offset));\n\t\t\t\timpl.add(add_op);\n\n\t\t\t\trow_id = add_op->id;\n\t\t\t}\n\n\t\t\top->add_id(row_id);\n\t\t}\n\n\t\tif (num_cols > 1)\n\t\t{\n\t\t\tspv::Id col_id = impl.get_id_for_value(instruction->getOperand(3), 32);\n\t\t\tif (meta.lowering && meta.start_col != 0)\n\t\t\t{\n\t\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\t\tadd_op->add_id(col_id);\n\t\t\t\tadd_op->add_id(builder.makeUintConstant(meta.start_col));\n\t\t\t\timpl.add(add_op);\n\n\t\t\t\tcol_id = add_op->id;\n\t\t\t}\n\t\t\top->add_id(col_id);\n\t\t}\n\n\t\timpl.add(op);\n\t}\n\telse\n\t\tptr_id = var_id;\n\n\tauto *storage_type = instruction->getOperand(4)->getType();\n\n\tspv::Id store_value = impl.get_id_for_value(instruction->getOperand(4));\n\timpl.register_externally_visible_write(instruction->getOperand(4));\n\n\t// Tess factors are for some reason classified as inputs\n\tspv::BuiltIn builtin = { };\n\n\tif (impl.options.max_tess_factor &&\n\t    impl.spirv_module.query_builtin_shader_input(meta.id, &builtin) &&\n\t    (builtin == spv::BuiltInTessLevelInner || builtin == spv::BuiltInTessLevelOuter) &&\n\t    storage_type->isFloatingPointTy() && !type_is_64bit(storage_type))\n\t{\n\t\tspv::Id max_tess_factor_id = builder.makeFloatConstant(impl.options.max_tess_factor);\n\n\t\t// Don't bother bit-twiddling this into an fp16 constant manually\n\t\tif (type_is_16bit(storage_type))\n\t\t{\n\t\t\tmax_tess_factor_id = impl.build_value_cast(max_tess_factor_id, DXIL::ComponentType::F32,\n\t\t\t                                           DXIL::ComponentType::F16, 1);\n\t\t}\n\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\tauto *min_op = impl.allocate(spv::OpExtInst, impl.get_type_id(storage_type));\n\t\tmin_op->add_id(impl.glsl_std450_ext);\n\t\tmin_op->add_literal(GLSLstd450::GLSLstd450NMin);\n\t\tmin_op->add_id(store_value);\n\t\tmin_op->add_id(max_tess_factor_id);\n\t\timpl.add(min_op);\n\n\t\tstore_value = min_op->id;\n\t}\n\n\tOperation *op = impl.allocate(spv::OpStore);\n\top->add_id(ptr_id);\n\n\tif (meta.lowering)\n\t{\n\t\tif (type_is_64bit(storage_type))\n\t\t{\n\t\t\tLOGE(\"Lowering for dxbc 64-bit patch output not supported.\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!storage_type->isIntegerTy())\n\t\t{\n\t\t\tauto *cast_op = impl.allocate(spv::OpBitcast, builder.makeUintType(32));\n\t\t\tcast_op->add_id(store_value);\n\t\t\timpl.add(cast_op);\n\t\t\tstore_value = cast_op->id;\n\t\t}\n\t}\n\telse\n\t{\n\t\tstore_value = impl.fixup_store_type_io(meta.component_type, 1, store_value);\n\t}\n\n\top->add_id(store_value);\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_load_output_generic_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tuint32_t input_element_index;\n\tif (!get_constant_operand(instruction, 1, &input_element_index))\n\t\treturn false;\n\n\t// Normally this is only used for control point reads in tess, but here we make it generic to\n\t// allow reading outputs at any time.\n\t// Technically mesh shader path could go here, but custom IR doesn't support that.\n\tbool is_hull = impl.execution_model == spv::ExecutionModelTessellationControl;\n\tbool array_index = !llvm::isa<llvm::UndefValue>(instruction->getOperand(4)) && is_hull;\n\n\tif (is_hull && !array_index)\n\t{\n\t\tLOGE(\"Hull outputs must be read with array index.\\n\");\n\t\treturn false;\n\t}\n\n\tconst auto &meta = impl.output_elements_meta[input_element_index];\n\tuint32_t var_id = meta.id;\n\n\tspv::Id input_type_id = builder.getDerefTypeId(var_id);\n\n\tif (array_index)\n\t\tinput_type_id = builder.getContainedTypeId(input_type_id);\n\n\tbool row_index = false;\n\tif (builder.isArrayType(input_type_id))\n\t{\n\t\trow_index = true;\n\t\tinput_type_id = builder.getContainedTypeId(input_type_id);\n\t}\n\n\tuint32_t num_cols = builder.getNumTypeComponents(input_type_id);\n\n\t// Need to deal with signed vs unsigned here.\n\tOperation *op = impl.allocate(\n\t    spv::OpAccessChain, builder.makePointer(spv::StorageClassOutput, impl.get_type_id(meta.component_type, 1, 1)));\n\tspv::Id ptr_id = op->id;\n\n\top->add_id(var_id);\n\tif (array_index)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(4)));\n\tif (row_index)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\tif (num_cols > 1)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(3), 32));\n\n\timpl.add(op);\n\n\t// Need to deal with signed vs unsigned here.\n\top = impl.allocate(spv::OpLoad, instruction, impl.get_type_id(meta.component_type, 1, 1));\n\top->add_id(ptr_id);\n\timpl.add(op);\n\n\t// Need to bitcast after we load.\n\timpl.fixup_load_type_io(meta.component_type, 1, instruction);\n\treturn true;\n}\n\nbool emit_domain_location_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id tess_coord_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInTessCoord);\n\n\tauto *op =\n\t    impl.allocate(spv::OpAccessChain, builder.makePointer(spv::StorageClassInput, builder.makeFloatType(32)));\n\top->add_id(tess_coord_id);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1), 32));\n\timpl.add(op);\n\ttess_coord_id = op->id;\n\n\top = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(tess_coord_id);\n\timpl.add(op);\n\n\treturn true;\n}\n\nbool emit_output_control_point_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInInvocationId);\n\n\tauto *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\timpl.add(op);\n\n\treturn true;\n}\n\nbool emit_load_patch_constant_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tuint32_t output_element_index;\n\tif (!get_constant_operand(instruction, 1, &output_element_index))\n\t\treturn false;\n\n\tconst auto &meta = impl.patch_elements_meta[output_element_index];\n\tuint32_t var_id = meta.id;\n\tspv::Id ptr_id;\n\n\tspv::Id output_type_id = builder.getDerefTypeId(var_id);\n\n\tbool row_index = false;\n\tif (builder.isArrayType(output_type_id))\n\t{\n\t\trow_index = true;\n\t\toutput_type_id = builder.getContainedTypeId(output_type_id);\n\t}\n\tuint32_t num_cols = builder.getNumTypeComponents(output_type_id);\n\n\tspv::StorageClass storage = impl.execution_model == spv::ExecutionModelTessellationEvaluation ?\n\t                                spv::StorageClassInput :\n\t                                spv::StorageClassOutput;\n\n\tspv::Id load_type_id;\n\n\tif (row_index || num_cols > 1)\n\t{\n\t\tload_type_id = builder.getScalarTypeId(output_type_id);\n\t\tOperation *op =\n\t\t    impl.allocate(spv::OpAccessChain, builder.makePointer(storage, load_type_id));\n\t\tptr_id = op->id;\n\t\top->add_id(var_id);\n\n\t\tif (row_index)\n\t\t{\n\t\t\tspv::Id row_id = impl.get_id_for_value(instruction->getOperand(2));\n\n\t\t\tif (meta.semantic_offset != 0)\n\t\t\t{\n\t\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\t\tadd_op->add_id(row_id);\n\t\t\t\tadd_op->add_id(builder.makeUintConstant(meta.semantic_offset));\n\t\t\t\timpl.add(add_op);\n\n\t\t\t\trow_id = add_op->id;\n\t\t\t}\n\n\t\t\top->add_id(row_id);\n\t\t}\n\n\t\tif (num_cols > 1)\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(3), 32));\n\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\tptr_id = var_id;\n\t\tload_type_id = output_type_id;\n\t}\n\n\tOperation *op = impl.allocate(spv::OpLoad, instruction, load_type_id);\n\top->add_id(ptr_id);\n\timpl.add(op);\n\n\timpl.fixup_load_type_io(meta.component_type, 1, instruction);\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_tessellation.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_store_patch_constant_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_load_output_generic_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_domain_location_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_load_patch_constant_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_output_control_point_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_waveops.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_waveops.hpp\"\n#include \"dxil_common.hpp\"\n#include \"dxil_resources.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n#include <limits>\n\nnamespace dxil_spv\n{\nstatic bool wave_op_needs_helper_lane_masking(Converter::Impl &impl)\n{\n\treturn impl.execution_model == spv::ExecutionModelFragment &&\n\t       impl.options.strict_helper_lane_waveops &&\n\t       !impl.execution_mode_meta.waveops_include_helper_lanes;\n}\n\nbool emit_wave_is_first_lane_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t{\n\t\tauto *is_helper = impl.allocate(spv::OpIsHelperInvocationEXT, builder.makeBoolType());\n\t\timpl.add(is_helper);\n\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::WaveIsFirstLaneMasked);\n\t\tauto *op = impl.allocate(spv::OpFunctionCall, instruction);\n\t\top->add_id(call_id);\n\t\top->add_id(is_helper->id);\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\tauto *op = impl.allocate(spv::OpGroupNonUniformElect, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\t\timpl.add(op);\n\t}\n\n\treturn true;\n}\n\nstatic void add_vkmm_volatile(Converter::Impl &impl, Operation *op, spv::BuiltIn builtin)\n{\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan &&\n\t    impl.spirv_module.builtin_requires_volatile(builtin))\n\t{\n\t\top->add_literal(spv::MemoryAccessVolatileMask);\n\t}\n}\n\nbool emit_wave_builtin_instruction(spv::BuiltIn builtin, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (impl.options.force_subgroup_size && builtin == spv::BuiltInSubgroupSize)\n\t{\n\t\timpl.rewrite_value(instruction, impl.builder().makeUintConstant(impl.options.force_subgroup_size));\n\t\treturn true;\n\t}\n\n\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(builtin);\n\tauto *op = impl.allocate(spv::OpLoad, instruction);\n\top->add_id(var_id);\n\n\tadd_vkmm_volatile(impl, op, builtin);\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_wave_boolean_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// Given how ReadFirstLane is questionable w.r.t undef, be defensive here for now.\n#if 0\n\tif (opcode == spv::OpGroupNonUniformAllEqual && wave_op_needs_helper_lane_masking(impl))\n\t{\n\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\t\timpl.add(is_helper_lane);\n\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(\n\t\t    HelperCall::WaveActiveAllEqualMasked, impl.get_type_id(instruction->getOperand(1)->getType()));\n\t\tauto *op = impl.allocate(spv::OpFunctionCall, instruction);\n\t\top->add_id(call_id);\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\top->add_id(is_helper_lane->id);\n\n\t\timpl.add(op);\n\t\treturn true;\n\t}\n#endif\n\n\tauto &builder = impl.builder();\n\tauto *op = impl.allocate(opcode, instruction);\n\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\n\tspv::Id value = impl.get_id_for_value(instruction->getOperand(1));\n\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t{\n\t\t// Helper lanes cannot affect the result, but let them participate.\n\t\t// Just force a specific boolean value here that ensures invariant result.\n\n\t\tif (opcode == spv::OpGroupNonUniformAny)\n\t\t{\n\t\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\t\t\timpl.add(is_helper_lane);\n\n\t\t\t// Force false for helpers.\n\t\t\tauto *is_active = impl.allocate(spv::OpLogicalNot, impl.builder().makeBoolType());\n\t\t\tis_active->add_id(is_helper_lane->id);\n\t\t\timpl.add(is_active);\n\t\t\tauto *and_op = impl.allocate(spv::OpLogicalAnd, impl.builder().makeBoolType());\n\t\t\tand_op->add_id(value);\n\t\t\tand_op->add_id(is_active->id);\n\t\t\timpl.add(and_op);\n\t\t\tvalue = and_op->id;\n\t\t}\n\t\telse if (opcode == spv::OpGroupNonUniformAll)\n\t\t{\n\t\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\t\t\timpl.add(is_helper_lane);\n\n\t\t\t// Force true for helpers.\n\t\t\tauto *or_op = impl.allocate(spv::OpLogicalOr, impl.builder().makeBoolType());\n\t\t\tor_op->add_id(value);\n\t\t\tor_op->add_id(is_helper_lane->id);\n\t\t\timpl.add(or_op);\n\t\t\tvalue = or_op->id;\n\t\t}\n\t}\n\n\top->add_id(value);\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformVote);\n\timpl.add(op);\n\treturn true;\n}\n\nstatic spv::Id build_masked_ballot(Converter::Impl &impl, spv::Id input_value)\n{\n\tauto &builder = impl.builder();\n\n\tauto *is_helper = impl.allocate(spv::OpIsHelperInvocationEXT, builder.makeBoolType());\n\timpl.add(is_helper);\n\n\tauto *is_active = impl.allocate(spv::OpLogicalNot, builder.makeBoolType());\n\tis_active->add_id(is_helper->id);\n\timpl.add(is_active);\n\n\tauto *is_active_ballot = impl.allocate(spv::OpLogicalAnd, builder.makeBoolType());\n\tis_active_ballot->add_ids({ input_value, is_active->id });\n\timpl.add(is_active_ballot);\n\n\treturn is_active_ballot->id;\n}\n\nbool emit_wave_ballot_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id bool_value;\n\n\tbool_value = impl.get_id_for_value(instruction->getOperand(1));\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t\tbool_value = build_masked_ballot(impl, bool_value);\n\n\tauto *op = impl.allocate(spv::OpGroupNonUniformBallot, instruction,\n\t                         builder.makeVectorType(builder.makeUintType(32), 4));\n\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\top->add_id(bool_value);\n\n\timpl.add(op);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\treturn true;\n}\n\nbool value_is_statically_wave_uniform(Converter::Impl &impl, const llvm::Value *value)\n{\n\t// A surprising amount of shaders try to broadcast a value that is provably wave-uniform already.\n\t// Just forward this directly ...\n\t// This is an SSA value, so the input must dominate the use. The active threads here must be a subset of\n\t// the active threads when the wave uniform value was generated, so it is impossible for the input value to\n\t// not be wave uniform. We might end up promoting an undef value to not undef, but that is fine, since undef is ...\n\t// well, undef.\n\n\tif (const auto *unary = llvm::dyn_cast<llvm::UnaryOperator>(value))\n\t{\n\t\treturn value_is_statically_wave_uniform(impl, unary->getOperand(0));\n\t}\n\telse if (const auto *binary = llvm::dyn_cast<llvm::BinaryOperator>(value))\n\t{\n\t\treturn value_is_statically_wave_uniform(impl, binary->getOperand(0)) &&\n\t\t       value_is_statically_wave_uniform(impl, binary->getOperand(1));\n\t}\n\n\tif (value_is_dx_op_instrinsic(value, DXIL::Op::AnnotateNodeHandle))\n\t{\n\t\tauto *node = llvm::cast<llvm::CallInst>(value)->getOperand(1);\n\t\t// This is a static index.\n\t\tif (!value_is_dx_op_instrinsic(node, DXIL::Op::IndexNodeHandle))\n\t\t\treturn true;\n\n\t\t// If the array index is wave uniform, the handle is wave uniform.\n\t\tvalue = llvm::cast<llvm::CallInst>(node)->getOperand(2);\n\t}\n\n\t// Buffer loads usually go through extractvalue first.\n\t// Ignore extractelement, it's only used in esoteric cases in DXR.\n\tif (const auto *extract = llvm::dyn_cast<llvm::ExtractValueInst>(value))\n\t\tvalue = extract->getAggregateOperand();\n\n\tif (llvm::isa<llvm::Constant>(value))\n\t\treturn true;\n\n\tif (value_is_dx_op_instrinsic(value, DXIL::Op::WaveActiveOp) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::WaveActiveAllEqual) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::WaveActiveBit) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::WaveActiveBallot) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::WaveAnyTrue) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::WaveAllTrue) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::WaveReadLaneFirst) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::GroupId))\n\t{\n\t\treturn true;\n\t}\n\n\t// Also detect loading a provably uniform value. This happens as well for some reason ...\n\tif (value_is_dx_op_instrinsic(value, DXIL::Op::CBufferLoadLegacy) ||\n\t    value_is_dx_op_instrinsic(value, DXIL::Op::CBufferLoad))\n\t{\n\t\tauto *call_op = llvm::cast<llvm::CallInst>(value);\n\t\treturn value_is_statically_wave_uniform(impl, call_op->getOperand(2)) &&\n\t\t       resource_handle_is_uniform_readonly_descriptor(impl, call_op->getOperand(1));\n\t}\n\telse if (value_is_dx_op_instrinsic(value, DXIL::Op::BufferLoad) ||\n\t         value_is_dx_op_instrinsic(value, DXIL::Op::RawBufferLoad))\n\t{\n\t\tauto *call_op = llvm::cast<llvm::CallInst>(value);\n\n\t\t// For byte-address-buffers, arg 3 will be undef and treated as wave uniform (it's a constant).\n\t\treturn value_is_statically_wave_uniform(impl, call_op->getOperand(2)) &&\n\t\t       value_is_statically_wave_uniform(impl, call_op->getOperand(3)) &&\n\t\t       resource_handle_is_uniform_readonly_descriptor(impl, call_op->getOperand(1));\n\t}\n\n\treturn false;\n}\n\nstatic bool value_depends_on_dxil_op(\n    const llvm::Instruction *inst, UnorderedSet<const llvm::Instruction *> &visit_cache,\n    const DXIL::Op *ops, unsigned ops_count)\n{\n\tif (visit_cache.count(inst))\n\t\treturn false;\n\tvisit_cache.insert(inst);\n\n\tfor (unsigned i = 0; i < ops_count; i++)\n\t\tif (value_is_dx_op_instrinsic(inst, ops[i]))\n\t\t\treturn true;\n\n\tif (const auto *phi = llvm::dyn_cast<llvm::PHINode>(inst))\n\t{\n\t\tfor (uint32_t i = 0; i < phi->getNumIncomingValues(); i++)\n\t\t\tif (const auto *dependent_inst = llvm::dyn_cast<llvm::Instruction>(phi->getIncomingValue(i)))\n\t\t\t\tif (value_depends_on_dxil_op(dependent_inst, visit_cache, ops, ops_count))\n\t\t\t\t\treturn true;\n\t}\n\telse\n\t{\n\t\tfor (uint32_t i = 0; i < inst->getNumOperands(); i++)\n\t\t\tif (const auto *dependent_inst = llvm::dyn_cast<llvm::Instruction>(inst->getOperand(i)))\n\t\t\t\tif (value_depends_on_dxil_op(dependent_inst, visit_cache, ops, ops_count))\n\t\t\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool value_is_likely_non_uniform(Converter::Impl &, const llvm::Value *value)\n{\n\t// If the index is loaded from VS input or PS varying, it's almost guaranteed to be nonuniform in some way.\n\t// Similar with using InstanceID as bindless index.\n\tUnorderedSet<const llvm::Instruction *> visit_cache;\n\tif (const auto *inst = llvm::dyn_cast<llvm::Instruction>(value))\n\t{\n\t\tstatic const DXIL::Op ops[] = { DXIL::Op::LoadInput, DXIL::Op::InstanceID };\n\t\treturn value_depends_on_dxil_op(inst, visit_cache, ops, 2);\n\t}\n\telse\n\t\treturn false;\n}\n\nstatic bool value_is_local_invocation_index_dependent(const llvm::Value *value)\n{\n\t// If the index is loaded from VS input or PS varying, it's almost guaranteed to be nonuniform in some way.\n\t// Similar with using InstanceID as bindless index.\n\tUnorderedSet<const llvm::Instruction *> visit_cache;\n\tif (const auto *inst = llvm::dyn_cast<llvm::Instruction>(value))\n\t{\n\t\tstatic const DXIL::Op ops[] = { DXIL::Op::ThreadIdInGroup, DXIL::Op::FlattenedThreadIdInGroup };\n\t\treturn value_depends_on_dxil_op(inst, visit_cache, ops, 2);\n\t}\n\telse\n\t\treturn false;\n}\n\nbool emit_wave_read_lane_first_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (value_is_statically_wave_uniform(impl, instruction->getOperand(1)))\n\t{\n\t\t// This is hit where you least expect ;_;\n\t\timpl.rewrite_value(instruction, impl.get_id_for_value(instruction->getOperand(1)));\n\t\treturn true;\n\t}\n\n\tif (wave_op_needs_helper_lane_masking(impl) && impl.wave_op_forced_helper_lanes.count(instruction) == 0)\n\t{\n\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\t\timpl.add(is_helper_lane);\n\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::WaveReadFirstLaneMasked,\n\t\t                                                       impl.get_type_id(instruction->getOperand(1)->getType()));\n\t\tauto *op = impl.allocate(spv::OpFunctionCall, instruction);\n\t\top->add_id(call_id);\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\top->add_id(is_helper_lane->id);\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\tauto &builder = impl.builder();\n\t\tauto *op = impl.allocate(spv::OpGroupNonUniformBroadcastFirst, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\n\t\timpl.add(op);\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t}\n\n\treturn true;\n}\n\nstatic bool execution_model_can_quad_op(spv::ExecutionModel model)\n{\n\treturn model == spv::ExecutionModelFragment ||\n\t       model == spv::ExecutionModelGLCompute;\n}\n\nstatic bool value_is_wave_lane(const llvm::Value *value)\n{\n\tauto *dxil_op = llvm::dyn_cast<llvm::CallInst>(value);\n\tif (!dxil_op)\n\t\treturn false;\n\tif (strncmp(dxil_op->getCalledFunction()->getName().data(), \"dx.op\", 5) != 0)\n\t\treturn false;\n\n\tuint32_t op;\n\tif (!get_constant_operand(dxil_op, 0, &op))\n\t\treturn false;\n\n\treturn DXIL::Op(op) == DXIL::Op::WaveGetLaneIndex;\n}\n\nstatic bool get_constant_int(const llvm::Value *value, uint32_t *const_value)\n{\n\tif (const auto *c = llvm::dyn_cast<llvm::ConstantInt>(value))\n\t{\n\t\t*const_value = uint32_t(c->getUniqueInteger().getZExtValue());\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nstatic bool get_constant_xor_lane(const llvm::Value *lane, uint32_t *xor_lane)\n{\n\tauto *binop = llvm::dyn_cast<llvm::BinaryOperator>(lane);\n\tif (!binop)\n\t\treturn false;\n\n\tif (binop->getOpcode() != llvm::BinaryOperator::BinaryOps::Xor)\n\t\treturn false;\n\n\tauto *lhs = binop->getOperand(0);\n\tauto *rhs = binop->getOperand(1);\n\tbool lhs_is_wave_lane = value_is_wave_lane(lhs);\n\tbool rhs_is_wave_lane = value_is_wave_lane(rhs);\n\n\tif (lhs_is_wave_lane && llvm::isa<llvm::ConstantInt>(rhs))\n\t\treturn get_constant_int(rhs, xor_lane);\n\telse if (rhs_is_wave_lane && llvm::isa<llvm::ConstantInt>(lhs))\n\t\treturn get_constant_int(lhs, xor_lane);\n\n\treturn false;\n}\n\nstatic bool get_constant_quad_lane(const llvm::Value *lane, uint32_t *quad_lane)\n{\n\t// Cases to consider:\n\t// - (gl_SubgroupInvocationID & ~3u) | C, where C is [0, 1, 2, 3].\n\t// - (gl_SubgroupInvocationID & ~3u) + C, where C is [0, 1, 2, 3].\n\t// - (gl_SubgroupInvocationID & ~3u) -> C = 0\n\t// - (gl_SubgroupInvocationID | 3u) -> C = 3\n\tauto *binop = llvm::dyn_cast<llvm::BinaryOperator>(lane);\n\tif (!binop)\n\t\treturn false;\n\n\tauto *lhs = binop->getOperand(0);\n\tauto *rhs = binop->getOperand(1);\n\tbool lhs_is_wave_lane = value_is_wave_lane(lhs);\n\tbool rhs_is_wave_lane = value_is_wave_lane(rhs);\n\tuint32_t secondary_quad_lane = 0;\n\n\tif (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Or)\n\t{\n\t\tif ((get_constant_int(lhs, quad_lane) && rhs_is_wave_lane) ||\n\t\t    (lhs_is_wave_lane && get_constant_int(rhs, quad_lane)))\n\t\t{\n\t\t\t// Case 3\n\t\t\treturn *quad_lane == 3;\n\t\t}\n\t\telse if ((get_constant_int(lhs, quad_lane) && get_constant_quad_lane(rhs, &secondary_quad_lane)) ||\n\t\t         (get_constant_quad_lane(lhs, &secondary_quad_lane) && get_constant_int(rhs, quad_lane)))\n\t\t{\n\t\t\t// Case 0\n\t\t\treturn *quad_lane < 4 && secondary_quad_lane == 0;\n\t\t}\n\t}\n\telse if (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::And)\n\t{\n\t\tif ((get_constant_int(lhs, quad_lane) && rhs_is_wave_lane) ||\n\t\t    (lhs_is_wave_lane && get_constant_int(rhs, quad_lane)))\n\t\t{\n\t\t\t// Case 2\n\t\t\tif (*quad_lane == ~3u)\n\t\t\t{\n\t\t\t\t*quad_lane = 0;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\telse if (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::Add)\n\t{\n\t\tif ((get_constant_int(lhs, quad_lane) && get_constant_quad_lane(rhs, &secondary_quad_lane)) ||\n\t\t    (get_constant_quad_lane(lhs, &secondary_quad_lane) && get_constant_int(rhs, quad_lane)))\n\t\t{\n\t\t\t// Case 0\n\t\t\treturn *quad_lane < 4 && secondary_quad_lane == 0;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic bool lane_is_wave32_masked(const llvm::Value *lane)\n{\n\tconst auto *bin_op = llvm::dyn_cast<llvm::BinaryOperator>(lane);\n\tif (!bin_op)\n\t\treturn false;\n\n\tif (bin_op->getOpcode() != llvm::BinaryOperator::BinaryOps::And &&\n\t    bin_op->getOpcode() != llvm::BinaryOperator::BinaryOps::URem)\n\t\treturn false;\n\n\tauto *op0 = bin_op->getOperand(0);\n\tauto *op1 = bin_op->getOperand(1);\n\n\tif (llvm::isa<llvm::ConstantInt>(op1))\n\t\tstd::swap(op0, op1);\n\n\tconst auto *const_mask = llvm::dyn_cast<llvm::ConstantInt>(op0);\n\tif (!const_mask)\n\t\treturn false;\n\n\tuint32_t mask = const_mask->getUniqueInteger().getZExtValue();\n\treturn (bin_op->getOpcode() == llvm::BinaryOperator::BinaryOps::And && mask == 31) ||\n\t       (bin_op->getOpcode() == llvm::BinaryOperator::BinaryOps::URem && mask == 32);\n}\n\nbool emit_wave_read_lane_at_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tauto *lane = instruction->getOperand(2);\n\n\tOperation *op;\n\tif (llvm::isa<llvm::ConstantInt>(lane))\n\t{\n\t\top = impl.allocate(spv::OpGroupNonUniformBroadcast, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\top->add_id(impl.get_id_for_value(lane));\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t}\n\telse\n\t{\n\t\t// Some games seem to use WaveReadLaneAt where it should have used QuadReadLaneAt.\n\t\t// This generates a flurry of ds_permute instructions, where it could have used implicit quad shuffle instead.\n\t\t// Rather than emitting a ton of shuffles, try to optimize the statements back to a quad broadcast.\n\n\t\tuint32_t const_lane = 0;\n\t\tif (execution_model_can_quad_op(impl.execution_model) && get_constant_quad_lane(lane, &const_lane))\n\t\t{\n\t\t\top = impl.allocate(spv::OpGroupNonUniformQuadBroadcast, instruction);\n\t\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\t\top->add_id(builder.makeUintConstant(const_lane));\n\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\t\t}\n\t\telse if (get_constant_xor_lane(lane, &const_lane))\n\t\t{\n\t\t\tif (execution_model_can_quad_op(impl.execution_model) && const_lane < 4 && const_lane > 0)\n\t\t\t{\n\t\t\t\t// Here we assume that derivative groups are 1D.\n\t\t\t\t// This is always the case since we rewrite LocalInvocationID.\n\t\t\t\top = impl.allocate(spv::OpGroupNonUniformQuadSwap, instruction);\n\t\t\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\t\t\top->add_id(builder.makeUintConstant(const_lane - 1u));\n\t\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\top = impl.allocate(spv::OpGroupNonUniformShuffleXor, instruction);\n\t\t\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\t\t\top->add_id(builder.makeUintConstant(const_lane));\n\t\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformShuffle);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\top = impl.allocate(spv::OpGroupNonUniformShuffle, instruction);\n\t\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\t\top->add_id(impl.get_id_for_value(lane));\n\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformShuffle);\n\n\t\t\t// For shuffle, wave64 is particularly slow on RDNA, so suggest wave32.\n\t\t\timpl.suggest_maximum_wave_size(32);\n\n\t\t\tif (impl.execution_model == spv::ExecutionModelGLCompute ||\n\t\t\t    impl.execution_model == spv::ExecutionModelMeshEXT ||\n\t\t\t    impl.execution_model == spv::ExecutionModelTaskEXT)\n\t\t\t{\n\t\t\t\tif (!impl.shader_analysis.has_group_shared_barrier &&\n\t\t\t\t    impl.execution_mode_meta.workgroup_threads[0] == 32 &&\n\t\t\t\t    impl.execution_mode_meta.workgroup_threads[1] == 1 &&\n\t\t\t\t    impl.execution_mode_meta.workgroup_threads[2] == 1 &&\n\t\t\t\t    lane_is_wave32_masked(lane))\n\t\t\t\t{\n\t\t\t\t\t// Intel workaround. Some shaders may simply assume that wave16 doesn't exist.\n\t\t\t\t\t// The heuristic is to check if shader masks the lane by a constant 31\n\t\t\t\t\t// and no group-shared is used, which would suggest that shader considers wave size < 32.\n\t\t\t\t\timpl.suggest_minimum_wave_size(32);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\timpl.shader_analysis.require_subgroup_shuffles = true;\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_wave_bit_count_instruction(spv::GroupOperation operation, Converter::Impl &impl,\n                                     const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tauto *ballot_op = impl.allocate(spv::OpGroupNonUniformBallot, builder.makeVectorType(builder.makeUintType(32), 4));\n\tballot_op->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\n\tspv::Id bool_value = impl.get_id_for_value(instruction->getOperand(1));\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t\tbool_value = build_masked_ballot(impl, bool_value);\n\tballot_op->add_id(bool_value);\n\n\timpl.add(ballot_op);\n\n\tauto *op = impl.allocate(spv::OpGroupNonUniformBallotBitCount, instruction);\n\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\top->add_literal(operation);\n\top->add_id(ballot_op->id);\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\timpl.add(op);\n\treturn true;\n}\n\nstatic spv::Op select_opcode(const llvm::CallInst *instruction, spv::Op fp, spv::Op s, spv::Op u)\n{\n\tuint32_t sign_kind;\n\tif (!get_constant_operand(instruction, 3, &sign_kind))\n\t\treturn spv::OpNop;\n\n\tif (instruction->getType()->getTypeID() != llvm::Type::TypeID::IntegerTyID)\n\t\treturn fp;\n\telse if (static_cast<DXIL::SignedOpKind>(sign_kind) == DXIL::SignedOpKind::Signed)\n\t\treturn s;\n\telse\n\t\treturn u;\n}\n\nstatic spv::Id build_mask_reduction_input_arith(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                spv::Id input_value, DXIL::WaveOpKind op_kind)\n{\n\tauto &builder = impl.builder();\n\n\t// For arithmetic cases, we can just replace the input with a sentinel value\n\t// if we're a helper lane.\n\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\timpl.add(is_helper_lane);\n\n\tuint32_t sign_kind;\n\tif (!get_constant_operand(instruction, 3, &sign_kind))\n\t\treturn 0;\n\n#define DECLARE_TYPE_TEMPLATE(type, product, sum, min, max) do { \\\n\tswitch (op_kind) \\\n\t{ \\\n\tcase DXIL::WaveOpKind::Product: \\\n\t\treplacement_value = builder.make##type##Constant(product); \\\n\t\tbreak; \\\n\tcase DXIL::WaveOpKind::Sum: \\\n\t\treplacement_value = builder.make##type##Constant(sum); \\\n\t\tbreak; \\\n\tcase DXIL::WaveOpKind::Min: \\\n\t\treplacement_value = builder.make##type##Constant(min); \\\n\t\tbreak; \\\n\tcase DXIL::WaveOpKind::Max: \\\n\t\treplacement_value = builder.make##type##Constant(max); \\\n\t\tbreak; \\\n\t} \\\n} while(0)\n\n\tspv::Id replacement_value;\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID)\n\t{\n\t\tDECLARE_TYPE_TEMPLATE(Float,\n\t\t                      1.0f, 0.0f,\n\t\t                      std::numeric_limits<float>::infinity(),\n\t\t                      -std::numeric_limits<float>::infinity());\n\t}\n\telse if (instruction->getType()->getTypeID() == llvm::Type::TypeID::DoubleTyID)\n\t{\n\t\tDECLARE_TYPE_TEMPLATE(Double,\n\t\t                      1.0, 0.0,\n\t\t                      std::numeric_limits<double>::infinity(),\n\t\t                      -std::numeric_limits<double>::infinity());\n\t}\n\telse if (instruction->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t{\n\t\tDECLARE_TYPE_TEMPLATE(Float16, 0x3c00, 0, 0x7c00, 0xfc00);\n\t}\n\telse if (static_cast<DXIL::SignedOpKind>(sign_kind) == DXIL::SignedOpKind::Signed)\n\t{\n\t\tswitch (instruction->getOperand(1)->getType()->getIntegerBitWidth())\n\t\t{\n\t\tcase 16:\n\t\t\tDECLARE_TYPE_TEMPLATE(Uint16, 1, 0,\n\t\t\t                      uint16_t(std::numeric_limits<int16_t>::max()),\n\t\t\t                      uint16_t(std::numeric_limits<int16_t>::min()));\n\t\t\tbreak;\n\n\t\tcase 32:\n\t\t\tDECLARE_TYPE_TEMPLATE(Uint, 1, 0,\n\t\t\t                      uint32_t(std::numeric_limits<int32_t>::max()),\n\t\t\t                      uint32_t(std::numeric_limits<int32_t>::min()));\n\t\t\tbreak;\n\n\t\tcase 64:\n\t\t\tDECLARE_TYPE_TEMPLATE(Uint64, 1, 0,\n\t\t\t                      uint64_t(std::numeric_limits<int64_t>::max()),\n\t\t\t                      uint64_t(std::numeric_limits<int64_t>::min()));\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn 0;\n\t\t}\n\t}\n\telse\n\t{\n\t\tswitch (instruction->getOperand(1)->getType()->getIntegerBitWidth())\n\t\t{\n\t\tcase 16:\n\t\t\tDECLARE_TYPE_TEMPLATE(Uint16, 1, 0,\n\t\t\t                      std::numeric_limits<uint16_t>::max(),\n\t\t\t                      std::numeric_limits<uint16_t>::min());\n\t\t\tbreak;\n\n\t\tcase 32:\n\t\t\tDECLARE_TYPE_TEMPLATE(Uint, 1, 0,\n\t\t\t                      std::numeric_limits<uint32_t>::max(),\n\t\t\t                      std::numeric_limits<uint32_t>::min());\n\t\t\tbreak;\n\n\t\tcase 64:\n\t\t\tDECLARE_TYPE_TEMPLATE(Uint64, 1, 0,\n\t\t\t                      std::numeric_limits<uint64_t>::max(),\n\t\t\t                      std::numeric_limits<uint64_t>::min());\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tauto *replace_op = impl.allocate(spv::OpSelect, impl.get_type_id(instruction->getOperand(1)->getType()));\n\treplace_op->add_id(is_helper_lane->id);\n\treplace_op->add_id(replacement_value);\n\treplace_op->add_id(input_value);\n\timpl.add(replace_op);\n\treturn replace_op->id;\n}\n\nstatic spv::Id build_mask_reduction_input_bitwise(Converter::Impl &impl, const llvm::CallInst *instruction,\n                                                  spv::Id input_value, DXIL::WaveBitOpKind op_kind)\n{\n\tauto &builder = impl.builder();\n\n\t// For bitwise cases, we can just replace the input with a sentinel value\n\t// if we're a helper lane.\n\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\timpl.add(is_helper_lane);\n\n\tspv::Id replacement_value;\n\tswitch (instruction->getOperand(1)->getType()->getIntegerBitWidth())\n\t{\n\tcase 16:\n\t\treplacement_value = builder.makeUint16Constant(\n\t\t    op_kind == DXIL::WaveBitOpKind::And ? std::numeric_limits<uint16_t>::max() : 0u);\n\t\tbreak;\n\n\tcase 32:\n\t\treplacement_value = builder.makeUintConstant(\n\t\t\top_kind == DXIL::WaveBitOpKind::And ? std::numeric_limits<uint32_t>::max() : 0u);\n\t\tbreak;\n\n\tcase 64:\n\t\treplacement_value = builder.makeUint64Constant(\n\t\t\top_kind == DXIL::WaveBitOpKind::And ? std::numeric_limits<uint64_t>::max() : 0u);\n\t\tbreak;\n\n\tdefault:\n\t\treplacement_value = 0;\n\t\tbreak;\n\t}\n\n\tauto *replace_op = impl.allocate(spv::OpSelect, impl.get_type_id(instruction->getOperand(1)->getType()));\n\treplace_op->add_id(is_helper_lane->id);\n\treplace_op->add_id(replacement_value);\n\treplace_op->add_id(input_value);\n\timpl.add(replace_op);\n\treturn replace_op->id;\n}\n\nstatic spv::Op select_opcode(const llvm::CallInst *instruction, spv::Op fp, spv::Op i)\n{\n\tif (instruction->getType()->getTypeID() != llvm::Type::TypeID::IntegerTyID)\n\t\treturn fp;\n\telse\n\t\treturn i;\n}\n\nbool emit_wave_active_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Op opcode = spv::OpNop;\n\n\tuint32_t op_kind;\n\tif (!get_constant_operand(instruction, 2, &op_kind))\n\t\treturn false;\n\n\tswitch (DXIL::WaveOpKind(op_kind))\n\t{\n\tcase DXIL::WaveOpKind::Sum:\n\t\topcode = select_opcode(instruction, spv::OpGroupNonUniformFAdd, spv::OpGroupNonUniformIAdd,\n\t\t                       spv::OpGroupNonUniformIAdd);\n\t\tbreak;\n\n\tcase DXIL::WaveOpKind::Product:\n\t\topcode = select_opcode(instruction, spv::OpGroupNonUniformFMul, spv::OpGroupNonUniformIMul,\n\t\t                       spv::OpGroupNonUniformIMul);\n\t\tbreak;\n\n\tcase DXIL::WaveOpKind::Min:\n\t\topcode = select_opcode(instruction, spv::OpGroupNonUniformFMin, spv::OpGroupNonUniformSMin,\n\t\t                       spv::OpGroupNonUniformUMin);\n\t\tbreak;\n\n\tcase DXIL::WaveOpKind::Max:\n\t\topcode = select_opcode(instruction, spv::OpGroupNonUniformFMax, spv::OpGroupNonUniformSMax,\n\t\t                       spv::OpGroupNonUniformUMax);\n\t\tbreak;\n\t}\n\n\tauto *op = impl.allocate(opcode, instruction);\n\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\top->add_literal(spv::GroupOperationReduce);\n\n\tspv::Id input_value = impl.get_id_for_value(instruction->getOperand(1));\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t\tinput_value = build_mask_reduction_input_arith(impl, instruction, input_value, DXIL::WaveOpKind(op_kind));\n\n\top->add_id(input_value);\n\n\timpl.add(op);\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformArithmetic);\n\n\tif (impl.execution_model == spv::ExecutionModelGLCompute ||\n\t    impl.execution_model == spv::ExecutionModelMeshEXT ||\n\t    impl.execution_model == spv::ExecutionModelTaskEXT)\n\t{\n\t\tif (impl.execution_mode_meta.workgroup_threads[0] == 32 &&\n\t\t    impl.execution_mode_meta.workgroup_threads[1] == 1 &&\n\t\t    impl.execution_mode_meta.workgroup_threads[2] == 1 &&\n\t\t    value_is_local_invocation_index_dependent(instruction->getOperand(1)))\n\t\t{\n\t\t\t// Intel workaround. Some shaders may simply assume that wave16 doesn't exist.\n\t\t\t// The heuristic is to check if the broadcast depends on LocalInvocationID.\n\t\t\t// On wave32, LocalInvocationID is vaguely equal to SubgroupInvocationID,\n\t\t\t// but on Wave16, that assumption does not hold, so a shader doing that looks sus.\n\t\t\timpl.suggest_minimum_wave_size(32);\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool emit_wave_prefix_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Op opcode;\n\n\tuint32_t op_kind;\n\tif (!get_constant_operand(instruction, 2, &op_kind))\n\t\treturn false;\n\n\tswitch (static_cast<DXIL::WaveOpKind>(op_kind))\n\t{\n\tcase DXIL::WaveOpKind::Sum:\n\t\topcode = select_opcode(instruction, spv::OpGroupNonUniformFAdd, spv::OpGroupNonUniformIAdd);\n\t\tbreak;\n\n\tcase DXIL::WaveOpKind::Product:\n\t\topcode = select_opcode(instruction, spv::OpGroupNonUniformFMul, spv::OpGroupNonUniformIMul);\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tauto *op = impl.allocate(opcode, instruction);\n\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\top->add_literal(spv::GroupOperationExclusiveScan);\n\n\tspv::Id input_value = impl.get_id_for_value(instruction->getOperand(1));\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t\tinput_value = build_mask_reduction_input_arith(impl, instruction, input_value, DXIL::WaveOpKind(op_kind));\n\n\top->add_id(input_value);\n\n\timpl.add(op);\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformArithmetic);\n\treturn true;\n}\n\nbool emit_wave_multi_prefix_count_bits_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\t// There is no NV equivalent for this one.\n\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::WaveMultiPrefixCountBits);\n\tauto *op = impl.allocate(spv::OpFunctionCall, instruction);\n\top->add_id(call_id);\n\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\n\tspv::Id ballot[4];\n\tfor (unsigned i = 0; i < 4; i++)\n\t\tballot[i] = impl.get_id_for_value(instruction->getOperand(2 + i));\n\top->add_id(impl.build_vector(builder.makeUintType(32), ballot, 4));\n\n\tif (!impl.options.nv_subgroup_partition_enabled &&\n\t    wave_op_needs_helper_lane_masking(impl))\n\t{\n\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\t\timpl.add(is_helper_lane);\n\t\top->add_id(is_helper_lane->id);\n\t}\n\n\timpl.add(op);\n\n\treturn true;\n}\n\nstatic spv::Id emit_masked_ballot(Converter::Impl &impl, spv::Id value)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id uvec4_type = builder.makeVectorType(builder.makeUintType(32), 4);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\tauto *ballot_op = impl.allocate(spv::OpGroupNonUniformBallot, uvec4_type);\n\tballot_op->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\n\tspv::Id helper_ballot = 0;\n\tspv::Id is_helper_id = 0;\n\tspv::Id ballot_id;\n\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t{\n\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, builder.makeBoolType());\n\t\timpl.add(is_helper_lane);\n\t\tis_helper_id = is_helper_lane->id;\n\n\t\tauto *helper_op = impl.allocate(spv::OpGroupNonUniformBallot,\n\t\t                                builder.makeVectorType(builder.makeUintType(32), 4));\n\t\thelper_op->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\thelper_op->add_id(is_helper_id);\n\t\timpl.add(helper_op);\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t\thelper_ballot = helper_op->id;\n\n\t\tauto *not_op = impl.allocate(spv::OpLogicalNot, builder.makeBoolType());\n\t\tnot_op->add_id(is_helper_id);\n\t\timpl.add(not_op);\n\n\t\tballot_id = not_op->id;\n\t}\n\telse\n\t{\n\t\tballot_id = builder.makeBoolConstant(true);\n\t}\n\n\tballot_op->add_id(ballot_id);\n\timpl.add(ballot_op);\n\n\tauto *and_op = impl.allocate(spv::OpBitwiseAnd, uvec4_type);\n\tand_op->add_id(value);\n\tand_op->add_id(ballot_op->id);\n\timpl.add(and_op);\n\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t{\n\t\t// Helper lanes may participate, and they will need a valid partition mask, since the SPV_NV extension\n\t\t// requires this.\n\t\tconst spv::Id is_helper_ids[] = { is_helper_id, is_helper_id, is_helper_id, is_helper_id };\n\t\tspv::Id bvec_splat_id = impl.build_vector(builder.makeBoolType(), is_helper_ids, 4);\n\n\t\tauto *ballot_select = impl.allocate(spv::OpSelect, builder.makeVectorType(builder.makeUintType(32), 4));\n\t\tballot_select->add_id(bvec_splat_id);\n\t\tballot_select->add_id(helper_ballot);\n\t\tballot_select->add_id(and_op->id);\n\t\timpl.add(ballot_select);\n\n\t\treturn ballot_select->id;\n\t}\n\telse\n\t{\n\t\treturn and_op->id;\n\t}\n}\n\nbool emit_wave_multi_prefix_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tuint32_t op_kind;\n\tif (!get_constant_operand(instruction, 6, &op_kind))\n\t\treturn false;\n\n\tHelperCall helper_call;\n\tspv::Op partitioned_op;\n\tbool fp = !instruction->getOperand(1)->getType()->isIntegerTy();\n\n\tswitch (static_cast<DXIL::WaveMultiPrefixOpKind>(op_kind))\n\t{\n\tcase DXIL::WaveMultiPrefixOpKind::Sum:\n\t\thelper_call = fp ? HelperCall::WaveMultiPrefixFAdd : HelperCall::WaveMultiPrefixIAdd;\n\t\tpartitioned_op = fp ? spv::OpGroupNonUniformFAdd : spv::OpGroupNonUniformIAdd;\n\t\tbreak;\n\n\tcase DXIL::WaveMultiPrefixOpKind::Product:\n\t\thelper_call = fp ? HelperCall::WaveMultiPrefixFMul : HelperCall::WaveMultiPrefixIMul;\n\t\tpartitioned_op = fp ? spv::OpGroupNonUniformFMul : spv::OpGroupNonUniformIMul;\n\t\tbreak;\n\n\tcase DXIL::WaveMultiPrefixOpKind::And:\n\t\thelper_call = HelperCall::WaveMultiPrefixBitAnd;\n\t\tpartitioned_op = spv::OpGroupNonUniformBitwiseAnd;\n\t\tbreak;\n\n\tcase DXIL::WaveMultiPrefixOpKind::Or:\n\t\thelper_call = HelperCall::WaveMultiPrefixBitOr;\n\t\tpartitioned_op = spv::OpGroupNonUniformBitwiseOr;\n\t\tbreak;\n\n\tcase DXIL::WaveMultiPrefixOpKind::Xor:\n\t\thelper_call = HelperCall::WaveMultiPrefixBitXor;\n\t\tpartitioned_op = spv::OpGroupNonUniformBitwiseXor;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tspv::Id type_id = impl.get_type_id(instruction->getOperand(1)->getType());\n\n\tOperation *op;\n\n\tif (impl.options.nv_subgroup_partition_enabled)\n\t{\n\t\tbuilder.addExtension(\"SPV_NV_shader_subgroup_partitioned\");\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV);\n\t\top = impl.allocate(partitioned_op, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_literal(spv::GroupOperationPartitionedExclusiveScanNV);\n\t}\n\telse\n\t{\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(helper_call, type_id);\n\t\top = impl.allocate(spv::OpFunctionCall, instruction);\n\t\top->add_id(call_id);\n\t}\n\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\n\tspv::Id ballot[4];\n\tfor (unsigned i = 0; i < 4; i++)\n\t\tballot[i] = impl.get_id_for_value(instruction->getOperand(2 + i));\n\n\tspv::Id ballot_value = impl.build_vector(builder.makeUintType(32), ballot, 4);\n\n\t// Have to explicitly ignore inactive lanes here to make sure that lanes in the same partition have equal\n\t// partition values.\n\tif (impl.options.nv_subgroup_partition_enabled)\n\t\tballot_value = emit_masked_ballot(impl, ballot_value);\n\n\top->add_id(ballot_value);\n\n\tif (!impl.options.nv_subgroup_partition_enabled &&\n\t    wave_op_needs_helper_lane_masking(impl))\n\t{\n\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\t\timpl.add(is_helper_lane);\n\t\top->add_id(is_helper_lane->id);\n\t}\n\n\timpl.add(op);\n\n\treturn true;\n}\n\nbool emit_wave_active_bit_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Op opcode = spv::OpNop;\n\n\tuint32_t op_kind;\n\tif (!get_constant_operand(instruction, 2, &op_kind))\n\t\treturn false;\n\n\tswitch (static_cast<DXIL::WaveBitOpKind>(op_kind))\n\t{\n\tcase DXIL::WaveBitOpKind::And:\n\t\topcode = spv::OpGroupNonUniformBitwiseAnd;\n\t\tbreak;\n\n\tcase DXIL::WaveBitOpKind::Or:\n\t\topcode = spv::OpGroupNonUniformBitwiseOr;\n\t\tbreak;\n\n\tcase DXIL::WaveBitOpKind::Xor:\n\t\topcode = spv::OpGroupNonUniformBitwiseXor;\n\t\tbreak;\n\t}\n\n\tauto *op = impl.allocate(opcode, instruction);\n\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\top->add_literal(spv::GroupOperationReduce);\n\n\tspv::Id input_value = impl.get_id_for_value(instruction->getOperand(1));\n\tif (wave_op_needs_helper_lane_masking(impl))\n\t\tinput_value = build_mask_reduction_input_bitwise(impl, instruction, input_value, DXIL::WaveBitOpKind(op_kind));\n\n\top->add_id(input_value);\n\n\timpl.add(op);\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformArithmetic);\n\treturn true;\n}\n\nbool emit_wave_quad_vote_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tuint32_t vote_kind;\n\tif (!get_constant_operand(instruction, 2, &vote_kind))\n\t\treturn false;\n\n\temit_expect_assume_quad_uniform(impl);\n\n\tif (impl.options.supports_quad_control)\n\t{\n\t\tauto &builder = impl.builder();\n\t\tbuilder.addExtension(\"SPV_KHR_quad_control\");\n\t\tbuilder.addCapability(spv::CapabilityQuadControlKHR);\n\n\t\tspv::Op opcode = vote_kind ? spv::OpGroupNonUniformQuadAllKHR : spv::OpGroupNonUniformQuadAnyKHR;\n\n\t\tauto *op = impl.allocate(opcode, instruction);\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\t// All lanes must be active according to SM 6.7 (and backed up by tests), so quadBroadcast\n\t\t// pattern is valid and can be optimized by compilers into the intrinsic short form.\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(vote_kind ? HelperCall::QuadAll : HelperCall::QuadAny);\n\n\t\tauto *op = impl.allocate(spv::OpFunctionCall, instruction);\n\t\top->add_id(call_id);\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(op);\n\t}\n\n\tif (impl.execution_model == spv::ExecutionModelFragment)\n\t\timpl.execution_mode_meta.needs_quad_derivatives = true;\n\n\treturn true;\n}\n\nbool emit_wave_quad_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tif (impl.execution_mode_meta.synthesize_dummy_derivatives)\n\t{\n\t\timpl.rewrite_value(instruction, impl.get_id_for_value(instruction->getOperand(1)));\n\t\treturn true;\n\t}\n\n\temit_expect_assume_quad_uniform(impl);\n\n\t// Matches with SPIR-V.\n\tuint32_t swap_kind;\n\tif (!get_constant_operand(instruction, 2, &swap_kind))\n\t\treturn false;\n\n\tOperation *op;\n\tif (execution_model_can_quad_op(impl.execution_model))\n\t{\n\t\top = impl.allocate(spv::OpGroupNonUniformQuadSwap, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\top->add_id(builder.makeUintConstant(swap_kind));\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\t}\n\telse\n\t{\n\t\t// Use ShuffleXor for non-fragment stages.\n\t\top = impl.allocate(spv::OpGroupNonUniformShuffleXor, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\n\t\t// 1: Horizontal, 2: Vertical, 3: Diagonal.\n\t\top->add_id(builder.makeUintConstant(swap_kind + 1));\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformShuffle);\n\t}\n\n\timpl.add(op);\n\treturn true;\n}\n\nstatic spv::Id emit_current_ballot_value(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\n\t// Very stupid workaround. Check if the lane is active, and mask in 0 if not.\n\tif (!impl.memoized.current_ballot_value_id)\n\t{\n\t\tauto *ballot = impl.allocate(\n\t\t\tspv::OpGroupNonUniformBallot, builder.makeVectorType(builder.makeUintType(32), 4));\n\t\tballot->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tballot->add_id(builder.makeBoolConstant(true));\n\t\timpl.add(ballot);\n\t\timpl.memoized.current_ballot_value_id = ballot->id;\n\t}\n\n\treturn impl.memoized.current_ballot_value_id;\n}\n\nstatic spv::Id emit_current_subgroup_quad_index(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\n\tif (!impl.memoized.current_subgroup_quad_index_id)\n\t{\n\t\tspv::Id var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSubgroupLocalInvocationId);\n\t\tauto *load_op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\tload_op->add_id(var_id);\n\t\timpl.add(load_op);\n\n\t\tauto *mask = impl.allocate(spv::OpBitwiseAnd, builder.makeUintType(32));\n\t\tmask->add_id(load_op->id);\n\t\tmask->add_id(builder.makeUintConstant(~3u));\n\t\timpl.add(mask);\n\n\t\timpl.memoized.current_subgroup_quad_index_id = mask->id;\n\t}\n\n\treturn impl.memoized.current_subgroup_quad_index_id;\n}\n\nspv::Id emit_current_quad_lane_active(Converter::Impl &impl, uint32_t quad_lane)\n{\n\tauto &builder = impl.builder();\n\n\tif (!impl.memoized.current_quad_lane_active_id[quad_lane])\n\t{\n\t\tauto *add = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\tadd->add_id(emit_current_subgroup_quad_index(impl));\n\t\tadd->add_id(builder.makeUintConstant(quad_lane));\n\t\timpl.add(add);\n\n\t\tauto *extract = impl.allocate(spv::OpGroupNonUniformBallotBitExtract, builder.makeBoolType());\n\t\textract->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\textract->add_id(emit_current_ballot_value(impl));\n\t\textract->add_id(add->id);\n\t\timpl.add(extract);\n\n\t\timpl.memoized.current_quad_lane_active_id[quad_lane] = extract->id;\n\t}\n\n\treturn impl.memoized.current_quad_lane_active_id[quad_lane];\n}\n\nbool emit_wave_quad_read_lane_at_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tif (impl.execution_mode_meta.synthesize_dummy_derivatives)\n\t{\n\t\timpl.rewrite_value(instruction, impl.get_id_for_value(instruction->getOperand(1)));\n\t\treturn true;\n\t}\n\n\temit_expect_assume_quad_uniform(impl);\n\n\tauto *lane = instruction->getOperand(2);\n\n\tOperation *op;\n\tif (execution_model_can_quad_op(impl.execution_model) && llvm::isa<llvm::ConstantInt>(lane))\n\t{\n\t\top = impl.allocate(spv::OpGroupNonUniformQuadBroadcast, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\top->add_id(impl.get_id_for_value(lane));\n\t\timpl.add(op);\n\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\n\t\tif (impl.options.quirks.robust_compute_quad_broadcast && impl.execution_model == spv::ExecutionModelGLCompute)\n\t\t{\n\t\t\t// Very stupid workaround. Check if the lane is active, and mask in 0 if not.\n\t\t\tuint32_t quad_lane = 0;\n\t\t\tif (!get_constant_int(lane, &quad_lane) || quad_lane >= 4)\n\t\t\t\treturn false;\n\n\t\t\tauto *sel = impl.allocate(spv::OpSelect, impl.get_type_id(instruction->getType()));\n\t\t\tsel->add_id(emit_current_quad_lane_active(impl, quad_lane));\n\t\t\tsel->add_id(op->id);\n\t\t\tsel->add_id(builder.makeNullConstant(impl.get_type_id(instruction->getType())));\n\t\t\timpl.add(sel);\n\n\t\t\timpl.rewrite_value(instruction, sel->id);\n\t\t}\n\t}\n\telse\n\t{\n\t\t// Have to emulate this with Shuffle.\n\t\tspv::Id local_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInSubgroupLocalInvocationId);\n\t\t{\n\t\t\tOperation *load_op = impl.allocate(spv::OpLoad, builder.makeUintType(32));\n\t\t\tload_op->add_id(local_id);\n\t\t\tadd_vkmm_volatile(impl, load_op, spv::BuiltInSubgroupLocalInvocationId);\n\t\t\timpl.add(load_op);\n\t\t\tlocal_id = load_op->id;\n\t\t}\n\n\t\t{\n\t\t\tOperation *mask_op = impl.allocate(spv::OpBitwiseAnd, builder.makeUintType(32));\n\t\t\tmask_op->add_id(local_id);\n\t\t\tmask_op->add_id(builder.makeUintConstant(~3u));\n\t\t\timpl.add(mask_op);\n\t\t\tlocal_id = mask_op->id;\n\t\t}\n\n\t\t{\n\t\t\tOperation *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\t\t\tadd_op->add_id(local_id);\n\t\t\tadd_op->add_id(impl.get_id_for_value(lane));\n\t\t\timpl.add(add_op);\n\t\t\tlocal_id = add_op->id;\n\t\t}\n\n\t\t// Use Shuffle for non-fragment stages.\n\t\top = impl.allocate(spv::OpGroupNonUniformShuffle, instruction);\n\t\top->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\top->add_id(local_id);\n\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformShuffle);\n\n\t\t// For shuffle, wave64 is particularly slow on RDNA, so suggest wave32.\n\t\timpl.suggest_maximum_wave_size(32);\n\t\timpl.add(op);\n\t}\n\n\timpl.shader_analysis.require_subgroup_shuffles = true;\n\treturn true;\n}\n\nbool emit_wave_match_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tspv::Id type_id = impl.get_type_id(instruction->getOperand(1)->getType());\n\tspv::Id value_id = impl.get_id_for_value(instruction->getOperand(1));\n\n\t// It's not safe to use FOrdEqual since a loop with NaN will never compare equal to BroadcastFirst().\n\t// Make sure we compare equal with uint.\n\tspv::Op cast_op = spv::OpNop;\n\tswitch (instruction->getOperand(1)->getType()->getTypeID())\n\t{\n\tcase llvm::Type::TypeID::HalfTyID:\n\t\ttype_id = builder.makeUintType(impl.support_native_fp16_operations() ? 16 : 32);\n\t\tcast_op = spv::OpBitcast;\n\t\tbreak;\n\n\tcase llvm::Type::TypeID::FloatTyID:\n\t\ttype_id = builder.makeUintType(32);\n\t\tcast_op = spv::OpBitcast;\n\t\tbreak;\n\n\tcase llvm::Type::TypeID::DoubleTyID:\n\t\ttype_id = builder.makeUintType(64);\n\t\tcast_op = spv::OpBitcast;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (cast_op != spv::OpNop)\n\t{\n\t\tauto *bitcast_op = impl.allocate(cast_op, type_id);\n\t\tbitcast_op->add_id(value_id);\n\t\tvalue_id = bitcast_op->id;\n\t\timpl.add(bitcast_op);\n\t}\n\n\tif (impl.options.nv_subgroup_partition_enabled)\n\t{\n\t\tbuilder.addExtension(\"SPV_NV_shader_subgroup_partitioned\");\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV);\n\t\tauto *op = impl.allocate(spv::OpGroupNonUniformPartitionNV, instruction,\n\t\t                         builder.makeVectorType(builder.makeUintType(32), 4));\n\t\top->add_id(value_id);\n\t\timpl.add(op);\n\n\t\tif (wave_op_needs_helper_lane_masking(impl))\n\t\t{\n\t\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, builder.makeBoolType());\n\t\t\timpl.add(is_helper_lane);\n\n\t\t\tauto *not_op = impl.allocate(spv::OpLogicalNot, builder.makeBoolType());\n\t\t\tnot_op->add_id(is_helper_lane->id);\n\t\t\timpl.add(not_op);\n\n\t\t\tauto *non_helper_op = impl.allocate(spv::OpGroupNonUniformBallot,\n\t\t\t                                    builder.makeVectorType(builder.makeUintType(32), 4));\n\t\t\tnon_helper_op->add_id(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tnon_helper_op->add_id(not_op->id);\n\t\t\timpl.add(non_helper_op);\n\t\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\n\t\t\tauto *and_op = impl.allocate(spv::OpBitwiseAnd, builder.makeVectorType(builder.makeUintType(32), 4));\n\t\t\tand_op->add_id(op->id);\n\t\t\tand_op->add_id(non_helper_op->id);\n\t\t\timpl.add(and_op);\n\n\t\t\timpl.rewrite_value(instruction, and_op->id);\n\t\t}\n\t}\n\telse\n\t{\n\t\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::WaveMatch, type_id);\n\t\tauto *call_op =\n\t\t    impl.allocate(spv::OpFunctionCall, instruction, builder.makeVectorType(builder.makeUintType(32), 4));\n\t\tcall_op->add_id(call_id);\n\t\tcall_op->add_id(value_id);\n\n\t\tif (wave_op_needs_helper_lane_masking(impl))\n\t\t{\n\t\t\tauto *is_helper_lane = impl.allocate(spv::OpIsHelperInvocationEXT, impl.builder().makeBoolType());\n\t\t\timpl.add(is_helper_lane);\n\t\t\tcall_op->add_id(is_helper_lane->id);\n\t\t}\n\n\t\timpl.add(call_op);\n\t}\n\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_waveops.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_wave_is_first_lane_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_builtin_instruction(spv::BuiltIn builtin, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_boolean_instruction(spv::Op opcode, Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_ballot_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_read_lane_first_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_read_lane_at_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nbool emit_wave_bit_count_instruction(spv::GroupOperation operation, Converter::Impl &impl,\n                                     const llvm::CallInst *instruction);\n\nbool emit_wave_active_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_active_bit_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_prefix_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_multi_prefix_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_multi_prefix_count_bits_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_quad_op_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_quad_vote_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_quad_read_lane_at_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_wave_match_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\n\ntemplate <spv::GroupOperation operation>\nstatic inline bool emit_wave_bit_count_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_wave_bit_count_instruction(operation, impl, instruction);\n}\n\ntemplate <spv::Op opcode>\nstatic inline bool emit_wave_boolean_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_wave_boolean_instruction(opcode, impl, instruction);\n}\n\ntemplate <spv::BuiltIn builtin>\nstatic inline bool emit_wave_builtin_dispatch(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\treturn emit_wave_builtin_instruction(builtin, impl, instruction);\n}\n\nbool value_is_statically_wave_uniform(Converter::Impl &impl, const llvm::Value *value);\nbool value_is_likely_non_uniform(Converter::Impl &impl, const llvm::Value *value);\n\nspv::Id emit_current_quad_lane_active(Converter::Impl &impl, uint32_t quad_lane);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/dxil/dxil_workgraph.cpp",
    "content": "/* Copyright (c) 2024 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"dxil_workgraph.hpp\"\n#include \"dxil_common.hpp\"\n#include \"dxil_waveops.hpp\"\n#include \"opcodes/converter_impl.hpp\"\n#include \"spirv_module.hpp\"\n#include \"node.hpp\"\n\nnamespace dxil_spv\n{\nuint32_t get_node_io_from_annotate_handle(const llvm::CallInst *inst)\n{\n\tauto *type_operand = llvm::cast<llvm::ConstantAggregate>(inst->getOperand(2));\n\tuint32_t node_io_flags = llvm::cast<llvm::ConstantInt>(type_operand->getOperand(0))->getUniqueInteger().getZExtValue();\n\treturn node_io_flags;\n}\n\nstatic uint32_t get_node_stride_from_annotate_handle(const llvm::CallInst *inst)\n{\n\t// This is a red herring, since the flags are wrong. Gotta keep digging ... >_<\n\tif (value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::IndexNodeHandle))\n\t{\n\t\tauto *index_handle = llvm::cast<llvm::CallInst>(inst->getOperand(1));\n\t\tinst = llvm::cast<llvm::CallInst>(index_handle->getOperand(1));\n\t}\n\n\tauto *type_operand = llvm::cast<llvm::ConstantAggregate>(inst->getOperand(2));\n\tuint32_t node_io_flags = llvm::cast<llvm::ConstantInt>(type_operand->getOperand(0))->getUniqueInteger().getZExtValue();\n\tuint32_t stride = llvm::cast<llvm::ConstantInt>(type_operand->getOperand(1))->getUniqueInteger().getZExtValue();\n\n\tif ((node_io_flags & DXIL::NodeIOTrackRWInputSharingBit) != 0)\n\t{\n\t\tstride = (stride + 3u) & ~3u;\n\t\tstride += 4;\n\t}\n\n\treturn stride;\n}\n\nstatic uint32_t get_node_meta_index_from_annotate_handle(const llvm::CallInst *inst)\n{\n\t// Crawl through the SSA noise until we find CreateNodeOutputHandle.\n\twhile (!value_is_dx_op_instrinsic(inst, DXIL::Op::CreateNodeOutputHandle))\n\t{\n\t\tif (value_is_dx_op_instrinsic(inst, DXIL::Op::AnnotateNodeRecordHandle) ||\n\t\t    value_is_dx_op_instrinsic(inst, DXIL::Op::AnnotateNodeHandle) ||\n\t\t    value_is_dx_op_instrinsic(inst, DXIL::Op::IndexNodeHandle) ||\n\t\t    value_is_dx_op_instrinsic(inst, DXIL::Op::AllocateNodeOutputRecords))\n\t\t{\n\t\t\tinst = llvm::cast<llvm::CallInst>(inst->getOperand(1));\n\t\t}\n\t}\n\n\tuint32_t meta_index = UINT32_MAX;\n\tif (value_is_dx_op_instrinsic(inst, DXIL::Op::CreateNodeOutputHandle))\n\t\tget_constant_operand(inst, 1, &meta_index);\n\n\treturn meta_index;\n}\n\nspv::Id emit_load_node_input_push_parameter(\n\tConverter::Impl &impl, NodeInputParameter param, spv::Id type)\n{\n\tauto *access_offset_point = impl.allocate(spv::OpAccessChain, impl.builder().makePointer(\n\t\tspv::StorageClassPushConstant, type));\n\taccess_offset_point->add_id(impl.node_input.node_dispatch_push_id);\n\taccess_offset_point->add_id(impl.builder().makeUintConstant(param));\n\timpl.add(access_offset_point);\n\n\tauto *load_offset_point = impl.allocate(spv::OpLoad, type);\n\tload_offset_point->add_id(access_offset_point->id);\n\timpl.add(load_offset_point);\n\n\treturn load_offset_point->id;\n}\n\nstatic spv::Id emit_load_node_input_push_pointer(\n\tConverter::Impl &impl, spv::Id ptr_id, spv::Id type_id, uint32_t alignment)\n{\n\tauto *access_chain = impl.allocate(spv::OpAccessChain, impl.builder().makePointer(\n\t\tspv::StorageClassPhysicalStorageBuffer, type_id));\n\taccess_chain->add_id(ptr_id);\n\taccess_chain->add_id(impl.builder().makeUintConstant(0));\n\timpl.add(access_chain);\n\n\tauto *load_op = impl.allocate(spv::OpLoad, type_id);\n\tload_op->add_id(access_chain->id);\n\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\tload_op->add_literal(alignment);\n\timpl.add(load_op);\n\n\treturn load_op->id;\n}\n\nstatic spv::Id emit_build_output_payload_offset(\n    Converter::Impl &impl, const llvm::Value *base_offset, const llvm::Value *index, uint32_t stride)\n{\n\tauto &builder = impl.builder();\n\tauto *mul_op = impl.allocate(spv::OpIMul, builder.makeUintType(32));\n\tmul_op->add_id(impl.get_id_for_value(index));\n\tmul_op->add_id(builder.makeUintConstant(stride));\n\timpl.add(mul_op);\n\n\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(32));\n\tadd_op->add_id(impl.get_id_for_value(base_offset));\n\tadd_op->add_id(mul_op->id);\n\timpl.add(add_op);\n\n\treturn add_op->id;\n}\n\nstatic spv::Id emit_build_input_payload_offset(Converter::Impl &impl, const llvm::Value *value)\n{\n\t// There is no extra offset in broadcast / thread. We've already resolved it.\n\tif (impl.node_input.launch_type != DXIL::NodeLaunchType::Coalescing)\n\t\treturn 0;\n\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\t// Compute the effective offset.\n\tauto *load_op = impl.allocate(spv::OpLoad, u32_type);\n\tload_op->add_id(impl.node_input.private_coalesce_offset_id);\n\timpl.add(load_op);\n\n\tauto *add_op = impl.allocate(spv::OpIAdd, u32_type);\n\tadd_op->add_id(load_op->id);\n\tadd_op->add_id(impl.get_id_for_value(value));\n\timpl.add(add_op);\n\n\tconst spv::Id aux_ids[] = {\n\t\timpl.node_input.is_entry_point_id,\n\t\timpl.node_input.private_stride_var_id,\n\t\timpl.node_input.u32_array_ptr_type_id,\n\t};\n\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::NodeCoalescePayloadOffset,\n\t                                                       aux_ids, sizeof(aux_ids) / sizeof(aux_ids[0]));\n\n\tspv::Id ptr_offset_id =\n\t\temit_load_node_input_push_parameter(impl, NodePayloadStrideOrOffsetsBDA, builder.makeVectorType(u32_type, 2));\n\n\tauto *call = impl.allocate(spv::OpFunctionCall, u32_type);\n\tcall->add_id(call_id);\n\tcall->add_id(add_op->id);\n\tcall->add_id(ptr_offset_id);\n\timpl.add(call);\n\n\tauto *conv_op = impl.allocate(spv::OpUConvert, builder.makeUintType(64));\n\tconv_op->add_id(call->id);\n\timpl.add(conv_op);\n\treturn conv_op->id;\n}\n\nbool emit_allocate_node_output_records(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tauto &builder = impl.builder();\n\tuint32_t is_per_thread = 0;\n\tif (!get_constant_operand(inst, 3, &is_per_thread))\n\t\treturn false;\n\n\tif (!value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::AnnotateNodeHandle))\n\t\treturn false;\n\n\tuint32_t stride = get_node_stride_from_annotate_handle(llvm::cast<llvm::CallInst>(inst->getOperand(1)));\n\tspv::Id node_index = impl.get_id_for_value(inst->getOperand(1));\n\tspv::Id alloc_count = impl.get_id_for_value(inst->getOperand(2));\n\n\tHelperCall required_call;\n\tif (is_per_thread)\n\t{\n\t\tif (value_is_statically_wave_uniform(impl, inst->getOperand(1)))\n\t\t\trequired_call = HelperCall::AllocateThreadNodeRecords;\n\t\telse\n\t\t\trequired_call = HelperCall::AllocateThreadNodeRecordsWaterfall;\n\t}\n\telse\n\t\trequired_call = HelperCall::AllocateGroupNodeRecords;\n\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(required_call);\n\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, inst, builder.makeUintType(32));\n\tcall_op->add_id(call_id);\n\tspv::Id atomic_addr = emit_load_node_input_push_parameter(impl, NodePayloadOutputAtomicBDA, builder.makeUintType(64));\n\tcall_op->add_id(atomic_addr);\n\tcall_op->add_id(node_index);\n\tcall_op->add_id(alloc_count);\n\tcall_op->add_id(builder.makeUintConstant(stride));\n\tcall_op->add_id(emit_load_node_input_push_parameter(impl, NodePayloadOutputOffset, builder.makeUintType(32)));\n\timpl.add(call_op);\n\n\treturn true;\n}\n\nbool emit_get_node_record_ptr(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tauto &builder = impl.builder();\n\tif (!value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::AnnotateNodeRecordHandle))\n\t\treturn false;\n\n\tauto *annotation = llvm::cast<llvm::CallInst>(inst->getOperand(1));\n\tauto *type_operand = llvm::cast<llvm::ConstantAggregate>(annotation->getOperand(2));\n\n\tuint32_t node_io_flags =\n\t    llvm::cast<llvm::ConstantInt>(type_operand->getOperand(0))->getUniqueInteger().getZExtValue();\n\n\tConverter::Impl::TypeLayoutFlags flags = Converter::Impl::TYPE_LAYOUT_PHYSICAL_BIT;\n\n\tif ((node_io_flags & DXIL::NodeIOReadWriteBit) == 0)\n\t\tflags |= Converter::Impl::TYPE_LAYOUT_READ_ONLY_BIT;\n\t// We might have to promote this to coherent if device-scope barrier is used just like normal UAVs.\n\tif ((node_io_flags & DXIL::NodeIOGloballyCoherentBit) != 0)\n\t\tflags |= Converter::Impl::TYPE_LAYOUT_COHERENT_BIT;\n\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t{\n\t\tif ((node_io_flags & DXIL::NodeIOInputBit) != 0 && impl.shader_analysis.require_node_input_group_coherence)\n\t\t\tflags |= Converter::Impl::TYPE_LAYOUT_COHERENT_BIT;\n\t\telse if ((node_io_flags & DXIL::NodeIOOutputBit) != 0 && impl.shader_analysis.require_node_output_group_coherence)\n\t\t\tflags |= Converter::Impl::TYPE_LAYOUT_COHERENT_BIT;\n\t}\n\n\tspv::Id physical_block_type_id =\n\t    impl.get_type_id(inst->getType(), Converter::Impl::TYPE_LAYOUT_BLOCK_BIT | flags);\n\tspv::Id physical_type_id = impl.get_type_id(inst->getType(), Converter::Impl::TYPE_LAYOUT_PHYSICAL_BIT);\n\n\tspv::Id addr;\n\n\tif (value_is_dx_op_instrinsic(annotation->getOperand(1), DXIL::Op::AllocateNodeOutputRecords))\n\t{\n\t\tspv::Id base_addr = emit_load_node_input_push_parameter(impl, NodePayloadOutputBDA, builder.makeUintType(64));\n\n\t\t// The NodeIOTracking flags only exist on the annotation for AllocateNodeOutputRecords for some reason ...\n\t\t// Probably a DXC bug, but oh well.\n\t\tauto *alloc_node_outputs = llvm::cast<llvm::CallInst>(annotation->getOperand(1));\n\t\tauto *real_annotation = llvm::cast<llvm::CallInst>(alloc_node_outputs->getOperand(1));\n\n\t\tspv::Id offset_id = emit_build_output_payload_offset(impl, annotation->getOperand(1), inst->getOperand(2),\n\t\t                                                     get_node_stride_from_annotate_handle(real_annotation));\n\n\t\tauto *cast_op = impl.allocate(spv::OpUConvert, builder.makeUintType(64));\n\t\tcast_op->add_id(offset_id);\n\t\timpl.add(cast_op);\n\n\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(64));\n\t\tadd_op->add_id(base_addr);\n\t\tadd_op->add_id(cast_op->id);\n\t\timpl.add(add_op);\n\n\t\taddr = add_op->id;\n\t}\n\telse\n\t{\n\t\tauto *load_op = impl.allocate(spv::OpLoad, builder.makeUintType(64));\n\t\tload_op->add_id(impl.node_input.private_bda_var_id);\n\t\timpl.add(load_op);\n\t\taddr = load_op->id;\n\n\t\tspv::Id addr_offset_id = emit_build_input_payload_offset(impl, inst->getOperand(2));\n\n\t\tif (addr_offset_id != 0)\n\t\t{\n\t\t\tauto *add_op = impl.allocate(spv::OpIAdd, builder.makeUintType(64));\n\t\t\tadd_op->add_id(addr);\n\t\t\tadd_op->add_id(addr_offset_id);\n\t\t\timpl.add(add_op);\n\t\t\taddr = add_op->id;\n\t\t}\n\t}\n\n\tauto *cast_op = impl.allocate(spv::OpConvertUToPtr, physical_block_type_id);\n\tcast_op->add_id(addr);\n\timpl.add(cast_op);\n\n\t// Start the chain at the first member.\n\t// This way we get coherency / read-only to propagate properly.\n\tauto *chain_op = impl.allocate(spv::OpAccessChain, inst, physical_type_id);\n\tchain_op->add_id(cast_op->id);\n\tchain_op->add_id(builder.makeUintConstant(0));\n\timpl.add(chain_op);\n\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan &&\n\t    (flags & Converter::Impl::TYPE_LAYOUT_COHERENT_BIT) != 0)\n\t{\n\t\t// Need to propgate this information down.\n\t\timpl.llvm_vkmm_coherent_ptrs.push_back(inst);\n\t}\n\n\treturn true;\n}\n\nbool emit_increment_output_count(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tauto &builder = impl.builder();\n\n\tuint32_t is_per_thread = 0;\n\tif (!get_constant_operand(inst, 3, &is_per_thread))\n\t\treturn false;\n\n\tif (!value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::AnnotateNodeHandle))\n\t\treturn false;\n\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(\n\t    is_per_thread ? HelperCall::ThreadIncrementOutputCount : HelperCall::GroupIncrementOutputCount);\n\n\tspv::Id atomic_addr = emit_load_node_input_push_parameter(impl, NodePayloadOutputAtomicBDA, builder.makeUintType(64));\n\tspv::Id node_index = impl.get_id_for_value(inst->getOperand(1));\n\tspv::Id alloc_count = impl.get_id_for_value(inst->getOperand(2));\n\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, builder.makeVoidType());\n\tcall_op->add_id(call_id);\n\tcall_op->add_id(atomic_addr);\n\tcall_op->add_id(node_index);\n\tcall_op->add_id(alloc_count);\n\timpl.add(call_op);\n\n\treturn true;\n}\n\nbool emit_output_complete(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\treturn true;\n}\n\nbool emit_get_input_record_count(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tspv::Id u32_type = impl.builder().makeUintType(32);\n\tauto *load_op = impl.allocate(spv::OpLoad, inst, u32_type);\n\tload_op->add_id(impl.node_input.private_coalesce_count_id);\n\timpl.add(load_op);\n\treturn true;\n}\n\nbool emit_finished_cross_group_sharing(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tspv::Id call_id = impl.spirv_module.get_helper_call_id(HelperCall::FinishCrossGroupSharing);\n\n\tauto *load_op = impl.allocate(spv::OpLoad, impl.builder().makeUintType(64));\n\tload_op->add_id(impl.node_input.private_bda_var_id);\n\timpl.add(load_op);\n\n\tauto *add_op = impl.allocate(spv::OpIAdd, impl.builder().makeUintType(64));\n\tadd_op->add_id(load_op->id);\n\t// Use the last 4 bytes of the node as the u32 cookie.\n\t// We don't have the node pointer type here, so this is the most convenient approach.\n\tadd_op->add_id(impl.builder().makeUint64Constant(impl.node_input.payload_stride - 4));\n\timpl.add(add_op);\n\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, inst, impl.builder().makeBoolType());\n\tcall_op->add_id(call_id);\n\tcall_op->add_id(add_op->id);\n\timpl.add(call_op);\n\n\treturn true;\n}\n\nstatic bool emit_barrier(Converter::Impl &impl, uint32_t memory_flags, uint32_t semantic_flags)\n{\n\tauto &builder = impl.builder();\n\tbool is_sync = (semantic_flags & DXIL::GroupSyncBit) != 0;\n\tauto *op = impl.allocate(is_sync ? spv::OpControlBarrier : spv::OpMemoryBarrier);\n\tif (is_sync)\n\t\top->add_id(builder.makeUintConstant(spv::ScopeWorkgroup));\n\n\tbool needs_device_memory_scope = false;\n\tif ((semantic_flags & DXIL::DeviceScopeBit) != 0)\n\t\tneeds_device_memory_scope = true;\n\n\t// We only ever need explicit Vis/Avail in workgroup scope for VkMM.\n\t// globallycoherent is handled per-operation,\n\t// and we only need acquire release to ensure ordering.\n\tspv::Scope memory_scope;\n\tif (needs_device_memory_scope && impl.execution_mode_meta.memory_model == spv::MemoryModelGLSL450)\n\t\tmemory_scope = spv::ScopeDevice;\n\telse\n\t\tmemory_scope = spv::ScopeWorkgroup;\n\n\top->add_id(builder.makeUintConstant(memory_scope));\n\n\tuint32_t semantics = spv::MemorySemanticsAcquireReleaseMask;\n\tif ((memory_flags & (DXIL::MemoryTypeNodeInputBit | DXIL::MemoryTypeNodeOutputBit | DXIL::MemoryTypeUavBit)) != 0)\n\t\tsemantics |= spv::MemorySemanticsUniformMemoryMask;\n\tif ((memory_flags & DXIL::MemoryTypeUavBit) != 0)\n\t\tsemantics |= spv::MemorySemanticsImageMemoryMask;\n\tif ((memory_flags & DXIL::MemoryTypeGroupSharedBit) != 0)\n\t\tsemantics |= spv::MemorySemanticsWorkgroupMemoryMask;\n\n\tif (impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan)\n\t\tsemantics |= spv::MemorySemanticsMakeAvailableMask | spv::MemorySemanticsMakeVisibleMask;\n\n\top->add_id(builder.makeUintConstant(semantics));\n\timpl.add(op);\n\n\treturn true;\n}\n\nbool emit_barrier_by_memory_type(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tuint32_t memory_flags = 0;\n\tuint32_t semantics_flags = 0;\n\tif (!get_constant_operand(inst, 1, &memory_flags) ||\n\t    !get_constant_operand(inst, 2, &semantics_flags))\n\t{\n\t\treturn false;\n\t}\n\n\treturn emit_barrier(impl, memory_flags, semantics_flags);\n}\n\nbool emit_barrier_by_memory_handle(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tuint32_t semantics = 0;\n\tif (!get_constant_operand(inst, 2, &semantics))\n\t\treturn false;\n\n\tif (value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::AnnotateHandle))\n\t{\n\t\t// Plain UAV.\n\t\treturn emit_barrier(impl, DXIL::MemoryTypeUavBit, semantics);\n\t}\n\telse\n\t\treturn false;\n}\n\nbool emit_barrier_by_node_record_handle(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tuint32_t semantics = 0;\n\tif (!get_constant_operand(inst, 2, &semantics))\n\t\treturn false;\n\n\tif (value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::AnnotateNodeRecordHandle))\n\t{\n\t\tauto *annotation = llvm::cast<llvm::CallInst>(inst->getOperand(1));\n\t\tuint32_t node_io = get_node_io_from_annotate_handle(annotation);\n\t\tif ((node_io & DXIL::NodeIOInputBit) != 0)\n\t\t\treturn emit_barrier(impl, DXIL::MemoryTypeNodeInputBit, semantics);\n\t\telse if ((node_io & DXIL::NodeIOOutputBit) != 0)\n\t\t\treturn emit_barrier(impl, DXIL::MemoryTypeNodeOutputBit, semantics);\n\t\telse\n\t\t\treturn false;\n\t}\n\telse\n\t\treturn false;\n}\n\nbool emit_index_node_handle(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\t// This is fairly easy, just add. This becomes the index into atomic array.\n\tauto &builder = impl.builder();\n\tauto *add_op = impl.allocate(spv::OpIAdd, inst, builder.makeUintType(32));\n\tadd_op->add_id(impl.get_id_for_value(inst->getOperand(1)));\n\tadd_op->add_id(impl.get_id_for_value(inst->getOperand(2)));\n\timpl.add(add_op);\n\treturn true;\n}\n\nbool emit_annotate_node_handle(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\t// Not sure why there are two separate opcodes for annotating a handle, but DXIL's gonna DXIL ...\n\tif (value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::IndexNodeHandle))\n\t{\n\t\t// Trivially forward the annotation.\n\t\timpl.rewrite_value(inst, impl.get_id_for_value(inst->getOperand(1)));\n\t\treturn true;\n\t}\n\n\tif (!value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::CreateNodeOutputHandle))\n\t\treturn false;\n\n\tauto *node_output = llvm::cast<llvm::CallInst>(inst->getOperand(1));\n\tuint32_t node_meta_index = 0;\n\tif (!get_constant_operand(node_output, 1, &node_meta_index))\n\t\treturn false;\n\n\tif (node_meta_index >= impl.node_outputs.size())\n\t\treturn false;\n\n\tauto &node_meta = impl.node_outputs[node_meta_index];\n\timpl.rewrite_value(inst, node_meta.spec_constant_node_index);\n\treturn true;\n}\n\nbool emit_create_node_input_record_handle(Converter::Impl &, const llvm::CallInst *)\n{\n\t// Node input index must be 0, since there's only one node input.\n\t// Do nothing here. We have to annotate the handle first, and there we can look at the node instruction.\n\treturn true;\n}\n\nbool emit_create_node_output_handle(Converter::Impl &, const llvm::CallInst *)\n{\n\t// Do nothing here. We have to annotate the handle first, and there we can look at the node instruction.\n\treturn true;\n}\n\nbool emit_annotate_node_record_handle(Converter::Impl &, const llvm::CallInst *inst)\n{\n\treturn value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::CreateNodeInputRecordHandle) ||\n\t       value_is_dx_op_instrinsic(inst->getOperand(1), DXIL::Op::AllocateNodeOutputRecords);\n}\n\nbool emit_node_output_is_valid(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tauto &builder = impl.builder();\n\n\tuint32_t output_meta_index = get_node_meta_index_from_annotate_handle(llvm::cast<llvm::CallInst>(inst->getOperand(1)));\n\tif (output_meta_index >= impl.node_outputs.size())\n\t\treturn false;\n\n\tauto &node_meta = impl.node_outputs[output_meta_index];\n\tif (node_meta.is_recursive)\n\t{\n\t\tspv::Id id = emit_load_node_input_push_parameter(impl, NodeRemainingRecursionLevels, builder.makeUintType(32));\n\t\tauto *eq_op = impl.allocate(spv::OpINotEqual, inst);\n\t\teq_op->add_id(id);\n\t\teq_op->add_id(builder.makeUintConstant(0));\n\t\timpl.add(eq_op);\n\t}\n\telse\n\t{\n\t\t// TODO: For now, assume that every output is valid. This will need a lot of spec constant magic later.\n\t\timpl.rewrite_value(inst, builder.makeBoolConstant(true));\n\t}\n\n\treturn true;\n}\n\nbool emit_get_remaining_recursion_levels(Converter::Impl &impl, const llvm::CallInst *inst)\n{\n\tauto &builder = impl.builder();\n\tspv::Id id = emit_load_node_input_push_parameter(impl, NodeRemainingRecursionLevels, builder.makeUintType(32));\n\timpl.rewrite_value(inst, id);\n\treturn true;\n}\n\nstatic spv::Id emit_real_builtin_id(Converter::Impl &impl, spv::Id &id, spv::BuiltIn builtin)\n{\n\tif (id)\n\t\treturn id;\n\n\t// Build our own true workgroup ID. This is hidden from application.\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id uvec3_type = builder.makeVectorType(u32_type, 3);\n\tspv::Id workgroup_id = impl.create_variable(spv::StorageClassInput, uvec3_type);\n\tbuilder.addDecoration(workgroup_id, spv::DecorationBuiltIn, builtin);\n\tid = workgroup_id;\n\treturn id;\n}\n\nstatic spv::Id emit_real_workgroup_id(Converter::Impl &impl)\n{\n\treturn emit_real_builtin_id(impl, impl.node_input.real_workgroup_id, spv::BuiltInWorkgroupId);\n}\n\nstatic spv::Id emit_real_global_invocation_id(Converter::Impl &impl)\n{\n\treturn emit_real_builtin_id(impl, impl.node_input.real_global_invocation_id, spv::BuiltInGlobalInvocationId);\n}\n\nstatic spv::Id emit_linear_node_index(Converter::Impl &impl)\n{\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id uvec3_type = builder.makeVectorType(u32_type, 3);\n\tspv::Id workgroup_id = emit_real_workgroup_id(impl);\n\n\tauto *load_wg_id = impl.allocate(spv::OpLoad, uvec3_type);\n\tload_wg_id->add_id(workgroup_id);\n\timpl.add(load_wg_id);\n\n\tauto *wg_x = impl.allocate(spv::OpCompositeExtract, u32_type);\n\twg_x->add_id(load_wg_id->id);\n\twg_x->add_literal(0);\n\timpl.add(wg_x);\n\n\tauto *wg_y = impl.allocate(spv::OpCompositeExtract, u32_type);\n\twg_y->add_id(load_wg_id->id);\n\twg_y->add_literal(1);\n\timpl.add(wg_y);\n\n\tauto *y_node_index = impl.allocate(spv::OpIMul, u32_type);\n\ty_node_index->add_id(wg_y->id);\n\ty_node_index->add_id(builder.makeUintConstant(32 * 1024));\n\timpl.add(y_node_index);\n\n\tauto *linear_wg_index = impl.allocate(spv::OpIAdd, u32_type);\n\tlinear_wg_index->add_id(y_node_index->id);\n\tlinear_wg_index->add_id(wg_x->id);\n\timpl.add(linear_wg_index);\n\n\tspv::Id linear_id;\n\n\tif (impl.node_input.launch_type == DXIL::NodeLaunchType::Thread)\n\t{\n\t\tspv::Id workgroup_size = builder.makeUintConstant(1, true);\n\t\tbuilder.addDecoration(workgroup_size, spv::DecorationSpecId, 0); // TODO: Make this configurable.\n\t\tbuilder.addName(workgroup_size, \"ThreadGroupSize\");\n\n\t\tauto *mul_wg_index = impl.allocate(spv::OpIMul, u32_type);\n\t\tmul_wg_index->add_id(linear_wg_index->id);\n\t\tmul_wg_index->add_id(workgroup_size);\n\t\timpl.add(mul_wg_index);\n\n\t\tspv::Id local_invocation_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInLocalInvocationIndex);\n\t\tauto *load_local = impl.allocate(spv::OpLoad, u32_type);\n\t\tload_local->add_id(local_invocation_id);\n\t\timpl.add(load_local);\n\n\t\tauto *add_op = impl.allocate(spv::OpIAdd, u32_type);\n\t\tadd_op->add_id(mul_wg_index->id);\n\t\tadd_op->add_id(load_local->id);\n\t\timpl.add(add_op);\n\t\tlinear_id = add_op->id;\n\t}\n\telse if (impl.node_input.launch_type == DXIL::NodeLaunchType::Coalescing)\n\t{\n\t\tauto *mul_wg_index = impl.allocate(spv::OpIMul, u32_type);\n\t\tmul_wg_index->add_id(linear_wg_index->id);\n\t\tmul_wg_index->add_id(builder.makeUintConstant(impl.node_input.coalesce_stride));\n\t\timpl.add(mul_wg_index);\n\t\tlinear_id = mul_wg_index->id;\n\t}\n\telse\n\t{\n\t\tlinear_id = linear_wg_index->id;\n\t}\n\n\tspv::Id linear_ptr = emit_load_node_input_push_parameter(\n\t    impl, NodeLinearOffsetBDA, impl.node_input.u32_ptr_type_id);\n\tspv::Id linear_offset = emit_load_node_input_push_pointer(\n\t    impl, linear_ptr, u32_type, sizeof(uint32_t));\n\n\tauto *offset_op = impl.allocate(spv::OpIAdd, u32_type);\n\toffset_op->add_id(linear_id);\n\toffset_op->add_id(linear_offset);\n\timpl.add(offset_op);\n\n\tif (impl.node_input.launch_type == DXIL::NodeLaunchType::Broadcasting)\n\t{\n\t\t// Select between static payload and WorkGroupID.xy driven payload.\n\t\tauto *linear_id_select = impl.allocate(spv::OpSelect, u32_type);\n\t\tlinear_id_select->add_id(impl.node_input.is_static_broadcast_node_id);\n\t\tlinear_id_select->add_id(linear_offset);\n\t\tlinear_id_select->add_id(offset_op->id);\n\t\timpl.add(linear_id_select);\n\t\treturn linear_id_select->id;\n\t}\n\telse\n\t\treturn offset_op->id;\n}\n\nstatic bool emit_payload_pointer_resolve(Converter::Impl &impl, spv::Id linear_node_index_id,\n                                         DXIL::NodeLaunchType launch_type, bool is_entry_point)\n{\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id u64_type = builder.makeUintType(64);\n\n\tif (launch_type != DXIL::NodeLaunchType::Coalescing && impl.node_input.private_bda_var_id)\n\t{\n\t\tauto *payload_base = impl.allocate(spv::OpLoad, u64_type);\n\t\tpayload_base->add_id(impl.node_input.private_bda_var_id);\n\t\timpl.add(payload_base);\n\n\t\tspv::Id payload_offset_id;\n\n\t\t// Entry points are linear. Read stride (this can be sourced from GPU buffer, so has to be a pointer).\n\t\tif (is_entry_point)\n\t\t{\n\t\t\tauto *stride_load = impl.allocate(spv::OpLoad, u32_type);\n\t\t\tstride_load->add_id(impl.node_input.private_stride_var_id);\n\t\t\timpl.add(stride_load);\n\n\t\t\tauto *payload_offset = impl.allocate(spv::OpIMul, u32_type);\n\t\t\tpayload_offset->add_id(linear_node_index_id);\n\t\t\tpayload_offset->add_id(stride_load->id);\n\t\t\timpl.add(payload_offset);\n\n\t\t\tpayload_offset_id = payload_offset->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tspv::Id uvec2_type = builder.makeVectorType(u32_type, 2);\n\t\t\tspv::Id payload_stride_ptr_uvec2 = emit_load_node_input_push_parameter(\n\t\t\t\timpl, NodePayloadStrideOrOffsetsBDA, uvec2_type);\n\n\t\t\tauto *cast_op = impl.allocate(spv::OpBitcast, impl.node_input.u32_array_ptr_type_id);\n\t\t\tcast_op->add_id(payload_stride_ptr_uvec2);\n\t\t\timpl.add(cast_op);\n\n\t\t\t// Load offset to payload indirectly.\n\t\t\tauto *offset_chain = impl.allocate(\n\t\t\t\tspv::OpInBoundsAccessChain,\n\t\t\t\tbuilder.makePointer(spv::StorageClassPhysicalStorageBuffer, u32_type));\n\n\t\t\toffset_chain->add_id(cast_op->id);\n\t\t\toffset_chain->add_id(builder.makeUintConstant(0));\n\t\t\toffset_chain->add_id(linear_node_index_id);\n\t\t\timpl.add(offset_chain);\n\n\t\t\tauto *load_op = impl.allocate(spv::OpLoad, u32_type);\n\t\t\tload_op->add_id(offset_chain->id);\n\t\t\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\t\t\tload_op->add_literal(sizeof(uint32_t));\n\t\t\timpl.add(load_op);\n\n\t\t\tpayload_offset_id = load_op->id;\n\t\t}\n\n\t\tauto *upconv = impl.allocate(spv::OpUConvert, u64_type);\n\t\tupconv->add_id(payload_offset_id);\n\t\timpl.add(upconv);\n\n\t\tauto *offset_payload = impl.allocate(spv::OpIAdd, u64_type);\n\t\toffset_payload->add_id(payload_base->id);\n\t\toffset_payload->add_id(upconv->id);\n\t\timpl.add(offset_payload);\n\n\t\tauto *store_op = impl.allocate(spv::OpStore);\n\t\tstore_op->add_id(impl.node_input.private_bda_var_id);\n\t\tstore_op->add_id(offset_payload->id);\n\t\timpl.add(store_op);\n\t}\n\telse if (launch_type == DXIL::NodeLaunchType::Coalescing)\n\t{\n\t\t// For Coalesce, we can load an array of payloads, have to defer the resolve.\n\t\t// Fortunately, we don't have to read the payload in dispatcher, so we're okay.\n\t\tspv::Id end_ptr = emit_load_node_input_push_parameter(impl, NodeEndNodesBDA, impl.node_input.u32_ptr_type_id);\n\t\tspv::Id end_id = emit_load_node_input_push_pointer(impl, end_ptr, u32_type, sizeof(uint32_t));\n\n\t\tauto *store_op = impl.allocate(spv::OpStore);\n\t\tstore_op->add_id(impl.node_input.private_coalesce_offset_id);\n\t\tstore_op->add_id(linear_node_index_id);\n\t\timpl.add(store_op);\n\n\t\tauto *count_id = impl.allocate(spv::OpISub, u32_type);\n\t\tcount_id->add_id(end_id);\n\t\tcount_id->add_id(linear_node_index_id);\n\t\timpl.add(count_id);\n\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\t\tauto *min_id = impl.allocate(spv::OpExtInst, u32_type);\n\t\tmin_id->add_id(impl.glsl_std450_ext);\n\t\tmin_id->add_literal(GLSLstd450UMin);\n\t\tmin_id->add_id(count_id->id);\n\t\tmin_id->add_id(builder.makeUintConstant(impl.node_input.coalesce_stride));\n\t\timpl.add(min_id);\n\n\t\tstore_op = impl.allocate(spv::OpStore);\n\t\tstore_op->add_id(impl.node_input.private_coalesce_count_id);\n\t\tstore_op->add_id(min_id->id);\n\t\timpl.add(store_op);\n\t}\n\n\treturn true;\n}\n\nstatic spv::Id emit_dispatch_bit_count(Converter::Impl &impl, spv::Id count_minus_1)\n{\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\tauto *bits = impl.allocate(spv::OpExtInst, u32_type);\n\tbits->add_id(impl.glsl_std450_ext);\n\tbits->add_literal(GLSLstd450FindUMsb);\n\tbits->add_id(count_minus_1);\n\timpl.add(bits);\n\n\tauto *plus1 = impl.allocate(spv::OpIAdd, u32_type);\n\tplus1->add_id(bits->id);\n\tplus1->add_id(builder.makeUintConstant(1));\n\timpl.add(plus1);\n\n\treturn plus1->id;\n}\n\nstatic CFGNode *emit_workgraph_dispatcher_path_broadcast_static_payload(\n\tConverter::Impl &impl, CFGNode *path, spv::Id main_entry_id)\n{\n\timpl.current_block = &path->ir.operations;\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id uvec3_type = builder.makeVectorType(u32_type, 3);\n\n\tspv::Id workgroup_var_id = emit_real_workgroup_id(impl);\n\tspv::Id global_invocation_id = emit_real_global_invocation_id(impl);\n\n\tauto *load_wg = impl.allocate(spv::OpLoad, uvec3_type);\n\tload_wg->add_id(workgroup_var_id);\n\timpl.add(load_wg);\n\n\tauto *load_gid = impl.allocate(spv::OpLoad, uvec3_type);\n\tload_gid->add_id(global_invocation_id);\n\timpl.add(load_gid);\n\n\tauto *store_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(impl.spirv_module.get_builtin_shader_input(spv::BuiltInWorkgroupId));\n\tstore_op->add_id(load_wg->id);\n\timpl.add(store_op);\n\n\tstore_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(impl.spirv_module.get_builtin_shader_input(spv::BuiltInGlobalInvocationId));\n\tstore_op->add_id(load_gid->id);\n\timpl.add(store_op);\n\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, impl.builder().makeVoidType());\n\tcall_op->add_id(main_entry_id);\n\timpl.add(call_op);\n\n\treturn path;\n}\n\nstatic CFGNode *emit_workgraph_dispatcher_path_broadcast_amplified(\n    Converter::Impl &impl, CFGNodePool &pool, CFGNode *path,\n    spv::Id main_entry_id, bool broadcast_has_max_grid)\n{\n\timpl.current_block = &path->ir.operations;\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id u64_type = builder.makeUintType(64);\n\tspv::Id uvec3_type = builder.makeVectorType(u32_type, 3);\n\tspv::Id real_workgroup_var_id = emit_real_workgroup_id(impl);\n\n\t// Load gl_WorkGroupID.\n\tauto *load_wg = impl.allocate(spv::OpLoad, uvec3_type);\n\tload_wg->add_id(real_workgroup_var_id);\n\timpl.add(load_wg);\n\n\t// gl_WorkGroupID.z.\n\tauto *dispatch_z = impl.allocate(spv::OpCompositeExtract, u32_type);\n\tdispatch_z->add_id(load_wg->id);\n\tdispatch_z->add_literal(2);\n\timpl.add(dispatch_z);\n\n\tspv::Id num_workgroups_var_id = impl.spirv_module.get_builtin_shader_input(spv::BuiltInNumWorkgroups);\n\tauto *num_workgroups = impl.allocate(spv::OpLoad, uvec3_type);\n\tnum_workgroups->add_id(num_workgroups_var_id);\n\timpl.add(num_workgroups);\n\n\tauto *num_workgroups_z = impl.allocate(spv::OpCompositeExtract, u32_type);\n\tnum_workgroups_z->add_id(num_workgroups->id);\n\tnum_workgroups_z->add_literal(2);\n\timpl.add(num_workgroups_z);\n\n\t// The grid size is embedded in the payload itself.\n\tspv::Id target_dispatch_grid_minus_1[3] = {};\n\tspv::Id workgroup_bit_offset[3] = {};\n\tspv::Id workgroup_bit_count[3] = {};\n\tbool dimension_is_trivial[3] = {};\n\tspv::Id upper_dimension_size_id = 0;\n\tspv::Id target_amplification_rate_id = 0;\n\tspv::Id workgroup_size_id = 0;\n\n\tif (!impl.glsl_std450_ext)\n\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\tif (broadcast_has_max_grid && impl.node_input.dispatch_grid.count)\n\t{\n\t\tspv::Id target_dispatch_grid[3];\n\n\t\tauto *load_bda = impl.allocate(spv::OpLoad, u64_type);\n\t\tload_bda->add_id(impl.node_input.private_bda_var_id);\n\t\timpl.add(load_bda);\n\n\t\tauto *offset_ptr = impl.allocate(spv::OpIAdd, u64_type);\n\t\toffset_ptr->add_id(load_bda->id);\n\t\toffset_ptr->add_id(builder.makeUint64Constant(impl.node_input.dispatch_grid.offset));\n\t\timpl.add(offset_ptr);\n\n\t\tspv::Id u32_grid_type_id = impl.get_type_id(DXIL::ComponentType::U32, 1,\n\t\t                                            impl.node_input.dispatch_grid.count);\n\t\tspv::Id grid_type_id = impl.get_type_id(impl.node_input.dispatch_grid.component_type,\n\t\t                                        1, impl.node_input.dispatch_grid.count);\n\n\t\tauto *grid_cast = impl.allocate(\n\t\t    spv::OpBitcast, builder.makePointer(spv::StorageClassPhysicalStorageBuffer, grid_type_id));\n\t\tgrid_cast->add_id(offset_ptr->id);\n\t\timpl.add(grid_cast);\n\n\t\tauto *load_grid = impl.allocate(spv::OpLoad, grid_type_id);\n\t\tload_grid->add_id(grid_cast->id);\n\t\tload_grid->add_literal(spv::MemoryAccessAlignedMask);\n\t\tload_grid->add_literal(impl.node_input.dispatch_grid.component_type == DXIL::ComponentType::U32 ?\n\t\t                           sizeof(uint32_t) : sizeof(uint16_t));\n\t\timpl.add(load_grid);\n\n\t\tif (impl.node_input.dispatch_grid.component_type == DXIL::ComponentType::U16)\n\t\t{\n\t\t\tauto *conv_op = impl.allocate(spv::OpUConvert, u32_grid_type_id);\n\t\t\tconv_op->add_id(load_grid->id);\n\t\t\timpl.add(conv_op);\n\t\t\tload_grid = conv_op;\n\t\t}\n\n\t\tfor (uint32_t i = 0; i < impl.node_input.dispatch_grid.count; i++)\n\t\t{\n\t\t\tif (impl.node_input.dispatch_grid.count == 1)\n\t\t\t{\n\t\t\t\ttarget_dispatch_grid[i] = load_grid->id;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto *ext = impl.allocate(spv::OpCompositeExtract, u32_type);\n\t\t\t\text->add_id(load_grid->id);\n\t\t\t\text->add_literal(i);\n\t\t\t\timpl.add(ext);\n\t\t\t\ttarget_dispatch_grid[i] = ext->id;\n\t\t\t}\n\n\t\t\tauto *sub = impl.allocate(spv::OpISub, u32_type);\n\t\t\tsub->add_id(target_dispatch_grid[i]);\n\t\t\tsub->add_id(builder.makeUintConstant(1));\n\t\t\timpl.add(sub);\n\n\t\t\ttarget_dispatch_grid_minus_1[i] = sub->id;\n\t\t\tworkgroup_bit_count[i] = emit_dispatch_bit_count(impl, target_dispatch_grid_minus_1[i]);\n\t\t}\n\n\t\tupper_dimension_size_id = target_dispatch_grid[impl.node_input.dispatch_grid.count - 1];\n\n\t\tfor (uint32_t i = impl.node_input.dispatch_grid.count; i < 3; i++)\n\t\t{\n\t\t\ttarget_dispatch_grid_minus_1[i] = builder.makeUintConstant(0);\n\t\t\tworkgroup_bit_count[i] = builder.makeUintConstant(0);\n\t\t\tdimension_is_trivial[i] = true;\n\t\t}\n\t}\n\telse\n\t{\n\t\tfor (uint32_t i = 0; i < 3; i++)\n\t\t\ttarget_dispatch_grid_minus_1[i] = impl.node_input.max_broadcast_grid_minus_1_id[i];\n\t}\n\n\tif (broadcast_has_max_grid && impl.node_input.dispatch_grid.count)\n\t{\n\t\tworkgroup_bit_offset[0] = builder.makeUintConstant(0);\n\t\tworkgroup_bit_offset[1] = workgroup_bit_count[0];\n\t\tauto *count_add = impl.allocate(spv::OpIAdd, u32_type);\n\t\tcount_add->add_id(workgroup_bit_count[0]);\n\t\tcount_add->add_id(workgroup_bit_count[1]);\n\t\timpl.add(count_add);\n\t\tworkgroup_bit_offset[2] = count_add->id;\n\n\t\t// We want to avoid expensive non-constant udivs if we can help it.\n\t\tauto *shift = impl.allocate(spv::OpShiftLeftLogical, u32_type);\n\t\tshift->add_id(upper_dimension_size_id);\n\t\tshift->add_id(workgroup_bit_offset[impl.node_input.dispatch_grid.count - 1]);\n\t\timpl.add(shift);\n\t\ttarget_amplification_rate_id = shift->id;\n\n\t\tworkgroup_size_id = impl.build_vector(u32_type, target_dispatch_grid_minus_1, 3);\n\n\t\tOperation *is_any_zero;\n\n\t\tif (impl.node_input.dispatch_grid.count > 1)\n\t\t{\n\t\t\tauto *is_zero = impl.allocate(\n\t\t\t\tspv::OpSLessThan, builder.makeVectorType(builder.makeBoolType(), impl.node_input.dispatch_grid.count));\n\n\t\t\tif (impl.node_input.dispatch_grid.count == 3)\n\t\t\t\tis_zero->add_id(workgroup_size_id);\n\t\t\telse\n\t\t\t\tis_zero->add_id(impl.build_vector(u32_type, target_dispatch_grid_minus_1, impl.node_input.dispatch_grid.count));\n\n\t\t\tis_zero->add_id(impl.build_splat_constant_vector(u32_type, builder.makeUintConstant(0),\n\t\t\t                                                 impl.node_input.dispatch_grid.count));\n\t\t\timpl.add(is_zero);\n\n\t\t\tis_any_zero = impl.allocate(spv::OpAny, builder.makeBoolType());\n\t\t\tis_any_zero->add_id(is_zero->id);\n\t\t\timpl.add(is_any_zero);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tis_any_zero = impl.allocate(spv::OpSLessThan, builder.makeBoolType());\n\t\t\tis_any_zero->add_id(target_dispatch_grid_minus_1[0]);\n\t\t\tis_any_zero->add_id(builder.makeUintConstant(0));\n\t\t\timpl.add(is_any_zero);\n\t\t}\n\n\t\tauto *select_rate = impl.allocate(spv::OpSelect, u32_type);\n\t\tselect_rate->add_id(is_any_zero->id);\n\t\tselect_rate->add_id(builder.makeUintConstant(0));\n\t\tselect_rate->add_id(target_amplification_rate_id);\n\t\timpl.add(select_rate);\n\n\t\ttarget_amplification_rate_id = select_rate->id;\n\t}\n\telse\n\t{\n\t\tspv::Id amp_xy = builder.createSpecConstantOp(\n\t\t\tspv::OpIMul, u32_type,\n\t\t\t{ impl.node_input.max_broadcast_grid_id[0], impl.node_input.max_broadcast_grid_id[1] }, {});\n\n\t\ttarget_amplification_rate_id = builder.createSpecConstantOp(\n\t\t\tspv::OpIMul, u32_type,\n\t\t\t{ amp_xy, impl.node_input.max_broadcast_grid_id[2] }, {});\n\t}\n\n\t// Loop over target_amplification_rate_id.\n\tauto *loop_header = pool.create_node();\n\tauto *loop_body = pool.create_node();\n\tauto *loop_continue = pool.create_node();\n\tauto *loop_merge = pool.create_node();\n\tloop_header->name = \"loop-header\";\n\tloop_body->name = \"loop-body\";\n\tloop_continue->name = \"loop-continue\";\n\tloop_merge->name = \"loop-merge\";\n\tpath->name = \"path\";\n\n\tpath->ir.terminator.type = Terminator::Type::Branch;\n\tpath->ir.terminator.direct_block = loop_header;\n\tpath->add_branch(loop_header);\n\n\t// Bit-extract the real workgroup size.\n\t// Reroll the dispatch grid into a 3-dimensional vector.\n\tspv::Id amp_id = builder.getUniqueId();\n\tbuilder.addName(amp_id, \"amplification_index\");\n\n\tauto *dispatch_increment = impl.allocate(spv::OpIAdd, u32_type);\n\tdispatch_increment->add_id(amp_id);\n\tdispatch_increment->add_id(num_workgroups_z->id);\n\timpl.current_block = &loop_continue->ir.operations;\n\timpl.add(dispatch_increment);\n\n\tloop_continue->ir.terminator.type = Terminator::Type::Branch;\n\tloop_continue->ir.terminator.direct_block = loop_header;\n\tloop_continue->add_branch(loop_header);\n\n\tPHI phi;\n\tphi.id = amp_id;\n\tphi.type_id = u32_type;\n\tphi.incoming.push_back({ path, dispatch_z->id });\n\tphi.incoming.push_back({ loop_continue, dispatch_increment->id });\n\n\tauto *loop_cond = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\tloop_cond->add_id(phi.id);\n\tloop_cond->add_id(target_amplification_rate_id);\n\timpl.current_block = &loop_header->ir.operations;\n\timpl.add(loop_cond);\n\n\tloop_header->ir.terminator.type = Terminator::Type::Condition;\n\tloop_header->ir.terminator.true_block = loop_body;\n\tloop_header->ir.terminator.false_block = loop_merge;\n\tloop_header->ir.terminator.conditional_id = loop_cond->id;\n\tloop_header->add_branch(loop_body);\n\tloop_header->add_branch(loop_merge);\n\tloop_header->ir.phi.push_back(std::move(phi));\n\n\timpl.current_block = &loop_body->ir.operations;\n\n\tspv::Id workgroup_elems[3];\n\n\tif (broadcast_has_max_grid && impl.node_input.dispatch_grid.count)\n\t{\n\t\tfor (uint32_t i = 0; i < 3; i++)\n\t\t{\n\t\t\tif (dimension_is_trivial[i])\n\t\t\t{\n\t\t\t\tworkgroup_elems[i] = builder.makeUintConstant(0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto *ext = impl.allocate(spv::OpBitFieldUExtract, u32_type);\n\t\t\t\text->add_id(amp_id);\n\t\t\t\text->add_id(workgroup_bit_offset[i]);\n\t\t\t\text->add_id(workgroup_bit_count[i]);\n\t\t\t\timpl.add(ext);\n\t\t\t\tworkgroup_elems[i] = ext->id;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tauto *wg_x = impl.allocate(spv::OpUMod, u32_type);\n\t\twg_x->add_id(amp_id);\n\t\twg_x->add_id(impl.node_input.max_broadcast_grid_id[0]);\n\t\timpl.add(wg_x);\n\t\tworkgroup_elems[0] = wg_x->id;\n\n\t\tauto *wg_yz = impl.allocate(spv::OpUDiv, u32_type);\n\t\twg_yz->add_id(amp_id);\n\t\twg_yz->add_id(impl.node_input.max_broadcast_grid_id[0]);\n\t\timpl.add(wg_yz);\n\n\t\tauto *wg_y = impl.allocate(spv::OpUMod, u32_type);\n\t\twg_y->add_id(wg_yz->id);\n\t\twg_y->add_id(impl.node_input.max_broadcast_grid_id[1]);\n\t\timpl.add(wg_y);\n\n\t\tauto *wg_z = impl.allocate(spv::OpUDiv, u32_type);\n\t\twg_z->add_id(wg_yz->id);\n\t\twg_z->add_id(impl.node_input.max_broadcast_grid_id[1]);\n\t\timpl.add(wg_z);\n\n\t\tworkgroup_elems[1] = wg_y->id;\n\t\tworkgroup_elems[2] = wg_z->id;\n\t}\n\n\tspv::Id workgroup_id = impl.build_vector(u32_type, workgroup_elems, 3);\n\n\tauto *store_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(impl.spirv_module.get_builtin_shader_input(spv::BuiltInWorkgroupId));\n\tstore_op->add_id(workgroup_id);\n\timpl.add(store_op);\n\n\tauto *load_local_id = impl.allocate(spv::OpLoad, uvec3_type);\n\tload_local_id->add_id(impl.spirv_module.get_builtin_shader_input(spv::BuiltInLocalInvocationId));\n\timpl.add(load_local_id);\n\n\tauto *mul_op = impl.allocate(spv::OpIMul, uvec3_type);\n\tmul_op->add_id(impl.node_input.thread_group_size_id);\n\tmul_op->add_id(workgroup_id);\n\timpl.add(mul_op);\n\n\tauto *add_op = impl.allocate(spv::OpIAdd, uvec3_type);\n\tadd_op->add_id(mul_op->id);\n\tadd_op->add_id(load_local_id->id);\n\timpl.add(add_op);\n\n\tstore_op = impl.allocate(spv::OpStore);\n\tstore_op->add_id(impl.spirv_module.get_builtin_shader_input(spv::BuiltInGlobalInvocationId));\n\tstore_op->add_id(add_op->id);\n\timpl.add(store_op);\n\n\tif (broadcast_has_max_grid && impl.node_input.dispatch_grid.count)\n\t{\n\t\tauto *mask_op = impl.allocate(spv::OpULessThanEqual, builder.makeVectorType(builder.makeBoolType(), 3));\n\t\tmask_op->add_id(workgroup_id);\n\t\tmask_op->add_id(impl.build_vector(u32_type, target_dispatch_grid_minus_1, 3));\n\t\timpl.add(mask_op);\n\n\t\tauto *all_op = impl.allocate(spv::OpAll, builder.makeBoolType());\n\t\tall_op->add_id(mask_op->id);\n\t\timpl.add(all_op);\n\n\t\tauto *call_block = pool.create_node();\n\t\tcall_block->name = \"caller\";\n\n\t\tloop_body->ir.terminator.type = Terminator::Type::Condition;\n\t\tloop_body->ir.terminator.conditional_id = all_op->id;\n\t\tloop_body->ir.terminator.true_block = call_block;\n\t\tloop_body->ir.terminator.false_block = loop_continue;\n\t\tloop_body->add_branch(call_block);\n\t\tloop_body->add_branch(loop_continue);\n\t\tcall_block->add_branch(loop_continue);\n\t\tcall_block->ir.terminator.type = Terminator::Type::Branch;\n\t\tcall_block->ir.terminator.direct_block = loop_continue;\n\t\timpl.current_block = &call_block->ir.operations;\n\t}\n\telse\n\t{\n\t\tloop_body->ir.terminator.type = Terminator::Type::Branch;\n\t\tloop_body->ir.terminator.direct_block = loop_continue;\n\t\tloop_body->add_branch(loop_continue);\n\t}\n\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, impl.builder().makeVoidType());\n\tcall_op->add_id(main_entry_id);\n\timpl.add(call_op);\n\n\tauto *barrier_op = impl.allocate(spv::OpControlBarrier);\n\tbarrier_op->add_id(builder.makeUintConstant(spv::ScopeWorkgroup));\n\tbarrier_op->add_id(builder.makeUintConstant(spv::ScopeWorkgroup));\n\tbarrier_op->add_id(builder.getWorkgroupBarrierSemanticsId());\n\timpl.add(barrier_op);\n\n\treturn loop_merge;\n}\n\nstatic CFGNode *emit_workgraph_dispatcher_path_broadcast(\n\tConverter::Impl &impl, CFGNodePool &pool, CFGNode *path,\n\tspv::Id main_entry_id, spv::Id linear_node_index_id,\n    bool broadcast_has_max_grid, bool is_entry_point)\n{\n\timpl.current_block = &path->ir.operations;\n\temit_payload_pointer_resolve(impl, linear_node_index_id, DXIL::NodeLaunchType::Broadcasting, is_entry_point);\n\n\tif (broadcast_has_max_grid)\n\t{\n\t\treturn emit_workgraph_dispatcher_path_broadcast_amplified(\n\t\t\timpl, pool, path, main_entry_id, broadcast_has_max_grid);\n\t}\n\telse\n\t{\n\t\tauto *static_path = pool.create_node();\n\t\tauto *amplified_path = pool.create_node();\n\t\tauto *merge_block = pool.create_node();\n\n\t\tauto *static_end = emit_workgraph_dispatcher_path_broadcast_static_payload(\n\t\t\timpl, static_path, main_entry_id);\n\n\t\tauto *amplified_end = emit_workgraph_dispatcher_path_broadcast_amplified(\n\t\t\timpl, pool, amplified_path, main_entry_id, broadcast_has_max_grid);\n\n\t\tpath->ir.terminator.type = Terminator::Type::Condition;\n\t\tpath->ir.terminator.conditional_id = impl.node_input.is_static_broadcast_node_id;\n\t\tpath->ir.terminator.true_block = static_path;\n\t\tpath->ir.terminator.false_block = amplified_path;\n\t\tpath->add_branch(static_path);\n\t\tpath->add_branch(amplified_path);\n\n\t\tstatic_end->ir.terminator.type = Terminator::Type::Branch;\n\t\tstatic_end->ir.terminator.direct_block = merge_block;\n\t\tstatic_end->add_branch(merge_block);\n\n\t\tamplified_end->ir.terminator.type = Terminator::Type::Branch;\n\t\tamplified_end->ir.terminator.direct_block = merge_block;\n\t\tamplified_end->add_branch(merge_block);\n\n\t\treturn merge_block;\n\t}\n}\n\nstatic CFGNode *emit_workgraph_dispatcher_path_thread(\n    Converter::Impl &impl, CFGNodePool &pool, CFGNode *path,\n    spv::Id main_entry_id, spv::Id linear_node_index_id, bool is_entry_point)\n{\n\tauto &builder = impl.builder();\n\tspv::Id u32_type = builder.makeUintType(32);\n\timpl.current_block = &path->ir.operations;\n\n\t// Execution mask is just based on linear index < total threads.\n\t// Nice and easy.\n\tspv::Id end_ptr = emit_load_node_input_push_parameter(impl, NodeEndNodesBDA, impl.node_input.u32_ptr_type_id);\n\tspv::Id end_id = emit_load_node_input_push_pointer(impl, end_ptr, u32_type, sizeof(uint32_t));\n\tauto *compare_op = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\tcompare_op->add_id(linear_node_index_id);\n\tcompare_op->add_id(end_id);\n\timpl.add(compare_op);\n\n\tauto *call_block = pool.create_node();\n\tauto *merge_block = pool.create_node();\n\n\tpath->ir.terminator.type = Terminator::Type::Condition;\n\tpath->ir.terminator.conditional_id = compare_op->id;\n\tpath->ir.terminator.true_block = call_block;\n\tpath->ir.terminator.false_block = merge_block;\n\tpath->add_branch(call_block);\n\tpath->add_branch(merge_block);\n\tcall_block->add_branch(merge_block);\n\tcall_block->ir.terminator.type = Terminator::Type::Branch;\n\tcall_block->ir.terminator.direct_block = merge_block;\n\timpl.current_block = &call_block->ir.operations;\n\n\temit_payload_pointer_resolve(impl, linear_node_index_id, DXIL::NodeLaunchType::Thread, is_entry_point);\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, impl.builder().makeVoidType());\n\tcall_op->add_id(main_entry_id);\n\timpl.add(call_op);\n\n\treturn merge_block;\n}\n\nstatic CFGNode *emit_workgraph_dispatcher_path_coalescing(\n    Converter::Impl &impl, CFGNodePool &, CFGNode *path,\n    spv::Id main_entry_id, spv::Id linear_node_index_id)\n{\n\timpl.current_block = &path->ir.operations;\n\temit_payload_pointer_resolve(impl, linear_node_index_id, DXIL::NodeLaunchType::Coalescing, true);\n\tauto *call_op = impl.allocate(spv::OpFunctionCall, impl.builder().makeVoidType());\n\tcall_op->add_id(main_entry_id);\n\timpl.add(call_op);\n\treturn path;\n}\n\nstatic CFGNode *emit_workgraph_dispatcher_path(\n\tConverter::Impl &impl, CFGNode *return_block,\n\tCFGNodePool &pool,\n\tDXIL::NodeLaunchType launch_type,\n\tbool broadcast_has_max_grid,\n\tspv::Id main_entry_id,\n\tspv::Id linear_node_index_id,\n\tbool is_entry_point)\n{\n\tauto *path = pool.create_node();\n\tCFGNode *end_path;\n\n\tif (launch_type == DXIL::NodeLaunchType::Broadcasting)\n\t{\n\t\tend_path = emit_workgraph_dispatcher_path_broadcast(\n\t\t\timpl, pool, path, main_entry_id, linear_node_index_id,\n\t\t\tbroadcast_has_max_grid, is_entry_point);\n\t}\n\telse if (launch_type == DXIL::NodeLaunchType::Thread)\n\t{\n\t\tend_path = emit_workgraph_dispatcher_path_thread(\n\t\t\timpl, pool, path, main_entry_id, linear_node_index_id,\n\t\t\tis_entry_point);\n\t}\n\telse\n\t{\n\t\tend_path = emit_workgraph_dispatcher_path_coalescing(\n\t\t\timpl, pool, path, main_entry_id, linear_node_index_id);\n\t}\n\n\timpl.current_block = &end_path->ir.operations;\n\tend_path->ir.terminator.type = Terminator::Type::Branch;\n\tend_path->ir.terminator.direct_block = return_block;\n\tend_path->add_branch(return_block);\n\n\treturn path;\n}\n\nbool emit_workgraph_dispatcher(Converter::Impl &impl, CFGNodePool &pool, CFGNode *entry, spv::Id main_entry_id)\n{\n\tauto &builder = impl.builder();\n\n\tspv::Id linear_node_index_id = emit_linear_node_index(impl);\n\tif (!linear_node_index_id)\n\t\treturn false;\n\n\tif (impl.node_input.private_bda_var_id)\n\t{\n\t\tspv::Id u64_type = builder.makeUintType(64);\n\t\tspv::Id payload_base = emit_load_node_input_push_parameter(impl, NodePayloadBDA, u64_type);\n\t\tauto *store_op = impl.allocate(spv::OpStore);\n\t\tstore_op->add_id(impl.node_input.private_bda_var_id);\n\t\tstore_op->add_id(payload_base);\n\t\timpl.add(store_op);\n\n\t\tauto *is_entry_block = pool.create_node();\n\t\tauto *after_is_entry_block = pool.create_node();\n\t\tentry->ir.terminator.type = Terminator::Type::Condition;\n\t\tentry->ir.terminator.conditional_id = impl.node_input.is_entry_point_id;\n\t\tentry->ir.terminator.true_block = is_entry_block;\n\t\tentry->ir.terminator.false_block = after_is_entry_block;\n\t\tentry->add_branch(is_entry_block);\n\t\tentry->add_branch(after_is_entry_block);\n\n\t\timpl.current_block = &is_entry_block->ir.operations;\n\t\t{\n\t\t\tspv::Id u32_type = builder.makeUintType(32);\n\t\t\tspv::Id uvec2_type = builder.makeVectorType(u32_type, 2);\n\t\t\tspv::Id stride_base = emit_load_node_input_push_parameter(impl, NodePayloadStrideOrOffsetsBDA, uvec2_type);\n\n\t\t\tauto *extracted = impl.allocate(spv::OpCompositeExtract, u32_type);\n\t\t\textracted->add_id(stride_base);\n\t\t\textracted->add_literal(0);\n\t\t\timpl.add(extracted);\n\n\t\t\tstore_op = impl.allocate(spv::OpStore);\n\t\t\tstore_op->add_id(impl.node_input.private_stride_var_id);\n\t\t\tstore_op->add_id(extracted->id);\n\t\t\timpl.add(store_op);\n\n\t\t\tauto *masked_block = pool.create_node();\n\t\t\timpl.current_block = &masked_block->ir.operations;\n\n\t\t\t// Resolve Payload pointer\n\t\t\t{\n\t\t\t\tauto *cast_op = impl.allocate(spv::OpConvertUToPtr, impl.node_input.u64_ptr_type_id);\n\t\t\t\tcast_op->add_id(payload_base);\n\t\t\t\timpl.add(cast_op);\n\n\t\t\t\tauto *chain_op = impl.allocate(spv::OpAccessChain,\n\t\t\t\t                               builder.makePointer(spv::StorageClassPhysicalStorageBuffer,\n\t\t\t\t                                                   u64_type));\n\t\t\t\tchain_op->add_id(cast_op->id);\n\t\t\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\t\t\timpl.add(chain_op);\n\n\t\t\t\tauto *load_op = impl.allocate(spv::OpLoad, u64_type);\n\t\t\t\tload_op->add_id(chain_op->id);\n\t\t\t\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\t\t\t\tload_op->add_literal(sizeof(uint64_t));\n\t\t\t\timpl.add(load_op);\n\n\t\t\t\tstore_op = impl.allocate(spv::OpStore);\n\t\t\t\tstore_op->add_id(impl.node_input.private_bda_var_id);\n\t\t\t\tstore_op->add_id(load_op->id);\n\t\t\t\timpl.add(store_op);\n\t\t\t}\n\n\t\t\t// Resolve stride pointer\n\t\t\t{\n\t\t\t\tauto *cast_op = impl.allocate(spv::OpBitcast, impl.node_input.u32_ptr_type_id);\n\t\t\t\tcast_op->add_id(stride_base);\n\t\t\t\timpl.add(cast_op);\n\n\t\t\t\tauto *chain_op = impl.allocate(spv::OpAccessChain,\n\t\t\t\t                               builder.makePointer(spv::StorageClassPhysicalStorageBuffer,\n\t\t\t\t                                                   u32_type));\n\t\t\t\tchain_op->add_id(cast_op->id);\n\t\t\t\tchain_op->add_id(builder.makeUintConstant(0));\n\t\t\t\timpl.add(chain_op);\n\n\t\t\t\tauto *load_op = impl.allocate(spv::OpLoad, u32_type);\n\t\t\t\tload_op->add_id(chain_op->id);\n\t\t\t\tload_op->add_literal(spv::MemoryAccessAlignedMask);\n\t\t\t\tload_op->add_literal(sizeof(uint32_t));\n\t\t\t\timpl.add(load_op);\n\n\t\t\t\tstore_op = impl.allocate(spv::OpStore);\n\t\t\t\tstore_op->add_id(impl.node_input.private_stride_var_id);\n\t\t\t\tstore_op->add_id(load_op->id);\n\t\t\t\timpl.add(store_op);\n\t\t\t}\n\n\t\t\tauto *merge = pool.create_node();\n\n\t\t\tis_entry_block->ir.terminator.type = Terminator::Type::Condition;\n\t\t\tis_entry_block->ir.terminator.conditional_id = impl.node_input.is_indirect_payload_stride_id;\n\t\t\tis_entry_block->ir.terminator.true_block = masked_block;\n\t\t\tis_entry_block->ir.terminator.false_block = merge;\n\t\t\tis_entry_block->add_branch(masked_block);\n\t\t\tis_entry_block->add_branch(merge);\n\t\t\tmasked_block->add_branch(merge);\n\t\t\tmasked_block->ir.terminator.type = Terminator::Type::Branch;\n\t\t\tmasked_block->ir.terminator.direct_block = merge;\n\n\t\t\tmerge->ir.terminator.type = Terminator::Type::Branch;\n\t\t\tmerge->ir.terminator.direct_block = after_is_entry_block;\n\t\t\tmerge->add_branch(after_is_entry_block);\n\t\t}\n\n\t\tentry = after_is_entry_block;\n\t\timpl.current_block = &entry->ir.operations;\n\t}\n\n\tauto *return_block = pool.create_node();\n\treturn_block->ir.terminator.type = Terminator::Type::Return;\n\n\tconst auto make_cond_branch = [](CFGNode *header, CFGNode *true_block, CFGNode *false_block, spv::Id cond_id) {\n\t\theader->ir.terminator.type = Terminator::Type::Condition;\n\t\theader->ir.terminator.conditional_id = cond_id;\n\t\theader->ir.terminator.true_block = true_block;\n\t\theader->ir.terminator.false_block = false_block;\n\t\theader->add_branch(true_block);\n\t\theader->add_branch(false_block);\n\t};\n\n\tswitch (impl.node_input.launch_type)\n\t{\n\tcase DXIL::NodeLaunchType::Broadcasting:\n\t{\n\t\tauto *masked_broadcast_path_entry = emit_workgraph_dispatcher_path(\n\t\t    impl, return_block, pool, DXIL::NodeLaunchType::Broadcasting,\n\t\t    true, main_entry_id, linear_node_index_id, true);\n\t\tauto *broadcast_path_entry = emit_workgraph_dispatcher_path(\n\t\t    impl, return_block, pool, DXIL::NodeLaunchType::Broadcasting,\n\t\t    false, main_entry_id, linear_node_index_id, true);\n\n\t\tauto *masked_broadcast_path_node = emit_workgraph_dispatcher_path(\n\t\t    impl, return_block, pool, DXIL::NodeLaunchType::Broadcasting,\n\t\t    true, main_entry_id, linear_node_index_id, false);\n\t\tauto *broadcast_path_node = emit_workgraph_dispatcher_path(\n\t\t    impl, return_block, pool, DXIL::NodeLaunchType::Broadcasting,\n\t\t    false, main_entry_id, linear_node_index_id, false);\n\n\t\tauto *is_masked = pool.create_node();\n\t\tauto *is_unmasked = pool.create_node();\n\n\t\tmake_cond_branch(entry, is_masked, is_unmasked, impl.node_input.broadcast_has_max_grid_id);\n\t\tmake_cond_branch(is_masked, masked_broadcast_path_entry, masked_broadcast_path_node, impl.node_input.is_entry_point_id);\n\t\tmake_cond_branch(is_unmasked, broadcast_path_entry, broadcast_path_node, impl.node_input.is_entry_point_id);\n\n\t\tbreak;\n\t}\n\n\tcase DXIL::NodeLaunchType::Thread:\n\t{\n\t\tauto *thread_path_entry = emit_workgraph_dispatcher_path(\n\t\t    impl, return_block, pool, DXIL::NodeLaunchType::Thread,\n\t\t    false, main_entry_id, linear_node_index_id, true);\n\n\t\tauto *thread_path_node = emit_workgraph_dispatcher_path(\n\t\t    impl, return_block, pool, DXIL::NodeLaunchType::Thread,\n\t\t    false, main_entry_id, linear_node_index_id, false);\n\n\t\tmake_cond_branch(entry, thread_path_entry, thread_path_node, impl.node_input.is_entry_point_id);\n\t\tbreak;\n\t}\n\n\tcase DXIL::NodeLaunchType::Coalescing:\n\t{\n\t\tauto *coalesce_path = emit_workgraph_dispatcher_path(\n\t\t\timpl, return_block, pool, DXIL::NodeLaunchType::Coalescing,\n\t\t\tfalse, main_entry_id, linear_node_index_id, true);\n\t\tentry->ir.terminator.type = Terminator::Type::Branch;\n\t\tentry->ir.terminator.direct_block = coalesce_path;\n\t\tentry->add_branch(coalesce_path);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn true;\n}\n}\n"
  },
  {
    "path": "opcodes/dxil/dxil_workgraph.hpp",
    "content": "/* Copyright (c) 2024 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n#include \"opcodes/opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_allocate_node_output_records(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_get_node_record_ptr(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_increment_output_count(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_output_complete(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_get_input_record_count(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_finished_cross_group_sharing(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_barrier_by_memory_type(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_barrier_by_memory_handle(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_barrier_by_node_record_handle(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_index_node_handle(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_annotate_node_handle(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_create_node_input_record_handle(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_create_node_output_handle(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_annotate_node_record_handle(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_node_output_is_valid(Converter::Impl &impl, const llvm::CallInst *inst);\nbool emit_get_remaining_recursion_levels(Converter::Impl &impl, const llvm::CallInst *inst);\n\nuint32_t get_node_io_from_annotate_handle(const llvm::CallInst *inst);\n\nenum NodeInputParameter\n{\n\tNodePayloadBDA = 0,\n\tNodeLinearOffsetBDA = 1,\n\tNodeEndNodesBDA = 2,\n\tNodePayloadStrideOrOffsetsBDA = 3,\n\tNodePayloadOutputBDA = 4,\n\tNodePayloadOutputAtomicBDA = 5,\n\tNodeLocalRootSignatureBDA = 6,\n\tNodePayloadOutputOffset = 7,\n\tNodeRemainingRecursionLevels = 8\n};\n\nenum NodeSpecConstant\n{\n\tNodeSpecIdGroupSizeX = 0,\n\tNodeSpecIdGroupSizeY = 1,\n\tNodeSpecIdGroupSizeZ = 2,\n\tNodeSpecIdIsEntryPoint = 3,\n\tNodeSpecIdIndirectPayloadStride = 4,\n\tNodeSpecIdDispatchGridIsUpperBound = 5,\n\tNodeSpecIdIsStaticBroadcastNode = 6,\n\tNodeSpecIdMaxBroadcastGridX = 7,\n\tNodeSpecIdMaxBroadcastGridY = 8,\n\tNodeSpecIdMaxBroadcastGridZ = 9,\n\tNodeSpecIdOutputBase = 100,\n};\n\nspv::Id emit_load_node_input_push_parameter(\n\tConverter::Impl &impl, NodeInputParameter param, spv::Id type);\n\nbool emit_workgraph_dispatcher(Converter::Impl &impl, CFGNodePool &pool, CFGNode *entry, spv::Id main_entry_id);\n}\n"
  },
  {
    "path": "opcodes/opcodes.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"dxil_converter.hpp\"\n#include \"ir.hpp\"\n\n#ifdef HAVE_LLVMBC\n#include \"cast.hpp\"\n#include \"instruction.hpp\"\n#include \"module.hpp\"\n#include \"value.hpp\"\n#else\n#include <llvm/IR/Instructions.h>\n#endif\n\n#include <vector>\n\nnamespace dxil_spv\n{\nenum class RawType { Integer, Float, Count };\nenum class RawWidth { B8 = 0, B16, B32, B64, Count };\nenum class RawVecSize { V1 = 0, V2, V3, V4, Count };\n\nenum class MagicResource : uint8_t\n{\n\tNone,\n\tAGS\n};\n\nstruct AgsInstruction\n{\n\tenum { MaxInstructions = 21 };\n\tuint32_t opcode;\n\tuint32_t phase;\n\tuint32_t immediate;\n};\n}\n"
  },
  {
    "path": "opcodes/opcodes_dxil_builtins.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"opcodes_dxil_builtins.hpp\"\n#include \"converter_impl.hpp\"\n#include \"logging.hpp\"\n#include \"opcodes/dxil/dxil_arithmetic.hpp\"\n#include \"opcodes/dxil/dxil_buffer.hpp\"\n#include \"opcodes/dxil/dxil_common.hpp\"\n#include \"opcodes/dxil/dxil_compute.hpp\"\n#include \"opcodes/dxil/dxil_geometry.hpp\"\n#include \"opcodes/dxil/dxil_pixel_ops.hpp\"\n#include \"opcodes/dxil/dxil_resources.hpp\"\n#include \"opcodes/dxil/dxil_sampling.hpp\"\n#include \"opcodes/dxil/dxil_tessellation.hpp\"\n#include \"opcodes/dxil/dxil_waveops.hpp\"\n#include \"opcodes/dxil/dxil_ray_tracing.hpp\"\n#include \"opcodes/dxil/dxil_mesh.hpp\"\n#include \"opcodes/dxil/dxil_ags.hpp\"\n#include \"opcodes/dxil/dxil_nvapi.hpp\"\n#include \"opcodes/dxil/dxil_workgraph.hpp\"\n\nnamespace dxil_spv\n{\nstruct DXILDispatcher\n{\n#define OP(x) builder_lut[unsigned(DXIL::Op::x)]\n\tDXILDispatcher() noexcept\n\t{\n\t\t// Work around lack of designated initializers in C++.\n\n\t\t// dxil_resources.hpp\n\t\tOP(LoadInput) = emit_load_input_dispatch<false>;\n\t\tOP(ExtendedSpirvLoadInput) = emit_load_input_dispatch<true>;\n\t\t// Basically exactly the same, where gsVertexAxis is replaced with vertexIndex.\n\t\tOP(AttributeAtVertex) = emit_load_input_dispatch<false>;\n\t\tOP(StoreOutput) = emit_store_output_instruction;\n\t\tOP(CreateHandle) = emit_create_handle_instruction;\n\t\tOP(CreateHandleForLib) = emit_create_handle_for_lib_instruction;\n\t\tOP(CBufferLoadLegacy) = emit_cbuffer_load_legacy_instruction;\n\t\tOP(CBufferLoad) = emit_cbuffer_load_instruction;\n\t\tOP(EvalSnapped) = emit_interpolate_dispatch<GLSLstd450InterpolateAtOffset, false>;\n\t\tOP(ExtendedEvalSnapped) = emit_interpolate_dispatch<GLSLstd450InterpolateAtOffset, true>;\n\t\tOP(EvalSampleIndex) = emit_interpolate_dispatch<GLSLstd450InterpolateAtSample, false>;\n\t\tOP(EvalCentroid) = emit_interpolate_dispatch<GLSLstd450InterpolateAtCentroid, false>;\n\t\tOP(AnnotateHandle) = emit_annotate_handle_instruction;\n\t\tOP(CreateHandleFromHeap) = emit_create_handle_from_heap_instruction;\n\t\tOP(CreateHandleFromBinding) = emit_create_handle_from_binding_instruction;\n\t\tOP(StartVertexLocation) = emit_load_draw_parameter_dispatch<spv::BuiltInBaseVertex>;\n\t\tOP(StartInstanceLocation) = emit_load_draw_parameter_dispatch<spv::BuiltInBaseInstance>;\n\t\tOP(ExtendedSpirvControlPointCountIn) = emit_load_control_point_count_in;\n\n\t\t// dxil_sampling.hpp\n\t\tOP(Sample) = emit_sample_instruction_dispatch<DXIL::Op::Sample>;\n\t\tOP(SampleBias) = emit_sample_instruction_dispatch<DXIL::Op::SampleBias>;\n\t\tOP(SampleLevel) = emit_sample_instruction_dispatch<DXIL::Op::SampleLevel>;\n\t\tOP(SampleCmp) = emit_sample_instruction_dispatch<DXIL::Op::SampleCmp>;\n\t\tOP(SampleCmpLevelZero) = emit_sample_instruction_dispatch<DXIL::Op::SampleCmpLevelZero>;\n\t\tOP(SampleCmpLevel) = emit_sample_instruction_dispatch<DXIL::Op::SampleCmpLevel>;\n\t\tOP(SampleCmpBias) = emit_sample_instruction_dispatch<DXIL::Op::SampleCmpBias>;\n\t\tOP(SampleGrad) = emit_sample_grad_instruction_dispatch<DXIL::Op::SampleGrad>;\n\t\tOP(SampleCmpGrad) = emit_sample_grad_instruction_dispatch<DXIL::Op::SampleCmpGrad>;\n\t\tOP(TextureLoad) = emit_texture_load_instruction;\n\t\tOP(TextureStore) = emit_texture_store_instruction<false>;\n\t\tOP(TextureStoreSample) = emit_texture_store_instruction<true>;\n\t\tOP(GetDimensions) = emit_get_dimensions_dispatch<false>;\n\t\tOP(ExtendedGetDimensions) = emit_get_dimensions_dispatch<true>;\n\t\tOP(TextureGather) = emit_texture_gather_dispatch<false, false>;\n\t\tOP(TextureGatherRaw) = emit_texture_gather_dispatch<false, true>;\n\t\tOP(TextureGatherCmp) = emit_texture_gather_dispatch<true, false>;\n\t\tOP(CalculateLOD) = emit_calculate_lod_dispatch<false>;\n\t\tOP(ExtendedCalculateLOD) = emit_calculate_lod_dispatch<true>;\n\t\tOP(Texture2DMSGetSamplePosition) = emit_get_sample_position_dispatch<true>;\n\t\tOP(RenderTargetGetSamplePosition) = emit_get_sample_position_dispatch<false>;\n\t\tOP(RenderTargetGetSampleCount) = emit_get_render_target_sample_count;\n\t\tOP(CheckAccessFullyMapped) = emit_check_access_fully_mapped_instruction;\n\t\tOP(WriteSamplerFeedback) = emit_write_sampler_feedback_instruction<DXIL::Op::WriteSamplerFeedback>;\n\t\tOP(WriteSamplerFeedbackLevel) = emit_write_sampler_feedback_instruction<DXIL::Op::WriteSamplerFeedbackLevel>;\n\t\tOP(WriteSamplerFeedbackGrad) = emit_write_sampler_feedback_instruction<DXIL::Op::WriteSamplerFeedbackGrad>;\n\t\tOP(WriteSamplerFeedbackBias) = emit_write_sampler_feedback_instruction<DXIL::Op::WriteSamplerFeedbackBias>;\n\n\t\t// dxil_buffer.hpp\n\t\tOP(BufferLoad) = emit_buffer_load_instruction;\n\t\tOP(RawBufferLoad) = emit_raw_buffer_load_instruction;\n\t\tOP(BufferStore) = emit_buffer_store_instruction;\n\t\tOP(RawBufferStore) = emit_raw_buffer_store_instruction;\n\t\tOP(BufferUpdateCounter) = emit_buffer_update_counter_instruction;\n\t\tOP(AtomicBinOp) = emit_atomic_binop_instruction;\n\t\tOP(AtomicCompareExchange) = emit_atomic_cmpxchg_instruction;\n\n\t\t// dxil_arithmetic.hpp\n\t\tOP(Saturate) = emit_saturate_instruction;\n\n\t\tOP(FMin) = std450_binary_dispatch<GLSLstd450NMin>;\n\t\tOP(FMax) = std450_binary_dispatch<GLSLstd450NMax>;\n\t\tOP(IMin) = std450_binary_dispatch<GLSLstd450SMin>;\n\t\tOP(IMax) = std450_binary_dispatch<GLSLstd450SMax>;\n\t\tOP(UMin) = std450_binary_dispatch<GLSLstd450UMin>;\n\t\tOP(UMax) = std450_binary_dispatch<GLSLstd450UMax>;\n\t\tOP(IMul) = wide_arith_dispatch<spv::OpSMulExtended, false>;\n\t\tOP(UMul) = wide_arith_dispatch<spv::OpUMulExtended, false>;\n\t\tOP(UAddc) = wide_arith_dispatch<spv::OpIAddCarry, false>;\n\t\tOP(USubb) = wide_arith_dispatch<spv::OpISubBorrow, false>;\n\t\tOP(ExtendedSpirvSMulExtended) = wide_arith_dispatch<spv::OpSMulExtended, true>;\n\t\tOP(ExtendedSpirvUMulExtended) = wide_arith_dispatch<spv::OpUMulExtended, true>;\n\t\tOP(ExtendedSpirvIAddCarry) = wide_arith_dispatch<spv::OpIAddCarry, true>;\n\t\tOP(ExtendedSpirvISubBorrow) = wide_arith_dispatch<spv::OpISubBorrow, true>;\n\t\tOP(UDiv) = emit_dxbc_udiv_instruction;\n\t\tOP(IsNan) = unary_dispatch<spv::OpIsNan>;\n\t\tOP(IsInf) = unary_dispatch<spv::OpIsInf>;\n\t\tOP(IsFinite) = emit_isfinite_instruction;\n\t\tOP(ExtendedFClamp) = std450_trinary_dispatch<GLSLstd450NClamp>;\n\t\tOP(ExtendedIClamp) = std450_trinary_dispatch<GLSLstd450SClamp>;\n\t\tOP(ExtendedUClamp) = std450_trinary_dispatch<GLSLstd450UClamp>;\n\t\tOP(ExtendedPow) = std450_binary_dispatch<GLSLstd450Pow>;\n\n\t\tOP(Cos) = std450_unary_dispatch<GLSLstd450Cos>;\n\t\tOP(Sin) = std450_unary_dispatch<GLSLstd450Sin>;\n\t\tOP(Tan) = std450_unary_dispatch<GLSLstd450Tan>;\n\t\tOP(Acos) = std450_unary_dispatch<GLSLstd450Acos>;\n\t\tOP(Asin) = std450_unary_dispatch<GLSLstd450Asin>;\n\t\tOP(Atan) = std450_unary_dispatch<GLSLstd450Atan>;\n\t\tOP(Hcos) = std450_unary_dispatch<GLSLstd450Cosh>;\n\t\tOP(Hsin) = std450_unary_dispatch<GLSLstd450Sinh>;\n\t\tOP(Htan) = std450_unary_dispatch<GLSLstd450Tanh>;\n\t\tOP(Exp) = std450_unary_dispatch<GLSLstd450Exp2>;\n\t\tOP(Log) = std450_unary_dispatch<GLSLstd450Log2>;\n\n\t\tOP(Rsqrt) = std450_unary_dispatch<GLSLstd450InverseSqrt>;\n\t\tOP(Sqrt) = std450_unary_dispatch<GLSLstd450Sqrt>;\n\t\tOP(FAbs) = std450_unary_dispatch<GLSLstd450FAbs>;\n\t\tOP(Frc) = std450_unary_dispatch<GLSLstd450Fract>;\n\t\tOP(ExtendedIAbs) = std450_unary_dispatch<GLSLstd450SAbs>;\n\n\t\tOP(Round_ne) = std450_unary_dispatch<GLSLstd450RoundEven>;\n\t\tOP(Round_ni) = std450_unary_dispatch<GLSLstd450Floor>;\n\t\tOP(Round_pi) = std450_unary_dispatch<GLSLstd450Ceil>;\n\t\tOP(Round_z) = std450_unary_dispatch<GLSLstd450Trunc>;\n\n\t\tOP(Bfrev) = emit_bit_reverse_instruction;\n\t\tOP(Countbits) = emit_bit_count_instruction;\n\t\tOP(FirstbitLo) = emit_find_low_bit_instruction;\n\t\tOP(FirstbitSHi) = emit_find_high_bit_dispatch<GLSLstd450FindSMsb>;\n\t\tOP(FirstbitHi) = emit_find_high_bit_dispatch<GLSLstd450FindUMsb>;\n\n\t\tOP(Dot2) = emit_dot_dispatch<2>;\n\t\tOP(Dot3) = emit_dot_dispatch<3>;\n\t\tOP(Dot4) = emit_dot_dispatch<4>;\n\n\t\tOP(Fma) = std450_trinary_dispatch<GLSLstd450Fma>;\n\t\tOP(FMad) = emit_fmad_instruction;\n\t\tOP(IMad) = emit_imad_instruction;\n\t\tOP(UMad) = emit_imad_instruction;\n\n\t\tOP(Dot4AddI8Packed) = emit_i8_dot_instruction<true>;\n\t\tOP(Dot4AddU8Packed) = emit_i8_dot_instruction<false>;\n\t\tOP(Dot2AddHalf) = emit_dot2_add_half_instruction;\n\n\t\tOP(Ibfe) = emit_bfe_dispatch<spv::OpBitFieldSExtract, false>;\n\t\tOP(Ubfe) = emit_bfe_dispatch<spv::OpBitFieldUExtract, false>;\n\t\tOP(Bfi) = emit_bfi_dispatch<false>;\n\t\tOP(ExtendedSpirvIbfe) = emit_bfe_dispatch<spv::OpBitFieldSExtract, true>;\n\t\tOP(ExtendedSpirvUbfe) = emit_bfe_dispatch<spv::OpBitFieldUExtract, true>;\n\t\tOP(ExtendedSpirvBfi) = emit_bfi_dispatch<true>;\n\t\tOP(ExtendedSpirvFindLSB) = std450_unary_dispatch<GLSLstd450FindILsb>;\n\t\tOP(ExtendedSpirvIFindMSB) = std450_unary_dispatch<GLSLstd450FindSMsb>;\n\t\tOP(ExtendedSpirvUFindMSB) = std450_unary_dispatch<GLSLstd450FindUMsb>;\n\n\t\tOP(MakeDouble) = emit_make_double_instruction;\n\t\tOP(SplitDouble) = emit_split_double_instruction;\n\t\tOP(LegacyF16ToF32) = emit_legacy_f16_to_f32_instruction;\n\t\tOP(LegacyF32ToF16) = emit_legacy_f32_to_f16_instruction;\n\t\tOP(ExtendedLegacyF16ToF32) = std450_unary_dispatch<GLSLstd450UnpackHalf2x16>;\n\t\tOP(ExtendedLegacyF32ToF16) = std450_unary_dispatch<GLSLstd450PackHalf2x16>;\n\t\tOP(LegacyDoubleToFloat) = emit_legacy_double_conv_dispatch<spv::OpFConvert>;\n\t\tOP(LegacyDoubleToSInt32) = emit_legacy_double_conv_dispatch<spv::OpConvertFToS>;\n\t\tOP(LegacyDoubleToUInt32) = emit_legacy_double_conv_dispatch<spv::OpConvertFToU>;\n\t\tOP(BitcastF16toI16) = emit_bitcast_instruction;\n\t\tOP(BitcastI16toF16) = emit_bitcast_instruction;\n\t\tOP(BitcastF32toI32) = emit_bitcast_instruction;\n\t\tOP(BitcastI32toF32) = emit_bitcast_instruction;\n\t\tOP(BitcastF64toI64) = emit_bitcast_instruction;\n\t\tOP(BitcastI64toF64) = emit_bitcast_instruction;\n\t\tOP(Unpack4x8) = emit_unpack4x8_instruction;\n\t\tOP(Pack4x8) = emit_pack4x8_instruction;\n\n\t\tOP(Msad) = emit_msad_instruction;\n\n\t\t// dxil_compute.hpp\n\t\tOP(Barrier) = emit_barrier_instruction;\n\t\tOP(ThreadId) = emit_thread_id_load_dispatch<spv::BuiltInGlobalInvocationId>;\n\t\tOP(GroupId) = emit_thread_id_load_dispatch<spv::BuiltInWorkgroupId>;\n\t\tOP(ThreadIdInGroup) = emit_thread_id_load_dispatch<spv::BuiltInLocalInvocationId>;\n\t\tOP(FlattenedThreadIdInGroup) = emit_thread_id_load_dispatch<spv::BuiltInLocalInvocationIndex>;\n\n\t\t// dxil_pixel_ops.hpp\n\t\tOP(Discard) = emit_discard_instruction;\n\t\tOP(DerivCoarseX) = emit_derivative_dispatch<spv::OpDPdxCoarse>;\n\t\tOP(DerivCoarseY) = emit_derivative_dispatch<spv::OpDPdyCoarse>;\n\t\tOP(DerivFineX) = emit_derivative_dispatch<spv::OpDPdxFine>;\n\t\tOP(DerivFineY) = emit_derivative_dispatch<spv::OpDPdyFine>;\n\t\tOP(SampleIndex) = emit_sample_index_instruction;\n\t\tOP(Coverage) = emit_coverage_instruction;\n\t\tOP(InnerCoverage) = emit_inner_coverage_instruction;\n\t\tOP(IsHelperLane) = emit_is_helper_lane_instruction;\n\t\tOP(ExtendedDeriv) = emit_extended_derivative_instruction;\n\n\t\t// dxil_geometry.hpp\n\t\tOP(EmitStream) = emit_stream_instruction;\n\t\tOP(CutStream) = emit_cut_stream_instruction;\n\t\tOP(EmitThenCutStream) = emit_then_cut_stream_instruction;\n\t\tOP(GSInstanceID) = emit_gs_instance_instruction;\n\t\tOP(PrimitiveID) = emit_primitive_id_instruction;\n\t\tOP(ViewID) = emit_view_id_instruction;\n\n\t\t// dxil_tessellation.hpp\n\t\tOP(StorePatchConstant) = emit_store_patch_constant_instruction;\n\t\tOP(LoadOutputControlPoint) = emit_load_output_generic_instruction;\n\t\tOP(DomainLocation) = emit_domain_location_instruction;\n\t\tOP(LoadPatchConstant) = emit_load_patch_constant_instruction;\n\t\tOP(OutputControlPointID) = emit_output_control_point_instruction;\n\n\t\t// dxil_waveops.hpp\n\t\tOP(WaveIsFirstLane) = emit_wave_is_first_lane_instruction;\n\t\tOP(WaveGetLaneCount) = emit_wave_builtin_dispatch<spv::BuiltInSubgroupSize>;\n\t\tOP(WaveGetLaneIndex) = emit_wave_builtin_dispatch<spv::BuiltInSubgroupLocalInvocationId>;\n\t\tOP(WaveAllTrue) = emit_wave_boolean_dispatch<spv::OpGroupNonUniformAll>;\n\t\tOP(WaveAnyTrue) = emit_wave_boolean_dispatch<spv::OpGroupNonUniformAny>;\n\t\tOP(WaveActiveAllEqual) = emit_wave_boolean_dispatch<spv::OpGroupNonUniformAllEqual>;\n\t\tOP(WaveActiveBallot) = emit_wave_ballot_instruction;\n\t\tOP(WaveReadLaneFirst) = emit_wave_read_lane_first_instruction;\n\t\tOP(WaveReadLaneAt) = emit_wave_read_lane_at_instruction;\n\t\tOP(WaveAllBitCount) = emit_wave_bit_count_dispatch<spv::GroupOperationReduce>;\n\t\tOP(WavePrefixBitCount) = emit_wave_bit_count_dispatch<spv::GroupOperationExclusiveScan>;\n\t\tOP(WaveActiveOp) = emit_wave_active_op_instruction;\n\t\tOP(WaveActiveBit) = emit_wave_active_bit_instruction;\n\t\tOP(WavePrefixOp) = emit_wave_prefix_op_instruction;\n\t\tOP(QuadOp) = emit_wave_quad_op_instruction;\n\t\tOP(QuadVote) = emit_wave_quad_vote_instruction;\n\t\tOP(QuadReadLaneAt) = emit_wave_quad_read_lane_at_instruction;\n\t\tOP(WaveMatch) = emit_wave_match_instruction;\n\t\tOP(WaveMultiPrefixBitCount) = emit_wave_multi_prefix_count_bits_instruction;\n\t\tOP(WaveMultiPrefixOp) = emit_wave_multi_prefix_op_instruction;\n\n\t\t// dxil_ray_tracing.cpp\n\t\tOP(TraceRay) = emit_trace_ray_instruction;\n\t\tOP(DispatchRaysIndex) = emit_dispatch_rays_index_instruction;\n\t\tOP(DispatchRaysDimensions) = emit_dispatch_rays_dimensions_instruction;\n\t\tOP(ObjectRayOrigin) = emit_object_ray_origin_instruction;\n\t\tOP(WorldRayOrigin) = emit_world_ray_origin_instruction;\n\t\tOP(ObjectRayDirection) = emit_object_ray_direction_instruction;\n\t\tOP(WorldRayDirection) = emit_world_ray_direction_instruction;\n\t\tOP(RayTMin) = emit_ray_t_min_instruction;\n\t\tOP(RayTCurrent) = emit_ray_t_current_instruction;\n\t\tOP(WorldToObject) = emit_world_to_object_instruction;\n\t\tOP(ObjectToWorld) = emit_object_to_world_instruction;\n\t\tOP(InstanceID) = emit_ray_tracing_instance_id_instruction;\n\t\tOP(InstanceIndex) = emit_ray_tracing_instance_index_instruction;\n\t\tOP(RayQuery_GeometryIndex) = emit_ray_tracing_geometry_index_instruction;\n\t\tOP(PrimitiveIndex) = emit_ray_tracing_primitive_index_instruction;\n\t\tOP(RayFlags) = emit_ray_tracing_ray_flags_instruction;\n\t\tOP(HitKind) = emit_ray_tracing_hit_kind_instruction;\n\t\tOP(ReportHit) = emit_ray_tracing_report_hit;\n\t\tOP(AcceptHitAndEndSearch) = emit_ray_tracing_accept_hit_and_end_search;\n\t\tOP(IgnoreHit) = emit_ray_tracing_ignore_hit;\n\t\tOP(CallShader) = emit_ray_tracing_call_shader;\n\n\t\t// Ray query\n\t\tOP(AllocateRayQuery) = emit_allocate_ray_query;\n\t\tOP(RayQuery_TraceRayInline) = emit_ray_query_trace_ray_inline_instruction;\n\t\tOP(RayQuery_Proceed) = emit_ray_query_proceed_instruction;\n\t\tOP(RayQuery_Abort) = emit_ray_query_abort_instruction;\n\n\t\t// Global status\n\t\tOP(RayQuery_CandidateType) = emit_ray_query_intersection_type_instruction<spv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CommittedStatus) = emit_ray_query_intersection_type_instruction<spv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\n\t\t// System variables\n\t\tOP(RayQuery_RayFlags) = emit_ray_query_system_value_instruction<spv::OpRayQueryGetRayFlagsKHR, 1>;\n\t\tOP(RayQuery_RayTMin) = emit_ray_query_system_value_instruction<spv::OpRayQueryGetRayTMinKHR, 1>;\n\t\tOP(RayQuery_WorldRayDirection) = emit_ray_query_system_value_instruction<spv::OpRayQueryGetWorldRayDirectionKHR, 3>;\n\t\tOP(RayQuery_WorldRayOrigin) = emit_ray_query_system_value_instruction<spv::OpRayQueryGetWorldRayOriginKHR, 3>;\n\n\t\t// Candidates\n\t\tOP(RayQuery_CommitNonOpaqueTriangleHit) = emit_ray_query_commit_non_opaque_triangle_instruction;\n\t\tOP(RayQuery_CommitProceduralPrimitiveHit) = emit_ray_query_commit_procedural_primitive_instruction;\n\t\tOP(RayQuery_CandidateProceduralPrimitiveNonOpaque) = emit_ray_query_candidate_procedural_primitive_non_opaque_instruction;\n\n\t\t// Getters (candidate)\n\t\tOP(RayQuery_CandidateTriangleRayT) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionTKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateInstanceIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionInstanceIdKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateInstanceID) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionInstanceCustomIndexKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateGeometryIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionGeometryIndexKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidatePrimitiveIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionPrimitiveIndexKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateObjectRayOrigin) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionObjectRayOriginKHR, 3,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateObjectRayDirection) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionObjectRayDirectionKHR, 3,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateTriangleBarycentrics) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionBarycentricsKHR, 2,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateTriangleFrontFace) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionFrontFaceKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateInstanceContributionToHitGroupIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateWorldToObject3x4) =\n\t\t\temit_ray_query_get_matrix_value_instruction<spv::OpRayQueryGetIntersectionWorldToObjectKHR,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\t\tOP(RayQuery_CandidateObjectToWorld3x4) =\n\t\t\temit_ray_query_get_matrix_value_instruction<spv::OpRayQueryGetIntersectionObjectToWorldKHR,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCandidateIntersectionKHR>;\n\n\t\t// Getters (committed)\n\t\tOP(RayQuery_CommittedRayT) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionTKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedInstanceIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionInstanceIdKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedInstanceID) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionInstanceCustomIndexKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedGeometryIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionGeometryIndexKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedPrimitiveIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionPrimitiveIndexKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedObjectRayOrigin) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionObjectRayOriginKHR, 3,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedObjectRayDirection) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionObjectRayDirectionKHR, 3,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedTriangleBarycentrics) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionBarycentricsKHR, 2,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedTriangleFrontFace) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionFrontFaceKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedInstanceContributionToHitGroupIndex) =\n\t\t\temit_ray_query_get_value_instruction<spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, 1,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedWorldToObject3x4) =\n\t\t\temit_ray_query_get_matrix_value_instruction<spv::OpRayQueryGetIntersectionWorldToObjectKHR,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\tOP(RayQuery_CommittedObjectToWorld3x4) =\n\t\t\temit_ray_query_get_matrix_value_instruction<spv::OpRayQueryGetIntersectionObjectToWorldKHR,\n\t\t\t\tspv::RayQueryIntersectionRayQueryCommittedIntersectionKHR>;\n\t\t////////////\n\n\t\t// dxil_mesh.cpp\n\t\tOP(SetMeshOutputCounts) = emit_set_mesh_output_counts_instruction;\n\t\tOP(EmitIndices) = emit_emit_indices_instruction;\n\t\tOP(GetMeshPayload) = emit_get_mesh_payload_instruction;\n\t\tOP(StoreVertexOutput) = emit_store_vertex_output_instruction;\n\t\tOP(StorePrimitiveOutput) = emit_store_primitive_output_instruction;\n\t\tOP(DispatchMesh) = emit_dispatch_mesh_instruction;\n\n\t\t// dxil_workgraph.hpp\n\t\tOP(AllocateNodeOutputRecords) = emit_allocate_node_output_records;\n\t\tOP(GetNodeRecordPtr) = emit_get_node_record_ptr;\n\t\tOP(IncrementOutputCount) = emit_increment_output_count;\n\t\tOP(OutputComplete) = emit_output_complete;\n\t\tOP(GetInputRecordCount) = emit_get_input_record_count;\n\t\tOP(FinishedCrossGroupSharing) = emit_finished_cross_group_sharing;\n\t\tOP(BarrierByMemoryType) = emit_barrier_by_memory_type;\n\t\tOP(BarrierByMemoryHandle) = emit_barrier_by_memory_handle;\n\t\tOP(BarrierByNodeRecordHandle) = emit_barrier_by_node_record_handle;\n\t\tOP(IndexNodeHandle) = emit_index_node_handle;\n\t\tOP(AnnotateNodeHandle) = emit_annotate_node_handle;\n\t\tOP(CreateNodeInputRecordHandle) = emit_create_node_input_record_handle;\n\t\tOP(CreateNodeOutputHandle) = emit_create_node_output_handle;\n\t\tOP(AnnotateNodeRecordHandle) = emit_annotate_node_record_handle;\n\t\tOP(NodeOutputIsValid) = emit_node_output_is_valid;\n\t\tOP(GetRemainingRecursionLevels) = emit_get_remaining_recursion_levels;\n\t}\n\n#undef OP\n\n\tDXILOperationBuilder builder_lut[unsigned(DXIL::Op::Count)] = {};\n};\n\n// Sets up LUT once.\nstatic DXILDispatcher global_dispatcher;\n\nbool emit_dxil_instruction(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// The opcode is encoded as a constant integer.\n\tuint32_t opcode;\n\tif (!get_constant_operand(instruction, 0, &opcode))\n\t\treturn false;\n\n\tif (opcode >= unsigned(DXIL::Op::Count))\n\t{\n\t\tLOGE(\"DXIL opcode %u is out of range.\\n\", opcode);\n\t\treturn false;\n\t}\n\n\tif (global_dispatcher.builder_lut[opcode] == nullptr)\n\t{\n\t\tLOGE(\"Unimplemented DXIL opcode %u\\n\", opcode);\n\t\treturn false;\n\t}\n\n\tif (!global_dispatcher.builder_lut[opcode](impl, instruction))\n\t{\n\t\tLOGE(\"Failed DXIL opcode %u.\\n\", opcode);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool dxil_instruction_has_side_effects(const llvm::CallInst *instruction)\n{\n\tuint32_t opcode;\n\tif (!get_constant_operand(instruction, 0, &opcode))\n\t\treturn false;\n\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::VoidTyID)\n\t\treturn true;\n\n\tbool ret;\n\n\t// Most of these are covered by the void check, but be exhaustive for completeness.\n\tswitch (DXIL::Op(opcode))\n\t{\n\tcase DXIL::Op::StoreOutput:\n\tcase DXIL::Op::TextureStore:\n\tcase DXIL::Op::BufferStore:\n\tcase DXIL::Op::BufferUpdateCounter:\n\tcase DXIL::Op::AtomicBinOp:\n\tcase DXIL::Op::AtomicCompareExchange:\n\tcase DXIL::Op::Barrier:\n\tcase DXIL::Op::Discard:\n\tcase DXIL::Op::EmitStream:\n\tcase DXIL::Op::CutStream:\n\tcase DXIL::Op::EmitThenCutStream:\n\tcase DXIL::Op::StorePatchConstant:\n\tcase DXIL::Op::RawBufferStore:\n\tcase DXIL::Op::IgnoreHit:\n\tcase DXIL::Op::AcceptHitAndEndSearch:\n\tcase DXIL::Op::TraceRay:\n\tcase DXIL::Op::ReportHit:\n\tcase DXIL::Op::CallShader:\n\tcase DXIL::Op::SetMeshOutputCounts:\n\tcase DXIL::Op::EmitIndices:\n\tcase DXIL::Op::StoreVertexOutput:\n\tcase DXIL::Op::StorePrimitiveOutput:\n\tcase DXIL::Op::DispatchMesh:\n\tcase DXIL::Op::WriteSamplerFeedback:\n\tcase DXIL::Op::WriteSamplerFeedbackBias:\n\tcase DXIL::Op::WriteSamplerFeedbackLevel:\n\tcase DXIL::Op::WriteSamplerFeedbackGrad:\n\tcase DXIL::Op::RayQuery_TraceRayInline:\n\tcase DXIL::Op::RayQuery_Proceed:\n\tcase DXIL::Op::RayQuery_Abort:\n\tcase DXIL::Op::RayQuery_CommitNonOpaqueTriangleHit:\n\tcase DXIL::Op::RayQuery_CommitProceduralPrimitiveHit:\n\tcase DXIL::Op::TextureStoreSample:\n\t\tret = true;\n\t\tbreak;\n\n\tdefault:\n\t\tret = false;\n\t\tbreak;\n\t}\n\n\treturn ret;\n}\n\nstatic void update_raw_access_tracking_from_vector_type(\n    AccessTracking &tracking, const llvm::Type *type, RawVecSize vec_size)\n{\n\t// For SSBOs, always use uint types, except for 64-bit since Float64 vs Int64 are two separate features.\n\tif (type->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\ttracking.raw_access_buffer_declarations[int(RawType::Integer)][int(RawWidth::B16)][int(vec_size)] = true;\n\telse if (type->getTypeID() == llvm::Type::TypeID::FloatTyID)\n\t\ttracking.raw_access_buffer_declarations[int(RawType::Integer)][int(RawWidth::B32)][int(vec_size)] = true;\n\telse if (type->getTypeID() == llvm::Type::TypeID::DoubleTyID)\n\t\ttracking.raw_access_buffer_declarations[int(RawType::Float)][int(RawWidth::B64)][int(vec_size)] = true;\n\telse if (type->getTypeID() == llvm::Type::TypeID::IntegerTyID)\n\t{\n\t\tif (type->getIntegerBitWidth() == 16)\n\t\t\ttracking.raw_access_buffer_declarations[int(RawType::Integer)][int(RawWidth::B16)][int(vec_size)] = true;\n\t\telse if (type->getIntegerBitWidth() == 32)\n\t\t\ttracking.raw_access_buffer_declarations[int(RawType::Integer)][int(RawWidth::B32)][int(vec_size)] = true;\n\t\telse if (type->getIntegerBitWidth() == 64)\n\t\t\ttracking.raw_access_buffer_declarations[int(RawType::Integer)][int(RawWidth::B64)][int(vec_size)] = true;\n\t}\n}\n\nstatic void update_raw_access_tracking_from_scalar_type(AccessTracking &tracking, const llvm::Type *type)\n{\n\tupdate_raw_access_tracking_from_vector_type(tracking, type, RawVecSize::V1);\n}\n\nstatic void update_raw_access_tracking_for_byte_address(\n\tConverter::Impl &impl,\n\tAccessTracking &tracking,\n\tconst llvm::Type *type,\n\tconst llvm::Value *byte_offset,\n\tuint32_t mask)\n{\n    // If we have raw access chains, we don't bother trying to vectorize the SSBOs.\n    // Just emit one alias and we can go from there.\n    if (!impl.options.nv_raw_access_chains)\n    {\n        auto vec = raw_access_byte_address_vectorize(impl, type, byte_offset, mask);\n        update_raw_access_tracking_from_vector_type(tracking, type, vec);\n    }\n}\n\nstatic void update_raw_access_tracking_for_structured(\n\tConverter::Impl &impl,\n\tAccessTracking &tracking,\n\tconst llvm::Type *type,\n\tconst llvm::Value *index,\n\tunsigned stride,\n\tconst llvm::Value *byte_offset,\n\tuint32_t mask)\n{\n    if (!impl.options.nv_raw_access_chains)\n    {\n        auto vec = raw_access_structured_vectorize(impl, type, index, stride, byte_offset, mask);\n        update_raw_access_tracking_from_vector_type(tracking, type, vec);\n    }\n}\n\nstatic void analyze_descriptor_handle_sink(Converter::Impl &impl,\n                                           const llvm::CallInst *instruction,\n                                           const llvm::BasicBlock *bb)\n{\n\t// Even if we only use a resource in a branch in HLSL code, DXC might still unconditionally load\n\t// the resource handle, which means descriptor QA checks might not be entirely accurate.\n\t// To ensure we handle control flow correctly, sink instruction to BBs which actually use the\n\t// resource handle.\n\tunsigned count = instruction->getNumOperands();\n\tfor (unsigned i = 1; i < count; i++)\n\t{\n\t\tif (auto *call_op = llvm::dyn_cast<llvm::CallInst>(instruction->getOperand(i)))\n\t\t{\n\t\t\tauto itr = impl.resource_handle_to_block.find(call_op);\n\t\t\tif (itr != impl.resource_handle_to_block.end())\n\t\t\t{\n\t\t\t\tauto *orig_bb = itr->second;\n\t\t\t\tif (!impl.resource_handle_is_conservative.count(call_op) && orig_bb != bb)\n\t\t\t\t{\n\t\t\t\t\timpl.resource_handles_needing_sink.insert(call_op);\n\t\t\t\t\tauto &sinks = impl.bb_to_sinks[bb];\n\t\t\t\t\tif (std::find(sinks.begin(), sinks.end(), call_op) == sinks.end())\n\t\t\t\t\t\tsinks.push_back(call_op);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If we use the handle in the same block we created it,\n\t\t\t\t\t// don't try to sink anything. One QA check is enough.\n\t\t\t\t\timpl.resource_handle_is_conservative.insert(call_op);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic Converter::Impl::RawBufferMeta\nget_resource_meta_from_buffer_op(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tauto itr = impl.llvm_value_to_srv_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_srv_resource_index_map.end())\n\t\treturn impl.get_raw_buffer_meta(DXIL::ResourceType::SRV, itr->second);\n\n\titr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t\treturn impl.get_raw_buffer_meta(DXIL::ResourceType::UAV, itr->second);\n\n\tauto annotate_itr = impl.llvm_annotate_handle_uses.find(instruction->getOperand(1));\n\tif (annotate_itr != impl.llvm_annotate_handle_uses.end())\n\t\treturn { annotate_itr->second.resource_kind, annotate_itr->second.stride };\n\n\tLOGE(\"No resource?\\n\");\n\treturn { DXIL::ResourceKind::Invalid, 0 };\n}\n\nbool analyze_alloca_cbv_forwarding_pre_resource_emit(Converter::Impl &impl, const llvm::Type *scalar_type,\n                                                     AllocaCBVForwardingTracking &tracking)\n{\n\tif (!tracking.cbv_handle)\n\t\treturn true;\n\n\tif (!tracking.has_load || !tracking.stride)\n\t{\n\t\ttracking.cbv_handle = nullptr;\n\t\treturn true;\n\t}\n\n\t// Robustness purposes, if we cannot prove that all input data was read,\n\t// we may falsely cause an OOB read on BDA to happen when we redirect a load to it.\n\tif (tracking.highest_store_index < tracking.min_highest_store_index)\n\t{\n\t\ttracking.cbv_handle = nullptr;\n\t\treturn true;\n\t}\n\n\tAccessTracking *cbv_tracking = nullptr;\n\tauto itr = impl.llvm_value_to_cbv_resource_index_map.find(tracking.cbv_handle);\n\tif (itr != impl.llvm_value_to_cbv_resource_index_map.end())\n\t\tcbv_tracking = &impl.cbv_access_tracking[itr->second];\n\n\tif (!cbv_tracking)\n\t{\n\t\tauto annotate_itr = impl.llvm_annotate_handle_uses.find(tracking.cbv_handle);\n\t\tif (annotate_itr != impl.llvm_annotate_handle_uses.end())\n\t\t\tcbv_tracking = &annotate_itr->second.tracking;\n\t}\n\n\tif (cbv_tracking)\n\t{\n\t\tauto raw_type = scalar_type->isFloatingPointTy() ? RawType::Float : RawType::Integer;\n\t\tcbv_tracking->raw_access_buffer_declarations[int(raw_type)][int(RawWidth::B32)][int(RawVecSize::V1)] = true;\n\t}\n\n\treturn true;\n}\n\nbool analyze_alloca_cbv_forwarding_post_resource_emit(Converter::Impl &impl, AllocaCBVForwardingTracking &tracking)\n{\n\tif (!tracking.cbv_handle)\n\t\treturn true;\n\n\t// We don't know this until after resource creation.\n\tif (!cbuffer_supports_gep_punchthrough(impl, tracking.cbv_handle))\n\t{\n\t\ttracking.cbv_handle = nullptr;\n\t\treturn true;\n\t}\n\n\treturn true;\n}\n\nstatic void analyze_dxil_cbuffer_load(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tAccessTracking *tracking = nullptr;\n\tauto itr = impl.llvm_value_to_cbv_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_cbv_resource_index_map.end())\n\t\ttracking = &impl.cbv_access_tracking[itr->second];\n\n\tif (!tracking)\n\t{\n\t\tauto annotate_itr = impl.llvm_annotate_handle_uses.find(instruction->getOperand(1));\n\t\tif (annotate_itr != impl.llvm_annotate_handle_uses.end())\n\t\t\ttracking = &annotate_itr->second.tracking;\n\t}\n\n\tif (tracking)\n\t{\n\t\t// For root parameters this is not normally allowed by D3D12, but some games are broken.\n\t\t// We can work around it robustly since it's legal code in Vulkan (if dynamically uniform).\n\t\tif (!llvm::isa<llvm::ConstantInt>(instruction->getOperand(2)))\n\t\t\ttracking->dynamically_indexed_cbv = true;\n\n\t\tif (type_is_composite_return_value(instruction->getType()))\n\t\t{\n\t\t\t// Legacy float4 model. However, it seems like DXIL also supports f16x8, f32x4 and f64x2 ... :(\n\t\t\tswitch (get_type_scalar_alignment(impl, get_composite_element_type(instruction->getType())))\n\t\t\t{\n\t\t\tcase 2:\n\t\t\tcase 4:\n\t\t\t\t// We'll bit-cast on-demand for f16x8.\n\t\t\t\ttracking->raw_access_buffer_declarations[int(RawType::Float)][int(RawWidth::B32)][int(RawVecSize::V4)] = true;\n\t\t\t\tbreak;\n\n\t\t\tcase 8:\n\t\t\t{\n\t\t\t\t// Need aliases here to handle difference in Float64 vs Int64 support.\n\t\t\t\t// For 16-bit, support is gated behind both types.\n\t\t\t\tbool is_float = get_composite_element_type(instruction->getType())->getTypeID() == llvm::Type::TypeID::DoubleTyID;\n\t\t\t\ttracking->raw_access_buffer_declarations[int(is_float ? RawType::Float : RawType::Integer)][int(RawWidth::B64)][int(RawVecSize::V2)] = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tswitch (get_type_scalar_alignment(impl, instruction->getType()))\n\t\t\t{\n\t\t\tcase 2:\n\t\t\t\ttracking->raw_access_buffer_declarations[int(RawType::Float)][int(RawWidth::B16)][int(RawVecSize::V1)] = true;\n\t\t\t\tbreak;\n\n\t\t\tcase 4:\n\t\t\t\ttracking->raw_access_buffer_declarations[int(RawType::Float)][int(RawWidth::B32)][int(RawVecSize::V1)] = true;\n\t\t\t\tbreak;\n\n\t\t\tcase 8:\n\t\t\t{\n\t\t\t\t// Need aliases here to handle difference in Float64 vs Int64 support.\n\t\t\t\t// For 16-bit, support is gated behind both types.\n\t\t\t\tbool is_float = instruction->getType()->getTypeID() == llvm::Type::TypeID::DoubleTyID;\n\t\t\t\ttracking->raw_access_buffer_declarations[int(is_float ? RawType::Float : RawType::Integer)][int(RawWidth::B64)][int(RawVecSize::V1)] = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// dxilconv is broken and doesn't flag the UAV counter bit in metadata in all situations.\nstatic void analyze_dxil_atomic_counter(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tif (analyze_nvapi_buffer_update_counter(impl, instruction))\n\t\treturn;\n\n\tAccessTracking *tracking = nullptr;\n\n\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t\ttracking = &impl.uav_access_tracking[itr->second];\n\n\tif (tracking)\n\t\ttracking->has_counter = true;\n}\n\nstatic void analyze_dxil_buffer_load(Converter::Impl &impl, const llvm::CallInst *instruction, DXIL::Op opcode)\n{\n\tAccessTracking *tracking = nullptr;\n\n\t// In DXIL, whether or not an opcode is sparse depends on if the 4th argument is statically used by SSA ...\n\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t\ttracking = &impl.uav_access_tracking[itr->second];\n\n\tif (!tracking)\n\t{\n\t\titr = impl.llvm_value_to_srv_resource_index_map.find(instruction->getOperand(1));\n\t\tif (itr != impl.llvm_value_to_srv_resource_index_map.end())\n\t\t\ttracking = &impl.srv_access_tracking[itr->second];\n\t}\n\n\tif (!tracking)\n\t{\n\t\tauto annotate_itr = impl.llvm_annotate_handle_uses.find(instruction->getOperand(1));\n\t\tif (annotate_itr != impl.llvm_annotate_handle_uses.end())\n\t\t\ttracking = &annotate_itr->second.tracking;\n\t}\n\n\tif (tracking)\n\t{\n\t\tif (analyze_ags_buffer_load(impl, instruction, tracking))\n\t\t\treturn;\n\t\tif (analyze_nvapi_buffer_load(impl, instruction, tracking))\n\t\t\treturn;\n\n\t\ttracking->has_read = true;\n\n\t\tif (opcode != DXIL::Op::TextureLoad)\n\t\t{\n\t\t\tauto meta = get_resource_meta_from_buffer_op(impl, instruction);\n\n\t\t\tuint32_t access_mask = 0;\n\t\t\tauto composite_itr = impl.llvm_composite_meta.find(instruction);\n\t\t\tif (composite_itr != impl.llvm_composite_meta.end())\n\t\t\t\taccess_mask = composite_itr->second.access_mask & 0xfu;\n\n\t\t\t// Smear read masks.\n\t\t\taccess_mask |= access_mask >> 1u;\n\t\t\taccess_mask |= access_mask >> 2u;\n\n\t\t\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t\t\t{\n\t\t\t\tupdate_raw_access_tracking_for_byte_address(impl, *tracking,\n\t\t\t\t                                            get_composite_element_type(instruction->getType()),\n\t\t\t\t                                            instruction->getOperand(2), access_mask);\n\t\t\t}\n\t\t\telse if (meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t\t{\n\t\t\t\tupdate_raw_access_tracking_for_structured(impl, *tracking,\n\t\t\t\t                                          get_composite_element_type(instruction->getType()),\n\t\t\t\t                                          instruction->getOperand(2),\n\t\t\t\t                                          meta.stride,\n\t\t\t\t                                          instruction->getOperand(3),\n\t\t\t\t                                          access_mask);\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void analyze_dxil_buffer_store(Converter::Impl &impl, const llvm::CallInst *instruction, DXIL::Op opcode)\n{\n\tAccessTracking *tracking = nullptr;\n\n\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t\ttracking = &impl.uav_access_tracking[itr->second];\n\n\tif (!tracking)\n\t{\n\t\tauto annotate_itr = impl.llvm_annotate_handle_uses.find(instruction->getOperand(1));\n\t\tif (annotate_itr != impl.llvm_annotate_handle_uses.end())\n\t\t\ttracking = &annotate_itr->second.tracking;\n\t}\n\n\tif (tracking)\n\t{\n\t\ttracking->has_written = true;\n\n\t\tanalyze_ags_buffer_store(impl, instruction, tracking, opcode);\n\t\tanalyze_nvapi_buffer_store(impl, instruction, tracking, opcode);\n\n\t\tif (opcode != DXIL::Op::TextureStore && opcode != DXIL::Op::TextureStoreSample)\n\t\t{\n\t\t\tauto meta = get_resource_meta_from_buffer_op(impl, instruction);\n\n\t\t\tif (meta.kind == DXIL::ResourceKind::RawBuffer)\n\t\t\t{\n\t\t\t\tunsigned mask = llvm::cast<llvm::ConstantInt>(instruction->getOperand(8))->getUniqueInteger().getZExtValue();\n\t\t\t\tupdate_raw_access_tracking_for_byte_address(impl, *tracking,\n\t\t\t\t                                            instruction->getOperand(4)->getType(),\n\t\t\t\t                                            instruction->getOperand(2), mask);\n\t\t\t}\n\t\t\telse if (meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t\t{\n\t\t\t\tunsigned mask = llvm::cast<llvm::ConstantInt>(instruction->getOperand(8))->getUniqueInteger().getZExtValue();\n\t\t\t\tupdate_raw_access_tracking_for_structured(impl, *tracking,\n\t\t\t\t                                          instruction->getOperand(4)->getType(),\n\t\t\t\t                                          instruction->getOperand(2),\n\t\t\t\t                                          meta.stride,\n\t\t\t\t                                          instruction->getOperand(3),\n\t\t\t\t                                          mask);\n\t\t\t}\n\t\t}\n\t\timpl.shader_analysis.has_side_effects = true;\n\t}\n}\n\nstatic bool analyze_dxil_atomic_op(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\tAccessTracking *tracking = nullptr;\n\n\tauto itr = impl.llvm_value_to_uav_resource_index_map.find(instruction->getOperand(1));\n\tif (itr != impl.llvm_value_to_uav_resource_index_map.end())\n\t{\n\t\tif (analyze_prepass_ags_dxil_atomic_op(impl, instruction, itr->second))\n\t\t\treturn true;\n\n\t\ttracking = &impl.uav_access_tracking[itr->second];\n\t}\n\n\tauto annotate_itr = impl.llvm_annotate_handle_uses.find(instruction->getOperand(1));\n\tif (annotate_itr != impl.llvm_annotate_handle_uses.end())\n\t\ttracking = &annotate_itr->second.tracking;\n\n\tif (tracking)\n\t{\n\t\ttracking->has_read = true;\n\t\ttracking->has_written = true;\n\t\ttracking->has_atomic = true;\n\n\t\tuint32_t op = 0;\n\t\tget_constant_operand(instruction, 0, &op);\n\n\t\tswitch (DXIL::Op(op))\n\t\t{\n\t\tcase DXIL::Op::AtomicBinOp:\n\t\tcase DXIL::Op::AtomicCompareExchange:\n\t\t\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t\t\t    instruction->getType()->getIntegerBitWidth() == 64)\n\t\t\t\ttracking->has_atomic_64bit = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\t// Feedback, always 64-bit.\n\t\t\ttracking->has_atomic_64bit = true;\n\t\t\tbreak;\n\t\t}\n\n\t\tauto meta = get_resource_meta_from_buffer_op(impl, instruction);\n\t\tif (meta.kind == DXIL::ResourceKind::RawBuffer || meta.kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t\tupdate_raw_access_tracking_from_scalar_type(*tracking, instruction->getType());\n\n\t\timpl.shader_analysis.has_side_effects = true;\n\t}\n\n\treturn true;\n}\n\nbool analyze_dxil_instruction_secondary_pass(Converter::Impl &impl, const llvm::CallInst *instruction)\n{\n\t// The opcode is encoded as a constant integer.\n\tuint32_t opcode;\n\tif (!get_constant_operand(instruction, 0, &opcode))\n\t\treturn false;\n\n\tauto op = static_cast<DXIL::Op>(opcode);\n\n\tswitch (op)\n\t{\n\tcase DXIL::Op::BufferLoad:\n\tcase DXIL::Op::RawBufferLoad:\n\t\tanalyze_dxil_buffer_load(impl, instruction, op);\n\t\tbreak;\n\n\tcase DXIL::Op::AtomicCompareExchange:\n\tcase DXIL::Op::AtomicBinOp:\n\tcase DXIL::Op::WriteSamplerFeedback:\n\tcase DXIL::Op::WriteSamplerFeedbackBias:\n\tcase DXIL::Op::WriteSamplerFeedbackGrad:\n\tcase DXIL::Op::WriteSamplerFeedbackLevel:\n\t\t// Writing sampler feedback is more or less equivalent to an atomic.\n\t\tif (!analyze_dxil_atomic_op(impl, instruction))\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase DXIL::Op::TextureStore:\n\tcase DXIL::Op::BufferStore:\n\tcase DXIL::Op::RawBufferStore:\n\t\t// TextureStore only needed here to track AGS U64 image atomics.\n\t\tanalyze_dxil_buffer_store(impl, instruction, op);\n\t\tbreak;\n\n\tcase DXIL::Op::BufferUpdateCounter:\n\t\tanalyze_dxil_atomic_counter(impl, instruction);\n\t\tbreak;\n\n\tcase DXIL::Op::TraceRay:\n\t{\n\t\t// Mark alloca'd variables which should be considered as payloads rather than StorageClassFunction.\n\t\t// Moved to secondary pass to help NVAPI analysis since it uses TraceRay for nefarious needs,\n\t\t// and we need to have completed NVAPI analysis first.\n\t\tif (analyze_nvapi_trace_ray(impl, instruction))\n\t\t\tbreak;\n\n\t\tif (const auto *alloca_inst = llvm::dyn_cast<llvm::AllocaInst>(instruction->getOperand(15)))\n\t\t{\n\t\t\tauto storage = impl.get_effective_storage_class(alloca_inst, spv::StorageClassFunction);\n\t\t\tif (storage != spv::StorageClassFunction && storage != spv::StorageClassRayPayloadKHR)\n\t\t\t{\n\t\t\t\timpl.handle_to_storage_class[alloca_inst] = spv::StorageClassFunction;\n\t\t\t\tif (!impl.get_needs_temp_storage_copy(alloca_inst))\n\t\t\t\t\timpl.needs_temp_storage_copy.insert(alloca_inst);\n\t\t\t}\n\t\t\telse if (!impl.get_needs_temp_storage_copy(alloca_inst))\n\t\t\t{\n\t\t\t\timpl.handle_to_storage_class[alloca_inst] = spv::StorageClassRayPayloadKHR;\n\t\t\t}\n\t\t}\n\n\t\tif (const auto *flags_inst = llvm::dyn_cast<llvm::ConstantInt>(instruction->getOperand(2)))\n\t\t{\n\t\t\tauto value = flags_inst->getUniqueInteger().getZExtValue();\n\t\t\tif ((value & (spv::RayFlagsSkipTrianglesKHRMask | spv::RayFlagsSkipAABBsKHRMask)) != 0)\n\t\t\t{\n\t\t\t\timpl.shader_analysis.can_require_primitive_culling = true;\n\t\t\t}\n\t\t\tif ((value & spv::RayFlagsForceOpacityMicromap2StateEXTMask) != 0)\n\t\t\t{\n\t\t\t\timpl.shader_analysis.can_require_opacity_micromap = true;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Non constant flags, so we must be conservative.\n\t\t\timpl.shader_analysis.can_require_primitive_culling = true;\n\t\t\timpl.shader_analysis.can_require_opacity_micromap = true;\n\t\t}\n\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::CallShader:\n\t{\n\t\t// Mark alloca'd variables which should be considered as payloads rather than StorageClassFunction.\n\t\t// Moved to secondary pass to help NVAPI analysis since it uses CallShader for nefarious needs,\n\t\t// and we need to have completed NVAPI analysis first.\n\t\tif (analyze_nvapi_call_shader(impl, instruction))\n\t\t\tbreak;\n\n\t\tif (const auto *alloca_inst = llvm::dyn_cast<llvm::AllocaInst>(instruction->getOperand(2)))\n\t\t{\n\t\t\tauto storage = impl.get_effective_storage_class(alloca_inst, spv::StorageClassFunction);\n\t\t\tif (storage != spv::StorageClassFunction && storage != spv::StorageClassCallableDataKHR)\n\t\t\t{\n\t\t\t\timpl.handle_to_storage_class[alloca_inst] = spv::StorageClassFunction;\n\t\t\t\tif (!impl.get_needs_temp_storage_copy(alloca_inst))\n\t\t\t\t\timpl.needs_temp_storage_copy.insert(alloca_inst);\n\t\t\t}\n\t\t\telse if (!impl.get_needs_temp_storage_copy(alloca_inst))\n\t\t\t{\n\t\t\t\timpl.handle_to_storage_class[alloca_inst] = spv::StorageClassCallableDataKHR;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn true;\n}\n\nbool analyze_dxil_instruction_primary_pass(Converter::Impl &impl, const llvm::CallInst *instruction, const llvm::BasicBlock *bb)\n{\n\t// The opcode is encoded as a constant integer.\n\tuint32_t opcode;\n\tif (!get_constant_operand(instruction, 0, &opcode))\n\t\treturn false;\n\n\tif (impl.options.descriptor_qa_enabled && impl.options.descriptor_qa_sink_handles)\n\t\tanalyze_descriptor_handle_sink(impl, instruction, bb);\n\n\t// Mark struct types which are never really used as \"proper\" struct types.\n\t// We prefer to use normal vector types instead when possible.\n\t// The only real exception to this rule is when using sparse.\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::StructTyID &&\n\t    instruction->getType()->getStructNumElements() >= 4)\n\t{\n\t\tif (std::find(impl.llvm_dxil_op_fake_struct_types.begin(),\n\t\t              impl.llvm_dxil_op_fake_struct_types.end(),\n\t\t              instruction->getType()) == impl.llvm_dxil_op_fake_struct_types.end())\n\t\t{\n\t\t\timpl.llvm_dxil_op_fake_struct_types.push_back(instruction->getType());\n\t\t}\n\t}\n\n\tauto op = static_cast<DXIL::Op>(opcode);\n\n\tswitch (op)\n\t{\n\tcase DXIL::Op::CreateHandle:\n\t{\n\t\tuint32_t resource_type_operand, resource_range;\n\t\tif (!get_constant_operand(instruction, 1, &resource_type_operand))\n\t\t\treturn false;\n\t\tif (!get_constant_operand(instruction, 2, &resource_range))\n\t\t\treturn false;\n\n\t\tif (static_cast<DXIL::ResourceType>(resource_type_operand) == DXIL::ResourceType::UAV)\n\t\t\timpl.llvm_value_to_uav_resource_index_map[instruction] = resource_range;\n\t\telse if (static_cast<DXIL::ResourceType>(resource_type_operand) == DXIL::ResourceType::SRV)\n\t\t\timpl.llvm_value_to_srv_resource_index_map[instruction] = resource_range;\n\t\telse if (static_cast<DXIL::ResourceType>(resource_type_operand) == DXIL::ResourceType::CBV)\n\t\t\timpl.llvm_value_to_cbv_resource_index_map[instruction] = resource_range;\n\n\t\tif (impl.options.descriptor_qa_enabled && impl.options.descriptor_qa_sink_handles)\n\t\t\timpl.resource_handle_to_block[instruction] = bb;\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::CreateHandleForLib:\n\t{\n\t\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(instruction->getOperand(1));\n\t\tif (itr == impl.llvm_global_variable_to_resource_mapping.end())\n\t\t\treturn false;\n\n\t\tif (itr->second.type == DXIL::ResourceType::UAV)\n\t\t\timpl.llvm_value_to_uav_resource_index_map[instruction] = itr->second.meta_index;\n\t\telse if (itr->second.type == DXIL::ResourceType::SRV)\n\t\t\timpl.llvm_value_to_srv_resource_index_map[instruction] = itr->second.meta_index;\n\t\telse if (itr->second.type == DXIL::ResourceType::CBV)\n\t\t\timpl.llvm_value_to_cbv_resource_index_map[instruction] = itr->second.meta_index;\n\n\t\timpl.llvm_active_global_resource_variables.insert(itr->second.variable);\n\n\t\tif (impl.options.descriptor_qa_enabled && impl.options.descriptor_qa_sink_handles)\n\t\t\timpl.resource_handle_to_block[instruction] = bb;\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::AnnotateHandle:\n\t{\n\t\tAnnotateHandleMeta meta = {};\n\t\tif (!get_annotate_handle_meta(impl, instruction, meta))\n\t\t\treturn false;\n\n\t\tif (meta.resource_op == DXIL::Op::CreateHandleFromHeap)\n\t\t{\n\t\t\t// Annotating handle forms the real resource.\n\t\t\t// CreateHandleFromHeap merely holds the index / nonuniform.\n\t\t\t// For analysis purposes, this is irrelevant.\n\t\t\tauto ordinal = unsigned(impl.llvm_annotate_handle_uses.size());\n\t\t\tauto &use = impl.llvm_annotate_handle_uses[instruction];\n\t\t\tuse = {};\n\t\t\tuse.ordinal = ordinal;\n\n\t\t\tauto *constant = llvm::dyn_cast<llvm::ConstantAggregate>(instruction->getOperand(2));\n\t\t\tif (!constant || constant->getType()->getTypeID() != llvm::Type::TypeID::StructTyID ||\n\t\t\t    constant->getNumOperands() != 2)\n\t\t\t{\n\t\t\t\tLOGE(\"AnnotateHandle takes a ConstantAggregate.\\n\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tuint32_t type = constant->getOperand(0)->getUniqueInteger().getZExtValue();\n\t\t\tuint32_t params = constant->getOperand(1)->getUniqueInteger().getZExtValue();\n\n\t\t\t// The encoding here is very ... peculiar.\n\t\t\tconstexpr uint32_t AnnotateUAVMask = 1u << 12;\n\t\t\tconstexpr uint32_t AnnotateROVMask = 1u << 13;\n\t\t\tconstexpr uint32_t AnnotateGloballyCoherentMask = 1u << 14;\n\t\t\tconstexpr uint32_t AnnotateCounterMask = 1u << 15;\n\t\t\tuse.resource_kind = DXIL::ResourceKind(type & 0xff);\n\t\t\tswitch (use.resource_kind)\n\t\t\t{\n\t\t\tcase DXIL::ResourceKind::CBuffer:\n\t\t\t\tuse.resource_type = DXIL::ResourceType::CBV;\n\t\t\t\tbreak;\n\n\t\t\tcase DXIL::ResourceKind::Sampler:\n\t\t\t\tuse.resource_type = DXIL::ResourceType::Sampler;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tuse.resource_type = (type & AnnotateUAVMask) != 0 ? DXIL::ResourceType::UAV : DXIL::ResourceType::SRV;\n\t\t\t\tuse.coherent = (type & AnnotateGloballyCoherentMask) != 0;\n\t\t\t\tuse.rov = (type & AnnotateROVMask) != 0;\n\t\t\t\tuse.counter = (type & AnnotateCounterMask) != 0;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (use.resource_kind == DXIL::ResourceKind::StructuredBuffer)\n\t\t\t\tuse.stride = params;\n\t\t\telse if (use.resource_kind != DXIL::ResourceKind::RawBuffer &&\n\t\t\t         use.resource_kind != DXIL::ResourceKind::CBuffer)\n\t\t\t\tuse.component_type = DXIL::ComponentType(params & 0xff);\n\t\t}\n\t\telse if (meta.resource_op == DXIL::Op::CreateHandleFromBinding ||\n\t\t         meta.resource_op == DXIL::Op::CreateHandleForLib)\n\t\t{\n\t\t\tif (meta.resource_type == DXIL::ResourceType::UAV)\n\t\t\t\timpl.llvm_value_to_uav_resource_index_map[instruction] = meta.binding_index;\n\t\t\telse if (meta.resource_type == DXIL::ResourceType::SRV)\n\t\t\t\timpl.llvm_value_to_srv_resource_index_map[instruction] = meta.binding_index;\n\t\t\telse if (meta.resource_type == DXIL::ResourceType::CBV)\n\t\t\t\timpl.llvm_value_to_cbv_resource_index_map[instruction] = meta.binding_index;\n\t\t}\n\n\t\tif (impl.options.descriptor_qa_enabled && impl.options.descriptor_qa_sink_handles)\n\t\t\timpl.resource_handle_to_block[instruction] = bb;\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::TextureLoad:\n\t\tanalyze_dxil_buffer_load(impl, instruction, op);\n\t\tbreak;\n\n\tcase DXIL::Op::TextureStore:\n\tcase DXIL::Op::TextureStoreSample:\n\t\tanalyze_dxil_buffer_store(impl, instruction, op);\n\t\tbreak;\n\n\tcase DXIL::Op::CBufferLoad:\n\tcase DXIL::Op::CBufferLoadLegacy:\n\t\tanalyze_dxil_cbuffer_load(impl, instruction);\n\t\tbreak;\n\n\tcase DXIL::Op::BufferUpdateCounter:\n\t{\n\t\tif (nvapi_buffer_update_counter_filter(impl, instruction))\n\t\t\tbreak;\n\t\timpl.llvm_values_using_update_counter.insert(instruction->getOperand(1));\n\t\timpl.shader_analysis.has_side_effects = true;\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::ReportHit:\n\t{\n\t\tauto *payload = instruction->getOperand(3);\n\t\tauto *type = payload->getType();\n\t\tif (impl.llvm_hit_attribute_output_type && impl.llvm_hit_attribute_output_type != type)\n\t\t{\n\t\t\tLOGE(\"Hit attribute types must match.\\n\");\n\t\t\treturn false;\n\t\t}\n\t\timpl.llvm_hit_attribute_output_type = type;\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::Discard:\n\t\timpl.shader_analysis.discards = true;\n\t\tbreak;\n\n\tcase DXIL::Op::AttributeAtVertex:\n\t{\n\t\t// If this is used, promote a vertex input to PerVertex.\n\t\tuint32_t input_sig_index = 0;\n\t\tif (!get_constant_operand(instruction, 1, &input_sig_index))\n\t\t\treturn false;\n\t\timpl.llvm_attribute_at_vertex_indices.insert(input_sig_index);\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::ExtendedCalculateLOD:\n\tcase DXIL::Op::ExtendedDeriv:\n\tcase DXIL::Op::DerivCoarseX:\n\tcase DXIL::Op::DerivCoarseY:\n\tcase DXIL::Op::DerivFineX:\n\tcase DXIL::Op::DerivFineY:\n\tcase DXIL::Op::CalculateLOD:\n\tcase DXIL::Op::SampleBias:\n\tcase DXIL::Op::Sample:\n\tcase DXIL::Op::SampleCmp:\n\tcase DXIL::Op::SampleCmpBias:\n\t\tif (impl.execution_model == spv::ExecutionModelGLCompute ||\n\t\t    impl.execution_model == spv::ExecutionModelTaskEXT ||\n\t\t    impl.execution_model == spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\t// We're trying to do shader derivatives outside fragment, uh oh.\n\t\t\t// Also, we need to map 4 lanes to invocation IDs.\n\t\t\t// Either, we will set up a 1D mapping with ComputeDerivativeGroupLinearNV and run the code as-is,\n\t\t\t// or we run with LinearNV, but rewrite the thread IDs to fake 2D grouping.\n\t\t\t// We could rely on QuadNV here, but it's not widely supported.\n\t\t\timpl.shader_analysis.require_compute_shader_derivatives = true;\n\t\t}\n\t\telse if (impl.options.instruction_instrumentation.enabled &&\n\t\t         impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume &&\n\t\t         impl.execution_model == spv::ExecutionModelFragment)\n\t\t{\n\t\t\timpl.shader_analysis.need_maximal_reconvergence_helper_call = true;\n\t\t}\n\t\tbreak;\n\n\tcase DXIL::Op::WaveIsFirstLane:\n\tcase DXIL::Op::WaveGetLaneIndex:\n\tcase DXIL::Op::WaveGetLaneCount:\n\tcase DXIL::Op::WaveAnyTrue:\n\tcase DXIL::Op::WaveAllTrue:\n\tcase DXIL::Op::WaveActiveAllEqual:\n\tcase DXIL::Op::WaveActiveBallot:\n\tcase DXIL::Op::WaveReadLaneAt:\n\tcase DXIL::Op::WaveReadLaneFirst:\n\tcase DXIL::Op::WaveActiveOp:\n\tcase DXIL::Op::WaveActiveBit:\n\tcase DXIL::Op::WavePrefixOp:\n\tcase DXIL::Op::WaveAllBitCount:\n\tcase DXIL::Op::WavePrefixBitCount:\n\t\timpl.shader_analysis.require_subgroups = true;\n\t\tbreak;\n\n\tcase DXIL::Op::QuadOp:\n\tcase DXIL::Op::QuadVote:\n\tcase DXIL::Op::QuadReadLaneAt:\n\t\tif (impl.execution_model == spv::ExecutionModelGLCompute ||\n\t\t    impl.execution_model == spv::ExecutionModelTaskEXT ||\n\t\t    impl.execution_model == spv::ExecutionModelMeshEXT)\n\t\t{\n\t\t\tuint32_t sm_major = 0, sm_minor = 0;\n\t\t\tConverter::Impl::get_shader_model(impl.bitcode_parser.get_module(), nullptr, &sm_major, &sm_minor);\n\t\t\tif (sm_major * 1000 + sm_minor >= 6006)\n\t\t\t{\n\t\t\t\t// In SM 6.6, the semantics of quad ops in compute changes.\n\t\t\t\t// They follow compute shader derivative rules,\n\t\t\t\t// where they might be 1D or 2D based on workgroup size.\n\t\t\t\timpl.shader_analysis.require_compute_shader_derivatives = true;\n\t\t\t}\n\t\t}\n\n\t\timpl.shader_analysis.require_subgroups = true;\n\t\tbreak;\n\n\tcase DXIL::Op::LegacyF16ToF32:\n\t\t// Very specific check for HZD invariance. See f32_to_f16 code for details.\n\t\tif (instruction->hasMetadata(\"dx.precise\") || impl.options.force_precise)\n\t\t\timpl.shader_analysis.precise_f16_to_f32_observed = true;\n\t\tbreak;\n\n\tcase DXIL::Op::DispatchMesh:\n\t\timpl.handle_to_storage_class[instruction->getOperand(4)] = spv::StorageClassTaskPayloadWorkgroupEXT;\n\t\tbreak;\n\n\tcase DXIL::Op::Barrier:\n\t{\n\t\tuint32_t operation;\n\t\tif (!get_constant_operand(instruction, 1, &operation))\n\t\t\treturn false;\n\n\t\t// See D3D11 functional spec: 7.14.4 Global vs Group/Local Coherency on Non-Atomic UAV Reads.\n\t\t// In the GLSL memory model, we need coherent between invocations in general.\n\t\t// There is no guarantee for intra-workgroup coherence sadly :(\n\t\tif ((operation & (DXIL::AccessUAVThreadGroup | DXIL::AccessUAVGlobal)) != 0)\n\t\t\timpl.shader_analysis.require_uav_thread_group_coherence = true;\n\t\tif ((operation & DXIL::AccessGroupShared) != 0)\n\t\t{\n\t\t\timpl.shader_analysis.has_group_shared_barrier = true;\n\t\t\tif (impl.options.quirks.promote_group_to_device_memory_barrier)\n\t\t\t\timpl.shader_analysis.require_uav_thread_group_coherence = true;\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::BarrierByMemoryType:\n\t{\n\t\tuint32_t memory_flags = 0;\n\t\tuint32_t semantic_flags = 0;\n\t\tif (!get_constant_operand(instruction, 1, &memory_flags))\n\t\t\treturn false;\n\t\tif (!get_constant_operand(instruction, 2, &semantic_flags))\n\t\t\treturn false;\n\n\t\tif ((semantic_flags & DXIL::GroupScopeBit) != 0)\n\t\t{\n\t\t\t// Similar. If we observe a UAV + Group barrier, we need to consider coherence for any UAV.\n\t\t\t// For DeviceScope bit, shader already needs to declare with globallycoherent for that to work.\n\t\t\tif ((memory_flags & DXIL::MemoryTypeUavBit) != 0)\n\t\t\t\timpl.shader_analysis.require_uav_thread_group_coherence = true;\n\t\t\tif ((memory_flags & DXIL::MemoryTypeNodeOutputBit) != 0)\n\t\t\t\timpl.shader_analysis.require_node_output_group_coherence = true;\n\t\t\tif ((memory_flags & DXIL::MemoryTypeNodeInputBit) != 0)\n\t\t\t\timpl.shader_analysis.require_node_input_group_coherence = true;\n\t\t\tif ((memory_flags & DXIL::MemoryTypeGroupSharedBit) != 0)\n\t\t\t{\n\t\t\t\timpl.shader_analysis.has_group_shared_barrier = true;\n\t\t\t\tif (impl.options.quirks.promote_group_to_device_memory_barrier)\n\t\t\t\t\timpl.shader_analysis.require_uav_thread_group_coherence = true;\n\t\t\t}\n\t\t}\n\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::BarrierByNodeRecordHandle:\n\t{\n\t\tuint32_t semantics = 0;\n\t\tif (!get_constant_operand(instruction, 2, &semantics))\n\t\t\treturn false;\n\n\t\tif ((semantics & DXIL::GroupScopeBit) != 0)\n\t\t{\n\t\t\tif (!value_is_dx_op_instrinsic(instruction->getOperand(1), DXIL::Op::AnnotateNodeRecordHandle))\n\t\t\t\treturn false;\n\n\t\t\tauto *annotation = llvm::cast<llvm::CallInst>(instruction->getOperand(1));\n\t\t\tuint32_t node_io = get_node_io_from_annotate_handle(annotation);\n\n\t\t\t// If the resource isn't declared as globally coherent, promote.\n\t\t\t// TODO: Could promote on a per-node basis, but seems overkill for now.\n\t\t\tif ((node_io & DXIL::NodeIOGloballyCoherentBit) == 0)\n\t\t\t{\n\t\t\t\tif ((node_io & DXIL::NodeIOInputBit) != 0)\n\t\t\t\t\timpl.shader_analysis.require_node_input_group_coherence = true;\n\t\t\t\telse if ((node_io & DXIL::NodeIOOutputBit) != 0)\n\t\t\t\t\timpl.shader_analysis.require_node_output_group_coherence = true;\n\t\t\t}\n\t\t}\n\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::BarrierByMemoryHandle:\n\t{\n\t\tuint32_t semantics = 0;\n\t\tif (!get_constant_operand(instruction, 2, &semantics))\n\t\t\treturn false;\n\n\t\tif ((semantics & DXIL::GroupScopeBit) != 0)\n\t\t{\n\t\t\tif (!value_is_dx_op_instrinsic(instruction->getOperand(1), DXIL::Op::AnnotateHandle))\n\t\t\t\treturn false;\n\n\t\t\tauto *annotation = llvm::cast<llvm::CallInst>(instruction->getOperand(1));\n\t\t\tauto *aggregate = llvm::cast<llvm::ConstantAggregate>(annotation->getOperand(2));\n\n\t\t\tuint32_t type = aggregate->getOperand(0)->getUniqueInteger().getZExtValue();\n\t\t\tconstexpr uint32_t AnnotateUAVMask = 1u << 12;\n\t\t\tconstexpr uint32_t AnnotateGloballyCoherentMask = 1u << 14;\n\n\t\t\t// If the resource isn't declared as globally coherent, promote.\n\t\t\t// TODO: Could promote on a per-resource basis, but seems overkill for now.\n\t\t\tif ((type & AnnotateUAVMask) != 0 && (type & AnnotateGloballyCoherentMask) == 0)\n\t\t\t\timpl.shader_analysis.require_uav_thread_group_coherence = true;\n\t\t}\n\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::AllocateNodeOutputRecords:\n\t{\n\t\tuint32_t is_per_thread = 0;\n\t\t// Per-thread allocator needs careful subgroup operations in potential control flow.\n\t\tif (get_constant_operand(instruction, 2, &is_per_thread) && is_per_thread)\n\t\t\timpl.shader_analysis.need_maximal_reconvergence_helper_call = true;\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::AtomicCompareExchange:\n\t\tif (!analyze_ags_dxil_cmpxchg_op(impl, instruction))\n\t\t\treturn false;\n\t\tbreak;\n\n\tcase DXIL::Op::RayQuery_TraceRayInline:\n\t{\n\t\t// Any ray query object being used must be initialized first with TraceRayInline,\n\t\t// so there isn't much point in testing every instruction.\n\n\t\t// If every TraceRayInline uses the same handle value, we can collapse all ray query\n\t\t// object allocations into one, since there cannot be concurrent, valid instances in flight.\n\t\tauto *object = instruction->getOperand(1);\n\n\t\tif (impl.shader_analysis.ray_query.reference_handle_value &&\n\t\t\timpl.shader_analysis.ray_query.reference_handle_value != object)\n\t\t{\n\t\t\timpl.shader_analysis.ray_query.uses_divergent_handles = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\timpl.shader_analysis.ray_query.reference_handle_value = object;\n\t\t}\n\n\t\tif (!value_is_dx_op_instrinsic(object, DXIL::Op::AllocateRayQuery))\n\t\t\timpl.shader_analysis.ray_query.uses_non_direct_indexing = true;\n\n\t\tbreak;\n\t}\n\n\tcase DXIL::Op::AllocateRayQuery:\n\t\t// If we have to do worst-case allocation.\n\t\timpl.shader_analysis.ray_query.num_ray_query_alloca++;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn true;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/opcodes_dxil_builtins.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"opcodes.hpp\"\n\nnamespace dxil_spv\n{\nusing DXILOperationBuilder = bool (*)(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool emit_dxil_instruction(Converter::Impl &impl, const llvm::CallInst *instruction);\nbool dxil_instruction_has_side_effects(const llvm::CallInst *instruction);\n\nbool analyze_dxil_instruction_primary_pass(Converter::Impl &impl, const llvm::CallInst *instruction, const llvm::BasicBlock *bb);\nbool analyze_dxil_instruction_secondary_pass(Converter::Impl &impl, const llvm::CallInst *instruction);\n\nstruct AllocaCBVForwardingTracking;\nbool analyze_alloca_cbv_forwarding_pre_resource_emit(Converter::Impl &impl,\n                                                     const llvm::Type *scalar_type,\n                                                     AllocaCBVForwardingTracking &tracking);\nbool analyze_alloca_cbv_forwarding_post_resource_emit(Converter::Impl &impl, AllocaCBVForwardingTracking &tracking);\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/opcodes_llvm_builtins.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"opcodes_llvm_builtins.hpp\"\n#include \"converter_impl.hpp\"\n#include \"logging.hpp\"\n#include \"spirv_module.hpp\"\n#include \"dxil/dxil_common.hpp\"\n#include \"dxil/dxil_resources.hpp\"\n#include \"dxil/dxil_arithmetic.hpp\"\n#include \"dxil/dxil_ags.hpp\"\n#include <limits>\n\nnamespace dxil_spv\n{\nunsigned physical_integer_bit_width(unsigned width)\n{\n\tswitch (width)\n\t{\n\tcase 1:\n\tcase 8:\n\tcase 16:\n\tcase 32:\n\tcase 64:\n\t\treturn width;\n\n\tdefault:\n\t\treturn width <= 32 ? 32 : 64;\n\t}\n}\n\nstatic bool instruction_is_ballot(const llvm::Value *aggregate)\n{\n\tif (const auto *call_inst = llvm::dyn_cast<llvm::CallInst>(aggregate))\n\t{\n\t\tauto *called_function = call_inst->getCalledFunction();\n\t\tif (strncmp(called_function->getName().data(), \"dx.op\", 5) == 0)\n\t\t{\n\t\t\tauto *constant = llvm::dyn_cast<llvm::ConstantInt>(call_inst->getOperand(0));\n\t\t\tif (constant)\n\t\t\t{\n\t\t\t\tauto elem = constant->getUniqueInteger().getZExtValue();\n\t\t\t\treturn static_cast<DXIL::Op>(elem) == DXIL::Op::WaveActiveBallot;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic spv::Id build_naturally_extended_value(Converter::Impl &impl, const llvm::Value *value,\n                                              unsigned bits, bool is_signed)\n{\n\tspv::Id id = impl.get_id_for_value(value);\n\tif (value->getType()->getTypeID() != llvm::Type::TypeID::IntegerTyID)\n\t\treturn id;\n\n\tauto logical_bits = value->getType()->getIntegerBitWidth();\n\tauto physical_bits = physical_integer_bit_width(logical_bits);\n\n\tif (bits == 0)\n\t\tbits = logical_bits;\n\tif (bits == physical_bits)\n\t\treturn id;\n\n\tauto &builder = impl.builder();\n\tauto *mask_op = impl.allocate(is_signed ? spv::OpBitFieldSExtract : spv::OpBitFieldUExtract,\n\t                              impl.get_type_id(value->getType()));\n\tmask_op->add_id(id);\n\tmask_op->add_id(builder.makeUintConstant(0));\n\tmask_op->add_id(builder.makeUintConstant(bits));\n\timpl.add(mask_op);\n\treturn mask_op->id;\n}\n\nstatic spv::Id build_naturally_extended_value(Converter::Impl &impl, const llvm::Value *value, bool is_signed)\n{\n\tspv::Id id = impl.get_id_for_value(value);\n\tif (value->getType()->getTypeID() != llvm::Type::TypeID::IntegerTyID)\n\t\treturn id;\n\n\tauto logical_bits = value->getType()->getIntegerBitWidth();\n\treturn build_naturally_extended_value(impl, value, logical_bits, is_signed);\n}\n\nstatic spv::Id emit_fixup_fdiv_sqrt(Converter::Impl &, const llvm::ConstantExpr *)\n{\n\treturn 0;\n}\n\nstatic spv::Id emit_fixup_fdiv_sqrt(Converter::Impl &impl, const llvm::BinaryOperator *instruction)\n{\n\t// Only peephole fast math.\n\tif (!instruction->isFast() || impl.options.force_precise || !impl.options.quirks.fixup_rsqrt)\n\t\treturn 0;\n\n\t// Only consider normal FP32 floats for simplicity since this is just a workaround.\n\tif (instruction->getType()->getTypeID() != llvm::Type::TypeID::FloatTyID)\n\t\treturn 0;\n\n\tif (value_is_dx_op_instrinsic(instruction->getOperand(1), DXIL::Op::Sqrt))\n\t{\n\t\tauto *sqrt_op = llvm::cast<llvm::CallInst>(instruction->getOperand(1));\n\t\tif (sqrt_op->hasMetadata(\"dx.precise\"))\n\t\t\treturn 0;\n\n\t\tauto *sqrt_input = sqrt_op->getOperand(1);\n\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = impl.builder().import(\"GLSL.std.450\");\n\n\t\tspv::Id input_id = impl.get_id_for_value(sqrt_input);\n\t\tspv::Id inv_sqrt_id = 0;\n\n\t\tfor (auto &transform : impl.peephole_transformation_cache)\n\t\t{\n\t\t\tif (transform.input_id == input_id && transform.key == GLSLstd450InverseSqrt)\n\t\t\t{\n\t\t\t\tinv_sqrt_id = transform.result_id;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (inv_sqrt_id == 0)\n\t\t{\n\t\t\tauto *inv_sqrt = impl.allocate(spv::OpExtInst, impl.get_type_id(instruction->getType()));\n\t\t\tinv_sqrt->add_id(impl.glsl_std450_ext);\n\t\t\tinv_sqrt->add_literal(GLSLstd450InverseSqrt);\n\t\t\tinv_sqrt->add_id(impl.get_id_for_value(sqrt_input));\n\t\t\timpl.add(inv_sqrt);\n\n\t\t\tauto *clamp = impl.allocate(spv::OpExtInst, impl.get_type_id(instruction->getType()));\n\t\t\tclamp->add_id(impl.glsl_std450_ext);\n\t\t\tclamp->add_literal(GLSLstd450NMin);\n\t\t\tclamp->add_id(inv_sqrt->id);\n\t\t\tclamp->add_id(impl.builder().makeFloatConstant(std::numeric_limits<float>::max()));\n\t\t\timpl.add(clamp);\n\n\t\t\tinv_sqrt_id = clamp->id;\n\t\t\timpl.peephole_transformation_cache.push_back({ input_id, inv_sqrt_id, GLSLstd450InverseSqrt });\n\t\t}\n\n\t\tauto *mul = impl.allocate(spv::OpFMul, instruction);\n\t\tmul->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\t\tmul->add_id(inv_sqrt_id);\n\t\timpl.add(mul);\n\n\t\treturn mul->id;\n\t}\n\n\treturn 0;\n}\n\nstatic spv::Id peephole_trivial_arithmetic_identity(Converter::Impl &,\n                                                    const llvm::ConstantExpr *,\n                                                    llvm::BinaryOperator::BinaryOps,\n                                                    bool)\n{\n\treturn 0;\n}\n\nstatic spv::Id peephole_trivial_arithmetic_identity(Converter::Impl &impl,\n                                                    const llvm::BinaryOperator *instruction,\n                                                    llvm::BinaryOperator::BinaryOps inverse_operation,\n                                                    bool is_commutative)\n{\n\t// Only peephole fast math.\n\tif (!instruction->isFast() || impl.options.force_precise)\n\t\treturn 0;\n\n\t// CP77 can trigger a scenario where we do (a / b) * b in fast math.\n\t// When b is 0, we hit a singularity, but native drivers optimize this away.\n\tauto *op0 = instruction->getOperand(0);\n\tauto *op1 = instruction->getOperand(1);\n\n\t// This is the case for mul/div or add/sub.\n\tbool counter_op_is_commutative = !is_commutative;\n\n\t// Current expression is op(op0, op1)\n\t// Find pattern where we have one of 4 cases:\n\t// - c = F(a, F^-1(c, a)) // F = fmul -> is_commutative\n\t// - c = F(F^-1(c, b), b) // F = fmul -> is_commutative\n\t// - c = F(F^-1(c, b), b) // F = fdiv -> !is_commutative\n\t// - c = F(F^-1(b, c), b) // F = fdiv -> !is_commutative\n\n\tconst auto hoist_value = [&](llvm::BinaryOperator *binop, llvm::Value *inverse_value) -> bool {\n\t\tauto *cancel_op0 = binop->getOperand(0);\n\t\tauto *cancel_op1 = binop->getOperand(1);\n\t\tif (counter_op_is_commutative && cancel_op0 == inverse_value)\n\t\t{\n\t\t\t// op0 is canceled by outer expression, so we're left with op1.\n\t\t\timpl.rewrite_value(instruction, impl.get_id_for_value(cancel_op1));\n\t\t\treturn true;\n\t\t}\n\t\telse if (cancel_op1 == inverse_value)\n\t\t{\n\t\t\t// op1 is canceled by outer expression, so we're left with op0.\n\t\t\timpl.rewrite_value(instruction, impl.get_id_for_value(cancel_op0));\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t};\n\n\tif (auto *binop = llvm::dyn_cast<llvm::BinaryOperator>(op0))\n\t\tif (binop->isFast() && binop->getOpcode() == inverse_operation && hoist_value(binop, op1))\n\t\t\treturn impl.get_id_for_value(instruction);\n\n\tif (is_commutative)\n\t\tif (auto *binop = llvm::dyn_cast<llvm::BinaryOperator>(op1))\n\t\t\tif (binop->isFast() && binop->getOpcode() == inverse_operation && hoist_value(binop, op0))\n\t\t\t\treturn impl.get_id_for_value(instruction);\n\n\treturn 0;\n}\n\nstatic spv::Id resolve_llvm_actual_value_type(Converter::Impl &impl,\n                                              const llvm::Value *dependent_value,\n                                              const llvm::Value *value, spv::Id default_value_type)\n{\n\tauto itr = impl.llvm_value_actual_type.find(value);\n\tif (itr != impl.llvm_value_actual_type.end())\n\t{\n\t\tif (dependent_value)\n\t\t{\n\t\t\t// Forward the remapped type as required.\n\t\t\timpl.llvm_value_actual_type[dependent_value] = itr->second;\n\t\t}\n\t\treturn itr->second;\n\t}\n\telse\n\t\treturn default_value_type;\n}\n\nstatic bool instruction_is_fast_math(const llvm::BinaryOperator *op)\n{\n\treturn op->isFast();\n}\n\nstatic bool instruction_is_fast_math(const llvm::ConstantExpr *)\n{\n\t// Don't want reordering in constant folding anyways.\n\treturn false;\n}\n\nstatic bool instruction_is_undefined_value(const llvm::Value *value)\n{\n\tif (llvm::isa<llvm::UndefValue>(value))\n\t{\n\t\treturn true;\n\t}\n\telse if (const auto *cexpr = llvm::dyn_cast<llvm::ConstantExpr>(value))\n\t{\n\t\treturn instruction_is_undefined_value(cexpr->getOperand(0)) &&\n\t\t       instruction_is_undefined_value(cexpr->getOperand(1));\n\t}\n\telse if (const auto *expr = llvm::dyn_cast<llvm::BinaryOperator>(value))\n\t{\n\t\treturn instruction_is_undefined_value(expr->getOperand(0)) &&\n\t\t       instruction_is_undefined_value(expr->getOperand(1));\n\t}\n\telse\n\t\treturn false;\n}\n\ntemplate <typename T>\nbool can_optimize_to_snegate_inner(const T *instruction)\n{\n\tif (instruction->getOpcode() != llvm::BinaryOperator::BinaryOps::Sub)\n\t\treturn false;\n\n\t// Peephole. LLVM doesn't have concept of negation apparently ...\n\tif (const auto *cint = llvm::dyn_cast<llvm::ConstantInt>(instruction->getOperand(0)))\n\t\treturn cint->getUniqueInteger().getZExtValue() == 0;\n\treturn false;\n}\n\nbool can_optimize_to_snegate(const llvm::BinaryOperator *instruction)\n{\n\treturn can_optimize_to_snegate_inner(instruction);\n}\n\nbool can_optimize_to_snegate(const llvm::ConstantExpr *instruction)\n{\n\treturn can_optimize_to_snegate_inner(instruction);\n}\n\nstatic bool constant_is_all_bits_set(llvm::Value *v)\n{\n\tif (auto *vec = llvm::dyn_cast<llvm::ConstantDataVector>(v))\n\t{\n\t\tfor (unsigned i = 0; i < vec->getNumElements(); i++)\n\t\t\tif (!constant_is_all_bits_set(vec->getElementAsConstant(i)))\n\t\t\t\treturn false;\n\n\t\treturn true;\n\t}\n\telse if (const auto *c = llvm::dyn_cast<llvm::ConstantInt>(v))\n\t{\n\t\tuint64_t mask;\n\t\tif (c->getType()->getIntegerBitWidth() == 64)\n\t\t\tmask = UINT64_MAX;\n\t\telse\n\t\t\tmask = (1ull << c->getType()->getIntegerBitWidth()) - 1ull;\n\n\t\treturn (c->getUniqueInteger().getZExtValue() & mask) == mask;\n\t}\n\telse\n\t\treturn false;\n}\n\nstatic llvm::Value *get_bitwise_not_from_xor(llvm::Value *a, llvm::Value *b)\n{\n\tif (constant_is_all_bits_set(a))\n\t\treturn b;\n\telse if (constant_is_all_bits_set(b))\n\t\treturn a;\n\telse\n\t\treturn nullptr;\n}\n\ntemplate <typename InstructionType>\nstatic spv::Id emit_binary_instruction_impl(Converter::Impl &impl, const InstructionType *instruction)\n{\n\tbool signed_input = false;\n\tbool is_width_sensitive = false;\n\tbool is_precision_sensitive = false;\n\tbool can_relax_precision = false;\n\tspv::Op opcode;\n\n\tauto *type = instruction->getType();\n\tif (const auto *vec = llvm::dyn_cast<llvm::VectorType>(type))\n\t\ttype = vec->getElementType();\n\n\tswitch (llvm::Instruction::BinaryOps(instruction->getOpcode()))\n\t{\n\tcase llvm::BinaryOperator::BinaryOps::FAdd:\n\t\topcode = spv::OpFAdd;\n\t\tis_precision_sensitive = true;\n\t\tcan_relax_precision = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::FSub:\n\t\topcode = spv::OpFSub;\n\t\tis_precision_sensitive = true;\n\t\tcan_relax_precision = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::FMul:\n\t{\n\t\topcode = spv::OpFMul;\n\t\tis_precision_sensitive = true;\n\t\tcan_relax_precision = true;\n\t\tif (spv::Id id = peephole_trivial_arithmetic_identity(impl, instruction, llvm::BinaryOperator::BinaryOps::FDiv, true))\n\t\t\treturn id;\n\t\tbreak;\n\t}\n\n\tcase llvm::BinaryOperator::BinaryOps::FDiv:\n\t\topcode = spv::OpFDiv;\n\t\tis_precision_sensitive = true;\n\t\tcan_relax_precision = true;\n\t\tif (spv::Id id = peephole_trivial_arithmetic_identity(impl, instruction, llvm::BinaryOperator::BinaryOps::FMul, false))\n\t\t\treturn id;\n\t\tif (spv::Id id = emit_fixup_fdiv_sqrt(impl, instruction))\n\t\t\treturn id;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::Add:\n\t\topcode = spv::OpIAdd;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::Sub:\n\t{\n\t\t// Peephole. LLVM doesn't have concept of negation apparently ...\n\t\tif (can_optimize_to_snegate(instruction))\n\t\t{\n\t\t\tauto op = impl.allocate(spv::OpSNegate, instruction);\n\t\t\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\t\timpl.add(op);\n\t\t\treturn op->id;\n\t\t}\n\n\t\topcode = spv::OpISub;\n\t\tbreak;\n\t}\n\n\tcase llvm::BinaryOperator::BinaryOps::Mul:\n\t\topcode = spv::OpIMul;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::SDiv:\n\t\topcode = spv::OpSDiv;\n\t\tsigned_input = true;\n\t\tis_width_sensitive = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::UDiv:\n\t\topcode = spv::OpUDiv;\n\t\tis_width_sensitive = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::Shl:\n\t\topcode = spv::OpShiftLeftLogical;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::LShr:\n\t\topcode = spv::OpShiftRightLogical;\n\t\tis_width_sensitive = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::AShr:\n\t\topcode = spv::OpShiftRightArithmetic;\n\t\tsigned_input = true;\n\t\tis_width_sensitive = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::SRem:\n\t\topcode = spv::OpSRem;\n\t\tsigned_input = true;\n\t\tis_width_sensitive = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::FRem:\n\t\topcode = spv::OpFRem;\n\t\tis_precision_sensitive = true;\n\t\tcan_relax_precision = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::URem:\n\t\t// Is this correct? There is no URem.\n\t\topcode = spv::OpUMod;\n\t\tis_width_sensitive = true;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::Xor:\n\t\t// Logical not in LLVM IR is encoded as XOR i1 against true.\n\t\tif (const auto *not_value = get_bitwise_not_from_xor(instruction->getOperand(0), instruction->getOperand(1)))\n\t\t{\n\t\t\tspv::Id not_id = impl.get_id_for_value(not_value);\n\t\t\topcode = type->getIntegerBitWidth() == 1 ? spv::OpLogicalNot : spv::OpNot;\n\n\t\t\tOperation *op;\n\t\t\tif (llvm::isa<llvm::ConstantExpr>(instruction))\n\t\t\t\top = impl.allocate(opcode, impl.get_type_id(instruction->getType()));\n\t\t\telse\n\t\t\t\top = impl.allocate(opcode, instruction);\n\n\t\t\top->add_id(not_id);\n\t\t\timpl.add(op);\n\t\t\treturn op->id;\n\t\t}\n\n\t\topcode = type->getIntegerBitWidth() == 1 ? spv::OpLogicalNotEqual : spv::OpBitwiseXor;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::And:\n\t\tif (type->getIntegerBitWidth() == 1)\n\t\t\topcode = spv::OpLogicalAnd;\n\t\telse\n\t\t\topcode = spv::OpBitwiseAnd;\n\t\tbreak;\n\n\tcase llvm::BinaryOperator::BinaryOps::Or:\n\t\tif (type->getIntegerBitWidth() == 1)\n\t\t\topcode = spv::OpLogicalOr;\n\t\telse\n\t\t\topcode = spv::OpBitwiseOr;\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unknown binary operator.\\n\");\n\t\treturn false;\n\t}\n\n\t// If we can collapse the expression to undefined (yes, DXIL really emits jank like this!),\n\t// just emit the non-undefined part.\n\t// We can consider the value to be undefined in a way that it is irrelevant.\n\n\t// Here we make the assumption that undef is not frozen to a fixed but indeterminate value,\n\t// it can take different values when it's instantiated.\n\tbool a_is_undef = instruction_is_undefined_value(instruction->getOperand(0));\n\tbool b_is_undef = instruction_is_undefined_value(instruction->getOperand(1));\n\tspv::Id forward_value = 0;\n\tif (b_is_undef)\n\t\tforward_value = impl.get_id_for_value(instruction->getOperand(0));\n\telse if (a_is_undef)\n\t\tforward_value = impl.get_id_for_value(instruction->getOperand(1));\n\n\tOperation *op;\n\tif (llvm::isa<llvm::ConstantExpr>(instruction))\n\t{\n\t\tif (forward_value != 0)\n\t\t\treturn forward_value;\n\n\t\top = impl.allocate(opcode, impl.get_type_id(instruction->getType()));\n\t}\n\telse if (forward_value != 0)\n\t{\n\t\timpl.rewrite_value(instruction, forward_value);\n\t\treturn forward_value;\n\t}\n\telse\n\t{\n\t\top = impl.allocate(opcode, instruction);\n\t}\n\n\tuint32_t id0, id1;\n\tif (is_width_sensitive)\n\t{\n\t\tid0 = build_naturally_extended_value(impl, instruction->getOperand(0), signed_input);\n\t\tid1 = build_naturally_extended_value(impl, instruction->getOperand(1), signed_input);\n\t}\n\telse\n\t{\n\t\tid0 = impl.get_id_for_value(instruction->getOperand(0));\n\t\tid1 = impl.get_id_for_value(instruction->getOperand(1));\n\t}\n\top->add_ids({ id0, id1 });\n\n\timpl.add(op);\n\tif (is_precision_sensitive && (impl.options.force_precise || !instruction_is_fast_math(instruction)))\n\t\timpl.builder().addDecoration(op->id, spv::DecorationNoContraction);\n\n\t// Only bother relaxing FP, since Integers are murky w.r.t. signage in DXIL.\n\tif (can_relax_precision)\n\t\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\n\treturn op->id;\n}\n\nbool emit_binary_instruction(Converter::Impl &impl, const llvm::BinaryOperator *instruction)\n{\n\treturn emit_binary_instruction_impl(impl, instruction) != 0;\n}\n\nbool emit_unary_instruction(Converter::Impl &impl, const llvm::UnaryOperator *instruction)\n{\n\tspv::Op opcode;\n\n\tswitch (instruction->getOpcode())\n\t{\n\tcase llvm::UnaryOperator::UnaryOps::FNeg:\n\t\topcode = spv::OpFNegate;\n\t\tbreak;\n\n#ifdef HAVE_LLVMBC\n\tcase llvm::UnaryOperator::UnaryOps::INeg:\n\t\topcode = spv::OpSNegate;\n\t\tbreak;\n#endif\n\n\tdefault:\n\t\tLOGE(\"Unknown unary operator.\\n\");\n\t\treturn false;\n\t}\n\n\tOperation *op = impl.allocate(opcode, instruction);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\n\timpl.add(op);\n\treturn true;\n}\n\ntemplate <typename InstructionType>\nstatic spv::Id emit_boolean_trunc_instruction(Converter::Impl &impl, const InstructionType *instruction)\n{\n\tauto &builder = impl.builder();\n\tOperation *op = impl.allocate(spv::OpINotEqual, instruction);\n\top->add_id(build_naturally_extended_value(impl, instruction->getOperand(0), false));\n\n\tunsigned physical_width = physical_integer_bit_width(instruction->getOperand(0)->getType()->getIntegerBitWidth());\n\n\tswitch (physical_width)\n\t{\n\tcase 16:\n\t\top->add_id(builder.makeUint16Constant(0));\n\t\tbreak;\n\n\tcase 32:\n\t\top->add_id(builder.makeUintConstant(0));\n\t\tbreak;\n\n\tcase 64:\n\t\top->add_id(builder.makeUint64Constant(0));\n\t\tbreak;\n\n\tdefault:\n\t\treturn 0;\n\t}\n\n\timpl.add(op);\n\treturn op->id;\n}\n\ntemplate <typename InstructionType>\nstatic spv::Id emit_boolean_convert_instruction(Converter::Impl &impl, const InstructionType *instruction, bool is_signed)\n{\n\tauto &builder = impl.builder();\n\tspv::Id const_0;\n\tspv::Id const_1;\n\n\tswitch (instruction->getType()->getTypeID())\n\t{\n\tcase llvm::Type::TypeID::HalfTyID:\n\t\tif (impl.support_native_fp16_operations())\n\t\t{\n\t\t\tconst_0 = builder.makeFloat16Constant(0);\n\t\t\tconst_1 = builder.makeFloat16Constant(0x3c00u | (is_signed ? 0x8000u : 0u));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconst_0 = builder.makeFloatConstant(0.0f);\n\t\t\tconst_1 = builder.makeFloatConstant(is_signed ? -1.0f : 1.0f);\n\t\t}\n\t\tbreak;\n\n\tcase llvm::Type::TypeID::FloatTyID:\n\t\tconst_0 = builder.makeFloatConstant(0.0f);\n\t\tconst_1 = builder.makeFloatConstant(is_signed ? -1.0f : 1.0f);\n\t\tbreak;\n\n\tcase llvm::Type::TypeID::DoubleTyID:\n\t\tconst_0 = builder.makeDoubleConstant(0.0);\n\t\tconst_1 = builder.makeDoubleConstant(is_signed ? -1.0 : 1.0);\n\t\tbreak;\n\n\tcase llvm::Type::TypeID::IntegerTyID:\n\t\tswitch (physical_integer_bit_width(instruction->getType()->getIntegerBitWidth()))\n\t\t{\n\t\tcase 16:\n\t\t\tconst_0 = builder.makeUint16Constant(0);\n\t\t\tconst_1 = builder.makeUint16Constant(is_signed ? 0xffff : 1u);\n\t\t\tbreak;\n\n\t\tcase 32:\n\t\t\tconst_0 = builder.makeUintConstant(0);\n\t\t\tconst_1 = builder.makeUintConstant(is_signed ? 0xffffffffu : 1u);\n\t\t\tbreak;\n\n\t\tcase 64:\n\t\t\tconst_0 = builder.makeUint64Constant(0ull);\n\t\t\tconst_1 = builder.makeUint64Constant(is_signed ? ~0ull : 1ull);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn 0;\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tOperation *op = impl.allocate(spv::OpSelect, instruction);\n\top->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\top->add_ids({ const_1, const_0 });\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\treturn op->id;\n}\n\ntemplate <typename InstructionType>\nstatic spv::Id emit_masked_cast_instruction(Converter::Impl &impl, const InstructionType *instruction, spv::Op opcode)\n{\n\tauto logical_output_bits = instruction->getType()->getIntegerBitWidth();\n\tauto logical_input_bits = instruction->getOperand(0)->getType()->getIntegerBitWidth();\n\tauto physical_output_bits = physical_integer_bit_width(logical_output_bits);\n\tauto physical_input_bits = physical_integer_bit_width(logical_input_bits);\n\tauto logical_bits = (std::min)(logical_output_bits, logical_input_bits);\n\n\tif (physical_output_bits == physical_input_bits)\n\t{\n\t\t// We cannot use a cast operation in SPIR-V here, just extend the value to physical size and roll with it.\n\t\tspv::Id extended_id = build_naturally_extended_value(impl, instruction->getOperand(0), logical_bits,\n\t\t                                                     opcode == spv::OpSConvert);\n\t\timpl.rewrite_value(instruction, extended_id);\n\t\treturn extended_id;\n\t}\n\telse if (physical_input_bits != logical_input_bits)\n\t{\n\t\t// Before extending, we must properly sign-extend.\n\t\tauto *mask_op = impl.allocate(opcode, instruction);\n\t\tmask_op->add_id(build_naturally_extended_value(impl, instruction->getOperand(0), logical_bits,\n\t\t                                               opcode == spv::OpSConvert));\n\t\timpl.add(mask_op);\n\t\treturn mask_op->id;\n\t}\n\n\treturn 0;\n}\n\ntemplate <typename InstructionType>\nstatic bool value_cast_is_noop(Converter::Impl &impl, const InstructionType *instruction, bool &relaxed_precision_cast)\n{\n\trelaxed_precision_cast = false;\n\n\t// In case we extend min16int to int without native 16-bit ints, this is just a noop.\n\t// I don't believe overflow is well defined for min-precision integers ...\n\t// They certainly are not in Vulkan.\n\tswitch (instruction->getOpcode())\n\t{\n\tcase llvm::Instruction::CastOps::FPExt:\n\t\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID &&\n\t\t    instruction->getOperand(0)->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID &&\n\t\t    !impl.support_native_fp16_operations())\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::FPTrunc:\n\t{\n\t\tif (instruction->getOperand(0)->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID &&\n\t\t    instruction->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID &&\n\t\t    !impl.support_native_fp16_operations())\n\t\t{\n\t\t\trelaxed_precision_cast = impl.options.arithmetic_relaxed_precision;\n\t\t\treturn true;\n\t\t}\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nstatic bool value_cast_is_fp16_quantization(Converter::Impl &impl, const llvm::CastInst *cast_inst, spv::Id &value_id)\n{\n\tif (cast_inst->getOpcode() == llvm::Instruction::CastOps::FPExt &&\n\t    cast_inst->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID)\n\t{\n\t\tif (const auto *trunc_inst = llvm::dyn_cast<llvm::CastInst>(cast_inst->getOperand(0)))\n\t\t{\n\t\t\tif (trunc_inst->getOpcode() == llvm::Instruction::CastOps::FPTrunc &&\n\t\t\t    trunc_inst->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID &&\n\t\t\t    trunc_inst->getOperand(0)->getType()->getTypeID() == llvm::Type::TypeID::FloatTyID)\n\t\t\t{\n\t\t\t\tvalue_id = impl.get_id_for_value(trunc_inst->getOperand(0));\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic bool value_cast_is_fp16_quantization(Converter::Impl &, const llvm::ConstantExpr *, spv::Id &)\n{\n\treturn false;\n}\n\ntemplate <typename InstructionType>\nstatic spv::Id emit_dxbc_tgsm_bitcast(Converter::Impl &impl, const InstructionType *instruction)\n{\n\t// dxbc2dxil workarounds. Backing storage is i8 array. Rewrite this to i32.\n\t// This can happen with a constexpr bitcast from i8 array to unarrayed i32.\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::PointerTyID &&\n\t    DXIL::AddressSpace(instruction->getType()->getPointerAddressSpace()) == DXIL::AddressSpace::GroupShared)\n\t{\n\t\tauto *input_value = instruction->getOperand(0);\n\t\tuint32_t constant_gep_offset = 0;\n\t\twhile (llvm::isa<llvm::ConstantExpr>(input_value))\n\t\t{\n\t\t\tauto *cexpr = llvm::cast<llvm::ConstantExpr>(input_value);\n\t\t\tif (cexpr->getOpcode() == llvm::Instruction::GetElementPtr && cexpr->getNumOperands() == 3)\n\t\t\t\tconstant_gep_offset = cexpr->getOperand(2)->getUniqueInteger().getZExtValue();\n\t\t\tinput_value = llvm::cast<llvm::ConstantExpr>(input_value)->getOperand(0);\n\t\t}\n\n\t\tauto *elem_type = input_value->getType()->getPointerElementType();\n\n\t\tuint32_t input_pointer_depth = 0;\n\t\twhile (elem_type->getTypeID() == llvm::Type::TypeID::ArrayTyID)\n\t\t{\n\t\t\tinput_pointer_depth++;\n\t\t\telem_type = elem_type->getArrayElementType();\n\t\t}\n\n\t\tuint32_t output_pointer_depth = 0;\n\t\tauto *output_elem_type = instruction->getType()->getPointerElementType();\n\t\twhile (output_elem_type->getTypeID() == llvm::Type::TypeID::ArrayTyID)\n\t\t{\n\t\t\toutput_pointer_depth++;\n\t\t\toutput_elem_type = output_elem_type->getArrayElementType();\n\t\t}\n\n\t\tif (elem_type->getTypeID() == llvm::Type::TypeID::IntegerTyID && elem_type->getIntegerBitWidth() == 8)\n\t\t{\n\t\t\tif (constant_gep_offset % 4)\n\t\t\t{\n\t\t\t\tLOGE(\"Expected 4 byte aligned constant gep offset for TGSM.\\n\");\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tauto &builder = impl.builder();\n\t\t\tspv::Id input_id = impl.get_id_for_value(input_value);\n\n\t\t\tif (output_pointer_depth < input_pointer_depth)\n\t\t\t{\n\t\t\t\tauto *chain = impl.allocate(\n\t\t\t\t    spv::OpInBoundsAccessChain,\n\t\t\t\t    builder.makePointer(spv::StorageClassWorkgroup, builder.makeUintType(32)));\n\n\t\t\t\tchain->add_id(input_id);\n\t\t\t\twhile (output_pointer_depth < input_pointer_depth)\n\t\t\t\t{\n\t\t\t\t\toutput_pointer_depth++;\n\t\t\t\t\tchain->add_id(builder.makeUintConstant(constant_gep_offset / 4));\n\t\t\t\t\tconstant_gep_offset = 0;\n\t\t\t\t}\n\t\t\t\timpl.add(chain);\n\t\t\t\tinput_id = chain->id;\n\t\t\t}\n\n\t\t\t// The backing storage is always 32-bit.\n\t\t\timpl.rewrite_value(instruction, input_id);\n\t\t\timpl.llvm_value_actual_type[instruction] = builder.makeUintType(32);\n\t\t\treturn input_id;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nspv::Id emit_bypass_fp16_trunc(Converter::Impl &impl, const llvm::Instruction *instruction)\n{\n\tauto &builder = impl.builder();\n\n\t// Try to find a cast chain where we can extract the native half value as-is.\n\tauto *value = instruction->getOperand(llvm::isa<llvm::CallInst>(instruction) ? 1 : 0);\n\n\tif (value_is_dx_op_instrinsic(value, DXIL::Op::LegacyF16ToF32))\n\t{\n\t\tauto *input_uint = llvm::cast<llvm::CallInst>(value)->getOperand(1);\n\t\tint component = 0;\n\t\tuint32_t cop = 0;\n\n\t\tif (const auto *binop = llvm::dyn_cast<llvm::BinaryOperator>(input_uint))\n\t\t{\n\t\t\tif (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::LShr &&\n\t\t\t    get_constant_operand(binop, 1, &cop) && cop == 16)\n\t\t\t{\n\t\t\t\tinput_uint = binop->getOperand(0);\n\t\t\t\tcomponent = 1;\n\t\t\t}\n\t\t\telse if (binop->getOpcode() == llvm::BinaryOperator::BinaryOps::And &&\n\t\t\t         get_constant_operand(binop, 1, &cop) && (cop & 0xffffu) == 0xffffu)\n\t\t\t{\n\t\t\t\tinput_uint = binop->getOperand(0);\n\t\t\t}\n\t\t}\n\n\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeVectorType(builder.makeUintType(16), 2));\n\t\tbitcast->add_id(impl.get_id_for_value(input_uint));\n\t\timpl.add(bitcast);\n\n\t\tauto *ext = impl.allocate(spv::OpCompositeExtract, builder.makeUintType(16));\n\t\text->add_id(bitcast->id);\n\t\text->add_literal(component);\n\t\timpl.add(ext);\n\n\t\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\t{\n\t\t\tauto *fp16_cast = impl.allocate(spv::OpBitcast, instruction);\n\t\t\tfp16_cast->add_id(ext->id);\n\t\t\timpl.add(fp16_cast);\n\t\t\treturn fp16_cast->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *upcast = impl.allocate(spv::OpUConvert, instruction);\n\t\t\tupcast->add_id(ext->id);\n\t\t\timpl.add(upcast);\n\t\t\treturn upcast->id;\n\t\t}\n\t}\n\telse if (const auto *cast = llvm::dyn_cast<llvm::CastInst>(value))\n\t{\n\t\tif (cast->getOpcode() == llvm::CastInst::CastOps::FPExt &&\n\t\t    cast->getOperand(0)->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t\t{\n\t\t\tspv::Id id = impl.get_id_for_value(cast->getOperand(0));\n\t\t\tif (instruction->getType()->getTypeID() != llvm::Type::TypeID::HalfTyID)\n\t\t\t{\n\t\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(16));\n\t\t\t\tbitcast->add_id(id);\n\t\t\t\timpl.add(bitcast);\n\n\t\t\t\tauto *upcast = impl.allocate(spv::OpUConvert, instruction);\n\t\t\t\tupcast->add_id(bitcast->id);\n\t\t\t\timpl.add(upcast);\n\t\t\t\treturn upcast->id;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\timpl.rewrite_value(instruction, id);\n\t\t\t\treturn id;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nstatic spv::Id emit_special_non_native_packing_bitcast(Converter::Impl &impl, const llvm::CastInst *instruction)\n{\n\tauto &builder = impl.builder();\n\tauto *input = instruction->getOperand(0);\n\n\tauto *output_scalar_type = instruction->getType();\n\tbool output_is_vec2 = false;\n\tauto *input_scalar_type = input->getType();\n\tbool input_is_vec2 = false;\n\n\tif (auto *vec_type = llvm::dyn_cast<llvm::VectorType>(output_scalar_type))\n\t{\n\t\toutput_scalar_type = vec_type->getElementType();\n\t\toutput_is_vec2 = true;\n\t}\n\n\tif (auto *vec_type = llvm::dyn_cast<llvm::VectorType>(input_scalar_type))\n\t{\n\t\tinput_scalar_type = vec_type->getElementType();\n\t\tinput_is_vec2 = true;\n\t}\n\n\tif (output_scalar_type->getTypeID() == llvm::Type::TypeID::HalfTyID &&\n\t    input_scalar_type->getTypeID() == llvm::Type::TypeID::IntegerTyID)\n\t{\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\tspv::Id id = impl.get_id_for_value(input);\n\n\t\tif (input_is_vec2 == output_is_vec2)\n\t\t{\n\t\t\tif (!input_is_vec2)\n\t\t\t{\n\t\t\t\tauto *upconv = impl.allocate(spv::OpUConvert, builder.makeUintType(32));\n\t\t\t\tupconv->add_id(id);\n\t\t\t\timpl.add(upconv);\n\t\t\t\tid = upconv->id;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, builder.makeUintType(32));\n\t\t\t\tbitcast->add_id(id);\n\t\t\t\timpl.add(bitcast);\n\t\t\t\tid = bitcast->id;\n\t\t\t}\n\t\t}\n\n\t\tauto *cast = impl.allocate(spv::OpExtInst, builder.makeVectorType(builder.makeFloatType(32), 2));\n\t\tcast->add_id(impl.glsl_std450_ext);\n\t\tcast->add_literal(GLSLstd450UnpackHalf2x16);\n\t\tcast->add_id(id);\n\t\timpl.add(cast);\n\n\t\tif (output_is_vec2)\n\t\t{\n\t\t\timpl.rewrite_value(instruction, cast->id);\n\t\t\treturn cast->id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *ext = impl.allocate(spv::OpCompositeExtract, instruction);\n\t\t\text->add_id(cast->id);\n\t\t\text->add_literal(0);\n\t\t\timpl.add(ext);\n\t\t\treturn ext->id;\n\t\t}\n\t}\n\telse if (output_scalar_type->getTypeID() == llvm::Type::TypeID::IntegerTyID &&\n\t         input_scalar_type->getTypeID() == llvm::Type::TypeID::HalfTyID)\n\t{\n\t\tif (!impl.glsl_std450_ext)\n\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\tspv::Id id = impl.get_id_for_value(input);\n\t\tif (!input_is_vec2)\n\t\t{\n\t\t\tspv::Id lanes[2] = { id, builder.makeFloatConstant(0.0f) };\n\t\t\tid = impl.build_vector(builder.makeFloatType(32), lanes, 2);\n\t\t}\n\n\t\tauto *cast = impl.allocate(spv::OpExtInst, builder.makeUintType(32));\n\t\tcast->add_id(impl.glsl_std450_ext);\n\t\tcast->add_literal(GLSLstd450PackHalf2x16);\n\t\tcast->add_id(id);\n\t\timpl.add(cast);\n\n\t\tif (output_is_vec2 == input_is_vec2)\n\t\t{\n\t\t\tif (output_is_vec2)\n\t\t\t{\n\t\t\t\tauto *bitcast = impl.allocate(spv::OpBitcast, instruction);\n\t\t\t\tbitcast->add_id(cast->id);\n\t\t\t\timpl.add(bitcast);\n\t\t\t\treturn bitcast->id;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto *downconv = impl.allocate(spv::OpUConvert, instruction);\n\t\t\t\tdownconv->add_id(cast->id);\n\t\t\t\timpl.add(downconv);\n\t\t\t\treturn downconv->id;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\timpl.rewrite_value(instruction, cast->id);\n\t\t\treturn cast->id;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nstatic spv::Id emit_bypass_fp16_trunc(Converter::Impl &, const llvm::ConstantExpr *)\n{\n\t// If it's constexpr, no point in optimizing ourselves. Really won't happen.\n\treturn 0;\n}\n\nstatic spv::Id emit_special_non_native_packing_bitcast(Converter::Impl &, const llvm::ConstantExpr *)\n{\n\t// If it's constexpr, no point in optimizing ourselves. Really won't happen.\n\treturn 0;\n}\n\ntemplate <typename InstructionType>\nstatic spv::Id emit_cast_instruction_impl(Converter::Impl &impl, const InstructionType *instruction)\n{\n\tbool can_relax_precision = false;\n\tbool signed_input = false;\n\tspv::Id value_id = 0;\n\tspv::Op opcode;\n\n\tif (value_cast_is_fp16_quantization(impl, instruction, value_id) &&\n\t    impl.execution_mode_meta.native_16bit_operations)\n\t{\n\t\t// D3D12 compilers will enforce a truncate here through a FP32 -> FP16 -> FP32 chain,\n\t\t// where Vulkan compilers ... don't :(\n\t\t// If we find this pattern, assume that compilers will try to be clever about it (NoContract does not work on NV),\n\t\t// and force use of QuantizeToFP16 instead.\n\t\t// Rounding mode of this operation is not well-defined,\n\t\t// but that is also the case for D3D12. AMD drivers will prefer RTZ here for example.\n\t\tauto *quant_op = impl.allocate(spv::OpQuantizeToF16, instruction);\n\t\tquant_op->add_id(value_id);\n\t\timpl.add(quant_op);\n\t\treturn quant_op->id;\n\t}\n\n\tif (value_cast_is_noop(impl, instruction, can_relax_precision))\n\t{\n\t\tspv::Id id;\n\t\tif (can_relax_precision)\n\t\t{\n\t\t\t// We cannot change the type, but we can mark the copied object\n\t\t\t// as relaxed to attempt to signal the intent.\n\t\t\tauto *trunc_op = impl.allocate(spv::OpCopyObject, instruction);\n\t\t\ttrunc_op->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\t\t\timpl.add(trunc_op);\n\t\t\tid = trunc_op->id;\n\t\t\timpl.builder().addDecoration(id, spv::DecorationRelaxedPrecision);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tid = impl.get_id_for_value(instruction->getOperand(0));\n\t\t\timpl.rewrite_value(instruction, id);\n\t\t}\n\n\t\treturn id;\n\t}\n\n\tif (instruction->getOpcode() == llvm::Instruction::CastOps::FPTrunc &&\n\t    instruction->getType()->getTypeID() == llvm::Type::TypeID::HalfTyID &&\n\t    impl.support_native_fp16_operations())\n\t{\n\t\t// Avoid roundtrip. Can happen for shaders which cast between min16 types, legacy packing, etc, etc.\n\t\tif (spv::Id id = emit_bypass_fp16_trunc(impl, instruction))\n\t\t\treturn id;\n\t}\n\n\tswitch (instruction->getOpcode())\n\t{\n\tcase llvm::Instruction::CastOps::BitCast:\n\t\tif (!impl.support_native_fp16_operations())\n\t\t\tif (spv::Id id = emit_special_non_native_packing_bitcast(impl, instruction))\n\t\t\t\treturn id;\n\t\topcode = spv::OpBitcast;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::SExt:\n\t\tif (instruction->getOperand(0)->getType()->getIntegerBitWidth() == 1)\n\t\t\treturn emit_boolean_convert_instruction(impl, instruction, true);\n\t\topcode = spv::OpSConvert;\n\t\tsigned_input = true;\n\t\tif (spv::Id id = emit_masked_cast_instruction(impl, instruction, opcode))\n\t\t\treturn id;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::ZExt:\n\t\tif (instruction->getOperand(0)->getType()->getIntegerBitWidth() == 1)\n\t\t\treturn emit_boolean_convert_instruction(impl, instruction, false);\n\t\topcode = spv::OpUConvert;\n\t\tif (spv::Id id = emit_masked_cast_instruction(impl, instruction, opcode))\n\t\t    return id;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::Trunc:\n\t\tif (instruction->getType()->getIntegerBitWidth() == 1)\n\t\t\treturn emit_boolean_trunc_instruction(impl, instruction);\n\t\topcode = spv::OpUConvert;\n\t\tif (spv::Id id = emit_masked_cast_instruction(impl, instruction, opcode))\n\t\t\treturn id;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::FPTrunc:\n\tcase llvm::Instruction::CastOps::FPExt:\n\t\topcode = spv::OpFConvert;\n\t\t// Relaxing precision on integers in DXIL is very sketchy, so don't bother.\n\t\tcan_relax_precision = true;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::FPToUI:\n\t\topcode = spv::OpConvertFToU;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::FPToSI:\n\t\topcode = spv::OpConvertFToS;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::SIToFP:\n\t\tif (instruction->getOperand(0)->getType()->getIntegerBitWidth() == 1)\n\t\t\treturn emit_boolean_convert_instruction(impl, instruction, true);\n\t\topcode = spv::OpConvertSToF;\n\t\tsigned_input = true;\n\t\tbreak;\n\n\tcase llvm::Instruction::CastOps::UIToFP:\n\t\tif (instruction->getOperand(0)->getType()->getIntegerBitWidth() == 1)\n\t\t\treturn emit_boolean_convert_instruction(impl, instruction, false);\n\t\topcode = spv::OpConvertUToF;\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unknown cast operation.\\n\");\n\t\treturn 0;\n\t}\n\n\tif (spv::Id id = emit_dxbc_tgsm_bitcast(impl, instruction))\n\t\treturn id;\n\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::PointerTyID)\n\t{\n\t\t// I have observed this code in the wild\n\t\t// %blah = bitcast float* %foo to i32*\n\t\t// on function local memory.\n\t\t// I have no idea if this is legal DXIL.\n\t\t// Fake this by copying the object instead without any cast, and resolve the bitcast in OpLoad/OpStore instead.\n\t\tauto *pointer_type = llvm::cast<llvm::PointerType>(instruction->getOperand(0)->getType());\n\t\tauto *pointee_type = pointer_type->getPointerElementType();\n\n\t\tauto *output_type = llvm::cast<llvm::PointerType>(instruction->getType());\n\t\tauto *output_value_type = output_type->getPointerElementType();\n\t\tunsigned input_pointer_array_depth = 0;\n\t\tunsigned output_pointer_array_depth = 0;\n\n\t\t// The pointee type can be an array if we're bitcasting a pointer to array.\n\t\t// The intention is that we will eventually access chain into the bitcast pointer.\n\t\t// In DXIL we can only store scalars, so chase down the underlying type.\n\t\twhile (pointee_type->getTypeID() == llvm::Type::TypeID::ArrayTyID)\n\t\t{\n\t\t\tpointee_type = pointee_type->getArrayElementType();\n\t\t\tinput_pointer_array_depth++;\n\t\t}\n\n\t\twhile (output_value_type->getTypeID() == llvm::Type::TypeID::ArrayTyID)\n\t\t{\n\t\t\toutput_value_type = output_value_type->getArrayElementType();\n\t\t\toutput_pointer_array_depth++;\n\t\t}\n\n\t\tif (pointee_type->getTypeID() == llvm::Type::TypeID::PointerTyID ||\n\t\t    output_value_type->getTypeID() == llvm::Type::TypeID::PointerTyID)\n\t\t{\n\t\t\t// Pretty sure DXIL does not support this ...\n\t\t\tLOGE(\"Cannot handle pointer-to-pointer.\\n\");\n\t\t\treturn 0;\n\t\t}\n\n\t\tspv::Id value_type = impl.get_type_id(pointee_type);\n\t\t// In case we get back-to-back pointer bitcasts for no good reason :v\n\t\tvalue_type = resolve_llvm_actual_value_type(impl, instruction,\n\t\t                                            instruction->getOperand(0), value_type);\n\n\t\tspv::StorageClass fallback_storage;\n\t\tif (static_cast<DXIL::AddressSpace>(pointer_type->getAddressSpace()) == DXIL::AddressSpace::GroupShared)\n\t\t\tfallback_storage = spv::StorageClassWorkgroup;\n\t\telse\n\t\t\tfallback_storage = spv::StorageClassFunction;\n\n\t\tspv::StorageClass storage = impl.get_effective_storage_class(instruction->getOperand(0), fallback_storage);\n\n\t\tspv::Id id = impl.get_id_for_value(instruction->getOperand(0));\n\n\t\tif (output_pointer_array_depth != input_pointer_array_depth)\n\t\t{\n\t\t\tif (output_pointer_array_depth > input_pointer_array_depth)\n\t\t\t{\n\t\t\t\t// Non-sensical.\n\t\t\t\tLOGE(\"Bitcasting pointer while adding more array dimensions.\\n\");\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\telse if (output_pointer_array_depth != 0)\n\t\t\t{\n\t\t\t\t// Bitcasting an array to anything other than scalar is non-sense.\n\t\t\t\t// We might be able to make it work by access chaining partially, but don't bother unless we observe\n\t\t\t\t// this. DXIL generally does not support array-of-array anyways ...\n\t\t\t\tLOGE(\"Bitcasting pointer to unexpected number of array dimensions.\\n\");\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\t// It is apparently possible to bitcast pointer-to-array into pointer-to-value.\n\t\t\t// Since we don't implement pointer bitcast,\n\t\t\t// we pretend to do so by accessing chaining into the first element.\n\t\t\tspv::Id type_id = impl.builder().makePointer(storage, value_type);\n\t\t\tOperation *op = impl.allocate(spv::OpInBoundsAccessChain, type_id);\n\t\t\top->add_id(id);\n\t\t\tfor (unsigned i = 0; i < input_pointer_array_depth; i++)\n\t\t\t\top->add_id(impl.builder().makeUintConstant(0));\n\t\t\timpl.add(op);\n\t\t\tid = op->id;\n\t\t}\n\t\telse if (!llvm::isa<llvm::ConstantExpr>(instruction))\n\t\t{\n\t\t\t// Shouldn't try to copy constant expressions.\n\t\t\t// They are built on-demand either way, and we risk infinite recursion that way.\n\t\t\tspv::Id type_id = impl.builder().makePointer(storage, value_type);\n\t\t\tOperation *op = impl.allocate(spv::OpCopyObject, instruction, type_id);\n\t\t\top->add_id(id);\n\t\t\timpl.add(op);\n\t\t\tid = op->id;\n\t\t}\n\n\t\t// Remember that we will need to bitcast on load or store to the real underlying type.\n\t\timpl.llvm_value_actual_type[instruction] = value_type;\n\t\timpl.handle_to_storage_class[instruction] = storage;\n\t\treturn id;\n\t}\n\telse\n\t{\n\t\tOperation *op;\n\t\tif (llvm::isa<llvm::ConstantExpr>(instruction))\n\t\t\top = impl.allocate(opcode, impl.get_type_id(instruction->getType()));\n\t\telse\n\t\t\top = impl.allocate(opcode, instruction);\n\n\t\top->add_id(build_naturally_extended_value(impl, instruction->getOperand(0), signed_input));\n\t\timpl.add(op);\n\t\tif (can_relax_precision)\n\t\t\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\t\treturn op->id;\n\t}\n}\n\nstatic bool cast_instruction_is_ignored(Converter::Impl &, const llvm::CastInst *instruction)\n{\n\t// llvm.lifetime.begin takes i8*, but this pointer type is not allowed otherwise.\n\t// We have to explicitly ignore this.\n\t// Ignore any bitcast to i8*,\n\t// it happens for lib_6_6 and is completely meaningless for us.\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::PointerTyID)\n\t{\n\t\tauto *result_type = instruction->getType()->getPointerElementType();\n\t\tif (result_type->getTypeID() == llvm::Type::TypeID::IntegerTyID && result_type->getIntegerBitWidth() == 8)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool emit_cast_instruction(Converter::Impl &impl, const llvm::CastInst *instruction)\n{\n\tif (cast_instruction_is_ignored(impl, instruction))\n\t\treturn true;\n\n\treturn emit_cast_instruction_impl(impl, instruction) != 0;\n}\n\nstatic bool elementptr_is_nonuniform(const llvm::GetElementPtrInst *inst)\n{\n\treturn inst->hasMetadata(\"dx.nonuniform\");\n}\n\nstatic bool elementptr_is_nonuniform(const llvm::ConstantExpr *)\n{\n\treturn false;\n}\n\ntemplate <typename Inst>\nstatic bool emit_getelementptr_resource(Converter::Impl &impl, const Inst *instruction,\n                                        const Converter::Impl::ResourceMetaReference &meta)\n{\n\tauto *elem_index = instruction->getOperand(1);\n\n\t// This one must be constant 0, ignore it.\n\tif (!llvm::isa<llvm::ConstantInt>(elem_index))\n\t{\n\t\tLOGE(\"First GetElementPtr operand is not constant 0.\\n\");\n\t\treturn false;\n\t}\n\n\tif (instruction->getNumOperands() != 3)\n\t{\n\t\tLOGE(\"Number of operands to getelementptr for a resource handle is unexpected.\\n\");\n\t\treturn false;\n\t}\n\n\tauto indexed_meta = meta;\n\tindexed_meta.offset = instruction->getOperand(2);\n\tindexed_meta.non_uniform = elementptr_is_nonuniform(instruction);\n\timpl.llvm_global_variable_to_resource_mapping[instruction] = indexed_meta;\n\treturn true;\n}\n\nstatic spv::Id build_constant_getelementptr(Converter::Impl &impl, const llvm::ConstantExpr *cexpr)\n{\n\tauto &builder = impl.builder();\n\tspv::Id ptr_id = impl.get_id_for_value(cexpr->getOperand(0));\n\n\tauto *element_type = cexpr->getType()->getPointerElementType();\n\tspv::Id type_id = impl.get_type_id(element_type);\n\n\t// If we're trying to getelementptr into a bitcasted pointer to array, we have to rewrite the pointer type.\n\ttype_id = resolve_llvm_actual_value_type(impl, cexpr, cexpr->getOperand(0), type_id);\n\n\tauto storage = impl.get_effective_storage_class(cexpr->getOperand(0), builder.getStorageClass(ptr_id));\n\ttype_id = builder.makePointer(storage, type_id);\n\n\tOperation *op = impl.allocate(spv::OpAccessChain, type_id);\n\n\top->add_id(ptr_id);\n\n\tauto *elem_index = cexpr->getOperand(1);\n\n\t// This one must be constant 0, ignore it.\n\tif (!llvm::isa<llvm::ConstantInt>(elem_index))\n\t{\n\t\tLOGE(\"First GetElementPtr operand is not constant 0.\\n\");\n\t\treturn 0;\n\t}\n\n\tif (llvm::cast<llvm::ConstantInt>(elem_index)->getUniqueInteger().getZExtValue() != 0)\n\t{\n\t\tLOGE(\"First GetElementPtr operand is not constant 0.\\n\");\n\t\treturn 0;\n\t}\n\n\tunsigned num_operands = cexpr->getNumOperands();\n\tfor (uint32_t i = 2; i < num_operands; i++)\n\t\top->add_id(impl.get_id_for_value(cexpr->getOperand(i)));\n\n\timpl.add(op);\n\treturn op->id;\n}\n\nstatic spv::Id build_constant_cast(Converter::Impl &impl, const llvm::ConstantExpr *cexpr)\n{\n\treturn emit_cast_instruction_impl(impl, cexpr);\n}\n\nspv::Id build_constant_expression(Converter::Impl &impl, const llvm::ConstantExpr *cexpr)\n{\n\tswitch (cexpr->getOpcode())\n\t{\n\tcase llvm::Instruction::GetElementPtr:\n\t\treturn build_constant_getelementptr(impl, cexpr);\n\n\tcase llvm::Instruction::Trunc:\n\tcase llvm::Instruction::ZExt:\n\tcase llvm::Instruction::SExt:\n\tcase llvm::Instruction::FPToUI:\n\tcase llvm::Instruction::FPToSI:\n\tcase llvm::Instruction::UIToFP:\n\tcase llvm::Instruction::SIToFP:\n\tcase llvm::Instruction::FPTrunc:\n\tcase llvm::Instruction::FPExt:\n\tcase llvm::Instruction::PtrToInt:\n\tcase llvm::Instruction::IntToPtr:\n\tcase llvm::Instruction::BitCast:\n\tcase llvm::Instruction::AddrSpaceCast:\n\t\treturn build_constant_cast(impl, cexpr);\n\n\tcase llvm::Instruction::Add:\n\tcase llvm::Instruction::FAdd:\n\tcase llvm::Instruction::Sub:\n\tcase llvm::Instruction::FSub:\n\tcase llvm::Instruction::Mul:\n\tcase llvm::Instruction::FMul:\n\tcase llvm::Instruction::UDiv:\n\tcase llvm::Instruction::SDiv:\n\tcase llvm::Instruction::FDiv:\n\tcase llvm::Instruction::URem:\n\tcase llvm::Instruction::SRem:\n\tcase llvm::Instruction::FRem:\n\tcase llvm::Instruction::Shl:\n\tcase llvm::Instruction::LShr:\n\tcase llvm::Instruction::AShr:\n\tcase llvm::Instruction::And:\n\tcase llvm::Instruction::Or:\n\tcase llvm::Instruction::Xor:\n\t\treturn emit_binary_instruction_impl(impl, cexpr);\n\n\tdefault:\n\t{\n\t\tLOGE(\"Unknown constant-expr.\\n\");\n\t\tbreak;\n\t}\n\t}\n\n\treturn 0;\n}\n\nstruct AllocaTrackedIndex\n{\n\tconst llvm::AllocaInst *alloca_inst;\n\tconst llvm::Value *index;\n\tUnorderedMap<const llvm::AllocaInst *, AllocaCBVForwardingTracking>::iterator itr;\n\tconst llvm::Value *cbv_handle;\n};\n\nstatic AllocaTrackedIndex gep_pointer_to_alloca_tracked_inst(Converter::Impl &impl, const llvm::Value *ptr)\n{\n\tif (const auto *gep_inst = llvm::dyn_cast<llvm::GetElementPtrInst>(ptr))\n\t{\n\t\tif (const auto *alloca_inst = llvm::dyn_cast<llvm::AllocaInst>(gep_inst->getOperand(0)))\n\t\t{\n\t\t\tauto itr = impl.alloca_tracking.find(alloca_inst);\n\t\t\tif (itr != impl.alloca_tracking.end())\n\t\t\t\treturn { alloca_inst, gep_inst->getOperand(2), itr, itr->second.cbv_handle };\n\t\t}\n\t}\n\n\treturn {};\n}\n\nstatic void get_dxbc_tgsm_gep_workaround(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction,\n                                         uint32_t &elementptr_shift, spv::Id &type_id)\n{\n\t// Workaround dxbc2dxil where we access chain into i8 array which is non-sense.\n\t// The backing variable is i32 array instead. Rewrite appropriately.\n\tif (DXIL::AddressSpace(instruction->getType()->getPointerAddressSpace()) == DXIL::AddressSpace::GroupShared)\n\t{\n\t\tauto *elem_type = instruction->getOperand(0)->getType()->getPointerElementType();\n\t\tif (elem_type->getTypeID() == llvm::Type::TypeID::ArrayTyID)\n\t\t\telem_type = elem_type->getArrayElementType();\n\t\tif (elem_type->getTypeID() == llvm::Type::TypeID::IntegerTyID && elem_type->getIntegerBitWidth() == 8)\n\t\t{\n\t\t\telementptr_shift = 2;\n\t\t\ttype_id = impl.builder().makeUintType(32);\n\t\t}\n\t}\n}\n\nbool emit_getelementptr_instruction(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction)\n{\n\tif (emit_ags_getelementptr(impl, instruction))\n\t\treturn true;\n\n\t// This is actually the same as PtrAccessChain, but we would need to use variable pointers to support that properly.\n\t// For now, just assert that the first index is constant 0, in which case PtrAccessChain == AccessChain.\n\n\t// Detour the GEP instruction via a cbuffer + AccessChain.\n\t// This is the store that is ignored.\n\tauto tracker = gep_pointer_to_alloca_tracked_inst(impl, instruction);\n\n\tif (tracker.cbv_handle)\n\t{\n\t\tif (impl.masked_alloca_forward_gep.count(instruction))\n\t\t\treturn true;\n\n\t\treturn emit_gep_as_cbuffer_scalar_offset(\n\t\t\timpl, instruction,\n\t\t\ttracker.cbv_handle, tracker.itr->second.scalar_index_offset, tracker.itr->second.stride);\n\t}\n\n\tauto global_itr = impl.llvm_global_variable_to_resource_mapping.find(instruction->getOperand(0));\n\tif (global_itr != impl.llvm_global_variable_to_resource_mapping.end())\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Id ptr_id = impl.get_id_for_value(instruction->getOperand(0));\n\tuint32_t elementptr_shift = 0;\n\tspv::Id type_id = 0;\n\n\tget_dxbc_tgsm_gep_workaround(impl, instruction, elementptr_shift, type_id);\n\n\tif (type_id == 0)\n\t\ttype_id = impl.get_type_id(instruction->getType()->getPointerElementType());\n\n\t// If we're trying to getelementptr into a bitcasted pointer to array, we have to rewrite the pointer type.\n\tresolve_llvm_actual_value_type(impl, instruction, instruction->getOperand(0), type_id);\n\n\tags_getelementptr_filter(impl, instruction, type_id);\n\n\tspv::StorageClass storage;\n\tif (DXIL::AddressSpace(instruction->getOperand(0)->getType()->getPointerAddressSpace()) == DXIL::AddressSpace::PhysicalNodeIO)\n\t\tstorage = spv::StorageClassPhysicalStorageBuffer;\n\telse\n\t\tstorage = impl.get_effective_storage_class(instruction->getOperand(0), builder.getStorageClass(ptr_id));\n\n\ttype_id = builder.makePointer(storage, type_id);\n\n\tOperation *op = impl.allocate(instruction->isInBounds() ? spv::OpInBoundsAccessChain : spv::OpAccessChain,\n\t                              instruction, type_id);\n\n\top->add_id(ptr_id);\n\n\tauto *elem_index = instruction->getOperand(1);\n\n\t// This one must be constant 0, ignore it.\n\tif (!llvm::isa<llvm::ConstantInt>(elem_index))\n\t{\n\t\tLOGE(\"First GetElementPtr operand is not constant 0.\\n\");\n\t\treturn false;\n\t}\n\n\tif (llvm::cast<llvm::ConstantInt>(elem_index)->getUniqueInteger().getZExtValue() != 0)\n\t{\n\t\tLOGE(\"First GetElementPtr operand is not constant 0.\\n\");\n\t\treturn false;\n\t}\n\n\tunsigned num_operands = instruction->getNumOperands();\n\tfor (uint32_t i = 2; i < num_operands; i++)\n\t{\n\t\t// Be a bit careful with the typing since we might have some weird bitcast pointer types flying around.\n\t\tif (i == 2 && !llvm::isa<llvm::Constant>(instruction->getOperand(2)))\n\t\t{\n\t\t\tif (auto *aggregate_type = llvm::dyn_cast<llvm::PointerType>(instruction->getOperand(0)->getType()))\n\t\t\t{\n\t\t\t\tif (auto *array_type = llvm::dyn_cast<llvm::ArrayType>(aggregate_type->getPointerElementType()))\n\t\t\t\t{\n\t\t\t\t\tauto address_space = DXIL::AddressSpace(aggregate_type->getPointerAddressSpace());\n\t\t\t\t\tif (address_space == DXIL::AddressSpace::GroupShared || address_space == DXIL::AddressSpace::Thread)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto *global_var = llvm::dyn_cast<llvm::GlobalVariable>(instruction->getOperand(0));\n\t\t\t\t\t\tif (global_var && global_var->hasInitializer() && global_var->isConstant() &&\n\t\t\t\t\t\t    impl.options.extended_robustness.constant_lut &&\n\t\t\t\t\t\t    !elementptr_shift && address_space == DXIL::AddressSpace::Thread)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Robustness for constant LUTs.\n\t\t\t\t\t\t\tif (!impl.glsl_std450_ext)\n\t\t\t\t\t\t\t\timpl.glsl_std450_ext = builder.import(\"GLSL.std.450\");\n\n\t\t\t\t\t\t\tauto *clamp_op = impl.allocate(spv::OpExtInst, builder.makeUintType(32));\n\t\t\t\t\t\t\tclamp_op->add_id(impl.glsl_std450_ext);\n\t\t\t\t\t\t\tclamp_op->add_id(GLSLstd450UMin);\n\t\t\t\t\t\t\tclamp_op->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\t\t\t\t\t\tclamp_op->add_id(builder.makeUintConstant(array_type->getArrayNumElements()));\n\t\t\t\t\t\t\timpl.add(clamp_op);\n\t\t\t\t\t\t\top->add_id(clamp_op->id);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (address_space == DXIL::AddressSpace::Thread && impl.options.extended_robustness.alloca)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tunsigned num_elements = array_type->getArrayNumElements();\n\t\t\t\t\t\t\tauto *is_in_bounds = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\t\t\t\t\t\t\tis_in_bounds->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\t\t\t\t\t\tis_in_bounds->add_id(builder.makeUintConstant(num_elements));\n\t\t\t\t\t\t\timpl.add(is_in_bounds);\n\n\t\t\t\t\t\t\timpl.handle_to_robustness[instruction] = is_in_bounds->id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (address_space == DXIL::AddressSpace::GroupShared && impl.options.extended_robustness.group_shared)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Need to handle atomics as well, and it'll be a mess to add support for that.\n\t\t\t\t\t\t\tLOGW(\"Robust group shared GEP not yet implemented.\\n\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (impl.options.instruction_instrumentation.enabled &&\n\t\t\t\t\t\t         impl.options.instruction_instrumentation.type == InstructionInstrumentationType::ExpectAssume)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Fallback expect-assume case.\n\t\t\t\t\t\t\tunsigned num_elements = array_type->getArrayNumElements();\n\t\t\t\t\t\t\tauto *is_in_bounds = impl.allocate(spv::OpULessThan, builder.makeBoolType());\n\t\t\t\t\t\t\tis_in_bounds->add_id(impl.get_id_for_value(instruction->getOperand(2)));\n\t\t\t\t\t\t\tis_in_bounds->add_id(builder.makeUintConstant(num_elements));\n\t\t\t\t\t\t\timpl.add(is_in_bounds);\n\n\t\t\t\t\t\t\tauto *assert_that = impl.allocate(spv::OpAssumeTrueKHR);\n\t\t\t\t\t\t\tassert_that->add_id(is_in_bounds->id);\n\t\t\t\t\t\t\timpl.add(assert_that);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (i == 2 && elementptr_shift != 0)\n\t\t{\n\t\t\tspv::Id index = build_index_divider(impl, instruction->getOperand(2), elementptr_shift, 1);\n\t\t\top->add_id(index);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tspv::Id id = impl.get_id_for_value(instruction->getOperand(i));\n\n\t\t\tif (i == 2)\n\t\t\t{\n\t\t\t\tid = rewrite_alloca_gep_index(impl, instruction, id);\n\t\t\t\tif (id == UINT32_MAX)\n\t\t\t\t\treturn true;\n\t\t\t\tif (!id)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\top->add_id(id);\n\t\t}\n\t}\n\n\timpl.handle_to_storage_class[instruction] = storage;\n\timpl.add(op);\n\treturn true;\n}\n\nstatic bool needs_group_shared_auto_barrier(Converter::Impl &impl, const llvm::Value *ptr_value)\n{\n\treturn impl.shader_analysis.needs_auto_group_shared_barriers &&\n\t       DXIL::AddressSpace(ptr_value->getType()->getPointerAddressSpace()) ==\n\t       DXIL::AddressSpace::GroupShared;\n}\n\nstatic bool vkmm_requires_auto_visibility(Converter::Impl &impl, const llvm::Value *ptr)\n{\n\tauto &ptrs = impl.llvm_vkmm_coherent_ptrs;\n\tif (ptrs.empty())\n\t\treturn false;\n\n\tfor (;;)\n\t{\n\t\tif (std::find(ptrs.begin(), ptrs.end(), ptr) != ptrs.end())\n\t\t\treturn true;\n\n\t\tif (const auto *gep = llvm::dyn_cast<llvm::GetElementPtrInst>(ptr))\n\t\t\tptr = gep->getOperand(0);\n\t\telse if (const auto *cast = llvm::dyn_cast<llvm::CastInst>(ptr))\n\t\t\tptr = cast->getOperand(0);\n\t\telse\n\t\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nbool emit_load_instruction(Converter::Impl &impl, const llvm::LoadInst *instruction)\n{\n\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(instruction->getPointerOperand());\n\n\t// If we are trying to load a resource in RT, this does not translate in SPIR-V, defer this to createHandleForLib.\n\tif (itr != impl.llvm_global_variable_to_resource_mapping.end())\n\t\treturn true;\n\n\tif (ags_llvm_load_filter_cexpr(impl, instruction))\n\t\treturn true;\n\n\t// We need to get the ID here as the constexpr chain could set our type.\n\tspv::Id value_id = impl.get_id_for_value(instruction->getPointerOperand());\n\n\tspv::Id remapped_type_id = resolve_llvm_actual_value_type(impl, nullptr,\n\t                                                          instruction->getPointerOperand(), 0);\n\n\tauto addr_space = DXIL::AddressSpace(instruction->getPointerOperand()->getType()->getPointerAddressSpace());\n\tbool non_private = addr_space != DXIL::AddressSpace::Thread &&\n\t                   impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan;\n\n\tif (remapped_type_id != 0)\n\t{\n\t\tOperation *load_op = impl.allocate(spv::OpLoad, remapped_type_id);\n\t\tload_op->add_id(value_id);\n\t\tadd_vkmm_access_qualifiers(impl, load_op, { non_private });\n\t\timpl.add(load_op);\n\n\t\tif (needs_group_shared_auto_barrier(impl, instruction->getPointerOperand()))\n\t\t\tload_op->flags |= Operation::AutoGroupSharedBarrier;\n\n\t\tOperation *cast_op = impl.allocate(spv::OpBitcast, instruction);\n\t\tcast_op->add_id(load_op->id);\n\t\timpl.add(cast_op);\n\t}\n\telse\n\t{\n\t\tauto robust_itr = impl.handle_to_robustness.find(instruction->getPointerOperand());\n\t\tOperation *op = impl.allocate(robust_itr != impl.handle_to_robustness.end() ? spv::PseudoOpMaskedLoad : spv::OpLoad, instruction);\n\t\top->add_id(value_id);\n\n\t\tif (needs_group_shared_auto_barrier(impl, instruction->getPointerOperand()))\n\t\t\top->flags |= Operation::AutoGroupSharedBarrier;\n\n\t\t// If this is remapped to BDA, need to add Aligned mask.\n\t\tauto tracked = gep_pointer_to_alloca_tracked_inst(impl, instruction->getPointerOperand());\n\t\tif (tracked.alloca_inst && tracked.itr->second.cbv_handle)\n\t\t{\n\t\t\tspv::Id ptr_id = impl.get_id_for_value(tracked.itr->second.cbv_handle);\n\t\t\tauto &meta = impl.handle_to_resource_meta[ptr_id];\n\t\t\tif (meta.storage == spv::StorageClassPhysicalStorageBuffer)\n\t\t\t{\n\t\t\t\top->add_literal(spv::MemoryAccessAlignedMask);\n\t\t\t\top->add_literal(4);\n\t\t\t}\n\t\t}\n\n\t\tbool auto_visibility = false;\n\n\t\t// For NodeIO, we always have to tag with aligned mask.\n\t\tif (addr_space == DXIL::AddressSpace::PhysicalNodeIO)\n\t\t{\n\t\t\t// TODO: Properly track aligned size based on the GEP, but for now, just assume scalar.\n\t\t\top->add_literal(spv::MemoryAccessAlignedMask);\n\t\t\tauto size_alignment = impl.get_physical_size_for_type(\n\t\t\t    impl.builder().getContainedTypeId(impl.get_type_id(instruction->getPointerOperand()->getType(), true)));\n\t\t\top->add_literal(size_alignment.alignment);\n\n\t\t\tauto_visibility = vkmm_requires_auto_visibility(impl, instruction->getPointerOperand());\n\t\t}\n\n\t\tadd_vkmm_access_qualifiers(impl, op, { non_private, auto_visibility });\n\n\t\tif (op->op == spv::PseudoOpMaskedLoad)\n\t\t{\n\t\t\t// OpSampledImage must be consumed in same block.\n\t\t\t// We'll split blocks here, so just recreate the combined sampler image if needed.\n\t\t\timpl.combined_image_sampler_cache.clear();\n\t\t\top->add_id(robust_itr->second);\n\t\t}\n\n\t\tif (ags_llvm_load_filter(impl, op, instruction))\n\t\t\treturn true;\n\n\t\timpl.add(op);\n\t}\n\n\treturn true;\n}\n\nbool emit_store_instruction(Converter::Impl &impl, const llvm::StoreInst *instruction)\n{\n\t// Ignore stores to remapped alloca().\n\tauto tracking = gep_pointer_to_alloca_tracked_inst(impl, instruction->getOperand(1));\n\tif (tracking.cbv_handle)\n\t\treturn true;\n\n\t// Ignore stores of WMMA if it's not the first component\n\tif (wmma_store_is_masked(impl, instruction))\n\t\treturn true;\n\n\t// May need to handle constexpr GEP.\n\tif (ags_store_filter(impl, instruction))\n\t\treturn true;\n\n\tauto robust_itr = impl.handle_to_robustness.find(instruction->getOperand(1));\n\tOperation *op = impl.allocate(robust_itr != impl.handle_to_robustness.end() ? spv::PseudoOpMaskedStore : spv::OpStore);\n\n\tif (needs_group_shared_auto_barrier(impl, instruction->getOperand(1)))\n\t\top->flags |= Operation::AutoGroupSharedBarrier;\n\n\t// We need to get the ID here as the constexpr chain could set our type.\n\top->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\n\tspv::Id remapped_type_id = resolve_llvm_actual_value_type(impl, nullptr, instruction->getOperand(1), 0);\n\n\tif (remapped_type_id != 0)\n\t{\n\t\tOperation *cast_op = impl.allocate(spv::OpBitcast, remapped_type_id);\n\t\tcast_op->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\t\timpl.add(cast_op);\n\t\top->add_id(cast_op->id);\n\t}\n\telse\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\n\tauto addr_space = DXIL::AddressSpace(instruction->getOperand(1)->getType()->getPointerAddressSpace());\n\tbool non_private = addr_space != DXIL::AddressSpace::Thread &&\n\t                   impl.execution_mode_meta.memory_model == spv::MemoryModelVulkan;\n\tbool auto_visibility = false;\n\n\t// For NodeIO, we always have to tag with aligned mask.\n\tif (addr_space == DXIL::AddressSpace::PhysicalNodeIO)\n\t{\n\t\t// TODO: Properly track aligned size based on the GEP, but for now, just assume scalar.\n\t\top->add_literal(spv::MemoryAccessAlignedMask);\n\t\tauto size_alignment = impl.get_physical_size_for_type(\n\t\t\timpl.builder().getContainedTypeId(impl.get_type_id(instruction->getOperand(1)->getType(), true)));\n\t\top->add_literal(size_alignment.alignment);\n\n\t\tauto_visibility = vkmm_requires_auto_visibility(impl, instruction->getOperand(1));\n\t}\n\n\tadd_vkmm_access_qualifiers(impl, op, { non_private, auto_visibility });\n\n\tif (op->op == spv::PseudoOpMaskedStore)\n\t{\n\t\t// OpSampledImage must be consumed in same block.\n\t\t// We'll split blocks here, so just recreate the combined sampler image if needed.\n\t\timpl.combined_image_sampler_cache.clear();\n\t\top->add_id(robust_itr->second);\n\t}\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_compare_instruction(Converter::Impl &impl, const llvm::CmpInst *instruction)\n{\n\tbool signed_input = false;\n\tspv::Op opcode;\n\n\tswitch (instruction->getPredicate())\n\t{\n\tcase llvm::CmpInst::Predicate::FCMP_OEQ:\n\t\topcode = spv::OpFOrdEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_UEQ:\n\t\topcode = spv::OpFUnordEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_OGT:\n\t\topcode = spv::OpFOrdGreaterThan;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_UGT:\n\t\topcode = spv::OpFUnordGreaterThan;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_OGE:\n\t\topcode = spv::OpFOrdGreaterThanEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_UGE:\n\t\topcode = spv::OpFUnordGreaterThanEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_OLT:\n\t\topcode = spv::OpFOrdLessThan;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_ULT:\n\t\topcode = spv::OpFUnordLessThan;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_OLE:\n\t\topcode = spv::OpFOrdLessThanEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_ULE:\n\t\topcode = spv::OpFUnordLessThanEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_ONE:\n\t\topcode = spv::OpFOrdNotEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_UNE:\n\t\topcode = spv::OpFUnordNotEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_FALSE:\n\t{\n\t\t// Why on earth is this a thing ...\n\t\timpl.rewrite_value(instruction, impl.builder().makeBoolConstant(false));\n\t\treturn true;\n\t}\n\n\tcase llvm::CmpInst::Predicate::FCMP_TRUE:\n\t{\n\t\t// Why on earth is this a thing ...\n\t\timpl.rewrite_value(instruction, impl.builder().makeBoolConstant(true));\n\t\treturn true;\n\t}\n\n\tcase llvm::CmpInst::Predicate::ICMP_EQ:\n\t\tif (instruction->getOperand(0)->getType()->getIntegerBitWidth() == 1)\n\t\t\topcode = spv::OpLogicalEqual;\n\t\telse\n\t\t\topcode = spv::OpIEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_NE:\n\t\tif (instruction->getOperand(0)->getType()->getIntegerBitWidth() == 1)\n\t\t\topcode = spv::OpLogicalNotEqual;\n\t\telse\n\t\t\topcode = spv::OpINotEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_SLT:\n\t\topcode = spv::OpSLessThan;\n\t\tsigned_input = true;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_SLE:\n\t\topcode = spv::OpSLessThanEqual;\n\t\tsigned_input = true;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_SGT:\n\t\topcode = spv::OpSGreaterThan;\n\t\tsigned_input = true;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_SGE:\n\t\topcode = spv::OpSGreaterThanEqual;\n\t\tsigned_input = true;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_ULT:\n\t\topcode = spv::OpULessThan;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_ULE:\n\t\topcode = spv::OpULessThanEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_UGT:\n\t\topcode = spv::OpUGreaterThan;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::ICMP_UGE:\n\t\topcode = spv::OpUGreaterThanEqual;\n\t\tbreak;\n\n\tcase llvm::CmpInst::Predicate::FCMP_UNO:\n\t{\n\t\tOperation *first_op = impl.allocate(spv::OpIsNan, impl.builder().makeBoolType());\n\t\tfirst_op->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\t\timpl.add(first_op);\n\n\t\tOperation *second_op = impl.allocate(spv::OpIsNan, impl.builder().makeBoolType());\n\t\tsecond_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(second_op);\n\n\t\tOperation *op = impl.allocate(spv::OpLogicalOr, instruction);\n\t\top->add_ids({ first_op->id, second_op->id });\n\t\timpl.add(op);\n\t\treturn true;\n\t}\n\n\tcase llvm::CmpInst::Predicate::FCMP_ORD:\n\t{\n\t\tOperation *first_op = impl.allocate(spv::OpIsNan, impl.builder().makeBoolType());\n\t\tfirst_op->add_id(impl.get_id_for_value(instruction->getOperand(0)));\n\t\timpl.add(first_op);\n\n\t\tOperation *second_op = impl.allocate(spv::OpIsNan, impl.builder().makeBoolType());\n\t\tsecond_op->add_id(impl.get_id_for_value(instruction->getOperand(1)));\n\t\timpl.add(second_op);\n\n\t\tOperation *unordered_op = impl.allocate(spv::OpLogicalOr, impl.builder().makeBoolType());\n\t\tunordered_op->add_ids({ first_op->id, second_op->id });\n\t\timpl.add(unordered_op);\n\n\t\tOperation *op = impl.allocate(spv::OpLogicalNot, instruction);\n\t\top->add_id(unordered_op->id);\n\t\timpl.add(op);\n\t\treturn true;\n\t}\n\n\tdefault:\n\t\tLOGE(\"Unknown CmpInst predicate.\\n\");\n\t\treturn false;\n\t}\n\n\tOperation *op = impl.allocate(opcode, instruction);\n\n\tuint32_t id0 = build_naturally_extended_value(impl, instruction->getOperand(0), signed_input);\n\tuint32_t id1 = build_naturally_extended_value(impl, instruction->getOperand(1), signed_input);\n\top->add_ids({ id0, id1 });\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_extract_value_instruction(Converter::Impl &impl, const llvm::ExtractValueInst *instruction)\n{\n\tif (emit_ags_extract_value(impl, instruction))\n\t\treturn true;\n\n\tauto itr = impl.llvm_composite_meta.find(instruction->getAggregateOperand());\n\n\tif (itr != impl.llvm_composite_meta.end() &&\n\t    itr->second.components == 1 &&\n\t    !itr->second.forced_composite)\n\t{\n\t\t// Forward the ID. The composite was originally emitted as a scalar.\n\t\tspv::Id rewrite_id = impl.get_id_for_value(instruction->getAggregateOperand());\n\t\timpl.rewrite_value(instruction, rewrite_id);\n\t}\n\telse\n\t{\n\t\tOperation *op = impl.allocate(spv::OpCompositeExtract, instruction);\n\n\t\top->add_id(impl.get_id_for_value(instruction->getAggregateOperand()));\n\t\tfor (unsigned i = 0; i < instruction->getNumIndices(); i++)\n\t\t\top->add_literal(instruction->getIndices()[i]);\n\n\t\timpl.add(op);\n\t\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\t}\n\n\treturn true;\n}\n\nbool emit_alloca_instruction(Converter::Impl &impl, const llvm::AllocaInst *instruction)\n{\n\t// Remapped. Ignore.\n\tauto itr = impl.alloca_tracking.find(instruction);\n\tif (itr != impl.alloca_tracking.end() && itr->second.cbv_handle)\n\t\treturn true;\n\n\tauto *element_type = instruction->getType()->getPointerElementType();\n\tif (llvm::isa<llvm::PointerType>(element_type))\n\t{\n\t\tLOGE(\"Cannot alloca elements of pointer type.\\n\");\n\t\treturn false;\n\t}\n\n\tspv::Id pointee_type_id = impl.get_type_id(element_type);\n\n\t// DXC seems to allocate arrays on stack as 1 element of array type rather than N elements of basic non-array type.\n\t// Should be possible to support both schemes if desirable, but this will do.\n\tif (!llvm::isa<llvm::ConstantInt>(instruction->getArraySize()))\n\t{\n\t\tLOGE(\"Array size for alloca must be constant int.\\n\");\n\t\treturn false;\n\t}\n\n\tif (llvm::cast<llvm::ConstantInt>(instruction->getArraySize())->getUniqueInteger().getZExtValue() != 1)\n\t{\n\t\tLOGE(\"Alloca array size must be constant 1.\\n\");\n\t\treturn false;\n\t}\n\n\tauto address_space = static_cast<DXIL::AddressSpace>(instruction->getType()->getAddressSpace());\n\tif (address_space != DXIL::AddressSpace::Thread)\n\t\treturn false;\n\n\tif (!ags_alloca_or_global_filter(impl, instruction, pointee_type_id))\n\t\treturn false;\n\n\tauto storage = impl.get_effective_storage_class(instruction, spv::StorageClassFunction);\n\tspv::Id var_id = impl.create_variable(storage, pointee_type_id);\n\timpl.rewrite_value(instruction, var_id);\n\timpl.handle_to_storage_class[instruction] = storage;\n\timpl.decorate_relaxed_precision(element_type, var_id, false);\n\treturn true;\n}\n\nstatic bool emit_peephole_findmsb(Converter::Impl &impl, const llvm::Instruction *instruction)\n{\n\t// DXIL is CLZ, while original HLSL is Vulkan-style findMSB. Peephole the double-conversion pattern.\n\tauto *cond = instruction->getOperand(0);\n\tauto *true_value = instruction->getOperand(1);\n\tauto *false_value = instruction->getOperand(2);\n\tconst llvm::CallInst *clz_instruction = nullptr;\n\n\t// Optimize clz(x) == -1 ? -1 : (bits - 1 - clz(x)) -> findmsb(x)\n\n\tif (auto *cmp = llvm::dyn_cast<llvm::CmpInst>(cond))\n\t{\n\t\tif (cmp->getPredicate() != llvm::CmpInst::Predicate::ICMP_EQ)\n\t\t\treturn false;\n\n\t\tif (!value_is_dx_op_instrinsic(cmp->getOperand(0), DXIL::Op::FirstbitHi) &&\n\t\t    !value_is_dx_op_instrinsic(cmp->getOperand(0), DXIL::Op::FirstbitSHi))\n\t\t\treturn false;\n\n\t\tuint32_t const_val = 0;\n\t\tif (!get_constant_operand(cmp, 1, &const_val) || const_val != UINT32_MAX)\n\t\t\treturn false;\n\n\t\tclz_instruction = llvm::cast<llvm::CallInst>(cmp->getOperand(0));\n\t}\n\telse\n\t\treturn false;\n\n\tif (auto *true_const_value = llvm::dyn_cast<llvm::ConstantInt>(true_value))\n\t{\n\t\tif (true_const_value->getUniqueInteger().getSExtValue() != -1)\n\t\t\treturn false;\n\t}\n\telse\n\t\treturn false;\n\n\tif (auto *sub_inst = llvm::dyn_cast<llvm::BinaryOperator>(false_value))\n\t{\n\t\tif (sub_inst->getOpcode() != llvm::Instruction::BinaryOps::Sub)\n\t\t\treturn false;\n\n\t\tif (sub_inst->getOperand(1) != clz_instruction)\n\t\t\treturn false;\n\n\t\tuint32_t const_val = 0;\n\t\tif (!get_constant_operand(sub_inst, 0, &const_val) ||\n\t\t    const_val != clz_instruction->getOperand(1)->getType()->getIntegerBitWidth() - 1)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t\treturn false;\n\n\tGLSLstd450 opcode;\n\tif (value_is_dx_op_instrinsic(clz_instruction, DXIL::Op::FirstbitHi))\n\t\topcode = GLSLstd450FindUMsb;\n\telse\n\t\topcode = GLSLstd450FindSMsb;\n\n\temit_native_bitscan(opcode, impl, instruction, clz_instruction->getOperand(1));\n\treturn true;\n}\n\nbool emit_select_instruction(Converter::Impl &impl, const llvm::SelectInst *instruction)\n{\n\tif (emit_peephole_findmsb(impl, instruction))\n\t\treturn true;\n\n\tOperation *op = impl.allocate(spv::OpSelect, instruction);\n\n\tfor (unsigned i = 0; i < 3; i++)\n\t\top->add_id(impl.get_id_for_value(instruction->getOperand(i)));\n\n\timpl.add(op);\n\timpl.decorate_relaxed_precision(instruction->getType(), op->id, false);\n\treturn true;\n}\n\nbool emit_cmpxchg_instruction(Converter::Impl &impl, const llvm::AtomicCmpXchgInst *instruction)\n{\n\tauto &builder = impl.builder();\n\n\tunsigned bits;\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::StructTyID)\n\t\tbits = get_composite_element_type(instruction->getType())->getIntegerBitWidth();\n\telse\n\t\tbits = instruction->getType()->getIntegerBitWidth();\n\n\tif (bits == 64)\n\t\tbuilder.addCapability(spv::CapabilityInt64Atomics);\n\n\tOperation *atomic_op = impl.allocate(spv::OpAtomicCompareExchange, builder.makeUintType(bits));\n\tif (needs_group_shared_auto_barrier(impl, instruction->getPointerOperand()))\n\t\tatomic_op->flags |= Operation::AutoGroupSharedBarrier;\n\n\tatomic_op->add_id(impl.get_id_for_value(instruction->getPointerOperand()));\n\n\tatomic_op->add_id(builder.makeUintConstant(spv::ScopeWorkgroup));\n\tatomic_op->add_id(builder.makeUintConstant(0));\n\tatomic_op->add_id(builder.makeUintConstant(0));\n\tatomic_op->add_id(impl.get_id_for_value(instruction->getNewValOperand()));\n\tatomic_op->add_id(impl.get_id_for_value(instruction->getCompareOperand()));\n\n\timpl.add(atomic_op);\n\n\tif (instruction->getType()->getTypeID() == llvm::Type::TypeID::StructTyID)\n\t{\n\t\tOperation *cmp_op = impl.allocate(spv::OpIEqual, builder.makeBoolType());\n\t\tcmp_op->add_ids({ atomic_op->id, impl.get_id_for_value(instruction->getCompareOperand()) });\n\t\timpl.add(cmp_op);\n\n\t\tspv::Id cmpxchg_type = impl.get_struct_type({ builder.makeUintType(bits), builder.makeBoolType() }, 0, \"CmpXchgResult\");\n\n\t\tOperation *op = impl.allocate(spv::OpCompositeConstruct, instruction, cmpxchg_type);\n\t\top->add_ids({ atomic_op->id, cmp_op->id });\n\t\timpl.add(op);\n\t}\n\telse\n\t{\n\t\t// Extension for custom IR, we don't care about success bit.\n\t\timpl.rewrite_value(instruction, atomic_op->id);\n\t}\n\n\treturn true;\n}\n\nbool emit_atomicrmw_instruction(Converter::Impl &impl, const llvm::AtomicRMWInst *instruction)\n{\n\tif (emit_ags_atomicrmw(impl, instruction))\n\t\treturn true;\n\n\tauto &builder = impl.builder();\n\tspv::Op opcode;\n\tswitch (instruction->getOperation())\n\t{\n\tcase llvm::AtomicRMWInst::BinOp::Add:\n\t\topcode = spv::OpAtomicIAdd;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::Sub:\n\t\topcode = spv::OpAtomicISub;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::And:\n\t\topcode = spv::OpAtomicAnd;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::Or:\n\t\topcode = spv::OpAtomicOr;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::Xor:\n\t\topcode = spv::OpAtomicXor;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::UMax:\n\t\topcode = spv::OpAtomicUMax;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::UMin:\n\t\topcode = spv::OpAtomicUMin;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::Max:\n\t\topcode = spv::OpAtomicSMax;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::Min:\n\t\topcode = spv::OpAtomicSMin;\n\t\tbreak;\n\n\tcase llvm::AtomicRMWInst::BinOp::Xchg:\n\t\topcode = spv::OpAtomicExchange;\n\t\tbreak;\n\n\tdefault:\n\t\tLOGE(\"Unrecognized atomicrmw opcode: %u.\\n\", unsigned(instruction->getOperation()));\n\t\treturn false;\n\t}\n\n\tunsigned bits = instruction->getType()->getIntegerBitWidth();\n\tif (bits == 64)\n\t\tbuilder.addCapability(spv::CapabilityInt64Atomics);\n\n\tOperation *op = impl.allocate(opcode, instruction);\n\tif (needs_group_shared_auto_barrier(impl, instruction->getPointerOperand()))\n\t\top->flags |= Operation::AutoGroupSharedBarrier;\n\n\top->add_id(impl.get_id_for_value(instruction->getPointerOperand()));\n\n\top->add_id(builder.makeUintConstant(spv::ScopeWorkgroup));\n\top->add_id(builder.makeUintConstant(0));\n\top->add_id(impl.get_id_for_value(instruction->getValOperand()));\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_shufflevector_instruction(Converter::Impl &impl, const llvm::ShuffleVectorInst *inst)\n{\n\tOperation *op = impl.allocate(spv::OpVectorShuffle, inst);\n\n\tfor (unsigned i = 0; i < 2; i++)\n\t\top->add_id(impl.get_id_for_value(inst->getOperand(i)));\n\n\tunsigned num_outputs = inst->getType()->getVectorNumElements();\n\tfor (unsigned i = 0; i < num_outputs; i++)\n\t\top->add_literal(inst->getMaskValue(i));\n\n\timpl.add(op);\n\treturn true;\n}\n\nbool emit_extractelement_instruction(Converter::Impl &impl, const llvm::ExtractElementInst *inst)\n{\n\tspv::Id id;\n\tif (auto *constant_int = llvm::dyn_cast<llvm::ConstantInt>(inst->getIndexOperand()))\n\t{\n\t\tOperation *op = impl.allocate(spv::OpCompositeExtract, inst);\n\t\top->add_id(impl.get_id_for_value(inst->getVectorOperand()));\n\t\top->add_literal(uint32_t(constant_int->getUniqueInteger().getZExtValue()));\n\t\timpl.add(op);\n\t\tid = op->id;\n\t}\n\telse\n\t{\n\t\tOperation *op = impl.allocate(spv::OpVectorExtractDynamic, inst);\n\t\top->add_id(impl.get_id_for_value(inst->getVectorOperand()));\n\t\top->add_id(impl.get_id_for_value(inst->getIndexOperand()));\n\t\timpl.add(op);\n\t\tid = op->id;\n\t}\n\timpl.decorate_relaxed_precision(inst->getType(), id, false);\n\treturn true;\n}\n\nbool emit_insertelement_instruction(Converter::Impl &impl, const llvm::InsertElementInst *inst)\n{\n\tauto *vec = inst->getOperand(0);\n\tauto *value = inst->getOperand(1);\n\tauto *index = inst->getOperand(2);\n\n\tif (!llvm::isa<llvm::ConstantInt>(index))\n\t{\n\t\tLOGE(\"Index to insertelement must be a constant.\\n\");\n\t\treturn false;\n\t}\n\tOperation *op = impl.allocate(spv::OpCompositeInsert, inst);\n\top->add_id(impl.get_id_for_value(value));\n\top->add_id(impl.get_id_for_value(vec));\n\top->add_literal(uint32_t(llvm::cast<llvm::ConstantInt>(index)->getUniqueInteger().getZExtValue()));\n\timpl.add(op);\n\treturn true;\n}\n\nbool analyze_getelementptr_instruction(Converter::Impl &impl, const llvm::GetElementPtrInst *inst)\n{\n\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(inst->getOperand(0));\n\tif (itr != impl.llvm_global_variable_to_resource_mapping.end() &&\n\t    !emit_getelementptr_resource(impl, inst, itr->second))\n\t{\n\t\treturn false;\n\t}\n\n\t// If this GEP is associated with a tracked alloca, we might want to mask the GEP\n\t// if this GEP is actually never consumed.\n\t// Avoids lots of dead code being emitted which looks goofy in disassemblies.\n\tauto tracking = gep_pointer_to_alloca_tracked_inst(impl, inst);\n\tif (tracking.alloca_inst)\n\t\timpl.masked_alloca_forward_gep.insert(inst);\n\n\treturn true;\n}\n\nbool analyze_load_instruction(Converter::Impl &impl, const llvm::LoadInst *inst)\n{\n\tauto tracked = gep_pointer_to_alloca_tracked_inst(impl, inst->getPointerOperand());\n\tif (tracked.cbv_handle)\n\t{\n\t\ttracked.itr->second.has_load = true;\n\t\t// We'll need this GEP after all.\n\t\timpl.masked_alloca_forward_gep.erase(llvm::cast<llvm::GetElementPtrInst>(inst->getPointerOperand()));\n\t}\n\n\tif (DXIL::AddressSpace(inst->getPointerOperand()->getType()->getPointerAddressSpace()) == DXIL::AddressSpace::GroupShared)\n\t\timpl.shader_analysis.has_group_shared_access = true;\n\n\tif (auto *const_expr = llvm::dyn_cast<llvm::ConstantExpr>(inst->getPointerOperand()))\n\t{\n\t\tif (const_expr->getOpcode() == llvm::Instruction::GetElementPtr)\n\t\t{\n\t\t\tauto *ptr = const_expr->getOperand(0);\n\t\t\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(ptr);\n\t\t\tif (itr != impl.llvm_global_variable_to_resource_mapping.end() &&\n\t\t\t    !emit_getelementptr_resource(impl, const_expr, itr->second))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\tauto itr = impl.llvm_global_variable_to_resource_mapping.find(inst->getPointerOperand());\n\tif (itr != impl.llvm_global_variable_to_resource_mapping.end())\n\t\timpl.llvm_global_variable_to_resource_mapping[inst] = itr->second;\n\n\treturn true;\n}\n\nstatic bool analyze_alloca_store(Converter::Impl &impl,\n                                 const llvm::AllocaInst *alloca_inst,\n                                 AllocaCBVForwardingTracking &tracking,\n                                 const llvm::Value *index,\n                                 const llvm::Value *store_value)\n{\n\t// If we observe store after load, invalidate.\n\t// Instructions are processed in domination order, so this kind of linear tracking is fine.\n\t// If a store instruction is reachable after a load, it will be processed after the load.\n\tif (tracking.has_load)\n\t\treturn false;\n\n\t// Need to store with constant GEP index.\n\tconst auto *const_index = llvm::dyn_cast<llvm::ConstantInt>(index);\n\tif (!const_index)\n\t\treturn false;\n\n\tuint32_t store_index = const_index->getUniqueInteger().getZExtValue();\n\n\t// This needs to be extractvalue from a cbuffer load, that is directly stored into alloca().\n\t// Ignore non-legacy cbuffer for now. Can be expanded as needed. Non-legacy cbuffer is very rare.\n\tconst auto *extract_value = llvm::dyn_cast<llvm::ExtractValueInst>(store_value);\n\tif (!extract_value)\n\t\treturn false;\n\n\tconst auto *aggregate = extract_value->getAggregateOperand();\n\tif (!value_is_dx_op_instrinsic(aggregate, DXIL::Op::CBufferLoadLegacy))\n\t\treturn false;\n\n\tconst auto *cbuf_load = llvm::cast<llvm::CallInst>(aggregate);\n\tconst auto *cbuffer_handle = cbuf_load->getOperand(1);\n\tif (tracking.cbv_handle && cbuffer_handle != tracking.cbv_handle)\n\t\treturn false;\n\n\tconst auto *cbv_index = llvm::dyn_cast<llvm::ConstantInt>(cbuf_load->getOperand(2));\n\tif (!cbv_index)\n\t\treturn false;\n\n\tuint32_t scalar_index_offset =\n\t\tcbv_index->getUniqueInteger().getZExtValue() * 4 + extract_value->getIndices()[0];\n\n\t// Don't want negative word offsets, that does not make much sense.\n\tif (scalar_index_offset < store_index)\n\t\treturn false;\n\n\tif (tracking.cbv_handle)\n\t{\n\t\t// Redundant store just needs to be validated.\n\t\tif (store_index == 0)\n\t\t\treturn tracking.scalar_index_offset == scalar_index_offset;\n\n\t\t// Negative stride. Non-sense.\n\t\tif (scalar_index_offset < tracking.scalar_index_offset)\n\t\t\treturn false;\n\n\t\tscalar_index_offset -= tracking.scalar_index_offset;\n\t\tuint32_t stride = scalar_index_offset / store_index;\n\n\t\t// Awkward and doesn't happen in practice. We use this as sentinel.\n\t\tif (stride == 0)\n\t\t\treturn false;\n\n\t\t// This comes up when alloca-ing vectors. We end up with multiple scalar arrays.\n\t\t// When accessing the CBV we have to multiply the stride back up again.\n\t\tif ((tracking.stride && stride != tracking.stride) || (scalar_index_offset % stride != 0))\n\t\t\treturn false;\n\n\t\ttracking.stride = stride;\n\t}\n\telse\n\t{\n\t\t// The first store should be to offset 0. This latches base values.\n\t\tif (store_index != 0)\n\t\t\treturn false;\n\n\t\t// Must observe a write to last element, for robustness reasons.\n\t\t// We only need to care about this for BDA, but always checking is fine with shaders in the wild.\n\t\ttracking.min_highest_store_index = alloca_inst->getType()->getPointerElementType()->getArrayNumElements() - 1;\n\t\ttracking.cbv_handle = cbuffer_handle;\n\t\ttracking.scalar_index_offset = scalar_index_offset;\n\t}\n\n\ttracking.highest_store_index = std::max<uint32_t>(tracking.highest_store_index, store_index);\n\treturn true;\n}\n\nstatic void register_ray_query_mapping(Converter::Impl &impl, const llvm::Value *store_value,\n                                       const llvm::Value *store_ptr)\n{\n\tif (!value_is_dx_op_instrinsic(store_value, DXIL::Op::AllocateRayQuery))\n\t\treturn;\n\n\tif (auto *gep = llvm::dyn_cast<llvm::GetElementPtrInst>(store_ptr))\n\t{\n\t\tif (auto *alloca = llvm::dyn_cast<llvm::AllocaInst>(gep->getOperand(0)))\n\t\t{\n\t\t\tauto &mappings = impl.shader_analysis.ray_query.alloca_mappings;\n\t\t\tauto itr = std::find_if(mappings.begin(), mappings.end(),\n\t\t\t\t\t\t\t\t\t[&](const auto &mapping) { return mapping.alloca == alloca; });\n\n\t\t\tif (itr == mappings.end())\n\t\t\t{\n\t\t\t\tuint32_t ray_flags;\n\t\t\t\tif (get_constant_operand(llvm::cast<llvm::CallInst>(store_value), 1, &ray_flags))\n\t\t\t\t\tmappings.push_back({ alloca, ray_flags });\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool analyze_phi_instruction(Converter::Impl &impl, const llvm::PHINode *instruction)\n{\n\t// Just need to forward the mapping in case it's used as a store to alloca.\n\tspv::Id override_type = 0;\n\tags_filter_phi(impl, *instruction, override_type);\n\treturn true;\n}\n\nbool analyze_store_instruction(Converter::Impl &impl, const llvm::StoreInst *inst)\n{\n\tauto tracked = gep_pointer_to_alloca_tracked_inst(impl, inst->getOperand(1));\n\tif (tracked.index && !analyze_alloca_store(\n\t\timpl, tracked.alloca_inst,\n\t\ttracked.itr->second, tracked.index, inst->getOperand(0)))\n\t{\n\t\timpl.alloca_tracking.erase(tracked.itr);\n\t}\n\n\tif (DXIL::AddressSpace(inst->getOperand(1)->getType()->getPointerAddressSpace()) == DXIL::AddressSpace::GroupShared)\n\t\timpl.shader_analysis.has_group_shared_access = true;\n\n\tif (!analyze_ags_wmma_store(impl, inst))\n\t\treturn false;\n\n\t// If we store ray query allocas into an array we need to mark the compile time constant ray query flags.\n\tregister_ray_query_mapping(impl, inst->getOperand(0), inst->getOperand(1));\n\n\t// Assume we're consuming the entire uvec4.\n\tif (instruction_is_ballot(inst->getOperand(0)))\n\t{\n\t\timpl.shader_analysis.subgroup_ballot_reads_first = true;\n\t\timpl.shader_analysis.subgroup_ballot_reads_upper = true;\n\t}\n\n\treturn true;\n}\n\nbool analyze_atomicrmw_instruction(Converter::Impl &impl, const llvm::AtomicRMWInst *inst)\n{\n\tif (DXIL::AddressSpace(inst->getPointerOperand()->getType()->getPointerAddressSpace()) == DXIL::AddressSpace::GroupShared)\n\t\timpl.shader_analysis.has_group_shared_access = true;\n\treturn true;\n}\n\nbool analyze_cmpxchg_instruction(Converter::Impl &impl, const llvm::AtomicCmpXchgInst *inst)\n{\n\tif (DXIL::AddressSpace(inst->getPointerOperand()->getType()->getPointerAddressSpace()) == DXIL::AddressSpace::GroupShared)\n\t\timpl.shader_analysis.has_group_shared_access = true;\n\treturn true;\n}\n\nbool analyze_alloca_instruction(Converter::Impl &impl, const llvm::AllocaInst *inst)\n{\n\t// Only attempt to track simple 32-bit scalar cases.\n\t// We don't want to deal with DXR vector types, or weird 16-bit promotion shenanigans.\n\tif (DXIL::AddressSpace(inst->getType()->getAddressSpace()) != DXIL::AddressSpace::Thread)\n\t\treturn true;\n\n\tif (const auto *array_type = llvm::dyn_cast<llvm::ArrayType>(inst->getType()->getPointerElementType()))\n\t{\n\t\tauto *elem_type = array_type->getArrayElementType();\n\t\tbool simple_scalar;\n\n\t\tswitch (elem_type->getTypeID())\n\t\t{\n\t\tcase llvm::Type::TypeID::FloatTyID:\n\t\t\tsimple_scalar = true;\n\t\t\tbreak;\n\n\t\tcase llvm::Type::TypeID::IntegerTyID:\n\t\t\tsimple_scalar = elem_type->getIntegerBitWidth() == 32;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tsimple_scalar = false;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (simple_scalar)\n\t\t\timpl.alloca_tracking[inst] = {};\n\t}\n\n\treturn true;\n}\n\nstatic void analyze_extractvalue_instruction(\n    Converter::Impl &impl, const llvm::Value *aggregate, unsigned index)\n{\n\tauto &meta = impl.llvm_composite_meta[aggregate];\n\tbool forward_progress = false;\n\tconst auto *phi = llvm::dyn_cast<llvm::PHINode>(aggregate);\n\n\tbool is_fake_struct =\n\t    std::find(impl.llvm_dxil_op_fake_struct_types.begin(),\n\t              impl.llvm_dxil_op_fake_struct_types.end(), aggregate->getType()) !=\n\t    impl.llvm_dxil_op_fake_struct_types.end();\n\n\tbool splat_composite_access = phi && index < 4 && is_fake_struct;\n\n\tif (splat_composite_access)\n\t{\n\t\tif ((meta.access_mask & 0xf) != 0xf)\n\t\t{\n\t\t\tmeta.access_mask |= 0xf;\n\t\t\tmeta.components = std::max<uint32_t>(4, meta.components);\n\t\t\tforward_progress = true;\n\t\t}\n\t}\n\telse if ((meta.access_mask & (1u << index)) == 0)\n\t{\n\t\tmeta.access_mask |= 1u << index;\n\t\tmeta.components = std::max<uint32_t>(index + 1, meta.components);\n\t\tforward_progress = true;\n\t}\n\n\tif (instruction_is_ballot(aggregate))\n\t{\n\t\tif (index == 0)\n\t\t\timpl.shader_analysis.subgroup_ballot_reads_first = true;\n\t\telse\n\t\t\timpl.shader_analysis.subgroup_ballot_reads_upper = true;\n\t}\n\telse if (forward_progress && phi)\n\t{\n\t\t// Incoming values to a PHI aggregate must also be flagged as having access.\n\t\t// Try to avoid potential cycles if there are PHIs in a loop.\n\t\tfor (uint32_t i = 0; i < phi->getNumIncomingValues(); i++)\n\t\t{\n\t\t\tif (splat_composite_access)\n\t\t\t{\n\t\t\t\t// Enforce that we get the full 4 components from a normal resource load.\n\t\t\t\tfor (uint32_t c = 0; c < 4; c++)\n\t\t\t\t\tanalyze_extractvalue_instruction(impl, phi->getIncomingValue(i), c);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tanalyze_extractvalue_instruction(impl, phi->getIncomingValue(i), index);\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool analyze_extractvalue_instruction(Converter::Impl &impl, const llvm::ExtractValueInst *inst)\n{\n\tif (inst->getNumIndices() == 1 && type_is_composite_return_value(inst->getAggregateOperand()->getType()))\n\t\tanalyze_extractvalue_instruction(impl, inst->getAggregateOperand(), inst->getIndices()[0]);\n\treturn true;\n}\n\nbool analyze_compare_instruction(Converter::Impl &impl, const llvm::CmpInst *inst)\n{\n\t// With patterns like WaveReadFirstLane(x) == x, we have to be extremely careful.\n\t// A boolean like this will generally be used in control flow later, and if this is in a loop,\n\t// we risk infinite loops. This is technically undefined in DX without WaveOpsIncludeHelperLanes,\n\t// but games rely on it working ... somehow :')\n\n\tif (inst->getPredicate() != llvm::CmpInst::Predicate::ICMP_EQ &&\n\t    inst->getPredicate() != llvm::CmpInst::Predicate::ICMP_NE)\n\t{\n\t\treturn true;\n\t}\n\n\tauto *op0 = inst->getOperand(0);\n\tauto *op1 = inst->getOperand(1);\n\n\tbool op0_is_read_first = value_is_dx_op_instrinsic(op0, DXIL::Op::WaveReadLaneFirst);\n\tbool op1_is_read_first = value_is_dx_op_instrinsic(op1, DXIL::Op::WaveReadLaneFirst);\n\tif (op1_is_read_first)\n\t{\n\t\tstd::swap(op0, op1);\n\t\tstd::swap(op0_is_read_first, op1_is_read_first);\n\t}\n\n\tif (op0_is_read_first && !op1_is_read_first)\n\t{\n\t\tauto *call = llvm::cast<llvm::CallInst>(op0);\n\t\tif (call->getOperand(1) == op1)\n\t\t\timpl.wave_op_forced_helper_lanes.insert(call);\n\t}\n\n\treturn true;\n}\n\nbool can_optimize_conditional_branch_to_static(\n    Converter::Impl &impl, const llvm::Value *value, bool &static_cond)\n{\n\t// Can be expanded as needed.\n\t// For now, search for common exhaustive loop unrolling patterns that DXC farts out.\n\t// Expect pattern of:\n\t// lower_bounded_expression > constant.\n\t// In the shader we've seen, we have: constant / WaveGetLaneCount(), which\n\t// we must narrow the bound of to avoid generating invalid code.\n\tconst auto *comp_inst = llvm::dyn_cast<llvm::CmpInst>(value);\n\tif (!comp_inst)\n\t\treturn false;\n\n\tif (comp_inst->getPredicate() != llvm::CmpInst::Predicate::ICMP_UGT)\n\t\treturn false;\n\n\tconst auto *rhs = llvm::dyn_cast<llvm::ConstantInt>(comp_inst->getOperand(1));\n\tif (!rhs)\n\t\treturn false;\n\n\tuint64_t rhs_value = rhs->getUniqueInteger().getZExtValue();\n\n\tconst auto *lhs = llvm::dyn_cast<llvm::BinaryOperator>(comp_inst->getOperand(0));\n\tif (!lhs)\n\t\treturn false;\n\n\tif (lhs->getOpcode() != llvm::BinaryOperator::BinaryOps::UDiv)\n\t\treturn false;\n\n\tconst auto *num = llvm::dyn_cast<llvm::ConstantInt>(lhs->getOperand(0));\n\tif (!num)\n\t\treturn false;\n\tif (!value_is_dx_op_instrinsic(lhs->getOperand(1), DXIL::Op::WaveGetLaneCount))\n\t\treturn false;\n\n\tuint64_t upper_bound =\n\t    num->getUniqueInteger().getZExtValue() / impl.options.subgroup_size.implementation_minimum;\n\tuint64_t lower_bound =\n\t\tnum->getUniqueInteger().getZExtValue() / impl.options.subgroup_size.implementation_maximum;\n\n\tif (lower_bound > rhs_value)\n\t{\n\t\tstatic_cond = true;\n\t\treturn true;\n\t}\n\telse if (rhs_value >= upper_bound)\n\t{\n\t\tstatic_cond = false;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\tstatic_cond = false;\n\t\treturn false;\n\t}\n}\n\n#ifdef HAVE_LLVMBC\n// Extensions to normal LLVM API used by custom IR.\nstatic bool emit_composite_construct_instruction(Converter::Impl &impl, const llvm::CompositeConstructInst *inst)\n{\n\tauto *constr = impl.allocate(spv::OpCompositeConstruct, inst);\n\tfor (unsigned i = 0; i < inst->getNumOperands(); i++)\n\t\tconstr->add_id(impl.get_id_for_value(inst->getOperand(i)));\n\timpl.add(constr);\n\treturn true;\n}\n#endif\n\nbool emit_call_instruction(Converter::Impl &impl, const llvm::CallInst &inst)\n{\n\tauto *call = impl.allocate(spv::OpFunctionCall, &inst);\n\tcall->add_id(impl.get_id_for_value(inst.getCalledFunction()));\n\tfor (uint32_t i = 0; i < inst.getNumOperands(); i++)\n\t\tcall->add_id(impl.get_id_for_value(inst.getOperand(i)));\n\timpl.add(call);\n\treturn true;\n}\n\nbool emit_llvm_instruction(Converter::Impl &impl, const llvm::Instruction &instruction)\n{\n\tif (auto *binary_inst = llvm::dyn_cast<llvm::BinaryOperator>(&instruction))\n\t\treturn emit_binary_instruction(impl, binary_inst);\n\telse if (auto *unary_inst = llvm::dyn_cast<llvm::UnaryOperator>(&instruction))\n\t\treturn emit_unary_instruction(impl, unary_inst);\n\telse if (auto *cast_inst = llvm::dyn_cast<llvm::CastInst>(&instruction))\n\t\treturn emit_cast_instruction(impl, cast_inst);\n\telse if (auto *getelementptr_inst = llvm::dyn_cast<llvm::GetElementPtrInst>(&instruction))\n\t\treturn emit_getelementptr_instruction(impl, getelementptr_inst);\n\telse if (auto *load_inst = llvm::dyn_cast<llvm::LoadInst>(&instruction))\n\t\treturn emit_load_instruction(impl, load_inst);\n\telse if (auto *store_inst = llvm::dyn_cast<llvm::StoreInst>(&instruction))\n\t\treturn emit_store_instruction(impl, store_inst);\n\telse if (auto *compare_inst = llvm::dyn_cast<llvm::CmpInst>(&instruction))\n\t\treturn emit_compare_instruction(impl, compare_inst);\n\telse if (auto *extract_inst = llvm::dyn_cast<llvm::ExtractValueInst>(&instruction))\n\t\treturn emit_extract_value_instruction(impl, extract_inst);\n\telse if (auto *alloca_inst = llvm::dyn_cast<llvm::AllocaInst>(&instruction))\n\t\treturn emit_alloca_instruction(impl, alloca_inst);\n\telse if (auto *select_inst = llvm::dyn_cast<llvm::SelectInst>(&instruction))\n\t\treturn emit_select_instruction(impl, select_inst);\n\telse if (auto *atomic_inst = llvm::dyn_cast<llvm::AtomicRMWInst>(&instruction))\n\t\treturn emit_atomicrmw_instruction(impl, atomic_inst);\n\telse if (auto *cmpxchg_inst = llvm::dyn_cast<llvm::AtomicCmpXchgInst>(&instruction))\n\t\treturn emit_cmpxchg_instruction(impl, cmpxchg_inst);\n\telse if (auto *shufflevec_inst = llvm::dyn_cast<llvm::ShuffleVectorInst>(&instruction))\n\t\treturn emit_shufflevector_instruction(impl, shufflevec_inst);\n\telse if (auto *extractelement_inst = llvm::dyn_cast<llvm::ExtractElementInst>(&instruction))\n\t\treturn emit_extractelement_instruction(impl, extractelement_inst);\n\telse if (auto *insertelement_inst = llvm::dyn_cast<llvm::InsertElementInst>(&instruction))\n\t\treturn emit_insertelement_instruction(impl, insertelement_inst);\n#ifdef HAVE_LLVMBC\n\telse if (auto *composite_construct_inst = llvm::dyn_cast<llvm::CompositeConstructInst>(&instruction))\n\t\treturn emit_composite_construct_instruction(impl, composite_construct_inst);\n#endif\n\telse\n\t\treturn false;\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "opcodes/opcodes_llvm_builtins.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"opcodes.hpp\"\n\nnamespace dxil_spv\n{\nbool emit_binary_instruction(Converter::Impl &impl, const llvm::BinaryOperator *instruction);\nbool emit_unary_instruction(Converter::Impl &impl, const llvm::UnaryOperator *instruction);\nbool emit_cast_instruction(Converter::Impl &impl, const llvm::CastInst *instruction);\nbool emit_getelementptr_instruction(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction);\nbool emit_load_instruction(Converter::Impl &impl, const llvm::LoadInst *instruction);\nbool emit_store_instruction(Converter::Impl &impl, const llvm::StoreInst *instruction);\nbool emit_compare_instruction(Converter::Impl &impl, const llvm::CmpInst *instruction);\nbool emit_extract_value_instruction(Converter::Impl &impl, const llvm::ExtractValueInst *instruction);\nbool emit_alloca_instruction(Converter::Impl &impl, const llvm::AllocaInst *instruction);\nbool emit_select_instruction(Converter::Impl &impl, const llvm::SelectInst *instruction);\nbool emit_atomicrmw_instruction(Converter::Impl &impl, const llvm::AtomicRMWInst *instruction);\nbool emit_cmpxchg_instruction(Converter::Impl &impl, const llvm::AtomicCmpXchgInst *instruction);\nbool emit_shufflevector_instruction(Converter::Impl &impl, const llvm::ShuffleVectorInst *instruction);\nbool emit_extractelement_instruction(Converter::Impl &impl, const llvm::ExtractElementInst *instruction);\nbool emit_insertelement_instruction(Converter::Impl &impl, const llvm::InsertElementInst *instruction);\n\nbool analyze_load_instruction(Converter::Impl &impl, const llvm::LoadInst *instruction);\nbool analyze_store_instruction(Converter::Impl &impl, const llvm::StoreInst *instruction);\nbool analyze_phi_instruction(Converter::Impl &impl, const llvm::PHINode *instruction);\nbool analyze_atomicrmw_instruction(Converter::Impl &impl, const llvm::AtomicRMWInst *instruction);\nbool analyze_cmpxchg_instruction(Converter::Impl &impl, const llvm::AtomicCmpXchgInst *instruction);\nbool analyze_alloca_instruction(Converter::Impl &impl, const llvm::AllocaInst *instruction);\nbool analyze_getelementptr_instruction(Converter::Impl &impl, const llvm::GetElementPtrInst *instruction);\nbool analyze_extractvalue_instruction(Converter::Impl &impl, const llvm::ExtractValueInst *instruction);\nbool analyze_compare_instruction(Converter::Impl &impl, const llvm::CmpInst *instruction);\n\nbool emit_llvm_instruction(Converter::Impl &impl, const llvm::Instruction &instruction);\nbool emit_call_instruction(Converter::Impl &impl, const llvm::CallInst &instruction);\n\nunsigned physical_integer_bit_width(unsigned width);\n\nspv::Id build_constant_expression(Converter::Impl &impl, const llvm::ConstantExpr *cexpr);\n\nbool can_optimize_conditional_branch_to_static(Converter::Impl &impl, const llvm::Value *value, bool &static_cond_value);\n\nbool can_optimize_to_snegate(const llvm::BinaryOperator *inst);\nbool can_optimize_to_snegate(const llvm::ConstantExpr *inst);\n\nspv::Id emit_bypass_fp16_trunc(Converter::Impl &impl, const llvm::Instruction *instruction);\n} // namespace dxil_spv\n"
  },
  {
    "path": "pkg-config/dxil-spirv-c-shared.pc.in",
    "content": "prefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=@CMAKE_INSTALL_PREFIX@\nlibdir=@DXIL_SPV_INSTALL_LIB_DIR@\nsharedlibdir=@DXIL_SPV_INSTALL_LIB_DIR@\nincludedir=@DXIL_SPV_INSTALL_INC_DIR@\n\nName: dxil-spirv-c-shared\nDescription: C API for dxil-spirv\nVersion: @DXIL_SPV_VERSION@\n\nRequires:\nLibs: -L${libdir} -L${sharedlibdir} -ldxil-spirv-c-shared\nCflags: -I${includedir}\n"
  },
  {
    "path": "reference/shaders/ags/ags.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_image_int64 : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) buffer _12_14\n{\n    uint64_t _m0[];\n} _14;\n\nlayout(set = 0, binding = 4, std430) buffer _25_27\n{\n    uint _m0[];\n} _27;\n\nlayout(set = 0, binding = 4, std430) buffer _30_32\n{\n    uvec2 _m0[];\n} _32;\n\nlayout(set = 0, binding = 1, r64ui) uniform u64image1D _17;\nlayout(set = 0, binding = 2, r64ui) uniform u64image2D _20;\nlayout(set = 0, binding = 3, r64ui) uniform u64image3D _23;\n\nvoid main()\n{\n    uint64_t _58 = atomicMax(_14._m0[gl_GlobalInvocationID.x], packUint2x32(uvec2(40u, 50u)));\n    _32._m0[gl_GlobalInvocationID.x] = uvec2(unpackUint2x32(_58));\n    uint64_t _71 = imageAtomicMin(_17, int(gl_GlobalInvocationID.x), packUint2x32(uvec2(60u, 70u)));\n    uvec2 _72 = unpackUint2x32(_71);\n    _32._m0[gl_GlobalInvocationID.x] = uvec2(_32._m0[gl_GlobalInvocationID.x].x + _72.x, _32._m0[gl_GlobalInvocationID.x].y + _72.y);\n    uint64_t _89 = imageAtomicXor(_20, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), packUint2x32(uvec2(80u, 90u)));\n    uvec2 _90 = unpackUint2x32(_89);\n    _32._m0[gl_GlobalInvocationID.x] = uvec2(_32._m0[gl_GlobalInvocationID.x].x + _90.x, _32._m0[gl_GlobalInvocationID.x].y + _90.y);\n    uint64_t _107 = imageAtomicAdd(_23, ivec3(uvec3(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, gl_GlobalInvocationID.z)), packUint2x32(uvec2(100u, 110u)));\n    uvec2 _108 = unpackUint2x32(_107);\n    _32._m0[gl_GlobalInvocationID.x] = uvec2(_32._m0[gl_GlobalInvocationID.x].x + _108.x, _32._m0[gl_GlobalInvocationID.x].y + _108.y);\n    uint _119 = gl_GlobalInvocationID.x << 4u;\n    _27._m0[gl_GlobalInvocationID.x * 2u] += subgroupBroadcastFirst(_119);\n    _27._m0[gl_GlobalInvocationID.x * 2u] = uint(float(_27._m0[gl_GlobalInvocationID.x * 2u]) + uintBitsToFloat(subgroupBroadcastFirst(floatBitsToUint(float(gl_GlobalInvocationID.y << 4u)))));\n    _27._m0[(gl_GlobalInvocationID.x * 2u) + 1u] = _32._m0[gl_GlobalInvocationID.x].y + subgroupBroadcast(gl_GlobalInvocationID.z << 4u, 7u);\n    _27._m0[(gl_GlobalInvocationID.x * 2u) + 1u] = uint(float(_32._m0[gl_GlobalInvocationID.x].y) + uintBitsToFloat(subgroupBroadcast(floatBitsToUint(float(_119)), 9u)));\n    _32._m0[gl_GlobalInvocationID.x] = uvec2(_32._m0[gl_GlobalInvocationID.x].x + gl_SubgroupInvocationID, _32._m0[gl_GlobalInvocationID.x].y + gl_SubgroupInvocationID);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 179\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability Image1D\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability Int64ImageEXT\nOpExtension \"SPV_EXT_shader_image_int64\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %39 %167\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %25 \"SSBO\"\nOpName %30 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 Aliased\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 Aliased\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 1\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 2\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 3\nOpDecorate %24 ArrayStride 4\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %29 ArrayStride 8\nOpMemberDecorate %30 0 Offset 0\nOpDecorate %30 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 4\nOpDecorate %27 Aliased\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 4\nOpDecorate %32 Aliased\nOpDecorate %39 BuiltIn GlobalInvocationId\nOpDecorate %167 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeInt 64 0\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeImage %10 1D 0 0 0 2 R64ui\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %10 2D 0 0 0 2 R64ui\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %10 3D 0 0 0 2 R64ui\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeRuntimeArray %5\n%25 = OpTypeStruct %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeVector %5 2\n%29 = OpTypeRuntimeArray %28\n%30 = OpTypeStruct %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%37 = OpTypeVector %5 3\n%38 = OpTypePointer Input %37\n%39 = OpVariable %38 Input\n%40 = OpTypePointer Input %5\n%42 = OpConstant %5 0\n%45 = OpConstant %5 1\n%48 = OpConstant %5 2\n%51 = OpConstant %5 3\n%52 = OpTypePointer StorageBuffer %10\n%54 = OpConstant %5 40\n%55 = OpConstant %5 50\n%63 = OpTypePointer StorageBuffer %28\n%65 = OpTypePointer Image %10\n%67 = OpConstant %5 60\n%68 = OpConstant %5 70\n%85 = OpConstant %5 80\n%86 = OpConstant %5 90\n%103 = OpConstant %5 100\n%104 = OpConstant %5 110\n%120 = OpConstant %5 4\n%123 = OpTypePointer StorageBuffer %5\n%130 = OpTypeFloat 32\n%145 = OpConstant %5 7\n%156 = OpConstant %5 9\n%167 = OpVariable %40 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %177\n%177 = OpLabel\n%34 = OpLoad %21 %23\n%35 = OpLoad %18 %20\n%36 = OpLoad %15 %17\n%41 = OpAccessChain %40 %39 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %40 %39 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %40 %39 %48\n%49 = OpLoad %5 %47\n%50 = OpShiftLeftLogical %5 %43 %51\n%53 = OpAccessChain %52 %14 %42 %43\n%56 = OpCompositeConstruct %28 %54 %55\n%57 = OpBitcast %10 %56\n%58 = OpAtomicUMax %10 %53 %45 %42 %57\n%59 = OpBitcast %28 %58\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpCompositeExtract %5 %59 1\n%62 = OpCompositeConstruct %28 %60 %61\n%64 = OpAccessChain %63 %32 %42 %43\nOpStore %64 %62\n%66 = OpImageTexelPointer %65 %17 %43 %42\n%69 = OpCompositeConstruct %28 %67 %68\n%70 = OpBitcast %10 %69\n%71 = OpAtomicUMin %10 %66 %45 %42 %70\n%72 = OpBitcast %28 %71\n%73 = OpCompositeExtract %5 %72 0\n%74 = OpCompositeExtract %5 %72 1\n%75 = OpAccessChain %63 %32 %42 %43\n%76 = OpLoad %28 %75\n%77 = OpCompositeExtract %5 %76 0\n%78 = OpCompositeExtract %5 %76 1\n%79 = OpIAdd %5 %77 %73\n%80 = OpIAdd %5 %78 %74\n%81 = OpCompositeConstruct %28 %79 %80\n%82 = OpAccessChain %63 %32 %42 %43\nOpStore %82 %81\n%83 = OpCompositeConstruct %28 %43 %46\n%84 = OpImageTexelPointer %65 %20 %83 %42\n%87 = OpCompositeConstruct %28 %85 %86\n%88 = OpBitcast %10 %87\n%89 = OpAtomicXor %10 %84 %45 %42 %88\n%90 = OpBitcast %28 %89\n%91 = OpCompositeExtract %5 %90 0\n%92 = OpCompositeExtract %5 %90 1\n%93 = OpAccessChain %63 %32 %42 %43\n%94 = OpLoad %28 %93\n%95 = OpCompositeExtract %5 %94 0\n%96 = OpCompositeExtract %5 %94 1\n%97 = OpIAdd %5 %95 %91\n%98 = OpIAdd %5 %96 %92\n%99 = OpCompositeConstruct %28 %97 %98\n%100 = OpAccessChain %63 %32 %42 %43\nOpStore %100 %99\n%101 = OpCompositeConstruct %37 %43 %46 %49\n%102 = OpImageTexelPointer %65 %23 %101 %42\n%105 = OpCompositeConstruct %28 %103 %104\n%106 = OpBitcast %10 %105\n%107 = OpAtomicIAdd %10 %102 %45 %42 %106\n%108 = OpBitcast %28 %107\n%109 = OpCompositeExtract %5 %108 0\n%110 = OpCompositeExtract %5 %108 1\n%111 = OpAccessChain %63 %32 %42 %43\n%112 = OpLoad %28 %111\n%113 = OpCompositeExtract %5 %112 0\n%114 = OpCompositeExtract %5 %112 1\n%115 = OpIAdd %5 %113 %109\n%116 = OpIAdd %5 %114 %110\n%117 = OpCompositeConstruct %28 %115 %116\n%118 = OpAccessChain %63 %32 %42 %43\nOpStore %118 %117\n%119 = OpShiftLeftLogical %5 %43 %120\n%121 = OpGroupNonUniformBroadcastFirst %5 %51 %119\n%122 = OpIMul %5 %43 %48\n%124 = OpAccessChain %123 %27 %42 %122\n%125 = OpLoad %5 %124\n%126 = OpIAdd %5 %125 %121\n%127 = OpIMul %5 %43 %48\n%128 = OpAccessChain %123 %27 %42 %127\nOpStore %128 %126\n%129 = OpShiftLeftLogical %5 %46 %120\n%131 = OpConvertUToF %130 %129\n%132 = OpBitcast %5 %131\n%133 = OpGroupNonUniformBroadcastFirst %5 %51 %132\n%134 = OpBitcast %130 %133\n%135 = OpIMul %5 %43 %48\n%136 = OpAccessChain %123 %27 %42 %135\n%137 = OpLoad %5 %136\n%138 = OpConvertUToF %130 %137\n%139 = OpFAdd %130 %138 %134\n%140 = OpConvertFToU %5 %139\n%141 = OpIMul %5 %43 %48\n%142 = OpAccessChain %123 %27 %42 %141\nOpStore %142 %140\n%143 = OpShiftLeftLogical %5 %49 %120\n%144 = OpGroupNonUniformBroadcast %5 %51 %143 %145\n%146 = OpAccessChain %63 %32 %42 %43\n%147 = OpLoad %28 %146\n%148 = OpCompositeExtract %5 %147 1\n%149 = OpIAdd %5 %148 %144\n%150 = OpIMul %5 %43 %48\n%151 = OpIAdd %5 %150 %45\n%152 = OpAccessChain %123 %27 %42 %151\nOpStore %152 %149\n%153 = OpConvertUToF %130 %119\n%154 = OpBitcast %5 %153\n%155 = OpGroupNonUniformBroadcast %5 %51 %154 %156\n%157 = OpBitcast %130 %155\n%158 = OpAccessChain %63 %32 %42 %43\n%159 = OpLoad %28 %158\n%160 = OpCompositeExtract %5 %159 1\n%161 = OpConvertUToF %130 %160\n%162 = OpFAdd %130 %161 %157\n%163 = OpConvertFToU %5 %162\n%164 = OpIMul %5 %43 %48\n%165 = OpIAdd %5 %164 %45\n%166 = OpAccessChain %123 %27 %42 %165\nOpStore %166 %163\n%168 = OpLoad %5 %167\n%169 = OpAccessChain %63 %32 %42 %43\n%170 = OpLoad %28 %169\n%171 = OpCompositeExtract %5 %170 0\n%172 = OpCompositeExtract %5 %170 1\n%173 = OpIAdd %5 %171 %168\n%174 = OpIAdd %5 %172 %168\n%175 = OpCompositeConstruct %28 %173 %174\n%176 = OpAccessChain %63 %32 %42 %43\nOpStore %176 %175\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_constexpr_wmma_gep.sm66.full-wmma.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_float_e4m3 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\ncoopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _29[5] = coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>[](coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(floate4m3_t(0.0)));\ncoopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33[5] = coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>[](coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(floate4m3_t(0.0)), coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(floate4m3_t(0.0)));\n\nvoid main()\n{\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _38;\n    coopMatLoad(_38, _20._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    _29[0u] = _38;\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _43;\n    coopMatLoad(_43, _20._m0, 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    _33[0u] = _43;\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _48;\n    coopMatLoad(_48, _20._m0, 32u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    _29[1u] = _48;\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _52;\n    coopMatLoad(_52, _20._m0, 1056u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    _33[1u] = _52;\n    uint _54;\n    _54 = 2u;\n    for (;;)\n    {\n        uint _56 = _54 << 5u;\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _58;\n        coopMatLoad(_58, _20._m0, _56, 64u, gl_CooperativeMatrixLayoutRowMajor);\n        _29[_54] = _58;\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _89;\n        coopMatLoad(_89, _20._m0, _56 + 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n        _33[_54] = _89;\n        uint _55 = _54 + 1u;\n        if (_55 == 5u)\n        {\n            break;\n        }\n        else\n        {\n            _54 = _55;\n        }\n    }\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _128;\n    uint _130;\n    _128 = coopMatMulAdd(_29[1u], _33[1u], coopMatMulAdd(_29[0u], _33[0u], coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0.0), 0), 0);\n    _130 = 2u;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _196;\n    for (;;)\n    {\n        _196 = coopMatMulAdd(_29[_130], _33[_130], _128, 0);\n        uint _131 = _130 + 1u;\n        if (_131 == 5u)\n        {\n            break;\n        }\n        else\n        {\n            _128 = _196;\n            _130 = _131;\n        }\n    }\n    coopMatStore(_196, _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 205\n; Schema: 0\nOpCapability Shader\nOpCapability Int8\nOpCapability Float8EXT\nOpCapability Float8CooperativeMatrixEXT\nOpCapability StorageBuffer8BitAccess\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_EXT_float8\"\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24 %29 %33\nOpExecutionMode %14 LocalSize 32 1 1\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 8 Float8E4M3EXT\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpConstant %2 5\n%26 = OpTypeArray %5 %25\n%27 = OpConstantNull %26\n%28 = OpTypePointer Private %26\n%29 = OpVariable %28 Private %27\n%30 = OpTypeArray %8 %25\n%31 = OpConstantNull %30\n%32 = OpTypePointer Private %30\n%33 = OpVariable %32 Private %31\n%35 = OpTypePointer StorageBuffer %16\n%37 = OpConstant %2 64\n%39 = OpTypePointer Private %5\n%42 = OpConstant %2 1024\n%44 = OpTypePointer Private %8\n%47 = OpConstant %2 32\n%51 = OpConstant %2 1056\n%60 = OpConstant %2 8\n%74 = OpConstant %2 4\n%81 = OpConstant %2 6\n%85 = OpConstant %2 7\n%114 = OpTypeBool\n%116 = OpConstant %9 0\n%117 = OpConstantComposite %11 %116\n%14 = OpFunction %12 None %13\n%15 = OpLabel\nOpBranch %199\n%199 = OpLabel\n%36 = OpAccessChain %35 %20 %3 %3\n%38 = OpCooperativeMatrixLoadKHR %5 %36 %3 %37 NonPrivatePointer\n%40 = OpAccessChain %39 %29 %3\nOpStore %40 %38\n%41 = OpAccessChain %35 %20 %3 %42\n%43 = OpCooperativeMatrixLoadKHR %8 %41 %7 %37 NonPrivatePointer\n%45 = OpAccessChain %44 %33 %3\nOpStore %45 %43\n%46 = OpAccessChain %35 %20 %3 %47\n%48 = OpCooperativeMatrixLoadKHR %5 %46 %3 %37 NonPrivatePointer\n%49 = OpAccessChain %39 %29 %7\nOpStore %49 %48\n%50 = OpAccessChain %35 %20 %3 %51\n%52 = OpCooperativeMatrixLoadKHR %8 %50 %7 %37 NonPrivatePointer\n%53 = OpAccessChain %44 %33 %7\nOpStore %53 %52\nOpBranch %200\n%200 = OpLabel\n%54 = OpPhi %2 %10 %199 %55 %200\n%56 = OpShiftLeftLogical %2 %54 %25\n%57 = OpAccessChain %35 %20 %3 %56\n%58 = OpCooperativeMatrixLoadKHR %5 %57 %3 %37 NonPrivatePointer\n%59 = OpIMul %2 %54 %60\n%61 = OpIAdd %2 %3 %59\n%62 = OpAccessChain %39 %29 %54\nOpStore %62 %58\n%63 = OpIMul %2 %54 %60\n%64 = OpIAdd %2 %7 %63\n%66 = OpIMul %2 %54 %60\n%67 = OpIAdd %2 %10 %66\n%69 = OpIMul %2 %54 %60\n%70 = OpIAdd %2 %6 %69\n%72 = OpIMul %2 %54 %60\n%73 = OpIAdd %2 %74 %72\n%76 = OpIMul %2 %54 %60\n%77 = OpIAdd %2 %25 %76\n%79 = OpIMul %2 %54 %60\n%80 = OpIAdd %2 %81 %79\n%83 = OpIMul %2 %54 %60\n%84 = OpIAdd %2 %85 %83\n%87 = OpIAdd %2 %56 %42\n%88 = OpAccessChain %35 %20 %3 %87\n%89 = OpCooperativeMatrixLoadKHR %8 %88 %7 %37 NonPrivatePointer\n%90 = OpIMul %2 %54 %60\n%91 = OpIAdd %2 %3 %90\n%92 = OpAccessChain %44 %33 %54\nOpStore %92 %89\n%93 = OpIMul %2 %54 %60\n%94 = OpIAdd %2 %7 %93\n%96 = OpIMul %2 %54 %60\n%97 = OpIAdd %2 %10 %96\n%99 = OpIMul %2 %54 %60\n%100 = OpIAdd %2 %6 %99\n%102 = OpIMul %2 %54 %60\n%103 = OpIAdd %2 %74 %102\n%105 = OpIMul %2 %54 %60\n%106 = OpIAdd %2 %25 %105\n%108 = OpIMul %2 %54 %60\n%109 = OpIAdd %2 %81 %108\n%111 = OpIMul %2 %54 %60\n%112 = OpIAdd %2 %85 %111\n%55 = OpIAdd %2 %54 %7\n%115 = OpIEqual %114 %55 %25\nOpLoopMerge %201 %200 None\nOpBranchConditional %115 %201 %200\n%201 = OpLabel\n%118 = OpAccessChain %39 %29 %3\n%119 = OpLoad %5 %118\n%120 = OpAccessChain %44 %33 %3\n%121 = OpLoad %8 %120\n%122 = OpCooperativeMatrixMulAddKHR %11 %119 %121 %117\n%123 = OpAccessChain %39 %29 %7\n%124 = OpLoad %5 %123\n%125 = OpAccessChain %44 %33 %7\n%126 = OpLoad %8 %125\n%127 = OpCooperativeMatrixMulAddKHR %11 %124 %126 %122\nOpBranch %202\n%202 = OpLabel\n%128 = OpPhi %11 %127 %201 %196 %202\n%130 = OpPhi %2 %10 %201 %131 %202\n%132 = OpIMul %2 %130 %60\n%133 = OpIAdd %2 %3 %132\n%134 = OpAccessChain %39 %29 %130\n%135 = OpLoad %5 %134\n%136 = OpIMul %2 %130 %60\n%137 = OpIAdd %2 %7 %136\n%140 = OpIMul %2 %130 %60\n%141 = OpIAdd %2 %10 %140\n%144 = OpIMul %2 %130 %60\n%145 = OpIAdd %2 %6 %144\n%148 = OpIMul %2 %130 %60\n%149 = OpIAdd %2 %74 %148\n%152 = OpIMul %2 %130 %60\n%153 = OpIAdd %2 %25 %152\n%156 = OpIMul %2 %130 %60\n%157 = OpIAdd %2 %81 %156\n%160 = OpIMul %2 %130 %60\n%161 = OpIAdd %2 %85 %160\n%164 = OpIMul %2 %130 %60\n%165 = OpIAdd %2 %3 %164\n%166 = OpAccessChain %44 %33 %130\n%167 = OpLoad %8 %166\n%168 = OpIMul %2 %130 %60\n%169 = OpIAdd %2 %7 %168\n%172 = OpIMul %2 %130 %60\n%173 = OpIAdd %2 %10 %172\n%176 = OpIMul %2 %130 %60\n%177 = OpIAdd %2 %6 %176\n%180 = OpIMul %2 %130 %60\n%181 = OpIAdd %2 %74 %180\n%184 = OpIMul %2 %130 %60\n%185 = OpIAdd %2 %25 %184\n%188 = OpIMul %2 %130 %60\n%189 = OpIAdd %2 %81 %188\n%192 = OpIMul %2 %130 %60\n%193 = OpIAdd %2 %85 %192\n%196 = OpCooperativeMatrixMulAddKHR %11 %135 %167 %128\n%131 = OpIAdd %2 %130 %7\n%197 = OpIEqual %114 %131 %25\nOpLoopMerge %203 %202 None\nOpBranchConditional %197 %203 %202\n%203 = OpLabel\n%198 = OpAccessChain %35 %24 %3 %3\nOpCooperativeMatrixStoreKHR %198 %196 %7 %37 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_constexpr_wmma_gep.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _29[5] = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>[](coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(float16_t(0.0)));\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33[5] = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>[](coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(float16_t(0.0)), coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(float16_t(0.0)));\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _43)\n{\n    uint _51;\n    _51 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _52 = _51 + 1u;\n        coop_output[_51] = int16BitsToFloat16((int16_t(int8_t(_43[_51])) << 7s) & (-16385s));\n        if (_52 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _51 = _52;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _80)\n{\n    uint _88;\n    _88 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _89 = _88 + 1u;\n        coop_output[_88] = int16BitsToFloat16((int16_t(int8_t(_80[_88])) << 7s) & (-16385s));\n        if (_89 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _88 = _89;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _39;\n    coopMatLoad(_39, _20._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _70 = _39;\n    _29[0u] = CoopMatFP8toFP16(_70);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _77;\n    coopMatLoad(_77, _20._m0, 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _101 = _77;\n    _33[0u] = CoopMatFP8toFP16_1(_101);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _107;\n    coopMatLoad(_107, _20._m0, 32u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _108 = _107;\n    _29[1u] = CoopMatFP8toFP16(_108);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _113;\n    coopMatLoad(_113, _20._m0, 1056u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _114 = _113;\n    _33[1u] = CoopMatFP8toFP16_1(_114);\n    uint _117;\n    _117 = 2u;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _122;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _155;\n    for (;;)\n    {\n        uint _119 = _117 << 5u;\n        coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _121;\n        coopMatLoad(_121, _20._m0, _119, 64u, gl_CooperativeMatrixLayoutRowMajor);\n        _122 = _121;\n        _29[_117] = CoopMatFP8toFP16(_122);\n        coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _154;\n        coopMatLoad(_154, _20._m0, _119 + 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n        _155 = _154;\n        _33[_117] = CoopMatFP8toFP16_1(_155);\n        uint _118 = _117 + 1u;\n        if (_118 == 5u)\n        {\n            break;\n        }\n        else\n        {\n            _117 = _118;\n        }\n    }\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _194;\n    uint _196;\n    _194 = coopMatMulAdd(_29[1u], _33[1u], coopMatMulAdd(_29[0u], _33[0u], coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0.0), 0), 0);\n    _196 = 2u;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _262;\n    for (;;)\n    {\n        _262 = coopMatMulAdd(_29[_196], _33[_196], _194, 0);\n        uint _197 = _196 + 1u;\n        if (_197 == 5u)\n        {\n            break;\n        }\n        else\n        {\n            _194 = _262;\n            _196 = _197;\n        }\n    }\n    coopMatStore(_262, _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 271\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24 %29 %33\nOpExecutionMode %14 LocalSize 32 1 1\nOpExecutionMode %14 DenormPreserve 16\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %44 \"CoopMatFP8toFP16\"\nOpName %47 \"coop_output\"\nOpName %81 \"CoopMatFP8toFP16\"\nOpName %84 \"coop_output\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpConstant %2 5\n%26 = OpTypeArray %5 %25\n%27 = OpConstantNull %26\n%28 = OpTypePointer Private %26\n%29 = OpVariable %28 Private %27\n%30 = OpTypeArray %8 %25\n%31 = OpConstantNull %30\n%32 = OpTypePointer Private %30\n%33 = OpVariable %32 Private %31\n%35 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %3\n%36 = OpTypePointer StorageBuffer %16\n%38 = OpConstant %2 64\n%40 = OpTypeBool\n%41 = OpTypePointer Function %35\n%42 = OpTypeFunction %5 %41\n%46 = OpTypePointer Function %5\n%53 = OpTypePointer Function %16\n%56 = OpTypeInt 16 1\n%59 = OpConstant %56 7\n%61 = OpConstant %56 -16385\n%63 = OpTypePointer Function %1\n%68 = OpConstant %1 0x1p+8\n%72 = OpTypePointer Private %5\n%74 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %7\n%76 = OpConstant %2 1024\n%78 = OpTypePointer Function %74\n%79 = OpTypeFunction %8 %78\n%83 = OpTypePointer Function %8\n%103 = OpTypePointer Private %8\n%106 = OpConstant %2 32\n%112 = OpConstant %2 1056\n%125 = OpConstant %2 8\n%139 = OpConstant %2 4\n%146 = OpConstant %2 6\n%150 = OpConstant %2 7\n%182 = OpConstant %9 0\n%183 = OpConstantComposite %11 %182\n%14 = OpFunction %12 None %13\n%15 = OpLabel\n%70 = OpVariable %41 Function\n%101 = OpVariable %78 Function\n%108 = OpVariable %41 Function\n%114 = OpVariable %78 Function\n%122 = OpVariable %41 Function\n%155 = OpVariable %78 Function\nOpBranch %265\n%265 = OpLabel\n%37 = OpAccessChain %36 %20 %3 %3\n%39 = OpCooperativeMatrixLoadKHR %35 %37 %3 %38 NonPrivatePointer\nOpStore %70 %39\n%71 = OpFunctionCall %5 %44 %70\n%73 = OpAccessChain %72 %29 %3\nOpStore %73 %71\n%75 = OpAccessChain %36 %20 %3 %76\n%77 = OpCooperativeMatrixLoadKHR %74 %75 %7 %38 NonPrivatePointer\nOpStore %101 %77\n%102 = OpFunctionCall %8 %81 %101\n%104 = OpAccessChain %103 %33 %3\nOpStore %104 %102\n%105 = OpAccessChain %36 %20 %3 %106\n%107 = OpCooperativeMatrixLoadKHR %35 %105 %3 %38 NonPrivatePointer\nOpStore %108 %107\n%109 = OpFunctionCall %5 %44 %108\n%110 = OpAccessChain %72 %29 %7\nOpStore %110 %109\n%111 = OpAccessChain %36 %20 %3 %112\n%113 = OpCooperativeMatrixLoadKHR %74 %111 %7 %38 NonPrivatePointer\nOpStore %114 %113\n%115 = OpFunctionCall %8 %81 %114\n%116 = OpAccessChain %103 %33 %7\nOpStore %116 %115\nOpBranch %266\n%266 = OpLabel\n%117 = OpPhi %2 %10 %265 %118 %266\n%119 = OpShiftLeftLogical %2 %117 %25\n%120 = OpAccessChain %36 %20 %3 %119\n%121 = OpCooperativeMatrixLoadKHR %35 %120 %3 %38 NonPrivatePointer\nOpStore %122 %121\n%123 = OpFunctionCall %5 %44 %122\n%124 = OpIMul %2 %117 %125\n%126 = OpIAdd %2 %3 %124\n%127 = OpAccessChain %72 %29 %117\nOpStore %127 %123\n%128 = OpIMul %2 %117 %125\n%129 = OpIAdd %2 %7 %128\n%131 = OpIMul %2 %117 %125\n%132 = OpIAdd %2 %10 %131\n%134 = OpIMul %2 %117 %125\n%135 = OpIAdd %2 %6 %134\n%137 = OpIMul %2 %117 %125\n%138 = OpIAdd %2 %139 %137\n%141 = OpIMul %2 %117 %125\n%142 = OpIAdd %2 %25 %141\n%144 = OpIMul %2 %117 %125\n%145 = OpIAdd %2 %146 %144\n%148 = OpIMul %2 %117 %125\n%149 = OpIAdd %2 %150 %148\n%152 = OpIAdd %2 %119 %76\n%153 = OpAccessChain %36 %20 %3 %152\n%154 = OpCooperativeMatrixLoadKHR %74 %153 %7 %38 NonPrivatePointer\nOpStore %155 %154\n%156 = OpFunctionCall %8 %81 %155\n%157 = OpIMul %2 %117 %125\n%158 = OpIAdd %2 %3 %157\n%159 = OpAccessChain %103 %33 %117\nOpStore %159 %156\n%160 = OpIMul %2 %117 %125\n%161 = OpIAdd %2 %7 %160\n%163 = OpIMul %2 %117 %125\n%164 = OpIAdd %2 %10 %163\n%166 = OpIMul %2 %117 %125\n%167 = OpIAdd %2 %6 %166\n%169 = OpIMul %2 %117 %125\n%170 = OpIAdd %2 %139 %169\n%172 = OpIMul %2 %117 %125\n%173 = OpIAdd %2 %25 %172\n%175 = OpIMul %2 %117 %125\n%176 = OpIAdd %2 %146 %175\n%178 = OpIMul %2 %117 %125\n%179 = OpIAdd %2 %150 %178\n%118 = OpIAdd %2 %117 %7\n%181 = OpIEqual %40 %118 %25\nOpLoopMerge %267 %266 None\nOpBranchConditional %181 %267 %266\n%267 = OpLabel\n%184 = OpAccessChain %72 %29 %3\n%185 = OpLoad %5 %184\n%186 = OpAccessChain %103 %33 %3\n%187 = OpLoad %8 %186\n%188 = OpCooperativeMatrixMulAddKHR %11 %185 %187 %183\n%189 = OpAccessChain %72 %29 %7\n%190 = OpLoad %5 %189\n%191 = OpAccessChain %103 %33 %7\n%192 = OpLoad %8 %191\n%193 = OpCooperativeMatrixMulAddKHR %11 %190 %192 %188\nOpBranch %268\n%268 = OpLabel\n%194 = OpPhi %11 %193 %267 %262 %268\n%196 = OpPhi %2 %10 %267 %197 %268\n%198 = OpIMul %2 %196 %125\n%199 = OpIAdd %2 %3 %198\n%200 = OpAccessChain %72 %29 %196\n%201 = OpLoad %5 %200\n%202 = OpIMul %2 %196 %125\n%203 = OpIAdd %2 %7 %202\n%206 = OpIMul %2 %196 %125\n%207 = OpIAdd %2 %10 %206\n%210 = OpIMul %2 %196 %125\n%211 = OpIAdd %2 %6 %210\n%214 = OpIMul %2 %196 %125\n%215 = OpIAdd %2 %139 %214\n%218 = OpIMul %2 %196 %125\n%219 = OpIAdd %2 %25 %218\n%222 = OpIMul %2 %196 %125\n%223 = OpIAdd %2 %146 %222\n%226 = OpIMul %2 %196 %125\n%227 = OpIAdd %2 %150 %226\n%230 = OpIMul %2 %196 %125\n%231 = OpIAdd %2 %3 %230\n%232 = OpAccessChain %103 %33 %196\n%233 = OpLoad %8 %232\n%234 = OpIMul %2 %196 %125\n%235 = OpIAdd %2 %7 %234\n%238 = OpIMul %2 %196 %125\n%239 = OpIAdd %2 %10 %238\n%242 = OpIMul %2 %196 %125\n%243 = OpIAdd %2 %6 %242\n%246 = OpIMul %2 %196 %125\n%247 = OpIAdd %2 %139 %246\n%250 = OpIMul %2 %196 %125\n%251 = OpIAdd %2 %25 %250\n%254 = OpIMul %2 %196 %125\n%255 = OpIAdd %2 %146 %254\n%258 = OpIMul %2 %196 %125\n%259 = OpIAdd %2 %150 %258\n%262 = OpCooperativeMatrixMulAddKHR %11 %201 %233 %194\n%197 = OpIAdd %2 %196 %7\n%263 = OpIEqual %40 %197 %25\nOpLoopMerge %269 %268 None\nOpBranchConditional %263 %269 %268\n%269 = OpLabel\n%264 = OpAccessChain %36 %24 %3 %3\nOpCooperativeMatrixStoreKHR %264 %262 %7 %38 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%44 = OpFunction %5 None %42\n%43 = OpFunctionParameter %41\n%45 = OpLabel\n%47 = OpVariable %46 Function\n%48 = OpCooperativeMatrixLengthKHR %2 %35\nOpBranch %49\n%49 = OpLabel\n%51 = OpPhi %2 %3 %45 %52 %49\n%52 = OpIAdd %2 %51 %7\n%54 = OpInBoundsAccessChain %53 %43 %51\n%55 = OpLoad %16 %54\n%57 = OpSConvert %56 %55\n%58 = OpShiftLeftLogical %56 %57 %59\n%60 = OpBitwiseAnd %56 %58 %61\n%62 = OpBitcast %1 %60\n%64 = OpInBoundsAccessChain %63 %47 %51\nOpStore %64 %62\n%65 = OpULessThan %40 %52 %48\nOpLoopMerge %50 %49 None\nOpBranchConditional %65 %49 %50\n%50 = OpLabel\n%66 = OpLoad %5 %47\n%67 = OpMatrixTimesScalar %5 %66 %68\nOpReturnValue %67\nOpFunctionEnd\n%81 = OpFunction %8 None %79\n%80 = OpFunctionParameter %78\n%82 = OpLabel\n%84 = OpVariable %83 Function\n%85 = OpCooperativeMatrixLengthKHR %2 %74\nOpBranch %86\n%86 = OpLabel\n%88 = OpPhi %2 %3 %82 %89 %86\n%89 = OpIAdd %2 %88 %7\n%90 = OpInBoundsAccessChain %53 %80 %88\n%91 = OpLoad %16 %90\n%92 = OpSConvert %56 %91\n%93 = OpShiftLeftLogical %56 %92 %59\n%94 = OpBitwiseAnd %56 %93 %61\n%95 = OpBitcast %1 %94\n%96 = OpInBoundsAccessChain %63 %84 %88\nOpStore %96 %95\n%97 = OpULessThan %40 %89 %85\nOpLoopMerge %87 %86 None\nOpBranchConditional %97 %86 %87\n%87 = OpLabel\n%98 = OpLoad %8 %84\n%99 = OpMatrixTimesScalar %8 %98 %68\nOpReturnValue %99\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_alloca.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\nvoid main()\n{\n    uint _34;\n    _34 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _32[2];\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _33[2];\n    for (;;)\n    {\n        uint _36 = _34 << 5u;\n        coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _42;\n        coopMatLoad(_42, _20._m0, _36, 64u, gl_CooperativeMatrixLayoutRowMajor);\n        _33[_34] = _42;\n        coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _75;\n        coopMatLoad(_75, _20._m0, _36 + 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n        _32[_34] = _75;\n        uint _35 = _34 + 1u;\n        if (_35 == 2u)\n        {\n            break;\n        }\n        else\n        {\n            _34 = _35;\n        }\n    }\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _105;\n    coopMatLoad(_105, _20._m0, 32u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _31[2];\n    _31[1u] = _105;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _123;\n    coopMatLoad(_123, _20._m0, 1056u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _28[2];\n    _28[1u] = _123;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _133;\n    coopMatLoad(_133, _20._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    _31[0u] = _133;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _143;\n    coopMatLoad(_143, _20._m0, 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    _28[0u] = _143;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _154;\n    uint _156;\n    _154 = coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0.0);\n    _156 = 0u;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _222;\n    for (;;)\n    {\n        _222 = coopMatMulAdd(_33[_156], _32[_156], _154, 0);\n        uint _157 = _156 + 1u;\n        if (_157 == 2u)\n        {\n            break;\n        }\n        else\n        {\n            _154 = _222;\n            _156 = _157;\n        }\n    }\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _224;\n    uint _226;\n    _224 = _222;\n    _226 = 0u;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _292;\n    for (;;)\n    {\n        _292 = coopMatMulAdd(_31[_226], _28[_226], _224, 0);\n        uint _227 = _226 + 1u;\n        if (_227 == 2u)\n        {\n            break;\n        }\n        else\n        {\n            _224 = _292;\n            _226 = _227;\n        }\n    }\n    coopMatStore(_292, _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 303\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24\nOpExecutionMode %14 LocalSize 32 1 1\nOpExecutionMode %14 DenormPreserve 16\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeArray %2 %4\n%26 = OpTypeArray %8 %10\n%27 = OpTypePointer Function %26\n%29 = OpTypeArray %5 %10\n%30 = OpTypePointer Function %29\n%37 = OpConstant %2 5\n%39 = OpTypePointer StorageBuffer %16\n%41 = OpConstant %2 64\n%44 = OpConstant %2 8\n%46 = OpTypePointer Function %5\n%59 = OpConstant %2 4\n%66 = OpConstant %2 6\n%70 = OpConstant %2 7\n%73 = OpConstant %2 1024\n%78 = OpTypePointer Function %8\n%101 = OpTypeBool\n%104 = OpConstant %2 32\n%108 = OpConstant %2 9\n%110 = OpConstant %2 10\n%112 = OpConstant %2 11\n%114 = OpConstant %2 12\n%116 = OpConstant %2 13\n%118 = OpConstant %2 14\n%120 = OpConstant %2 15\n%122 = OpConstant %2 1056\n%152 = OpConstant %9 0\n%153 = OpConstantComposite %11 %152\n%14 = OpFunction %12 None %13\n%15 = OpLabel\n%28 = OpVariable %27 Function\n%31 = OpVariable %30 Function\n%32 = OpVariable %27 Function\n%33 = OpVariable %30 Function\nOpBranch %295\n%295 = OpLabel\nOpBranch %296\n%296 = OpLabel\n%34 = OpPhi %2 %3 %295 %35 %296\n%36 = OpShiftLeftLogical %2 %34 %37\n%40 = OpAccessChain %39 %20 %3 %36\n%42 = OpCooperativeMatrixLoadKHR %5 %40 %3 %41 NonPrivatePointer\n%43 = OpIMul %2 %34 %44\n%45 = OpIAdd %2 %3 %43\n%47 = OpAccessChain %46 %33 %34\nOpStore %47 %42\n%48 = OpIMul %2 %34 %44\n%49 = OpIAdd %2 %7 %48\n%51 = OpIMul %2 %34 %44\n%52 = OpIAdd %2 %10 %51\n%54 = OpIMul %2 %34 %44\n%55 = OpIAdd %2 %6 %54\n%57 = OpIMul %2 %34 %44\n%58 = OpIAdd %2 %59 %57\n%61 = OpIMul %2 %34 %44\n%62 = OpIAdd %2 %37 %61\n%64 = OpIMul %2 %34 %44\n%65 = OpIAdd %2 %66 %64\n%68 = OpIMul %2 %34 %44\n%69 = OpIAdd %2 %70 %68\n%72 = OpIAdd %2 %36 %73\n%74 = OpAccessChain %39 %20 %3 %72\n%75 = OpCooperativeMatrixLoadKHR %8 %74 %7 %41 NonPrivatePointer\n%76 = OpIMul %2 %34 %44\n%77 = OpIAdd %2 %3 %76\n%79 = OpAccessChain %78 %32 %34\nOpStore %79 %75\n%80 = OpIMul %2 %34 %44\n%81 = OpIAdd %2 %7 %80\n%83 = OpIMul %2 %34 %44\n%84 = OpIAdd %2 %10 %83\n%86 = OpIMul %2 %34 %44\n%87 = OpIAdd %2 %6 %86\n%89 = OpIMul %2 %34 %44\n%90 = OpIAdd %2 %59 %89\n%92 = OpIMul %2 %34 %44\n%93 = OpIAdd %2 %37 %92\n%95 = OpIMul %2 %34 %44\n%96 = OpIAdd %2 %66 %95\n%98 = OpIMul %2 %34 %44\n%99 = OpIAdd %2 %70 %98\n%35 = OpIAdd %2 %34 %7\n%102 = OpIEqual %101 %35 %10\nOpLoopMerge %297 %296 None\nOpBranchConditional %102 %297 %296\n%297 = OpLabel\n%103 = OpAccessChain %39 %20 %3 %104\n%105 = OpCooperativeMatrixLoadKHR %5 %103 %3 %41 NonPrivatePointer\n%106 = OpAccessChain %46 %31 %7\nOpStore %106 %105\n%121 = OpAccessChain %39 %20 %3 %122\n%123 = OpCooperativeMatrixLoadKHR %8 %121 %7 %41 NonPrivatePointer\n%124 = OpAccessChain %78 %28 %7\nOpStore %124 %123\n%132 = OpAccessChain %39 %20 %3 %3\n%133 = OpCooperativeMatrixLoadKHR %5 %132 %3 %41 NonPrivatePointer\n%134 = OpAccessChain %46 %31 %3\nOpStore %134 %133\n%142 = OpAccessChain %39 %20 %3 %73\n%143 = OpCooperativeMatrixLoadKHR %8 %142 %7 %41 NonPrivatePointer\n%144 = OpAccessChain %78 %28 %3\nOpStore %144 %143\nOpBranch %298\n%298 = OpLabel\n%154 = OpPhi %11 %153 %297 %222 %298\n%156 = OpPhi %2 %3 %297 %157 %298\n%158 = OpIMul %2 %156 %44\n%159 = OpIAdd %2 %7 %158\n%162 = OpIMul %2 %156 %44\n%163 = OpIAdd %2 %3 %162\n%164 = OpAccessChain %46 %33 %156\n%165 = OpLoad %5 %164\n%166 = OpIMul %2 %156 %44\n%167 = OpIAdd %2 %6 %166\n%170 = OpIMul %2 %156 %44\n%171 = OpIAdd %2 %10 %170\n%174 = OpIMul %2 %156 %44\n%175 = OpIAdd %2 %37 %174\n%178 = OpIMul %2 %156 %44\n%179 = OpIAdd %2 %59 %178\n%182 = OpIMul %2 %156 %44\n%183 = OpIAdd %2 %70 %182\n%186 = OpIMul %2 %156 %44\n%187 = OpIAdd %2 %66 %186\n%190 = OpIMul %2 %156 %44\n%191 = OpIAdd %2 %7 %190\n%194 = OpIMul %2 %156 %44\n%195 = OpIAdd %2 %3 %194\n%196 = OpAccessChain %78 %32 %156\n%197 = OpLoad %8 %196\n%198 = OpIMul %2 %156 %44\n%199 = OpIAdd %2 %6 %198\n%202 = OpIMul %2 %156 %44\n%203 = OpIAdd %2 %10 %202\n%206 = OpIMul %2 %156 %44\n%207 = OpIAdd %2 %37 %206\n%210 = OpIMul %2 %156 %44\n%211 = OpIAdd %2 %59 %210\n%214 = OpIMul %2 %156 %44\n%215 = OpIAdd %2 %70 %214\n%218 = OpIMul %2 %156 %44\n%219 = OpIAdd %2 %66 %218\n%222 = OpCooperativeMatrixMulAddKHR %11 %165 %197 %154\n%157 = OpIAdd %2 %156 %7\n%223 = OpIEqual %101 %157 %10\nOpLoopMerge %299 %298 None\nOpBranchConditional %223 %299 %298\n%299 = OpLabel\nOpBranch %300\n%300 = OpLabel\n%224 = OpPhi %11 %222 %299 %292 %300\n%226 = OpPhi %2 %3 %299 %227 %300\n%228 = OpIMul %2 %226 %44\n%229 = OpIAdd %2 %7 %228\n%232 = OpIMul %2 %226 %44\n%233 = OpIAdd %2 %3 %232\n%234 = OpAccessChain %46 %31 %226\n%235 = OpLoad %5 %234\n%236 = OpIMul %2 %226 %44\n%237 = OpIAdd %2 %6 %236\n%240 = OpIMul %2 %226 %44\n%241 = OpIAdd %2 %10 %240\n%244 = OpIMul %2 %226 %44\n%245 = OpIAdd %2 %37 %244\n%248 = OpIMul %2 %226 %44\n%249 = OpIAdd %2 %59 %248\n%252 = OpIMul %2 %226 %44\n%253 = OpIAdd %2 %70 %252\n%256 = OpIMul %2 %226 %44\n%257 = OpIAdd %2 %66 %256\n%260 = OpIMul %2 %226 %44\n%261 = OpIAdd %2 %7 %260\n%264 = OpIMul %2 %226 %44\n%265 = OpIAdd %2 %3 %264\n%266 = OpAccessChain %78 %28 %226\n%267 = OpLoad %8 %266\n%268 = OpIMul %2 %226 %44\n%269 = OpIAdd %2 %6 %268\n%272 = OpIMul %2 %226 %44\n%273 = OpIAdd %2 %10 %272\n%276 = OpIMul %2 %226 %44\n%277 = OpIAdd %2 %37 %276\n%280 = OpIMul %2 %226 %44\n%281 = OpIAdd %2 %59 %280\n%284 = OpIMul %2 %226 %44\n%285 = OpIAdd %2 %70 %284\n%288 = OpIMul %2 %226 %44\n%289 = OpIAdd %2 %66 %288\n%292 = OpCooperativeMatrixMulAddKHR %11 %235 %267 %224\n%227 = OpIAdd %2 %226 %7\n%293 = OpIEqual %101 %227 %10\nOpLoopMerge %301 %300 None\nOpBranchConditional %293 %301 %300\n%301 = OpLabel\n%294 = OpAccessChain %39 %24 %3 %3\nOpCooperativeMatrixStoreKHR %294 %292 %7 %41 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_copy_transpose_fp16.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_spirv_intrinsics : require\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\nshared uint LDSTransposeScratch[256];\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> CoopMatSaturateFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _55)\n{\n    uint _62;\n    _62 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> coop_output;\n    for (;;)\n    {\n        uint _63 = _62 + 1u;\n        coop_output[_62] = spvNClamp(_55[_62], float16_t(-448.0), float16_t(448.0));\n        if (_63 < uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length()))\n        {\n            _62 = _63;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output;\n}\n\ncoopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP16toFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _91)\n{\n    uint _99;\n    _99 = 0u;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _100 = _99 + 2u;\n        uint _101 = _99 + 1u;\n        i16vec2 _107 = float16BitsToInt16(f16vec2(_91[_99], _91[_101]));\n        i16vec2 _117 = (_107 << i16vec2(1)) - i16vec2(16384);\n        i16vec2 _123 = (_117 >> i16vec2(11)) - i16vec2(1);\n        i16vec2 _138 = (_117 & ((_123 & i16vec2(-2048)) ^ i16vec2(-1))) | (_123 & i16vec2(2048));\n        i16vec2 _142 = _138 >> max((-_123), i16vec2(0));\n        i16vec2 _144 = i16vec2(u16vec2(_142) >> u16vec2(i16vec2(8)));\n        u8vec2 _159 = u8vec2(((_144 + i16vec2(greaterThan(u16vec2(((_144 & i16vec2(1)) | (_142 | (_138 & i16vec2(127)))) << i16vec2(8)), u16vec2(32768)))) & i16vec2(127)) | (i16vec2(u16vec2(_107) >> u16vec2(i16vec2(15))) << i16vec2(7)));\n        coop_output[_99] = _159.x;\n        coop_output[_101] = _159.y;\n        if (_100 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _99 = _100;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output;\n}\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _30;\n    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n    uint _38 = gl_SubgroupID * 256u;\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopMatStore(_30, LDSTransposeScratch, _38, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _42;\n    coopMatLoad(_42, LDSTransposeScratch, _38, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    uint _44 = gl_SubgroupID * 256u;\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopMatStore(_30, LDSTransposeScratch, _44, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _46;\n    coopMatLoad(_46, LDSTransposeScratch, _44, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _48 = coopMatMulAdd(_42, _46, coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(_30), 0);\n    coopMatStore(_48, _25._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _75 = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(_48);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _76 = CoopMatSaturateFP8(_75);\n    uint _78 = gl_SubgroupID * 256u;\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopMatStore(_76, LDSTransposeScratch, _78, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _80;\n    coopMatLoad(_80, LDSTransposeScratch, _78, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _168 = _80;\n    coopMatStore(CoopMatFP16toFP8(_168), _25._m0, 1024u, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    uint _171 = gl_SubgroupID * 256u;\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopMatStore(_80, LDSTransposeScratch, _171, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _173;\n    coopMatLoad(_173, LDSTransposeScratch, _171, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopMatStore(coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(_173), _25._m0, 2048u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 179\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability GroupNonUniform\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\n%67 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25 %34 %36\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %34 \"LDSTransposeScratch\"\nOpName %56 \"CoopMatSaturateFP8\"\nOpName %58 \"coop_output\"\nOpName %92 \"CoopMatFP16toFP8\"\nOpName %95 \"coop_output\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %36 BuiltIn SubgroupId\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 2\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 0\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpConstant %2 1\n%10 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %9\n%11 = OpTypeFloat 32\n%12 = OpTypeCooperativeMatrixKHR %11 %6 %4 %4 %3\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypePointer StorageBuffer %17\n%29 = OpConstant %2 32\n%31 = OpConstant %2 256\n%32 = OpTypeArray %2 %31\n%33 = OpTypePointer Workgroup %32\n%34 = OpVariable %33 Workgroup\n%35 = OpTypePointer Input %2\n%36 = OpVariable %35 Input\n%39 = OpTypePointer Workgroup %2\n%41 = OpConstant %2 24840\n%50 = OpConstant %2 64\n%52 = OpTypeBool\n%53 = OpTypePointer Function %5\n%54 = OpTypeFunction %5 %53\n%64 = OpTypePointer Function %1\n%69 = OpConstant %1 -0x1.cp+8\n%70 = OpConstant %1 0x1.cp+8\n%82 = OpConstant %2 1024\n%83 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %9\n%84 = OpTypeInt 16 1\n%85 = OpTypeVector %52 2\n%86 = OpTypeVector %1 2\n%87 = OpTypeVector %84 2\n%88 = OpTypeVector %17 2\n%89 = OpTypePointer Function %10\n%90 = OpTypeFunction %83 %89\n%94 = OpTypePointer Function %83\n%109 = OpConstant %84 15\n%110 = OpConstantComposite %87 %109 %109\n%112 = OpConstant %84 7\n%113 = OpConstantComposite %87 %112 %112\n%115 = OpConstant %84 1\n%116 = OpConstantComposite %87 %115 %115\n%118 = OpConstant %84 16384\n%119 = OpConstantComposite %87 %118 %118\n%121 = OpConstant %84 11\n%122 = OpConstantComposite %87 %121 %121\n%126 = OpConstant %84 0\n%127 = OpConstantComposite %87 %126 %126\n%129 = OpConstant %84 2048\n%130 = OpConstantComposite %87 %129 %129\n%132 = OpConstant %84 -2048\n%133 = OpConstantComposite %87 %132 %132\n%135 = OpConstant %84 -1\n%136 = OpConstantComposite %87 %135 %135\n%140 = OpConstant %84 127\n%141 = OpConstantComposite %87 %140 %140\n%145 = OpConstant %84 8\n%146 = OpConstantComposite %87 %145 %145\n%151 = OpTypeInt 16 0\n%152 = OpConstant %151 32768\n%153 = OpTypeVector %151 2\n%154 = OpConstantComposite %153 %152 %152\n%160 = OpTypePointer Function %17\n%176 = OpConstant %2 2048\n%15 = OpFunction %13 None %14\n%16 = OpLabel\n%75 = OpVariable %53 Function\n%168 = OpVariable %89 Function\nOpBranch %177\n%177 = OpLabel\n%28 = OpAccessChain %27 %21 %7 %7\n%30 = OpCooperativeMatrixLoadKHR %5 %28 %9 %29 NonPrivatePointer\n%37 = OpLoad %2 %36\n%38 = OpIMul %2 %37 %31\n%40 = OpInBoundsAccessChain %39 %34 %38\nOpControlBarrier %6 %6 %41\nOpCooperativeMatrixStoreKHR %40 %30 %9 %4 NonPrivatePointer\nOpControlBarrier %6 %6 %41\n%42 = OpCooperativeMatrixLoadKHR %8 %40 %9 %4 NonPrivatePointer\n%43 = OpLoad %2 %36\n%44 = OpIMul %2 %43 %31\n%45 = OpInBoundsAccessChain %39 %34 %44\nOpControlBarrier %6 %6 %41\nOpCooperativeMatrixStoreKHR %45 %30 %9 %4 NonPrivatePointer\nOpControlBarrier %6 %6 %41\n%46 = OpCooperativeMatrixLoadKHR %10 %45 %9 %4 NonPrivatePointer\n%47 = OpFConvert %12 %30\n%48 = OpCooperativeMatrixMulAddKHR %12 %42 %46 %47\n%49 = OpAccessChain %27 %25 %7 %7\nOpCooperativeMatrixStoreKHR %49 %48 %9 %50 NonPrivatePointer\n%51 = OpFConvert %5 %48\nOpStore %75 %51\n%76 = OpFunctionCall %5 %56 %75\n%77 = OpLoad %2 %36\n%78 = OpIMul %2 %77 %31\n%79 = OpInBoundsAccessChain %39 %34 %78\nOpControlBarrier %6 %6 %41\nOpCooperativeMatrixStoreKHR %79 %76 %9 %4 NonPrivatePointer\nOpControlBarrier %6 %6 %41\n%80 = OpCooperativeMatrixLoadKHR %10 %79 %9 %4 NonPrivatePointer\n%81 = OpAccessChain %27 %25 %7 %82\nOpStore %168 %80\n%169 = OpFunctionCall %83 %92 %168\nOpCooperativeMatrixStoreKHR %81 %169 %9 %4 NonPrivatePointer\n%170 = OpLoad %2 %36\n%171 = OpIMul %2 %170 %31\n%172 = OpInBoundsAccessChain %39 %34 %171\nOpControlBarrier %6 %6 %41\nOpCooperativeMatrixStoreKHR %172 %80 %9 %4 NonPrivatePointer\nOpControlBarrier %6 %6 %41\n%173 = OpCooperativeMatrixLoadKHR %5 %172 %9 %4 NonPrivatePointer\n%174 = OpFConvert %12 %173\n%175 = OpAccessChain %27 %25 %7 %176\nOpCooperativeMatrixStoreKHR %175 %174 %9 %50 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%56 = OpFunction %5 None %54\n%55 = OpFunctionParameter %53\n%57 = OpLabel\n%58 = OpVariable %53 Function\n%59 = OpCooperativeMatrixLengthKHR %2 %5\nOpBranch %60\n%60 = OpLabel\n%62 = OpPhi %2 %7 %57 %63 %60\n%63 = OpIAdd %2 %62 %9\n%65 = OpInBoundsAccessChain %64 %55 %62\n%66 = OpLoad %1 %65\n%68 = OpExtInst %1 %67 NClamp %66 %69 %70\n%71 = OpInBoundsAccessChain %64 %58 %62\nOpStore %71 %68\n%72 = OpULessThan %52 %63 %59\nOpLoopMerge %61 %60 None\nOpBranchConditional %72 %60 %61\n%61 = OpLabel\n%73 = OpLoad %5 %58\nOpReturnValue %73\nOpFunctionEnd\n%92 = OpFunction %83 None %90\n%91 = OpFunctionParameter %89\n%93 = OpLabel\n%95 = OpVariable %94 Function\n%96 = OpCooperativeMatrixLengthKHR %2 %83\nOpBranch %97\n%97 = OpLabel\n%99 = OpPhi %2 %7 %93 %100 %97\n%100 = OpIAdd %2 %99 %3\n%101 = OpIAdd %2 %99 %9\n%102 = OpInBoundsAccessChain %64 %91 %99\n%103 = OpLoad %1 %102\n%104 = OpInBoundsAccessChain %64 %91 %101\n%105 = OpLoad %1 %104\n%106 = OpCompositeConstruct %86 %103 %105\n%107 = OpBitcast %87 %106\n%108 = OpShiftRightLogical %87 %107 %110\n%111 = OpShiftLeftLogical %87 %108 %113\n%114 = OpShiftLeftLogical %87 %107 %116\n%117 = OpISub %87 %114 %119\n%120 = OpShiftRightArithmetic %87 %117 %122\n%123 = OpISub %87 %120 %116\n%124 = OpSNegate %87 %123\n%125 = OpExtInst %87 %67 SMax %124 %127\n%128 = OpBitwiseAnd %87 %123 %130\n%131 = OpBitwiseAnd %87 %123 %133\n%134 = OpBitwiseXor %87 %131 %136\n%137 = OpBitwiseAnd %87 %117 %134\n%138 = OpBitwiseOr %87 %137 %128\n%139 = OpBitwiseAnd %87 %138 %141\n%142 = OpShiftRightArithmetic %87 %138 %125\n%143 = OpBitwiseOr %87 %142 %139\n%144 = OpShiftRightLogical %87 %142 %146\n%147 = OpBitwiseAnd %87 %144 %116\n%148 = OpBitwiseOr %87 %147 %143\n%149 = OpShiftLeftLogical %87 %148 %146\n%150 = OpUGreaterThan %85 %149 %154\n%155 = OpSelect %87 %150 %116 %127\n%156 = OpIAdd %87 %144 %155\n%157 = OpBitwiseAnd %87 %156 %141\n%158 = OpBitwiseOr %87 %157 %111\n%159 = OpUConvert %88 %158\n%161 = OpInBoundsAccessChain %160 %95 %99\n%162 = OpCompositeExtract %17 %159 0\nOpStore %161 %162\n%163 = OpInBoundsAccessChain %160 %95 %101\n%164 = OpCompositeExtract %17 %159 1\nOpStore %163 %164\n%165 = OpULessThan %52 %100 %96\nOpLoopMerge %98 %97 None\nOpBranchConditional %165 %97 %98\n%98 = OpLabel\n%166 = OpLoad %83 %95\nOpReturnValue %166\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_copy_transpose_fp16.sm66.ssbo.full-wmma.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_NV_cooperative_matrix2 : require\n#extension GL_EXT_float_e4m3 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _18;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _20_22\n{\n    uint8_t _m0[];\n} _22;\n\ncoopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> CoopMatSaturationFixup(coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _32)\n{\n    uint _39;\n    _39 = 0u;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> coop_output;\n    for (;;)\n    {\n        uint _40 = _39 + 1u;\n        coop_output[_39] = isinf(_32[_39]) ? uintBitsToFloat(0x7fc00000u /* nan */) : _32[_39];\n        if (_40 < uint(coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length()))\n        {\n            _39 = _40;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output;\n}\n\nvoid main()\n{\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _28;\n    coopMatLoad(_28, _18._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _51 = _28;\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _53;\n    saturatedConvertEXT(_53, CoopMatSaturationFixup(_51));\n    coopMatStore(_53, _22._m0, 1024u, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 58\n; Schema: 0\nOpCapability Shader\nOpCapability Int8\nOpCapability Float8EXT\nOpCapability Float8CooperativeMatrixEXT\nOpCapability StorageBuffer8BitAccess\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixConversionsNV\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_EXT_float8\"\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_NV_cooperative_matrix2\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %12 \"main\" %18 %22\nOpExecutionMode %12 LocalSize 32 1 1\nOpName %12 \"main\"\nOpName %16 \"SSBO\"\nOpName %20 \"SSBO\"\nOpName %33 \"CoopMatSaturationFixup\"\nOpName %35 \"coop_output\"\nOpDecorate %15 ArrayStride 1\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %18 NonWritable\nOpDecorate %18 Restrict\nOpDecorate %19 ArrayStride 1\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 0\nOpDecorate %22 NonReadable\nOpDecorate %53 SaturatedToLargestFloat8NormalConversionEXT\n%1 = OpTypeFloat 32\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 2\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpTypeFloat 8 Float8E4M3EXT\n%8 = OpConstant %2 1\n%9 = OpTypeCooperativeMatrixKHR %7 %6 %4 %4 %8\n%10 = OpTypeVoid\n%11 = OpTypeFunction %10\n%14 = OpTypeInt 8 0\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %14\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%24 = OpTypePointer StorageBuffer %14\n%26 = OpConstant %2 0\n%27 = OpConstant %2 64\n%29 = OpTypeBool\n%30 = OpTypePointer Function %5\n%31 = OpTypeFunction %5 %30\n%41 = OpTypePointer Function %1\n%46 = OpConstant %1 0x1.8p+128\n%55 = OpConstant %2 1024\n%12 = OpFunction %10 None %11\n%13 = OpLabel\n%51 = OpVariable %30 Function\nOpBranch %56\n%56 = OpLabel\n%25 = OpAccessChain %24 %18 %26 %26\n%28 = OpCooperativeMatrixLoadKHR %5 %25 %8 %27 NonPrivatePointer\nOpStore %51 %28\n%52 = OpFunctionCall %5 %33 %51\n%53 = OpFConvert %9 %52\n%54 = OpAccessChain %24 %22 %26 %55\nOpCooperativeMatrixStoreKHR %54 %53 %8 %4 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%33 = OpFunction %5 None %31\n%32 = OpFunctionParameter %30\n%34 = OpLabel\n%35 = OpVariable %30 Function\n%36 = OpCooperativeMatrixLengthKHR %2 %5\nOpBranch %37\n%37 = OpLabel\n%39 = OpPhi %2 %26 %34 %40 %37\n%40 = OpIAdd %2 %39 %8\n%42 = OpInBoundsAccessChain %41 %32 %39\n%43 = OpLoad %1 %42\n%44 = OpIsInf %29 %43\n%45 = OpSelect %1 %44 %46 %43\n%47 = OpInBoundsAccessChain %41 %35 %39\nOpStore %47 %45\n%48 = OpULessThan %29 %40 %36\nOpLoopMerge %38 %37 None\nOpBranchConditional %48 %37 %38\n%38 = OpLabel\n%49 = OpLoad %5 %35\nOpReturnValue %49\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_extract_insert.sm66.ssbo.full-wmma.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_float_e4m3 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _15;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _17_19\n{\n    uint8_t _m0[];\n} _19;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _21_23\n{\n    uint _m0[];\n} _23;\n\nvoid main()\n{\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _15._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    uint _32 = uint(coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()) / 4u;\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _36;\n    if (_32 == 0u)\n    {\n        _36 = _30;\n    }\n    else\n    {\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _39;\n        uint _40;\n        _39 = _30;\n        _40 = 0u;\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _94;\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _43;\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _74;\n        for (;;)\n        {\n            _43 = _39;\n            uint _44 = _40 * 4u;\n            uint _62 = (fe4m3vec4(_43[_44 + 0u], _43[_44 + 1u], _43[_44 + 2u], _43[_44 + 3u]));\n            uint _64 = _40 + (_32 * gl_LocalInvocationIndex);\n            _23._m0[_64 + 64u] = _62;\n            _74 = _39;\n            u8vec4 _76 = unpack8(_62 ^ 16711935u);\n            uint _77 = _40 * 4u;\n            _74[_77 + 0u] = uintBitsToFloate4m3EXT(_76.x);\n            _74[_77 + 1u] = uintBitsToFloate4m3EXT(_76.y);\n            _74[_77 + 2u] = uintBitsToFloate4m3EXT(_76.z);\n            _74[_77 + 3u] = uintBitsToFloate4m3EXT(_76.w);\n            _94 = _74;\n            uint _41 = _40 + 1u;\n            if (_41 == _32)\n            {\n                break;\n            }\n            else\n            {\n                _39 = _94;\n                _40 = _41;\n            }\n        }\n        _36 = _94;\n    }\n    coopMatStore(_36, _19._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\nOpCapability Shader\nOpCapability Int8\nOpCapability Float8EXT\nOpCapability Float8CooperativeMatrixEXT\nOpCapability StorageBuffer8BitAccess\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_EXT_float8\"\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %9 \"main\" %15 %19 %23 %25\nOpExecutionMode %9 LocalSize 32 1 1\nOpName %9 \"main\"\nOpName %13 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %21 \"SSBO\"\nOpDecorate %12 ArrayStride 1\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %16 ArrayStride 1\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %20 ArrayStride 4\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %19 NonReadable\nOpDecorate %19 Aliased\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %23 NonReadable\nOpDecorate %23 Aliased\nOpDecorate %25 BuiltIn LocalInvocationIndex\n%1 = OpTypeFloat 8 Float8E4M3EXT\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpTypeVoid\n%8 = OpTypeFunction %7\n%11 = OpTypeInt 8 0\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypeStruct %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeRuntimeArray %11\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %2\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypePointer Input %2\n%25 = OpVariable %24 Input\n%28 = OpTypePointer StorageBuffer %11\n%33 = OpConstant %2 4\n%34 = OpTypeBool\n%42 = OpTypePointer Function %5\n%46 = OpTypePointer Function %1\n%50 = OpConstant %2 1\n%54 = OpConstant %2 2\n%60 = OpTypeVector %1 4\n%67 = OpConstant %2 256\n%69 = OpConstant %2 64\n%70 = OpTypePointer StorageBuffer %2\n%73 = OpConstant %2 16711935\n%75 = OpTypeVector %11 4\n%9 = OpFunction %7 None %8\n%10 = OpLabel\n%43 = OpVariable %42 Function\n%74 = OpVariable %42 Function\nOpBranch %96\n%96 = OpLabel\n%26 = OpLoad %2 %25\n%29 = OpAccessChain %28 %15 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %5 %29 %3 %4 NonPrivatePointer\n%31 = OpCooperativeMatrixLengthKHR %2 %5\n%32 = OpUDiv %2 %31 %33\n%35 = OpIEqual %34 %32 %3\nOpSelectionMerge %100 None\nOpBranchConditional %35 %100 %97\n%97 = OpLabel\nOpBranch %98\n%98 = OpLabel\n%39 = OpPhi %5 %30 %97 %94 %98\n%40 = OpPhi %2 %3 %97 %41 %98\nOpStore %43 %39\n%44 = OpIMul %2 %40 %33\n%45 = OpIAdd %2 %44 %3\n%47 = OpInBoundsAccessChain %46 %43 %45\n%48 = OpLoad %1 %47\n%49 = OpIAdd %2 %44 %50\n%51 = OpInBoundsAccessChain %46 %43 %49\n%52 = OpLoad %1 %51\n%53 = OpIAdd %2 %44 %54\n%55 = OpInBoundsAccessChain %46 %43 %53\n%56 = OpLoad %1 %55\n%57 = OpIAdd %2 %44 %6\n%58 = OpInBoundsAccessChain %46 %43 %57\n%59 = OpLoad %1 %58\n%61 = OpCompositeConstruct %60 %48 %52 %56 %59\n%62 = OpBitcast %2 %61\n%63 = OpIMul %2 %32 %26\n%64 = OpIAdd %2 %40 %63\n%65 = OpShiftLeftLogical %2 %64 %54\n%66 = OpIAdd %2 %65 %67\n%68 = OpIAdd %2 %64 %69\n%71 = OpAccessChain %70 %23 %3 %68\nOpStore %71 %62 NonPrivatePointer\n%72 = OpBitwiseXor %2 %62 %73\nOpStore %74 %39\n%76 = OpBitcast %75 %72\n%77 = OpIMul %2 %40 %33\n%78 = OpCompositeExtract %11 %76 0\n%79 = OpBitcast %1 %78\n%80 = OpIAdd %2 %77 %3\n%81 = OpInBoundsAccessChain %46 %74 %80\nOpStore %81 %79\n%82 = OpCompositeExtract %11 %76 1\n%83 = OpBitcast %1 %82\n%84 = OpIAdd %2 %77 %50\n%85 = OpInBoundsAccessChain %46 %74 %84\nOpStore %85 %83\n%86 = OpCompositeExtract %11 %76 2\n%87 = OpBitcast %1 %86\n%88 = OpIAdd %2 %77 %54\n%89 = OpInBoundsAccessChain %46 %74 %88\nOpStore %89 %87\n%90 = OpCompositeExtract %11 %76 3\n%91 = OpBitcast %1 %90\n%92 = OpIAdd %2 %77 %6\n%93 = OpInBoundsAccessChain %46 %74 %92\nOpStore %93 %91\n%94 = OpLoad %5 %74\n%41 = OpIAdd %2 %40 %50\n%95 = OpIEqual %34 %41 %32\nOpLoopMerge %99 %98 None\nOpBranchConditional %95 %99 %98\n%99 = OpLabel\nOpBranch %100\n%100 = OpLabel\n%36 = OpPhi %5 %30 %96 %94 %99\n%38 = OpAccessChain %28 %19 %3 %3\nOpCooperativeMatrixStoreKHR %38 %36 %3 %4 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33;\n    coopMatLoad(_33, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _37;\n    coopMatLoad(_37, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(_30, _33, _37, 0)), _25._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypePointer StorageBuffer %17\n%29 = OpConstant %2 32\n%32 = OpConstant %2 512\n%35 = OpConstant %2 1024\n%36 = OpConstant %2 64\n%15 = OpFunction %13 None %14\n%16 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%28 = OpAccessChain %27 %21 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %5 %28 %3 %29 NonPrivatePointer\n%31 = OpAccessChain %27 %21 %3 %32\n%33 = OpCooperativeMatrixLoadKHR %8 %31 %3 %29 NonPrivatePointer\n%34 = OpAccessChain %27 %21 %3 %35\n%37 = OpCooperativeMatrixLoadKHR %11 %34 %3 %36 NonPrivatePointer\n%38 = OpCooperativeMatrixMulAddKHR %11 %30 %33 %37\n%39 = OpFConvert %12 %38\n%40 = OpAccessChain %27 %25 %3 %3\nOpCooperativeMatrixStoreKHR %40 %39 %3 %29 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_at.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33;\n    coopMatLoad(_33, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _37;\n    coopMatLoad(_37, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(_30, _33, _37, 0)), _25._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypePointer StorageBuffer %17\n%29 = OpConstant %2 32\n%32 = OpConstant %2 512\n%35 = OpConstant %2 1024\n%36 = OpConstant %2 64\n%15 = OpFunction %13 None %14\n%16 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%28 = OpAccessChain %27 %21 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %5 %28 %7 %29 NonPrivatePointer\n%31 = OpAccessChain %27 %21 %3 %32\n%33 = OpCooperativeMatrixLoadKHR %8 %31 %3 %29 NonPrivatePointer\n%34 = OpAccessChain %27 %21 %3 %35\n%37 = OpCooperativeMatrixLoadKHR %11 %34 %3 %36 NonPrivatePointer\n%38 = OpCooperativeMatrixMulAddKHR %11 %30 %33 %37\n%39 = OpFConvert %12 %38\n%40 = OpAccessChain %27 %25 %3 %3\nOpCooperativeMatrixStoreKHR %40 %39 %3 %29 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_bt.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33;\n    coopMatLoad(_33, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _37;\n    coopMatLoad(_37, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(_30, _33, _37, 0)), _25._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypePointer StorageBuffer %17\n%29 = OpConstant %2 32\n%32 = OpConstant %2 512\n%35 = OpConstant %2 1024\n%36 = OpConstant %2 64\n%15 = OpFunction %13 None %14\n%16 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%28 = OpAccessChain %27 %21 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %5 %28 %3 %29 NonPrivatePointer\n%31 = OpAccessChain %27 %21 %3 %32\n%33 = OpCooperativeMatrixLoadKHR %8 %31 %7 %29 NonPrivatePointer\n%34 = OpAccessChain %27 %21 %3 %35\n%37 = OpCooperativeMatrixLoadKHR %11 %34 %3 %36 NonPrivatePointer\n%38 = OpCooperativeMatrixMulAddKHR %11 %30 %33 %37\n%39 = OpFConvert %12 %38\n%40 = OpAccessChain %27 %25 %3 %3\nOpCooperativeMatrixStoreKHR %40 %39 %3 %29 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_ct.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33;\n    coopMatLoad(_33, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _37;\n    coopMatLoad(_37, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(_30, _33, _37, 0)), _25._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypePointer StorageBuffer %17\n%29 = OpConstant %2 32\n%32 = OpConstant %2 512\n%35 = OpConstant %2 1024\n%36 = OpConstant %2 64\n%15 = OpFunction %13 None %14\n%16 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%28 = OpAccessChain %27 %21 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %5 %28 %3 %29 NonPrivatePointer\n%31 = OpAccessChain %27 %21 %3 %32\n%33 = OpCooperativeMatrixLoadKHR %8 %31 %3 %29 NonPrivatePointer\n%34 = OpAccessChain %27 %21 %3 %35\n%37 = OpCooperativeMatrixLoadKHR %11 %34 %7 %36 NonPrivatePointer\n%38 = OpCooperativeMatrixMulAddKHR %11 %30 %33 %37\n%39 = OpFConvert %12 %38\n%40 = OpAccessChain %27 %25 %3 %3\nOpCooperativeMatrixStoreKHR %40 %39 %3 %29 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_ot.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33;\n    coopMatLoad(_33, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _37;\n    coopMatLoad(_37, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(_30, _33, _37, 0)), _25._m0, 0u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypePointer StorageBuffer %17\n%29 = OpConstant %2 32\n%32 = OpConstant %2 512\n%35 = OpConstant %2 1024\n%36 = OpConstant %2 64\n%15 = OpFunction %13 None %14\n%16 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%28 = OpAccessChain %27 %21 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %5 %28 %3 %29 NonPrivatePointer\n%31 = OpAccessChain %27 %21 %3 %32\n%33 = OpCooperativeMatrixLoadKHR %8 %31 %3 %29 NonPrivatePointer\n%34 = OpAccessChain %27 %21 %3 %35\n%37 = OpCooperativeMatrixLoadKHR %11 %34 %3 %36 NonPrivatePointer\n%38 = OpCooperativeMatrixMulAddKHR %11 %30 %33 %37\n%39 = OpFConvert %12 %38\n%40 = OpAccessChain %27 %25 %3 %3\nOpCooperativeMatrixStoreKHR %40 %39 %7 %29 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_f16_quant_fp8.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_spirv_intrinsics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> CoopMatSaturateFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _43)\n{\n    uint _50;\n    _50 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> coop_output;\n    for (;;)\n    {\n        uint _51 = _50 + 1u;\n        coop_output[_50] = spvNClamp(_43[_50], float16_t(-448.0), float16_t(448.0));\n        if (_51 < uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length()))\n        {\n            _50 = _51;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output;\n}\n\ncoopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> CoopMatFP16toFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _73)\n{\n    uint _81;\n    _81 = 0u;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> coop_output;\n    for (;;)\n    {\n        uint _82 = _81 + 2u;\n        uint _83 = _81 + 1u;\n        i16vec2 _89 = float16BitsToInt16(f16vec2(_73[_81], _73[_83]));\n        i16vec2 _99 = (_89 << i16vec2(1)) - i16vec2(16384);\n        i16vec2 _105 = (_99 >> i16vec2(11)) - i16vec2(1);\n        i16vec2 _120 = (_99 & ((_105 & i16vec2(-2048)) ^ i16vec2(-1))) | (_105 & i16vec2(2048));\n        i16vec2 _124 = _120 >> max((-_105), i16vec2(0));\n        i16vec2 _126 = i16vec2(u16vec2(_124) >> u16vec2(i16vec2(8)));\n        u8vec2 _141 = u8vec2(((_126 + i16vec2(greaterThan(u16vec2(((_126 & i16vec2(1)) | (_124 | (_120 & i16vec2(127)))) << i16vec2(8)), u16vec2(32768)))) & i16vec2(127)) | (i16vec2(u16vec2(_89) >> u16vec2(i16vec2(15))) << i16vec2(7)));\n        coop_output[_81] = _141.x;\n        coop_output[_83] = _141.y;\n        if (_82 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length()))\n        {\n            _81 = _82;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output;\n}\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33;\n    coopMatLoad(_33, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _37;\n    coopMatLoad(_37, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _63 = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(_30, _33, _37, 0));\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _150 = CoopMatSaturateFP8(_63);\n    coopMatStore(CoopMatFP16toFP8(_150), _25._m0, 0u, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 154\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\n%55 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %44 \"CoopMatSaturateFP8\"\nOpName %46 \"coop_output\"\nOpName %74 \"CoopMatFP16toFP8\"\nOpName %77 \"coop_output\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypePointer StorageBuffer %17\n%29 = OpConstant %2 32\n%32 = OpConstant %2 512\n%35 = OpConstant %2 1024\n%36 = OpConstant %2 64\n%40 = OpTypeBool\n%41 = OpTypePointer Function %12\n%42 = OpTypeFunction %12 %41\n%52 = OpTypePointer Function %1\n%57 = OpConstant %1 -0x1.cp+8\n%58 = OpConstant %1 0x1.cp+8\n%66 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %10\n%67 = OpTypeInt 16 1\n%68 = OpTypeVector %40 2\n%69 = OpTypeVector %1 2\n%70 = OpTypeVector %67 2\n%71 = OpTypeVector %17 2\n%72 = OpTypeFunction %66 %41\n%76 = OpTypePointer Function %66\n%91 = OpConstant %67 15\n%92 = OpConstantComposite %70 %91 %91\n%94 = OpConstant %67 7\n%95 = OpConstantComposite %70 %94 %94\n%97 = OpConstant %67 1\n%98 = OpConstantComposite %70 %97 %97\n%100 = OpConstant %67 16384\n%101 = OpConstantComposite %70 %100 %100\n%103 = OpConstant %67 11\n%104 = OpConstantComposite %70 %103 %103\n%108 = OpConstant %67 0\n%109 = OpConstantComposite %70 %108 %108\n%111 = OpConstant %67 2048\n%112 = OpConstantComposite %70 %111 %111\n%114 = OpConstant %67 -2048\n%115 = OpConstantComposite %70 %114 %114\n%117 = OpConstant %67 -1\n%118 = OpConstantComposite %70 %117 %117\n%122 = OpConstant %67 127\n%123 = OpConstantComposite %70 %122 %122\n%127 = OpConstant %67 8\n%128 = OpConstantComposite %70 %127 %127\n%133 = OpTypeInt 16 0\n%134 = OpConstant %133 32768\n%135 = OpTypeVector %133 2\n%136 = OpConstantComposite %135 %134 %134\n%142 = OpTypePointer Function %17\n%15 = OpFunction %13 None %14\n%16 = OpLabel\n%63 = OpVariable %41 Function\n%150 = OpVariable %41 Function\nOpBranch %152\n%152 = OpLabel\n%28 = OpAccessChain %27 %21 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %5 %28 %3 %29 NonPrivatePointer\n%31 = OpAccessChain %27 %21 %3 %32\n%33 = OpCooperativeMatrixLoadKHR %8 %31 %7 %29 NonPrivatePointer\n%34 = OpAccessChain %27 %21 %3 %35\n%37 = OpCooperativeMatrixLoadKHR %11 %34 %7 %36 NonPrivatePointer\n%38 = OpCooperativeMatrixMulAddKHR %11 %30 %33 %37\n%39 = OpFConvert %12 %38\nOpStore %63 %39\n%64 = OpFunctionCall %12 %44 %63\n%65 = OpAccessChain %27 %25 %3 %3\nOpStore %150 %64\n%151 = OpFunctionCall %66 %74 %150\nOpCooperativeMatrixStoreKHR %65 %151 %7 %4 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%44 = OpFunction %12 None %42\n%43 = OpFunctionParameter %41\n%45 = OpLabel\n%46 = OpVariable %41 Function\n%47 = OpCooperativeMatrixLengthKHR %2 %12\nOpBranch %48\n%48 = OpLabel\n%50 = OpPhi %2 %3 %45 %51 %48\n%51 = OpIAdd %2 %50 %7\n%53 = OpInBoundsAccessChain %52 %43 %50\n%54 = OpLoad %1 %53\n%56 = OpExtInst %1 %55 NClamp %54 %57 %58\n%59 = OpInBoundsAccessChain %52 %46 %50\nOpStore %59 %56\n%60 = OpULessThan %40 %51 %47\nOpLoopMerge %49 %48 None\nOpBranchConditional %60 %48 %49\n%49 = OpLabel\n%61 = OpLoad %12 %46\nOpReturnValue %61\nOpFunctionEnd\n%74 = OpFunction %66 None %72\n%73 = OpFunctionParameter %41\n%75 = OpLabel\n%77 = OpVariable %76 Function\n%78 = OpCooperativeMatrixLengthKHR %2 %66\nOpBranch %79\n%79 = OpLabel\n%81 = OpPhi %2 %3 %75 %82 %79\n%82 = OpIAdd %2 %81 %10\n%83 = OpIAdd %2 %81 %7\n%84 = OpInBoundsAccessChain %52 %73 %81\n%85 = OpLoad %1 %84\n%86 = OpInBoundsAccessChain %52 %73 %83\n%87 = OpLoad %1 %86\n%88 = OpCompositeConstruct %69 %85 %87\n%89 = OpBitcast %70 %88\n%90 = OpShiftRightLogical %70 %89 %92\n%93 = OpShiftLeftLogical %70 %90 %95\n%96 = OpShiftLeftLogical %70 %89 %98\n%99 = OpISub %70 %96 %101\n%102 = OpShiftRightArithmetic %70 %99 %104\n%105 = OpISub %70 %102 %98\n%106 = OpSNegate %70 %105\n%107 = OpExtInst %70 %55 SMax %106 %109\n%110 = OpBitwiseAnd %70 %105 %112\n%113 = OpBitwiseAnd %70 %105 %115\n%116 = OpBitwiseXor %70 %113 %118\n%119 = OpBitwiseAnd %70 %99 %116\n%120 = OpBitwiseOr %70 %119 %110\n%121 = OpBitwiseAnd %70 %120 %123\n%124 = OpShiftRightArithmetic %70 %120 %107\n%125 = OpBitwiseOr %70 %124 %121\n%126 = OpShiftRightLogical %70 %124 %128\n%129 = OpBitwiseAnd %70 %126 %98\n%130 = OpBitwiseOr %70 %129 %125\n%131 = OpShiftLeftLogical %70 %130 %128\n%132 = OpUGreaterThan %68 %131 %136\n%137 = OpSelect %70 %132 %98 %109\n%138 = OpIAdd %70 %126 %137\n%139 = OpBitwiseAnd %70 %138 %123\n%140 = OpBitwiseOr %70 %139 %93\n%141 = OpUConvert %71 %140\n%143 = OpInBoundsAccessChain %142 %77 %81\n%144 = OpCompositeExtract %17 %141 0\nOpStore %143 %144\n%145 = OpInBoundsAccessChain %142 %77 %83\n%146 = OpCompositeExtract %17 %141 1\nOpStore %145 %146\n%147 = OpULessThan %40 %82 %78\nOpLoopMerge %80 %79 None\nOpBranchConditional %147 %79 %80\n%80 = OpLabel\n%148 = OpLoad %66 %77\nOpReturnValue %148\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_fp8.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _33)\n{\n    uint _41;\n    _41 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _42 = _41 + 1u;\n        coop_output[_41] = int16BitsToFloat16((int16_t(int8_t(_33[_41])) << 7s) & (-16385s));\n        if (_42 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _41 = _42;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _68)\n{\n    uint _76;\n    _76 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _77 = _76 + 1u;\n        coop_output[_76] = int16BitsToFloat16((int16_t(int8_t(_68[_76])) << 7s) & (-16385s));\n        if (_77 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _76 = _77;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _29;\n    coopMatLoad(_29, _20._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _60 = _29;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _65;\n    coopMatLoad(_65, _20._m0, 256u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _89 = _65;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _94;\n    coopMatLoad(_94, _20._m0, 512u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopMatMulAdd(CoopMatFP8toFP16(_60), CoopMatFP8toFP16_1(_89), _94, 0), _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24\nOpExecutionMode %14 LocalSize 32 1 1\nOpExecutionMode %14 DenormPreserve 16\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %34 \"CoopMatFP8toFP16\"\nOpName %37 \"coop_output\"\nOpName %69 \"CoopMatFP8toFP16\"\nOpName %72 \"coop_output\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%26 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %3\n%27 = OpTypePointer StorageBuffer %16\n%30 = OpTypeBool\n%31 = OpTypePointer Function %26\n%32 = OpTypeFunction %5 %31\n%36 = OpTypePointer Function %5\n%43 = OpTypePointer Function %16\n%46 = OpTypeInt 16 1\n%49 = OpConstant %46 7\n%51 = OpConstant %46 -16385\n%53 = OpTypePointer Function %1\n%58 = OpConstant %1 0x1p+8\n%62 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %7\n%64 = OpConstant %2 256\n%66 = OpTypePointer Function %62\n%67 = OpTypeFunction %8 %66\n%71 = OpTypePointer Function %8\n%92 = OpConstant %2 512\n%93 = OpConstant %2 64\n%14 = OpFunction %12 None %13\n%15 = OpLabel\n%60 = OpVariable %31 Function\n%89 = OpVariable %66 Function\nOpBranch %97\n%97 = OpLabel\n%28 = OpAccessChain %27 %20 %3 %3\n%29 = OpCooperativeMatrixLoadKHR %26 %28 %3 %4 NonPrivatePointer\nOpStore %60 %29\n%61 = OpFunctionCall %5 %34 %60\n%63 = OpAccessChain %27 %20 %3 %64\n%65 = OpCooperativeMatrixLoadKHR %62 %63 %3 %4 NonPrivatePointer\nOpStore %89 %65\n%90 = OpFunctionCall %8 %69 %89\n%91 = OpAccessChain %27 %20 %3 %92\n%94 = OpCooperativeMatrixLoadKHR %11 %91 %3 %93 NonPrivatePointer\n%95 = OpCooperativeMatrixMulAddKHR %11 %61 %90 %94\n%96 = OpAccessChain %27 %24 %3 %3\nOpCooperativeMatrixStoreKHR %96 %95 %3 %93 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%34 = OpFunction %5 None %32\n%33 = OpFunctionParameter %31\n%35 = OpLabel\n%37 = OpVariable %36 Function\n%38 = OpCooperativeMatrixLengthKHR %2 %26\nOpBranch %39\n%39 = OpLabel\n%41 = OpPhi %2 %3 %35 %42 %39\n%42 = OpIAdd %2 %41 %7\n%44 = OpInBoundsAccessChain %43 %33 %41\n%45 = OpLoad %16 %44\n%47 = OpSConvert %46 %45\n%48 = OpShiftLeftLogical %46 %47 %49\n%50 = OpBitwiseAnd %46 %48 %51\n%52 = OpBitcast %1 %50\n%54 = OpInBoundsAccessChain %53 %37 %41\nOpStore %54 %52\n%55 = OpULessThan %30 %42 %38\nOpLoopMerge %40 %39 None\nOpBranchConditional %55 %39 %40\n%40 = OpLabel\n%56 = OpLoad %5 %37\n%57 = OpMatrixTimesScalar %5 %56 %58\nOpReturnValue %57\nOpFunctionEnd\n%69 = OpFunction %8 None %67\n%68 = OpFunctionParameter %66\n%70 = OpLabel\n%72 = OpVariable %71 Function\n%73 = OpCooperativeMatrixLengthKHR %2 %62\nOpBranch %74\n%74 = OpLabel\n%76 = OpPhi %2 %3 %70 %77 %74\n%77 = OpIAdd %2 %76 %7\n%78 = OpInBoundsAccessChain %43 %68 %76\n%79 = OpLoad %16 %78\n%80 = OpSConvert %46 %79\n%81 = OpShiftLeftLogical %46 %80 %49\n%82 = OpBitwiseAnd %46 %81 %51\n%83 = OpBitcast %1 %82\n%84 = OpInBoundsAccessChain %53 %72 %76\nOpStore %84 %83\n%85 = OpULessThan %30 %77 %73\nOpLoopMerge %75 %74 None\nOpBranchConditional %85 %74 %75\n%75 = OpLabel\n%86 = OpLoad %8 %72\n%87 = OpMatrixTimesScalar %8 %86 %58\nOpReturnValue %87\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_fp8.sm66.ssbo.full-wmma.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_float_e4m3 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\nvoid main()\n{\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _28;\n    coopMatLoad(_28, _20._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _31;\n    coopMatLoad(_31, _20._m0, 256u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _35;\n    coopMatLoad(_35, _20._m0, 512u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopMatMulAdd(_28, _31, _35, 0), _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\nOpCapability Shader\nOpCapability Int8\nOpCapability Float8EXT\nOpCapability Float8CooperativeMatrixEXT\nOpCapability StorageBuffer8BitAccess\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_EXT_float8\"\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24\nOpExecutionMode %14 LocalSize 32 1 1\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 8 Float8E4M3EXT\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%26 = OpTypePointer StorageBuffer %16\n%30 = OpConstant %2 256\n%33 = OpConstant %2 512\n%34 = OpConstant %2 64\n%14 = OpFunction %12 None %13\n%15 = OpLabel\nOpBranch %38\n%38 = OpLabel\n%27 = OpAccessChain %26 %20 %3 %3\n%28 = OpCooperativeMatrixLoadKHR %5 %27 %3 %4 NonPrivatePointer\n%29 = OpAccessChain %26 %20 %3 %30\n%31 = OpCooperativeMatrixLoadKHR %8 %29 %3 %4 NonPrivatePointer\n%32 = OpAccessChain %26 %20 %3 %33\n%35 = OpCooperativeMatrixLoadKHR %11 %32 %3 %34 NonPrivatePointer\n%36 = OpCooperativeMatrixMulAddKHR %11 %28 %31 %35\n%37 = OpAccessChain %26 %24 %3 %3\nOpCooperativeMatrixStoreKHR %37 %36 %3 %34 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f16.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _34)\n{\n    uint _42;\n    _42 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _43 = _42 + 1u;\n        coop_output[_42] = int16BitsToFloat16((int16_t(int8_t(_34[_42])) << 7s) & (-16385s));\n        if (_43 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _42 = _43;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _69)\n{\n    uint _77;\n    _77 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _78 = _77 + 1u;\n        coop_output[_77] = int16BitsToFloat16((int16_t(int8_t(_69[_77])) << 7s) & (-16385s));\n        if (_78 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _77 = _78;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;\n    coopMatLoad(_30, _21._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _61 = _30;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _66;\n    coopMatLoad(_66, _21._m0, 256u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _90 = _66;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _95;\n    coopMatLoad(_95, _21._m0, 512u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(CoopMatFP8toFP16(_61), CoopMatFP8toFP16_1(_90), _95, 0)), _25._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %35 \"CoopMatFP8toFP16\"\nOpName %38 \"coop_output\"\nOpName %70 \"CoopMatFP8toFP16\"\nOpName %73 \"coop_output\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %3\n%28 = OpTypePointer StorageBuffer %17\n%31 = OpTypeBool\n%32 = OpTypePointer Function %27\n%33 = OpTypeFunction %5 %32\n%37 = OpTypePointer Function %5\n%44 = OpTypePointer Function %17\n%47 = OpTypeInt 16 1\n%50 = OpConstant %47 7\n%52 = OpConstant %47 -16385\n%54 = OpTypePointer Function %1\n%59 = OpConstant %1 0x1p+8\n%63 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %7\n%65 = OpConstant %2 256\n%67 = OpTypePointer Function %63\n%68 = OpTypeFunction %8 %67\n%72 = OpTypePointer Function %8\n%93 = OpConstant %2 512\n%94 = OpConstant %2 64\n%99 = OpConstant %2 32\n%15 = OpFunction %13 None %14\n%16 = OpLabel\n%61 = OpVariable %32 Function\n%90 = OpVariable %67 Function\nOpBranch %100\n%100 = OpLabel\n%29 = OpAccessChain %28 %21 %3 %3\n%30 = OpCooperativeMatrixLoadKHR %27 %29 %3 %4 NonPrivatePointer\nOpStore %61 %30\n%62 = OpFunctionCall %5 %35 %61\n%64 = OpAccessChain %28 %21 %3 %65\n%66 = OpCooperativeMatrixLoadKHR %63 %64 %3 %4 NonPrivatePointer\nOpStore %90 %66\n%91 = OpFunctionCall %8 %70 %90\n%92 = OpAccessChain %28 %21 %3 %93\n%95 = OpCooperativeMatrixLoadKHR %11 %92 %3 %94 NonPrivatePointer\n%96 = OpCooperativeMatrixMulAddKHR %11 %62 %91 %95\n%97 = OpFConvert %12 %96\n%98 = OpAccessChain %28 %25 %3 %3\nOpCooperativeMatrixStoreKHR %98 %97 %3 %99 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%35 = OpFunction %5 None %33\n%34 = OpFunctionParameter %32\n%36 = OpLabel\n%38 = OpVariable %37 Function\n%39 = OpCooperativeMatrixLengthKHR %2 %27\nOpBranch %40\n%40 = OpLabel\n%42 = OpPhi %2 %3 %36 %43 %40\n%43 = OpIAdd %2 %42 %7\n%45 = OpInBoundsAccessChain %44 %34 %42\n%46 = OpLoad %17 %45\n%48 = OpSConvert %47 %46\n%49 = OpShiftLeftLogical %47 %48 %50\n%51 = OpBitwiseAnd %47 %49 %52\n%53 = OpBitcast %1 %51\n%55 = OpInBoundsAccessChain %54 %38 %42\nOpStore %55 %53\n%56 = OpULessThan %31 %43 %39\nOpLoopMerge %41 %40 None\nOpBranchConditional %56 %40 %41\n%41 = OpLabel\n%57 = OpLoad %5 %38\n%58 = OpMatrixTimesScalar %5 %57 %59\nOpReturnValue %58\nOpFunctionEnd\n%70 = OpFunction %8 None %68\n%69 = OpFunctionParameter %67\n%71 = OpLabel\n%73 = OpVariable %72 Function\n%74 = OpCooperativeMatrixLengthKHR %2 %63\nOpBranch %75\n%75 = OpLabel\n%77 = OpPhi %2 %3 %71 %78 %75\n%78 = OpIAdd %2 %77 %7\n%79 = OpInBoundsAccessChain %44 %69 %77\n%80 = OpLoad %17 %79\n%81 = OpSConvert %47 %80\n%82 = OpShiftLeftLogical %47 %81 %50\n%83 = OpBitwiseAnd %47 %82 %52\n%84 = OpBitcast %1 %83\n%85 = OpInBoundsAccessChain %54 %73 %77\nOpStore %85 %84\n%86 = OpULessThan %31 %78 %74\nOpLoopMerge %76 %75 None\nOpBranchConditional %86 %75 %76\n%76 = OpLabel\n%87 = OpLoad %8 %73\n%88 = OpMatrixTimesScalar %8 %87 %59\nOpReturnValue %88\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f16_strided.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _35)\n{\n    uint _43;\n    _43 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _44 = _43 + 1u;\n        coop_output[_43] = int16BitsToFloat16((int16_t(int8_t(_35[_43])) << 7s) & (-16385s));\n        if (_44 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _43 = _44;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _70)\n{\n    uint _78;\n    _78 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _79 = _78 + 1u;\n        coop_output[_78] = int16BitsToFloat16((int16_t(int8_t(_70[_78])) << 7s) & (-16385s));\n        if (_79 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _78 = _79;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _31;\n    coopMatLoad(_31, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _62 = _31;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _67;\n    coopMatLoad(_67, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _91 = _67;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _96;\n    coopMatLoad(_96, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(CoopMatFP8toFP16(_62), CoopMatFP8toFP16_1(_91), _96, 0)), _25._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %36 \"CoopMatFP8toFP16\"\nOpName %39 \"coop_output\"\nOpName %71 \"CoopMatFP8toFP16\"\nOpName %74 \"coop_output\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %3\n%28 = OpTypePointer StorageBuffer %17\n%30 = OpConstant %2 32\n%32 = OpTypeBool\n%33 = OpTypePointer Function %27\n%34 = OpTypeFunction %5 %33\n%38 = OpTypePointer Function %5\n%45 = OpTypePointer Function %17\n%48 = OpTypeInt 16 1\n%51 = OpConstant %48 7\n%53 = OpConstant %48 -16385\n%55 = OpTypePointer Function %1\n%60 = OpConstant %1 0x1p+8\n%64 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %7\n%66 = OpConstant %2 512\n%68 = OpTypePointer Function %64\n%69 = OpTypeFunction %8 %68\n%73 = OpTypePointer Function %8\n%94 = OpConstant %2 1024\n%95 = OpConstant %2 64\n%15 = OpFunction %13 None %14\n%16 = OpLabel\n%62 = OpVariable %33 Function\n%91 = OpVariable %68 Function\nOpBranch %100\n%100 = OpLabel\n%29 = OpAccessChain %28 %21 %3 %3\n%31 = OpCooperativeMatrixLoadKHR %27 %29 %3 %30 NonPrivatePointer\nOpStore %62 %31\n%63 = OpFunctionCall %5 %36 %62\n%65 = OpAccessChain %28 %21 %3 %66\n%67 = OpCooperativeMatrixLoadKHR %64 %65 %3 %30 NonPrivatePointer\nOpStore %91 %67\n%92 = OpFunctionCall %8 %71 %91\n%93 = OpAccessChain %28 %21 %3 %94\n%96 = OpCooperativeMatrixLoadKHR %11 %93 %3 %95 NonPrivatePointer\n%97 = OpCooperativeMatrixMulAddKHR %11 %63 %92 %96\n%98 = OpFConvert %12 %97\n%99 = OpAccessChain %28 %25 %3 %3\nOpCooperativeMatrixStoreKHR %99 %98 %3 %95 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%36 = OpFunction %5 None %34\n%35 = OpFunctionParameter %33\n%37 = OpLabel\n%39 = OpVariable %38 Function\n%40 = OpCooperativeMatrixLengthKHR %2 %27\nOpBranch %41\n%41 = OpLabel\n%43 = OpPhi %2 %3 %37 %44 %41\n%44 = OpIAdd %2 %43 %7\n%46 = OpInBoundsAccessChain %45 %35 %43\n%47 = OpLoad %17 %46\n%49 = OpSConvert %48 %47\n%50 = OpShiftLeftLogical %48 %49 %51\n%52 = OpBitwiseAnd %48 %50 %53\n%54 = OpBitcast %1 %52\n%56 = OpInBoundsAccessChain %55 %39 %43\nOpStore %56 %54\n%57 = OpULessThan %32 %44 %40\nOpLoopMerge %42 %41 None\nOpBranchConditional %57 %41 %42\n%42 = OpLabel\n%58 = OpLoad %5 %39\n%59 = OpMatrixTimesScalar %5 %58 %60\nOpReturnValue %59\nOpFunctionEnd\n%71 = OpFunction %8 None %69\n%70 = OpFunctionParameter %68\n%72 = OpLabel\n%74 = OpVariable %73 Function\n%75 = OpCooperativeMatrixLengthKHR %2 %64\nOpBranch %76\n%76 = OpLabel\n%78 = OpPhi %2 %3 %72 %79 %76\n%79 = OpIAdd %2 %78 %7\n%80 = OpInBoundsAccessChain %45 %70 %78\n%81 = OpLoad %17 %80\n%82 = OpSConvert %48 %81\n%83 = OpShiftLeftLogical %48 %82 %51\n%84 = OpBitwiseAnd %48 %83 %53\n%85 = OpBitcast %1 %84\n%86 = OpInBoundsAccessChain %55 %74 %78\nOpStore %86 %85\n%87 = OpULessThan %32 %79 %75\nOpLoopMerge %77 %76 None\nOpBranchConditional %87 %76 %77\n%77 = OpLabel\n%88 = OpLoad %8 %74\n%89 = OpMatrixTimesScalar %8 %88 %60\nOpReturnValue %89\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f16_strided_transpose.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _21;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    uint8_t _m0[];\n} _25;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _35)\n{\n    uint _43;\n    _43 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _44 = _43 + 1u;\n        coop_output[_43] = int16BitsToFloat16((int16_t(int8_t(_35[_43])) << 7s) & (-16385s));\n        if (_44 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _43 = _44;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _70)\n{\n    uint _78;\n    _78 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _79 = _78 + 1u;\n        coop_output[_78] = int16BitsToFloat16((int16_t(int8_t(_70[_78])) << 7s) & (-16385s));\n        if (_79 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _78 = _79;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _31;\n    coopMatLoad(_31, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _62 = _31;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _67;\n    coopMatLoad(_67, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _91 = _67;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _96;\n    coopMatLoad(_96, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(CoopMatFP8toFP16(_62), CoopMatFP8toFP16_1(_91), _96, 0)), _25._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %21 %25\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %19 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %36 \"CoopMatFP8toFP16\"\nOpName %39 \"coop_output\"\nOpName %71 \"CoopMatFP8toFP16\"\nOpName %74 \"coop_output\"\nOpDecorate %18 ArrayStride 1\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 1\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeInt 8 0\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %17\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%27 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %3\n%28 = OpTypePointer StorageBuffer %17\n%30 = OpConstant %2 32\n%32 = OpTypeBool\n%33 = OpTypePointer Function %27\n%34 = OpTypeFunction %5 %33\n%38 = OpTypePointer Function %5\n%45 = OpTypePointer Function %17\n%48 = OpTypeInt 16 1\n%51 = OpConstant %48 7\n%53 = OpConstant %48 -16385\n%55 = OpTypePointer Function %1\n%60 = OpConstant %1 0x1p+8\n%64 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %7\n%66 = OpConstant %2 512\n%68 = OpTypePointer Function %64\n%69 = OpTypeFunction %8 %68\n%73 = OpTypePointer Function %8\n%94 = OpConstant %2 1024\n%95 = OpConstant %2 64\n%15 = OpFunction %13 None %14\n%16 = OpLabel\n%62 = OpVariable %33 Function\n%91 = OpVariable %68 Function\nOpBranch %100\n%100 = OpLabel\n%29 = OpAccessChain %28 %21 %3 %3\n%31 = OpCooperativeMatrixLoadKHR %27 %29 %7 %30 NonPrivatePointer\nOpStore %62 %31\n%63 = OpFunctionCall %5 %36 %62\n%65 = OpAccessChain %28 %21 %3 %66\n%67 = OpCooperativeMatrixLoadKHR %64 %65 %7 %30 NonPrivatePointer\nOpStore %91 %67\n%92 = OpFunctionCall %8 %71 %91\n%93 = OpAccessChain %28 %21 %3 %94\n%96 = OpCooperativeMatrixLoadKHR %11 %93 %7 %95 NonPrivatePointer\n%97 = OpCooperativeMatrixMulAddKHR %11 %63 %92 %96\n%98 = OpFConvert %12 %97\n%99 = OpAccessChain %28 %25 %3 %3\nOpCooperativeMatrixStoreKHR %99 %98 %7 %95 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%36 = OpFunction %5 None %34\n%35 = OpFunctionParameter %33\n%37 = OpLabel\n%39 = OpVariable %38 Function\n%40 = OpCooperativeMatrixLengthKHR %2 %27\nOpBranch %41\n%41 = OpLabel\n%43 = OpPhi %2 %3 %37 %44 %41\n%44 = OpIAdd %2 %43 %7\n%46 = OpInBoundsAccessChain %45 %35 %43\n%47 = OpLoad %17 %46\n%49 = OpSConvert %48 %47\n%50 = OpShiftLeftLogical %48 %49 %51\n%52 = OpBitwiseAnd %48 %50 %53\n%54 = OpBitcast %1 %52\n%56 = OpInBoundsAccessChain %55 %39 %43\nOpStore %56 %54\n%57 = OpULessThan %32 %44 %40\nOpLoopMerge %42 %41 None\nOpBranchConditional %57 %41 %42\n%42 = OpLabel\n%58 = OpLoad %5 %39\n%59 = OpMatrixTimesScalar %5 %58 %60\nOpReturnValue %59\nOpFunctionEnd\n%71 = OpFunction %8 None %69\n%70 = OpFunctionParameter %68\n%72 = OpLabel\n%74 = OpVariable %73 Function\n%75 = OpCooperativeMatrixLengthKHR %2 %64\nOpBranch %76\n%76 = OpLabel\n%78 = OpPhi %2 %3 %72 %79 %76\n%79 = OpIAdd %2 %78 %7\n%80 = OpInBoundsAccessChain %45 %70 %78\n%81 = OpLoad %17 %80\n%82 = OpSConvert %48 %81\n%83 = OpShiftLeftLogical %48 %82 %51\n%84 = OpBitwiseAnd %48 %83 %53\n%85 = OpBitcast %1 %84\n%86 = OpInBoundsAccessChain %55 %74 %78\nOpStore %86 %85\n%87 = OpULessThan %32 %79 %75\nOpLoopMerge %77 %76 None\nOpBranchConditional %87 %76 %77\n%77 = OpLabel\n%88 = OpLoad %8 %74\n%89 = OpMatrixTimesScalar %8 %88 %60\nOpReturnValue %89\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f32.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _33)\n{\n    uint _41;\n    _41 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _42 = _41 + 1u;\n        coop_output[_41] = int16BitsToFloat16((int16_t(int8_t(_33[_41])) << 7s) & (-16385s));\n        if (_42 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _41 = _42;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _68)\n{\n    uint _76;\n    _76 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _77 = _76 + 1u;\n        coop_output[_76] = int16BitsToFloat16((int16_t(int8_t(_68[_76])) << 7s) & (-16385s));\n        if (_77 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _76 = _77;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _29;\n    coopMatLoad(_29, _20._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _60 = _29;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _65;\n    coopMatLoad(_65, _20._m0, 256u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _89 = _65;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _94;\n    coopMatLoad(_94, _20._m0, 512u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopMatMulAdd(CoopMatFP8toFP16(_60), CoopMatFP8toFP16_1(_89), _94, 0), _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24\nOpExecutionMode %14 LocalSize 32 1 1\nOpExecutionMode %14 DenormPreserve 16\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %34 \"CoopMatFP8toFP16\"\nOpName %37 \"coop_output\"\nOpName %69 \"CoopMatFP8toFP16\"\nOpName %72 \"coop_output\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%26 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %3\n%27 = OpTypePointer StorageBuffer %16\n%30 = OpTypeBool\n%31 = OpTypePointer Function %26\n%32 = OpTypeFunction %5 %31\n%36 = OpTypePointer Function %5\n%43 = OpTypePointer Function %16\n%46 = OpTypeInt 16 1\n%49 = OpConstant %46 7\n%51 = OpConstant %46 -16385\n%53 = OpTypePointer Function %1\n%58 = OpConstant %1 0x1p+8\n%62 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %7\n%64 = OpConstant %2 256\n%66 = OpTypePointer Function %62\n%67 = OpTypeFunction %8 %66\n%71 = OpTypePointer Function %8\n%92 = OpConstant %2 512\n%93 = OpConstant %2 64\n%14 = OpFunction %12 None %13\n%15 = OpLabel\n%60 = OpVariable %31 Function\n%89 = OpVariable %66 Function\nOpBranch %97\n%97 = OpLabel\n%28 = OpAccessChain %27 %20 %3 %3\n%29 = OpCooperativeMatrixLoadKHR %26 %28 %3 %4 NonPrivatePointer\nOpStore %60 %29\n%61 = OpFunctionCall %5 %34 %60\n%63 = OpAccessChain %27 %20 %3 %64\n%65 = OpCooperativeMatrixLoadKHR %62 %63 %3 %4 NonPrivatePointer\nOpStore %89 %65\n%90 = OpFunctionCall %8 %69 %89\n%91 = OpAccessChain %27 %20 %3 %92\n%94 = OpCooperativeMatrixLoadKHR %11 %91 %3 %93 NonPrivatePointer\n%95 = OpCooperativeMatrixMulAddKHR %11 %61 %90 %94\n%96 = OpAccessChain %27 %24 %3 %3\nOpCooperativeMatrixStoreKHR %96 %95 %3 %93 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%34 = OpFunction %5 None %32\n%33 = OpFunctionParameter %31\n%35 = OpLabel\n%37 = OpVariable %36 Function\n%38 = OpCooperativeMatrixLengthKHR %2 %26\nOpBranch %39\n%39 = OpLabel\n%41 = OpPhi %2 %3 %35 %42 %39\n%42 = OpIAdd %2 %41 %7\n%44 = OpInBoundsAccessChain %43 %33 %41\n%45 = OpLoad %16 %44\n%47 = OpSConvert %46 %45\n%48 = OpShiftLeftLogical %46 %47 %49\n%50 = OpBitwiseAnd %46 %48 %51\n%52 = OpBitcast %1 %50\n%54 = OpInBoundsAccessChain %53 %37 %41\nOpStore %54 %52\n%55 = OpULessThan %30 %42 %38\nOpLoopMerge %40 %39 None\nOpBranchConditional %55 %39 %40\n%40 = OpLabel\n%56 = OpLoad %5 %37\n%57 = OpMatrixTimesScalar %5 %56 %58\nOpReturnValue %57\nOpFunctionEnd\n%69 = OpFunction %8 None %67\n%68 = OpFunctionParameter %66\n%70 = OpLabel\n%72 = OpVariable %71 Function\n%73 = OpCooperativeMatrixLengthKHR %2 %62\nOpBranch %74\n%74 = OpLabel\n%76 = OpPhi %2 %3 %70 %77 %74\n%77 = OpIAdd %2 %76 %7\n%78 = OpInBoundsAccessChain %43 %68 %76\n%79 = OpLoad %16 %78\n%80 = OpSConvert %46 %79\n%81 = OpShiftLeftLogical %46 %80 %49\n%82 = OpBitwiseAnd %46 %81 %51\n%83 = OpBitcast %1 %82\n%84 = OpInBoundsAccessChain %53 %72 %76\nOpStore %84 %83\n%85 = OpULessThan %30 %77 %73\nOpLoopMerge %75 %74 None\nOpBranchConditional %85 %74 %75\n%75 = OpLabel\n%86 = OpLoad %8 %72\n%87 = OpMatrixTimesScalar %8 %86 %58\nOpReturnValue %87\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_fp16_fp8_conversions.sm66.ssbo.full-wmma.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_float_e4m3 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uvec2 _m0[];\n} _17;\n\nvoid main()\n{\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _36 = coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(uint16BitsToFloat16(uint16_t(gl_WorkGroupID.x))));\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _37 = coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(uint16BitsToFloat16(uint16_t(gl_WorkGroupID.x | 32768u))));\n    if (gl_LocalInvocationIndex == 0u)\n    {\n        _17._m0[gl_WorkGroupID.x] = uvec2((fe4m3vec4(_36[0], _36[1], _36[2], _36[3])), (fe4m3vec4(_37[0], _37[1], _37[2], _37[3])));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Float8EXT\nOpCapability Float8CooperativeMatrixEXT\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_EXT_float8\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %11 \"main\" %17 %19 %23\nOpExecutionMode %11 LocalSize 32 1 1\nOpExecutionMode %11 DenormPreserve 16\nOpName %11 \"main\"\nOpName %15 \"SSBO\"\nOpDecorate %14 ArrayStride 8\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 NonReadable\nOpDecorate %19 BuiltIn LocalInvocationIndex\nOpDecorate %23 BuiltIn WorkgroupId\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpTypeFloat 8 Float8E4M3EXT\n%8 = OpTypeCooperativeMatrixKHR %7 %6 %4 %4 %3\n%9 = OpTypeVoid\n%10 = OpTypeFunction %9\n%13 = OpTypeVector %2 2\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypeStruct %14\n%16 = OpTypePointer StorageBuffer %15\n%17 = OpVariable %16 StorageBuffer\n%18 = OpTypePointer Input %2\n%19 = OpVariable %18 Input\n%21 = OpTypeVector %2 3\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%27 = OpTypeInt 16 0\n%32 = OpConstant %2 32768\n%42 = OpTypeVector %7 4\n%51 = OpTypeBool\n%55 = OpTypePointer StorageBuffer %13\n%11 = OpFunction %9 None %10\n%12 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%20 = OpLoad %2 %19\n%24 = OpAccessChain %18 %23 %3\n%25 = OpLoad %2 %24\n%28 = OpUConvert %27 %25\n%29 = OpBitcast %1 %28\n%30 = OpCompositeConstruct %5 %29\n%31 = OpBitwiseOr %2 %25 %32\n%33 = OpUConvert %27 %31\n%34 = OpBitcast %1 %33\n%35 = OpCompositeConstruct %5 %34\n%36 = OpFConvert %8 %30\n%37 = OpFConvert %8 %35\n%38 = OpCompositeExtract %7 %36 0\n%39 = OpCompositeExtract %7 %36 1\n%40 = OpCompositeExtract %7 %36 2\n%41 = OpCompositeExtract %7 %36 3\n%43 = OpCompositeConstruct %42 %38 %39 %40 %41\n%44 = OpBitcast %2 %43\n%45 = OpCompositeExtract %7 %37 0\n%46 = OpCompositeExtract %7 %37 1\n%47 = OpCompositeExtract %7 %37 2\n%48 = OpCompositeExtract %7 %37 3\n%49 = OpCompositeConstruct %42 %45 %46 %47 %48\n%50 = OpBitcast %2 %49\n%52 = OpIEqual %51 %20 %3\nOpSelectionMerge %59 None\nOpBranchConditional %52 %58 %59\n%58 = OpLabel\n%53 = OpShiftLeftLogical %2 %25 %6\n%54 = OpCompositeConstruct %13 %44 %50\n%56 = OpAccessChain %55 %17 %3 %25\nOpStore %56 %54 NonPrivatePointer\nOpBranch %59\n%59 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_fp32_fp16_conversions.sm66.ssbo.full-wmma.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_NV_cooperative_matrix2 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _17;\n\nvoid main()\n{\n    if (gl_LocalInvocationIndex == 0u)\n    {\n        _17._m0[gl_WorkGroupID.x >> 2u] = uint(float16BitsToUint16((coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(uintBitsToFloat(gl_WorkGroupID.x))))[0]));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixConversionsNV\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_cooperative_matrix2\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %12 \"main\" %17 %19 %23\nOpExecutionMode %12 LocalSize 32 1 1\nOpExecutionMode %12 DenormPreserve 16\nOpName %12 \"main\"\nOpName %15 \"SSBO\"\nOpDecorate %14 ArrayStride 4\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 NonReadable\nOpDecorate %19 BuiltIn LocalInvocationIndex\nOpDecorate %23 BuiltIn WorkgroupId\n%1 = OpTypeFloat 32\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 2\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpTypeFloat 16\n%8 = OpConstant %2 1\n%9 = OpTypeCooperativeMatrixKHR %7 %6 %4 %4 %8\n%10 = OpTypeVoid\n%11 = OpTypeFunction %10\n%14 = OpTypeRuntimeArray %2\n%15 = OpTypeStruct %14\n%16 = OpTypePointer StorageBuffer %15\n%17 = OpVariable %16 StorageBuffer\n%18 = OpTypePointer Input %2\n%19 = OpVariable %18 Input\n%21 = OpTypeVector %2 3\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%25 = OpConstant %2 0\n%32 = OpTypeInt 16 0\n%35 = OpTypeBool\n%38 = OpTypePointer StorageBuffer %2\n%12 = OpFunction %10 None %11\n%13 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%20 = OpLoad %2 %19\n%24 = OpAccessChain %18 %23 %25\n%26 = OpLoad %2 %24\n%28 = OpBitcast %1 %26\n%29 = OpCompositeConstruct %5 %28\n%30 = OpFConvert %9 %29\n%31 = OpCompositeExtract %7 %30 0\n%33 = OpBitcast %32 %31\n%34 = OpUConvert %2 %33\n%36 = OpIEqual %35 %20 %25\nOpSelectionMerge %42 None\nOpBranchConditional %36 %41 %42\n%41 = OpLabel\n%37 = OpShiftRightLogical %2 %26 %3\n%39 = OpAccessChain %38 %17 %25 %37\nOpStore %39 %34 NonPrivatePointer\nOpBranch %42\n%42 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_fp32_fp8_conversions.sm66.ssbo.nv-coopmat2.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_spirv_intrinsics : require\n#extension GL_NV_cooperative_matrix2 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint8_t _m0[];\n} _18;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> CoopMatSaturateFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _34)\n{\n    uint _41;\n    _41 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> coop_output;\n    for (;;)\n    {\n        uint _42 = _41 + 1u;\n        coop_output[_41] = spvNClamp(_34[_41], float16_t(-448.0), float16_t(448.0));\n        if (_42 < uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length()))\n        {\n            _41 = _42;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output;\n}\n\ncoopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP16toFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _67)\n{\n    uint _75;\n    _75 = 0u;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _76 = _75 + 2u;\n        uint _77 = _75 + 1u;\n        i16vec2 _83 = float16BitsToInt16(f16vec2(_67[_75], _67[_77]));\n        i16vec2 _93 = (_83 << i16vec2(1)) - i16vec2(16384);\n        i16vec2 _99 = (_93 >> i16vec2(11)) - i16vec2(1);\n        i16vec2 _114 = (_93 & ((_99 & i16vec2(-2048)) ^ i16vec2(-1))) | (_99 & i16vec2(2048));\n        i16vec2 _118 = _114 >> max((-_99), i16vec2(0));\n        i16vec2 _120 = i16vec2(u16vec2(_118) >> u16vec2(i16vec2(8)));\n        u8vec2 _135 = u8vec2(((_120 + i16vec2(greaterThan(u16vec2(((_120 & i16vec2(1)) | (_118 | (_114 & i16vec2(127)))) << i16vec2(8)), u16vec2(32768)))) & i16vec2(127)) | (i16vec2(u16vec2(_83) >> u16vec2(i16vec2(15))) << i16vec2(7)));\n        coop_output[_75] = _135.x;\n        coop_output[_77] = _135.y;\n        if (_76 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _75 = _76;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output;\n}\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _54 = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(uintBitsToFloat(gl_WorkGroupID.x)));\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _144 = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(CoopMatSaturateFP8(_54));\n    coopMatStore(CoopMatFP16toFP8(_144), _18._m0, 0u, 16u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 148\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixConversionsNV\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_cooperative_matrix2\"\n%46 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %12 \"main\" %18 %21\nOpExecutionMode %12 LocalSize 32 1 1\nOpExecutionMode %12 DenormPreserve 16\nOpName %12 \"main\"\nOpName %16 \"SSBO\"\nOpName %35 \"CoopMatSaturateFP8\"\nOpName %37 \"coop_output\"\nOpName %68 \"CoopMatFP16toFP8\"\nOpName %71 \"coop_output\"\nOpDecorate %15 ArrayStride 1\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %18 NonReadable\nOpDecorate %21 BuiltIn WorkgroupId\n%1 = OpTypeFloat 32\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 2\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpTypeFloat 16\n%8 = OpConstant %2 1\n%9 = OpTypeCooperativeMatrixKHR %7 %6 %4 %4 %8\n%10 = OpTypeVoid\n%11 = OpTypeFunction %10\n%14 = OpTypeInt 8 0\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeVector %2 3\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Input %2\n%24 = OpConstant %2 0\n%29 = OpTypeCooperativeMatrixKHR %7 %6 %4 %4 %3\n%31 = OpTypeBool\n%32 = OpTypePointer Function %29\n%33 = OpTypeFunction %29 %32\n%43 = OpTypePointer Function %7\n%48 = OpConstant %7 -0x1.cp+8\n%49 = OpConstant %7 0x1.cp+8\n%57 = OpTypePointer StorageBuffer %14\n%59 = OpTypeCooperativeMatrixKHR %14 %6 %4 %4 %8\n%60 = OpTypeInt 16 1\n%61 = OpTypeVector %31 2\n%62 = OpTypeVector %7 2\n%63 = OpTypeVector %60 2\n%64 = OpTypeVector %14 2\n%65 = OpTypePointer Function %9\n%66 = OpTypeFunction %59 %65\n%70 = OpTypePointer Function %59\n%85 = OpConstant %60 15\n%86 = OpConstantComposite %63 %85 %85\n%88 = OpConstant %60 7\n%89 = OpConstantComposite %63 %88 %88\n%91 = OpConstant %60 1\n%92 = OpConstantComposite %63 %91 %91\n%94 = OpConstant %60 16384\n%95 = OpConstantComposite %63 %94 %94\n%97 = OpConstant %60 11\n%98 = OpConstantComposite %63 %97 %97\n%102 = OpConstant %60 0\n%103 = OpConstantComposite %63 %102 %102\n%105 = OpConstant %60 2048\n%106 = OpConstantComposite %63 %105 %105\n%108 = OpConstant %60 -2048\n%109 = OpConstantComposite %63 %108 %108\n%111 = OpConstant %60 -1\n%112 = OpConstantComposite %63 %111 %111\n%116 = OpConstant %60 127\n%117 = OpConstantComposite %63 %116 %116\n%121 = OpConstant %60 8\n%122 = OpConstantComposite %63 %121 %121\n%127 = OpTypeInt 16 0\n%128 = OpConstant %127 32768\n%129 = OpTypeVector %127 2\n%130 = OpConstantComposite %129 %128 %128\n%136 = OpTypePointer Function %14\n%12 = OpFunction %10 None %11\n%13 = OpLabel\n%54 = OpVariable %32 Function\n%144 = OpVariable %65 Function\nOpBranch %146\n%146 = OpLabel\n%23 = OpAccessChain %22 %21 %24\n%25 = OpLoad %2 %23\n%27 = OpBitcast %1 %25\n%28 = OpCompositeConstruct %5 %27\n%30 = OpFConvert %29 %28\nOpStore %54 %30\n%55 = OpFunctionCall %29 %35 %54\n%56 = OpCooperativeMatrixConvertNV %9 %55\n%58 = OpAccessChain %57 %18 %24 %24\nOpStore %144 %56\n%145 = OpFunctionCall %59 %68 %144\nOpCooperativeMatrixStoreKHR %58 %145 %8 %4 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%35 = OpFunction %29 None %33\n%34 = OpFunctionParameter %32\n%36 = OpLabel\n%37 = OpVariable %32 Function\n%38 = OpCooperativeMatrixLengthKHR %2 %29\nOpBranch %39\n%39 = OpLabel\n%41 = OpPhi %2 %24 %36 %42 %39\n%42 = OpIAdd %2 %41 %8\n%44 = OpInBoundsAccessChain %43 %34 %41\n%45 = OpLoad %7 %44\n%47 = OpExtInst %7 %46 NClamp %45 %48 %49\n%50 = OpInBoundsAccessChain %43 %37 %41\nOpStore %50 %47\n%51 = OpULessThan %31 %42 %38\nOpLoopMerge %40 %39 None\nOpBranchConditional %51 %39 %40\n%40 = OpLabel\n%52 = OpLoad %29 %37\nOpReturnValue %52\nOpFunctionEnd\n%68 = OpFunction %59 None %66\n%67 = OpFunctionParameter %65\n%69 = OpLabel\n%71 = OpVariable %70 Function\n%72 = OpCooperativeMatrixLengthKHR %2 %59\nOpBranch %73\n%73 = OpLabel\n%75 = OpPhi %2 %24 %69 %76 %73\n%76 = OpIAdd %2 %75 %3\n%77 = OpIAdd %2 %75 %8\n%78 = OpInBoundsAccessChain %43 %67 %75\n%79 = OpLoad %7 %78\n%80 = OpInBoundsAccessChain %43 %67 %77\n%81 = OpLoad %7 %80\n%82 = OpCompositeConstruct %62 %79 %81\n%83 = OpBitcast %63 %82\n%84 = OpShiftRightLogical %63 %83 %86\n%87 = OpShiftLeftLogical %63 %84 %89\n%90 = OpShiftLeftLogical %63 %83 %92\n%93 = OpISub %63 %90 %95\n%96 = OpShiftRightArithmetic %63 %93 %98\n%99 = OpISub %63 %96 %92\n%100 = OpSNegate %63 %99\n%101 = OpExtInst %63 %46 SMax %100 %103\n%104 = OpBitwiseAnd %63 %99 %106\n%107 = OpBitwiseAnd %63 %99 %109\n%110 = OpBitwiseXor %63 %107 %112\n%113 = OpBitwiseAnd %63 %93 %110\n%114 = OpBitwiseOr %63 %113 %104\n%115 = OpBitwiseAnd %63 %114 %117\n%118 = OpShiftRightArithmetic %63 %114 %101\n%119 = OpBitwiseOr %63 %118 %115\n%120 = OpShiftRightLogical %63 %118 %122\n%123 = OpBitwiseAnd %63 %120 %92\n%124 = OpBitwiseOr %63 %123 %119\n%125 = OpShiftLeftLogical %63 %124 %122\n%126 = OpUGreaterThan %61 %125 %130\n%131 = OpSelect %63 %126 %92 %103\n%132 = OpIAdd %63 %120 %131\n%133 = OpBitwiseAnd %63 %132 %117\n%134 = OpBitwiseOr %63 %133 %87\n%135 = OpUConvert %64 %134\n%137 = OpInBoundsAccessChain %136 %71 %75\n%138 = OpCompositeExtract %14 %135 0\nOpStore %137 %138\n%139 = OpInBoundsAccessChain %136 %71 %77\n%140 = OpCompositeExtract %14 %135 1\nOpStore %139 %140\n%141 = OpULessThan %31 %76 %72\nOpLoopMerge %74 %73 None\nOpBranchConditional %141 %73 %74\n%74 = OpLabel\n%142 = OpLoad %59 %71\nOpReturnValue %142\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_fp8_fp32_conversions.sm66.ssbo.full-wmma.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_float_e4m3 : require\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _20;\n\nshared uint _24[512];\n\nvoid main()\n{\n    coopMatStore(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(uintBitsToFloate4m3EXT(uint8_t(gl_WorkGroupID.x)))), _24, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    barrier();\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _44;\n    coopMatLoad(_44, _24, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    if (gl_LocalInvocationIndex == 0u)\n    {\n        _20._m0[gl_WorkGroupID.x] = floatBitsToUint((coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(_44))[0]);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 57\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability Float8EXT\nOpCapability Float8CooperativeMatrixEXT\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_EXT_float8\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %15 \"main\" %20 %24 %26 %30\nOpExecutionMode %15 LocalSize 32 1 1\nOpExecutionMode %15 DenormPreserve 16\nOpName %15 \"main\"\nOpName %18 \"SSBO\"\nOpDecorate %17 ArrayStride 4\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonReadable\nOpDecorate %26 BuiltIn LocalInvocationIndex\nOpDecorate %30 BuiltIn WorkgroupId\n%1 = OpTypeFloat 8 Float8E4M3EXT\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpTypeFloat 16\n%8 = OpTypeCooperativeMatrixKHR %7 %6 %4 %4 %3\n%9 = OpConstant %2 2\n%10 = OpTypeCooperativeMatrixKHR %7 %6 %4 %4 %9\n%11 = OpTypeFloat 32\n%12 = OpTypeCooperativeMatrixKHR %11 %6 %4 %4 %9\n%13 = OpTypeVoid\n%14 = OpTypeFunction %13\n%17 = OpTypeRuntimeArray %2\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpConstant %2 512\n%22 = OpTypeArray %2 %21\n%23 = OpTypePointer Workgroup %22\n%24 = OpVariable %23 Workgroup\n%25 = OpTypePointer Input %2\n%26 = OpVariable %25 Input\n%28 = OpTypeVector %2 3\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%34 = OpTypeInt 8 0\n%39 = OpTypePointer Workgroup %2\n%41 = OpConstant %2 32\n%42 = OpConstant %2 24840\n%48 = OpTypeBool\n%51 = OpTypePointer StorageBuffer %2\n%15 = OpFunction %13 None %14\n%16 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%27 = OpLoad %2 %26\n%31 = OpAccessChain %25 %30 %3\n%32 = OpLoad %2 %31\n%35 = OpUConvert %34 %32\n%36 = OpBitcast %1 %35\n%37 = OpCompositeConstruct %5 %36\n%38 = OpFConvert %8 %37\n%40 = OpAccessChain %39 %24 %3\nOpCooperativeMatrixStoreKHR %40 %38 %3 %41 NonPrivatePointer\nOpControlBarrier %9 %9 %42\n%43 = OpAccessChain %39 %24 %3\nOpControlBarrier %6 %6 %42\n%44 = OpCooperativeMatrixLoadKHR %10 %43 %3 %41 NonPrivatePointer\nOpControlBarrier %6 %6 %42\n%45 = OpFConvert %12 %44\n%46 = OpCompositeExtract %11 %45 0\n%47 = OpBitcast %2 %46\n%49 = OpIEqual %48 %27 %3\nOpSelectionMerge %55 None\nOpBranchConditional %49 %54 %55\n%54 = OpLabel\n%50 = OpShiftLeftLogical %2 %32 %9\n%52 = OpAccessChain %51 %20 %3 %32\nOpStore %52 %47 NonPrivatePointer\nOpBranch %55\n%55 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_lds_transpose.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\nshared uint _28[512];\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _33;\n    coopMatLoad(_33, _20._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(_33, _28, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    barrier();\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _38;\n    coopMatLoad(_38, _28, 0u, 32u, gl_CooperativeMatrixLayoutColumnMajor);\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _40;\n    coopMatLoad(_40, _28, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    coopMatStore(coopMatMulAdd(_38, _40, coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0.0), 0), _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24 %28\nOpExecutionMode %14 LocalSize 32 1 1\nOpExecutionMode %14 DenormPreserve 16\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpConstant %2 512\n%26 = OpTypeArray %2 %25\n%27 = OpTypePointer Workgroup %26\n%28 = OpVariable %27 Workgroup\n%30 = OpTypePointer StorageBuffer %16\n%32 = OpConstant %2 32\n%34 = OpTypePointer Workgroup %2\n%36 = OpConstant %2 24840\n%41 = OpConstant %9 0\n%42 = OpConstantComposite %11 %41\n%45 = OpConstant %2 64\n%14 = OpFunction %12 None %13\n%15 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%31 = OpAccessChain %30 %20 %3 %3\n%33 = OpCooperativeMatrixLoadKHR %5 %31 %3 %32 NonPrivatePointer\n%35 = OpAccessChain %34 %28 %3\nOpCooperativeMatrixStoreKHR %35 %33 %3 %32 NonPrivatePointer\nOpControlBarrier %10 %10 %36\n%37 = OpAccessChain %34 %28 %3\nOpControlBarrier %6 %6 %36\n%38 = OpCooperativeMatrixLoadKHR %5 %37 %7 %32 NonPrivatePointer\nOpControlBarrier %6 %6 %36\n%39 = OpAccessChain %34 %28 %3\nOpControlBarrier %6 %6 %36\n%40 = OpCooperativeMatrixLoadKHR %8 %39 %3 %32 NonPrivatePointer\nOpControlBarrier %6 %6 %36\n%43 = OpCooperativeMatrixMulAddKHR %11 %38 %40 %42\n%44 = OpAccessChain %30 %24 %3 %3\nOpCooperativeMatrixStoreKHR %44 %43 %3 %45 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_matrix_length.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nvoid main()\n{\n    uint _13[10];\n    _13[0u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length());\n    _13[1u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length());\n    _13[2u] = uint(coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length());\n    _13[3u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()) / 4u;\n    _13[4u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()) / 4u;\n    _13[5u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length());\n    _13[6u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length());\n    _13[7u] = uint(coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length());\n    _13[8u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()) / 4u;\n    _13[9u] = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()) / 4u;\n    uint _56;\n    uint _58;\n    _56 = uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length());\n    _58 = 0u;\n    uint _59;\n    for (;;)\n    {\n        _9._m0[_58] = _56;\n        _59 = _58 + 1u;\n        if (_59 == 10u)\n        {\n            break;\n        }\n        else\n        {\n            _56 = _13[_59];\n            _58 = _59;\n            continue;\n        }\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %9\nOpExecutionMode %3 LocalSize 32 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpConstant %5 10\n%11 = OpTypeArray %5 %10\n%12 = OpTypePointer Function %11\n%15 = OpTypeFloat 16\n%16 = OpConstant %5 0\n%17 = OpConstant %5 16\n%19 = OpConstant %5 3\n%18 = OpTypeCooperativeMatrixKHR %15 %19 %17 %17 %16\n%21 = OpTypePointer Function %5\n%23 = OpConstant %5 1\n%24 = OpTypeCooperativeMatrixKHR %15 %19 %17 %17 %23\n%27 = OpTypeFloat 32\n%28 = OpConstant %5 2\n%29 = OpTypeCooperativeMatrixKHR %27 %19 %17 %17 %28\n%34 = OpConstant %5 4\n%41 = OpConstant %5 5\n%44 = OpConstant %5 6\n%47 = OpConstant %5 7\n%51 = OpConstant %5 8\n%55 = OpConstant %5 9\n%61 = OpTypePointer StorageBuffer %5\n%63 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%13 = OpVariable %12 Function\nOpBranch %66\n%66 = OpLabel\n%20 = OpCooperativeMatrixLengthKHR %5 %18\n%22 = OpInBoundsAccessChain %21 %13 %16\nOpStore %22 %20\n%25 = OpCooperativeMatrixLengthKHR %5 %24\n%26 = OpInBoundsAccessChain %21 %13 %23\nOpStore %26 %25\n%30 = OpCooperativeMatrixLengthKHR %5 %29\n%31 = OpInBoundsAccessChain %21 %13 %28\nOpStore %31 %30\n%32 = OpCooperativeMatrixLengthKHR %5 %18\n%33 = OpUDiv %5 %32 %34\n%35 = OpInBoundsAccessChain %21 %13 %19\nOpStore %35 %33\n%36 = OpCooperativeMatrixLengthKHR %5 %24\n%37 = OpUDiv %5 %36 %34\n%38 = OpInBoundsAccessChain %21 %13 %34\nOpStore %38 %37\n%39 = OpCooperativeMatrixLengthKHR %5 %18\n%40 = OpInBoundsAccessChain %21 %13 %41\nOpStore %40 %39\n%42 = OpCooperativeMatrixLengthKHR %5 %24\n%43 = OpInBoundsAccessChain %21 %13 %44\nOpStore %43 %42\n%45 = OpCooperativeMatrixLengthKHR %5 %29\n%46 = OpInBoundsAccessChain %21 %13 %47\nOpStore %46 %45\n%48 = OpCooperativeMatrixLengthKHR %5 %18\n%49 = OpUDiv %5 %48 %34\n%50 = OpInBoundsAccessChain %21 %13 %51\nOpStore %50 %49\n%52 = OpCooperativeMatrixLengthKHR %5 %24\n%53 = OpUDiv %5 %52 %34\n%54 = OpInBoundsAccessChain %21 %13 %55\nOpStore %54 %53\nOpBranch %67\n%67 = OpLabel\n%56 = OpPhi %5 %20 %66 %57 %69\n%58 = OpPhi %5 %16 %66 %59 %69\n%60 = OpShiftLeftLogical %5 %58 %28\n%62 = OpAccessChain %61 %9 %16 %58\nOpStore %62 %56 NonPrivatePointer\n%59 = OpIAdd %5 %58 %23\n%64 = OpIEqual %63 %59 %10\nOpLoopMerge %70 %69 None\nOpBranchConditional %64 %70 %68\n%68 = OpLabel\nOpBranch %69\n%69 = OpLabel\n%65 = OpInBoundsAccessChain %21 %13 %59\n%57 = OpLoad %5 %65\nOpBranch %67\n%70 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_store_phi.full-wmma.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\n#extension GL_EXT_float_e4m3 : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\nlayout(set = 0, binding = 0, std140) uniform _27_29\n{\n    vec4 _m0[1];\n} _29;\n\nvoid main()\n{\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _89;\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33[2];\n    coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _36[2];\n    uint _37 = 0u;\n    uint _39;\n    bool _82;\n    for (;;)\n    {\n        _39 = _37 << 5u;\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _45;\n        coopMatLoad(_45, _20._m0, _39, 64u, gl_CooperativeMatrixLayoutRowMajor);\n        _36[_37] = _45;\n        _82 = floatBitsToUint(_29._m0[0u]).x == 1u;\n        coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> frontier_phi_4_pred;\n        if (_82)\n        {\n            coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _86;\n            coopMatLoad(_86, _20._m0, _39 + 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n            frontier_phi_4_pred = _86;\n        }\n        else\n        {\n            frontier_phi_4_pred = coopmat<floate4m3_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(floate4m3_t(0.0));\n        }\n        _89 = frontier_phi_4_pred;\n        _33[_37] = _89;\n        uint _38 = _37 + 1u;\n        if (_38 == 2u)\n        {\n            break;\n        }\n        else\n        {\n            _37 = _38;\n            continue;\n        }\n    }\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _118;\n    uint _120;\n    _118 = coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0.0);\n    _120 = 0u;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _186;\n    for (;;)\n    {\n        _186 = coopMatMulAdd(_36[_120], _33[_120], _118, 0);\n        uint _121 = _120 + 1u;\n        if (_121 == 2u)\n        {\n            break;\n        }\n        else\n        {\n            _118 = _186;\n            _120 = _121;\n        }\n    }\n    coopMatStore(_186, _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 201\n; Schema: 0\nOpCapability Shader\nOpCapability Int8\nOpCapability Float8EXT\nOpCapability Float8CooperativeMatrixEXT\nOpCapability StorageBuffer8BitAccess\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_EXT_float8\"\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24 %29\nOpExecutionMode %14 LocalSize 32 1 1\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %27 \"\"\nOpName %189 \"frontier_phi_4.pred\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\n%1 = OpTypeFloat 8 Float8E4M3EXT\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeVector %9 4\n%26 = OpTypeArray %25 %7\n%27 = OpTypeStruct %26\n%28 = OpTypePointer Uniform %27\n%29 = OpVariable %28 Uniform\n%30 = OpTypeArray %2 %4\n%31 = OpTypeArray %8 %10\n%32 = OpTypePointer Function %31\n%34 = OpTypeArray %5 %10\n%35 = OpTypePointer Function %34\n%40 = OpConstant %2 5\n%42 = OpTypePointer StorageBuffer %16\n%44 = OpConstant %2 64\n%47 = OpConstant %2 8\n%49 = OpTypePointer Function %5\n%62 = OpConstant %2 4\n%69 = OpConstant %2 6\n%73 = OpConstant %2 7\n%75 = OpTypePointer Uniform %25\n%78 = OpTypeVector %2 4\n%81 = OpTypeBool\n%84 = OpConstant %2 1024\n%87 = OpConstant %1 0x0p+0\n%88 = OpConstantComposite %8 %87\n%92 = OpTypePointer Function %8\n%116 = OpConstant %9 0\n%117 = OpConstantComposite %11 %116\n%14 = OpFunction %12 None %13\n%15 = OpLabel\n%33 = OpVariable %32 Function\n%36 = OpVariable %35 Function\nOpBranch %190\n%190 = OpLabel\nOpBranch %191\n%191 = OpLabel\n%37 = OpPhi %2 %3 %190 %38 %196\n%39 = OpShiftLeftLogical %2 %37 %40\n%43 = OpAccessChain %42 %20 %3 %39\n%45 = OpCooperativeMatrixLoadKHR %5 %43 %3 %44 NonPrivatePointer\n%46 = OpIMul %2 %37 %47\n%48 = OpIAdd %2 %3 %46\n%50 = OpAccessChain %49 %36 %37\nOpStore %50 %45\n%51 = OpIMul %2 %37 %47\n%52 = OpIAdd %2 %7 %51\n%54 = OpIMul %2 %37 %47\n%55 = OpIAdd %2 %10 %54\n%57 = OpIMul %2 %37 %47\n%58 = OpIAdd %2 %6 %57\n%60 = OpIMul %2 %37 %47\n%61 = OpIAdd %2 %62 %60\n%64 = OpIMul %2 %37 %47\n%65 = OpIAdd %2 %40 %64\n%67 = OpIMul %2 %37 %47\n%68 = OpIAdd %2 %69 %67\n%71 = OpIMul %2 %37 %47\n%72 = OpIAdd %2 %73 %71\n%76 = OpAccessChain %75 %29 %3 %3\n%77 = OpLoad %25 %76\n%79 = OpBitcast %78 %77\n%80 = OpCompositeExtract %2 %79 0\n%82 = OpIEqual %81 %80 %7\nOpLoopMerge %197 %196 None\nOpBranch %192\n%192 = OpLabel\nOpSelectionMerge %195 None\nOpBranchConditional %82 %194 %193\n%194 = OpLabel\n%83 = OpIAdd %2 %39 %84\n%85 = OpAccessChain %42 %20 %3 %83\n%86 = OpCooperativeMatrixLoadKHR %8 %85 %7 %44 NonPrivatePointer\nOpBranch %195\n%193 = OpLabel\nOpBranch %195\n%195 = OpLabel\n%189 = OpPhi %8 %86 %194 %88 %193\n%89 = OpCopyObject %8 %189\nOpBranch %196\n%196 = OpLabel\n%90 = OpIMul %2 %37 %47\n%91 = OpIAdd %2 %3 %90\n%93 = OpAccessChain %92 %33 %37\nOpStore %93 %89\n%94 = OpIMul %2 %37 %47\n%95 = OpIAdd %2 %7 %94\n%97 = OpIMul %2 %37 %47\n%98 = OpIAdd %2 %10 %97\n%100 = OpIMul %2 %37 %47\n%101 = OpIAdd %2 %6 %100\n%103 = OpIMul %2 %37 %47\n%104 = OpIAdd %2 %62 %103\n%106 = OpIMul %2 %37 %47\n%107 = OpIAdd %2 %40 %106\n%109 = OpIMul %2 %37 %47\n%110 = OpIAdd %2 %69 %109\n%112 = OpIMul %2 %37 %47\n%113 = OpIAdd %2 %73 %112\n%38 = OpIAdd %2 %37 %7\n%115 = OpIEqual %81 %38 %10\nOpBranchConditional %115 %197 %191\n%197 = OpLabel\nOpBranch %198\n%198 = OpLabel\n%118 = OpPhi %11 %117 %197 %186 %198\n%120 = OpPhi %2 %3 %197 %121 %198\n%122 = OpIMul %2 %120 %47\n%123 = OpIAdd %2 %7 %122\n%126 = OpIMul %2 %120 %47\n%127 = OpIAdd %2 %3 %126\n%128 = OpAccessChain %49 %36 %120\n%129 = OpLoad %5 %128\n%130 = OpIMul %2 %120 %47\n%131 = OpIAdd %2 %6 %130\n%134 = OpIMul %2 %120 %47\n%135 = OpIAdd %2 %10 %134\n%138 = OpIMul %2 %120 %47\n%139 = OpIAdd %2 %40 %138\n%142 = OpIMul %2 %120 %47\n%143 = OpIAdd %2 %62 %142\n%146 = OpIMul %2 %120 %47\n%147 = OpIAdd %2 %73 %146\n%150 = OpIMul %2 %120 %47\n%151 = OpIAdd %2 %69 %150\n%154 = OpIMul %2 %120 %47\n%155 = OpIAdd %2 %7 %154\n%158 = OpIMul %2 %120 %47\n%159 = OpIAdd %2 %3 %158\n%160 = OpAccessChain %92 %33 %120\n%161 = OpLoad %8 %160\n%162 = OpIMul %2 %120 %47\n%163 = OpIAdd %2 %6 %162\n%166 = OpIMul %2 %120 %47\n%167 = OpIAdd %2 %10 %166\n%170 = OpIMul %2 %120 %47\n%171 = OpIAdd %2 %40 %170\n%174 = OpIMul %2 %120 %47\n%175 = OpIAdd %2 %62 %174\n%178 = OpIMul %2 %120 %47\n%179 = OpIAdd %2 %73 %178\n%182 = OpIMul %2 %120 %47\n%183 = OpIAdd %2 %69 %182\n%186 = OpCooperativeMatrixMulAddKHR %11 %129 %161 %118\n%121 = OpIAdd %2 %120 %7\n%187 = OpIEqual %81 %121 %10\nOpLoopMerge %199 %198 None\nOpBranchConditional %187 %199 %198\n%199 = OpLabel\n%188 = OpAccessChain %42 %24 %3 %3\nOpCooperativeMatrixStoreKHR %188 %186 %7 %44 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/ags/cs_wmma_store_phi.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\nlayout(set = 0, binding = 0, std140) uniform _27_29\n{\n    vec4 _m0[1];\n} _29;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _50)\n{\n    uint _58;\n    _58 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _59 = _58 + 1u;\n        coop_output[_58] = int16BitsToFloat16((int16_t(int8_t(_50[_58])) << 7s) & (-16385s));\n        if (_59 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _58 = _59;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _121)\n{\n    uint _129;\n    _129 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _130 = _129 + 1u;\n        coop_output[_129] = int16BitsToFloat16((int16_t(int8_t(_121[_129])) << 7s) & (-16385s));\n        if (_130 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _129 = _130;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _146;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33[2];\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _36[2];\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _77;\n    uint _37 = 0u;\n    uint _39;\n    bool _113;\n    for (;;)\n    {\n        _39 = _37 << 5u;\n        coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _46;\n        coopMatLoad(_46, _20._m0, _39, 64u, gl_CooperativeMatrixLayoutRowMajor);\n        _77 = _46;\n        _36[_37] = CoopMatFP8toFP16(_77);\n        _113 = floatBitsToUint(_29._m0[0u]).x == 1u;\n        coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> frontier_phi_4_pred;\n        if (_113)\n        {\n            coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _118;\n            coopMatLoad(_118, _20._m0, _39 + 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n            coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _142 = _118;\n            frontier_phi_4_pred = CoopMatFP8toFP16_1(_142);\n        }\n        else\n        {\n            frontier_phi_4_pred = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(float16_t(0.0));\n        }\n        _146 = frontier_phi_4_pred;\n        _33[_37] = _146;\n        uint _38 = _37 + 1u;\n        if (_38 == 2u)\n        {\n            break;\n        }\n        else\n        {\n            _37 = _38;\n            continue;\n        }\n    }\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _174;\n    uint _176;\n    _174 = coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0.0);\n    _176 = 0u;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _242;\n    for (;;)\n    {\n        _242 = coopMatMulAdd(_36[_176], _33[_176], _174, 0);\n        uint _177 = _176 + 1u;\n        if (_177 == 2u)\n        {\n            break;\n        }\n        else\n        {\n            _174 = _242;\n            _176 = _177;\n        }\n    }\n    coopMatStore(_242, _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutColumnMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 257\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24 %29\nOpExecutionMode %14 LocalSize 32 1 1\nOpExecutionMode %14 DenormPreserve 16\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %27 \"\"\nOpName %51 \"CoopMatFP8toFP16\"\nOpName %54 \"coop_output\"\nOpName %122 \"CoopMatFP8toFP16\"\nOpName %125 \"coop_output\"\nOpName %245 \"frontier_phi_4.pred\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeVector %9 4\n%26 = OpTypeArray %25 %7\n%27 = OpTypeStruct %26\n%28 = OpTypePointer Uniform %27\n%29 = OpVariable %28 Uniform\n%30 = OpTypeArray %2 %4\n%31 = OpTypeArray %8 %10\n%32 = OpTypePointer Function %31\n%34 = OpTypeArray %5 %10\n%35 = OpTypePointer Function %34\n%40 = OpConstant %2 5\n%42 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %3\n%43 = OpTypePointer StorageBuffer %16\n%45 = OpConstant %2 64\n%47 = OpTypeBool\n%48 = OpTypePointer Function %42\n%49 = OpTypeFunction %5 %48\n%53 = OpTypePointer Function %5\n%60 = OpTypePointer Function %16\n%63 = OpTypeInt 16 1\n%66 = OpConstant %63 7\n%68 = OpConstant %63 -16385\n%70 = OpTypePointer Function %1\n%75 = OpConstant %1 0x1p+8\n%80 = OpConstant %2 8\n%94 = OpConstant %2 4\n%101 = OpConstant %2 6\n%105 = OpConstant %2 7\n%107 = OpTypePointer Uniform %25\n%110 = OpTypeVector %2 4\n%115 = OpConstant %2 1024\n%116 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %7\n%119 = OpTypePointer Function %116\n%120 = OpTypeFunction %8 %119\n%124 = OpTypePointer Function %8\n%144 = OpConstant %1 0x0p+0\n%145 = OpConstantComposite %8 %144\n%172 = OpConstant %9 0\n%173 = OpConstantComposite %11 %172\n%14 = OpFunction %12 None %13\n%15 = OpLabel\n%33 = OpVariable %32 Function\n%36 = OpVariable %35 Function\n%77 = OpVariable %48 Function\n%142 = OpVariable %119 Function\nOpBranch %246\n%246 = OpLabel\nOpBranch %247\n%247 = OpLabel\n%37 = OpPhi %2 %3 %246 %38 %252\n%39 = OpShiftLeftLogical %2 %37 %40\n%44 = OpAccessChain %43 %20 %3 %39\n%46 = OpCooperativeMatrixLoadKHR %42 %44 %3 %45 NonPrivatePointer\nOpStore %77 %46\n%78 = OpFunctionCall %5 %51 %77\n%79 = OpIMul %2 %37 %80\n%81 = OpIAdd %2 %3 %79\n%82 = OpAccessChain %53 %36 %37\nOpStore %82 %78\n%83 = OpIMul %2 %37 %80\n%84 = OpIAdd %2 %7 %83\n%86 = OpIMul %2 %37 %80\n%87 = OpIAdd %2 %10 %86\n%89 = OpIMul %2 %37 %80\n%90 = OpIAdd %2 %6 %89\n%92 = OpIMul %2 %37 %80\n%93 = OpIAdd %2 %94 %92\n%96 = OpIMul %2 %37 %80\n%97 = OpIAdd %2 %40 %96\n%99 = OpIMul %2 %37 %80\n%100 = OpIAdd %2 %101 %99\n%103 = OpIMul %2 %37 %80\n%104 = OpIAdd %2 %105 %103\n%108 = OpAccessChain %107 %29 %3 %3\n%109 = OpLoad %25 %108\n%111 = OpBitcast %110 %109\n%112 = OpCompositeExtract %2 %111 0\n%113 = OpIEqual %47 %112 %7\nOpLoopMerge %253 %252 None\nOpBranch %248\n%248 = OpLabel\nOpSelectionMerge %251 None\nOpBranchConditional %113 %250 %249\n%250 = OpLabel\n%114 = OpIAdd %2 %39 %115\n%117 = OpAccessChain %43 %20 %3 %114\n%118 = OpCooperativeMatrixLoadKHR %116 %117 %7 %45 NonPrivatePointer\nOpStore %142 %118\n%143 = OpFunctionCall %8 %122 %142\nOpBranch %251\n%249 = OpLabel\nOpBranch %251\n%251 = OpLabel\n%245 = OpPhi %8 %143 %250 %145 %249\n%146 = OpCopyObject %8 %245\nOpBranch %252\n%252 = OpLabel\n%147 = OpIMul %2 %37 %80\n%148 = OpIAdd %2 %3 %147\n%149 = OpAccessChain %124 %33 %37\nOpStore %149 %146\n%150 = OpIMul %2 %37 %80\n%151 = OpIAdd %2 %7 %150\n%153 = OpIMul %2 %37 %80\n%154 = OpIAdd %2 %10 %153\n%156 = OpIMul %2 %37 %80\n%157 = OpIAdd %2 %6 %156\n%159 = OpIMul %2 %37 %80\n%160 = OpIAdd %2 %94 %159\n%162 = OpIMul %2 %37 %80\n%163 = OpIAdd %2 %40 %162\n%165 = OpIMul %2 %37 %80\n%166 = OpIAdd %2 %101 %165\n%168 = OpIMul %2 %37 %80\n%169 = OpIAdd %2 %105 %168\n%38 = OpIAdd %2 %37 %7\n%171 = OpIEqual %47 %38 %10\nOpBranchConditional %171 %253 %247\n%253 = OpLabel\nOpBranch %254\n%254 = OpLabel\n%174 = OpPhi %11 %173 %253 %242 %254\n%176 = OpPhi %2 %3 %253 %177 %254\n%178 = OpIMul %2 %176 %80\n%179 = OpIAdd %2 %7 %178\n%182 = OpIMul %2 %176 %80\n%183 = OpIAdd %2 %3 %182\n%184 = OpAccessChain %53 %36 %176\n%185 = OpLoad %5 %184\n%186 = OpIMul %2 %176 %80\n%187 = OpIAdd %2 %6 %186\n%190 = OpIMul %2 %176 %80\n%191 = OpIAdd %2 %10 %190\n%194 = OpIMul %2 %176 %80\n%195 = OpIAdd %2 %40 %194\n%198 = OpIMul %2 %176 %80\n%199 = OpIAdd %2 %94 %198\n%202 = OpIMul %2 %176 %80\n%203 = OpIAdd %2 %105 %202\n%206 = OpIMul %2 %176 %80\n%207 = OpIAdd %2 %101 %206\n%210 = OpIMul %2 %176 %80\n%211 = OpIAdd %2 %7 %210\n%214 = OpIMul %2 %176 %80\n%215 = OpIAdd %2 %3 %214\n%216 = OpAccessChain %124 %33 %176\n%217 = OpLoad %8 %216\n%218 = OpIMul %2 %176 %80\n%219 = OpIAdd %2 %6 %218\n%222 = OpIMul %2 %176 %80\n%223 = OpIAdd %2 %10 %222\n%226 = OpIMul %2 %176 %80\n%227 = OpIAdd %2 %40 %226\n%230 = OpIMul %2 %176 %80\n%231 = OpIAdd %2 %94 %230\n%234 = OpIMul %2 %176 %80\n%235 = OpIAdd %2 %105 %234\n%238 = OpIMul %2 %176 %80\n%239 = OpIAdd %2 %101 %238\n%242 = OpCooperativeMatrixMulAddKHR %11 %185 %217 %174\n%177 = OpIAdd %2 %176 %7\n%243 = OpIEqual %47 %177 %10\nOpLoopMerge %255 %254 None\nOpBranchConditional %243 %255 %254\n%255 = OpLabel\n%244 = OpAccessChain %43 %24 %3 %3\nOpCooperativeMatrixStoreKHR %244 %242 %7 %45 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%51 = OpFunction %5 None %49\n%50 = OpFunctionParameter %48\n%52 = OpLabel\n%54 = OpVariable %53 Function\n%55 = OpCooperativeMatrixLengthKHR %2 %42\nOpBranch %56\n%56 = OpLabel\n%58 = OpPhi %2 %3 %52 %59 %56\n%59 = OpIAdd %2 %58 %7\n%61 = OpInBoundsAccessChain %60 %50 %58\n%62 = OpLoad %16 %61\n%64 = OpSConvert %63 %62\n%65 = OpShiftLeftLogical %63 %64 %66\n%67 = OpBitwiseAnd %63 %65 %68\n%69 = OpBitcast %1 %67\n%71 = OpInBoundsAccessChain %70 %54 %58\nOpStore %71 %69\n%72 = OpULessThan %47 %59 %55\nOpLoopMerge %57 %56 None\nOpBranchConditional %72 %56 %57\n%57 = OpLabel\n%73 = OpLoad %5 %54\n%74 = OpMatrixTimesScalar %5 %73 %75\nOpReturnValue %74\nOpFunctionEnd\n%122 = OpFunction %8 None %120\n%121 = OpFunctionParameter %119\n%123 = OpLabel\n%125 = OpVariable %124 Function\n%126 = OpCooperativeMatrixLengthKHR %2 %116\nOpBranch %127\n%127 = OpLabel\n%129 = OpPhi %2 %3 %123 %130 %127\n%130 = OpIAdd %2 %129 %7\n%131 = OpInBoundsAccessChain %60 %121 %129\n%132 = OpLoad %16 %131\n%133 = OpSConvert %63 %132\n%134 = OpShiftLeftLogical %63 %133 %66\n%135 = OpBitwiseAnd %63 %134 %68\n%136 = OpBitcast %1 %135\n%137 = OpInBoundsAccessChain %70 %125 %129\nOpStore %137 %136\n%138 = OpULessThan %47 %130 %126\nOpLoopMerge %128 %127 None\nOpBranchConditional %138 %127 %128\n%128 = OpLabel\n%139 = OpLoad %8 %125\n%140 = OpMatrixTimesScalar %8 %139 %75\nOpReturnValue %140\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/bad-stride.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[6];\n} _12;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _35[6];\n    float _36[6];\n    float _37[6];\n    float _38[6];\n    _35[0u] = _12._m0[0u].x;\n    _36[0u] = _12._m0[0u].y;\n    _37[0u] = _12._m0[0u].z;\n    _38[0u] = _12._m0[0u].w;\n    _35[1u] = _12._m0[1u].x;\n    _36[1u] = _12._m0[1u].y;\n    _37[1u] = _12._m0[1u].z;\n    _38[1u] = _12._m0[1u].w;\n    _35[2u] = _12._m0[3u].x;\n    _36[2u] = _12._m0[3u].y;\n    _37[2u] = _12._m0[3u].z;\n    _38[2u] = _12._m0[3u].w;\n    uint _71 = A % 6u;\n    SV_Target.x = _35[_71] * P.x;\n    SV_Target.y = _36[_71] * P.y;\n    SV_Target.z = _37[_71] * P.z;\n    SV_Target.w = _38[_71] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"A\"\nOpName %16 \"P\"\nOpName %18 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %16 Location 1\nOpDecorate %18 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 6\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %8\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %8\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %7\n%21 = OpConstant %5 0\n%24 = OpConstant %5 1\n%27 = OpConstant %5 2\n%30 = OpConstant %5 3\n%33 = OpTypeArray %7 %6\n%34 = OpTypePointer Function %33\n%39 = OpTypePointer Uniform %8\n%46 = OpTypePointer Function %7\n%84 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%35 = OpVariable %34 Function\n%36 = OpVariable %34 Function\n%37 = OpVariable %34 Function\n%38 = OpVariable %34 Function\nOpBranch %89\n%89 = OpLabel\n%20 = OpAccessChain %19 %16 %21\n%22 = OpLoad %7 %20\n%23 = OpAccessChain %19 %16 %24\n%25 = OpLoad %7 %23\n%26 = OpAccessChain %19 %16 %27\n%28 = OpLoad %7 %26\n%29 = OpAccessChain %19 %16 %30\n%31 = OpLoad %7 %29\n%32 = OpLoad %5 %14\n%40 = OpAccessChain %39 %12 %21 %21\n%41 = OpLoad %8 %40\n%42 = OpCompositeExtract %7 %41 0\n%43 = OpCompositeExtract %7 %41 1\n%44 = OpCompositeExtract %7 %41 2\n%45 = OpCompositeExtract %7 %41 3\n%47 = OpAccessChain %46 %35 %21\n%48 = OpAccessChain %46 %36 %21\n%49 = OpAccessChain %46 %37 %21\n%50 = OpAccessChain %46 %38 %21\nOpStore %47 %42\nOpStore %48 %43\nOpStore %49 %44\nOpStore %50 %45\n%51 = OpAccessChain %39 %12 %21 %24\n%52 = OpLoad %8 %51\n%53 = OpCompositeExtract %7 %52 0\n%54 = OpCompositeExtract %7 %52 1\n%55 = OpCompositeExtract %7 %52 2\n%56 = OpCompositeExtract %7 %52 3\n%57 = OpAccessChain %46 %35 %24\n%58 = OpAccessChain %46 %36 %24\n%59 = OpAccessChain %46 %37 %24\n%60 = OpAccessChain %46 %38 %24\nOpStore %57 %53\nOpStore %58 %54\nOpStore %59 %55\nOpStore %60 %56\n%61 = OpAccessChain %39 %12 %21 %30\n%62 = OpLoad %8 %61\n%63 = OpCompositeExtract %7 %62 0\n%64 = OpCompositeExtract %7 %62 1\n%65 = OpCompositeExtract %7 %62 2\n%66 = OpCompositeExtract %7 %62 3\n%67 = OpAccessChain %46 %35 %27\n%68 = OpAccessChain %46 %36 %27\n%69 = OpAccessChain %46 %37 %27\n%70 = OpAccessChain %46 %38 %27\nOpStore %67 %63\nOpStore %68 %64\nOpStore %69 %65\nOpStore %70 %66\n%71 = OpUMod %5 %32 %6\n%72 = OpAccessChain %46 %35 %71\n%73 = OpAccessChain %46 %36 %71\n%74 = OpAccessChain %46 %37 %71\n%75 = OpAccessChain %46 %38 %71\n%76 = OpLoad %7 %72\n%77 = OpLoad %7 %73\n%78 = OpLoad %7 %74\n%79 = OpLoad %7 %75\n%80 = OpFMul %7 %76 %22\n%81 = OpFMul %7 %77 %25\n%82 = OpFMul %7 %78 %28\n%83 = OpFMul %7 %79 %31\n%85 = OpAccessChain %84 %18 %21\nOpStore %85 %80\n%86 = OpAccessChain %84 %18 %24\nOpStore %86 %81\n%87 = OpAccessChain %84 %18 %27\nOpStore %87 %82\n%88 = OpAccessChain %84 %18 %30\nOpStore %88 %83\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/double-array-load.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    dvec2 _m0[12];\n} _12;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    double _38[6];\n    double _39[6];\n    double _40[6];\n    double _41[6];\n    _38[0u] = _12._m0[0u].x;\n    _39[0u] = _12._m0[0u].y;\n    _40[0u] = _12._m0[1u].x;\n    _41[0u] = _12._m0[1u].y;\n    _38[1u] = _12._m0[2u].x;\n    _39[1u] = _12._m0[2u].y;\n    _40[1u] = _12._m0[3u].x;\n    _41[1u] = _12._m0[3u].y;\n    _38[2u] = _12._m0[4u].x;\n    _39[2u] = _12._m0[4u].y;\n    _40[2u] = _12._m0[5u].x;\n    _41[2u] = _12._m0[5u].y;\n    _38[3u] = _12._m0[6u].x;\n    _39[3u] = _12._m0[6u].y;\n    _40[3u] = _12._m0[7u].x;\n    _41[3u] = _12._m0[7u].y;\n    _38[4u] = _12._m0[8u].x;\n    _39[4u] = _12._m0[8u].y;\n    _40[4u] = _12._m0[9u].x;\n    _41[4u] = _12._m0[9u].y;\n    _38[5u] = _12._m0[10u].x;\n    _39[5u] = _12._m0[10u].y;\n    _40[5u] = _12._m0[11u].x;\n    _41[5u] = _12._m0[11u].y;\n    uint _123 = A % 6u;\n    SV_Target.x = float(_38[_123]) * P.x;\n    SV_Target.y = float(_39[_123]) * P.y;\n    SV_Target.z = float(_40[_123]) * P.z;\n    SV_Target.w = float(_41[_123]) * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 147\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %18 %20\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"A\"\nOpName %18 \"P\"\nOpName %20 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %18 Location 1\nOpDecorate %20 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 12\n%7 = OpTypeFloat 64\n%8 = OpTypeVector %7 2\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%15 = OpTypeFloat 32\n%16 = OpTypeVector %15 4\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Output %16\n%20 = OpVariable %19 Output\n%21 = OpTypePointer Input %15\n%23 = OpConstant %5 0\n%26 = OpConstant %5 1\n%29 = OpConstant %5 2\n%32 = OpConstant %5 3\n%35 = OpConstant %5 6\n%36 = OpTypeArray %7 %35\n%37 = OpTypePointer Function %36\n%42 = OpTypePointer Uniform %8\n%51 = OpTypePointer Function %7\n%68 = OpConstant %5 4\n%73 = OpConstant %5 5\n%86 = OpConstant %5 7\n%95 = OpConstant %5 8\n%100 = OpConstant %5 9\n%109 = OpConstant %5 10\n%114 = OpConstant %5 11\n%140 = OpTypePointer Output %15\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%38 = OpVariable %37 Function\n%39 = OpVariable %37 Function\n%40 = OpVariable %37 Function\n%41 = OpVariable %37 Function\nOpBranch %145\n%145 = OpLabel\n%22 = OpAccessChain %21 %18 %23\n%24 = OpLoad %15 %22\n%25 = OpAccessChain %21 %18 %26\n%27 = OpLoad %15 %25\n%28 = OpAccessChain %21 %18 %29\n%30 = OpLoad %15 %28\n%31 = OpAccessChain %21 %18 %32\n%33 = OpLoad %15 %31\n%34 = OpLoad %5 %14\n%43 = OpAccessChain %42 %12 %23 %23\n%44 = OpLoad %8 %43\n%45 = OpCompositeExtract %7 %44 0\n%46 = OpCompositeExtract %7 %44 1\n%47 = OpAccessChain %42 %12 %23 %26\n%48 = OpLoad %8 %47\n%49 = OpCompositeExtract %7 %48 0\n%50 = OpCompositeExtract %7 %48 1\n%52 = OpAccessChain %51 %38 %23\n%53 = OpAccessChain %51 %39 %23\n%54 = OpAccessChain %51 %40 %23\n%55 = OpAccessChain %51 %41 %23\nOpStore %52 %45\nOpStore %53 %46\nOpStore %54 %49\nOpStore %55 %50\n%56 = OpAccessChain %42 %12 %23 %29\n%57 = OpLoad %8 %56\n%58 = OpCompositeExtract %7 %57 0\n%59 = OpCompositeExtract %7 %57 1\n%60 = OpAccessChain %42 %12 %23 %32\n%61 = OpLoad %8 %60\n%62 = OpCompositeExtract %7 %61 0\n%63 = OpCompositeExtract %7 %61 1\n%64 = OpAccessChain %51 %38 %26\n%65 = OpAccessChain %51 %39 %26\n%66 = OpAccessChain %51 %40 %26\n%67 = OpAccessChain %51 %41 %26\nOpStore %64 %58\nOpStore %65 %59\nOpStore %66 %62\nOpStore %67 %63\n%69 = OpAccessChain %42 %12 %23 %68\n%70 = OpLoad %8 %69\n%71 = OpCompositeExtract %7 %70 0\n%72 = OpCompositeExtract %7 %70 1\n%74 = OpAccessChain %42 %12 %23 %73\n%75 = OpLoad %8 %74\n%76 = OpCompositeExtract %7 %75 0\n%77 = OpCompositeExtract %7 %75 1\n%78 = OpAccessChain %51 %38 %29\n%79 = OpAccessChain %51 %39 %29\n%80 = OpAccessChain %51 %40 %29\n%81 = OpAccessChain %51 %41 %29\nOpStore %78 %71\nOpStore %79 %72\nOpStore %80 %76\nOpStore %81 %77\n%82 = OpAccessChain %42 %12 %23 %35\n%83 = OpLoad %8 %82\n%84 = OpCompositeExtract %7 %83 0\n%85 = OpCompositeExtract %7 %83 1\n%87 = OpAccessChain %42 %12 %23 %86\n%88 = OpLoad %8 %87\n%89 = OpCompositeExtract %7 %88 0\n%90 = OpCompositeExtract %7 %88 1\n%91 = OpAccessChain %51 %38 %32\n%92 = OpAccessChain %51 %39 %32\n%93 = OpAccessChain %51 %40 %32\n%94 = OpAccessChain %51 %41 %32\nOpStore %91 %84\nOpStore %92 %85\nOpStore %93 %89\nOpStore %94 %90\n%96 = OpAccessChain %42 %12 %23 %95\n%97 = OpLoad %8 %96\n%98 = OpCompositeExtract %7 %97 0\n%99 = OpCompositeExtract %7 %97 1\n%101 = OpAccessChain %42 %12 %23 %100\n%102 = OpLoad %8 %101\n%103 = OpCompositeExtract %7 %102 0\n%104 = OpCompositeExtract %7 %102 1\n%105 = OpAccessChain %51 %38 %68\n%106 = OpAccessChain %51 %39 %68\n%107 = OpAccessChain %51 %40 %68\n%108 = OpAccessChain %51 %41 %68\nOpStore %105 %98\nOpStore %106 %99\nOpStore %107 %103\nOpStore %108 %104\n%110 = OpAccessChain %42 %12 %23 %109\n%111 = OpLoad %8 %110\n%112 = OpCompositeExtract %7 %111 0\n%113 = OpCompositeExtract %7 %111 1\n%115 = OpAccessChain %42 %12 %23 %114\n%116 = OpLoad %8 %115\n%117 = OpCompositeExtract %7 %116 0\n%118 = OpCompositeExtract %7 %116 1\n%119 = OpAccessChain %51 %38 %73\n%120 = OpAccessChain %51 %39 %73\n%121 = OpAccessChain %51 %40 %73\n%122 = OpAccessChain %51 %41 %73\nOpStore %119 %112\nOpStore %120 %113\nOpStore %121 %117\nOpStore %122 %118\n%123 = OpUMod %5 %34 %35\n%124 = OpAccessChain %51 %38 %123\n%125 = OpAccessChain %51 %39 %123\n%126 = OpAccessChain %51 %40 %123\n%127 = OpAccessChain %51 %41 %123\n%128 = OpLoad %7 %124\n%129 = OpLoad %7 %125\n%130 = OpLoad %7 %126\n%131 = OpLoad %7 %127\n%132 = OpFConvert %15 %128\n%133 = OpFConvert %15 %129\n%134 = OpFConvert %15 %130\n%135 = OpFConvert %15 %131\n%136 = OpFMul %15 %132 %24\n%137 = OpFMul %15 %133 %27\n%138 = OpFMul %15 %134 %30\n%139 = OpFMul %15 %135 %33\n%141 = OpAccessChain %140 %20 %23\nOpStore %141 %136\n%142 = OpAccessChain %140 %20 %26\nOpStore %142 %137\n%143 = OpAccessChain %140 %20 %29\nOpStore %143 %138\n%144 = OpAccessChain %140 %20 %32\nOpStore %144 %139\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/float4-array-load.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 5, binding = 0, scalar) uniform BindlessCBV\n{\n    float _m0[16384];\n} _15[];\n\nlayout(set = 5, binding = 0, std140) uniform _19_22\n{\n    vec4 _m0[4096];\n} _22[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _91 = A % 6u;\n    SV_Target.x = _15[registers._m5]._m0[_91 * 4u] * P.x;\n    SV_Target.y = _15[registers._m5]._m0[(_91 * 4u) + 1u] * P.y;\n    SV_Target.z = _15[registers._m5]._m0[(_91 * 4u) + 2u] * P.z;\n    SV_Target.w = _15[registers._m5]._m0[(_91 * 4u) + 3u] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 120\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %26 %28\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"BindlessCBV\"\nOpName %19 \"BindlessCBV\"\nOpName %24 \"A\"\nOpName %26 \"P\"\nOpName %28 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 4\nOpDecorate %12 Block\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %15 DescriptorSet 5\nOpDecorate %15 Binding 0\nOpDecorate %18 ArrayStride 16\nOpDecorate %19 Block\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %22 DescriptorSet 5\nOpDecorate %22 Binding 0\nOpDecorate %24 Flat\nOpDecorate %24 Location 0\nOpDecorate %26 Location 1\nOpDecorate %28 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpConstant %5 16384\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer Uniform %13\n%15 = OpVariable %14 Uniform\n%16 = OpTypeVector %9 4\n%17 = OpConstant %5 4096\n%18 = OpTypeArray %16 %17\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer Uniform %20\n%22 = OpVariable %21 Uniform\n%23 = OpTypePointer Input %5\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %16\n%26 = OpVariable %25 Input\n%27 = OpTypePointer Output %16\n%28 = OpVariable %27 Output\n%29 = OpTypePointer Uniform %12\n%31 = OpTypePointer PushConstant %5\n%33 = OpConstant %5 5\n%35 = OpTypePointer Uniform %19\n%39 = OpTypePointer Input %9\n%41 = OpConstant %5 0\n%44 = OpConstant %5 1\n%47 = OpConstant %5 2\n%50 = OpConstant %5 3\n%53 = OpTypePointer Uniform %16\n%78 = OpConstant %5 4\n%92 = OpConstant %5 6\n%94 = OpTypePointer Uniform %9\n%113 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %118\n%118 = OpLabel\n%32 = OpAccessChain %31 %8 %33\n%34 = OpLoad %5 %32\n%30 = OpAccessChain %29 %15 %34\n%37 = OpAccessChain %31 %8 %33\n%38 = OpLoad %5 %37\n%36 = OpAccessChain %35 %22 %38\n%40 = OpAccessChain %39 %26 %41\n%42 = OpLoad %9 %40\n%43 = OpAccessChain %39 %26 %44\n%45 = OpLoad %9 %43\n%46 = OpAccessChain %39 %26 %47\n%48 = OpLoad %9 %46\n%49 = OpAccessChain %39 %26 %50\n%51 = OpLoad %9 %49\n%52 = OpLoad %5 %24\n%54 = OpAccessChain %53 %36 %41 %41\n%55 = OpLoad %16 %54\n%56 = OpCompositeExtract %9 %55 0\n%57 = OpCompositeExtract %9 %55 1\n%58 = OpCompositeExtract %9 %55 2\n%59 = OpCompositeExtract %9 %55 3\n%60 = OpAccessChain %53 %36 %41 %44\n%61 = OpLoad %16 %60\n%62 = OpCompositeExtract %9 %61 0\n%63 = OpCompositeExtract %9 %61 1\n%64 = OpCompositeExtract %9 %61 2\n%65 = OpCompositeExtract %9 %61 3\n%66 = OpAccessChain %53 %36 %41 %47\n%67 = OpLoad %16 %66\n%68 = OpCompositeExtract %9 %67 0\n%69 = OpCompositeExtract %9 %67 1\n%70 = OpCompositeExtract %9 %67 2\n%71 = OpCompositeExtract %9 %67 3\n%72 = OpAccessChain %53 %36 %41 %50\n%73 = OpLoad %16 %72\n%74 = OpCompositeExtract %9 %73 0\n%75 = OpCompositeExtract %9 %73 1\n%76 = OpCompositeExtract %9 %73 2\n%77 = OpCompositeExtract %9 %73 3\n%79 = OpAccessChain %53 %36 %41 %78\n%80 = OpLoad %16 %79\n%81 = OpCompositeExtract %9 %80 0\n%82 = OpCompositeExtract %9 %80 1\n%83 = OpCompositeExtract %9 %80 2\n%84 = OpCompositeExtract %9 %80 3\n%85 = OpAccessChain %53 %36 %41 %33\n%86 = OpLoad %16 %85\n%87 = OpCompositeExtract %9 %86 0\n%88 = OpCompositeExtract %9 %86 1\n%89 = OpCompositeExtract %9 %86 2\n%90 = OpCompositeExtract %9 %86 3\n%91 = OpUMod %5 %52 %92\n%93 = OpIMul %5 %91 %78\n%95 = OpAccessChain %94 %30 %41 %93\n%96 = OpIMul %5 %91 %78\n%97 = OpIAdd %5 %96 %44\n%98 = OpAccessChain %94 %30 %41 %97\n%99 = OpIMul %5 %91 %78\n%100 = OpIAdd %5 %99 %47\n%101 = OpAccessChain %94 %30 %41 %100\n%102 = OpIMul %5 %91 %78\n%103 = OpIAdd %5 %102 %50\n%104 = OpAccessChain %94 %30 %41 %103\n%105 = OpLoad %9 %95\n%106 = OpLoad %9 %98\n%107 = OpLoad %9 %101\n%108 = OpLoad %9 %104\n%109 = OpFMul %9 %105 %42\n%110 = OpFMul %9 %106 %45\n%111 = OpFMul %9 %107 %48\n%112 = OpFMul %9 %108 %51\n%114 = OpAccessChain %113 %28 %41\nOpStore %114 %109\n%115 = OpAccessChain %113 %28 %44\nOpStore %115 %110\n%116 = OpAccessChain %113 %28 %47\nOpStore %116 %111\n%117 = OpAccessChain %113 %28 %50\nOpStore %117 %112\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/float4-array-load.bindless.root-constants.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 5, binding = 0, scalar) uniform BindlessCBV\n{\n    float _m0[16384];\n} _15[];\n\nlayout(set = 5, binding = 0, std140) uniform _19_22\n{\n    vec4 _m0[4096];\n} _22[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _91 = A % 6u;\n    SV_Target.x = _15[registers._m5]._m0[_91 * 4u] * P.x;\n    SV_Target.y = _15[registers._m5]._m0[(_91 * 4u) + 1u] * P.y;\n    SV_Target.z = _15[registers._m5]._m0[(_91 * 4u) + 2u] * P.z;\n    SV_Target.w = _15[registers._m5]._m0[(_91 * 4u) + 3u] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 120\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %26 %28\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"BindlessCBV\"\nOpName %19 \"BindlessCBV\"\nOpName %24 \"A\"\nOpName %26 \"P\"\nOpName %28 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 4\nOpDecorate %12 Block\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %15 DescriptorSet 5\nOpDecorate %15 Binding 0\nOpDecorate %18 ArrayStride 16\nOpDecorate %19 Block\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %22 DescriptorSet 5\nOpDecorate %22 Binding 0\nOpDecorate %24 Flat\nOpDecorate %24 Location 0\nOpDecorate %26 Location 1\nOpDecorate %28 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpConstant %5 16384\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer Uniform %13\n%15 = OpVariable %14 Uniform\n%16 = OpTypeVector %9 4\n%17 = OpConstant %5 4096\n%18 = OpTypeArray %16 %17\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer Uniform %20\n%22 = OpVariable %21 Uniform\n%23 = OpTypePointer Input %5\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %16\n%26 = OpVariable %25 Input\n%27 = OpTypePointer Output %16\n%28 = OpVariable %27 Output\n%29 = OpTypePointer Uniform %12\n%31 = OpTypePointer PushConstant %5\n%33 = OpConstant %5 5\n%35 = OpTypePointer Uniform %19\n%39 = OpTypePointer Input %9\n%41 = OpConstant %5 0\n%44 = OpConstant %5 1\n%47 = OpConstant %5 2\n%50 = OpConstant %5 3\n%53 = OpTypePointer Uniform %16\n%78 = OpConstant %5 4\n%92 = OpConstant %5 6\n%94 = OpTypePointer Uniform %9\n%113 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %118\n%118 = OpLabel\n%32 = OpAccessChain %31 %8 %33\n%34 = OpLoad %5 %32\n%30 = OpAccessChain %29 %15 %34\n%37 = OpAccessChain %31 %8 %33\n%38 = OpLoad %5 %37\n%36 = OpAccessChain %35 %22 %38\n%40 = OpAccessChain %39 %26 %41\n%42 = OpLoad %9 %40\n%43 = OpAccessChain %39 %26 %44\n%45 = OpLoad %9 %43\n%46 = OpAccessChain %39 %26 %47\n%48 = OpLoad %9 %46\n%49 = OpAccessChain %39 %26 %50\n%51 = OpLoad %9 %49\n%52 = OpLoad %5 %24\n%54 = OpAccessChain %53 %36 %41 %41\n%55 = OpLoad %16 %54\n%56 = OpCompositeExtract %9 %55 0\n%57 = OpCompositeExtract %9 %55 1\n%58 = OpCompositeExtract %9 %55 2\n%59 = OpCompositeExtract %9 %55 3\n%60 = OpAccessChain %53 %36 %41 %44\n%61 = OpLoad %16 %60\n%62 = OpCompositeExtract %9 %61 0\n%63 = OpCompositeExtract %9 %61 1\n%64 = OpCompositeExtract %9 %61 2\n%65 = OpCompositeExtract %9 %61 3\n%66 = OpAccessChain %53 %36 %41 %47\n%67 = OpLoad %16 %66\n%68 = OpCompositeExtract %9 %67 0\n%69 = OpCompositeExtract %9 %67 1\n%70 = OpCompositeExtract %9 %67 2\n%71 = OpCompositeExtract %9 %67 3\n%72 = OpAccessChain %53 %36 %41 %50\n%73 = OpLoad %16 %72\n%74 = OpCompositeExtract %9 %73 0\n%75 = OpCompositeExtract %9 %73 1\n%76 = OpCompositeExtract %9 %73 2\n%77 = OpCompositeExtract %9 %73 3\n%79 = OpAccessChain %53 %36 %41 %78\n%80 = OpLoad %16 %79\n%81 = OpCompositeExtract %9 %80 0\n%82 = OpCompositeExtract %9 %80 1\n%83 = OpCompositeExtract %9 %80 2\n%84 = OpCompositeExtract %9 %80 3\n%85 = OpAccessChain %53 %36 %41 %33\n%86 = OpLoad %16 %85\n%87 = OpCompositeExtract %9 %86 0\n%88 = OpCompositeExtract %9 %86 1\n%89 = OpCompositeExtract %9 %86 2\n%90 = OpCompositeExtract %9 %86 3\n%91 = OpUMod %5 %52 %92\n%93 = OpIMul %5 %91 %78\n%95 = OpAccessChain %94 %30 %41 %93\n%96 = OpIMul %5 %91 %78\n%97 = OpIAdd %5 %96 %44\n%98 = OpAccessChain %94 %30 %41 %97\n%99 = OpIMul %5 %91 %78\n%100 = OpIAdd %5 %99 %47\n%101 = OpAccessChain %94 %30 %41 %100\n%102 = OpIMul %5 %91 %78\n%103 = OpIAdd %5 %102 %50\n%104 = OpAccessChain %94 %30 %41 %103\n%105 = OpLoad %9 %95\n%106 = OpLoad %9 %98\n%107 = OpLoad %9 %101\n%108 = OpLoad %9 %104\n%109 = OpFMul %9 %105 %42\n%110 = OpFMul %9 %106 %45\n%111 = OpFMul %9 %107 %48\n%112 = OpFMul %9 %108 %51\n%114 = OpAccessChain %113 %28 %41\nOpStore %114 %109\n%115 = OpAccessChain %113 %28 %44\nOpStore %115 %110\n%116 = OpAccessChain %113 %28 %47\nOpStore %116 %111\n%117 = OpAccessChain %113 %28 %50\nOpStore %117 %112\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/float4-array-load.frag",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _9_11\n{\n    float _m0[24];\n} _11;\n\nlayout(set = 0, binding = 0, std140) uniform _15_17\n{\n    vec4 _m0[6];\n} _17;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _77 = A % 6u;\n    SV_Target.x = _11._m0[_77 * 4u] * P.x;\n    SV_Target.y = _11._m0[(_77 * 4u) + 1u] * P.y;\n    SV_Target.z = _11._m0[(_77 * 4u) + 2u] * P.z;\n    SV_Target.w = _11._m0[(_77 * 4u) + 3u] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 105\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %19 %21 %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %9 \"\"\nOpName %15 \"\"\nOpName %19 \"A\"\nOpName %21 \"P\"\nOpName %23 \"SV_Target\"\nOpDecorate %8 ArrayStride 4\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %9 Block\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %21 Location 1\nOpDecorate %23 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 24\n%7 = OpTypeFloat 32\n%8 = OpTypeArray %7 %6\n%9 = OpTypeStruct %8\n%10 = OpTypePointer Uniform %9\n%11 = OpVariable %10 Uniform\n%12 = OpConstant %5 6\n%13 = OpTypeVector %7 4\n%14 = OpTypeArray %13 %12\n%15 = OpTypeStruct %14\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %13\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Output %13\n%23 = OpVariable %22 Output\n%24 = OpTypePointer Input %7\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%32 = OpConstant %5 2\n%35 = OpConstant %5 3\n%38 = OpTypePointer Uniform %13\n%63 = OpConstant %5 4\n%70 = OpConstant %5 5\n%79 = OpTypePointer Uniform %7\n%98 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %103\n%103 = OpLabel\n%25 = OpAccessChain %24 %21 %26\n%27 = OpLoad %7 %25\n%28 = OpAccessChain %24 %21 %29\n%30 = OpLoad %7 %28\n%31 = OpAccessChain %24 %21 %32\n%33 = OpLoad %7 %31\n%34 = OpAccessChain %24 %21 %35\n%36 = OpLoad %7 %34\n%37 = OpLoad %5 %19\n%39 = OpAccessChain %38 %17 %26 %26\n%40 = OpLoad %13 %39\n%41 = OpCompositeExtract %7 %40 0\n%42 = OpCompositeExtract %7 %40 1\n%43 = OpCompositeExtract %7 %40 2\n%44 = OpCompositeExtract %7 %40 3\n%45 = OpAccessChain %38 %17 %26 %29\n%46 = OpLoad %13 %45\n%47 = OpCompositeExtract %7 %46 0\n%48 = OpCompositeExtract %7 %46 1\n%49 = OpCompositeExtract %7 %46 2\n%50 = OpCompositeExtract %7 %46 3\n%51 = OpAccessChain %38 %17 %26 %32\n%52 = OpLoad %13 %51\n%53 = OpCompositeExtract %7 %52 0\n%54 = OpCompositeExtract %7 %52 1\n%55 = OpCompositeExtract %7 %52 2\n%56 = OpCompositeExtract %7 %52 3\n%57 = OpAccessChain %38 %17 %26 %35\n%58 = OpLoad %13 %57\n%59 = OpCompositeExtract %7 %58 0\n%60 = OpCompositeExtract %7 %58 1\n%61 = OpCompositeExtract %7 %58 2\n%62 = OpCompositeExtract %7 %58 3\n%64 = OpAccessChain %38 %17 %26 %63\n%65 = OpLoad %13 %64\n%66 = OpCompositeExtract %7 %65 0\n%67 = OpCompositeExtract %7 %65 1\n%68 = OpCompositeExtract %7 %65 2\n%69 = OpCompositeExtract %7 %65 3\n%71 = OpAccessChain %38 %17 %26 %70\n%72 = OpLoad %13 %71\n%73 = OpCompositeExtract %7 %72 0\n%74 = OpCompositeExtract %7 %72 1\n%75 = OpCompositeExtract %7 %72 2\n%76 = OpCompositeExtract %7 %72 3\n%77 = OpUMod %5 %37 %12\n%78 = OpIMul %5 %77 %63\n%80 = OpAccessChain %79 %11 %26 %78\n%81 = OpIMul %5 %77 %63\n%82 = OpIAdd %5 %81 %29\n%83 = OpAccessChain %79 %11 %26 %82\n%84 = OpIMul %5 %77 %63\n%85 = OpIAdd %5 %84 %32\n%86 = OpAccessChain %79 %11 %26 %85\n%87 = OpIMul %5 %77 %63\n%88 = OpIAdd %5 %87 %35\n%89 = OpAccessChain %79 %11 %26 %88\n%90 = OpLoad %7 %80\n%91 = OpLoad %7 %83\n%92 = OpLoad %7 %86\n%93 = OpLoad %7 %89\n%94 = OpFMul %7 %90 %27\n%95 = OpFMul %7 %91 %30\n%96 = OpFMul %7 %92 %33\n%97 = OpFMul %7 %93 %36\n%99 = OpAccessChain %98 %23 %26\nOpStore %99 %94\n%100 = OpAccessChain %98 %23 %29\nOpStore %100 %95\n%101 = OpAccessChain %98 %23 %32\nOpStore %101 %96\n%102 = OpAccessChain %98 %23 %35\nOpStore %102 %97\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/float4-array-load.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 3, scalar) uniform _12_14\n{\n    float _m0[12];\n} _14;\n\nlayout(set = 0, binding = 3, std140) uniform _18_20\n{\n    vec4 _m0[3];\n} _20;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _61 = uintBitsToFloat(uvec4(registers._m4, registers._m5, registers._m6, registers._m7));\n    float _42[3];\n    float _43[3];\n    float _44[3];\n    float _45[3];\n    _42[0u] = _61.x;\n    _43[0u] = _61.y;\n    _44[0u] = _61.z;\n    _45[0u] = _61.w;\n    vec4 _84 = uintBitsToFloat(uvec4(registers._m8, registers._m9, registers._m10, registers._m11));\n    _42[1u] = _84.x;\n    _43[1u] = _84.y;\n    _44[1u] = _84.z;\n    _45[1u] = _84.w;\n    vec4 _105 = uintBitsToFloat(uvec4(registers._m12, registers._m13, registers._m14, registers._m15));\n    _42[2u] = _105.x;\n    _43[2u] = _105.y;\n    _44[2u] = _105.z;\n    _45[2u] = _105.w;\n    uint _133 = A % 3u;\n    SV_Target.x = _14._m0[_133 * 4u] + (_42[_133] * P.x);\n    SV_Target.y = _14._m0[(_133 * 4u) + 1u] + (_43[_133] * P.y);\n    SV_Target.z = _14._m0[(_133 * 4u) + 2u] + (_44[_133] * P.z);\n    SV_Target.w = _14._m0[(_133 * 4u) + 3u] + (_45[_133] * P.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 173\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %22 %24 %26\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"\"\nOpName %18 \"\"\nOpName %22 \"A\"\nOpName %24 \"P\"\nOpName %26 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %17 ArrayStride 16\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 3\nOpDecorate %22 Flat\nOpDecorate %22 Location 0\nOpDecorate %24 Location 1\nOpDecorate %26 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpConstant %5 12\n%10 = OpTypeFloat 32\n%11 = OpTypeArray %10 %9\n%12 = OpTypeStruct %11\n%13 = OpTypePointer Uniform %12\n%14 = OpVariable %13 Uniform\n%15 = OpConstant %5 3\n%16 = OpTypeVector %10 4\n%17 = OpTypeArray %16 %15\n%18 = OpTypeStruct %17\n%19 = OpTypePointer Uniform %18\n%20 = OpVariable %19 Uniform\n%21 = OpTypePointer Input %5\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Input %16\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Output %16\n%26 = OpVariable %25 Output\n%27 = OpTypePointer Input %10\n%29 = OpConstant %5 0\n%32 = OpConstant %5 1\n%35 = OpConstant %5 2\n%40 = OpTypeArray %10 %15\n%41 = OpTypePointer Function %40\n%46 = OpTypePointer PushConstant %5\n%48 = OpConstant %5 4\n%51 = OpConstant %5 5\n%54 = OpConstant %5 6\n%57 = OpConstant %5 7\n%59 = OpTypeVector %5 4\n%66 = OpTypePointer Function %10\n%72 = OpConstant %5 8\n%75 = OpConstant %5 9\n%78 = OpConstant %5 10\n%81 = OpConstant %5 11\n%96 = OpConstant %5 13\n%99 = OpConstant %5 14\n%102 = OpConstant %5 15\n%114 = OpTypePointer Uniform %16\n%147 = OpTypePointer Uniform %10\n%166 = OpTypePointer Output %10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%42 = OpVariable %41 Function\n%43 = OpVariable %41 Function\n%44 = OpVariable %41 Function\n%45 = OpVariable %41 Function\nOpBranch %171\n%171 = OpLabel\n%28 = OpAccessChain %27 %24 %29\n%30 = OpLoad %10 %28\n%31 = OpAccessChain %27 %24 %32\n%33 = OpLoad %10 %31\n%34 = OpAccessChain %27 %24 %35\n%36 = OpLoad %10 %34\n%37 = OpAccessChain %27 %24 %15\n%38 = OpLoad %10 %37\n%39 = OpLoad %5 %22\n%47 = OpAccessChain %46 %8 %48\n%49 = OpLoad %5 %47\n%50 = OpAccessChain %46 %8 %51\n%52 = OpLoad %5 %50\n%53 = OpAccessChain %46 %8 %54\n%55 = OpLoad %5 %53\n%56 = OpAccessChain %46 %8 %57\n%58 = OpLoad %5 %56\n%60 = OpCompositeConstruct %59 %49 %52 %55 %58\n%61 = OpBitcast %16 %60\n%62 = OpCompositeExtract %10 %61 0\n%63 = OpCompositeExtract %10 %61 1\n%64 = OpCompositeExtract %10 %61 2\n%65 = OpCompositeExtract %10 %61 3\n%67 = OpAccessChain %66 %42 %29\n%68 = OpAccessChain %66 %43 %29\n%69 = OpAccessChain %66 %44 %29\n%70 = OpAccessChain %66 %45 %29\nOpStore %67 %62\nOpStore %68 %63\nOpStore %69 %64\nOpStore %70 %65\n%71 = OpAccessChain %46 %8 %72\n%73 = OpLoad %5 %71\n%74 = OpAccessChain %46 %8 %75\n%76 = OpLoad %5 %74\n%77 = OpAccessChain %46 %8 %78\n%79 = OpLoad %5 %77\n%80 = OpAccessChain %46 %8 %81\n%82 = OpLoad %5 %80\n%83 = OpCompositeConstruct %59 %73 %76 %79 %82\n%84 = OpBitcast %16 %83\n%85 = OpCompositeExtract %10 %84 0\n%86 = OpCompositeExtract %10 %84 1\n%87 = OpCompositeExtract %10 %84 2\n%88 = OpCompositeExtract %10 %84 3\n%89 = OpAccessChain %66 %42 %32\n%90 = OpAccessChain %66 %43 %32\n%91 = OpAccessChain %66 %44 %32\n%92 = OpAccessChain %66 %45 %32\nOpStore %89 %85\nOpStore %90 %86\nOpStore %91 %87\nOpStore %92 %88\n%93 = OpAccessChain %46 %8 %9\n%94 = OpLoad %5 %93\n%95 = OpAccessChain %46 %8 %96\n%97 = OpLoad %5 %95\n%98 = OpAccessChain %46 %8 %99\n%100 = OpLoad %5 %98\n%101 = OpAccessChain %46 %8 %102\n%103 = OpLoad %5 %101\n%104 = OpCompositeConstruct %59 %94 %97 %100 %103\n%105 = OpBitcast %16 %104\n%106 = OpCompositeExtract %10 %105 0\n%107 = OpCompositeExtract %10 %105 1\n%108 = OpCompositeExtract %10 %105 2\n%109 = OpCompositeExtract %10 %105 3\n%110 = OpAccessChain %66 %42 %35\n%111 = OpAccessChain %66 %43 %35\n%112 = OpAccessChain %66 %44 %35\n%113 = OpAccessChain %66 %45 %35\nOpStore %110 %106\nOpStore %111 %107\nOpStore %112 %108\nOpStore %113 %109\n%115 = OpAccessChain %114 %20 %29 %29\n%116 = OpLoad %16 %115\n%117 = OpCompositeExtract %10 %116 0\n%118 = OpCompositeExtract %10 %116 1\n%119 = OpCompositeExtract %10 %116 2\n%120 = OpCompositeExtract %10 %116 3\n%121 = OpAccessChain %114 %20 %29 %32\n%122 = OpLoad %16 %121\n%123 = OpCompositeExtract %10 %122 0\n%124 = OpCompositeExtract %10 %122 1\n%125 = OpCompositeExtract %10 %122 2\n%126 = OpCompositeExtract %10 %122 3\n%127 = OpAccessChain %114 %20 %29 %35\n%128 = OpLoad %16 %127\n%129 = OpCompositeExtract %10 %128 0\n%130 = OpCompositeExtract %10 %128 1\n%131 = OpCompositeExtract %10 %128 2\n%132 = OpCompositeExtract %10 %128 3\n%133 = OpUMod %5 %39 %15\n%134 = OpAccessChain %66 %42 %133\n%135 = OpAccessChain %66 %43 %133\n%136 = OpAccessChain %66 %44 %133\n%137 = OpAccessChain %66 %45 %133\n%138 = OpLoad %10 %134\n%139 = OpLoad %10 %135\n%140 = OpLoad %10 %136\n%141 = OpLoad %10 %137\n%142 = OpFMul %10 %138 %30\n%143 = OpFMul %10 %139 %33\n%144 = OpFMul %10 %140 %36\n%145 = OpFMul %10 %141 %38\n%146 = OpIMul %5 %133 %48\n%148 = OpAccessChain %147 %14 %29 %146\n%149 = OpIMul %5 %133 %48\n%150 = OpIAdd %5 %149 %32\n%151 = OpAccessChain %147 %14 %29 %150\n%152 = OpIMul %5 %133 %48\n%153 = OpIAdd %5 %152 %35\n%154 = OpAccessChain %147 %14 %29 %153\n%155 = OpIMul %5 %133 %48\n%156 = OpIAdd %5 %155 %15\n%157 = OpAccessChain %147 %14 %29 %156\n%158 = OpLoad %10 %148\n%159 = OpLoad %10 %151\n%160 = OpLoad %10 %154\n%161 = OpLoad %10 %157\n%162 = OpFAdd %10 %158 %142\n%163 = OpFAdd %10 %159 %143\n%164 = OpFAdd %10 %160 %144\n%165 = OpFAdd %10 %161 %145\n%167 = OpAccessChain %166 %26 %29\nOpStore %167 %162\n%168 = OpAccessChain %166 %26 %32\nOpStore %168 %163\n%169 = OpAccessChain %166 %26 %35\nOpStore %169 %164\n%170 = OpAccessChain %166 %26 %15\nOpStore %170 %165\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/float4-array-load.root-descriptor.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatNonWriteCBVArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerFloatNonWriteCBVArray\n{\n    float value[16384];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _84 = A % 6u;\n    SV_Target.x = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[_84 * 4u] * P.x;\n    SV_Target.y = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[(_84 * 4u) + 1u] * P.y;\n    SV_Target.z = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[(_84 * 4u) + 2u] * P.z;\n    SV_Target.w = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[(_84 * 4u) + 3u] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 121\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15 %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %11 \"A\"\nOpName %15 \"P\"\nOpName %17 \"SV_Target\"\nOpName %37 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %37 0 \"value\"\nOpName %89 \"PhysicalPointerFloatNonWriteCBVArray\"\nOpMemberName %89 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 1\nOpDecorate %17 Location 0\nOpDecorate %36 ArrayStride 16\nOpMemberDecorate %37 0 Offset 0\nOpDecorate %37 Block\nOpMemberDecorate %37 0 NonWritable\nOpDecorate %88 ArrayStride 4\nOpMemberDecorate %89 0 Offset 0\nOpDecorate %89 Block\nOpMemberDecorate %89 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Output %13\n%17 = OpVariable %16 Output\n%18 = OpTypePointer PushConstant %6\n%20 = OpConstant %5 0\n%22 = OpTypePointer Input %12\n%26 = OpConstant %5 1\n%29 = OpConstant %5 2\n%32 = OpConstant %5 3\n%35 = OpConstant %5 4096\n%36 = OpTypeArray %13 %35\n%37 = OpTypeStruct %36\n%38 = OpTypePointer PhysicalStorageBuffer %37\n%40 = OpTypePointer PhysicalStorageBuffer %13\n%68 = OpConstant %5 4\n%76 = OpConstant %5 5\n%85 = OpConstant %5 6\n%87 = OpConstant %5 16384\n%88 = OpTypeArray %12 %87\n%89 = OpTypeStruct %88\n%90 = OpTypePointer PhysicalStorageBuffer %89\n%92 = OpTypePointer PhysicalStorageBuffer %12\n%114 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %119\n%119 = OpLabel\n%19 = OpAccessChain %18 %9 %20\n%21 = OpLoad %6 %19\n%23 = OpAccessChain %22 %15 %20\n%24 = OpLoad %12 %23\n%25 = OpAccessChain %22 %15 %26\n%27 = OpLoad %12 %25\n%28 = OpAccessChain %22 %15 %29\n%30 = OpLoad %12 %28\n%31 = OpAccessChain %22 %15 %32\n%33 = OpLoad %12 %31\n%34 = OpLoad %5 %11\n%39 = OpBitcast %38 %21\n%41 = OpInBoundsAccessChain %40 %39 %20 %20\n%42 = OpLoad %13 %41 Aligned 16\n%43 = OpCompositeExtract %12 %42 0\n%44 = OpCompositeExtract %12 %42 1\n%45 = OpCompositeExtract %12 %42 2\n%46 = OpCompositeExtract %12 %42 3\n%47 = OpBitcast %38 %21\n%48 = OpInBoundsAccessChain %40 %47 %20 %26\n%49 = OpLoad %13 %48 Aligned 16\n%50 = OpCompositeExtract %12 %49 0\n%51 = OpCompositeExtract %12 %49 1\n%52 = OpCompositeExtract %12 %49 2\n%53 = OpCompositeExtract %12 %49 3\n%54 = OpBitcast %38 %21\n%55 = OpInBoundsAccessChain %40 %54 %20 %29\n%56 = OpLoad %13 %55 Aligned 16\n%57 = OpCompositeExtract %12 %56 0\n%58 = OpCompositeExtract %12 %56 1\n%59 = OpCompositeExtract %12 %56 2\n%60 = OpCompositeExtract %12 %56 3\n%61 = OpBitcast %38 %21\n%62 = OpInBoundsAccessChain %40 %61 %20 %32\n%63 = OpLoad %13 %62 Aligned 16\n%64 = OpCompositeExtract %12 %63 0\n%65 = OpCompositeExtract %12 %63 1\n%66 = OpCompositeExtract %12 %63 2\n%67 = OpCompositeExtract %12 %63 3\n%69 = OpBitcast %38 %21\n%70 = OpInBoundsAccessChain %40 %69 %20 %68\n%71 = OpLoad %13 %70 Aligned 16\n%72 = OpCompositeExtract %12 %71 0\n%73 = OpCompositeExtract %12 %71 1\n%74 = OpCompositeExtract %12 %71 2\n%75 = OpCompositeExtract %12 %71 3\n%77 = OpBitcast %38 %21\n%78 = OpInBoundsAccessChain %40 %77 %20 %76\n%79 = OpLoad %13 %78 Aligned 16\n%80 = OpCompositeExtract %12 %79 0\n%81 = OpCompositeExtract %12 %79 1\n%82 = OpCompositeExtract %12 %79 2\n%83 = OpCompositeExtract %12 %79 3\n%84 = OpUMod %5 %34 %85\n%86 = OpIMul %5 %84 %68\n%91 = OpBitcast %90 %21\n%93 = OpInBoundsAccessChain %92 %91 %20 %86\n%94 = OpIMul %5 %84 %68\n%95 = OpIAdd %5 %94 %26\n%96 = OpBitcast %90 %21\n%97 = OpInBoundsAccessChain %92 %96 %20 %95\n%98 = OpIMul %5 %84 %68\n%99 = OpIAdd %5 %98 %29\n%100 = OpBitcast %90 %21\n%101 = OpInBoundsAccessChain %92 %100 %20 %99\n%102 = OpIMul %5 %84 %68\n%103 = OpIAdd %5 %102 %32\n%104 = OpBitcast %90 %21\n%105 = OpInBoundsAccessChain %92 %104 %20 %103\n%106 = OpLoad %12 %93 Aligned 4\n%107 = OpLoad %12 %97 Aligned 4\n%108 = OpLoad %12 %101 Aligned 4\n%109 = OpLoad %12 %105 Aligned 4\n%110 = OpFMul %12 %106 %24\n%111 = OpFMul %12 %107 %27\n%112 = OpFMul %12 %108 %30\n%113 = OpFMul %12 %109 %33\n%115 = OpAccessChain %114 %17 %20\nOpStore %115 %110\n%116 = OpAccessChain %114 %17 %26\nOpStore %116 %111\n%117 = OpAccessChain %114 %17 %29\nOpStore %117 %112\n%118 = OpAccessChain %114 %17 %32\nOpStore %118 %113\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/float4-array-load.root-descriptor.root-constants.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatNonWriteCBVArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerFloatNonWriteCBVArray\n{\n    float value[16384];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _84 = A % 6u;\n    SV_Target.x = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[_84 * 4u] * P.x;\n    SV_Target.y = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[(_84 * 4u) + 1u] * P.y;\n    SV_Target.z = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[(_84 * 4u) + 2u] * P.z;\n    SV_Target.w = PhysicalPointerFloatNonWriteCBVArray(registers._m0).value[(_84 * 4u) + 3u] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 121\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15 %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %11 \"A\"\nOpName %15 \"P\"\nOpName %17 \"SV_Target\"\nOpName %37 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %37 0 \"value\"\nOpName %89 \"PhysicalPointerFloatNonWriteCBVArray\"\nOpMemberName %89 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 1\nOpDecorate %17 Location 0\nOpDecorate %36 ArrayStride 16\nOpMemberDecorate %37 0 Offset 0\nOpDecorate %37 Block\nOpMemberDecorate %37 0 NonWritable\nOpDecorate %88 ArrayStride 4\nOpMemberDecorate %89 0 Offset 0\nOpDecorate %89 Block\nOpMemberDecorate %89 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Output %13\n%17 = OpVariable %16 Output\n%18 = OpTypePointer PushConstant %6\n%20 = OpConstant %5 0\n%22 = OpTypePointer Input %12\n%26 = OpConstant %5 1\n%29 = OpConstant %5 2\n%32 = OpConstant %5 3\n%35 = OpConstant %5 4096\n%36 = OpTypeArray %13 %35\n%37 = OpTypeStruct %36\n%38 = OpTypePointer PhysicalStorageBuffer %37\n%40 = OpTypePointer PhysicalStorageBuffer %13\n%68 = OpConstant %5 4\n%76 = OpConstant %5 5\n%85 = OpConstant %5 6\n%87 = OpConstant %5 16384\n%88 = OpTypeArray %12 %87\n%89 = OpTypeStruct %88\n%90 = OpTypePointer PhysicalStorageBuffer %89\n%92 = OpTypePointer PhysicalStorageBuffer %12\n%114 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %119\n%119 = OpLabel\n%19 = OpAccessChain %18 %9 %20\n%21 = OpLoad %6 %19\n%23 = OpAccessChain %22 %15 %20\n%24 = OpLoad %12 %23\n%25 = OpAccessChain %22 %15 %26\n%27 = OpLoad %12 %25\n%28 = OpAccessChain %22 %15 %29\n%30 = OpLoad %12 %28\n%31 = OpAccessChain %22 %15 %32\n%33 = OpLoad %12 %31\n%34 = OpLoad %5 %11\n%39 = OpBitcast %38 %21\n%41 = OpInBoundsAccessChain %40 %39 %20 %20\n%42 = OpLoad %13 %41 Aligned 16\n%43 = OpCompositeExtract %12 %42 0\n%44 = OpCompositeExtract %12 %42 1\n%45 = OpCompositeExtract %12 %42 2\n%46 = OpCompositeExtract %12 %42 3\n%47 = OpBitcast %38 %21\n%48 = OpInBoundsAccessChain %40 %47 %20 %26\n%49 = OpLoad %13 %48 Aligned 16\n%50 = OpCompositeExtract %12 %49 0\n%51 = OpCompositeExtract %12 %49 1\n%52 = OpCompositeExtract %12 %49 2\n%53 = OpCompositeExtract %12 %49 3\n%54 = OpBitcast %38 %21\n%55 = OpInBoundsAccessChain %40 %54 %20 %29\n%56 = OpLoad %13 %55 Aligned 16\n%57 = OpCompositeExtract %12 %56 0\n%58 = OpCompositeExtract %12 %56 1\n%59 = OpCompositeExtract %12 %56 2\n%60 = OpCompositeExtract %12 %56 3\n%61 = OpBitcast %38 %21\n%62 = OpInBoundsAccessChain %40 %61 %20 %32\n%63 = OpLoad %13 %62 Aligned 16\n%64 = OpCompositeExtract %12 %63 0\n%65 = OpCompositeExtract %12 %63 1\n%66 = OpCompositeExtract %12 %63 2\n%67 = OpCompositeExtract %12 %63 3\n%69 = OpBitcast %38 %21\n%70 = OpInBoundsAccessChain %40 %69 %20 %68\n%71 = OpLoad %13 %70 Aligned 16\n%72 = OpCompositeExtract %12 %71 0\n%73 = OpCompositeExtract %12 %71 1\n%74 = OpCompositeExtract %12 %71 2\n%75 = OpCompositeExtract %12 %71 3\n%77 = OpBitcast %38 %21\n%78 = OpInBoundsAccessChain %40 %77 %20 %76\n%79 = OpLoad %13 %78 Aligned 16\n%80 = OpCompositeExtract %12 %79 0\n%81 = OpCompositeExtract %12 %79 1\n%82 = OpCompositeExtract %12 %79 2\n%83 = OpCompositeExtract %12 %79 3\n%84 = OpUMod %5 %34 %85\n%86 = OpIMul %5 %84 %68\n%91 = OpBitcast %90 %21\n%93 = OpInBoundsAccessChain %92 %91 %20 %86\n%94 = OpIMul %5 %84 %68\n%95 = OpIAdd %5 %94 %26\n%96 = OpBitcast %90 %21\n%97 = OpInBoundsAccessChain %92 %96 %20 %95\n%98 = OpIMul %5 %84 %68\n%99 = OpIAdd %5 %98 %29\n%100 = OpBitcast %90 %21\n%101 = OpInBoundsAccessChain %92 %100 %20 %99\n%102 = OpIMul %5 %84 %68\n%103 = OpIAdd %5 %102 %32\n%104 = OpBitcast %90 %21\n%105 = OpInBoundsAccessChain %92 %104 %20 %103\n%106 = OpLoad %12 %93 Aligned 4\n%107 = OpLoad %12 %97 Aligned 4\n%108 = OpLoad %12 %101 Aligned 4\n%109 = OpLoad %12 %105 Aligned 4\n%110 = OpFMul %12 %106 %24\n%111 = OpFMul %12 %107 %27\n%112 = OpFMul %12 %108 %30\n%113 = OpFMul %12 %109 %33\n%115 = OpAccessChain %114 %17 %20\nOpStore %115 %110\n%116 = OpAccessChain %114 %17 %26\nOpStore %116 %111\n%117 = OpAccessChain %114 %17 %29\nOpStore %117 %112\n%118 = OpAccessChain %114 %17 %32\nOpStore %118 %113\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/load-different.frag",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _9_11\n{\n    float _m0[4];\n} _11;\n\nlayout(set = 0, binding = 0, std140) uniform _15_17\n{\n    vec4 _m0[1];\n} _17;\n\nlayout(set = 0, binding = 1, std140) uniform _19_21\n{\n    vec4 _m0[1];\n} _21;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _43[4];\n    _43[0u] = _17._m0[0u].x;\n    _43[1u] = _17._m0[0u].y;\n    _43[2u] = _21._m0[0u].z;\n    _43[3u] = _21._m0[0u].w;\n    uint _60 = A & 3u;\n    float _66 = _43[_60] * _11._m0[_60];\n    SV_Target.x = _66 * P.x;\n    SV_Target.y = _66 * P.y;\n    SV_Target.z = _66 * P.z;\n    SV_Target.w = _66 * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 78\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %25 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %9 \"\"\nOpName %15 \"\"\nOpName %19 \"\"\nOpName %23 \"A\"\nOpName %25 \"P\"\nOpName %27 \"SV_Target\"\nOpDecorate %8 ArrayStride 4\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %9 Block\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %18 ArrayStride 16\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 1\nOpDecorate %23 Flat\nOpDecorate %23 Location 0\nOpDecorate %25 Location 1\nOpDecorate %27 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 4\n%7 = OpTypeFloat 32\n%8 = OpTypeArray %7 %6\n%9 = OpTypeStruct %8\n%10 = OpTypePointer Uniform %9\n%11 = OpVariable %10 Uniform\n%12 = OpConstant %5 1\n%13 = OpTypeVector %7 4\n%14 = OpTypeArray %13 %12\n%15 = OpTypeStruct %14\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypeArray %13 %12\n%19 = OpTypeStruct %18\n%20 = OpTypePointer Uniform %19\n%21 = OpVariable %20 Uniform\n%22 = OpTypePointer Input %5\n%23 = OpVariable %22 Input\n%24 = OpTypePointer Input %13\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Output %13\n%27 = OpVariable %26 Output\n%28 = OpTypePointer Input %7\n%30 = OpConstant %5 0\n%35 = OpConstant %5 2\n%38 = OpConstant %5 3\n%41 = OpTypeArray %7 %6\n%42 = OpTypePointer Function %41\n%44 = OpTypePointer Uniform %13\n%51 = OpTypePointer Function %7\n%61 = OpTypePointer Uniform %7\n%71 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%43 = OpVariable %42 Function\nOpBranch %76\n%76 = OpLabel\n%29 = OpAccessChain %28 %25 %30\n%31 = OpLoad %7 %29\n%32 = OpAccessChain %28 %25 %12\n%33 = OpLoad %7 %32\n%34 = OpAccessChain %28 %25 %35\n%36 = OpLoad %7 %34\n%37 = OpAccessChain %28 %25 %38\n%39 = OpLoad %7 %37\n%40 = OpLoad %5 %23\n%45 = OpAccessChain %44 %17 %30 %30\n%46 = OpLoad %13 %45\n%47 = OpCompositeExtract %7 %46 0\n%48 = OpCompositeExtract %7 %46 1\n%49 = OpCompositeExtract %7 %46 2\n%50 = OpCompositeExtract %7 %46 3\n%52 = OpInBoundsAccessChain %51 %43 %30\nOpStore %52 %47\n%53 = OpInBoundsAccessChain %51 %43 %12\nOpStore %53 %48\n%54 = OpAccessChain %44 %21 %30 %30\n%55 = OpLoad %13 %54\n%56 = OpCompositeExtract %7 %55 2\n%57 = OpInBoundsAccessChain %51 %43 %35\nOpStore %57 %56\n%58 = OpCompositeExtract %7 %55 3\n%59 = OpInBoundsAccessChain %51 %43 %38\nOpStore %59 %58\n%60 = OpBitwiseAnd %5 %40 %38\n%62 = OpAccessChain %61 %11 %30 %60\n%63 = OpLoad %7 %62\n%64 = OpInBoundsAccessChain %51 %43 %60\n%65 = OpLoad %7 %64\n%66 = OpFMul %7 %65 %63\n%67 = OpFMul %7 %66 %31\n%68 = OpFMul %7 %66 %33\n%69 = OpFMul %7 %66 %36\n%70 = OpFMul %7 %66 %39\n%72 = OpAccessChain %71 %27 %30\nOpStore %72 %67\n%73 = OpAccessChain %71 %27 %12\nOpStore %73 %68\n%74 = OpAccessChain %71 %27 %35\nOpStore %74 %69\n%75 = OpAccessChain %71 %27 %38\nOpStore %75 %70\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/local-root-constants.local-root-signature.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatNonWriteCBVArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerFloatNonWriteCBVArray\n{\n    float value[16384];\n};\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(set = 0, binding = 0) uniform writeonly image2D RWIMG;\n\nvoid main()\n{\n    vec4 _43 = uintBitsToFloat(uvec4(SBT._m0[0u], SBT._m0[1u], SBT._m0[2u], SBT._m0[3u]));\n    float _21[4];\n    _21[0u] = _43.x;\n    _21[1u] = _43.y;\n    _21[2u] = _43.z;\n    _21[3u] = _43.w;\n    imageStore(RWIMG, ivec2(uvec2(gl_LaunchIDEXT.x, gl_LaunchIDEXT.y)), vec4(PhysicalPointerFloatNonWriteCBVArray(SBT._m6).value[gl_LaunchIDEXT.y & 3u] * _21[gl_LaunchIDEXT.x & 3u]));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %13 %17 %67\nOpName %3 \"main\"\nOpName %11 \"SBTBlock\"\nOpName %13 \"SBT\"\nOpName %17 \"RWIMG\"\nOpName %55 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %55 0 \"value\"\nOpName %79 \"PhysicalPointerFloatNonWriteCBVArray\"\nOpMemberName %79 0 \"value\"\nOpDecorate %7 ArrayStride 4\nOpDecorate %9 ArrayStride 4\nOpDecorate %11 Block\nOpMemberDecorate %11 0 Offset 0\nOpMemberDecorate %11 1 Offset 20\nOpMemberDecorate %11 2 Offset 48\nOpMemberDecorate %11 3 Offset 56\nOpMemberDecorate %11 4 Offset 64\nOpMemberDecorate %11 5 Offset 72\nOpMemberDecorate %11 6 Offset 80\nOpMemberDecorate %11 7 Offset 88\nOpMemberDecorate %11 8 Offset 96\nOpMemberDecorate %11 9 Offset 104\nOpMemberDecorate %11 10 Offset 112\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 NonReadable\nOpDecorate %54 ArrayStride 16\nOpMemberDecorate %55 0 Offset 0\nOpDecorate %55 Block\nOpMemberDecorate %55 0 NonWritable\nOpDecorate %67 BuiltIn LaunchIdKHR\nOpDecorate %78 ArrayStride 4\nOpMemberDecorate %79 0 Offset 0\nOpDecorate %79 Block\nOpMemberDecorate %79 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 5\n%7 = OpTypeArray %5 %6\n%8 = OpConstant %5 6\n%9 = OpTypeArray %5 %8\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %7 %9 %10 %10 %10 %10 %10 %10 %10 %10 %10\n%12 = OpTypePointer ShaderRecordBufferKHR %11\n%13 = OpVariable %12 ShaderRecordBufferKHR\n%14 = OpTypeFloat 32\n%15 = OpTypeImage %14 2D 0 0 0 2 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpConstant %5 4\n%19 = OpTypeArray %14 %18\n%20 = OpTypePointer Function %19\n%22 = OpTypePointer ShaderRecordBufferKHR %10\n%25 = OpTypePointer ShaderRecordBufferKHR %7\n%27 = OpConstant %5 0\n%28 = OpTypePointer ShaderRecordBufferKHR %5\n%32 = OpConstant %5 1\n%35 = OpConstant %5 2\n%38 = OpConstant %5 3\n%40 = OpTypeVector %5 4\n%42 = OpTypeVector %14 4\n%45 = OpTypePointer Function %14\n%53 = OpConstant %5 4096\n%54 = OpTypeArray %42 %53\n%55 = OpTypeStruct %54\n%56 = OpTypePointer PhysicalStorageBuffer %55\n%58 = OpTypePointer PhysicalStorageBuffer %42\n%65 = OpTypeVector %5 3\n%66 = OpTypePointer Input %65\n%67 = OpVariable %66 Input\n%68 = OpTypePointer Input %5\n%77 = OpConstant %5 16384\n%78 = OpTypeArray %14 %77\n%79 = OpTypeStruct %78\n%80 = OpTypePointer PhysicalStorageBuffer %79\n%82 = OpTypePointer PhysicalStorageBuffer %14\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%21 = OpVariable %20 Function\nOpBranch %89\n%89 = OpLabel\n%23 = OpAccessChain %22 %13 %8\n%24 = OpLoad %10 %23\n%26 = OpAccessChain %25 %13 %27\n%29 = OpAccessChain %28 %26 %27\n%30 = OpLoad %5 %29\n%31 = OpAccessChain %28 %26 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %28 %26 %35\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %28 %26 %38\n%39 = OpLoad %5 %37\n%41 = OpCompositeConstruct %40 %30 %33 %36 %39\n%43 = OpBitcast %42 %41\n%44 = OpCompositeExtract %14 %43 0\n%46 = OpInBoundsAccessChain %45 %21 %27\nOpStore %46 %44\n%47 = OpCompositeExtract %14 %43 1\n%48 = OpInBoundsAccessChain %45 %21 %32\nOpStore %48 %47\n%49 = OpCompositeExtract %14 %43 2\n%50 = OpInBoundsAccessChain %45 %21 %35\nOpStore %50 %49\n%51 = OpCompositeExtract %14 %43 3\n%52 = OpInBoundsAccessChain %45 %21 %38\nOpStore %52 %51\n%57 = OpBitcast %56 %24\n%59 = OpInBoundsAccessChain %58 %57 %27 %27\n%60 = OpLoad %42 %59 Aligned 16\n%61 = OpCompositeExtract %14 %60 0\n%62 = OpCompositeExtract %14 %60 1\n%63 = OpCompositeExtract %14 %60 2\n%64 = OpCompositeExtract %14 %60 3\n%69 = OpAccessChain %68 %67 %27\n%70 = OpLoad %5 %69\n%71 = OpAccessChain %68 %67 %32\n%72 = OpLoad %5 %71\n%73 = OpBitwiseAnd %5 %70 %38\n%74 = OpInBoundsAccessChain %45 %21 %73\n%75 = OpLoad %14 %74\n%76 = OpBitwiseAnd %5 %72 %38\n%81 = OpBitcast %80 %24\n%83 = OpInBoundsAccessChain %82 %81 %27 %76\n%84 = OpLoad %14 %83 Aligned 4\n%85 = OpFMul %14 %84 %75\n%86 = OpLoad %15 %17\n%87 = OpCompositeConstruct %10 %70 %72\n%88 = OpCompositeConstruct %42 %85 %85 %85 %85\nOpImageWrite %86 %87 %88\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/matrix-load.frag",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _9_11\n{\n    float _m0[104];\n} _11;\n\nlayout(set = 0, binding = 0, std140) uniform _15_17\n{\n    vec4 _m0[26];\n} _17;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _121 = A % 3u;\n    SV_Target.x = _11._m0[(2u + (_121 * 16u)) + 8u] * P.x;\n    SV_Target.y = _11._m0[(6u + (_121 * 16u)) + 8u] * P.y;\n    SV_Target.z = _11._m0[(10u + (_121 * 16u)) + 8u] * P.z;\n    SV_Target.w = _11._m0[(14u + (_121 * 16u)) + 8u] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 156\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %19 %21 %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %9 \"\"\nOpName %15 \"\"\nOpName %19 \"A\"\nOpName %21 \"P\"\nOpName %23 \"SV_Target\"\nOpDecorate %8 ArrayStride 4\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %9 Block\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %21 Location 1\nOpDecorate %23 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 104\n%7 = OpTypeFloat 32\n%8 = OpTypeArray %7 %6\n%9 = OpTypeStruct %8\n%10 = OpTypePointer Uniform %9\n%11 = OpVariable %10 Uniform\n%12 = OpConstant %5 26\n%13 = OpTypeVector %7 4\n%14 = OpTypeArray %13 %12\n%15 = OpTypeStruct %14\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %13\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Output %13\n%23 = OpVariable %22 Output\n%24 = OpTypePointer Input %7\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%32 = OpConstant %5 2\n%35 = OpConstant %5 3\n%38 = OpTypePointer Uniform %13\n%51 = OpConstant %5 4\n%58 = OpConstant %5 5\n%65 = OpConstant %5 6\n%72 = OpConstant %5 7\n%79 = OpConstant %5 8\n%86 = OpConstant %5 9\n%93 = OpConstant %5 10\n%100 = OpConstant %5 11\n%107 = OpConstant %5 12\n%114 = OpConstant %5 13\n%123 = OpConstant %5 16\n%126 = OpTypePointer Uniform %7\n%141 = OpConstant %5 14\n%149 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %154\n%154 = OpLabel\n%25 = OpAccessChain %24 %21 %26\n%27 = OpLoad %7 %25\n%28 = OpAccessChain %24 %21 %29\n%30 = OpLoad %7 %28\n%31 = OpAccessChain %24 %21 %32\n%33 = OpLoad %7 %31\n%34 = OpAccessChain %24 %21 %35\n%36 = OpLoad %7 %34\n%37 = OpLoad %5 %19\n%39 = OpAccessChain %38 %17 %26 %32\n%40 = OpLoad %13 %39\n%41 = OpCompositeExtract %7 %40 0\n%42 = OpCompositeExtract %7 %40 1\n%43 = OpCompositeExtract %7 %40 2\n%44 = OpCompositeExtract %7 %40 3\n%45 = OpAccessChain %38 %17 %26 %35\n%46 = OpLoad %13 %45\n%47 = OpCompositeExtract %7 %46 0\n%48 = OpCompositeExtract %7 %46 1\n%49 = OpCompositeExtract %7 %46 2\n%50 = OpCompositeExtract %7 %46 3\n%52 = OpAccessChain %38 %17 %26 %51\n%53 = OpLoad %13 %52\n%54 = OpCompositeExtract %7 %53 0\n%55 = OpCompositeExtract %7 %53 1\n%56 = OpCompositeExtract %7 %53 2\n%57 = OpCompositeExtract %7 %53 3\n%59 = OpAccessChain %38 %17 %26 %58\n%60 = OpLoad %13 %59\n%61 = OpCompositeExtract %7 %60 0\n%62 = OpCompositeExtract %7 %60 1\n%63 = OpCompositeExtract %7 %60 2\n%64 = OpCompositeExtract %7 %60 3\n%66 = OpAccessChain %38 %17 %26 %65\n%67 = OpLoad %13 %66\n%68 = OpCompositeExtract %7 %67 0\n%69 = OpCompositeExtract %7 %67 1\n%70 = OpCompositeExtract %7 %67 2\n%71 = OpCompositeExtract %7 %67 3\n%73 = OpAccessChain %38 %17 %26 %72\n%74 = OpLoad %13 %73\n%75 = OpCompositeExtract %7 %74 0\n%76 = OpCompositeExtract %7 %74 1\n%77 = OpCompositeExtract %7 %74 2\n%78 = OpCompositeExtract %7 %74 3\n%80 = OpAccessChain %38 %17 %26 %79\n%81 = OpLoad %13 %80\n%82 = OpCompositeExtract %7 %81 0\n%83 = OpCompositeExtract %7 %81 1\n%84 = OpCompositeExtract %7 %81 2\n%85 = OpCompositeExtract %7 %81 3\n%87 = OpAccessChain %38 %17 %26 %86\n%88 = OpLoad %13 %87\n%89 = OpCompositeExtract %7 %88 0\n%90 = OpCompositeExtract %7 %88 1\n%91 = OpCompositeExtract %7 %88 2\n%92 = OpCompositeExtract %7 %88 3\n%94 = OpAccessChain %38 %17 %26 %93\n%95 = OpLoad %13 %94\n%96 = OpCompositeExtract %7 %95 0\n%97 = OpCompositeExtract %7 %95 1\n%98 = OpCompositeExtract %7 %95 2\n%99 = OpCompositeExtract %7 %95 3\n%101 = OpAccessChain %38 %17 %26 %100\n%102 = OpLoad %13 %101\n%103 = OpCompositeExtract %7 %102 0\n%104 = OpCompositeExtract %7 %102 1\n%105 = OpCompositeExtract %7 %102 2\n%106 = OpCompositeExtract %7 %102 3\n%108 = OpAccessChain %38 %17 %26 %107\n%109 = OpLoad %13 %108\n%110 = OpCompositeExtract %7 %109 0\n%111 = OpCompositeExtract %7 %109 1\n%112 = OpCompositeExtract %7 %109 2\n%113 = OpCompositeExtract %7 %109 3\n%115 = OpAccessChain %38 %17 %26 %114\n%116 = OpLoad %13 %115\n%117 = OpCompositeExtract %7 %116 0\n%118 = OpCompositeExtract %7 %116 1\n%119 = OpCompositeExtract %7 %116 2\n%120 = OpCompositeExtract %7 %116 3\n%121 = OpUMod %5 %37 %35\n%122 = OpIMul %5 %121 %123\n%124 = OpIAdd %5 %32 %122\n%125 = OpIAdd %5 %124 %79\n%127 = OpAccessChain %126 %11 %26 %125\n%128 = OpLoad %7 %127\n%129 = OpIMul %5 %121 %123\n%130 = OpIAdd %5 %65 %129\n%131 = OpIAdd %5 %130 %79\n%132 = OpAccessChain %126 %11 %26 %131\n%133 = OpLoad %7 %132\n%134 = OpIMul %5 %121 %123\n%135 = OpIAdd %5 %93 %134\n%136 = OpIAdd %5 %135 %79\n%137 = OpAccessChain %126 %11 %26 %136\n%138 = OpLoad %7 %137\n%139 = OpIMul %5 %121 %123\n%140 = OpIAdd %5 %141 %139\n%142 = OpIAdd %5 %140 %79\n%143 = OpAccessChain %126 %11 %26 %142\n%144 = OpLoad %7 %143\n%145 = OpFMul %7 %128 %27\n%146 = OpFMul %7 %133 %30\n%147 = OpFMul %7 %138 %33\n%148 = OpFMul %7 %144 %36\n%150 = OpAccessChain %149 %23 %26\nOpStore %150 %145\n%151 = OpAccessChain %149 %23 %29\nOpStore %151 %146\n%152 = OpAccessChain %149 %23 %32\nOpStore %152 %147\n%153 = OpAccessChain %149 %23 %35\nOpStore %153 %148\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/missing-first.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[6];\n} _12;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _35[6];\n    float _36[6];\n    float _37[6];\n    float _38[6];\n    _35[1u] = _12._m0[1u].x;\n    _36[1u] = _12._m0[1u].y;\n    _37[1u] = _12._m0[1u].z;\n    _38[1u] = _12._m0[1u].w;\n    _35[2u] = _12._m0[2u].x;\n    _36[2u] = _12._m0[2u].y;\n    _37[2u] = _12._m0[2u].z;\n    _38[2u] = _12._m0[2u].w;\n    _35[3u] = _12._m0[3u].x;\n    _36[3u] = _12._m0[3u].y;\n    _37[3u] = _12._m0[3u].z;\n    _38[3u] = _12._m0[3u].w;\n    _35[4u] = _12._m0[4u].x;\n    _36[4u] = _12._m0[4u].y;\n    _37[4u] = _12._m0[4u].z;\n    _38[4u] = _12._m0[4u].w;\n    _35[5u] = _12._m0[5u].x;\n    _36[5u] = _12._m0[5u].y;\n    _37[5u] = _12._m0[5u].z;\n    _38[5u] = _12._m0[5u].w;\n    uint _93 = A % 6u;\n    SV_Target.x = _35[_93] * P.x;\n    SV_Target.y = _36[_93] * P.y;\n    SV_Target.z = _37[_93] * P.z;\n    SV_Target.w = _38[_93] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 113\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"A\"\nOpName %16 \"P\"\nOpName %18 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %16 Location 1\nOpDecorate %18 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 6\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %8\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %8\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %7\n%21 = OpConstant %5 0\n%24 = OpConstant %5 1\n%27 = OpConstant %5 2\n%30 = OpConstant %5 3\n%33 = OpTypeArray %7 %6\n%34 = OpTypePointer Function %33\n%39 = OpTypePointer Uniform %8\n%46 = OpTypePointer Function %7\n%71 = OpConstant %5 4\n%82 = OpConstant %5 5\n%106 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%35 = OpVariable %34 Function\n%36 = OpVariable %34 Function\n%37 = OpVariable %34 Function\n%38 = OpVariable %34 Function\nOpBranch %111\n%111 = OpLabel\n%20 = OpAccessChain %19 %16 %21\n%22 = OpLoad %7 %20\n%23 = OpAccessChain %19 %16 %24\n%25 = OpLoad %7 %23\n%26 = OpAccessChain %19 %16 %27\n%28 = OpLoad %7 %26\n%29 = OpAccessChain %19 %16 %30\n%31 = OpLoad %7 %29\n%32 = OpLoad %5 %14\n%40 = OpAccessChain %39 %12 %21 %24\n%41 = OpLoad %8 %40\n%42 = OpCompositeExtract %7 %41 0\n%43 = OpCompositeExtract %7 %41 1\n%44 = OpCompositeExtract %7 %41 2\n%45 = OpCompositeExtract %7 %41 3\n%47 = OpAccessChain %46 %35 %24\n%48 = OpAccessChain %46 %36 %24\n%49 = OpAccessChain %46 %37 %24\n%50 = OpAccessChain %46 %38 %24\nOpStore %47 %42\nOpStore %48 %43\nOpStore %49 %44\nOpStore %50 %45\n%51 = OpAccessChain %39 %12 %21 %27\n%52 = OpLoad %8 %51\n%53 = OpCompositeExtract %7 %52 0\n%54 = OpCompositeExtract %7 %52 1\n%55 = OpCompositeExtract %7 %52 2\n%56 = OpCompositeExtract %7 %52 3\n%57 = OpAccessChain %46 %35 %27\n%58 = OpAccessChain %46 %36 %27\n%59 = OpAccessChain %46 %37 %27\n%60 = OpAccessChain %46 %38 %27\nOpStore %57 %53\nOpStore %58 %54\nOpStore %59 %55\nOpStore %60 %56\n%61 = OpAccessChain %39 %12 %21 %30\n%62 = OpLoad %8 %61\n%63 = OpCompositeExtract %7 %62 0\n%64 = OpCompositeExtract %7 %62 1\n%65 = OpCompositeExtract %7 %62 2\n%66 = OpCompositeExtract %7 %62 3\n%67 = OpAccessChain %46 %35 %30\n%68 = OpAccessChain %46 %36 %30\n%69 = OpAccessChain %46 %37 %30\n%70 = OpAccessChain %46 %38 %30\nOpStore %67 %63\nOpStore %68 %64\nOpStore %69 %65\nOpStore %70 %66\n%72 = OpAccessChain %39 %12 %21 %71\n%73 = OpLoad %8 %72\n%74 = OpCompositeExtract %7 %73 0\n%75 = OpCompositeExtract %7 %73 1\n%76 = OpCompositeExtract %7 %73 2\n%77 = OpCompositeExtract %7 %73 3\n%78 = OpAccessChain %46 %35 %71\n%79 = OpAccessChain %46 %36 %71\n%80 = OpAccessChain %46 %37 %71\n%81 = OpAccessChain %46 %38 %71\nOpStore %78 %74\nOpStore %79 %75\nOpStore %80 %76\nOpStore %81 %77\n%83 = OpAccessChain %39 %12 %21 %82\n%84 = OpLoad %8 %83\n%85 = OpCompositeExtract %7 %84 0\n%86 = OpCompositeExtract %7 %84 1\n%87 = OpCompositeExtract %7 %84 2\n%88 = OpCompositeExtract %7 %84 3\n%89 = OpAccessChain %46 %35 %82\n%90 = OpAccessChain %46 %36 %82\n%91 = OpAccessChain %46 %37 %82\n%92 = OpAccessChain %46 %38 %82\nOpStore %89 %85\nOpStore %90 %86\nOpStore %91 %87\nOpStore %92 %88\n%93 = OpUMod %5 %32 %6\n%94 = OpAccessChain %46 %35 %93\n%95 = OpAccessChain %46 %36 %93\n%96 = OpAccessChain %46 %37 %93\n%97 = OpAccessChain %46 %38 %93\n%98 = OpLoad %7 %94\n%99 = OpLoad %7 %95\n%100 = OpLoad %7 %96\n%101 = OpLoad %7 %97\n%102 = OpFMul %7 %98 %22\n%103 = OpFMul %7 %99 %25\n%104 = OpFMul %7 %100 %28\n%105 = OpFMul %7 %101 %31\n%107 = OpAccessChain %106 %18 %21\nOpStore %107 %102\n%108 = OpAccessChain %106 %18 %24\nOpStore %108 %103\n%109 = OpAccessChain %106 %18 %27\nOpStore %109 %104\n%110 = OpAccessChain %106 %18 %30\nOpStore %110 %105\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/missing-last-element.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[6];\n} _12;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _35[6];\n    float _36[6];\n    float _37[6];\n    float _38[6];\n    _35[0u] = _12._m0[0u].x;\n    _36[0u] = _12._m0[0u].y;\n    _37[0u] = _12._m0[0u].z;\n    _38[0u] = _12._m0[0u].w;\n    _35[1u] = _12._m0[1u].x;\n    _36[1u] = _12._m0[1u].y;\n    _37[1u] = _12._m0[1u].z;\n    _38[1u] = _12._m0[1u].w;\n    _35[2u] = _12._m0[2u].x;\n    _36[2u] = _12._m0[2u].y;\n    _37[2u] = _12._m0[2u].z;\n    _38[2u] = _12._m0[2u].w;\n    _35[3u] = _12._m0[3u].x;\n    _36[3u] = _12._m0[3u].y;\n    _37[3u] = _12._m0[3u].z;\n    _38[3u] = _12._m0[3u].w;\n    _35[4u] = _12._m0[4u].x;\n    _36[4u] = _12._m0[4u].y;\n    _37[4u] = _12._m0[4u].z;\n    _38[4u] = _12._m0[4u].w;\n    uint _92 = A % 6u;\n    SV_Target.x = _35[_92] * P.x;\n    SV_Target.y = _36[_92] * P.y;\n    SV_Target.z = _37[_92] * P.z;\n    SV_Target.w = _38[_92] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 112\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"A\"\nOpName %16 \"P\"\nOpName %18 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %16 Location 1\nOpDecorate %18 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 6\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %8\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %8\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %7\n%21 = OpConstant %5 0\n%24 = OpConstant %5 1\n%27 = OpConstant %5 2\n%30 = OpConstant %5 3\n%33 = OpTypeArray %7 %6\n%34 = OpTypePointer Function %33\n%39 = OpTypePointer Uniform %8\n%46 = OpTypePointer Function %7\n%81 = OpConstant %5 4\n%105 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%35 = OpVariable %34 Function\n%36 = OpVariable %34 Function\n%37 = OpVariable %34 Function\n%38 = OpVariable %34 Function\nOpBranch %110\n%110 = OpLabel\n%20 = OpAccessChain %19 %16 %21\n%22 = OpLoad %7 %20\n%23 = OpAccessChain %19 %16 %24\n%25 = OpLoad %7 %23\n%26 = OpAccessChain %19 %16 %27\n%28 = OpLoad %7 %26\n%29 = OpAccessChain %19 %16 %30\n%31 = OpLoad %7 %29\n%32 = OpLoad %5 %14\n%40 = OpAccessChain %39 %12 %21 %21\n%41 = OpLoad %8 %40\n%42 = OpCompositeExtract %7 %41 0\n%43 = OpCompositeExtract %7 %41 1\n%44 = OpCompositeExtract %7 %41 2\n%45 = OpCompositeExtract %7 %41 3\n%47 = OpAccessChain %46 %35 %21\n%48 = OpAccessChain %46 %36 %21\n%49 = OpAccessChain %46 %37 %21\n%50 = OpAccessChain %46 %38 %21\nOpStore %47 %42\nOpStore %48 %43\nOpStore %49 %44\nOpStore %50 %45\n%51 = OpAccessChain %39 %12 %21 %24\n%52 = OpLoad %8 %51\n%53 = OpCompositeExtract %7 %52 0\n%54 = OpCompositeExtract %7 %52 1\n%55 = OpCompositeExtract %7 %52 2\n%56 = OpCompositeExtract %7 %52 3\n%57 = OpAccessChain %46 %35 %24\n%58 = OpAccessChain %46 %36 %24\n%59 = OpAccessChain %46 %37 %24\n%60 = OpAccessChain %46 %38 %24\nOpStore %57 %53\nOpStore %58 %54\nOpStore %59 %55\nOpStore %60 %56\n%61 = OpAccessChain %39 %12 %21 %27\n%62 = OpLoad %8 %61\n%63 = OpCompositeExtract %7 %62 0\n%64 = OpCompositeExtract %7 %62 1\n%65 = OpCompositeExtract %7 %62 2\n%66 = OpCompositeExtract %7 %62 3\n%67 = OpAccessChain %46 %35 %27\n%68 = OpAccessChain %46 %36 %27\n%69 = OpAccessChain %46 %37 %27\n%70 = OpAccessChain %46 %38 %27\nOpStore %67 %63\nOpStore %68 %64\nOpStore %69 %65\nOpStore %70 %66\n%71 = OpAccessChain %39 %12 %21 %30\n%72 = OpLoad %8 %71\n%73 = OpCompositeExtract %7 %72 0\n%74 = OpCompositeExtract %7 %72 1\n%75 = OpCompositeExtract %7 %72 2\n%76 = OpCompositeExtract %7 %72 3\n%77 = OpAccessChain %46 %35 %30\n%78 = OpAccessChain %46 %36 %30\n%79 = OpAccessChain %46 %37 %30\n%80 = OpAccessChain %46 %38 %30\nOpStore %77 %73\nOpStore %78 %74\nOpStore %79 %75\nOpStore %80 %76\n%82 = OpAccessChain %39 %12 %21 %81\n%83 = OpLoad %8 %82\n%84 = OpCompositeExtract %7 %83 0\n%85 = OpCompositeExtract %7 %83 1\n%86 = OpCompositeExtract %7 %83 2\n%87 = OpCompositeExtract %7 %83 3\n%88 = OpAccessChain %46 %35 %81\n%89 = OpAccessChain %46 %36 %81\n%90 = OpAccessChain %46 %37 %81\n%91 = OpAccessChain %46 %38 %81\nOpStore %88 %84\nOpStore %89 %85\nOpStore %90 %86\nOpStore %91 %87\n%92 = OpUMod %5 %32 %6\n%93 = OpAccessChain %46 %35 %92\n%94 = OpAccessChain %46 %36 %92\n%95 = OpAccessChain %46 %37 %92\n%96 = OpAccessChain %46 %38 %92\n%97 = OpLoad %7 %93\n%98 = OpLoad %7 %94\n%99 = OpLoad %7 %95\n%100 = OpLoad %7 %96\n%101 = OpFMul %7 %97 %22\n%102 = OpFMul %7 %98 %25\n%103 = OpFMul %7 %99 %28\n%104 = OpFMul %7 %100 %31\n%106 = OpAccessChain %105 %18 %21\nOpStore %106 %101\n%107 = OpAccessChain %105 %18 %24\nOpStore %107 %102\n%108 = OpAccessChain %105 %18 %27\nOpStore %108 %103\n%109 = OpAccessChain %105 %18 %30\nOpStore %109 %104\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/out-of-order-load.frag",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _9_11\n{\n    float _m0[24];\n} _11;\n\nlayout(set = 0, binding = 0, std140) uniform _15_17\n{\n    vec4 _m0[6];\n} _17;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _58 = A % 6u;\n    SV_Target.x = _11._m0[_58 * 4u] * P.x;\n    SV_Target.y = _11._m0[(_58 * 4u) + 1u] * P.y;\n    SV_Target.z = _11._m0[(_58 * 4u) + 2u] * P.z;\n    SV_Target.w = _11._m0[(_58 * 4u) + 3u] * P.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %19 %21 %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %9 \"\"\nOpName %15 \"\"\nOpName %19 \"A\"\nOpName %21 \"P\"\nOpName %23 \"SV_Target\"\nOpDecorate %8 ArrayStride 4\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %9 Block\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %21 Location 1\nOpDecorate %23 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 24\n%7 = OpTypeFloat 32\n%8 = OpTypeArray %7 %6\n%9 = OpTypeStruct %8\n%10 = OpTypePointer Uniform %9\n%11 = OpVariable %10 Uniform\n%12 = OpConstant %5 6\n%13 = OpTypeVector %7 4\n%14 = OpTypeArray %13 %12\n%15 = OpTypeStruct %14\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %13\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Output %13\n%23 = OpVariable %22 Output\n%24 = OpTypePointer Input %7\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%32 = OpConstant %5 2\n%35 = OpConstant %5 3\n%38 = OpTypePointer Uniform %13\n%45 = OpConstant %5 5\n%60 = OpConstant %5 4\n%61 = OpTypePointer Uniform %7\n%80 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %85\n%85 = OpLabel\n%25 = OpAccessChain %24 %21 %26\n%27 = OpLoad %7 %25\n%28 = OpAccessChain %24 %21 %29\n%30 = OpLoad %7 %28\n%31 = OpAccessChain %24 %21 %32\n%33 = OpLoad %7 %31\n%34 = OpAccessChain %24 %21 %35\n%36 = OpLoad %7 %34\n%37 = OpLoad %5 %19\n%39 = OpAccessChain %38 %17 %26 %26\n%40 = OpLoad %13 %39\n%41 = OpCompositeExtract %7 %40 0\n%42 = OpCompositeExtract %7 %40 1\n%43 = OpCompositeExtract %7 %40 2\n%44 = OpCompositeExtract %7 %40 3\n%46 = OpAccessChain %38 %17 %26 %45\n%47 = OpLoad %13 %46\n%48 = OpCompositeExtract %7 %47 0\n%49 = OpCompositeExtract %7 %47 1\n%50 = OpCompositeExtract %7 %47 2\n%51 = OpCompositeExtract %7 %47 3\n%52 = OpAccessChain %38 %17 %26 %35\n%53 = OpLoad %13 %52\n%54 = OpCompositeExtract %7 %53 0\n%55 = OpCompositeExtract %7 %53 1\n%56 = OpCompositeExtract %7 %53 2\n%57 = OpCompositeExtract %7 %53 3\n%58 = OpUMod %5 %37 %12\n%59 = OpIMul %5 %58 %60\n%62 = OpAccessChain %61 %11 %26 %59\n%63 = OpIMul %5 %58 %60\n%64 = OpIAdd %5 %63 %29\n%65 = OpAccessChain %61 %11 %26 %64\n%66 = OpIMul %5 %58 %60\n%67 = OpIAdd %5 %66 %32\n%68 = OpAccessChain %61 %11 %26 %67\n%69 = OpIMul %5 %58 %60\n%70 = OpIAdd %5 %69 %35\n%71 = OpAccessChain %61 %11 %26 %70\n%72 = OpLoad %7 %62\n%73 = OpLoad %7 %65\n%74 = OpLoad %7 %68\n%75 = OpLoad %7 %71\n%76 = OpFMul %7 %72 %27\n%77 = OpFMul %7 %73 %30\n%78 = OpFMul %7 %74 %33\n%79 = OpFMul %7 %75 %36\n%81 = OpAccessChain %80 %23 %26\nOpStore %81 %76\n%82 = OpAccessChain %80 %23 %29\nOpStore %82 %77\n%83 = OpAccessChain %80 %23 %32\nOpStore %83 %78\n%84 = OpAccessChain %80 %23 %35\nOpStore %84 %79\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/store-after-load.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[6];\n} _12;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _35[6];\n    float _36[6];\n    float _37[6];\n    float _38[6];\n    _35[0u] = _12._m0[0u].x;\n    _36[0u] = _12._m0[0u].y;\n    _37[0u] = _12._m0[0u].z;\n    _38[0u] = _12._m0[0u].w;\n    _35[1u] = _12._m0[1u].x;\n    _36[1u] = _12._m0[1u].y;\n    _37[1u] = _12._m0[1u].z;\n    _38[1u] = _12._m0[1u].w;\n    _35[2u] = _12._m0[2u].x;\n    _36[2u] = _12._m0[2u].y;\n    _37[2u] = _12._m0[2u].z;\n    _38[2u] = _12._m0[2u].w;\n    uint _71 = A % 3u;\n    float _76 = _35[_71];\n    float _77 = _36[_71];\n    float _78 = _37[_71];\n    float _79 = _38[_71];\n    _35[3u] = _12._m0[3u].x;\n    _36[3u] = _12._m0[3u].y;\n    _37[3u] = _12._m0[3u].z;\n    _38[3u] = _12._m0[3u].w;\n    _35[4u] = _12._m0[4u].x;\n    _36[4u] = _12._m0[4u].y;\n    _37[4u] = _12._m0[4u].z;\n    _38[4u] = _12._m0[4u].w;\n    _35[5u] = _12._m0[5u].x;\n    _36[5u] = _12._m0[5u].y;\n    _37[5u] = _12._m0[5u].z;\n    _38[5u] = _12._m0[5u].w;\n    uint _112 = A % 6u;\n    SV_Target.x = (_35[_112] * P.x) + _76;\n    SV_Target.y = (_36[_112] * P.y) + _77;\n    SV_Target.z = (_37[_112] * P.z) + _78;\n    SV_Target.w = (_38[_112] * P.w) + _79;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 136\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"A\"\nOpName %16 \"P\"\nOpName %18 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %16 Location 1\nOpDecorate %18 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 6\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %8\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %8\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %7\n%21 = OpConstant %5 0\n%24 = OpConstant %5 1\n%27 = OpConstant %5 2\n%30 = OpConstant %5 3\n%33 = OpTypeArray %7 %6\n%34 = OpTypePointer Function %33\n%39 = OpTypePointer Uniform %8\n%46 = OpTypePointer Function %7\n%90 = OpConstant %5 4\n%101 = OpConstant %5 5\n%129 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%35 = OpVariable %34 Function\n%36 = OpVariable %34 Function\n%37 = OpVariable %34 Function\n%38 = OpVariable %34 Function\nOpBranch %134\n%134 = OpLabel\n%20 = OpAccessChain %19 %16 %21\n%22 = OpLoad %7 %20\n%23 = OpAccessChain %19 %16 %24\n%25 = OpLoad %7 %23\n%26 = OpAccessChain %19 %16 %27\n%28 = OpLoad %7 %26\n%29 = OpAccessChain %19 %16 %30\n%31 = OpLoad %7 %29\n%32 = OpLoad %5 %14\n%40 = OpAccessChain %39 %12 %21 %21\n%41 = OpLoad %8 %40\n%42 = OpCompositeExtract %7 %41 0\n%43 = OpCompositeExtract %7 %41 1\n%44 = OpCompositeExtract %7 %41 2\n%45 = OpCompositeExtract %7 %41 3\n%47 = OpAccessChain %46 %35 %21\n%48 = OpAccessChain %46 %36 %21\n%49 = OpAccessChain %46 %37 %21\n%50 = OpAccessChain %46 %38 %21\nOpStore %47 %42\nOpStore %48 %43\nOpStore %49 %44\nOpStore %50 %45\n%51 = OpAccessChain %39 %12 %21 %24\n%52 = OpLoad %8 %51\n%53 = OpCompositeExtract %7 %52 0\n%54 = OpCompositeExtract %7 %52 1\n%55 = OpCompositeExtract %7 %52 2\n%56 = OpCompositeExtract %7 %52 3\n%57 = OpAccessChain %46 %35 %24\n%58 = OpAccessChain %46 %36 %24\n%59 = OpAccessChain %46 %37 %24\n%60 = OpAccessChain %46 %38 %24\nOpStore %57 %53\nOpStore %58 %54\nOpStore %59 %55\nOpStore %60 %56\n%61 = OpAccessChain %39 %12 %21 %27\n%62 = OpLoad %8 %61\n%63 = OpCompositeExtract %7 %62 0\n%64 = OpCompositeExtract %7 %62 1\n%65 = OpCompositeExtract %7 %62 2\n%66 = OpCompositeExtract %7 %62 3\n%67 = OpAccessChain %46 %35 %27\n%68 = OpAccessChain %46 %36 %27\n%69 = OpAccessChain %46 %37 %27\n%70 = OpAccessChain %46 %38 %27\nOpStore %67 %63\nOpStore %68 %64\nOpStore %69 %65\nOpStore %70 %66\n%71 = OpUMod %5 %32 %30\n%72 = OpAccessChain %46 %35 %71\n%73 = OpAccessChain %46 %36 %71\n%74 = OpAccessChain %46 %37 %71\n%75 = OpAccessChain %46 %38 %71\n%76 = OpLoad %7 %72\n%77 = OpLoad %7 %73\n%78 = OpLoad %7 %74\n%79 = OpLoad %7 %75\n%80 = OpAccessChain %39 %12 %21 %30\n%81 = OpLoad %8 %80\n%82 = OpCompositeExtract %7 %81 0\n%83 = OpCompositeExtract %7 %81 1\n%84 = OpCompositeExtract %7 %81 2\n%85 = OpCompositeExtract %7 %81 3\n%86 = OpAccessChain %46 %35 %30\n%87 = OpAccessChain %46 %36 %30\n%88 = OpAccessChain %46 %37 %30\n%89 = OpAccessChain %46 %38 %30\nOpStore %86 %82\nOpStore %87 %83\nOpStore %88 %84\nOpStore %89 %85\n%91 = OpAccessChain %39 %12 %21 %90\n%92 = OpLoad %8 %91\n%93 = OpCompositeExtract %7 %92 0\n%94 = OpCompositeExtract %7 %92 1\n%95 = OpCompositeExtract %7 %92 2\n%96 = OpCompositeExtract %7 %92 3\n%97 = OpAccessChain %46 %35 %90\n%98 = OpAccessChain %46 %36 %90\n%99 = OpAccessChain %46 %37 %90\n%100 = OpAccessChain %46 %38 %90\nOpStore %97 %93\nOpStore %98 %94\nOpStore %99 %95\nOpStore %100 %96\n%102 = OpAccessChain %39 %12 %21 %101\n%103 = OpLoad %8 %102\n%104 = OpCompositeExtract %7 %103 0\n%105 = OpCompositeExtract %7 %103 1\n%106 = OpCompositeExtract %7 %103 2\n%107 = OpCompositeExtract %7 %103 3\n%108 = OpAccessChain %46 %35 %101\n%109 = OpAccessChain %46 %36 %101\n%110 = OpAccessChain %46 %37 %101\n%111 = OpAccessChain %46 %38 %101\nOpStore %108 %104\nOpStore %109 %105\nOpStore %110 %106\nOpStore %111 %107\n%112 = OpUMod %5 %32 %6\n%113 = OpAccessChain %46 %35 %112\n%114 = OpAccessChain %46 %36 %112\n%115 = OpAccessChain %46 %37 %112\n%116 = OpAccessChain %46 %38 %112\n%117 = OpLoad %7 %113\n%118 = OpLoad %7 %114\n%119 = OpLoad %7 %115\n%120 = OpLoad %7 %116\n%121 = OpFMul %7 %117 %22\n%122 = OpFMul %7 %118 %25\n%123 = OpFMul %7 %119 %28\n%124 = OpFMul %7 %120 %31\n%125 = OpFAdd %7 %121 %76\n%126 = OpFAdd %7 %122 %77\n%127 = OpFAdd %7 %123 %78\n%128 = OpFAdd %7 %124 %79\n%130 = OpAccessChain %129 %18 %21\nOpStore %130 %125\n%131 = OpAccessChain %129 %18 %24\nOpStore %131 %126\n%132 = OpAccessChain %129 %18 %27\nOpStore %132 %127\n%133 = OpAccessChain %129 %18 %30\nOpStore %133 %128\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/alloca-opts/uint4-array-load.frag",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _8_10\n{\n    uint _m0[24];\n} _10;\n\nlayout(set = 0, binding = 0, std140) uniform _15_17\n{\n    vec4 _m0[6];\n} _17;\n\nlayout(location = 0) flat in uint A;\nlayout(location = 1) in vec4 P;\nlayout(location = 0) out uvec4 SV_Target;\n\nvoid main()\n{\n    uint _84 = A % 6u;\n    SV_Target.x = uint(float(_10._m0[_84 * 4u]) * P.x);\n    SV_Target.y = uint(float(_10._m0[(_84 * 4u) + 1u]) * P.y);\n    SV_Target.z = uint(float(_10._m0[(_84 * 4u) + 2u]) * P.z);\n    SV_Target.w = uint(float(_10._m0[(_84 * 4u) + 3u]) * P.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 120\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %19 %21 %24\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"\"\nOpName %15 \"\"\nOpName %19 \"A\"\nOpName %21 \"P\"\nOpName %24 \"SV_Target\"\nOpDecorate %7 ArrayStride 4\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %21 Location 1\nOpDecorate %24 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 24\n%7 = OpTypeArray %5 %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer Uniform %8\n%10 = OpVariable %9 Uniform\n%11 = OpConstant %5 6\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypeArray %13 %11\n%15 = OpTypeStruct %14\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %13\n%21 = OpVariable %20 Input\n%22 = OpTypeVector %5 4\n%23 = OpTypePointer Output %22\n%24 = OpVariable %23 Output\n%25 = OpTypePointer Input %12\n%27 = OpConstant %5 0\n%30 = OpConstant %5 1\n%33 = OpConstant %5 2\n%36 = OpConstant %5 3\n%39 = OpTypePointer Uniform %13\n%68 = OpConstant %5 4\n%76 = OpConstant %5 5\n%86 = OpTypePointer Uniform %5\n%113 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %118\n%118 = OpLabel\n%26 = OpAccessChain %25 %21 %27\n%28 = OpLoad %12 %26\n%29 = OpAccessChain %25 %21 %30\n%31 = OpLoad %12 %29\n%32 = OpAccessChain %25 %21 %33\n%34 = OpLoad %12 %32\n%35 = OpAccessChain %25 %21 %36\n%37 = OpLoad %12 %35\n%38 = OpLoad %5 %19\n%40 = OpAccessChain %39 %17 %27 %27\n%41 = OpLoad %13 %40\n%42 = OpBitcast %22 %41\n%43 = OpCompositeExtract %5 %42 0\n%44 = OpCompositeExtract %5 %42 1\n%45 = OpCompositeExtract %5 %42 2\n%46 = OpCompositeExtract %5 %42 3\n%47 = OpAccessChain %39 %17 %27 %30\n%48 = OpLoad %13 %47\n%49 = OpBitcast %22 %48\n%50 = OpCompositeExtract %5 %49 0\n%51 = OpCompositeExtract %5 %49 1\n%52 = OpCompositeExtract %5 %49 2\n%53 = OpCompositeExtract %5 %49 3\n%54 = OpAccessChain %39 %17 %27 %33\n%55 = OpLoad %13 %54\n%56 = OpBitcast %22 %55\n%57 = OpCompositeExtract %5 %56 0\n%58 = OpCompositeExtract %5 %56 1\n%59 = OpCompositeExtract %5 %56 2\n%60 = OpCompositeExtract %5 %56 3\n%61 = OpAccessChain %39 %17 %27 %36\n%62 = OpLoad %13 %61\n%63 = OpBitcast %22 %62\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpCompositeExtract %5 %63 1\n%66 = OpCompositeExtract %5 %63 2\n%67 = OpCompositeExtract %5 %63 3\n%69 = OpAccessChain %39 %17 %27 %68\n%70 = OpLoad %13 %69\n%71 = OpBitcast %22 %70\n%72 = OpCompositeExtract %5 %71 0\n%73 = OpCompositeExtract %5 %71 1\n%74 = OpCompositeExtract %5 %71 2\n%75 = OpCompositeExtract %5 %71 3\n%77 = OpAccessChain %39 %17 %27 %76\n%78 = OpLoad %13 %77\n%79 = OpBitcast %22 %78\n%80 = OpCompositeExtract %5 %79 0\n%81 = OpCompositeExtract %5 %79 1\n%82 = OpCompositeExtract %5 %79 2\n%83 = OpCompositeExtract %5 %79 3\n%84 = OpUMod %5 %38 %11\n%85 = OpIMul %5 %84 %68\n%87 = OpAccessChain %86 %10 %27 %85\n%88 = OpIMul %5 %84 %68\n%89 = OpIAdd %5 %88 %30\n%90 = OpAccessChain %86 %10 %27 %89\n%91 = OpIMul %5 %84 %68\n%92 = OpIAdd %5 %91 %33\n%93 = OpAccessChain %86 %10 %27 %92\n%94 = OpIMul %5 %84 %68\n%95 = OpIAdd %5 %94 %36\n%96 = OpAccessChain %86 %10 %27 %95\n%97 = OpLoad %5 %87\n%98 = OpLoad %5 %90\n%99 = OpLoad %5 %93\n%100 = OpLoad %5 %96\n%101 = OpConvertUToF %12 %97\n%102 = OpConvertUToF %12 %98\n%103 = OpConvertUToF %12 %99\n%104 = OpConvertUToF %12 %100\n%105 = OpFMul %12 %101 %28\n%106 = OpFMul %12 %102 %31\n%107 = OpFMul %12 %103 %34\n%108 = OpFMul %12 %104 %37\n%109 = OpConvertFToU %5 %105\n%110 = OpConvertFToU %5 %106\n%111 = OpConvertFToU %5 %107\n%112 = OpConvertFToU %5 %108\n%114 = OpAccessChain %113 %24 %27\nOpStore %114 %109\n%115 = OpAccessChain %113 %24 %30\nOpStore %115 %110\n%116 = OpAccessChain %113 %24 %33\nOpStore %116 %111\n%117 = OpAccessChain %113 %24 %36\nOpStore %117 %112\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/asm/bfi.bc.dxil",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[1];\n} _12;\n\nlayout(location = 0) out uvec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _20 = floatBitsToUint(_12._m0[0u]);\n    uint _27 = _20.y & 31u;\n    uint _32 = bitfieldInsert(_20.w, _20.z, int(_27), int(min((_20.x & 31u), (32u - _27))));\n    SV_Target.x = _32;\n    SV_Target.y = _32;\n    SV_Target.z = _32;\n    SV_Target.w = _32;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\n%31 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeVector %5 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%16 = OpConstant %5 0\n%17 = OpTypePointer Uniform %8\n%26 = OpConstant %5 31\n%29 = OpConstant %5 32\n%33 = OpTypePointer Output %5\n%37 = OpConstant %5 2\n%39 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%18 = OpAccessChain %17 %12 %16 %16\n%19 = OpLoad %8 %18\n%20 = OpBitcast %13 %19\n%21 = OpCompositeExtract %5 %20 0\n%22 = OpCompositeExtract %5 %20 1\n%23 = OpCompositeExtract %5 %20 2\n%24 = OpCompositeExtract %5 %20 3\n%25 = OpBitwiseAnd %5 %21 %26\n%27 = OpBitwiseAnd %5 %22 %26\n%28 = OpISub %5 %29 %27\n%30 = OpExtInst %5 %31 UMin %25 %28\n%32 = OpBitFieldInsert %5 %24 %23 %27 %30\n%34 = OpAccessChain %33 %15 %16\nOpStore %34 %32\n%35 = OpAccessChain %33 %15 %6\nOpStore %35 %32\n%36 = OpAccessChain %33 %15 %37\nOpStore %36 %32\n%38 = OpAccessChain %33 %15 %39\nOpStore %38 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/asm/cbv.no-legacy-cbuf-layout.sm66-heaps-single-alias.bc.dxil",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform BindlessCBV\n{\n    float _m0[16384];\n} _12[];\n\nlayout(set = 0, binding = 0, std140) uniform _16_19\n{\n    vec4 _m0[4096];\n} _19[];\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _34 = floatBitsToUint(_12[1u]._m0[1u]) >> 2u;\n    SV_Target.x = _12[0u]._m0[_34];\n    SV_Target.y = _12[0u]._m0[_34];\n    SV_Target.z = _12[0u]._m0[_34];\n    SV_Target.w = _12[0u]._m0[_34];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %21\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %9 \"BindlessCBV\"\nOpName %16 \"BindlessCBV\"\nOpName %21 \"SV_Target\"\nOpDecorate %8 ArrayStride 4\nOpDecorate %9 Block\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %15 ArrayStride 16\nOpDecorate %16 Block\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %21 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 16384\n%8 = OpTypeArray %5 %7\n%9 = OpTypeStruct %8\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeVector %5 4\n%14 = OpConstant %6 4096\n%15 = OpTypeArray %13 %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer Uniform %17\n%19 = OpVariable %18 Uniform\n%20 = OpTypePointer Output %13\n%21 = OpVariable %20 Output\n%22 = OpTypePointer Uniform %9\n%24 = OpConstant %6 0\n%26 = OpConstant %6 1\n%27 = OpTypePointer Uniform %16\n%29 = OpConstant %6 2\n%30 = OpTypePointer Uniform %5\n%37 = OpTypePointer Output %5\n%42 = OpConstant %6 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%23 = OpAccessChain %22 %12 %24\n%25 = OpAccessChain %22 %12 %26\n%28 = OpAccessChain %27 %19 %29\n%31 = OpAccessChain %30 %25 %24 %26\n%32 = OpLoad %5 %31\n%33 = OpBitcast %6 %32\n%34 = OpShiftRightLogical %6 %33 %29\n%35 = OpAccessChain %30 %23 %24 %34\n%36 = OpLoad %5 %35\n%38 = OpAccessChain %37 %21 %24\nOpStore %38 %36\n%39 = OpAccessChain %37 %21 %26\nOpStore %39 %36\n%40 = OpAccessChain %37 %21 %29\nOpStore %40 %36\n%41 = OpAccessChain %37 %21 %42\nOpStore %41 %36\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/asm/cbv.no-legacy-cbuf-layout.sm66-heaps.bc.dxil",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform BindlessCBV\n{\n    float _m0[16384];\n} _12[];\n\nlayout(set = 0, binding = 0, scalar) uniform _16_19\n{\n    float16_t _m0[32768];\n} _19[];\n\nlayout(set = 0, binding = 0, scalar) uniform _23_26\n{\n    uint64_t _m0[8192];\n} _26[];\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _51 = (_12[0u]._m0[1u] + float(_19[1u]._m0[1u])) + float(_26[2u]._m0[1u]);\n    SV_Target.x = _51;\n    SV_Target.y = _51;\n    SV_Target.z = _51;\n    SV_Target.w = _51;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int64\nOpCapability UniformAndStorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %29\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %9 \"BindlessCBV\"\nOpName %16 \"BindlessCBV\"\nOpName %23 \"BindlessCBV\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 ArrayStride 4\nOpDecorate %9 Block\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %15 ArrayStride 2\nOpDecorate %16 Block\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %22 ArrayStride 8\nOpDecorate %23 Block\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 16384\n%8 = OpTypeArray %5 %7\n%9 = OpTypeStruct %8\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeFloat 16\n%14 = OpConstant %6 32768\n%15 = OpTypeArray %13 %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer Uniform %17\n%19 = OpVariable %18 Uniform\n%20 = OpTypeInt 64 0\n%21 = OpConstant %6 8192\n%22 = OpTypeArray %20 %21\n%23 = OpTypeStruct %22\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer Uniform %24\n%26 = OpVariable %25 Uniform\n%27 = OpTypeVector %5 4\n%28 = OpTypePointer Output %27\n%29 = OpVariable %28 Output\n%30 = OpTypePointer Uniform %9\n%32 = OpConstant %6 0\n%33 = OpTypePointer Uniform %16\n%35 = OpConstant %6 1\n%36 = OpTypePointer Uniform %23\n%38 = OpConstant %6 2\n%39 = OpTypePointer Uniform %5\n%42 = OpTypePointer Uniform %13\n%45 = OpTypePointer Uniform %20\n%52 = OpTypePointer Output %5\n%57 = OpConstant %6 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %58\n%58 = OpLabel\n%31 = OpAccessChain %30 %12 %32\n%34 = OpAccessChain %33 %19 %35\n%37 = OpAccessChain %36 %26 %38\n%40 = OpAccessChain %39 %31 %32 %35\n%41 = OpLoad %5 %40\n%43 = OpAccessChain %42 %34 %32 %35\n%44 = OpLoad %13 %43\n%46 = OpAccessChain %45 %37 %32 %35\n%47 = OpLoad %20 %46\n%48 = OpFConvert %5 %44\n%49 = OpConvertUToF %5 %47\n%50 = OpFAdd %5 %41 %48\n%51 = OpFAdd %5 %50 %49\n%53 = OpAccessChain %52 %29 %32\nOpStore %53 %51\n%54 = OpAccessChain %52 %29 %35\nOpStore %54 %51\n%55 = OpAccessChain %52 %29 %38\nOpStore %55 %51\n%56 = OpAccessChain %52 %29 %57\nOpStore %56 %51\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/asm/constant-struct-aggregate.bc.dxil",
    "content": "#version 460\n\nstruct _13\n{\n    float _m0;\n    float _m1;\n};\n\nconst _13 _27[4] = _13[](_13(1.0, 2.0), _13(3.0, 4.0), _13(5.0, 6.0), _13(7.0, 8.0));\n\nlayout(location = 0) in float F;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = _27[uint(int(F)) & 3u]._m1;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"F\"\nOpName %10 \"SV_Target\"\nOpName %13 \"\"\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 2\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 4\n%13 = OpTypeStruct %5 %5\n%14 = OpTypeArray %13 %12\n%15 = OpConstant %5 1\n%16 = OpConstant %5 2\n%17 = OpConstantComposite %13 %15 %16\n%18 = OpConstant %5 3\n%19 = OpConstant %5 4\n%20 = OpConstantComposite %13 %18 %19\n%21 = OpConstant %5 5\n%22 = OpConstant %5 6\n%23 = OpConstantComposite %13 %21 %22\n%24 = OpConstant %5 7\n%25 = OpConstant %5 8\n%26 = OpConstantComposite %13 %24 %25\n%27 = OpConstantComposite %14 %17 %20 %23 %26\n%28 = OpTypePointer Private %14\n%29 = OpVariable %28 Private %27\n%33 = OpConstant %11 3\n%34 = OpTypePointer Private %5\n%36 = OpConstant %11 1\n%38 = OpTypePointer Output %5\n%40 = OpConstant %11 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%30 = OpLoad %5 %7\n%31 = OpConvertFToS %11 %30\n%32 = OpBitwiseAnd %11 %31 %33\n%35 = OpAccessChain %34 %29 %32 %36\n%37 = OpLoad %5 %35\n%39 = OpAccessChain %38 %10 %40\nOpStore %39 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/asm/control-flow-multi-break-with-non-idom-loop-header.dxil",
    "content": "#version 460\nlayout(local_size_x = 8, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) readonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid _someFn_YAXI_Z(uint _15)\n{\n    uint _21 = atomicAdd(_9._m0[0u], 1u);\n    _9._m0[_21] = _15;\n}\n\nuint _getBranchTarget_YAII_Z(uint _25)\n{\n    return _13._m0[_25];\n}\n\nvoid main()\n{\n    uint _32;\n    bool selector_5;\n    uint _31 = 0u;\n    for (;;)\n    {\n        _32 = 17u;\n        _someFn_YAXI_Z(_32);\n        _31++;\n        _32 = 18u;\n        _someFn_YAXI_Z(_32);\n        if (_getBranchTarget_YAII_Z(_32) == 20u)\n        {\n            selector_5 = false;\n            break;\n        }\n        _32 = 21u;\n        _someFn_YAXI_Z(_32);\n        if (!(_getBranchTarget_YAII_Z(_32) == 32u))\n        {\n            _32 = 24u;\n            _someFn_YAXI_Z(_32);\n            if (_getBranchTarget_YAII_Z(_32) == 30u)\n            {\n                selector_5 = true;\n                break;\n            }\n            _32 = 43u;\n            _someFn_YAXI_Z(_32);\n            if (_getBranchTarget_YAII_Z(_32) == 30u)\n            {\n                selector_5 = true;\n                break;\n            }\n        }\n        _32 = 32u;\n        _someFn_YAXI_Z(_32);\n        if (int(_31) < int(99u))\n        {\n            continue;\n        }\n        else\n        {\n            selector_5 = false;\n            break;\n        }\n    }\n    if (selector_5)\n    {\n        _32 = 30u;\n        _someFn_YAXI_Z(_32);\n    }\n    else\n    {\n        _32 = 20u;\n        _someFn_YAXI_Z(_32);\n    }\n    _32 = 23u;\n    _someFn_YAXI_Z(_32);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 8 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %16 \"\u0001?someFn@@YAXI@Z\"\nOpName %26 \"\u0001?getBranchTarget@@YAII@Z\"\nOpName %78 \"selector_5\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFunction %1 %5\n%18 = OpConstant %5 0\n%19 = OpTypePointer StorageBuffer %5\n%22 = OpConstant %5 1\n%24 = OpTypeFunction %5 %5\n%30 = OpTypePointer Function %5\n%33 = OpConstant %5 17\n%38 = OpConstant %5 18\n%43 = OpTypeBool\n%45 = OpConstant %5 20\n%48 = OpConstant %5 21\n%54 = OpConstant %5 32\n%55 = OpConstant %5 23\n%62 = OpConstant %5 99\n%63 = OpConstant %5 24\n%69 = OpConstant %5 30\n%72 = OpConstant %5 43\n%79 = OpConstantFalse %43\n%80 = OpConstantTrue %43\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%31 = OpVariable %30 Function\n%32 = OpVariable %30 Function\nOpBranch %81\n%81 = OpLabel\nOpStore %31 %18\nOpBranch %82\n%82 = OpLabel\nOpStore %32 %33\n%34 = OpLoad %5 %32\n%35 = OpFunctionCall %1 %16 %34\n%36 = OpLoad %5 %31\n%37 = OpIAdd %5 %36 %22\nOpStore %31 %37\nOpLoopMerge %90 %89 None\nOpBranch %83\n%83 = OpLabel\nOpStore %32 %38\n%39 = OpLoad %5 %32\n%40 = OpFunctionCall %1 %16 %39\n%41 = OpLoad %5 %32\n%42 = OpFunctionCall %5 %26 %41\n%44 = OpIEqual %43 %42 %45\nOpSelectionMerge %84 None\nOpBranchConditional %44 %90 %84\n%84 = OpLabel\nOpStore %32 %48\n%49 = OpLoad %5 %32\n%50 = OpFunctionCall %1 %16 %49\n%51 = OpLoad %5 %32\n%52 = OpFunctionCall %5 %26 %51\n%53 = OpIEqual %43 %52 %54\nOpSelectionMerge %88 None\nOpBranchConditional %53 %88 %85\n%85 = OpLabel\nOpStore %32 %63\n%64 = OpLoad %5 %32\n%65 = OpFunctionCall %1 %16 %64\n%66 = OpLoad %5 %32\n%67 = OpFunctionCall %5 %26 %66\n%68 = OpIEqual %43 %67 %69\nOpSelectionMerge %86 None\nOpBranchConditional %68 %90 %86\n%86 = OpLabel\nOpStore %32 %72\n%73 = OpLoad %5 %32\n%74 = OpFunctionCall %1 %16 %73\n%75 = OpLoad %5 %32\n%76 = OpFunctionCall %5 %26 %75\n%77 = OpIEqual %43 %76 %69\nOpSelectionMerge %87 None\nOpBranchConditional %77 %90 %87\n%87 = OpLabel\nOpBranch %88\n%88 = OpLabel\nOpBranch %89\n%89 = OpLabel\nOpStore %32 %54\n%58 = OpLoad %5 %32\n%59 = OpFunctionCall %1 %16 %58\n%60 = OpLoad %5 %31\n%61 = OpSLessThan %43 %60 %62\nOpBranchConditional %61 %82 %90\n%90 = OpLabel\n%78 = OpPhi %43 %79 %83 %79 %89 %80 %85 %80 %86\nOpSelectionMerge %93 None\nOpBranchConditional %78 %91 %92\n%91 = OpLabel\nOpStore %32 %69\n%70 = OpLoad %5 %32\n%71 = OpFunctionCall %1 %16 %70\nOpBranch %93\n%92 = OpLabel\nOpStore %32 %45\n%46 = OpLoad %5 %32\n%47 = OpFunctionCall %1 %16 %46\nOpBranch %93\n%93 = OpLabel\nOpStore %32 %55\n%56 = OpLoad %5 %32\n%57 = OpFunctionCall %1 %16 %56\nOpReturn\nOpFunctionEnd\n%16 = OpFunction %1 None %14\n%15 = OpFunctionParameter %5\n%17 = OpLabel\nOpBranch %95\n%95 = OpLabel\n%20 = OpAccessChain %19 %9 %18 %18\n%21 = OpAtomicIAdd %5 %20 %22 %18 %22\n%23 = OpAccessChain %19 %9 %18 %21\nOpStore %23 %15\nOpReturn\nOpFunctionEnd\n%26 = OpFunction %5 None %24\n%25 = OpFunctionParameter %5\n%27 = OpLabel\nOpBranch %97\n%97 = OpLabel\n%28 = OpAccessChain %19 %13 %18 %25\n%29 = OpLoad %5 %28\nOpReturnValue %29\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/asm/ibfe.bc.dxil",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[1];\n} _12;\n\nlayout(location = 0) out uvec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _20 = floatBitsToUint(_12._m0[0u]);\n    uint _26 = _20.y & 31u;\n    uint _31 = uint(bitfieldExtract(int(_20.z), int(_26), int(min((_20.x & 31u), (32u - _26)))));\n    SV_Target.x = _31;\n    SV_Target.y = _31;\n    SV_Target.z = _31;\n    SV_Target.w = _31;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\n%30 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeVector %5 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%16 = OpConstant %5 0\n%17 = OpTypePointer Uniform %8\n%25 = OpConstant %5 31\n%28 = OpConstant %5 32\n%32 = OpTypePointer Output %5\n%36 = OpConstant %5 2\n%38 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%18 = OpAccessChain %17 %12 %16 %16\n%19 = OpLoad %8 %18\n%20 = OpBitcast %13 %19\n%21 = OpCompositeExtract %5 %20 0\n%22 = OpCompositeExtract %5 %20 1\n%23 = OpCompositeExtract %5 %20 2\n%24 = OpBitwiseAnd %5 %21 %25\n%26 = OpBitwiseAnd %5 %22 %25\n%27 = OpISub %5 %28 %26\n%29 = OpExtInst %5 %30 UMin %24 %27\n%31 = OpBitFieldSExtract %5 %23 %26 %29\n%33 = OpAccessChain %32 %15 %16\nOpStore %33 %31\n%34 = OpAccessChain %32 %15 %6\nOpStore %34 %31\n%35 = OpAccessChain %32 %15 %36\nOpStore %35 %31\n%37 = OpAccessChain %32 %15 %38\nOpStore %37 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/asm/ubfe.bc.dxil",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[1];\n} _12;\n\nlayout(location = 0) out uvec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _20 = floatBitsToUint(_12._m0[0u]);\n    uint _26 = _20.y & 31u;\n    uint _31 = bitfieldExtract(_20.z, int(_26), int(min((_20.x & 31u), (32u - _26))));\n    SV_Target.x = _31;\n    SV_Target.y = _31;\n    SV_Target.z = _31;\n    SV_Target.w = _31;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\n%30 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeVector %5 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%16 = OpConstant %5 0\n%17 = OpTypePointer Uniform %8\n%25 = OpConstant %5 31\n%28 = OpConstant %5 32\n%32 = OpTypePointer Output %5\n%36 = OpConstant %5 2\n%38 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%18 = OpAccessChain %17 %12 %16 %16\n%19 = OpLoad %8 %18\n%20 = OpBitcast %13 %19\n%21 = OpCompositeExtract %5 %20 0\n%22 = OpCompositeExtract %5 %20 1\n%23 = OpCompositeExtract %5 %20 2\n%24 = OpBitwiseAnd %5 %21 %25\n%26 = OpBitwiseAnd %5 %22 %25\n%27 = OpISub %5 %28 %26\n%29 = OpExtInst %5 %30 UMin %24 %27\n%31 = OpBitFieldUExtract %5 %23 %26 %29\n%33 = OpAccessChain %32 %15 %16\nOpStore %33 %31\n%34 = OpAccessChain %32 %15 %6\nOpStore %34 %31\n%35 = OpAccessChain %32 %15 %36\nOpStore %35 %31\n%37 = OpAccessChain %32 %15 %38\nOpStore %37 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/auto-barrier/complex-loop.auto-group-shared-barrier.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared uint _12[32];\n\nvoid main()\n{\n    uint _34;\n    uint _17 = 0u;\n    for (;;)\n    {\n        subgroupMemoryBarrierShared();\n        subgroupBarrier();\n        _12[gl_LocalInvocationIndex] = 40u;\n        subgroupMemoryBarrierShared();\n        subgroupBarrier();\n        imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 31u]));\n        imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 15u]));\n        _34 = 0u;\n        for (;;)\n        {\n            subgroupMemoryBarrierShared();\n            subgroupBarrier();\n            uint _36 = atomicAdd(_12[gl_LocalInvocationIndex], 1u);\n            uint _39 = atomicOr(_12[gl_LocalInvocationIndex], _36);\n            uint _40 = atomicXor(_12[gl_LocalInvocationIndex], _39);\n            uint _35 = _34 + 1u;\n            if (_35 == 4u)\n            {\n                break;\n            }\n            else\n            {\n                _34 = _35;\n            }\n        }\n        uint _19 = _17 + 1u;\n        if (_19 == 4u)\n        {\n            break;\n        }\n        else\n        {\n            _17 = _19;\n            continue;\n        }\n    }\n}\n\n/* WARNINGS:\n- Has group shared access, but no group shared barrier anywhere.\n*/\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %15\nOpExecutionMode %3 LocalSize 32 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %15 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 32\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%18 = OpConstant %5 0\n%20 = OpTypePointer Workgroup %5\n%22 = OpConstant %5 40\n%24 = OpConstant %5 31\n%27 = OpTypeVector %5 4\n%30 = OpConstant %5 15\n%37 = OpConstant %5 2\n%38 = OpConstant %5 1\n%41 = OpTypeBool\n%43 = OpConstant %5 4\n%51 = OpConstant %5 3\n%52 = OpConstant %5 264\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %45\n%45 = OpLabel\n%13 = OpLoad %6 %8\n%16 = OpLoad %5 %15\nOpBranch %46\n%46 = OpLabel\n%17 = OpPhi %5 %18 %45 %19 %49\nOpControlBarrier %51 %51 %52\n%21 = OpAccessChain %20 %12 %16\nOpStore %21 %22\n%23 = OpBitwiseXor %5 %16 %24\n%25 = OpAccessChain %20 %12 %23\nOpControlBarrier %51 %51 %52\n%26 = OpLoad %5 %25\n%28 = OpCompositeConstruct %27 %26 %26 %26 %26\nOpImageWrite %13 %16 %28\n%29 = OpBitwiseXor %5 %16 %30\n%31 = OpAccessChain %20 %12 %29\n%32 = OpLoad %5 %31\n%33 = OpCompositeConstruct %27 %32 %32 %32 %32\nOpImageWrite %13 %16 %33\nOpLoopMerge %50 %49 None\nOpBranch %47\n%47 = OpLabel\n%34 = OpPhi %5 %18 %46 %35 %47\nOpControlBarrier %51 %51 %52\n%36 = OpAtomicIAdd %5 %21 %37 %18 %38\n%39 = OpAtomicOr %5 %21 %37 %18 %36\n%40 = OpAtomicXor %5 %21 %37 %18 %39\n%35 = OpIAdd %5 %34 %38\n%42 = OpIEqual %41 %35 %43\nOpLoopMerge %48 %47 None\nOpBranchConditional %42 %48 %47\n%48 = OpLabel\nOpBranch %49\n%49 = OpLabel\n%19 = OpIAdd %5 %17 %38\n%44 = OpIEqual %41 %19 %43\nOpBranchConditional %44 %50 %46\n%50 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/auto-barrier/inner-to-inner.auto-group-shared-barrier.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform readonly uimageBuffer _9;\n\nshared uint _13[32];\n\nvoid main()\n{\n    bool _20 = gl_LocalInvocationIndex < 16u;\n    if (_20)\n    {\n        _13[gl_LocalInvocationIndex] = imageLoad(_8, int(gl_LocalInvocationIndex + 1024u)).x;\n    }\n    else\n    {\n        _13[gl_LocalInvocationIndex ^ 1u] = imageLoad(_9, int(gl_LocalInvocationIndex + 1024u)).x;\n    }\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    if (_20)\n    {\n        if (imageLoad(_8, int(gl_LocalInvocationIndex)).x == 50u)\n        {\n            imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_13[gl_LocalInvocationIndex ^ 31u]));\n        }\n    }\n}\n\n/* WARNINGS:\n- Has group shared access, but no group shared barrier anywhere.\n*/\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17\nOpExecutionMode %3 LocalSize 32 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonWritable\nOpDecorate %17 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpConstant %5 32\n%11 = OpTypeArray %5 %10\n%12 = OpTypePointer Workgroup %11\n%13 = OpVariable %12 Workgroup\n%16 = OpTypePointer Input %5\n%17 = OpVariable %16 Input\n%19 = OpTypeBool\n%21 = OpConstant %5 16\n%23 = OpConstant %5 1024\n%25 = OpTypeVector %5 4\n%28 = OpTypePointer Workgroup %5\n%34 = OpConstant %5 1\n%39 = OpConstant %5 50\n%41 = OpConstant %5 31\n%53 = OpConstant %5 3\n%54 = OpConstant %5 264\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %45\n%45 = OpLabel\n%14 = OpLoad %6 %9\n%15 = OpLoad %6 %8\n%18 = OpLoad %5 %17\n%20 = OpULessThan %19 %18 %21\n%22 = OpIAdd %5 %18 %23\nOpSelectionMerge %48 None\nOpBranchConditional %20 %47 %46\n%47 = OpLabel\n%24 = OpIAdd %5 %18 %23\n%26 = OpImageRead %25 %15 %24\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpAccessChain %28 %13 %18\nOpStore %29 %27\nOpBranch %48\n%46 = OpLabel\n%30 = OpIAdd %5 %18 %23\n%31 = OpImageRead %25 %14 %30\n%32 = OpCompositeExtract %5 %31 0\n%33 = OpBitwiseXor %5 %18 %34\n%35 = OpAccessChain %28 %13 %33\nOpStore %35 %32\nOpBranch %48\n%48 = OpLabel\nOpControlBarrier %53 %53 %54\nOpSelectionMerge %52 None\nOpBranchConditional %20 %49 %52\n%49 = OpLabel\n%36 = OpImageRead %25 %15 %18\n%37 = OpCompositeExtract %5 %36 0\n%38 = OpIEqual %19 %37 %39\nOpSelectionMerge %51 None\nOpBranchConditional %38 %50 %51\n%50 = OpLabel\n%40 = OpBitwiseXor %5 %18 %41\n%42 = OpAccessChain %28 %13 %40\n%43 = OpLoad %5 %42\n%44 = OpCompositeConstruct %25 %43 %43 %43 %43\nOpImageWrite %15 %18 %44\nOpBranch %51\n%51 = OpLabel\nOpBranch %52\n%52 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/auto-barrier/inner-to-outer.auto-group-shared-barrier.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nshared uint _10;\n\nvoid main()\n{\n    if (gl_LocalInvocationIndex < 16u)\n    {\n        if (imageLoad(_8, int(gl_LocalInvocationIndex)).x == 50u)\n        {\n            _10 = 50u;\n        }\n    }\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_10));\n}\n\n/* WARNINGS:\n- Has group shared access, but no group shared barrier anywhere.\n*/\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %13\nOpExecutionMode %3 LocalSize 32 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypePointer Workgroup %5\n%10 = OpVariable %9 Workgroup\n%12 = OpTypePointer Input %5\n%13 = OpVariable %12 Input\n%15 = OpTypeBool\n%17 = OpConstant %5 16\n%18 = OpTypeVector %5 4\n%22 = OpConstant %5 50\n%30 = OpConstant %5 3\n%31 = OpConstant %5 264\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%11 = OpLoad %6 %8\n%14 = OpLoad %5 %13\n%16 = OpULessThan %15 %14 %17\nOpSelectionMerge %29 None\nOpBranchConditional %16 %26 %29\n%26 = OpLabel\n%19 = OpImageRead %18 %11 %14\n%20 = OpCompositeExtract %5 %19 0\n%21 = OpIEqual %15 %20 %22\nOpSelectionMerge %28 None\nOpBranchConditional %21 %27 %28\n%27 = OpLabel\nOpStore %10 %22\nOpBranch %28\n%28 = OpLabel\nOpBranch %29\n%29 = OpLabel\nOpControlBarrier %30 %30 %31\n%23 = OpLoad %5 %10\n%24 = OpCompositeConstruct %18 %23 %23 %23 %23\nOpImageWrite %11 %14 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/auto-barrier/outer-to-inner.auto-group-shared-barrier.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nshared uint _12[32];\n\nvoid main()\n{\n    _12[gl_LocalInvocationIndex] = imageLoad(_8, int(gl_LocalInvocationIndex + 1024u)).x;\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    if (gl_LocalInvocationIndex < 16u)\n    {\n        if (imageLoad(_8, int(gl_LocalInvocationIndex)).x == 50u)\n        {\n            imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 31u]));\n        }\n    }\n}\n\n/* WARNINGS:\n- Has group shared access, but no group shared barrier anywhere.\n*/\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %15\nOpExecutionMode %3 LocalSize 32 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %15 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 32\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%18 = OpConstant %5 1024\n%20 = OpTypeVector %5 4\n%23 = OpTypePointer Workgroup %5\n%25 = OpTypeBool\n%27 = OpConstant %5 16\n%31 = OpConstant %5 50\n%33 = OpConstant %5 31\n%42 = OpConstant %5 3\n%43 = OpConstant %5 264\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%13 = OpLoad %6 %8\n%16 = OpLoad %5 %15\n%17 = OpIAdd %5 %16 %18\n%19 = OpIAdd %5 %16 %18\n%21 = OpImageRead %20 %13 %19\n%22 = OpCompositeExtract %5 %21 0\n%24 = OpAccessChain %23 %12 %16\nOpStore %24 %22\n%26 = OpULessThan %25 %16 %27\nOpControlBarrier %42 %42 %43\nOpSelectionMerge %41 None\nOpBranchConditional %26 %38 %41\n%38 = OpLabel\n%28 = OpImageRead %20 %13 %16\n%29 = OpCompositeExtract %5 %28 0\n%30 = OpIEqual %25 %29 %31\nOpSelectionMerge %40 None\nOpBranchConditional %30 %39 %40\n%39 = OpLabel\n%32 = OpBitwiseXor %5 %16 %33\n%34 = OpAccessChain %23 %12 %32\n%35 = OpLoad %5 %34\n%36 = OpCompositeConstruct %20 %35 %35 %35 %35\nOpImageWrite %13 %16 %36\nOpBranch %40\n%40 = OpLabel\nOpBranch %41\n%41 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/auto-barrier/single-block-loop.auto-group-shared-barrier.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared uint _12[32];\n\nvoid main()\n{\n    uint _17;\n    _17 = 0u;\n    for (;;)\n    {\n        _12[gl_LocalInvocationIndex] = 40u;\n        subgroupMemoryBarrierShared();\n        subgroupBarrier();\n        imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 31u]));\n        imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 15u]));\n        subgroupMemoryBarrierShared();\n        subgroupBarrier();\n        uint _34 = atomicAdd(_12[gl_LocalInvocationIndex], 1u);\n        uint _37 = atomicOr(_12[gl_LocalInvocationIndex], 1u);\n        uint _38 = atomicXor(_12[gl_LocalInvocationIndex], 1u);\n        uint _19 = _17 + 1u;\n        subgroupMemoryBarrierShared();\n        subgroupBarrier();\n        if (_19 == 4u)\n        {\n            break;\n        }\n        else\n        {\n            _17 = _19;\n        }\n    }\n}\n\n/* WARNINGS:\n- Has group shared access, but no group shared barrier anywhere.\n*/\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %15\nOpExecutionMode %3 LocalSize 32 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %15 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 32\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%18 = OpConstant %5 0\n%20 = OpTypePointer Workgroup %5\n%22 = OpConstant %5 40\n%24 = OpConstant %5 31\n%27 = OpTypeVector %5 4\n%30 = OpConstant %5 15\n%35 = OpConstant %5 2\n%36 = OpConstant %5 1\n%39 = OpTypeBool\n%41 = OpConstant %5 4\n%45 = OpConstant %5 3\n%46 = OpConstant %5 264\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%13 = OpLoad %6 %8\n%16 = OpLoad %5 %15\nOpBranch %43\n%43 = OpLabel\n%17 = OpPhi %5 %18 %42 %19 %43\n%21 = OpAccessChain %20 %12 %16\nOpStore %21 %22\n%23 = OpBitwiseXor %5 %16 %24\n%25 = OpAccessChain %20 %12 %23\nOpControlBarrier %45 %45 %46\n%26 = OpLoad %5 %25\n%28 = OpCompositeConstruct %27 %26 %26 %26 %26\nOpImageWrite %13 %16 %28\n%29 = OpBitwiseXor %5 %16 %30\n%31 = OpAccessChain %20 %12 %29\n%32 = OpLoad %5 %31\n%33 = OpCompositeConstruct %27 %32 %32 %32 %32\nOpImageWrite %13 %16 %33\nOpControlBarrier %45 %45 %46\n%34 = OpAtomicIAdd %5 %21 %35 %18 %36\n%37 = OpAtomicOr %5 %21 %35 %18 %36\n%38 = OpAtomicXor %5 %21 %35 %18 %36\n%19 = OpIAdd %5 %17 %36\n%40 = OpIEqual %39 %19 %41\nOpControlBarrier %45 %45 %46\nOpLoopMerge %44 %43 None\nOpBranchConditional %40 %44 %43\n%44 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/auto-barrier/single-block.auto-group-shared-barrier.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared uint _12[32];\n\nvoid main()\n{\n    _12[gl_LocalInvocationIndex] = 40u;\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 31u]));\n    imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 15u]));\n    subgroupMemoryBarrierShared();\n    subgroupBarrier();\n    uint _31 = atomicAdd(_12[gl_LocalInvocationIndex], 1u);\n    uint _35 = atomicOr(_12[gl_LocalInvocationIndex], 1u);\n    uint _36 = atomicXor(_12[gl_LocalInvocationIndex], 1u);\n}\n\n/* WARNINGS:\n- Has group shared access, but no group shared barrier anywhere.\n*/\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %15\nOpExecutionMode %3 LocalSize 32 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %15 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 32\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer Workgroup %5\n%19 = OpConstant %5 40\n%21 = OpConstant %5 31\n%24 = OpTypeVector %5 4\n%27 = OpConstant %5 15\n%32 = OpConstant %5 2\n%33 = OpConstant %5 0\n%34 = OpConstant %5 1\n%38 = OpConstant %5 3\n%39 = OpConstant %5 264\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%13 = OpLoad %6 %8\n%16 = OpLoad %5 %15\n%18 = OpAccessChain %17 %12 %16\nOpStore %18 %19\n%20 = OpBitwiseXor %5 %16 %21\n%22 = OpAccessChain %17 %12 %20\nOpControlBarrier %38 %38 %39\n%23 = OpLoad %5 %22\n%25 = OpCompositeConstruct %24 %23 %23 %23 %23\nOpImageWrite %13 %16 %25\n%26 = OpBitwiseXor %5 %16 %27\n%28 = OpAccessChain %17 %12 %26\n%29 = OpLoad %5 %28\n%30 = OpCompositeConstruct %24 %29 %29 %29 %29\nOpImageWrite %13 %16 %30\nOpControlBarrier %38 %38 %39\n%31 = OpAtomicIAdd %5 %18 %32 %33 %34\n%35 = OpAtomicOr %5 %18 %32 %33 %34\n%36 = OpAtomicXor %5 %18 %32 %33 %34\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/branch-return-2.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _37;\n    uint _16;\n    uint _19;\n    uint _22;\n    bool _24;\n    for (;;)\n    {\n        _16 = gl_GlobalInvocationID.x;\n        _19 = gl_GlobalInvocationID.y;\n        _22 = gl_GlobalInvocationID.z;\n        _24 = _16 == 10u;\n        uint _31;\n        if (_24)\n        {\n            if (_22 == 40u)\n            {\n                _37 = _19 * 10u;\n                break;\n            }\n            _31 = 20u;\n        }\n        else\n        {\n            uint frontier_phi_4_2_ladder;\n            if (_19 == 20u)\n            {\n                if (_22 == 50u)\n                {\n                    _37 = _16 * 24u;\n                    break;\n                }\n                uint frontier_phi_4_2_ladder_5_ladder;\n                uint _42;\n                bool _43;\n                for (;;)\n                {\n                    _42 = _16 + 10u;\n                    _43 = _16 == 0u;\n                    uint _46;\n                    if (_43)\n                    {\n                        if (_22 == 30u)\n                        {\n                            frontier_phi_4_2_ladder_5_ladder = _42 * 30u;\n                            break;\n                        }\n                        _46 = _42;\n                    }\n                    else\n                    {\n                        _46 = 0u;\n                    }\n                    frontier_phi_4_2_ladder_5_ladder = _46 + _42;\n                    break;\n                }\n                frontier_phi_4_2_ladder = frontier_phi_4_2_ladder_5_ladder;\n            }\n            else\n            {\n                frontier_phi_4_2_ladder = 0u;\n            }\n            _31 = frontier_phi_4_2_ladder;\n        }\n        _37 = _31 + _16;\n        break;\n    }\n    imageStore(_8, int(0u), uvec4(_37));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 70\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %47 \"frontier_phi_4.2.ladder.5.ladder\"\nOpName %48 \"frontier_phi_4.2.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeBool\n%25 = OpConstant %5 10\n%27 = OpConstant %5 40\n%29 = OpConstant %5 20\n%36 = OpConstant %5 50\n%39 = OpTypeVector %5 4\n%41 = OpConstant %5 24\n%45 = OpConstant %5 30\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %49\n%49 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%24 = OpIEqual %23 %16 %25\nOpLoopMerge %66 %67 None\nOpBranch %50\n%50 = OpLabel\nOpSelectionMerge %64 None\nOpBranchConditional %24 %62 %51\n%62 = OpLabel\n%26 = OpIEqual %23 %22 %27\nOpSelectionMerge %63 None\nOpBranchConditional %26 %65 %63\n%65 = OpLabel\n%30 = OpIMul %5 %19 %25\nOpBranch %66\n%63 = OpLabel\nOpBranch %64\n%51 = OpLabel\n%28 = OpIEqual %23 %19 %29\nOpSelectionMerge %60 None\nOpBranchConditional %28 %52 %60\n%52 = OpLabel\n%35 = OpIEqual %23 %22 %36\nOpSelectionMerge %53 None\nOpBranchConditional %35 %61 %53\n%61 = OpLabel\n%38 = OpIMul %5 %16 %41\nOpBranch %66\n%53 = OpLabel\n%42 = OpIAdd %5 %16 %25\n%43 = OpIEqual %23 %16 %15\nOpLoopMerge %59 %68 None\nOpBranch %54\n%54 = OpLabel\nOpSelectionMerge %57 None\nOpBranchConditional %43 %55 %57\n%55 = OpLabel\n%44 = OpIEqual %23 %22 %45\nOpSelectionMerge %56 None\nOpBranchConditional %44 %58 %56\n%58 = OpLabel\n%32 = OpIMul %5 %42 %45\nOpBranch %59\n%56 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%46 = OpPhi %5 %15 %54 %42 %56\n%33 = OpIAdd %5 %46 %42\nOpBranch %59\n%68 = OpLabel\nOpBranch %53\n%59 = OpLabel\n%47 = OpPhi %5 %32 %58 %33 %57\nOpBranch %60\n%60 = OpLabel\n%48 = OpPhi %5 %15 %51 %47 %59\nOpBranch %64\n%64 = OpLabel\n%31 = OpPhi %5 %29 %63 %48 %60\n%34 = OpIAdd %5 %31 %16\nOpBranch %66\n%67 = OpLabel\nOpBranch %49\n%66 = OpLabel\n%37 = OpPhi %5 %30 %65 %34 %64 %38 %61\n%40 = OpCompositeConstruct %39 %37 %37 %37 %37\nOpImageWrite %9 %15 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/branch-return.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _35;\n    uint _16;\n    uint _19;\n    uint _22;\n    bool _24;\n    for (;;)\n    {\n        _16 = gl_GlobalInvocationID.x;\n        _19 = gl_GlobalInvocationID.y;\n        _22 = gl_GlobalInvocationID.z;\n        _24 = _16 == 10u;\n        uint _31;\n        if (_24)\n        {\n            if (_22 == 40u)\n            {\n                _35 = _19 * 10u;\n                break;\n            }\n            _31 = _19;\n        }\n        else\n        {\n            uint frontier_phi_4_2_ladder;\n            if (_19 == 20u)\n            {\n                if (_22 == 50u)\n                {\n                    _35 = _16 * 24u;\n                    break;\n                }\n                frontier_phi_4_2_ladder = _22;\n            }\n            else\n            {\n                frontier_phi_4_2_ladder = 0u;\n            }\n            _31 = frontier_phi_4_2_ladder;\n        }\n        _35 = _31 + _16;\n        break;\n    }\n    imageStore(_8, int(0u), uvec4(_35));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %40 \"frontier_phi_4.2.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeBool\n%25 = OpConstant %5 10\n%27 = OpConstant %5 40\n%29 = OpConstant %5 20\n%34 = OpConstant %5 50\n%37 = OpTypeVector %5 4\n%39 = OpConstant %5 24\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%24 = OpIEqual %23 %16 %25\nOpLoopMerge %52 %53 None\nOpBranch %42\n%42 = OpLabel\nOpSelectionMerge %50 None\nOpBranchConditional %24 %48 %43\n%48 = OpLabel\n%26 = OpIEqual %23 %22 %27\nOpSelectionMerge %49 None\nOpBranchConditional %26 %51 %49\n%51 = OpLabel\n%30 = OpIMul %5 %19 %25\nOpBranch %52\n%49 = OpLabel\nOpBranch %50\n%43 = OpLabel\n%28 = OpIEqual %23 %19 %29\nOpSelectionMerge %46 None\nOpBranchConditional %28 %44 %46\n%44 = OpLabel\n%33 = OpIEqual %23 %22 %34\nOpSelectionMerge %45 None\nOpBranchConditional %33 %47 %45\n%47 = OpLabel\n%36 = OpIMul %5 %16 %39\nOpBranch %52\n%45 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%40 = OpPhi %5 %15 %43 %22 %45\nOpBranch %50\n%50 = OpLabel\n%31 = OpPhi %5 %19 %49 %40 %46\n%32 = OpIAdd %5 %31 %16\nOpBranch %52\n%53 = OpLabel\nOpBranch %41\n%52 = OpLabel\n%35 = OpPhi %5 %30 %51 %32 %50 %36 %47\n%38 = OpCompositeConstruct %37 %35 %35 %35 %35\nOpImageWrite %9 %15 %38\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/branch.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _23;\n    if (gl_GlobalInvocationID.x == 10u)\n    {\n        _23 = 40u;\n    }\n    else\n    {\n        _23 = 50u;\n    }\n    uint _36;\n    if (gl_GlobalInvocationID.x == 20u)\n    {\n        uint frontier_phi_9_3_ladder;\n        if (gl_GlobalInvocationID.y == 30u)\n        {\n            frontier_phi_9_3_ladder = _23 + 20u;\n        }\n        else\n        {\n            frontier_phi_9_3_ladder = _23 * _23;\n        }\n        _36 = frontier_phi_9_3_ladder;\n    }\n    else\n    {\n        uint frontier_phi_9_4_ladder;\n        if (gl_GlobalInvocationID.y == 40u)\n        {\n            frontier_phi_9_4_ladder = _23 + 70u;\n        }\n        else\n        {\n            frontier_phi_9_4_ladder = _23 * 10u;\n        }\n        _36 = frontier_phi_9_4_ladder;\n    }\n    imageStore(_8, int(0u), uvec4(_36));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %39 \"frontier_phi_9.4.ladder\"\nOpName %40 \"frontier_phi_9.3.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%20 = OpTypeBool\n%22 = OpConstant %5 10\n%24 = OpConstant %5 50\n%25 = OpConstant %5 40\n%27 = OpConstant %5 20\n%29 = OpConstant %5 30\n%34 = OpConstant %5 70\n%37 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%21 = OpIEqual %20 %16 %22\nOpSelectionMerge %43 None\nOpBranchConditional %21 %43 %42\n%42 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%23 = OpPhi %5 %25 %41 %24 %42\n%26 = OpIEqual %20 %16 %27\nOpSelectionMerge %52 None\nOpBranchConditional %26 %48 %44\n%48 = OpLabel\n%28 = OpIEqual %20 %19 %29\nOpSelectionMerge %51 None\nOpBranchConditional %28 %50 %49\n%50 = OpLabel\n%31 = OpIAdd %5 %23 %27\nOpBranch %51\n%49 = OpLabel\n%32 = OpIMul %5 %23 %23\nOpBranch %51\n%51 = OpLabel\n%40 = OpPhi %5 %31 %50 %32 %49\nOpBranch %52\n%44 = OpLabel\n%30 = OpIEqual %20 %19 %25\nOpSelectionMerge %47 None\nOpBranchConditional %30 %46 %45\n%46 = OpLabel\n%33 = OpIAdd %5 %23 %34\nOpBranch %47\n%45 = OpLabel\n%35 = OpIMul %5 %23 %22\nOpBranch %47\n%47 = OpLabel\n%39 = OpPhi %5 %33 %46 %35 %45\nOpBranch %52\n%52 = OpLabel\n%36 = OpPhi %5 %40 %51 %39 %47\n%38 = OpCompositeConstruct %37 %36 %36 %36 %36\nOpImageWrite %9 %15 %38\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/conditional-break-into-if-else-if-ladder-2.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _24;\n    if ((gl_GlobalInvocationID.x & 1u) == 0u)\n    {\n        _24 = 0u;\n    }\n    else\n    {\n        uint frontier_phi_3_2_ladder;\n        if ((gl_GlobalInvocationID.x & 2u) == 0u)\n        {\n            uint frontier_phi_3_2_ladder_4_ladder;\n            if ((gl_GlobalInvocationID.x & 4u) == 0u)\n            {\n                uint frontier_phi_3_2_ladder_4_ladder_5_ladder;\n                if ((gl_GlobalInvocationID.x & 8u) == 0u)\n                {\n                    uint frontier_phi_3_2_ladder_4_ladder_5_ladder_6_ladder;\n                    if ((gl_GlobalInvocationID.x & 16u) == 0u)\n                    {\n                        frontier_phi_3_2_ladder_4_ladder_5_ladder_6_ladder = 0u;\n                    }\n                    else\n                    {\n                        frontier_phi_3_2_ladder_4_ladder_5_ladder_6_ladder = 50u;\n                    }\n                    frontier_phi_3_2_ladder_4_ladder_5_ladder = frontier_phi_3_2_ladder_4_ladder_5_ladder_6_ladder;\n                }\n                else\n                {\n                    frontier_phi_3_2_ladder_4_ladder_5_ladder = 40u;\n                }\n                frontier_phi_3_2_ladder_4_ladder = frontier_phi_3_2_ladder_4_ladder_5_ladder;\n            }\n            else\n            {\n                frontier_phi_3_2_ladder_4_ladder = 30u;\n            }\n            frontier_phi_3_2_ladder = frontier_phi_3_2_ladder_4_ladder;\n        }\n        else\n        {\n            frontier_phi_3_2_ladder = 60u;\n        }\n        _24 = frontier_phi_3_2_ladder;\n    }\n    imageStore(_8, int(0u), uvec4(_24));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 57\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %40 \"frontier_phi_3.2.ladder.4.ladder.5.ladder.6.ladder\"\nOpName %41 \"frontier_phi_3.2.ladder.4.ladder.5.ladder\"\nOpName %42 \"frontier_phi_3.2.ladder.4.ladder\"\nOpName %43 \"frontier_phi_3.2.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%19 = OpTypeBool\n%22 = OpConstant %5 2\n%25 = OpConstant %5 60\n%26 = OpConstant %5 30\n%27 = OpConstant %5 40\n%28 = OpConstant %5 50\n%29 = OpTypeVector %5 4\n%32 = OpConstant %5 4\n%35 = OpConstant %5 8\n%38 = OpConstant %5 16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpBitwiseAnd %5 %16 %18\n%20 = OpIEqual %19 %17 %15\nOpSelectionMerge %55 None\nOpBranchConditional %20 %54 %45\n%54 = OpLabel\nOpBranch %55\n%45 = OpLabel\n%21 = OpBitwiseAnd %5 %16 %22\n%23 = OpIEqual %19 %21 %15\nOpSelectionMerge %53 None\nOpBranchConditional %23 %46 %53\n%46 = OpLabel\n%31 = OpBitwiseAnd %5 %16 %32\n%33 = OpIEqual %19 %31 %15\nOpSelectionMerge %52 None\nOpBranchConditional %33 %47 %52\n%47 = OpLabel\n%34 = OpBitwiseAnd %5 %16 %35\n%36 = OpIEqual %19 %34 %15\nOpSelectionMerge %51 None\nOpBranchConditional %36 %48 %51\n%48 = OpLabel\n%37 = OpBitwiseAnd %5 %16 %38\n%39 = OpIEqual %19 %37 %15\nOpSelectionMerge %50 None\nOpBranchConditional %39 %49 %50\n%49 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%40 = OpPhi %5 %15 %49 %28 %48\nOpBranch %51\n%51 = OpLabel\n%41 = OpPhi %5 %27 %47 %40 %50\nOpBranch %52\n%52 = OpLabel\n%42 = OpPhi %5 %26 %46 %41 %51\nOpBranch %53\n%53 = OpLabel\n%43 = OpPhi %5 %25 %45 %42 %52\nOpBranch %55\n%55 = OpLabel\n%24 = OpPhi %5 %15 %54 %43 %53\n%30 = OpCompositeConstruct %29 %24 %24 %24 %24\nOpImageWrite %9 %15 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/conditional-break-into-if-else-if-ladder.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _24;\n    if ((gl_GlobalInvocationID.x & 1u) == 0u)\n    {\n        _24 = 0u;\n    }\n    else\n    {\n        uint frontier_phi_3_2_ladder;\n        if ((gl_GlobalInvocationID.x & 2u) == 0u)\n        {\n            uint frontier_phi_3_2_ladder_4_ladder;\n            if ((gl_GlobalInvocationID.x & 4u) == 0u)\n            {\n                uint frontier_phi_3_2_ladder_4_ladder_6_ladder;\n                if ((gl_GlobalInvocationID.x & 8u) == 0u)\n                {\n                    uint frontier_phi_3_2_ladder_4_ladder_6_ladder_7_ladder;\n                    if ((gl_GlobalInvocationID.x & 16u) == 0u)\n                    {\n                        frontier_phi_3_2_ladder_4_ladder_6_ladder_7_ladder = 0u;\n                    }\n                    else\n                    {\n                        frontier_phi_3_2_ladder_4_ladder_6_ladder_7_ladder = 50u;\n                    }\n                    frontier_phi_3_2_ladder_4_ladder_6_ladder = frontier_phi_3_2_ladder_4_ladder_6_ladder_7_ladder;\n                }\n                else\n                {\n                    frontier_phi_3_2_ladder_4_ladder_6_ladder = 40u;\n                }\n                frontier_phi_3_2_ladder_4_ladder = frontier_phi_3_2_ladder_4_ladder_6_ladder;\n            }\n            else\n            {\n                frontier_phi_3_2_ladder_4_ladder = 30u;\n            }\n            frontier_phi_3_2_ladder = frontier_phi_3_2_ladder_4_ladder;\n        }\n        else\n        {\n            imageStore(_8, int(2u), uvec4(20u));\n            frontier_phi_3_2_ladder = 60u;\n        }\n        _24 = frontier_phi_3_2_ladder;\n    }\n    imageStore(_8, int(0u), uvec4(_24));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %42 \"frontier_phi_3.2.ladder.4.ladder.6.ladder.7.ladder\"\nOpName %43 \"frontier_phi_3.2.ladder.4.ladder.6.ladder\"\nOpName %44 \"frontier_phi_3.2.ladder.4.ladder\"\nOpName %45 \"frontier_phi_3.2.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%19 = OpTypeBool\n%22 = OpConstant %5 2\n%25 = OpConstant %5 60\n%26 = OpConstant %5 30\n%27 = OpConstant %5 40\n%28 = OpConstant %5 50\n%29 = OpTypeVector %5 4\n%32 = OpConstant %5 4\n%34 = OpConstant %5 20\n%37 = OpConstant %5 8\n%40 = OpConstant %5 16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpBitwiseAnd %5 %16 %18\n%20 = OpIEqual %19 %17 %15\nOpSelectionMerge %58 None\nOpBranchConditional %20 %57 %47\n%57 = OpLabel\nOpBranch %58\n%47 = OpLabel\n%21 = OpBitwiseAnd %5 %16 %22\n%23 = OpIEqual %19 %21 %15\nOpSelectionMerge %56 None\nOpBranchConditional %23 %49 %48\n%49 = OpLabel\n%31 = OpBitwiseAnd %5 %16 %32\n%33 = OpIEqual %19 %31 %15\nOpSelectionMerge %55 None\nOpBranchConditional %33 %50 %55\n%50 = OpLabel\n%36 = OpBitwiseAnd %5 %16 %37\n%38 = OpIEqual %19 %36 %15\nOpSelectionMerge %54 None\nOpBranchConditional %38 %51 %54\n%51 = OpLabel\n%39 = OpBitwiseAnd %5 %16 %40\n%41 = OpIEqual %19 %39 %15\nOpSelectionMerge %53 None\nOpBranchConditional %41 %52 %53\n%52 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%42 = OpPhi %5 %15 %52 %28 %51\nOpBranch %54\n%54 = OpLabel\n%43 = OpPhi %5 %27 %50 %42 %53\nOpBranch %55\n%55 = OpLabel\n%44 = OpPhi %5 %26 %49 %43 %54\nOpBranch %56\n%48 = OpLabel\n%35 = OpCompositeConstruct %29 %34 %34 %34 %34\nOpImageWrite %9 %22 %35\nOpBranch %56\n%56 = OpLabel\n%45 = OpPhi %5 %25 %48 %44 %55\nOpBranch %58\n%58 = OpLabel\n%24 = OpPhi %5 %15 %57 %45 %56\n%30 = OpCompositeConstruct %29 %24 %24 %24 %24\nOpImageWrite %9 %15 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/dual-inner-loop-early-return.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nuint _50;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _23;\n    uint _25;\n    uint _37;\n    for (;;)\n    {\n        _23 = 0u;\n        _25 = gl_GlobalInvocationID.y;\n        uint _27;\n        uint _29;\n        bool ladder_phi_8;\n        uint frontier_phi_7_pred_pred;\n        uint frontier_phi_7_pred_pred_1;\n        for (;;)\n        {\n            _27 = 0u;\n            _29 = _25;\n            bool ladder_phi_7_pred;\n            bool _31;\n            for (;;)\n            {\n                _31 = _29 < 10u;\n                if (_31)\n                {\n                    ladder_phi_7_pred = true;\n                    frontier_phi_7_pred_pred = gl_GlobalInvocationID.y;\n                    frontier_phi_7_pred_pred_1 = 50u;\n                    break;\n                }\n                else\n                {\n                    if (!(gl_GlobalInvocationID.z < 10u))\n                    {\n                        uint _26 = _29 + 1u;\n                        uint _28 = _27 + 1u;\n                        if (int(_28) < int(20u))\n                        {\n                            _27 = _28;\n                            _29 = _26;\n                            continue;\n                        }\n                        else\n                        {\n                            ladder_phi_7_pred = false;\n                            frontier_phi_7_pred_pred = _26;\n                            frontier_phi_7_pred_pred_1 = _50;\n                            break;\n                        }\n                    }\n                    ladder_phi_7_pred = true;\n                    frontier_phi_7_pred_pred = gl_GlobalInvocationID.y;\n                    frontier_phi_7_pred_pred_1 = 70u;\n                    break;\n                }\n            }\n            if (ladder_phi_7_pred)\n            {\n                ladder_phi_8 = true;\n                break;\n            }\n            uint _24 = _23 + 1u;\n            if (int(_24) < int(10u))\n            {\n                _23 = _24;\n                _25 = frontier_phi_7_pred_pred;\n                continue;\n            }\n            else\n            {\n                ladder_phi_8 = false;\n                break;\n            }\n        }\n        if (ladder_phi_8)\n        {\n            _37 = frontier_phi_7_pred_pred_1;\n            break;\n        }\n        _37 = 80u;\n        break;\n    }\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(_37));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 70\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %44 \"ladder_phi_7.pred\"\nOpName %47 \"ladder_phi_8\"\nOpName %48 \"frontier_phi_7.pred.pred\"\nOpName %49 \"frontier_phi_7.pred.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%30 = OpTypeBool\n%32 = OpConstant %5 10\n%34 = OpConstant %5 70\n%35 = OpConstant %5 50\n%38 = OpConstant %5 80\n%39 = OpTypeVector %5 4\n%42 = OpConstant %5 20\n%45 = OpConstantFalse %30\n%46 = OpConstantTrue %30\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%50 = OpUndef %5\nOpBranch %51\n%51 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\nOpBranch %52\n%52 = OpLabel\nOpLoopMerge %65 %66 None\nOpBranch %53\n%53 = OpLabel\n%23 = OpPhi %5 %15 %52 %24 %62\n%25 = OpPhi %5 %19 %52 %48 %62\nOpLoopMerge %63 %62 None\nOpBranch %54\n%54 = OpLabel\n%27 = OpPhi %5 %15 %53 %28 %57\n%29 = OpPhi %5 %25 %53 %26 %57\n%31 = OpULessThan %30 %29 %32\nOpLoopMerge %60 %57 None\nOpBranch %67\n%67 = OpLabel\nOpSelectionMerge %68 None\nOpBranchConditional %31 %59 %55\n%59 = OpLabel\nOpBranch %60\n%55 = OpLabel\n%36 = OpULessThan %30 %22 %32\nOpSelectionMerge %58 None\nOpBranchConditional %36 %58 %56\n%56 = OpLabel\nOpBranch %57\n%58 = OpLabel\nOpBranch %60\n%68 = OpLabel\nOpUnreachable\n%57 = OpLabel\n%26 = OpIAdd %5 %29 %18\n%28 = OpIAdd %5 %27 %18\n%41 = OpSLessThan %30 %28 %42\nOpBranchConditional %41 %54 %60\n%60 = OpLabel\n%44 = OpPhi %30 %45 %57 %46 %59 %46 %58\n%48 = OpPhi %5 %26 %57 %19 %59 %19 %58\n%49 = OpPhi %5 %50 %57 %35 %59 %34 %58\nOpSelectionMerge %61 None\nOpBranchConditional %44 %63 %61\n%61 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%24 = OpIAdd %5 %23 %18\n%43 = OpSLessThan %30 %24 %32\nOpBranchConditional %43 %53 %63\n%63 = OpLabel\n%47 = OpPhi %30 %45 %62 %46 %60\nOpSelectionMerge %64 None\nOpBranchConditional %47 %65 %64\n%64 = OpLabel\nOpBranch %65\n%66 = OpLabel\nOpBranch %52\n%65 = OpLabel\n%37 = OpPhi %5 %38 %64 %49 %63\n%40 = OpCompositeConstruct %39 %37 %37 %37 %37\nOpImageWrite %9 %16 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/if-else-if-into-continue.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    if (!(gl_GlobalInvocationID.x == 0u))\n    {\n        uint _25 = 0u;\n        uint _27 = gl_GlobalInvocationID.x;\n        uint _29 = gl_GlobalInvocationID.y;\n        uint _31 = gl_GlobalInvocationID.z;\n        bool _33;\n        for (;;)\n        {\n            _33 = _31 < 10u;\n            if (_33)\n            {\n                imageStore(_8, int(_29), uvec4(20u));\n            }\n            else\n            {\n                if (_29 < 5u)\n                {\n                    imageStore(_8, int(_31), uvec4(40u));\n                }\n            }\n            uint _28 = _27 + 1u;\n            uint _26 = _25 + 1u;\n            if (_26 < _28)\n            {\n                _25 = _26;\n                _27 = _28;\n                _29++;\n                _31++;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeBool\n%20 = OpConstant %5 2\n%23 = OpConstant %5 1\n%34 = OpConstant %5 10\n%35 = OpConstant %5 20\n%36 = OpTypeVector %5 4\n%39 = OpConstant %5 5\n%41 = OpConstant %5 40\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpIEqual %17 %16 %15\nOpSelectionMerge %54 None\nOpBranchConditional %18 %54 %44\n%44 = OpLabel\n%19 = OpAccessChain %13 %12 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %13 %12 %23\n%24 = OpLoad %5 %22\nOpBranch %45\n%45 = OpLabel\n%25 = OpPhi %5 %15 %44 %26 %52\n%27 = OpPhi %5 %16 %44 %28 %52\n%29 = OpPhi %5 %24 %44 %30 %52\n%31 = OpPhi %5 %21 %44 %32 %52\n%33 = OpULessThan %17 %31 %34\nOpLoopMerge %53 %52 None\nOpBranch %46\n%46 = OpLabel\nOpSelectionMerge %51 None\nOpBranchConditional %33 %50 %47\n%50 = OpLabel\n%37 = OpCompositeConstruct %36 %35 %35 %35 %35\nOpImageWrite %9 %29 %37\nOpBranch %51\n%47 = OpLabel\n%38 = OpULessThan %17 %29 %39\nOpSelectionMerge %49 None\nOpBranchConditional %38 %48 %49\n%48 = OpLabel\n%42 = OpCompositeConstruct %36 %41 %41 %41 %41\nOpImageWrite %9 %31 %42\nOpBranch %49\n%49 = OpLabel\nOpBranch %51\n%51 = OpLabel\nOpBranch %52\n%52 = OpLabel\n%28 = OpIAdd %5 %27 %23\n%30 = OpIAdd %5 %29 %23\n%32 = OpIAdd %5 %31 %23\n%26 = OpIAdd %5 %25 %23\n%40 = OpULessThan %17 %26 %28\nOpBranchConditional %40 %45 %53\n%53 = OpLabel\nOpBranch %54\n%54 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/inner-loop-early-return.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nuint _41;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _20;\n    uint _30;\n    for (;;)\n    {\n        _20 = 0u;\n        uint _22;\n        bool ladder_phi_7;\n        uint frontier_phi_6_pred_pred;\n        for (;;)\n        {\n            _22 = 0u;\n            bool ladder_phi_6_pred;\n            bool _25;\n            for (;;)\n            {\n                _25 = gl_GlobalInvocationID.z < 10u;\n                if (_25)\n                {\n                    ladder_phi_6_pred = true;\n                    frontier_phi_6_pred_pred = 70u;\n                    break;\n                }\n                else\n                {\n                    uint _23 = _22 + 1u;\n                    if (int(_23) < int(20u))\n                    {\n                        _22 = _23;\n                        continue;\n                    }\n                    else\n                    {\n                        ladder_phi_6_pred = false;\n                        frontier_phi_6_pred_pred = _41;\n                        break;\n                    }\n                }\n            }\n            if (ladder_phi_6_pred)\n            {\n                ladder_phi_7 = true;\n                break;\n            }\n            uint _21 = _20 + 1u;\n            if (int(_21) < int(10u))\n            {\n                _20 = _21;\n                continue;\n            }\n            else\n            {\n                ladder_phi_7 = false;\n                break;\n            }\n        }\n        if (ladder_phi_7)\n        {\n            _30 = frontier_phi_6_pred_pred;\n            break;\n        }\n        _30 = 80u;\n        break;\n    }\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(_30));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %36 \"ladder_phi_6.pred\"\nOpName %39 \"ladder_phi_7\"\nOpName %40 \"frontier_phi_6.pred.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 2\n%24 = OpTypeBool\n%26 = OpConstant %5 10\n%27 = OpConstant %5 1\n%29 = OpConstant %5 20\n%31 = OpConstant %5 70\n%32 = OpConstant %5 80\n%33 = OpTypeVector %5 4\n%37 = OpConstantFalse %24\n%38 = OpConstantTrue %24\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%41 = OpUndef %5\nOpBranch %42\n%42 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\nOpBranch %43\n%43 = OpLabel\nOpLoopMerge %54 %55 None\nOpBranch %44\n%44 = OpLabel\n%20 = OpPhi %5 %15 %43 %21 %51\nOpLoopMerge %52 %51 None\nOpBranch %45\n%45 = OpLabel\n%22 = OpPhi %5 %15 %44 %23 %47\n%25 = OpULessThan %24 %19 %26\nOpLoopMerge %49 %47 None\nOpBranch %56\n%56 = OpLabel\nOpSelectionMerge %57 None\nOpBranchConditional %25 %48 %46\n%48 = OpLabel\nOpBranch %49\n%46 = OpLabel\nOpBranch %47\n%57 = OpLabel\nOpUnreachable\n%47 = OpLabel\n%23 = OpIAdd %5 %22 %27\n%28 = OpSLessThan %24 %23 %29\nOpBranchConditional %28 %45 %49\n%49 = OpLabel\n%36 = OpPhi %24 %37 %47 %38 %48\n%40 = OpPhi %5 %41 %47 %31 %48\nOpSelectionMerge %50 None\nOpBranchConditional %36 %52 %50\n%50 = OpLabel\nOpBranch %51\n%51 = OpLabel\n%21 = OpIAdd %5 %20 %27\n%35 = OpSLessThan %24 %21 %26\nOpBranchConditional %35 %44 %52\n%52 = OpLabel\n%39 = OpPhi %24 %37 %51 %38 %49\nOpSelectionMerge %53 None\nOpBranchConditional %39 %54 %53\n%53 = OpLabel\nOpBranch %54\n%55 = OpLabel\nOpBranch %43\n%54 = OpLabel\n%30 = OpPhi %5 %32 %53 %40 %52\n%34 = OpCompositeConstruct %33 %30 %30 %30 %30\nOpImageWrite %9 %16 %34\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/interleaved-unrolled-loop-breaks.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nuint _75;\nuint _77;\nuint _78;\nuint _80;\nuint _81;\nuint _82;\nuint _83;\nuint _84;\nuint _85;\nuint _86;\nuint _87;\nuint _88;\nuint _89;\nuint _90;\nuint _92;\nuint _93;\nuint _94;\nuint _95;\nuint _96;\nuint _97;\nuint _98;\nuint _99;\nuint _100;\nuint _101;\nuint _102;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    int selector_5;\n    uint frontier_phi_5_pred;\n    uint frontier_phi_5_pred_1;\n    uint frontier_phi_5_pred_2;\n    uint frontier_phi_5_pred_3;\n    uint frontier_phi_5_pred_4;\n    uint _13;\n    for (;;)\n    {\n        _13 = imageAtomicAdd(_8, int(0u), 1u);\n        if ((_13 & 13u) == 0u)\n        {\n            if (!((_13 & 1u) == 0u))\n            {\n                selector_5 = 1;\n                frontier_phi_5_pred = _13;\n                frontier_phi_5_pred_1 = _13;\n                frontier_phi_5_pred_2 = _77;\n                frontier_phi_5_pred_3 = _86;\n                frontier_phi_5_pred_4 = _98;\n                break;\n            }\n            if (!((_13 & 2u) == 0u))\n            {\n                selector_5 = 0;\n                frontier_phi_5_pred = _13;\n                frontier_phi_5_pred_1 = _13;\n                frontier_phi_5_pred_2 = _13;\n                frontier_phi_5_pred_3 = _82;\n                frontier_phi_5_pred_4 = _94;\n                break;\n            }\n            uint _22 = imageAtomicAdd(_8, int(0u), _13);\n            if (!((_22 & 13u) == 0u))\n            {\n                selector_5 = 2;\n                frontier_phi_5_pred = _22;\n                frontier_phi_5_pred_1 = _13;\n                frontier_phi_5_pred_2 = _13;\n                frontier_phi_5_pred_3 = _89;\n                frontier_phi_5_pred_4 = _101;\n                break;\n            }\n            if (!((_22 & 1u) == 0u))\n            {\n                selector_5 = 1;\n                frontier_phi_5_pred = _22;\n                frontier_phi_5_pred_1 = _22;\n                frontier_phi_5_pred_2 = _13;\n                frontier_phi_5_pred_3 = _85;\n                frontier_phi_5_pred_4 = _97;\n                break;\n            }\n            if (!((_22 & 2u) == 0u))\n            {\n                selector_5 = 0;\n                frontier_phi_5_pred = _22;\n                frontier_phi_5_pred_1 = _22;\n                frontier_phi_5_pred_2 = _22;\n                frontier_phi_5_pred_3 = _81;\n                frontier_phi_5_pred_4 = _93;\n                break;\n            }\n            uint _23 = imageAtomicAdd(_8, int(0u), _22);\n            if (!((_23 & 13u) == 0u))\n            {\n                selector_5 = 2;\n                frontier_phi_5_pred = _23;\n                frontier_phi_5_pred_1 = _22;\n                frontier_phi_5_pred_2 = _22;\n                frontier_phi_5_pred_3 = _88;\n                frontier_phi_5_pred_4 = _100;\n                break;\n            }\n            if (!((_23 & 1u) == 0u))\n            {\n                selector_5 = 1;\n                frontier_phi_5_pred = _23;\n                frontier_phi_5_pred_1 = _23;\n                frontier_phi_5_pred_2 = _22;\n                frontier_phi_5_pred_3 = _84;\n                frontier_phi_5_pred_4 = _96;\n                break;\n            }\n            if (!((_23 & 2u) == 0u))\n            {\n                selector_5 = 0;\n                frontier_phi_5_pred = _23;\n                frontier_phi_5_pred_1 = _23;\n                frontier_phi_5_pred_2 = _23;\n                frontier_phi_5_pred_3 = _80;\n                frontier_phi_5_pred_4 = _92;\n                break;\n            }\n            uint _24 = imageAtomicAdd(_8, int(0u), _23);\n            if (!((_24 & 13u) == 0u))\n            {\n                selector_5 = 2;\n                frontier_phi_5_pred = _24;\n                frontier_phi_5_pred_1 = _23;\n                frontier_phi_5_pred_2 = _23;\n                frontier_phi_5_pred_3 = _87;\n                frontier_phi_5_pred_4 = _99;\n                break;\n            }\n            if (!((_24 & 1u) == 0u))\n            {\n                selector_5 = 1;\n                frontier_phi_5_pred = _24;\n                frontier_phi_5_pred_1 = _24;\n                frontier_phi_5_pred_2 = _23;\n                frontier_phi_5_pred_3 = _83;\n                frontier_phi_5_pred_4 = _95;\n                break;\n            }\n            if ((_24 & 2u) == 0u)\n            {\n                selector_5 = -1;\n                frontier_phi_5_pred = _24;\n                frontier_phi_5_pred_1 = _24;\n                frontier_phi_5_pred_2 = _24;\n                frontier_phi_5_pred_3 = 0u;\n                frontier_phi_5_pred_4 = _24;\n                break;\n            }\n            selector_5 = 0;\n            frontier_phi_5_pred = _24;\n            frontier_phi_5_pred_1 = _24;\n            frontier_phi_5_pred_2 = _24;\n            frontier_phi_5_pred_3 = 0u;\n            frontier_phi_5_pred_4 = _24;\n            break;\n        }\n        else\n        {\n            selector_5 = 2;\n            frontier_phi_5_pred = _13;\n            frontier_phi_5_pred_1 = _75;\n            frontier_phi_5_pred_2 = _78;\n            frontier_phi_5_pred_3 = _90;\n            frontier_phi_5_pred_4 = _102;\n            break;\n        }\n    }\n    uint _21 = frontier_phi_5_pred;\n    uint _30 = frontier_phi_5_pred_1;\n    uint _46 = frontier_phi_5_pred_2;\n    uint _34;\n    uint _36;\n    switch (selector_5)\n    {\n        case 0:\n        {\n            uint _37 = imageAtomicOr(_8, int(0u), _46);\n            _34 = 3u;\n            _36 = _37;\n            break;\n        }\n        case 1:\n        {\n            if ((_30 & 4u) == 0u)\n            {\n                _34 = 2u;\n                _36 = _30;\n                break;\n            }\n            uint _38 = imageAtomicOr(_8, int(0u), _30);\n            _34 = 2u;\n            _36 = _38;\n            break;\n        }\n        case 2:\n        {\n            uint _26 = imageAtomicAdd(_8, int(0u), _21);\n            _34 = 1u;\n            _36 = _26;\n            break;\n        }\n        default:\n        {\n            _34 = frontier_phi_5_pred_3;\n            _36 = frontier_phi_5_pred_4;\n            break;\n        }\n    }\n    uint _40 = imageAtomicAdd(_8, int(0u), _36);\n    uint _42 = imageAtomicAdd(_8, int(0u), _34);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 124\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %67 \"selector_5\"\nOpName %73 \"frontier_phi_5.pred\"\nOpName %74 \"frontier_phi_5.pred\"\nOpName %76 \"frontier_phi_5.pred\"\nOpName %79 \"frontier_phi_5.pred\"\nOpName %91 \"frontier_phi_5.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpConstant %5 0\n%11 = OpTypePointer Image %5\n%14 = OpConstant %5 1\n%16 = OpConstant %5 13\n%17 = OpTypeBool\n%28 = OpConstant %5 2\n%32 = OpConstant %5 4\n%35 = OpConstant %5 3\n%68 = OpTypeInt 32 1\n%69 = OpConstant %68 -1\n%70 = OpConstant %68 0\n%71 = OpConstant %68 1\n%72 = OpConstant %68 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%75 = OpUndef %5\n%77 = OpUndef %5\n%78 = OpUndef %5\n%80 = OpUndef %5\n%81 = OpUndef %5\n%82 = OpUndef %5\n%83 = OpUndef %5\n%84 = OpUndef %5\n%85 = OpUndef %5\n%86 = OpUndef %5\n%87 = OpUndef %5\n%88 = OpUndef %5\n%89 = OpUndef %5\n%90 = OpUndef %5\n%92 = OpUndef %5\n%93 = OpUndef %5\n%94 = OpUndef %5\n%95 = OpUndef %5\n%96 = OpUndef %5\n%97 = OpUndef %5\n%98 = OpUndef %5\n%99 = OpUndef %5\n%100 = OpUndef %5\n%101 = OpUndef %5\n%102 = OpUndef %5\nOpBranch %103\n%103 = OpLabel\n%9 = OpLoad %6 %8\n%12 = OpImageTexelPointer %11 %8 %10 %10\n%13 = OpAtomicIAdd %5 %12 %14 %10 %14\n%15 = OpBitwiseAnd %5 %13 %16\n%18 = OpIEqual %17 %15 %10\nOpLoopMerge %116 %122 None\nOpBranchConditional %18 %104 %116\n%104 = OpLabel\n%19 = OpBitwiseAnd %5 %13 %14\n%20 = OpIEqual %17 %19 %10\nOpSelectionMerge %105 None\nOpBranchConditional %20 %105 %116\n%105 = OpLabel\n%27 = OpBitwiseAnd %5 %13 %28\n%29 = OpIEqual %17 %27 %10\nOpSelectionMerge %106 None\nOpBranchConditional %29 %106 %116\n%106 = OpLabel\n%43 = OpImageTexelPointer %11 %8 %10 %10\n%22 = OpAtomicIAdd %5 %43 %14 %10 %13\n%44 = OpBitwiseAnd %5 %22 %16\n%45 = OpIEqual %17 %44 %10\nOpSelectionMerge %107 None\nOpBranchConditional %45 %107 %116\n%107 = OpLabel\n%49 = OpBitwiseAnd %5 %22 %14\n%50 = OpIEqual %17 %49 %10\nOpSelectionMerge %108 None\nOpBranchConditional %50 %108 %116\n%108 = OpLabel\n%51 = OpBitwiseAnd %5 %22 %28\n%52 = OpIEqual %17 %51 %10\nOpSelectionMerge %109 None\nOpBranchConditional %52 %109 %116\n%109 = OpLabel\n%53 = OpImageTexelPointer %11 %8 %10 %10\n%23 = OpAtomicIAdd %5 %53 %14 %10 %22\n%54 = OpBitwiseAnd %5 %23 %16\n%55 = OpIEqual %17 %54 %10\nOpSelectionMerge %110 None\nOpBranchConditional %55 %110 %116\n%110 = OpLabel\n%56 = OpBitwiseAnd %5 %23 %14\n%57 = OpIEqual %17 %56 %10\nOpSelectionMerge %111 None\nOpBranchConditional %57 %111 %116\n%111 = OpLabel\n%58 = OpBitwiseAnd %5 %23 %28\n%59 = OpIEqual %17 %58 %10\nOpSelectionMerge %112 None\nOpBranchConditional %59 %112 %116\n%112 = OpLabel\n%60 = OpImageTexelPointer %11 %8 %10 %10\n%24 = OpAtomicIAdd %5 %60 %14 %10 %23\n%61 = OpBitwiseAnd %5 %24 %16\n%62 = OpIEqual %17 %61 %10\nOpSelectionMerge %113 None\nOpBranchConditional %62 %113 %116\n%113 = OpLabel\n%63 = OpBitwiseAnd %5 %24 %14\n%64 = OpIEqual %17 %63 %10\nOpSelectionMerge %114 None\nOpBranchConditional %64 %114 %116\n%114 = OpLabel\n%65 = OpBitwiseAnd %5 %24 %28\n%66 = OpIEqual %17 %65 %10\nOpSelectionMerge %115 None\nOpBranchConditional %66 %116 %115\n%115 = OpLabel\nOpBranch %116\n%122 = OpLabel\nOpBranch %103\n%116 = OpLabel\n%67 = OpPhi %68 %69 %114 %70 %115 %70 %111 %70 %108 %70 %105 %71 %113 %71 %110 %71 %107 %71 %104 %72 %112 %72 %109 %72 %106 %72 %103\n%73 = OpPhi %5 %24 %114 %24 %115 %23 %111 %22 %108 %13 %105 %24 %113 %23 %110 %22 %107 %13 %104 %24 %112 %23 %109 %22 %106 %13 %103\n%74 = OpPhi %5 %24 %114 %24 %115 %23 %111 %22 %108 %13 %105 %24 %113 %23 %110 %22 %107 %13 %104 %23 %112 %22 %109 %13 %106 %75 %103\n%76 = OpPhi %5 %24 %114 %24 %115 %23 %111 %22 %108 %13 %105 %23 %113 %22 %110 %13 %107 %77 %104 %23 %112 %22 %109 %13 %106 %78 %103\n%79 = OpPhi %5 %10 %114 %10 %115 %80 %111 %81 %108 %82 %105 %83 %113 %84 %110 %85 %107 %86 %104 %87 %112 %88 %109 %89 %106 %90 %103\n%91 = OpPhi %5 %24 %114 %24 %115 %92 %111 %93 %108 %94 %105 %95 %113 %96 %110 %97 %107 %98 %104 %99 %112 %100 %109 %101 %106 %102 %103\n%21 = OpCopyObject %5 %73\n%30 = OpCopyObject %5 %74\n%46 = OpCopyObject %5 %76\nOpSelectionMerge %121 None\nOpSwitch %67 %121 0 %120 1 %118 2 %117\n%120 = OpLabel\n%47 = OpImageTexelPointer %11 %8 %10 %10\n%37 = OpAtomicOr %5 %47 %14 %10 %46\nOpBranch %121\n%118 = OpLabel\n%31 = OpBitwiseAnd %5 %30 %32\n%33 = OpIEqual %17 %31 %10\nOpSelectionMerge %119 None\nOpBranchConditional %33 %121 %119\n%119 = OpLabel\n%48 = OpImageTexelPointer %11 %8 %10 %10\n%38 = OpAtomicOr %5 %48 %14 %10 %30\nOpBranch %121\n%117 = OpLabel\n%25 = OpImageTexelPointer %11 %8 %10 %10\n%26 = OpAtomicIAdd %5 %25 %14 %10 %21\nOpBranch %121\n%121 = OpLabel\n%34 = OpPhi %5 %35 %120 %28 %118 %28 %119 %14 %117 %79 %116\n%36 = OpPhi %5 %37 %120 %30 %118 %38 %119 %26 %117 %91 %116\n%39 = OpImageTexelPointer %11 %8 %10 %10\n%40 = OpAtomicIAdd %5 %39 %14 %10 %36\n%41 = OpImageTexelPointer %11 %8 %10 %10\n%42 = OpAtomicIAdd %5 %41 %14 %10 %34\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-break-2.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _20;\n    if (gl_GlobalInvocationID.z == 0u)\n    {\n        _20 = 0u;\n    }\n    else\n    {\n        uint frontier_phi_6;\n        uint _25 = 0u;\n        uint _26 = 0u;\n        uint _30;\n        bool _31;\n        for (;;)\n        {\n            _30 = imageLoad(_8, int(_26)).x;\n            _31 = _30 == 30u;\n            if (_31)\n            {\n                frontier_phi_6 = imageLoad(_8, int(25u)).x + _25;\n                break;\n            }\n            else\n            {\n                uint _22 = _30 + _25;\n                uint _27 = _26 + 1u;\n                if (_27 < gl_GlobalInvocationID.z)\n                {\n                    _25 = _22;\n                    _26 = _27;\n                    continue;\n                }\n                else\n                {\n                    frontier_phi_6 = _22;\n                    break;\n                }\n            }\n        }\n        _20 = frontier_phi_6;\n    }\n    imageStore(_8, int(0u), uvec4(_20));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 50\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %38 \"frontier_phi_6\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 2\n%17 = OpTypeBool\n%19 = OpConstant %5 0\n%23 = OpTypeVector %5 4\n%32 = OpConstant %5 30\n%33 = OpConstant %5 25\n%36 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpIEqual %17 %16 %19\nOpSelectionMerge %46 None\nOpBranchConditional %18 %46 %40\n%40 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%25 = OpPhi %5 %19 %40 %22 %43\n%26 = OpPhi %5 %19 %40 %27 %43\n%28 = OpShiftLeftLogical %5 %26 %15\n%29 = OpImageRead %23 %9 %26\n%30 = OpCompositeExtract %5 %29 0\n%31 = OpIEqual %17 %30 %32\nOpLoopMerge %45 %43 None\nOpBranch %47\n%47 = OpLabel\nOpSelectionMerge %48 None\nOpBranchConditional %31 %44 %42\n%44 = OpLabel\n%34 = OpImageRead %23 %9 %33\n%35 = OpCompositeExtract %5 %34 0\n%21 = OpIAdd %5 %35 %25\nOpBranch %45\n%42 = OpLabel\nOpBranch %43\n%48 = OpLabel\nOpUnreachable\n%43 = OpLabel\n%22 = OpIAdd %5 %30 %25\n%27 = OpIAdd %5 %26 %36\n%37 = OpULessThan %17 %27 %16\nOpBranchConditional %37 %41 %45\n%45 = OpLabel\n%38 = OpPhi %5 %22 %43 %21 %44\nOpBranch %46\n%46 = OpLabel\n%20 = OpPhi %5 %19 %39 %38 %45\n%24 = OpCompositeConstruct %23 %20 %20 %20 %20\nOpImageWrite %9 %19 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-break.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _20;\n    if (gl_GlobalInvocationID.z == 0u)\n    {\n        _20 = 0u;\n    }\n    else\n    {\n        uint _21;\n        uint _24 = 0u;\n        uint _26 = 0u;\n        uint _30;\n        for (;;)\n        {\n            _30 = imageLoad(_8, int(_26)).x;\n            if (_30 == 30u)\n            {\n                _21 = _24;\n                break;\n            }\n            else\n            {\n                uint _25 = _30 + _24;\n                uint _27 = _26 + 1u;\n                if (_27 < gl_GlobalInvocationID.z)\n                {\n                    _24 = _25;\n                    _26 = _27;\n                    continue;\n                }\n                else\n                {\n                    _21 = _25;\n                    break;\n                }\n            }\n        }\n        _20 = _21;\n    }\n    imageStore(_8, int(0u), uvec4(_20));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 2\n%17 = OpTypeBool\n%19 = OpConstant %5 0\n%22 = OpTypeVector %5 4\n%32 = OpConstant %5 30\n%33 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpIEqual %17 %16 %19\nOpSelectionMerge %41 None\nOpBranchConditional %18 %41 %36\n%36 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%24 = OpPhi %5 %19 %36 %25 %39\n%26 = OpPhi %5 %19 %36 %27 %39\n%28 = OpShiftLeftLogical %5 %26 %15\n%29 = OpImageRead %22 %9 %26\n%30 = OpCompositeExtract %5 %29 0\n%31 = OpIEqual %17 %30 %32\nOpLoopMerge %40 %39 None\nOpBranchConditional %31 %40 %38\n%38 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%25 = OpIAdd %5 %30 %24\n%27 = OpIAdd %5 %26 %33\n%34 = OpULessThan %17 %27 %16\nOpBranchConditional %34 %37 %40\n%40 = OpLabel\n%21 = OpPhi %5 %24 %37 %25 %39\nOpBranch %41\n%41 = OpLabel\n%20 = OpPhi %5 %19 %35 %21 %40\n%23 = OpCompositeConstruct %22 %20 %20 %20 %20\nOpImageWrite %9 %19 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-continue-2.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _22;\n    if (gl_GlobalInvocationID.x == 0u)\n    {\n        _22 = 0u;\n    }\n    else\n    {\n        uint _23;\n        uint _44;\n        uint _26 = 0u;\n        uint _27 = 0u;\n        bool _33;\n        for (;;)\n        {\n            _33 = imageLoad(_8, int(_27)).x == 40u;\n            uint frontier_phi_6_pred;\n            uint frontier_phi_6_pred_1;\n            for (;;)\n            {\n                uint _51;\n                if (_33)\n                {\n                    if (_27 == 10u)\n                    {\n                        frontier_phi_6_pred = _26;\n                        frontier_phi_6_pred_1 = gl_GlobalInvocationID.y;\n                        break;\n                    }\n                    _51 = imageLoad(_8, int(_27 * 4u)).x;\n                }\n                else\n                {\n                    _51 = imageLoad(_8, int(_27 * 3u)).x;\n                }\n                frontier_phi_6_pred = (_51 + _26) + imageLoad(_8, int(_27 * 2u)).x;\n                frontier_phi_6_pred_1 = 1u;\n                break;\n            }\n            _23 = frontier_phi_6_pred;\n            _44 = frontier_phi_6_pred_1;\n            uint _28 = _44 + _27;\n            if (_28 < gl_GlobalInvocationID.x)\n            {\n                _26 = _23;\n                _27 = _28;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n        _22 = _23;\n    }\n    imageStore(_8, int(0u), uvec4(_22));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 74\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %57 \"frontier_phi_6.pred\"\nOpName %58 \"frontier_phi_6.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%20 = OpTypeBool\n%24 = OpTypeVector %5 4\n%30 = OpConstant %5 2\n%34 = OpConstant %5 40\n%36 = OpConstant %5 10\n%38 = OpConstant %5 12\n%40 = OpConstant %5 3\n%47 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%21 = OpIEqual %20 %16 %15\nOpSelectionMerge %71 None\nOpBranchConditional %21 %71 %60\n%60 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%26 = OpPhi %5 %15 %60 %23 %69\n%27 = OpPhi %5 %15 %60 %28 %69\n%29 = OpShiftLeftLogical %5 %27 %30\n%31 = OpImageRead %24 %9 %27\n%32 = OpCompositeExtract %5 %31 0\n%33 = OpIEqual %20 %32 %34\nOpLoopMerge %70 %69 None\nOpBranch %62\n%62 = OpLabel\nOpLoopMerge %68 %72 None\nOpBranch %63\n%63 = OpLabel\nOpSelectionMerge %67 None\nOpBranchConditional %33 %65 %64\n%65 = OpLabel\n%35 = OpIEqual %20 %27 %36\nOpSelectionMerge %66 None\nOpBranchConditional %35 %68 %66\n%66 = OpLabel\n%46 = OpShiftLeftLogical %5 %27 %47\n%48 = OpIMul %5 %27 %47\n%49 = OpImageRead %24 %9 %48\n%50 = OpCompositeExtract %5 %49 0\nOpBranch %67\n%64 = OpLabel\n%37 = OpIMul %5 %27 %38\n%39 = OpIMul %5 %27 %40\n%41 = OpImageRead %24 %9 %39\n%42 = OpCompositeExtract %5 %41 0\nOpBranch %67\n%67 = OpLabel\n%51 = OpPhi %5 %42 %64 %50 %66\n%52 = OpIAdd %5 %51 %26\n%53 = OpShiftLeftLogical %5 %27 %40\n%54 = OpIMul %5 %27 %30\n%55 = OpImageRead %24 %9 %54\n%56 = OpCompositeExtract %5 %55 0\n%43 = OpIAdd %5 %52 %56\nOpBranch %68\n%72 = OpLabel\nOpBranch %62\n%68 = OpLabel\n%57 = OpPhi %5 %26 %65 %43 %67\n%58 = OpPhi %5 %19 %65 %18 %67\n%23 = OpCopyObject %5 %57\n%44 = OpCopyObject %5 %58\nOpBranch %69\n%69 = OpLabel\n%28 = OpIAdd %5 %44 %27\n%45 = OpULessThan %20 %28 %16\nOpBranchConditional %45 %61 %70\n%70 = OpLabel\nOpBranch %71\n%71 = OpLabel\n%22 = OpPhi %5 %15 %59 %23 %70\n%25 = OpCompositeConstruct %24 %22 %22 %22 %22\nOpImageWrite %9 %15 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-continue-3.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _22;\n    if (gl_GlobalInvocationID.x == 0u)\n    {\n        _22 = 0u;\n    }\n    else\n    {\n        uint _23;\n        uint _28;\n        uint _26 = 0u;\n        uint _27 = 0u;\n        bool _33;\n        for (;;)\n        {\n            _33 = imageLoad(_8, int(_27)).x == 40u;\n            uint frontier_phi_9_pred;\n            uint frontier_phi_9_pred_1;\n            for (;;)\n            {\n                uint _51;\n                if (_33)\n                {\n                    if (_27 == 10u)\n                    {\n                        imageStore(_8, int(640u), uvec4(10u));\n                        frontier_phi_9_pred = _26;\n                        frontier_phi_9_pred_1 = gl_GlobalInvocationID.y * 10u;\n                        break;\n                    }\n                    _51 = imageLoad(_8, int(_27 * 4u)).x;\n                }\n                else\n                {\n                    _51 = imageLoad(_8, int(_27 * 3u)).x;\n                }\n                frontier_phi_9_pred = (_51 + _26) + imageLoad(_8, int(_27 * 2u)).x;\n                frontier_phi_9_pred_1 = _27 + 1u;\n                break;\n            }\n            _23 = frontier_phi_9_pred;\n            _28 = frontier_phi_9_pred_1;\n            if (_28 < gl_GlobalInvocationID.x)\n            {\n                _26 = _23;\n                _27 = _28;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n        _22 = _23;\n    }\n    imageStore(_8, int(0u), uvec4(_22));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 78\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %60 \"frontier_phi_9.pred\"\nOpName %61 \"frontier_phi_9.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%20 = OpTypeBool\n%24 = OpTypeVector %5 4\n%30 = OpConstant %5 2\n%34 = OpConstant %5 40\n%36 = OpConstant %5 10\n%38 = OpConstant %5 12\n%40 = OpConstant %5 3\n%43 = OpConstant %5 640\n%47 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%21 = OpIEqual %20 %16 %15\nOpSelectionMerge %75 None\nOpBranchConditional %21 %75 %63\n%63 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%26 = OpPhi %5 %15 %63 %23 %73\n%27 = OpPhi %5 %15 %63 %28 %73\n%29 = OpShiftLeftLogical %5 %27 %30\n%31 = OpImageRead %24 %9 %27\n%32 = OpCompositeExtract %5 %31 0\n%33 = OpIEqual %20 %32 %34\nOpLoopMerge %74 %73 None\nOpBranch %65\n%65 = OpLabel\nOpLoopMerge %72 %76 None\nOpBranch %66\n%66 = OpLabel\nOpSelectionMerge %70 None\nOpBranchConditional %33 %68 %67\n%68 = OpLabel\n%35 = OpIEqual %20 %27 %36\nOpSelectionMerge %69 None\nOpBranchConditional %35 %71 %69\n%71 = OpLabel\n%44 = OpCompositeConstruct %24 %36 %36 %36 %36\nOpImageWrite %9 %43 %44\n%45 = OpIMul %5 %19 %36\nOpBranch %72\n%69 = OpLabel\n%46 = OpShiftLeftLogical %5 %27 %47\n%48 = OpIMul %5 %27 %47\n%49 = OpImageRead %24 %9 %48\n%50 = OpCompositeExtract %5 %49 0\nOpBranch %70\n%67 = OpLabel\n%37 = OpIMul %5 %27 %38\n%39 = OpIMul %5 %27 %40\n%41 = OpImageRead %24 %9 %39\n%42 = OpCompositeExtract %5 %41 0\nOpBranch %70\n%70 = OpLabel\n%51 = OpPhi %5 %42 %67 %50 %69\n%52 = OpIAdd %5 %51 %26\n%53 = OpShiftLeftLogical %5 %27 %40\n%54 = OpIMul %5 %27 %30\n%55 = OpImageRead %24 %9 %54\n%56 = OpCompositeExtract %5 %55 0\n%57 = OpIAdd %5 %52 %56\n%58 = OpIAdd %5 %27 %18\nOpBranch %72\n%76 = OpLabel\nOpBranch %65\n%72 = OpLabel\n%60 = OpPhi %5 %26 %71 %57 %70\n%61 = OpPhi %5 %45 %71 %58 %70\n%23 = OpCopyObject %5 %60\n%28 = OpCopyObject %5 %61\nOpBranch %73\n%73 = OpLabel\n%59 = OpULessThan %20 %28 %16\nOpBranchConditional %59 %64 %74\n%74 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%22 = OpPhi %5 %15 %62 %23 %74\n%25 = OpCompositeConstruct %24 %22 %22 %22 %22\nOpImageWrite %9 %15 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-continue.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _19;\n    if (gl_GlobalInvocationID.x == 0u)\n    {\n        _19 = 0u;\n    }\n    else\n    {\n        uint _20;\n        uint _23 = 0u;\n        uint _24 = 0u;\n        bool _30;\n        for (;;)\n        {\n            _30 = imageLoad(_8, int(_24)).x == 40u;\n            uint frontier_phi_6_pred;\n            for (;;)\n            {\n                uint _48;\n                if (_30)\n                {\n                    if (_24 == 10u)\n                    {\n                        frontier_phi_6_pred = _23;\n                        break;\n                    }\n                    _48 = imageLoad(_8, int(_24 * 4u)).x;\n                }\n                else\n                {\n                    _48 = imageLoad(_8, int(_24 * 3u)).x;\n                }\n                frontier_phi_6_pred = (_48 + _23) + imageLoad(_8, int(_24 * 2u)).x;\n                break;\n            }\n            _20 = frontier_phi_6_pred;\n            uint _25 = _24 + 1u;\n            if (_25 == gl_GlobalInvocationID.x)\n            {\n                break;\n            }\n            else\n            {\n                _23 = _20;\n                _24 = _25;\n                continue;\n            }\n        }\n        _19 = _20;\n    }\n    imageStore(_8, int(0u), uvec4(_19));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 70\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %54 \"frontier_phi_6.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeBool\n%21 = OpTypeVector %5 4\n%27 = OpConstant %5 2\n%31 = OpConstant %5 40\n%33 = OpConstant %5 10\n%35 = OpConstant %5 12\n%37 = OpConstant %5 3\n%41 = OpConstant %5 1\n%44 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %55\n%55 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpIEqual %17 %16 %15\nOpSelectionMerge %67 None\nOpBranchConditional %18 %67 %56\n%56 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%23 = OpPhi %5 %15 %56 %20 %65\n%24 = OpPhi %5 %15 %56 %25 %65\n%26 = OpShiftLeftLogical %5 %24 %27\n%28 = OpImageRead %21 %9 %24\n%29 = OpCompositeExtract %5 %28 0\n%30 = OpIEqual %17 %29 %31\nOpLoopMerge %66 %65 None\nOpBranch %58\n%58 = OpLabel\nOpLoopMerge %64 %68 None\nOpBranch %59\n%59 = OpLabel\nOpSelectionMerge %63 None\nOpBranchConditional %30 %61 %60\n%61 = OpLabel\n%32 = OpIEqual %17 %24 %33\nOpSelectionMerge %62 None\nOpBranchConditional %32 %64 %62\n%62 = OpLabel\n%43 = OpShiftLeftLogical %5 %24 %44\n%45 = OpIMul %5 %24 %44\n%46 = OpImageRead %21 %9 %45\n%47 = OpCompositeExtract %5 %46 0\nOpBranch %63\n%60 = OpLabel\n%34 = OpIMul %5 %24 %35\n%36 = OpIMul %5 %24 %37\n%38 = OpImageRead %21 %9 %36\n%39 = OpCompositeExtract %5 %38 0\nOpBranch %63\n%63 = OpLabel\n%48 = OpPhi %5 %39 %60 %47 %62\n%49 = OpIAdd %5 %48 %23\n%50 = OpShiftLeftLogical %5 %24 %37\n%51 = OpIMul %5 %24 %27\n%52 = OpImageRead %21 %9 %51\n%53 = OpCompositeExtract %5 %52 0\n%40 = OpIAdd %5 %49 %53\nOpBranch %64\n%68 = OpLabel\nOpBranch %58\n%64 = OpLabel\n%54 = OpPhi %5 %23 %61 %40 %63\n%20 = OpCopyObject %5 %54\nOpBranch %65\n%65 = OpLabel\n%25 = OpIAdd %5 %24 %41\n%42 = OpIEqual %17 %25 %16\nOpBranchConditional %42 %66 %57\n%66 = OpLabel\nOpBranch %67\n%67 = OpLabel\n%19 = OpPhi %5 %15 %55 %20 %66\n%22 = OpCompositeConstruct %21 %19 %19 %19 %19\nOpImageWrite %9 %15 %22\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-inside-infinite-loop-2.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nlayout(location = 0) flat in uvec4 V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _71;\n    uint _72;\n    uint _73;\n    uint _74;\n    if (V.x < 10u)\n    {\n        uint _36;\n        _36 = V.x;\n        bool _41;\n        for (;;)\n        {\n            uint _40 = imageAtomicAdd(_8, int(0u), _36);\n            _41 = V.y == 0u;\n            if (!_41)\n            {\n                uint _50 = _36 & 3u;\n                bool ladder_phi_16;\n                uint _54 = _50;\n                uint _55 = 0u;\n                for (;;)\n                {\n                    if (_54 == 0u)\n                    {\n                        if (!((_36 & 7u) == 0u))\n                        {\n                            ladder_phi_16 = false;\n                            break;\n                        }\n                        uint _69 = imageAtomicAdd(_8, int(0u), _36);\n                        uint _56 = _55 + 1u;\n                        if (_56 < V.y)\n                        {\n                            _54 = 0u;\n                            _55 = _56;\n                            continue;\n                        }\n                        else\n                        {\n                            ladder_phi_16 = false;\n                            break;\n                        }\n                    }\n                    else\n                    {\n                        ladder_phi_16 = true;\n                        break;\n                    }\n                }\n                if (ladder_phi_16)\n                {\n                    break;\n                }\n            }\n            uint _49 = imageAtomicAdd(_8, int(0u), _36);\n            _36++;\n            continue;\n        }\n        _71 = _36;\n        _72 = V.y;\n        _73 = V.z;\n        _74 = V.w;\n    }\n    else\n    {\n        uint _34 = ~V.y;\n        uint _42;\n        _42 = ~V.x;\n        bool _46;\n        for (;;)\n        {\n            uint _45 = imageAtomicAdd(_8, int(0u), _42);\n            _46 = V.y == 4294967295u;\n            if (!_46)\n            {\n                uint _53 = _42 & 3u;\n                bool ladder_phi_19;\n                uint _58 = _53;\n                uint _59 = 0u;\n                for (;;)\n                {\n                    if (_58 == 0u)\n                    {\n                        if (!((_42 & 7u) == 0u))\n                        {\n                            ladder_phi_19 = false;\n                            break;\n                        }\n                        uint _85 = imageAtomicAdd(_8, int(0u), _42);\n                        uint _60 = _59 + 1u;\n                        if (_60 < _34)\n                        {\n                            _58 = 0u;\n                            _59 = _60;\n                            continue;\n                        }\n                        else\n                        {\n                            ladder_phi_19 = false;\n                            break;\n                        }\n                    }\n                    else\n                    {\n                        ladder_phi_19 = true;\n                        break;\n                    }\n                }\n                if (ladder_phi_19)\n                {\n                    break;\n                }\n            }\n            uint _52 = imageAtomicAdd(_8, int(0u), _42);\n            _42++;\n            continue;\n        }\n        _71 = _42;\n        _72 = _34;\n        _73 = ~V.z;\n        _74 = ~V.w;\n    }\n    SV_Target.x = float(_71);\n    SV_Target.y = float(_72);\n    SV_Target.z = float(_73);\n    SV_Target.w = float(_74);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 120\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"V\"\nOpName %15 \"SV_Target\"\nOpName %87 \"ladder_phi_16\"\nOpName %90 \"ladder_phi_19\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 1\n%25 = OpConstant %5 2\n%28 = OpConstant %5 3\n%30 = OpTypeBool\n%32 = OpConstant %5 10\n%38 = OpTypePointer Image %5\n%47 = OpConstant %5 4294967295\n%63 = OpConstant %5 7\n%79 = OpTypePointer Output %12\n%88 = OpConstantFalse %30\n%89 = OpConstantTrue %30\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %91\n%91 = OpLabel\n%16 = OpLoad %6 %8\n%18 = OpAccessChain %17 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %17 %11 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %17 %11 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %17 %11 %28\n%29 = OpLoad %5 %27\n%31 = OpULessThan %30 %20 %32\nOpSelectionMerge %115 None\nOpBranchConditional %31 %105 %92\n%105 = OpLabel\nOpBranch %106\n%106 = OpLabel\n%36 = OpPhi %5 %20 %105 %37 %118\n%39 = OpImageTexelPointer %38 %8 %19 %19\n%40 = OpAtomicIAdd %5 %39 %22 %19 %36\n%41 = OpIEqual %30 %23 %19\nOpLoopMerge %114 %118 None\nOpBranch %107\n%107 = OpLabel\nOpSelectionMerge %117 None\nOpBranchConditional %41 %117 %108\n%108 = OpLabel\n%50 = OpBitwiseAnd %5 %36 %28\nOpBranch %109\n%109 = OpLabel\n%54 = OpPhi %5 %50 %108 %19 %112\n%55 = OpPhi %5 %19 %108 %56 %112\n%57 = OpIEqual %30 %54 %19\nOpLoopMerge %113 %112 None\nOpBranchConditional %57 %110 %113\n%110 = OpLabel\n%62 = OpBitwiseAnd %5 %36 %63\n%64 = OpIEqual %30 %62 %19\nOpSelectionMerge %111 None\nOpBranchConditional %64 %111 %113\n%111 = OpLabel\nOpBranch %112\n%112 = OpLabel\n%68 = OpImageTexelPointer %38 %8 %19 %19\n%69 = OpAtomicIAdd %5 %68 %22 %19 %36\n%56 = OpIAdd %5 %55 %22\n%70 = OpULessThan %30 %56 %23\nOpBranchConditional %70 %109 %113\n%113 = OpLabel\n%87 = OpPhi %30 %88 %110 %88 %112 %89 %109\nOpSelectionMerge %116 None\nOpBranchConditional %87 %114 %116\n%116 = OpLabel\nOpBranch %117\n%117 = OpLabel\nOpBranch %118\n%118 = OpLabel\n%48 = OpImageTexelPointer %38 %8 %19 %19\n%49 = OpAtomicIAdd %5 %48 %22 %19 %36\n%37 = OpIAdd %5 %36 %22\nOpBranch %106\n%114 = OpLabel\nOpBranch %115\n%92 = OpLabel\n%33 = OpNot %5 %20\n%34 = OpNot %5 %23\n%35 = OpNot %5 %26\nOpBranch %93\n%93 = OpLabel\n%42 = OpPhi %5 %33 %92 %43 %104\n%44 = OpImageTexelPointer %38 %8 %19 %19\n%45 = OpAtomicIAdd %5 %44 %22 %19 %42\n%46 = OpIEqual %30 %23 %47\nOpLoopMerge %101 %104 None\nOpBranch %94\n%94 = OpLabel\nOpSelectionMerge %103 None\nOpBranchConditional %46 %103 %95\n%95 = OpLabel\n%53 = OpBitwiseAnd %5 %42 %28\nOpBranch %96\n%96 = OpLabel\n%58 = OpPhi %5 %53 %95 %19 %99\n%59 = OpPhi %5 %19 %95 %60 %99\n%61 = OpIEqual %30 %58 %19\nOpLoopMerge %100 %99 None\nOpBranchConditional %61 %97 %100\n%97 = OpLabel\n%65 = OpBitwiseAnd %5 %42 %63\n%66 = OpIEqual %30 %65 %19\nOpSelectionMerge %98 None\nOpBranchConditional %66 %98 %100\n%98 = OpLabel\nOpBranch %99\n%99 = OpLabel\n%84 = OpImageTexelPointer %38 %8 %19 %19\n%85 = OpAtomicIAdd %5 %84 %22 %19 %42\n%60 = OpIAdd %5 %59 %22\n%86 = OpULessThan %30 %60 %34\nOpBranchConditional %86 %96 %100\n%100 = OpLabel\n%90 = OpPhi %30 %88 %97 %88 %99 %89 %96\nOpSelectionMerge %102 None\nOpBranchConditional %90 %101 %102\n%102 = OpLabel\nOpBranch %103\n%103 = OpLabel\nOpBranch %104\n%104 = OpLabel\n%51 = OpImageTexelPointer %38 %8 %19 %19\n%52 = OpAtomicIAdd %5 %51 %22 %19 %42\n%43 = OpIAdd %5 %42 %22\nOpBranch %93\n%101 = OpLabel\n%67 = OpNot %5 %29\nOpBranch %115\n%115 = OpLabel\n%71 = OpPhi %5 %36 %114 %42 %101\n%72 = OpPhi %5 %23 %114 %34 %101\n%73 = OpPhi %5 %26 %114 %35 %101\n%74 = OpPhi %5 %29 %114 %67 %101\n%75 = OpConvertUToF %12 %71\n%76 = OpConvertUToF %12 %72\n%77 = OpConvertUToF %12 %73\n%78 = OpConvertUToF %12 %74\n%80 = OpAccessChain %79 %15 %19\nOpStore %80 %75\n%81 = OpAccessChain %79 %15 %22\nOpStore %81 %76\n%82 = OpAccessChain %79 %15 %25\nOpStore %82 %77\n%83 = OpAccessChain %79 %15 %28\nOpStore %83 %78\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-inside-infinite-loop.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nlayout(location = 0) flat in uvec4 V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _33;\n    float _36;\n    float _38;\n    float _40;\n    if (V.x < 10u)\n    {\n        uint _47;\n        _47 = V.x;\n        bool _52;\n        for (;;)\n        {\n            uint _51 = imageAtomicAdd(_8, int(0u), _47);\n            _52 = V.y == 0u;\n            if (!_52)\n            {\n                uint _55 = _47 & 3u;\n                bool ladder_phi_10;\n                uint _56 = _55;\n                uint _57 = 0u;\n                for (;;)\n                {\n                    if (_56 == 0u)\n                    {\n                        if (!((_47 & 7u) == 0u))\n                        {\n                            ladder_phi_10 = false;\n                            break;\n                        }\n                        uint _64 = imageAtomicAdd(_8, int(0u), _47);\n                        uint _58 = _57 + 1u;\n                        if (_58 < V.y)\n                        {\n                            _56 = 0u;\n                            _57 = _58;\n                            continue;\n                        }\n                        else\n                        {\n                            ladder_phi_10 = false;\n                            break;\n                        }\n                    }\n                    else\n                    {\n                        ladder_phi_10 = true;\n                        break;\n                    }\n                }\n                if (ladder_phi_10)\n                {\n                    break;\n                }\n            }\n            uint _54 = imageAtomicAdd(_8, int(0u), _47);\n            _47++;\n            continue;\n        }\n        _33 = float(_47);\n        _36 = float(V.y);\n        _38 = float(V.z);\n        _40 = float(V.w);\n    }\n    else\n    {\n        _33 = 0.0;\n        _36 = 0.0;\n        _38 = 0.0;\n        _40 = 0.0;\n    }\n    SV_Target.x = _33;\n    SV_Target.y = _36;\n    SV_Target.z = _38;\n    SV_Target.w = _40;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 85\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"V\"\nOpName %15 \"SV_Target\"\nOpName %66 \"ladder_phi_10\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 1\n%25 = OpConstant %5 2\n%28 = OpConstant %5 3\n%30 = OpTypeBool\n%32 = OpConstant %5 10\n%35 = OpConstant %12 0\n%42 = OpTypePointer Output %12\n%49 = OpTypePointer Image %5\n%61 = OpConstant %5 7\n%67 = OpConstantFalse %30\n%68 = OpConstantTrue %30\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %69\n%69 = OpLabel\n%16 = OpLoad %6 %8\n%18 = OpAccessChain %17 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %17 %11 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %17 %11 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %17 %11 %28\n%29 = OpLoad %5 %27\n%31 = OpULessThan %30 %20 %32\nOpSelectionMerge %80 None\nOpBranchConditional %31 %70 %80\n%70 = OpLabel\nOpBranch %71\n%71 = OpLabel\n%47 = OpPhi %5 %20 %70 %48 %83\n%50 = OpImageTexelPointer %49 %8 %19 %19\n%51 = OpAtomicIAdd %5 %50 %22 %19 %47\n%52 = OpIEqual %30 %23 %19\nOpLoopMerge %79 %83 None\nOpBranch %72\n%72 = OpLabel\nOpSelectionMerge %82 None\nOpBranchConditional %52 %82 %73\n%73 = OpLabel\n%55 = OpBitwiseAnd %5 %47 %28\nOpBranch %74\n%74 = OpLabel\n%56 = OpPhi %5 %55 %73 %19 %77\n%57 = OpPhi %5 %19 %73 %58 %77\n%59 = OpIEqual %30 %56 %19\nOpLoopMerge %78 %77 None\nOpBranchConditional %59 %75 %78\n%75 = OpLabel\n%60 = OpBitwiseAnd %5 %47 %61\n%62 = OpIEqual %30 %60 %19\nOpSelectionMerge %76 None\nOpBranchConditional %62 %76 %78\n%76 = OpLabel\nOpBranch %77\n%77 = OpLabel\n%63 = OpImageTexelPointer %49 %8 %19 %19\n%64 = OpAtomicIAdd %5 %63 %22 %19 %47\n%58 = OpIAdd %5 %57 %22\n%65 = OpULessThan %30 %58 %23\nOpBranchConditional %65 %74 %78\n%78 = OpLabel\n%66 = OpPhi %30 %67 %75 %67 %77 %68 %74\nOpSelectionMerge %81 None\nOpBranchConditional %66 %79 %81\n%81 = OpLabel\nOpBranch %82\n%82 = OpLabel\nOpBranch %83\n%83 = OpLabel\n%53 = OpImageTexelPointer %49 %8 %19 %19\n%54 = OpAtomicIAdd %5 %53 %22 %19 %47\n%48 = OpIAdd %5 %47 %22\nOpBranch %71\n%79 = OpLabel\n%34 = OpConvertUToF %12 %47\n%37 = OpConvertUToF %12 %23\n%39 = OpConvertUToF %12 %26\n%41 = OpConvertUToF %12 %29\nOpBranch %80\n%80 = OpLabel\n%33 = OpPhi %12 %35 %69 %34 %79\n%36 = OpPhi %12 %35 %69 %37 %79\n%38 = OpPhi %12 %35 %69 %39 %79\n%40 = OpPhi %12 %35 %69 %41 %79\n%43 = OpAccessChain %42 %15 %19\nOpStore %43 %33\n%44 = OpAccessChain %42 %15 %22\nOpStore %44 %36\n%45 = OpAccessChain %42 %15 %25\nOpStore %45 %38\n%46 = OpAccessChain %42 %15 %28\nOpStore %46 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop-return.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _28;\n    if (gl_GlobalInvocationID.x < 100u)\n    {\n        uint frontier_phi_3_1_ladder;\n        if (gl_GlobalInvocationID.x == 0u)\n        {\n            frontier_phi_3_1_ladder = 0u;\n        }\n        else\n        {\n            uint _35;\n            _35 = 0u;\n            uint _31;\n            uint frontier_phi_12;\n            uint _37 = 0u;\n            bool _38;\n            for (;;)\n            {\n                _38 = gl_GlobalInvocationID.y == 0u;\n                uint frontier_phi_8_pred;\n                if (_38)\n                {\n                    frontier_phi_8_pred = _37;\n                }\n                else\n                {\n                    bool ladder_phi_20;\n                    uint frontier_phi_20_pred;\n                    uint frontier_phi_20_pred_1;\n                    uint _47 = _37;\n                    uint _48 = 0u;\n                    bool _54;\n                    for (;;)\n                    {\n                        uint _50 = _48 ^ _35;\n                        _54 = imageLoad(_8, int(_50)).x == 100u;\n                        if (_54)\n                        {\n                            ladder_phi_20 = true;\n                            frontier_phi_20_pred = _37;\n                            frontier_phi_20_pred_1 = imageLoad(_8, int(32u)).x + _47;\n                            break;\n                        }\n                        else\n                        {\n                            uint _43 = imageLoad(_8, int(((_35 << 2u) * _48) >> 2u)).x + _47;\n                            uint _49 = _48 + 1u;\n                            if (_49 < gl_GlobalInvocationID.y)\n                            {\n                                _47 = _43;\n                                _48 = _49;\n                                continue;\n                            }\n                            else\n                            {\n                                ladder_phi_20 = false;\n                                frontier_phi_20_pred = _43;\n                                frontier_phi_20_pred_1 = 0u;\n                                break;\n                            }\n                        }\n                    }\n                    if (ladder_phi_20)\n                    {\n                        frontier_phi_12 = frontier_phi_20_pred_1;\n                        break;\n                    }\n                    frontier_phi_8_pred = frontier_phi_20_pred;\n                }\n                _31 = frontier_phi_8_pred;\n                uint _36 = _35 + 1u;\n                if (_36 < gl_GlobalInvocationID.x)\n                {\n                    _35 = _36;\n                    _37 = _31;\n                    continue;\n                }\n                else\n                {\n                    frontier_phi_12 = _31;\n                    break;\n                }\n            }\n            frontier_phi_3_1_ladder = frontier_phi_12;\n        }\n        _28 = frontier_phi_3_1_ladder;\n    }\n    else\n    {\n        uint frontier_phi_3_2_ladder;\n        if (gl_GlobalInvocationID.z == 0u)\n        {\n            frontier_phi_3_2_ladder = 0u;\n        }\n        else\n        {\n            uint _39;\n            _39 = 0u;\n            uint _32;\n            uint frontier_phi_14;\n            uint _41 = 0u;\n            bool _42;\n            for (;;)\n            {\n                _42 = gl_GlobalInvocationID.y == 0u;\n                uint frontier_phi_10_pred;\n                if (_42)\n                {\n                    frontier_phi_10_pred = _41;\n                }\n                else\n                {\n                    bool ladder_phi_21;\n                    uint frontier_phi_21_pred;\n                    uint frontier_phi_21_pred_1;\n                    uint _55 = 0u;\n                    uint _57 = _41;\n                    bool _62;\n                    for (;;)\n                    {\n                        uint _58 = _55 ^ _39;\n                        _62 = imageLoad(_8, int(_58)).x == 100u;\n                        if (_62)\n                        {\n                            ladder_phi_21 = true;\n                            frontier_phi_21_pred = _41;\n                            frontier_phi_21_pred_1 = imageLoad(_8, int(32u)).x + _57;\n                            break;\n                        }\n                        else\n                        {\n                            uint _45 = imageLoad(_8, int(((_39 << 2u) * _55) >> 2u)).x + _57;\n                            uint _56 = _55 + 1u;\n                            if (_56 < gl_GlobalInvocationID.y)\n                            {\n                                _55 = _56;\n                                _57 = _45;\n                                continue;\n                            }\n                            else\n                            {\n                                ladder_phi_21 = false;\n                                frontier_phi_21_pred = _45;\n                                frontier_phi_21_pred_1 = 0u;\n                                break;\n                            }\n                        }\n                    }\n                    if (ladder_phi_21)\n                    {\n                        frontier_phi_14 = frontier_phi_21_pred_1;\n                        break;\n                    }\n                    frontier_phi_10_pred = frontier_phi_21_pred;\n                }\n                _32 = frontier_phi_10_pred;\n                uint _40 = _39 + 1u;\n                if (_40 < gl_GlobalInvocationID.z)\n                {\n                    _39 = _40;\n                    _41 = _32;\n                    continue;\n                }\n                else\n                {\n                    frontier_phi_14 = _32;\n                    break;\n                }\n            }\n            frontier_phi_3_2_ladder = frontier_phi_14;\n        }\n        _28 = frontier_phi_3_2_ladder;\n    }\n    imageStore(_8, int(0u), uvec4(_28));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 131\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %80 \"ladder_phi_20\"\nOpName %83 \"ladder_phi_21\"\nOpName %84 \"frontier_phi_21.pred\"\nOpName %85 \"frontier_phi_10.pred\"\nOpName %86 \"frontier_phi_20.pred\"\nOpName %87 \"frontier_phi_8.pred\"\nOpName %88 \"frontier_phi_21.pred\"\nOpName %89 \"frontier_phi_14\"\nOpName %90 \"frontier_phi_3.2.ladder\"\nOpName %91 \"frontier_phi_20.pred\"\nOpName %92 \"frontier_phi_12\"\nOpName %93 \"frontier_phi_3.1.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeBool\n%25 = OpConstant %5 100\n%33 = OpTypeVector %5 4\n%63 = OpConstant %5 32\n%81 = OpConstantFalse %23\n%82 = OpConstantTrue %23\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %94\n%94 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%24 = OpULessThan %23 %16 %25\nOpSelectionMerge %125 None\nOpBranchConditional %24 %110 %95\n%110 = OpLabel\n%26 = OpIEqual %23 %16 %15\nOpSelectionMerge %124 None\nOpBranchConditional %26 %124 %111\n%111 = OpLabel\nOpBranch %112\n%112 = OpLabel\n%35 = OpPhi %5 %15 %111 %36 %122\n%37 = OpPhi %5 %15 %111 %31 %122\n%38 = OpIEqual %23 %19 %15\nOpLoopMerge %123 %122 None\nOpBranch %113\n%113 = OpLabel\nOpSelectionMerge %121 None\nOpBranchConditional %38 %121 %114\n%114 = OpLabel\nOpBranch %115\n%115 = OpLabel\n%47 = OpPhi %5 %37 %114 %43 %117\n%48 = OpPhi %5 %15 %114 %49 %117\n%50 = OpBitwiseXor %5 %48 %35\n%51 = OpShiftLeftLogical %5 %50 %21\n%52 = OpImageRead %33 %9 %50\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpIEqual %23 %53 %25\nOpLoopMerge %119 %117 None\nOpBranch %128\n%128 = OpLabel\nOpSelectionMerge %129 None\nOpBranchConditional %54 %118 %116\n%118 = OpLabel\n%64 = OpImageRead %33 %9 %63\n%65 = OpCompositeExtract %5 %64 0\n%29 = OpIAdd %5 %65 %47\nOpBranch %119\n%116 = OpLabel\nOpBranch %117\n%129 = OpLabel\nOpUnreachable\n%117 = OpLabel\n%66 = OpShiftLeftLogical %5 %35 %21\n%67 = OpIMul %5 %66 %48\n%68 = OpShiftRightLogical %5 %67 %21\n%69 = OpImageRead %33 %9 %68\n%70 = OpCompositeExtract %5 %69 0\n%43 = OpIAdd %5 %70 %47\n%49 = OpIAdd %5 %48 %18\n%71 = OpULessThan %23 %49 %19\nOpBranchConditional %71 %115 %119\n%119 = OpLabel\n%80 = OpPhi %23 %81 %117 %82 %118\n%86 = OpPhi %5 %43 %117 %37 %118\n%91 = OpPhi %5 %15 %117 %29 %118\nOpSelectionMerge %120 None\nOpBranchConditional %80 %123 %120\n%120 = OpLabel\nOpBranch %121\n%121 = OpLabel\n%87 = OpPhi %5 %37 %113 %86 %120\n%31 = OpCopyObject %5 %87\nOpBranch %122\n%122 = OpLabel\n%36 = OpIAdd %5 %35 %18\n%44 = OpULessThan %23 %36 %16\nOpBranchConditional %44 %112 %123\n%123 = OpLabel\n%92 = OpPhi %5 %31 %122 %91 %119\nOpBranch %124\n%124 = OpLabel\n%93 = OpPhi %5 %15 %110 %92 %123\nOpBranch %125\n%95 = OpLabel\n%27 = OpIEqual %23 %22 %15\nOpSelectionMerge %109 None\nOpBranchConditional %27 %109 %96\n%96 = OpLabel\nOpBranch %97\n%97 = OpLabel\n%39 = OpPhi %5 %15 %96 %40 %107\n%41 = OpPhi %5 %15 %96 %32 %107\n%42 = OpIEqual %23 %19 %15\nOpLoopMerge %108 %107 None\nOpBranch %98\n%98 = OpLabel\nOpSelectionMerge %106 None\nOpBranchConditional %42 %106 %99\n%99 = OpLabel\nOpBranch %100\n%100 = OpLabel\n%55 = OpPhi %5 %15 %99 %56 %102\n%57 = OpPhi %5 %41 %99 %45 %102\n%58 = OpBitwiseXor %5 %55 %39\n%59 = OpShiftLeftLogical %5 %58 %21\n%60 = OpImageRead %33 %9 %58\n%61 = OpCompositeExtract %5 %60 0\n%62 = OpIEqual %23 %61 %25\nOpLoopMerge %104 %102 None\nOpBranch %126\n%126 = OpLabel\nOpSelectionMerge %127 None\nOpBranchConditional %62 %103 %101\n%103 = OpLabel\n%72 = OpImageRead %33 %9 %63\n%73 = OpCompositeExtract %5 %72 0\n%30 = OpIAdd %5 %73 %57\nOpBranch %104\n%101 = OpLabel\nOpBranch %102\n%127 = OpLabel\nOpUnreachable\n%102 = OpLabel\n%74 = OpShiftLeftLogical %5 %39 %21\n%75 = OpIMul %5 %74 %55\n%76 = OpShiftRightLogical %5 %75 %21\n%77 = OpImageRead %33 %9 %76\n%78 = OpCompositeExtract %5 %77 0\n%45 = OpIAdd %5 %78 %57\n%56 = OpIAdd %5 %55 %18\n%79 = OpULessThan %23 %56 %19\nOpBranchConditional %79 %100 %104\n%104 = OpLabel\n%83 = OpPhi %23 %81 %102 %82 %103\n%84 = OpPhi %5 %45 %102 %41 %103\n%88 = OpPhi %5 %15 %102 %30 %103\nOpSelectionMerge %105 None\nOpBranchConditional %83 %108 %105\n%105 = OpLabel\nOpBranch %106\n%106 = OpLabel\n%85 = OpPhi %5 %41 %98 %84 %105\n%32 = OpCopyObject %5 %85\nOpBranch %107\n%107 = OpLabel\n%40 = OpIAdd %5 %39 %18\n%46 = OpULessThan %23 %40 %22\nOpBranchConditional %46 %97 %108\n%108 = OpLabel\n%89 = OpPhi %5 %32 %107 %88 %104\nOpBranch %109\n%109 = OpLabel\n%90 = OpPhi %5 %15 %95 %89 %108\nOpBranch %125\n%125 = OpLabel\n%28 = OpPhi %5 %93 %124 %90 %109\n%34 = OpCompositeConstruct %33 %28 %28 %28 %28\nOpImageWrite %9 %15 %34\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/loop.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _20;\n    if (gl_GlobalInvocationID.z == 0u)\n    {\n        _20 = 0u;\n    }\n    else\n    {\n        uint _24;\n        uint _25;\n        _24 = 0u;\n        _25 = 0u;\n        uint _21;\n        for (;;)\n        {\n            _21 = imageLoad(_8, int(_25)).x + _24;\n            uint _26 = _25 + 1u;\n            if (_26 == gl_GlobalInvocationID.z)\n            {\n                break;\n            }\n            else\n            {\n                _24 = _21;\n                _25 = _26;\n            }\n        }\n        _20 = _21;\n    }\n    imageStore(_8, int(0u), uvec4(_20));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 2\n%17 = OpTypeBool\n%19 = OpConstant %5 0\n%22 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpIEqual %17 %16 %19\nOpSelectionMerge %36 None\nOpBranchConditional %18 %36 %33\n%33 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%24 = OpPhi %5 %19 %33 %21 %34\n%25 = OpPhi %5 %19 %33 %26 %34\n%27 = OpShiftLeftLogical %5 %25 %15\n%28 = OpImageRead %22 %9 %25\n%29 = OpCompositeExtract %5 %28 0\n%21 = OpIAdd %5 %29 %24\n%26 = OpIAdd %5 %25 %30\n%31 = OpIEqual %17 %26 %16\nOpLoopMerge %35 %34 None\nOpBranchConditional %31 %35 %34\n%35 = OpLabel\nOpBranch %36\n%36 = OpLabel\n%20 = OpPhi %5 %19 %32 %21 %35\n%23 = OpCompositeConstruct %22 %20 %20 %20 %20\nOpImageWrite %9 %19 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/nested-loop-break-2.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _23;\n    if (gl_GlobalInvocationID.y == 0u)\n    {\n        _23 = 0u;\n    }\n    else\n    {\n        uint _27;\n        _27 = 0u;\n        uint _24;\n        uint _29 = 0u;\n        bool _30;\n        for (;;)\n        {\n            _30 = gl_GlobalInvocationID.z == 0u;\n            uint frontier_phi_4_pred;\n            if (_30)\n            {\n                frontier_phi_4_pred = _29;\n            }\n            else\n            {\n                uint frontier_phi_10;\n                uint _34 = _29;\n                uint _35 = 0u;\n                bool _43;\n                for (;;)\n                {\n                    _43 = imageLoad(_8, int(_35 * 32u)).x == 10u;\n                    if (_43)\n                    {\n                        frontier_phi_10 = imageLoad(_8, int(2u)).x + _34;\n                        break;\n                    }\n                    else\n                    {\n                        uint _47 = _35 ^ _27;\n                        uint _32 = imageLoad(_8, int(_47)).x + _34;\n                        uint _36 = _35 + 1u;\n                        if (_36 < gl_GlobalInvocationID.z)\n                        {\n                            _34 = _32;\n                            _35 = _36;\n                            continue;\n                        }\n                        else\n                        {\n                            frontier_phi_10 = _32;\n                            break;\n                        }\n                    }\n                }\n                frontier_phi_4_pred = frontier_phi_10;\n            }\n            _24 = frontier_phi_4_pred;\n            uint _28 = _27 + 1u;\n            if (_28 == gl_GlobalInvocationID.y)\n            {\n                break;\n            }\n            else\n            {\n                _27 = _28;\n                _29 = _24;\n                continue;\n            }\n        }\n        _23 = _24;\n    }\n    imageStore(_8, int(0u), uvec4(_23));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %52 \"frontier_phi_10\"\nOpName %53 \"frontier_phi_4.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 1\n%18 = OpConstant %5 2\n%20 = OpTypeBool\n%22 = OpConstant %5 0\n%25 = OpTypeVector %5 4\n%38 = OpConstant %5 7\n%40 = OpConstant %5 32\n%44 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%21 = OpIEqual %20 %16 %22\nOpSelectionMerge %67 None\nOpBranchConditional %21 %67 %55\n%55 = OpLabel\nOpBranch %56\n%56 = OpLabel\n%27 = OpPhi %5 %22 %55 %28 %65\n%29 = OpPhi %5 %22 %55 %24 %65\n%30 = OpIEqual %20 %19 %22\nOpLoopMerge %66 %65 None\nOpBranch %57\n%57 = OpLabel\nOpSelectionMerge %64 None\nOpBranchConditional %30 %64 %58\n%58 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%34 = OpPhi %5 %29 %58 %32 %61\n%35 = OpPhi %5 %22 %58 %36 %61\n%37 = OpShiftLeftLogical %5 %35 %38\n%39 = OpIMul %5 %35 %40\n%41 = OpImageRead %25 %9 %39\n%42 = OpCompositeExtract %5 %41 0\n%43 = OpIEqual %20 %42 %44\nOpLoopMerge %63 %61 None\nOpBranch %68\n%68 = OpLabel\nOpSelectionMerge %69 None\nOpBranchConditional %43 %62 %60\n%62 = OpLabel\n%45 = OpImageRead %25 %9 %18\n%46 = OpCompositeExtract %5 %45 0\n%31 = OpIAdd %5 %46 %34\nOpBranch %63\n%60 = OpLabel\nOpBranch %61\n%69 = OpLabel\nOpUnreachable\n%61 = OpLabel\n%47 = OpBitwiseXor %5 %35 %27\n%48 = OpShiftLeftLogical %5 %47 %18\n%49 = OpImageRead %25 %9 %47\n%50 = OpCompositeExtract %5 %49 0\n%32 = OpIAdd %5 %50 %34\n%36 = OpIAdd %5 %35 %15\n%51 = OpULessThan %20 %36 %19\nOpBranchConditional %51 %59 %63\n%63 = OpLabel\n%52 = OpPhi %5 %32 %61 %31 %62\nOpBranch %64\n%64 = OpLabel\n%53 = OpPhi %5 %29 %57 %52 %63\n%24 = OpCopyObject %5 %53\nOpBranch %65\n%65 = OpLabel\n%28 = OpIAdd %5 %27 %15\n%33 = OpIEqual %20 %28 %16\nOpBranchConditional %33 %66 %56\n%66 = OpLabel\nOpBranch %67\n%67 = OpLabel\n%23 = OpPhi %5 %22 %54 %24 %66\n%26 = OpCompositeConstruct %25 %23 %23 %23 %23\nOpImageWrite %9 %22 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/nested-loop-break.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _25;\n    if (gl_GlobalInvocationID.x == 0u)\n    {\n        _25 = 0u;\n    }\n    else\n    {\n        uint _29;\n        _29 = 0u;\n        uint _26;\n        uint _31 = 0u;\n        bool _32;\n        for (;;)\n        {\n            _32 = gl_GlobalInvocationID.y == 0u;\n            uint frontier_phi_4_pred;\n            if (_32)\n            {\n                frontier_phi_4_pred = _31;\n            }\n            else\n            {\n                uint _36;\n                _36 = 0u;\n                uint _34;\n                uint frontier_phi_12;\n                uint _38 = _31;\n                bool _45;\n                for (;;)\n                {\n                    _45 = imageLoad(_8, int(_36 * 32u)).x == 10u;\n                    if (_45)\n                    {\n                        frontier_phi_12 = imageLoad(_8, int(1u)).x + _38;\n                        break;\n                    }\n                    else\n                    {\n                        uint frontier_phi_10_pred;\n                        if (gl_GlobalInvocationID.z == 0u)\n                        {\n                            frontier_phi_10_pred = _38;\n                        }\n                        else\n                        {\n                            uint frontier_phi_16;\n                            uint _53 = _38;\n                            uint _54 = 0u;\n                            bool _60;\n                            for (;;)\n                            {\n                                _60 = imageLoad(_8, int(_54 * 32u)).x == 10u;\n                                if (_60)\n                                {\n                                    frontier_phi_16 = imageLoad(_8, int(2u)).x + _53;\n                                    break;\n                                }\n                                else\n                                {\n                                    uint _64 = (_36 ^ _29) ^ _54;\n                                    uint _51 = imageLoad(_8, int(_64)).x + _53;\n                                    uint _55 = _54 + 1u;\n                                    if (_55 < gl_GlobalInvocationID.z)\n                                    {\n                                        _53 = _51;\n                                        _54 = _55;\n                                        continue;\n                                    }\n                                    else\n                                    {\n                                        frontier_phi_16 = _51;\n                                        break;\n                                    }\n                                }\n                            }\n                            frontier_phi_10_pred = frontier_phi_16;\n                        }\n                        _34 = frontier_phi_10_pred;\n                        uint _37 = _36 + 1u;\n                        if (_37 < gl_GlobalInvocationID.y)\n                        {\n                            _36 = _37;\n                            _38 = _34;\n                            continue;\n                        }\n                        else\n                        {\n                            frontier_phi_12 = _34;\n                            break;\n                        }\n                    }\n                }\n                frontier_phi_4_pred = frontier_phi_12;\n            }\n            _26 = frontier_phi_4_pred;\n            uint _30 = _29 + 1u;\n            if (_30 == gl_GlobalInvocationID.x)\n            {\n                break;\n            }\n            else\n            {\n                _29 = _30;\n                _31 = _26;\n                continue;\n            }\n        }\n        _25 = _26;\n    }\n    imageStore(_8, int(0u), uvec4(_25));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %69 \"frontier_phi_16\"\nOpName %70 \"frontier_phi_10.pred\"\nOpName %71 \"frontier_phi_12\"\nOpName %72 \"frontier_phi_4.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeBool\n%27 = OpTypeVector %5 4\n%40 = OpConstant %5 7\n%42 = OpConstant %5 32\n%46 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%24 = OpIEqual %23 %16 %15\nOpSelectionMerge %93 None\nOpBranchConditional %24 %93 %74\n%74 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%29 = OpPhi %5 %15 %74 %30 %91\n%31 = OpPhi %5 %15 %74 %26 %91\n%32 = OpIEqual %23 %19 %15\nOpLoopMerge %92 %91 None\nOpBranch %76\n%76 = OpLabel\nOpSelectionMerge %90 None\nOpBranchConditional %32 %90 %77\n%77 = OpLabel\nOpBranch %78\n%78 = OpLabel\n%36 = OpPhi %5 %15 %77 %37 %87\n%38 = OpPhi %5 %31 %77 %34 %87\n%39 = OpShiftLeftLogical %5 %36 %40\n%41 = OpIMul %5 %36 %42\n%43 = OpImageRead %27 %9 %41\n%44 = OpCompositeExtract %5 %43 0\n%45 = OpIEqual %23 %44 %46\nOpLoopMerge %89 %87 None\nOpBranch %94\n%94 = OpLabel\nOpSelectionMerge %95 None\nOpBranchConditional %45 %88 %79\n%88 = OpLabel\n%47 = OpImageRead %27 %9 %18\n%48 = OpCompositeExtract %5 %47 0\n%33 = OpIAdd %5 %48 %38\nOpBranch %89\n%79 = OpLabel\n%49 = OpIEqual %23 %22 %15\nOpSelectionMerge %86 None\nOpBranchConditional %49 %86 %80\n%80 = OpLabel\nOpBranch %81\n%81 = OpLabel\n%53 = OpPhi %5 %38 %80 %51 %83\n%54 = OpPhi %5 %15 %80 %55 %83\n%56 = OpShiftLeftLogical %5 %54 %40\n%57 = OpIMul %5 %54 %42\n%58 = OpImageRead %27 %9 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpIEqual %23 %59 %46\nOpLoopMerge %85 %83 None\nOpBranch %96\n%96 = OpLabel\nOpSelectionMerge %97 None\nOpBranchConditional %60 %84 %82\n%84 = OpLabel\n%61 = OpImageRead %27 %9 %21\n%62 = OpCompositeExtract %5 %61 0\n%50 = OpIAdd %5 %62 %53\nOpBranch %85\n%82 = OpLabel\nOpBranch %83\n%97 = OpLabel\nOpUnreachable\n%83 = OpLabel\n%63 = OpBitwiseXor %5 %36 %29\n%64 = OpBitwiseXor %5 %63 %54\n%65 = OpShiftLeftLogical %5 %64 %21\n%66 = OpImageRead %27 %9 %64\n%67 = OpCompositeExtract %5 %66 0\n%51 = OpIAdd %5 %67 %53\n%55 = OpIAdd %5 %54 %18\n%68 = OpULessThan %23 %55 %22\nOpBranchConditional %68 %81 %85\n%85 = OpLabel\n%69 = OpPhi %5 %51 %83 %50 %84\nOpBranch %86\n%86 = OpLabel\n%70 = OpPhi %5 %38 %79 %69 %85\n%34 = OpCopyObject %5 %70\nOpBranch %87\n%95 = OpLabel\nOpUnreachable\n%87 = OpLabel\n%37 = OpIAdd %5 %36 %18\n%52 = OpULessThan %23 %37 %19\nOpBranchConditional %52 %78 %89\n%89 = OpLabel\n%71 = OpPhi %5 %34 %87 %33 %88\nOpBranch %90\n%90 = OpLabel\n%72 = OpPhi %5 %31 %76 %71 %89\n%26 = OpCopyObject %5 %72\nOpBranch %91\n%91 = OpLabel\n%30 = OpIAdd %5 %29 %18\n%35 = OpIEqual %23 %30 %16\nOpBranchConditional %35 %92 %75\n%92 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%25 = OpPhi %5 %15 %73 %26 %92\n%28 = OpCompositeConstruct %27 %25 %25 %25 %25\nOpImageWrite %9 %15 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/nested-loop.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _25;\n    if (gl_GlobalInvocationID.x == 0u)\n    {\n        _25 = 0u;\n    }\n    else\n    {\n        uint _26;\n        uint _29 = 0u;\n        uint _31 = 0u;\n        bool _32;\n        for (;;)\n        {\n            _32 = gl_GlobalInvocationID.y == 0u;\n            uint frontier_phi_4_pred;\n            if (_32)\n            {\n                frontier_phi_4_pred = _31;\n            }\n            else\n            {\n                uint _33;\n                uint _35 = 0u;\n                uint _37 = _31;\n                bool _38;\n                for (;;)\n                {\n                    _38 = gl_GlobalInvocationID.z == 0u;\n                    uint frontier_phi_8_pred;\n                    if (_38)\n                    {\n                        frontier_phi_8_pred = _37;\n                    }\n                    else\n                    {\n                        uint _41;\n                        uint _42;\n                        _41 = _37;\n                        _42 = 0u;\n                        uint _39;\n                        for (;;)\n                        {\n                            uint _45 = (_35 ^ _29) ^ _42;\n                            _39 = imageLoad(_8, int(_45)).x + _41;\n                            uint _43 = _42 + 1u;\n                            if (_43 == gl_GlobalInvocationID.z)\n                            {\n                                break;\n                            }\n                            else\n                            {\n                                _41 = _39;\n                                _42 = _43;\n                            }\n                        }\n                        frontier_phi_8_pred = _39;\n                    }\n                    _33 = frontier_phi_8_pred;\n                    uint _36 = _35 + 1u;\n                    if (_36 == gl_GlobalInvocationID.y)\n                    {\n                        break;\n                    }\n                    else\n                    {\n                        _35 = _36;\n                        _37 = _33;\n                        continue;\n                    }\n                }\n                frontier_phi_4_pred = _33;\n            }\n            _26 = frontier_phi_4_pred;\n            uint _30 = _29 + 1u;\n            if (_30 == gl_GlobalInvocationID.x)\n            {\n                break;\n            }\n            else\n            {\n                _29 = _30;\n                _31 = _26;\n                continue;\n            }\n        }\n        _25 = _26;\n    }\n    imageStore(_8, int(0u), uvec4(_25));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 70\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %50 \"frontier_phi_8.pred\"\nOpName %51 \"frontier_phi_4.pred\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeBool\n%27 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %52\n%52 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%24 = OpIEqual %23 %16 %15\nOpSelectionMerge %68 None\nOpBranchConditional %24 %68 %53\n%53 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%29 = OpPhi %5 %15 %53 %30 %66\n%31 = OpPhi %5 %15 %53 %26 %66\n%32 = OpIEqual %23 %19 %15\nOpLoopMerge %67 %66 None\nOpBranch %55\n%55 = OpLabel\nOpSelectionMerge %65 None\nOpBranchConditional %32 %65 %56\n%56 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%35 = OpPhi %5 %15 %56 %36 %63\n%37 = OpPhi %5 %31 %56 %33 %63\n%38 = OpIEqual %23 %22 %15\nOpLoopMerge %64 %63 None\nOpBranch %58\n%58 = OpLabel\nOpSelectionMerge %62 None\nOpBranchConditional %38 %62 %59\n%59 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%41 = OpPhi %5 %37 %59 %39 %60\n%42 = OpPhi %5 %15 %59 %43 %60\n%44 = OpBitwiseXor %5 %35 %29\n%45 = OpBitwiseXor %5 %44 %42\n%46 = OpShiftLeftLogical %5 %45 %21\n%47 = OpImageRead %27 %9 %45\n%48 = OpCompositeExtract %5 %47 0\n%39 = OpIAdd %5 %48 %41\n%43 = OpIAdd %5 %42 %18\n%49 = OpIEqual %23 %43 %22\nOpLoopMerge %61 %60 None\nOpBranchConditional %49 %61 %60\n%61 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%50 = OpPhi %5 %37 %58 %39 %61\n%33 = OpCopyObject %5 %50\nOpBranch %63\n%63 = OpLabel\n%36 = OpIAdd %5 %35 %18\n%40 = OpIEqual %23 %36 %19\nOpBranchConditional %40 %64 %57\n%64 = OpLabel\nOpBranch %65\n%65 = OpLabel\n%51 = OpPhi %5 %31 %55 %33 %64\n%26 = OpCopyObject %5 %51\nOpBranch %66\n%66 = OpLabel\n%30 = OpIAdd %5 %29 %18\n%34 = OpIEqual %23 %30 %16\nOpBranchConditional %34 %67 %54\n%67 = OpLabel\nOpBranch %68\n%68 = OpLabel\n%25 = OpPhi %5 %15 %52 %26 %67\n%28 = OpCompositeConstruct %27 %25 %25 %25 %25\nOpImageWrite %9 %15 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/selection-merge-split-post-domination.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _25;\n    if (V.x > 0.0)\n    {\n        _25 = 20.0;\n    }\n    else\n    {\n        _25 = 10.0;\n    }\n    float _31;\n    float _33;\n    if (V.y > 0.0)\n    {\n        float _32;\n        if (V.x > 1.0)\n        {\n            _32 = 10.0;\n        }\n        else\n        {\n            _32 = 20.0;\n        }\n        float frontier_phi_4_6_ladder;\n        float frontier_phi_4_6_ladder_1;\n        if (V.z > 0.0)\n        {\n            frontier_phi_4_6_ladder = _32;\n            frontier_phi_4_6_ladder_1 = 30.0;\n        }\n        else\n        {\n            frontier_phi_4_6_ladder = _32;\n            frontier_phi_4_6_ladder_1 = 10.0;\n        }\n        _31 = frontier_phi_4_6_ladder;\n        _33 = frontier_phi_4_6_ladder_1;\n    }\n    else\n    {\n        _31 = 0.0;\n        _33 = 10.0;\n    }\n    SV_Target.x = _25;\n    SV_Target.y = _31 + 10.0;\n    SV_Target.z = 10.0;\n    SV_Target.w = _33;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"V\"\nOpName %10 \"SV_Target\"\nOpName %43 \"frontier_phi_4.6.ladder\"\nOpName %44 \"frontier_phi_4.6.ladder\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%22 = OpTypeBool\n%24 = OpConstant %5 0\n%26 = OpConstant %5 20\n%27 = OpConstant %5 10\n%30 = OpConstant %5 1\n%34 = OpConstant %5 30\n%36 = OpTypePointer Output %5\n%41 = OpConstant %13 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %45\n%45 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%23 = OpFOrdGreaterThan %22 %15 %24\nOpSelectionMerge %47 None\nOpBranchConditional %23 %46 %47\n%46 = OpLabel\nOpBranch %47\n%47 = OpLabel\n%25 = OpPhi %5 %27 %45 %26 %46\n%28 = OpFOrdGreaterThan %22 %18 %24\nOpSelectionMerge %53 None\nOpBranchConditional %28 %48 %53\n%48 = OpLabel\n%29 = OpFOrdGreaterThan %22 %15 %30\nOpSelectionMerge %50 None\nOpBranchConditional %29 %49 %50\n%49 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%32 = OpPhi %5 %26 %48 %27 %49\n%42 = OpFOrdGreaterThan %22 %21 %24\nOpSelectionMerge %52 None\nOpBranchConditional %42 %51 %52\n%51 = OpLabel\nOpBranch %52\n%52 = OpLabel\n%43 = OpPhi %5 %32 %51 %32 %50\n%44 = OpPhi %5 %34 %51 %27 %50\nOpBranch %53\n%53 = OpLabel\n%31 = OpPhi %5 %24 %47 %43 %52\n%33 = OpPhi %5 %27 %47 %44 %52\n%35 = OpFAdd %5 %31 %27\n%37 = OpAccessChain %36 %10 %14\nOpStore %37 %25\n%38 = OpAccessChain %36 %10 %17\nOpStore %38 %35\n%39 = OpAccessChain %36 %10 %20\nOpStore %39 %27\n%40 = OpAccessChain %36 %10 %41\nOpStore %40 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/switch-continue.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec4 I;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    uint _17 = uint(I.x);\n    uint _29 = uint(I.w);\n    uint _31;\n    uint _32;\n    _31 = uint(I.y);\n    _32 = uint(I.z);\n    uint _34;\n    uint _30 = _17;\n    uint _33 = _29;\n    for (;;)\n    {\n        bool _41_ladder_break = false;\n        switch (_30)\n        {\n            case 5u:\n            {\n                _34 = 6u;\n                _30 = _31;\n                _31 = _32;\n                _32 = _33;\n                _33 = _34;\n                continue;\n            }\n            case 7u:\n            {\n                _34 = 17u;\n                _30 = _31;\n                _31 = _32;\n                _32 = _33;\n                _33 = _34;\n                continue;\n            }\n            default:\n            {\n                _41_ladder_break = true;\n                break;\n            }\n        }\n        if (_41_ladder_break)\n        {\n            break;\n        }\n    }\n    SV_Target = float(int(_32 + _31));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"I\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeFloat 32\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%19 = OpConstant %14 1\n%23 = OpConstant %14 2\n%27 = OpConstant %14 3\n%37 = OpConstant %14 17\n%38 = OpConstant %14 6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpBitcast %14 %16\n%18 = OpAccessChain %12 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpBitcast %14 %20\n%22 = OpAccessChain %12 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpBitcast %14 %24\n%26 = OpAccessChain %12 %8 %27\n%28 = OpLoad %5 %26\n%29 = OpBitcast %14 %28\nOpBranch %40\n%40 = OpLabel\n%30 = OpPhi %14 %17 %39 %31 %44\n%31 = OpPhi %14 %21 %39 %32 %44\n%32 = OpPhi %14 %25 %39 %33 %44\n%33 = OpPhi %14 %29 %39 %34 %44\nOpLoopMerge %46 %44 None\nOpBranch %41\n%41 = OpLabel\nOpSelectionMerge %47 None\nOpSwitch %30 %45 5 %43 7 %42\n%45 = OpLabel\nOpBranch %46\n%43 = OpLabel\nOpBranch %44\n%42 = OpLabel\nOpBranch %44\n%47 = OpLabel\nOpUnreachable\n%44 = OpLabel\n%34 = OpPhi %14 %37 %42 %38 %43\nOpBranch %40\n%46 = OpLabel\n%35 = OpIAdd %14 %32 %31\n%36 = OpConvertSToF %9 %35\nOpStore %11 %36\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/switch-merge-into-other-merge.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _22;\n    if (gl_GlobalInvocationID.y == 0u)\n    {\n        _22 = 0u;\n    }\n    else\n    {\n        uint _23;\n        if (imageLoad(_8, int(100u)).x > 20u)\n        {\n            imageStore(_8, int(50u), uvec4(imageLoad(_8, int(50u)).x + 320u));\n            _23 = 4u;\n        }\n        else\n        {\n            _23 = 0u;\n        }\n        uint frontier_phi_1_switch_merge;\n        switch (gl_GlobalInvocationID.x)\n        {\n            case 0u:\n            {\n                imageStore(_8, int(0u), uvec4(imageLoad(_8, int(0u)).x + _23));\n                frontier_phi_1_switch_merge = _23;\n                break;\n            }\n            case 1u:\n            {\n                imageStore(_8, int(40u), uvec4(imageLoad(_8, int(40u)).x + (_23 << 1u)));\n                frontier_phi_1_switch_merge = _23;\n                break;\n            }\n            case 5u:\n            {\n                imageStore(_8, int(60u), uvec4(imageLoad(_8, int(60u)).x + (_23 * 3u)));\n                frontier_phi_1_switch_merge = _23;\n                break;\n            }\n            default:\n            {\n                imageStore(_8, int(100u), uvec4(imageLoad(_8, int(100u)).x + (_23 << 2u)));\n                frontier_phi_1_switch_merge = _23;\n                break;\n            }\n        }\n        _22 = frontier_phi_1_switch_merge;\n    }\n    imageStore(_8, int(1u), uvec4(_22));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 73\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %61 \"frontier_phi_1.switch-merge\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%20 = OpTypeBool\n%24 = OpTypeVector %5 4\n%26 = OpConstant %5 100\n%30 = OpConstant %5 20\n%31 = OpConstant %5 50\n%35 = OpConstant %5 320\n%37 = OpConstant %5 4\n%39 = OpConstant %5 2\n%49 = OpConstant %5 40\n%55 = OpConstant %5 3\n%56 = OpConstant %5 60\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%21 = OpIEqual %20 %19 %15\nOpSelectionMerge %71 None\nOpBranchConditional %21 %71 %63\n%63 = OpLabel\n%27 = OpImageRead %24 %9 %26\n%28 = OpCompositeExtract %5 %27 0\n%29 = OpUGreaterThan %20 %28 %30\nOpSelectionMerge %65 None\nOpBranchConditional %29 %64 %65\n%64 = OpLabel\n%32 = OpImageRead %24 %9 %31\n%33 = OpCompositeExtract %5 %32 0\n%34 = OpIAdd %5 %33 %35\n%36 = OpCompositeConstruct %24 %34 %34 %34 %34\nOpImageWrite %9 %31 %36\nOpBranch %65\n%65 = OpLabel\n%23 = OpPhi %5 %15 %63 %37 %64\nOpSelectionMerge %70 None\nOpSwitch %16 %69 0 %68 1 %67 5 %66\n%69 = OpLabel\n%38 = OpShiftLeftLogical %5 %23 %39\n%40 = OpImageRead %24 %9 %26\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpIAdd %5 %41 %38\n%43 = OpCompositeConstruct %24 %42 %42 %42 %42\nOpImageWrite %9 %26 %43\nOpBranch %70\n%68 = OpLabel\n%44 = OpImageRead %24 %9 %15\n%45 = OpCompositeExtract %5 %44 0\n%46 = OpIAdd %5 %45 %23\n%47 = OpCompositeConstruct %24 %46 %46 %46 %46\nOpImageWrite %9 %15 %47\nOpBranch %70\n%67 = OpLabel\n%48 = OpShiftLeftLogical %5 %23 %18\n%50 = OpImageRead %24 %9 %49\n%51 = OpCompositeExtract %5 %50 0\n%52 = OpIAdd %5 %51 %48\n%53 = OpCompositeConstruct %24 %52 %52 %52 %52\nOpImageWrite %9 %49 %53\nOpBranch %70\n%66 = OpLabel\n%54 = OpIMul %5 %23 %55\n%57 = OpImageRead %24 %9 %56\n%58 = OpCompositeExtract %5 %57 0\n%59 = OpIAdd %5 %58 %54\n%60 = OpCompositeConstruct %24 %59 %59 %59 %59\nOpImageWrite %9 %56 %60\nOpBranch %70\n%70 = OpLabel\n%61 = OpPhi %5 %23 %69 %23 %68 %23 %67 %23 %66\nOpBranch %71\n%71 = OpLabel\n%22 = OpPhi %5 %15 %62 %61 %70\n%25 = OpCompositeConstruct %24 %22 %22 %22 %22\nOpImageWrite %9 %18 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/switch-shared-header-with-loop.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    if (!(gl_GlobalInvocationID.y == 0u))\n    {\n        uint _24 = 0u;\n        for (;;)\n        {\n            switch (gl_GlobalInvocationID.x)\n            {\n                case 0u:\n                {\n                    imageStore(_8, int(0u), uvec4(imageLoad(_8, int(0u)).x));\n                    break;\n                }\n                case 1u:\n                {\n                    imageStore(_8, int(40u), uvec4(imageLoad(_8, int(40u)).x));\n                    break;\n                }\n                case 5u:\n                {\n                    imageStore(_8, int(60u), uvec4(imageLoad(_8, int(60u)).x));\n                    break;\n                }\n                default:\n                {\n                    imageStore(_8, int(100u), uvec4(imageLoad(_8, int(100u)).x));\n                    break;\n                }\n            }\n            uint _25 = _24 + 1u;\n            if (_25 == gl_GlobalInvocationID.y)\n            {\n                break;\n            }\n            else\n            {\n                _24 = _25;\n                continue;\n            }\n        }\n    }\n    imageStore(_8, int(1u), uvec4(0u));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%20 = OpTypeBool\n%22 = OpTypeVector %5 4\n%26 = OpConstant %5 100\n%33 = OpConstant %5 40\n%37 = OpConstant %5 60\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%21 = OpIEqual %20 %19 %15\nOpSelectionMerge %53 None\nOpBranchConditional %21 %53 %43\n%43 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%24 = OpPhi %5 %15 %43 %25 %51\nOpLoopMerge %52 %51 None\nOpBranch %45\n%45 = OpLabel\nOpSelectionMerge %50 None\nOpSwitch %16 %49 0 %48 1 %47 5 %46\n%49 = OpLabel\n%27 = OpImageRead %22 %9 %26\n%28 = OpCompositeExtract %5 %27 0\n%29 = OpCompositeConstruct %22 %28 %28 %28 %28\nOpImageWrite %9 %26 %29\nOpBranch %50\n%48 = OpLabel\n%30 = OpImageRead %22 %9 %15\n%31 = OpCompositeExtract %5 %30 0\n%32 = OpCompositeConstruct %22 %31 %31 %31 %31\nOpImageWrite %9 %15 %32\nOpBranch %50\n%47 = OpLabel\n%34 = OpImageRead %22 %9 %33\n%35 = OpCompositeExtract %5 %34 0\n%36 = OpCompositeConstruct %22 %35 %35 %35 %35\nOpImageWrite %9 %33 %36\nOpBranch %50\n%46 = OpLabel\n%38 = OpImageRead %22 %9 %37\n%39 = OpCompositeExtract %5 %38 0\n%40 = OpCompositeConstruct %22 %39 %39 %39 %39\nOpImageWrite %9 %37 %40\nOpBranch %50\n%50 = OpLabel\nOpBranch %51\n%51 = OpLabel\n%25 = OpIAdd %5 %24 %18\n%41 = OpIEqual %20 %25 %19\nOpBranchConditional %41 %52 %44\n%52 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%23 = OpCompositeConstruct %22 %15 %15 %15 %15\nOpImageWrite %9 %18 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/control-flow/wave-size-dependent-loop-unroll.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared float _13[256];\n\nvoid main()\n{\n    uint _24 = 256u / gl_SubgroupSize;\n    bool _26 = _24 == 0u;\n    bool _27;\n    if (_26)\n    {\n        _27 = true;\n    }\n    else\n    {\n        _13[0u] = 0.0;\n        _13[1u] = 1.0;\n        _13[2u] = 2.0;\n        _13[3u] = 3.0;\n        _13[4u] = 4.0;\n        _13[5u] = 5.0;\n        _13[6u] = 6.0;\n        _13[7u] = 7.0;\n        _13[8u] = 8.0;\n        _13[9u] = 9.0;\n        _13[10u] = 10.0;\n        _13[11u] = 11.0;\n        _13[12u] = 12.0;\n        _13[13u] = 13.0;\n        _13[14u] = 14.0;\n        _13[15u] = 15.0;\n        bool frontier_phi_1_9_ladder;\n        if (_24 > 4u)\n        {\n            _13[16u] = 16.0;\n            _13[17u] = 17.0;\n            _13[18u] = 18.0;\n            _13[19u] = 19.0;\n            bool frontier_phi_1_9_ladder_10_ladder;\n            if (_24 > 5u)\n            {\n                _13[20u] = 20.0;\n                _13[21u] = 21.0;\n                _13[22u] = 22.0;\n                _13[23u] = 23.0;\n                bool frontier_phi_1_9_ladder_10_ladder_11_ladder;\n                if (_24 > 6u)\n                {\n                    _13[24u] = 24.0;\n                    _13[25u] = 25.0;\n                    _13[26u] = 26.0;\n                    _13[27u] = 27.0;\n                    bool frontier_phi_1_9_ladder_10_ladder_11_ladder_12_ladder;\n                    if (_24 > 7u)\n                    {\n                        _13[28u] = 28.0;\n                        _13[29u] = 29.0;\n                        _13[30u] = 30.0;\n                        _13[31u] = 31.0;\n                        frontier_phi_1_9_ladder_10_ladder_11_ladder_12_ladder = _26;\n                    }\n                    else\n                    {\n                        frontier_phi_1_9_ladder_10_ladder_11_ladder_12_ladder = _26;\n                    }\n                    frontier_phi_1_9_ladder_10_ladder_11_ladder = frontier_phi_1_9_ladder_10_ladder_11_ladder_12_ladder;\n                }\n                else\n                {\n                    frontier_phi_1_9_ladder_10_ladder_11_ladder = _26;\n                }\n                frontier_phi_1_9_ladder_10_ladder = frontier_phi_1_9_ladder_10_ladder_11_ladder;\n            }\n            else\n            {\n                frontier_phi_1_9_ladder_10_ladder = _26;\n            }\n            frontier_phi_1_9_ladder = frontier_phi_1_9_ladder_10_ladder;\n        }\n        else\n        {\n            frontier_phi_1_9_ladder = _26;\n        }\n        _27 = frontier_phi_1_9_ladder;\n    }\n    barrier();\n    if (!_27)\n    {\n        uint _56;\n        _56 = 0u;\n        for (;;)\n        {\n            uint _74 = gl_GlobalInvocationID.x * 4u;\n            imageStore(_8, int(_74), uvec4(floatBitsToUint(_13[0u + (_56 * 4u)])));\n            imageStore(_8, int(_74 + 1u), uvec4(floatBitsToUint(_13[1u + (_56 * 4u)])));\n            imageStore(_8, int(_74 + 2u), uvec4(floatBitsToUint(_13[2u + (_56 * 4u)])));\n            imageStore(_8, int(_74 + 3u), uvec4(floatBitsToUint(_13[3u + (_56 * 4u)])));\n            uint _57 = _56 + 1u;\n            if (_57 < _24)\n            {\n                _56 = _57;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 189\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17 %22\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %166 \"frontier_phi_1.9.ladder.10.ladder.11.ladder.12.ladder\"\nOpName %167 \"frontier_phi_1.9.ladder.10.ladder.11.ladder\"\nOpName %168 \"frontier_phi_1.9.ladder.10.ladder\"\nOpName %169 \"frontier_phi_1.9.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %17 BuiltIn GlobalInvocationId\nOpDecorate %22 BuiltIn SubgroupSize\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 256\n%10 = OpTypeFloat 32\n%11 = OpTypeArray %10 %9\n%12 = OpTypePointer Workgroup %11\n%13 = OpVariable %12 Workgroup\n%15 = OpTypeVector %5 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %5\n%20 = OpConstant %5 0\n%22 = OpVariable %18 Input\n%25 = OpTypeBool\n%28 = OpConstantTrue %25\n%29 = OpConstant %5 2\n%30 = OpConstant %5 264\n%31 = OpTypePointer Workgroup %10\n%33 = OpConstant %10 0\n%35 = OpConstant %5 1\n%36 = OpConstant %10 1\n%38 = OpConstant %10 2\n%40 = OpConstant %5 3\n%41 = OpConstant %10 3\n%44 = OpConstant %5 4\n%45 = OpConstant %10 4\n%47 = OpConstant %5 5\n%48 = OpConstant %10 5\n%50 = OpConstant %5 6\n%51 = OpConstant %10 6\n%53 = OpConstant %5 7\n%54 = OpConstant %10 7\n%79 = OpTypeVector %5 4\n%89 = OpConstant %5 8\n%90 = OpConstant %10 8\n%92 = OpConstant %5 9\n%93 = OpConstant %10 9\n%95 = OpConstant %5 10\n%96 = OpConstant %10 10\n%98 = OpConstant %5 11\n%99 = OpConstant %10 11\n%102 = OpConstant %5 12\n%103 = OpConstant %10 12\n%105 = OpConstant %5 13\n%106 = OpConstant %10 13\n%108 = OpConstant %5 14\n%109 = OpConstant %10 14\n%111 = OpConstant %5 15\n%112 = OpConstant %10 15\n%115 = OpConstant %5 16\n%116 = OpConstant %10 16\n%118 = OpConstant %5 17\n%119 = OpConstant %10 17\n%121 = OpConstant %5 18\n%122 = OpConstant %10 18\n%124 = OpConstant %5 19\n%125 = OpConstant %10 19\n%128 = OpConstant %5 20\n%129 = OpConstant %10 20\n%131 = OpConstant %5 21\n%132 = OpConstant %10 21\n%134 = OpConstant %5 22\n%135 = OpConstant %10 22\n%137 = OpConstant %5 23\n%138 = OpConstant %10 23\n%141 = OpConstant %5 24\n%142 = OpConstant %10 24\n%144 = OpConstant %5 25\n%145 = OpConstant %10 25\n%147 = OpConstant %5 26\n%148 = OpConstant %10 26\n%150 = OpConstant %5 27\n%151 = OpConstant %10 27\n%154 = OpConstant %5 28\n%155 = OpConstant %10 28\n%157 = OpConstant %5 29\n%158 = OpConstant %10 29\n%160 = OpConstant %5 30\n%161 = OpConstant %10 30\n%163 = OpConstant %5 31\n%164 = OpConstant %10 31\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %170\n%170 = OpLabel\n%14 = OpLoad %6 %8\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%23 = OpLoad %5 %22\n%24 = OpUDiv %5 %9 %23\n%26 = OpIEqual %25 %24 %20\nOpSelectionMerge %183 None\nOpBranchConditional %26 %183 %171\n%171 = OpLabel\n%32 = OpAccessChain %31 %13 %20\nOpStore %32 %33\n%34 = OpAccessChain %31 %13 %35\nOpStore %34 %36\n%37 = OpAccessChain %31 %13 %29\nOpStore %37 %38\n%39 = OpAccessChain %31 %13 %40\nOpStore %39 %41\n%42 = OpUGreaterThan %25 %24 %35\nOpBranch %172\n%172 = OpLabel\n%43 = OpAccessChain %31 %13 %44\nOpStore %43 %45\n%46 = OpAccessChain %31 %13 %47\nOpStore %46 %48\n%49 = OpAccessChain %31 %13 %50\nOpStore %49 %51\n%52 = OpAccessChain %31 %13 %53\nOpStore %52 %54\n%55 = OpUGreaterThan %25 %24 %29\nOpBranch %173\n%173 = OpLabel\n%88 = OpAccessChain %31 %13 %89\nOpStore %88 %90\n%91 = OpAccessChain %31 %13 %92\nOpStore %91 %93\n%94 = OpAccessChain %31 %13 %95\nOpStore %94 %96\n%97 = OpAccessChain %31 %13 %98\nOpStore %97 %99\n%100 = OpUGreaterThan %25 %24 %40\nOpBranch %174\n%174 = OpLabel\n%101 = OpAccessChain %31 %13 %102\nOpStore %101 %103\n%104 = OpAccessChain %31 %13 %105\nOpStore %104 %106\n%107 = OpAccessChain %31 %13 %108\nOpStore %107 %109\n%110 = OpAccessChain %31 %13 %111\nOpStore %110 %112\n%113 = OpUGreaterThan %25 %24 %44\nOpSelectionMerge %182 None\nOpBranchConditional %113 %175 %182\n%175 = OpLabel\n%114 = OpAccessChain %31 %13 %115\nOpStore %114 %116\n%117 = OpAccessChain %31 %13 %118\nOpStore %117 %119\n%120 = OpAccessChain %31 %13 %121\nOpStore %120 %122\n%123 = OpAccessChain %31 %13 %124\nOpStore %123 %125\n%126 = OpUGreaterThan %25 %24 %47\nOpSelectionMerge %181 None\nOpBranchConditional %126 %176 %181\n%176 = OpLabel\n%127 = OpAccessChain %31 %13 %128\nOpStore %127 %129\n%130 = OpAccessChain %31 %13 %131\nOpStore %130 %132\n%133 = OpAccessChain %31 %13 %134\nOpStore %133 %135\n%136 = OpAccessChain %31 %13 %137\nOpStore %136 %138\n%139 = OpUGreaterThan %25 %24 %50\nOpSelectionMerge %180 None\nOpBranchConditional %139 %177 %180\n%177 = OpLabel\n%140 = OpAccessChain %31 %13 %141\nOpStore %140 %142\n%143 = OpAccessChain %31 %13 %144\nOpStore %143 %145\n%146 = OpAccessChain %31 %13 %147\nOpStore %146 %148\n%149 = OpAccessChain %31 %13 %150\nOpStore %149 %151\n%152 = OpUGreaterThan %25 %24 %53\nOpSelectionMerge %179 None\nOpBranchConditional %152 %178 %179\n%178 = OpLabel\n%153 = OpAccessChain %31 %13 %154\nOpStore %153 %155\n%156 = OpAccessChain %31 %13 %157\nOpStore %156 %158\n%159 = OpAccessChain %31 %13 %160\nOpStore %159 %161\n%162 = OpAccessChain %31 %13 %163\nOpStore %162 %164\n%165 = OpUGreaterThan %25 %24 %89\nOpBranch %179\n%179 = OpLabel\n%166 = OpPhi %25 %26 %178 %26 %177\nOpBranch %180\n%180 = OpLabel\n%167 = OpPhi %25 %26 %176 %166 %179\nOpBranch %181\n%181 = OpLabel\n%168 = OpPhi %25 %26 %175 %167 %180\nOpBranch %182\n%182 = OpLabel\n%169 = OpPhi %25 %26 %174 %168 %181\nOpBranch %183\n%183 = OpLabel\n%27 = OpPhi %25 %28 %170 %169 %182\nOpControlBarrier %29 %29 %30\nOpSelectionMerge %187 None\nOpBranchConditional %27 %187 %184\n%184 = OpLabel\nOpBranch %185\n%185 = OpLabel\n%56 = OpPhi %5 %20 %184 %57 %185\n%58 = OpIMul %5 %56 %44\n%59 = OpIAdd %5 %20 %58\n%60 = OpAccessChain %31 %13 %59\n%61 = OpLoad %10 %60\n%62 = OpIMul %5 %56 %44\n%63 = OpIAdd %5 %35 %62\n%64 = OpAccessChain %31 %13 %63\n%65 = OpLoad %10 %64\n%66 = OpIMul %5 %56 %44\n%67 = OpIAdd %5 %29 %66\n%68 = OpAccessChain %31 %13 %67\n%69 = OpLoad %10 %68\n%70 = OpIMul %5 %56 %44\n%71 = OpIAdd %5 %40 %70\n%72 = OpAccessChain %31 %13 %71\n%73 = OpLoad %10 %72\n%74 = OpIMul %5 %21 %44\n%75 = OpBitcast %5 %61\n%76 = OpBitcast %5 %65\n%77 = OpBitcast %5 %69\n%78 = OpBitcast %5 %73\n%80 = OpCompositeConstruct %79 %75 %75 %75 %75\nOpImageWrite %14 %74 %80\n%81 = OpCompositeConstruct %79 %76 %76 %76 %76\n%82 = OpIAdd %5 %74 %35\nOpImageWrite %14 %82 %81\n%83 = OpCompositeConstruct %79 %77 %77 %77 %77\n%84 = OpIAdd %5 %74 %29\nOpImageWrite %14 %84 %83\n%85 = OpCompositeConstruct %79 %78 %78 %78 %78\n%86 = OpIAdd %5 %74 %40\nOpImageWrite %14 %86 %85\n%57 = OpIAdd %5 %56 %35\n%87 = OpULessThan %25 %57 %24\nOpLoopMerge %186 %185 None\nOpBranchConditional %87 %185 %186\n%186 = OpLabel\nOpBranch %187\n%187 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/acceleration-structure.bindless.descriptor-qa.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nstruct _15\n{\n    vec4 _m0;\n};\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _12[];\nlayout(location = 0) rayPayloadEXT _15 _17;\nlayout(location = 1) rayPayloadEXT _15 _18;\nlayout(location = 2) rayPayloadEXT _15 _19;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _47 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_47 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _84 = QAHeapData.descriptor_count;\n    uint _86 = QAHeapData.heap_index;\n    uint _89 = QAGlobalData.va_map_timestamp;\n    uvec3 _92 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _101 = QAGlobalData.live_status_table[_92.x >> 5u];\n    uint _115 = ((uint(heap_offset >= _84) | (((_92.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_101 & (1u << (_92.x & 31u))) != 0u) ? 0u : 4u)) | ((_89 >= _92.y) ? 0u : 8u);\n    if (_115 != 0u)\n    {\n        descriptor_qa_report_fault(_115, heap_offset, _92.x, _86, descriptor_type_mask, _92.z, instruction);\n        return _84;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    uint _28 = descriptor_qa_check(registers._m0 + 110u, 64u, 1u);\n    _19._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n    traceRayEXT(_12[_28], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 2);\n    uint _140 = descriptor_qa_check(registers._m0 + 3u, 64u, 2u);\n    _18._m0 = _19._m0;\n    traceRayEXT(_12[_140], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    uint _154 = descriptor_qa_check((registers._m0 + 100u) + uint(int(_18._m0.w)), 64u, 3u);\n    _17._m0 = _18._m0;\n    traceRayEXT(_12[nonuniformEXT(_154)], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 161\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %17 %18 %19 %33 %76\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"\"\nOpName %31 \"DescriptorHeapGlobalQAData\"\nOpMemberName %31 0 \"failed_shader_hash\"\nOpMemberName %31 1 \"failed_offset\"\nOpMemberName %31 2 \"failed_heap\"\nOpMemberName %31 3 \"failed_cookie\"\nOpMemberName %31 4 \"fault_atomic\"\nOpMemberName %31 5 \"failed_instruction\"\nOpMemberName %31 6 \"failed_descriptor_type_mask\"\nOpMemberName %31 7 \"actual_descriptor_type_mask\"\nOpMemberName %31 8 \"fault_type\"\nOpMemberName %31 9 \"va_map_timestamp\"\nOpMemberName %31 10 \"live_status_table\"\nOpName %33 \"QAGlobalData\"\nOpName %42 \"descriptor_qa_report_fault\"\nOpName %35 \"fault_type\"\nOpName %36 \"heap_offset\"\nOpName %37 \"cookie\"\nOpName %38 \"heap_index\"\nOpName %39 \"descriptor_type\"\nOpName %40 \"actual_descriptor_type\"\nOpName %41 \"instruction\"\nOpName %74 \"DescriptorHeapQAData\"\nOpMemberName %74 0 \"descriptor_count\"\nOpMemberName %74 1 \"heap_index\"\nOpMemberName %74 2 \"cookies_descriptor_info\"\nOpName %76 \"QAHeapData\"\nOpName %81 \"descriptor_qa_check\"\nOpName %78 \"heap_offset\"\nOpName %79 \"descriptor_type_mask\"\nOpName %80 \"instruction\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %30 ArrayStride 4\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 1 Offset 8\nOpMemberDecorate %31 2 Offset 12\nOpMemberDecorate %31 3 Offset 16\nOpMemberDecorate %31 4 Offset 20\nOpMemberDecorate %31 5 Offset 24\nOpMemberDecorate %31 6 Offset 28\nOpMemberDecorate %31 7 Offset 32\nOpMemberDecorate %31 8 Offset 36\nOpMemberDecorate %31 9 Offset 40\nOpMemberDecorate %31 10 Offset 44\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 10\nOpDecorate %33 Binding 10\nOpDecorate %73 ArrayStride 12\nOpMemberDecorate %74 0 Offset 0\nOpMemberDecorate %74 1 Offset 4\nOpMemberDecorate %74 2 Offset 8\nOpDecorate %74 Block\nOpDecorate %76 DescriptorSet 10\nOpDecorate %76 Binding 11\nOpDecorate %76 NonWritable\nOpDecorate %154 NonUniform\nOpDecorate %155 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeAccelerationStructureKHR\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeStruct %14\n%16 = OpTypePointer RayPayloadKHR %15\n%17 = OpVariable %16 RayPayloadKHR\n%18 = OpVariable %16 RayPayloadKHR\n%19 = OpVariable %16 RayPayloadKHR\n%20 = OpTypePointer UniformConstant %9\n%22 = OpTypePointer PushConstant %5\n%24 = OpConstant %5 0\n%27 = OpConstant %5 110\n%29 = OpTypeVector %5 2\n%30 = OpTypeRuntimeArray %5\n%31 = OpTypeStruct %29 %5 %5 %5 %5 %5 %5 %5 %5 %5 %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%44 = OpTypePointer StorageBuffer %5\n%46 = OpConstant %5 4\n%48 = OpConstant %5 1\n%49 = OpTypeBool\n%54 = OpConstant %5 3\n%57 = OpConstant %5 2\n%59 = OpConstant %5 6\n%61 = OpConstant %5 7\n%63 = OpConstant %5 5\n%64 = OpConstant %5 3735928559\n%65 = OpConstantComposite %29 %64 %24\n%66 = OpTypePointer StorageBuffer %29\n%68 = OpConstant %5 72\n%70 = OpConstant %5 8\n%72 = OpTypeVector %5 3\n%73 = OpTypeRuntimeArray %72\n%74 = OpTypeStruct %5 %5 %73\n%75 = OpTypePointer StorageBuffer %74\n%76 = OpVariable %75 StorageBuffer\n%77 = OpTypeFunction %5 %5 %5 %5\n%88 = OpConstant %5 9\n%90 = OpTypePointer StorageBuffer %72\n%98 = OpConstant %5 31\n%100 = OpConstant %5 10\n%122 = OpConstant %5 64\n%124 = OpTypePointer RayPayloadKHR %14\n%126 = OpConstant %13 1\n%127 = OpConstant %13 2\n%128 = OpConstant %13 3\n%129 = OpConstant %13 4\n%130 = OpConstantComposite %14 %126 %127 %128 %129\n%131 = OpConstant %13 0\n%132 = OpTypeVector %13 3\n%152 = OpConstant %5 100\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %159\n%159 = OpLabel\n%23 = OpAccessChain %22 %8 %24\n%25 = OpLoad %5 %23\n%26 = OpIAdd %5 %25 %27\n%28 = OpFunctionCall %5 %81 %26 %122 %48\n%21 = OpAccessChain %20 %12 %28\n%123 = OpLoad %9 %21\n%125 = OpInBoundsAccessChain %124 %19 %24\nOpStore %125 %130\n%133 = OpCompositeConstruct %132 %126 %127 %128\n%134 = OpCompositeConstruct %132 %131 %131 %126\nOpTraceRayKHR %123 %24 %24 %24 %24 %24 %133 %126 %134 %129 %19\n%135 = OpLoad %14 %125\n%137 = OpAccessChain %22 %8 %24\n%138 = OpLoad %5 %137\n%139 = OpIAdd %5 %138 %54\n%140 = OpFunctionCall %5 %81 %139 %122 %57\n%136 = OpAccessChain %20 %12 %140\n%141 = OpLoad %9 %136\n%142 = OpInBoundsAccessChain %124 %18 %24\nOpStore %142 %135\n%143 = OpCompositeConstruct %132 %126 %127 %128\n%144 = OpCompositeConstruct %132 %131 %131 %126\nOpTraceRayKHR %141 %24 %24 %24 %24 %24 %143 %126 %144 %129 %18\n%145 = OpLoad %14 %142\n%146 = OpCompositeExtract %13 %145 3\n%147 = OpConvertFToS %5 %146\n%149 = OpAccessChain %22 %8 %24\n%150 = OpLoad %5 %149\n%151 = OpIAdd %5 %150 %152\n%153 = OpIAdd %5 %151 %147\n%154 = OpFunctionCall %5 %81 %153 %122 %54\n%148 = OpAccessChain %20 %12 %154\n%155 = OpLoad %9 %148\n%156 = OpInBoundsAccessChain %124 %17 %24\nOpStore %156 %145\n%157 = OpCompositeConstruct %132 %126 %127 %128\n%158 = OpCompositeConstruct %132 %131 %131 %126\nOpTraceRayKHR %155 %24 %24 %24 %24 %24 %157 %126 %158 %129 %17\nOpReturn\nOpFunctionEnd\n%42 = OpFunction %1 None %34\n%35 = OpFunctionParameter %5\n%36 = OpFunctionParameter %5\n%37 = OpFunctionParameter %5\n%38 = OpFunctionParameter %5\n%39 = OpFunctionParameter %5\n%40 = OpFunctionParameter %5\n%41 = OpFunctionParameter %5\n%43 = OpLabel\n%45 = OpAccessChain %44 %33 %46\n%47 = OpAtomicIAdd %5 %45 %48 %24 %48\n%50 = OpIEqual %49 %47 %24\nOpSelectionMerge %52 None\nOpBranchConditional %50 %51 %52\n%51 = OpLabel\n%53 = OpAccessChain %44 %33 %54\nOpStore %53 %37\n%55 = OpAccessChain %44 %33 %48\nOpStore %55 %36\n%56 = OpAccessChain %44 %33 %57\nOpStore %56 %38\n%58 = OpAccessChain %44 %33 %59\nOpStore %58 %39\n%60 = OpAccessChain %44 %33 %61\nOpStore %60 %40\n%62 = OpAccessChain %44 %33 %63\nOpStore %62 %41\n%67 = OpAccessChain %66 %33 %24\nOpStore %67 %65\nOpMemoryBarrier %48 %68\n%69 = OpAccessChain %44 %33 %70\nOpStore %69 %35\nOpBranch %52\n%52 = OpLabel\nOpReturn\nOpFunctionEnd\n%81 = OpFunction %5 None %77\n%78 = OpFunctionParameter %5\n%79 = OpFunctionParameter %5\n%80 = OpFunctionParameter %5\n%82 = OpLabel\n%83 = OpAccessChain %44 %76 %24\n%84 = OpLoad %5 %83\n%85 = OpAccessChain %44 %76 %48\n%86 = OpLoad %5 %85\n%87 = OpAccessChain %44 %33 %88\n%89 = OpLoad %5 %87\n%91 = OpAccessChain %90 %76 %57 %78\n%92 = OpLoad %72 %91\n%93 = OpCompositeExtract %5 %92 0\n%94 = OpCompositeExtract %5 %92 1\n%95 = OpCompositeExtract %5 %92 2\n%96 = OpShiftRightLogical %5 %93 %63\n%97 = OpBitwiseAnd %5 %93 %98\n%99 = OpAccessChain %44 %33 %100 %96\n%101 = OpLoad %5 %99\n%102 = OpShiftLeftLogical %5 %48 %97\n%103 = OpBitwiseAnd %5 %101 %102\n%104 = OpINotEqual %49 %103 %24\n%105 = OpBitwiseAnd %5 %95 %79\n%106 = OpIEqual %49 %105 %79\n%107 = OpUGreaterThanEqual %49 %78 %84\n%108 = OpSelect %5 %107 %48 %24\n%109 = OpSelect %5 %106 %24 %57\n%110 = OpSelect %5 %104 %24 %46\n%111 = OpUGreaterThanEqual %49 %89 %94\n%112 = OpSelect %5 %111 %24 %70\n%113 = OpBitwiseOr %5 %108 %109\n%114 = OpBitwiseOr %5 %113 %110\n%115 = OpBitwiseOr %5 %114 %112\n%116 = OpINotEqual %49 %115 %24\nOpSelectionMerge %118 None\nOpBranchConditional %116 %117 %118\n%117 = OpLabel\n%119 = OpFunctionCall %1 %42 %115 %78 %93 %86 %79 %95 %80\nOpReturnValue %84\n%118 = OpLabel\nOpReturnValue %78\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/acceleration-structure.bindless.descriptor-qa.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nstruct _15\n{\n    vec4 _m0;\n};\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _12[];\nlayout(location = 0) rayPayloadEXT _15 _17;\nlayout(location = 1) rayPayloadEXT _15 _18;\nlayout(location = 2) rayPayloadEXT _15 _19;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _47 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_47 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _84 = QAHeapData.descriptor_count;\n    uint _86 = QAHeapData.heap_index;\n    uint _89 = QAGlobalData.va_map_timestamp;\n    uvec3 _92 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _101 = QAGlobalData.live_status_table[_92.x >> 5u];\n    uint _115 = ((uint(heap_offset >= _84) | (((_92.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_101 & (1u << (_92.x & 31u))) != 0u) ? 0u : 4u)) | ((_89 >= _92.y) ? 0u : 8u);\n    if (_115 != 0u)\n    {\n        descriptor_qa_report_fault(_115, heap_offset, _92.x, _86, descriptor_type_mask, _92.z, instruction);\n        return _84;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    uint _28 = descriptor_qa_check(registers._m0 + 110u, 64u, 1u);\n    _19._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n    traceRayEXT(_12[_28], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 2);\n    uint _140 = descriptor_qa_check(registers._m0 + 3u, 64u, 2u);\n    _18._m0 = _19._m0;\n    traceRayEXT(_12[_140], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    uint _154 = descriptor_qa_check((registers._m0 + 100u) + uint(int(_18._m0.w)), 64u, 3u);\n    _17._m0 = _18._m0;\n    traceRayEXT(_12[nonuniformEXT(_154)], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 161\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %17 %18 %19 %33 %76\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"\"\nOpName %31 \"DescriptorHeapGlobalQAData\"\nOpMemberName %31 0 \"failed_shader_hash\"\nOpMemberName %31 1 \"failed_offset\"\nOpMemberName %31 2 \"failed_heap\"\nOpMemberName %31 3 \"failed_cookie\"\nOpMemberName %31 4 \"fault_atomic\"\nOpMemberName %31 5 \"failed_instruction\"\nOpMemberName %31 6 \"failed_descriptor_type_mask\"\nOpMemberName %31 7 \"actual_descriptor_type_mask\"\nOpMemberName %31 8 \"fault_type\"\nOpMemberName %31 9 \"va_map_timestamp\"\nOpMemberName %31 10 \"live_status_table\"\nOpName %33 \"QAGlobalData\"\nOpName %42 \"descriptor_qa_report_fault\"\nOpName %35 \"fault_type\"\nOpName %36 \"heap_offset\"\nOpName %37 \"cookie\"\nOpName %38 \"heap_index\"\nOpName %39 \"descriptor_type\"\nOpName %40 \"actual_descriptor_type\"\nOpName %41 \"instruction\"\nOpName %74 \"DescriptorHeapQAData\"\nOpMemberName %74 0 \"descriptor_count\"\nOpMemberName %74 1 \"heap_index\"\nOpMemberName %74 2 \"cookies_descriptor_info\"\nOpName %76 \"QAHeapData\"\nOpName %81 \"descriptor_qa_check\"\nOpName %78 \"heap_offset\"\nOpName %79 \"descriptor_type_mask\"\nOpName %80 \"instruction\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %30 ArrayStride 4\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 1 Offset 8\nOpMemberDecorate %31 2 Offset 12\nOpMemberDecorate %31 3 Offset 16\nOpMemberDecorate %31 4 Offset 20\nOpMemberDecorate %31 5 Offset 24\nOpMemberDecorate %31 6 Offset 28\nOpMemberDecorate %31 7 Offset 32\nOpMemberDecorate %31 8 Offset 36\nOpMemberDecorate %31 9 Offset 40\nOpMemberDecorate %31 10 Offset 44\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 10\nOpDecorate %33 Binding 10\nOpDecorate %73 ArrayStride 12\nOpMemberDecorate %74 0 Offset 0\nOpMemberDecorate %74 1 Offset 4\nOpMemberDecorate %74 2 Offset 8\nOpDecorate %74 Block\nOpDecorate %76 DescriptorSet 10\nOpDecorate %76 Binding 11\nOpDecorate %76 NonWritable\nOpDecorate %154 NonUniform\nOpDecorate %155 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeAccelerationStructureKHR\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeStruct %14\n%16 = OpTypePointer RayPayloadKHR %15\n%17 = OpVariable %16 RayPayloadKHR\n%18 = OpVariable %16 RayPayloadKHR\n%19 = OpVariable %16 RayPayloadKHR\n%20 = OpTypePointer UniformConstant %9\n%22 = OpTypePointer PushConstant %5\n%24 = OpConstant %5 0\n%27 = OpConstant %5 110\n%29 = OpTypeVector %5 2\n%30 = OpTypeRuntimeArray %5\n%31 = OpTypeStruct %29 %5 %5 %5 %5 %5 %5 %5 %5 %5 %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%44 = OpTypePointer StorageBuffer %5\n%46 = OpConstant %5 4\n%48 = OpConstant %5 1\n%49 = OpTypeBool\n%54 = OpConstant %5 3\n%57 = OpConstant %5 2\n%59 = OpConstant %5 6\n%61 = OpConstant %5 7\n%63 = OpConstant %5 5\n%64 = OpConstant %5 3735928559\n%65 = OpConstantComposite %29 %64 %24\n%66 = OpTypePointer StorageBuffer %29\n%68 = OpConstant %5 72\n%70 = OpConstant %5 8\n%72 = OpTypeVector %5 3\n%73 = OpTypeRuntimeArray %72\n%74 = OpTypeStruct %5 %5 %73\n%75 = OpTypePointer StorageBuffer %74\n%76 = OpVariable %75 StorageBuffer\n%77 = OpTypeFunction %5 %5 %5 %5\n%88 = OpConstant %5 9\n%90 = OpTypePointer StorageBuffer %72\n%98 = OpConstant %5 31\n%100 = OpConstant %5 10\n%122 = OpConstant %5 64\n%124 = OpTypePointer RayPayloadKHR %14\n%126 = OpConstant %13 1\n%127 = OpConstant %13 2\n%128 = OpConstant %13 3\n%129 = OpConstant %13 4\n%130 = OpConstantComposite %14 %126 %127 %128 %129\n%131 = OpConstant %13 0\n%132 = OpTypeVector %13 3\n%152 = OpConstant %5 100\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %159\n%159 = OpLabel\n%23 = OpAccessChain %22 %8 %24\n%25 = OpLoad %5 %23\n%26 = OpIAdd %5 %25 %27\n%28 = OpFunctionCall %5 %81 %26 %122 %48\n%21 = OpAccessChain %20 %12 %28\n%123 = OpLoad %9 %21\n%125 = OpInBoundsAccessChain %124 %19 %24\nOpStore %125 %130\n%133 = OpCompositeConstruct %132 %126 %127 %128\n%134 = OpCompositeConstruct %132 %131 %131 %126\nOpTraceRayKHR %123 %24 %24 %24 %24 %24 %133 %126 %134 %129 %19\n%135 = OpLoad %14 %125\n%137 = OpAccessChain %22 %8 %24\n%138 = OpLoad %5 %137\n%139 = OpIAdd %5 %138 %54\n%140 = OpFunctionCall %5 %81 %139 %122 %57\n%136 = OpAccessChain %20 %12 %140\n%141 = OpLoad %9 %136\n%142 = OpInBoundsAccessChain %124 %18 %24\nOpStore %142 %135\n%143 = OpCompositeConstruct %132 %126 %127 %128\n%144 = OpCompositeConstruct %132 %131 %131 %126\nOpTraceRayKHR %141 %24 %24 %24 %24 %24 %143 %126 %144 %129 %18\n%145 = OpLoad %14 %142\n%146 = OpCompositeExtract %13 %145 3\n%147 = OpConvertFToS %5 %146\n%149 = OpAccessChain %22 %8 %24\n%150 = OpLoad %5 %149\n%151 = OpIAdd %5 %150 %152\n%153 = OpIAdd %5 %151 %147\n%154 = OpFunctionCall %5 %81 %153 %122 %54\n%148 = OpAccessChain %20 %12 %154\n%155 = OpLoad %9 %148\n%156 = OpInBoundsAccessChain %124 %17 %24\nOpStore %156 %145\n%157 = OpCompositeConstruct %132 %126 %127 %128\n%158 = OpCompositeConstruct %132 %131 %131 %126\nOpTraceRayKHR %155 %24 %24 %24 %24 %24 %157 %126 %158 %129 %17\nOpReturn\nOpFunctionEnd\n%42 = OpFunction %1 None %34\n%35 = OpFunctionParameter %5\n%36 = OpFunctionParameter %5\n%37 = OpFunctionParameter %5\n%38 = OpFunctionParameter %5\n%39 = OpFunctionParameter %5\n%40 = OpFunctionParameter %5\n%41 = OpFunctionParameter %5\n%43 = OpLabel\n%45 = OpAccessChain %44 %33 %46\n%47 = OpAtomicIAdd %5 %45 %48 %24 %48\n%50 = OpIEqual %49 %47 %24\nOpSelectionMerge %52 None\nOpBranchConditional %50 %51 %52\n%51 = OpLabel\n%53 = OpAccessChain %44 %33 %54\nOpStore %53 %37\n%55 = OpAccessChain %44 %33 %48\nOpStore %55 %36\n%56 = OpAccessChain %44 %33 %57\nOpStore %56 %38\n%58 = OpAccessChain %44 %33 %59\nOpStore %58 %39\n%60 = OpAccessChain %44 %33 %61\nOpStore %60 %40\n%62 = OpAccessChain %44 %33 %63\nOpStore %62 %41\n%67 = OpAccessChain %66 %33 %24\nOpStore %67 %65\nOpMemoryBarrier %48 %68\n%69 = OpAccessChain %44 %33 %70\nOpStore %69 %35\nOpBranch %52\n%52 = OpLabel\nOpReturn\nOpFunctionEnd\n%81 = OpFunction %5 None %77\n%78 = OpFunctionParameter %5\n%79 = OpFunctionParameter %5\n%80 = OpFunctionParameter %5\n%82 = OpLabel\n%83 = OpAccessChain %44 %76 %24\n%84 = OpLoad %5 %83\n%85 = OpAccessChain %44 %76 %48\n%86 = OpLoad %5 %85\n%87 = OpAccessChain %44 %33 %88\n%89 = OpLoad %5 %87\n%91 = OpAccessChain %90 %76 %57 %78\n%92 = OpLoad %72 %91\n%93 = OpCompositeExtract %5 %92 0\n%94 = OpCompositeExtract %5 %92 1\n%95 = OpCompositeExtract %5 %92 2\n%96 = OpShiftRightLogical %5 %93 %63\n%97 = OpBitwiseAnd %5 %93 %98\n%99 = OpAccessChain %44 %33 %100 %96\n%101 = OpLoad %5 %99\n%102 = OpShiftLeftLogical %5 %48 %97\n%103 = OpBitwiseAnd %5 %101 %102\n%104 = OpINotEqual %49 %103 %24\n%105 = OpBitwiseAnd %5 %95 %79\n%106 = OpIEqual %49 %105 %79\n%107 = OpUGreaterThanEqual %49 %78 %84\n%108 = OpSelect %5 %107 %48 %24\n%109 = OpSelect %5 %106 %24 %57\n%110 = OpSelect %5 %104 %24 %46\n%111 = OpUGreaterThanEqual %49 %89 %94\n%112 = OpSelect %5 %111 %24 %70\n%113 = OpBitwiseOr %5 %108 %109\n%114 = OpBitwiseOr %5 %113 %110\n%115 = OpBitwiseOr %5 %114 %112\n%116 = OpINotEqual %49 %115 %24\nOpSelectionMerge %118 None\nOpBranchConditional %116 %117 %118\n%117 = OpLabel\n%119 = OpFunctionCall %1 %42 %115 %78 %93 %86 %79 %95 %80\nOpReturnValue %84\n%118 = OpLabel\nOpReturnValue %78\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/acceleration-structure.bindless.ssbo-rtas.local-root-signature.descriptor-qa.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _23\n{\n    vec4 _m0;\n};\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer RTASHeap\n{\n    uvec2 _m0[];\n} _20;\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) rayPayloadEXT _23 _25;\nlayout(location = 1) rayPayloadEXT _23 _26;\nlayout(location = 2) rayPayloadEXT _23 _27;\nlayout(location = 3) rayPayloadEXT _23 _28;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _53 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_53 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _88 = QAHeapData.descriptor_count;\n    uint _90 = QAHeapData.heap_index;\n    uint _93 = QAGlobalData.va_map_timestamp;\n    uvec3 _96 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _105 = QAGlobalData.live_status_table[_96.x >> 5u];\n    uint _119 = ((uint(heap_offset >= _88) | (((_96.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_105 & (1u << (_96.x & 31u))) != 0u) ? 0u : 4u)) | ((_93 >= _96.y) ? 0u : 8u);\n    if (_119 != 0u)\n    {\n        descriptor_qa_report_fault(_119, heap_offset, _96.x, _90, descriptor_type_mask, _96.z, instruction);\n        return _88;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    uint _35 = descriptor_qa_check(registers._m0 + 110u, 320u, 1u);\n    _28._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n    traceRayEXT(accelerationStructureEXT(_20._m0[subgroupBroadcastFirst(_35)]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 3);\n    uint _147 = descriptor_qa_check(registers._m0 + 3u, 320u, 2u);\n    _27._m0 = _28._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[subgroupBroadcastFirst(_147)]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 2);\n    uint _163 = descriptor_qa_check((registers._m0 + 100u) + uint(int(_27._m0.w)), 320u, 3u);\n    _26._m0 = _27._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[_163]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    uint _177 = descriptor_qa_check((SBT._m7.x >> 6u) + 210u, 320u, 4u);\n    _25._m0 = _26._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[subgroupBroadcastFirst(_177)]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 187\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %16 %20 %25 %26 %27 %28 %39 %80\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %14 \"SBTBlock\"\nOpName %16 \"SBT\"\nOpName %18 \"RTASHeap\"\nOpName %23 \"\"\nOpName %37 \"DescriptorHeapGlobalQAData\"\nOpMemberName %37 0 \"failed_shader_hash\"\nOpMemberName %37 1 \"failed_offset\"\nOpMemberName %37 2 \"failed_heap\"\nOpMemberName %37 3 \"failed_cookie\"\nOpMemberName %37 4 \"fault_atomic\"\nOpMemberName %37 5 \"failed_instruction\"\nOpMemberName %37 6 \"failed_descriptor_type_mask\"\nOpMemberName %37 7 \"actual_descriptor_type_mask\"\nOpMemberName %37 8 \"fault_type\"\nOpMemberName %37 9 \"va_map_timestamp\"\nOpMemberName %37 10 \"live_status_table\"\nOpName %39 \"QAGlobalData\"\nOpName %48 \"descriptor_qa_report_fault\"\nOpName %41 \"fault_type\"\nOpName %42 \"heap_offset\"\nOpName %43 \"cookie\"\nOpName %44 \"heap_index\"\nOpName %45 \"descriptor_type\"\nOpName %46 \"actual_descriptor_type\"\nOpName %47 \"instruction\"\nOpName %78 \"DescriptorHeapQAData\"\nOpMemberName %78 0 \"descriptor_count\"\nOpMemberName %78 1 \"heap_index\"\nOpMemberName %78 2 \"cookies_descriptor_info\"\nOpName %80 \"QAHeapData\"\nOpName %85 \"descriptor_qa_check\"\nOpName %82 \"heap_offset\"\nOpName %83 \"descriptor_type_mask\"\nOpName %84 \"instruction\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 4\nOpDecorate %12 ArrayStride 4\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpMemberDecorate %14 1 Offset 20\nOpMemberDecorate %14 2 Offset 48\nOpMemberDecorate %14 3 Offset 56\nOpMemberDecorate %14 4 Offset 64\nOpMemberDecorate %14 5 Offset 72\nOpMemberDecorate %14 6 Offset 80\nOpMemberDecorate %14 7 Offset 88\nOpMemberDecorate %14 8 Offset 96\nOpMemberDecorate %14 9 Offset 104\nOpMemberDecorate %14 10 Offset 112\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %36 ArrayStride 4\nOpMemberDecorate %37 0 Offset 0\nOpMemberDecorate %37 1 Offset 8\nOpMemberDecorate %37 2 Offset 12\nOpMemberDecorate %37 3 Offset 16\nOpMemberDecorate %37 4 Offset 20\nOpMemberDecorate %37 5 Offset 24\nOpMemberDecorate %37 6 Offset 28\nOpMemberDecorate %37 7 Offset 32\nOpMemberDecorate %37 8 Offset 36\nOpMemberDecorate %37 9 Offset 40\nOpMemberDecorate %37 10 Offset 44\nOpDecorate %37 Block\nOpDecorate %39 DescriptorSet 10\nOpDecorate %39 Binding 10\nOpDecorate %77 ArrayStride 12\nOpMemberDecorate %78 0 Offset 0\nOpMemberDecorate %78 1 Offset 4\nOpMemberDecorate %78 2 Offset 8\nOpDecorate %78 Block\nOpDecorate %80 DescriptorSet 10\nOpDecorate %80 Binding 11\nOpDecorate %80 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpConstant %5 5\n%10 = OpTypeArray %5 %9\n%11 = OpConstant %5 6\n%12 = OpTypeArray %5 %11\n%13 = OpTypeVector %5 2\n%14 = OpTypeStruct %10 %12 %13 %13 %13 %13 %13 %13 %13 %13 %13\n%15 = OpTypePointer ShaderRecordBufferKHR %14\n%16 = OpVariable %15 ShaderRecordBufferKHR\n%17 = OpTypeRuntimeArray %13\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypeStruct %22\n%24 = OpTypePointer RayPayloadKHR %23\n%25 = OpVariable %24 RayPayloadKHR\n%26 = OpVariable %24 RayPayloadKHR\n%27 = OpVariable %24 RayPayloadKHR\n%28 = OpVariable %24 RayPayloadKHR\n%29 = OpTypePointer PushConstant %5\n%31 = OpConstant %5 0\n%34 = OpConstant %5 110\n%36 = OpTypeRuntimeArray %5\n%37 = OpTypeStruct %13 %5 %5 %5 %5 %5 %5 %5 %5 %5 %36\n%38 = OpTypePointer StorageBuffer %37\n%39 = OpVariable %38 StorageBuffer\n%40 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%50 = OpTypePointer StorageBuffer %5\n%52 = OpConstant %5 4\n%54 = OpConstant %5 1\n%55 = OpTypeBool\n%60 = OpConstant %5 3\n%63 = OpConstant %5 2\n%66 = OpConstant %5 7\n%68 = OpConstant %5 3735928559\n%69 = OpConstantComposite %13 %68 %31\n%70 = OpTypePointer StorageBuffer %13\n%72 = OpConstant %5 72\n%74 = OpConstant %5 8\n%76 = OpTypeVector %5 3\n%77 = OpTypeRuntimeArray %76\n%78 = OpTypeStruct %5 %5 %77\n%79 = OpTypePointer StorageBuffer %78\n%80 = OpVariable %79 StorageBuffer\n%81 = OpTypeFunction %5 %5 %5 %5\n%92 = OpConstant %5 9\n%94 = OpTypePointer StorageBuffer %76\n%102 = OpConstant %5 31\n%104 = OpConstant %5 10\n%126 = OpConstant %5 320\n%130 = OpTypeAccelerationStructureKHR\n%132 = OpTypePointer RayPayloadKHR %22\n%134 = OpConstant %21 1\n%135 = OpConstant %21 2\n%136 = OpConstant %21 3\n%137 = OpConstant %21 4\n%138 = OpConstantComposite %22 %134 %135 %136 %137\n%139 = OpConstant %21 0\n%140 = OpTypeVector %21 3\n%161 = OpConstant %5 100\n%171 = OpTypePointer ShaderRecordBufferKHR %5\n%176 = OpConstant %5 210\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %185\n%185 = OpLabel\n%30 = OpAccessChain %29 %8 %31\n%32 = OpLoad %5 %30\n%33 = OpIAdd %5 %32 %34\n%35 = OpFunctionCall %5 %85 %33 %126 %54\n%127 = OpGroupNonUniformBroadcastFirst %5 %60 %35\n%128 = OpAccessChain %70 %20 %31 %127\n%129 = OpLoad %13 %128\n%131 = OpConvertUToAccelerationStructureKHR %130 %129\n%133 = OpInBoundsAccessChain %132 %28 %31\nOpStore %133 %138\n%141 = OpCompositeConstruct %140 %134 %135 %136\n%142 = OpCompositeConstruct %140 %139 %139 %134\nOpTraceRayKHR %131 %31 %31 %31 %31 %31 %141 %134 %142 %137 %28\n%143 = OpLoad %22 %133\n%144 = OpAccessChain %29 %8 %31\n%145 = OpLoad %5 %144\n%146 = OpIAdd %5 %145 %60\n%147 = OpFunctionCall %5 %85 %146 %126 %63\n%148 = OpGroupNonUniformBroadcastFirst %5 %60 %147\n%149 = OpAccessChain %70 %20 %31 %148\n%150 = OpLoad %13 %149\n%151 = OpConvertUToAccelerationStructureKHR %130 %150\n%152 = OpInBoundsAccessChain %132 %27 %31\nOpStore %152 %143\n%153 = OpCompositeConstruct %140 %134 %135 %136\n%154 = OpCompositeConstruct %140 %139 %139 %134\nOpTraceRayKHR %151 %31 %31 %31 %31 %31 %153 %134 %154 %137 %27\n%155 = OpLoad %22 %152\n%156 = OpCompositeExtract %21 %155 3\n%157 = OpConvertFToS %5 %156\n%158 = OpAccessChain %29 %8 %31\n%159 = OpLoad %5 %158\n%160 = OpIAdd %5 %159 %161\n%162 = OpIAdd %5 %160 %157\n%163 = OpFunctionCall %5 %85 %162 %126 %60\n%164 = OpAccessChain %70 %20 %31 %163\n%165 = OpLoad %13 %164\n%166 = OpConvertUToAccelerationStructureKHR %130 %165\n%167 = OpInBoundsAccessChain %132 %26 %31\nOpStore %167 %155\n%168 = OpCompositeConstruct %140 %134 %135 %136\n%169 = OpCompositeConstruct %140 %139 %139 %134\nOpTraceRayKHR %166 %31 %31 %31 %31 %31 %168 %134 %169 %137 %26\n%170 = OpLoad %22 %167\n%172 = OpAccessChain %171 %16 %66 %31\n%173 = OpLoad %5 %172\n%174 = OpShiftRightLogical %5 %173 %11\n%175 = OpIAdd %5 %174 %176\n%177 = OpFunctionCall %5 %85 %175 %126 %52\n%178 = OpGroupNonUniformBroadcastFirst %5 %60 %177\n%179 = OpAccessChain %70 %20 %31 %178\n%180 = OpLoad %13 %179\n%181 = OpConvertUToAccelerationStructureKHR %130 %180\n%182 = OpInBoundsAccessChain %132 %25 %31\nOpStore %182 %170\n%183 = OpCompositeConstruct %140 %134 %135 %136\n%184 = OpCompositeConstruct %140 %139 %139 %134\nOpTraceRayKHR %181 %31 %31 %31 %31 %31 %183 %134 %184 %137 %25\nOpReturn\nOpFunctionEnd\n%48 = OpFunction %1 None %40\n%41 = OpFunctionParameter %5\n%42 = OpFunctionParameter %5\n%43 = OpFunctionParameter %5\n%44 = OpFunctionParameter %5\n%45 = OpFunctionParameter %5\n%46 = OpFunctionParameter %5\n%47 = OpFunctionParameter %5\n%49 = OpLabel\n%51 = OpAccessChain %50 %39 %52\n%53 = OpAtomicIAdd %5 %51 %54 %31 %54\n%56 = OpIEqual %55 %53 %31\nOpSelectionMerge %58 None\nOpBranchConditional %56 %57 %58\n%57 = OpLabel\n%59 = OpAccessChain %50 %39 %60\nOpStore %59 %43\n%61 = OpAccessChain %50 %39 %54\nOpStore %61 %42\n%62 = OpAccessChain %50 %39 %63\nOpStore %62 %44\n%64 = OpAccessChain %50 %39 %11\nOpStore %64 %45\n%65 = OpAccessChain %50 %39 %66\nOpStore %65 %46\n%67 = OpAccessChain %50 %39 %9\nOpStore %67 %47\n%71 = OpAccessChain %70 %39 %31\nOpStore %71 %69\nOpMemoryBarrier %54 %72\n%73 = OpAccessChain %50 %39 %74\nOpStore %73 %41\nOpBranch %58\n%58 = OpLabel\nOpReturn\nOpFunctionEnd\n%85 = OpFunction %5 None %81\n%82 = OpFunctionParameter %5\n%83 = OpFunctionParameter %5\n%84 = OpFunctionParameter %5\n%86 = OpLabel\n%87 = OpAccessChain %50 %80 %31\n%88 = OpLoad %5 %87\n%89 = OpAccessChain %50 %80 %54\n%90 = OpLoad %5 %89\n%91 = OpAccessChain %50 %39 %92\n%93 = OpLoad %5 %91\n%95 = OpAccessChain %94 %80 %63 %82\n%96 = OpLoad %76 %95\n%97 = OpCompositeExtract %5 %96 0\n%98 = OpCompositeExtract %5 %96 1\n%99 = OpCompositeExtract %5 %96 2\n%100 = OpShiftRightLogical %5 %97 %9\n%101 = OpBitwiseAnd %5 %97 %102\n%103 = OpAccessChain %50 %39 %104 %100\n%105 = OpLoad %5 %103\n%106 = OpShiftLeftLogical %5 %54 %101\n%107 = OpBitwiseAnd %5 %105 %106\n%108 = OpINotEqual %55 %107 %31\n%109 = OpBitwiseAnd %5 %99 %83\n%110 = OpIEqual %55 %109 %83\n%111 = OpUGreaterThanEqual %55 %82 %88\n%112 = OpSelect %5 %111 %54 %31\n%113 = OpSelect %5 %110 %31 %63\n%114 = OpSelect %5 %108 %31 %52\n%115 = OpUGreaterThanEqual %55 %93 %98\n%116 = OpSelect %5 %115 %31 %74\n%117 = OpBitwiseOr %5 %112 %113\n%118 = OpBitwiseOr %5 %117 %114\n%119 = OpBitwiseOr %5 %118 %116\n%120 = OpINotEqual %55 %119 %31\nOpSelectionMerge %122 None\nOpBranchConditional %120 %121 %122\n%121 = OpLabel\n%123 = OpFunctionCall %1 %48 %119 %82 %97 %90 %83 %99 %84\nOpReturnValue %88\n%122 = OpLabel\nOpReturnValue %82\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/descriptor_qa.bindless.cbv-as-ssbo.descriptor-qa.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _33;\n\nlayout(set = 5, binding = 0, std430) readonly buffer BindlessCBV\n{\n    vec4 _m0[4096];\n} _47[];\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 1, binding = 0) uniform samplerBuffer _17[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _21[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _24[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _28[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _36[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _40[];\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _82 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_82 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _115 = QAHeapData.descriptor_count;\n    uint _117 = QAHeapData.heap_index;\n    uint _120 = QAGlobalData.va_map_timestamp;\n    uvec3 _123 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _132 = QAGlobalData.live_status_table[_123.x >> 5u];\n    uint _146 = ((uint(heap_offset >= _115) | (((_123.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_132 & (1u << (_123.x & 31u))) != 0u) ? 0u : 4u)) | ((_120 >= _123.y) ? 0u : 8u);\n    if (_146 != 0u)\n    {\n        descriptor_qa_report_fault(_146, heap_offset, _123.x, _117, descriptor_type_mask, _123.z, instruction);\n        return _115;\n    }\n    return heap_offset;\n}\n\nuint RobustPhysicalAtomicCounter(uvec2 _373, uint _374, uint _375)\n{\n    uint _388;\n    if (any(notEqual(_373, uvec2(0u))))\n    {\n        uint _386 = atomicAdd(uintPointer(_373).value, _374);\n        _388 = _386 + _375;\n    }\n    else\n    {\n        _388 = 0u;\n    }\n    return _388;\n}\n\nvoid main()\n{\n    float _157;\n    if (gl_GlobalInvocationID.x > 2u)\n    {\n        uint _64 = descriptor_qa_check(registers._m5, 8u, 1u);\n        _157 = _47[_64]._m0[0u].x;\n    }\n    else\n    {\n        _157 = 0.0;\n    }\n    float _170;\n    if (gl_GlobalInvocationID.x > 3u)\n    {\n        uint _165 = descriptor_qa_check(registers._m5 + (gl_GlobalInvocationID.x + 1u), 8u, 2u);\n        _170 = _47[_165]._m0[0u].x + _157;\n    }\n    else\n    {\n        _170 = _157;\n    }\n    float _182;\n    if (gl_GlobalInvocationID.x > 4u)\n    {\n        uint _176 = descriptor_qa_check(registers._m0, 1u, 3u);\n        _182 = texelFetch(_13[_176], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), int(0u)).x + _170;\n    }\n    else\n    {\n        _182 = _170;\n    }\n    float _196;\n    if (gl_GlobalInvocationID.x > 5u)\n    {\n        uint _190 = descriptor_qa_check(registers._m0 + ((gl_GlobalInvocationID.x & 1u) + 1u), 1u, 4u);\n        _196 = texelFetch(_13[_190], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), int(0u)).x + _182;\n    }\n    else\n    {\n        _196 = _182;\n    }\n    float _209;\n    if (gl_GlobalInvocationID.x > 6u)\n    {\n        uint _203 = descriptor_qa_check(registers._m1 + 3u, 16u, 5u);\n        _209 = texelFetch(_17[_203], int(gl_GlobalInvocationID.x)).x + _196;\n    }\n    else\n    {\n        _209 = _196;\n    }\n    float _222;\n    if (gl_GlobalInvocationID.x > 7u)\n    {\n        uint _217 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 4u), 16u, 6u);\n        _222 = texelFetch(_17[_217], int(gl_GlobalInvocationID.x)).x + _209;\n    }\n    else\n    {\n        _222 = _209;\n    }\n    float _236;\n    if (gl_GlobalInvocationID.x > 8u)\n    {\n        uint _229 = descriptor_qa_check(registers._m1 + 6u, 16u, 7u);\n        _236 = uintBitsToFloat(texelFetch(_21[_229], int(gl_GlobalInvocationID.x)).x) + _222;\n    }\n    else\n    {\n        _236 = _222;\n    }\n    float _250;\n    if (gl_GlobalInvocationID.x > 9u)\n    {\n        uint _244 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 7u), 16u, 8u);\n        _250 = uintBitsToFloat(texelFetch(_21[_244], int(gl_GlobalInvocationID.x)).x) + _236;\n    }\n    else\n    {\n        _250 = _236;\n    }\n    float _263;\n    if (gl_GlobalInvocationID.x > 10u)\n    {\n        uint _256 = descriptor_qa_check(registers._m1 + 9u, 16u, 9u);\n        _263 = uintBitsToFloat(texelFetch(_24[_256], int(gl_GlobalInvocationID.x)).x) + _250;\n    }\n    else\n    {\n        _263 = _250;\n    }\n    float _279;\n    if (gl_GlobalInvocationID.x > 11u)\n    {\n        uint _272 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 10u), 16u, 10u);\n        _279 = uintBitsToFloat(texelFetch(_24[_272], int(gl_GlobalInvocationID.x >> 2u)).x) + _263;\n    }\n    else\n    {\n        _279 = _263;\n    }\n    if (gl_GlobalInvocationID.x > 1u)\n    {\n        uint _285 = descriptor_qa_check(registers._m4, 32u, 11u);\n        uint _291 = descriptor_qa_check(registers._m4, 256u, 12u);\n        imageStore(_28[_285], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_279)));\n    }\n    if (gl_GlobalInvocationID.x > 30u)\n    {\n        uint _305 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 1u), 32u, 13u);\n        imageStore(_28[_305], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_279)));\n    }\n    if (gl_GlobalInvocationID.x > 40u)\n    {\n        uint _316 = descriptor_qa_check(registers._m4 + 3u, 32u, 14u);\n        imageStore(_36[_316], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_279)));\n    }\n    if (gl_GlobalInvocationID.x > 50u)\n    {\n        uint _332 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 4u), 32u, 15u);\n        imageStore(_36[_332], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_279)));\n    }\n    if (gl_GlobalInvocationID.x > 80u)\n    {\n        uint _343 = descriptor_qa_check(registers._m3 + 6u, 2u, 16u);\n        imageStore(_40[_343], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(_279));\n    }\n    if (gl_GlobalInvocationID.x > 90u)\n    {\n        uint _355 = descriptor_qa_check(registers._m3 + ((gl_GlobalInvocationID.x & 1u) + 7u), 2u, 17u);\n        imageStore(_40[_355], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), vec4(_279));\n    }\n    uint _363 = descriptor_qa_check(registers._m4, 32u, 18u);\n    uint _369 = descriptor_qa_check(registers._m4, 256u, 19u);\n    uvec2 _371 = _33.counters[_369];\n    uint _390 = RobustPhysicalAtomicCounter(_371, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 425\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %50\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %31 \"AtomicCounters\"\nOpMemberName %31 0 \"counters\"\nOpName %44 \"BindlessCBV\"\nOpName %66 \"DescriptorHeapGlobalQAData\"\nOpMemberName %66 0 \"failed_shader_hash\"\nOpMemberName %66 1 \"failed_offset\"\nOpMemberName %66 2 \"failed_heap\"\nOpMemberName %66 3 \"failed_cookie\"\nOpMemberName %66 4 \"fault_atomic\"\nOpMemberName %66 5 \"failed_instruction\"\nOpMemberName %66 6 \"failed_descriptor_type_mask\"\nOpMemberName %66 7 \"actual_descriptor_type_mask\"\nOpMemberName %66 8 \"fault_type\"\nOpMemberName %66 9 \"va_map_timestamp\"\nOpMemberName %66 10 \"live_status_table\"\nOpName %68 \"QAGlobalData\"\nOpName %77 \"descriptor_qa_report_fault\"\nOpName %70 \"fault_type\"\nOpName %71 \"heap_offset\"\nOpName %72 \"cookie\"\nOpName %73 \"heap_index\"\nOpName %74 \"descriptor_type\"\nOpName %75 \"actual_descriptor_type\"\nOpName %76 \"instruction\"\nOpName %105 \"DescriptorHeapQAData\"\nOpMemberName %105 0 \"descriptor_count\"\nOpMemberName %105 1 \"heap_index\"\nOpMemberName %105 2 \"cookies_descriptor_info\"\nOpName %107 \"QAHeapData\"\nOpName %112 \"descriptor_qa_check\"\nOpName %109 \"heap_offset\"\nOpName %110 \"descriptor_type_mask\"\nOpName %111 \"instruction\"\nOpName %376 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 1\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %28 DescriptorSet 4\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %30 ArrayStride 8\nOpDecorate %31 Block\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 0 NonWritable\nOpDecorate %33 DescriptorSet 7\nOpDecorate %33 Binding 0\nOpDecorate %33 AliasedPointer\nOpDecorate %36 DescriptorSet 4\nOpDecorate %36 Binding 0\nOpDecorate %36 NonReadable\nOpDecorate %40 DescriptorSet 3\nOpDecorate %40 Binding 0\nOpDecorate %40 NonReadable\nOpDecorate %43 ArrayStride 16\nOpDecorate %44 Block\nOpMemberDecorate %44 0 NonWritable\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %47 DescriptorSet 5\nOpDecorate %47 Binding 0\nOpDecorate %50 BuiltIn GlobalInvocationId\nOpDecorate %65 ArrayStride 4\nOpMemberDecorate %66 0 Offset 0\nOpMemberDecorate %66 1 Offset 8\nOpMemberDecorate %66 2 Offset 12\nOpMemberDecorate %66 3 Offset 16\nOpMemberDecorate %66 4 Offset 20\nOpMemberDecorate %66 5 Offset 24\nOpMemberDecorate %66 6 Offset 28\nOpMemberDecorate %66 7 Offset 32\nOpMemberDecorate %66 8 Offset 36\nOpMemberDecorate %66 9 Offset 40\nOpMemberDecorate %66 10 Offset 44\nOpDecorate %66 Block\nOpDecorate %68 DescriptorSet 10\nOpDecorate %68 Binding 10\nOpDecorate %104 ArrayStride 12\nOpMemberDecorate %105 0 Offset 0\nOpMemberDecorate %105 1 Offset 4\nOpMemberDecorate %105 2 Offset 8\nOpDecorate %105 Block\nOpDecorate %107 DescriptorSet 10\nOpDecorate %107 Binding 11\nOpDecorate %107 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeRuntimeArray %18\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeVector %5 2\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypeStruct %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeRuntimeArray %25\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%38 = OpTypeRuntimeArray %37\n%39 = OpTypePointer UniformConstant %38\n%40 = OpVariable %39 UniformConstant\n%41 = OpTypeVector %9 4\n%42 = OpConstant %5 4096\n%43 = OpTypeArray %41 %42\n%44 = OpTypeStruct %43\n%45 = OpTypeRuntimeArray %44\n%46 = OpTypePointer StorageBuffer %45\n%47 = OpVariable %46 StorageBuffer\n%48 = OpTypeVector %5 3\n%49 = OpTypePointer Input %48\n%50 = OpVariable %49 Input\n%51 = OpTypePointer Input %5\n%53 = OpConstant %5 0\n%55 = OpTypeBool\n%57 = OpConstant %5 2\n%58 = OpTypePointer StorageBuffer %44\n%60 = OpTypePointer PushConstant %5\n%62 = OpConstant %5 5\n%65 = OpTypeRuntimeArray %5\n%66 = OpTypeStruct %29 %5 %5 %5 %5 %5 %5 %5 %5 %5 %65\n%67 = OpTypePointer StorageBuffer %66\n%68 = OpVariable %67 StorageBuffer\n%69 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%79 = OpTypePointer StorageBuffer %5\n%81 = OpConstant %5 4\n%83 = OpConstant %5 1\n%88 = OpConstant %5 3\n%92 = OpConstant %5 6\n%94 = OpConstant %5 7\n%96 = OpConstant %5 3735928559\n%97 = OpConstantComposite %29 %96 %53\n%98 = OpTypePointer StorageBuffer %29\n%100 = OpConstant %5 72\n%102 = OpConstant %5 8\n%104 = OpTypeRuntimeArray %48\n%105 = OpTypeStruct %5 %5 %104\n%106 = OpTypePointer StorageBuffer %105\n%107 = OpVariable %106 StorageBuffer\n%108 = OpTypeFunction %5 %5 %5 %5\n%119 = OpConstant %5 9\n%121 = OpTypePointer StorageBuffer %48\n%129 = OpConstant %5 31\n%131 = OpConstant %5 10\n%153 = OpTypePointer StorageBuffer %41\n%158 = OpConstant %9 0\n%172 = OpTypePointer UniformConstant %10\n%198 = OpTypePointer UniformConstant %14\n%204 = OpConstant %5 16\n%224 = OpTypePointer UniformConstant %18\n%231 = OpTypeVector %5 4\n%265 = OpConstant %5 11\n%281 = OpTypePointer UniformConstant %25\n%286 = OpConstant %5 32\n%292 = OpConstant %5 256\n%293 = OpConstant %5 12\n%298 = OpConstant %5 30\n%306 = OpConstant %5 13\n%311 = OpConstant %5 40\n%317 = OpConstant %5 14\n%323 = OpConstant %5 50\n%333 = OpConstant %5 15\n%337 = OpConstant %5 80\n%338 = OpTypePointer UniformConstant %37\n%348 = OpConstant %5 90\n%356 = OpConstant %5 17\n%364 = OpConstant %5 18\n%370 = OpConstant %5 19\n%372 = OpTypeFunction %5 %29 %5 %5\n%380 = OpTypeVector %55 2\n%381 = OpConstantNull %29\n%384 = OpTypePointer PhysicalStorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %391\n%391 = OpLabel\n%52 = OpAccessChain %51 %50 %53\n%54 = OpLoad %5 %52\n%56 = OpUGreaterThan %55 %54 %57\nOpSelectionMerge %393 None\nOpBranchConditional %56 %392 %393\n%392 = OpLabel\n%61 = OpAccessChain %60 %8 %62\n%63 = OpLoad %5 %61\n%64 = OpFunctionCall %5 %112 %63 %102 %83\n%59 = OpAccessChain %58 %47 %64\n%154 = OpAccessChain %153 %59 %53 %53\n%155 = OpLoad %41 %154\n%156 = OpCompositeExtract %9 %155 0\nOpBranch %393\n%393 = OpLabel\n%157 = OpPhi %9 %158 %391 %156 %392\n%159 = OpUGreaterThan %55 %54 %88\nOpSelectionMerge %395 None\nOpBranchConditional %159 %394 %395\n%394 = OpLabel\n%160 = OpIAdd %5 %54 %83\n%162 = OpAccessChain %60 %8 %62\n%163 = OpLoad %5 %162\n%164 = OpIAdd %5 %163 %160\n%165 = OpFunctionCall %5 %112 %164 %102 %57\n%161 = OpAccessChain %58 %47 %165\n%166 = OpAccessChain %153 %161 %53 %53\n%167 = OpLoad %41 %166\n%168 = OpCompositeExtract %9 %167 0\n%169 = OpFAdd %9 %168 %157\nOpBranch %395\n%395 = OpLabel\n%170 = OpPhi %9 %157 %393 %169 %394\n%171 = OpUGreaterThan %55 %54 %81\nOpSelectionMerge %397 None\nOpBranchConditional %171 %396 %397\n%396 = OpLabel\n%174 = OpAccessChain %60 %8 %53\n%175 = OpLoad %5 %174\n%176 = OpFunctionCall %5 %112 %175 %83 %88\n%173 = OpAccessChain %172 %13 %176\n%177 = OpLoad %10 %173\n%179 = OpCompositeConstruct %29 %54 %53\n%178 = OpImageFetch %41 %177 %179 Lod %53\n%180 = OpCompositeExtract %9 %178 0\n%181 = OpFAdd %9 %180 %170\nOpBranch %397\n%397 = OpLabel\n%182 = OpPhi %9 %170 %395 %181 %396\n%183 = OpUGreaterThan %55 %54 %62\nOpSelectionMerge %399 None\nOpBranchConditional %183 %398 %399\n%398 = OpLabel\n%184 = OpBitwiseAnd %5 %54 %83\n%185 = OpIAdd %5 %184 %83\n%187 = OpAccessChain %60 %8 %53\n%188 = OpLoad %5 %187\n%189 = OpIAdd %5 %188 %185\n%190 = OpFunctionCall %5 %112 %189 %83 %81\n%186 = OpAccessChain %172 %13 %190\n%191 = OpLoad %10 %186\n%193 = OpCompositeConstruct %29 %53 %54\n%192 = OpImageFetch %41 %191 %193 Lod %53\n%194 = OpCompositeExtract %9 %192 0\n%195 = OpFAdd %9 %194 %182\nOpBranch %399\n%399 = OpLabel\n%196 = OpPhi %9 %182 %397 %195 %398\n%197 = OpUGreaterThan %55 %54 %92\nOpSelectionMerge %401 None\nOpBranchConditional %197 %400 %401\n%400 = OpLabel\n%200 = OpAccessChain %60 %8 %83\n%201 = OpLoad %5 %200\n%202 = OpIAdd %5 %201 %88\n%203 = OpFunctionCall %5 %112 %202 %204 %62\n%199 = OpAccessChain %198 %17 %203\n%205 = OpLoad %14 %199\n%206 = OpImageFetch %41 %205 %54\n%207 = OpCompositeExtract %9 %206 0\n%208 = OpFAdd %9 %207 %196\nOpBranch %401\n%401 = OpLabel\n%209 = OpPhi %9 %196 %399 %208 %400\n%210 = OpUGreaterThan %55 %54 %94\nOpSelectionMerge %403 None\nOpBranchConditional %210 %402 %403\n%402 = OpLabel\n%211 = OpBitwiseAnd %5 %54 %83\n%212 = OpIAdd %5 %211 %81\n%214 = OpAccessChain %60 %8 %83\n%215 = OpLoad %5 %214\n%216 = OpIAdd %5 %215 %212\n%217 = OpFunctionCall %5 %112 %216 %204 %92\n%213 = OpAccessChain %198 %17 %217\n%218 = OpLoad %14 %213\n%219 = OpImageFetch %41 %218 %54\n%220 = OpCompositeExtract %9 %219 0\n%221 = OpFAdd %9 %220 %209\nOpBranch %403\n%403 = OpLabel\n%222 = OpPhi %9 %209 %401 %221 %402\n%223 = OpUGreaterThan %55 %54 %102\nOpSelectionMerge %405 None\nOpBranchConditional %223 %404 %405\n%404 = OpLabel\n%226 = OpAccessChain %60 %8 %83\n%227 = OpLoad %5 %226\n%228 = OpIAdd %5 %227 %92\n%229 = OpFunctionCall %5 %112 %228 %204 %94\n%225 = OpAccessChain %224 %21 %229\n%230 = OpLoad %18 %225\n%232 = OpImageFetch %231 %230 %54\n%233 = OpCompositeExtract %5 %232 0\n%234 = OpBitcast %9 %233\n%235 = OpFAdd %9 %234 %222\nOpBranch %405\n%405 = OpLabel\n%236 = OpPhi %9 %222 %403 %235 %404\n%237 = OpUGreaterThan %55 %54 %119\nOpSelectionMerge %407 None\nOpBranchConditional %237 %406 %407\n%406 = OpLabel\n%238 = OpBitwiseAnd %5 %54 %83\n%239 = OpIAdd %5 %238 %94\n%241 = OpAccessChain %60 %8 %83\n%242 = OpLoad %5 %241\n%243 = OpIAdd %5 %242 %239\n%244 = OpFunctionCall %5 %112 %243 %204 %102\n%240 = OpAccessChain %224 %21 %244\n%245 = OpLoad %18 %240\n%246 = OpImageFetch %231 %245 %54\n%247 = OpCompositeExtract %5 %246 0\n%248 = OpBitcast %9 %247\n%249 = OpFAdd %9 %248 %236\nOpBranch %407\n%407 = OpLabel\n%250 = OpPhi %9 %236 %405 %249 %406\n%251 = OpUGreaterThan %55 %54 %131\nOpSelectionMerge %409 None\nOpBranchConditional %251 %408 %409\n%408 = OpLabel\n%253 = OpAccessChain %60 %8 %83\n%254 = OpLoad %5 %253\n%255 = OpIAdd %5 %254 %119\n%256 = OpFunctionCall %5 %112 %255 %204 %119\n%252 = OpAccessChain %224 %24 %256\n%257 = OpLoad %18 %252\n%258 = OpShiftLeftLogical %5 %54 %57\n%259 = OpImageFetch %231 %257 %54\n%260 = OpCompositeExtract %5 %259 0\n%261 = OpBitcast %9 %260\n%262 = OpFAdd %9 %261 %250\nOpBranch %409\n%409 = OpLabel\n%263 = OpPhi %9 %250 %407 %262 %408\n%264 = OpUGreaterThan %55 %54 %265\nOpSelectionMerge %411 None\nOpBranchConditional %264 %410 %411\n%410 = OpLabel\n%266 = OpBitwiseAnd %5 %54 %83\n%267 = OpIAdd %5 %266 %131\n%269 = OpAccessChain %60 %8 %83\n%270 = OpLoad %5 %269\n%271 = OpIAdd %5 %270 %267\n%272 = OpFunctionCall %5 %112 %271 %204 %131\n%268 = OpAccessChain %224 %24 %272\n%273 = OpLoad %18 %268\n%274 = OpShiftRightLogical %5 %54 %57\n%275 = OpImageFetch %231 %273 %274\n%276 = OpCompositeExtract %5 %275 0\n%277 = OpBitcast %9 %276\n%278 = OpFAdd %9 %277 %263\nOpBranch %411\n%411 = OpLabel\n%279 = OpPhi %9 %263 %409 %278 %410\n%280 = OpUGreaterThan %55 %54 %83\nOpSelectionMerge %413 None\nOpBranchConditional %280 %412 %413\n%412 = OpLabel\n%283 = OpAccessChain %60 %8 %81\n%284 = OpLoad %5 %283\n%285 = OpFunctionCall %5 %112 %284 %286 %265\n%282 = OpAccessChain %281 %28 %285\n%287 = OpLoad %25 %282\n%289 = OpAccessChain %60 %8 %81\n%290 = OpLoad %5 %289\n%291 = OpFunctionCall %5 %112 %290 %292 %293\n%288 = OpAccessChain %98 %33 %53 %291\n%294 = OpLoad %29 %288\n%295 = OpBitcast %5 %279\n%296 = OpCompositeConstruct %231 %295 %295 %295 %295\nOpImageWrite %287 %54 %296\nOpBranch %413\n%413 = OpLabel\n%297 = OpUGreaterThan %55 %54 %298\nOpSelectionMerge %415 None\nOpBranchConditional %297 %414 %415\n%414 = OpLabel\n%299 = OpBitwiseAnd %5 %54 %83\n%300 = OpIAdd %5 %299 %83\n%302 = OpAccessChain %60 %8 %81\n%303 = OpLoad %5 %302\n%304 = OpIAdd %5 %303 %300\n%305 = OpFunctionCall %5 %112 %304 %286 %306\n%301 = OpAccessChain %281 %28 %305\n%307 = OpLoad %25 %301\n%308 = OpBitcast %5 %279\n%309 = OpCompositeConstruct %231 %308 %308 %308 %308\nOpImageWrite %307 %54 %309\nOpBranch %415\n%415 = OpLabel\n%310 = OpUGreaterThan %55 %54 %311\nOpSelectionMerge %417 None\nOpBranchConditional %310 %416 %417\n%416 = OpLabel\n%313 = OpAccessChain %60 %8 %81\n%314 = OpLoad %5 %313\n%315 = OpIAdd %5 %314 %88\n%316 = OpFunctionCall %5 %112 %315 %286 %317\n%312 = OpAccessChain %281 %36 %316\n%318 = OpLoad %25 %312\n%319 = OpBitcast %5 %279\n%320 = OpShiftLeftLogical %5 %54 %57\n%321 = OpCompositeConstruct %231 %319 %319 %319 %319\nOpImageWrite %318 %54 %321\nOpBranch %417\n%417 = OpLabel\n%322 = OpUGreaterThan %55 %54 %323\nOpSelectionMerge %419 None\nOpBranchConditional %322 %418 %419\n%418 = OpLabel\n%324 = OpBitwiseAnd %5 %54 %83\n%325 = OpBitcast %5 %279\n%326 = OpShiftLeftLogical %5 %54 %57\n%327 = OpIAdd %5 %324 %81\n%329 = OpAccessChain %60 %8 %81\n%330 = OpLoad %5 %329\n%331 = OpIAdd %5 %330 %327\n%332 = OpFunctionCall %5 %112 %331 %286 %333\n%328 = OpAccessChain %281 %36 %332\n%334 = OpLoad %25 %328\n%335 = OpCompositeConstruct %231 %325 %325 %325 %325\nOpImageWrite %334 %54 %335\nOpBranch %419\n%419 = OpLabel\n%336 = OpUGreaterThan %55 %54 %337\nOpSelectionMerge %421 None\nOpBranchConditional %336 %420 %421\n%420 = OpLabel\n%340 = OpAccessChain %60 %8 %88\n%341 = OpLoad %5 %340\n%342 = OpIAdd %5 %341 %92\n%343 = OpFunctionCall %5 %112 %342 %57 %204\n%339 = OpAccessChain %338 %40 %343\n%344 = OpLoad %37 %339\n%345 = OpCompositeConstruct %29 %54 %53\n%346 = OpCompositeConstruct %41 %279 %279 %279 %279\nOpImageWrite %344 %345 %346\nOpBranch %421\n%421 = OpLabel\n%347 = OpUGreaterThan %55 %54 %348\nOpSelectionMerge %423 None\nOpBranchConditional %347 %422 %423\n%422 = OpLabel\n%349 = OpBitwiseAnd %5 %54 %83\n%350 = OpIAdd %5 %349 %94\n%352 = OpAccessChain %60 %8 %88\n%353 = OpLoad %5 %352\n%354 = OpIAdd %5 %353 %350\n%355 = OpFunctionCall %5 %112 %354 %57 %356\n%351 = OpAccessChain %338 %40 %355\n%357 = OpLoad %37 %351\n%358 = OpCompositeConstruct %29 %53 %54\n%359 = OpCompositeConstruct %41 %279 %279 %279 %279\nOpImageWrite %357 %358 %359\nOpBranch %423\n%423 = OpLabel\n%361 = OpAccessChain %60 %8 %81\n%362 = OpLoad %5 %361\n%363 = OpFunctionCall %5 %112 %362 %286 %364\n%360 = OpAccessChain %281 %28 %363\n%365 = OpLoad %25 %360\n%367 = OpAccessChain %60 %8 %81\n%368 = OpLoad %5 %367\n%369 = OpFunctionCall %5 %112 %368 %292 %370\n%366 = OpAccessChain %98 %33 %53 %369\n%371 = OpLoad %29 %366\n%390 = OpFunctionCall %5 %376 %371 %83 %53\nOpReturn\nOpFunctionEnd\n%77 = OpFunction %1 None %69\n%70 = OpFunctionParameter %5\n%71 = OpFunctionParameter %5\n%72 = OpFunctionParameter %5\n%73 = OpFunctionParameter %5\n%74 = OpFunctionParameter %5\n%75 = OpFunctionParameter %5\n%76 = OpFunctionParameter %5\n%78 = OpLabel\n%80 = OpAccessChain %79 %68 %81\n%82 = OpAtomicIAdd %5 %80 %83 %53 %83\n%84 = OpIEqual %55 %82 %53\nOpSelectionMerge %86 None\nOpBranchConditional %84 %85 %86\n%85 = OpLabel\n%87 = OpAccessChain %79 %68 %88\nOpStore %87 %72\n%89 = OpAccessChain %79 %68 %83\nOpStore %89 %71\n%90 = OpAccessChain %79 %68 %57\nOpStore %90 %73\n%91 = OpAccessChain %79 %68 %92\nOpStore %91 %74\n%93 = OpAccessChain %79 %68 %94\nOpStore %93 %75\n%95 = OpAccessChain %79 %68 %62\nOpStore %95 %76\n%99 = OpAccessChain %98 %68 %53\nOpStore %99 %97\nOpMemoryBarrier %83 %100\n%101 = OpAccessChain %79 %68 %102\nOpStore %101 %70\nOpBranch %86\n%86 = OpLabel\nOpReturn\nOpFunctionEnd\n%112 = OpFunction %5 None %108\n%109 = OpFunctionParameter %5\n%110 = OpFunctionParameter %5\n%111 = OpFunctionParameter %5\n%113 = OpLabel\n%114 = OpAccessChain %79 %107 %53\n%115 = OpLoad %5 %114\n%116 = OpAccessChain %79 %107 %83\n%117 = OpLoad %5 %116\n%118 = OpAccessChain %79 %68 %119\n%120 = OpLoad %5 %118\n%122 = OpAccessChain %121 %107 %57 %109\n%123 = OpLoad %48 %122\n%124 = OpCompositeExtract %5 %123 0\n%125 = OpCompositeExtract %5 %123 1\n%126 = OpCompositeExtract %5 %123 2\n%127 = OpShiftRightLogical %5 %124 %62\n%128 = OpBitwiseAnd %5 %124 %129\n%130 = OpAccessChain %79 %68 %131 %127\n%132 = OpLoad %5 %130\n%133 = OpShiftLeftLogical %5 %83 %128\n%134 = OpBitwiseAnd %5 %132 %133\n%135 = OpINotEqual %55 %134 %53\n%136 = OpBitwiseAnd %5 %126 %110\n%137 = OpIEqual %55 %136 %110\n%138 = OpUGreaterThanEqual %55 %109 %115\n%139 = OpSelect %5 %138 %83 %53\n%140 = OpSelect %5 %137 %53 %57\n%141 = OpSelect %5 %135 %53 %81\n%142 = OpUGreaterThanEqual %55 %120 %125\n%143 = OpSelect %5 %142 %53 %102\n%144 = OpBitwiseOr %5 %139 %140\n%145 = OpBitwiseOr %5 %144 %141\n%146 = OpBitwiseOr %5 %145 %143\n%147 = OpINotEqual %55 %146 %53\nOpSelectionMerge %149 None\nOpBranchConditional %147 %148 %149\n%148 = OpLabel\n%150 = OpFunctionCall %1 %77 %146 %109 %124 %117 %110 %126 %111\nOpReturnValue %115\n%149 = OpLabel\nOpReturnValue %109\nOpFunctionEnd\n%376 = OpFunction %5 None %372\n%373 = OpFunctionParameter %29\n%374 = OpFunctionParameter %5\n%375 = OpFunctionParameter %5\n%377 = OpLabel\n%382 = OpINotEqual %380 %373 %381\n%383 = OpAny %55 %382\nOpSelectionMerge %379 None\nOpBranchConditional %383 %378 %379\n%378 = OpLabel\n%385 = OpBitcast %384 %373\n%386 = OpAtomicIAdd %5 %385 %83 %53 %374\n%387 = OpIAdd %5 %386 %375\nOpBranch %379\n%379 = OpLabel\n%388 = OpPhi %5 %53 %377 %387 %378\nOpReturnValue %388\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/descriptor_qa.bindless.descriptor-qa.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _33;\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _47[];\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 1, binding = 0) uniform samplerBuffer _17[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _21[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _24[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _28[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _36[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _40[];\nlayout(set = 2, binding = 0) uniform sampler _51[];\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _86 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_86 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _119 = QAHeapData.descriptor_count;\n    uint _121 = QAHeapData.heap_index;\n    uint _124 = QAGlobalData.va_map_timestamp;\n    uvec3 _127 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _136 = QAGlobalData.live_status_table[_127.x >> 5u];\n    uint _150 = ((uint(heap_offset >= _119) | (((_127.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_136 & (1u << (_127.x & 31u))) != 0u) ? 0u : 4u)) | ((_124 >= _127.y) ? 0u : 8u);\n    if (_150 != 0u)\n    {\n        descriptor_qa_report_fault(_150, heap_offset, _127.x, _121, descriptor_type_mask, _127.z, instruction);\n        return _119;\n    }\n    return heap_offset;\n}\n\nuint RobustPhysicalAtomicCounter(uvec2 _386, uint _387, uint _388)\n{\n    uint _401;\n    if (any(notEqual(_386, uvec2(0u))))\n    {\n        uint _399 = atomicAdd(uintPointer(_386).value, _387);\n        _401 = _399 + _388;\n    }\n    else\n    {\n        _401 = 0u;\n    }\n    return _401;\n}\n\nvoid main()\n{\n    float _161;\n    if (gl_GlobalInvocationID.x > 2u)\n    {\n        uint _68 = descriptor_qa_check(registers._m5, 4u, 1u);\n        _161 = _47[_68]._m0[0u].x;\n    }\n    else\n    {\n        _161 = 0.0;\n    }\n    float _174;\n    if (gl_GlobalInvocationID.x > 3u)\n    {\n        uint _169 = descriptor_qa_check(registers._m5 + (gl_GlobalInvocationID.x + 1u), 4u, 2u);\n        _174 = _47[_169]._m0[0u].x + _161;\n    }\n    else\n    {\n        _174 = _161;\n    }\n    float _195;\n    if (gl_GlobalInvocationID.x > 4u)\n    {\n        uint _180 = descriptor_qa_check(registers._m0, 1u, 3u);\n        _195 = textureLod(sampler2D(_13[_180], _51[registers._m2]), vec2(0.5), 0.0).x + _174;\n    }\n    else\n    {\n        _195 = _174;\n    }\n    float _209;\n    if (gl_GlobalInvocationID.x > 5u)\n    {\n        uint _203 = descriptor_qa_check(registers._m0 + ((gl_GlobalInvocationID.x & 1u) + 1u), 1u, 4u);\n        _209 = texelFetch(_13[_203], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), int(0u)).x + _195;\n    }\n    else\n    {\n        _209 = _195;\n    }\n    float _222;\n    if (gl_GlobalInvocationID.x > 6u)\n    {\n        uint _216 = descriptor_qa_check(registers._m1 + 3u, 16u, 5u);\n        _222 = texelFetch(_17[_216], int(gl_GlobalInvocationID.x)).x + _209;\n    }\n    else\n    {\n        _222 = _209;\n    }\n    float _235;\n    if (gl_GlobalInvocationID.x > 7u)\n    {\n        uint _230 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 4u), 16u, 6u);\n        _235 = texelFetch(_17[_230], int(gl_GlobalInvocationID.x)).x + _222;\n    }\n    else\n    {\n        _235 = _222;\n    }\n    float _249;\n    if (gl_GlobalInvocationID.x > 8u)\n    {\n        uint _242 = descriptor_qa_check(registers._m1 + 6u, 16u, 7u);\n        _249 = uintBitsToFloat(texelFetch(_21[_242], int(gl_GlobalInvocationID.x)).x) + _235;\n    }\n    else\n    {\n        _249 = _235;\n    }\n    float _263;\n    if (gl_GlobalInvocationID.x > 9u)\n    {\n        uint _257 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 7u), 16u, 8u);\n        _263 = uintBitsToFloat(texelFetch(_21[_257], int(gl_GlobalInvocationID.x)).x) + _249;\n    }\n    else\n    {\n        _263 = _249;\n    }\n    float _276;\n    if (gl_GlobalInvocationID.x > 10u)\n    {\n        uint _269 = descriptor_qa_check(registers._m1 + 9u, 16u, 9u);\n        _276 = uintBitsToFloat(texelFetch(_24[_269], int(gl_GlobalInvocationID.x)).x) + _263;\n    }\n    else\n    {\n        _276 = _263;\n    }\n    float _292;\n    if (gl_GlobalInvocationID.x > 11u)\n    {\n        uint _285 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 10u), 16u, 10u);\n        _292 = uintBitsToFloat(texelFetch(_24[_285], int(gl_GlobalInvocationID.x >> 2u)).x) + _276;\n    }\n    else\n    {\n        _292 = _276;\n    }\n    if (gl_GlobalInvocationID.x > 1u)\n    {\n        uint _298 = descriptor_qa_check(registers._m4, 32u, 11u);\n        uint _304 = descriptor_qa_check(registers._m4, 256u, 12u);\n        imageStore(_28[_298], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 30u)\n    {\n        uint _318 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 1u), 32u, 13u);\n        imageStore(_28[_318], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 40u)\n    {\n        uint _329 = descriptor_qa_check(registers._m4 + 3u, 32u, 14u);\n        imageStore(_36[_329], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 50u)\n    {\n        uint _345 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 4u), 32u, 15u);\n        imageStore(_36[_345], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 80u)\n    {\n        uint _356 = descriptor_qa_check(registers._m3 + 6u, 2u, 16u);\n        imageStore(_40[_356], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(_292));\n    }\n    if (gl_GlobalInvocationID.x > 90u)\n    {\n        uint _368 = descriptor_qa_check(registers._m3 + ((gl_GlobalInvocationID.x & 1u) + 7u), 2u, 17u);\n        imageStore(_40[_368], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), vec4(_292));\n    }\n    uint _376 = descriptor_qa_check(registers._m4, 32u, 18u);\n    uint _382 = descriptor_qa_check(registers._m4, 256u, 19u);\n    uvec2 _384 = _33.counters[_382];\n    uint _403 = RobustPhysicalAtomicCounter(_384, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 438\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %54\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %31 \"AtomicCounters\"\nOpMemberName %31 0 \"counters\"\nOpName %44 \"BindlessCBV\"\nOpName %70 \"DescriptorHeapGlobalQAData\"\nOpMemberName %70 0 \"failed_shader_hash\"\nOpMemberName %70 1 \"failed_offset\"\nOpMemberName %70 2 \"failed_heap\"\nOpMemberName %70 3 \"failed_cookie\"\nOpMemberName %70 4 \"fault_atomic\"\nOpMemberName %70 5 \"failed_instruction\"\nOpMemberName %70 6 \"failed_descriptor_type_mask\"\nOpMemberName %70 7 \"actual_descriptor_type_mask\"\nOpMemberName %70 8 \"fault_type\"\nOpMemberName %70 9 \"va_map_timestamp\"\nOpMemberName %70 10 \"live_status_table\"\nOpName %72 \"QAGlobalData\"\nOpName %81 \"descriptor_qa_report_fault\"\nOpName %74 \"fault_type\"\nOpName %75 \"heap_offset\"\nOpName %76 \"cookie\"\nOpName %77 \"heap_index\"\nOpName %78 \"descriptor_type\"\nOpName %79 \"actual_descriptor_type\"\nOpName %80 \"instruction\"\nOpName %109 \"DescriptorHeapQAData\"\nOpMemberName %109 0 \"descriptor_count\"\nOpMemberName %109 1 \"heap_index\"\nOpMemberName %109 2 \"cookies_descriptor_info\"\nOpName %111 \"QAHeapData\"\nOpName %116 \"descriptor_qa_check\"\nOpName %113 \"heap_offset\"\nOpName %114 \"descriptor_type_mask\"\nOpName %115 \"instruction\"\nOpName %389 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 1\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %28 DescriptorSet 4\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %30 ArrayStride 8\nOpDecorate %31 Block\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 0 NonWritable\nOpDecorate %33 DescriptorSet 7\nOpDecorate %33 Binding 0\nOpDecorate %33 AliasedPointer\nOpDecorate %36 DescriptorSet 4\nOpDecorate %36 Binding 0\nOpDecorate %36 NonReadable\nOpDecorate %40 DescriptorSet 3\nOpDecorate %40 Binding 0\nOpDecorate %40 NonReadable\nOpDecorate %43 ArrayStride 16\nOpDecorate %44 Block\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %47 DescriptorSet 5\nOpDecorate %47 Binding 0\nOpDecorate %51 DescriptorSet 2\nOpDecorate %51 Binding 0\nOpDecorate %54 BuiltIn GlobalInvocationId\nOpDecorate %69 ArrayStride 4\nOpMemberDecorate %70 0 Offset 0\nOpMemberDecorate %70 1 Offset 8\nOpMemberDecorate %70 2 Offset 12\nOpMemberDecorate %70 3 Offset 16\nOpMemberDecorate %70 4 Offset 20\nOpMemberDecorate %70 5 Offset 24\nOpMemberDecorate %70 6 Offset 28\nOpMemberDecorate %70 7 Offset 32\nOpMemberDecorate %70 8 Offset 36\nOpMemberDecorate %70 9 Offset 40\nOpMemberDecorate %70 10 Offset 44\nOpDecorate %70 Block\nOpDecorate %72 DescriptorSet 10\nOpDecorate %72 Binding 10\nOpDecorate %108 ArrayStride 12\nOpMemberDecorate %109 0 Offset 0\nOpMemberDecorate %109 1 Offset 4\nOpMemberDecorate %109 2 Offset 8\nOpDecorate %109 Block\nOpDecorate %111 DescriptorSet 10\nOpDecorate %111 Binding 11\nOpDecorate %111 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeRuntimeArray %18\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeVector %5 2\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypeStruct %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeRuntimeArray %25\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%38 = OpTypeRuntimeArray %37\n%39 = OpTypePointer UniformConstant %38\n%40 = OpVariable %39 UniformConstant\n%41 = OpTypeVector %9 4\n%42 = OpConstant %5 4096\n%43 = OpTypeArray %41 %42\n%44 = OpTypeStruct %43\n%45 = OpTypeRuntimeArray %44\n%46 = OpTypePointer Uniform %45\n%47 = OpVariable %46 Uniform\n%48 = OpTypeSampler\n%49 = OpTypeRuntimeArray %48\n%50 = OpTypePointer UniformConstant %49\n%51 = OpVariable %50 UniformConstant\n%52 = OpTypeVector %5 3\n%53 = OpTypePointer Input %52\n%54 = OpVariable %53 Input\n%55 = OpTypePointer Input %5\n%57 = OpConstant %5 0\n%59 = OpTypeBool\n%61 = OpConstant %5 2\n%62 = OpTypePointer Uniform %44\n%64 = OpTypePointer PushConstant %5\n%66 = OpConstant %5 5\n%69 = OpTypeRuntimeArray %5\n%70 = OpTypeStruct %29 %5 %5 %5 %5 %5 %5 %5 %5 %5 %69\n%71 = OpTypePointer StorageBuffer %70\n%72 = OpVariable %71 StorageBuffer\n%73 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%83 = OpTypePointer StorageBuffer %5\n%85 = OpConstant %5 4\n%87 = OpConstant %5 1\n%92 = OpConstant %5 3\n%96 = OpConstant %5 6\n%98 = OpConstant %5 7\n%100 = OpConstant %5 3735928559\n%101 = OpConstantComposite %29 %100 %57\n%102 = OpTypePointer StorageBuffer %29\n%104 = OpConstant %5 72\n%106 = OpConstant %5 8\n%108 = OpTypeRuntimeArray %52\n%109 = OpTypeStruct %5 %5 %108\n%110 = OpTypePointer StorageBuffer %109\n%111 = OpVariable %110 StorageBuffer\n%112 = OpTypeFunction %5 %5 %5 %5\n%123 = OpConstant %5 9\n%125 = OpTypePointer StorageBuffer %52\n%133 = OpConstant %5 31\n%135 = OpConstant %5 10\n%157 = OpTypePointer Uniform %41\n%162 = OpConstant %9 0\n%176 = OpTypePointer UniformConstant %10\n%182 = OpTypePointer UniformConstant %48\n%187 = OpTypeSampledImage %10\n%189 = OpConstant %9 0.5\n%191 = OpTypeVector %9 2\n%211 = OpTypePointer UniformConstant %14\n%217 = OpConstant %5 16\n%237 = OpTypePointer UniformConstant %18\n%244 = OpTypeVector %5 4\n%278 = OpConstant %5 11\n%294 = OpTypePointer UniformConstant %25\n%299 = OpConstant %5 32\n%305 = OpConstant %5 256\n%306 = OpConstant %5 12\n%311 = OpConstant %5 30\n%319 = OpConstant %5 13\n%324 = OpConstant %5 40\n%330 = OpConstant %5 14\n%336 = OpConstant %5 50\n%346 = OpConstant %5 15\n%350 = OpConstant %5 80\n%351 = OpTypePointer UniformConstant %37\n%361 = OpConstant %5 90\n%369 = OpConstant %5 17\n%377 = OpConstant %5 18\n%383 = OpConstant %5 19\n%385 = OpTypeFunction %5 %29 %5 %5\n%393 = OpTypeVector %59 2\n%394 = OpConstantNull %29\n%397 = OpTypePointer PhysicalStorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %404\n%404 = OpLabel\n%56 = OpAccessChain %55 %54 %57\n%58 = OpLoad %5 %56\n%60 = OpUGreaterThan %59 %58 %61\nOpSelectionMerge %406 None\nOpBranchConditional %60 %405 %406\n%405 = OpLabel\n%65 = OpAccessChain %64 %8 %66\n%67 = OpLoad %5 %65\n%68 = OpFunctionCall %5 %116 %67 %85 %87\n%63 = OpAccessChain %62 %47 %68\n%158 = OpAccessChain %157 %63 %57 %57\n%159 = OpLoad %41 %158\n%160 = OpCompositeExtract %9 %159 0\nOpBranch %406\n%406 = OpLabel\n%161 = OpPhi %9 %162 %404 %160 %405\n%163 = OpUGreaterThan %59 %58 %92\nOpSelectionMerge %408 None\nOpBranchConditional %163 %407 %408\n%407 = OpLabel\n%164 = OpIAdd %5 %58 %87\n%166 = OpAccessChain %64 %8 %66\n%167 = OpLoad %5 %166\n%168 = OpIAdd %5 %167 %164\n%169 = OpFunctionCall %5 %116 %168 %85 %61\n%165 = OpAccessChain %62 %47 %169\n%170 = OpAccessChain %157 %165 %57 %57\n%171 = OpLoad %41 %170\n%172 = OpCompositeExtract %9 %171 0\n%173 = OpFAdd %9 %172 %161\nOpBranch %408\n%408 = OpLabel\n%174 = OpPhi %9 %161 %406 %173 %407\n%175 = OpUGreaterThan %59 %58 %85\nOpSelectionMerge %410 None\nOpBranchConditional %175 %409 %410\n%409 = OpLabel\n%178 = OpAccessChain %64 %8 %57\n%179 = OpLoad %5 %178\n%180 = OpFunctionCall %5 %116 %179 %87 %92\n%177 = OpAccessChain %176 %13 %180\n%181 = OpLoad %10 %177\n%184 = OpAccessChain %64 %8 %61\n%185 = OpLoad %5 %184\n%183 = OpAccessChain %182 %51 %185\n%186 = OpLoad %48 %183\n%188 = OpSampledImage %187 %181 %186\n%192 = OpCompositeConstruct %191 %189 %189\n%190 = OpImageSampleExplicitLod %41 %188 %192 Lod %162\n%193 = OpCompositeExtract %9 %190 0\n%194 = OpFAdd %9 %193 %174\nOpBranch %410\n%410 = OpLabel\n%195 = OpPhi %9 %174 %408 %194 %409\n%196 = OpUGreaterThan %59 %58 %66\nOpSelectionMerge %412 None\nOpBranchConditional %196 %411 %412\n%411 = OpLabel\n%197 = OpBitwiseAnd %5 %58 %87\n%198 = OpIAdd %5 %197 %87\n%200 = OpAccessChain %64 %8 %57\n%201 = OpLoad %5 %200\n%202 = OpIAdd %5 %201 %198\n%203 = OpFunctionCall %5 %116 %202 %87 %85\n%199 = OpAccessChain %176 %13 %203\n%204 = OpLoad %10 %199\n%206 = OpCompositeConstruct %29 %57 %58\n%205 = OpImageFetch %41 %204 %206 Lod %57\n%207 = OpCompositeExtract %9 %205 0\n%208 = OpFAdd %9 %207 %195\nOpBranch %412\n%412 = OpLabel\n%209 = OpPhi %9 %195 %410 %208 %411\n%210 = OpUGreaterThan %59 %58 %96\nOpSelectionMerge %414 None\nOpBranchConditional %210 %413 %414\n%413 = OpLabel\n%213 = OpAccessChain %64 %8 %87\n%214 = OpLoad %5 %213\n%215 = OpIAdd %5 %214 %92\n%216 = OpFunctionCall %5 %116 %215 %217 %66\n%212 = OpAccessChain %211 %17 %216\n%218 = OpLoad %14 %212\n%219 = OpImageFetch %41 %218 %58\n%220 = OpCompositeExtract %9 %219 0\n%221 = OpFAdd %9 %220 %209\nOpBranch %414\n%414 = OpLabel\n%222 = OpPhi %9 %209 %412 %221 %413\n%223 = OpUGreaterThan %59 %58 %98\nOpSelectionMerge %416 None\nOpBranchConditional %223 %415 %416\n%415 = OpLabel\n%224 = OpBitwiseAnd %5 %58 %87\n%225 = OpIAdd %5 %224 %85\n%227 = OpAccessChain %64 %8 %87\n%228 = OpLoad %5 %227\n%229 = OpIAdd %5 %228 %225\n%230 = OpFunctionCall %5 %116 %229 %217 %96\n%226 = OpAccessChain %211 %17 %230\n%231 = OpLoad %14 %226\n%232 = OpImageFetch %41 %231 %58\n%233 = OpCompositeExtract %9 %232 0\n%234 = OpFAdd %9 %233 %222\nOpBranch %416\n%416 = OpLabel\n%235 = OpPhi %9 %222 %414 %234 %415\n%236 = OpUGreaterThan %59 %58 %106\nOpSelectionMerge %418 None\nOpBranchConditional %236 %417 %418\n%417 = OpLabel\n%239 = OpAccessChain %64 %8 %87\n%240 = OpLoad %5 %239\n%241 = OpIAdd %5 %240 %96\n%242 = OpFunctionCall %5 %116 %241 %217 %98\n%238 = OpAccessChain %237 %21 %242\n%243 = OpLoad %18 %238\n%245 = OpImageFetch %244 %243 %58\n%246 = OpCompositeExtract %5 %245 0\n%247 = OpBitcast %9 %246\n%248 = OpFAdd %9 %247 %235\nOpBranch %418\n%418 = OpLabel\n%249 = OpPhi %9 %235 %416 %248 %417\n%250 = OpUGreaterThan %59 %58 %123\nOpSelectionMerge %420 None\nOpBranchConditional %250 %419 %420\n%419 = OpLabel\n%251 = OpBitwiseAnd %5 %58 %87\n%252 = OpIAdd %5 %251 %98\n%254 = OpAccessChain %64 %8 %87\n%255 = OpLoad %5 %254\n%256 = OpIAdd %5 %255 %252\n%257 = OpFunctionCall %5 %116 %256 %217 %106\n%253 = OpAccessChain %237 %21 %257\n%258 = OpLoad %18 %253\n%259 = OpImageFetch %244 %258 %58\n%260 = OpCompositeExtract %5 %259 0\n%261 = OpBitcast %9 %260\n%262 = OpFAdd %9 %261 %249\nOpBranch %420\n%420 = OpLabel\n%263 = OpPhi %9 %249 %418 %262 %419\n%264 = OpUGreaterThan %59 %58 %135\nOpSelectionMerge %422 None\nOpBranchConditional %264 %421 %422\n%421 = OpLabel\n%266 = OpAccessChain %64 %8 %87\n%267 = OpLoad %5 %266\n%268 = OpIAdd %5 %267 %123\n%269 = OpFunctionCall %5 %116 %268 %217 %123\n%265 = OpAccessChain %237 %24 %269\n%270 = OpLoad %18 %265\n%271 = OpShiftLeftLogical %5 %58 %61\n%272 = OpImageFetch %244 %270 %58\n%273 = OpCompositeExtract %5 %272 0\n%274 = OpBitcast %9 %273\n%275 = OpFAdd %9 %274 %263\nOpBranch %422\n%422 = OpLabel\n%276 = OpPhi %9 %263 %420 %275 %421\n%277 = OpUGreaterThan %59 %58 %278\nOpSelectionMerge %424 None\nOpBranchConditional %277 %423 %424\n%423 = OpLabel\n%279 = OpBitwiseAnd %5 %58 %87\n%280 = OpIAdd %5 %279 %135\n%282 = OpAccessChain %64 %8 %87\n%283 = OpLoad %5 %282\n%284 = OpIAdd %5 %283 %280\n%285 = OpFunctionCall %5 %116 %284 %217 %135\n%281 = OpAccessChain %237 %24 %285\n%286 = OpLoad %18 %281\n%287 = OpShiftRightLogical %5 %58 %61\n%288 = OpImageFetch %244 %286 %287\n%289 = OpCompositeExtract %5 %288 0\n%290 = OpBitcast %9 %289\n%291 = OpFAdd %9 %290 %276\nOpBranch %424\n%424 = OpLabel\n%292 = OpPhi %9 %276 %422 %291 %423\n%293 = OpUGreaterThan %59 %58 %87\nOpSelectionMerge %426 None\nOpBranchConditional %293 %425 %426\n%425 = OpLabel\n%296 = OpAccessChain %64 %8 %85\n%297 = OpLoad %5 %296\n%298 = OpFunctionCall %5 %116 %297 %299 %278\n%295 = OpAccessChain %294 %28 %298\n%300 = OpLoad %25 %295\n%302 = OpAccessChain %64 %8 %85\n%303 = OpLoad %5 %302\n%304 = OpFunctionCall %5 %116 %303 %305 %306\n%301 = OpAccessChain %102 %33 %57 %304\n%307 = OpLoad %29 %301\n%308 = OpBitcast %5 %292\n%309 = OpCompositeConstruct %244 %308 %308 %308 %308\nOpImageWrite %300 %58 %309\nOpBranch %426\n%426 = OpLabel\n%310 = OpUGreaterThan %59 %58 %311\nOpSelectionMerge %428 None\nOpBranchConditional %310 %427 %428\n%427 = OpLabel\n%312 = OpBitwiseAnd %5 %58 %87\n%313 = OpIAdd %5 %312 %87\n%315 = OpAccessChain %64 %8 %85\n%316 = OpLoad %5 %315\n%317 = OpIAdd %5 %316 %313\n%318 = OpFunctionCall %5 %116 %317 %299 %319\n%314 = OpAccessChain %294 %28 %318\n%320 = OpLoad %25 %314\n%321 = OpBitcast %5 %292\n%322 = OpCompositeConstruct %244 %321 %321 %321 %321\nOpImageWrite %320 %58 %322\nOpBranch %428\n%428 = OpLabel\n%323 = OpUGreaterThan %59 %58 %324\nOpSelectionMerge %430 None\nOpBranchConditional %323 %429 %430\n%429 = OpLabel\n%326 = OpAccessChain %64 %8 %85\n%327 = OpLoad %5 %326\n%328 = OpIAdd %5 %327 %92\n%329 = OpFunctionCall %5 %116 %328 %299 %330\n%325 = OpAccessChain %294 %36 %329\n%331 = OpLoad %25 %325\n%332 = OpBitcast %5 %292\n%333 = OpShiftLeftLogical %5 %58 %61\n%334 = OpCompositeConstruct %244 %332 %332 %332 %332\nOpImageWrite %331 %58 %334\nOpBranch %430\n%430 = OpLabel\n%335 = OpUGreaterThan %59 %58 %336\nOpSelectionMerge %432 None\nOpBranchConditional %335 %431 %432\n%431 = OpLabel\n%337 = OpBitwiseAnd %5 %58 %87\n%338 = OpBitcast %5 %292\n%339 = OpShiftLeftLogical %5 %58 %61\n%340 = OpIAdd %5 %337 %85\n%342 = OpAccessChain %64 %8 %85\n%343 = OpLoad %5 %342\n%344 = OpIAdd %5 %343 %340\n%345 = OpFunctionCall %5 %116 %344 %299 %346\n%341 = OpAccessChain %294 %36 %345\n%347 = OpLoad %25 %341\n%348 = OpCompositeConstruct %244 %338 %338 %338 %338\nOpImageWrite %347 %58 %348\nOpBranch %432\n%432 = OpLabel\n%349 = OpUGreaterThan %59 %58 %350\nOpSelectionMerge %434 None\nOpBranchConditional %349 %433 %434\n%433 = OpLabel\n%353 = OpAccessChain %64 %8 %92\n%354 = OpLoad %5 %353\n%355 = OpIAdd %5 %354 %96\n%356 = OpFunctionCall %5 %116 %355 %61 %217\n%352 = OpAccessChain %351 %40 %356\n%357 = OpLoad %37 %352\n%358 = OpCompositeConstruct %29 %58 %57\n%359 = OpCompositeConstruct %41 %292 %292 %292 %292\nOpImageWrite %357 %358 %359\nOpBranch %434\n%434 = OpLabel\n%360 = OpUGreaterThan %59 %58 %361\nOpSelectionMerge %436 None\nOpBranchConditional %360 %435 %436\n%435 = OpLabel\n%362 = OpBitwiseAnd %5 %58 %87\n%363 = OpIAdd %5 %362 %98\n%365 = OpAccessChain %64 %8 %92\n%366 = OpLoad %5 %365\n%367 = OpIAdd %5 %366 %363\n%368 = OpFunctionCall %5 %116 %367 %61 %369\n%364 = OpAccessChain %351 %40 %368\n%370 = OpLoad %37 %364\n%371 = OpCompositeConstruct %29 %57 %58\n%372 = OpCompositeConstruct %41 %292 %292 %292 %292\nOpImageWrite %370 %371 %372\nOpBranch %436\n%436 = OpLabel\n%374 = OpAccessChain %64 %8 %85\n%375 = OpLoad %5 %374\n%376 = OpFunctionCall %5 %116 %375 %299 %377\n%373 = OpAccessChain %294 %28 %376\n%378 = OpLoad %25 %373\n%380 = OpAccessChain %64 %8 %85\n%381 = OpLoad %5 %380\n%382 = OpFunctionCall %5 %116 %381 %305 %383\n%379 = OpAccessChain %102 %33 %57 %382\n%384 = OpLoad %29 %379\n%403 = OpFunctionCall %5 %389 %384 %87 %57\nOpReturn\nOpFunctionEnd\n%81 = OpFunction %1 None %73\n%74 = OpFunctionParameter %5\n%75 = OpFunctionParameter %5\n%76 = OpFunctionParameter %5\n%77 = OpFunctionParameter %5\n%78 = OpFunctionParameter %5\n%79 = OpFunctionParameter %5\n%80 = OpFunctionParameter %5\n%82 = OpLabel\n%84 = OpAccessChain %83 %72 %85\n%86 = OpAtomicIAdd %5 %84 %87 %57 %87\n%88 = OpIEqual %59 %86 %57\nOpSelectionMerge %90 None\nOpBranchConditional %88 %89 %90\n%89 = OpLabel\n%91 = OpAccessChain %83 %72 %92\nOpStore %91 %76\n%93 = OpAccessChain %83 %72 %87\nOpStore %93 %75\n%94 = OpAccessChain %83 %72 %61\nOpStore %94 %77\n%95 = OpAccessChain %83 %72 %96\nOpStore %95 %78\n%97 = OpAccessChain %83 %72 %98\nOpStore %97 %79\n%99 = OpAccessChain %83 %72 %66\nOpStore %99 %80\n%103 = OpAccessChain %102 %72 %57\nOpStore %103 %101\nOpMemoryBarrier %87 %104\n%105 = OpAccessChain %83 %72 %106\nOpStore %105 %74\nOpBranch %90\n%90 = OpLabel\nOpReturn\nOpFunctionEnd\n%116 = OpFunction %5 None %112\n%113 = OpFunctionParameter %5\n%114 = OpFunctionParameter %5\n%115 = OpFunctionParameter %5\n%117 = OpLabel\n%118 = OpAccessChain %83 %111 %57\n%119 = OpLoad %5 %118\n%120 = OpAccessChain %83 %111 %87\n%121 = OpLoad %5 %120\n%122 = OpAccessChain %83 %72 %123\n%124 = OpLoad %5 %122\n%126 = OpAccessChain %125 %111 %61 %113\n%127 = OpLoad %52 %126\n%128 = OpCompositeExtract %5 %127 0\n%129 = OpCompositeExtract %5 %127 1\n%130 = OpCompositeExtract %5 %127 2\n%131 = OpShiftRightLogical %5 %128 %66\n%132 = OpBitwiseAnd %5 %128 %133\n%134 = OpAccessChain %83 %72 %135 %131\n%136 = OpLoad %5 %134\n%137 = OpShiftLeftLogical %5 %87 %132\n%138 = OpBitwiseAnd %5 %136 %137\n%139 = OpINotEqual %59 %138 %57\n%140 = OpBitwiseAnd %5 %130 %114\n%141 = OpIEqual %59 %140 %114\n%142 = OpUGreaterThanEqual %59 %113 %119\n%143 = OpSelect %5 %142 %87 %57\n%144 = OpSelect %5 %141 %57 %61\n%145 = OpSelect %5 %139 %57 %85\n%146 = OpUGreaterThanEqual %59 %124 %129\n%147 = OpSelect %5 %146 %57 %106\n%148 = OpBitwiseOr %5 %143 %144\n%149 = OpBitwiseOr %5 %148 %145\n%150 = OpBitwiseOr %5 %149 %147\n%151 = OpINotEqual %59 %150 %57\nOpSelectionMerge %153 None\nOpBranchConditional %151 %152 %153\n%152 = OpLabel\n%154 = OpFunctionCall %1 %81 %150 %113 %128 %121 %114 %130 %115\nOpReturnValue %119\n%153 = OpLabel\nOpReturnValue %113\nOpFunctionEnd\n%389 = OpFunction %5 None %385\n%386 = OpFunctionParameter %29\n%387 = OpFunctionParameter %5\n%388 = OpFunctionParameter %5\n%390 = OpLabel\n%395 = OpINotEqual %393 %386 %394\n%396 = OpAny %59 %395\nOpSelectionMerge %392 None\nOpBranchConditional %396 %391 %392\n%391 = OpLabel\n%398 = OpBitcast %397 %386\n%399 = OpAtomicIAdd %5 %398 %87 %57 %387\n%400 = OpIAdd %5 %399 %388\nOpBranch %392\n%392 = OpLabel\n%401 = OpPhi %5 %57 %390 %400 %391\nOpReturnValue %401\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/descriptor_qa.bindless.descriptor-qa.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _33;\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _47[];\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 1, binding = 0) uniform samplerBuffer _17[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _21[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _24[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _28[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _36[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _40[];\nlayout(set = 2, binding = 0) uniform sampler _51[];\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _88 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_88 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _121 = QAHeapData.descriptor_count;\n    uint _123 = QAHeapData.heap_index;\n    uint _126 = QAGlobalData.va_map_timestamp;\n    uvec3 _129 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _138 = QAGlobalData.live_status_table[_129.x >> 5u];\n    uint _152 = ((uint(heap_offset >= _121) | (((_129.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_138 & (1u << (_129.x & 31u))) != 0u) ? 0u : 4u)) | ((_126 >= _129.y) ? 0u : 8u);\n    if (_152 != 0u)\n    {\n        descriptor_qa_report_fault(_152, heap_offset, _129.x, _123, descriptor_type_mask, _129.z, instruction);\n        return _121;\n    }\n    return heap_offset;\n}\n\nuint RobustPhysicalAtomicCounter(uvec2 _409, uint _410, uint _411)\n{\n    uint _424;\n    if (any(notEqual(_409, uvec2(0u))))\n    {\n        uint _422 = atomicAdd(uintPointer(_409).value, _410);\n        _424 = _422 + _411;\n    }\n    else\n    {\n        _424 = 0u;\n    }\n    return _424;\n}\n\nvoid main()\n{\n    float _163;\n    if ((gl_GlobalInvocationID.x & 3423432u) > 2u)\n    {\n        uint _70 = descriptor_qa_check(registers._m5, 4u, 1u);\n        _163 = _47[_70]._m0[0u].x;\n    }\n    else\n    {\n        _163 = 0.0;\n    }\n    float _178;\n    if ((gl_GlobalInvocationID.x & 234232u) > 3u)\n    {\n        uint _173 = descriptor_qa_check(registers._m5 + (gl_GlobalInvocationID.x + 1u), 4u, 2u);\n        _178 = _47[_173]._m0[0u].x + _163;\n    }\n    else\n    {\n        _178 = _163;\n    }\n    float _201;\n    if ((gl_GlobalInvocationID.x & 236234u) > 4u)\n    {\n        uint _186 = descriptor_qa_check(registers._m0, 1u, 3u);\n        _201 = textureLod(sampler2D(_13[_186], _51[registers._m2]), vec2(0.5), 0.0).x + _178;\n    }\n    else\n    {\n        _201 = _178;\n    }\n    uint _202 = gl_GlobalInvocationID.x & 34234u;\n    float _217;\n    if (_202 > 5u)\n    {\n        uint _211 = descriptor_qa_check(registers._m0 + ((gl_GlobalInvocationID.x & 1u) + 1u), 1u, 4u);\n        _217 = texelFetch(_13[_211], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), int(0u)).x + _201;\n    }\n    else\n    {\n        _217 = _201;\n    }\n    float _232;\n    if ((gl_GlobalInvocationID.x & 234u) > 6u)\n    {\n        uint _226 = descriptor_qa_check(registers._m1 + 3u, 16u, 5u);\n        _232 = texelFetch(_17[_226], int(gl_GlobalInvocationID.x)).x + _217;\n    }\n    else\n    {\n        _232 = _217;\n    }\n    float _246;\n    if ((gl_GlobalInvocationID.x & 16u) > 7u)\n    {\n        uint _241 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 4u), 16u, 6u);\n        _246 = texelFetch(_17[_241], int(gl_GlobalInvocationID.x)).x + _232;\n    }\n    else\n    {\n        _246 = _232;\n    }\n    float _262;\n    if ((gl_GlobalInvocationID.x & 9234234u) > 8u)\n    {\n        uint _255 = descriptor_qa_check(registers._m1 + 6u, 16u, 7u);\n        _262 = uintBitsToFloat(texelFetch(_21[_255], int(gl_GlobalInvocationID.x)).x) + _246;\n    }\n    else\n    {\n        _262 = _246;\n    }\n    float _278;\n    if ((gl_GlobalInvocationID.x & 2342342u) > 9u)\n    {\n        uint _272 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 7u), 16u, 8u);\n        _278 = uintBitsToFloat(texelFetch(_21[_272], int(gl_GlobalInvocationID.x)).x) + _262;\n    }\n    else\n    {\n        _278 = _262;\n    }\n    float _293;\n    if ((gl_GlobalInvocationID.x & 234234324u) > 10u)\n    {\n        uint _287 = descriptor_qa_check(registers._m1 + 9u, 16u, 9u);\n        _293 = uintBitsToFloat(texelFetch(_24[_287], int(gl_GlobalInvocationID.x)).x) + _278;\n    }\n    else\n    {\n        _293 = _278;\n    }\n    float _311;\n    if ((gl_GlobalInvocationID.x & 234234232u) > 11u)\n    {\n        uint _304 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 10u), 16u, 10u);\n        _311 = uintBitsToFloat(texelFetch(_24[_304], int(gl_GlobalInvocationID.x >> 2u)).x) + _293;\n    }\n    else\n    {\n        _311 = _293;\n    }\n    if ((gl_GlobalInvocationID.x & 234884u) > 1u)\n    {\n        uint _319 = descriptor_qa_check(registers._m4, 32u, 11u);\n        imageStore(_28[_319], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_311)));\n    }\n    if ((gl_GlobalInvocationID.x & 9999u) > 30u)\n    {\n        uint _334 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 1u), 32u, 12u);\n        imageStore(_28[_334], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_311)));\n    }\n    if ((gl_GlobalInvocationID.x & 8888u) > 40u)\n    {\n        uint _349 = descriptor_qa_check(registers._m4 + 3u, 32u, 13u);\n        imageStore(_36[_349], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_311)));\n    }\n    if ((gl_GlobalInvocationID.x & 7777u) > 50u)\n    {\n        uint _365 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 4u), 32u, 14u);\n        imageStore(_36[_365], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_311)));\n    }\n    if ((gl_GlobalInvocationID.x & 5555u) > 80u)\n    {\n        uint _378 = descriptor_qa_check(registers._m3 + 6u, 2u, 15u);\n        imageStore(_40[_378], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(_311));\n    }\n    if (_202 > 90u)\n    {\n        uint _391 = descriptor_qa_check(registers._m3 + ((gl_GlobalInvocationID.x & 1u) + 7u), 2u, 16u);\n        imageStore(_40[_391], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), vec4(_311));\n    }\n    uint _398 = descriptor_qa_check(registers._m4, 32u, 17u);\n    uint _404 = descriptor_qa_check(registers._m4, 256u, 18u);\n    uvec2 _407 = _33.counters[_404];\n    uint _426 = RobustPhysicalAtomicCounter(_407, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 461\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %54\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %31 \"AtomicCounters\"\nOpMemberName %31 0 \"counters\"\nOpName %44 \"BindlessCBV\"\nOpName %72 \"DescriptorHeapGlobalQAData\"\nOpMemberName %72 0 \"failed_shader_hash\"\nOpMemberName %72 1 \"failed_offset\"\nOpMemberName %72 2 \"failed_heap\"\nOpMemberName %72 3 \"failed_cookie\"\nOpMemberName %72 4 \"fault_atomic\"\nOpMemberName %72 5 \"failed_instruction\"\nOpMemberName %72 6 \"failed_descriptor_type_mask\"\nOpMemberName %72 7 \"actual_descriptor_type_mask\"\nOpMemberName %72 8 \"fault_type\"\nOpMemberName %72 9 \"va_map_timestamp\"\nOpMemberName %72 10 \"live_status_table\"\nOpName %74 \"QAGlobalData\"\nOpName %83 \"descriptor_qa_report_fault\"\nOpName %76 \"fault_type\"\nOpName %77 \"heap_offset\"\nOpName %78 \"cookie\"\nOpName %79 \"heap_index\"\nOpName %80 \"descriptor_type\"\nOpName %81 \"actual_descriptor_type\"\nOpName %82 \"instruction\"\nOpName %111 \"DescriptorHeapQAData\"\nOpMemberName %111 0 \"descriptor_count\"\nOpMemberName %111 1 \"heap_index\"\nOpMemberName %111 2 \"cookies_descriptor_info\"\nOpName %113 \"QAHeapData\"\nOpName %118 \"descriptor_qa_check\"\nOpName %115 \"heap_offset\"\nOpName %116 \"descriptor_type_mask\"\nOpName %117 \"instruction\"\nOpName %412 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 1\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %28 DescriptorSet 4\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %30 ArrayStride 8\nOpDecorate %31 Block\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 0 NonWritable\nOpDecorate %33 DescriptorSet 7\nOpDecorate %33 Binding 0\nOpDecorate %33 AliasedPointer\nOpDecorate %36 DescriptorSet 4\nOpDecorate %36 Binding 0\nOpDecorate %36 NonReadable\nOpDecorate %40 DescriptorSet 3\nOpDecorate %40 Binding 0\nOpDecorate %40 NonReadable\nOpDecorate %43 ArrayStride 16\nOpDecorate %44 Block\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %47 DescriptorSet 5\nOpDecorate %47 Binding 0\nOpDecorate %51 DescriptorSet 2\nOpDecorate %51 Binding 0\nOpDecorate %54 BuiltIn GlobalInvocationId\nOpDecorate %71 ArrayStride 4\nOpMemberDecorate %72 0 Offset 0\nOpMemberDecorate %72 1 Offset 8\nOpMemberDecorate %72 2 Offset 12\nOpMemberDecorate %72 3 Offset 16\nOpMemberDecorate %72 4 Offset 20\nOpMemberDecorate %72 5 Offset 24\nOpMemberDecorate %72 6 Offset 28\nOpMemberDecorate %72 7 Offset 32\nOpMemberDecorate %72 8 Offset 36\nOpMemberDecorate %72 9 Offset 40\nOpMemberDecorate %72 10 Offset 44\nOpDecorate %72 Block\nOpDecorate %74 DescriptorSet 10\nOpDecorate %74 Binding 10\nOpDecorate %110 ArrayStride 12\nOpMemberDecorate %111 0 Offset 0\nOpMemberDecorate %111 1 Offset 4\nOpMemberDecorate %111 2 Offset 8\nOpDecorate %111 Block\nOpDecorate %113 DescriptorSet 10\nOpDecorate %113 Binding 11\nOpDecorate %113 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeRuntimeArray %18\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeVector %5 2\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypeStruct %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeRuntimeArray %25\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%38 = OpTypeRuntimeArray %37\n%39 = OpTypePointer UniformConstant %38\n%40 = OpVariable %39 UniformConstant\n%41 = OpTypeVector %9 4\n%42 = OpConstant %5 4096\n%43 = OpTypeArray %41 %42\n%44 = OpTypeStruct %43\n%45 = OpTypeRuntimeArray %44\n%46 = OpTypePointer Uniform %45\n%47 = OpVariable %46 Uniform\n%48 = OpTypeSampler\n%49 = OpTypeRuntimeArray %48\n%50 = OpTypePointer UniformConstant %49\n%51 = OpVariable %50 UniformConstant\n%52 = OpTypeVector %5 3\n%53 = OpTypePointer Input %52\n%54 = OpVariable %53 Input\n%55 = OpTypePointer Input %5\n%57 = OpConstant %5 0\n%60 = OpConstant %5 3423432\n%61 = OpTypeBool\n%63 = OpConstant %5 2\n%64 = OpTypePointer Uniform %44\n%66 = OpTypePointer PushConstant %5\n%68 = OpConstant %5 5\n%71 = OpTypeRuntimeArray %5\n%72 = OpTypeStruct %29 %5 %5 %5 %5 %5 %5 %5 %5 %5 %71\n%73 = OpTypePointer StorageBuffer %72\n%74 = OpVariable %73 StorageBuffer\n%75 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%85 = OpTypePointer StorageBuffer %5\n%87 = OpConstant %5 4\n%89 = OpConstant %5 1\n%94 = OpConstant %5 3\n%98 = OpConstant %5 6\n%100 = OpConstant %5 7\n%102 = OpConstant %5 3735928559\n%103 = OpConstantComposite %29 %102 %57\n%104 = OpTypePointer StorageBuffer %29\n%106 = OpConstant %5 72\n%108 = OpConstant %5 8\n%110 = OpTypeRuntimeArray %52\n%111 = OpTypeStruct %5 %5 %110\n%112 = OpTypePointer StorageBuffer %111\n%113 = OpVariable %112 StorageBuffer\n%114 = OpTypeFunction %5 %5 %5 %5\n%125 = OpConstant %5 9\n%127 = OpTypePointer StorageBuffer %52\n%135 = OpConstant %5 31\n%137 = OpConstant %5 10\n%159 = OpTypePointer Uniform %41\n%164 = OpConstant %9 0\n%166 = OpConstant %5 234232\n%180 = OpConstant %5 236234\n%182 = OpTypePointer UniformConstant %10\n%188 = OpTypePointer UniformConstant %48\n%193 = OpTypeSampledImage %10\n%195 = OpConstant %9 0.5\n%197 = OpTypeVector %9 2\n%203 = OpConstant %5 34234\n%219 = OpConstant %5 234\n%221 = OpTypePointer UniformConstant %14\n%227 = OpConstant %5 16\n%248 = OpConstant %5 9234234\n%250 = OpTypePointer UniformConstant %18\n%257 = OpTypeVector %5 4\n%264 = OpConstant %5 2342342\n%280 = OpConstant %5 234234324\n%295 = OpConstant %5 234234232\n%297 = OpConstant %5 11\n%313 = OpConstant %5 234884\n%315 = OpTypePointer UniformConstant %25\n%320 = OpConstant %5 32\n%325 = OpConstant %5 9999\n%327 = OpConstant %5 30\n%335 = OpConstant %5 12\n%340 = OpConstant %5 8888\n%342 = OpConstant %5 40\n%350 = OpConstant %5 13\n%354 = OpConstant %5 7777\n%356 = OpConstant %5 50\n%366 = OpConstant %5 14\n%370 = OpConstant %5 5555\n%372 = OpConstant %5 80\n%373 = OpTypePointer UniformConstant %37\n%379 = OpConstant %5 15\n%384 = OpConstant %5 90\n%399 = OpConstant %5 17\n%405 = OpConstant %5 256\n%406 = OpConstant %5 18\n%408 = OpTypeFunction %5 %29 %5 %5\n%416 = OpTypeVector %61 2\n%417 = OpConstantNull %29\n%420 = OpTypePointer PhysicalStorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %427\n%427 = OpLabel\n%56 = OpAccessChain %55 %54 %57\n%58 = OpLoad %5 %56\n%59 = OpBitwiseAnd %5 %58 %60\n%62 = OpUGreaterThan %61 %59 %63\nOpSelectionMerge %429 None\nOpBranchConditional %62 %428 %429\n%428 = OpLabel\n%67 = OpAccessChain %66 %8 %68\n%69 = OpLoad %5 %67\n%70 = OpFunctionCall %5 %118 %69 %87 %89\n%65 = OpAccessChain %64 %47 %70\n%160 = OpAccessChain %159 %65 %57 %57\n%161 = OpLoad %41 %160\n%162 = OpCompositeExtract %9 %161 0\nOpBranch %429\n%429 = OpLabel\n%163 = OpPhi %9 %164 %427 %162 %428\n%165 = OpBitwiseAnd %5 %58 %166\n%167 = OpUGreaterThan %61 %165 %94\nOpSelectionMerge %431 None\nOpBranchConditional %167 %430 %431\n%430 = OpLabel\n%168 = OpIAdd %5 %58 %89\n%170 = OpAccessChain %66 %8 %68\n%171 = OpLoad %5 %170\n%172 = OpIAdd %5 %171 %168\n%173 = OpFunctionCall %5 %118 %172 %87 %63\n%169 = OpAccessChain %64 %47 %173\n%174 = OpAccessChain %159 %169 %57 %57\n%175 = OpLoad %41 %174\n%176 = OpCompositeExtract %9 %175 0\n%177 = OpFAdd %9 %176 %163\nOpBranch %431\n%431 = OpLabel\n%178 = OpPhi %9 %163 %429 %177 %430\n%179 = OpBitwiseAnd %5 %58 %180\n%181 = OpUGreaterThan %61 %179 %87\nOpSelectionMerge %433 None\nOpBranchConditional %181 %432 %433\n%432 = OpLabel\n%184 = OpAccessChain %66 %8 %57\n%185 = OpLoad %5 %184\n%186 = OpFunctionCall %5 %118 %185 %89 %94\n%183 = OpAccessChain %182 %13 %186\n%187 = OpLoad %10 %183\n%190 = OpAccessChain %66 %8 %63\n%191 = OpLoad %5 %190\n%189 = OpAccessChain %188 %51 %191\n%192 = OpLoad %48 %189\n%194 = OpSampledImage %193 %187 %192\n%198 = OpCompositeConstruct %197 %195 %195\n%196 = OpImageSampleExplicitLod %41 %194 %198 Lod %164\n%199 = OpCompositeExtract %9 %196 0\n%200 = OpFAdd %9 %199 %178\nOpBranch %433\n%433 = OpLabel\n%201 = OpPhi %9 %178 %431 %200 %432\n%202 = OpBitwiseAnd %5 %58 %203\n%204 = OpUGreaterThan %61 %202 %68\nOpSelectionMerge %435 None\nOpBranchConditional %204 %434 %435\n%434 = OpLabel\n%205 = OpBitwiseAnd %5 %58 %89\n%206 = OpIAdd %5 %205 %89\n%208 = OpAccessChain %66 %8 %57\n%209 = OpLoad %5 %208\n%210 = OpIAdd %5 %209 %206\n%211 = OpFunctionCall %5 %118 %210 %89 %87\n%207 = OpAccessChain %182 %13 %211\n%212 = OpLoad %10 %207\n%214 = OpCompositeConstruct %29 %57 %58\n%213 = OpImageFetch %41 %212 %214 Lod %57\n%215 = OpCompositeExtract %9 %213 0\n%216 = OpFAdd %9 %215 %201\nOpBranch %435\n%435 = OpLabel\n%217 = OpPhi %9 %201 %433 %216 %434\n%218 = OpBitwiseAnd %5 %58 %219\n%220 = OpUGreaterThan %61 %218 %98\nOpSelectionMerge %437 None\nOpBranchConditional %220 %436 %437\n%436 = OpLabel\n%223 = OpAccessChain %66 %8 %89\n%224 = OpLoad %5 %223\n%225 = OpIAdd %5 %224 %94\n%226 = OpFunctionCall %5 %118 %225 %227 %68\n%222 = OpAccessChain %221 %17 %226\n%228 = OpLoad %14 %222\n%229 = OpImageFetch %41 %228 %58\n%230 = OpCompositeExtract %9 %229 0\n%231 = OpFAdd %9 %230 %217\nOpBranch %437\n%437 = OpLabel\n%232 = OpPhi %9 %217 %435 %231 %436\n%233 = OpBitwiseAnd %5 %58 %227\n%234 = OpUGreaterThan %61 %233 %100\nOpSelectionMerge %439 None\nOpBranchConditional %234 %438 %439\n%438 = OpLabel\n%235 = OpBitwiseAnd %5 %58 %89\n%236 = OpIAdd %5 %235 %87\n%238 = OpAccessChain %66 %8 %89\n%239 = OpLoad %5 %238\n%240 = OpIAdd %5 %239 %236\n%241 = OpFunctionCall %5 %118 %240 %227 %98\n%237 = OpAccessChain %221 %17 %241\n%242 = OpLoad %14 %237\n%243 = OpImageFetch %41 %242 %58\n%244 = OpCompositeExtract %9 %243 0\n%245 = OpFAdd %9 %244 %232\nOpBranch %439\n%439 = OpLabel\n%246 = OpPhi %9 %232 %437 %245 %438\n%247 = OpBitwiseAnd %5 %58 %248\n%249 = OpUGreaterThan %61 %247 %108\nOpSelectionMerge %441 None\nOpBranchConditional %249 %440 %441\n%440 = OpLabel\n%252 = OpAccessChain %66 %8 %89\n%253 = OpLoad %5 %252\n%254 = OpIAdd %5 %253 %98\n%255 = OpFunctionCall %5 %118 %254 %227 %100\n%251 = OpAccessChain %250 %21 %255\n%256 = OpLoad %18 %251\n%258 = OpImageFetch %257 %256 %58\n%259 = OpCompositeExtract %5 %258 0\n%260 = OpBitcast %9 %259\n%261 = OpFAdd %9 %260 %246\nOpBranch %441\n%441 = OpLabel\n%262 = OpPhi %9 %246 %439 %261 %440\n%263 = OpBitwiseAnd %5 %58 %264\n%265 = OpUGreaterThan %61 %263 %125\nOpSelectionMerge %443 None\nOpBranchConditional %265 %442 %443\n%442 = OpLabel\n%266 = OpBitwiseAnd %5 %58 %89\n%267 = OpIAdd %5 %266 %100\n%269 = OpAccessChain %66 %8 %89\n%270 = OpLoad %5 %269\n%271 = OpIAdd %5 %270 %267\n%272 = OpFunctionCall %5 %118 %271 %227 %108\n%268 = OpAccessChain %250 %21 %272\n%273 = OpLoad %18 %268\n%274 = OpImageFetch %257 %273 %58\n%275 = OpCompositeExtract %5 %274 0\n%276 = OpBitcast %9 %275\n%277 = OpFAdd %9 %276 %262\nOpBranch %443\n%443 = OpLabel\n%278 = OpPhi %9 %262 %441 %277 %442\n%279 = OpBitwiseAnd %5 %58 %280\n%281 = OpUGreaterThan %61 %279 %137\nOpSelectionMerge %445 None\nOpBranchConditional %281 %444 %445\n%444 = OpLabel\n%282 = OpShiftLeftLogical %5 %58 %63\n%284 = OpAccessChain %66 %8 %89\n%285 = OpLoad %5 %284\n%286 = OpIAdd %5 %285 %125\n%287 = OpFunctionCall %5 %118 %286 %227 %125\n%283 = OpAccessChain %250 %24 %287\n%288 = OpLoad %18 %283\n%289 = OpImageFetch %257 %288 %58\n%290 = OpCompositeExtract %5 %289 0\n%291 = OpBitcast %9 %290\n%292 = OpFAdd %9 %291 %278\nOpBranch %445\n%445 = OpLabel\n%293 = OpPhi %9 %278 %443 %292 %444\n%294 = OpBitwiseAnd %5 %58 %295\n%296 = OpUGreaterThan %61 %294 %297\nOpSelectionMerge %447 None\nOpBranchConditional %296 %446 %447\n%446 = OpLabel\n%298 = OpBitwiseAnd %5 %58 %89\n%299 = OpIAdd %5 %298 %137\n%301 = OpAccessChain %66 %8 %89\n%302 = OpLoad %5 %301\n%303 = OpIAdd %5 %302 %299\n%304 = OpFunctionCall %5 %118 %303 %227 %137\n%300 = OpAccessChain %250 %24 %304\n%305 = OpLoad %18 %300\n%306 = OpShiftRightLogical %5 %58 %63\n%307 = OpImageFetch %257 %305 %306\n%308 = OpCompositeExtract %5 %307 0\n%309 = OpBitcast %9 %308\n%310 = OpFAdd %9 %309 %293\nOpBranch %447\n%447 = OpLabel\n%311 = OpPhi %9 %293 %445 %310 %446\n%312 = OpBitwiseAnd %5 %58 %313\n%314 = OpUGreaterThan %61 %312 %89\nOpSelectionMerge %449 None\nOpBranchConditional %314 %448 %449\n%448 = OpLabel\n%317 = OpAccessChain %66 %8 %87\n%318 = OpLoad %5 %317\n%319 = OpFunctionCall %5 %118 %318 %320 %297\n%316 = OpAccessChain %315 %28 %319\n%321 = OpLoad %25 %316\n%322 = OpBitcast %5 %311\n%323 = OpCompositeConstruct %257 %322 %322 %322 %322\nOpImageWrite %321 %58 %323\nOpBranch %449\n%449 = OpLabel\n%324 = OpBitwiseAnd %5 %58 %325\n%326 = OpUGreaterThan %61 %324 %327\nOpSelectionMerge %451 None\nOpBranchConditional %326 %450 %451\n%450 = OpLabel\n%328 = OpBitwiseAnd %5 %58 %89\n%329 = OpIAdd %5 %328 %89\n%331 = OpAccessChain %66 %8 %87\n%332 = OpLoad %5 %331\n%333 = OpIAdd %5 %332 %329\n%334 = OpFunctionCall %5 %118 %333 %320 %335\n%330 = OpAccessChain %315 %28 %334\n%336 = OpLoad %25 %330\n%337 = OpBitcast %5 %311\n%338 = OpCompositeConstruct %257 %337 %337 %337 %337\nOpImageWrite %336 %58 %338\nOpBranch %451\n%451 = OpLabel\n%339 = OpBitwiseAnd %5 %58 %340\n%341 = OpUGreaterThan %61 %339 %342\nOpSelectionMerge %453 None\nOpBranchConditional %341 %452 %453\n%452 = OpLabel\n%343 = OpBitcast %5 %311\n%344 = OpShiftLeftLogical %5 %58 %63\n%346 = OpAccessChain %66 %8 %87\n%347 = OpLoad %5 %346\n%348 = OpIAdd %5 %347 %94\n%349 = OpFunctionCall %5 %118 %348 %320 %350\n%345 = OpAccessChain %315 %36 %349\n%351 = OpLoad %25 %345\n%352 = OpCompositeConstruct %257 %343 %343 %343 %343\nOpImageWrite %351 %58 %352\nOpBranch %453\n%453 = OpLabel\n%353 = OpBitwiseAnd %5 %58 %354\n%355 = OpUGreaterThan %61 %353 %356\nOpSelectionMerge %455 None\nOpBranchConditional %355 %454 %455\n%454 = OpLabel\n%357 = OpBitwiseAnd %5 %58 %89\n%358 = OpBitcast %5 %311\n%359 = OpShiftLeftLogical %5 %58 %63\n%360 = OpIAdd %5 %357 %87\n%362 = OpAccessChain %66 %8 %87\n%363 = OpLoad %5 %362\n%364 = OpIAdd %5 %363 %360\n%365 = OpFunctionCall %5 %118 %364 %320 %366\n%361 = OpAccessChain %315 %36 %365\n%367 = OpLoad %25 %361\n%368 = OpCompositeConstruct %257 %358 %358 %358 %358\nOpImageWrite %367 %58 %368\nOpBranch %455\n%455 = OpLabel\n%369 = OpBitwiseAnd %5 %58 %370\n%371 = OpUGreaterThan %61 %369 %372\nOpSelectionMerge %457 None\nOpBranchConditional %371 %456 %457\n%456 = OpLabel\n%375 = OpAccessChain %66 %8 %94\n%376 = OpLoad %5 %375\n%377 = OpIAdd %5 %376 %98\n%378 = OpFunctionCall %5 %118 %377 %63 %379\n%374 = OpAccessChain %373 %40 %378\n%380 = OpLoad %37 %374\n%381 = OpCompositeConstruct %29 %58 %57\n%382 = OpCompositeConstruct %41 %311 %311 %311 %311\nOpImageWrite %380 %381 %382\nOpBranch %457\n%457 = OpLabel\n%383 = OpUGreaterThan %61 %202 %384\nOpSelectionMerge %459 None\nOpBranchConditional %383 %458 %459\n%458 = OpLabel\n%385 = OpBitwiseAnd %5 %58 %89\n%386 = OpIAdd %5 %385 %100\n%388 = OpAccessChain %66 %8 %94\n%389 = OpLoad %5 %388\n%390 = OpIAdd %5 %389 %386\n%391 = OpFunctionCall %5 %118 %390 %63 %227\n%387 = OpAccessChain %373 %40 %391\n%392 = OpLoad %37 %387\n%393 = OpCompositeConstruct %29 %57 %58\n%394 = OpCompositeConstruct %41 %311 %311 %311 %311\nOpImageWrite %392 %393 %394\nOpBranch %459\n%459 = OpLabel\n%396 = OpAccessChain %66 %8 %87\n%397 = OpLoad %5 %396\n%398 = OpFunctionCall %5 %118 %397 %320 %399\n%395 = OpAccessChain %315 %28 %398\n%400 = OpLoad %25 %395\n%402 = OpAccessChain %66 %8 %87\n%403 = OpLoad %5 %402\n%404 = OpFunctionCall %5 %118 %403 %405 %406\n%401 = OpAccessChain %104 %33 %57 %404\n%407 = OpLoad %29 %401\n%426 = OpFunctionCall %5 %412 %407 %89 %57\nOpReturn\nOpFunctionEnd\n%83 = OpFunction %1 None %75\n%76 = OpFunctionParameter %5\n%77 = OpFunctionParameter %5\n%78 = OpFunctionParameter %5\n%79 = OpFunctionParameter %5\n%80 = OpFunctionParameter %5\n%81 = OpFunctionParameter %5\n%82 = OpFunctionParameter %5\n%84 = OpLabel\n%86 = OpAccessChain %85 %74 %87\n%88 = OpAtomicIAdd %5 %86 %89 %57 %89\n%90 = OpIEqual %61 %88 %57\nOpSelectionMerge %92 None\nOpBranchConditional %90 %91 %92\n%91 = OpLabel\n%93 = OpAccessChain %85 %74 %94\nOpStore %93 %78\n%95 = OpAccessChain %85 %74 %89\nOpStore %95 %77\n%96 = OpAccessChain %85 %74 %63\nOpStore %96 %79\n%97 = OpAccessChain %85 %74 %98\nOpStore %97 %80\n%99 = OpAccessChain %85 %74 %100\nOpStore %99 %81\n%101 = OpAccessChain %85 %74 %68\nOpStore %101 %82\n%105 = OpAccessChain %104 %74 %57\nOpStore %105 %103\nOpMemoryBarrier %89 %106\n%107 = OpAccessChain %85 %74 %108\nOpStore %107 %76\nOpBranch %92\n%92 = OpLabel\nOpReturn\nOpFunctionEnd\n%118 = OpFunction %5 None %114\n%115 = OpFunctionParameter %5\n%116 = OpFunctionParameter %5\n%117 = OpFunctionParameter %5\n%119 = OpLabel\n%120 = OpAccessChain %85 %113 %57\n%121 = OpLoad %5 %120\n%122 = OpAccessChain %85 %113 %89\n%123 = OpLoad %5 %122\n%124 = OpAccessChain %85 %74 %125\n%126 = OpLoad %5 %124\n%128 = OpAccessChain %127 %113 %63 %115\n%129 = OpLoad %52 %128\n%130 = OpCompositeExtract %5 %129 0\n%131 = OpCompositeExtract %5 %129 1\n%132 = OpCompositeExtract %5 %129 2\n%133 = OpShiftRightLogical %5 %130 %68\n%134 = OpBitwiseAnd %5 %130 %135\n%136 = OpAccessChain %85 %74 %137 %133\n%138 = OpLoad %5 %136\n%139 = OpShiftLeftLogical %5 %89 %134\n%140 = OpBitwiseAnd %5 %138 %139\n%141 = OpINotEqual %61 %140 %57\n%142 = OpBitwiseAnd %5 %132 %116\n%143 = OpIEqual %61 %142 %116\n%144 = OpUGreaterThanEqual %61 %115 %121\n%145 = OpSelect %5 %144 %89 %57\n%146 = OpSelect %5 %143 %57 %63\n%147 = OpSelect %5 %141 %57 %87\n%148 = OpUGreaterThanEqual %61 %126 %131\n%149 = OpSelect %5 %148 %57 %108\n%150 = OpBitwiseOr %5 %145 %146\n%151 = OpBitwiseOr %5 %150 %147\n%152 = OpBitwiseOr %5 %151 %149\n%153 = OpINotEqual %61 %152 %57\nOpSelectionMerge %155 None\nOpBranchConditional %153 %154 %155\n%154 = OpLabel\n%156 = OpFunctionCall %1 %83 %152 %115 %130 %123 %116 %132 %117\nOpReturnValue %121\n%155 = OpLabel\nOpReturnValue %115\nOpFunctionEnd\n%412 = OpFunction %5 None %408\n%409 = OpFunctionParameter %29\n%410 = OpFunctionParameter %5\n%411 = OpFunctionParameter %5\n%413 = OpLabel\n%418 = OpINotEqual %416 %409 %417\n%419 = OpAny %61 %418\nOpSelectionMerge %415 None\nOpBranchConditional %419 %414 %415\n%414 = OpLabel\n%421 = OpBitcast %420 %409\n%422 = OpAtomicIAdd %5 %421 %89 %57 %410\n%423 = OpIAdd %5 %422 %411\nOpBranch %415\n%415 = OpLabel\n%424 = OpPhi %5 %57 %413 %423 %414\nOpReturnValue %424\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/descriptor_qa.bindless.ssbo.descriptor-qa.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _22[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _24_27\n{\n    uint _m0[];\n} _27[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _29_32\n{\n    uint _m0[];\n} _32[];\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _37;\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _39_42\n{\n    uint _m0[];\n} _42[];\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _53[];\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 1, binding = 0) uniform samplerBuffer _17[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _46[];\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _88 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_88 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _121 = QAHeapData.descriptor_count;\n    uint _123 = QAHeapData.heap_index;\n    uint _126 = QAGlobalData.va_map_timestamp;\n    uvec3 _129 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _138 = QAGlobalData.live_status_table[_129.x >> 5u];\n    uint _152 = ((uint(heap_offset >= _121) | (((_129.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_138 & (1u << (_129.x & 31u))) != 0u) ? 0u : 4u)) | ((_126 >= _129.y) ? 0u : 8u);\n    if (_152 != 0u)\n    {\n        descriptor_qa_report_fault(_152, heap_offset, _129.x, _123, descriptor_type_mask, _129.z, instruction);\n        return _121;\n    }\n    return heap_offset;\n}\n\nuint RobustPhysicalAtomicCounter(uvec2 _370, uint _371, uint _372)\n{\n    uint _385;\n    if (any(notEqual(_370, uvec2(0u))))\n    {\n        uint _383 = atomicAdd(uintPointer(_370).value, _371);\n        _385 = _383 + _372;\n    }\n    else\n    {\n        _385 = 0u;\n    }\n    return _385;\n}\n\nvoid main()\n{\n    float _163;\n    if (gl_GlobalInvocationID.x > 2u)\n    {\n        uint _70 = descriptor_qa_check(registers._m5, 4u, 1u);\n        _163 = _53[_70]._m0[0u].x;\n    }\n    else\n    {\n        _163 = 0.0;\n    }\n    float _176;\n    if (gl_GlobalInvocationID.x > 3u)\n    {\n        uint _171 = descriptor_qa_check(registers._m5 + (gl_GlobalInvocationID.x + 1u), 4u, 2u);\n        _176 = _53[_171]._m0[0u].x + _163;\n    }\n    else\n    {\n        _176 = _163;\n    }\n    float _188;\n    if (gl_GlobalInvocationID.x > 4u)\n    {\n        uint _182 = descriptor_qa_check(registers._m0, 1u, 3u);\n        _188 = texelFetch(_13[_182], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), int(0u)).x + _176;\n    }\n    else\n    {\n        _188 = _176;\n    }\n    float _202;\n    if (gl_GlobalInvocationID.x > 5u)\n    {\n        uint _196 = descriptor_qa_check(registers._m0 + ((gl_GlobalInvocationID.x & 1u) + 1u), 1u, 4u);\n        _202 = texelFetch(_13[_196], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), int(0u)).x + _188;\n    }\n    else\n    {\n        _202 = _188;\n    }\n    float _215;\n    if (gl_GlobalInvocationID.x > 6u)\n    {\n        uint _209 = descriptor_qa_check(registers._m1 + 3u, 16u, 5u);\n        _215 = texelFetch(_17[_209], int(gl_GlobalInvocationID.x)).x + _202;\n    }\n    else\n    {\n        _215 = _202;\n    }\n    float _228;\n    if (gl_GlobalInvocationID.x > 7u)\n    {\n        uint _223 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 4u), 16u, 6u);\n        _228 = texelFetch(_17[_223], int(gl_GlobalInvocationID.x)).x + _215;\n    }\n    else\n    {\n        _228 = _215;\n    }\n    float _240;\n    if (gl_GlobalInvocationID.x > 8u)\n    {\n        uint _235 = descriptor_qa_check(registers._m1 + 6u, 8u, 7u);\n        _240 = uintBitsToFloat(_22[_235]._m0[gl_GlobalInvocationID.x]) + _228;\n    }\n    else\n    {\n        _240 = _228;\n    }\n    float _253;\n    if (gl_GlobalInvocationID.x > 9u)\n    {\n        uint _248 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 7u), 8u, 8u);\n        _253 = uintBitsToFloat(_22[_248]._m0[gl_GlobalInvocationID.x]) + _240;\n    }\n    else\n    {\n        _253 = _240;\n    }\n    float _266;\n    if (gl_GlobalInvocationID.x > 10u)\n    {\n        uint _260 = descriptor_qa_check(registers._m1 + 9u, 8u, 9u);\n        _266 = uintBitsToFloat(_27[_260]._m0[gl_GlobalInvocationID.x]) + _253;\n    }\n    else\n    {\n        _266 = _253;\n    }\n    float _281;\n    if (gl_GlobalInvocationID.x > 11u)\n    {\n        uint _275 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 10u), 8u, 10u);\n        _281 = uintBitsToFloat(_27[_275]._m0[gl_GlobalInvocationID.x >> 2u]) + _266;\n    }\n    else\n    {\n        _281 = _266;\n    }\n    if (gl_GlobalInvocationID.x > 1u)\n    {\n        uint _287 = descriptor_qa_check(registers._m4, 8u, 11u);\n        uint _291 = descriptor_qa_check(registers._m4, 256u, 12u);\n        _32[_287]._m0[gl_GlobalInvocationID.x] = floatBitsToUint(_281);\n    }\n    if (gl_GlobalInvocationID.x > 30u)\n    {\n        uint _305 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 1u), 8u, 13u);\n        _32[_305]._m0[gl_GlobalInvocationID.x] = floatBitsToUint(_281);\n    }\n    if (gl_GlobalInvocationID.x > 40u)\n    {\n        uint _316 = descriptor_qa_check(registers._m4 + 3u, 8u, 14u);\n        _42[_316]._m0[gl_GlobalInvocationID.x] = floatBitsToUint(_281);\n    }\n    if (gl_GlobalInvocationID.x > 50u)\n    {\n        uint _331 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 4u), 8u, 15u);\n        _42[_331]._m0[gl_GlobalInvocationID.x] = floatBitsToUint(_281);\n    }\n    if (gl_GlobalInvocationID.x > 80u)\n    {\n        uint _341 = descriptor_qa_check(registers._m3 + 6u, 2u, 16u);\n        imageStore(_46[_341], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(_281));\n    }\n    if (gl_GlobalInvocationID.x > 90u)\n    {\n        uint _353 = descriptor_qa_check(registers._m3 + ((gl_GlobalInvocationID.x & 1u) + 7u), 2u, 17u);\n        imageStore(_46[_353], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), vec4(_281));\n    }\n    uint _361 = descriptor_qa_check(registers._m4, 8u, 18u);\n    uint _366 = descriptor_qa_check(registers._m4, 256u, 19u);\n    uvec2 _368 = _37.counters[_366];\n    uint _387 = RobustPhysicalAtomicCounter(_368, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 422\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %56\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %19 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %29 \"SSBO\"\nOpName %35 \"AtomicCounters\"\nOpMemberName %35 0 \"counters\"\nOpName %39 \"SSBO\"\nOpName %50 \"BindlessCBV\"\nOpName %72 \"DescriptorHeapGlobalQAData\"\nOpMemberName %72 0 \"failed_shader_hash\"\nOpMemberName %72 1 \"failed_offset\"\nOpMemberName %72 2 \"failed_heap\"\nOpMemberName %72 3 \"failed_cookie\"\nOpMemberName %72 4 \"fault_atomic\"\nOpMemberName %72 5 \"failed_instruction\"\nOpMemberName %72 6 \"failed_descriptor_type_mask\"\nOpMemberName %72 7 \"actual_descriptor_type_mask\"\nOpMemberName %72 8 \"fault_type\"\nOpMemberName %72 9 \"va_map_timestamp\"\nOpMemberName %72 10 \"live_status_table\"\nOpName %74 \"QAGlobalData\"\nOpName %83 \"descriptor_qa_report_fault\"\nOpName %76 \"fault_type\"\nOpName %77 \"heap_offset\"\nOpName %78 \"cookie\"\nOpName %79 \"heap_index\"\nOpName %80 \"descriptor_type\"\nOpName %81 \"actual_descriptor_type\"\nOpName %82 \"instruction\"\nOpName %111 \"DescriptorHeapQAData\"\nOpMemberName %111 0 \"descriptor_count\"\nOpMemberName %111 1 \"heap_index\"\nOpMemberName %111 2 \"cookies_descriptor_info\"\nOpName %113 \"QAHeapData\"\nOpName %118 \"descriptor_qa_check\"\nOpName %115 \"heap_offset\"\nOpName %116 \"descriptor_type_mask\"\nOpName %117 \"instruction\"\nOpName %373 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %18 ArrayStride 4\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %22 DescriptorSet 1\nOpDecorate %22 Binding 0\nOpDecorate %22 NonWritable\nOpDecorate %22 Restrict\nOpDecorate %23 ArrayStride 4\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %27 DescriptorSet 1\nOpDecorate %27 Binding 0\nOpDecorate %27 NonWritable\nOpDecorate %27 Restrict\nOpDecorate %28 ArrayStride 4\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %32 DescriptorSet 4\nOpDecorate %32 Binding 0\nOpDecorate %32 NonReadable\nOpDecorate %34 ArrayStride 8\nOpDecorate %35 Block\nOpMemberDecorate %35 0 Offset 0\nOpMemberDecorate %35 0 NonWritable\nOpDecorate %37 DescriptorSet 7\nOpDecorate %37 Binding 0\nOpDecorate %37 AliasedPointer\nOpDecorate %38 ArrayStride 4\nOpMemberDecorate %39 0 Offset 0\nOpDecorate %39 Block\nOpDecorate %42 DescriptorSet 4\nOpDecorate %42 Binding 0\nOpDecorate %42 NonReadable\nOpDecorate %46 DescriptorSet 3\nOpDecorate %46 Binding 0\nOpDecorate %46 NonReadable\nOpDecorate %49 ArrayStride 16\nOpDecorate %50 Block\nOpMemberDecorate %50 0 Offset 0\nOpDecorate %53 DescriptorSet 5\nOpDecorate %53 Binding 0\nOpDecorate %56 BuiltIn GlobalInvocationId\nOpDecorate %71 ArrayStride 4\nOpMemberDecorate %72 0 Offset 0\nOpMemberDecorate %72 1 Offset 8\nOpMemberDecorate %72 2 Offset 12\nOpMemberDecorate %72 3 Offset 16\nOpMemberDecorate %72 4 Offset 20\nOpMemberDecorate %72 5 Offset 24\nOpMemberDecorate %72 6 Offset 28\nOpMemberDecorate %72 7 Offset 32\nOpMemberDecorate %72 8 Offset 36\nOpMemberDecorate %72 9 Offset 40\nOpMemberDecorate %72 10 Offset 44\nOpDecorate %72 Block\nOpDecorate %74 DescriptorSet 10\nOpDecorate %74 Binding 10\nOpDecorate %110 ArrayStride 12\nOpMemberDecorate %111 0 Offset 0\nOpMemberDecorate %111 1 Offset 4\nOpMemberDecorate %111 2 Offset 8\nOpDecorate %111 Block\nOpDecorate %113 DescriptorSet 10\nOpDecorate %113 Binding 11\nOpDecorate %113 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeRuntimeArray %5\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %5\n%24 = OpTypeStruct %23\n%25 = OpTypeRuntimeArray %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeRuntimeArray %5\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpTypeVector %5 2\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypeStruct %34\n%36 = OpTypePointer StorageBuffer %35\n%37 = OpVariable %36 StorageBuffer\n%38 = OpTypeRuntimeArray %5\n%39 = OpTypeStruct %38\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer StorageBuffer %40\n%42 = OpVariable %41 StorageBuffer\n%43 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%44 = OpTypeRuntimeArray %43\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpTypeVector %9 4\n%48 = OpConstant %5 4096\n%49 = OpTypeArray %47 %48\n%50 = OpTypeStruct %49\n%51 = OpTypeRuntimeArray %50\n%52 = OpTypePointer Uniform %51\n%53 = OpVariable %52 Uniform\n%54 = OpTypeVector %5 3\n%55 = OpTypePointer Input %54\n%56 = OpVariable %55 Input\n%57 = OpTypePointer Input %5\n%59 = OpConstant %5 0\n%61 = OpTypeBool\n%63 = OpConstant %5 2\n%64 = OpTypePointer Uniform %50\n%66 = OpTypePointer PushConstant %5\n%68 = OpConstant %5 5\n%71 = OpTypeRuntimeArray %5\n%72 = OpTypeStruct %33 %5 %5 %5 %5 %5 %5 %5 %5 %5 %71\n%73 = OpTypePointer StorageBuffer %72\n%74 = OpVariable %73 StorageBuffer\n%75 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%85 = OpTypePointer StorageBuffer %5\n%87 = OpConstant %5 4\n%89 = OpConstant %5 1\n%94 = OpConstant %5 3\n%98 = OpConstant %5 6\n%100 = OpConstant %5 7\n%102 = OpConstant %5 3735928559\n%103 = OpConstantComposite %33 %102 %59\n%104 = OpTypePointer StorageBuffer %33\n%106 = OpConstant %5 72\n%108 = OpConstant %5 8\n%110 = OpTypeRuntimeArray %54\n%111 = OpTypeStruct %5 %5 %110\n%112 = OpTypePointer StorageBuffer %111\n%113 = OpVariable %112 StorageBuffer\n%114 = OpTypeFunction %5 %5 %5 %5\n%125 = OpConstant %5 9\n%127 = OpTypePointer StorageBuffer %54\n%135 = OpConstant %5 31\n%137 = OpConstant %5 10\n%159 = OpTypePointer Uniform %47\n%164 = OpConstant %9 0\n%178 = OpTypePointer UniformConstant %10\n%204 = OpTypePointer UniformConstant %14\n%210 = OpConstant %5 16\n%230 = OpTypePointer StorageBuffer %19\n%255 = OpTypePointer StorageBuffer %24\n%268 = OpConstant %5 11\n%283 = OpTypePointer StorageBuffer %29\n%292 = OpConstant %5 256\n%293 = OpConstant %5 12\n%298 = OpConstant %5 30\n%306 = OpConstant %5 13\n%310 = OpConstant %5 40\n%311 = OpTypePointer StorageBuffer %39\n%317 = OpConstant %5 14\n%322 = OpConstant %5 50\n%332 = OpConstant %5 15\n%335 = OpConstant %5 80\n%336 = OpTypePointer UniformConstant %43\n%346 = OpConstant %5 90\n%354 = OpConstant %5 17\n%362 = OpConstant %5 18\n%367 = OpConstant %5 19\n%369 = OpTypeFunction %5 %33 %5 %5\n%377 = OpTypeVector %61 2\n%378 = OpConstantNull %33\n%381 = OpTypePointer PhysicalStorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %388\n%388 = OpLabel\n%58 = OpAccessChain %57 %56 %59\n%60 = OpLoad %5 %58\n%62 = OpUGreaterThan %61 %60 %63\nOpSelectionMerge %390 None\nOpBranchConditional %62 %389 %390\n%389 = OpLabel\n%67 = OpAccessChain %66 %8 %68\n%69 = OpLoad %5 %67\n%70 = OpFunctionCall %5 %118 %69 %87 %89\n%65 = OpAccessChain %64 %53 %70\n%160 = OpAccessChain %159 %65 %59 %59\n%161 = OpLoad %47 %160\n%162 = OpCompositeExtract %9 %161 0\nOpBranch %390\n%390 = OpLabel\n%163 = OpPhi %9 %164 %388 %162 %389\n%165 = OpUGreaterThan %61 %60 %94\nOpSelectionMerge %392 None\nOpBranchConditional %165 %391 %392\n%391 = OpLabel\n%166 = OpIAdd %5 %60 %89\n%168 = OpAccessChain %66 %8 %68\n%169 = OpLoad %5 %168\n%170 = OpIAdd %5 %169 %166\n%171 = OpFunctionCall %5 %118 %170 %87 %63\n%167 = OpAccessChain %64 %53 %171\n%172 = OpAccessChain %159 %167 %59 %59\n%173 = OpLoad %47 %172\n%174 = OpCompositeExtract %9 %173 0\n%175 = OpFAdd %9 %174 %163\nOpBranch %392\n%392 = OpLabel\n%176 = OpPhi %9 %163 %390 %175 %391\n%177 = OpUGreaterThan %61 %60 %87\nOpSelectionMerge %394 None\nOpBranchConditional %177 %393 %394\n%393 = OpLabel\n%180 = OpAccessChain %66 %8 %59\n%181 = OpLoad %5 %180\n%182 = OpFunctionCall %5 %118 %181 %89 %94\n%179 = OpAccessChain %178 %13 %182\n%183 = OpLoad %10 %179\n%185 = OpCompositeConstruct %33 %60 %59\n%184 = OpImageFetch %47 %183 %185 Lod %59\n%186 = OpCompositeExtract %9 %184 0\n%187 = OpFAdd %9 %186 %176\nOpBranch %394\n%394 = OpLabel\n%188 = OpPhi %9 %176 %392 %187 %393\n%189 = OpUGreaterThan %61 %60 %68\nOpSelectionMerge %396 None\nOpBranchConditional %189 %395 %396\n%395 = OpLabel\n%190 = OpBitwiseAnd %5 %60 %89\n%191 = OpIAdd %5 %190 %89\n%193 = OpAccessChain %66 %8 %59\n%194 = OpLoad %5 %193\n%195 = OpIAdd %5 %194 %191\n%196 = OpFunctionCall %5 %118 %195 %89 %87\n%192 = OpAccessChain %178 %13 %196\n%197 = OpLoad %10 %192\n%199 = OpCompositeConstruct %33 %59 %60\n%198 = OpImageFetch %47 %197 %199 Lod %59\n%200 = OpCompositeExtract %9 %198 0\n%201 = OpFAdd %9 %200 %188\nOpBranch %396\n%396 = OpLabel\n%202 = OpPhi %9 %188 %394 %201 %395\n%203 = OpUGreaterThan %61 %60 %98\nOpSelectionMerge %398 None\nOpBranchConditional %203 %397 %398\n%397 = OpLabel\n%206 = OpAccessChain %66 %8 %89\n%207 = OpLoad %5 %206\n%208 = OpIAdd %5 %207 %94\n%209 = OpFunctionCall %5 %118 %208 %210 %68\n%205 = OpAccessChain %204 %17 %209\n%211 = OpLoad %14 %205\n%212 = OpImageFetch %47 %211 %60\n%213 = OpCompositeExtract %9 %212 0\n%214 = OpFAdd %9 %213 %202\nOpBranch %398\n%398 = OpLabel\n%215 = OpPhi %9 %202 %396 %214 %397\n%216 = OpUGreaterThan %61 %60 %100\nOpSelectionMerge %400 None\nOpBranchConditional %216 %399 %400\n%399 = OpLabel\n%217 = OpBitwiseAnd %5 %60 %89\n%218 = OpIAdd %5 %217 %87\n%220 = OpAccessChain %66 %8 %89\n%221 = OpLoad %5 %220\n%222 = OpIAdd %5 %221 %218\n%223 = OpFunctionCall %5 %118 %222 %210 %98\n%219 = OpAccessChain %204 %17 %223\n%224 = OpLoad %14 %219\n%225 = OpImageFetch %47 %224 %60\n%226 = OpCompositeExtract %9 %225 0\n%227 = OpFAdd %9 %226 %215\nOpBranch %400\n%400 = OpLabel\n%228 = OpPhi %9 %215 %398 %227 %399\n%229 = OpUGreaterThan %61 %60 %108\nOpSelectionMerge %402 None\nOpBranchConditional %229 %401 %402\n%401 = OpLabel\n%232 = OpAccessChain %66 %8 %89\n%233 = OpLoad %5 %232\n%234 = OpIAdd %5 %233 %98\n%235 = OpFunctionCall %5 %118 %234 %108 %100\n%231 = OpAccessChain %230 %22 %235\n%236 = OpAccessChain %85 %231 %59 %60\n%237 = OpLoad %5 %236\n%238 = OpBitcast %9 %237\n%239 = OpFAdd %9 %238 %228\nOpBranch %402\n%402 = OpLabel\n%240 = OpPhi %9 %228 %400 %239 %401\n%241 = OpUGreaterThan %61 %60 %125\nOpSelectionMerge %404 None\nOpBranchConditional %241 %403 %404\n%403 = OpLabel\n%242 = OpBitwiseAnd %5 %60 %89\n%243 = OpIAdd %5 %242 %100\n%245 = OpAccessChain %66 %8 %89\n%246 = OpLoad %5 %245\n%247 = OpIAdd %5 %246 %243\n%248 = OpFunctionCall %5 %118 %247 %108 %108\n%244 = OpAccessChain %230 %22 %248\n%249 = OpAccessChain %85 %244 %59 %60\n%250 = OpLoad %5 %249\n%251 = OpBitcast %9 %250\n%252 = OpFAdd %9 %251 %240\nOpBranch %404\n%404 = OpLabel\n%253 = OpPhi %9 %240 %402 %252 %403\n%254 = OpUGreaterThan %61 %60 %137\nOpSelectionMerge %406 None\nOpBranchConditional %254 %405 %406\n%405 = OpLabel\n%257 = OpAccessChain %66 %8 %89\n%258 = OpLoad %5 %257\n%259 = OpIAdd %5 %258 %125\n%260 = OpFunctionCall %5 %118 %259 %108 %125\n%256 = OpAccessChain %255 %27 %260\n%261 = OpShiftLeftLogical %5 %60 %63\n%262 = OpAccessChain %85 %256 %59 %60\n%263 = OpLoad %5 %262\n%264 = OpBitcast %9 %263\n%265 = OpFAdd %9 %264 %253\nOpBranch %406\n%406 = OpLabel\n%266 = OpPhi %9 %253 %404 %265 %405\n%267 = OpUGreaterThan %61 %60 %268\nOpSelectionMerge %408 None\nOpBranchConditional %267 %407 %408\n%407 = OpLabel\n%269 = OpBitwiseAnd %5 %60 %89\n%270 = OpIAdd %5 %269 %137\n%272 = OpAccessChain %66 %8 %89\n%273 = OpLoad %5 %272\n%274 = OpIAdd %5 %273 %270\n%275 = OpFunctionCall %5 %118 %274 %108 %137\n%271 = OpAccessChain %255 %27 %275\n%276 = OpShiftRightLogical %5 %60 %63\n%277 = OpAccessChain %85 %271 %59 %276\n%278 = OpLoad %5 %277\n%279 = OpBitcast %9 %278\n%280 = OpFAdd %9 %279 %266\nOpBranch %408\n%408 = OpLabel\n%281 = OpPhi %9 %266 %406 %280 %407\n%282 = OpUGreaterThan %61 %60 %89\nOpSelectionMerge %410 None\nOpBranchConditional %282 %409 %410\n%409 = OpLabel\n%285 = OpAccessChain %66 %8 %87\n%286 = OpLoad %5 %285\n%287 = OpFunctionCall %5 %118 %286 %108 %268\n%284 = OpAccessChain %283 %32 %287\n%289 = OpAccessChain %66 %8 %87\n%290 = OpLoad %5 %289\n%291 = OpFunctionCall %5 %118 %290 %292 %293\n%288 = OpAccessChain %104 %37 %59 %291\n%294 = OpLoad %33 %288\n%295 = OpBitcast %5 %281\n%296 = OpAccessChain %85 %284 %59 %60\nOpStore %296 %295\nOpBranch %410\n%410 = OpLabel\n%297 = OpUGreaterThan %61 %60 %298\nOpSelectionMerge %412 None\nOpBranchConditional %297 %411 %412\n%411 = OpLabel\n%299 = OpBitwiseAnd %5 %60 %89\n%300 = OpIAdd %5 %299 %89\n%302 = OpAccessChain %66 %8 %87\n%303 = OpLoad %5 %302\n%304 = OpIAdd %5 %303 %300\n%305 = OpFunctionCall %5 %118 %304 %108 %306\n%301 = OpAccessChain %283 %32 %305\n%307 = OpBitcast %5 %281\n%308 = OpAccessChain %85 %301 %59 %60\nOpStore %308 %307\nOpBranch %412\n%412 = OpLabel\n%309 = OpUGreaterThan %61 %60 %310\nOpSelectionMerge %414 None\nOpBranchConditional %309 %413 %414\n%413 = OpLabel\n%313 = OpAccessChain %66 %8 %87\n%314 = OpLoad %5 %313\n%315 = OpIAdd %5 %314 %94\n%316 = OpFunctionCall %5 %118 %315 %108 %317\n%312 = OpAccessChain %311 %42 %316\n%318 = OpBitcast %5 %281\n%319 = OpShiftLeftLogical %5 %60 %63\n%320 = OpAccessChain %85 %312 %59 %60\nOpStore %320 %318\nOpBranch %414\n%414 = OpLabel\n%321 = OpUGreaterThan %61 %60 %322\nOpSelectionMerge %416 None\nOpBranchConditional %321 %415 %416\n%415 = OpLabel\n%323 = OpBitwiseAnd %5 %60 %89\n%324 = OpBitcast %5 %281\n%325 = OpShiftLeftLogical %5 %60 %63\n%326 = OpIAdd %5 %323 %87\n%328 = OpAccessChain %66 %8 %87\n%329 = OpLoad %5 %328\n%330 = OpIAdd %5 %329 %326\n%331 = OpFunctionCall %5 %118 %330 %108 %332\n%327 = OpAccessChain %311 %42 %331\n%333 = OpAccessChain %85 %327 %59 %60\nOpStore %333 %324\nOpBranch %416\n%416 = OpLabel\n%334 = OpUGreaterThan %61 %60 %335\nOpSelectionMerge %418 None\nOpBranchConditional %334 %417 %418\n%417 = OpLabel\n%338 = OpAccessChain %66 %8 %94\n%339 = OpLoad %5 %338\n%340 = OpIAdd %5 %339 %98\n%341 = OpFunctionCall %5 %118 %340 %63 %210\n%337 = OpAccessChain %336 %46 %341\n%342 = OpLoad %43 %337\n%343 = OpCompositeConstruct %33 %60 %59\n%344 = OpCompositeConstruct %47 %281 %281 %281 %281\nOpImageWrite %342 %343 %344\nOpBranch %418\n%418 = OpLabel\n%345 = OpUGreaterThan %61 %60 %346\nOpSelectionMerge %420 None\nOpBranchConditional %345 %419 %420\n%419 = OpLabel\n%347 = OpBitwiseAnd %5 %60 %89\n%348 = OpIAdd %5 %347 %100\n%350 = OpAccessChain %66 %8 %94\n%351 = OpLoad %5 %350\n%352 = OpIAdd %5 %351 %348\n%353 = OpFunctionCall %5 %118 %352 %63 %354\n%349 = OpAccessChain %336 %46 %353\n%355 = OpLoad %43 %349\n%356 = OpCompositeConstruct %33 %59 %60\n%357 = OpCompositeConstruct %47 %281 %281 %281 %281\nOpImageWrite %355 %356 %357\nOpBranch %420\n%420 = OpLabel\n%359 = OpAccessChain %66 %8 %87\n%360 = OpLoad %5 %359\n%361 = OpFunctionCall %5 %118 %360 %108 %362\n%358 = OpAccessChain %283 %32 %361\n%364 = OpAccessChain %66 %8 %87\n%365 = OpLoad %5 %364\n%366 = OpFunctionCall %5 %118 %365 %292 %367\n%363 = OpAccessChain %104 %37 %59 %366\n%368 = OpLoad %33 %363\n%387 = OpFunctionCall %5 %373 %368 %89 %59\nOpReturn\nOpFunctionEnd\n%83 = OpFunction %1 None %75\n%76 = OpFunctionParameter %5\n%77 = OpFunctionParameter %5\n%78 = OpFunctionParameter %5\n%79 = OpFunctionParameter %5\n%80 = OpFunctionParameter %5\n%81 = OpFunctionParameter %5\n%82 = OpFunctionParameter %5\n%84 = OpLabel\n%86 = OpAccessChain %85 %74 %87\n%88 = OpAtomicIAdd %5 %86 %89 %59 %89\n%90 = OpIEqual %61 %88 %59\nOpSelectionMerge %92 None\nOpBranchConditional %90 %91 %92\n%91 = OpLabel\n%93 = OpAccessChain %85 %74 %94\nOpStore %93 %78\n%95 = OpAccessChain %85 %74 %89\nOpStore %95 %77\n%96 = OpAccessChain %85 %74 %63\nOpStore %96 %79\n%97 = OpAccessChain %85 %74 %98\nOpStore %97 %80\n%99 = OpAccessChain %85 %74 %100\nOpStore %99 %81\n%101 = OpAccessChain %85 %74 %68\nOpStore %101 %82\n%105 = OpAccessChain %104 %74 %59\nOpStore %105 %103\nOpMemoryBarrier %89 %106\n%107 = OpAccessChain %85 %74 %108\nOpStore %107 %76\nOpBranch %92\n%92 = OpLabel\nOpReturn\nOpFunctionEnd\n%118 = OpFunction %5 None %114\n%115 = OpFunctionParameter %5\n%116 = OpFunctionParameter %5\n%117 = OpFunctionParameter %5\n%119 = OpLabel\n%120 = OpAccessChain %85 %113 %59\n%121 = OpLoad %5 %120\n%122 = OpAccessChain %85 %113 %89\n%123 = OpLoad %5 %122\n%124 = OpAccessChain %85 %74 %125\n%126 = OpLoad %5 %124\n%128 = OpAccessChain %127 %113 %63 %115\n%129 = OpLoad %54 %128\n%130 = OpCompositeExtract %5 %129 0\n%131 = OpCompositeExtract %5 %129 1\n%132 = OpCompositeExtract %5 %129 2\n%133 = OpShiftRightLogical %5 %130 %68\n%134 = OpBitwiseAnd %5 %130 %135\n%136 = OpAccessChain %85 %74 %137 %133\n%138 = OpLoad %5 %136\n%139 = OpShiftLeftLogical %5 %89 %134\n%140 = OpBitwiseAnd %5 %138 %139\n%141 = OpINotEqual %61 %140 %59\n%142 = OpBitwiseAnd %5 %132 %116\n%143 = OpIEqual %61 %142 %116\n%144 = OpUGreaterThanEqual %61 %115 %121\n%145 = OpSelect %5 %144 %89 %59\n%146 = OpSelect %5 %143 %59 %63\n%147 = OpSelect %5 %141 %59 %87\n%148 = OpUGreaterThanEqual %61 %126 %131\n%149 = OpSelect %5 %148 %59 %108\n%150 = OpBitwiseOr %5 %145 %146\n%151 = OpBitwiseOr %5 %150 %147\n%152 = OpBitwiseOr %5 %151 %149\n%153 = OpINotEqual %61 %152 %59\nOpSelectionMerge %155 None\nOpBranchConditional %153 %154 %155\n%154 = OpLabel\n%156 = OpFunctionCall %1 %83 %152 %115 %130 %123 %116 %132 %117\nOpReturnValue %121\n%155 = OpLabel\nOpReturnValue %115\nOpFunctionEnd\n%373 = OpFunction %5 None %369\n%370 = OpFunctionParameter %33\n%371 = OpFunctionParameter %5\n%372 = OpFunctionParameter %5\n%374 = OpLabel\n%379 = OpINotEqual %377 %370 %378\n%380 = OpAny %61 %379\nOpSelectionMerge %376 None\nOpBranchConditional %380 %375 %376\n%375 = OpLabel\n%382 = OpBitcast %381 %370\n%383 = OpAtomicIAdd %5 %382 %89 %59 %371\n%384 = OpIAdd %5 %383 %372\nOpBranch %376\n%376 = OpLabel\n%385 = OpPhi %5 %59 %374 %384 %375\nOpReturnValue %385\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/early-2.bindless.descriptor-qa.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 2, binding = 0) uniform sampler _17[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\nbool discard_state;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _61 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_61 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _96 = QAHeapData.descriptor_count;\n    uint _98 = QAHeapData.heap_index;\n    uint _101 = QAGlobalData.va_map_timestamp;\n    uvec3 _104 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _113 = QAGlobalData.live_status_table[_104.x >> 5u];\n    uint _127 = ((uint(heap_offset >= _96) | (((_104.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_113 & (1u << (_104.x & 31u))) != 0u) ? 0u : 4u)) | ((_101 >= _104.y) ? 0u : 8u);\n    if (_127 != 0u)\n    {\n        descriptor_qa_report_fault(_127, heap_offset, _104.x, _98, descriptor_type_mask, _104.z, instruction);\n        return _96;\n    }\n    return heap_offset;\n}\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (UV.x < 0.0)\n    {\n        discard_state = true;\n    }\n    uint _42 = descriptor_qa_check(registers._m0, 1u, 1u);\n    vec4 _142 = texture(sampler2D(_13[_42], _17[registers._m2]), vec2(UV.x, UV.y));\n    SV_Target.x = _142.x;\n    SV_Target.y = _142.y;\n    SV_Target.z = _142.z;\n    SV_Target.w = _142.w;\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 165\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %20 \"UV\"\nOpName %23 \"SV_Target\"\nOpName %35 \"discard_state\"\nOpName %45 \"DescriptorHeapGlobalQAData\"\nOpMemberName %45 0 \"failed_shader_hash\"\nOpMemberName %45 1 \"failed_offset\"\nOpMemberName %45 2 \"failed_heap\"\nOpMemberName %45 3 \"failed_cookie\"\nOpMemberName %45 4 \"fault_atomic\"\nOpMemberName %45 5 \"failed_instruction\"\nOpMemberName %45 6 \"failed_descriptor_type_mask\"\nOpMemberName %45 7 \"actual_descriptor_type_mask\"\nOpMemberName %45 8 \"fault_type\"\nOpMemberName %45 9 \"va_map_timestamp\"\nOpMemberName %45 10 \"live_status_table\"\nOpName %47 \"QAGlobalData\"\nOpName %56 \"descriptor_qa_report_fault\"\nOpName %49 \"fault_type\"\nOpName %50 \"heap_offset\"\nOpName %51 \"cookie\"\nOpName %52 \"heap_index\"\nOpName %53 \"descriptor_type\"\nOpName %54 \"actual_descriptor_type\"\nOpName %55 \"instruction\"\nOpName %86 \"DescriptorHeapQAData\"\nOpMemberName %86 0 \"descriptor_count\"\nOpMemberName %86 1 \"heap_index\"\nOpMemberName %86 2 \"cookies_descriptor_info\"\nOpName %88 \"QAHeapData\"\nOpName %93 \"descriptor_qa_check\"\nOpName %90 \"heap_offset\"\nOpName %91 \"descriptor_type_mask\"\nOpName %92 \"instruction\"\nOpName %157 \"discard_exit\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 2\nOpDecorate %17 Binding 0\nOpDecorate %20 Location 0\nOpDecorate %23 Location 0\nOpDecorate %44 ArrayStride 4\nOpMemberDecorate %45 0 Offset 0\nOpMemberDecorate %45 1 Offset 8\nOpMemberDecorate %45 2 Offset 12\nOpMemberDecorate %45 3 Offset 16\nOpMemberDecorate %45 4 Offset 20\nOpMemberDecorate %45 5 Offset 24\nOpMemberDecorate %45 6 Offset 28\nOpMemberDecorate %45 7 Offset 32\nOpMemberDecorate %45 8 Offset 36\nOpMemberDecorate %45 9 Offset 40\nOpMemberDecorate %45 10 Offset 44\nOpDecorate %45 Block\nOpDecorate %47 DescriptorSet 10\nOpDecorate %47 Binding 10\nOpDecorate %85 ArrayStride 12\nOpMemberDecorate %86 0 Offset 0\nOpMemberDecorate %86 1 Offset 4\nOpMemberDecorate %86 2 Offset 8\nOpDecorate %86 Block\nOpDecorate %88 DescriptorSet 10\nOpDecorate %88 Binding 11\nOpDecorate %88 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %9 2\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypeVector %9 4\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpTypePointer Input %9\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%31 = OpTypeBool\n%33 = OpConstant %9 0\n%34 = OpTypePointer Private %31\n%35 = OpVariable %34 Private\n%36 = OpConstantFalse %31\n%37 = OpTypePointer UniformConstant %10\n%39 = OpTypePointer PushConstant %5\n%43 = OpTypeVector %5 2\n%44 = OpTypeRuntimeArray %5\n%45 = OpTypeStruct %43 %5 %5 %5 %5 %5 %5 %5 %5 %5 %44\n%46 = OpTypePointer StorageBuffer %45\n%47 = OpVariable %46 StorageBuffer\n%48 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%58 = OpTypePointer StorageBuffer %5\n%60 = OpConstant %5 4\n%66 = OpConstant %5 3\n%69 = OpConstant %5 2\n%71 = OpConstant %5 6\n%73 = OpConstant %5 7\n%75 = OpConstant %5 5\n%76 = OpConstant %5 3735928559\n%77 = OpConstantComposite %43 %76 %26\n%78 = OpTypePointer StorageBuffer %43\n%80 = OpConstant %5 72\n%82 = OpConstant %5 8\n%84 = OpTypeVector %5 3\n%85 = OpTypeRuntimeArray %84\n%86 = OpTypeStruct %5 %5 %85\n%87 = OpTypePointer StorageBuffer %86\n%88 = OpVariable %87 StorageBuffer\n%89 = OpTypeFunction %5 %5 %5 %5\n%100 = OpConstant %5 9\n%102 = OpTypePointer StorageBuffer %84\n%110 = OpConstant %5 31\n%112 = OpConstant %5 10\n%135 = OpTypePointer UniformConstant %14\n%140 = OpTypeSampledImage %10\n%148 = OpTypePointer Output %9\n%156 = OpConstantTrue %31\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %35 %36\nOpBranch %153\n%153 = OpLabel\n%25 = OpAccessChain %24 %20 %26\n%27 = OpLoad %9 %25\n%28 = OpAccessChain %24 %20 %29\n%30 = OpLoad %9 %28\n%32 = OpFOrdLessThan %31 %27 %33\nOpSelectionMerge %155 None\nOpBranchConditional %32 %154 %155\n%154 = OpLabel\nOpStore %35 %156\nOpBranch %155\n%155 = OpLabel\n%40 = OpAccessChain %39 %8 %26\n%41 = OpLoad %5 %40\n%42 = OpFunctionCall %5 %93 %41 %29 %29\n%38 = OpAccessChain %37 %13 %42\n%134 = OpLoad %10 %38\n%137 = OpAccessChain %39 %8 %69\n%138 = OpLoad %5 %137\n%136 = OpAccessChain %135 %17 %138\n%139 = OpLoad %14 %136\n%141 = OpSampledImage %140 %134 %139\n%143 = OpCompositeConstruct %18 %27 %30\n%142 = OpImageSampleImplicitLod %21 %141 %143 None\n%144 = OpCompositeExtract %9 %142 0\n%145 = OpCompositeExtract %9 %142 1\n%146 = OpCompositeExtract %9 %142 2\n%147 = OpCompositeExtract %9 %142 3\n%149 = OpAccessChain %148 %23 %26\nOpStore %149 %144\n%150 = OpAccessChain %148 %23 %29\nOpStore %150 %145\n%151 = OpAccessChain %148 %23 %69\nOpStore %151 %146\n%152 = OpAccessChain %148 %23 %66\nOpStore %152 %147\n%163 = OpFunctionCall %1 %157\nOpReturn\nOpFunctionEnd\n%56 = OpFunction %1 None %48\n%49 = OpFunctionParameter %5\n%50 = OpFunctionParameter %5\n%51 = OpFunctionParameter %5\n%52 = OpFunctionParameter %5\n%53 = OpFunctionParameter %5\n%54 = OpFunctionParameter %5\n%55 = OpFunctionParameter %5\n%57 = OpLabel\n%59 = OpAccessChain %58 %47 %60\n%61 = OpAtomicIAdd %5 %59 %29 %26 %29\n%62 = OpIEqual %31 %61 %26\nOpSelectionMerge %64 None\nOpBranchConditional %62 %63 %64\n%63 = OpLabel\n%65 = OpAccessChain %58 %47 %66\nOpStore %65 %51\n%67 = OpAccessChain %58 %47 %29\nOpStore %67 %50\n%68 = OpAccessChain %58 %47 %69\nOpStore %68 %52\n%70 = OpAccessChain %58 %47 %71\nOpStore %70 %53\n%72 = OpAccessChain %58 %47 %73\nOpStore %72 %54\n%74 = OpAccessChain %58 %47 %75\nOpStore %74 %55\n%79 = OpAccessChain %78 %47 %26\nOpStore %79 %77\nOpMemoryBarrier %29 %80\n%81 = OpAccessChain %58 %47 %82\nOpStore %81 %49\nOpBranch %64\n%64 = OpLabel\nOpReturn\nOpFunctionEnd\n%93 = OpFunction %5 None %89\n%90 = OpFunctionParameter %5\n%91 = OpFunctionParameter %5\n%92 = OpFunctionParameter %5\n%94 = OpLabel\n%95 = OpAccessChain %58 %88 %26\n%96 = OpLoad %5 %95\n%97 = OpAccessChain %58 %88 %29\n%98 = OpLoad %5 %97\n%99 = OpAccessChain %58 %47 %100\n%101 = OpLoad %5 %99\n%103 = OpAccessChain %102 %88 %69 %90\n%104 = OpLoad %84 %103\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpCompositeExtract %5 %104 1\n%107 = OpCompositeExtract %5 %104 2\n%108 = OpShiftRightLogical %5 %105 %75\n%109 = OpBitwiseAnd %5 %105 %110\n%111 = OpAccessChain %58 %47 %112 %108\n%113 = OpLoad %5 %111\n%114 = OpShiftLeftLogical %5 %29 %109\n%115 = OpBitwiseAnd %5 %113 %114\n%116 = OpINotEqual %31 %115 %26\n%117 = OpBitwiseAnd %5 %107 %91\n%118 = OpIEqual %31 %117 %91\n%119 = OpUGreaterThanEqual %31 %90 %96\n%120 = OpSelect %5 %119 %29 %26\n%121 = OpSelect %5 %118 %26 %69\n%122 = OpSelect %5 %116 %26 %60\n%123 = OpUGreaterThanEqual %31 %101 %106\n%124 = OpSelect %5 %123 %26 %82\n%125 = OpBitwiseOr %5 %120 %121\n%126 = OpBitwiseOr %5 %125 %122\n%127 = OpBitwiseOr %5 %126 %124\n%128 = OpINotEqual %31 %127 %26\nOpSelectionMerge %130 None\nOpBranchConditional %128 %129 %130\n%129 = OpLabel\n%131 = OpFunctionCall %1 %56 %127 %90 %105 %98 %91 %107 %92\nOpReturnValue %96\n%130 = OpLabel\nOpReturnValue %90\nOpFunctionEnd\n%157 = OpFunction %1 None %2\n%158 = OpLabel\n%161 = OpLoad %31 %35\nOpSelectionMerge %160 None\nOpBranchConditional %161 %159 %160\n%159 = OpLabel\nOpKill\n%160 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/early-3.bindless.descriptor-qa.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 2, binding = 0) uniform sampler _17[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _51 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_51 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _88 = QAHeapData.descriptor_count;\n    uint _90 = QAHeapData.heap_index;\n    uint _93 = QAGlobalData.va_map_timestamp;\n    uvec3 _96 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _105 = QAGlobalData.live_status_table[_96.x >> 5u];\n    uint _119 = ((uint(heap_offset >= _88) | (((_96.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_105 & (1u << (_96.x & 31u))) != 0u) ? 0u : 4u)) | ((_93 >= _96.y) ? 0u : 8u);\n    if (_119 != 0u)\n    {\n        descriptor_qa_report_fault(_119, heap_offset, _96.x, _90, descriptor_type_mask, _96.z, instruction);\n        return _88;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    uint _32 = descriptor_qa_check(registers._m0, 1u, 1u);\n    vec4 _140 = texture(sampler2D(_13[_32], _17[registers._m2]), vec2(UV.x, UV.y));\n    SV_Target.x = _140.x;\n    SV_Target.y = _140.y;\n    SV_Target.z = _140.z;\n    SV_Target.w = _140.w;\n    gl_FragDepth = 0.5;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 153\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %23 %25\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DepthReplacing\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %20 \"UV\"\nOpName %23 \"SV_Target\"\nOpName %25 \"SV_Depth\"\nOpName %35 \"DescriptorHeapGlobalQAData\"\nOpMemberName %35 0 \"failed_shader_hash\"\nOpMemberName %35 1 \"failed_offset\"\nOpMemberName %35 2 \"failed_heap\"\nOpMemberName %35 3 \"failed_cookie\"\nOpMemberName %35 4 \"fault_atomic\"\nOpMemberName %35 5 \"failed_instruction\"\nOpMemberName %35 6 \"failed_descriptor_type_mask\"\nOpMemberName %35 7 \"actual_descriptor_type_mask\"\nOpMemberName %35 8 \"fault_type\"\nOpMemberName %35 9 \"va_map_timestamp\"\nOpMemberName %35 10 \"live_status_table\"\nOpName %37 \"QAGlobalData\"\nOpName %46 \"descriptor_qa_report_fault\"\nOpName %39 \"fault_type\"\nOpName %40 \"heap_offset\"\nOpName %41 \"cookie\"\nOpName %42 \"heap_index\"\nOpName %43 \"descriptor_type\"\nOpName %44 \"actual_descriptor_type\"\nOpName %45 \"instruction\"\nOpName %78 \"DescriptorHeapQAData\"\nOpMemberName %78 0 \"descriptor_count\"\nOpMemberName %78 1 \"heap_index\"\nOpMemberName %78 2 \"cookies_descriptor_info\"\nOpName %80 \"QAHeapData\"\nOpName %85 \"descriptor_qa_check\"\nOpName %82 \"heap_offset\"\nOpName %83 \"descriptor_type_mask\"\nOpName %84 \"instruction\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 2\nOpDecorate %17 Binding 0\nOpDecorate %20 Location 0\nOpDecorate %23 Location 0\nOpDecorate %25 BuiltIn FragDepth\nOpDecorate %34 ArrayStride 4\nOpMemberDecorate %35 0 Offset 0\nOpMemberDecorate %35 1 Offset 8\nOpMemberDecorate %35 2 Offset 12\nOpMemberDecorate %35 3 Offset 16\nOpMemberDecorate %35 4 Offset 20\nOpMemberDecorate %35 5 Offset 24\nOpMemberDecorate %35 6 Offset 28\nOpMemberDecorate %35 7 Offset 32\nOpMemberDecorate %35 8 Offset 36\nOpMemberDecorate %35 9 Offset 40\nOpMemberDecorate %35 10 Offset 44\nOpDecorate %35 Block\nOpDecorate %37 DescriptorSet 10\nOpDecorate %37 Binding 10\nOpDecorate %77 ArrayStride 12\nOpMemberDecorate %78 0 Offset 0\nOpMemberDecorate %78 1 Offset 4\nOpMemberDecorate %78 2 Offset 8\nOpDecorate %78 Block\nOpDecorate %80 DescriptorSet 10\nOpDecorate %80 Binding 11\nOpDecorate %80 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %9 2\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypeVector %9 4\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpTypePointer Output %9\n%25 = OpVariable %24 Output\n%26 = OpTypePointer UniformConstant %10\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 0\n%33 = OpTypeVector %5 2\n%34 = OpTypeRuntimeArray %5\n%35 = OpTypeStruct %33 %5 %5 %5 %5 %5 %5 %5 %5 %5 %34\n%36 = OpTypePointer StorageBuffer %35\n%37 = OpVariable %36 StorageBuffer\n%38 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%48 = OpTypePointer StorageBuffer %5\n%50 = OpConstant %5 4\n%52 = OpConstant %5 1\n%53 = OpTypeBool\n%58 = OpConstant %5 3\n%61 = OpConstant %5 2\n%63 = OpConstant %5 6\n%65 = OpConstant %5 7\n%67 = OpConstant %5 5\n%68 = OpConstant %5 3735928559\n%69 = OpConstantComposite %33 %68 %30\n%70 = OpTypePointer StorageBuffer %33\n%72 = OpConstant %5 72\n%74 = OpConstant %5 8\n%76 = OpTypeVector %5 3\n%77 = OpTypeRuntimeArray %76\n%78 = OpTypeStruct %5 %5 %77\n%79 = OpTypePointer StorageBuffer %78\n%80 = OpVariable %79 StorageBuffer\n%81 = OpTypeFunction %5 %5 %5 %5\n%92 = OpConstant %5 9\n%94 = OpTypePointer StorageBuffer %76\n%102 = OpConstant %5 31\n%104 = OpConstant %5 10\n%127 = OpTypePointer UniformConstant %14\n%132 = OpTypePointer Input %9\n%137 = OpTypeSampledImage %10\n%139 = OpConstant %9 0\n%150 = OpConstant %9 0.5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %151\n%151 = OpLabel\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%32 = OpFunctionCall %5 %85 %31 %52 %52\n%27 = OpAccessChain %26 %13 %32\n%126 = OpLoad %10 %27\n%129 = OpAccessChain %28 %8 %61\n%130 = OpLoad %5 %129\n%128 = OpAccessChain %127 %17 %130\n%131 = OpLoad %14 %128\n%133 = OpAccessChain %132 %20 %30\n%134 = OpLoad %9 %133\n%135 = OpAccessChain %132 %20 %52\n%136 = OpLoad %9 %135\n%138 = OpSampledImage %137 %126 %131\n%141 = OpCompositeConstruct %18 %134 %136\n%140 = OpImageSampleImplicitLod %21 %138 %141 None\n%142 = OpCompositeExtract %9 %140 0\n%143 = OpCompositeExtract %9 %140 1\n%144 = OpCompositeExtract %9 %140 2\n%145 = OpCompositeExtract %9 %140 3\n%146 = OpAccessChain %24 %23 %30\nOpStore %146 %142\n%147 = OpAccessChain %24 %23 %52\nOpStore %147 %143\n%148 = OpAccessChain %24 %23 %61\nOpStore %148 %144\n%149 = OpAccessChain %24 %23 %58\nOpStore %149 %145\nOpStore %25 %150\nOpReturn\nOpFunctionEnd\n%46 = OpFunction %1 None %38\n%39 = OpFunctionParameter %5\n%40 = OpFunctionParameter %5\n%41 = OpFunctionParameter %5\n%42 = OpFunctionParameter %5\n%43 = OpFunctionParameter %5\n%44 = OpFunctionParameter %5\n%45 = OpFunctionParameter %5\n%47 = OpLabel\n%49 = OpAccessChain %48 %37 %50\n%51 = OpAtomicIAdd %5 %49 %52 %30 %52\n%54 = OpIEqual %53 %51 %30\nOpSelectionMerge %56 None\nOpBranchConditional %54 %55 %56\n%55 = OpLabel\n%57 = OpAccessChain %48 %37 %58\nOpStore %57 %41\n%59 = OpAccessChain %48 %37 %52\nOpStore %59 %40\n%60 = OpAccessChain %48 %37 %61\nOpStore %60 %42\n%62 = OpAccessChain %48 %37 %63\nOpStore %62 %43\n%64 = OpAccessChain %48 %37 %65\nOpStore %64 %44\n%66 = OpAccessChain %48 %37 %67\nOpStore %66 %45\n%71 = OpAccessChain %70 %37 %30\nOpStore %71 %69\nOpMemoryBarrier %52 %72\n%73 = OpAccessChain %48 %37 %74\nOpStore %73 %39\nOpBranch %56\n%56 = OpLabel\nOpReturn\nOpFunctionEnd\n%85 = OpFunction %5 None %81\n%82 = OpFunctionParameter %5\n%83 = OpFunctionParameter %5\n%84 = OpFunctionParameter %5\n%86 = OpLabel\n%87 = OpAccessChain %48 %80 %30\n%88 = OpLoad %5 %87\n%89 = OpAccessChain %48 %80 %52\n%90 = OpLoad %5 %89\n%91 = OpAccessChain %48 %37 %92\n%93 = OpLoad %5 %91\n%95 = OpAccessChain %94 %80 %61 %82\n%96 = OpLoad %76 %95\n%97 = OpCompositeExtract %5 %96 0\n%98 = OpCompositeExtract %5 %96 1\n%99 = OpCompositeExtract %5 %96 2\n%100 = OpShiftRightLogical %5 %97 %67\n%101 = OpBitwiseAnd %5 %97 %102\n%103 = OpAccessChain %48 %37 %104 %100\n%105 = OpLoad %5 %103\n%106 = OpShiftLeftLogical %5 %52 %101\n%107 = OpBitwiseAnd %5 %105 %106\n%108 = OpINotEqual %53 %107 %30\n%109 = OpBitwiseAnd %5 %99 %83\n%110 = OpIEqual %53 %109 %83\n%111 = OpUGreaterThanEqual %53 %82 %88\n%112 = OpSelect %5 %111 %52 %30\n%113 = OpSelect %5 %110 %30 %61\n%114 = OpSelect %5 %108 %30 %50\n%115 = OpUGreaterThanEqual %53 %93 %98\n%116 = OpSelect %5 %115 %30 %74\n%117 = OpBitwiseOr %5 %112 %113\n%118 = OpBitwiseOr %5 %117 %114\n%119 = OpBitwiseOr %5 %118 %116\n%120 = OpINotEqual %53 %119 %30\nOpSelectionMerge %122 None\nOpBranchConditional %120 %121 %122\n%121 = OpLabel\n%123 = OpFunctionCall %1 %46 %119 %82 %97 %90 %83 %99 %84\nOpReturnValue %88\n%122 = OpLabel\nOpReturnValue %82\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/early-4.bindless.descriptor-qa.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 2, binding = 0) uniform sampler _17[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _53 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_53 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _89 = QAHeapData.descriptor_count;\n    uint _91 = QAHeapData.heap_index;\n    uint _94 = QAGlobalData.va_map_timestamp;\n    uvec3 _97 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _106 = QAGlobalData.live_status_table[_97.x >> 5u];\n    uint _120 = ((uint(heap_offset >= _89) | (((_97.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_106 & (1u << (_97.x & 31u))) != 0u) ? 0u : 4u)) | ((_94 >= _97.y) ? 0u : 8u);\n    if (_120 != 0u)\n    {\n        descriptor_qa_report_fault(_120, heap_offset, _97.x, _91, descriptor_type_mask, _97.z, instruction);\n        return _89;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    uint _34 = descriptor_qa_check(registers._m0, 1u, 1u);\n    vec4 _141 = texture(sampler2D(_13[_34], _17[registers._m2]), vec2(UV.x, UV.y));\n    SV_Target.x = _141.x;\n    SV_Target.y = _141.y;\n    SV_Target.z = _141.z;\n    SV_Target.w = _141.w;\n    gl_SampleMask[0u] = int(3u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 156\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %23 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %20 \"UV\"\nOpName %23 \"SV_Target\"\nOpName %27 \"SV_Coverage\"\nOpName %37 \"DescriptorHeapGlobalQAData\"\nOpMemberName %37 0 \"failed_shader_hash\"\nOpMemberName %37 1 \"failed_offset\"\nOpMemberName %37 2 \"failed_heap\"\nOpMemberName %37 3 \"failed_cookie\"\nOpMemberName %37 4 \"fault_atomic\"\nOpMemberName %37 5 \"failed_instruction\"\nOpMemberName %37 6 \"failed_descriptor_type_mask\"\nOpMemberName %37 7 \"actual_descriptor_type_mask\"\nOpMemberName %37 8 \"fault_type\"\nOpMemberName %37 9 \"va_map_timestamp\"\nOpMemberName %37 10 \"live_status_table\"\nOpName %39 \"QAGlobalData\"\nOpName %48 \"descriptor_qa_report_fault\"\nOpName %41 \"fault_type\"\nOpName %42 \"heap_offset\"\nOpName %43 \"cookie\"\nOpName %44 \"heap_index\"\nOpName %45 \"descriptor_type\"\nOpName %46 \"actual_descriptor_type\"\nOpName %47 \"instruction\"\nOpName %79 \"DescriptorHeapQAData\"\nOpMemberName %79 0 \"descriptor_count\"\nOpMemberName %79 1 \"heap_index\"\nOpMemberName %79 2 \"cookies_descriptor_info\"\nOpName %81 \"QAHeapData\"\nOpName %86 \"descriptor_qa_check\"\nOpName %83 \"heap_offset\"\nOpName %84 \"descriptor_type_mask\"\nOpName %85 \"instruction\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 2\nOpDecorate %17 Binding 0\nOpDecorate %20 Location 0\nOpDecorate %23 Location 0\nOpDecorate %27 BuiltIn SampleMask\nOpDecorate %36 ArrayStride 4\nOpMemberDecorate %37 0 Offset 0\nOpMemberDecorate %37 1 Offset 8\nOpMemberDecorate %37 2 Offset 12\nOpMemberDecorate %37 3 Offset 16\nOpMemberDecorate %37 4 Offset 20\nOpMemberDecorate %37 5 Offset 24\nOpMemberDecorate %37 6 Offset 28\nOpMemberDecorate %37 7 Offset 32\nOpMemberDecorate %37 8 Offset 36\nOpMemberDecorate %37 9 Offset 40\nOpMemberDecorate %37 10 Offset 44\nOpDecorate %37 Block\nOpDecorate %39 DescriptorSet 10\nOpDecorate %39 Binding 10\nOpDecorate %78 ArrayStride 12\nOpMemberDecorate %79 0 Offset 0\nOpMemberDecorate %79 1 Offset 4\nOpMemberDecorate %79 2 Offset 8\nOpDecorate %79 Block\nOpDecorate %81 DescriptorSet 10\nOpDecorate %81 Binding 11\nOpDecorate %81 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %9 2\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypeVector %9 4\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpConstant %5 1\n%25 = OpTypeArray %5 %24\n%26 = OpTypePointer Output %25\n%27 = OpVariable %26 Output\n%28 = OpTypePointer UniformConstant %10\n%30 = OpTypePointer PushConstant %5\n%32 = OpConstant %5 0\n%35 = OpTypeVector %5 2\n%36 = OpTypeRuntimeArray %5\n%37 = OpTypeStruct %35 %5 %5 %5 %5 %5 %5 %5 %5 %5 %36\n%38 = OpTypePointer StorageBuffer %37\n%39 = OpVariable %38 StorageBuffer\n%40 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%50 = OpTypePointer StorageBuffer %5\n%52 = OpConstant %5 4\n%54 = OpTypeBool\n%59 = OpConstant %5 3\n%62 = OpConstant %5 2\n%64 = OpConstant %5 6\n%66 = OpConstant %5 7\n%68 = OpConstant %5 5\n%69 = OpConstant %5 3735928559\n%70 = OpConstantComposite %35 %69 %32\n%71 = OpTypePointer StorageBuffer %35\n%73 = OpConstant %5 72\n%75 = OpConstant %5 8\n%77 = OpTypeVector %5 3\n%78 = OpTypeRuntimeArray %77\n%79 = OpTypeStruct %5 %5 %78\n%80 = OpTypePointer StorageBuffer %79\n%81 = OpVariable %80 StorageBuffer\n%82 = OpTypeFunction %5 %5 %5 %5\n%93 = OpConstant %5 9\n%95 = OpTypePointer StorageBuffer %77\n%103 = OpConstant %5 31\n%105 = OpConstant %5 10\n%128 = OpTypePointer UniformConstant %14\n%133 = OpTypePointer Input %9\n%138 = OpTypeSampledImage %10\n%140 = OpConstant %9 0\n%147 = OpTypePointer Output %9\n%152 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %154\n%154 = OpLabel\n%31 = OpAccessChain %30 %8 %32\n%33 = OpLoad %5 %31\n%34 = OpFunctionCall %5 %86 %33 %24 %24\n%29 = OpAccessChain %28 %13 %34\n%127 = OpLoad %10 %29\n%130 = OpAccessChain %30 %8 %62\n%131 = OpLoad %5 %130\n%129 = OpAccessChain %128 %17 %131\n%132 = OpLoad %14 %129\n%134 = OpAccessChain %133 %20 %32\n%135 = OpLoad %9 %134\n%136 = OpAccessChain %133 %20 %24\n%137 = OpLoad %9 %136\n%139 = OpSampledImage %138 %127 %132\n%142 = OpCompositeConstruct %18 %135 %137\n%141 = OpImageSampleImplicitLod %21 %139 %142 None\n%143 = OpCompositeExtract %9 %141 0\n%144 = OpCompositeExtract %9 %141 1\n%145 = OpCompositeExtract %9 %141 2\n%146 = OpCompositeExtract %9 %141 3\n%148 = OpAccessChain %147 %23 %32\nOpStore %148 %143\n%149 = OpAccessChain %147 %23 %24\nOpStore %149 %144\n%150 = OpAccessChain %147 %23 %62\nOpStore %150 %145\n%151 = OpAccessChain %147 %23 %59\nOpStore %151 %146\n%153 = OpAccessChain %152 %27 %32\nOpStore %153 %59\nOpReturn\nOpFunctionEnd\n%48 = OpFunction %1 None %40\n%41 = OpFunctionParameter %5\n%42 = OpFunctionParameter %5\n%43 = OpFunctionParameter %5\n%44 = OpFunctionParameter %5\n%45 = OpFunctionParameter %5\n%46 = OpFunctionParameter %5\n%47 = OpFunctionParameter %5\n%49 = OpLabel\n%51 = OpAccessChain %50 %39 %52\n%53 = OpAtomicIAdd %5 %51 %24 %32 %24\n%55 = OpIEqual %54 %53 %32\nOpSelectionMerge %57 None\nOpBranchConditional %55 %56 %57\n%56 = OpLabel\n%58 = OpAccessChain %50 %39 %59\nOpStore %58 %43\n%60 = OpAccessChain %50 %39 %24\nOpStore %60 %42\n%61 = OpAccessChain %50 %39 %62\nOpStore %61 %44\n%63 = OpAccessChain %50 %39 %64\nOpStore %63 %45\n%65 = OpAccessChain %50 %39 %66\nOpStore %65 %46\n%67 = OpAccessChain %50 %39 %68\nOpStore %67 %47\n%72 = OpAccessChain %71 %39 %32\nOpStore %72 %70\nOpMemoryBarrier %24 %73\n%74 = OpAccessChain %50 %39 %75\nOpStore %74 %41\nOpBranch %57\n%57 = OpLabel\nOpReturn\nOpFunctionEnd\n%86 = OpFunction %5 None %82\n%83 = OpFunctionParameter %5\n%84 = OpFunctionParameter %5\n%85 = OpFunctionParameter %5\n%87 = OpLabel\n%88 = OpAccessChain %50 %81 %32\n%89 = OpLoad %5 %88\n%90 = OpAccessChain %50 %81 %24\n%91 = OpLoad %5 %90\n%92 = OpAccessChain %50 %39 %93\n%94 = OpLoad %5 %92\n%96 = OpAccessChain %95 %81 %62 %83\n%97 = OpLoad %77 %96\n%98 = OpCompositeExtract %5 %97 0\n%99 = OpCompositeExtract %5 %97 1\n%100 = OpCompositeExtract %5 %97 2\n%101 = OpShiftRightLogical %5 %98 %68\n%102 = OpBitwiseAnd %5 %98 %103\n%104 = OpAccessChain %50 %39 %105 %101\n%106 = OpLoad %5 %104\n%107 = OpShiftLeftLogical %5 %24 %102\n%108 = OpBitwiseAnd %5 %106 %107\n%109 = OpINotEqual %54 %108 %32\n%110 = OpBitwiseAnd %5 %100 %84\n%111 = OpIEqual %54 %110 %84\n%112 = OpUGreaterThanEqual %54 %83 %89\n%113 = OpSelect %5 %112 %24 %32\n%114 = OpSelect %5 %111 %32 %62\n%115 = OpSelect %5 %109 %32 %52\n%116 = OpUGreaterThanEqual %54 %94 %99\n%117 = OpSelect %5 %116 %32 %75\n%118 = OpBitwiseOr %5 %113 %114\n%119 = OpBitwiseOr %5 %118 %115\n%120 = OpBitwiseOr %5 %119 %117\n%121 = OpINotEqual %54 %120 %32\nOpSelectionMerge %123 None\nOpBranchConditional %121 %122 %123\n%122 = OpLabel\n%124 = OpFunctionCall %1 %48 %120 %83 %98 %91 %84 %100 %85\nOpReturnValue %89\n%123 = OpLabel\nOpReturnValue %83\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/early-5.bindless.descriptor-qa.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _17[];\nlayout(set = 2, binding = 0) uniform sampler _21[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _63 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_63 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _97 = QAHeapData.descriptor_count;\n    uint _99 = QAHeapData.heap_index;\n    uint _102 = QAGlobalData.va_map_timestamp;\n    uvec3 _105 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _114 = QAGlobalData.live_status_table[_105.x >> 5u];\n    uint _128 = ((uint(heap_offset >= _97) | (((_105.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_114 & (1u << (_105.x & 31u))) != 0u) ? 0u : 4u)) | ((_102 >= _105.y) ? 0u : 8u);\n    if (_128 != 0u)\n    {\n        descriptor_qa_report_fault(_128, heap_offset, _105.x, _99, descriptor_type_mask, _105.z, instruction);\n        return _97;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    if (UV.x < 0.0)\n    {\n        uint _44 = descriptor_qa_check(registers._m3, 2u, 1u);\n        imageStore(_17[_44], ivec2(uvec2(uint(int(UV.x)), uint(int(UV.y)))), vec4(2.0));\n    }\n    uint _145 = descriptor_qa_check(registers._m0, 1u, 2u);\n    vec4 _154 = texture(sampler2D(_13[_145], _21[registers._m2]), vec2(UV.x, UV.y));\n    SV_Target.x = _154.x;\n    SV_Target.y = _154.y;\n    SV_Target.z = _154.z;\n    SV_Target.w = _154.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 169\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %24 \"UV\"\nOpName %27 \"SV_Target\"\nOpName %47 \"DescriptorHeapGlobalQAData\"\nOpMemberName %47 0 \"failed_shader_hash\"\nOpMemberName %47 1 \"failed_offset\"\nOpMemberName %47 2 \"failed_heap\"\nOpMemberName %47 3 \"failed_cookie\"\nOpMemberName %47 4 \"fault_atomic\"\nOpMemberName %47 5 \"failed_instruction\"\nOpMemberName %47 6 \"failed_descriptor_type_mask\"\nOpMemberName %47 7 \"actual_descriptor_type_mask\"\nOpMemberName %47 8 \"fault_type\"\nOpMemberName %47 9 \"va_map_timestamp\"\nOpMemberName %47 10 \"live_status_table\"\nOpName %49 \"QAGlobalData\"\nOpName %58 \"descriptor_qa_report_fault\"\nOpName %51 \"fault_type\"\nOpName %52 \"heap_offset\"\nOpName %53 \"cookie\"\nOpName %54 \"heap_index\"\nOpName %55 \"descriptor_type\"\nOpName %56 \"actual_descriptor_type\"\nOpName %57 \"instruction\"\nOpName %87 \"DescriptorHeapQAData\"\nOpMemberName %87 0 \"descriptor_count\"\nOpMemberName %87 1 \"heap_index\"\nOpMemberName %87 2 \"cookies_descriptor_info\"\nOpName %89 \"QAHeapData\"\nOpName %94 \"descriptor_qa_check\"\nOpName %91 \"heap_offset\"\nOpName %92 \"descriptor_type_mask\"\nOpName %93 \"instruction\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 3\nOpDecorate %17 Binding 0\nOpDecorate %17 NonReadable\nOpDecorate %21 DescriptorSet 2\nOpDecorate %21 Binding 0\nOpDecorate %24 Location 0\nOpDecorate %27 Location 0\nOpDecorate %46 ArrayStride 4\nOpMemberDecorate %47 0 Offset 0\nOpMemberDecorate %47 1 Offset 8\nOpMemberDecorate %47 2 Offset 12\nOpMemberDecorate %47 3 Offset 16\nOpMemberDecorate %47 4 Offset 20\nOpMemberDecorate %47 5 Offset 24\nOpMemberDecorate %47 6 Offset 28\nOpMemberDecorate %47 7 Offset 32\nOpMemberDecorate %47 8 Offset 36\nOpMemberDecorate %47 9 Offset 40\nOpMemberDecorate %47 10 Offset 44\nOpDecorate %47 Block\nOpDecorate %49 DescriptorSet 10\nOpDecorate %49 Binding 10\nOpDecorate %86 ArrayStride 12\nOpMemberDecorate %87 0 Offset 0\nOpMemberDecorate %87 1 Offset 4\nOpMemberDecorate %87 2 Offset 8\nOpDecorate %87 Block\nOpDecorate %89 DescriptorSet 10\nOpDecorate %89 Binding 11\nOpDecorate %89 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeVector %9 2\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypeVector %9 4\n%26 = OpTypePointer Output %25\n%27 = OpVariable %26 Output\n%28 = OpTypePointer Input %9\n%30 = OpConstant %5 0\n%33 = OpConstant %5 1\n%35 = OpTypeBool\n%37 = OpConstant %9 0\n%38 = OpTypePointer UniformConstant %14\n%40 = OpTypePointer PushConstant %5\n%42 = OpConstant %5 3\n%45 = OpTypeVector %5 2\n%46 = OpTypeRuntimeArray %5\n%47 = OpTypeStruct %45 %5 %5 %5 %5 %5 %5 %5 %5 %5 %46\n%48 = OpTypePointer StorageBuffer %47\n%49 = OpVariable %48 StorageBuffer\n%50 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%60 = OpTypePointer StorageBuffer %5\n%62 = OpConstant %5 4\n%70 = OpConstant %5 2\n%72 = OpConstant %5 6\n%74 = OpConstant %5 7\n%76 = OpConstant %5 5\n%77 = OpConstant %5 3735928559\n%78 = OpConstantComposite %45 %77 %30\n%79 = OpTypePointer StorageBuffer %45\n%81 = OpConstant %5 72\n%83 = OpConstant %5 8\n%85 = OpTypeVector %5 3\n%86 = OpTypeRuntimeArray %85\n%87 = OpTypeStruct %5 %5 %86\n%88 = OpTypePointer StorageBuffer %87\n%89 = OpVariable %88 StorageBuffer\n%90 = OpTypeFunction %5 %5 %5 %5\n%101 = OpConstant %5 9\n%103 = OpTypePointer StorageBuffer %85\n%111 = OpConstant %5 31\n%113 = OpConstant %5 10\n%138 = OpConstant %9 2\n%141 = OpTypePointer UniformConstant %10\n%147 = OpTypePointer UniformConstant %18\n%152 = OpTypeSampledImage %10\n%160 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %165\n%165 = OpLabel\n%29 = OpAccessChain %28 %24 %30\n%31 = OpLoad %9 %29\n%32 = OpAccessChain %28 %24 %33\n%34 = OpLoad %9 %32\n%36 = OpFOrdLessThan %35 %31 %37\nOpSelectionMerge %167 None\nOpBranchConditional %36 %166 %167\n%166 = OpLabel\n%41 = OpAccessChain %40 %8 %42\n%43 = OpLoad %5 %41\n%44 = OpFunctionCall %5 %94 %43 %70 %33\n%39 = OpAccessChain %38 %17 %44\n%135 = OpLoad %14 %39\n%136 = OpConvertFToS %5 %31\n%137 = OpConvertFToS %5 %34\n%139 = OpCompositeConstruct %45 %136 %137\n%140 = OpCompositeConstruct %25 %138 %138 %138 %138\nOpImageWrite %135 %139 %140\nOpBranch %167\n%167 = OpLabel\n%143 = OpAccessChain %40 %8 %30\n%144 = OpLoad %5 %143\n%145 = OpFunctionCall %5 %94 %144 %33 %70\n%142 = OpAccessChain %141 %13 %145\n%146 = OpLoad %10 %142\n%149 = OpAccessChain %40 %8 %70\n%150 = OpLoad %5 %149\n%148 = OpAccessChain %147 %21 %150\n%151 = OpLoad %18 %148\n%153 = OpSampledImage %152 %146 %151\n%155 = OpCompositeConstruct %22 %31 %34\n%154 = OpImageSampleImplicitLod %25 %153 %155 None\n%156 = OpCompositeExtract %9 %154 0\n%157 = OpCompositeExtract %9 %154 1\n%158 = OpCompositeExtract %9 %154 2\n%159 = OpCompositeExtract %9 %154 3\n%161 = OpAccessChain %160 %27 %30\nOpStore %161 %156\n%162 = OpAccessChain %160 %27 %33\nOpStore %162 %157\n%163 = OpAccessChain %160 %27 %70\nOpStore %163 %158\n%164 = OpAccessChain %160 %27 %42\nOpStore %164 %159\nOpReturn\nOpFunctionEnd\n%58 = OpFunction %1 None %50\n%51 = OpFunctionParameter %5\n%52 = OpFunctionParameter %5\n%53 = OpFunctionParameter %5\n%54 = OpFunctionParameter %5\n%55 = OpFunctionParameter %5\n%56 = OpFunctionParameter %5\n%57 = OpFunctionParameter %5\n%59 = OpLabel\n%61 = OpAccessChain %60 %49 %62\n%63 = OpAtomicIAdd %5 %61 %33 %30 %33\n%64 = OpIEqual %35 %63 %30\nOpSelectionMerge %66 None\nOpBranchConditional %64 %65 %66\n%65 = OpLabel\n%67 = OpAccessChain %60 %49 %42\nOpStore %67 %53\n%68 = OpAccessChain %60 %49 %33\nOpStore %68 %52\n%69 = OpAccessChain %60 %49 %70\nOpStore %69 %54\n%71 = OpAccessChain %60 %49 %72\nOpStore %71 %55\n%73 = OpAccessChain %60 %49 %74\nOpStore %73 %56\n%75 = OpAccessChain %60 %49 %76\nOpStore %75 %57\n%80 = OpAccessChain %79 %49 %30\nOpStore %80 %78\nOpMemoryBarrier %33 %81\n%82 = OpAccessChain %60 %49 %83\nOpStore %82 %51\nOpBranch %66\n%66 = OpLabel\nOpReturn\nOpFunctionEnd\n%94 = OpFunction %5 None %90\n%91 = OpFunctionParameter %5\n%92 = OpFunctionParameter %5\n%93 = OpFunctionParameter %5\n%95 = OpLabel\n%96 = OpAccessChain %60 %89 %30\n%97 = OpLoad %5 %96\n%98 = OpAccessChain %60 %89 %33\n%99 = OpLoad %5 %98\n%100 = OpAccessChain %60 %49 %101\n%102 = OpLoad %5 %100\n%104 = OpAccessChain %103 %89 %70 %91\n%105 = OpLoad %85 %104\n%106 = OpCompositeExtract %5 %105 0\n%107 = OpCompositeExtract %5 %105 1\n%108 = OpCompositeExtract %5 %105 2\n%109 = OpShiftRightLogical %5 %106 %76\n%110 = OpBitwiseAnd %5 %106 %111\n%112 = OpAccessChain %60 %49 %113 %109\n%114 = OpLoad %5 %112\n%115 = OpShiftLeftLogical %5 %33 %110\n%116 = OpBitwiseAnd %5 %114 %115\n%117 = OpINotEqual %35 %116 %30\n%118 = OpBitwiseAnd %5 %108 %92\n%119 = OpIEqual %35 %118 %92\n%120 = OpUGreaterThanEqual %35 %91 %97\n%121 = OpSelect %5 %120 %33 %30\n%122 = OpSelect %5 %119 %30 %70\n%123 = OpSelect %5 %117 %30 %62\n%124 = OpUGreaterThanEqual %35 %102 %107\n%125 = OpSelect %5 %124 %30 %83\n%126 = OpBitwiseOr %5 %121 %122\n%127 = OpBitwiseOr %5 %126 %123\n%128 = OpBitwiseOr %5 %127 %125\n%129 = OpINotEqual %35 %128 %30\nOpSelectionMerge %131 None\nOpBranchConditional %129 %130 %131\n%130 = OpLabel\n%132 = OpFunctionCall %1 %58 %128 %91 %106 %99 %92 %108 %93\nOpReturnValue %97\n%131 = OpLabel\nOpReturnValue %91\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/early-heap.descriptor-qa.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(early_fragment_tests) in;\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _48 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_48 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _84 = QAHeapData.descriptor_count;\n    uint _86 = QAHeapData.heap_index;\n    uint _89 = QAGlobalData.va_map_timestamp;\n    uvec3 _92 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _101 = QAGlobalData.live_status_table[_92.x >> 5u];\n    uint _115 = ((uint(heap_offset >= _84) | (((_92.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_101 & (1u << (_92.x & 31u))) != 0u) ? 0u : 4u)) | ((_89 >= _92.y) ? 0u : 8u);\n    if (_115 != 0u)\n    {\n        descriptor_qa_report_fault(_115, heap_offset, _92.x, _86, descriptor_type_mask, _92.z, instruction);\n        return _84;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    uint _29 = descriptor_qa_check(INDEX, 1u, 1u);\n    vec4 _125 = texelFetch(_9[_29], ivec2(uvec2(uint(int(UV.x)), uint(int(UV.y)))), int(0u));\n    SV_Target.x = _125.x;\n    SV_Target.y = _125.y;\n    SV_Target.z = _125.z;\n    SV_Target.w = _125.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 138\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %15 %18\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %15 \"UV\"\nOpName %18 \"SV_Target\"\nOpName %32 \"DescriptorHeapGlobalQAData\"\nOpMemberName %32 0 \"failed_shader_hash\"\nOpMemberName %32 1 \"failed_offset\"\nOpMemberName %32 2 \"failed_heap\"\nOpMemberName %32 3 \"failed_cookie\"\nOpMemberName %32 4 \"fault_atomic\"\nOpMemberName %32 5 \"failed_instruction\"\nOpMemberName %32 6 \"failed_descriptor_type_mask\"\nOpMemberName %32 7 \"actual_descriptor_type_mask\"\nOpMemberName %32 8 \"fault_type\"\nOpMemberName %32 9 \"va_map_timestamp\"\nOpMemberName %32 10 \"live_status_table\"\nOpName %34 \"QAGlobalData\"\nOpName %43 \"descriptor_qa_report_fault\"\nOpName %36 \"fault_type\"\nOpName %37 \"heap_offset\"\nOpName %38 \"cookie\"\nOpName %39 \"heap_index\"\nOpName %40 \"descriptor_type\"\nOpName %41 \"actual_descriptor_type\"\nOpName %42 \"instruction\"\nOpName %74 \"DescriptorHeapQAData\"\nOpMemberName %74 0 \"descriptor_count\"\nOpMemberName %74 1 \"heap_index\"\nOpMemberName %74 2 \"cookies_descriptor_info\"\nOpName %76 \"QAHeapData\"\nOpName %81 \"descriptor_qa_check\"\nOpName %78 \"heap_offset\"\nOpName %79 \"descriptor_type_mask\"\nOpName %80 \"instruction\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %15 Location 1\nOpDecorate %18 Location 0\nOpDecorate %31 ArrayStride 4\nOpMemberDecorate %32 0 Offset 0\nOpMemberDecorate %32 1 Offset 8\nOpMemberDecorate %32 2 Offset 12\nOpMemberDecorate %32 3 Offset 16\nOpMemberDecorate %32 4 Offset 20\nOpMemberDecorate %32 5 Offset 24\nOpMemberDecorate %32 6 Offset 28\nOpMemberDecorate %32 7 Offset 32\nOpMemberDecorate %32 8 Offset 36\nOpMemberDecorate %32 9 Offset 40\nOpMemberDecorate %32 10 Offset 44\nOpDecorate %32 Block\nOpDecorate %34 DescriptorSet 10\nOpDecorate %34 Binding 10\nOpDecorate %73 ArrayStride 12\nOpMemberDecorate %74 0 Offset 0\nOpMemberDecorate %74 1 Offset 4\nOpMemberDecorate %74 2 Offset 8\nOpDecorate %74 Block\nOpDecorate %76 DescriptorSet 10\nOpDecorate %76 Binding 11\nOpDecorate %76 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeVector %5 2\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%16 = OpTypeVector %5 4\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %5\n%21 = OpConstant %10 0\n%24 = OpConstant %10 1\n%27 = OpTypePointer UniformConstant %6\n%30 = OpTypeVector %10 2\n%31 = OpTypeRuntimeArray %10\n%32 = OpTypeStruct %30 %10 %10 %10 %10 %10 %10 %10 %10 %10 %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeFunction %1 %10 %10 %10 %10 %10 %10 %10\n%45 = OpTypePointer StorageBuffer %10\n%47 = OpConstant %10 4\n%49 = OpTypeBool\n%54 = OpConstant %10 3\n%57 = OpConstant %10 2\n%59 = OpConstant %10 6\n%61 = OpConstant %10 7\n%63 = OpConstant %10 5\n%64 = OpConstant %10 3735928559\n%65 = OpConstantComposite %30 %64 %21\n%66 = OpTypePointer StorageBuffer %30\n%68 = OpConstant %10 72\n%70 = OpConstant %10 8\n%72 = OpTypeVector %10 3\n%73 = OpTypeRuntimeArray %72\n%74 = OpTypeStruct %10 %10 %73\n%75 = OpTypePointer StorageBuffer %74\n%76 = OpVariable %75 StorageBuffer\n%77 = OpTypeFunction %10 %10 %10 %10\n%88 = OpConstant %10 9\n%90 = OpTypePointer StorageBuffer %72\n%98 = OpConstant %10 31\n%100 = OpConstant %10 10\n%131 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %136\n%136 = OpLabel\n%20 = OpAccessChain %19 %15 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %19 %15 %24\n%25 = OpLoad %5 %23\n%26 = OpLoad %10 %12\n%29 = OpFunctionCall %10 %81 %26 %24 %24\n%28 = OpAccessChain %27 %9 %29\n%122 = OpLoad %6 %28\n%123 = OpConvertFToS %10 %22\n%124 = OpConvertFToS %10 %25\n%126 = OpCompositeConstruct %30 %123 %124\n%125 = OpImageFetch %16 %122 %126 Lod %21\n%127 = OpCompositeExtract %5 %125 0\n%128 = OpCompositeExtract %5 %125 1\n%129 = OpCompositeExtract %5 %125 2\n%130 = OpCompositeExtract %5 %125 3\n%132 = OpAccessChain %131 %18 %21\nOpStore %132 %127\n%133 = OpAccessChain %131 %18 %24\nOpStore %133 %128\n%134 = OpAccessChain %131 %18 %57\nOpStore %134 %129\n%135 = OpAccessChain %131 %18 %54\nOpStore %135 %130\nOpReturn\nOpFunctionEnd\n%43 = OpFunction %1 None %35\n%36 = OpFunctionParameter %10\n%37 = OpFunctionParameter %10\n%38 = OpFunctionParameter %10\n%39 = OpFunctionParameter %10\n%40 = OpFunctionParameter %10\n%41 = OpFunctionParameter %10\n%42 = OpFunctionParameter %10\n%44 = OpLabel\n%46 = OpAccessChain %45 %34 %47\n%48 = OpAtomicIAdd %10 %46 %24 %21 %24\n%50 = OpIEqual %49 %48 %21\nOpSelectionMerge %52 None\nOpBranchConditional %50 %51 %52\n%51 = OpLabel\n%53 = OpAccessChain %45 %34 %54\nOpStore %53 %38\n%55 = OpAccessChain %45 %34 %24\nOpStore %55 %37\n%56 = OpAccessChain %45 %34 %57\nOpStore %56 %39\n%58 = OpAccessChain %45 %34 %59\nOpStore %58 %40\n%60 = OpAccessChain %45 %34 %61\nOpStore %60 %41\n%62 = OpAccessChain %45 %34 %63\nOpStore %62 %42\n%67 = OpAccessChain %66 %34 %21\nOpStore %67 %65\nOpMemoryBarrier %24 %68\n%69 = OpAccessChain %45 %34 %70\nOpStore %69 %36\nOpBranch %52\n%52 = OpLabel\nOpReturn\nOpFunctionEnd\n%81 = OpFunction %10 None %77\n%78 = OpFunctionParameter %10\n%79 = OpFunctionParameter %10\n%80 = OpFunctionParameter %10\n%82 = OpLabel\n%83 = OpAccessChain %45 %76 %21\n%84 = OpLoad %10 %83\n%85 = OpAccessChain %45 %76 %24\n%86 = OpLoad %10 %85\n%87 = OpAccessChain %45 %34 %88\n%89 = OpLoad %10 %87\n%91 = OpAccessChain %90 %76 %57 %78\n%92 = OpLoad %72 %91\n%93 = OpCompositeExtract %10 %92 0\n%94 = OpCompositeExtract %10 %92 1\n%95 = OpCompositeExtract %10 %92 2\n%96 = OpShiftRightLogical %10 %93 %63\n%97 = OpBitwiseAnd %10 %93 %98\n%99 = OpAccessChain %45 %34 %100 %96\n%101 = OpLoad %10 %99\n%102 = OpShiftLeftLogical %10 %24 %97\n%103 = OpBitwiseAnd %10 %101 %102\n%104 = OpINotEqual %49 %103 %21\n%105 = OpBitwiseAnd %10 %95 %79\n%106 = OpIEqual %49 %105 %79\n%107 = OpUGreaterThanEqual %49 %78 %84\n%108 = OpSelect %10 %107 %24 %21\n%109 = OpSelect %10 %106 %21 %57\n%110 = OpSelect %10 %104 %21 %47\n%111 = OpUGreaterThanEqual %49 %89 %94\n%112 = OpSelect %10 %111 %21 %70\n%113 = OpBitwiseOr %10 %108 %109\n%114 = OpBitwiseOr %10 %113 %110\n%115 = OpBitwiseOr %10 %114 %112\n%116 = OpINotEqual %49 %115 %21\nOpSelectionMerge %118 None\nOpBranchConditional %116 %117 %118\n%117 = OpLabel\n%119 = OpFunctionCall %1 %43 %115 %78 %93 %86 %79 %95 %80\nOpReturnValue %84\n%118 = OpLabel\nOpReturnValue %78\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/descriptor_qa/early.bindless.descriptor-qa.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\nlayout(early_fragment_tests) in;\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 2, binding = 0) uniform sampler _17[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _49 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_49 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _86 = QAHeapData.descriptor_count;\n    uint _88 = QAHeapData.heap_index;\n    uint _91 = QAGlobalData.va_map_timestamp;\n    uvec3 _94 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _103 = QAGlobalData.live_status_table[_94.x >> 5u];\n    uint _117 = ((uint(heap_offset >= _86) | (((_94.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_103 & (1u << (_94.x & 31u))) != 0u) ? 0u : 4u)) | ((_91 >= _94.y) ? 0u : 8u);\n    if (_117 != 0u)\n    {\n        descriptor_qa_report_fault(_117, heap_offset, _94.x, _88, descriptor_type_mask, _94.z, instruction);\n        return _86;\n    }\n    return heap_offset;\n}\n\nvoid main()\n{\n    uint _30 = descriptor_qa_check(registers._m0, 1u, 1u);\n    vec4 _138 = texture(sampler2D(_13[_30], _17[registers._m2]), vec2(UV.x, UV.y));\n    SV_Target.x = _138.x;\n    SV_Target.y = _138.y;\n    SV_Target.z = _138.z;\n    SV_Target.w = _138.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 151\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %23\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %20 \"UV\"\nOpName %23 \"SV_Target\"\nOpName %33 \"DescriptorHeapGlobalQAData\"\nOpMemberName %33 0 \"failed_shader_hash\"\nOpMemberName %33 1 \"failed_offset\"\nOpMemberName %33 2 \"failed_heap\"\nOpMemberName %33 3 \"failed_cookie\"\nOpMemberName %33 4 \"fault_atomic\"\nOpMemberName %33 5 \"failed_instruction\"\nOpMemberName %33 6 \"failed_descriptor_type_mask\"\nOpMemberName %33 7 \"actual_descriptor_type_mask\"\nOpMemberName %33 8 \"fault_type\"\nOpMemberName %33 9 \"va_map_timestamp\"\nOpMemberName %33 10 \"live_status_table\"\nOpName %35 \"QAGlobalData\"\nOpName %44 \"descriptor_qa_report_fault\"\nOpName %37 \"fault_type\"\nOpName %38 \"heap_offset\"\nOpName %39 \"cookie\"\nOpName %40 \"heap_index\"\nOpName %41 \"descriptor_type\"\nOpName %42 \"actual_descriptor_type\"\nOpName %43 \"instruction\"\nOpName %76 \"DescriptorHeapQAData\"\nOpMemberName %76 0 \"descriptor_count\"\nOpMemberName %76 1 \"heap_index\"\nOpMemberName %76 2 \"cookies_descriptor_info\"\nOpName %78 \"QAHeapData\"\nOpName %83 \"descriptor_qa_check\"\nOpName %80 \"heap_offset\"\nOpName %81 \"descriptor_type_mask\"\nOpName %82 \"instruction\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 2\nOpDecorate %17 Binding 0\nOpDecorate %20 Location 0\nOpDecorate %23 Location 0\nOpDecorate %32 ArrayStride 4\nOpMemberDecorate %33 0 Offset 0\nOpMemberDecorate %33 1 Offset 8\nOpMemberDecorate %33 2 Offset 12\nOpMemberDecorate %33 3 Offset 16\nOpMemberDecorate %33 4 Offset 20\nOpMemberDecorate %33 5 Offset 24\nOpMemberDecorate %33 6 Offset 28\nOpMemberDecorate %33 7 Offset 32\nOpMemberDecorate %33 8 Offset 36\nOpMemberDecorate %33 9 Offset 40\nOpMemberDecorate %33 10 Offset 44\nOpDecorate %33 Block\nOpDecorate %35 DescriptorSet 10\nOpDecorate %35 Binding 10\nOpDecorate %75 ArrayStride 12\nOpMemberDecorate %76 0 Offset 0\nOpMemberDecorate %76 1 Offset 4\nOpMemberDecorate %76 2 Offset 8\nOpDecorate %76 Block\nOpDecorate %78 DescriptorSet 10\nOpDecorate %78 Binding 11\nOpDecorate %78 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %9 2\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypeVector %9 4\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpTypePointer UniformConstant %10\n%26 = OpTypePointer PushConstant %5\n%28 = OpConstant %5 0\n%31 = OpTypeVector %5 2\n%32 = OpTypeRuntimeArray %5\n%33 = OpTypeStruct %31 %5 %5 %5 %5 %5 %5 %5 %5 %5 %32\n%34 = OpTypePointer StorageBuffer %33\n%35 = OpVariable %34 StorageBuffer\n%36 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%46 = OpTypePointer StorageBuffer %5\n%48 = OpConstant %5 4\n%50 = OpConstant %5 1\n%51 = OpTypeBool\n%56 = OpConstant %5 3\n%59 = OpConstant %5 2\n%61 = OpConstant %5 6\n%63 = OpConstant %5 7\n%65 = OpConstant %5 5\n%66 = OpConstant %5 3735928559\n%67 = OpConstantComposite %31 %66 %28\n%68 = OpTypePointer StorageBuffer %31\n%70 = OpConstant %5 72\n%72 = OpConstant %5 8\n%74 = OpTypeVector %5 3\n%75 = OpTypeRuntimeArray %74\n%76 = OpTypeStruct %5 %5 %75\n%77 = OpTypePointer StorageBuffer %76\n%78 = OpVariable %77 StorageBuffer\n%79 = OpTypeFunction %5 %5 %5 %5\n%90 = OpConstant %5 9\n%92 = OpTypePointer StorageBuffer %74\n%100 = OpConstant %5 31\n%102 = OpConstant %5 10\n%125 = OpTypePointer UniformConstant %14\n%130 = OpTypePointer Input %9\n%135 = OpTypeSampledImage %10\n%137 = OpConstant %9 0\n%144 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %149\n%149 = OpLabel\n%27 = OpAccessChain %26 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpFunctionCall %5 %83 %29 %50 %50\n%25 = OpAccessChain %24 %13 %30\n%124 = OpLoad %10 %25\n%127 = OpAccessChain %26 %8 %59\n%128 = OpLoad %5 %127\n%126 = OpAccessChain %125 %17 %128\n%129 = OpLoad %14 %126\n%131 = OpAccessChain %130 %20 %28\n%132 = OpLoad %9 %131\n%133 = OpAccessChain %130 %20 %50\n%134 = OpLoad %9 %133\n%136 = OpSampledImage %135 %124 %129\n%139 = OpCompositeConstruct %18 %132 %134\n%138 = OpImageSampleImplicitLod %21 %136 %139 None\n%140 = OpCompositeExtract %9 %138 0\n%141 = OpCompositeExtract %9 %138 1\n%142 = OpCompositeExtract %9 %138 2\n%143 = OpCompositeExtract %9 %138 3\n%145 = OpAccessChain %144 %23 %28\nOpStore %145 %140\n%146 = OpAccessChain %144 %23 %50\nOpStore %146 %141\n%147 = OpAccessChain %144 %23 %59\nOpStore %147 %142\n%148 = OpAccessChain %144 %23 %56\nOpStore %148 %143\nOpReturn\nOpFunctionEnd\n%44 = OpFunction %1 None %36\n%37 = OpFunctionParameter %5\n%38 = OpFunctionParameter %5\n%39 = OpFunctionParameter %5\n%40 = OpFunctionParameter %5\n%41 = OpFunctionParameter %5\n%42 = OpFunctionParameter %5\n%43 = OpFunctionParameter %5\n%45 = OpLabel\n%47 = OpAccessChain %46 %35 %48\n%49 = OpAtomicIAdd %5 %47 %50 %28 %50\n%52 = OpIEqual %51 %49 %28\nOpSelectionMerge %54 None\nOpBranchConditional %52 %53 %54\n%53 = OpLabel\n%55 = OpAccessChain %46 %35 %56\nOpStore %55 %39\n%57 = OpAccessChain %46 %35 %50\nOpStore %57 %38\n%58 = OpAccessChain %46 %35 %59\nOpStore %58 %40\n%60 = OpAccessChain %46 %35 %61\nOpStore %60 %41\n%62 = OpAccessChain %46 %35 %63\nOpStore %62 %42\n%64 = OpAccessChain %46 %35 %65\nOpStore %64 %43\n%69 = OpAccessChain %68 %35 %28\nOpStore %69 %67\nOpMemoryBarrier %50 %70\n%71 = OpAccessChain %46 %35 %72\nOpStore %71 %37\nOpBranch %54\n%54 = OpLabel\nOpReturn\nOpFunctionEnd\n%83 = OpFunction %5 None %79\n%80 = OpFunctionParameter %5\n%81 = OpFunctionParameter %5\n%82 = OpFunctionParameter %5\n%84 = OpLabel\n%85 = OpAccessChain %46 %78 %28\n%86 = OpLoad %5 %85\n%87 = OpAccessChain %46 %78 %50\n%88 = OpLoad %5 %87\n%89 = OpAccessChain %46 %35 %90\n%91 = OpLoad %5 %89\n%93 = OpAccessChain %92 %78 %59 %80\n%94 = OpLoad %74 %93\n%95 = OpCompositeExtract %5 %94 0\n%96 = OpCompositeExtract %5 %94 1\n%97 = OpCompositeExtract %5 %94 2\n%98 = OpShiftRightLogical %5 %95 %65\n%99 = OpBitwiseAnd %5 %95 %100\n%101 = OpAccessChain %46 %35 %102 %98\n%103 = OpLoad %5 %101\n%104 = OpShiftLeftLogical %5 %50 %99\n%105 = OpBitwiseAnd %5 %103 %104\n%106 = OpINotEqual %51 %105 %28\n%107 = OpBitwiseAnd %5 %97 %81\n%108 = OpIEqual %51 %107 %81\n%109 = OpUGreaterThanEqual %51 %80 %86\n%110 = OpSelect %5 %109 %50 %28\n%111 = OpSelect %5 %108 %28 %59\n%112 = OpSelect %5 %106 %28 %48\n%113 = OpUGreaterThanEqual %51 %91 %96\n%114 = OpSelect %5 %113 %28 %72\n%115 = OpBitwiseOr %5 %110 %111\n%116 = OpBitwiseOr %5 %115 %112\n%117 = OpBitwiseOr %5 %116 %114\n%118 = OpINotEqual %51 %117 %28\nOpSelectionMerge %120 None\nOpBranchConditional %118 %119 %120\n%119 = OpLabel\n%121 = OpFunctionCall %1 %44 %117 %80 %95 %88 %81 %97 %82\nOpReturnValue %86\n%120 = OpLabel\nOpReturnValue %80\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/accept-hit-and-end-search-ignore-hit.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    float _m0;\n};\n\nstruct _10\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _10 hit;\n\nvoid main()\n{\n    if (hit._m0.x > 10.0)\n    {\n        payload._m0 = 10.0;\n        terminateRayEXT;\n    }\n    else\n    {\n        ignoreIntersectionEXT;\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %12\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %10 \"\"\nOpName %12 \"hit\"\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeVector %5 2\n%10 = OpTypeStruct %9\n%11 = OpTypePointer HitAttributeKHR %10\n%12 = OpVariable %11 HitAttributeKHR\n%13 = OpTypePointer HitAttributeKHR %9\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpTypeBool\n%21 = OpConstant %5 10\n%22 = OpTypePointer IncomingRayPayloadKHR %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%14 = OpInBoundsAccessChain %13 %12 %16\n%17 = OpLoad %9 %14\n%18 = OpCompositeExtract %5 %17 0\n%20 = OpFOrdGreaterThan %19 %18 %21\nOpSelectionMerge %27 None\nOpBranchConditional %20 %26 %25\n%26 = OpLabel\n%23 = OpInBoundsAccessChain %22 %8 %16\nOpStore %23 %21\nOpTerminateRayKHR\n%25 = OpLabel\nOpIgnoreIntersectionKHR\n%27 = OpLabel\nOpUnreachable\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/acos.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = acos(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Acos %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/asin.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = asin(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Asin %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atan.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = atan(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Atan %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atomic-bin-op.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 3, binding = 0, r32ui) uniform uimage2D _12[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in uvec3 TEXCOORD;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _41 = imageAtomicAdd(_12[nonuniformEXT(registers._m3 + (INDEX + 2u))], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 3u);\n    SV_Target = _41;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %14 \"INDEX\"\nOpName %17 \"TEXCOORD\"\nOpName %19 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 3\nOpDecorate %12 Binding 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %17 Flat\nOpDecorate %17 Location 0\nOpDecorate %17 Component 1\nOpDecorate %19 Location 0\nOpDecorate %35 NonUniform\nOpDecorate %36 NonUniform\nOpDecorate %40 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 2D 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%15 = OpTypeVector %5 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %5\n%19 = OpVariable %18 Output\n%21 = OpConstant %5 0\n%24 = OpConstant %5 1\n%28 = OpConstant %5 2\n%29 = OpTypePointer UniformConstant %9\n%31 = OpTypePointer PushConstant %5\n%33 = OpConstant %5 3\n%37 = OpTypeVector %5 2\n%39 = OpTypePointer Image %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%20 = OpAccessChain %13 %17 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %13 %17 %24\n%25 = OpLoad %5 %23\n%26 = OpLoad %5 %14\n%27 = OpIAdd %5 %26 %28\n%32 = OpAccessChain %31 %8 %33\n%34 = OpLoad %5 %32\n%35 = OpIAdd %5 %34 %27\n%30 = OpAccessChain %29 %12 %35\n%36 = OpLoad %9 %30\n%38 = OpCompositeConstruct %37 %22 %25\n%40 = OpImageTexelPointer %39 %30 %38 %21\n%41 = OpAtomicIAdd %5 %40 %24 %21 %33\nOpStore %19 %41\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atomic-bin-op.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1D _8;\nlayout(set = 0, binding = 1, r32ui) uniform uimage1DArray _11;\nlayout(set = 0, binding = 2, r32ui) uniform uimage2D _14;\nlayout(set = 0, binding = 3, r32ui) uniform uimage2DArray _17;\nlayout(set = 0, binding = 4, r32ui) uniform uimage3D _20;\nlayout(set = 0, binding = 5, r32ui) uniform uimageBuffer _23;\nlayout(set = 1, binding = 0, r32i) uniform iimage1D _27;\nlayout(set = 1, binding = 2, r32i) uniform iimage2D _30;\nlayout(set = 0, binding = 6, r32ui) uniform uimageBuffer _31;\nlayout(set = 0, binding = 7, r32ui) uniform uimageBuffer _32;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _60 = imageAtomicAdd(_8, int(TEXCOORD.x), 1u);\n    uint _64 = imageAtomicAnd(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 2u);\n    uint _68 = imageAtomicExchange(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 3u);\n    uint _73 = imageAtomicMax(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 4u);\n    uint _78 = imageAtomicMin(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 5u);\n    uint _82 = imageAtomicOr(_23, int(TEXCOORD.x), 6u);\n    uint _86 = imageAtomicXor(_23, int(TEXCOORD.x), 7u);\n    int _91 = imageAtomicMin(_27, int(TEXCOORD.x), int(8u));\n    int _98 = imageAtomicMax(_30, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(9u));\n    uint _106 = imageAtomicAdd(_31, int((TEXCOORD.x * 4u) + 2u), 10u);\n    uint _111 = imageAtomicMax(_32, int(TEXCOORD.x), 12u);\n    SV_Target = (((((((((_64 + _60) + _68) + _73) + _78) + _82) + _86) + uint(_91)) + uint(_98)) + _106) + _111;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 116\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %35 %37\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %35 \"TEXCOORD\"\nOpName %37 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %27 DescriptorSet 1\nOpDecorate %27 Binding 0\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 2\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 6\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 7\nOpDecorate %35 Flat\nOpDecorate %35 Location 0\nOpDecorate %37 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 1D 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 2 R32ui\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 2 R32ui\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 2 R32ui\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeInt 32 1\n%25 = OpTypeImage %24 1D 0 0 0 2 R32i\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeImage %24 2D 0 0 0 2 R32i\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpVariable %22 UniformConstant\n%32 = OpVariable %22 UniformConstant\n%33 = OpTypeVector %5 3\n%34 = OpTypePointer Input %33\n%35 = OpVariable %34 Input\n%36 = OpTypePointer Output %5\n%37 = OpVariable %36 Output\n%48 = OpTypePointer Input %5\n%50 = OpConstant %5 0\n%53 = OpConstant %5 1\n%56 = OpConstant %5 2\n%58 = OpTypePointer Image %5\n%61 = OpTypeVector %5 2\n%69 = OpConstant %5 3\n%74 = OpConstant %5 4\n%79 = OpConstant %5 5\n%83 = OpConstant %5 6\n%87 = OpConstant %5 7\n%89 = OpTypePointer Image %24\n%92 = OpConstant %5 8\n%99 = OpConstant %5 9\n%107 = OpConstant %5 10\n%112 = OpConstant %5 12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%38 = OpLoad %21 %32\n%39 = OpLoad %21 %31\n%40 = OpLoad %28 %30\n%41 = OpLoad %25 %27\n%42 = OpLoad %21 %23\n%43 = OpLoad %18 %20\n%44 = OpLoad %15 %17\n%45 = OpLoad %12 %14\n%46 = OpLoad %9 %11\n%47 = OpLoad %6 %8\n%49 = OpAccessChain %48 %35 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %48 %35 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %48 %35 %56\n%57 = OpLoad %5 %55\n%59 = OpImageTexelPointer %58 %8 %51 %50\n%60 = OpAtomicIAdd %5 %59 %53 %50 %53\n%62 = OpCompositeConstruct %61 %51 %54\n%63 = OpImageTexelPointer %58 %11 %62 %50\n%64 = OpAtomicAnd %5 %63 %53 %50 %56\n%65 = OpIAdd %5 %64 %60\n%66 = OpCompositeConstruct %61 %51 %54\n%67 = OpImageTexelPointer %58 %14 %66 %50\n%68 = OpAtomicExchange %5 %67 %53 %50 %69\n%70 = OpIAdd %5 %65 %68\n%71 = OpCompositeConstruct %33 %51 %54 %57\n%72 = OpImageTexelPointer %58 %17 %71 %50\n%73 = OpAtomicUMax %5 %72 %53 %50 %74\n%75 = OpIAdd %5 %70 %73\n%76 = OpCompositeConstruct %33 %51 %54 %57\n%77 = OpImageTexelPointer %58 %20 %76 %50\n%78 = OpAtomicUMin %5 %77 %53 %50 %79\n%80 = OpIAdd %5 %75 %78\n%81 = OpImageTexelPointer %58 %23 %51 %50\n%82 = OpAtomicOr %5 %81 %53 %50 %83\n%84 = OpIAdd %5 %80 %82\n%85 = OpImageTexelPointer %58 %23 %51 %50\n%86 = OpAtomicXor %5 %85 %53 %50 %87\n%88 = OpIAdd %5 %84 %86\n%90 = OpImageTexelPointer %89 %27 %51 %50\n%93 = OpBitcast %24 %92\n%91 = OpAtomicSMin %24 %90 %53 %50 %93\n%94 = OpBitcast %5 %91\n%95 = OpIAdd %5 %88 %94\n%96 = OpCompositeConstruct %61 %51 %54\n%97 = OpImageTexelPointer %89 %30 %96 %50\n%100 = OpBitcast %24 %99\n%98 = OpAtomicSMax %24 %97 %53 %50 %100\n%101 = OpBitcast %5 %98\n%102 = OpIAdd %5 %95 %101\n%103 = OpIMul %5 %51 %74\n%104 = OpIAdd %5 %103 %56\n%105 = OpImageTexelPointer %58 %31 %104 %50\n%106 = OpAtomicIAdd %5 %105 %53 %50 %107\n%108 = OpIAdd %5 %102 %106\n%109 = OpShiftLeftLogical %5 %51 %56\n%110 = OpImageTexelPointer %58 %32 %51 %50\n%111 = OpAtomicUMax %5 %110 %53 %50 %112\n%113 = OpIAdd %5 %108 %111\nOpStore %37 %113\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atomic-bin-op.root-descriptor.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerUintArray;\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerUintArray\n{\n    uint value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    uint _21 = gl_GlobalInvocationID.x << 4u;\n    uint _30 = atomicAdd(PhysicalPointerUintArray(registers._m2).value[gl_GlobalInvocationID.x * 4u], 1u);\n    uint _37 = atomicAdd(PhysicalPointerUintArray(registers._m2).value[(gl_GlobalInvocationID.x * 4u) + 1u], 2u);\n    uint _42 = atomicAdd(PhysicalPointerUintArray(registers._m2).value[(_21 | 2u) >> 2u], 3u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %25 \"PhysicalPointerUintArray\"\nOpMemberName %25 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %16 BuiltIn GlobalInvocationId\nOpDecorate %24 ArrayStride 4\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypePointer PushConstant %6\n%12 = OpConstant %5 2\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 4\n%24 = OpTypeRuntimeArray %5\n%25 = OpTypeStruct %24\n%26 = OpTypePointer PhysicalStorageBuffer %25\n%28 = OpTypePointer PhysicalStorageBuffer %5\n%31 = OpConstant %5 1\n%43 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%11 = OpAccessChain %10 %9 %12\n%13 = OpLoad %6 %11\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%21 = OpShiftLeftLogical %5 %20 %22\n%23 = OpIMul %5 %20 %22\n%27 = OpBitcast %26 %13\n%29 = OpAccessChain %28 %27 %19 %23\n%30 = OpAtomicIAdd %5 %29 %31 %19 %31\n%32 = OpBitwiseOr %5 %21 %22\n%33 = OpIMul %5 %20 %22\n%34 = OpIAdd %5 %33 %31\n%35 = OpBitcast %26 %13\n%36 = OpAccessChain %28 %35 %19 %34\n%37 = OpAtomicIAdd %5 %36 %31 %19 %12\n%38 = OpBitwiseOr %5 %21 %12\n%39 = OpShiftRightLogical %5 %38 %12\n%40 = OpBitcast %26 %13\n%41 = OpAccessChain %28 %40 %19 %39\n%42 = OpAtomicIAdd %5 %41 %31 %19 %43\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atomic-bin-op.ssbo.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 6, std430) buffer SSBO\n{\n    uint _m0[];\n} _34;\n\nlayout(set = 0, binding = 7, std430) buffer _36_38\n{\n    uint _m0[];\n} _38;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1D _8;\nlayout(set = 0, binding = 1, r32ui) uniform uimage1DArray _11;\nlayout(set = 0, binding = 2, r32ui) uniform uimage2D _14;\nlayout(set = 0, binding = 3, r32ui) uniform uimage2DArray _17;\nlayout(set = 0, binding = 4, r32ui) uniform uimage3D _20;\nlayout(set = 0, binding = 5, r32ui) uniform uimageBuffer _23;\nlayout(set = 1, binding = 0, r32i) uniform iimage1D _27;\nlayout(set = 1, binding = 2, r32i) uniform iimage2D _30;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _64 = imageAtomicAdd(_8, int(TEXCOORD.x), 1u);\n    uint _68 = imageAtomicAnd(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 2u);\n    uint _72 = imageAtomicExchange(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 3u);\n    uint _77 = imageAtomicMax(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 4u);\n    uint _82 = imageAtomicMin(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 5u);\n    uint _86 = imageAtomicOr(_23, int(TEXCOORD.x), 6u);\n    uint _90 = imageAtomicXor(_23, int(TEXCOORD.x), 7u);\n    int _95 = imageAtomicMin(_27, int(TEXCOORD.x), int(8u));\n    int _102 = imageAtomicMax(_30, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(9u));\n    uint _111 = atomicAdd(_34._m0[(TEXCOORD.x * 4u) + 2u], 10u);\n    uint _116 = atomicMax(_38._m0[TEXCOORD.x], 12u);\n    SV_Target = (((((((((_68 + _64) + _72) + _77) + _82) + _86) + _90) + uint(_95)) + uint(_102)) + _111) + _116;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 121\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %41 %43\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"SSBO\"\nOpName %36 \"SSBO\"\nOpName %41 \"TEXCOORD\"\nOpName %43 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %27 DescriptorSet 1\nOpDecorate %27 Binding 0\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 2\nOpDecorate %31 ArrayStride 4\nOpMemberDecorate %32 0 Offset 0\nOpDecorate %32 Block\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 6\nOpDecorate %35 ArrayStride 4\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 7\nOpDecorate %41 Flat\nOpDecorate %41 Location 0\nOpDecorate %43 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 1D 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 2 R32ui\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 2 R32ui\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 2 R32ui\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeInt 32 1\n%25 = OpTypeImage %24 1D 0 0 0 2 R32i\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeImage %24 2D 0 0 0 2 R32i\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeRuntimeArray %5\n%32 = OpTypeStruct %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeRuntimeArray %5\n%36 = OpTypeStruct %35\n%37 = OpTypePointer StorageBuffer %36\n%38 = OpVariable %37 StorageBuffer\n%39 = OpTypeVector %5 3\n%40 = OpTypePointer Input %39\n%41 = OpVariable %40 Input\n%42 = OpTypePointer Output %5\n%43 = OpVariable %42 Output\n%52 = OpTypePointer Input %5\n%54 = OpConstant %5 0\n%57 = OpConstant %5 1\n%60 = OpConstant %5 2\n%62 = OpTypePointer Image %5\n%65 = OpTypeVector %5 2\n%73 = OpConstant %5 3\n%78 = OpConstant %5 4\n%83 = OpConstant %5 5\n%87 = OpConstant %5 6\n%91 = OpConstant %5 7\n%93 = OpTypePointer Image %24\n%96 = OpConstant %5 8\n%103 = OpConstant %5 9\n%109 = OpTypePointer StorageBuffer %5\n%112 = OpConstant %5 10\n%117 = OpConstant %5 12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %119\n%119 = OpLabel\n%44 = OpLoad %28 %30\n%45 = OpLoad %25 %27\n%46 = OpLoad %21 %23\n%47 = OpLoad %18 %20\n%48 = OpLoad %15 %17\n%49 = OpLoad %12 %14\n%50 = OpLoad %9 %11\n%51 = OpLoad %6 %8\n%53 = OpAccessChain %52 %41 %54\n%55 = OpLoad %5 %53\n%56 = OpAccessChain %52 %41 %57\n%58 = OpLoad %5 %56\n%59 = OpAccessChain %52 %41 %60\n%61 = OpLoad %5 %59\n%63 = OpImageTexelPointer %62 %8 %55 %54\n%64 = OpAtomicIAdd %5 %63 %57 %54 %57\n%66 = OpCompositeConstruct %65 %55 %58\n%67 = OpImageTexelPointer %62 %11 %66 %54\n%68 = OpAtomicAnd %5 %67 %57 %54 %60\n%69 = OpIAdd %5 %68 %64\n%70 = OpCompositeConstruct %65 %55 %58\n%71 = OpImageTexelPointer %62 %14 %70 %54\n%72 = OpAtomicExchange %5 %71 %57 %54 %73\n%74 = OpIAdd %5 %69 %72\n%75 = OpCompositeConstruct %39 %55 %58 %61\n%76 = OpImageTexelPointer %62 %17 %75 %54\n%77 = OpAtomicUMax %5 %76 %57 %54 %78\n%79 = OpIAdd %5 %74 %77\n%80 = OpCompositeConstruct %39 %55 %58 %61\n%81 = OpImageTexelPointer %62 %20 %80 %54\n%82 = OpAtomicUMin %5 %81 %57 %54 %83\n%84 = OpIAdd %5 %79 %82\n%85 = OpImageTexelPointer %62 %23 %55 %54\n%86 = OpAtomicOr %5 %85 %57 %54 %87\n%88 = OpIAdd %5 %84 %86\n%89 = OpImageTexelPointer %62 %23 %55 %54\n%90 = OpAtomicXor %5 %89 %57 %54 %91\n%92 = OpIAdd %5 %88 %90\n%94 = OpImageTexelPointer %93 %27 %55 %54\n%97 = OpBitcast %24 %96\n%95 = OpAtomicSMin %24 %94 %57 %54 %97\n%98 = OpBitcast %5 %95\n%99 = OpIAdd %5 %92 %98\n%100 = OpCompositeConstruct %65 %55 %58\n%101 = OpImageTexelPointer %93 %30 %100 %54\n%104 = OpBitcast %24 %103\n%102 = OpAtomicSMax %24 %101 %57 %54 %104\n%105 = OpBitcast %5 %102\n%106 = OpIAdd %5 %99 %105\n%107 = OpIMul %5 %55 %78\n%108 = OpIAdd %5 %107 %60\n%110 = OpAccessChain %109 %34 %54 %108\n%111 = OpAtomicIAdd %5 %110 %57 %54 %112\n%113 = OpIAdd %5 %106 %111\n%114 = OpShiftLeftLogical %5 %55 %60\n%115 = OpAccessChain %109 %38 %54 %55\n%116 = OpAtomicUMax %5 %115 %57 %54 %117\n%118 = OpIAdd %5 %113 %116\nOpStore %43 %118\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atomic-compare-exchange.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1D _8;\nlayout(set = 0, binding = 1, r32ui) uniform uimage1DArray _11;\nlayout(set = 0, binding = 2, r32ui) uniform uimage2D _14;\nlayout(set = 0, binding = 3, r32ui) uniform uimage2DArray _17;\nlayout(set = 0, binding = 4, r32ui) uniform uimage3D _20;\nlayout(set = 0, binding = 5, r32ui) uniform uimageBuffer _23;\nlayout(set = 1, binding = 0, r32i) uniform iimage1D _27;\nlayout(set = 1, binding = 2, r32i) uniform iimage2D _30;\nlayout(set = 0, binding = 6, r32ui) uniform uimageBuffer _31;\nlayout(set = 0, binding = 7, r32ui) uniform uimageBuffer _32;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _60 = imageAtomicCompSwap(_8, int(TEXCOORD.x), 20u, 30u);\n    uint _66 = imageAtomicCompSwap(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 20u, 30u);\n    uint _70 = imageAtomicCompSwap(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 20u, 30u);\n    uint _74 = imageAtomicCompSwap(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 20u, 30u);\n    uint _78 = imageAtomicCompSwap(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 20u, 30u);\n    uint _81 = imageAtomicCompSwap(_23, int(TEXCOORD.x), 20u, 30u);\n    uint _84 = imageAtomicCompSwap(_23, int(TEXCOORD.x), 20u, 30u);\n    int _88 = imageAtomicCompSwap(_27, int(TEXCOORD.x), int(20u), int(30u));\n    int _95 = imageAtomicCompSwap(_30, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(20u), int(30u));\n    uint _104 = imageAtomicCompSwap(_31, int((TEXCOORD.x * 4u) + 2u), 20u, 30u);\n    uint _108 = imageAtomicCompSwap(_32, int(TEXCOORD.x), 20u, 30u);\n    SV_Target = (((((((((_66 + _60) + _70) + _74) + _78) + _81) + _84) + uint(_88)) + uint(_95)) + _104) + _108;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 112\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %35 %37\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %35 \"TEXCOORD\"\nOpName %37 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %27 DescriptorSet 1\nOpDecorate %27 Binding 0\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 2\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 6\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 7\nOpDecorate %35 Flat\nOpDecorate %35 Location 0\nOpDecorate %37 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 1D 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 2 R32ui\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 2 R32ui\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 2 R32ui\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeInt 32 1\n%25 = OpTypeImage %24 1D 0 0 0 2 R32i\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeImage %24 2D 0 0 0 2 R32i\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpVariable %22 UniformConstant\n%32 = OpVariable %22 UniformConstant\n%33 = OpTypeVector %5 3\n%34 = OpTypePointer Input %33\n%35 = OpVariable %34 Input\n%36 = OpTypePointer Output %5\n%37 = OpVariable %36 Output\n%48 = OpTypePointer Input %5\n%50 = OpConstant %5 0\n%53 = OpConstant %5 1\n%56 = OpConstant %5 2\n%58 = OpTypePointer Image %5\n%61 = OpConstant %5 20\n%62 = OpConstant %5 30\n%63 = OpTypeVector %5 2\n%86 = OpTypePointer Image %24\n%101 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%38 = OpLoad %21 %32\n%39 = OpLoad %21 %31\n%40 = OpLoad %28 %30\n%41 = OpLoad %25 %27\n%42 = OpLoad %21 %23\n%43 = OpLoad %18 %20\n%44 = OpLoad %15 %17\n%45 = OpLoad %12 %14\n%46 = OpLoad %9 %11\n%47 = OpLoad %6 %8\n%49 = OpAccessChain %48 %35 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %48 %35 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %48 %35 %56\n%57 = OpLoad %5 %55\n%59 = OpImageTexelPointer %58 %8 %51 %50\n%60 = OpAtomicCompareExchange %5 %59 %53 %50 %50 %62 %61\n%64 = OpCompositeConstruct %63 %51 %54\n%65 = OpImageTexelPointer %58 %11 %64 %50\n%66 = OpAtomicCompareExchange %5 %65 %53 %50 %50 %62 %61\n%67 = OpIAdd %5 %66 %60\n%68 = OpCompositeConstruct %63 %51 %54\n%69 = OpImageTexelPointer %58 %14 %68 %50\n%70 = OpAtomicCompareExchange %5 %69 %53 %50 %50 %62 %61\n%71 = OpIAdd %5 %67 %70\n%72 = OpCompositeConstruct %33 %51 %54 %57\n%73 = OpImageTexelPointer %58 %17 %72 %50\n%74 = OpAtomicCompareExchange %5 %73 %53 %50 %50 %62 %61\n%75 = OpIAdd %5 %71 %74\n%76 = OpCompositeConstruct %33 %51 %54 %57\n%77 = OpImageTexelPointer %58 %20 %76 %50\n%78 = OpAtomicCompareExchange %5 %77 %53 %50 %50 %62 %61\n%79 = OpIAdd %5 %75 %78\n%80 = OpImageTexelPointer %58 %23 %51 %50\n%81 = OpAtomicCompareExchange %5 %80 %53 %50 %50 %62 %61\n%82 = OpIAdd %5 %79 %81\n%83 = OpImageTexelPointer %58 %23 %51 %50\n%84 = OpAtomicCompareExchange %5 %83 %53 %50 %50 %62 %61\n%85 = OpIAdd %5 %82 %84\n%87 = OpImageTexelPointer %86 %27 %51 %50\n%89 = OpBitcast %24 %61\n%90 = OpBitcast %24 %62\n%88 = OpAtomicCompareExchange %24 %87 %53 %50 %50 %90 %89\n%91 = OpBitcast %5 %88\n%92 = OpIAdd %5 %85 %91\n%93 = OpCompositeConstruct %63 %51 %54\n%94 = OpImageTexelPointer %86 %30 %93 %50\n%96 = OpBitcast %24 %61\n%97 = OpBitcast %24 %62\n%95 = OpAtomicCompareExchange %24 %94 %53 %50 %50 %97 %96\n%98 = OpBitcast %5 %95\n%99 = OpIAdd %5 %92 %98\n%100 = OpIMul %5 %51 %101\n%102 = OpIAdd %5 %100 %56\n%103 = OpImageTexelPointer %58 %31 %102 %50\n%104 = OpAtomicCompareExchange %5 %103 %53 %50 %50 %62 %61\n%105 = OpIAdd %5 %99 %104\n%106 = OpShiftLeftLogical %5 %51 %56\n%107 = OpImageTexelPointer %58 %32 %51 %50\n%108 = OpAtomicCompareExchange %5 %107 %53 %50 %50 %62 %61\n%109 = OpIAdd %5 %105 %108\nOpStore %37 %109\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atomic-compare-exchange.root-descriptor.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerUintArray;\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerUintArray\n{\n    uint value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    uint _28 = atomicCompSwap(PhysicalPointerUintArray(registers._m2).value[gl_GlobalInvocationID.x], 1u, 2u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %23 \"PhysicalPointerUintArray\"\nOpMemberName %23 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %16 BuiltIn GlobalInvocationId\nOpDecorate %22 ArrayStride 4\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypePointer PushConstant %6\n%12 = OpConstant %5 2\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpTypeRuntimeArray %5\n%23 = OpTypeStruct %22\n%24 = OpTypePointer PhysicalStorageBuffer %23\n%26 = OpTypePointer PhysicalStorageBuffer %5\n%29 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%11 = OpAccessChain %10 %9 %12\n%13 = OpLoad %6 %11\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%21 = OpShiftLeftLogical %5 %20 %12\n%25 = OpBitcast %24 %13\n%27 = OpAccessChain %26 %25 %19 %20\n%28 = OpAtomicCompareExchange %5 %27 %29 %19 %19 %12 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/atomic-compare-exchange.ssbo.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 6, std430) buffer SSBO\n{\n    uint _m0[];\n} _34;\n\nlayout(set = 0, binding = 7, std430) buffer _36_38\n{\n    uint _m0[];\n} _38;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1D _8;\nlayout(set = 0, binding = 1, r32ui) uniform uimage1DArray _11;\nlayout(set = 0, binding = 2, r32ui) uniform uimage2D _14;\nlayout(set = 0, binding = 3, r32ui) uniform uimage2DArray _17;\nlayout(set = 0, binding = 4, r32ui) uniform uimage3D _20;\nlayout(set = 0, binding = 5, r32ui) uniform uimageBuffer _23;\nlayout(set = 1, binding = 0, r32i) uniform iimage1D _27;\nlayout(set = 1, binding = 2, r32i) uniform iimage2D _30;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _64 = imageAtomicCompSwap(_8, int(TEXCOORD.x), 20u, 30u);\n    uint _70 = imageAtomicCompSwap(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 20u, 30u);\n    uint _74 = imageAtomicCompSwap(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), 20u, 30u);\n    uint _78 = imageAtomicCompSwap(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 20u, 30u);\n    uint _82 = imageAtomicCompSwap(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), 20u, 30u);\n    uint _85 = imageAtomicCompSwap(_23, int(TEXCOORD.x), 20u, 30u);\n    uint _88 = imageAtomicCompSwap(_23, int(TEXCOORD.x), 20u, 30u);\n    int _92 = imageAtomicCompSwap(_27, int(TEXCOORD.x), int(20u), int(30u));\n    int _99 = imageAtomicCompSwap(_30, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(20u), int(30u));\n    uint _109 = atomicCompSwap(_34._m0[(TEXCOORD.x * 4u) + 2u], 20u, 30u);\n    uint _113 = atomicCompSwap(_38._m0[TEXCOORD.x], 20u, 30u);\n    SV_Target = (((((((((_70 + _64) + _74) + _78) + _82) + _85) + _88) + uint(_92)) + uint(_99)) + _109) + _113;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 117\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %41 %43\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"SSBO\"\nOpName %36 \"SSBO\"\nOpName %41 \"TEXCOORD\"\nOpName %43 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %27 DescriptorSet 1\nOpDecorate %27 Binding 0\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 2\nOpDecorate %31 ArrayStride 4\nOpMemberDecorate %32 0 Offset 0\nOpDecorate %32 Block\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 6\nOpDecorate %35 ArrayStride 4\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 7\nOpDecorate %41 Flat\nOpDecorate %41 Location 0\nOpDecorate %43 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 1D 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 2 R32ui\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 2 R32ui\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 2 R32ui\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeInt 32 1\n%25 = OpTypeImage %24 1D 0 0 0 2 R32i\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeImage %24 2D 0 0 0 2 R32i\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeRuntimeArray %5\n%32 = OpTypeStruct %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeRuntimeArray %5\n%36 = OpTypeStruct %35\n%37 = OpTypePointer StorageBuffer %36\n%38 = OpVariable %37 StorageBuffer\n%39 = OpTypeVector %5 3\n%40 = OpTypePointer Input %39\n%41 = OpVariable %40 Input\n%42 = OpTypePointer Output %5\n%43 = OpVariable %42 Output\n%52 = OpTypePointer Input %5\n%54 = OpConstant %5 0\n%57 = OpConstant %5 1\n%60 = OpConstant %5 2\n%62 = OpTypePointer Image %5\n%65 = OpConstant %5 20\n%66 = OpConstant %5 30\n%67 = OpTypeVector %5 2\n%90 = OpTypePointer Image %24\n%105 = OpConstant %5 4\n%107 = OpTypePointer StorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %115\n%115 = OpLabel\n%44 = OpLoad %28 %30\n%45 = OpLoad %25 %27\n%46 = OpLoad %21 %23\n%47 = OpLoad %18 %20\n%48 = OpLoad %15 %17\n%49 = OpLoad %12 %14\n%50 = OpLoad %9 %11\n%51 = OpLoad %6 %8\n%53 = OpAccessChain %52 %41 %54\n%55 = OpLoad %5 %53\n%56 = OpAccessChain %52 %41 %57\n%58 = OpLoad %5 %56\n%59 = OpAccessChain %52 %41 %60\n%61 = OpLoad %5 %59\n%63 = OpImageTexelPointer %62 %8 %55 %54\n%64 = OpAtomicCompareExchange %5 %63 %57 %54 %54 %66 %65\n%68 = OpCompositeConstruct %67 %55 %58\n%69 = OpImageTexelPointer %62 %11 %68 %54\n%70 = OpAtomicCompareExchange %5 %69 %57 %54 %54 %66 %65\n%71 = OpIAdd %5 %70 %64\n%72 = OpCompositeConstruct %67 %55 %58\n%73 = OpImageTexelPointer %62 %14 %72 %54\n%74 = OpAtomicCompareExchange %5 %73 %57 %54 %54 %66 %65\n%75 = OpIAdd %5 %71 %74\n%76 = OpCompositeConstruct %39 %55 %58 %61\n%77 = OpImageTexelPointer %62 %17 %76 %54\n%78 = OpAtomicCompareExchange %5 %77 %57 %54 %54 %66 %65\n%79 = OpIAdd %5 %75 %78\n%80 = OpCompositeConstruct %39 %55 %58 %61\n%81 = OpImageTexelPointer %62 %20 %80 %54\n%82 = OpAtomicCompareExchange %5 %81 %57 %54 %54 %66 %65\n%83 = OpIAdd %5 %79 %82\n%84 = OpImageTexelPointer %62 %23 %55 %54\n%85 = OpAtomicCompareExchange %5 %84 %57 %54 %54 %66 %65\n%86 = OpIAdd %5 %83 %85\n%87 = OpImageTexelPointer %62 %23 %55 %54\n%88 = OpAtomicCompareExchange %5 %87 %57 %54 %54 %66 %65\n%89 = OpIAdd %5 %86 %88\n%91 = OpImageTexelPointer %90 %27 %55 %54\n%93 = OpBitcast %24 %65\n%94 = OpBitcast %24 %66\n%92 = OpAtomicCompareExchange %24 %91 %57 %54 %54 %94 %93\n%95 = OpBitcast %5 %92\n%96 = OpIAdd %5 %89 %95\n%97 = OpCompositeConstruct %67 %55 %58\n%98 = OpImageTexelPointer %90 %30 %97 %54\n%100 = OpBitcast %24 %65\n%101 = OpBitcast %24 %66\n%99 = OpAtomicCompareExchange %24 %98 %57 %54 %54 %101 %100\n%102 = OpBitcast %5 %99\n%103 = OpIAdd %5 %96 %102\n%104 = OpIMul %5 %55 %105\n%106 = OpIAdd %5 %104 %60\n%108 = OpAccessChain %107 %34 %54 %106\n%109 = OpAtomicCompareExchange %5 %108 %57 %54 %54 %66 %65\n%110 = OpIAdd %5 %103 %109\n%111 = OpShiftLeftLogical %5 %55 %60\n%112 = OpAccessChain %107 %38 %54 %55\n%113 = OpAtomicCompareExchange %5 %112 %57 %54 %54 %66 %65\n%114 = OpIAdd %5 %110 %113\nOpStore %43 %114\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/attributes.denorm-ftz.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _11;\n\nvoid main()\n{\n    imageStore(_11, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(texelFetch(_8, int(gl_GlobalInvocationID.x)).x) * 2.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability DenormFlushToZero\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormFlushToZero 32\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%21 = OpTypeVector %5 4\n%24 = OpTypeFloat 32\n%27 = OpConstant %24 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%12 = OpLoad %9 %11\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%22 = OpImageFetch %21 %13 %20\n%23 = OpCompositeExtract %5 %22 0\n%25 = OpBitcast %24 %23\n%26 = OpFMul %24 %25 %27\n%28 = OpBitcast %5 %26\n%29 = OpCompositeConstruct %21 %28 %28 %28 %28\nOpImageWrite %12 %20 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/attributes.denorm-preserve.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _11;\n\nvoid main()\n{\n    imageStore(_11, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(texelFetch(_8, int(gl_GlobalInvocationID.x)).x) * 2.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 32\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%21 = OpTypeVector %5 4\n%24 = OpTypeFloat 32\n%27 = OpConstant %24 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%12 = OpLoad %9 %11\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%22 = OpImageFetch %21 %13 %20\n%23 = OpCompositeExtract %5 %22 0\n%25 = OpBitcast %24 %23\n%26 = OpFMul %24 %25 %27\n%28 = OpBitcast %5 %26\n%29 = OpCompositeConstruct %21 %28 %28 %28 %28\nOpImageWrite %12 %20 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/barrier.comp",
    "content": "#version 460\nlayout(local_size_x = 7, local_size_y = 8, local_size_z = 9) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(0u), uvec4(5u));\n    memoryBarrierShared();\n    imageStore(_8, int(0u), uvec4(10u));\n    groupMemoryBarrier();\n    imageStore(_8, int(0u), uvec4(15u));\n    barrier();\n    imageStore(_8, int(0u), uvec4(20u));\n    groupMemoryBarrier();\n    barrier();\n    imageStore(_8, int(0u), uvec4(30u));\n    groupMemoryBarrier();\n    imageStore(_8, int(0u), uvec4(40u));\n    groupMemoryBarrier();\n    barrier();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 7 8 9\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpConstant %5 0\n%11 = OpConstant %5 5\n%12 = OpTypeVector %5 4\n%14 = OpConstant %5 2\n%15 = OpConstant %5 264\n%16 = OpConstant %5 10\n%18 = OpConstant %5 2376\n%19 = OpConstant %5 15\n%21 = OpConstant %5 20\n%23 = OpConstant %5 30\n%25 = OpConstant %5 2120\n%26 = OpConstant %5 40\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%9 = OpLoad %6 %8\n%13 = OpCompositeConstruct %12 %11 %11 %11 %11\nOpImageWrite %9 %10 %13\nOpMemoryBarrier %14 %15\n%17 = OpCompositeConstruct %12 %16 %16 %16 %16\nOpImageWrite %9 %10 %17\nOpMemoryBarrier %14 %18\n%20 = OpCompositeConstruct %12 %19 %19 %19 %19\nOpImageWrite %9 %10 %20\nOpControlBarrier %14 %14 %15\n%22 = OpCompositeConstruct %12 %21 %21 %21 %21\nOpImageWrite %9 %10 %22\nOpControlBarrier %14 %14 %18\n%24 = OpCompositeConstruct %12 %23 %23 %23 %23\nOpImageWrite %9 %10 %24\nOpMemoryBarrier %14 %25\n%27 = OpCompositeConstruct %12 %26 %26 %26 %26\nOpImageWrite %9 %10 %27\nOpControlBarrier %14 %14 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/barycentrics-2.frag",
    "content": "#version 460\n#extension GL_EXT_fragment_shader_barycentric : require\n\nlayout(location = 0) pervertexEXT in float ATTRIB[3];\nlayout(location = 0, component = 1) pervertexEXT in float ATTRIB_1[3];\nlayout(location = 0, component = 2) pervertexEXT in float ATTRIB_2[3];\nlayout(location = 1) centroid in float FOO;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (((ATTRIB[0u] * gl_BaryCoordEXT.x) + FOO) + (ATTRIB_1[1u] * gl_BaryCoordEXT.y)) + (ATTRIB_2[2u] * gl_BaryCoordEXT.z);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\nOpCapability Shader\nOpCapability SampleRateShading\nOpCapability FragmentBarycentricKHR\nOpExtension \"SPV_KHR_fragment_shader_barycentric\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %10 %11 %12 %15 %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"ATTRIB\"\nOpName %11 \"ATTRIB_1\"\nOpName %12 \"ATTRIB_2\"\nOpName %15 \"SV_Barycentrics\"\nOpName %17 \"FOO\"\nOpName %19 \"SV_Target\"\nOpDecorate %10 PerVertexKHR\nOpDecorate %10 Location 0\nOpDecorate %11 PerVertexKHR\nOpDecorate %11 Location 0\nOpDecorate %11 Component 1\nOpDecorate %12 PerVertexKHR\nOpDecorate %12 Location 0\nOpDecorate %12 Component 2\nOpDecorate %15 BuiltIn BaryCoordKHR\nOpDecorate %15 Sample\nOpDecorate %17 Centroid\nOpDecorate %17 Location 1\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpVariable %9 Input\n%12 = OpVariable %9 Input\n%13 = OpTypeVector %5 3\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Input %5\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %5\n%19 = OpVariable %18 Output\n%22 = OpConstant %6 0\n%25 = OpConstant %6 1\n%28 = OpConstant %6 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%20 = OpLoad %5 %17\n%21 = OpAccessChain %16 %15 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %16 %15 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %16 %15 %28\n%29 = OpLoad %5 %27\n%30 = OpAccessChain %16 %10 %22\n%31 = OpLoad %5 %30\n%32 = OpFMul %5 %31 %23\n%33 = OpAccessChain %16 %11 %25\n%34 = OpLoad %5 %33\n%35 = OpFMul %5 %34 %26\n%36 = OpAccessChain %16 %12 %28\n%37 = OpLoad %5 %36\n%38 = OpFMul %5 %37 %29\n%39 = OpFAdd %5 %32 %20\n%40 = OpFAdd %5 %39 %35\n%41 = OpFAdd %5 %40 %38\nOpStore %19 %41\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/barycentrics.frag",
    "content": "#version 460\n#extension GL_EXT_fragment_shader_barycentric : require\n\nlayout(location = 0) pervertexEXT in vec4 ATTRIB[3];\nlayout(location = 1) pervertexEXT in vec4 ATTRIB_2[3][2];\nlayout(location = 3) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = (((((ATTRIB[0u].x + gl_BaryCoordEXT.x) + (ATTRIB[0u].x * gl_BaryCoordEXT.x)) + (ATTRIB[1u].x * gl_BaryCoordEXT.y)) + (ATTRIB_2[0u][INDEX].x * gl_BaryCoordEXT.z)) + ((ATTRIB_2[0u][1u].x + ATTRIB_2[1u][0u].x) * gl_BaryCoordNoPerspEXT.x)) + ((ATTRIB_2[1u][1u].x + ATTRIB_2[2u][0u].x) * gl_BaryCoordNoPerspEXT.y);\n    SV_Target.y = (((((ATTRIB[0u].y + gl_BaryCoordEXT.y) + (ATTRIB[0u].y * gl_BaryCoordEXT.x)) + (ATTRIB[1u].y * gl_BaryCoordEXT.y)) + (ATTRIB_2[0u][INDEX].y * gl_BaryCoordEXT.z)) + ((ATTRIB_2[0u][1u].y + ATTRIB_2[1u][0u].y) * gl_BaryCoordNoPerspEXT.x)) + ((ATTRIB_2[1u][1u].y + ATTRIB_2[2u][0u].y) * gl_BaryCoordNoPerspEXT.y);\n    SV_Target.z = (((((ATTRIB[0u].z + gl_BaryCoordNoPerspEXT.y) + (ATTRIB[0u].z * gl_BaryCoordEXT.x)) + (ATTRIB[1u].z * gl_BaryCoordEXT.y)) + (ATTRIB_2[0u][INDEX].z * gl_BaryCoordEXT.z)) + ((ATTRIB_2[0u][1u].z + ATTRIB_2[1u][0u].z) * gl_BaryCoordNoPerspEXT.x)) + ((ATTRIB_2[1u][1u].z + ATTRIB_2[2u][0u].z) * gl_BaryCoordNoPerspEXT.y);\n    SV_Target.w = (((((ATTRIB[0u].w + gl_BaryCoordNoPerspEXT.x) + (ATTRIB[0u].w * gl_BaryCoordEXT.x)) + (ATTRIB[1u].w * gl_BaryCoordEXT.y)) + (ATTRIB_2[0u][INDEX].w * gl_BaryCoordEXT.z)) + ((ATTRIB_2[0u][1u].w + ATTRIB_2[1u][0u].w) * gl_BaryCoordNoPerspEXT.x)) + ((ATTRIB_2[1u][1u].w + ATTRIB_2[2u][0u].w) * gl_BaryCoordNoPerspEXT.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 162\n; Schema: 0\nOpCapability Shader\nOpCapability FragmentBarycentricKHR\nOpExtension \"SPV_KHR_fragment_shader_barycentric\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %16 %19 %20 %22 %24\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"ATTRIB\"\nOpName %16 \"ATTRIB_2\"\nOpName %19 \"SV_Barycentrics\"\nOpName %20 \"SV_Barycentrics_1\"\nOpName %22 \"INDEX\"\nOpName %24 \"SV_Target\"\nOpDecorate %11 PerVertexKHR\nOpDecorate %11 Location 0\nOpDecorate %16 PerVertexKHR\nOpDecorate %16 Location 1\nOpDecorate %19 BuiltIn BaryCoordKHR\nOpDecorate %20 BuiltIn BaryCoordNoPerspKHR\nOpDecorate %20 Centroid\nOpDecorate %22 Flat\nOpDecorate %22 Location 3\nOpDecorate %24 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpConstant %7 2\n%13 = OpTypeArray %6 %12\n%14 = OpTypeArray %13 %8\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpVariable %18 Input\n%21 = OpTypePointer Input %7\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Output %6\n%24 = OpVariable %23 Output\n%26 = OpTypePointer Input %5\n%28 = OpConstant %7 0\n%31 = OpConstant %7 1\n%155 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %160\n%160 = OpLabel\n%25 = OpLoad %7 %22\n%27 = OpAccessChain %26 %20 %28\n%29 = OpLoad %5 %27\n%30 = OpAccessChain %26 %20 %31\n%32 = OpLoad %5 %30\n%33 = OpAccessChain %26 %19 %28\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %26 %19 %31\n%36 = OpLoad %5 %35\n%37 = OpAccessChain %26 %19 %12\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %26 %11 %28 %28\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %26 %11 %28 %31\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %26 %11 %28 %12\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %26 %11 %28 %8\n%46 = OpLoad %5 %45\n%47 = OpAccessChain %26 %11 %28 %28\n%48 = OpLoad %5 %47\n%49 = OpAccessChain %26 %11 %28 %31\n%50 = OpLoad %5 %49\n%51 = OpAccessChain %26 %11 %28 %12\n%52 = OpLoad %5 %51\n%53 = OpAccessChain %26 %11 %28 %8\n%54 = OpLoad %5 %53\n%55 = OpFMul %5 %48 %34\n%56 = OpFMul %5 %50 %34\n%57 = OpFMul %5 %52 %34\n%58 = OpFMul %5 %54 %34\n%59 = OpAccessChain %26 %11 %31 %28\n%60 = OpLoad %5 %59\n%61 = OpAccessChain %26 %11 %31 %31\n%62 = OpLoad %5 %61\n%63 = OpAccessChain %26 %11 %31 %12\n%64 = OpLoad %5 %63\n%65 = OpAccessChain %26 %11 %31 %8\n%66 = OpLoad %5 %65\n%67 = OpFMul %5 %60 %36\n%68 = OpFMul %5 %62 %36\n%69 = OpFMul %5 %64 %36\n%70 = OpFMul %5 %66 %36\n%71 = OpAccessChain %26 %16 %28 %25 %28\n%72 = OpLoad %5 %71\n%73 = OpAccessChain %26 %16 %28 %25 %31\n%74 = OpLoad %5 %73\n%75 = OpAccessChain %26 %16 %28 %25 %12\n%76 = OpLoad %5 %75\n%77 = OpAccessChain %26 %16 %28 %25 %8\n%78 = OpLoad %5 %77\n%79 = OpFMul %5 %72 %38\n%80 = OpFMul %5 %74 %38\n%81 = OpFMul %5 %76 %38\n%82 = OpFMul %5 %78 %38\n%83 = OpAccessChain %26 %16 %31 %28 %28\n%84 = OpLoad %5 %83\n%85 = OpAccessChain %26 %16 %31 %28 %31\n%86 = OpLoad %5 %85\n%87 = OpAccessChain %26 %16 %31 %28 %12\n%88 = OpLoad %5 %87\n%89 = OpAccessChain %26 %16 %31 %28 %8\n%90 = OpLoad %5 %89\n%91 = OpAccessChain %26 %16 %12 %28 %28\n%92 = OpLoad %5 %91\n%93 = OpAccessChain %26 %16 %12 %28 %31\n%94 = OpLoad %5 %93\n%95 = OpAccessChain %26 %16 %12 %28 %12\n%96 = OpLoad %5 %95\n%97 = OpAccessChain %26 %16 %12 %28 %8\n%98 = OpLoad %5 %97\n%99 = OpAccessChain %26 %16 %28 %31 %28\n%100 = OpLoad %5 %99\n%101 = OpAccessChain %26 %16 %28 %31 %31\n%102 = OpLoad %5 %101\n%103 = OpAccessChain %26 %16 %28 %31 %12\n%104 = OpLoad %5 %103\n%105 = OpAccessChain %26 %16 %28 %31 %8\n%106 = OpLoad %5 %105\n%107 = OpAccessChain %26 %16 %31 %31 %28\n%108 = OpLoad %5 %107\n%109 = OpAccessChain %26 %16 %31 %31 %31\n%110 = OpLoad %5 %109\n%111 = OpAccessChain %26 %16 %31 %31 %12\n%112 = OpLoad %5 %111\n%113 = OpAccessChain %26 %16 %31 %31 %8\n%114 = OpLoad %5 %113\n%115 = OpFAdd %5 %108 %92\n%116 = OpFMul %5 %115 %32\n%117 = OpFAdd %5 %100 %84\n%118 = OpFMul %5 %117 %29\n%119 = OpFAdd %5 %40 %34\n%120 = OpFAdd %5 %119 %55\n%121 = OpFAdd %5 %120 %67\n%122 = OpFAdd %5 %121 %79\n%123 = OpFAdd %5 %122 %118\n%124 = OpFAdd %5 %123 %116\n%125 = OpFAdd %5 %110 %94\n%126 = OpFMul %5 %125 %32\n%127 = OpFAdd %5 %102 %86\n%128 = OpFMul %5 %127 %29\n%129 = OpFAdd %5 %42 %36\n%130 = OpFAdd %5 %129 %56\n%131 = OpFAdd %5 %130 %68\n%132 = OpFAdd %5 %131 %80\n%133 = OpFAdd %5 %132 %128\n%134 = OpFAdd %5 %133 %126\n%135 = OpFAdd %5 %112 %96\n%136 = OpFMul %5 %135 %32\n%137 = OpFAdd %5 %104 %88\n%138 = OpFMul %5 %137 %29\n%139 = OpFAdd %5 %44 %32\n%140 = OpFAdd %5 %139 %57\n%141 = OpFAdd %5 %140 %69\n%142 = OpFAdd %5 %141 %81\n%143 = OpFAdd %5 %142 %138\n%144 = OpFAdd %5 %143 %136\n%145 = OpFAdd %5 %114 %98\n%146 = OpFMul %5 %145 %32\n%147 = OpFAdd %5 %106 %90\n%148 = OpFMul %5 %147 %29\n%149 = OpFAdd %5 %46 %29\n%150 = OpFAdd %5 %149 %58\n%151 = OpFAdd %5 %150 %70\n%152 = OpFAdd %5 %151 %82\n%153 = OpFAdd %5 %152 %148\n%154 = OpFAdd %5 %153 %146\n%156 = OpAccessChain %155 %24 %28\nOpStore %156 %124\n%157 = OpAccessChain %155 %24 %31\nOpStore %157 %134\n%158 = OpAccessChain %155 %24 %12\nOpStore %158 %144\n%159 = OpAccessChain %155 %24 %8\nOpStore %159 %154\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/bfrev.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = bitfieldReverse(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 14\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %12\n%12 = OpLabel\n%10 = OpLoad %5 %7\n%11 = OpBitReverse %5 %10\nOpStore %9 %11\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/bitcount-bitrev-sizes.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint64_t _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) buffer _12_14\n{\n    uint16_t _m0[];\n} _14;\n\nvoid main()\n{\n    _9._m0[0u] = packUint2x32(bitfieldReverse(unpackUint2x32(_9._m0[0u])).yx);\n    _14._m0[0u] = unpackUint2x16(bitfieldReverse(uint(_14._m0[0u]))).y;\n    uvec2 _39 = uvec2(bitCount(unpackUint2x32(_9._m0[1u])));\n    _9._m0[1u] = uint64_t(_39.x + _39.y);\n    _14._m0[1u] = uint16_t(uint(bitCount(uint(_14._m0[1u]))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 53\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %6 ArrayStride 8\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %11 ArrayStride 2\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 64 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeInt 16 0\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%17 = OpTypePointer StorageBuffer %5\n%20 = OpTypeVector %15 2\n%26 = OpTypePointer StorageBuffer %10\n%29 = OpTypeVector %10 2\n%35 = OpConstant %15 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %51\n%51 = OpLabel\n%18 = OpAccessChain %17 %9 %16 %16\n%19 = OpLoad %5 %18\n%21 = OpBitcast %20 %19\n%22 = OpBitReverse %20 %21\n%23 = OpVectorShuffle %20 %22 %22 1 0\n%24 = OpBitcast %5 %23\n%25 = OpAccessChain %17 %9 %16 %16\nOpStore %25 %24\n%27 = OpAccessChain %26 %14 %16 %16\n%28 = OpLoad %10 %27\n%30 = OpUConvert %15 %28\n%31 = OpBitReverse %15 %30\n%32 = OpBitcast %29 %31\n%33 = OpCompositeExtract %10 %32 1\n%34 = OpAccessChain %26 %14 %16 %16\nOpStore %34 %33\n%36 = OpAccessChain %17 %9 %16 %35\n%37 = OpLoad %5 %36\n%38 = OpBitcast %20 %37\n%39 = OpBitCount %20 %38\n%40 = OpCompositeExtract %15 %39 0\n%41 = OpCompositeExtract %15 %39 1\n%42 = OpIAdd %15 %40 %41\n%43 = OpUConvert %5 %42\n%44 = OpAccessChain %17 %9 %16 %35\nOpStore %44 %43\n%45 = OpAccessChain %26 %14 %16 %35\n%46 = OpLoad %10 %45\n%47 = OpUConvert %15 %46\n%48 = OpBitCount %15 %47\n%49 = OpUConvert %10 %48\n%50 = OpAccessChain %26 %14 %16 %35\nOpStore %50 %49\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-load-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    uvec4 _m1;\n};\n\nstruct _38\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n};\n\nstruct _76\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nuint _40;\nuint _41;\nuint _60;\nuint _61;\nfloat _80;\nfloat _81;\nfloat _97;\nfloat _98;\n\nlayout(set = 0, binding = 1) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 2) uniform usamplerBuffer _9;\nlayout(set = 0, binding = 1, r32ui) uniform readonly uimageBuffer _12;\nlayout(set = 0, binding = 2, r32ui) uniform readonly uimageBuffer _13;\n\nlayout(location = 0) flat in uint TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _27 = TEXCOORD * 2u;\n    uint _122;\n    uvec4 _123;\n    _122 = sparseTexelFetchARB(_8, int(_27), _123);\n    SparseTexel _31 = SparseTexel(_122, _123);\n    _38 _39 = _38(_31._m1.x, texelFetch(_8, int(_27 + 1u)).x, _40, _41, _31._m0);\n    uint _52 = TEXCOORD * 2u;\n    uint _124;\n    uvec4 _125;\n    _124 = sparseImageLoadARB(_12, int(_52), _125);\n    SparseTexel _53 = SparseTexel(_124, _125);\n    _38 _59 = _38(_53._m1.x, imageLoad(_12, int(_52 + 1u)).x, _60, _61, _53._m0);\n    uint _69 = TEXCOORD * 2u;\n    uint _126;\n    uvec4 _127;\n    _126 = sparseTexelFetchARB(_9, int(_69), _127);\n    SparseTexel _70 = SparseTexel(_126, _127);\n    _76 _77 = _76(uintBitsToFloat(_70._m1.x), uintBitsToFloat(texelFetch(_9, int(_69 + 1u)).x), _80, _81, _70._m0);\n    uint _87 = TEXCOORD * 2u;\n    uint _128;\n    uvec4 _129;\n    _128 = sparseImageLoadARB(_13, int(_87), _129);\n    SparseTexel _88 = SparseTexel(_128, _129);\n    _76 _94 = _76(uintBitsToFloat(_88._m1.x), uintBitsToFloat(imageLoad(_13, int(_87 + 1u)).x), _97, _98, _88._m0);\n    float _103 = float(sparseTexelsResidentARB(int(_94._m4)));\n    float _105 = float(sparseTexelsResidentARB(int(_77._m4))) + (float(sparseTexelsResidentARB(int(_59._m4))) + float(sparseTexelsResidentARB(int(_39._m4))));\n    SV_Target.x = ((((_105 + uintBitsToFloat(_39._m0)) + uintBitsToFloat(_59._m0)) + _77._m0) + _94._m0) + _103;\n    SV_Target.y = ((((_105 + uintBitsToFloat(_39._m1)) + uintBitsToFloat(_59._m1)) + _77._m1) + _94._m1) + _103;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 122\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %15 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %15 \"TEXCOORD\"\nOpName %19 \"SV_Target\"\nOpName %30 \"SparseTexel\"\nOpName %38 \"\"\nOpName %76 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 2\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %12 NonWritable\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 2\nOpDecorate %13 NonWritable\nOpDecorate %15 Flat\nOpDecorate %15 Location 0\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpVariable %11 UniformConstant\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%16 = OpTypeFloat 32\n%17 = OpTypeVector %16 2\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%26 = OpConstant %5 3\n%28 = OpConstant %5 2\n%29 = OpTypeVector %5 4\n%30 = OpTypeStruct %5 %29\n%36 = OpConstant %5 1\n%38 = OpTypeStruct %5 %5 %5 %5 %5\n%45 = OpTypeBool\n%50 = OpConstant %16 1\n%51 = OpConstant %16 0\n%76 = OpTypeStruct %16 %16 %16 %16 %5\n%116 = OpTypePointer Output %16\n%118 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%40 = OpUndef %5\n%41 = OpUndef %5\n%60 = OpUndef %5\n%61 = OpUndef %5\n%80 = OpUndef %16\n%81 = OpUndef %16\n%97 = OpUndef %16\n%98 = OpUndef %16\nOpBranch %120\n%120 = OpLabel\n%20 = OpLoad %10 %13\n%21 = OpLoad %10 %12\n%22 = OpLoad %6 %9\n%23 = OpLoad %6 %8\n%24 = OpLoad %5 %15\n%25 = OpShiftLeftLogical %5 %24 %26\n%27 = OpIMul %5 %24 %28\n%31 = OpImageSparseFetch %30 %23 %27\n%32 = OpCompositeExtract %5 %31 0\n%33 = OpCompositeExtract %5 %31 1 0\n%35 = OpIAdd %5 %27 %36\n%34 = OpImageFetch %29 %23 %35\n%37 = OpCompositeExtract %5 %34 0\n%39 = OpCompositeConstruct %38 %33 %37 %40 %41 %32\n%42 = OpCompositeExtract %5 %39 0\n%43 = OpCompositeExtract %5 %39 1\n%44 = OpCompositeExtract %5 %39 4\n%46 = OpImageSparseTexelsResident %45 %44\n%47 = OpBitcast %16 %42\n%48 = OpBitcast %16 %43\n%49 = OpSelect %16 %46 %50 %51\n%52 = OpIMul %5 %24 %28\n%53 = OpImageSparseRead %30 %21 %52\n%54 = OpCompositeExtract %5 %53 0\n%55 = OpCompositeExtract %5 %53 1 0\n%57 = OpIAdd %5 %52 %36\n%56 = OpImageRead %29 %21 %57\n%58 = OpCompositeExtract %5 %56 0\n%59 = OpCompositeConstruct %38 %55 %58 %60 %61 %54\n%62 = OpCompositeExtract %5 %59 0\n%63 = OpCompositeExtract %5 %59 1\n%64 = OpCompositeExtract %5 %59 4\n%65 = OpImageSparseTexelsResident %45 %64\n%66 = OpBitcast %16 %62\n%67 = OpBitcast %16 %63\n%68 = OpSelect %16 %65 %50 %51\n%69 = OpIMul %5 %24 %28\n%70 = OpImageSparseFetch %30 %22 %69\n%71 = OpCompositeExtract %5 %70 0\n%72 = OpCompositeExtract %5 %70 1 0\n%74 = OpIAdd %5 %69 %36\n%73 = OpImageFetch %29 %22 %74\n%75 = OpCompositeExtract %5 %73 0\n%78 = OpBitcast %16 %72\n%79 = OpBitcast %16 %75\n%77 = OpCompositeConstruct %76 %78 %79 %80 %81 %71\n%82 = OpCompositeExtract %16 %77 0\n%83 = OpCompositeExtract %16 %77 1\n%84 = OpCompositeExtract %5 %77 4\n%85 = OpImageSparseTexelsResident %45 %84\n%86 = OpSelect %16 %85 %50 %51\n%87 = OpIMul %5 %24 %28\n%88 = OpImageSparseRead %30 %20 %87\n%89 = OpCompositeExtract %5 %88 0\n%90 = OpCompositeExtract %5 %88 1 0\n%92 = OpIAdd %5 %87 %36\n%91 = OpImageRead %29 %20 %92\n%93 = OpCompositeExtract %5 %91 0\n%95 = OpBitcast %16 %90\n%96 = OpBitcast %16 %93\n%94 = OpCompositeConstruct %76 %95 %96 %97 %98 %89\n%99 = OpCompositeExtract %16 %94 0\n%100 = OpCompositeExtract %16 %94 1\n%101 = OpCompositeExtract %5 %94 4\n%102 = OpImageSparseTexelsResident %45 %101\n%103 = OpSelect %16 %102 %50 %51\n%104 = OpFAdd %16 %68 %49\n%105 = OpFAdd %16 %86 %104\n%106 = OpFAdd %16 %105 %47\n%107 = OpFAdd %16 %106 %66\n%108 = OpFAdd %16 %107 %82\n%109 = OpFAdd %16 %108 %99\n%110 = OpFAdd %16 %109 %103\n%111 = OpFAdd %16 %105 %48\n%112 = OpFAdd %16 %111 %67\n%113 = OpFAdd %16 %112 %83\n%114 = OpFAdd %16 %113 %100\n%115 = OpFAdd %16 %114 %103\n%117 = OpAccessChain %116 %19 %118\nOpStore %117 %110\n%119 = OpAccessChain %116 %19 %36\nOpStore %119 %115\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-load-signed-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    ivec4 _m1;\n};\n\nstruct _32\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n};\n\nlayout(set = 0, binding = 0) uniform isamplerBuffer _8;\nlayout(set = 0, binding = 0, r32i) uniform readonly iimageBuffer _11;\n\nlayout(location = 0) flat in uint TEXCOORD;\nlayout(location = 0) out ivec2 SV_Target;\n\nvoid main()\n{\n    uint _68;\n    ivec4 _69;\n    _68 = sparseTexelFetchARB(_8, int(TEXCOORD), _69);\n    SparseTexel _23 = SparseTexel(_68, _69);\n    uvec4 _27 = uvec4(_23._m1);\n    _32 _33 = _32(_27.x, _27.y, _27.z, _27.w, _23._m0);\n    uint _70;\n    ivec4 _71;\n    _70 = sparseImageLoadARB(_11, int(TEXCOORD), _71);\n    SparseTexel _42 = SparseTexel(_70, _71);\n    uvec4 _45 = uvec4(_42._m1);\n    _32 _50 = _32(_45.x, _45.y, _45.z, _45.w, _42._m0);\n    uint _56 = uint(sparseTexelsResidentARB(int(_50._m4))) + uint(sparseTexelsResidentARB(int(_33._m4)));\n    SV_Target.x = int((_50._m0 + _33._m0) + _56);\n    SV_Target.y = int((_50._m1 + _33._m1) + _56);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 68\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"TEXCOORD\"\nOpName %17 \"SV_Target\"\nOpName %22 \"SparseTexel\"\nOpName %32 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonWritable\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %17 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32i\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeInt 32 0\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypeVector %5 2\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%21 = OpTypeVector %5 4\n%22 = OpTypeStruct %12 %21\n%26 = OpTypeVector %12 4\n%32 = OpTypeStruct %12 %12 %12 %12 %12\n%37 = OpTypeBool\n%39 = OpConstant %12 0\n%40 = OpConstant %12 1\n%61 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %66\n%66 = OpLabel\n%18 = OpLoad %9 %11\n%19 = OpLoad %6 %8\n%20 = OpLoad %12 %14\n%23 = OpImageSparseFetch %22 %19 %20\n%24 = OpCompositeExtract %12 %23 0\n%25 = OpCompositeExtract %21 %23 1\n%27 = OpBitcast %26 %25\n%28 = OpCompositeExtract %12 %27 0\n%29 = OpCompositeExtract %12 %27 1\n%30 = OpCompositeExtract %12 %27 2\n%31 = OpCompositeExtract %12 %27 3\n%33 = OpCompositeConstruct %32 %28 %29 %30 %31 %24\n%34 = OpCompositeExtract %12 %33 0\n%35 = OpCompositeExtract %12 %33 1\n%36 = OpCompositeExtract %12 %33 4\n%38 = OpImageSparseTexelsResident %37 %36\n%41 = OpSelect %12 %38 %40 %39\n%42 = OpImageSparseRead %22 %18 %20\n%43 = OpCompositeExtract %12 %42 0\n%44 = OpCompositeExtract %21 %42 1\n%45 = OpBitcast %26 %44\n%46 = OpCompositeExtract %12 %45 0\n%47 = OpCompositeExtract %12 %45 1\n%48 = OpCompositeExtract %12 %45 2\n%49 = OpCompositeExtract %12 %45 3\n%50 = OpCompositeConstruct %32 %46 %47 %48 %49 %43\n%51 = OpCompositeExtract %12 %50 0\n%52 = OpCompositeExtract %12 %50 1\n%53 = OpCompositeExtract %12 %50 4\n%54 = OpImageSparseTexelsResident %37 %53\n%55 = OpSelect %12 %54 %40 %39\n%56 = OpIAdd %12 %55 %41\n%57 = OpIAdd %12 %51 %34\n%58 = OpIAdd %12 %57 %56\n%59 = OpIAdd %12 %52 %35\n%60 = OpIAdd %12 %59 %56\n%62 = OpAccessChain %61 %17 %39\n%63 = OpBitcast %5 %58\nOpStore %62 %63\n%64 = OpAccessChain %61 %17 %40\n%65 = OpBitcast %5 %60\nOpStore %64 %65\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-load-signed.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0) uniform isamplerBuffer _8;\nlayout(set = 0, binding = 0, r32i) uniform readonly iimageBuffer _11;\n\nlayout(location = 0) flat in uint TEXCOORD;\nlayout(location = 0) out ivec2 SV_Target;\n\nvoid main()\n{\n    uvec4 _24 = uvec4(texelFetch(_8, int(TEXCOORD)));\n    uvec4 _28 = uvec4(imageLoad(_11, int(TEXCOORD)));\n    SV_Target.x = int(_28.x + _24.x);\n    SV_Target.y = int(_28.y + _24.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"TEXCOORD\"\nOpName %17 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonWritable\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %17 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32i\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeInt 32 0\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypeVector %5 2\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%21 = OpTypeVector %5 4\n%23 = OpTypeVector %12 4\n%33 = OpTypePointer Output %5\n%35 = OpConstant %12 0\n%38 = OpConstant %12 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%18 = OpLoad %9 %11\n%19 = OpLoad %6 %8\n%20 = OpLoad %12 %14\n%22 = OpImageFetch %21 %19 %20\n%24 = OpBitcast %23 %22\n%25 = OpCompositeExtract %12 %24 0\n%26 = OpCompositeExtract %12 %24 1\n%27 = OpImageRead %21 %18 %20\n%28 = OpBitcast %23 %27\n%29 = OpCompositeExtract %12 %28 0\n%30 = OpCompositeExtract %12 %28 1\n%31 = OpIAdd %12 %29 %25\n%32 = OpIAdd %12 %30 %26\n%34 = OpAccessChain %33 %17 %35\n%36 = OpBitcast %5 %31\nOpStore %34 %36\n%37 = OpAccessChain %33 %17 %38\n%39 = OpBitcast %5 %32\nOpStore %37 %39\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-load.frag",
    "content": "#version 460\n\nuint _104;\nuint _121;\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _12;\nlayout(set = 0, binding = 2) uniform usamplerBuffer _13;\nlayout(set = 0, binding = 3) uniform usamplerBuffer _14;\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _17;\nlayout(set = 0, binding = 1, r32ui) uniform readonly uimageBuffer _20;\nlayout(set = 0, binding = 2, r32ui) uniform readonly uimageBuffer _21;\nlayout(set = 0, binding = 3, r32ui) uniform readonly uimageBuffer _22;\n\nlayout(location = 0) flat in uint TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _38 = texelFetch(_8, int(TEXCOORD));\n    vec4 _41 = imageLoad(_17, int(TEXCOORD));\n    uint _48 = TEXCOORD * 2u;\n    uvec2 _58 = uvec2(texelFetch(_12, int(_48)).x, texelFetch(_12, int(_48 + 1u)).x);\n    uint _65 = TEXCOORD * 2u;\n    uvec2 _71 = uvec2(imageLoad(_20, int(_65)).x, imageLoad(_20, int(_65 + 1u)).x);\n    uint _78 = TEXCOORD * 2u;\n    vec2 _85 = uintBitsToFloat(uvec2(texelFetch(_13, int(_78)).x, texelFetch(_13, int(_78 + 1u)).x));\n    uint _90 = TEXCOORD * 2u;\n    vec2 _97 = uintBitsToFloat(uvec2(imageLoad(_21, int(_90)).x, imageLoad(_21, int(_90 + 1u)).x));\n    uint _102 = TEXCOORD * 6u;\n    vec3 _114 = uintBitsToFloat(uvec3(_104, texelFetch(_14, int(_102 + 1u)).x, texelFetch(_14, int(_102 + 2u)).x));\n    uint _120 = (TEXCOORD * 6u) + 3u;\n    vec3 _129 = uintBitsToFloat(uvec3(_121, imageLoad(_22, int(_120 + 1u)).x, imageLoad(_22, int(_120 + 2u)).x));\n    SV_Target.x = ((((((_41.x + _38.x) + uintBitsToFloat(_58.x)) + uintBitsToFloat(_71.x)) + _85.x) + _97.x) + _114.y) + _129.y;\n    SV_Target.y = ((((((_41.y + _38.y) + uintBitsToFloat(_58.y)) + uintBitsToFloat(_71.y)) + _85.y) + _97.y) + _114.z) + _129.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 140\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %24 \"TEXCOORD\"\nOpName %27 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 2\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 NonWritable\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %20 NonWritable\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 2\nOpDecorate %21 NonWritable\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 3\nOpDecorate %22 NonWritable\nOpDecorate %24 Flat\nOpDecorate %24 Location 0\nOpDecorate %27 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpVariable %11 UniformConstant\n%14 = OpVariable %11 UniformConstant\n%15 = OpTypeImage %5 Buffer 0 0 0 2 R32f\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %9 Buffer 0 0 0 2 R32ui\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpVariable %19 UniformConstant\n%22 = OpVariable %19 UniformConstant\n%23 = OpTypePointer Input %9\n%24 = OpVariable %23 Input\n%25 = OpTypeVector %5 2\n%26 = OpTypePointer Output %25\n%27 = OpVariable %26 Output\n%37 = OpTypeVector %5 4\n%47 = OpConstant %9 3\n%49 = OpConstant %9 2\n%50 = OpTypeVector %9 4\n%55 = OpConstant %9 1\n%57 = OpTypeVector %9 2\n%103 = OpConstant %9 6\n%111 = OpTypeVector %9 3\n%113 = OpTypeVector %5 3\n%134 = OpTypePointer Output %5\n%136 = OpConstant %9 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%104 = OpUndef %9\n%121 = OpUndef %9\nOpBranch %138\n%138 = OpLabel\n%28 = OpLoad %18 %22\n%29 = OpLoad %18 %21\n%30 = OpLoad %18 %20\n%31 = OpLoad %15 %17\n%32 = OpLoad %10 %14\n%33 = OpLoad %10 %13\n%34 = OpLoad %10 %12\n%35 = OpLoad %6 %8\n%36 = OpLoad %9 %24\n%38 = OpImageFetch %37 %35 %36\n%39 = OpCompositeExtract %5 %38 0\n%40 = OpCompositeExtract %5 %38 1\n%41 = OpImageRead %37 %31 %36\n%42 = OpCompositeExtract %5 %41 0\n%43 = OpCompositeExtract %5 %41 1\n%44 = OpFAdd %5 %42 %39\n%45 = OpFAdd %5 %43 %40\n%46 = OpShiftLeftLogical %9 %36 %47\n%48 = OpIMul %9 %36 %49\n%51 = OpImageFetch %50 %34 %48\n%52 = OpCompositeExtract %9 %51 0\n%54 = OpIAdd %9 %48 %55\n%53 = OpImageFetch %50 %34 %54\n%56 = OpCompositeExtract %9 %53 0\n%58 = OpCompositeConstruct %57 %52 %56\n%59 = OpCompositeExtract %9 %58 0\n%60 = OpCompositeExtract %9 %58 1\n%61 = OpBitcast %5 %59\n%62 = OpBitcast %5 %60\n%63 = OpFAdd %5 %44 %61\n%64 = OpFAdd %5 %45 %62\n%65 = OpIMul %9 %36 %49\n%66 = OpImageRead %50 %30 %65\n%67 = OpCompositeExtract %9 %66 0\n%69 = OpIAdd %9 %65 %55\n%68 = OpImageRead %50 %30 %69\n%70 = OpCompositeExtract %9 %68 0\n%71 = OpCompositeConstruct %57 %67 %70\n%72 = OpCompositeExtract %9 %71 0\n%73 = OpCompositeExtract %9 %71 1\n%74 = OpBitcast %5 %72\n%75 = OpBitcast %5 %73\n%76 = OpFAdd %5 %63 %74\n%77 = OpFAdd %5 %64 %75\n%78 = OpIMul %9 %36 %49\n%79 = OpImageFetch %50 %33 %78\n%80 = OpCompositeExtract %9 %79 0\n%82 = OpIAdd %9 %78 %55\n%81 = OpImageFetch %50 %33 %82\n%83 = OpCompositeExtract %9 %81 0\n%84 = OpCompositeConstruct %57 %80 %83\n%85 = OpBitcast %25 %84\n%86 = OpCompositeExtract %5 %85 0\n%87 = OpCompositeExtract %5 %85 1\n%88 = OpFAdd %5 %76 %86\n%89 = OpFAdd %5 %77 %87\n%90 = OpIMul %9 %36 %49\n%91 = OpImageRead %50 %29 %90\n%92 = OpCompositeExtract %9 %91 0\n%94 = OpIAdd %9 %90 %55\n%93 = OpImageRead %50 %29 %94\n%95 = OpCompositeExtract %9 %93 0\n%96 = OpCompositeConstruct %57 %92 %95\n%97 = OpBitcast %25 %96\n%98 = OpCompositeExtract %5 %97 0\n%99 = OpCompositeExtract %5 %97 1\n%100 = OpFAdd %5 %88 %98\n%101 = OpFAdd %5 %89 %99\n%102 = OpIMul %9 %36 %103\n%106 = OpIAdd %9 %102 %55\n%105 = OpImageFetch %50 %32 %106\n%107 = OpCompositeExtract %9 %105 0\n%109 = OpIAdd %9 %102 %49\n%108 = OpImageFetch %50 %32 %109\n%110 = OpCompositeExtract %9 %108 0\n%112 = OpCompositeConstruct %111 %104 %107 %110\n%114 = OpBitcast %113 %112\n%115 = OpCompositeExtract %5 %114 1\n%116 = OpCompositeExtract %5 %114 2\n%117 = OpFAdd %5 %100 %115\n%118 = OpFAdd %5 %101 %116\n%119 = OpIMul %9 %36 %103\n%120 = OpIAdd %9 %119 %47\n%123 = OpIAdd %9 %120 %55\n%122 = OpImageRead %50 %28 %123\n%124 = OpCompositeExtract %9 %122 0\n%126 = OpIAdd %9 %120 %49\n%125 = OpImageRead %50 %28 %126\n%127 = OpCompositeExtract %9 %125 0\n%128 = OpCompositeConstruct %111 %121 %124 %127\n%129 = OpBitcast %113 %128\n%130 = OpCompositeExtract %5 %129 1\n%131 = OpCompositeExtract %5 %129 2\n%132 = OpFAdd %5 %117 %130\n%133 = OpFAdd %5 %118 %131\n%135 = OpAccessChain %134 %27 %136\nOpStore %135 %132\n%137 = OpAccessChain %134 %27 %55\nOpStore %137 %133\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-load.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, std430) restrict readonly buffer _16_18\n{\n    uvec2 _m0[];\n} _18;\n\nlayout(set = 0, binding = 3, scalar) restrict readonly buffer _21_23\n{\n    uvec3 _m0[];\n} _23;\n\nlayout(set = 0, binding = 1, std430) readonly buffer _28_30\n{\n    uvec2 _m0[];\n} _30;\n\nlayout(set = 0, binding = 2, std430) readonly buffer _32_34\n{\n    uvec2 _m0[];\n} _34;\n\nlayout(set = 0, binding = 3, scalar) readonly buffer _36_38\n{\n    uvec3 _m0[];\n} _38;\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _8;\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _26;\n\nlayout(location = 0) flat in uint TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _48 = texelFetch(_8, int(TEXCOORD));\n    vec4 _51 = imageLoad(_26, int(TEXCOORD));\n    vec2 _78 = uintBitsToFloat(_18._m0[TEXCOORD]);\n    vec2 _85 = uintBitsToFloat(_34._m0[TEXCOORD]);\n    vec3 _96 = uintBitsToFloat(_23._m0[TEXCOORD * 2u]);\n    vec3 _106 = uintBitsToFloat(_38._m0[(TEXCOORD * 2u) + 1u]);\n    SV_Target.x = ((((((_51.x + _48.x) + uintBitsToFloat(_14._m0[TEXCOORD].x)) + uintBitsToFloat(_30._m0[TEXCOORD].x)) + _78.x) + _85.x) + _96.y) + _106.y;\n    SV_Target.y = ((((((_51.y + _48.y) + uintBitsToFloat(_14._m0[TEXCOORD].y)) + uintBitsToFloat(_30._m0[TEXCOORD].y)) + _78.y) + _85.y) + _96.z) + _106.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 116\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %40 %43\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %28 \"SSBO\"\nOpName %32 \"SSBO\"\nOpName %36 \"SSBO\"\nOpName %40 \"TEXCOORD\"\nOpName %43 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 8\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 2\nOpDecorate %18 NonWritable\nOpDecorate %18 Restrict\nOpDecorate %20 ArrayStride 12\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 3\nOpDecorate %23 NonWritable\nOpDecorate %23 Restrict\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %26 NonWritable\nOpDecorate %27 ArrayStride 8\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 1\nOpDecorate %30 NonWritable\nOpDecorate %31 ArrayStride 8\nOpMemberDecorate %32 0 Offset 0\nOpDecorate %32 Block\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 2\nOpDecorate %34 NonWritable\nOpDecorate %35 ArrayStride 12\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 3\nOpDecorate %38 NonWritable\nOpDecorate %40 Flat\nOpDecorate %40 Location 0\nOpDecorate %43 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeVector %9 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeVector %9 3\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeImage %5 Buffer 0 0 0 2 R32f\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeRuntimeArray %10\n%28 = OpTypeStruct %27\n%29 = OpTypePointer StorageBuffer %28\n%30 = OpVariable %29 StorageBuffer\n%31 = OpTypeRuntimeArray %10\n%32 = OpTypeStruct %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeRuntimeArray %19\n%36 = OpTypeStruct %35\n%37 = OpTypePointer StorageBuffer %36\n%38 = OpVariable %37 StorageBuffer\n%39 = OpTypePointer Input %9\n%40 = OpVariable %39 Input\n%41 = OpTypeVector %5 2\n%42 = OpTypePointer Output %41\n%43 = OpVariable %42 Output\n%47 = OpTypeVector %5 4\n%57 = OpConstant %9 3\n%58 = OpTypePointer StorageBuffer %10\n%60 = OpConstant %9 0\n%91 = OpConstant %9 2\n%92 = OpTypePointer StorageBuffer %19\n%95 = OpTypeVector %5 3\n%102 = OpConstant %9 1\n%111 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%44 = OpLoad %24 %26\n%45 = OpLoad %6 %8\n%46 = OpLoad %9 %40\n%48 = OpImageFetch %47 %45 %46\n%49 = OpCompositeExtract %5 %48 0\n%50 = OpCompositeExtract %5 %48 1\n%51 = OpImageRead %47 %44 %46\n%52 = OpCompositeExtract %5 %51 0\n%53 = OpCompositeExtract %5 %51 1\n%54 = OpFAdd %5 %52 %49\n%55 = OpFAdd %5 %53 %50\n%56 = OpShiftLeftLogical %9 %46 %57\n%59 = OpAccessChain %58 %14 %60 %46\n%61 = OpLoad %10 %59\n%62 = OpCompositeExtract %9 %61 0\n%63 = OpCompositeExtract %9 %61 1\n%64 = OpBitcast %5 %62\n%65 = OpBitcast %5 %63\n%66 = OpFAdd %5 %54 %64\n%67 = OpFAdd %5 %55 %65\n%68 = OpAccessChain %58 %30 %60 %46\n%69 = OpLoad %10 %68\n%70 = OpCompositeExtract %9 %69 0\n%71 = OpCompositeExtract %9 %69 1\n%72 = OpBitcast %5 %70\n%73 = OpBitcast %5 %71\n%74 = OpFAdd %5 %66 %72\n%75 = OpFAdd %5 %67 %73\n%76 = OpAccessChain %58 %18 %60 %46\n%77 = OpLoad %10 %76\n%78 = OpBitcast %41 %77\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpCompositeExtract %5 %78 1\n%81 = OpFAdd %5 %74 %79\n%82 = OpFAdd %5 %75 %80\n%83 = OpAccessChain %58 %34 %60 %46\n%84 = OpLoad %10 %83\n%85 = OpBitcast %41 %84\n%86 = OpCompositeExtract %5 %85 0\n%87 = OpCompositeExtract %5 %85 1\n%88 = OpFAdd %5 %81 %86\n%89 = OpFAdd %5 %82 %87\n%90 = OpIMul %9 %46 %91\n%93 = OpAccessChain %92 %23 %60 %90\n%94 = OpLoad %19 %93\n%96 = OpBitcast %95 %94\n%97 = OpCompositeExtract %5 %96 1\n%98 = OpCompositeExtract %5 %96 2\n%99 = OpFAdd %5 %88 %97\n%100 = OpFAdd %5 %89 %98\n%101 = OpIMul %9 %46 %91\n%103 = OpIAdd %9 %101 %102\n%104 = OpAccessChain %92 %38 %60 %103\n%105 = OpLoad %19 %104\n%106 = OpBitcast %95 %105\n%107 = OpCompositeExtract %5 %106 1\n%108 = OpCompositeExtract %5 %106 2\n%109 = OpFAdd %5 %99 %107\n%110 = OpFAdd %5 %100 %108\n%112 = OpAccessChain %111 %43 %60\nOpStore %112 %109\n%113 = OpAccessChain %111 %43 %102\nOpStore %113 %110\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-store-signed.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly iimageBuffer _8;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in ivec2 DATA;\n\nvoid main()\n{\n    uint _20 = uint(DATA.x);\n    imageStore(_8, int(INDEX), ivec4(uvec4(_20, uint(DATA.y), _20, _20)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %14\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %14 \"DATA\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %14 Component 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypeVector %5 2\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%16 = OpTypePointer Input %5\n%18 = OpConstant %9 0\n%22 = OpConstant %9 1\n%26 = OpTypeVector %9 4\n%28 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%15 = OpLoad %6 %8\n%17 = OpAccessChain %16 %14 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %9 %19\n%21 = OpAccessChain %16 %14 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %9 %23\n%25 = OpLoad %9 %11\n%27 = OpCompositeConstruct %26 %20 %24 %20 %20\n%29 = OpBitcast %28 %27\nOpImageWrite %15 %25 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-store.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _12;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _13;\nlayout(set = 0, binding = 3, r32ui) uniform writeonly uimageBuffer _14;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in vec2 DATA;\n\nvoid main()\n{\n    imageStore(_8, int(INDEX), vec4(DATA.x, DATA.y, DATA.x, DATA.x));\n    uint _38 = INDEX * 2u;\n    imageStore(_12, int(_38), uvec4(floatBitsToUint(DATA.x)));\n    imageStore(_12, int(_38 + 1u), uvec4(floatBitsToUint(DATA.y)));\n    uint _44 = INDEX * 2u;\n    imageStore(_13, int(_44), uvec4(floatBitsToUint(DATA.x)));\n    imageStore(_13, int(_44 + 1u), uvec4(floatBitsToUint(DATA.y)));\n    uint _52 = (INDEX * 5u) + 3u;\n    imageStore(_14, int(_52), uvec4(floatBitsToUint(DATA.x)));\n    imageStore(_14, int(_52 + 1u), uvec4(floatBitsToUint(DATA.y)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"INDEX\"\nOpName %19 \"DATA\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %12 NonReadable\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 2\nOpDecorate %13 NonReadable\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %14 NonReadable\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %19 Component 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeImage %9 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpVariable %11 UniformConstant\n%14 = OpVariable %11 UniformConstant\n%15 = OpTypePointer Input %9\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 2\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%24 = OpTypePointer Input %5\n%26 = OpConstant %9 0\n%29 = OpConstant %9 1\n%32 = OpTypeVector %5 4\n%37 = OpConstant %9 3\n%39 = OpConstant %9 2\n%40 = OpTypeVector %9 4\n%51 = OpConstant %9 5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %58\n%58 = OpLabel\n%20 = OpLoad %10 %14\n%21 = OpLoad %10 %13\n%22 = OpLoad %10 %12\n%23 = OpLoad %6 %8\n%25 = OpAccessChain %24 %19 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %24 %19 %29\n%30 = OpLoad %5 %28\n%31 = OpLoad %9 %16\n%33 = OpCompositeConstruct %32 %27 %30 %27 %27\nOpImageWrite %23 %31 %33\n%34 = OpBitcast %9 %27\n%35 = OpBitcast %9 %30\n%36 = OpShiftLeftLogical %9 %31 %37\n%38 = OpIMul %9 %31 %39\n%41 = OpCompositeConstruct %40 %34 %34 %34 %34\nOpImageWrite %22 %38 %41\n%42 = OpCompositeConstruct %40 %35 %35 %35 %35\n%43 = OpIAdd %9 %38 %29\nOpImageWrite %22 %43 %42\n%44 = OpIMul %9 %31 %39\n%45 = OpBitcast %9 %27\n%46 = OpBitcast %9 %30\n%47 = OpCompositeConstruct %40 %45 %45 %45 %45\nOpImageWrite %21 %44 %47\n%48 = OpCompositeConstruct %40 %46 %46 %46 %46\n%49 = OpIAdd %9 %44 %29\nOpImageWrite %21 %49 %48\n%50 = OpIMul %9 %31 %51\n%52 = OpIAdd %9 %50 %37\n%53 = OpBitcast %9 %27\n%54 = OpBitcast %9 %30\n%55 = OpCompositeConstruct %40 %53 %53 %53 %53\nOpImageWrite %20 %52 %55\n%56 = OpCompositeConstruct %40 %54 %54 %54 %54\n%57 = OpIAdd %9 %52 %29\nOpImageWrite %20 %57 %56\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-store.ssbo.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 1, std430) writeonly buffer SSBO\n{\n    uvec2 _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _16_18\n{\n    uvec2 _m0[];\n} _18;\n\nlayout(set = 0, binding = 3, std430) writeonly buffer _20_22\n{\n    uint _m0[];\n} _22;\n\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _8;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in vec2 DATA;\n\nvoid main()\n{\n    imageStore(_8, int(INDEX), vec4(DATA.x, DATA.y, DATA.x, DATA.x));\n    _14._m0[INDEX] = uvec2(floatBitsToUint(DATA.x), floatBitsToUint(DATA.y));\n    _18._m0[INDEX] = uvec2(floatBitsToUint(DATA.x), floatBitsToUint(DATA.y));\n    uint _52 = (INDEX * 5u) + 3u;\n    _22._m0[_52] = floatBitsToUint(DATA.x);\n    _22._m0[_52 + 1u] = floatBitsToUint(DATA.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %20 \"SSBO\"\nOpName %24 \"INDEX\"\nOpName %27 \"DATA\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %15 ArrayStride 8\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 2\nOpDecorate %18 NonReadable\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 3\nOpDecorate %22 NonReadable\nOpDecorate %24 Flat\nOpDecorate %24 Location 0\nOpDecorate %27 Flat\nOpDecorate %27 Location 0\nOpDecorate %27 Component 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeVector %9 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %9\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypePointer Input %9\n%24 = OpVariable %23 Input\n%25 = OpTypeVector %5 2\n%26 = OpTypePointer Input %25\n%27 = OpVariable %26 Input\n%29 = OpTypePointer Input %5\n%31 = OpConstant %9 0\n%34 = OpConstant %9 1\n%37 = OpTypeVector %5 4\n%42 = OpConstant %9 3\n%44 = OpTypePointer StorageBuffer %10\n%51 = OpConstant %9 5\n%55 = OpTypePointer StorageBuffer %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%28 = OpLoad %6 %8\n%30 = OpAccessChain %29 %27 %31\n%32 = OpLoad %5 %30\n%33 = OpAccessChain %29 %27 %34\n%35 = OpLoad %5 %33\n%36 = OpLoad %9 %24\n%38 = OpCompositeConstruct %37 %32 %35 %32 %32\nOpImageWrite %28 %36 %38\n%39 = OpBitcast %9 %32\n%40 = OpBitcast %9 %35\n%41 = OpShiftLeftLogical %9 %36 %42\n%43 = OpCompositeConstruct %10 %39 %40\n%45 = OpAccessChain %44 %14 %31 %36\nOpStore %45 %43\n%46 = OpBitcast %9 %32\n%47 = OpBitcast %9 %35\n%48 = OpCompositeConstruct %10 %46 %47\n%49 = OpAccessChain %44 %18 %31 %36\nOpStore %49 %48\n%50 = OpIMul %9 %36 %51\n%52 = OpIAdd %9 %50 %42\n%53 = OpBitcast %9 %32\n%54 = OpBitcast %9 %35\n%56 = OpAccessChain %55 %22 %31 %52\nOpStore %56 %53\n%58 = OpIAdd %9 %52 %34\n%57 = OpAccessChain %55 %22 %31 %58\nOpStore %57 %54\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/buffer-update-counter.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _8;\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _9;\nlayout(set = 0, binding = 1, r32ui) uniform readonly writeonly uimageBuffer _10;\nlayout(set = 7, binding = 1, r32ui) uniform uimageBuffer _11;\n\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _19 = imageAtomicAdd(_9, int(0u), 1u);\n    uint _22 = imageAtomicAdd(_11, int(0u), 4294967295u);\n    SV_Target = (_22 - 1u) + _19;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 7\nOpDecorate %9 Binding 0\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 1\nOpDecorate %10 NonReadable\nOpDecorate %10 NonWritable\nOpDecorate %11 DescriptorSet 7\nOpDecorate %11 Binding 1\nOpDecorate %13 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpVariable %7 UniformConstant\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%16 = OpTypePointer Image %5\n%18 = OpConstant %5 0\n%20 = OpConstant %5 1\n%23 = OpConstant %5 4294967295\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%14 = OpLoad %6 %10\n%15 = OpLoad %6 %8\n%17 = OpImageTexelPointer %16 %9 %18 %18\n%19 = OpAtomicIAdd %5 %17 %20 %18 %20\n%21 = OpImageTexelPointer %16 %11 %18 %18\n%22 = OpAtomicIAdd %5 %21 %20 %18 %23\n%24 = OpISub %5 %22 %20\n%25 = OpIAdd %5 %24 %19\nOpStore %13 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/calculate-lod.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0) uniform texture1D _8;\nlayout(set = 0, binding = 1) uniform texture1DArray _11;\nlayout(set = 0, binding = 2) uniform texture2D _14;\nlayout(set = 0, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 5) uniform textureCube _23;\nlayout(set = 0, binding = 6) uniform textureCubeArray _26;\nlayout(set = 0, binding = 0) uniform sampler _29;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = (((((textureQueryLod(sampler1DArray(_11, _29), TEXCOORD.x).x + textureQueryLod(sampler1D(_8, _29), TEXCOORD.x).x) + textureQueryLod(sampler2D(_14, _29), vec2(TEXCOORD.x, TEXCOORD.y)).x) + textureQueryLod(sampler2DArray(_17, _29), vec2(TEXCOORD.x, TEXCOORD.y)).x) + textureQueryLod(sampler3D(_20, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x) + textureQueryLod(samplerCube(_23, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x) + textureQueryLod(samplerCubeArray(_26, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x;\n    SV_Target.y = (((((textureQueryLod(sampler1DArray(_11, _29), TEXCOORD.x).y + textureQueryLod(sampler1D(_8, _29), TEXCOORD.x).y) + textureQueryLod(sampler2D(_14, _29), vec2(TEXCOORD.x, TEXCOORD.y)).y) + textureQueryLod(sampler2DArray(_17, _29), vec2(TEXCOORD.x, TEXCOORD.y)).y) + textureQueryLod(sampler3D(_20, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).y) + textureQueryLod(samplerCube(_23, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).y) + textureQueryLod(samplerCubeArray(_26, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 124\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpCapability ImageQuery\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeSampler\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeVector %5 3\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%44 = OpTypePointer Input %5\n%46 = OpTypeInt 32 0\n%47 = OpConstant %46 0\n%50 = OpConstant %46 1\n%53 = OpConstant %46 2\n%55 = OpTypeSampledImage %6\n%59 = OpTypeSampledImage %9\n%64 = OpTypeSampledImage %12\n%70 = OpTypeSampledImage %15\n%76 = OpTypeSampledImage %18\n%82 = OpTypeSampledImage %21\n%88 = OpTypeSampledImage %24\n%119 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %122\n%122 = OpLabel\n%36 = OpLoad %24 %26\n%37 = OpLoad %21 %23\n%38 = OpLoad %18 %20\n%39 = OpLoad %15 %17\n%40 = OpLoad %12 %14\n%41 = OpLoad %9 %11\n%42 = OpLoad %6 %8\n%43 = OpLoad %27 %29\n%45 = OpAccessChain %44 %32 %47\n%48 = OpLoad %5 %45\n%49 = OpAccessChain %44 %32 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %44 %32 %53\n%54 = OpLoad %5 %52\n%56 = OpSampledImage %55 %42 %43\n%57 = OpImageQueryLod %33 %56 %48\n%58 = OpCompositeExtract %5 %57 0\n%60 = OpSampledImage %59 %41 %43\n%61 = OpImageQueryLod %33 %60 %48\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpFAdd %5 %62 %58\n%65 = OpSampledImage %64 %40 %43\n%67 = OpCompositeConstruct %33 %48 %51\n%66 = OpImageQueryLod %33 %65 %67\n%68 = OpCompositeExtract %5 %66 0\n%69 = OpFAdd %5 %63 %68\n%71 = OpSampledImage %70 %39 %43\n%73 = OpCompositeConstruct %33 %48 %51\n%72 = OpImageQueryLod %33 %71 %73\n%74 = OpCompositeExtract %5 %72 0\n%75 = OpFAdd %5 %69 %74\n%77 = OpSampledImage %76 %38 %43\n%79 = OpCompositeConstruct %30 %48 %51 %54\n%78 = OpImageQueryLod %33 %77 %79\n%80 = OpCompositeExtract %5 %78 0\n%81 = OpFAdd %5 %75 %80\n%83 = OpSampledImage %82 %37 %43\n%85 = OpCompositeConstruct %30 %48 %51 %54\n%84 = OpImageQueryLod %33 %83 %85\n%86 = OpCompositeExtract %5 %84 0\n%87 = OpFAdd %5 %81 %86\n%89 = OpSampledImage %88 %36 %43\n%91 = OpCompositeConstruct %30 %48 %51 %54\n%90 = OpImageQueryLod %33 %89 %91\n%92 = OpCompositeExtract %5 %90 0\n%93 = OpFAdd %5 %87 %92\n%94 = OpImageQueryLod %33 %56 %48\n%95 = OpCompositeExtract %5 %94 1\n%96 = OpImageQueryLod %33 %60 %48\n%97 = OpCompositeExtract %5 %96 1\n%98 = OpFAdd %5 %97 %95\n%100 = OpCompositeConstruct %33 %48 %51\n%99 = OpImageQueryLod %33 %65 %100\n%101 = OpCompositeExtract %5 %99 1\n%102 = OpFAdd %5 %98 %101\n%104 = OpCompositeConstruct %33 %48 %51\n%103 = OpImageQueryLod %33 %71 %104\n%105 = OpCompositeExtract %5 %103 1\n%106 = OpFAdd %5 %102 %105\n%108 = OpCompositeConstruct %30 %48 %51 %54\n%107 = OpImageQueryLod %33 %77 %108\n%109 = OpCompositeExtract %5 %107 1\n%110 = OpFAdd %5 %106 %109\n%112 = OpCompositeConstruct %30 %48 %51 %54\n%111 = OpImageQueryLod %33 %83 %112\n%113 = OpCompositeExtract %5 %111 1\n%114 = OpFAdd %5 %110 %113\n%116 = OpCompositeConstruct %30 %48 %51 %54\n%115 = OpImageQueryLod %33 %89 %116\n%117 = OpCompositeExtract %5 %115 1\n%118 = OpFAdd %5 %114 %117\n%120 = OpAccessChain %119 %35 %47\nOpStore %120 %93\n%121 = OpAccessChain %119 %35 %50\nOpStore %121 %118\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/call-shader.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _10\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0) uniform writeonly image2D IMG;\nlayout(location = 0) callableDataEXT _10 _12;\nlayout(location = 1) callableDataEXT _10 _13;\nlayout(location = 2) callableDataEXT _10 _14;\nlayout(location = 3) callableDataEXT _10 _15;\n\nvoid main()\n{\n    executeCallableEXT(0u, 3);\n    executeCallableEXT(1u, 2);\n    executeCallableEXT(2u, 1);\n    executeCallableEXT(3u, 0);\n    imageStore(IMG, ivec2(uvec2(gl_LaunchIDEXT.x, gl_LaunchIDEXT.y)), vec4(((_14._m0.x + _15._m0.x) + _13._m0.x) + _12._m0.x, ((_14._m0.y + _15._m0.y) + _13._m0.y) + _12._m0.y, ((_14._m0.z + _15._m0.z) + _13._m0.z) + _12._m0.z, ((_14._m0.w + _15._m0.w) + _13._m0.w) + _12._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %13 %14 %15 %60\nOpName %3 \"main\"\nOpName %8 \"IMG\"\nOpName %10 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %60 BuiltIn LaunchIdKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypeStruct %9\n%11 = OpTypePointer CallableDataKHR %10\n%12 = OpVariable %11 CallableDataKHR\n%13 = OpVariable %11 CallableDataKHR\n%14 = OpVariable %11 CallableDataKHR\n%15 = OpVariable %11 CallableDataKHR\n%16 = OpTypeInt 32 0\n%17 = OpConstant %16 0\n%18 = OpTypePointer CallableDataKHR %9\n%25 = OpConstant %16 1\n%32 = OpConstant %16 2\n%39 = OpConstant %16 3\n%58 = OpTypeVector %16 3\n%59 = OpTypePointer Input %58\n%60 = OpVariable %59 Input\n%61 = OpTypePointer Input %16\n%67 = OpTypeVector %16 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %70\n%70 = OpLabel\nOpExecuteCallableKHR %17 %15\n%19 = OpInBoundsAccessChain %18 %15 %17\n%20 = OpLoad %9 %19\n%21 = OpCompositeExtract %5 %20 0\n%22 = OpCompositeExtract %5 %20 1\n%23 = OpCompositeExtract %5 %20 2\n%24 = OpCompositeExtract %5 %20 3\nOpExecuteCallableKHR %25 %14\n%26 = OpInBoundsAccessChain %18 %14 %17\n%27 = OpLoad %9 %26\n%28 = OpCompositeExtract %5 %27 0\n%29 = OpCompositeExtract %5 %27 1\n%30 = OpCompositeExtract %5 %27 2\n%31 = OpCompositeExtract %5 %27 3\nOpExecuteCallableKHR %32 %13\n%33 = OpInBoundsAccessChain %18 %13 %17\n%34 = OpLoad %9 %33\n%35 = OpCompositeExtract %5 %34 0\n%36 = OpCompositeExtract %5 %34 1\n%37 = OpCompositeExtract %5 %34 2\n%38 = OpCompositeExtract %5 %34 3\nOpExecuteCallableKHR %39 %12\n%40 = OpInBoundsAccessChain %18 %12 %17\n%41 = OpLoad %9 %40\n%42 = OpCompositeExtract %5 %41 0\n%43 = OpCompositeExtract %5 %41 1\n%44 = OpCompositeExtract %5 %41 2\n%45 = OpCompositeExtract %5 %41 3\n%46 = OpFAdd %5 %28 %21\n%47 = OpFAdd %5 %29 %22\n%48 = OpFAdd %5 %30 %23\n%49 = OpFAdd %5 %31 %24\n%50 = OpFAdd %5 %46 %35\n%51 = OpFAdd %5 %47 %36\n%52 = OpFAdd %5 %48 %37\n%53 = OpFAdd %5 %49 %38\n%54 = OpFAdd %5 %50 %42\n%55 = OpFAdd %5 %51 %43\n%56 = OpFAdd %5 %52 %44\n%57 = OpFAdd %5 %53 %45\n%62 = OpAccessChain %61 %60 %17\n%63 = OpLoad %16 %62\n%64 = OpAccessChain %61 %60 %25\n%65 = OpLoad %16 %64\n%66 = OpLoad %6 %8\n%68 = OpCompositeConstruct %67 %63 %65\n%69 = OpCompositeConstruct %9 %54 %55 %56 %57\nOpImageWrite %66 %68 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/clip.demote-to-helper.frag",
    "content": "#version 460\n#extension GL_EXT_demote_to_helper_invocation : require\n\nlayout(location = 0) in vec2 TEXCOORD;\n\nvoid demote_cond(bool _27)\n{\n    if (_27)\n    {\n        demote;\n    }\n}\n\nvoid main()\n{\n    demote_cond((TEXCOORD.x + (-10.0)) < 0.0);\n    demote_cond((TEXCOORD.y + (-20.0)) < 0.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability DemoteToHelperInvocation\nOpExtension \"SPV_EXT_demote_to_helper_invocation\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %28 \"demote_cond\"\nOpDecorate %8 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Input %5\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 0\n%15 = OpConstant %11 1\n%18 = OpConstant %5 -10\n%19 = OpTypeBool\n%21 = OpConstant %5 0\n%23 = OpConstant %5 -20\n%26 = OpTypeFunction %1 %19\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%10 = OpAccessChain %9 %8 %12\n%13 = OpLoad %5 %10\n%14 = OpAccessChain %9 %8 %15\n%16 = OpLoad %5 %14\n%17 = OpFAdd %5 %13 %18\n%20 = OpFOrdLessThan %19 %17 %21\n%33 = OpFunctionCall %1 %28 %20\n%22 = OpFAdd %5 %16 %23\n%24 = OpFOrdLessThan %19 %22 %21\n%34 = OpFunctionCall %1 %28 %24\nOpReturn\nOpFunctionEnd\n%28 = OpFunction %1 None %26\n%27 = OpFunctionParameter %19\n%29 = OpLabel\nOpSelectionMerge %31 None\nOpBranchConditional %27 %30 %31\n%30 = OpLabel\nOpDemoteToHelperInvocation\nOpBranch %31\n%31 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/clip.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec2 TEXCOORD;\nbool discard_state;\n\nvoid discard_cond(bool _30)\n{\n    if (_30)\n    {\n        discard_state = true;\n    }\n}\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    discard_cond((TEXCOORD.x + (-10.0)) < 0.0);\n    discard_cond((TEXCOORD.y + (-20.0)) < 0.0);\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %23 \"discard_state\"\nOpName %31 \"discard_cond\"\nOpName %39 \"discard_exit\"\nOpDecorate %8 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Input %5\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 0\n%15 = OpConstant %11 1\n%18 = OpConstant %5 -10\n%19 = OpTypeBool\n%21 = OpConstant %5 0\n%22 = OpTypePointer Private %19\n%23 = OpVariable %22 Private\n%24 = OpConstantFalse %19\n%26 = OpConstant %5 -20\n%29 = OpTypeFunction %1 %19\n%35 = OpConstantTrue %19\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %23 %24\nOpBranch %28\n%28 = OpLabel\n%10 = OpAccessChain %9 %8 %12\n%13 = OpLoad %5 %10\n%14 = OpAccessChain %9 %8 %15\n%16 = OpLoad %5 %14\n%17 = OpFAdd %5 %13 %18\n%20 = OpFOrdLessThan %19 %17 %21\n%37 = OpFunctionCall %1 %31 %20\n%25 = OpFAdd %5 %16 %26\n%27 = OpFOrdLessThan %19 %25 %21\n%38 = OpFunctionCall %1 %31 %27\n%45 = OpFunctionCall %1 %39\nOpReturn\nOpFunctionEnd\n%31 = OpFunction %1 None %29\n%30 = OpFunctionParameter %19\n%32 = OpLabel\nOpSelectionMerge %34 None\nOpBranchConditional %30 %33 %34\n%33 = OpLabel\nOpStore %23 %35\nOpBranch %34\n%34 = OpLabel\nOpReturn\nOpFunctionEnd\n%39 = OpFunction %1 None %2\n%40 = OpLabel\n%43 = OpLoad %19 %23\nOpSelectionMerge %42 None\nOpBranchConditional %43 %41 %42\n%41 = OpLabel\nOpKill\n%42 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/compute-shader-derivatives-cube-array.noderivs.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _13;\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _8;\nlayout(set = 0, binding = 0) uniform sampler _16;\n\nvoid main()\n{\n    float _24 = float(gl_GlobalInvocationID.x);\n    vec3 coord = vec3(_24 * 0.100000001490116119384765625, _24 * 0.20000000298023223876953125, _24 * 0.300000011920928955078125);\n    vec3 d_coord_dx = subgroupQuadSwapHorizontal(coord) - coord;\n    vec3 d_coord_dy = subgroupQuadSwapVertical(coord) - coord;\n    vec3 abs_uvw = abs(coord);\n    float _47 = abs_uvw.y;\n    float _49 = abs_uvw.z;\n    float max_component = max(_49, max(_47, abs_uvw.x));\n    bool z_major = _49 >= max_component;\n    bool y_major = _47 >= max_component;\n    vec3 d_str_dx = mix(mix(d_coord_dx.zyx, d_coord_dx.xzy, bvec3(y_major)), d_coord_dx, bvec3(z_major));\n    vec3 d_str_dy = mix(mix(d_coord_dy.zyx, d_coord_dy.xzy, bvec3(y_major)), d_coord_dy, bvec3(z_major));\n    vec4 cube_gradients = ((vec4(d_str_dx.x, d_str_dy.x, d_str_dx.y, d_str_dy.y) * max_component) - (mix(mix(coord.zyx, coord.xzy, bvec3(y_major)), coord, bvec3(z_major)).xxyy * vec4(d_str_dx.z, d_str_dy.z, d_str_dx.z, d_str_dy.z))) * (0.5 / (max_component * max_component));\n    vec2 _90 = vec2(textureSize(_8, 0).xy);\n    vec2 _91 = cube_gradients.xz * _90;\n    vec2 _92 = cube_gradients.yw * _90;\n    _13._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_13._m0[gl_GlobalInvocationID.x]) + max(min(log2(max(dot(_91, _91), dot(_92, _92))) * 0.5, float(textureQueryLevels(_8)) - (-1.0)), 0.0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 114\n; Schema: 0\nOpCapability Shader\nOpCapability SampledCubeArray\nOpCapability ImageQuery\nOpCapability GroupNonUniformQuad\n%44 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %19\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %11 \"SSBO\"\nOpName %34 \"coord\"\nOpName %40 \"d_coord_dx\"\nOpName %41 \"d_coord_dy\"\nOpName %45 \"abs_uvw\"\nOpName %50 \"max_component\"\nOpName %52 \"z_major\"\nOpName %53 \"y_major\"\nOpName %63 \"d_str_dx\"\nOpName %69 \"d_str_dy\"\nOpName %75 \"str\"\nOpName %82 \"cube_gradients\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeSampler\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeVector %9 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %9\n%22 = OpConstant %9 0\n%26 = OpConstant %5 0.100000001\n%28 = OpConstant %5 0.200000003\n%30 = OpConstant %5 0.300000012\n%33 = OpTypeVector %5 3\n%35 = OpTypeInt 32 1\n%37 = OpConstant %9 3\n%39 = OpConstant %9 1\n%42 = OpTypeVector %5 2\n%43 = OpTypeVector %5 4\n%51 = OpTypeBool\n%56 = OpConstant %5 0.5\n%59 = OpTypeVector %51 3\n%85 = OpTypeVector %35 3\n%87 = OpConstant %35 0\n%88 = OpTypeVector %35 2\n%101 = OpConstant %5 -1\n%104 = OpConstant %5 0\n%105 = OpTypePointer StorageBuffer %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %112\n%112 = OpLabel\n%21 = OpAccessChain %20 %19 %22\n%23 = OpLoad %9 %21\n%24 = OpConvertUToF %5 %23\n%25 = OpFMul %5 %24 %26\n%27 = OpFMul %5 %24 %28\n%29 = OpFMul %5 %24 %30\n%31 = OpLoad %6 %8\n%32 = OpLoad %14 %16\n%34 = OpCompositeConstruct %33 %25 %27 %29\n%36 = OpGroupNonUniformQuadSwap %33 %37 %34 %22\n%38 = OpGroupNonUniformQuadSwap %33 %37 %34 %39\n%40 = OpFSub %33 %36 %34\n%41 = OpFSub %33 %38 %34\n%45 = OpExtInst %33 %44 FAbs %34\n%46 = OpCompositeExtract %5 %45 0\n%47 = OpCompositeExtract %5 %45 1\n%48 = OpExtInst %5 %44 FMax %47 %46\n%49 = OpCompositeExtract %5 %45 2\n%50 = OpExtInst %5 %44 FMax %49 %48\n%52 = OpFOrdGreaterThanEqual %51 %49 %50\n%53 = OpFOrdGreaterThanEqual %51 %47 %50\n%54 = OpFMul %5 %50 %50\n%55 = OpFDiv %5 %56 %54\n%57 = OpVectorShuffle %33 %40 %40 0 2 1\n%58 = OpVectorShuffle %33 %40 %40 2 1 0\n%60 = OpCompositeConstruct %59 %52 %52 %52\n%61 = OpCompositeConstruct %59 %53 %53 %53\n%62 = OpSelect %33 %61 %57 %58\n%63 = OpSelect %33 %60 %40 %62\n%64 = OpVectorShuffle %33 %41 %41 0 2 1\n%65 = OpVectorShuffle %33 %41 %41 2 1 0\n%66 = OpCompositeConstruct %59 %52 %52 %52\n%67 = OpCompositeConstruct %59 %53 %53 %53\n%68 = OpSelect %33 %67 %64 %65\n%69 = OpSelect %33 %66 %41 %68\n%70 = OpVectorShuffle %33 %34 %34 0 2 1\n%71 = OpVectorShuffle %33 %34 %34 2 1 0\n%72 = OpCompositeConstruct %59 %52 %52 %52\n%73 = OpCompositeConstruct %59 %53 %53 %53\n%74 = OpSelect %33 %73 %70 %71\n%75 = OpSelect %33 %72 %34 %74\n%76 = OpVectorShuffle %43 %63 %69 0 3 1 4\n%77 = OpVectorShuffle %43 %75 %75 0 0 1 1\n%78 = OpVectorShuffle %43 %63 %69 2 5 2 5\n%79 = OpVectorTimesScalar %43 %76 %50\n%80 = OpFMul %43 %77 %78\n%81 = OpFSub %43 %79 %80\n%82 = OpVectorTimesScalar %43 %81 %55\n%83 = OpVectorShuffle %42 %82 %82 0 2\n%84 = OpVectorShuffle %42 %82 %82 1 3\n%86 = OpImageQuerySizeLod %85 %31 %87\n%89 = OpVectorShuffle %88 %86 %86 0 1\n%90 = OpConvertSToF %42 %89\n%91 = OpFMul %42 %83 %90\n%92 = OpFMul %42 %84 %90\n%93 = OpDot %5 %91 %91\n%94 = OpDot %5 %92 %92\n%95 = OpExtInst %5 %44 FMax %93 %94\n%96 = OpExtInst %5 %44 Log2 %95\n%97 = OpFMul %5 %96 %56\n%98 = OpImageQueryLevels %35 %31\n%99 = OpConvertSToF %5 %98\n%100 = OpFSub %5 %99 %101\n%102 = OpExtInst %5 %44 FMin %97 %100\n%103 = OpExtInst %5 %44 FMax %102 %104\n%106 = OpAccessChain %105 %13 %22 %23\n%107 = OpLoad %9 %106\n%108 = OpBitcast %5 %107\n%109 = OpFAdd %5 %108 %103\n%110 = OpBitcast %9 %109\n%111 = OpAccessChain %105 %13 %22 %23\nOpStore %111 %110\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/compute-shader-derivatives-cube.noderivs.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _13;\n\nlayout(set = 0, binding = 0) uniform textureCube _8;\nlayout(set = 0, binding = 0) uniform sampler _16;\n\nvoid main()\n{\n    float _24 = float(gl_GlobalInvocationID.x);\n    vec3 coord = vec3(_24 * 0.100000001490116119384765625, _24 * 0.20000000298023223876953125, _24 * 0.300000011920928955078125);\n    vec3 d_coord_dx = subgroupQuadSwapHorizontal(coord) - coord;\n    vec3 d_coord_dy = subgroupQuadSwapVertical(coord) - coord;\n    vec3 abs_uvw = abs(coord);\n    float _47 = abs_uvw.y;\n    float _49 = abs_uvw.z;\n    float max_component = max(_49, max(_47, abs_uvw.x));\n    bool z_major = _49 >= max_component;\n    bool y_major = _47 >= max_component;\n    vec3 d_str_dx = mix(mix(d_coord_dx.zyx, d_coord_dx.xzy, bvec3(y_major)), d_coord_dx, bvec3(z_major));\n    vec3 d_str_dy = mix(mix(d_coord_dy.zyx, d_coord_dy.xzy, bvec3(y_major)), d_coord_dy, bvec3(z_major));\n    vec4 cube_gradients = ((vec4(d_str_dx.x, d_str_dy.x, d_str_dx.y, d_str_dy.y) * max_component) - (mix(mix(coord.zyx, coord.xzy, bvec3(y_major)), coord, bvec3(z_major)).xxyy * vec4(d_str_dx.z, d_str_dy.z, d_str_dx.z, d_str_dy.z))) * (0.5 / (max_component * max_component));\n    vec2 _88 = vec2(textureSize(_8, 0));\n    vec2 _89 = cube_gradients.xz * _88;\n    vec2 _90 = cube_gradients.yw * _88;\n    _13._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_13._m0[gl_GlobalInvocationID.x]) + max(min(log2(max(dot(_89, _89), dot(_90, _90))) * 0.5, float(textureQueryLevels(_8)) - (-1.0)), 0.0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 112\n; Schema: 0\nOpCapability Shader\nOpCapability ImageQuery\nOpCapability GroupNonUniformQuad\n%44 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %19\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %11 \"SSBO\"\nOpName %34 \"coord\"\nOpName %40 \"d_coord_dx\"\nOpName %41 \"d_coord_dy\"\nOpName %45 \"abs_uvw\"\nOpName %50 \"max_component\"\nOpName %52 \"z_major\"\nOpName %53 \"y_major\"\nOpName %63 \"d_str_dx\"\nOpName %69 \"d_str_dy\"\nOpName %75 \"str\"\nOpName %82 \"cube_gradients\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeSampler\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeVector %9 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %9\n%22 = OpConstant %9 0\n%26 = OpConstant %5 0.100000001\n%28 = OpConstant %5 0.200000003\n%30 = OpConstant %5 0.300000012\n%33 = OpTypeVector %5 3\n%35 = OpTypeInt 32 1\n%37 = OpConstant %9 3\n%39 = OpConstant %9 1\n%42 = OpTypeVector %5 2\n%43 = OpTypeVector %5 4\n%51 = OpTypeBool\n%56 = OpConstant %5 0.5\n%59 = OpTypeVector %51 3\n%85 = OpTypeVector %35 2\n%87 = OpConstant %35 0\n%99 = OpConstant %5 -1\n%102 = OpConstant %5 0\n%103 = OpTypePointer StorageBuffer %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%21 = OpAccessChain %20 %19 %22\n%23 = OpLoad %9 %21\n%24 = OpConvertUToF %5 %23\n%25 = OpFMul %5 %24 %26\n%27 = OpFMul %5 %24 %28\n%29 = OpFMul %5 %24 %30\n%31 = OpLoad %6 %8\n%32 = OpLoad %14 %16\n%34 = OpCompositeConstruct %33 %25 %27 %29\n%36 = OpGroupNonUniformQuadSwap %33 %37 %34 %22\n%38 = OpGroupNonUniformQuadSwap %33 %37 %34 %39\n%40 = OpFSub %33 %36 %34\n%41 = OpFSub %33 %38 %34\n%45 = OpExtInst %33 %44 FAbs %34\n%46 = OpCompositeExtract %5 %45 0\n%47 = OpCompositeExtract %5 %45 1\n%48 = OpExtInst %5 %44 FMax %47 %46\n%49 = OpCompositeExtract %5 %45 2\n%50 = OpExtInst %5 %44 FMax %49 %48\n%52 = OpFOrdGreaterThanEqual %51 %49 %50\n%53 = OpFOrdGreaterThanEqual %51 %47 %50\n%54 = OpFMul %5 %50 %50\n%55 = OpFDiv %5 %56 %54\n%57 = OpVectorShuffle %33 %40 %40 0 2 1\n%58 = OpVectorShuffle %33 %40 %40 2 1 0\n%60 = OpCompositeConstruct %59 %52 %52 %52\n%61 = OpCompositeConstruct %59 %53 %53 %53\n%62 = OpSelect %33 %61 %57 %58\n%63 = OpSelect %33 %60 %40 %62\n%64 = OpVectorShuffle %33 %41 %41 0 2 1\n%65 = OpVectorShuffle %33 %41 %41 2 1 0\n%66 = OpCompositeConstruct %59 %52 %52 %52\n%67 = OpCompositeConstruct %59 %53 %53 %53\n%68 = OpSelect %33 %67 %64 %65\n%69 = OpSelect %33 %66 %41 %68\n%70 = OpVectorShuffle %33 %34 %34 0 2 1\n%71 = OpVectorShuffle %33 %34 %34 2 1 0\n%72 = OpCompositeConstruct %59 %52 %52 %52\n%73 = OpCompositeConstruct %59 %53 %53 %53\n%74 = OpSelect %33 %73 %70 %71\n%75 = OpSelect %33 %72 %34 %74\n%76 = OpVectorShuffle %43 %63 %69 0 3 1 4\n%77 = OpVectorShuffle %43 %75 %75 0 0 1 1\n%78 = OpVectorShuffle %43 %63 %69 2 5 2 5\n%79 = OpVectorTimesScalar %43 %76 %50\n%80 = OpFMul %43 %77 %78\n%81 = OpFSub %43 %79 %80\n%82 = OpVectorTimesScalar %43 %81 %55\n%83 = OpVectorShuffle %42 %82 %82 0 2\n%84 = OpVectorShuffle %42 %82 %82 1 3\n%86 = OpImageQuerySizeLod %85 %31 %87\n%88 = OpConvertSToF %42 %86\n%89 = OpFMul %42 %83 %88\n%90 = OpFMul %42 %84 %88\n%91 = OpDot %5 %89 %89\n%92 = OpDot %5 %90 %90\n%93 = OpExtInst %5 %44 FMax %91 %92\n%94 = OpExtInst %5 %44 Log2 %93\n%95 = OpFMul %5 %94 %56\n%96 = OpImageQueryLevels %35 %31\n%97 = OpConvertSToF %5 %96\n%98 = OpFSub %5 %97 %99\n%100 = OpExtInst %5 %44 FMin %95 %98\n%101 = OpExtInst %5 %44 FMax %100 %102\n%104 = OpAccessChain %103 %13 %22 %23\n%105 = OpLoad %9 %104\n%106 = OpBitcast %5 %105\n%107 = OpFAdd %5 %106 %101\n%108 = OpBitcast %9 %107\n%109 = OpAccessChain %103 %13 %22 %23\nOpStore %109 %108\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/compute-shader-derivatives-single-thread.sm66.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) coherent buffer SSBO\n{\n    uint _m0[];\n} _25;\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 1) uniform texture2DArray _11;\nlayout(set = 0, binding = 2) uniform textureCube _14;\nlayout(set = 0, binding = 3) uniform textureCubeArray _17;\nlayout(set = 0, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _28;\nlayout(set = 0, binding = 1) uniform samplerShadow _29;\n\nvoid main()\n{\n    float _37 = float(gl_GlobalInvocationID.x);\n    float _38 = _37 * 0.100000001490116119384765625;\n    float _40 = _37 * 0.20000000298023223876953125;\n    float _42 = _37 * 0.300000011920928955078125;\n    float _44 = _37 * 0.4000000059604644775390625;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(sampler2D(_8, _28), vec2(_38, _40), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(sampler2DArray(_11, _28), vec3(_38, _40, _42), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(samplerCube(_14, _28), vec3(_38, _40, _42), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(samplerCubeArray(_17, _28), vec4(_38, _40, _42, _44), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(sampler3D(_20, _28), vec3(_38, _40, _42), 0.0).x);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(sampler2D(_8, _28), vec2(_38, _40), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(sampler2DArray(_11, _28), vec3(_38, _40, _42), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(samplerCube(_14, _28), vec3(_38, _40, _42), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(samplerCubeArray(_17, _28), vec4(_38, _40, _42, _44), 0.0).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureLod(sampler3D(_20, _28), vec3(_38, _40, _42), 0.0).x);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureLod(sampler2DShadow(_8, _29), vec3(vec2(_38, _40), _44), 0.0)).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureGrad(sampler2DArrayShadow(_11, _29), vec4(vec3(_38, _40, _42), _44), vec2(0.0), vec2(0.0))).x);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureGrad(samplerCubeShadow(_14, _29), vec4(vec3(_38, _40, _42), _44), vec3(0.0), vec3(0.0))).x);\n    vec4 _229 = vec4(_38, _40, _42, _44);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureGrad(samplerCubeArrayShadow(_17, _29), _229, _44, vec3(0.0), vec3(0.0))).x);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + 0.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 324\n; Schema: 0\nOpCapability Shader\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %32\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %23 \"SSBO\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %22 ArrayStride 4\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 Coherent\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 1\nOpDecorate %32 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeInt 32 0\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeSampler\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpVariable %27 UniformConstant\n%30 = OpTypeVector %21 3\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypePointer Input %21\n%35 = OpConstant %21 0\n%39 = OpConstant %5 0.100000001\n%41 = OpConstant %5 0.200000003\n%43 = OpConstant %5 0.300000012\n%45 = OpConstant %5 0.400000006\n%48 = OpTypeSampledImage %6\n%50 = OpConstant %5 0\n%51 = OpTypeVector %5 4\n%53 = OpTypeVector %5 2\n%56 = OpTypePointer StorageBuffer %21\n%65 = OpTypeSampledImage %9\n%68 = OpTypeVector %5 3\n%79 = OpTypeSampledImage %12\n%92 = OpTypeSampledImage %15\n%105 = OpTypeSampledImage %18\n%116 = OpConstant %21 2\n%117 = OpConstant %21 2120\n%180 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%181 = OpTypeSampledImage %180\n%195 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%196 = OpTypeSampledImage %195\n%210 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%211 = OpTypeSampledImage %210\n%225 = OpTypeImage %5 Cube 1 1 0 1 Unknown\n%226 = OpTypeSampledImage %225\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %322\n%322 = OpLabel\n%34 = OpAccessChain %33 %32 %35\n%36 = OpLoad %21 %34\n%37 = OpConvertUToF %5 %36\n%38 = OpFMul %5 %37 %39\n%40 = OpFMul %5 %37 %41\n%42 = OpFMul %5 %37 %43\n%44 = OpFMul %5 %37 %45\n%46 = OpLoad %6 %8\n%47 = OpLoad %26 %28\n%49 = OpSampledImage %48 %46 %47\n%54 = OpCompositeConstruct %53 %38 %40\n%52 = OpImageSampleExplicitLod %51 %49 %54 Lod %50\n%55 = OpCompositeExtract %5 %52 0\n%57 = OpAccessChain %56 %25 %35 %36\n%58 = OpLoad %21 %57\n%59 = OpBitcast %5 %58\n%60 = OpFAdd %5 %59 %55\n%61 = OpBitcast %21 %60\n%62 = OpAccessChain %56 %25 %35 %36\nOpStore %62 %61\n%63 = OpLoad %9 %11\n%64 = OpLoad %26 %28\n%66 = OpSampledImage %65 %63 %64\n%69 = OpCompositeConstruct %68 %38 %40 %42\n%67 = OpImageSampleExplicitLod %51 %66 %69 Lod %50\n%70 = OpCompositeExtract %5 %67 0\n%71 = OpAccessChain %56 %25 %35 %36\n%72 = OpLoad %21 %71\n%73 = OpBitcast %5 %72\n%74 = OpFAdd %5 %73 %70\n%75 = OpBitcast %21 %74\n%76 = OpAccessChain %56 %25 %35 %36\nOpStore %76 %75\n%77 = OpLoad %12 %14\n%78 = OpLoad %26 %28\n%80 = OpSampledImage %79 %77 %78\n%82 = OpCompositeConstruct %68 %38 %40 %42\n%81 = OpImageSampleExplicitLod %51 %80 %82 Lod %50\n%83 = OpCompositeExtract %5 %81 0\n%84 = OpAccessChain %56 %25 %35 %36\n%85 = OpLoad %21 %84\n%86 = OpBitcast %5 %85\n%87 = OpFAdd %5 %86 %83\n%88 = OpBitcast %21 %87\n%89 = OpAccessChain %56 %25 %35 %36\nOpStore %89 %88\n%90 = OpLoad %15 %17\n%91 = OpLoad %26 %28\n%93 = OpSampledImage %92 %90 %91\n%95 = OpCompositeConstruct %51 %38 %40 %42 %44\n%94 = OpImageSampleExplicitLod %51 %93 %95 Lod %50\n%96 = OpCompositeExtract %5 %94 0\n%97 = OpAccessChain %56 %25 %35 %36\n%98 = OpLoad %21 %97\n%99 = OpBitcast %5 %98\n%100 = OpFAdd %5 %99 %96\n%101 = OpBitcast %21 %100\n%102 = OpAccessChain %56 %25 %35 %36\nOpStore %102 %101\n%103 = OpLoad %18 %20\n%104 = OpLoad %26 %28\n%106 = OpSampledImage %105 %103 %104\n%108 = OpCompositeConstruct %68 %38 %40 %42\n%107 = OpImageSampleExplicitLod %51 %106 %108 Lod %50\n%109 = OpCompositeExtract %5 %107 0\n%110 = OpAccessChain %56 %25 %35 %36\n%111 = OpLoad %21 %110\n%112 = OpBitcast %5 %111\n%113 = OpFAdd %5 %112 %109\n%114 = OpBitcast %21 %113\n%115 = OpAccessChain %56 %25 %35 %36\nOpStore %115 %114\nOpControlBarrier %116 %116 %117\n%118 = OpLoad %6 %8\n%119 = OpLoad %26 %28\n%120 = OpSampledImage %48 %118 %119\n%122 = OpCompositeConstruct %53 %38 %40\n%121 = OpImageSampleExplicitLod %51 %120 %122 Lod %50\n%123 = OpCompositeExtract %5 %121 0\n%124 = OpAccessChain %56 %25 %35 %36\n%125 = OpLoad %21 %124\n%126 = OpBitcast %5 %125\n%127 = OpFAdd %5 %126 %123\n%128 = OpBitcast %21 %127\n%129 = OpAccessChain %56 %25 %35 %36\nOpStore %129 %128\n%130 = OpLoad %9 %11\n%131 = OpLoad %26 %28\n%132 = OpSampledImage %65 %130 %131\n%134 = OpCompositeConstruct %68 %38 %40 %42\n%133 = OpImageSampleExplicitLod %51 %132 %134 Lod %50\n%135 = OpCompositeExtract %5 %133 0\n%136 = OpAccessChain %56 %25 %35 %36\n%137 = OpLoad %21 %136\n%138 = OpBitcast %5 %137\n%139 = OpFAdd %5 %138 %135\n%140 = OpBitcast %21 %139\n%141 = OpAccessChain %56 %25 %35 %36\nOpStore %141 %140\n%142 = OpLoad %12 %14\n%143 = OpLoad %26 %28\n%144 = OpSampledImage %79 %142 %143\n%146 = OpCompositeConstruct %68 %38 %40 %42\n%145 = OpImageSampleExplicitLod %51 %144 %146 Lod %50\n%147 = OpCompositeExtract %5 %145 0\n%148 = OpAccessChain %56 %25 %35 %36\n%149 = OpLoad %21 %148\n%150 = OpBitcast %5 %149\n%151 = OpFAdd %5 %150 %147\n%152 = OpBitcast %21 %151\n%153 = OpAccessChain %56 %25 %35 %36\nOpStore %153 %152\n%154 = OpLoad %15 %17\n%155 = OpLoad %26 %28\n%156 = OpSampledImage %92 %154 %155\n%158 = OpCompositeConstruct %51 %38 %40 %42 %44\n%157 = OpImageSampleExplicitLod %51 %156 %158 Lod %50\n%159 = OpCompositeExtract %5 %157 0\n%160 = OpAccessChain %56 %25 %35 %36\n%161 = OpLoad %21 %160\n%162 = OpBitcast %5 %161\n%163 = OpFAdd %5 %162 %159\n%164 = OpBitcast %21 %163\n%165 = OpAccessChain %56 %25 %35 %36\nOpStore %165 %164\n%166 = OpLoad %18 %20\n%167 = OpLoad %26 %28\n%168 = OpSampledImage %105 %166 %167\n%170 = OpCompositeConstruct %68 %38 %40 %42\n%169 = OpImageSampleExplicitLod %51 %168 %170 Lod %50\n%171 = OpCompositeExtract %5 %169 0\n%172 = OpAccessChain %56 %25 %35 %36\n%173 = OpLoad %21 %172\n%174 = OpBitcast %5 %173\n%175 = OpFAdd %5 %174 %171\n%176 = OpBitcast %21 %175\n%177 = OpAccessChain %56 %25 %35 %36\nOpStore %177 %176\nOpControlBarrier %116 %116 %117\n%178 = OpLoad %6 %8\n%179 = OpLoad %26 %29\n%182 = OpSampledImage %181 %178 %179\n%184 = OpCompositeConstruct %53 %38 %40\n%183 = OpImageSampleDrefExplicitLod %5 %182 %184 %44 Lod %50\n%185 = OpCompositeConstruct %51 %183 %183 %183 %183\n%186 = OpCompositeExtract %5 %185 0\n%187 = OpAccessChain %56 %25 %35 %36\n%188 = OpLoad %21 %187\n%189 = OpBitcast %5 %188\n%190 = OpFAdd %5 %189 %186\n%191 = OpBitcast %21 %190\n%192 = OpAccessChain %56 %25 %35 %36\nOpStore %192 %191\n%193 = OpLoad %9 %11\n%194 = OpLoad %26 %29\n%197 = OpSampledImage %196 %193 %194\n%199 = OpCompositeConstruct %68 %38 %40 %42\n%198 = OpImageSampleDrefExplicitLod %5 %197 %199 %44 Lod %50\n%200 = OpCompositeConstruct %51 %198 %198 %198 %198\n%201 = OpCompositeExtract %5 %200 0\n%202 = OpAccessChain %56 %25 %35 %36\n%203 = OpLoad %21 %202\n%204 = OpBitcast %5 %203\n%205 = OpFAdd %5 %204 %201\n%206 = OpBitcast %21 %205\n%207 = OpAccessChain %56 %25 %35 %36\nOpStore %207 %206\n%208 = OpLoad %12 %14\n%209 = OpLoad %26 %29\n%212 = OpSampledImage %211 %208 %209\n%214 = OpCompositeConstruct %68 %38 %40 %42\n%213 = OpImageSampleDrefExplicitLod %5 %212 %214 %44 Lod %50\n%215 = OpCompositeConstruct %51 %213 %213 %213 %213\n%216 = OpCompositeExtract %5 %215 0\n%217 = OpAccessChain %56 %25 %35 %36\n%218 = OpLoad %21 %217\n%219 = OpBitcast %5 %218\n%220 = OpFAdd %5 %219 %216\n%221 = OpBitcast %21 %220\n%222 = OpAccessChain %56 %25 %35 %36\nOpStore %222 %221\n%223 = OpLoad %15 %17\n%224 = OpLoad %26 %29\n%227 = OpSampledImage %226 %223 %224\n%229 = OpCompositeConstruct %51 %38 %40 %42 %44\n%228 = OpImageSampleDrefExplicitLod %5 %227 %229 %44 Lod %50\n%230 = OpCompositeConstruct %51 %228 %228 %228 %228\n%231 = OpCompositeExtract %5 %230 0\n%232 = OpAccessChain %56 %25 %35 %36\n%233 = OpLoad %21 %232\n%234 = OpBitcast %5 %233\n%235 = OpFAdd %5 %234 %231\n%236 = OpBitcast %21 %235\n%237 = OpAccessChain %56 %25 %35 %36\nOpStore %237 %236\nOpControlBarrier %116 %116 %117\n%238 = OpAccessChain %56 %25 %35 %36\n%239 = OpLoad %21 %238\n%240 = OpBitcast %5 %239\n%241 = OpFAdd %5 %240 %50\n%242 = OpBitcast %21 %241\n%243 = OpAccessChain %56 %25 %35 %36\nOpStore %243 %242\n%244 = OpAccessChain %56 %25 %35 %36\n%245 = OpLoad %21 %244\n%246 = OpBitcast %5 %245\n%247 = OpFAdd %5 %246 %50\n%248 = OpBitcast %21 %247\n%249 = OpAccessChain %56 %25 %35 %36\nOpStore %249 %248\nOpControlBarrier %116 %116 %117\n%250 = OpAccessChain %56 %25 %35 %36\n%251 = OpLoad %21 %250\n%252 = OpBitcast %5 %251\n%253 = OpFAdd %5 %252 %50\n%254 = OpBitcast %21 %253\n%255 = OpAccessChain %56 %25 %35 %36\nOpStore %255 %254\n%256 = OpAccessChain %56 %25 %35 %36\n%257 = OpLoad %21 %256\n%258 = OpBitcast %5 %257\n%259 = OpFAdd %5 %258 %50\n%260 = OpBitcast %21 %259\n%261 = OpAccessChain %56 %25 %35 %36\nOpStore %261 %260\nOpControlBarrier %116 %116 %117\n%262 = OpAccessChain %56 %25 %35 %36\n%263 = OpLoad %21 %262\n%264 = OpBitcast %5 %263\n%265 = OpFAdd %5 %264 %50\n%266 = OpBitcast %21 %265\n%267 = OpAccessChain %56 %25 %35 %36\nOpStore %267 %266\n%268 = OpAccessChain %56 %25 %35 %36\n%269 = OpLoad %21 %268\n%270 = OpBitcast %5 %269\n%271 = OpFAdd %5 %270 %50\n%272 = OpBitcast %21 %271\n%273 = OpAccessChain %56 %25 %35 %36\nOpStore %273 %272\nOpControlBarrier %116 %116 %117\n%274 = OpLoad %6 %8\n%275 = OpLoad %26 %28\n%276 = OpAccessChain %56 %25 %35 %36\n%277 = OpLoad %21 %276\n%278 = OpBitcast %5 %277\n%279 = OpFAdd %5 %278 %50\n%280 = OpBitcast %21 %279\n%281 = OpAccessChain %56 %25 %35 %36\nOpStore %281 %280\n%282 = OpLoad %9 %11\n%283 = OpLoad %26 %28\n%284 = OpAccessChain %56 %25 %35 %36\n%285 = OpLoad %21 %284\n%286 = OpBitcast %5 %285\n%287 = OpFAdd %5 %286 %50\n%288 = OpBitcast %21 %287\n%289 = OpAccessChain %56 %25 %35 %36\nOpStore %289 %288\n%290 = OpLoad %18 %20\n%291 = OpLoad %26 %28\n%292 = OpAccessChain %56 %25 %35 %36\n%293 = OpLoad %21 %292\n%294 = OpBitcast %5 %293\n%295 = OpFAdd %5 %294 %50\n%296 = OpBitcast %21 %295\n%297 = OpAccessChain %56 %25 %35 %36\nOpStore %297 %296\nOpControlBarrier %116 %116 %117\n%298 = OpLoad %6 %8\n%299 = OpLoad %26 %28\n%300 = OpAccessChain %56 %25 %35 %36\n%301 = OpLoad %21 %300\n%302 = OpBitcast %5 %301\n%303 = OpFAdd %5 %302 %50\n%304 = OpBitcast %21 %303\n%305 = OpAccessChain %56 %25 %35 %36\nOpStore %305 %304\n%306 = OpLoad %9 %11\n%307 = OpLoad %26 %28\n%308 = OpAccessChain %56 %25 %35 %36\n%309 = OpLoad %21 %308\n%310 = OpBitcast %5 %309\n%311 = OpFAdd %5 %310 %50\n%312 = OpBitcast %21 %311\n%313 = OpAccessChain %56 %25 %35 %36\nOpStore %313 %312\n%314 = OpLoad %18 %20\n%315 = OpLoad %26 %28\n%316 = OpAccessChain %56 %25 %35 %36\n%317 = OpLoad %21 %316\n%318 = OpBitcast %5 %317\n%319 = OpFAdd %5 %318 %50\n%320 = OpBitcast %21 %319\n%321 = OpAccessChain %56 %25 %35 %36\nOpStore %321 %320\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/compute-shader-derivatives.noderivs.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) coherent buffer SSBO\n{\n    uint _m0[];\n} _25;\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 1) uniform texture2DArray _11;\nlayout(set = 0, binding = 2) uniform textureCube _14;\nlayout(set = 0, binding = 3) uniform textureCubeArray _17;\nlayout(set = 0, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _28;\nlayout(set = 0, binding = 1) uniform samplerShadow _29;\n\nvoid main()\n{\n    float _37 = float(gl_GlobalInvocationID.x);\n    float _38 = _37 * 0.100000001490116119384765625;\n    float _40 = _37 * 0.20000000298023223876953125;\n    float _42 = _37 * 0.300000011920928955078125;\n    float _44 = _37 * 0.4000000059604644775390625;\n    vec2 _53 = vec2(_38, _40);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(sampler2D(_8, _28), vec2(_38, _40), _53 - subgroupQuadSwapHorizontal(_53), _53 - subgroupQuadSwapVertical(_53)).x);\n    vec2 _74 = vec2(_38, _40);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(sampler2DArray(_11, _28), vec3(_38, _40, _42), _74 - subgroupQuadSwapHorizontal(_74), _74 - subgroupQuadSwapVertical(_74)).x);\n    vec3 _93 = vec3(_38, _40, _42);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(samplerCube(_14, _28), vec3(_38, _40, _42), _93 - subgroupQuadSwapHorizontal(_93), _93 - subgroupQuadSwapVertical(_93)).x);\n    vec3 _111 = vec3(_38, _40, _42);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(samplerCubeArray(_17, _28), vec4(_38, _40, _42, _44), _111 - subgroupQuadSwapHorizontal(_111), _111 - subgroupQuadSwapVertical(_111)).x);\n    vec3 _129 = vec3(_38, _40, _42);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(sampler3D(_20, _28), vec3(_38, _40, _42), _129 - subgroupQuadSwapHorizontal(_129), _129 - subgroupQuadSwapVertical(_129)).x);\n    groupMemoryBarrier();\n    barrier();\n    vec2 _148 = vec2(_38, _40);\n    float _154 = exp2(_44);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(sampler2D(_8, _28), vec2(_38, _40), (_148 - subgroupQuadSwapHorizontal(_148)) * _154, (_148 - subgroupQuadSwapVertical(_148)) * _154).x);\n    vec2 _169 = vec2(_38, _40);\n    float _174 = exp2(_44);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(sampler2DArray(_11, _28), vec3(_38, _40, _42), (_169 - subgroupQuadSwapHorizontal(_169)) * _174, (_169 - subgroupQuadSwapVertical(_169)) * _174).x);\n    vec3 _189 = vec3(_38, _40, _42);\n    float _194 = exp2(_44);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(samplerCube(_14, _28), vec3(_38, _40, _42), (_189 - subgroupQuadSwapHorizontal(_189)) * _194, (_189 - subgroupQuadSwapVertical(_189)) * _194).x);\n    vec3 _209 = vec3(_38, _40, _42);\n    float _214 = exp2(_44);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(samplerCubeArray(_17, _28), vec4(_38, _40, _42, _44), (_209 - subgroupQuadSwapHorizontal(_209)) * _214, (_209 - subgroupQuadSwapVertical(_209)) * _214).x);\n    vec3 _229 = vec3(_38, _40, _42);\n    float _234 = exp2(_44);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + textureGrad(sampler3D(_20, _28), vec3(_38, _40, _42), (_229 - subgroupQuadSwapHorizontal(_229)) * _234, (_229 - subgroupQuadSwapVertical(_229)) * _234).x);\n    groupMemoryBarrier();\n    barrier();\n    vec2 _251 = vec2(_38, _40);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureGrad(sampler2DShadow(_8, _29), vec3(vec2(_38, _40), _44), _251 - subgroupQuadSwapHorizontal(_251), _251 - subgroupQuadSwapVertical(_251))).x);\n    vec2 _271 = vec2(_38, _40);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureGrad(sampler2DArrayShadow(_11, _29), vec4(vec3(_38, _40, _42), _44), _271 - subgroupQuadSwapHorizontal(_271), _271 - subgroupQuadSwapVertical(_271))).x);\n    vec3 _291 = vec3(_38, _40, _42);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureGrad(samplerCubeShadow(_14, _29), vec4(vec3(_38, _40, _42), _44), _291 - subgroupQuadSwapHorizontal(_291), _291 - subgroupQuadSwapVertical(_291))).x);\n    vec3 _311 = vec3(_38, _40, _42);\n    vec4 _317 = vec4(_38, _40, _42, _44);\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + vec4(textureGrad(samplerCubeArrayShadow(_17, _29), _317, _44, _311 - subgroupQuadSwapHorizontal(_311), _311 - subgroupQuadSwapVertical(_311))).x);\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + (subgroupQuadBroadcast(_44, 1u) - subgroupQuadBroadcast(_44, 0u)));\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + (subgroupQuadBroadcast(_44, 2u) - subgroupQuadBroadcast(_44, 0u)));\n    groupMemoryBarrier();\n    barrier();\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + (subgroupQuadBroadcast(_44, 1u) - subgroupQuadBroadcast(_44, 0u)));\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + (subgroupQuadBroadcast(_44, 2u) - subgroupQuadBroadcast(_44, 0u)));\n    groupMemoryBarrier();\n    barrier();\n    float _363 = subgroupQuadSwapHorizontal(_44) - _44;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + (((gl_SubgroupInvocationID & 1u) != 0u) ? subgroupQuadSwapHorizontal(_363) : _363));\n    float _378 = subgroupQuadSwapVertical(_44) - _44;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + (((gl_SubgroupInvocationID & 2u) != 0u) ? subgroupQuadSwapVertical(_378) : _378));\n    groupMemoryBarrier();\n    barrier();\n    vec2 _392 = vec2(_38, _40);\n    vec2 _401 = vec2(textureSize(_8, 0));\n    vec2 _402 = (subgroupQuadSwapHorizontal(_392) - _392) * _401;\n    vec2 _403 = (subgroupQuadSwapVertical(_392) - _392) * _401;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + max(min(log2(max(dot(_402, _402), dot(_403, _403))) * 0.5, float(textureQueryLevels(_8)) - (-1.0)), 0.0));\n    vec2 _424 = vec2(_38, _40);\n    vec2 _432 = vec2(textureSize(_11, 0).xy);\n    vec2 _433 = (subgroupQuadSwapHorizontal(_424) - _424) * _432;\n    vec2 _434 = (subgroupQuadSwapVertical(_424) - _424) * _432;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + max(min(log2(max(dot(_433, _433), dot(_434, _434))) * 0.5, float(textureQueryLevels(_11)) - (-1.0)), 0.0));\n    vec3 _453 = vec3(_38, _40, _42);\n    vec3 _459 = vec3(textureSize(_20, 0));\n    vec3 _460 = (subgroupQuadSwapHorizontal(_453) - _453) * _459;\n    vec3 _461 = (subgroupQuadSwapVertical(_453) - _453) * _459;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + max(min(log2(max(dot(_460, _460), dot(_461, _461))) * 0.5, float(textureQueryLevels(_20)) - (-1.0)), 0.0));\n    groupMemoryBarrier();\n    barrier();\n    vec2 _480 = vec2(_38, _40);\n    vec2 _486 = vec2(textureSize(_8, 0));\n    vec2 _487 = (subgroupQuadSwapHorizontal(_480) - _480) * _486;\n    vec2 _488 = (subgroupQuadSwapVertical(_480) - _480) * _486;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + clamp(log2(max(dot(_487, _487), dot(_488, _488))) * 0.5, -128.0, 128.0));\n    vec2 _505 = vec2(_38, _40);\n    vec2 _512 = vec2(textureSize(_11, 0).xy);\n    vec2 _513 = (subgroupQuadSwapHorizontal(_505) - _505) * _512;\n    vec2 _514 = (subgroupQuadSwapVertical(_505) - _505) * _512;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + clamp(log2(max(dot(_513, _513), dot(_514, _514))) * 0.5, -128.0, 128.0));\n    vec3 _529 = vec3(_38, _40, _42);\n    vec3 _535 = vec3(textureSize(_20, 0));\n    vec3 _536 = (subgroupQuadSwapHorizontal(_529) - _529) * _535;\n    vec3 _537 = (subgroupQuadSwapVertical(_529) - _529) * _535;\n    _25._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_25._m0[gl_GlobalInvocationID.x]) + clamp(log2(max(dot(_536, _536), dot(_537, _537))) * 0.5, -128.0, 128.0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 552\n; Schema: 0\nOpCapability Shader\nOpCapability SampledCubeArray\nOpCapability ImageQuery\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformQuad\n%153 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %32 %365\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %23 \"SSBO\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %22 ArrayStride 4\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 Coherent\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 1\nOpDecorate %32 BuiltIn GlobalInvocationId\nOpDecorate %365 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeInt 32 0\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeSampler\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpVariable %27 UniformConstant\n%30 = OpTypeVector %21 3\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypePointer Input %21\n%35 = OpConstant %21 0\n%39 = OpConstant %5 0.100000001\n%41 = OpConstant %5 0.200000003\n%43 = OpConstant %5 0.300000012\n%45 = OpConstant %5 0.400000006\n%48 = OpTypeSampledImage %6\n%50 = OpConstant %5 0\n%51 = OpTypeVector %5 4\n%52 = OpTypeVector %5 2\n%55 = OpConstant %21 3\n%57 = OpConstant %21 1\n%63 = OpTypePointer StorageBuffer %21\n%72 = OpTypeSampledImage %9\n%80 = OpTypeVector %5 3\n%91 = OpTypeSampledImage %12\n%109 = OpTypeSampledImage %15\n%127 = OpTypeSampledImage %18\n%143 = OpConstant %21 2\n%144 = OpConstant %21 2120\n%248 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%249 = OpTypeSampledImage %248\n%268 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%269 = OpTypeSampledImage %268\n%288 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%289 = OpTypeSampledImage %288\n%308 = OpTypeImage %5 Cube 1 1 0 1 Unknown\n%309 = OpTypeSampledImage %308\n%365 = OpVariable %33 Input\n%368 = OpTypeBool\n%393 = OpTypeInt 32 1\n%398 = OpTypeVector %393 2\n%400 = OpConstant %393 0\n%409 = OpConstant %5 0.5\n%413 = OpConstant %5 -1\n%429 = OpTypeVector %393 3\n%495 = OpConstant %5 -128\n%496 = OpConstant %5 128\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %550\n%550 = OpLabel\n%34 = OpAccessChain %33 %32 %35\n%36 = OpLoad %21 %34\n%37 = OpConvertUToF %5 %36\n%38 = OpFMul %5 %37 %39\n%40 = OpFMul %5 %37 %41\n%42 = OpFMul %5 %37 %43\n%44 = OpFMul %5 %37 %45\n%46 = OpLoad %6 %8\n%47 = OpLoad %26 %28\n%49 = OpSampledImage %48 %46 %47\n%53 = OpCompositeConstruct %52 %38 %40\n%54 = OpGroupNonUniformQuadSwap %52 %55 %53 %35\n%56 = OpGroupNonUniformQuadSwap %52 %55 %53 %57\n%58 = OpFSub %52 %53 %54\n%59 = OpFSub %52 %53 %56\n%61 = OpCompositeConstruct %52 %38 %40\n%60 = OpImageSampleExplicitLod %51 %49 %61 Grad %58 %59\n%62 = OpCompositeExtract %5 %60 0\n%64 = OpAccessChain %63 %25 %35 %36\n%65 = OpLoad %21 %64\n%66 = OpBitcast %5 %65\n%67 = OpFAdd %5 %66 %62\n%68 = OpBitcast %21 %67\n%69 = OpAccessChain %63 %25 %35 %36\nOpStore %69 %68\n%70 = OpLoad %9 %11\n%71 = OpLoad %26 %28\n%73 = OpSampledImage %72 %70 %71\n%74 = OpCompositeConstruct %52 %38 %40\n%75 = OpGroupNonUniformQuadSwap %52 %55 %74 %35\n%76 = OpGroupNonUniformQuadSwap %52 %55 %74 %57\n%77 = OpFSub %52 %74 %75\n%78 = OpFSub %52 %74 %76\n%81 = OpCompositeConstruct %80 %38 %40 %42\n%79 = OpImageSampleExplicitLod %51 %73 %81 Grad %77 %78\n%82 = OpCompositeExtract %5 %79 0\n%83 = OpAccessChain %63 %25 %35 %36\n%84 = OpLoad %21 %83\n%85 = OpBitcast %5 %84\n%86 = OpFAdd %5 %85 %82\n%87 = OpBitcast %21 %86\n%88 = OpAccessChain %63 %25 %35 %36\nOpStore %88 %87\n%89 = OpLoad %12 %14\n%90 = OpLoad %26 %28\n%92 = OpSampledImage %91 %89 %90\n%93 = OpCompositeConstruct %80 %38 %40 %42\n%94 = OpGroupNonUniformQuadSwap %80 %55 %93 %35\n%95 = OpGroupNonUniformQuadSwap %80 %55 %93 %57\n%96 = OpFSub %80 %93 %94\n%97 = OpFSub %80 %93 %95\n%99 = OpCompositeConstruct %80 %38 %40 %42\n%98 = OpImageSampleExplicitLod %51 %92 %99 Grad %96 %97\n%100 = OpCompositeExtract %5 %98 0\n%101 = OpAccessChain %63 %25 %35 %36\n%102 = OpLoad %21 %101\n%103 = OpBitcast %5 %102\n%104 = OpFAdd %5 %103 %100\n%105 = OpBitcast %21 %104\n%106 = OpAccessChain %63 %25 %35 %36\nOpStore %106 %105\n%107 = OpLoad %15 %17\n%108 = OpLoad %26 %28\n%110 = OpSampledImage %109 %107 %108\n%111 = OpCompositeConstruct %80 %38 %40 %42\n%112 = OpGroupNonUniformQuadSwap %80 %55 %111 %35\n%113 = OpGroupNonUniformQuadSwap %80 %55 %111 %57\n%114 = OpFSub %80 %111 %112\n%115 = OpFSub %80 %111 %113\n%117 = OpCompositeConstruct %51 %38 %40 %42 %44\n%116 = OpImageSampleExplicitLod %51 %110 %117 Grad %114 %115\n%118 = OpCompositeExtract %5 %116 0\n%119 = OpAccessChain %63 %25 %35 %36\n%120 = OpLoad %21 %119\n%121 = OpBitcast %5 %120\n%122 = OpFAdd %5 %121 %118\n%123 = OpBitcast %21 %122\n%124 = OpAccessChain %63 %25 %35 %36\nOpStore %124 %123\n%125 = OpLoad %18 %20\n%126 = OpLoad %26 %28\n%128 = OpSampledImage %127 %125 %126\n%129 = OpCompositeConstruct %80 %38 %40 %42\n%130 = OpGroupNonUniformQuadSwap %80 %55 %129 %35\n%131 = OpGroupNonUniformQuadSwap %80 %55 %129 %57\n%132 = OpFSub %80 %129 %130\n%133 = OpFSub %80 %129 %131\n%135 = OpCompositeConstruct %80 %38 %40 %42\n%134 = OpImageSampleExplicitLod %51 %128 %135 Grad %132 %133\n%136 = OpCompositeExtract %5 %134 0\n%137 = OpAccessChain %63 %25 %35 %36\n%138 = OpLoad %21 %137\n%139 = OpBitcast %5 %138\n%140 = OpFAdd %5 %139 %136\n%141 = OpBitcast %21 %140\n%142 = OpAccessChain %63 %25 %35 %36\nOpStore %142 %141\nOpControlBarrier %143 %143 %144\n%145 = OpLoad %6 %8\n%146 = OpLoad %26 %28\n%147 = OpSampledImage %48 %145 %146\n%148 = OpCompositeConstruct %52 %38 %40\n%149 = OpGroupNonUniformQuadSwap %52 %55 %148 %35\n%150 = OpGroupNonUniformQuadSwap %52 %55 %148 %57\n%151 = OpFSub %52 %148 %149\n%152 = OpFSub %52 %148 %150\n%154 = OpExtInst %5 %153 Exp2 %44\n%155 = OpVectorTimesScalar %52 %151 %154\n%156 = OpVectorTimesScalar %52 %152 %154\n%158 = OpCompositeConstruct %52 %38 %40\n%157 = OpImageSampleExplicitLod %51 %147 %158 Grad %155 %156\n%159 = OpCompositeExtract %5 %157 0\n%160 = OpAccessChain %63 %25 %35 %36\n%161 = OpLoad %21 %160\n%162 = OpBitcast %5 %161\n%163 = OpFAdd %5 %162 %159\n%164 = OpBitcast %21 %163\n%165 = OpAccessChain %63 %25 %35 %36\nOpStore %165 %164\n%166 = OpLoad %9 %11\n%167 = OpLoad %26 %28\n%168 = OpSampledImage %72 %166 %167\n%169 = OpCompositeConstruct %52 %38 %40\n%170 = OpGroupNonUniformQuadSwap %52 %55 %169 %35\n%171 = OpGroupNonUniformQuadSwap %52 %55 %169 %57\n%172 = OpFSub %52 %169 %170\n%173 = OpFSub %52 %169 %171\n%174 = OpExtInst %5 %153 Exp2 %44\n%175 = OpVectorTimesScalar %52 %172 %174\n%176 = OpVectorTimesScalar %52 %173 %174\n%178 = OpCompositeConstruct %80 %38 %40 %42\n%177 = OpImageSampleExplicitLod %51 %168 %178 Grad %175 %176\n%179 = OpCompositeExtract %5 %177 0\n%180 = OpAccessChain %63 %25 %35 %36\n%181 = OpLoad %21 %180\n%182 = OpBitcast %5 %181\n%183 = OpFAdd %5 %182 %179\n%184 = OpBitcast %21 %183\n%185 = OpAccessChain %63 %25 %35 %36\nOpStore %185 %184\n%186 = OpLoad %12 %14\n%187 = OpLoad %26 %28\n%188 = OpSampledImage %91 %186 %187\n%189 = OpCompositeConstruct %80 %38 %40 %42\n%190 = OpGroupNonUniformQuadSwap %80 %55 %189 %35\n%191 = OpGroupNonUniformQuadSwap %80 %55 %189 %57\n%192 = OpFSub %80 %189 %190\n%193 = OpFSub %80 %189 %191\n%194 = OpExtInst %5 %153 Exp2 %44\n%195 = OpVectorTimesScalar %80 %192 %194\n%196 = OpVectorTimesScalar %80 %193 %194\n%198 = OpCompositeConstruct %80 %38 %40 %42\n%197 = OpImageSampleExplicitLod %51 %188 %198 Grad %195 %196\n%199 = OpCompositeExtract %5 %197 0\n%200 = OpAccessChain %63 %25 %35 %36\n%201 = OpLoad %21 %200\n%202 = OpBitcast %5 %201\n%203 = OpFAdd %5 %202 %199\n%204 = OpBitcast %21 %203\n%205 = OpAccessChain %63 %25 %35 %36\nOpStore %205 %204\n%206 = OpLoad %15 %17\n%207 = OpLoad %26 %28\n%208 = OpSampledImage %109 %206 %207\n%209 = OpCompositeConstruct %80 %38 %40 %42\n%210 = OpGroupNonUniformQuadSwap %80 %55 %209 %35\n%211 = OpGroupNonUniformQuadSwap %80 %55 %209 %57\n%212 = OpFSub %80 %209 %210\n%213 = OpFSub %80 %209 %211\n%214 = OpExtInst %5 %153 Exp2 %44\n%215 = OpVectorTimesScalar %80 %212 %214\n%216 = OpVectorTimesScalar %80 %213 %214\n%218 = OpCompositeConstruct %51 %38 %40 %42 %44\n%217 = OpImageSampleExplicitLod %51 %208 %218 Grad %215 %216\n%219 = OpCompositeExtract %5 %217 0\n%220 = OpAccessChain %63 %25 %35 %36\n%221 = OpLoad %21 %220\n%222 = OpBitcast %5 %221\n%223 = OpFAdd %5 %222 %219\n%224 = OpBitcast %21 %223\n%225 = OpAccessChain %63 %25 %35 %36\nOpStore %225 %224\n%226 = OpLoad %18 %20\n%227 = OpLoad %26 %28\n%228 = OpSampledImage %127 %226 %227\n%229 = OpCompositeConstruct %80 %38 %40 %42\n%230 = OpGroupNonUniformQuadSwap %80 %55 %229 %35\n%231 = OpGroupNonUniformQuadSwap %80 %55 %229 %57\n%232 = OpFSub %80 %229 %230\n%233 = OpFSub %80 %229 %231\n%234 = OpExtInst %5 %153 Exp2 %44\n%235 = OpVectorTimesScalar %80 %232 %234\n%236 = OpVectorTimesScalar %80 %233 %234\n%238 = OpCompositeConstruct %80 %38 %40 %42\n%237 = OpImageSampleExplicitLod %51 %228 %238 Grad %235 %236\n%239 = OpCompositeExtract %5 %237 0\n%240 = OpAccessChain %63 %25 %35 %36\n%241 = OpLoad %21 %240\n%242 = OpBitcast %5 %241\n%243 = OpFAdd %5 %242 %239\n%244 = OpBitcast %21 %243\n%245 = OpAccessChain %63 %25 %35 %36\nOpStore %245 %244\nOpControlBarrier %143 %143 %144\n%246 = OpLoad %6 %8\n%247 = OpLoad %26 %29\n%250 = OpSampledImage %249 %246 %247\n%251 = OpCompositeConstruct %52 %38 %40\n%252 = OpGroupNonUniformQuadSwap %52 %55 %251 %35\n%253 = OpGroupNonUniformQuadSwap %52 %55 %251 %57\n%254 = OpFSub %52 %251 %252\n%255 = OpFSub %52 %251 %253\n%257 = OpCompositeConstruct %52 %38 %40\n%256 = OpImageSampleDrefExplicitLod %5 %250 %257 %44 Grad %254 %255\n%258 = OpCompositeConstruct %51 %256 %256 %256 %256\n%259 = OpCompositeExtract %5 %258 0\n%260 = OpAccessChain %63 %25 %35 %36\n%261 = OpLoad %21 %260\n%262 = OpBitcast %5 %261\n%263 = OpFAdd %5 %262 %259\n%264 = OpBitcast %21 %263\n%265 = OpAccessChain %63 %25 %35 %36\nOpStore %265 %264\n%266 = OpLoad %9 %11\n%267 = OpLoad %26 %29\n%270 = OpSampledImage %269 %266 %267\n%271 = OpCompositeConstruct %52 %38 %40\n%272 = OpGroupNonUniformQuadSwap %52 %55 %271 %35\n%273 = OpGroupNonUniformQuadSwap %52 %55 %271 %57\n%274 = OpFSub %52 %271 %272\n%275 = OpFSub %52 %271 %273\n%277 = OpCompositeConstruct %80 %38 %40 %42\n%276 = OpImageSampleDrefExplicitLod %5 %270 %277 %44 Grad %274 %275\n%278 = OpCompositeConstruct %51 %276 %276 %276 %276\n%279 = OpCompositeExtract %5 %278 0\n%280 = OpAccessChain %63 %25 %35 %36\n%281 = OpLoad %21 %280\n%282 = OpBitcast %5 %281\n%283 = OpFAdd %5 %282 %279\n%284 = OpBitcast %21 %283\n%285 = OpAccessChain %63 %25 %35 %36\nOpStore %285 %284\n%286 = OpLoad %12 %14\n%287 = OpLoad %26 %29\n%290 = OpSampledImage %289 %286 %287\n%291 = OpCompositeConstruct %80 %38 %40 %42\n%292 = OpGroupNonUniformQuadSwap %80 %55 %291 %35\n%293 = OpGroupNonUniformQuadSwap %80 %55 %291 %57\n%294 = OpFSub %80 %291 %292\n%295 = OpFSub %80 %291 %293\n%297 = OpCompositeConstruct %80 %38 %40 %42\n%296 = OpImageSampleDrefExplicitLod %5 %290 %297 %44 Grad %294 %295\n%298 = OpCompositeConstruct %51 %296 %296 %296 %296\n%299 = OpCompositeExtract %5 %298 0\n%300 = OpAccessChain %63 %25 %35 %36\n%301 = OpLoad %21 %300\n%302 = OpBitcast %5 %301\n%303 = OpFAdd %5 %302 %299\n%304 = OpBitcast %21 %303\n%305 = OpAccessChain %63 %25 %35 %36\nOpStore %305 %304\n%306 = OpLoad %15 %17\n%307 = OpLoad %26 %29\n%310 = OpSampledImage %309 %306 %307\n%311 = OpCompositeConstruct %80 %38 %40 %42\n%312 = OpGroupNonUniformQuadSwap %80 %55 %311 %35\n%313 = OpGroupNonUniformQuadSwap %80 %55 %311 %57\n%314 = OpFSub %80 %311 %312\n%315 = OpFSub %80 %311 %313\n%317 = OpCompositeConstruct %51 %38 %40 %42 %44\n%316 = OpImageSampleDrefExplicitLod %5 %310 %317 %44 Grad %314 %315\n%318 = OpCompositeConstruct %51 %316 %316 %316 %316\n%319 = OpCompositeExtract %5 %318 0\n%320 = OpAccessChain %63 %25 %35 %36\n%321 = OpLoad %21 %320\n%322 = OpBitcast %5 %321\n%323 = OpFAdd %5 %322 %319\n%324 = OpBitcast %21 %323\n%325 = OpAccessChain %63 %25 %35 %36\nOpStore %325 %324\nOpControlBarrier %143 %143 %144\n%326 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %35\n%327 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %57\n%328 = OpFSub %5 %327 %326\n%329 = OpAccessChain %63 %25 %35 %36\n%330 = OpLoad %21 %329\n%331 = OpBitcast %5 %330\n%332 = OpFAdd %5 %331 %328\n%333 = OpBitcast %21 %332\n%334 = OpAccessChain %63 %25 %35 %36\nOpStore %334 %333\n%335 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %35\n%336 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %143\n%337 = OpFSub %5 %336 %335\n%338 = OpAccessChain %63 %25 %35 %36\n%339 = OpLoad %21 %338\n%340 = OpBitcast %5 %339\n%341 = OpFAdd %5 %340 %337\n%342 = OpBitcast %21 %341\n%343 = OpAccessChain %63 %25 %35 %36\nOpStore %343 %342\nOpControlBarrier %143 %143 %144\n%344 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %35\n%345 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %57\n%346 = OpFSub %5 %345 %344\n%347 = OpAccessChain %63 %25 %35 %36\n%348 = OpLoad %21 %347\n%349 = OpBitcast %5 %348\n%350 = OpFAdd %5 %349 %346\n%351 = OpBitcast %21 %350\n%352 = OpAccessChain %63 %25 %35 %36\nOpStore %352 %351\n%353 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %35\n%354 = OpGroupNonUniformQuadBroadcast %5 %55 %44 %143\n%355 = OpFSub %5 %354 %353\n%356 = OpAccessChain %63 %25 %35 %36\n%357 = OpLoad %21 %356\n%358 = OpBitcast %5 %357\n%359 = OpFAdd %5 %358 %355\n%360 = OpBitcast %21 %359\n%361 = OpAccessChain %63 %25 %35 %36\nOpStore %361 %360\nOpControlBarrier %143 %143 %144\n%362 = OpGroupNonUniformQuadSwap %5 %55 %44 %35\n%363 = OpFSub %5 %362 %44\n%364 = OpGroupNonUniformQuadSwap %5 %55 %363 %35\n%366 = OpLoad %21 %365\n%367 = OpBitwiseAnd %21 %366 %57\n%369 = OpINotEqual %368 %367 %35\n%370 = OpSelect %5 %369 %364 %363\n%371 = OpAccessChain %63 %25 %35 %36\n%372 = OpLoad %21 %371\n%373 = OpBitcast %5 %372\n%374 = OpFAdd %5 %373 %370\n%375 = OpBitcast %21 %374\n%376 = OpAccessChain %63 %25 %35 %36\nOpStore %376 %375\n%377 = OpGroupNonUniformQuadSwap %5 %55 %44 %57\n%378 = OpFSub %5 %377 %44\n%379 = OpGroupNonUniformQuadSwap %5 %55 %378 %57\n%380 = OpLoad %21 %365\n%381 = OpBitwiseAnd %21 %380 %143\n%382 = OpINotEqual %368 %381 %35\n%383 = OpSelect %5 %382 %379 %378\n%384 = OpAccessChain %63 %25 %35 %36\n%385 = OpLoad %21 %384\n%386 = OpBitcast %5 %385\n%387 = OpFAdd %5 %386 %383\n%388 = OpBitcast %21 %387\n%389 = OpAccessChain %63 %25 %35 %36\nOpStore %389 %388\nOpControlBarrier %143 %143 %144\n%390 = OpLoad %6 %8\n%391 = OpLoad %26 %28\n%392 = OpCompositeConstruct %52 %38 %40\n%394 = OpGroupNonUniformQuadSwap %52 %55 %392 %35\n%395 = OpGroupNonUniformQuadSwap %52 %55 %392 %57\n%396 = OpFSub %52 %394 %392\n%397 = OpFSub %52 %395 %392\n%399 = OpImageQuerySizeLod %398 %390 %400\n%401 = OpConvertSToF %52 %399\n%402 = OpFMul %52 %396 %401\n%403 = OpFMul %52 %397 %401\n%404 = OpDot %5 %402 %402\n%405 = OpDot %5 %403 %403\n%406 = OpExtInst %5 %153 FMax %404 %405\n%407 = OpExtInst %5 %153 Log2 %406\n%408 = OpFMul %5 %407 %409\n%410 = OpImageQueryLevels %393 %390\n%411 = OpConvertSToF %5 %410\n%412 = OpFSub %5 %411 %413\n%414 = OpExtInst %5 %153 FMin %408 %412\n%415 = OpExtInst %5 %153 FMax %414 %50\n%416 = OpAccessChain %63 %25 %35 %36\n%417 = OpLoad %21 %416\n%418 = OpBitcast %5 %417\n%419 = OpFAdd %5 %418 %415\n%420 = OpBitcast %21 %419\n%421 = OpAccessChain %63 %25 %35 %36\nOpStore %421 %420\n%422 = OpLoad %9 %11\n%423 = OpLoad %26 %28\n%424 = OpCompositeConstruct %52 %38 %40\n%425 = OpGroupNonUniformQuadSwap %52 %55 %424 %35\n%426 = OpGroupNonUniformQuadSwap %52 %55 %424 %57\n%427 = OpFSub %52 %425 %424\n%428 = OpFSub %52 %426 %424\n%430 = OpImageQuerySizeLod %429 %422 %400\n%431 = OpVectorShuffle %398 %430 %430 0 1\n%432 = OpConvertSToF %52 %431\n%433 = OpFMul %52 %427 %432\n%434 = OpFMul %52 %428 %432\n%435 = OpDot %5 %433 %433\n%436 = OpDot %5 %434 %434\n%437 = OpExtInst %5 %153 FMax %435 %436\n%438 = OpExtInst %5 %153 Log2 %437\n%439 = OpFMul %5 %438 %409\n%440 = OpImageQueryLevels %393 %422\n%441 = OpConvertSToF %5 %440\n%442 = OpFSub %5 %441 %413\n%443 = OpExtInst %5 %153 FMin %439 %442\n%444 = OpExtInst %5 %153 FMax %443 %50\n%445 = OpAccessChain %63 %25 %35 %36\n%446 = OpLoad %21 %445\n%447 = OpBitcast %5 %446\n%448 = OpFAdd %5 %447 %444\n%449 = OpBitcast %21 %448\n%450 = OpAccessChain %63 %25 %35 %36\nOpStore %450 %449\n%451 = OpLoad %18 %20\n%452 = OpLoad %26 %28\n%453 = OpCompositeConstruct %80 %38 %40 %42\n%454 = OpGroupNonUniformQuadSwap %80 %55 %453 %35\n%455 = OpGroupNonUniformQuadSwap %80 %55 %453 %57\n%456 = OpFSub %80 %454 %453\n%457 = OpFSub %80 %455 %453\n%458 = OpImageQuerySizeLod %429 %451 %400\n%459 = OpConvertSToF %80 %458\n%460 = OpFMul %80 %456 %459\n%461 = OpFMul %80 %457 %459\n%462 = OpDot %5 %460 %460\n%463 = OpDot %5 %461 %461\n%464 = OpExtInst %5 %153 FMax %462 %463\n%465 = OpExtInst %5 %153 Log2 %464\n%466 = OpFMul %5 %465 %409\n%467 = OpImageQueryLevels %393 %451\n%468 = OpConvertSToF %5 %467\n%469 = OpFSub %5 %468 %413\n%470 = OpExtInst %5 %153 FMin %466 %469\n%471 = OpExtInst %5 %153 FMax %470 %50\n%472 = OpAccessChain %63 %25 %35 %36\n%473 = OpLoad %21 %472\n%474 = OpBitcast %5 %473\n%475 = OpFAdd %5 %474 %471\n%476 = OpBitcast %21 %475\n%477 = OpAccessChain %63 %25 %35 %36\nOpStore %477 %476\nOpControlBarrier %143 %143 %144\n%478 = OpLoad %6 %8\n%479 = OpLoad %26 %28\n%480 = OpCompositeConstruct %52 %38 %40\n%481 = OpGroupNonUniformQuadSwap %52 %55 %480 %35\n%482 = OpGroupNonUniformQuadSwap %52 %55 %480 %57\n%483 = OpFSub %52 %481 %480\n%484 = OpFSub %52 %482 %480\n%485 = OpImageQuerySizeLod %398 %478 %400\n%486 = OpConvertSToF %52 %485\n%487 = OpFMul %52 %483 %486\n%488 = OpFMul %52 %484 %486\n%489 = OpDot %5 %487 %487\n%490 = OpDot %5 %488 %488\n%491 = OpExtInst %5 %153 FMax %489 %490\n%492 = OpExtInst %5 %153 Log2 %491\n%493 = OpFMul %5 %492 %409\n%494 = OpExtInst %5 %153 FClamp %493 %495 %496\n%497 = OpAccessChain %63 %25 %35 %36\n%498 = OpLoad %21 %497\n%499 = OpBitcast %5 %498\n%500 = OpFAdd %5 %499 %494\n%501 = OpBitcast %21 %500\n%502 = OpAccessChain %63 %25 %35 %36\nOpStore %502 %501\n%503 = OpLoad %9 %11\n%504 = OpLoad %26 %28\n%505 = OpCompositeConstruct %52 %38 %40\n%506 = OpGroupNonUniformQuadSwap %52 %55 %505 %35\n%507 = OpGroupNonUniformQuadSwap %52 %55 %505 %57\n%508 = OpFSub %52 %506 %505\n%509 = OpFSub %52 %507 %505\n%510 = OpImageQuerySizeLod %429 %503 %400\n%511 = OpVectorShuffle %398 %510 %510 0 1\n%512 = OpConvertSToF %52 %511\n%513 = OpFMul %52 %508 %512\n%514 = OpFMul %52 %509 %512\n%515 = OpDot %5 %513 %513\n%516 = OpDot %5 %514 %514\n%517 = OpExtInst %5 %153 FMax %515 %516\n%518 = OpExtInst %5 %153 Log2 %517\n%519 = OpFMul %5 %518 %409\n%520 = OpExtInst %5 %153 FClamp %519 %495 %496\n%521 = OpAccessChain %63 %25 %35 %36\n%522 = OpLoad %21 %521\n%523 = OpBitcast %5 %522\n%524 = OpFAdd %5 %523 %520\n%525 = OpBitcast %21 %524\n%526 = OpAccessChain %63 %25 %35 %36\nOpStore %526 %525\n%527 = OpLoad %18 %20\n%528 = OpLoad %26 %28\n%529 = OpCompositeConstruct %80 %38 %40 %42\n%530 = OpGroupNonUniformQuadSwap %80 %55 %529 %35\n%531 = OpGroupNonUniformQuadSwap %80 %55 %529 %57\n%532 = OpFSub %80 %530 %529\n%533 = OpFSub %80 %531 %529\n%534 = OpImageQuerySizeLod %429 %527 %400\n%535 = OpConvertSToF %80 %534\n%536 = OpFMul %80 %532 %535\n%537 = OpFMul %80 %533 %535\n%538 = OpDot %5 %536 %536\n%539 = OpDot %5 %537 %537\n%540 = OpExtInst %5 %153 FMax %538 %539\n%541 = OpExtInst %5 %153 Log2 %540\n%542 = OpFMul %5 %541 %409\n%543 = OpExtInst %5 %153 FClamp %542 %495 %496\n%544 = OpAccessChain %63 %25 %35 %36\n%545 = OpLoad %21 %544\n%546 = OpBitcast %5 %545\n%547 = OpFAdd %5 %546 %543\n%548 = OpBitcast %21 %547\n%549 = OpAccessChain %63 %25 %35 %36\nOpStore %549 %548\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/cos.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = cos(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Cos %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/countbits.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(bitCount(A));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 14\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %12\n%12 = OpLabel\n%10 = OpLoad %5 %7\n%11 = OpBitCount %5 %10\nOpStore %9 %11\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/coverage.frag",
    "content": "#version 460\n\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(gl_SampleMaskIn[0u]);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 18\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn SampleMask\nOpDecorate %11 Flat\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Output %5\n%7 = OpVariable %6 Output\n%8 = OpConstant %5 1\n%9 = OpTypeArray %5 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %5\n%14 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %16\n%16 = OpLabel\n%13 = OpAccessChain %12 %11 %14\n%15 = OpLoad %5 %13\nOpStore %7 %15\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/derivative.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float16_t _33 = float16_t(TEXCOORD.x);\n    float16_t _34 = float16_t(TEXCOORD.y);\n    SV_Target.x = ((((dFdxFine(TEXCOORD.x) + dFdxCoarse(TEXCOORD.x)) + float(float16_t(dFdxCoarse(float(_33))))) + float(float16_t(dFdxFine(float(_33))))) + dFdxCoarse(TEXCOORD.x)) + dFdxFine(TEXCOORD.x);\n    SV_Target.y = ((((dFdxFine(TEXCOORD.y) + dFdxCoarse(TEXCOORD.y)) + float(float16_t(dFdxCoarse(float(_34))))) + float(float16_t(dFdxFine(float(_34))))) + dFdxCoarse(TEXCOORD.y)) + dFdxFine(TEXCOORD.y);\n    SV_Target.z = ((((dFdyFine(TEXCOORD.x) + dFdyCoarse(TEXCOORD.x)) + float(float16_t(dFdyCoarse(float(_33))))) + float(float16_t(dFdyFine(float(_33))))) + dFdyCoarse(TEXCOORD.x)) + dFdyFine(TEXCOORD.x);\n    SV_Target.w = ((((dFdyFine(TEXCOORD.y) + dFdyCoarse(TEXCOORD.y)) + float(float16_t(dFdyCoarse(float(_34))))) + float(float16_t(dFdyFine(float(_34))))) + dFdyCoarse(TEXCOORD.y)) + dFdyFine(TEXCOORD.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 100\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DerivativeControl\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%32 = OpTypeFloat 16\n%91 = OpTypePointer Output %5\n%95 = OpConstant %14 2\n%97 = OpConstant %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %98\n%98 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpDPdxCoarse %5 %16\n%21 = OpDPdxCoarse %5 %19\n%22 = OpDPdyCoarse %5 %16\n%23 = OpDPdyCoarse %5 %19\n%24 = OpDPdxFine %5 %16\n%25 = OpDPdxFine %5 %19\n%26 = OpFAdd %5 %24 %20\n%27 = OpFAdd %5 %25 %21\n%28 = OpDPdyFine %5 %16\n%29 = OpDPdyFine %5 %19\n%30 = OpFAdd %5 %28 %22\n%31 = OpFAdd %5 %29 %23\n%33 = OpFConvert %32 %16\n%34 = OpFConvert %32 %19\n%35 = OpFConvert %5 %33\n%36 = OpDPdxCoarse %5 %35\n%37 = OpFConvert %32 %36\n%38 = OpFConvert %5 %34\n%39 = OpDPdxCoarse %5 %38\n%40 = OpFConvert %32 %39\n%41 = OpFConvert %5 %37\n%42 = OpFConvert %5 %40\n%43 = OpFAdd %5 %26 %41\n%44 = OpFAdd %5 %27 %42\n%45 = OpFConvert %5 %33\n%46 = OpDPdyCoarse %5 %45\n%47 = OpFConvert %32 %46\n%48 = OpFConvert %5 %34\n%49 = OpDPdyCoarse %5 %48\n%50 = OpFConvert %32 %49\n%51 = OpFConvert %5 %47\n%52 = OpFConvert %5 %50\n%53 = OpFAdd %5 %30 %51\n%54 = OpFAdd %5 %31 %52\n%55 = OpFConvert %5 %33\n%56 = OpDPdxFine %5 %55\n%57 = OpFConvert %32 %56\n%58 = OpFConvert %5 %34\n%59 = OpDPdxFine %5 %58\n%60 = OpFConvert %32 %59\n%61 = OpFConvert %5 %57\n%62 = OpFConvert %5 %60\n%63 = OpFAdd %5 %43 %61\n%64 = OpFAdd %5 %44 %62\n%65 = OpFConvert %5 %33\n%66 = OpDPdyFine %5 %65\n%67 = OpFConvert %32 %66\n%68 = OpFConvert %5 %34\n%69 = OpDPdyFine %5 %68\n%70 = OpFConvert %32 %69\n%71 = OpFConvert %5 %67\n%72 = OpFConvert %5 %70\n%73 = OpFAdd %5 %53 %71\n%74 = OpFAdd %5 %54 %72\n%75 = OpDPdxCoarse %5 %16\n%76 = OpDPdxCoarse %5 %19\n%77 = OpFAdd %5 %63 %75\n%78 = OpFAdd %5 %64 %76\n%79 = OpDPdyCoarse %5 %16\n%80 = OpDPdyCoarse %5 %19\n%81 = OpFAdd %5 %73 %79\n%82 = OpFAdd %5 %74 %80\n%83 = OpDPdxFine %5 %16\n%84 = OpDPdxFine %5 %19\n%85 = OpFAdd %5 %77 %83\n%86 = OpFAdd %5 %78 %84\n%87 = OpDPdyFine %5 %16\n%88 = OpDPdyFine %5 %19\n%89 = OpFAdd %5 %81 %87\n%90 = OpFAdd %5 %82 %88\n%92 = OpAccessChain %91 %11 %15\nOpStore %92 %85\n%93 = OpAccessChain %91 %11 %18\nOpStore %93 %86\n%94 = OpAccessChain %91 %11 %95\nOpStore %94 %89\n%96 = OpAccessChain %91 %11 %97\nOpStore %96 %90\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/derivative.sm60.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    mediump float _32 = TEXCOORD.x;\n    mediump float _33 = TEXCOORD.y;\n    SV_Target.x = ((dFdxFine(TEXCOORD.x) + dFdxCoarse(TEXCOORD.x)) + dFdxCoarse(_32)) + dFdxFine(_32);\n    SV_Target.y = ((dFdxFine(TEXCOORD.y) + dFdxCoarse(TEXCOORD.y)) + dFdxCoarse(_33)) + dFdxFine(_33);\n    SV_Target.z = ((dFdyFine(TEXCOORD.x) + dFdyCoarse(TEXCOORD.x)) + dFdyCoarse(_32)) + dFdyFine(_32);\n    SV_Target.w = ((dFdyFine(TEXCOORD.y) + dFdyCoarse(TEXCOORD.y)) + dFdyCoarse(_33)) + dFdyFine(_33);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\nOpCapability Shader\nOpCapability DerivativeControl\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\nOpDecorate %32 RelaxedPrecision\nOpDecorate %33 RelaxedPrecision\nOpDecorate %34 RelaxedPrecision\nOpDecorate %35 RelaxedPrecision\nOpDecorate %38 RelaxedPrecision\nOpDecorate %39 RelaxedPrecision\nOpDecorate %42 RelaxedPrecision\nOpDecorate %43 RelaxedPrecision\nOpDecorate %46 RelaxedPrecision\nOpDecorate %47 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%50 = OpTypePointer Output %5\n%54 = OpConstant %14 2\n%56 = OpConstant %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpDPdxCoarse %5 %16\n%21 = OpDPdxCoarse %5 %19\n%22 = OpDPdyCoarse %5 %16\n%23 = OpDPdyCoarse %5 %19\n%24 = OpDPdxFine %5 %16\n%25 = OpDPdxFine %5 %19\n%26 = OpFAdd %5 %24 %20\n%27 = OpFAdd %5 %25 %21\n%28 = OpDPdyFine %5 %16\n%29 = OpDPdyFine %5 %19\n%30 = OpFAdd %5 %28 %22\n%31 = OpFAdd %5 %29 %23\n%32 = OpCopyObject %5 %16\n%33 = OpCopyObject %5 %19\n%34 = OpDPdxCoarse %5 %32\n%35 = OpDPdxCoarse %5 %33\n%36 = OpFAdd %5 %26 %34\n%37 = OpFAdd %5 %27 %35\n%38 = OpDPdyCoarse %5 %32\n%39 = OpDPdyCoarse %5 %33\n%40 = OpFAdd %5 %30 %38\n%41 = OpFAdd %5 %31 %39\n%42 = OpDPdxFine %5 %32\n%43 = OpDPdxFine %5 %33\n%44 = OpFAdd %5 %36 %42\n%45 = OpFAdd %5 %37 %43\n%46 = OpDPdyFine %5 %32\n%47 = OpDPdyFine %5 %33\n%48 = OpFAdd %5 %40 %46\n%49 = OpFAdd %5 %41 %47\n%51 = OpAccessChain %50 %11 %15\nOpStore %51 %44\n%52 = OpAccessChain %50 %11 %18\nOpStore %52 %45\n%53 = OpAccessChain %50 %11 %54\nOpStore %53 %48\n%55 = OpAccessChain %50 %11 %56\nOpStore %55 %49\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/derivative.sm60.native-fp16.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float16_t _33 = float16_t(TEXCOORD.x);\n    float16_t _34 = float16_t(TEXCOORD.y);\n    SV_Target.x = ((dFdxFine(TEXCOORD.x) + dFdxCoarse(TEXCOORD.x)) + float(float16_t(dFdxCoarse(float(_33))))) + float(float16_t(dFdxFine(float(_33))));\n    SV_Target.y = ((dFdxFine(TEXCOORD.y) + dFdxCoarse(TEXCOORD.y)) + float(float16_t(dFdxCoarse(float(_34))))) + float(float16_t(dFdxFine(float(_34))));\n    SV_Target.z = ((dFdyFine(TEXCOORD.x) + dFdyCoarse(TEXCOORD.x)) + float(float16_t(dFdyCoarse(float(_33))))) + float(float16_t(dFdyFine(float(_33))));\n    SV_Target.w = ((dFdyFine(TEXCOORD.y) + dFdyCoarse(TEXCOORD.y)) + float(float16_t(dFdyCoarse(float(_34))))) + float(float16_t(dFdyFine(float(_34))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 84\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DerivativeControl\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%32 = OpTypeFloat 16\n%75 = OpTypePointer Output %5\n%79 = OpConstant %14 2\n%81 = OpConstant %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %82\n%82 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpDPdxCoarse %5 %16\n%21 = OpDPdxCoarse %5 %19\n%22 = OpDPdyCoarse %5 %16\n%23 = OpDPdyCoarse %5 %19\n%24 = OpDPdxFine %5 %16\n%25 = OpDPdxFine %5 %19\n%26 = OpFAdd %5 %24 %20\n%27 = OpFAdd %5 %25 %21\n%28 = OpDPdyFine %5 %16\n%29 = OpDPdyFine %5 %19\n%30 = OpFAdd %5 %28 %22\n%31 = OpFAdd %5 %29 %23\n%33 = OpFConvert %32 %16\n%34 = OpFConvert %32 %19\n%35 = OpFConvert %5 %33\n%36 = OpDPdxCoarse %5 %35\n%37 = OpFConvert %32 %36\n%38 = OpFConvert %5 %34\n%39 = OpDPdxCoarse %5 %38\n%40 = OpFConvert %32 %39\n%41 = OpFConvert %5 %37\n%42 = OpFConvert %5 %40\n%43 = OpFAdd %5 %26 %41\n%44 = OpFAdd %5 %27 %42\n%45 = OpFConvert %5 %33\n%46 = OpDPdyCoarse %5 %45\n%47 = OpFConvert %32 %46\n%48 = OpFConvert %5 %34\n%49 = OpDPdyCoarse %5 %48\n%50 = OpFConvert %32 %49\n%51 = OpFConvert %5 %47\n%52 = OpFConvert %5 %50\n%53 = OpFAdd %5 %30 %51\n%54 = OpFAdd %5 %31 %52\n%55 = OpFConvert %5 %33\n%56 = OpDPdxFine %5 %55\n%57 = OpFConvert %32 %56\n%58 = OpFConvert %5 %34\n%59 = OpDPdxFine %5 %58\n%60 = OpFConvert %32 %59\n%61 = OpFConvert %5 %57\n%62 = OpFConvert %5 %60\n%63 = OpFAdd %5 %43 %61\n%64 = OpFAdd %5 %44 %62\n%65 = OpFConvert %5 %33\n%66 = OpDPdyFine %5 %65\n%67 = OpFConvert %32 %66\n%68 = OpFConvert %5 %34\n%69 = OpDPdyFine %5 %68\n%70 = OpFConvert %32 %69\n%71 = OpFConvert %5 %67\n%72 = OpFConvert %5 %70\n%73 = OpFAdd %5 %53 %71\n%74 = OpFAdd %5 %54 %72\n%76 = OpAccessChain %75 %11 %15\nOpStore %76 %63\n%77 = OpAccessChain %75 %11 %18\nOpStore %77 %64\n%78 = OpAccessChain %75 %11 %79\nOpStore %78 %73\n%80 = OpAccessChain %75 %11 %81\nOpStore %80 %74\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/derivatives.sm66.comp",
    "content": "#version 460\nlayout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;\n\nlayout(set = 0, binding = 0) uniform texture3D _8;\nlayout(set = 0, binding = 0) uniform writeonly image3D _11;\nlayout(set = 0, binding = 0) uniform sampler _14;\n\nvoid main()\n{\n    imageStore(_11, ivec3(uvec3(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, gl_GlobalInvocationID.z)), vec4(texture(sampler3D(_8, _14), vec3((float(gl_GlobalInvocationID.x) + 0.5) * 0.015625, (float(gl_GlobalInvocationID.y) + 0.5) * 0.015625, (float(gl_GlobalInvocationID.z) + 0.5) * 0.015625))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 58\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability ComputeDerivativeGroupQuadsKHR\nOpExtension \"SPV_KHR_compute_shader_derivatives\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 DerivativeGroupQuadsKHR\nOpExecutionMode %3 LocalSize 4 4 4\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 3D 0 0 0 2 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeSampler\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeInt 32 0\n%16 = OpTypeVector %15 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %15\n%21 = OpConstant %15 0\n%24 = OpConstant %15 1\n%27 = OpConstant %15 2\n%33 = OpConstant %5 0.5\n%37 = OpConstant %5 0.015625\n%42 = OpTypeSampledImage %6\n%44 = OpConstant %5 0\n%45 = OpTypeVector %5 4\n%47 = OpTypeVector %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %56\n%56 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %15 %20\n%23 = OpAccessChain %19 %18 %24\n%25 = OpLoad %15 %23\n%26 = OpAccessChain %19 %18 %27\n%28 = OpLoad %15 %26\n%29 = OpConvertUToF %5 %22\n%30 = OpConvertUToF %5 %25\n%31 = OpConvertUToF %5 %28\n%32 = OpFAdd %5 %29 %33\n%34 = OpFAdd %5 %30 %33\n%35 = OpFAdd %5 %31 %33\n%36 = OpFMul %5 %32 %37\n%38 = OpFMul %5 %34 %37\n%39 = OpFMul %5 %35 %37\n%40 = OpLoad %6 %8\n%41 = OpLoad %12 %14\n%43 = OpSampledImage %42 %40 %41\n%48 = OpCompositeConstruct %47 %36 %38 %39\n%46 = OpImageSampleImplicitLod %45 %43 %48 None\n%49 = OpCompositeExtract %5 %46 0\n%50 = OpCompositeExtract %5 %46 1\n%51 = OpCompositeExtract %5 %46 2\n%52 = OpCompositeExtract %5 %46 3\n%53 = OpLoad %9 %11\n%54 = OpCompositeConstruct %16 %22 %25 %28\n%55 = OpCompositeConstruct %45 %49 %50 %51 %52\nOpImageWrite %53 %54 %55\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/discard.demote-to-helper.frag",
    "content": "#version 460\n#extension GL_EXT_demote_to_helper_invocation : require\n\nlayout(location = 0) in vec2 TEXCOORD;\n\nvoid main()\n{\n    if (TEXCOORD.x > 10.0)\n    {\n        demote;\n    }\n    else\n    {\n        if (TEXCOORD.y > 20.0)\n        {\n            demote;\n        }\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpCapability DemoteToHelperInvocation\nOpExtension \"SPV_EXT_demote_to_helper_invocation\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpDecorate %8 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Input %5\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 0\n%14 = OpTypeBool\n%16 = OpConstant %5 10\n%18 = OpConstant %11 1\n%21 = OpConstant %5 20\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %22\n%22 = OpLabel\n%10 = OpAccessChain %9 %8 %12\n%13 = OpLoad %5 %10\n%15 = OpFOrdGreaterThan %14 %13 %16\nOpSelectionMerge %27 None\nOpBranchConditional %15 %26 %23\n%26 = OpLabel\nOpDemoteToHelperInvocation\nOpBranch %27\n%23 = OpLabel\n%17 = OpAccessChain %9 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpFOrdGreaterThan %14 %19 %21\nOpSelectionMerge %25 None\nOpBranchConditional %20 %24 %25\n%24 = OpLabel\nOpDemoteToHelperInvocation\nOpBranch %25\n%25 = OpLabel\nOpBranch %27\n%27 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/discard.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec2 TEXCOORD;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (TEXCOORD.x > 10.0)\n    {\n        discard_state = true;\n    }\n    else\n    {\n        if (TEXCOORD.y > 20.0)\n        {\n            discard_state = true;\n        }\n    }\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %18 \"discard_state\"\nOpName %32 \"discard_exit\"\nOpDecorate %8 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Input %5\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 0\n%14 = OpTypeBool\n%16 = OpConstant %5 10\n%17 = OpTypePointer Private %14\n%18 = OpVariable %17 Private\n%19 = OpConstantFalse %14\n%21 = OpConstant %11 1\n%24 = OpConstant %5 20\n%31 = OpConstantTrue %14\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %18 %19\nOpBranch %25\n%25 = OpLabel\n%10 = OpAccessChain %9 %8 %12\n%13 = OpLoad %5 %10\n%15 = OpFOrdGreaterThan %14 %13 %16\nOpSelectionMerge %30 None\nOpBranchConditional %15 %29 %26\n%29 = OpLabel\nOpStore %18 %31\nOpBranch %30\n%26 = OpLabel\n%20 = OpAccessChain %9 %8 %21\n%22 = OpLoad %5 %20\n%23 = OpFOrdGreaterThan %14 %22 %24\nOpSelectionMerge %28 None\nOpBranchConditional %23 %27 %28\n%27 = OpLabel\nOpStore %18 %31\nOpBranch %28\n%28 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%38 = OpFunctionCall %1 %32\nOpReturn\nOpFunctionEnd\n%32 = OpFunction %1 None %2\n%33 = OpLabel\n%36 = OpLoad %14 %18\nOpSelectionMerge %35 None\nOpBranchConditional %36 %34 %35\n%34 = OpLabel\nOpKill\n%35 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/dispatch-rays-dimensions.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform writeonly uimage2D UTex;\n\nvoid main()\n{\n    imageStore(UTex, ivec2(uvec2(gl_LaunchSizeEXT.x, gl_LaunchSizeEXT.y)), uvec4(1u, 2u, 3u, 1u));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %11\nOpName %3 \"main\"\nOpName %8 \"UTex\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 BuiltIn LaunchSizeKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 3\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %5\n%14 = OpConstant %5 0\n%17 = OpConstant %5 1\n%20 = OpConstant %5 2\n%21 = OpConstant %5 3\n%22 = OpTypeVector %5 2\n%24 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%13 = OpAccessChain %12 %11 %14\n%15 = OpLoad %5 %13\n%16 = OpAccessChain %12 %11 %17\n%18 = OpLoad %5 %16\n%19 = OpLoad %6 %8\n%23 = OpCompositeConstruct %22 %15 %18\n%25 = OpCompositeConstruct %24 %17 %20 %21 %17\nOpImageWrite %19 %23 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/dispatch-rays-index.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform writeonly uimage2D UTex;\n\nvoid main()\n{\n    imageStore(UTex, ivec2(uvec2(gl_LaunchIDEXT.x, gl_LaunchIDEXT.y)), uvec4(1u, 2u, 3u, 1u));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %11\nOpName %3 \"main\"\nOpName %8 \"UTex\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 BuiltIn LaunchIdKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 3\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %5\n%14 = OpConstant %5 0\n%17 = OpConstant %5 1\n%20 = OpConstant %5 2\n%21 = OpConstant %5 3\n%22 = OpTypeVector %5 2\n%24 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%13 = OpAccessChain %12 %11 %14\n%15 = OpLoad %5 %13\n%16 = OpAccessChain %12 %11 %17\n%18 = OpLoad %5 %16\n%19 = OpLoad %6 %8\n%23 = OpCompositeConstruct %22 %15 %18\n%25 = OpCompositeConstruct %24 %17 %20 %21 %17\nOpImageWrite %19 %23 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/dot2.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec2 A;\nlayout(location = 0, component = 2) in vec2 B;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = dot(vec2(A.x, A.y), vec2(B.x, B.y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 0\nOpDecorate %9 Component 2\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %5\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %8 %15\n%21 = OpLoad %5 %20\n%22 = OpAccessChain %12 %8 %18\n%23 = OpLoad %5 %22\n%25 = OpCompositeConstruct %6 %21 %23\n%26 = OpCompositeConstruct %6 %16 %19\n%24 = OpDot %5 %25 %26\nOpStore %11 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/dot3.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec3 A;\nlayout(location = 1) in vec3 B;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = dot(vec3(A.x, A.y, A.z), vec3(B.x, B.y, B.z));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %5\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %8 %15\n%24 = OpLoad %5 %23\n%25 = OpAccessChain %12 %8 %18\n%26 = OpLoad %5 %25\n%27 = OpAccessChain %12 %8 %21\n%28 = OpLoad %5 %27\n%30 = OpCompositeConstruct %6 %24 %26 %28\n%31 = OpCompositeConstruct %6 %16 %19 %22\n%29 = OpDot %5 %30 %31\nOpStore %11 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/dot4.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 1) in vec4 B;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = dot(vec4(A.x, A.y, A.z, A.w), vec4(B.x, B.y, B.z, B.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %5\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%24 = OpConstant %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %9 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %12 %8 %15\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %12 %8 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %12 %8 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %12 %8 %24\n%33 = OpLoad %5 %32\n%35 = OpCompositeConstruct %6 %27 %29 %31 %33\n%36 = OpCompositeConstruct %6 %16 %19 %22 %25\n%34 = OpDot %5 %35 %36\nOpStore %11 %34\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/eval-centroid.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec2 TEXCOORD[2];\nlayout(location = 0, component = 2) in float UV;\nlayout(location = 0, component = 3) in float UV_1[2];\nlayout(location = 2) flat in uint A;\nlayout(location = 2, component = 1) flat in uint B;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    float _38 = interpolateAtCentroid(UV_1[A]) + interpolateAtCentroid(UV);\n    SV_Target.x = (interpolateAtCentroid(TEXCOORD[B].x) + interpolateAtCentroid(TEXCOORD[A].x)) + _38;\n    SV_Target.y = (interpolateAtCentroid(TEXCOORD[B].y) + interpolateAtCentroid(TEXCOORD[A].y)) + _38;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability InterpolationFunction\n%26 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %13 %16 %18 %19 %21\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %13 \"UV\"\nOpName %16 \"UV_1\"\nOpName %18 \"A\"\nOpName %19 \"B\"\nOpName %21 \"SV_Target\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 2\nOpDecorate %16 Location 0\nOpDecorate %16 Component 3\nOpDecorate %18 Flat\nOpDecorate %18 Location 2\nOpDecorate %19 Flat\nOpDecorate %19 Location 2\nOpDecorate %19 Component 1\nOpDecorate %21 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 2\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %5\n%13 = OpVariable %12 Input\n%14 = OpTypeArray %5 %8\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %7\n%18 = OpVariable %17 Input\n%19 = OpVariable %17 Input\n%20 = OpTypePointer Output %6\n%21 = OpVariable %20 Output\n%25 = OpConstant %7 0\n%29 = OpConstant %7 1\n%43 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%22 = OpLoad %7 %19\n%23 = OpLoad %7 %18\n%24 = OpAccessChain %12 %11 %23 %25\n%27 = OpExtInst %5 %26 InterpolateAtCentroid %24\n%28 = OpAccessChain %12 %11 %23 %29\n%30 = OpExtInst %5 %26 InterpolateAtCentroid %28\n%31 = OpAccessChain %12 %11 %22 %25\n%32 = OpExtInst %5 %26 InterpolateAtCentroid %31\n%33 = OpAccessChain %12 %11 %22 %29\n%34 = OpExtInst %5 %26 InterpolateAtCentroid %33\n%35 = OpExtInst %5 %26 InterpolateAtCentroid %13\n%36 = OpAccessChain %12 %16 %23\n%37 = OpExtInst %5 %26 InterpolateAtCentroid %36\n%38 = OpFAdd %5 %37 %35\n%39 = OpFAdd %5 %32 %27\n%40 = OpFAdd %5 %39 %38\n%41 = OpFAdd %5 %34 %30\n%42 = OpFAdd %5 %41 %38\n%44 = OpAccessChain %43 %21 %25\nOpStore %44 %40\n%45 = OpAccessChain %43 %21 %29\nOpStore %45 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/eval-sample-index.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 1) flat in int SAMPLE;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _16 = uint(SAMPLE);\n    SV_Target.x = interpolateAtSample(TEXCOORD.x, _16) + interpolateAtSample(TEXCOORD.x, 1u);\n    SV_Target.y = interpolateAtSample(TEXCOORD.y, _16) + interpolateAtSample(TEXCOORD.y, 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability InterpolationFunction\n%20 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11 %13\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SAMPLE\"\nOpName %13 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %11 Flat\nOpDecorate %11 Location 1\nOpDecorate %13 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeInt 32 1\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Output %6\n%13 = OpVariable %12 Output\n%15 = OpTypeInt 32 0\n%17 = OpTypePointer Input %5\n%19 = OpConstant %15 0\n%21 = OpConstant %15 1\n%31 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%14 = OpLoad %9 %11\n%16 = OpBitcast %15 %14\n%18 = OpAccessChain %17 %8 %19\n%22 = OpExtInst %5 %20 InterpolateAtSample %18 %21\n%23 = OpAccessChain %17 %8 %21\n%24 = OpExtInst %5 %20 InterpolateAtSample %23 %21\n%25 = OpAccessChain %17 %8 %19\n%26 = OpExtInst %5 %20 InterpolateAtSample %25 %16\n%27 = OpAccessChain %17 %8 %21\n%28 = OpExtInst %5 %20 InterpolateAtSample %27 %16\n%29 = OpFAdd %5 %26 %22\n%30 = OpFAdd %5 %28 %24\n%32 = OpAccessChain %31 %13 %19\nOpStore %32 %29\n%33 = OpAccessChain %31 %13 %21\nOpStore %33 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/eval-snapped.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 1) flat in ivec2 CODE;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _20 = uint(CODE.x);\n    uint _24 = uint(CODE.y);\n    SV_Target.x = interpolateAtOffset(TEXCOORD.x, vec2(float(int(uint(bitfieldExtract(int(_20), int(0u), int(4u))))) * 0.0625, float(int(uint(bitfieldExtract(int(_24), int(0u), int(4u))))) * 0.0625)) + interpolateAtOffset(TEXCOORD.x, vec2(-0.4375, 0.25));\n    SV_Target.y = interpolateAtOffset(TEXCOORD.y, vec2(float(int(uint(bitfieldExtract(int(_20), int(0u), int(4u))))) * 0.0625, float(int(uint(bitfieldExtract(int(_24), int(0u), int(4u))))) * 0.0625)) + interpolateAtOffset(TEXCOORD.y, vec2(-0.4375, 0.25));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability InterpolationFunction\n%27 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %12 %14\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %12 \"CODE\"\nOpName %14 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %12 Flat\nOpDecorate %12 Location 1\nOpDecorate %14 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeInt 32 1\n%10 = OpTypeVector %9 2\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpTypePointer Input %9\n%17 = OpTypeInt 32 0\n%18 = OpConstant %17 0\n%22 = OpConstant %17 1\n%25 = OpTypePointer Input %5\n%28 = OpConstant %5 -0.4375\n%29 = OpConstant %5 0.25\n%30 = OpConstantComposite %6 %28 %29\n%36 = OpConstant %17 4\n%39 = OpConstant %5 0.0625\n%56 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%16 = OpAccessChain %15 %12 %18\n%19 = OpLoad %9 %16\n%20 = OpBitcast %17 %19\n%21 = OpAccessChain %15 %12 %22\n%23 = OpLoad %9 %21\n%24 = OpBitcast %17 %23\n%26 = OpAccessChain %25 %8 %18\n%31 = OpExtInst %5 %27 InterpolateAtOffset %26 %30\n%32 = OpAccessChain %25 %8 %22\n%33 = OpExtInst %5 %27 InterpolateAtOffset %32 %30\n%34 = OpAccessChain %25 %8 %18\n%35 = OpBitFieldSExtract %17 %20 %18 %36\n%37 = OpConvertSToF %5 %35\n%38 = OpFMul %5 %37 %39\n%40 = OpBitFieldSExtract %17 %24 %18 %36\n%41 = OpConvertSToF %5 %40\n%42 = OpFMul %5 %41 %39\n%43 = OpCompositeConstruct %6 %38 %42\n%44 = OpExtInst %5 %27 InterpolateAtOffset %34 %43\n%45 = OpAccessChain %25 %8 %22\n%46 = OpBitFieldSExtract %17 %20 %18 %36\n%47 = OpConvertSToF %5 %46\n%48 = OpFMul %5 %47 %39\n%49 = OpBitFieldSExtract %17 %24 %18 %36\n%50 = OpConvertSToF %5 %49\n%51 = OpFMul %5 %50 %39\n%52 = OpCompositeConstruct %6 %48 %51\n%53 = OpExtInst %5 %27 InterpolateAtOffset %45 %52\n%54 = OpFAdd %5 %44 %31\n%55 = OpFAdd %5 %53 %33\n%57 = OpAccessChain %56 %14 %18\nOpStore %57 %54\n%58 = OpAccessChain %56 %14 %22\nOpStore %58 %55\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/exp.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = exp2(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Exp2 %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/f16-to-f32.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = unpackHalf2x16(A).x;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 18\n; Schema: 0\nOpCapability Shader\n%12 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%13 = OpTypeVector %8 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %16\n%16 = OpLabel\n%11 = OpLoad %5 %7\n%14 = OpExtInst %13 %12 UnpackHalf2x16 %11\n%15 = OpCompositeExtract %8 %14 0\nOpStore %10 %15\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/f32-to-f16.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in float A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = packHalf2x16(vec2(A, 0.0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 19\n; Schema: 0\nOpCapability Shader\n%12 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeInt 32 0\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%14 = OpConstant %5 0\n%15 = OpTypeVector %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %17\n%17 = OpLabel\n%11 = OpLoad %5 %7\n%16 = OpCompositeConstruct %15 %11 %14\n%13 = OpExtInst %8 %12 PackHalf2x16 %16\nOpStore %10 %13\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/fabs.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = abs(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 FAbs %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbithi-16.sm62.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) flat in mediump uint A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint16_t _12 = uint16_t(A);\n    uint _15 = uint(findMSB(uint(_12)));\n    uint _21 = (_15 == 4294967295u) ? 4294967295u : (15u - _15);\n    SV_Target = uint(findMSB(uint(_12)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\n%13 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 RelaxedPrecision\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%11 = OpTypeInt 16 0\n%16 = OpTypeBool\n%18 = OpConstant %5 4294967295\n%20 = OpConstant %5 15\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpUConvert %11 %10\n%14 = OpUConvert %5 %12\n%15 = OpExtInst %5 %13 FindUMsb %14\n%17 = OpIEqual %16 %15 %18\n%19 = OpISub %5 %20 %15\n%21 = OpSelect %5 %17 %18 %19\n%22 = OpISub %5 %20 %21\n%23 = OpIEqual %16 %21 %18\n%24 = OpUConvert %5 %12\n%25 = OpExtInst %5 %13 FindUMsb %24\nOpStore %9 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbithi-64.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0, component = 1) flat in uint B;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint64_t _18 = uint64_t(A) | (uint64_t(B) << 32ul);\n    uvec2 _22 = uvec2(findMSB(unpackUint2x32(_18)));\n    uint _27 = uint(max(int(_22.x), int(_22.y | 32u)));\n    uint _33 = (_27 == 4294967295u) ? 4294967295u : (63u - _27);\n    uvec2 _37 = uvec2(findMSB(unpackUint2x32(_18)));\n    SV_Target = uint(max(int(_37.x), int(_37.y | 32u)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\n%19 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %8 \"B\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %8 Component 1\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%13 = OpTypeInt 64 0\n%17 = OpConstant %13 32\n%20 = OpTypeVector %5 2\n%26 = OpConstant %5 32\n%28 = OpTypeBool\n%30 = OpConstant %5 4294967295\n%32 = OpConstant %5 63\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%11 = OpLoad %5 %8\n%12 = OpLoad %5 %7\n%14 = OpUConvert %13 %12\n%15 = OpUConvert %13 %11\n%16 = OpShiftLeftLogical %13 %15 %17\n%18 = OpBitwiseOr %13 %14 %16\n%21 = OpBitcast %20 %18\n%22 = OpExtInst %20 %19 FindUMsb %21\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpCompositeExtract %5 %22 1\n%25 = OpBitwiseOr %5 %24 %26\n%27 = OpExtInst %5 %19 SMax %23 %25\n%29 = OpIEqual %28 %27 %30\n%31 = OpISub %5 %32 %27\n%33 = OpSelect %5 %29 %30 %31\n%34 = OpISub %5 %32 %33\n%35 = OpIEqual %28 %33 %30\n%36 = OpBitcast %20 %18\n%37 = OpExtInst %20 %19 FindUMsb %36\n%38 = OpCompositeExtract %5 %37 0\n%39 = OpCompositeExtract %5 %37 1\n%40 = OpBitwiseOr %5 %39 %26\n%41 = OpExtInst %5 %19 SMax %38 %40\nOpStore %10 %41\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbithi.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _12 = uint(findMSB(A));\n    uint _18 = (_12 == 4294967295u) ? 4294967295u : (31u - _12);\n    SV_Target = uint(findMSB(A));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 24\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%13 = OpTypeBool\n%15 = OpConstant %5 4294967295\n%17 = OpConstant %5 31\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %22\n%22 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 FindUMsb %10\n%14 = OpIEqual %13 %12 %15\n%16 = OpISub %5 %17 %12\n%18 = OpSelect %5 %14 %15 %16\n%19 = OpISub %5 %17 %18\n%20 = OpIEqual %13 %18 %15\n%21 = OpExtInst %5 %11 FindUMsb %10\nOpStore %9 %21\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbitlo-16.sm62.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) flat in mediump uint A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(findLSB(uint(uint16_t(A))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 18\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\n%13 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 RelaxedPrecision\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%11 = OpTypeInt 16 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %16\n%16 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpUConvert %11 %10\n%14 = OpUConvert %5 %12\n%15 = OpExtInst %5 %13 FindILsb %14\nOpStore %9 %15\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbitlo-64.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0, component = 1) flat in uint B;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uvec2 _22 = uvec2(findLSB(unpackUint2x32(uint64_t(A) | (uint64_t(B) << 32ul))));\n    SV_Target = min(_22.x, (_22.y | 32u));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\n%19 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %8 \"B\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %8 Component 1\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%13 = OpTypeInt 64 0\n%17 = OpConstant %13 32\n%20 = OpTypeVector %5 2\n%26 = OpConstant %5 32\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%11 = OpLoad %5 %8\n%12 = OpLoad %5 %7\n%14 = OpUConvert %13 %12\n%15 = OpUConvert %13 %11\n%16 = OpShiftLeftLogical %13 %15 %17\n%18 = OpBitwiseOr %13 %14 %16\n%21 = OpBitcast %20 %18\n%22 = OpExtInst %20 %19 FindILsb %21\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpCompositeExtract %5 %22 1\n%25 = OpBitwiseOr %5 %24 %26\n%27 = OpExtInst %5 %19 UMin %23 %25\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbitlo.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(findLSB(A));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 FindILsb %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbitshi-16.sm62.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) flat in mediump int A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint16_t _12 = uint16_t(A);\n    uint _16 = uint(findMSB(int(uint(int16_t(_12)))));\n    uint _22 = (_16 == 4294967295u) ? 4294967295u : (15u - _16);\n    SV_Target = int(uint(findMSB(int(uint(int16_t(_12))))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\n%13 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 RelaxedPrecision\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%11 = OpTypeInt 16 0\n%14 = OpTypeInt 32 0\n%17 = OpTypeBool\n%19 = OpConstant %14 4294967295\n%21 = OpConstant %14 15\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpSConvert %11 %10\n%15 = OpSConvert %14 %12\n%16 = OpExtInst %14 %13 FindSMsb %15\n%18 = OpIEqual %17 %16 %19\n%20 = OpISub %14 %21 %16\n%22 = OpSelect %14 %18 %19 %20\n%23 = OpISub %14 %21 %22\n%24 = OpIEqual %17 %22 %19\n%25 = OpSConvert %14 %12\n%26 = OpExtInst %14 %13 FindSMsb %25\n%27 = OpBitcast %5 %26\nOpStore %9 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbitshi-64.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n\nlayout(location = 0) flat in uint A;\nlayout(location = 0, component = 1) flat in uint B;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint64_t _19 = (uint64_t(B) << 32ul) | uint64_t(A);\n    uvec2 _22 = unpackUint2x32(_19);\n    uvec2 _29 = uvec2(findMSB(_22 ^ uvec2(ivec2(int(_22.y) >> 31))));\n    uint _34 = uint(max(int(_29.x), int(_29.y | 32u)));\n    uint _40 = (_34 == 4294967295u) ? 4294967295u : (63u - _34);\n    uvec2 _43 = unpackUint2x32(_19);\n    uvec2 _48 = uvec2(findMSB(_43 ^ uvec2(ivec2(int(_43.y) >> 31))));\n    SV_Target = int(uint(max(int(_48.x), int(_48.y | 32u))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\n%20 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %8 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %8 Component 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypeInt 32 1\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%14 = OpTypeInt 64 0\n%17 = OpConstant %14 32\n%21 = OpTypeVector %5 2\n%25 = OpConstant %9 31\n%27 = OpTypeVector %9 2\n%33 = OpConstant %5 32\n%35 = OpTypeBool\n%37 = OpConstant %5 4294967295\n%39 = OpConstant %5 63\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%12 = OpLoad %5 %8\n%13 = OpLoad %5 %7\n%15 = OpUConvert %14 %12\n%16 = OpShiftLeftLogical %14 %15 %17\n%18 = OpUConvert %14 %13\n%19 = OpBitwiseOr %14 %16 %18\n%22 = OpBitcast %21 %19\n%23 = OpCompositeExtract %5 %22 1\n%24 = OpShiftRightArithmetic %9 %23 %25\n%28 = OpCompositeConstruct %27 %24 %24\n%26 = OpBitwiseXor %21 %22 %28\n%29 = OpExtInst %21 %20 FindUMsb %26\n%30 = OpCompositeExtract %5 %29 0\n%31 = OpCompositeExtract %5 %29 1\n%32 = OpBitwiseOr %5 %31 %33\n%34 = OpExtInst %5 %20 SMax %30 %32\n%36 = OpIEqual %35 %34 %37\n%38 = OpISub %5 %39 %34\n%40 = OpSelect %5 %36 %37 %38\n%41 = OpISub %5 %39 %40\n%42 = OpIEqual %35 %40 %37\n%43 = OpBitcast %21 %19\n%44 = OpCompositeExtract %5 %43 1\n%45 = OpShiftRightArithmetic %9 %44 %25\n%47 = OpCompositeConstruct %27 %45 %45\n%46 = OpBitwiseXor %21 %43 %47\n%48 = OpExtInst %21 %20 FindUMsb %46\n%49 = OpCompositeExtract %5 %48 0\n%50 = OpCompositeExtract %5 %48 1\n%51 = OpBitwiseOr %5 %50 %33\n%52 = OpExtInst %5 %20 SMax %49 %51\n%53 = OpBitcast %9 %52\nOpStore %11 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/firstbitshi.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in int A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint _12 = uint(A);\n    uint _14 = uint(findMSB(int(_12)));\n    uint _20 = (_14 == 4294967295u) ? 4294967295u : (31u - _14);\n    SV_Target = int(uint(findMSB(int(_12))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\n%13 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%11 = OpTypeInt 32 0\n%15 = OpTypeBool\n%17 = OpConstant %11 4294967295\n%19 = OpConstant %11 31\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpBitcast %11 %10\n%14 = OpExtInst %11 %13 FindSMsb %12\n%16 = OpIEqual %15 %14 %17\n%18 = OpISub %11 %19 %14\n%20 = OpSelect %11 %16 %17 %18\n%21 = OpISub %11 %19 %20\n%22 = OpIEqual %15 %20 %17\n%23 = OpExtInst %11 %13 FindSMsb %12\n%24 = OpBitcast %5 %23\nOpStore %9 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/flattened_thread_id_in_group.comp",
    "content": "#version 460\nlayout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(gl_LocalInvocationIndex), uvec4(floatBitsToUint(10.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 20\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %11\nOpExecutionMode %3 LocalSize 2 2 2\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%13 = OpTypeFloat 32\n%14 = OpConstant %13 10\n%16 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %18\n%18 = OpLabel\n%9 = OpLoad %6 %8\n%12 = OpLoad %5 %11\n%15 = OpBitcast %5 %14\n%17 = OpCompositeConstruct %16 %15 %15 %15 %15\nOpImageWrite %9 %12 %17\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/fma.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec3 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = float(fma(double(A.x), double(A.y), double(A.z)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 31\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\n%26 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%22 = OpTypeFloat 64\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %29\n%29 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%23 = OpFConvert %22 %15\n%24 = OpFConvert %22 %18\n%25 = OpFConvert %22 %21\n%27 = OpExtInst %22 %26 Fma %23 %24 %25\n%28 = OpFConvert %5 %27\nOpStore %10 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/fmad-precise.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec3 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    precise float _22 = A.x * A.y;\n    precise float _23 = _22 + A.z;\n    SV_Target = _23;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\nOpDecorate %22 NoContraction\nOpDecorate %23 NoContraction\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpFMul %5 %15 %18\n%23 = OpFAdd %5 %22 %21\nOpStore %10 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/fmad.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec3 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = fma(A.x, A.y, A.z);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\n%22 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%23 = OpExtInst %5 %22 Fma %15 %18 %21\nOpStore %10 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/fmax.frag",
    "content": "#version 460\n#extension GL_EXT_spirv_intrinsics : require\n\nlayout(location = 0) in vec2 A;\nlayout(location = 0) out float SV_Target;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 80) float spvNMax(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec2 spvNMax(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec3 spvNMax(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec4 spvNMax(vec4, vec4);\n\nvoid main()\n{\n    SV_Target = spvNMax(A.x, A.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\nOpCapability Shader\n%19 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %21\n%21 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%20 = OpExtInst %5 %19 NMax %15 %18\nOpStore %10 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/fmin.frag",
    "content": "#version 460\n#extension GL_EXT_spirv_intrinsics : require\n\nlayout(location = 0) in vec2 A;\nlayout(location = 0) out float SV_Target;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float spvNMin(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec2 spvNMin(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec3 spvNMin(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec4 spvNMin(vec4, vec4);\n\nvoid main()\n{\n    SV_Target = spvNMin(A.x, A.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\nOpCapability Shader\n%19 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %21\n%21 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%20 = OpExtInst %5 %19 NMin %15 %18\nOpStore %10 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/frc.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = fract(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Fract %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/get-dimensions-w-only.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture1D _8;\nlayout(set = 0, binding = 1) uniform texture1DArray _11;\nlayout(set = 0, binding = 2) uniform texture2D _14;\nlayout(set = 0, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 4) uniform texture2DMS _20;\nlayout(set = 0, binding = 5) uniform texture2DMSArray _23;\nlayout(set = 0, binding = 6) uniform texture3D _26;\nlayout(set = 0, binding = 7) uniform textureCube _29;\nlayout(set = 0, binding = 8) uniform textureCubeArray _32;\n\nlayout(location = 0) flat in uint LEVEL;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (((((((uint(textureQueryLevels(_11)) + uint(textureQueryLevels(_8))) + uint(textureQueryLevels(_14))) + uint(textureQueryLevels(_17))) + uint(textureSamples(_20))) + uint(textureSamples(_23))) + uint(textureQueryLevels(_26))) + uint(textureQueryLevels(_29))) + uint(textureQueryLevels(_32));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 69\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpCapability ImageQuery\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %35 %37\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %35 \"LEVEL\"\nOpName %37 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 7\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 8\nOpDecorate %35 Flat\nOpDecorate %35 Location 0\nOpDecorate %37 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%31 = OpTypePointer UniformConstant %30\n%32 = OpVariable %31 UniformConstant\n%33 = OpTypeInt 32 0\n%34 = OpTypePointer Input %33\n%35 = OpVariable %34 Input\n%36 = OpTypePointer Output %33\n%37 = OpVariable %36 Output\n%49 = OpTypeVector %33 2\n%54 = OpTypeVector %33 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %67\n%67 = OpLabel\n%38 = OpLoad %30 %32\n%39 = OpLoad %27 %29\n%40 = OpLoad %24 %26\n%41 = OpLoad %21 %23\n%42 = OpLoad %18 %20\n%43 = OpLoad %15 %17\n%44 = OpLoad %12 %14\n%45 = OpLoad %9 %11\n%46 = OpLoad %6 %8\n%47 = OpLoad %33 %35\n%48 = OpImageQueryLevels %33 %46\n%50 = OpImageQueryLevels %33 %45\n%51 = OpIAdd %33 %50 %48\n%52 = OpImageQueryLevels %33 %44\n%53 = OpIAdd %33 %51 %52\n%55 = OpImageQueryLevels %33 %43\n%56 = OpIAdd %33 %53 %55\n%57 = OpImageQuerySamples %33 %42\n%58 = OpIAdd %33 %56 %57\n%59 = OpImageQuerySamples %33 %41\n%60 = OpIAdd %33 %58 %59\n%61 = OpImageQueryLevels %33 %40\n%62 = OpIAdd %33 %60 %61\n%63 = OpImageQueryLevels %33 %39\n%64 = OpIAdd %33 %62 %63\n%65 = OpImageQueryLevels %33 %38\n%66 = OpIAdd %33 %64 %65\nOpStore %37 %66\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/get-dimensions-xyz-only.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture1D _8;\nlayout(set = 0, binding = 1) uniform texture1DArray _11;\nlayout(set = 0, binding = 2) uniform texture2D _14;\nlayout(set = 0, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 4) uniform texture2DMS _20;\nlayout(set = 0, binding = 5) uniform texture2DMSArray _23;\nlayout(set = 0, binding = 6) uniform texture3D _26;\nlayout(set = 0, binding = 7) uniform textureCube _29;\nlayout(set = 0, binding = 8) uniform textureCubeArray _32;\nlayout(set = 0, binding = 9) uniform samplerBuffer _35;\nlayout(set = 0, binding = 10) uniform usamplerBuffer _39;\nlayout(set = 0, binding = 11) uniform usamplerBuffer _40;\nlayout(set = 0, binding = 0) uniform readonly writeonly image1D _43;\nlayout(set = 0, binding = 1) uniform readonly writeonly image1DArray _46;\nlayout(set = 0, binding = 2) uniform readonly writeonly image2D _49;\nlayout(set = 0, binding = 3) uniform readonly writeonly image2DArray _52;\nlayout(set = 0, binding = 6) uniform readonly writeonly image3D _55;\nlayout(set = 0, binding = 9) uniform readonly writeonly imageBuffer _58;\nlayout(set = 0, binding = 10, r32ui) uniform readonly writeonly uimageBuffer _61;\nlayout(set = 0, binding = 11, r32ui) uniform readonly writeonly uimageBuffer _62;\n\nlayout(location = 0) flat in uint LEVEL;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uvec2 _100 = mix(uvec2(0u), uvec2(textureSize(_11, int(LEVEL))), bvec2(LEVEL < uint(textureQueryLevels(_11))));\n    uvec2 _108 = mix(uvec2(0u), uvec2(textureSize(_14, int(LEVEL))), bvec2(LEVEL < uint(textureQueryLevels(_14))));\n    uvec3 _118 = mix(uvec3(0u), uvec3(textureSize(_17, int(LEVEL))), bvec3(LEVEL < uint(textureQueryLevels(_17))));\n    uvec2 _123 = uvec2(textureSize(_20));\n    uvec3 _126 = uvec3(textureSize(_23));\n    uvec3 _134 = mix(uvec3(0u), uvec3(textureSize(_26, int(LEVEL))), bvec3(LEVEL < uint(textureQueryLevels(_26))));\n    uvec2 _143 = mix(uvec2(0u), uvec2(textureSize(_29, int(LEVEL))), bvec2(LEVEL < uint(textureQueryLevels(_29))));\n    uvec3 _151 = mix(uvec3(0u), uvec3(textureSize(_32, int(LEVEL))), bvec3(LEVEL < uint(textureQueryLevels(_32))));\n    uint _156 = uint(textureSize(_35));\n    uint _158 = uint(imageSize(_43));\n    uvec2 _160 = uvec2(imageSize(_46));\n    uvec2 _163 = uvec2(imageSize(_49));\n    uvec3 _166 = uvec3(imageSize(_52));\n    uvec3 _170 = uvec3(imageSize(_55));\n    uint _174 = uint(imageSize(_58));\n    uint _177 = uint(textureSize(_39)) / 4u;\n    uint _181 = uint(imageSize(_61)) / 4u;\n    uint _184 = uint(textureSize(_40)) * 4u;\n    uint _187 = uint(imageSize(_62)) * 4u;\n    uint _215 = (((((((((((((((((((((((((((LEVEL < uint(textureQueryLevels(_8))) ? uint(textureSize(_8, int(LEVEL))) : 0u) + 32u) + _100.y) + _100.x) + _108.y) + _108.x) + _118.y) + _118.x) + _118.z) + _123.y) + _123.x) + _126.y) + _126.x) + _126.z) + _134.y) + _134.x) + _134.z) + _143.y) + _143.x) + _151.y) + _151.x) + _151.z) + (_156 * _156)) + (_158 * _158)) + _160.y) + _160.x) + _163.y;\n    SV_Target = (((((((((((_215 + _163.x) + _166.y) + _166.x) + _166.z) + _170.y) + _170.x) + _170.z) + (_174 * _174)) + (_177 * _177)) + (_181 * _181)) + (_184 * _184)) + (_187 * _187);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 230\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability Image1D\nOpCapability SampledCubeArray\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %64 %66\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %64 \"LEVEL\"\nOpName %66 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 7\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 8\nOpDecorate %35 DescriptorSet 0\nOpDecorate %35 Binding 9\nOpDecorate %39 DescriptorSet 0\nOpDecorate %39 Binding 10\nOpDecorate %40 DescriptorSet 0\nOpDecorate %40 Binding 11\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 0\nOpDecorate %43 NonReadable\nOpDecorate %43 NonWritable\nOpDecorate %46 DescriptorSet 0\nOpDecorate %46 Binding 1\nOpDecorate %46 NonReadable\nOpDecorate %46 NonWritable\nOpDecorate %49 DescriptorSet 0\nOpDecorate %49 Binding 2\nOpDecorate %49 NonReadable\nOpDecorate %49 NonWritable\nOpDecorate %52 DescriptorSet 0\nOpDecorate %52 Binding 3\nOpDecorate %52 NonReadable\nOpDecorate %52 NonWritable\nOpDecorate %55 DescriptorSet 0\nOpDecorate %55 Binding 6\nOpDecorate %55 NonReadable\nOpDecorate %55 NonWritable\nOpDecorate %58 DescriptorSet 0\nOpDecorate %58 Binding 9\nOpDecorate %58 NonReadable\nOpDecorate %58 NonWritable\nOpDecorate %61 DescriptorSet 0\nOpDecorate %61 Binding 10\nOpDecorate %61 NonReadable\nOpDecorate %61 NonWritable\nOpDecorate %62 DescriptorSet 0\nOpDecorate %62 Binding 11\nOpDecorate %62 NonReadable\nOpDecorate %62 NonWritable\nOpDecorate %64 Flat\nOpDecorate %64 Location 0\nOpDecorate %66 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%31 = OpTypePointer UniformConstant %30\n%32 = OpVariable %31 UniformConstant\n%33 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%34 = OpTypePointer UniformConstant %33\n%35 = OpVariable %34 UniformConstant\n%36 = OpTypeInt 32 0\n%37 = OpTypeImage %36 Buffer 0 0 0 1 Unknown\n%38 = OpTypePointer UniformConstant %37\n%39 = OpVariable %38 UniformConstant\n%40 = OpVariable %38 UniformConstant\n%41 = OpTypeImage %5 1D 0 0 0 2 Unknown\n%42 = OpTypePointer UniformConstant %41\n%43 = OpVariable %42 UniformConstant\n%44 = OpTypeImage %5 1D 0 1 0 2 Unknown\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%48 = OpTypePointer UniformConstant %47\n%49 = OpVariable %48 UniformConstant\n%50 = OpTypeImage %5 2D 0 1 0 2 Unknown\n%51 = OpTypePointer UniformConstant %50\n%52 = OpVariable %51 UniformConstant\n%53 = OpTypeImage %5 3D 0 0 0 2 Unknown\n%54 = OpTypePointer UniformConstant %53\n%55 = OpVariable %54 UniformConstant\n%56 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%57 = OpTypePointer UniformConstant %56\n%58 = OpVariable %57 UniformConstant\n%59 = OpTypeImage %36 Buffer 0 0 0 2 R32ui\n%60 = OpTypePointer UniformConstant %59\n%61 = OpVariable %60 UniformConstant\n%62 = OpVariable %60 UniformConstant\n%63 = OpTypePointer Input %36\n%64 = OpVariable %63 Input\n%65 = OpTypePointer Output %36\n%66 = OpVariable %65 Output\n%90 = OpTypeBool\n%93 = OpConstantNull %36\n%94 = OpTypeVector %36 2\n%98 = OpTypeVector %90 2\n%101 = OpConstantNull %94\n%109 = OpConstantNull %94\n%112 = OpTypeVector %36 3\n%116 = OpTypeVector %90 3\n%119 = OpConstantNull %112\n%135 = OpConstantNull %112\n%144 = OpConstantNull %94\n%152 = OpConstantNull %112\n%178 = OpConstant %36 4\n%190 = OpConstant %36 32\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %228\n%228 = OpLabel\n%67 = OpLoad %59 %62\n%68 = OpLoad %59 %61\n%69 = OpLoad %56 %58\n%70 = OpLoad %53 %55\n%71 = OpLoad %50 %52\n%72 = OpLoad %47 %49\n%73 = OpLoad %44 %46\n%74 = OpLoad %41 %43\n%75 = OpLoad %37 %40\n%76 = OpLoad %37 %39\n%77 = OpLoad %33 %35\n%78 = OpLoad %30 %32\n%79 = OpLoad %27 %29\n%80 = OpLoad %24 %26\n%81 = OpLoad %21 %23\n%82 = OpLoad %18 %20\n%83 = OpLoad %15 %17\n%84 = OpLoad %12 %14\n%85 = OpLoad %9 %11\n%86 = OpLoad %6 %8\n%87 = OpLoad %36 %64\n%88 = OpImageQuerySizeLod %36 %86 %87\n%89 = OpImageQueryLevels %36 %86\n%91 = OpULessThan %90 %87 %89\n%92 = OpSelect %36 %91 %88 %93\n%95 = OpImageQuerySizeLod %94 %85 %87\n%96 = OpImageQueryLevels %36 %85\n%97 = OpULessThan %90 %87 %96\n%99 = OpCompositeConstruct %98 %97 %97\n%100 = OpSelect %94 %99 %95 %101\n%102 = OpCompositeExtract %36 %100 0\n%103 = OpCompositeExtract %36 %100 1\n%104 = OpImageQuerySizeLod %94 %84 %87\n%105 = OpImageQueryLevels %36 %84\n%106 = OpULessThan %90 %87 %105\n%107 = OpCompositeConstruct %98 %106 %106\n%108 = OpSelect %94 %107 %104 %109\n%110 = OpCompositeExtract %36 %108 0\n%111 = OpCompositeExtract %36 %108 1\n%113 = OpImageQuerySizeLod %112 %83 %87\n%114 = OpImageQueryLevels %36 %83\n%115 = OpULessThan %90 %87 %114\n%117 = OpCompositeConstruct %116 %115 %115 %115\n%118 = OpSelect %112 %117 %113 %119\n%120 = OpCompositeExtract %36 %118 0\n%121 = OpCompositeExtract %36 %118 1\n%122 = OpCompositeExtract %36 %118 2\n%123 = OpImageQuerySize %94 %82\n%124 = OpCompositeExtract %36 %123 0\n%125 = OpCompositeExtract %36 %123 1\n%126 = OpImageQuerySize %112 %81\n%127 = OpCompositeExtract %36 %126 0\n%128 = OpCompositeExtract %36 %126 1\n%129 = OpCompositeExtract %36 %126 2\n%130 = OpImageQuerySizeLod %112 %80 %87\n%131 = OpImageQueryLevels %36 %80\n%132 = OpULessThan %90 %87 %131\n%133 = OpCompositeConstruct %116 %132 %132 %132\n%134 = OpSelect %112 %133 %130 %135\n%136 = OpCompositeExtract %36 %134 0\n%137 = OpCompositeExtract %36 %134 1\n%138 = OpCompositeExtract %36 %134 2\n%139 = OpImageQuerySizeLod %94 %79 %87\n%140 = OpImageQueryLevels %36 %79\n%141 = OpULessThan %90 %87 %140\n%142 = OpCompositeConstruct %98 %141 %141\n%143 = OpSelect %94 %142 %139 %144\n%145 = OpCompositeExtract %36 %143 0\n%146 = OpCompositeExtract %36 %143 1\n%147 = OpImageQuerySizeLod %112 %78 %87\n%148 = OpImageQueryLevels %36 %78\n%149 = OpULessThan %90 %87 %148\n%150 = OpCompositeConstruct %116 %149 %149 %149\n%151 = OpSelect %112 %150 %147 %152\n%153 = OpCompositeExtract %36 %151 0\n%154 = OpCompositeExtract %36 %151 1\n%155 = OpCompositeExtract %36 %151 2\n%156 = OpImageQuerySize %36 %77\n%157 = OpIMul %36 %156 %156\n%158 = OpImageQuerySize %36 %74\n%159 = OpIMul %36 %158 %158\n%160 = OpImageQuerySize %94 %73\n%161 = OpCompositeExtract %36 %160 0\n%162 = OpCompositeExtract %36 %160 1\n%163 = OpImageQuerySize %94 %72\n%164 = OpCompositeExtract %36 %163 0\n%165 = OpCompositeExtract %36 %163 1\n%166 = OpImageQuerySize %112 %71\n%167 = OpCompositeExtract %36 %166 0\n%168 = OpCompositeExtract %36 %166 1\n%169 = OpCompositeExtract %36 %166 2\n%170 = OpImageQuerySize %112 %70\n%171 = OpCompositeExtract %36 %170 0\n%172 = OpCompositeExtract %36 %170 1\n%173 = OpCompositeExtract %36 %170 2\n%174 = OpImageQuerySize %36 %69\n%175 = OpIMul %36 %174 %174\n%176 = OpImageQuerySize %36 %76\n%177 = OpUDiv %36 %176 %178\n%179 = OpIMul %36 %177 %177\n%180 = OpImageQuerySize %36 %68\n%181 = OpUDiv %36 %180 %178\n%182 = OpIMul %36 %181 %181\n%183 = OpImageQuerySize %36 %75\n%184 = OpIMul %36 %183 %178\n%185 = OpIMul %36 %184 %184\n%186 = OpImageQuerySize %36 %67\n%187 = OpIMul %36 %186 %178\n%188 = OpIMul %36 %187 %187\n%189 = OpIAdd %36 %92 %190\n%191 = OpIAdd %36 %189 %103\n%192 = OpIAdd %36 %191 %102\n%193 = OpIAdd %36 %192 %111\n%194 = OpIAdd %36 %193 %110\n%195 = OpIAdd %36 %194 %121\n%196 = OpIAdd %36 %195 %120\n%197 = OpIAdd %36 %196 %122\n%198 = OpIAdd %36 %197 %125\n%199 = OpIAdd %36 %198 %124\n%200 = OpIAdd %36 %199 %128\n%201 = OpIAdd %36 %200 %127\n%202 = OpIAdd %36 %201 %129\n%203 = OpIAdd %36 %202 %137\n%204 = OpIAdd %36 %203 %136\n%205 = OpIAdd %36 %204 %138\n%206 = OpIAdd %36 %205 %146\n%207 = OpIAdd %36 %206 %145\n%208 = OpIAdd %36 %207 %154\n%209 = OpIAdd %36 %208 %153\n%210 = OpIAdd %36 %209 %155\n%211 = OpIAdd %36 %210 %157\n%212 = OpIAdd %36 %211 %159\n%213 = OpIAdd %36 %212 %162\n%214 = OpIAdd %36 %213 %161\n%215 = OpIAdd %36 %214 %165\n%216 = OpIAdd %36 %215 %164\n%217 = OpIAdd %36 %216 %168\n%218 = OpIAdd %36 %217 %167\n%219 = OpIAdd %36 %218 %169\n%220 = OpIAdd %36 %219 %172\n%221 = OpIAdd %36 %220 %171\n%222 = OpIAdd %36 %221 %173\n%223 = OpIAdd %36 %222 %175\n%224 = OpIAdd %36 %223 %179\n%225 = OpIAdd %36 %224 %182\n%226 = OpIAdd %36 %225 %185\n%227 = OpIAdd %36 %226 %188\nOpStore %66 %227\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/get-dimensions.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nuint _67;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 1, binding = 0) uniform samplerBuffer _17[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _21[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _24[];\nlayout(set = 3, binding = 0) uniform readonly writeonly image2D _28[];\nlayout(set = 4, binding = 0) uniform readonly writeonly imageBuffer _32[];\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _36[];\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _39[];\n\nlayout(location = 0) flat in uint LEVEL;\nlayout(location = 0, component = 1) flat in uint INDEX;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _54 = registers._m0 + (INDEX + 0u);\n    uint _58 = uint(textureQueryLevels(_13[nonuniformEXT(_54)]));\n    uvec4 _66 = uvec4(mix(uvec2(0u), uvec2(textureSize(_13[nonuniformEXT(_54)], int(LEVEL))), bvec2(LEVEL < _58)), _67, _58);\n    uint _79 = uint(textureSize(_17[nonuniformEXT(registers._m1 + (INDEX + 0u))]));\n    uvec2 _89 = uvec2(imageSize(_28[nonuniformEXT(registers._m3 + (INDEX + 0u))]));\n    uint _100 = uint(imageSize(_32[nonuniformEXT(registers._m4 + (INDEX + 0u))]));\n    uint _110 = uint(textureSize(_21[nonuniformEXT(registers._m1 + (INDEX + 0u))])) / 4u;\n    uint _120 = uint(imageSize(_36[nonuniformEXT(registers._m4 + (INDEX + 0u))])) / 4u;\n    uint _129 = uint(textureSize(_24[nonuniformEXT(registers._m1 + (INDEX + 0u))])) * 4u;\n    uint _138 = uint(imageSize(_39[nonuniformEXT(registers._m4 + (INDEX + 0u))])) * 4u;\n    SV_Target = ((((((((((_66.y + 32u) + _66.x) + _66.w) + (_79 * _79)) + _89.y) + _89.x) + (_100 * _100)) + (_110 * _110)) + (_120 * _120)) + (_129 * _129)) + (_138 * _138);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 154\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %41 %42 %44\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %41 \"LEVEL\"\nOpName %42 \"INDEX\"\nOpName %44 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 1\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %28 DescriptorSet 3\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %28 NonWritable\nOpDecorate %32 DescriptorSet 4\nOpDecorate %32 Binding 0\nOpDecorate %32 NonReadable\nOpDecorate %32 NonWritable\nOpDecorate %36 DescriptorSet 4\nOpDecorate %36 Binding 0\nOpDecorate %36 NonReadable\nOpDecorate %36 NonWritable\nOpDecorate %39 DescriptorSet 4\nOpDecorate %39 Binding 0\nOpDecorate %39 NonReadable\nOpDecorate %39 NonWritable\nOpDecorate %41 Flat\nOpDecorate %41 Location 0\nOpDecorate %42 Flat\nOpDecorate %42 Location 0\nOpDecorate %42 Component 1\nOpDecorate %44 Location 0\nOpDecorate %54 NonUniform\nOpDecorate %55 NonUniform\nOpDecorate %77 NonUniform\nOpDecorate %78 NonUniform\nOpDecorate %87 NonUniform\nOpDecorate %88 NonUniform\nOpDecorate %98 NonUniform\nOpDecorate %99 NonUniform\nOpDecorate %107 NonUniform\nOpDecorate %108 NonUniform\nOpDecorate %117 NonUniform\nOpDecorate %118 NonUniform\nOpDecorate %126 NonUniform\nOpDecorate %127 NonUniform\nOpDecorate %135 NonUniform\nOpDecorate %136 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeRuntimeArray %18\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer UniformConstant %30\n%32 = OpVariable %31 UniformConstant\n%33 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeRuntimeArray %33\n%38 = OpTypePointer UniformConstant %37\n%39 = OpVariable %38 UniformConstant\n%40 = OpTypePointer Input %5\n%41 = OpVariable %40 Input\n%42 = OpVariable %40 Input\n%43 = OpTypePointer Output %5\n%44 = OpVariable %43 Output\n%48 = OpConstant %5 0\n%49 = OpTypePointer UniformConstant %10\n%51 = OpTypePointer PushConstant %5\n%56 = OpTypeVector %5 2\n%59 = OpTypeBool\n%61 = OpTypeVector %59 2\n%64 = OpConstantNull %56\n%65 = OpTypeVector %5 4\n%72 = OpTypePointer UniformConstant %14\n%75 = OpConstant %5 1\n%82 = OpTypePointer UniformConstant %25\n%85 = OpConstant %5 3\n%93 = OpTypePointer UniformConstant %29\n%96 = OpConstant %5 4\n%103 = OpTypePointer UniformConstant %18\n%113 = OpTypePointer UniformConstant %33\n%141 = OpConstant %5 32\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%67 = OpUndef %5\nOpBranch %152\n%152 = OpLabel\n%45 = OpLoad %5 %42\n%46 = OpLoad %5 %41\n%47 = OpIAdd %5 %45 %48\n%52 = OpAccessChain %51 %8 %48\n%53 = OpLoad %5 %52\n%54 = OpIAdd %5 %53 %47\n%50 = OpAccessChain %49 %13 %54\n%55 = OpLoad %10 %50\n%57 = OpImageQuerySizeLod %56 %55 %46\n%58 = OpImageQueryLevels %5 %55\n%60 = OpULessThan %59 %46 %58\n%62 = OpCompositeConstruct %61 %60 %60\n%63 = OpSelect %56 %62 %57 %64\n%66 = OpCompositeConstruct %65 %63 %67 %58\n%68 = OpCompositeExtract %5 %66 0\n%69 = OpCompositeExtract %5 %66 1\n%70 = OpCompositeExtract %5 %66 3\n%71 = OpIAdd %5 %45 %48\n%74 = OpAccessChain %51 %8 %75\n%76 = OpLoad %5 %74\n%77 = OpIAdd %5 %76 %71\n%73 = OpAccessChain %72 %17 %77\n%78 = OpLoad %14 %73\n%79 = OpImageQuerySize %5 %78\n%80 = OpIMul %5 %79 %79\n%81 = OpIAdd %5 %45 %48\n%84 = OpAccessChain %51 %8 %85\n%86 = OpLoad %5 %84\n%87 = OpIAdd %5 %86 %81\n%83 = OpAccessChain %82 %28 %87\n%88 = OpLoad %25 %83\n%89 = OpImageQuerySize %56 %88\n%90 = OpCompositeExtract %5 %89 0\n%91 = OpCompositeExtract %5 %89 1\n%92 = OpIAdd %5 %45 %48\n%95 = OpAccessChain %51 %8 %96\n%97 = OpLoad %5 %95\n%98 = OpIAdd %5 %97 %92\n%94 = OpAccessChain %93 %32 %98\n%99 = OpLoad %29 %94\n%100 = OpImageQuerySize %5 %99\n%101 = OpIMul %5 %100 %100\n%102 = OpIAdd %5 %45 %48\n%105 = OpAccessChain %51 %8 %75\n%106 = OpLoad %5 %105\n%107 = OpIAdd %5 %106 %102\n%104 = OpAccessChain %103 %21 %107\n%108 = OpLoad %18 %104\n%109 = OpImageQuerySize %5 %108\n%110 = OpUDiv %5 %109 %96\n%111 = OpIMul %5 %110 %110\n%112 = OpIAdd %5 %45 %48\n%115 = OpAccessChain %51 %8 %96\n%116 = OpLoad %5 %115\n%117 = OpIAdd %5 %116 %112\n%114 = OpAccessChain %113 %36 %117\n%118 = OpLoad %33 %114\n%119 = OpImageQuerySize %5 %118\n%120 = OpUDiv %5 %119 %96\n%121 = OpIMul %5 %120 %120\n%122 = OpIAdd %5 %45 %48\n%124 = OpAccessChain %51 %8 %75\n%125 = OpLoad %5 %124\n%126 = OpIAdd %5 %125 %122\n%123 = OpAccessChain %103 %24 %126\n%127 = OpLoad %18 %123\n%128 = OpImageQuerySize %5 %127\n%129 = OpIMul %5 %128 %96\n%130 = OpIMul %5 %129 %129\n%131 = OpIAdd %5 %45 %48\n%133 = OpAccessChain %51 %8 %96\n%134 = OpLoad %5 %133\n%135 = OpIAdd %5 %134 %131\n%132 = OpAccessChain %113 %39 %135\n%136 = OpLoad %33 %132\n%137 = OpImageQuerySize %5 %136\n%138 = OpIMul %5 %137 %96\n%139 = OpIMul %5 %138 %138\n%140 = OpIAdd %5 %69 %141\n%142 = OpIAdd %5 %140 %68\n%143 = OpIAdd %5 %142 %70\n%144 = OpIAdd %5 %143 %80\n%145 = OpIAdd %5 %144 %91\n%146 = OpIAdd %5 %145 %90\n%147 = OpIAdd %5 %146 %101\n%148 = OpIAdd %5 %147 %111\n%149 = OpIAdd %5 %148 %121\n%150 = OpIAdd %5 %149 %130\n%151 = OpIAdd %5 %150 %139\nOpStore %44 %151\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/get-dimensions.bindless.root-constant.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nuint _73;\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _22[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _24_27\n{\n    uint _m0[];\n} _27[];\n\nlayout(set = 4, binding = 0, std430) writeonly readonly buffer _37_40\n{\n    uint _m0[];\n} _40[];\n\nlayout(set = 4, binding = 0, std430) writeonly readonly buffer _42_45\n{\n    uint _m0[];\n} _45[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 1, binding = 0) uniform samplerBuffer _17[];\nlayout(set = 3, binding = 0) uniform readonly writeonly image2D _31[];\nlayout(set = 4, binding = 0) uniform readonly writeonly imageBuffer _35[];\n\nlayout(location = 0) flat in uint LEVEL;\nlayout(location = 0, component = 1) flat in uint INDEX;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _60 = registers._m0 + (INDEX + 0u);\n    uint _64 = uint(textureQueryLevels(_13[nonuniformEXT(_60)]));\n    uvec4 _72 = uvec4(mix(uvec2(0u), uvec2(textureSize(_13[nonuniformEXT(_60)], int(LEVEL))), bvec2(LEVEL < _64)), _73, _64);\n    uint _85 = uint(textureSize(_17[nonuniformEXT(registers._m1 + (INDEX + 0u))]));\n    uvec2 _95 = uvec2(imageSize(_31[nonuniformEXT(registers._m3 + (INDEX + 0u))]));\n    uint _106 = uint(imageSize(_35[nonuniformEXT(registers._m4 + (INDEX + 0u))]));\n    uint _115 = uint(_22[nonuniformEXT(registers._m1 + (INDEX + 0u))]._m0.length()) / 4u;\n    uint _124 = uint(_40[nonuniformEXT(registers._m4 + (INDEX + 0u))]._m0.length()) / 4u;\n    uint _133 = uint(_27[nonuniformEXT(registers._m1 + (INDEX + 0u))]._m0.length()) * 4u;\n    uint _142 = uint(_45[nonuniformEXT(registers._m4 + (INDEX + 0u))]._m0.length()) * 4u;\n    SV_Target = ((((((((((_72.y + 32u) + _72.x) + _72.w) + (_85 * _85)) + _95.y) + _95.x) + (_106 * _106)) + (_115 * _115)) + (_124 * _124)) + (_133 * _133)) + (_142 * _142);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 158\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %47 %48 %50\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %19 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %37 \"SSBO\"\nOpName %42 \"SSBO\"\nOpName %47 \"LEVEL\"\nOpName %48 \"INDEX\"\nOpName %50 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %18 ArrayStride 4\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %22 DescriptorSet 1\nOpDecorate %22 Binding 0\nOpDecorate %22 NonWritable\nOpDecorate %22 Restrict\nOpDecorate %23 ArrayStride 4\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %27 DescriptorSet 1\nOpDecorate %27 Binding 0\nOpDecorate %27 NonWritable\nOpDecorate %27 Restrict\nOpDecorate %31 DescriptorSet 3\nOpDecorate %31 Binding 0\nOpDecorate %31 NonReadable\nOpDecorate %31 NonWritable\nOpDecorate %35 DescriptorSet 4\nOpDecorate %35 Binding 0\nOpDecorate %35 NonReadable\nOpDecorate %35 NonWritable\nOpDecorate %36 ArrayStride 4\nOpMemberDecorate %37 0 Offset 0\nOpDecorate %37 Block\nOpDecorate %40 DescriptorSet 4\nOpDecorate %40 Binding 0\nOpDecorate %40 NonReadable\nOpDecorate %40 NonWritable\nOpDecorate %41 ArrayStride 4\nOpMemberDecorate %42 0 Offset 0\nOpDecorate %42 Block\nOpDecorate %45 DescriptorSet 4\nOpDecorate %45 Binding 0\nOpDecorate %45 NonReadable\nOpDecorate %45 NonWritable\nOpDecorate %47 Flat\nOpDecorate %47 Location 0\nOpDecorate %48 Flat\nOpDecorate %48 Location 0\nOpDecorate %48 Component 1\nOpDecorate %50 Location 0\nOpDecorate %60 NonUniform\nOpDecorate %61 NonUniform\nOpDecorate %83 NonUniform\nOpDecorate %84 NonUniform\nOpDecorate %93 NonUniform\nOpDecorate %94 NonUniform\nOpDecorate %104 NonUniform\nOpDecorate %105 NonUniform\nOpDecorate %113 NonUniform\nOpDecorate %110 NonUniform\nOpDecorate %122 NonUniform\nOpDecorate %119 NonUniform\nOpDecorate %131 NonUniform\nOpDecorate %128 NonUniform\nOpDecorate %140 NonUniform\nOpDecorate %137 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeRuntimeArray %5\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %5\n%24 = OpTypeStruct %23\n%25 = OpTypeRuntimeArray %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%29 = OpTypeRuntimeArray %28\n%30 = OpTypePointer UniformConstant %29\n%31 = OpVariable %30 UniformConstant\n%32 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%33 = OpTypeRuntimeArray %32\n%34 = OpTypePointer UniformConstant %33\n%35 = OpVariable %34 UniformConstant\n%36 = OpTypeRuntimeArray %5\n%37 = OpTypeStruct %36\n%38 = OpTypeRuntimeArray %37\n%39 = OpTypePointer StorageBuffer %38\n%40 = OpVariable %39 StorageBuffer\n%41 = OpTypeRuntimeArray %5\n%42 = OpTypeStruct %41\n%43 = OpTypeRuntimeArray %42\n%44 = OpTypePointer StorageBuffer %43\n%45 = OpVariable %44 StorageBuffer\n%46 = OpTypePointer Input %5\n%47 = OpVariable %46 Input\n%48 = OpVariable %46 Input\n%49 = OpTypePointer Output %5\n%50 = OpVariable %49 Output\n%54 = OpConstant %5 0\n%55 = OpTypePointer UniformConstant %10\n%57 = OpTypePointer PushConstant %5\n%62 = OpTypeVector %5 2\n%65 = OpTypeBool\n%67 = OpTypeVector %65 2\n%70 = OpConstantNull %62\n%71 = OpTypeVector %5 4\n%78 = OpTypePointer UniformConstant %14\n%81 = OpConstant %5 1\n%88 = OpTypePointer UniformConstant %28\n%91 = OpConstant %5 3\n%99 = OpTypePointer UniformConstant %32\n%102 = OpConstant %5 4\n%109 = OpTypePointer StorageBuffer %19\n%118 = OpTypePointer StorageBuffer %37\n%127 = OpTypePointer StorageBuffer %24\n%136 = OpTypePointer StorageBuffer %42\n%145 = OpConstant %5 32\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%73 = OpUndef %5\nOpBranch %156\n%156 = OpLabel\n%51 = OpLoad %5 %48\n%52 = OpLoad %5 %47\n%53 = OpIAdd %5 %51 %54\n%58 = OpAccessChain %57 %8 %54\n%59 = OpLoad %5 %58\n%60 = OpIAdd %5 %59 %53\n%56 = OpAccessChain %55 %13 %60\n%61 = OpLoad %10 %56\n%63 = OpImageQuerySizeLod %62 %61 %52\n%64 = OpImageQueryLevels %5 %61\n%66 = OpULessThan %65 %52 %64\n%68 = OpCompositeConstruct %67 %66 %66\n%69 = OpSelect %62 %68 %63 %70\n%72 = OpCompositeConstruct %71 %69 %73 %64\n%74 = OpCompositeExtract %5 %72 0\n%75 = OpCompositeExtract %5 %72 1\n%76 = OpCompositeExtract %5 %72 3\n%77 = OpIAdd %5 %51 %54\n%80 = OpAccessChain %57 %8 %81\n%82 = OpLoad %5 %80\n%83 = OpIAdd %5 %82 %77\n%79 = OpAccessChain %78 %17 %83\n%84 = OpLoad %14 %79\n%85 = OpImageQuerySize %5 %84\n%86 = OpIMul %5 %85 %85\n%87 = OpIAdd %5 %51 %54\n%90 = OpAccessChain %57 %8 %91\n%92 = OpLoad %5 %90\n%93 = OpIAdd %5 %92 %87\n%89 = OpAccessChain %88 %31 %93\n%94 = OpLoad %28 %89\n%95 = OpImageQuerySize %62 %94\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpCompositeExtract %5 %95 1\n%98 = OpIAdd %5 %51 %54\n%101 = OpAccessChain %57 %8 %102\n%103 = OpLoad %5 %101\n%104 = OpIAdd %5 %103 %98\n%100 = OpAccessChain %99 %35 %104\n%105 = OpLoad %32 %100\n%106 = OpImageQuerySize %5 %105\n%107 = OpIMul %5 %106 %106\n%108 = OpIAdd %5 %51 %54\n%111 = OpAccessChain %57 %8 %81\n%112 = OpLoad %5 %111\n%113 = OpIAdd %5 %112 %108\n%110 = OpAccessChain %109 %22 %113\n%114 = OpArrayLength %5 %110 0\n%115 = OpUDiv %5 %114 %102\n%116 = OpIMul %5 %115 %115\n%117 = OpIAdd %5 %51 %54\n%120 = OpAccessChain %57 %8 %102\n%121 = OpLoad %5 %120\n%122 = OpIAdd %5 %121 %117\n%119 = OpAccessChain %118 %40 %122\n%123 = OpArrayLength %5 %119 0\n%124 = OpUDiv %5 %123 %102\n%125 = OpIMul %5 %124 %124\n%126 = OpIAdd %5 %51 %54\n%129 = OpAccessChain %57 %8 %81\n%130 = OpLoad %5 %129\n%131 = OpIAdd %5 %130 %126\n%128 = OpAccessChain %127 %27 %131\n%132 = OpArrayLength %5 %128 0\n%133 = OpIMul %5 %132 %102\n%134 = OpIMul %5 %133 %133\n%135 = OpIAdd %5 %51 %54\n%138 = OpAccessChain %57 %8 %102\n%139 = OpLoad %5 %138\n%140 = OpIAdd %5 %139 %135\n%137 = OpAccessChain %136 %45 %140\n%141 = OpArrayLength %5 %137 0\n%142 = OpIMul %5 %141 %102\n%143 = OpIMul %5 %142 %142\n%144 = OpIAdd %5 %75 %145\n%146 = OpIAdd %5 %144 %74\n%147 = OpIAdd %5 %146 %76\n%148 = OpIAdd %5 %147 %86\n%149 = OpIAdd %5 %148 %97\n%150 = OpIAdd %5 %149 %96\n%151 = OpIAdd %5 %150 %107\n%152 = OpIAdd %5 %151 %116\n%153 = OpIAdd %5 %152 %125\n%154 = OpIAdd %5 %153 %134\n%155 = OpIAdd %5 %154 %143\nOpStore %50 %155\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/get-dimensions.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nuint _96;\nuint _97;\nuint _109;\nuint _120;\nuint _140;\nuint _169;\n\nlayout(set = 0, binding = 0) uniform texture1D _8;\nlayout(set = 0, binding = 1) uniform texture1DArray _11;\nlayout(set = 0, binding = 2) uniform texture2D _14;\nlayout(set = 0, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 4) uniform texture2DMS _20;\nlayout(set = 0, binding = 5) uniform texture2DMSArray _23;\nlayout(set = 0, binding = 6) uniform texture3D _26;\nlayout(set = 0, binding = 7) uniform textureCube _29;\nlayout(set = 0, binding = 8) uniform textureCubeArray _32;\nlayout(set = 0, binding = 9) uniform samplerBuffer _35;\nlayout(set = 0, binding = 10) uniform usamplerBuffer _39;\nlayout(set = 0, binding = 11) uniform usamplerBuffer _40;\nlayout(set = 0, binding = 0) uniform readonly writeonly image1D _43;\nlayout(set = 0, binding = 1) uniform readonly writeonly image1DArray _46;\nlayout(set = 0, binding = 2) uniform readonly writeonly image2D _49;\nlayout(set = 0, binding = 3) uniform readonly writeonly image2DArray _52;\nlayout(set = 0, binding = 6) uniform readonly writeonly image3D _55;\nlayout(set = 0, binding = 9) uniform readonly writeonly imageBuffer _58;\nlayout(set = 0, binding = 10, r32ui) uniform readonly writeonly uimageBuffer _61;\nlayout(set = 0, binding = 11, r32ui) uniform readonly writeonly uimageBuffer _62;\n\nlayout(location = 0) flat in uint LEVEL;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _89 = uint(textureQueryLevels(_8));\n    uvec4 _95 = uvec4((LEVEL < _89) ? uint(textureSize(_8, int(LEVEL))) : 0u, _96, _97, _89);\n    uint _102 = uint(textureQueryLevels(_11));\n    uvec4 _108 = uvec4(mix(uvec2(0u), uvec2(textureSize(_11, int(LEVEL))), bvec2(LEVEL < _102)), _109, _102);\n    uint _114 = uint(textureQueryLevels(_14));\n    uvec4 _119 = uvec4(mix(uvec2(0u), uvec2(textureSize(_14, int(LEVEL))), bvec2(LEVEL < _114)), _120, _114);\n    uint _126 = uint(textureQueryLevels(_17));\n    uvec4 _132 = uvec4(mix(uvec3(0u), uvec3(textureSize(_17, int(LEVEL))), bvec3(LEVEL < _126)), _126);\n    uvec4 _139 = uvec4(uvec2(textureSize(_20)), _140, uint(textureSamples(_20)));\n    uvec4 _146 = uvec4(uvec3(textureSize(_23)), uint(textureSamples(_23)));\n    uint _152 = uint(textureQueryLevels(_26));\n    uvec4 _157 = uvec4(mix(uvec3(0u), uvec3(textureSize(_26, int(LEVEL))), bvec3(LEVEL < _152)), _152);\n    uint _163 = uint(textureQueryLevels(_29));\n    uvec4 _168 = uvec4(mix(uvec2(0u), uvec2(textureSize(_29, int(LEVEL))), bvec2(LEVEL < _163)), _169, _163);\n    uint _174 = uint(textureQueryLevels(_32));\n    uvec4 _179 = uvec4(mix(uvec3(0u), uvec3(textureSize(_32, int(LEVEL))), bvec3(LEVEL < _174)), _174);\n    uint _184 = uint(textureSize(_35));\n    uint _186 = uint(imageSize(_43));\n    uvec2 _188 = uvec2(imageSize(_46));\n    uvec2 _191 = uvec2(imageSize(_49));\n    uvec3 _194 = uvec3(imageSize(_52));\n    uvec3 _198 = uvec3(imageSize(_55));\n    uint _202 = uint(imageSize(_58));\n    uint _205 = uint(textureSize(_39)) / 4u;\n    uint _209 = uint(imageSize(_61)) / 4u;\n    uint _212 = uint(textureSize(_40)) * 4u;\n    uint _215 = uint(imageSize(_62)) * 4u;\n    uint _246 = ((((((((((((((((((((((((((((_95.w + 32u) + _95.x) + _108.y) + _108.x) + _108.w) + _119.y) + _119.x) + _119.w) + _132.y) + _132.x) + _132.z) + _132.w) + _139.y) + _139.x) + _139.w) + _146.y) + _146.x) + _146.z) + _146.w) + _157.y) + _157.x) + _157.z) + _157.w) + _168.y) + _168.x) + _168.w) + _179.y) + _179.x) + _179.z;\n    SV_Target = (((((((((((((((((_246 + _179.w) + (_184 * _184)) + (_186 * _186)) + _188.y) + _188.x) + _191.y) + _191.x) + _194.y) + _194.x) + _194.z) + _198.y) + _198.x) + _198.z) + (_202 * _202)) + (_205 * _205)) + (_209 * _209)) + (_212 * _212)) + (_215 * _215);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 267\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability Image1D\nOpCapability SampledCubeArray\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %64 %66\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %64 \"LEVEL\"\nOpName %66 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 7\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 8\nOpDecorate %35 DescriptorSet 0\nOpDecorate %35 Binding 9\nOpDecorate %39 DescriptorSet 0\nOpDecorate %39 Binding 10\nOpDecorate %40 DescriptorSet 0\nOpDecorate %40 Binding 11\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 0\nOpDecorate %43 NonReadable\nOpDecorate %43 NonWritable\nOpDecorate %46 DescriptorSet 0\nOpDecorate %46 Binding 1\nOpDecorate %46 NonReadable\nOpDecorate %46 NonWritable\nOpDecorate %49 DescriptorSet 0\nOpDecorate %49 Binding 2\nOpDecorate %49 NonReadable\nOpDecorate %49 NonWritable\nOpDecorate %52 DescriptorSet 0\nOpDecorate %52 Binding 3\nOpDecorate %52 NonReadable\nOpDecorate %52 NonWritable\nOpDecorate %55 DescriptorSet 0\nOpDecorate %55 Binding 6\nOpDecorate %55 NonReadable\nOpDecorate %55 NonWritable\nOpDecorate %58 DescriptorSet 0\nOpDecorate %58 Binding 9\nOpDecorate %58 NonReadable\nOpDecorate %58 NonWritable\nOpDecorate %61 DescriptorSet 0\nOpDecorate %61 Binding 10\nOpDecorate %61 NonReadable\nOpDecorate %61 NonWritable\nOpDecorate %62 DescriptorSet 0\nOpDecorate %62 Binding 11\nOpDecorate %62 NonReadable\nOpDecorate %62 NonWritable\nOpDecorate %64 Flat\nOpDecorate %64 Location 0\nOpDecorate %66 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%31 = OpTypePointer UniformConstant %30\n%32 = OpVariable %31 UniformConstant\n%33 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%34 = OpTypePointer UniformConstant %33\n%35 = OpVariable %34 UniformConstant\n%36 = OpTypeInt 32 0\n%37 = OpTypeImage %36 Buffer 0 0 0 1 Unknown\n%38 = OpTypePointer UniformConstant %37\n%39 = OpVariable %38 UniformConstant\n%40 = OpVariable %38 UniformConstant\n%41 = OpTypeImage %5 1D 0 0 0 2 Unknown\n%42 = OpTypePointer UniformConstant %41\n%43 = OpVariable %42 UniformConstant\n%44 = OpTypeImage %5 1D 0 1 0 2 Unknown\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%48 = OpTypePointer UniformConstant %47\n%49 = OpVariable %48 UniformConstant\n%50 = OpTypeImage %5 2D 0 1 0 2 Unknown\n%51 = OpTypePointer UniformConstant %50\n%52 = OpVariable %51 UniformConstant\n%53 = OpTypeImage %5 3D 0 0 0 2 Unknown\n%54 = OpTypePointer UniformConstant %53\n%55 = OpVariable %54 UniformConstant\n%56 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%57 = OpTypePointer UniformConstant %56\n%58 = OpVariable %57 UniformConstant\n%59 = OpTypeImage %36 Buffer 0 0 0 2 R32ui\n%60 = OpTypePointer UniformConstant %59\n%61 = OpVariable %60 UniformConstant\n%62 = OpVariable %60 UniformConstant\n%63 = OpTypePointer Input %36\n%64 = OpVariable %63 Input\n%65 = OpTypePointer Output %36\n%66 = OpVariable %65 Output\n%90 = OpTypeBool\n%93 = OpConstantNull %36\n%94 = OpTypeVector %36 4\n%100 = OpTypeVector %36 2\n%104 = OpTypeVector %90 2\n%107 = OpConstantNull %100\n%118 = OpConstantNull %100\n%124 = OpTypeVector %36 3\n%128 = OpTypeVector %90 3\n%131 = OpConstantNull %124\n%156 = OpConstantNull %124\n%167 = OpConstantNull %100\n%178 = OpConstantNull %124\n%206 = OpConstant %36 4\n%218 = OpConstant %36 32\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%96 = OpUndef %36\n%97 = OpUndef %36\n%109 = OpUndef %36\n%120 = OpUndef %36\n%140 = OpUndef %36\n%169 = OpUndef %36\nOpBranch %265\n%265 = OpLabel\n%67 = OpLoad %59 %62\n%68 = OpLoad %59 %61\n%69 = OpLoad %56 %58\n%70 = OpLoad %53 %55\n%71 = OpLoad %50 %52\n%72 = OpLoad %47 %49\n%73 = OpLoad %44 %46\n%74 = OpLoad %41 %43\n%75 = OpLoad %37 %40\n%76 = OpLoad %37 %39\n%77 = OpLoad %33 %35\n%78 = OpLoad %30 %32\n%79 = OpLoad %27 %29\n%80 = OpLoad %24 %26\n%81 = OpLoad %21 %23\n%82 = OpLoad %18 %20\n%83 = OpLoad %15 %17\n%84 = OpLoad %12 %14\n%85 = OpLoad %9 %11\n%86 = OpLoad %6 %8\n%87 = OpLoad %36 %64\n%88 = OpImageQuerySizeLod %36 %86 %87\n%89 = OpImageQueryLevels %36 %86\n%91 = OpULessThan %90 %87 %89\n%92 = OpSelect %36 %91 %88 %93\n%95 = OpCompositeConstruct %94 %92 %96 %97 %89\n%98 = OpCompositeExtract %36 %95 0\n%99 = OpCompositeExtract %36 %95 3\n%101 = OpImageQuerySizeLod %100 %85 %87\n%102 = OpImageQueryLevels %36 %85\n%103 = OpULessThan %90 %87 %102\n%105 = OpCompositeConstruct %104 %103 %103\n%106 = OpSelect %100 %105 %101 %107\n%108 = OpCompositeConstruct %94 %106 %109 %102\n%110 = OpCompositeExtract %36 %108 0\n%111 = OpCompositeExtract %36 %108 1\n%112 = OpCompositeExtract %36 %108 3\n%113 = OpImageQuerySizeLod %100 %84 %87\n%114 = OpImageQueryLevels %36 %84\n%115 = OpULessThan %90 %87 %114\n%116 = OpCompositeConstruct %104 %115 %115\n%117 = OpSelect %100 %116 %113 %118\n%119 = OpCompositeConstruct %94 %117 %120 %114\n%121 = OpCompositeExtract %36 %119 0\n%122 = OpCompositeExtract %36 %119 1\n%123 = OpCompositeExtract %36 %119 3\n%125 = OpImageQuerySizeLod %124 %83 %87\n%126 = OpImageQueryLevels %36 %83\n%127 = OpULessThan %90 %87 %126\n%129 = OpCompositeConstruct %128 %127 %127 %127\n%130 = OpSelect %124 %129 %125 %131\n%132 = OpCompositeConstruct %94 %130 %126\n%133 = OpCompositeExtract %36 %132 0\n%134 = OpCompositeExtract %36 %132 1\n%135 = OpCompositeExtract %36 %132 2\n%136 = OpCompositeExtract %36 %132 3\n%137 = OpImageQuerySize %100 %82\n%138 = OpImageQuerySamples %36 %82\n%139 = OpCompositeConstruct %94 %137 %140 %138\n%141 = OpCompositeExtract %36 %139 0\n%142 = OpCompositeExtract %36 %139 1\n%143 = OpCompositeExtract %36 %139 3\n%144 = OpImageQuerySize %124 %81\n%145 = OpImageQuerySamples %36 %81\n%146 = OpCompositeConstruct %94 %144 %145\n%147 = OpCompositeExtract %36 %146 0\n%148 = OpCompositeExtract %36 %146 1\n%149 = OpCompositeExtract %36 %146 2\n%150 = OpCompositeExtract %36 %146 3\n%151 = OpImageQuerySizeLod %124 %80 %87\n%152 = OpImageQueryLevels %36 %80\n%153 = OpULessThan %90 %87 %152\n%154 = OpCompositeConstruct %128 %153 %153 %153\n%155 = OpSelect %124 %154 %151 %156\n%157 = OpCompositeConstruct %94 %155 %152\n%158 = OpCompositeExtract %36 %157 0\n%159 = OpCompositeExtract %36 %157 1\n%160 = OpCompositeExtract %36 %157 2\n%161 = OpCompositeExtract %36 %157 3\n%162 = OpImageQuerySizeLod %100 %79 %87\n%163 = OpImageQueryLevels %36 %79\n%164 = OpULessThan %90 %87 %163\n%165 = OpCompositeConstruct %104 %164 %164\n%166 = OpSelect %100 %165 %162 %167\n%168 = OpCompositeConstruct %94 %166 %169 %163\n%170 = OpCompositeExtract %36 %168 0\n%171 = OpCompositeExtract %36 %168 1\n%172 = OpCompositeExtract %36 %168 3\n%173 = OpImageQuerySizeLod %124 %78 %87\n%174 = OpImageQueryLevels %36 %78\n%175 = OpULessThan %90 %87 %174\n%176 = OpCompositeConstruct %128 %175 %175 %175\n%177 = OpSelect %124 %176 %173 %178\n%179 = OpCompositeConstruct %94 %177 %174\n%180 = OpCompositeExtract %36 %179 0\n%181 = OpCompositeExtract %36 %179 1\n%182 = OpCompositeExtract %36 %179 2\n%183 = OpCompositeExtract %36 %179 3\n%184 = OpImageQuerySize %36 %77\n%185 = OpIMul %36 %184 %184\n%186 = OpImageQuerySize %36 %74\n%187 = OpIMul %36 %186 %186\n%188 = OpImageQuerySize %100 %73\n%189 = OpCompositeExtract %36 %188 0\n%190 = OpCompositeExtract %36 %188 1\n%191 = OpImageQuerySize %100 %72\n%192 = OpCompositeExtract %36 %191 0\n%193 = OpCompositeExtract %36 %191 1\n%194 = OpImageQuerySize %124 %71\n%195 = OpCompositeExtract %36 %194 0\n%196 = OpCompositeExtract %36 %194 1\n%197 = OpCompositeExtract %36 %194 2\n%198 = OpImageQuerySize %124 %70\n%199 = OpCompositeExtract %36 %198 0\n%200 = OpCompositeExtract %36 %198 1\n%201 = OpCompositeExtract %36 %198 2\n%202 = OpImageQuerySize %36 %69\n%203 = OpIMul %36 %202 %202\n%204 = OpImageQuerySize %36 %76\n%205 = OpUDiv %36 %204 %206\n%207 = OpIMul %36 %205 %205\n%208 = OpImageQuerySize %36 %68\n%209 = OpUDiv %36 %208 %206\n%210 = OpIMul %36 %209 %209\n%211 = OpImageQuerySize %36 %75\n%212 = OpIMul %36 %211 %206\n%213 = OpIMul %36 %212 %212\n%214 = OpImageQuerySize %36 %67\n%215 = OpIMul %36 %214 %206\n%216 = OpIMul %36 %215 %215\n%217 = OpIAdd %36 %99 %218\n%219 = OpIAdd %36 %217 %98\n%220 = OpIAdd %36 %219 %111\n%221 = OpIAdd %36 %220 %110\n%222 = OpIAdd %36 %221 %112\n%223 = OpIAdd %36 %222 %122\n%224 = OpIAdd %36 %223 %121\n%225 = OpIAdd %36 %224 %123\n%226 = OpIAdd %36 %225 %134\n%227 = OpIAdd %36 %226 %133\n%228 = OpIAdd %36 %227 %135\n%229 = OpIAdd %36 %228 %136\n%230 = OpIAdd %36 %229 %142\n%231 = OpIAdd %36 %230 %141\n%232 = OpIAdd %36 %231 %143\n%233 = OpIAdd %36 %232 %148\n%234 = OpIAdd %36 %233 %147\n%235 = OpIAdd %36 %234 %149\n%236 = OpIAdd %36 %235 %150\n%237 = OpIAdd %36 %236 %159\n%238 = OpIAdd %36 %237 %158\n%239 = OpIAdd %36 %238 %160\n%240 = OpIAdd %36 %239 %161\n%241 = OpIAdd %36 %240 %171\n%242 = OpIAdd %36 %241 %170\n%243 = OpIAdd %36 %242 %172\n%244 = OpIAdd %36 %243 %181\n%245 = OpIAdd %36 %244 %180\n%246 = OpIAdd %36 %245 %182\n%247 = OpIAdd %36 %246 %183\n%248 = OpIAdd %36 %247 %185\n%249 = OpIAdd %36 %248 %187\n%250 = OpIAdd %36 %249 %190\n%251 = OpIAdd %36 %250 %189\n%252 = OpIAdd %36 %251 %193\n%253 = OpIAdd %36 %252 %192\n%254 = OpIAdd %36 %253 %196\n%255 = OpIAdd %36 %254 %195\n%256 = OpIAdd %36 %255 %197\n%257 = OpIAdd %36 %256 %200\n%258 = OpIAdd %36 %257 %199\n%259 = OpIAdd %36 %258 %201\n%260 = OpIAdd %36 %259 %203\n%261 = OpIAdd %36 %260 %207\n%262 = OpIAdd %36 %261 %210\n%263 = OpIAdd %36 %262 %213\n%264 = OpIAdd %36 %263 %216\nOpStore %66 %264\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/get-dimensions.ssbo.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 10, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 11, std430) writeonly readonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nlayout(location = 0) flat in uint LEVEL;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _19 = uint(_9._m0.length()) / 4u;\n    uint _25 = uint(_13._m0.length()) * 4u;\n    SV_Target = ((_19 * _19) + 16u) + (_25 * _25);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpCapability ImageQuery\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %15 %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %15 \"LEVEL\"\nOpName %17 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 10\nOpDecorate %9 NonReadable\nOpDecorate %9 NonWritable\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 11\nOpDecorate %13 NonReadable\nOpDecorate %13 NonWritable\nOpDecorate %15 Flat\nOpDecorate %15 Location 0\nOpDecorate %17 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Output %5\n%17 = OpVariable %16 Output\n%20 = OpConstant %5 4\n%23 = OpConstant %5 16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%18 = OpArrayLength %5 %9 0\n%19 = OpUDiv %5 %18 %20\n%21 = OpIMul %5 %19 %19\n%22 = OpIAdd %5 %21 %23\n%24 = OpArrayLength %5 %13 0\n%25 = OpIMul %5 %24 %20\n%26 = OpIMul %5 %25 %25\n%27 = OpIAdd %5 %22 %26\nOpStore %17 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/group_id.comp",
    "content": "#version 460\nlayout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(gl_WorkGroupID.x), uvec4(floatBitsToUint(10.0)));\n    imageStore(_8, int(gl_WorkGroupID.y), uvec4(floatBitsToUint(20.0)));\n    imageStore(_8, int(gl_WorkGroupID.z), uvec4(floatBitsToUint(30.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 2 2 2\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeFloat 32\n%24 = OpConstant %23 10\n%26 = OpTypeVector %5 4\n%28 = OpConstant %23 20\n%31 = OpConstant %23 30\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%25 = OpBitcast %5 %24\n%27 = OpCompositeConstruct %26 %25 %25 %25 %25\nOpImageWrite %9 %16 %27\n%29 = OpBitcast %5 %28\n%30 = OpCompositeConstruct %26 %29 %29 %29 %29\nOpImageWrite %9 %19 %30\n%32 = OpBitcast %5 %31\n%33 = OpCompositeConstruct %26 %32 %32 %32 %32\nOpImageWrite %9 %22 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/hcos.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = cosh(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Cosh %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/hsin.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = sinh(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Sinh %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/htan.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = tanh(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Tanh %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/imad.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec3 A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    SV_Target = int((uint(A.x) * uint(A.y)) + uint(A.z));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%22 = OpConstant %13 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %13 %23\n%25 = OpIMul %13 %16 %20\n%26 = OpIAdd %13 %25 %24\n%27 = OpBitcast %5 %26\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/imax.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec2 A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    SV_Target = int(uint(max(int(uint(A.x)), int(uint(A.y)))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\n%21 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%22 = OpExtInst %13 %21 SMax %16 %20\n%23 = OpBitcast %5 %22\nOpStore %10 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/imin.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec2 A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    SV_Target = int(uint(min(int(uint(A.x)), int(uint(A.y)))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\n%21 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%22 = OpExtInst %13 %21 SMin %16 %20\n%23 = OpBitcast %5 %22\nOpStore %10 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/instance-id.vert",
    "content": "#version 460\n\nvoid main()\n{\n    float _16 = float(uint(gl_InstanceIndex) - uint(gl_BaseInstance));\n    gl_Position.x = _16;\n    gl_Position.y = _16;\n    gl_Position.z = _16;\n    gl_Position.w = _16;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability DrawParameters\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"SV_InstanceID\"\nOpName %11 \"SV_Position\"\nOpDecorate %7 BuiltIn InstanceIndex\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn BaseInstance\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%13 = OpVariable %6 Input\n%17 = OpTypePointer Output %8\n%19 = OpConstant %5 0\n%21 = OpConstant %5 1\n%23 = OpConstant %5 2\n%25 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%12 = OpLoad %5 %7\n%14 = OpLoad %5 %13\n%15 = OpISub %5 %12 %14\n%16 = OpConvertUToF %8 %15\n%18 = OpAccessChain %17 %11 %19\nOpStore %18 %16\n%20 = OpAccessChain %17 %11 %21\nOpStore %20 %16\n%22 = OpAccessChain %17 %11 %23\nOpStore %22 %16\n%24 = OpAccessChain %17 %11 %25\nOpStore %24 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/is-helper-lane-2.demote-to-helper.sm66.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _22;\n    float _25;\n    float _27;\n    float _29;\n    if (gl_HelperInvocation)\n    {\n        _22 = 0.0;\n        _25 = 0.0;\n        _27 = 0.0;\n        _29 = 0.0;\n    }\n    else\n    {\n        _22 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : TEXCOORD.x);\n        _25 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : TEXCOORD.y);\n        _27 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : (TEXCOORD.x * TEXCOORD.x));\n        _29 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : (TEXCOORD.y * TEXCOORD.y));\n    }\n    SV_Target.x = _22;\n    SV_Target.y = _25;\n    SV_Target.z = _27;\n    SV_Target.w = _29;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformArithmetic\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11 %52\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\nOpDecorate %52 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%20 = OpTypeBool\n%23 = OpConstant %5 0\n%31 = OpTypePointer Output %5\n%35 = OpConstant %14 2\n%37 = OpConstant %14 3\n%51 = OpTypePointer Input %20\n%52 = OpVariable %51 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %48\n%48 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%21 = OpLoad %20 %52\nOpSelectionMerge %50 None\nOpBranchConditional %21 %50 %49\n%49 = OpLabel\n%38 = OpFMul %5 %16 %16\n%39 = OpFMul %5 %19 %19\n%40 = OpLoad %20 %52\n%41 = OpSelect %5 %40 %23 %16\n%24 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %41\n%42 = OpLoad %20 %52\n%43 = OpSelect %5 %42 %23 %19\n%26 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %43\n%44 = OpLoad %20 %52\n%45 = OpSelect %5 %44 %23 %38\n%28 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %45\n%46 = OpLoad %20 %52\n%47 = OpSelect %5 %46 %23 %39\n%30 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %47\nOpBranch %50\n%50 = OpLabel\n%22 = OpPhi %5 %23 %48 %24 %49\n%25 = OpPhi %5 %23 %48 %26 %49\n%27 = OpPhi %5 %23 %48 %28 %49\n%29 = OpPhi %5 %23 %48 %30 %49\n%32 = OpAccessChain %31 %11 %15\nOpStore %32 %22\n%33 = OpAccessChain %31 %11 %18\nOpStore %33 %25\n%34 = OpAccessChain %31 %11 %35\nOpStore %34 %27\n%36 = OpAccessChain %31 %11 %37\nOpStore %36 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/is-helper-lane-2.sm66.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _22;\n    float _25;\n    float _27;\n    float _29;\n    if (gl_HelperInvocation)\n    {\n        _22 = 0.0;\n        _25 = 0.0;\n        _27 = 0.0;\n        _29 = 0.0;\n    }\n    else\n    {\n        _22 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : TEXCOORD.x);\n        _25 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : TEXCOORD.y);\n        _27 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : (TEXCOORD.x * TEXCOORD.x));\n        _29 = subgroupExclusiveAdd(gl_HelperInvocation ? 0.0 : (TEXCOORD.y * TEXCOORD.y));\n    }\n    SV_Target.x = _22;\n    SV_Target.y = _25;\n    SV_Target.z = _27;\n    SV_Target.w = _29;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformArithmetic\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11 %52\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\nOpDecorate %52 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%20 = OpTypeBool\n%23 = OpConstant %5 0\n%31 = OpTypePointer Output %5\n%35 = OpConstant %14 2\n%37 = OpConstant %14 3\n%51 = OpTypePointer Input %20\n%52 = OpVariable %51 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %48\n%48 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%21 = OpLoad %20 %52\nOpSelectionMerge %50 None\nOpBranchConditional %21 %50 %49\n%49 = OpLabel\n%38 = OpFMul %5 %16 %16\n%39 = OpFMul %5 %19 %19\n%40 = OpLoad %20 %52\n%41 = OpSelect %5 %40 %23 %16\n%24 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %41\n%42 = OpLoad %20 %52\n%43 = OpSelect %5 %42 %23 %19\n%26 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %43\n%44 = OpLoad %20 %52\n%45 = OpSelect %5 %44 %23 %38\n%28 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %45\n%46 = OpLoad %20 %52\n%47 = OpSelect %5 %46 %23 %39\n%30 = OpGroupNonUniformFAdd %5 %37 ExclusiveScan %47\nOpBranch %50\n%50 = OpLabel\n%22 = OpPhi %5 %23 %48 %24 %49\n%25 = OpPhi %5 %23 %48 %26 %49\n%27 = OpPhi %5 %23 %48 %28 %49\n%29 = OpPhi %5 %23 %48 %30 %49\n%32 = OpAccessChain %31 %11 %15\nOpStore %32 %22\n%33 = OpAccessChain %31 %11 %18\nOpStore %33 %25\n%34 = OpAccessChain %31 %11 %35\nOpStore %34 %27\n%36 = OpAccessChain %31 %11 %37\nOpStore %36 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/is-helper-lane.demote-to-helper.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_demote_to_helper_invocation : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    if (TEXCOORD.x > 10.0)\n    {\n        demote;\n    }\n    else\n    {\n        if (TEXCOORD.y > 20.0)\n        {\n            demote;\n        }\n    }\n    bool _25 = helperInvocationEXT();\n    float _26;\n    float _29;\n    float _31;\n    float _33;\n    if (_25)\n    {\n        _26 = 0.0;\n        _29 = 0.0;\n        _31 = 0.0;\n        _33 = 0.0;\n    }\n    else\n    {\n        bool _44 = helperInvocationEXT();\n        bool _46 = helperInvocationEXT();\n        bool _48 = helperInvocationEXT();\n        bool _50 = helperInvocationEXT();\n        _26 = subgroupExclusiveAdd(_44 ? 0.0 : TEXCOORD.x);\n        _29 = subgroupExclusiveAdd(_46 ? 0.0 : TEXCOORD.y);\n        _31 = subgroupExclusiveAdd(_48 ? 0.0 : (TEXCOORD.x * TEXCOORD.x));\n        _33 = subgroupExclusiveAdd(_50 ? 0.0 : (TEXCOORD.y * TEXCOORD.y));\n    }\n    SV_Target.x = _26;\n    SV_Target.y = _29;\n    SV_Target.z = _31;\n    SV_Target.w = _33;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformArithmetic\nOpCapability DemoteToHelperInvocation\nOpExtension \"SPV_EXT_demote_to_helper_invocation\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%20 = OpTypeBool\n%22 = OpConstant %5 10\n%24 = OpConstant %5 20\n%27 = OpConstant %5 0\n%35 = OpTypePointer Output %5\n%39 = OpConstant %14 2\n%41 = OpConstant %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %52\n%52 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%21 = OpFOrdGreaterThan %20 %16 %22\nOpSelectionMerge %57 None\nOpBranchConditional %21 %56 %53\n%56 = OpLabel\nOpDemoteToHelperInvocation\nOpBranch %57\n%53 = OpLabel\n%23 = OpFOrdGreaterThan %20 %19 %24\nOpSelectionMerge %55 None\nOpBranchConditional %23 %54 %55\n%54 = OpLabel\nOpDemoteToHelperInvocation\nOpBranch %55\n%55 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%25 = OpIsHelperInvocationEXT %20\nOpSelectionMerge %59 None\nOpBranchConditional %25 %59 %58\n%58 = OpLabel\n%42 = OpFMul %5 %16 %16\n%43 = OpFMul %5 %19 %19\n%44 = OpIsHelperInvocationEXT %20\n%45 = OpSelect %5 %44 %27 %16\n%28 = OpGroupNonUniformFAdd %5 %41 ExclusiveScan %45\n%46 = OpIsHelperInvocationEXT %20\n%47 = OpSelect %5 %46 %27 %19\n%30 = OpGroupNonUniformFAdd %5 %41 ExclusiveScan %47\n%48 = OpIsHelperInvocationEXT %20\n%49 = OpSelect %5 %48 %27 %42\n%32 = OpGroupNonUniformFAdd %5 %41 ExclusiveScan %49\n%50 = OpIsHelperInvocationEXT %20\n%51 = OpSelect %5 %50 %27 %43\n%34 = OpGroupNonUniformFAdd %5 %41 ExclusiveScan %51\nOpBranch %59\n%59 = OpLabel\n%26 = OpPhi %5 %27 %57 %28 %58\n%29 = OpPhi %5 %27 %57 %30 %58\n%31 = OpPhi %5 %27 %57 %32 %58\n%33 = OpPhi %5 %27 %57 %34 %58\n%36 = OpAccessChain %35 %11 %15\nOpStore %36 %26\n%37 = OpAccessChain %35 %11 %18\nOpStore %37 %29\n%38 = OpAccessChain %35 %11 %39\nOpStore %38 %31\n%40 = OpAccessChain %35 %11 %41\nOpStore %40 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/is-helper-lane.sm66.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (TEXCOORD.x > 10.0)\n    {\n        discard_state = true;\n    }\n    else\n    {\n        if (TEXCOORD.y > 20.0)\n        {\n            discard_state = true;\n        }\n    }\n    float _29;\n    float _32;\n    float _34;\n    float _36;\n    if (gl_HelperInvocation || discard_state)\n    {\n        _29 = 0.0;\n        _32 = 0.0;\n        _34 = 0.0;\n        _36 = 0.0;\n    }\n    else\n    {\n        _29 = subgroupExclusiveAdd((gl_HelperInvocation || discard_state) ? 0.0 : TEXCOORD.x);\n        _32 = subgroupExclusiveAdd((gl_HelperInvocation || discard_state) ? 0.0 : TEXCOORD.y);\n        _34 = subgroupExclusiveAdd((gl_HelperInvocation || discard_state) ? 0.0 : (TEXCOORD.x * TEXCOORD.x));\n        _36 = subgroupExclusiveAdd((gl_HelperInvocation || discard_state) ? 0.0 : (TEXCOORD.y * TEXCOORD.y));\n    }\n    SV_Target.x = _29;\n    SV_Target.y = _32;\n    SV_Target.z = _34;\n    SV_Target.w = _36;\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 84\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformArithmetic\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11 %65\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %11 \"SV_Target\"\nOpName %24 \"discard_state\"\nOpName %76 \"discard_exit\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\nOpDecorate %65 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%20 = OpTypeBool\n%22 = OpConstant %5 10\n%23 = OpTypePointer Private %20\n%24 = OpVariable %23 Private\n%25 = OpConstantFalse %20\n%27 = OpConstant %5 20\n%30 = OpConstant %5 0\n%38 = OpTypePointer Output %5\n%42 = OpConstant %14 2\n%44 = OpConstant %14 3\n%63 = OpConstantTrue %20\n%64 = OpTypePointer Input %20\n%65 = OpVariable %64 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %24 %25\nOpBranch %55\n%55 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%21 = OpFOrdGreaterThan %20 %16 %22\nOpSelectionMerge %60 None\nOpBranchConditional %21 %59 %56\n%59 = OpLabel\nOpStore %24 %63\nOpBranch %60\n%56 = OpLabel\n%26 = OpFOrdGreaterThan %20 %19 %27\nOpSelectionMerge %58 None\nOpBranchConditional %26 %57 %58\n%57 = OpLabel\nOpStore %24 %63\nOpBranch %58\n%58 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%66 = OpLoad %20 %65\n%67 = OpLoad %20 %24\n%28 = OpLogicalOr %20 %66 %67\nOpSelectionMerge %62 None\nOpBranchConditional %28 %62 %61\n%61 = OpLabel\n%45 = OpFMul %5 %16 %16\n%46 = OpFMul %5 %19 %19\n%68 = OpLoad %20 %65\n%69 = OpLoad %20 %24\n%47 = OpLogicalOr %20 %68 %69\n%48 = OpSelect %5 %47 %30 %16\n%31 = OpGroupNonUniformFAdd %5 %44 ExclusiveScan %48\n%70 = OpLoad %20 %65\n%71 = OpLoad %20 %24\n%49 = OpLogicalOr %20 %70 %71\n%50 = OpSelect %5 %49 %30 %19\n%33 = OpGroupNonUniformFAdd %5 %44 ExclusiveScan %50\n%72 = OpLoad %20 %65\n%73 = OpLoad %20 %24\n%51 = OpLogicalOr %20 %72 %73\n%52 = OpSelect %5 %51 %30 %45\n%35 = OpGroupNonUniformFAdd %5 %44 ExclusiveScan %52\n%74 = OpLoad %20 %65\n%75 = OpLoad %20 %24\n%53 = OpLogicalOr %20 %74 %75\n%54 = OpSelect %5 %53 %30 %46\n%37 = OpGroupNonUniformFAdd %5 %44 ExclusiveScan %54\nOpBranch %62\n%62 = OpLabel\n%29 = OpPhi %5 %30 %60 %31 %61\n%32 = OpPhi %5 %30 %60 %33 %61\n%34 = OpPhi %5 %30 %60 %35 %61\n%36 = OpPhi %5 %30 %60 %37 %61\n%39 = OpAccessChain %38 %11 %15\nOpStore %39 %29\n%40 = OpAccessChain %38 %11 %18\nOpStore %40 %32\n%41 = OpAccessChain %38 %11 %42\nOpStore %41 %34\n%43 = OpAccessChain %38 %11 %44\nOpStore %43 %36\n%82 = OpFunctionCall %1 %76\nOpReturn\nOpFunctionEnd\n%76 = OpFunction %1 None %2\n%77 = OpLabel\n%80 = OpLoad %20 %24\nOpSelectionMerge %79 None\nOpBranchConditional %80 %78 %79\n%78 = OpLabel\nOpKill\n%79 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/isfinite.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec3 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (!(isnan(A.x) || isinf(A.x))) ? A.y : A.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%22 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%23 = OpIsNan %22 %15\n%24 = OpIsInf %22 %15\n%25 = OpLogicalOr %22 %23 %24\n%26 = OpLogicalNot %22 %25\n%27 = OpSelect %5 %26 %18 %21\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/isinf.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec3 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = isinf(A.x) ? A.y : A.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%22 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%23 = OpIsInf %22 %15\n%24 = OpSelect %5 %23 %18 %21\nOpStore %10 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/isnan.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec3 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = isnan(A.x) ? A.y : A.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%22 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%23 = OpIsNan %22 %15\n%24 = OpSelect %5 %23 %18 %21\nOpStore %10 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/log.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = log2(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Log2 %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/make-double.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec2 VALUE;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = float(packDouble2x32(uvec2(VALUE.x, VALUE.y)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\n%19 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %8 \"VALUE\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeFloat 32\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpConstant %5 0\n%17 = OpConstant %5 1\n%20 = OpTypeFloat 64\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%13 = OpAccessChain %12 %8 %14\n%15 = OpLoad %5 %13\n%16 = OpAccessChain %12 %8 %17\n%18 = OpLoad %5 %16\n%22 = OpCompositeConstruct %6 %15 %18\n%21 = OpExtInst %20 %19 PackDouble2x32 %22\n%23 = OpFConvert %9 %21\nOpStore %11 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/msaa-uav.sm67.comp",
    "content": "#version 460\nlayout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2DMS _8;\nlayout(set = 0, binding = 1, r32f) uniform coherent image2DMSArray _11;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _15;\n\nvoid main()\n{\n    uint _33 = gl_GlobalInvocationID.x ^ 1u;\n    uint _34 = gl_GlobalInvocationID.y ^ 2u;\n    uint _35 = gl_GlobalInvocationID.z ^ 3u;\n    uint _44 = ((_34 << 4u) + (_33 << 2u)) + (_35 << 6u);\n    float _45 = float(_44);\n    float _47 = float(_44 | 1u);\n    float _49 = float(_44 | 2u);\n    float _51 = float(_44 | 3u);\n    if (gl_GlobalInvocationID.z == 3u)\n    {\n        imageStore(_8, ivec2(uvec2(_33, _34)), 0u, vec4(_45));\n        imageStore(_8, ivec2(uvec2(_33, _34)), 1u, vec4(_47));\n        imageStore(_8, ivec2(uvec2(_33, _34)), 2u, vec4(_49));\n        imageStore(_8, ivec2(uvec2(_33, _34)), 3u, vec4(_51));\n    }\n    else\n    {\n        imageStore(_11, ivec3(uvec3(_33, _34, _35)), 0u, vec4(_45));\n        imageStore(_11, ivec3(uvec3(_33, _34, _35)), 1u, vec4(_47));\n        imageStore(_11, ivec3(uvec3(_33, _34, _35)), 2u, vec4(_49));\n        imageStore(_11, ivec3(uvec3(_33, _34, _35)), 3u, vec4(_51));\n    }\n    groupMemoryBarrier();\n    barrier();\n    float _32[4];\n    float _102;\n    float _104;\n    float _106;\n    float _108;\n    if (gl_GlobalInvocationID.z == 0u)\n    {\n        vec4 _83 = imageLoad(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), 0u);\n        float _85 = _83.x;\n        _32[0u] = _85;\n        vec4 _86 = imageLoad(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), 1u);\n        float _88 = _86.x;\n        _32[1u] = _88;\n        vec4 _90 = imageLoad(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), 2u);\n        float _92 = _90.x;\n        _32[2u] = _92;\n        vec4 _94 = imageLoad(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), 3u);\n        float _96 = _94.x;\n        _32[3u] = _96;\n        _102 = _96;\n        _104 = _92;\n        _106 = _88;\n        _108 = _85;\n    }\n    else\n    {\n        _32[0u] = imageLoad(_11, ivec3(uvec3(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, gl_GlobalInvocationID.z)), 0u).x;\n        uint _128;\n        _128 = 1u;\n        for (;;)\n        {\n            _32[_128] = imageLoad(_11, ivec3(uvec3(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, gl_GlobalInvocationID.z)), _128).x;\n            uint _129 = _128 + 1u;\n            if (_129 == 4u)\n            {\n                break;\n            }\n            else\n            {\n                _128 = _129;\n            }\n        }\n        _102 = _32[3u];\n        _104 = _32[2u];\n        _106 = _32[1u];\n        _108 = _32[0u];\n    }\n    uint _115 = (((gl_GlobalInvocationID.y << 2u) + gl_GlobalInvocationID.x) + (gl_GlobalInvocationID.z << 4u)) * 4u;\n    imageStore(_15, int(_115), uvec4(floatBitsToUint(_108)));\n    imageStore(_15, int(_115 + 1u), uvec4(floatBitsToUint(_106)));\n    imageStore(_15, int(_115 + 2u), uvec4(floatBitsToUint(_104)));\n    imageStore(_15, int(_115 + 3u), uvec4(floatBitsToUint(_102)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 149\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageMultisample\nOpCapability ImageBuffer\nOpCapability ImageMSArray\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 4 4 4\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %11 Coherent\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 2\nOpDecorate %15 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 1 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 1 2 R32f\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeInt 32 0\n%13 = OpTypeImage %12 Buffer 0 0 0 2 R32ui\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypeVector %12 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %12\n%21 = OpConstant %12 0\n%24 = OpConstant %12 1\n%27 = OpConstant %12 2\n%29 = OpConstant %12 4\n%30 = OpTypeArray %5 %29\n%31 = OpTypePointer Function %30\n%36 = OpConstant %12 3\n%37 = OpTypeBool\n%40 = OpConstant %12 6\n%53 = OpTypeVector %12 2\n%55 = OpTypeVector %5 4\n%78 = OpConstant %12 2120\n%80 = OpTypePointer Function %5\n%120 = OpTypeVector %12 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%32 = OpVariable %31 Function\nOpBranch %139\n%139 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %12 %20\n%23 = OpAccessChain %19 %18 %24\n%25 = OpLoad %12 %23\n%26 = OpAccessChain %19 %18 %27\n%28 = OpLoad %12 %26\n%33 = OpBitwiseXor %12 %22 %24\n%34 = OpBitwiseXor %12 %25 %27\n%35 = OpBitwiseXor %12 %28 %36\n%38 = OpIEqual %37 %28 %36\n%39 = OpShiftLeftLogical %12 %35 %40\n%41 = OpShiftLeftLogical %12 %34 %29\n%42 = OpShiftLeftLogical %12 %33 %27\n%43 = OpIAdd %12 %41 %42\n%44 = OpIAdd %12 %43 %39\n%45 = OpConvertUToF %5 %44\n%46 = OpBitwiseOr %12 %44 %24\n%47 = OpConvertUToF %5 %46\n%48 = OpBitwiseOr %12 %44 %27\n%49 = OpConvertUToF %5 %48\n%50 = OpBitwiseOr %12 %44 %36\n%51 = OpConvertUToF %5 %50\nOpSelectionMerge %142 None\nOpBranchConditional %38 %141 %140\n%141 = OpLabel\n%52 = OpLoad %6 %8\n%54 = OpCompositeConstruct %53 %33 %34\n%56 = OpCompositeConstruct %55 %45 %45 %45 %45\nOpImageWrite %52 %54 %56 Sample %21\n%57 = OpLoad %6 %8\n%58 = OpCompositeConstruct %53 %33 %34\n%59 = OpCompositeConstruct %55 %47 %47 %47 %47\nOpImageWrite %57 %58 %59 Sample %24\n%60 = OpLoad %6 %8\n%61 = OpCompositeConstruct %53 %33 %34\n%62 = OpCompositeConstruct %55 %49 %49 %49 %49\nOpImageWrite %60 %61 %62 Sample %27\n%63 = OpLoad %6 %8\n%64 = OpCompositeConstruct %53 %33 %34\n%65 = OpCompositeConstruct %55 %51 %51 %51 %51\nOpImageWrite %63 %64 %65 Sample %36\nOpBranch %142\n%140 = OpLabel\n%66 = OpLoad %9 %11\n%67 = OpCompositeConstruct %16 %33 %34 %35\n%68 = OpCompositeConstruct %55 %45 %45 %45 %45\nOpImageWrite %66 %67 %68 Sample %21\n%69 = OpLoad %9 %11\n%70 = OpCompositeConstruct %16 %33 %34 %35\n%71 = OpCompositeConstruct %55 %47 %47 %47 %47\nOpImageWrite %69 %70 %71 Sample %24\n%72 = OpLoad %9 %11\n%73 = OpCompositeConstruct %16 %33 %34 %35\n%74 = OpCompositeConstruct %55 %49 %49 %49 %49\nOpImageWrite %72 %73 %74 Sample %27\n%75 = OpLoad %9 %11\n%76 = OpCompositeConstruct %16 %33 %34 %35\n%77 = OpCompositeConstruct %55 %51 %51 %51 %51\nOpImageWrite %75 %76 %77 Sample %36\nOpBranch %142\n%142 = OpLabel\nOpControlBarrier %27 %27 %78\n%79 = OpIEqual %37 %28 %21\n%81 = OpAccessChain %80 %32 %21\nOpSelectionMerge %147 None\nOpBranchConditional %79 %146 %143\n%146 = OpLabel\n%82 = OpLoad %6 %8\n%84 = OpCompositeConstruct %53 %22 %25\n%83 = OpImageRead %55 %82 %84 Sample %21\n%85 = OpCompositeExtract %5 %83 0\nOpStore %81 %85\n%87 = OpCompositeConstruct %53 %22 %25\n%86 = OpImageRead %55 %82 %87 Sample %24\n%88 = OpCompositeExtract %5 %86 0\n%89 = OpAccessChain %80 %32 %24\nOpStore %89 %88\n%91 = OpCompositeConstruct %53 %22 %25\n%90 = OpImageRead %55 %82 %91 Sample %27\n%92 = OpCompositeExtract %5 %90 0\n%93 = OpAccessChain %80 %32 %27\nOpStore %93 %92\n%95 = OpCompositeConstruct %53 %22 %25\n%94 = OpImageRead %55 %82 %95 Sample %36\n%96 = OpCompositeExtract %5 %94 0\n%97 = OpAccessChain %80 %32 %36\nOpStore %97 %96\nOpBranch %147\n%143 = OpLabel\n%98 = OpLoad %9 %11\n%100 = OpCompositeConstruct %16 %22 %25 %28\n%99 = OpImageRead %55 %98 %100 Sample %21\n%101 = OpCompositeExtract %5 %99 0\nOpStore %81 %101\nOpBranch %144\n%144 = OpLabel\n%128 = OpPhi %12 %24 %143 %129 %144\n%130 = OpLoad %9 %11\n%132 = OpCompositeConstruct %16 %22 %25 %28\n%131 = OpImageRead %55 %130 %132 Sample %128\n%133 = OpCompositeExtract %5 %131 0\n%134 = OpAccessChain %80 %32 %128\nOpStore %134 %133\n%129 = OpIAdd %12 %128 %24\n%135 = OpIEqual %37 %129 %29\nOpLoopMerge %145 %144 None\nOpBranchConditional %135 %145 %144\n%145 = OpLabel\n%109 = OpLoad %5 %81\n%136 = OpInBoundsAccessChain %80 %32 %24\n%107 = OpLoad %5 %136\n%137 = OpInBoundsAccessChain %80 %32 %27\n%105 = OpLoad %5 %137\n%138 = OpInBoundsAccessChain %80 %32 %36\n%103 = OpLoad %5 %138\nOpBranch %147\n%147 = OpLabel\n%102 = OpPhi %5 %96 %146 %103 %145\n%104 = OpPhi %5 %92 %146 %105 %145\n%106 = OpPhi %5 %88 %146 %107 %145\n%108 = OpPhi %5 %85 %146 %109 %145\n%110 = OpShiftLeftLogical %12 %28 %29\n%111 = OpShiftLeftLogical %12 %25 %27\n%112 = OpIAdd %12 %111 %22\n%113 = OpIAdd %12 %112 %110\n%114 = OpLoad %13 %15\n%115 = OpIMul %12 %113 %29\n%116 = OpBitcast %12 %108\n%117 = OpBitcast %12 %106\n%118 = OpBitcast %12 %104\n%119 = OpBitcast %12 %102\n%121 = OpCompositeConstruct %120 %116 %116 %116 %116\nOpImageWrite %114 %115 %121\n%122 = OpCompositeConstruct %120 %117 %117 %117 %117\n%123 = OpIAdd %12 %115 %24\nOpImageWrite %114 %123 %122\n%124 = OpCompositeConstruct %120 %118 %118 %118 %118\n%125 = OpIAdd %12 %115 %27\nOpImageWrite %114 %125 %124\n%126 = OpCompositeConstruct %120 %119 %119 %119 %119\n%127 = OpIAdd %12 %115 %36\nOpImageWrite %114 %127 %126\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/msad.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _11;\n\nvoid main()\n{\n    uint _21 = gl_GlobalInvocationID.x * 4u;\n    uvec4 _38 = uvec4(texelFetch(_8, int(_21)).x, texelFetch(_8, int(_21 + 1u)).x, texelFetch(_8, int(_21 + 2u)).x, texelFetch(_8, int(_21 + 3u)).x);\n    uint _39 = _38.w;\n    uint _40 = _38.y;\n    uint _41 = _38.z;\n    uint _42 = _38.x;\n    uint _47 = 24u & 31u;\n    uint _53 = bitfieldInsert(_40 >> 8u, _41, int(_47), int(min((8u & 31u), (32u - _47))));\n    uint _57 = 16u & 31u;\n    uint _60 = bitfieldInsert(_40 >> 16u, _41, int(_57), int(min((16u & 31u), (32u - _57))));\n    uint _63 = 8u & 31u;\n    uint _66 = bitfieldInsert(_40 >> 24u, _41, int(_63), int(min((24u & 31u), (32u - _63))));\n    uvec4 _77 = uvec4(bitfieldExtract(_42, int(0u), int(8u)), bitfieldExtract(_42, int(8u), int(8u)), bitfieldExtract(_42, int(16u), int(8u)), bitfieldExtract(_42, int(24u), int(8u)));\n    uvec4 _83 = mix(uvec4(abs(ivec4(_77 - uvec4(bitfieldExtract(_40, int(0u), int(8u)), bitfieldExtract(_40, int(8u), int(8u)), bitfieldExtract(_40, int(16u), int(8u)), bitfieldExtract(_40, int(24u), int(8u)))))), uvec4(0u), equal(_77, uvec4(0u)));\n    uvec4 _100 = uvec4(bitfieldExtract(_42, int(0u), int(8u)), bitfieldExtract(_42, int(8u), int(8u)), bitfieldExtract(_42, int(16u), int(8u)), bitfieldExtract(_42, int(24u), int(8u)));\n    uvec4 _106 = mix(uvec4(abs(ivec4(_100 - uvec4(bitfieldExtract(_53, int(0u), int(8u)), bitfieldExtract(_53, int(8u), int(8u)), bitfieldExtract(_53, int(16u), int(8u)), bitfieldExtract(_53, int(24u), int(8u)))))), uvec4(0u), equal(_100, uvec4(0u)));\n    uvec4 _123 = uvec4(bitfieldExtract(_42, int(0u), int(8u)), bitfieldExtract(_42, int(8u), int(8u)), bitfieldExtract(_42, int(16u), int(8u)), bitfieldExtract(_42, int(24u), int(8u)));\n    uvec4 _129 = mix(uvec4(abs(ivec4(_123 - uvec4(bitfieldExtract(_60, int(0u), int(8u)), bitfieldExtract(_60, int(8u), int(8u)), bitfieldExtract(_60, int(16u), int(8u)), bitfieldExtract(_60, int(24u), int(8u)))))), uvec4(0u), equal(_123, uvec4(0u)));\n    uvec4 _146 = uvec4(bitfieldExtract(_42, int(0u), int(8u)), bitfieldExtract(_42, int(8u), int(8u)), bitfieldExtract(_42, int(16u), int(8u)), bitfieldExtract(_42, int(24u), int(8u)));\n    uvec4 _152 = mix(uvec4(abs(ivec4(_146 - uvec4(bitfieldExtract(_66, int(0u), int(8u)), bitfieldExtract(_66, int(8u), int(8u)), bitfieldExtract(_66, int(16u), int(8u)), bitfieldExtract(_66, int(24u), int(8u)))))), uvec4(0u), equal(_146, uvec4(0u)));\n    uint _161 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_11, int(_161), uvec4(_39 + (((_83.x + _83.y) + _83.z) + _83.w)));\n    imageStore(_11, int(_161 + 1u), uvec4(_39 + (((_106.x + _106.y) + _106.z) + _106.w)));\n    imageStore(_11, int(_161 + 2u), uvec4(_39 + (((_129.x + _129.y) + _129.z) + _129.w)));\n    imageStore(_11, int(_161 + 3u), uvec4(_39 + (((_152.x + _152.y) + _152.z) + _152.w)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 171\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\n%52 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 4\n%23 = OpTypeVector %5 4\n%28 = OpConstant %5 1\n%32 = OpConstant %5 2\n%36 = OpConstant %5 3\n%44 = OpConstant %5 8\n%46 = OpConstant %5 31\n%48 = OpConstant %5 24\n%50 = OpConstant %5 32\n%55 = OpConstant %5 16\n%67 = OpTypeBool\n%68 = OpTypeVector %67 4\n%79 = OpConstantNull %23\n%102 = OpConstantNull %23\n%125 = OpConstantNull %23\n%148 = OpConstantNull %23\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %169\n%169 = OpLabel\n%12 = OpLoad %9 %11\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%21 = OpIMul %5 %20 %22\n%24 = OpImageFetch %23 %13 %21\n%25 = OpCompositeExtract %5 %24 0\n%27 = OpIAdd %5 %21 %28\n%26 = OpImageFetch %23 %13 %27\n%29 = OpCompositeExtract %5 %26 0\n%31 = OpIAdd %5 %21 %32\n%30 = OpImageFetch %23 %13 %31\n%33 = OpCompositeExtract %5 %30 0\n%35 = OpIAdd %5 %21 %36\n%34 = OpImageFetch %23 %13 %35\n%37 = OpCompositeExtract %5 %34 0\n%38 = OpCompositeConstruct %23 %25 %29 %33 %37\n%39 = OpCompositeExtract %5 %38 3\n%40 = OpCompositeExtract %5 %38 1\n%41 = OpCompositeExtract %5 %38 2\n%42 = OpCompositeExtract %5 %38 0\n%43 = OpShiftRightLogical %5 %40 %44\n%45 = OpBitwiseAnd %5 %44 %46\n%47 = OpBitwiseAnd %5 %48 %46\n%49 = OpISub %5 %50 %47\n%51 = OpExtInst %5 %52 UMin %45 %49\n%53 = OpBitFieldInsert %5 %43 %41 %47 %51\n%54 = OpShiftRightLogical %5 %40 %55\n%56 = OpBitwiseAnd %5 %55 %46\n%57 = OpBitwiseAnd %5 %55 %46\n%58 = OpISub %5 %50 %57\n%59 = OpExtInst %5 %52 UMin %56 %58\n%60 = OpBitFieldInsert %5 %54 %41 %57 %59\n%61 = OpShiftRightLogical %5 %40 %48\n%62 = OpBitwiseAnd %5 %48 %46\n%63 = OpBitwiseAnd %5 %44 %46\n%64 = OpISub %5 %50 %63\n%65 = OpExtInst %5 %52 UMin %62 %64\n%66 = OpBitFieldInsert %5 %61 %41 %63 %65\n%69 = OpBitFieldUExtract %5 %42 %19 %44\n%70 = OpBitFieldUExtract %5 %40 %19 %44\n%71 = OpBitFieldUExtract %5 %42 %44 %44\n%72 = OpBitFieldUExtract %5 %40 %44 %44\n%73 = OpBitFieldUExtract %5 %42 %55 %44\n%74 = OpBitFieldUExtract %5 %40 %55 %44\n%75 = OpBitFieldUExtract %5 %42 %48 %44\n%76 = OpBitFieldUExtract %5 %40 %48 %44\n%77 = OpCompositeConstruct %23 %69 %71 %73 %75\n%78 = OpCompositeConstruct %23 %70 %72 %74 %76\n%80 = OpIEqual %68 %77 %79\n%81 = OpISub %23 %77 %78\n%82 = OpExtInst %23 %52 SAbs %81\n%83 = OpSelect %23 %80 %79 %82\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpCompositeExtract %5 %83 1\n%86 = OpIAdd %5 %84 %85\n%87 = OpCompositeExtract %5 %83 2\n%88 = OpIAdd %5 %86 %87\n%89 = OpCompositeExtract %5 %83 3\n%90 = OpIAdd %5 %88 %89\n%91 = OpIAdd %5 %39 %90\n%92 = OpBitFieldUExtract %5 %42 %19 %44\n%93 = OpBitFieldUExtract %5 %53 %19 %44\n%94 = OpBitFieldUExtract %5 %42 %44 %44\n%95 = OpBitFieldUExtract %5 %53 %44 %44\n%96 = OpBitFieldUExtract %5 %42 %55 %44\n%97 = OpBitFieldUExtract %5 %53 %55 %44\n%98 = OpBitFieldUExtract %5 %42 %48 %44\n%99 = OpBitFieldUExtract %5 %53 %48 %44\n%100 = OpCompositeConstruct %23 %92 %94 %96 %98\n%101 = OpCompositeConstruct %23 %93 %95 %97 %99\n%103 = OpIEqual %68 %100 %102\n%104 = OpISub %23 %100 %101\n%105 = OpExtInst %23 %52 SAbs %104\n%106 = OpSelect %23 %103 %102 %105\n%107 = OpCompositeExtract %5 %106 0\n%108 = OpCompositeExtract %5 %106 1\n%109 = OpIAdd %5 %107 %108\n%110 = OpCompositeExtract %5 %106 2\n%111 = OpIAdd %5 %109 %110\n%112 = OpCompositeExtract %5 %106 3\n%113 = OpIAdd %5 %111 %112\n%114 = OpIAdd %5 %39 %113\n%115 = OpBitFieldUExtract %5 %42 %19 %44\n%116 = OpBitFieldUExtract %5 %60 %19 %44\n%117 = OpBitFieldUExtract %5 %42 %44 %44\n%118 = OpBitFieldUExtract %5 %60 %44 %44\n%119 = OpBitFieldUExtract %5 %42 %55 %44\n%120 = OpBitFieldUExtract %5 %60 %55 %44\n%121 = OpBitFieldUExtract %5 %42 %48 %44\n%122 = OpBitFieldUExtract %5 %60 %48 %44\n%123 = OpCompositeConstruct %23 %115 %117 %119 %121\n%124 = OpCompositeConstruct %23 %116 %118 %120 %122\n%126 = OpIEqual %68 %123 %125\n%127 = OpISub %23 %123 %124\n%128 = OpExtInst %23 %52 SAbs %127\n%129 = OpSelect %23 %126 %125 %128\n%130 = OpCompositeExtract %5 %129 0\n%131 = OpCompositeExtract %5 %129 1\n%132 = OpIAdd %5 %130 %131\n%133 = OpCompositeExtract %5 %129 2\n%134 = OpIAdd %5 %132 %133\n%135 = OpCompositeExtract %5 %129 3\n%136 = OpIAdd %5 %134 %135\n%137 = OpIAdd %5 %39 %136\n%138 = OpBitFieldUExtract %5 %42 %19 %44\n%139 = OpBitFieldUExtract %5 %66 %19 %44\n%140 = OpBitFieldUExtract %5 %42 %44 %44\n%141 = OpBitFieldUExtract %5 %66 %44 %44\n%142 = OpBitFieldUExtract %5 %42 %55 %44\n%143 = OpBitFieldUExtract %5 %66 %55 %44\n%144 = OpBitFieldUExtract %5 %42 %48 %44\n%145 = OpBitFieldUExtract %5 %66 %48 %44\n%146 = OpCompositeConstruct %23 %138 %140 %142 %144\n%147 = OpCompositeConstruct %23 %139 %141 %143 %145\n%149 = OpIEqual %68 %146 %148\n%150 = OpISub %23 %146 %147\n%151 = OpExtInst %23 %52 SAbs %150\n%152 = OpSelect %23 %149 %148 %151\n%153 = OpCompositeExtract %5 %152 0\n%154 = OpCompositeExtract %5 %152 1\n%155 = OpIAdd %5 %153 %154\n%156 = OpCompositeExtract %5 %152 2\n%157 = OpIAdd %5 %155 %156\n%158 = OpCompositeExtract %5 %152 3\n%159 = OpIAdd %5 %157 %158\n%160 = OpIAdd %5 %39 %159\n%161 = OpIMul %5 %20 %22\n%162 = OpCompositeConstruct %23 %91 %91 %91 %91\nOpImageWrite %12 %161 %162\n%163 = OpCompositeConstruct %23 %114 %114 %114 %114\n%164 = OpIAdd %5 %161 %28\nOpImageWrite %12 %164 %163\n%165 = OpCompositeConstruct %23 %137 %137 %137 %137\n%166 = OpIAdd %5 %161 %32\nOpImageWrite %12 %166 %165\n%167 = OpCompositeConstruct %23 %160 %160 %160 %160\n%168 = OpIAdd %5 %161 %36\nOpImageWrite %12 %168 %167\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/object-ray-direction.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _22;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _21;\n    _21.x = gl_ObjectRayDirectionEXT.x;\n    _21.y = gl_ObjectRayDirectionEXT.y;\n    _21.z = gl_ObjectRayDirectionEXT.z;\n    payload._m0 = _21;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %15\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn ObjectRayDirectionKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %6\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Input %5\n%18 = OpTypeInt 32 0\n%19 = OpConstant %18 0\n%24 = OpConstant %18 1\n%28 = OpConstant %18 2\n%31 = OpTypePointer IncomingRayPayloadKHR %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%22 = OpUndef %6\nOpBranch %33\n%33 = OpLabel\n%17 = OpAccessChain %16 %15 %19\n%20 = OpLoad %5 %17\n%21 = OpCompositeInsert %6 %20 %22 0\n%23 = OpAccessChain %16 %15 %24\n%25 = OpLoad %5 %23\n%26 = OpCompositeInsert %6 %25 %21 1\n%27 = OpAccessChain %16 %15 %28\n%29 = OpLoad %5 %27\n%30 = OpCompositeInsert %6 %29 %26 2\n%32 = OpInBoundsAccessChain %31 %9 %19\nOpStore %32 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/object-ray-origin.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _22;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _21;\n    _21.x = gl_ObjectRayOriginEXT.x;\n    _21.y = gl_ObjectRayOriginEXT.y;\n    _21.z = gl_ObjectRayOriginEXT.z;\n    payload._m0 = _21;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %15\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn ObjectRayOriginKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %6\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Input %5\n%18 = OpTypeInt 32 0\n%19 = OpConstant %18 0\n%24 = OpConstant %18 1\n%28 = OpConstant %18 2\n%31 = OpTypePointer IncomingRayPayloadKHR %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%22 = OpUndef %6\nOpBranch %33\n%33 = OpLabel\n%17 = OpAccessChain %16 %15 %19\n%20 = OpLoad %5 %17\n%21 = OpCompositeInsert %6 %20 %22 0\n%23 = OpAccessChain %16 %15 %24\n%25 = OpLoad %5 %23\n%26 = OpCompositeInsert %6 %25 %21 1\n%27 = OpAccessChain %16 %15 %28\n%29 = OpLoad %5 %27\n%30 = OpCompositeInsert %6 %29 %26 2\n%32 = OpInBoundsAccessChain %31 %9 %19\nOpStore %32 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/object-to-world-3x4.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _59;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _58;\n    _58.x = fma(gl_ObjectToWorldEXT[2u].x, payload._m0.z, fma(gl_ObjectToWorldEXT[1u].x, payload._m0.y, gl_ObjectToWorldEXT[0u].x * payload._m0.x)) + gl_ObjectToWorldEXT[3u].x;\n    _58.y = fma(gl_ObjectToWorldEXT[2u].y, payload._m0.z, fma(gl_ObjectToWorldEXT[1u].y, payload._m0.y, gl_ObjectToWorldEXT[0u].y * payload._m0.x)) + gl_ObjectToWorldEXT[3u].y;\n    _58.z = fma(gl_ObjectToWorldEXT[2u].z, payload._m0.z, fma(gl_ObjectToWorldEXT[1u].z, payload._m0.y, gl_ObjectToWorldEXT[0u].z * payload._m0.x)) + gl_ObjectToWorldEXT[3u].z;\n    payload._m0 = _58;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\n%54 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %24\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %24 BuiltIn ObjectToWorldKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer IncomingRayPayloadKHR %6\n%16 = OpTypeInt 32 0\n%17 = OpConstant %16 0\n%22 = OpTypeMatrix %6 4\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %5\n%29 = OpConstant %16 1\n%32 = OpConstant %16 2\n%35 = OpConstant %16 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%59 = OpUndef %6\nOpBranch %70\n%70 = OpLabel\n%15 = OpInBoundsAccessChain %14 %9 %17\n%18 = OpLoad %6 %15\n%19 = OpCompositeExtract %5 %18 0\n%20 = OpCompositeExtract %5 %18 1\n%21 = OpCompositeExtract %5 %18 2\n%26 = OpAccessChain %25 %24 %17 %17\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %25 %24 %29 %17\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %25 %24 %32 %17\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %25 %24 %35 %17\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %25 %24 %17 %29\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %25 %24 %29 %29\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %25 %24 %32 %29\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %25 %24 %35 %29\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %25 %24 %17 %32\n%46 = OpLoad %5 %45\n%47 = OpAccessChain %25 %24 %29 %32\n%48 = OpLoad %5 %47\n%49 = OpAccessChain %25 %24 %32 %32\n%50 = OpLoad %5 %49\n%51 = OpAccessChain %25 %24 %35 %32\n%52 = OpLoad %5 %51\n%53 = OpFMul %5 %27 %19\n%55 = OpExtInst %5 %54 Fma %30 %20 %53\n%56 = OpExtInst %5 %54 Fma %33 %21 %55\n%57 = OpFAdd %5 %56 %36\n%58 = OpCompositeInsert %6 %57 %59 0\n%60 = OpFMul %5 %38 %19\n%61 = OpExtInst %5 %54 Fma %40 %20 %60\n%62 = OpExtInst %5 %54 Fma %42 %21 %61\n%63 = OpFAdd %5 %62 %44\n%64 = OpCompositeInsert %6 %63 %58 1\n%65 = OpFMul %5 %46 %19\n%66 = OpExtInst %5 %54 Fma %48 %20 %65\n%67 = OpExtInst %5 %54 Fma %50 %21 %66\n%68 = OpFAdd %5 %67 %52\n%69 = OpCompositeInsert %6 %68 %64 2\nOpStore %15 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/object-to-world-4x3.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _59;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _58;\n    _58.x = fma(payload._m0.z, gl_ObjectToWorldEXT[2u].x, fma(payload._m0.y, gl_ObjectToWorldEXT[1u].x, payload._m0.x * gl_ObjectToWorldEXT[0u].x)) + gl_ObjectToWorldEXT[3u].x;\n    _58.y = fma(payload._m0.z, gl_ObjectToWorldEXT[2u].y, fma(payload._m0.y, gl_ObjectToWorldEXT[1u].y, payload._m0.x * gl_ObjectToWorldEXT[0u].y)) + gl_ObjectToWorldEXT[3u].y;\n    _58.z = fma(payload._m0.z, gl_ObjectToWorldEXT[2u].z, fma(payload._m0.y, gl_ObjectToWorldEXT[1u].z, payload._m0.x * gl_ObjectToWorldEXT[0u].z)) + gl_ObjectToWorldEXT[3u].z;\n    payload._m0 = _58;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\n%54 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %16\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %16 BuiltIn ObjectToWorldKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypeMatrix %6 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpTypeInt 32 0\n%20 = OpConstant %19 0\n%23 = OpConstant %19 1\n%26 = OpConstant %19 2\n%41 = OpConstant %19 3\n%47 = OpTypePointer IncomingRayPayloadKHR %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%59 = OpUndef %6\nOpBranch %70\n%70 = OpLabel\n%18 = OpAccessChain %17 %16 %20 %20\n%21 = OpLoad %5 %18\n%22 = OpAccessChain %17 %16 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %17 %16 %20 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %17 %16 %23 %20\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %17 %16 %23 %23\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %17 %16 %23 %26\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %17 %16 %26 %20\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %17 %16 %26 %23\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %17 %16 %26 %26\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %17 %16 %41 %20\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %17 %16 %41 %23\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %17 %16 %41 %26\n%46 = OpLoad %5 %45\n%48 = OpInBoundsAccessChain %47 %9 %20\n%49 = OpLoad %6 %48\n%50 = OpCompositeExtract %5 %49 0\n%51 = OpCompositeExtract %5 %49 1\n%52 = OpCompositeExtract %5 %49 2\n%53 = OpFMul %5 %50 %21\n%55 = OpExtInst %5 %54 Fma %51 %29 %53\n%56 = OpExtInst %5 %54 Fma %52 %35 %55\n%57 = OpFAdd %5 %56 %42\n%58 = OpCompositeInsert %6 %57 %59 0\n%60 = OpFMul %5 %50 %24\n%61 = OpExtInst %5 %54 Fma %51 %31 %60\n%62 = OpExtInst %5 %54 Fma %52 %37 %61\n%63 = OpFAdd %5 %62 %44\n%64 = OpCompositeInsert %6 %63 %58 1\n%65 = OpFMul %5 %50 %27\n%66 = OpExtInst %5 %54 Fma %51 %33 %65\n%67 = OpExtInst %5 %54 Fma %52 %39 %66\n%68 = OpFAdd %5 %67 %46\n%69 = OpCompositeInsert %6 %68 %64 2\nOpStore %48 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/pack-unpack.ssbo.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 1, std430) buffer _18_20\n{\n    u16vec4 _m0[];\n} _20;\n\nvoid main()\n{\n    _14._m0[gl_GlobalInvocationID.x] = uvec4(uvec4(unpack8(_9._m0[gl_GlobalInvocationID.x])));\n    _20._m0[gl_GlobalInvocationID.x] = u16vec4(u16vec4(unpack8(_9._m0[gl_GlobalInvocationID.x])));\n    _14._m0[gl_GlobalInvocationID.x] = uvec4(uvec4(i8vec4(unpack8(_9._m0[gl_GlobalInvocationID.x]))));\n    _20._m0[gl_GlobalInvocationID.x] = u16vec4(u16vec4(i8vec4(unpack8(_9._m0[gl_GlobalInvocationID.x]))));\n    uint _69 = gl_GlobalInvocationID.x + 100000u;\n    uint _78 = pack32(u8vec4(uvec4(_14._m0[_69])));\n    _14._m0[gl_GlobalInvocationID.x + 1000u] = uvec4(_78, _78, pack32(u8vec4(clamp(ivec4(uvec4(_14._m0[_69])), ivec4(0), ivec4(255)))), pack32(u8vec4(clamp(ivec4(uvec4(_14._m0[_69])), ivec4(-128), ivec4(127)))));\n    uint _103 = gl_GlobalInvocationID.x + 100000u;\n    uint16_t _131 = uint16_t(pack32(u8vec4(u16vec4(_20._m0[_103]))));\n    _20._m0[gl_GlobalInvocationID.x + 1000u] = u16vec4(_131, _131, uint16_t(pack32(u8vec4(clamp(i16vec4(u16vec4(_20._m0[_103])), i16vec4(0), i16vec4(255))))), uint16_t(pack32(u8vec4(clamp(i16vec4(u16vec4(_20._m0[_103])), i16vec4(-128), i16vec4(127))))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 139\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer16BitAccess\n%80 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %23\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %18 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %23 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 16 0\n%16 = OpTypeVector %15 4\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeVector %5 3\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypePointer Input %5\n%26 = OpConstant %5 0\n%28 = OpTypePointer StorageBuffer %5\n%31 = OpTypeInt 8 0\n%32 = OpTypeVector %31 4\n%40 = OpTypePointer StorageBuffer %10\n%49 = OpTypePointer StorageBuffer %16\n%68 = OpConstant %5 100000\n%81 = OpTypeInt 32 1\n%82 = OpConstant %81 0\n%83 = OpConstant %81 255\n%84 = OpTypeVector %81 4\n%85 = OpConstantComposite %84 %82 %82 %82 %82\n%86 = OpConstantComposite %84 %83 %83 %83 %83\n%91 = OpConstant %81 -128\n%92 = OpConstant %81 127\n%93 = OpConstantComposite %84 %91 %91 %91 %91\n%94 = OpConstantComposite %84 %92 %92 %92 %92\n%99 = OpConstant %5 1000\n%114 = OpTypeInt 16 1\n%115 = OpConstant %114 0\n%116 = OpConstant %114 255\n%117 = OpTypeVector %114 4\n%118 = OpConstantComposite %117 %115 %115 %115 %115\n%119 = OpConstantComposite %117 %116 %116 %116 %116\n%124 = OpConstant %114 -128\n%125 = OpConstant %114 127\n%126 = OpConstantComposite %117 %124 %124 %124 %124\n%127 = OpConstantComposite %117 %125 %125 %125 %125\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %137\n%137 = OpLabel\n%25 = OpAccessChain %24 %23 %26\n%27 = OpLoad %5 %25\n%29 = OpAccessChain %28 %9 %26 %27\n%30 = OpLoad %5 %29\n%33 = OpBitcast %32 %30\n%34 = OpUConvert %10 %33\n%35 = OpCompositeExtract %5 %34 0\n%36 = OpCompositeExtract %5 %34 1\n%37 = OpCompositeExtract %5 %34 2\n%38 = OpCompositeExtract %5 %34 3\n%39 = OpCompositeConstruct %10 %35 %36 %37 %38\n%41 = OpAccessChain %40 %14 %26 %27\nOpStore %41 %39\n%42 = OpBitcast %32 %30\n%43 = OpUConvert %16 %42\n%44 = OpCompositeExtract %15 %43 0\n%45 = OpCompositeExtract %15 %43 1\n%46 = OpCompositeExtract %15 %43 2\n%47 = OpCompositeExtract %15 %43 3\n%48 = OpCompositeConstruct %16 %44 %45 %46 %47\n%50 = OpAccessChain %49 %20 %26 %27\nOpStore %50 %48\n%51 = OpBitcast %32 %30\n%52 = OpSConvert %10 %51\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpCompositeExtract %5 %52 1\n%55 = OpCompositeExtract %5 %52 2\n%56 = OpCompositeExtract %5 %52 3\n%57 = OpCompositeConstruct %10 %53 %54 %55 %56\n%58 = OpAccessChain %40 %14 %26 %27\nOpStore %58 %57\n%59 = OpBitcast %32 %30\n%60 = OpSConvert %16 %59\n%61 = OpCompositeExtract %15 %60 0\n%62 = OpCompositeExtract %15 %60 1\n%63 = OpCompositeExtract %15 %60 2\n%64 = OpCompositeExtract %15 %60 3\n%65 = OpCompositeConstruct %16 %61 %62 %63 %64\n%66 = OpAccessChain %49 %20 %26 %27\nOpStore %66 %65\n%67 = OpIAdd %5 %27 %68\n%69 = OpIAdd %5 %27 %68\n%70 = OpAccessChain %40 %14 %26 %69\n%71 = OpLoad %10 %70\n%72 = OpCompositeExtract %5 %71 0\n%73 = OpCompositeExtract %5 %71 1\n%74 = OpCompositeExtract %5 %71 2\n%75 = OpCompositeExtract %5 %71 3\n%76 = OpCompositeConstruct %10 %72 %73 %74 %75\n%77 = OpUConvert %32 %76\n%78 = OpBitcast %5 %77\n%79 = OpCompositeConstruct %10 %72 %73 %74 %75\n%87 = OpExtInst %84 %80 SClamp %79 %85 %86\n%88 = OpUConvert %32 %87\n%89 = OpBitcast %5 %88\n%90 = OpCompositeConstruct %10 %72 %73 %74 %75\n%95 = OpExtInst %84 %80 SClamp %90 %93 %94\n%96 = OpUConvert %32 %95\n%97 = OpBitcast %5 %96\n%98 = OpIAdd %5 %27 %99\n%100 = OpIAdd %5 %27 %99\n%101 = OpCompositeConstruct %10 %78 %78 %89 %97\n%102 = OpAccessChain %40 %14 %26 %100\nOpStore %102 %101\n%103 = OpIAdd %5 %27 %68\n%104 = OpAccessChain %49 %20 %26 %103\n%105 = OpLoad %16 %104\n%106 = OpCompositeExtract %15 %105 0\n%107 = OpCompositeExtract %15 %105 1\n%108 = OpCompositeExtract %15 %105 2\n%109 = OpCompositeExtract %15 %105 3\n%110 = OpCompositeConstruct %16 %106 %107 %108 %109\n%111 = OpUConvert %32 %110\n%112 = OpBitcast %5 %111\n%113 = OpCompositeConstruct %16 %106 %107 %108 %109\n%120 = OpExtInst %117 %80 SClamp %113 %118 %119\n%121 = OpUConvert %32 %120\n%122 = OpBitcast %5 %121\n%123 = OpCompositeConstruct %16 %106 %107 %108 %109\n%128 = OpExtInst %117 %80 SClamp %123 %126 %127\n%129 = OpUConvert %32 %128\n%130 = OpBitcast %5 %129\n%131 = OpUConvert %15 %112\n%132 = OpUConvert %15 %122\n%133 = OpUConvert %15 %130\n%134 = OpIAdd %5 %27 %99\n%135 = OpCompositeConstruct %16 %131 %131 %132 %133\n%136 = OpAccessChain %49 %20 %26 %134\nOpStore %136 %135\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-all-any.sm67.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\n\nbool QuadAny(bool _24)\n{\n    return ((subgroupQuadBroadcast(_24, 0u) || subgroupQuadBroadcast(_24, 1u)) || subgroupQuadBroadcast(_24, 2u)) || subgroupQuadBroadcast(_24, 3u);\n}\n\nbool QuadAll(bool _43)\n{\n    return ((subgroupQuadBroadcast(_43, 0u) && subgroupQuadBroadcast(_43, 1u)) && subgroupQuadBroadcast(_43, 2u)) && subgroupQuadBroadcast(_43, 3u);\n}\n\nvoid main()\n{\n    imageStore(_9, int(gl_GlobalInvocationID.x * 2u), uvec4(uint(QuadAny(imageLoad(_8, int(gl_GlobalInvocationID.x)).x != 0u))));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 2u) + 1u), uvec4(uint(QuadAll(imageLoad(_8, int(gl_GlobalInvocationID.x)).x != 0u))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 68\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformQuad\nOpCapability ComputeDerivativeGroupQuadsKHR\nOpExtension \"SPV_KHR_compute_shader_derivatives\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 DerivativeGroupQuadsKHR\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %25 \"QuadAny\"\nOpName %44 \"QuadAll\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpTypeVector %5 4\n%21 = OpTypeBool\n%23 = OpTypeFunction %21 %21\n%28 = OpConstant %5 3\n%30 = OpConstant %5 1\n%32 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %66\n%66 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpLoad %6 %8\n%19 = OpImageRead %18 %17 %16\n%20 = OpCompositeExtract %5 %19 0\n%22 = OpINotEqual %21 %20 %15\n%38 = OpFunctionCall %21 %25 %22\n%39 = OpLoad %6 %8\n%40 = OpImageRead %18 %39 %16\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpINotEqual %21 %41 %15\n%54 = OpFunctionCall %21 %44 %42\n%55 = OpSelect %5 %38 %30 %15\n%56 = OpShiftLeftLogical %5 %16 %30\n%57 = OpLoad %6 %9\n%58 = OpIMul %5 %16 %32\n%59 = OpCompositeConstruct %18 %55 %55 %55 %55\nOpImageWrite %57 %58 %59\n%60 = OpSelect %5 %54 %30 %15\n%61 = OpBitwiseOr %5 %56 %30\n%62 = OpLoad %6 %9\n%63 = OpIMul %5 %16 %32\n%64 = OpIAdd %5 %63 %30\n%65 = OpCompositeConstruct %18 %60 %60 %60 %60\nOpImageWrite %62 %64 %65\nOpReturn\nOpFunctionEnd\n%25 = OpFunction %21 None %23\n%24 = OpFunctionParameter %21\n%26 = OpLabel\n%27 = OpGroupNonUniformQuadBroadcast %21 %28 %24 %15\n%29 = OpGroupNonUniformQuadBroadcast %21 %28 %24 %30\n%31 = OpGroupNonUniformQuadBroadcast %21 %28 %24 %32\n%33 = OpGroupNonUniformQuadBroadcast %21 %28 %24 %28\n%34 = OpLogicalOr %21 %27 %29\n%35 = OpLogicalOr %21 %34 %31\n%36 = OpLogicalOr %21 %35 %33\nOpReturnValue %36\nOpFunctionEnd\n%44 = OpFunction %21 None %23\n%43 = OpFunctionParameter %21\n%45 = OpLabel\n%46 = OpGroupNonUniformQuadBroadcast %21 %28 %43 %15\n%47 = OpGroupNonUniformQuadBroadcast %21 %28 %43 %30\n%48 = OpGroupNonUniformQuadBroadcast %21 %28 %43 %32\n%49 = OpGroupNonUniformQuadBroadcast %21 %28 %43 %28\n%50 = OpLogicalAnd %21 %46 %47\n%51 = OpLogicalAnd %21 %50 %48\n%52 = OpLogicalAnd %21 %51 %49\nOpReturnValue %52\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-all-any.sm67.quad-maximal-reconvergence.noglsl.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability QuadControlKHR\nOpCapability ComputeDerivativeGroupQuadsKHR\nOpExtension \"SPV_KHR_compute_shader_derivatives\"\nOpExtension \"SPV_KHR_quad_control\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 DerivativeGroupQuadsKHR\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpTypeVector %5 4\n%21 = OpTypeBool\n%29 = OpConstant %5 1\n%34 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpLoad %6 %8\n%19 = OpImageRead %18 %17 %16\n%20 = OpCompositeExtract %5 %19 0\n%22 = OpINotEqual %21 %20 %15\n%23 = OpGroupNonUniformQuadAnyKHR %21 %22\n%24 = OpLoad %6 %8\n%25 = OpImageRead %18 %24 %16\n%26 = OpCompositeExtract %5 %25 0\n%27 = OpINotEqual %21 %26 %15\n%28 = OpGroupNonUniformQuadAllKHR %21 %27\n%30 = OpSelect %5 %23 %29 %15\n%31 = OpShiftLeftLogical %5 %16 %29\n%32 = OpLoad %6 %9\n%33 = OpIMul %5 %16 %34\n%35 = OpCompositeConstruct %18 %30 %30 %30 %30\nOpImageWrite %32 %33 %35\n%36 = OpSelect %5 %28 %29 %15\n%37 = OpBitwiseOr %5 %31 %29\n%38 = OpLoad %6 %9\n%39 = OpIMul %5 %16 %34\n%40 = OpIAdd %5 %39 %29\n%41 = OpCompositeConstruct %18 %36 %36 %36 %36\nOpImageWrite %38 %40 %41\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-read-at-2d.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_shuffle : require\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\n\nvoid main()\n{\n    uint _23 = (gl_WorkGroupID.x << 6u) + gl_LocalInvocationIndex;\n    uvec4 _27 = imageLoad(_8, int(_23));\n    uint _28 = _27.x;\n    uint _40 = _23 * 2u;\n    imageStore(_9, int(_40), uvec4(subgroupQuadBroadcast(_28, 1u)));\n    imageStore(_9, int(_40 + 1u), uvec4(subgroupShuffle(_28, (gl_SubgroupInvocationID & 4294967292u) + (_28 & 3u))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformShuffle\nOpCapability GroupNonUniformQuad\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %13 %17 %33\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %13 BuiltIn LocalInvocationIndex\nOpDecorate %17 BuiltIn WorkgroupId\nOpDecorate %33 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%12 = OpTypePointer Input %5\n%13 = OpVariable %12 Input\n%15 = OpTypeVector %5 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%19 = OpConstant %5 0\n%22 = OpConstant %5 6\n%25 = OpConstant %5 2\n%26 = OpTypeVector %5 4\n%30 = OpConstant %5 3\n%31 = OpConstant %5 1\n%33 = OpVariable %12 Input\n%36 = OpConstant %5 4294967292\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%10 = OpLoad %6 %9\n%11 = OpLoad %6 %8\n%14 = OpLoad %5 %13\n%18 = OpAccessChain %12 %17 %19\n%20 = OpLoad %5 %18\n%21 = OpShiftLeftLogical %5 %20 %22\n%23 = OpIAdd %5 %21 %14\n%24 = OpShiftLeftLogical %5 %23 %25\n%27 = OpImageRead %26 %11 %23\n%28 = OpCompositeExtract %5 %27 0\n%29 = OpGroupNonUniformQuadBroadcast %5 %30 %28 %31\n%32 = OpBitwiseAnd %5 %28 %30\n%34 = OpLoad %5 %33\n%35 = OpBitwiseAnd %5 %34 %36\n%37 = OpIAdd %5 %35 %32\n%38 = OpGroupNonUniformShuffle %5 %30 %28 %37\n%39 = OpShiftLeftLogical %5 %23 %30\n%40 = OpIMul %5 %23 %25\n%41 = OpCompositeConstruct %26 %29 %29 %29 %29\nOpImageWrite %10 %40 %41\n%42 = OpCompositeConstruct %26 %38 %38 %38 %38\n%43 = OpIAdd %5 %40 %31\nOpImageWrite %10 %43 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-read-at-2d.sm66.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_shuffle : require\nlayout(local_size_x = 8, local_size_y = 4, local_size_z = 2) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\n\nvoid main()\n{\n    uint _21 = (gl_WorkGroupID.x << 6u) + gl_LocalInvocationIndex;\n    uvec4 _26 = imageLoad(_8, int(_21));\n    uint _27 = _26.x;\n    uint _40 = _21 * 2u;\n    imageStore(_9, int(_40), uvec4(subgroupQuadBroadcast(_27, 1u)));\n    imageStore(_9, int(_40 + 1u), uvec4(subgroupShuffle(_27, (gl_SubgroupInvocationID & 4294967292u) + (_27 & 3u))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformShuffle\nOpCapability GroupNonUniformQuad\nOpCapability ComputeDerivativeGroupQuadsKHR\nOpExtension \"SPV_KHR_compute_shader_derivatives\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %11 %15 %32\nOpExecutionMode %3 DerivativeGroupQuadsKHR\nOpExecutionMode %3 LocalSize 8 4 2\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %11 BuiltIn LocalInvocationIndex\nOpDecorate %15 BuiltIn WorkgroupId\nOpDecorate %32 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%13 = OpTypeVector %5 3\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%17 = OpConstant %5 0\n%20 = OpConstant %5 6\n%23 = OpConstant %5 2\n%25 = OpTypeVector %5 4\n%29 = OpConstant %5 3\n%30 = OpConstant %5 1\n%32 = OpVariable %10 Input\n%35 = OpConstant %5 4294967292\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%12 = OpLoad %5 %11\n%16 = OpAccessChain %10 %15 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%21 = OpIAdd %5 %19 %12\n%22 = OpShiftLeftLogical %5 %21 %23\n%24 = OpLoad %6 %8\n%26 = OpImageRead %25 %24 %21\n%27 = OpCompositeExtract %5 %26 0\n%28 = OpGroupNonUniformQuadBroadcast %5 %29 %27 %30\n%31 = OpBitwiseAnd %5 %27 %29\n%33 = OpLoad %5 %32\n%34 = OpBitwiseAnd %5 %33 %35\n%36 = OpIAdd %5 %34 %31\n%37 = OpGroupNonUniformShuffle %5 %29 %27 %36\n%38 = OpShiftLeftLogical %5 %21 %29\n%39 = OpLoad %6 %9\n%40 = OpIMul %5 %21 %23\n%41 = OpCompositeConstruct %25 %28 %28 %28 %28\nOpImageWrite %39 %40 %41\n%42 = OpCompositeConstruct %25 %37 %37 %37 %37\n%43 = OpIAdd %5 %40 %30\nOpImageWrite %39 %43 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-read-at.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_shuffle : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\n\nvoid main()\n{\n    uvec4 _22 = imageLoad(_8, int(gl_GlobalInvocationID.x));\n    uint _23 = _22.x;\n    uint _35 = gl_GlobalInvocationID.x * 2u;\n    imageStore(_9, int(_35), uvec4(subgroupQuadBroadcast(_23, 1u)));\n    imageStore(_9, int(_35 + 1u), uvec4(subgroupShuffle(_23, (gl_SubgroupInvocationID & 4294967292u) + (_23 & 3u))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformShuffle\nOpCapability GroupNonUniformQuad\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14 %28\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %14 BuiltIn GlobalInvocationId\nOpDecorate %28 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 2\n%21 = OpTypeVector %5 4\n%25 = OpConstant %5 3\n%26 = OpConstant %5 1\n%28 = OpVariable %15 Input\n%31 = OpConstant %5 4294967292\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%10 = OpLoad %6 %9\n%11 = OpLoad %6 %8\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpImageRead %21 %11 %18\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpGroupNonUniformQuadBroadcast %5 %25 %23 %26\n%27 = OpBitwiseAnd %5 %23 %25\n%29 = OpLoad %5 %28\n%30 = OpBitwiseAnd %5 %29 %31\n%32 = OpIAdd %5 %30 %27\n%33 = OpGroupNonUniformShuffle %5 %25 %23 %32\n%34 = OpShiftLeftLogical %5 %18 %25\n%35 = OpIMul %5 %18 %20\n%36 = OpCompositeConstruct %21 %24 %24 %24 %24\nOpImageWrite %10 %35 %36\n%37 = OpCompositeConstruct %21 %33 %33 %33 %33\n%38 = OpIAdd %5 %35 %26\nOpImageWrite %10 %38 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-read-at.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_shuffle : require\n\nlayout(location = 0) in float V;\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = subgroupQuadBroadcast(V, 2u);\n    SV_Target.y = subgroupShuffle(V, (gl_SubgroupInvocationID & 4294967292u) + INDEX);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformShuffle\nOpCapability GroupNonUniformQuad\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10 %13 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"V\"\nOpName %10 \"INDEX\"\nOpName %13 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %10 Flat\nOpDecorate %10 Location 1\nOpDecorate %13 Location 0\nOpDecorate %19 BuiltIn SubgroupLocalInvocationId\nOpDecorate %19 Flat\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeInt 32 0\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpTypeVector %5 2\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%17 = OpConstant %8 3\n%18 = OpConstant %8 2\n%19 = OpVariable %9 Input\n%22 = OpConstant %8 4294967292\n%25 = OpTypePointer Output %5\n%27 = OpConstant %8 0\n%29 = OpConstant %8 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%14 = OpLoad %8 %10\n%15 = OpLoad %5 %7\n%16 = OpGroupNonUniformQuadBroadcast %5 %17 %15 %18\n%20 = OpLoad %8 %19\n%21 = OpBitwiseAnd %8 %20 %22\n%23 = OpIAdd %8 %21 %14\n%24 = OpGroupNonUniformShuffle %5 %17 %15 %23\n%26 = OpAccessChain %25 %13 %27\nOpStore %26 %16\n%28 = OpAccessChain %25 %13 %29\nOpStore %28 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-swap.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\n\nvoid main()\n{\n    uvec4 _22 = imageLoad(_8, int(gl_GlobalInvocationID.x));\n    uint _23 = _22.x;\n    uint _31 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_9, int(_31), uvec4(_23));\n    imageStore(_9, int(_31 + 1u), uvec4(subgroupQuadSwapHorizontal(_23)));\n    imageStore(_9, int(_31 + 2u), uvec4(subgroupQuadSwapVertical(_23)));\n    imageStore(_9, int(_31 + 3u), uvec4(subgroupQuadSwapDiagonal(_23)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformQuad\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 2\n%21 = OpTypeVector %5 4\n%25 = OpConstant %5 3\n%27 = OpConstant %5 1\n%30 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%10 = OpLoad %6 %9\n%11 = OpLoad %6 %8\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpImageRead %21 %11 %18\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpGroupNonUniformQuadSwap %5 %25 %23 %17\n%26 = OpGroupNonUniformQuadSwap %5 %25 %23 %27\n%28 = OpGroupNonUniformQuadSwap %5 %25 %23 %20\n%29 = OpShiftLeftLogical %5 %18 %30\n%31 = OpIMul %5 %18 %30\n%32 = OpCompositeConstruct %21 %23 %23 %23 %23\nOpImageWrite %10 %31 %32\n%33 = OpCompositeConstruct %21 %24 %24 %24 %24\n%34 = OpIAdd %5 %31 %27\nOpImageWrite %10 %34 %33\n%35 = OpCompositeConstruct %21 %26 %26 %26 %26\n%36 = OpIAdd %5 %31 %20\nOpImageWrite %10 %36 %35\n%37 = OpCompositeConstruct %21 %28 %28 %28 %28\n%38 = OpIAdd %5 %31 %25\nOpImageWrite %10 %38 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/quad-swap.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_quad : require\n\nlayout(location = 0) in float A;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = A;\n    SV_Target.y = subgroupQuadSwapHorizontal(A);\n    SV_Target.z = subgroupQuadSwapVertical(A);\n    SV_Target.w = subgroupQuadSwapDiagonal(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformQuad\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 4\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 3\n%15 = OpConstant %13 0\n%17 = OpConstant %13 1\n%19 = OpConstant %13 2\n%20 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%11 = OpLoad %5 %7\n%12 = OpGroupNonUniformQuadSwap %5 %14 %11 %15\n%16 = OpGroupNonUniformQuadSwap %5 %14 %11 %17\n%18 = OpGroupNonUniformQuadSwap %5 %14 %11 %19\n%21 = OpAccessChain %20 %10 %15\nOpStore %21 %11\n%22 = OpAccessChain %20 %10 %17\nOpStore %22 %12\n%23 = OpAccessChain %20 %10 %19\nOpStore %23 %16\n%24 = OpAccessChain %20 %10 %14\nOpStore %24 %18\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/raw-gather-offset-sparse.sm67.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_ARB_sparse_texture2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct SparseTexel\n{\n    uint _m0;\n    uvec4 _m1;\n};\n\nstruct _54\n{\n    uint16_t _m0;\n    uint16_t _m1;\n    uint16_t _m2;\n    uint16_t _m3;\n    uint _m4;\n};\n\nstruct _80\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n};\n\nstruct _118\n{\n    uint64_t _m0;\n    uint64_t _m1;\n    uint64_t _m2;\n    uint64_t _m3;\n    uint _m4;\n};\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _17_19\n{\n    uvec4 _m0[];\n} _19;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    u64vec4 _m0[];\n} _25;\n\nlayout(set = 0, binding = 0) uniform mediump utexture2D _8;\nlayout(set = 0, binding = 1) uniform utexture2D _9;\nlayout(set = 0, binding = 2) uniform utexture2D _10;\nlayout(set = 0, binding = 0) uniform sampler _28;\n\nvoid main()\n{\n    uint _147;\n    uvec4 _148;\n    _147 = sparseTextureGatherOffsetARB(usampler2D(_8, _28), vec2(0.5), ivec2(-3, -2), _148);\n    SparseTexel _42 = SparseTexel(_147, _148);\n    u16vec4 _49 = u16vec4(_42._m1);\n    _54 _55 = _54(_49.x, _49.y, _49.z, _49.w, _42._m0);\n    uint _65 = uint(_55._m0);\n    uint _66 = uint(_55._m1);\n    uint _149;\n    uvec4 _150;\n    _149 = sparseTextureGatherOffsetARB(usampler2D(_9, _28), vec2(0.5), ivec2(int(_65), int(_66)), _150);\n    SparseTexel _72 = SparseTexel(_149, _150);\n    uvec4 _75 = _72._m1;\n    _80 _81 = _80(_75.x, _75.y, _75.z, _75.w, _72._m0);\n    vec2 _91 = vec2(0.5);\n    uint _151;\n    uvec4 _152;\n    _151 = sparseTextureGatherOffsetARB(usampler2D(_10, _28), _91, ivec2(-3, -2), _152);\n    SparseTexel _92 = SparseTexel(_151, _152);\n    uvec4 _93 = textureGatherOffset(usampler2D(_10, _28), _91, ivec2(-3, -2), int(1u));\n    uvec4 _94 = _92._m1;\n    u64vec4 _112 = u64vec4(packUint2x32(uvec2(_94.x, _93.x)), packUint2x32(uvec2(_94.y, _93.y)), packUint2x32(uvec2(_94.z, _93.z)), packUint2x32(uvec2(_94.w, _93.w)));\n    _118 _119 = _118(_112.x, _112.y, _112.z, _112.w, _92._m0);\n    _19._m0[0u] = uvec4(_65, _66, uint(_55._m2), uint(_55._m3));\n    _19._m0[1u] = uvec4(_81._m0, _81._m1, _81._m2, _81._m3);\n    _25._m0[1u] = u64vec4(_119._m0, _119._m1, _119._m2, _119._m3);\n    _14._m0[16u] = uint(sparseTexelsResidentARB(int(_55._m4)));\n    uint _141 = 16u + 1u;\n    _14._m0[_141] = uint(sparseTexelsResidentARB(int(_81._m4)));\n    uint _143 = 16u + 2u;\n    _14._m0[_143] = uint(sparseTexelsResidentARB(int(_119._m4)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 147\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int16\nOpCapability ImageGatherExtended\nOpCapability SparseResidency\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %12 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %41 \"SparseTexel\"\nOpName %54 \"\"\nOpName %80 \"\"\nOpName %118 \"\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %16 ArrayStride 16\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %22 ArrayStride 32\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonReadable\nOpDecorate %14 Aliased\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %19 NonReadable\nOpDecorate %19 Aliased\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %25 Aliased\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypeRuntimeArray %5\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 4\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeInt 64 0\n%21 = OpTypeVector %20 4\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeSampler\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%31 = OpTypeSampledImage %6\n%33 = OpTypeFloat 32\n%34 = OpConstant %33 0.5\n%35 = OpTypeVector %33 2\n%37 = OpTypeInt 32 1\n%38 = OpConstant %37 -3\n%39 = OpConstant %37 -2\n%40 = OpConstant %5 0\n%41 = OpTypeStruct %5 %15\n%43 = OpTypeVector %37 2\n%44 = OpConstantComposite %43 %38 %39\n%47 = OpTypeInt 16 0\n%48 = OpTypeVector %47 4\n%54 = OpTypeStruct %47 %47 %47 %47 %5\n%61 = OpTypeBool\n%63 = OpConstant %5 1\n%80 = OpTypeStruct %5 %5 %5 %5 %5\n%97 = OpTypeVector %5 2\n%118 = OpTypeStruct %20 %20 %20 %20 %5\n%130 = OpTypePointer StorageBuffer %15\n%135 = OpTypePointer StorageBuffer %21\n%137 = OpConstant %5 16\n%138 = OpTypePointer StorageBuffer %5\n%144 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %145\n%145 = OpLabel\n%29 = OpLoad %6 %8\n%30 = OpLoad %26 %28\n%32 = OpSampledImage %31 %29 %30\n%36 = OpCompositeConstruct %35 %34 %34\n%42 = OpImageSparseGather %41 %32 %36 %40 ConstOffset %44\n%45 = OpCompositeExtract %5 %42 0\n%46 = OpCompositeExtract %15 %42 1\n%49 = OpUConvert %48 %46\n%50 = OpCompositeExtract %47 %49 0\n%51 = OpCompositeExtract %47 %49 1\n%52 = OpCompositeExtract %47 %49 2\n%53 = OpCompositeExtract %47 %49 3\n%55 = OpCompositeConstruct %54 %50 %51 %52 %53 %45\n%56 = OpCompositeExtract %47 %55 0\n%57 = OpCompositeExtract %47 %55 1\n%58 = OpCompositeExtract %47 %55 2\n%59 = OpCompositeExtract %47 %55 3\n%60 = OpCompositeExtract %5 %55 4\n%62 = OpImageSparseTexelsResident %61 %60\n%64 = OpSelect %5 %62 %63 %40\n%65 = OpUConvert %5 %56\n%66 = OpUConvert %5 %57\n%67 = OpLoad %6 %9\n%68 = OpSampledImage %31 %67 %30\n%69 = OpCompositeConstruct %35 %34 %34\n%70 = OpBitcast %37 %65\n%71 = OpBitcast %37 %66\n%73 = OpCompositeConstruct %43 %70 %71\n%72 = OpImageSparseGather %41 %68 %69 %40 Offset %73\n%74 = OpCompositeExtract %5 %72 0\n%75 = OpCompositeExtract %15 %72 1\n%76 = OpCompositeExtract %5 %75 0\n%77 = OpCompositeExtract %5 %75 1\n%78 = OpCompositeExtract %5 %75 2\n%79 = OpCompositeExtract %5 %75 3\n%81 = OpCompositeConstruct %80 %76 %77 %78 %79 %74\n%82 = OpCompositeExtract %5 %81 0\n%83 = OpCompositeExtract %5 %81 1\n%84 = OpCompositeExtract %5 %81 2\n%85 = OpCompositeExtract %5 %81 3\n%86 = OpCompositeExtract %5 %81 4\n%87 = OpImageSparseTexelsResident %61 %86\n%88 = OpSelect %5 %87 %63 %40\n%89 = OpLoad %6 %10\n%90 = OpSampledImage %31 %89 %30\n%91 = OpCompositeConstruct %35 %34 %34\n%92 = OpImageSparseGather %41 %90 %91 %40 ConstOffset %44\n%93 = OpImageGather %15 %90 %91 %63 ConstOffset %44\n%94 = OpCompositeExtract %15 %92 1\n%95 = OpCompositeExtract %5 %94 0\n%96 = OpCompositeExtract %5 %93 0\n%98 = OpCompositeConstruct %97 %95 %96\n%99 = OpBitcast %20 %98\n%100 = OpCompositeExtract %5 %94 1\n%101 = OpCompositeExtract %5 %93 1\n%102 = OpCompositeConstruct %97 %100 %101\n%103 = OpBitcast %20 %102\n%104 = OpCompositeExtract %5 %94 2\n%105 = OpCompositeExtract %5 %93 2\n%106 = OpCompositeConstruct %97 %104 %105\n%107 = OpBitcast %20 %106\n%108 = OpCompositeExtract %5 %94 3\n%109 = OpCompositeExtract %5 %93 3\n%110 = OpCompositeConstruct %97 %108 %109\n%111 = OpBitcast %20 %110\n%112 = OpCompositeConstruct %21 %99 %103 %107 %111\n%113 = OpCompositeExtract %5 %92 0\n%114 = OpCompositeExtract %20 %112 0\n%115 = OpCompositeExtract %20 %112 1\n%116 = OpCompositeExtract %20 %112 2\n%117 = OpCompositeExtract %20 %112 3\n%119 = OpCompositeConstruct %118 %114 %115 %116 %117 %113\n%120 = OpCompositeExtract %20 %119 0\n%121 = OpCompositeExtract %20 %119 1\n%122 = OpCompositeExtract %20 %119 2\n%123 = OpCompositeExtract %20 %119 3\n%124 = OpCompositeExtract %5 %119 4\n%125 = OpImageSparseTexelsResident %61 %124\n%126 = OpSelect %5 %125 %63 %40\n%127 = OpUConvert %5 %58\n%128 = OpUConvert %5 %59\n%129 = OpCompositeConstruct %15 %65 %66 %127 %128\n%131 = OpAccessChain %130 %19 %40 %40\nOpStore %131 %129\n%132 = OpCompositeConstruct %15 %82 %83 %84 %85\n%133 = OpAccessChain %130 %19 %40 %63\nOpStore %133 %132\n%134 = OpCompositeConstruct %21 %120 %121 %122 %123\n%136 = OpAccessChain %135 %25 %40 %63\nOpStore %136 %134\n%139 = OpAccessChain %138 %14 %40 %137\nOpStore %139 %64\n%141 = OpIAdd %5 %137 %63\n%140 = OpAccessChain %138 %14 %40 %141\nOpStore %140 %88\n%143 = OpIAdd %5 %137 %144\n%142 = OpAccessChain %138 %14 %40 %143\nOpStore %142 %126\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/raw-gather-offset.sm67.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uvec4 _m0[];\n} _15;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _19_21\n{\n    u64vec4 _m0[];\n} _21;\n\nlayout(set = 0, binding = 0) uniform mediump utexture2D _8;\nlayout(set = 0, binding = 1) uniform utexture2D _9;\nlayout(set = 0, binding = 2) uniform utexture2D _10;\nlayout(set = 0, binding = 0) uniform sampler _24;\n\nvoid main()\n{\n    u16vec4 _42 = u16vec4(textureGatherOffset(usampler2D(_8, _24), vec2(0.5), ivec2(1, 2)));\n    uint _47 = uint(_42.x);\n    uint _48 = uint(_42.y);\n    vec2 _62 = vec2(0.5);\n    uvec4 _65 = textureGatherOffset(usampler2D(_10, _24), _62, ivec2(4, 5));\n    uvec4 _67 = textureGatherOffset(usampler2D(_10, _24), _62, ivec2(4, 5), int(1u));\n    _15._m0[0u] = uvec4(_47, _48, uint(_42.z), uint(_42.w));\n    _15._m0[1u] = uvec4(textureGatherOffset(usampler2D(_9, _24), vec2(0.5), ivec2(int(_47), int(_48))));\n    _21._m0[1u] = u64vec4(u64vec4(packUint2x32(uvec2(_65.x, _67.x)), packUint2x32(uvec2(_65.y, _67.y)), packUint2x32(uvec2(_65.z, _67.z)), packUint2x32(uvec2(_65.w, _67.w))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 103\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int16\nOpCapability ImageGatherExtended\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %13 \"SSBO\"\nOpName %19 \"SSBO\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %12 ArrayStride 16\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %18 ArrayStride 32\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonReadable\nOpDecorate %15 Aliased\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonReadable\nOpDecorate %21 Aliased\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypeVector %5 4\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypeStruct %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeInt 64 0\n%17 = OpTypeVector %16 4\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeSampler\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%27 = OpTypeSampledImage %6\n%29 = OpTypeFloat 32\n%30 = OpConstant %29 0.5\n%31 = OpTypeVector %29 2\n%33 = OpTypeInt 32 1\n%34 = OpConstant %33 1\n%35 = OpConstant %33 2\n%36 = OpConstant %5 0\n%38 = OpTypeVector %33 2\n%39 = OpConstantComposite %38 %34 %35\n%40 = OpTypeInt 16 0\n%41 = OpTypeVector %40 4\n%63 = OpConstant %33 4\n%64 = OpConstant %33 5\n%66 = OpConstantComposite %38 %63 %64\n%68 = OpConstant %5 1\n%71 = OpTypeVector %5 2\n%94 = OpTypePointer StorageBuffer %11\n%99 = OpTypePointer StorageBuffer %17\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %101\n%101 = OpLabel\n%25 = OpLoad %6 %8\n%26 = OpLoad %22 %24\n%28 = OpSampledImage %27 %25 %26\n%32 = OpCompositeConstruct %31 %30 %30\n%37 = OpImageGather %11 %28 %32 %36 ConstOffset %39\n%42 = OpUConvert %41 %37\n%43 = OpCompositeExtract %40 %42 0\n%44 = OpCompositeExtract %40 %42 1\n%45 = OpCompositeExtract %40 %42 2\n%46 = OpCompositeExtract %40 %42 3\n%47 = OpUConvert %5 %43\n%48 = OpUConvert %5 %44\n%49 = OpLoad %6 %9\n%50 = OpSampledImage %27 %49 %26\n%51 = OpCompositeConstruct %31 %30 %30\n%52 = OpBitcast %33 %47\n%53 = OpBitcast %33 %48\n%55 = OpCompositeConstruct %38 %52 %53\n%54 = OpImageGather %11 %50 %51 %36 Offset %55\n%56 = OpCompositeExtract %5 %54 0\n%57 = OpCompositeExtract %5 %54 1\n%58 = OpCompositeExtract %5 %54 2\n%59 = OpCompositeExtract %5 %54 3\n%60 = OpLoad %6 %10\n%61 = OpSampledImage %27 %60 %26\n%62 = OpCompositeConstruct %31 %30 %30\n%65 = OpImageGather %11 %61 %62 %36 ConstOffset %66\n%67 = OpImageGather %11 %61 %62 %68 ConstOffset %66\n%69 = OpCompositeExtract %5 %65 0\n%70 = OpCompositeExtract %5 %67 0\n%72 = OpCompositeConstruct %71 %69 %70\n%73 = OpBitcast %16 %72\n%74 = OpCompositeExtract %5 %65 1\n%75 = OpCompositeExtract %5 %67 1\n%76 = OpCompositeConstruct %71 %74 %75\n%77 = OpBitcast %16 %76\n%78 = OpCompositeExtract %5 %65 2\n%79 = OpCompositeExtract %5 %67 2\n%80 = OpCompositeConstruct %71 %78 %79\n%81 = OpBitcast %16 %80\n%82 = OpCompositeExtract %5 %65 3\n%83 = OpCompositeExtract %5 %67 3\n%84 = OpCompositeConstruct %71 %82 %83\n%85 = OpBitcast %16 %84\n%86 = OpCompositeConstruct %17 %73 %77 %81 %85\n%87 = OpCompositeExtract %16 %86 0\n%88 = OpCompositeExtract %16 %86 1\n%89 = OpCompositeExtract %16 %86 2\n%90 = OpCompositeExtract %16 %86 3\n%91 = OpUConvert %5 %45\n%92 = OpUConvert %5 %46\n%93 = OpCompositeConstruct %11 %47 %48 %91 %92\n%95 = OpAccessChain %94 %15 %36 %36\nOpStore %95 %93\n%96 = OpCompositeConstruct %11 %56 %57 %58 %59\n%97 = OpAccessChain %94 %15 %36 %68\nOpStore %97 %96\n%98 = OpCompositeConstruct %17 %87 %88 %89 %90\n%100 = OpAccessChain %99 %21 %36 %68\nOpStore %100 %98\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/raw-gather-sparse.sm67.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_ARB_sparse_texture2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct SparseTexel\n{\n    uint _m0;\n    uvec4 _m1;\n};\n\nstruct _49\n{\n    uint16_t _m0;\n    uint16_t _m1;\n    uint16_t _m2;\n    uint16_t _m3;\n    uint _m4;\n};\n\nstruct _70\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n};\n\nstruct _108\n{\n    uint64_t _m0;\n    uint64_t _m1;\n    uint64_t _m2;\n    uint64_t _m3;\n    uint _m4;\n};\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _17_19\n{\n    uvec4 _m0[];\n} _19;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _23_25\n{\n    u64vec4 _m0[];\n} _25;\n\nlayout(set = 0, binding = 0) uniform mediump utexture2D _8;\nlayout(set = 0, binding = 1) uniform utexture2D _9;\nlayout(set = 0, binding = 2) uniform utexture2D _10;\nlayout(set = 0, binding = 0) uniform sampler _28;\n\nvoid main()\n{\n    uint _139;\n    uvec4 _140;\n    _139 = sparseTextureGatherARB(usampler2D(_8, _28), vec2(0.5), _140);\n    SparseTexel _39 = SparseTexel(_139, _140);\n    u16vec4 _44 = u16vec4(_39._m1);\n    _49 _50 = _49(_44.x, _44.y, _44.z, _44.w, _39._m0);\n    uint _141;\n    uvec4 _142;\n    _141 = sparseTextureGatherARB(usampler2D(_9, _28), vec2(0.5), _142);\n    SparseTexel _63 = SparseTexel(_141, _142);\n    uvec4 _65 = _63._m1;\n    _70 _71 = _70(_65.x, _65.y, _65.z, _65.w, _63._m0);\n    vec2 _81 = vec2(0.5);\n    uint _143;\n    uvec4 _144;\n    _143 = sparseTextureGatherARB(usampler2D(_10, _28), _81, _144);\n    SparseTexel _82 = SparseTexel(_143, _144);\n    uvec4 _83 = textureGather(usampler2D(_10, _28), _81, int(1u));\n    uvec4 _84 = _82._m1;\n    u64vec4 _102 = u64vec4(packUint2x32(uvec2(_84.x, _83.x)), packUint2x32(uvec2(_84.y, _83.y)), packUint2x32(uvec2(_84.z, _83.z)), packUint2x32(uvec2(_84.w, _83.w)));\n    _108 _109 = _108(_102.x, _102.y, _102.z, _102.w, _82._m0);\n    _19._m0[0u] = uvec4(uint(_50._m0), uint(_50._m1), uint(_50._m2), uint(_50._m3));\n    _19._m0[1u] = uvec4(_71._m0, _71._m1, _71._m2, _71._m3);\n    _25._m0[1u] = u64vec4(_109._m0, _109._m1, _109._m2, _109._m3);\n    _14._m0[16u] = uint(sparseTexelsResidentARB(int(_50._m4)));\n    uint _133 = 16u + 1u;\n    _14._m0[_133] = uint(sparseTexelsResidentARB(int(_71._m4)));\n    uint _135 = 16u + 2u;\n    _14._m0[_135] = uint(sparseTexelsResidentARB(int(_109._m4)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 139\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int16\nOpCapability SparseResidency\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %12 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %38 \"SparseTexel\"\nOpName %49 \"\"\nOpName %70 \"\"\nOpName %108 \"\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %16 ArrayStride 16\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %22 ArrayStride 32\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonReadable\nOpDecorate %14 Aliased\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %19 NonReadable\nOpDecorate %19 Aliased\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %25 Aliased\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypeRuntimeArray %5\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 4\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeInt 64 0\n%21 = OpTypeVector %20 4\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeSampler\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%31 = OpTypeSampledImage %6\n%33 = OpTypeFloat 32\n%34 = OpConstant %33 0.5\n%35 = OpTypeVector %33 2\n%37 = OpConstant %5 0\n%38 = OpTypeStruct %5 %15\n%42 = OpTypeInt 16 0\n%43 = OpTypeVector %42 4\n%49 = OpTypeStruct %42 %42 %42 %42 %5\n%56 = OpTypeBool\n%58 = OpConstant %5 1\n%70 = OpTypeStruct %5 %5 %5 %5 %5\n%87 = OpTypeVector %5 2\n%108 = OpTypeStruct %20 %20 %20 %20 %5\n%122 = OpTypePointer StorageBuffer %15\n%127 = OpTypePointer StorageBuffer %21\n%129 = OpConstant %5 16\n%130 = OpTypePointer StorageBuffer %5\n%136 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %137\n%137 = OpLabel\n%29 = OpLoad %6 %8\n%30 = OpLoad %26 %28\n%32 = OpSampledImage %31 %29 %30\n%36 = OpCompositeConstruct %35 %34 %34\n%39 = OpImageSparseGather %38 %32 %36 %37\n%40 = OpCompositeExtract %5 %39 0\n%41 = OpCompositeExtract %15 %39 1\n%44 = OpUConvert %43 %41\n%45 = OpCompositeExtract %42 %44 0\n%46 = OpCompositeExtract %42 %44 1\n%47 = OpCompositeExtract %42 %44 2\n%48 = OpCompositeExtract %42 %44 3\n%50 = OpCompositeConstruct %49 %45 %46 %47 %48 %40\n%51 = OpCompositeExtract %42 %50 0\n%52 = OpCompositeExtract %42 %50 1\n%53 = OpCompositeExtract %42 %50 2\n%54 = OpCompositeExtract %42 %50 3\n%55 = OpCompositeExtract %5 %50 4\n%57 = OpImageSparseTexelsResident %56 %55\n%59 = OpSelect %5 %57 %58 %37\n%60 = OpLoad %6 %9\n%61 = OpSampledImage %31 %60 %30\n%62 = OpCompositeConstruct %35 %34 %34\n%63 = OpImageSparseGather %38 %61 %62 %37\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpCompositeExtract %15 %63 1\n%66 = OpCompositeExtract %5 %65 0\n%67 = OpCompositeExtract %5 %65 1\n%68 = OpCompositeExtract %5 %65 2\n%69 = OpCompositeExtract %5 %65 3\n%71 = OpCompositeConstruct %70 %66 %67 %68 %69 %64\n%72 = OpCompositeExtract %5 %71 0\n%73 = OpCompositeExtract %5 %71 1\n%74 = OpCompositeExtract %5 %71 2\n%75 = OpCompositeExtract %5 %71 3\n%76 = OpCompositeExtract %5 %71 4\n%77 = OpImageSparseTexelsResident %56 %76\n%78 = OpSelect %5 %77 %58 %37\n%79 = OpLoad %6 %10\n%80 = OpSampledImage %31 %79 %30\n%81 = OpCompositeConstruct %35 %34 %34\n%82 = OpImageSparseGather %38 %80 %81 %37\n%83 = OpImageGather %15 %80 %81 %58\n%84 = OpCompositeExtract %15 %82 1\n%85 = OpCompositeExtract %5 %84 0\n%86 = OpCompositeExtract %5 %83 0\n%88 = OpCompositeConstruct %87 %85 %86\n%89 = OpBitcast %20 %88\n%90 = OpCompositeExtract %5 %84 1\n%91 = OpCompositeExtract %5 %83 1\n%92 = OpCompositeConstruct %87 %90 %91\n%93 = OpBitcast %20 %92\n%94 = OpCompositeExtract %5 %84 2\n%95 = OpCompositeExtract %5 %83 2\n%96 = OpCompositeConstruct %87 %94 %95\n%97 = OpBitcast %20 %96\n%98 = OpCompositeExtract %5 %84 3\n%99 = OpCompositeExtract %5 %83 3\n%100 = OpCompositeConstruct %87 %98 %99\n%101 = OpBitcast %20 %100\n%102 = OpCompositeConstruct %21 %89 %93 %97 %101\n%103 = OpCompositeExtract %5 %82 0\n%104 = OpCompositeExtract %20 %102 0\n%105 = OpCompositeExtract %20 %102 1\n%106 = OpCompositeExtract %20 %102 2\n%107 = OpCompositeExtract %20 %102 3\n%109 = OpCompositeConstruct %108 %104 %105 %106 %107 %103\n%110 = OpCompositeExtract %20 %109 0\n%111 = OpCompositeExtract %20 %109 1\n%112 = OpCompositeExtract %20 %109 2\n%113 = OpCompositeExtract %20 %109 3\n%114 = OpCompositeExtract %5 %109 4\n%115 = OpImageSparseTexelsResident %56 %114\n%116 = OpSelect %5 %115 %58 %37\n%117 = OpUConvert %5 %51\n%118 = OpUConvert %5 %52\n%119 = OpUConvert %5 %53\n%120 = OpUConvert %5 %54\n%121 = OpCompositeConstruct %15 %117 %118 %119 %120\n%123 = OpAccessChain %122 %19 %37 %37\nOpStore %123 %121\n%124 = OpCompositeConstruct %15 %72 %73 %74 %75\n%125 = OpAccessChain %122 %19 %37 %58\nOpStore %125 %124\n%126 = OpCompositeConstruct %21 %110 %111 %112 %113\n%128 = OpAccessChain %127 %25 %37 %58\nOpStore %128 %126\n%131 = OpAccessChain %130 %14 %37 %129\nOpStore %131 %59\n%133 = OpIAdd %5 %129 %58\n%132 = OpAccessChain %130 %14 %37 %133\nOpStore %132 %78\n%135 = OpIAdd %5 %129 %136\n%134 = OpAccessChain %130 %14 %37 %135\nOpStore %134 %116\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/raw-gather.sm67.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uvec4 _m0[];\n} _15;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _19_21\n{\n    u64vec4 _m0[];\n} _21;\n\nlayout(set = 0, binding = 0) uniform mediump utexture2D _8;\nlayout(set = 0, binding = 1) uniform utexture2D _9;\nlayout(set = 0, binding = 2) uniform utexture2D _10;\nlayout(set = 0, binding = 0) uniform sampler _24;\n\nvoid main()\n{\n    u16vec4 _37 = u16vec4(textureGather(usampler2D(_8, _24), vec2(0.5)));\n    vec2 _52 = vec2(0.5);\n    uvec4 _53 = textureGather(usampler2D(_10, _24), _52);\n    uvec4 _54 = textureGather(usampler2D(_10, _24), _52, int(1u));\n    _15._m0[0u] = uvec4(uint(_37.x), uint(_37.y), uint(_37.z), uint(_37.w));\n    _15._m0[1u] = uvec4(textureGather(usampler2D(_9, _24), vec2(0.5)));\n    _21._m0[1u] = u64vec4(u64vec4(packUint2x32(uvec2(_53.x, _54.x)), packUint2x32(uvec2(_53.y, _54.y)), packUint2x32(uvec2(_53.z, _54.z)), packUint2x32(uvec2(_53.w, _54.w))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 92\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int16\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %13 \"SSBO\"\nOpName %19 \"SSBO\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %12 ArrayStride 16\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %18 ArrayStride 32\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonReadable\nOpDecorate %15 Aliased\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonReadable\nOpDecorate %21 Aliased\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypeVector %5 4\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypeStruct %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeInt 64 0\n%17 = OpTypeVector %16 4\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeSampler\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%27 = OpTypeSampledImage %6\n%29 = OpTypeFloat 32\n%30 = OpConstant %29 0.5\n%31 = OpTypeVector %29 2\n%33 = OpConstant %5 0\n%35 = OpTypeInt 16 0\n%36 = OpTypeVector %35 4\n%55 = OpConstant %5 1\n%58 = OpTypeVector %5 2\n%83 = OpTypePointer StorageBuffer %11\n%88 = OpTypePointer StorageBuffer %17\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %90\n%90 = OpLabel\n%25 = OpLoad %6 %8\n%26 = OpLoad %22 %24\n%28 = OpSampledImage %27 %25 %26\n%32 = OpCompositeConstruct %31 %30 %30\n%34 = OpImageGather %11 %28 %32 %33\n%37 = OpUConvert %36 %34\n%38 = OpCompositeExtract %35 %37 0\n%39 = OpCompositeExtract %35 %37 1\n%40 = OpCompositeExtract %35 %37 2\n%41 = OpCompositeExtract %35 %37 3\n%42 = OpLoad %6 %9\n%43 = OpSampledImage %27 %42 %26\n%44 = OpCompositeConstruct %31 %30 %30\n%45 = OpImageGather %11 %43 %44 %33\n%46 = OpCompositeExtract %5 %45 0\n%47 = OpCompositeExtract %5 %45 1\n%48 = OpCompositeExtract %5 %45 2\n%49 = OpCompositeExtract %5 %45 3\n%50 = OpLoad %6 %10\n%51 = OpSampledImage %27 %50 %26\n%52 = OpCompositeConstruct %31 %30 %30\n%53 = OpImageGather %11 %51 %52 %33\n%54 = OpImageGather %11 %51 %52 %55\n%56 = OpCompositeExtract %5 %53 0\n%57 = OpCompositeExtract %5 %54 0\n%59 = OpCompositeConstruct %58 %56 %57\n%60 = OpBitcast %16 %59\n%61 = OpCompositeExtract %5 %53 1\n%62 = OpCompositeExtract %5 %54 1\n%63 = OpCompositeConstruct %58 %61 %62\n%64 = OpBitcast %16 %63\n%65 = OpCompositeExtract %5 %53 2\n%66 = OpCompositeExtract %5 %54 2\n%67 = OpCompositeConstruct %58 %65 %66\n%68 = OpBitcast %16 %67\n%69 = OpCompositeExtract %5 %53 3\n%70 = OpCompositeExtract %5 %54 3\n%71 = OpCompositeConstruct %58 %69 %70\n%72 = OpBitcast %16 %71\n%73 = OpCompositeConstruct %17 %60 %64 %68 %72\n%74 = OpCompositeExtract %16 %73 0\n%75 = OpCompositeExtract %16 %73 1\n%76 = OpCompositeExtract %16 %73 2\n%77 = OpCompositeExtract %16 %73 3\n%78 = OpUConvert %5 %38\n%79 = OpUConvert %5 %39\n%80 = OpUConvert %5 %40\n%81 = OpUConvert %5 %41\n%82 = OpCompositeConstruct %11 %78 %79 %80 %81\n%84 = OpAccessChain %83 %15 %33 %33\nOpStore %84 %82\n%85 = OpCompositeConstruct %11 %46 %47 %48 %49\n%86 = OpAccessChain %83 %15 %33 %55\nOpStore %86 %85\n%87 = OpCompositeConstruct %17 %74 %75 %76 %77\n%89 = OpAccessChain %88 %21 %33 %55\nOpStore %89 %87\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-query-phi-multi.invalid.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _14_16\n{\n    vec4 _m0[1];\n} _16;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8[];\n\nrayQueryEXT RayQueryHeap[2];\n\nvoid main()\n{\n    float _33 = float(gl_GlobalInvocationID.x) + 0.5;\n    float _35 = float(gl_GlobalInvocationID.y) + 0.5;\n    uvec4 _40 = floatBitsToUint(_16._m0[0u]);\n    uint _44;\n    if (_40.y == 0u)\n    {\n        _44 = 0u;\n    }\n    else\n    {\n        _44 = 1u;\n    }\n    uint _45 = _40.x;\n    rayQueryInitializeEXT(RayQueryHeap[_44], _8[_45], 4u, 255u, vec3(_33, _35, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n    rayQueryInitializeEXT(RayQueryHeap[1u], _8[_45], 4u, 255u, vec3(_33, _35, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 68\n; Schema: 0\nOpCapability Shader\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_query\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %24\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %14 \"\"\nOpName %21 \"RayQueryHeap\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 ArrayStride 16\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %24 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeAccelerationStructureKHR\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypeArray %12 %10\n%14 = OpTypeStruct %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeRayQueryKHR\n%18 = OpConstant %9 2\n%19 = OpTypeArray %17 %18\n%20 = OpTypePointer Private %19\n%21 = OpVariable %20 Private\n%22 = OpTypeVector %9 3\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %9\n%27 = OpConstant %9 0\n%34 = OpConstant %11 0.5\n%36 = OpTypePointer Uniform %12\n%39 = OpTypeVector %9 4\n%42 = OpTypeBool\n%46 = OpTypePointer UniformConstant %5\n%49 = OpTypePointer Private %17\n%51 = OpConstant %9 4\n%52 = OpConstant %9 255\n%53 = OpConstant %11 0\n%54 = OpConstant %11 -1\n%55 = OpConstant %11 1\n%56 = OpTypeVector %11 3\n%58 = OpConstant %11 0.100000001\n%60 = OpConstant %11 1000\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%26 = OpAccessChain %25 %24 %27\n%28 = OpLoad %9 %26\n%29 = OpAccessChain %25 %24 %10\n%30 = OpLoad %9 %29\n%31 = OpConvertUToF %11 %28\n%32 = OpConvertUToF %11 %30\n%33 = OpFAdd %11 %31 %34\n%35 = OpFAdd %11 %32 %34\n%37 = OpAccessChain %36 %16 %27 %27\n%38 = OpLoad %12 %37\n%40 = OpBitcast %39 %38\n%41 = OpCompositeExtract %9 %40 1\n%43 = OpIEqual %42 %41 %27\nOpSelectionMerge %66 None\nOpBranchConditional %43 %66 %65\n%65 = OpLabel\nOpBranch %66\n%66 = OpLabel\n%44 = OpPhi %9 %27 %64 %10 %65\n%45 = OpCompositeExtract %9 %40 0\n%47 = OpAccessChain %46 %8 %45\n%48 = OpLoad %5 %47\n%50 = OpInBoundsAccessChain %49 %21 %44\n%57 = OpCompositeConstruct %56 %33 %35 %54\n%59 = OpCompositeConstruct %56 %53 %53 %55\nOpRayQueryInitializeKHR %50 %48 %51 %52 %57 %58 %59 %60\n%61 = OpInBoundsAccessChain %49 %21 %10\n%62 = OpCompositeConstruct %56 %33 %35 %54\n%63 = OpCompositeConstruct %56 %53 %53 %55\nOpRayQueryInitializeKHR %61 %48 %51 %52 %62 %58 %63 %60\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-query-phi-simple.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _14_16\n{\n    vec4 _m0[1];\n} _16;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8[];\n\nrayQueryEXT RayQueryHeap;\n\nvoid main()\n{\n    uvec4 _38 = floatBitsToUint(_16._m0[0u]);\n    uint _42;\n    if (_38.y == 0u)\n    {\n        _42 = 0u;\n    }\n    else\n    {\n        _42 = 0u;\n    }\n    rayQueryInitializeEXT(RayQueryHeap, _8[_38.x], 4u, 255u, vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_query\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %22\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %14 \"\"\nOpName %19 \"RayQueryHeap\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 ArrayStride 16\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %22 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeAccelerationStructureKHR\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypeArray %12 %10\n%14 = OpTypeStruct %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeRayQueryKHR\n%18 = OpTypePointer Private %17\n%19 = OpVariable %18 Private\n%20 = OpTypeVector %9 3\n%21 = OpTypePointer Input %20\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Input %9\n%25 = OpConstant %9 0\n%32 = OpConstant %11 0.5\n%34 = OpTypePointer Uniform %12\n%37 = OpTypeVector %9 4\n%40 = OpTypeBool\n%44 = OpTypePointer UniformConstant %5\n%47 = OpConstant %9 4\n%48 = OpConstant %9 255\n%49 = OpConstant %11 0\n%50 = OpConstant %11 -1\n%51 = OpConstant %11 1\n%52 = OpTypeVector %11 3\n%54 = OpConstant %11 0.100000001\n%56 = OpConstant %11 1000\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%24 = OpAccessChain %23 %22 %25\n%26 = OpLoad %9 %24\n%27 = OpAccessChain %23 %22 %10\n%28 = OpLoad %9 %27\n%29 = OpConvertUToF %11 %26\n%30 = OpConvertUToF %11 %28\n%31 = OpFAdd %11 %29 %32\n%33 = OpFAdd %11 %30 %32\n%35 = OpAccessChain %34 %16 %25 %25\n%36 = OpLoad %12 %35\n%38 = OpBitcast %37 %36\n%39 = OpCompositeExtract %9 %38 1\n%41 = OpIEqual %40 %39 %25\nOpSelectionMerge %59 None\nOpBranchConditional %41 %59 %58\n%58 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%42 = OpPhi %9 %25 %57 %25 %58\n%43 = OpCompositeExtract %9 %38 0\n%45 = OpAccessChain %44 %8 %43\n%46 = OpLoad %5 %45\n%53 = OpCompositeConstruct %52 %31 %33 %50\n%55 = OpCompositeConstruct %52 %49 %49 %51\nOpRayQueryInitializeKHR %19 %46 %47 %48 %53 %54 %55 %56\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-query-select-multi.invalid.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _14_16\n{\n    vec4 _m0[1];\n} _16;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8[];\n\nrayQueryEXT RayQueryHeap[2];\n\nvoid main()\n{\n    float _33 = float(gl_GlobalInvocationID.x) + 0.5;\n    float _35 = float(gl_GlobalInvocationID.y) + 0.5;\n    uvec4 _40 = floatBitsToUint(_16._m0[0u]);\n    uint _45 = _40.x;\n    rayQueryInitializeEXT(RayQueryHeap[uint(_40.y != 0u)], _8[_45], 4u, 255u, vec3(_33, _35, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n    rayQueryInitializeEXT(RayQueryHeap[1u], _8[_45], 4u, 255u, vec3(_33, _35, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\nOpCapability Shader\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_query\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %24\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %14 \"\"\nOpName %21 \"RayQueryHeap\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 ArrayStride 16\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %24 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeAccelerationStructureKHR\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypeArray %12 %10\n%14 = OpTypeStruct %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeRayQueryKHR\n%18 = OpConstant %9 2\n%19 = OpTypeArray %17 %18\n%20 = OpTypePointer Private %19\n%21 = OpVariable %20 Private\n%22 = OpTypeVector %9 3\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %9\n%27 = OpConstant %9 0\n%34 = OpConstant %11 0.5\n%36 = OpTypePointer Uniform %12\n%39 = OpTypeVector %9 4\n%42 = OpTypeBool\n%46 = OpTypePointer UniformConstant %5\n%49 = OpTypePointer Private %17\n%51 = OpConstant %9 4\n%52 = OpConstant %9 255\n%53 = OpConstant %11 0\n%54 = OpConstant %11 -1\n%55 = OpConstant %11 1\n%56 = OpTypeVector %11 3\n%58 = OpConstant %11 0.100000001\n%60 = OpConstant %11 1000\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%26 = OpAccessChain %25 %24 %27\n%28 = OpLoad %9 %26\n%29 = OpAccessChain %25 %24 %10\n%30 = OpLoad %9 %29\n%31 = OpConvertUToF %11 %28\n%32 = OpConvertUToF %11 %30\n%33 = OpFAdd %11 %31 %34\n%35 = OpFAdd %11 %32 %34\n%37 = OpAccessChain %36 %16 %27 %27\n%38 = OpLoad %12 %37\n%40 = OpBitcast %39 %38\n%41 = OpCompositeExtract %9 %40 1\n%43 = OpINotEqual %42 %41 %27\n%44 = OpSelect %9 %43 %10 %27\n%45 = OpCompositeExtract %9 %40 0\n%47 = OpAccessChain %46 %8 %45\n%48 = OpLoad %5 %47\n%50 = OpInBoundsAccessChain %49 %21 %44\n%57 = OpCompositeConstruct %56 %33 %35 %54\n%59 = OpCompositeConstruct %56 %53 %53 %55\nOpRayQueryInitializeKHR %50 %48 %51 %52 %57 %58 %59 %60\n%61 = OpInBoundsAccessChain %49 %21 %10\n%62 = OpCompositeConstruct %56 %33 %35 %54\n%63 = OpCompositeConstruct %56 %53 %53 %55\nOpRayQueryInitializeKHR %61 %48 %51 %52 %62 %58 %63 %60\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-query-select-simple.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _14_16\n{\n    vec4 _m0[1];\n} _16;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8[];\n\nrayQueryEXT RayQueryHeap;\n\nvoid main()\n{\n    uvec4 _38 = floatBitsToUint(_16._m0[0u]);\n    rayQueryInitializeEXT(RayQueryHeap, _8[_38.x], 4u, 255u, vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\nOpCapability Shader\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_query\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %22\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %14 \"\"\nOpName %19 \"RayQueryHeap\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 ArrayStride 16\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %22 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeAccelerationStructureKHR\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypeArray %12 %10\n%14 = OpTypeStruct %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeRayQueryKHR\n%18 = OpTypePointer Private %17\n%19 = OpVariable %18 Private\n%20 = OpTypeVector %9 3\n%21 = OpTypePointer Input %20\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Input %9\n%25 = OpConstant %9 0\n%32 = OpConstant %11 0.5\n%34 = OpTypePointer Uniform %12\n%37 = OpTypeVector %9 4\n%40 = OpTypeBool\n%44 = OpTypePointer UniformConstant %5\n%47 = OpConstant %9 4\n%48 = OpConstant %9 255\n%49 = OpConstant %11 0\n%50 = OpConstant %11 -1\n%51 = OpConstant %11 1\n%52 = OpTypeVector %11 3\n%54 = OpConstant %11 0.100000001\n%56 = OpConstant %11 1000\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%24 = OpAccessChain %23 %22 %25\n%26 = OpLoad %9 %24\n%27 = OpAccessChain %23 %22 %10\n%28 = OpLoad %9 %27\n%29 = OpConvertUToF %11 %26\n%30 = OpConvertUToF %11 %28\n%31 = OpFAdd %11 %29 %32\n%33 = OpFAdd %11 %30 %32\n%35 = OpAccessChain %34 %16 %25 %25\n%36 = OpLoad %12 %35\n%38 = OpBitcast %37 %36\n%39 = OpCompositeExtract %9 %38 1\n%41 = OpINotEqual %40 %39 %25\n%42 = OpSelect %9 %41 %25 %25\n%43 = OpCompositeExtract %9 %38 0\n%45 = OpAccessChain %44 %8 %43\n%46 = OpLoad %5 %45\n%53 = OpCompositeConstruct %52 %31 %33 %50\n%55 = OpCompositeConstruct %52 %49 %49 %51\nOpRayQueryInitializeKHR %19 %46 %47 %48 %53 %54 %55 %56\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-query-store-multi.invalid.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _14_16\n{\n    vec4 _m0[1];\n} _16;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8[];\n\nrayQueryEXT RayQueryHeap[8];\n\nvoid main()\n{\n    float _38 = float(gl_GlobalInvocationID.x) + 0.5;\n    float _40 = float(gl_GlobalInvocationID.y) + 0.5;\n    uint _34[4];\n    _34[0u] = 0u;\n    _34[1u] = 1u;\n    _34[2u] = 2u;\n    _34[3u] = 3u;\n    uint _35[4];\n    _35[0u] = 4u;\n    _35[1u] = 5u;\n    _35[2u] = 6u;\n    _35[3u] = 7u;\n    uvec4 _59 = floatBitsToUint(_16._m0[0u]);\n    uint _60 = _59.y;\n    uint _67 = _59.x;\n    rayQueryInitializeEXT(RayQueryHeap[_34[_60 ^ 1u]], _8[_67], 4u, 255u, vec3(_38, _40, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n    rayQueryInitializeEXT(RayQueryHeap[_35[_60 ^ 2u]], _8[_67], 1u, 255u, vec3(_38, _40, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_query\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %24\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %14 \"\"\nOpName %21 \"RayQueryHeap\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 ArrayStride 16\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %24 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeAccelerationStructureKHR\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypeArray %12 %10\n%14 = OpTypeStruct %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeRayQueryKHR\n%18 = OpConstant %9 8\n%19 = OpTypeArray %17 %18\n%20 = OpTypePointer Private %19\n%21 = OpVariable %20 Private\n%22 = OpTypeVector %9 3\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %9\n%27 = OpConstant %9 0\n%31 = OpConstant %9 4\n%32 = OpTypeArray %9 %31\n%33 = OpTypePointer Function %32\n%39 = OpConstant %11 0.5\n%41 = OpTypePointer Function %9\n%44 = OpConstant %9 2\n%46 = OpConstant %9 3\n%49 = OpConstant %9 5\n%51 = OpConstant %9 6\n%53 = OpConstant %9 7\n%55 = OpTypePointer Uniform %12\n%58 = OpTypeVector %9 4\n%68 = OpTypePointer UniformConstant %5\n%71 = OpTypePointer Private %17\n%73 = OpConstant %9 255\n%74 = OpConstant %11 0\n%75 = OpConstant %11 -1\n%76 = OpConstant %11 1\n%77 = OpTypeVector %11 3\n%79 = OpConstant %11 0.100000001\n%81 = OpConstant %11 1000\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%34 = OpVariable %33 Function\n%35 = OpVariable %33 Function\nOpBranch %85\n%85 = OpLabel\n%26 = OpAccessChain %25 %24 %27\n%28 = OpLoad %9 %26\n%29 = OpAccessChain %25 %24 %10\n%30 = OpLoad %9 %29\n%36 = OpConvertUToF %11 %28\n%37 = OpConvertUToF %11 %30\n%38 = OpFAdd %11 %36 %39\n%40 = OpFAdd %11 %37 %39\n%42 = OpInBoundsAccessChain %41 %34 %27\nOpStore %42 %27\n%43 = OpInBoundsAccessChain %41 %34 %10\nOpStore %43 %10\n%45 = OpInBoundsAccessChain %41 %34 %44\nOpStore %45 %44\n%47 = OpInBoundsAccessChain %41 %34 %46\nOpStore %47 %46\n%48 = OpInBoundsAccessChain %41 %35 %27\nOpStore %48 %31\n%50 = OpInBoundsAccessChain %41 %35 %10\nOpStore %50 %49\n%52 = OpInBoundsAccessChain %41 %35 %44\nOpStore %52 %51\n%54 = OpInBoundsAccessChain %41 %35 %46\nOpStore %54 %53\n%56 = OpAccessChain %55 %16 %27 %27\n%57 = OpLoad %12 %56\n%59 = OpBitcast %58 %57\n%60 = OpCompositeExtract %9 %59 1\n%61 = OpBitwiseXor %9 %60 %10\n%62 = OpInBoundsAccessChain %41 %34 %61\n%63 = OpLoad %9 %62\n%64 = OpBitwiseXor %9 %60 %44\n%65 = OpInBoundsAccessChain %41 %35 %64\n%66 = OpLoad %9 %65\n%67 = OpCompositeExtract %9 %59 0\n%69 = OpAccessChain %68 %8 %67\n%70 = OpLoad %5 %69\n%72 = OpInBoundsAccessChain %71 %21 %63\n%78 = OpCompositeConstruct %77 %38 %40 %75\n%80 = OpCompositeConstruct %77 %74 %74 %76\nOpRayQueryInitializeKHR %72 %70 %31 %73 %78 %79 %80 %81\n%82 = OpInBoundsAccessChain %71 %21 %66\n%83 = OpCompositeConstruct %77 %38 %40 %75\n%84 = OpCompositeConstruct %77 %74 %74 %76\nOpRayQueryInitializeKHR %82 %70 %10 %73 %83 %79 %84 %81\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-query-store-simple.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _14_16\n{\n    vec4 _m0[1];\n} _16;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8[];\n\nrayQueryEXT RayQueryHeap;\n\nvoid main()\n{\n    uint _32[4];\n    _32[0u] = 0u;\n    _32[1u] = 0u;\n    _32[2u] = 0u;\n    _32[3u] = 0u;\n    uvec4 _49 = floatBitsToUint(_16._m0[0u]);\n    rayQueryInitializeEXT(RayQueryHeap, _8[_49.x], 4u, 255u, vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, -1.0), 0.100000001490116119384765625, vec3(0.0, 0.0, 1.0), 1000.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 68\n; Schema: 0\nOpCapability Shader\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_query\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %22\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %14 \"\"\nOpName %19 \"RayQueryHeap\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 ArrayStride 16\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %22 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeAccelerationStructureKHR\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypeArray %12 %10\n%14 = OpTypeStruct %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeRayQueryKHR\n%18 = OpTypePointer Private %17\n%19 = OpVariable %18 Private\n%20 = OpTypeVector %9 3\n%21 = OpTypePointer Input %20\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Input %9\n%25 = OpConstant %9 0\n%29 = OpConstant %9 4\n%30 = OpTypeArray %9 %29\n%31 = OpTypePointer Function %30\n%36 = OpConstant %11 0.5\n%38 = OpTypePointer Function %9\n%42 = OpConstant %9 2\n%44 = OpConstant %9 3\n%45 = OpTypePointer Uniform %12\n%48 = OpTypeVector %9 4\n%54 = OpTypePointer UniformConstant %5\n%57 = OpConstant %9 255\n%58 = OpConstant %11 0\n%59 = OpConstant %11 -1\n%60 = OpConstant %11 1\n%61 = OpTypeVector %11 3\n%63 = OpConstant %11 0.100000001\n%65 = OpConstant %11 1000\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%32 = OpVariable %31 Function\nOpBranch %66\n%66 = OpLabel\n%24 = OpAccessChain %23 %22 %25\n%26 = OpLoad %9 %24\n%27 = OpAccessChain %23 %22 %10\n%28 = OpLoad %9 %27\n%33 = OpConvertUToF %11 %26\n%34 = OpConvertUToF %11 %28\n%35 = OpFAdd %11 %33 %36\n%37 = OpFAdd %11 %34 %36\n%39 = OpInBoundsAccessChain %38 %32 %25\nOpStore %39 %25\n%40 = OpInBoundsAccessChain %38 %32 %10\nOpStore %40 %25\n%41 = OpInBoundsAccessChain %38 %32 %42\nOpStore %41 %25\n%43 = OpInBoundsAccessChain %38 %32 %44\nOpStore %43 %25\n%46 = OpAccessChain %45 %16 %25 %25\n%47 = OpLoad %12 %46\n%49 = OpBitcast %48 %47\n%50 = OpCompositeExtract %9 %49 1\n%51 = OpInBoundsAccessChain %38 %32 %50\n%52 = OpLoad %9 %51\n%53 = OpCompositeExtract %9 %49 0\n%55 = OpAccessChain %54 %8 %53\n%56 = OpLoad %5 %55\n%62 = OpCompositeConstruct %61 %35 %37 %59\n%64 = OpCompositeConstruct %61 %58 %58 %60\nOpRayQueryInitializeKHR %19 %56 %29 %57 %62 %63 %64 %65\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-query.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\nlayout(primitive_culling);\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _12;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _13;\nlayout(set = 0, binding = 3, r32ui) uniform writeonly uimageBuffer _14;\nlayout(set = 0, binding = 4, r32ui) uniform writeonly uimageBuffer _15;\n\nrayQueryEXT _26;\n\nvoid main()\n{\n    rayQueryInitializeEXT(_26, _8, 132u, 170u, vec3(1.0, 2.0, 3.0), 4.0, vec3(5.0, 6.0, 7.0), 8.0);\n    bool _42 = rayQueryProceedEXT(_26);\n    uint _176;\n    uint _177;\n    uint _178;\n    uint _179;\n    if (_42)\n    {\n        uint _46;\n        uint _49;\n        uint _51;\n        uint _45 = 0u;\n        uint _48 = 0u;\n        uint _50 = 0u;\n        uint _53;\n        uint _174;\n        bool _175;\n        for (;;)\n        {\n            uint _52 = rayQueryGetIntersectionInstanceIdEXT(_26, bool(0u));\n            _53 = gl_LocalInvocationIndex << 6u;\n            imageStore(_12, int(gl_LocalInvocationIndex * 64u), uvec4(_52));\n            uint _58 = rayQueryGetIntersectionInstanceCustomIndexEXT(_26, bool(0u));\n            imageStore(_12, int((gl_LocalInvocationIndex * 64u) + 1u), uvec4(_58));\n            uint _64 = rayQueryGetIntersectionGeometryIndexEXT(_26, bool(0u));\n            imageStore(_12, int((gl_LocalInvocationIndex * 64u) + 2u), uvec4(_64));\n            uint _70 = rayQueryGetIntersectionPrimitiveIndexEXT(_26, bool(0u));\n            imageStore(_12, int((gl_LocalInvocationIndex * 64u) + 3u), uvec4(_70));\n            vec3 _76 = rayQueryGetIntersectionObjectRayOriginEXT(_26, bool(0u));\n            imageStore(_13, int((gl_LocalInvocationIndex * 64u) + 4u), uvec4(floatBitsToUint(_76.x)));\n            vec3 _84 = rayQueryGetIntersectionObjectRayDirectionEXT(_26, bool(0u));\n            imageStore(_13, int((gl_LocalInvocationIndex * 64u) + 5u), uvec4(floatBitsToUint(_84.y)));\n            uint _92 = rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(_26, bool(0u));\n            imageStore(_12, int((gl_LocalInvocationIndex * 64u) + 16u), uvec4(_92));\n            mat4x3 _99 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(0u));\n            mat4x3 _101 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(0u));\n            mat4x3 _103 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(0u));\n            mat4x3 _105 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(0u));\n            mat4x3 _107 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(0u));\n            mat4x3 _109 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(0u));\n            mat4x3 _111 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(0u));\n            mat4x3 _113 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(0u));\n            uint _116 = gl_LocalInvocationIndex * 16u;\n            imageStore(_14, int(_116), uvec4(floatBitsToUint(_99[0].x)));\n            imageStore(_14, int(_116 + 1u), uvec4(floatBitsToUint(_101[1].x)));\n            imageStore(_14, int(_116 + 2u), uvec4(floatBitsToUint(_103[2].x)));\n            imageStore(_14, int(_116 + 3u), uvec4(floatBitsToUint(_105[3].x)));\n            uint _130 = (gl_LocalInvocationIndex * 16u) + 4u;\n            imageStore(_14, int(_130), uvec4(floatBitsToUint(_107[0].x)));\n            imageStore(_14, int(_130 + 1u), uvec4(floatBitsToUint(_109[1].x)));\n            imageStore(_14, int(_130 + 2u), uvec4(floatBitsToUint(_111[2].x)));\n            imageStore(_14, int(_130 + 3u), uvec4(floatBitsToUint(_113[3].x)));\n            mat4x3 _142 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(0u));\n            mat4x3 _144 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(0u));\n            mat4x3 _146 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(0u));\n            mat4x3 _148 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(0u));\n            mat4x3 _150 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(0u));\n            mat4x3 _152 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(0u));\n            uint _154 = gl_LocalInvocationIndex * 12u;\n            imageStore(_15, int(_154), uvec4(floatBitsToUint(_142[0].x)));\n            imageStore(_15, int(_154 + 1u), uvec4(floatBitsToUint(_144[0].y)));\n            imageStore(_15, int(_154 + 2u), uvec4(floatBitsToUint(_146[0].z)));\n            uint _165 = (gl_LocalInvocationIndex * 12u) + 3u;\n            imageStore(_15, int(_165), uvec4(floatBitsToUint(_148[0].x)));\n            imageStore(_15, int(_165 + 1u), uvec4(floatBitsToUint(_150[0].y)));\n            imageStore(_15, int(_165 + 2u), uvec4(floatBitsToUint(_152[0].z)));\n            _174 = rayQueryGetIntersectionTypeEXT(_26, bool(0u));\n            _175 = _174 == 0u;\n            if (_175)\n            {\n                float _207 = rayQueryGetIntersectionTEXT(_26, bool(0u));\n                imageStore(_13, int((gl_LocalInvocationIndex * 64u) + 6u), uvec4(floatBitsToUint(_207)));\n                vec2 _214 = rayQueryGetIntersectionBarycentricsEXT(_26, bool(0u));\n                imageStore(_13, int((gl_LocalInvocationIndex * 64u) + 7u), uvec4(floatBitsToUint(_214.y)));\n                bool _222 = rayQueryGetIntersectionFrontFaceEXT(_26, bool(0u));\n                imageStore(_12, int((gl_LocalInvocationIndex * 64u) + 8u), uvec4(_222 ? 100u : 10u));\n                rayQueryConfirmIntersectionEXT(_26);\n                _46 = _45 + 1u;\n                _49 = _48;\n                _51 = _50;\n            }\n            else\n            {\n                uint frontier_phi_9_6_ladder;\n                uint frontier_phi_9_6_ladder_1;\n                uint frontier_phi_9_6_ladder_2;\n                if (_174 == 1u)\n                {\n                    bool _368 = rayQueryGetIntersectionCandidateAABBOpaqueEXT(_26);\n                    uint _370 = uint(!_368);\n                    rayQueryGenerateIntersectionEXT(_26, 0.5);\n                    frontier_phi_9_6_ladder = _45;\n                    frontier_phi_9_6_ladder_1 = _370 + _48;\n                    frontier_phi_9_6_ladder_2 = (_370 ^ 1u) + _50;\n                }\n                else\n                {\n                    frontier_phi_9_6_ladder = _45;\n                    frontier_phi_9_6_ladder_1 = _48;\n                    frontier_phi_9_6_ladder_2 = _50;\n                }\n                _46 = frontier_phi_9_6_ladder;\n                _49 = frontier_phi_9_6_ladder_1;\n                _51 = frontier_phi_9_6_ladder_2;\n            }\n            if (_46 == 4u)\n            {\n                rayQueryTerminateEXT(_26);\n            }\n            bool _391 = rayQueryProceedEXT(_26);\n            if (_391)\n            {\n                _45 = _46;\n                _48 = _49;\n                _50 = _51;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n        _176 = _53;\n        _177 = _46;\n        _178 = _49;\n        _179 = _51;\n    }\n    else\n    {\n        _176 = gl_LocalInvocationIndex << 6u;\n        _177 = 0u;\n        _178 = 0u;\n        _179 = 0u;\n    }\n    uint _180 = rayQueryGetRayFlagsEXT(_26);\n    imageStore(_12, int((_176 | 9u) + 0u), uvec4(_180));\n    vec3 _185 = rayQueryGetWorldRayOriginEXT(_26);\n    imageStore(_13, int(_176 + 10u), uvec4(floatBitsToUint(_185.x)));\n    vec3 _192 = rayQueryGetWorldRayDirectionEXT(_26);\n    imageStore(_13, int((_176 | 11u) + 0u), uvec4(floatBitsToUint(_192.y)));\n    float _199 = rayQueryGetRayTMinEXT(_26);\n    imageStore(_13, int(_176 + 12u), uvec4(floatBitsToUint(_199)));\n    uint _204 = rayQueryGetIntersectionTypeEXT(_26, bool(1u));\n    if (!(_204 == 0u))\n    {\n        uint _233 = rayQueryGetIntersectionInstanceIdEXT(_26, bool(1u));\n        imageStore(_12, int(_176 + 32u), uvec4(_233));\n        uint _238 = rayQueryGetIntersectionInstanceCustomIndexEXT(_26, bool(1u));\n        imageStore(_12, int((_176 | 33u) + 0u), uvec4(_238));\n        uint _243 = rayQueryGetIntersectionGeometryIndexEXT(_26, bool(1u));\n        imageStore(_12, int(_176 + 34u), uvec4(_243));\n        uint _248 = rayQueryGetIntersectionPrimitiveIndexEXT(_26, bool(1u));\n        imageStore(_12, int((_176 | 35u) + 0u), uvec4(_248));\n        vec3 _253 = rayQueryGetIntersectionObjectRayOriginEXT(_26, bool(1u));\n        imageStore(_13, int(_176 + 36u), uvec4(floatBitsToUint(_253.x)));\n        vec3 _260 = rayQueryGetIntersectionObjectRayDirectionEXT(_26, bool(1u));\n        imageStore(_13, int((_176 | 37u) + 0u), uvec4(floatBitsToUint(_260.y)));\n        uint _267 = rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(_26, bool(1u));\n        imageStore(_12, int(_176 + 38u), uvec4(_267));\n        mat4x3 _272 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(1u));\n        mat4x3 _274 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(1u));\n        mat4x3 _276 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(1u));\n        mat4x3 _278 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(1u));\n        mat4x3 _280 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(1u));\n        mat4x3 _282 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(1u));\n        mat4x3 _284 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(1u));\n        mat4x3 _286 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(1u));\n        uint _288 = gl_LocalInvocationIndex << 2u;\n        uint _293 = (gl_LocalInvocationIndex * 16u) + 156u;\n        imageStore(_14, int(_293), uvec4(floatBitsToUint(_272[0].x)));\n        imageStore(_14, int(_293 + 1u), uvec4(floatBitsToUint(_274[1].x)));\n        imageStore(_14, int(_293 + 2u), uvec4(floatBitsToUint(_276[2].x)));\n        imageStore(_14, int(_293 + 3u), uvec4(floatBitsToUint(_278[3].x)));\n        uint _309 = (gl_LocalInvocationIndex * 16u) + 160u;\n        imageStore(_14, int(_309), uvec4(floatBitsToUint(_280[0].x)));\n        imageStore(_14, int(_309 + 1u), uvec4(floatBitsToUint(_282[1].x)));\n        imageStore(_14, int(_309 + 2u), uvec4(floatBitsToUint(_284[2].x)));\n        imageStore(_14, int(_309 + 3u), uvec4(floatBitsToUint(_286[3].x)));\n        mat4x3 _321 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(1u));\n        mat4x3 _323 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(1u));\n        mat4x3 _325 = rayQueryGetIntersectionWorldToObjectEXT(_26, bool(1u));\n        mat4x3 _327 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(1u));\n        mat4x3 _329 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(1u));\n        mat4x3 _331 = rayQueryGetIntersectionObjectToWorldEXT(_26, bool(1u));\n        uint _337 = (gl_LocalInvocationIndex * 12u) + 123u;\n        imageStore(_15, int(_337), uvec4(floatBitsToUint(_321[0].x)));\n        imageStore(_15, int(_337 + 1u), uvec4(floatBitsToUint(_323[0].y)));\n        imageStore(_15, int(_337 + 2u), uvec4(floatBitsToUint(_325[0].z)));\n        uint _350 = (gl_LocalInvocationIndex * 12u) + 126u;\n        imageStore(_15, int(_350), uvec4(floatBitsToUint(_327[0].x)));\n        imageStore(_15, int(_350 + 1u), uvec4(floatBitsToUint(_329[0].y)));\n        imageStore(_15, int(_350 + 2u), uvec4(floatBitsToUint(_331[0].z)));\n        float _359 = rayQueryGetIntersectionTEXT(_26, bool(1u));\n        imageStore(_13, int((_176 | 43u) + 0u), uvec4(floatBitsToUint(_359)));\n    }\n    uint _231 = rayQueryGetIntersectionTypeEXT(_26, bool(1u));\n    if (_231 == 1u)\n    {\n        imageStore(_12, int((_176 | 13u) + 0u), uvec4(_177));\n        vec2 _377 = rayQueryGetIntersectionBarycentricsEXT(_26, bool(1u));\n        imageStore(_13, int(_176 + 44u), uvec4(floatBitsToUint(_377.y)));\n        bool _384 = rayQueryGetIntersectionFrontFaceEXT(_26, bool(1u));\n        imageStore(_12, int((_176 | 45u) + 0u), uvec4(_384 ? 100u : 10u));\n    }\n    else\n    {\n        if (_231 == 2u)\n        {\n            imageStore(_12, int(_176 + 14u), uvec4(_178));\n        }\n        else\n        {\n            imageStore(_12, int((_176 | 15u) + 0u), uvec4(_179));\n        }\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 427\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpExtension \"SPV_KHR_ray_query\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %22\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %400 \"frontier_phi_9.6.ladder\"\nOpName %401 \"frontier_phi_9.6.ladder\"\nOpName %402 \"frontier_phi_9.6.ladder\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %12 NonReadable\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 2\nOpDecorate %13 NonReadable\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %14 NonReadable\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 4\nOpDecorate %15 NonReadable\nOpDecorate %22 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeImage %9 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpVariable %11 UniformConstant\n%14 = OpVariable %11 UniformConstant\n%15 = OpVariable %11 UniformConstant\n%21 = OpTypePointer Input %9\n%22 = OpVariable %21 Input\n%24 = OpTypeRayQueryKHR\n%25 = OpTypePointer Private %24\n%26 = OpVariable %25 Private\n%27 = OpConstant %9 132\n%28 = OpConstant %9 170\n%29 = OpTypeFloat 32\n%30 = OpConstant %29 1\n%31 = OpConstant %29 5\n%32 = OpConstant %29 2\n%33 = OpConstant %29 6\n%34 = OpConstant %29 3\n%35 = OpConstant %29 7\n%36 = OpTypeVector %29 3\n%38 = OpConstant %29 4\n%40 = OpConstant %29 8\n%41 = OpTypeBool\n%44 = OpConstant %9 6\n%47 = OpConstant %9 0\n%55 = OpConstant %9 64\n%56 = OpTypeVector %9 4\n%60 = OpConstant %9 1\n%66 = OpConstant %9 2\n%72 = OpConstant %9 3\n%79 = OpConstant %9 4\n%87 = OpConstant %9 5\n%94 = OpConstant %9 16\n%98 = OpTypeMatrix %36 4\n%155 = OpConstant %9 12\n%182 = OpConstant %9 9\n%188 = OpConstant %9 10\n%195 = OpConstant %9 11\n%213 = OpTypeVector %29 2\n%217 = OpConstant %9 7\n%224 = OpConstant %9 100\n%226 = OpConstant %9 8\n%235 = OpConstant %9 32\n%240 = OpConstant %9 33\n%245 = OpConstant %9 34\n%250 = OpConstant %9 35\n%256 = OpConstant %9 36\n%263 = OpConstant %9 37\n%269 = OpConstant %9 38\n%290 = OpConstant %9 39\n%292 = OpConstant %9 156\n%306 = OpConstant %9 40\n%308 = OpConstant %9 160\n%334 = OpConstant %9 41\n%336 = OpConstant %9 123\n%347 = OpConstant %9 42\n%349 = OpConstant %9 126\n%361 = OpConstant %9 43\n%372 = OpConstant %29 0.5\n%374 = OpConstant %9 13\n%380 = OpConstant %9 44\n%387 = OpConstant %9 45\n%393 = OpConstant %9 14\n%397 = OpConstant %9 15\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %403\n%403 = OpLabel\n%16 = OpLoad %10 %15\n%17 = OpLoad %10 %14\n%18 = OpLoad %10 %13\n%19 = OpLoad %10 %12\n%20 = OpLoad %6 %8\n%23 = OpLoad %9 %22\n%37 = OpCompositeConstruct %36 %30 %32 %34\n%39 = OpCompositeConstruct %36 %31 %33 %35\nOpRayQueryInitializeKHR %26 %20 %27 %28 %37 %38 %39 %40\n%42 = OpRayQueryProceedKHR %41 %26\nOpSelectionMerge %417 None\nOpBranchConditional %42 %405 %404\n%405 = OpLabel\nOpBranch %406\n%406 = OpLabel\n%45 = OpPhi %9 %47 %405 %46 %415\n%48 = OpPhi %9 %47 %405 %49 %415\n%50 = OpPhi %9 %47 %405 %51 %415\n%52 = OpRayQueryGetIntersectionInstanceIdKHR %9 %26 %47\n%53 = OpShiftLeftLogical %9 %23 %44\n%54 = OpIMul %9 %23 %55\n%57 = OpCompositeConstruct %56 %52 %52 %52 %52\nOpImageWrite %19 %54 %57\n%58 = OpRayQueryGetIntersectionInstanceCustomIndexKHR %9 %26 %47\n%59 = OpBitwiseOr %9 %53 %60\n%61 = OpIMul %9 %23 %55\n%62 = OpIAdd %9 %61 %60\n%63 = OpCompositeConstruct %56 %58 %58 %58 %58\nOpImageWrite %19 %62 %63\n%64 = OpRayQueryGetIntersectionGeometryIndexKHR %9 %26 %47\n%65 = OpBitwiseOr %9 %53 %66\n%67 = OpIMul %9 %23 %55\n%68 = OpIAdd %9 %67 %66\n%69 = OpCompositeConstruct %56 %64 %64 %64 %64\nOpImageWrite %19 %68 %69\n%70 = OpRayQueryGetIntersectionPrimitiveIndexKHR %9 %26 %47\n%71 = OpBitwiseOr %9 %53 %72\n%73 = OpIMul %9 %23 %55\n%74 = OpIAdd %9 %73 %72\n%75 = OpCompositeConstruct %56 %70 %70 %70 %70\nOpImageWrite %19 %74 %75\n%76 = OpRayQueryGetIntersectionObjectRayOriginKHR %36 %26 %47\n%77 = OpCompositeExtract %29 %76 0\n%78 = OpBitwiseOr %9 %53 %79\n%80 = OpIMul %9 %23 %55\n%81 = OpIAdd %9 %80 %79\n%82 = OpBitcast %9 %77\n%83 = OpCompositeConstruct %56 %82 %82 %82 %82\nOpImageWrite %18 %81 %83\n%84 = OpRayQueryGetIntersectionObjectRayDirectionKHR %36 %26 %47\n%85 = OpCompositeExtract %29 %84 1\n%86 = OpBitwiseOr %9 %53 %87\n%88 = OpIMul %9 %23 %55\n%89 = OpIAdd %9 %88 %87\n%90 = OpBitcast %9 %85\n%91 = OpCompositeConstruct %56 %90 %90 %90 %90\nOpImageWrite %18 %89 %91\n%92 = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %9 %26 %47\n%93 = OpBitwiseOr %9 %53 %94\n%95 = OpIMul %9 %23 %55\n%96 = OpIAdd %9 %95 %94\n%97 = OpCompositeConstruct %56 %92 %92 %92 %92\nOpImageWrite %19 %96 %97\n%99 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %47\n%100 = OpCompositeExtract %29 %99 0 0\n%101 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %47\n%102 = OpCompositeExtract %29 %101 1 0\n%103 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %47\n%104 = OpCompositeExtract %29 %103 2 0\n%105 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %47\n%106 = OpCompositeExtract %29 %105 3 0\n%107 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %47\n%108 = OpCompositeExtract %29 %107 0 0\n%109 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %47\n%110 = OpCompositeExtract %29 %109 1 0\n%111 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %47\n%112 = OpCompositeExtract %29 %111 2 0\n%113 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %47\n%114 = OpCompositeExtract %29 %113 3 0\n%115 = OpShiftLeftLogical %9 %23 %66\n%116 = OpIMul %9 %23 %94\n%117 = OpBitcast %9 %100\n%118 = OpBitcast %9 %102\n%119 = OpBitcast %9 %104\n%120 = OpBitcast %9 %106\n%121 = OpCompositeConstruct %56 %117 %117 %117 %117\nOpImageWrite %17 %116 %121\n%122 = OpCompositeConstruct %56 %118 %118 %118 %118\n%123 = OpIAdd %9 %116 %60\nOpImageWrite %17 %123 %122\n%124 = OpCompositeConstruct %56 %119 %119 %119 %119\n%125 = OpIAdd %9 %116 %66\nOpImageWrite %17 %125 %124\n%126 = OpCompositeConstruct %56 %120 %120 %120 %120\n%127 = OpIAdd %9 %116 %72\nOpImageWrite %17 %127 %126\n%128 = OpBitwiseOr %9 %115 %60\n%129 = OpIMul %9 %23 %94\n%130 = OpIAdd %9 %129 %79\n%131 = OpBitcast %9 %108\n%132 = OpBitcast %9 %110\n%133 = OpBitcast %9 %112\n%134 = OpBitcast %9 %114\n%135 = OpCompositeConstruct %56 %131 %131 %131 %131\nOpImageWrite %17 %130 %135\n%136 = OpCompositeConstruct %56 %132 %132 %132 %132\n%137 = OpIAdd %9 %130 %60\nOpImageWrite %17 %137 %136\n%138 = OpCompositeConstruct %56 %133 %133 %133 %133\n%139 = OpIAdd %9 %130 %66\nOpImageWrite %17 %139 %138\n%140 = OpCompositeConstruct %56 %134 %134 %134 %134\n%141 = OpIAdd %9 %130 %72\nOpImageWrite %17 %141 %140\n%142 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %47\n%143 = OpCompositeExtract %29 %142 0 0\n%144 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %47\n%145 = OpCompositeExtract %29 %144 0 1\n%146 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %47\n%147 = OpCompositeExtract %29 %146 0 2\n%148 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %47\n%149 = OpCompositeExtract %29 %148 0 0\n%150 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %47\n%151 = OpCompositeExtract %29 %150 0 1\n%152 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %47\n%153 = OpCompositeExtract %29 %152 0 2\n%154 = OpIMul %9 %23 %155\n%156 = OpBitcast %9 %143\n%157 = OpBitcast %9 %145\n%158 = OpBitcast %9 %147\n%159 = OpCompositeConstruct %56 %156 %156 %156 %156\nOpImageWrite %16 %154 %159\n%160 = OpCompositeConstruct %56 %157 %157 %157 %157\n%161 = OpIAdd %9 %154 %60\nOpImageWrite %16 %161 %160\n%162 = OpCompositeConstruct %56 %158 %158 %158 %158\n%163 = OpIAdd %9 %154 %66\nOpImageWrite %16 %163 %162\n%164 = OpIMul %9 %23 %155\n%165 = OpIAdd %9 %164 %72\n%166 = OpBitcast %9 %149\n%167 = OpBitcast %9 %151\n%168 = OpBitcast %9 %153\n%169 = OpCompositeConstruct %56 %166 %166 %166 %166\nOpImageWrite %16 %165 %169\n%170 = OpCompositeConstruct %56 %167 %167 %167 %167\n%171 = OpIAdd %9 %165 %60\nOpImageWrite %16 %171 %170\n%172 = OpCompositeConstruct %56 %168 %168 %168 %168\n%173 = OpIAdd %9 %165 %66\nOpImageWrite %16 %173 %172\n%174 = OpRayQueryGetIntersectionTypeKHR %9 %26 %47\n%175 = OpIEqual %41 %174 %47\nOpLoopMerge %416 %415 None\nOpBranch %407\n%407 = OpLabel\nOpSelectionMerge %412 None\nOpBranchConditional %175 %411 %408\n%411 = OpLabel\n%206 = OpIAdd %9 %45 %60\n%207 = OpRayQueryGetIntersectionTKHR %29 %26 %47\n%208 = OpBitwiseOr %9 %53 %44\n%209 = OpIMul %9 %23 %55\n%210 = OpIAdd %9 %209 %44\n%211 = OpBitcast %9 %207\n%212 = OpCompositeConstruct %56 %211 %211 %211 %211\nOpImageWrite %18 %210 %212\n%214 = OpRayQueryGetIntersectionBarycentricsKHR %213 %26 %47\n%215 = OpCompositeExtract %29 %214 1\n%216 = OpBitwiseOr %9 %53 %217\n%218 = OpIMul %9 %23 %55\n%219 = OpIAdd %9 %218 %217\n%220 = OpBitcast %9 %215\n%221 = OpCompositeConstruct %56 %220 %220 %220 %220\nOpImageWrite %18 %219 %221\n%222 = OpRayQueryGetIntersectionFrontFaceKHR %41 %26 %47\n%223 = OpSelect %9 %222 %224 %188\n%225 = OpBitwiseOr %9 %53 %226\n%227 = OpIMul %9 %23 %55\n%228 = OpIAdd %9 %227 %226\n%229 = OpCompositeConstruct %56 %223 %223 %223 %223\nOpImageWrite %19 %228 %229\nOpRayQueryConfirmIntersectionKHR %26\nOpBranch %412\n%408 = OpLabel\n%230 = OpIEqual %41 %174 %60\nOpSelectionMerge %410 None\nOpBranchConditional %230 %409 %410\n%409 = OpLabel\n%368 = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %41 %26\n%369 = OpLogicalNot %41 %368\n%370 = OpSelect %9 %369 %60 %47\n%365 = OpIAdd %9 %370 %48\n%371 = OpBitwiseXor %9 %370 %60\n%366 = OpIAdd %9 %371 %50\nOpRayQueryGenerateIntersectionKHR %26 %372\nOpBranch %410\n%410 = OpLabel\n%400 = OpPhi %9 %45 %409 %45 %408\n%401 = OpPhi %9 %365 %409 %48 %408\n%402 = OpPhi %9 %366 %409 %50 %408\nOpBranch %412\n%412 = OpLabel\n%46 = OpPhi %9 %206 %411 %400 %410\n%49 = OpPhi %9 %48 %411 %401 %410\n%51 = OpPhi %9 %50 %411 %402 %410\n%367 = OpIEqual %41 %46 %79\nOpSelectionMerge %414 None\nOpBranchConditional %367 %413 %414\n%413 = OpLabel\nOpRayQueryTerminateKHR %26\nOpBranch %414\n%414 = OpLabel\nOpBranch %415\n%415 = OpLabel\n%391 = OpRayQueryProceedKHR %41 %26\nOpBranchConditional %391 %406 %416\n%416 = OpLabel\nOpBranch %417\n%404 = OpLabel\n%43 = OpShiftLeftLogical %9 %23 %44\nOpBranch %417\n%417 = OpLabel\n%176 = OpPhi %9 %43 %404 %53 %416\n%177 = OpPhi %9 %47 %404 %46 %416\n%178 = OpPhi %9 %47 %404 %49 %416\n%179 = OpPhi %9 %47 %404 %51 %416\n%180 = OpRayQueryGetRayFlagsKHR %9 %26\n%181 = OpBitwiseOr %9 %176 %182\n%183 = OpIAdd %9 %181 %47\n%184 = OpCompositeConstruct %56 %180 %180 %180 %180\nOpImageWrite %19 %183 %184\n%185 = OpRayQueryGetWorldRayOriginKHR %36 %26\n%186 = OpCompositeExtract %29 %185 0\n%187 = OpBitwiseOr %9 %176 %188\n%189 = OpIAdd %9 %176 %188\n%190 = OpBitcast %9 %186\n%191 = OpCompositeConstruct %56 %190 %190 %190 %190\nOpImageWrite %18 %189 %191\n%192 = OpRayQueryGetWorldRayDirectionKHR %36 %26\n%193 = OpCompositeExtract %29 %192 1\n%194 = OpBitwiseOr %9 %176 %195\n%196 = OpIAdd %9 %194 %47\n%197 = OpBitcast %9 %193\n%198 = OpCompositeConstruct %56 %197 %197 %197 %197\nOpImageWrite %18 %196 %198\n%199 = OpRayQueryGetRayTMinKHR %29 %26\n%200 = OpBitwiseOr %9 %176 %155\n%201 = OpIAdd %9 %176 %155\n%202 = OpBitcast %9 %199\n%203 = OpCompositeConstruct %56 %202 %202 %202 %202\nOpImageWrite %18 %201 %203\n%204 = OpRayQueryGetIntersectionTypeKHR %9 %26 %60\n%205 = OpIEqual %41 %204 %47\nOpSelectionMerge %419 None\nOpBranchConditional %205 %419 %418\n%418 = OpLabel\n%233 = OpRayQueryGetIntersectionInstanceIdKHR %9 %26 %60\n%234 = OpBitwiseOr %9 %176 %235\n%236 = OpIAdd %9 %176 %235\n%237 = OpCompositeConstruct %56 %233 %233 %233 %233\nOpImageWrite %19 %236 %237\n%238 = OpRayQueryGetIntersectionInstanceCustomIndexKHR %9 %26 %60\n%239 = OpBitwiseOr %9 %176 %240\n%241 = OpIAdd %9 %239 %47\n%242 = OpCompositeConstruct %56 %238 %238 %238 %238\nOpImageWrite %19 %241 %242\n%243 = OpRayQueryGetIntersectionGeometryIndexKHR %9 %26 %60\n%244 = OpBitwiseOr %9 %176 %245\n%246 = OpIAdd %9 %176 %245\n%247 = OpCompositeConstruct %56 %243 %243 %243 %243\nOpImageWrite %19 %246 %247\n%248 = OpRayQueryGetIntersectionPrimitiveIndexKHR %9 %26 %60\n%249 = OpBitwiseOr %9 %176 %250\n%251 = OpIAdd %9 %249 %47\n%252 = OpCompositeConstruct %56 %248 %248 %248 %248\nOpImageWrite %19 %251 %252\n%253 = OpRayQueryGetIntersectionObjectRayOriginKHR %36 %26 %60\n%254 = OpCompositeExtract %29 %253 0\n%255 = OpBitwiseOr %9 %176 %256\n%257 = OpIAdd %9 %176 %256\n%258 = OpBitcast %9 %254\n%259 = OpCompositeConstruct %56 %258 %258 %258 %258\nOpImageWrite %18 %257 %259\n%260 = OpRayQueryGetIntersectionObjectRayDirectionKHR %36 %26 %60\n%261 = OpCompositeExtract %29 %260 1\n%262 = OpBitwiseOr %9 %176 %263\n%264 = OpIAdd %9 %262 %47\n%265 = OpBitcast %9 %261\n%266 = OpCompositeConstruct %56 %265 %265 %265 %265\nOpImageWrite %18 %264 %266\n%267 = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %9 %26 %60\n%268 = OpBitwiseOr %9 %176 %269\n%270 = OpIAdd %9 %176 %269\n%271 = OpCompositeConstruct %56 %267 %267 %267 %267\nOpImageWrite %19 %270 %271\n%272 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %60\n%273 = OpCompositeExtract %29 %272 0 0\n%274 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %60\n%275 = OpCompositeExtract %29 %274 1 0\n%276 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %60\n%277 = OpCompositeExtract %29 %276 2 0\n%278 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %60\n%279 = OpCompositeExtract %29 %278 3 0\n%280 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %60\n%281 = OpCompositeExtract %29 %280 0 0\n%282 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %60\n%283 = OpCompositeExtract %29 %282 1 0\n%284 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %60\n%285 = OpCompositeExtract %29 %284 2 0\n%286 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %60\n%287 = OpCompositeExtract %29 %286 3 0\n%288 = OpShiftLeftLogical %9 %23 %66\n%289 = OpIAdd %9 %288 %290\n%291 = OpIMul %9 %23 %94\n%293 = OpIAdd %9 %291 %292\n%294 = OpBitcast %9 %273\n%295 = OpBitcast %9 %275\n%296 = OpBitcast %9 %277\n%297 = OpBitcast %9 %279\n%298 = OpCompositeConstruct %56 %294 %294 %294 %294\nOpImageWrite %17 %293 %298\n%299 = OpCompositeConstruct %56 %295 %295 %295 %295\n%300 = OpIAdd %9 %293 %60\nOpImageWrite %17 %300 %299\n%301 = OpCompositeConstruct %56 %296 %296 %296 %296\n%302 = OpIAdd %9 %293 %66\nOpImageWrite %17 %302 %301\n%303 = OpCompositeConstruct %56 %297 %297 %297 %297\n%304 = OpIAdd %9 %293 %72\nOpImageWrite %17 %304 %303\n%305 = OpIAdd %9 %288 %306\n%307 = OpIMul %9 %23 %94\n%309 = OpIAdd %9 %307 %308\n%310 = OpBitcast %9 %281\n%311 = OpBitcast %9 %283\n%312 = OpBitcast %9 %285\n%313 = OpBitcast %9 %287\n%314 = OpCompositeConstruct %56 %310 %310 %310 %310\nOpImageWrite %17 %309 %314\n%315 = OpCompositeConstruct %56 %311 %311 %311 %311\n%316 = OpIAdd %9 %309 %60\nOpImageWrite %17 %316 %315\n%317 = OpCompositeConstruct %56 %312 %312 %312 %312\n%318 = OpIAdd %9 %309 %66\nOpImageWrite %17 %318 %317\n%319 = OpCompositeConstruct %56 %313 %313 %313 %313\n%320 = OpIAdd %9 %309 %72\nOpImageWrite %17 %320 %319\n%321 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %60\n%322 = OpCompositeExtract %29 %321 0 0\n%323 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %60\n%324 = OpCompositeExtract %29 %323 0 1\n%325 = OpRayQueryGetIntersectionWorldToObjectKHR %98 %26 %60\n%326 = OpCompositeExtract %29 %325 0 2\n%327 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %60\n%328 = OpCompositeExtract %29 %327 0 0\n%329 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %60\n%330 = OpCompositeExtract %29 %329 0 1\n%331 = OpRayQueryGetIntersectionObjectToWorldKHR %98 %26 %60\n%332 = OpCompositeExtract %29 %331 0 2\n%333 = OpIAdd %9 %288 %334\n%335 = OpIMul %9 %23 %155\n%337 = OpIAdd %9 %335 %336\n%338 = OpBitcast %9 %322\n%339 = OpBitcast %9 %324\n%340 = OpBitcast %9 %326\n%341 = OpCompositeConstruct %56 %338 %338 %338 %338\nOpImageWrite %16 %337 %341\n%342 = OpCompositeConstruct %56 %339 %339 %339 %339\n%343 = OpIAdd %9 %337 %60\nOpImageWrite %16 %343 %342\n%344 = OpCompositeConstruct %56 %340 %340 %340 %340\n%345 = OpIAdd %9 %337 %66\nOpImageWrite %16 %345 %344\n%346 = OpIAdd %9 %288 %347\n%348 = OpIMul %9 %23 %155\n%350 = OpIAdd %9 %348 %349\n%351 = OpBitcast %9 %328\n%352 = OpBitcast %9 %330\n%353 = OpBitcast %9 %332\n%354 = OpCompositeConstruct %56 %351 %351 %351 %351\nOpImageWrite %16 %350 %354\n%355 = OpCompositeConstruct %56 %352 %352 %352 %352\n%356 = OpIAdd %9 %350 %60\nOpImageWrite %16 %356 %355\n%357 = OpCompositeConstruct %56 %353 %353 %353 %353\n%358 = OpIAdd %9 %350 %66\nOpImageWrite %16 %358 %357\n%359 = OpRayQueryGetIntersectionTKHR %29 %26 %60\n%360 = OpBitwiseOr %9 %176 %361\n%362 = OpIAdd %9 %360 %47\n%363 = OpBitcast %9 %359\n%364 = OpCompositeConstruct %56 %363 %363 %363 %363\nOpImageWrite %18 %362 %364\nOpBranch %419\n%419 = OpLabel\n%231 = OpRayQueryGetIntersectionTypeKHR %9 %26 %60\n%232 = OpIEqual %41 %231 %60\nOpSelectionMerge %425 None\nOpBranchConditional %232 %424 %420\n%424 = OpLabel\n%373 = OpBitwiseOr %9 %176 %374\n%375 = OpIAdd %9 %373 %47\n%376 = OpCompositeConstruct %56 %177 %177 %177 %177\nOpImageWrite %19 %375 %376\n%377 = OpRayQueryGetIntersectionBarycentricsKHR %213 %26 %60\n%378 = OpCompositeExtract %29 %377 1\n%379 = OpBitwiseOr %9 %176 %380\n%381 = OpIAdd %9 %176 %380\n%382 = OpBitcast %9 %378\n%383 = OpCompositeConstruct %56 %382 %382 %382 %382\nOpImageWrite %18 %381 %383\n%384 = OpRayQueryGetIntersectionFrontFaceKHR %41 %26 %60\n%385 = OpSelect %9 %384 %224 %188\n%386 = OpBitwiseOr %9 %176 %387\n%388 = OpIAdd %9 %386 %47\n%389 = OpCompositeConstruct %56 %385 %385 %385 %385\nOpImageWrite %19 %388 %389\nOpBranch %425\n%420 = OpLabel\n%390 = OpIEqual %41 %231 %66\nOpSelectionMerge %423 None\nOpBranchConditional %390 %422 %421\n%422 = OpLabel\n%392 = OpBitwiseOr %9 %176 %393\n%394 = OpIAdd %9 %176 %393\n%395 = OpCompositeConstruct %56 %178 %178 %178 %178\nOpImageWrite %19 %394 %395\nOpBranch %423\n%421 = OpLabel\n%396 = OpBitwiseOr %9 %176 %397\n%398 = OpIAdd %9 %396 %47\n%399 = OpCompositeConstruct %56 %179 %179 %179 %179\nOpImageWrite %19 %398 %399\nOpBranch %423\n%423 = OpLabel\nOpBranch %425\n%425 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-t-current.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _18;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _17;\n    _17.x = gl_RayTmaxEXT;\n    _17.y = gl_RayTmaxEXT;\n    _17.z = gl_RayTmaxEXT;\n    payload._m0 = _17;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %15\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn RayTmaxKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%21 = OpTypePointer IncomingRayPayloadKHR %6\n%23 = OpTypeInt 32 0\n%24 = OpConstant %23 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%18 = OpUndef %6\nOpBranch %25\n%25 = OpLabel\n%16 = OpLoad %5 %15\n%17 = OpCompositeInsert %6 %16 %18 0\n%19 = OpCompositeInsert %6 %16 %17 1\n%20 = OpCompositeInsert %6 %16 %19 2\n%22 = OpInBoundsAccessChain %21 %9 %24\nOpStore %22 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/ray-t-min.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _18;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _17;\n    _17.x = gl_RayTminEXT;\n    _17.y = gl_RayTminEXT;\n    _17.z = gl_RayTminEXT;\n    payload._m0 = _17;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %15\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn RayTminKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%21 = OpTypePointer IncomingRayPayloadKHR %6\n%23 = OpTypeInt 32 0\n%24 = OpConstant %23 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%18 = OpUndef %6\nOpBranch %25\n%25 = OpLabel\n%16 = OpLoad %5 %15\n%17 = OpCompositeInsert %6 %16 %18 0\n%19 = OpCompositeInsert %6 %16 %17 1\n%20 = OpCompositeInsert %6 %16 %19 2\n%22 = OpInBoundsAccessChain %21 %9 %24\nOpStore %22 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/render-target-sample-count.frag",
    "content": "#version 460\n\nlayout(constant_id = 0) const uint _10 = 1u;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _11 = float(_10);\n    SV_Target.x = _11;\n    SV_Target.y = _11;\n    SV_Target.z = _11;\n    SV_Target.w = _11;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 SpecId 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpSpecConstant %9 1\n%12 = OpTypePointer Output %5\n%14 = OpConstant %9 0\n%16 = OpConstant %9 1\n%18 = OpConstant %9 2\n%20 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %21\n%21 = OpLabel\n%11 = OpConvertUToF %5 %10\n%13 = OpAccessChain %12 %8 %14\nOpStore %13 %11\n%15 = OpAccessChain %12 %8 %16\nOpStore %15 %11\n%17 = OpAccessChain %12 %8 %18\nOpStore %17 %11\n%19 = OpAccessChain %12 %8 %20\nOpStore %19 %11\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/render-target-sample-position.frag",
    "content": "#version 460\n\nlayout(constant_id = 0) const uint _13 = 1u;\nconst vec2 _63[31] = vec2[](vec2(0.0), vec2(0.25), vec2(-0.25), vec2(-0.125, -0.375), vec2(0.375, -0.125), vec2(-0.375, 0.125), vec2(0.125, 0.375), vec2(0.0625, -0.1875), vec2(-0.0625, 0.1875), vec2(0.3125, 0.0625), vec2(-0.1875, -0.3125), vec2(-0.3125, 0.3125), vec2(-0.4375, -0.0625), vec2(0.1875, 0.4375), vec2(0.4375, -0.4375), vec2(0.0625), vec2(-0.0625, -0.1875), vec2(-0.1875, 0.125), vec2(0.25, -0.0625), vec2(-0.3125, -0.125), vec2(0.125, 0.3125), vec2(0.3125, 0.1875), vec2(0.1875, -0.3125), vec2(-0.125, 0.375), vec2(0.0, -0.4375), vec2(-0.25, -0.375), vec2(-0.375, 0.25), vec2(-0.5, 0.0), vec2(0.4375, -0.25), vec2(0.375, 0.4375), vec2(-0.4375, -0.5));\n\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _66 = _13 - 1u;\n    uint _74 = ((uint(gl_SampleID) < _13) && (_13 <= 16u)) ? (_66 + uint(gl_SampleID)) : 0u;\n    SV_Target.x = _63[_74].x;\n    SV_Target.y = _63[_74].y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 86\n; Schema: 0\nOpCapability Shader\nOpCapability SampleRateShading\nOpCapability ImageQuery\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_SampleIndex\"\nOpName %11 \"SV_Target\"\nOpName %65 \"Texture2DMSSamplePositionLUT\"\nOpDecorate %7 BuiltIn SampleId\nOpDecorate %7 Flat\nOpDecorate %11 Location 0\nOpDecorate %13 SpecId 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 2\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%13 = OpSpecConstant %5 1\n%14 = OpConstant %8 0\n%15 = OpConstantComposite %9 %14 %14\n%16 = OpConstant %8 0.25\n%17 = OpConstantComposite %9 %16 %16\n%18 = OpConstant %8 -0.25\n%19 = OpConstantComposite %9 %18 %18\n%20 = OpConstant %8 -0.125\n%21 = OpConstant %8 -0.375\n%22 = OpConstantComposite %9 %20 %21\n%23 = OpConstant %8 0.375\n%24 = OpConstantComposite %9 %23 %20\n%25 = OpConstant %8 0.125\n%26 = OpConstantComposite %9 %21 %25\n%27 = OpConstantComposite %9 %25 %23\n%28 = OpConstant %8 0.0625\n%29 = OpConstant %8 -0.1875\n%30 = OpConstantComposite %9 %28 %29\n%31 = OpConstant %8 -0.0625\n%32 = OpConstant %8 0.1875\n%33 = OpConstantComposite %9 %31 %32\n%34 = OpConstant %8 0.3125\n%35 = OpConstantComposite %9 %34 %28\n%36 = OpConstant %8 -0.3125\n%37 = OpConstantComposite %9 %29 %36\n%38 = OpConstantComposite %9 %36 %34\n%39 = OpConstant %8 -0.4375\n%40 = OpConstantComposite %9 %39 %31\n%41 = OpConstant %8 0.4375\n%42 = OpConstantComposite %9 %32 %41\n%43 = OpConstantComposite %9 %41 %39\n%44 = OpConstantComposite %9 %28 %28\n%45 = OpConstantComposite %9 %31 %29\n%46 = OpConstantComposite %9 %29 %25\n%47 = OpConstantComposite %9 %16 %31\n%48 = OpConstantComposite %9 %36 %20\n%49 = OpConstantComposite %9 %25 %34\n%50 = OpConstantComposite %9 %34 %32\n%51 = OpConstantComposite %9 %32 %36\n%52 = OpConstantComposite %9 %20 %23\n%53 = OpConstantComposite %9 %14 %39\n%54 = OpConstantComposite %9 %18 %21\n%55 = OpConstantComposite %9 %21 %16\n%56 = OpConstant %8 -0.5\n%57 = OpConstantComposite %9 %56 %14\n%58 = OpConstantComposite %9 %41 %18\n%59 = OpConstantComposite %9 %23 %41\n%60 = OpConstantComposite %9 %39 %56\n%61 = OpConstant %5 31\n%62 = OpTypeArray %9 %61\n%63 = OpConstantComposite %62 %15 %17 %19 %22 %24 %26 %27 %30 %33 %35 %37 %38 %40 %42 %43 %44 %45 %46 %47 %48 %49 %50 %51 %52 %53 %54 %55 %57 %58 %59 %60\n%64 = OpTypePointer Private %62\n%65 = OpVariable %64 Private %63\n%67 = OpConstant %5 1\n%69 = OpTypeBool\n%72 = OpConstant %5 16\n%75 = OpConstant %5 0\n%76 = OpTypePointer Private %9\n%81 = OpTypePointer Output %8\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %84\n%84 = OpLabel\n%12 = OpLoad %5 %7\n%66 = OpISub %5 %13 %67\n%68 = OpIAdd %5 %66 %12\n%70 = OpULessThan %69 %12 %13\n%71 = OpULessThanEqual %69 %13 %72\n%73 = OpLogicalAnd %69 %70 %71\n%74 = OpSelect %5 %73 %68 %75\n%77 = OpAccessChain %76 %65 %74\n%78 = OpLoad %9 %77\n%79 = OpCompositeExtract %8 %78 0\n%80 = OpCompositeExtract %8 %78 1\n%82 = OpAccessChain %81 %11 %75\nOpStore %82 %79\n%83 = OpAccessChain %81 %11 %67\nOpStore %83 %80\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/report-hit.rint",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    float _m0;\n};\n\nhitAttributeEXT _6 hit;\n\nvoid main()\n{\n    float _14 = gl_RayTmaxEXT;\n    _6 _11;\n    _11._m0 = _14;\n    hit = _11;\n    bool _23 = reportIntersectionEXT(4.0, 100u);\n    _6 _10;\n    _10._m0 = gl_RayTminEXT;\n    hit = _10;\n    bool _28 = reportIntersectionEXT(3.0, 50u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint IntersectionKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"hit\"\nOpDecorate %13 BuiltIn RayTmaxKHR\nOpDecorate %13 Volatile\nOpDecorate %15 BuiltIn RayTminKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeStruct %5\n%7 = OpTypePointer HitAttributeKHR %6\n%8 = OpVariable %7 HitAttributeKHR\n%9 = OpTypePointer Function %6\n%12 = OpTypePointer Input %5\n%13 = OpVariable %12 Input\n%15 = OpVariable %12 Input\n%17 = OpTypePointer Function %5\n%19 = OpTypeInt 32 0\n%20 = OpConstant %19 0\n%22 = OpTypeBool\n%24 = OpConstant %5 4\n%25 = OpConstant %19 100\n%29 = OpConstant %5 3\n%30 = OpConstant %19 50\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%10 = OpVariable %9 Function\n%11 = OpVariable %9 Function\nOpBranch %31\n%31 = OpLabel\n%14 = OpLoad %5 %13\n%16 = OpLoad %5 %15\n%18 = OpInBoundsAccessChain %17 %11 %20\nOpStore %18 %14\n%21 = OpLoad %6 %11\nOpStore %8 %21\n%23 = OpReportIntersectionKHR %22 %24 %25\n%26 = OpInBoundsAccessChain %17 %10 %20\nOpStore %26 %16\n%27 = OpLoad %6 %10\nOpStore %8 %27\n%28 = OpReportIntersectionKHR %22 %29 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/round-ne.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = roundEven(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 RoundEven %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/round-ni.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = floor(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Floor %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/round-pi.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = ceil(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Ceil %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/round-z.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = trunc(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Trunc %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/rsqrt.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = inversesqrt(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 InverseSqrt %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/rt-geometry-index.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    uint _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = gl_BuiltIn_5352;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn RayGeometryIndexKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer IncomingRayPayloadKHR %5\n%19 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%16 = OpLoad %5 %15\n%18 = OpInBoundsAccessChain %17 %8 %19\nOpStore %18 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/rt-hit-kind.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    uint _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = gl_HitKindEXT;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn HitKindKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer IncomingRayPayloadKHR %5\n%19 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%16 = OpLoad %5 %15\n%18 = OpInBoundsAccessChain %17 %8 %19\nOpStore %18 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/rt-instance-id.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    uint _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = uint(gl_InstanceCustomIndexEXT);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn InstanceCustomIndexKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer IncomingRayPayloadKHR %5\n%19 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%16 = OpLoad %5 %15\n%18 = OpInBoundsAccessChain %17 %8 %19\nOpStore %18 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/rt-instance-index.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    uint _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = uint(gl_InstanceID);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn InstanceId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer IncomingRayPayloadKHR %5\n%19 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%16 = OpLoad %5 %15\n%18 = OpInBoundsAccessChain %17 %8 %19\nOpStore %18 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/rt-primitive-index.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    uint _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = uint(gl_PrimitiveID);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn PrimitiveId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer IncomingRayPayloadKHR %5\n%19 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%16 = OpLoad %5 %15\n%18 = OpInBoundsAccessChain %17 %8 %19\nOpStore %18 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/rt-ray-flags.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    uint _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = gl_IncomingRayFlagsEXT;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn IncomingRayFlagsKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer IncomingRayPayloadKHR %5\n%19 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%16 = OpLoad %5 %15\n%18 = OpInBoundsAccessChain %17 %8 %19\nOpStore %18 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-bias-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _70\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 1, binding = 5) uniform textureCube _23;\nlayout(set = 1, binding = 6) uniform textureCubeArray _26;\nlayout(set = 0, binding = 0) uniform sampler _29;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _204;\n    vec4 _205;\n    _204 = sparseTextureClampARB(sampler1D(_8, _29), TEXCOORD.x, 1.5, _205, 0.0);\n    SparseTexel _63 = SparseTexel(_204, _205);\n    vec4 _65 = _63._m1;\n    _70 _71 = _70(_65.x, _65.y, _65.z, _65.w, _63._m0);\n    float _77 = float(sparseTexelsResidentARB(int(_71._m4)));\n    uint _206;\n    vec4 _207;\n    _206 = sparseTextureClampARB(sampler1DArray(_11, _29), vec2(TEXCOORD.x, TEXCOORD.y), 1.5, _207, 0.0);\n    SparseTexel _83 = SparseTexel(_206, _207);\n    vec4 _86 = _83._m1;\n    _70 _91 = _70(_86.x, _86.y, _86.z, _86.w, _83._m0);\n    float _92 = _91._m0;\n    float _97 = float(sparseTexelsResidentARB(int(_91._m4)));\n    uint _208;\n    vec4 _209;\n    _208 = sparseTextureClampARB(sampler2D(_14, _29), vec2(TEXCOORD.x, TEXCOORD.y), 1.5, _209, 0.0);\n    SparseTexel _102 = SparseTexel(_208, _209);\n    vec4 _105 = _102._m1;\n    _70 _110 = _70(_105.x, _105.y, _105.z, _105.w, _102._m0);\n    float _117 = float(sparseTexelsResidentARB(int(_110._m4)));\n    uint _210;\n    vec4 _211;\n    _210 = sparseTextureClampARB(sampler2DArray(_17, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), 1.5, _211, 0.0);\n    SparseTexel _122 = SparseTexel(_210, _211);\n    vec4 _126 = _122._m1;\n    _70 _131 = _70(_126.x, _126.y, _126.z, _126.w, _122._m0);\n    float _132 = _131._m0;\n    float _137 = float(sparseTexelsResidentARB(int(_131._m4)));\n    uint _212;\n    vec4 _213;\n    _212 = sparseTextureClampARB(sampler3D(_20, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), 1.5, _213, 0.0);\n    SparseTexel _142 = SparseTexel(_212, _213);\n    vec4 _145 = _142._m1;\n    _70 _150 = _70(_145.x, _145.y, _145.z, _145.w, _142._m0);\n    float _157 = float(sparseTexelsResidentARB(int(_150._m4)));\n    uint _214;\n    vec4 _215;\n    _214 = sparseTextureClampARB(samplerCube(_23, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), 1.5, _215, 0.0);\n    SparseTexel _162 = SparseTexel(_214, _215);\n    vec4 _165 = _162._m1;\n    _70 _170 = _70(_165.x, _165.y, _165.z, _165.w, _162._m0);\n    float _177 = float(sparseTexelsResidentARB(int(_170._m4)));\n    uint _216;\n    vec4 _217;\n    _216 = sparseTextureClampARB(samplerCubeArray(_26, _29), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w), 1.5, _217, 0.0);\n    SparseTexel _182 = SparseTexel(_216, _217);\n    vec4 _185 = _182._m1;\n    _70 _190 = _70(_185.x, _185.y, _185.z, _185.w, _182._m0);\n    float _191 = _190._m0;\n    float _196 = float(sparseTexelsResidentARB(int(_190._m4)));\n    SV_Target.x = ((((((((((((_77 + _71._m0) + _92) + _97) + _110._m0) + _117) + _132) + _137) + _150._m0) + _157) + _170._m0) + _177) + _191) + _196;\n    SV_Target.y = ((((((((((((_77 + _71._m1) + _92) + _97) + _110._m1) + _117) + _132) + _137) + _150._m1) + _157) + _170._m1) + _177) + _191) + _196;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 204\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability MinLod\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpName %62 \"SparseTexel\"\nOpName %70 \"\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeSampler\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeVector %5 4\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%44 = OpTypePointer Input %5\n%46 = OpTypeInt 32 0\n%47 = OpConstant %46 0\n%50 = OpConstant %46 1\n%53 = OpConstant %46 2\n%56 = OpConstant %46 3\n%58 = OpTypeSampledImage %6\n%60 = OpConstant %5 1.5\n%61 = OpConstant %5 0\n%62 = OpTypeStruct %46 %30\n%70 = OpTypeStruct %5 %5 %5 %5 %46\n%75 = OpTypeBool\n%78 = OpConstant %5 1\n%81 = OpTypeSampledImage %9\n%100 = OpTypeSampledImage %12\n%120 = OpTypeSampledImage %15\n%123 = OpTypeVector %5 3\n%140 = OpTypeSampledImage %18\n%160 = OpTypeSampledImage %21\n%180 = OpTypeSampledImage %24\n%199 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %202\n%202 = OpLabel\n%36 = OpLoad %24 %26\n%37 = OpLoad %21 %23\n%38 = OpLoad %18 %20\n%39 = OpLoad %15 %17\n%40 = OpLoad %12 %14\n%41 = OpLoad %9 %11\n%42 = OpLoad %6 %8\n%43 = OpLoad %27 %29\n%45 = OpAccessChain %44 %32 %47\n%48 = OpLoad %5 %45\n%49 = OpAccessChain %44 %32 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %44 %32 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %44 %32 %56\n%57 = OpLoad %5 %55\n%59 = OpSampledImage %58 %42 %43\n%63 = OpImageSparseSampleImplicitLod %62 %59 %48 Bias|MinLod %61 %60\n%64 = OpCompositeExtract %46 %63 0\n%65 = OpCompositeExtract %30 %63 1\n%66 = OpCompositeExtract %5 %65 0\n%67 = OpCompositeExtract %5 %65 1\n%68 = OpCompositeExtract %5 %65 2\n%69 = OpCompositeExtract %5 %65 3\n%71 = OpCompositeConstruct %70 %66 %67 %68 %69 %64\n%72 = OpCompositeExtract %5 %71 0\n%73 = OpCompositeExtract %5 %71 1\n%74 = OpCompositeExtract %46 %71 4\n%76 = OpImageSparseTexelsResident %75 %74\n%77 = OpSelect %5 %76 %78 %61\n%79 = OpFAdd %5 %77 %72\n%80 = OpFAdd %5 %77 %73\n%82 = OpSampledImage %81 %41 %43\n%84 = OpCompositeConstruct %33 %48 %51\n%83 = OpImageSparseSampleImplicitLod %62 %82 %84 Bias|MinLod %61 %60\n%85 = OpCompositeExtract %46 %83 0\n%86 = OpCompositeExtract %30 %83 1\n%87 = OpCompositeExtract %5 %86 0\n%88 = OpCompositeExtract %5 %86 1\n%89 = OpCompositeExtract %5 %86 2\n%90 = OpCompositeExtract %5 %86 3\n%91 = OpCompositeConstruct %70 %87 %88 %89 %90 %85\n%92 = OpCompositeExtract %5 %91 0\n%93 = OpCompositeExtract %46 %91 4\n%94 = OpImageSparseTexelsResident %75 %93\n%95 = OpFAdd %5 %79 %92\n%96 = OpFAdd %5 %80 %92\n%97 = OpSelect %5 %94 %78 %61\n%98 = OpFAdd %5 %95 %97\n%99 = OpFAdd %5 %96 %97\n%101 = OpSampledImage %100 %40 %43\n%103 = OpCompositeConstruct %33 %48 %51\n%102 = OpImageSparseSampleImplicitLod %62 %101 %103 Bias|MinLod %61 %60\n%104 = OpCompositeExtract %46 %102 0\n%105 = OpCompositeExtract %30 %102 1\n%106 = OpCompositeExtract %5 %105 0\n%107 = OpCompositeExtract %5 %105 1\n%108 = OpCompositeExtract %5 %105 2\n%109 = OpCompositeExtract %5 %105 3\n%110 = OpCompositeConstruct %70 %106 %107 %108 %109 %104\n%111 = OpCompositeExtract %5 %110 0\n%112 = OpCompositeExtract %5 %110 1\n%113 = OpCompositeExtract %46 %110 4\n%114 = OpImageSparseTexelsResident %75 %113\n%115 = OpFAdd %5 %98 %111\n%116 = OpFAdd %5 %99 %112\n%117 = OpSelect %5 %114 %78 %61\n%118 = OpFAdd %5 %115 %117\n%119 = OpFAdd %5 %116 %117\n%121 = OpSampledImage %120 %39 %43\n%124 = OpCompositeConstruct %123 %48 %51 %54\n%122 = OpImageSparseSampleImplicitLod %62 %121 %124 Bias|MinLod %61 %60\n%125 = OpCompositeExtract %46 %122 0\n%126 = OpCompositeExtract %30 %122 1\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpCompositeExtract %5 %126 1\n%129 = OpCompositeExtract %5 %126 2\n%130 = OpCompositeExtract %5 %126 3\n%131 = OpCompositeConstruct %70 %127 %128 %129 %130 %125\n%132 = OpCompositeExtract %5 %131 0\n%133 = OpCompositeExtract %46 %131 4\n%134 = OpImageSparseTexelsResident %75 %133\n%135 = OpFAdd %5 %118 %132\n%136 = OpFAdd %5 %119 %132\n%137 = OpSelect %5 %134 %78 %61\n%138 = OpFAdd %5 %135 %137\n%139 = OpFAdd %5 %136 %137\n%141 = OpSampledImage %140 %38 %43\n%143 = OpCompositeConstruct %123 %48 %51 %54\n%142 = OpImageSparseSampleImplicitLod %62 %141 %143 Bias|MinLod %61 %60\n%144 = OpCompositeExtract %46 %142 0\n%145 = OpCompositeExtract %30 %142 1\n%146 = OpCompositeExtract %5 %145 0\n%147 = OpCompositeExtract %5 %145 1\n%148 = OpCompositeExtract %5 %145 2\n%149 = OpCompositeExtract %5 %145 3\n%150 = OpCompositeConstruct %70 %146 %147 %148 %149 %144\n%151 = OpCompositeExtract %5 %150 0\n%152 = OpCompositeExtract %5 %150 1\n%153 = OpCompositeExtract %46 %150 4\n%154 = OpImageSparseTexelsResident %75 %153\n%155 = OpFAdd %5 %138 %151\n%156 = OpFAdd %5 %139 %152\n%157 = OpSelect %5 %154 %78 %61\n%158 = OpFAdd %5 %155 %157\n%159 = OpFAdd %5 %156 %157\n%161 = OpSampledImage %160 %37 %43\n%163 = OpCompositeConstruct %123 %48 %51 %54\n%162 = OpImageSparseSampleImplicitLod %62 %161 %163 Bias|MinLod %61 %60\n%164 = OpCompositeExtract %46 %162 0\n%165 = OpCompositeExtract %30 %162 1\n%166 = OpCompositeExtract %5 %165 0\n%167 = OpCompositeExtract %5 %165 1\n%168 = OpCompositeExtract %5 %165 2\n%169 = OpCompositeExtract %5 %165 3\n%170 = OpCompositeConstruct %70 %166 %167 %168 %169 %164\n%171 = OpCompositeExtract %5 %170 0\n%172 = OpCompositeExtract %5 %170 1\n%173 = OpCompositeExtract %46 %170 4\n%174 = OpImageSparseTexelsResident %75 %173\n%175 = OpFAdd %5 %158 %171\n%176 = OpFAdd %5 %159 %172\n%177 = OpSelect %5 %174 %78 %61\n%178 = OpFAdd %5 %175 %177\n%179 = OpFAdd %5 %176 %177\n%181 = OpSampledImage %180 %36 %43\n%183 = OpCompositeConstruct %30 %48 %51 %54 %57\n%182 = OpImageSparseSampleImplicitLod %62 %181 %183 Bias|MinLod %61 %60\n%184 = OpCompositeExtract %46 %182 0\n%185 = OpCompositeExtract %30 %182 1\n%186 = OpCompositeExtract %5 %185 0\n%187 = OpCompositeExtract %5 %185 1\n%188 = OpCompositeExtract %5 %185 2\n%189 = OpCompositeExtract %5 %185 3\n%190 = OpCompositeConstruct %70 %186 %187 %188 %189 %184\n%191 = OpCompositeExtract %5 %190 0\n%192 = OpCompositeExtract %46 %190 4\n%193 = OpImageSparseTexelsResident %75 %192\n%194 = OpFAdd %5 %178 %191\n%195 = OpFAdd %5 %179 %191\n%196 = OpSelect %5 %193 %78 %61\n%197 = OpFAdd %5 %194 %196\n%198 = OpFAdd %5 %195 %196\n%200 = OpAccessChain %199 %35 %47\nOpStore %200 %197\n%201 = OpAccessChain %199 %35 %50\nOpStore %201 %198\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-bias-offset.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _54 = textureOffset(sampler1D(_8, _23), TEXCOORD.x, 1, TEXCOORD.w);\n    vec4 _66 = textureOffset(sampler2D(_14, _23), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(2, 3), TEXCOORD.w);\n    vec4 _85 = textureOffset(sampler3D(_20, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec3(-4, -5, 3), TEXCOORD.w);\n    float _91 = textureOffset(sampler2DArray(_17, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec2(-1, -3), TEXCOORD.w).x + textureOffset(sampler1DArray(_11, _23), vec2(TEXCOORD.x, TEXCOORD.y), 2, TEXCOORD.w).x;\n    SV_Target.x = ((_66.x + _54.x) + _91) + _85.x;\n    SV_Target.y = ((_66.y + _54.y) + _91) + _85.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 103\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypeVector %5 2\n%28 = OpTypePointer Output %27\n%29 = OpVariable %28 Output\n%36 = OpTypePointer Input %5\n%38 = OpTypeInt 32 0\n%39 = OpConstant %38 0\n%42 = OpConstant %38 1\n%45 = OpConstant %38 2\n%48 = OpConstant %38 3\n%50 = OpTypeSampledImage %6\n%52 = OpTypeInt 32 1\n%53 = OpConstant %52 1\n%57 = OpTypeSampledImage %9\n%59 = OpConstant %52 2\n%63 = OpTypeSampledImage %12\n%65 = OpConstant %52 3\n%68 = OpTypeVector %52 2\n%69 = OpConstantComposite %68 %59 %65\n%72 = OpTypeSampledImage %15\n%74 = OpConstant %52 -1\n%75 = OpConstant %52 -3\n%77 = OpTypeVector %5 3\n%79 = OpConstantComposite %68 %74 %75\n%81 = OpTypeSampledImage %18\n%83 = OpConstant %52 -4\n%84 = OpConstant %52 -5\n%87 = OpTypeVector %52 3\n%88 = OpConstantComposite %87 %83 %84 %65\n%98 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %101\n%101 = OpLabel\n%30 = OpLoad %18 %20\n%31 = OpLoad %15 %17\n%32 = OpLoad %12 %14\n%33 = OpLoad %9 %11\n%34 = OpLoad %6 %8\n%35 = OpLoad %21 %23\n%37 = OpAccessChain %36 %26 %39\n%40 = OpLoad %5 %37\n%41 = OpAccessChain %36 %26 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %36 %26 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %36 %26 %48\n%49 = OpLoad %5 %47\n%51 = OpSampledImage %50 %34 %35\n%54 = OpImageSampleImplicitLod %24 %51 %40 Bias|ConstOffset %49 %53\n%55 = OpCompositeExtract %5 %54 0\n%56 = OpCompositeExtract %5 %54 1\n%58 = OpSampledImage %57 %33 %35\n%61 = OpCompositeConstruct %27 %40 %43\n%60 = OpImageSampleImplicitLod %24 %58 %61 Bias|ConstOffset %49 %59\n%62 = OpCompositeExtract %5 %60 0\n%64 = OpSampledImage %63 %32 %35\n%67 = OpCompositeConstruct %27 %40 %43\n%66 = OpImageSampleImplicitLod %24 %64 %67 Bias|ConstOffset %49 %69\n%70 = OpCompositeExtract %5 %66 0\n%71 = OpCompositeExtract %5 %66 1\n%73 = OpSampledImage %72 %31 %35\n%78 = OpCompositeConstruct %77 %40 %43 %46\n%76 = OpImageSampleImplicitLod %24 %73 %78 Bias|ConstOffset %49 %79\n%80 = OpCompositeExtract %5 %76 0\n%82 = OpSampledImage %81 %30 %35\n%86 = OpCompositeConstruct %77 %40 %43 %46\n%85 = OpImageSampleImplicitLod %24 %82 %86 Bias|ConstOffset %49 %88\n%89 = OpCompositeExtract %5 %85 0\n%90 = OpCompositeExtract %5 %85 1\n%91 = OpFAdd %5 %80 %62\n%92 = OpFAdd %5 %70 %55\n%93 = OpFAdd %5 %92 %91\n%94 = OpFAdd %5 %93 %89\n%95 = OpFAdd %5 %71 %56\n%96 = OpFAdd %5 %95 %91\n%97 = OpFAdd %5 %96 %90\n%99 = OpAccessChain %98 %29 %39\nOpStore %99 %94\n%100 = OpAccessChain %98 %29 %42\nOpStore %100 %97\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-bias.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 1, binding = 5) uniform textureCube _23;\nlayout(set = 1, binding = 6) uniform textureCubeArray _26;\nlayout(set = 0, binding = 0) uniform sampler _29;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _60 = texture(sampler1D(_8, _29), TEXCOORD.x, TEXCOORD.w);\n    vec4 _70 = texture(sampler2D(_14, _29), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w);\n    vec4 _82 = texture(sampler3D(_20, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w);\n    vec4 _88 = texture(samplerCube(_23, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w);\n    float _98 = texture(samplerCubeArray(_26, _29), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w), TEXCOORD.w).x + (texture(sampler2DArray(_17, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w).x + texture(sampler1DArray(_11, _29), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w).x);\n    SV_Target.x = (((_98 + _60.x) + _70.x) + _82.x) + _88.x;\n    SV_Target.y = (((_98 + _60.y) + _70.y) + _82.y) + _88.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 112\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeSampler\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeVector %5 4\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%44 = OpTypePointer Input %5\n%46 = OpTypeInt 32 0\n%47 = OpConstant %46 0\n%50 = OpConstant %46 1\n%53 = OpConstant %46 2\n%56 = OpConstant %46 3\n%58 = OpTypeSampledImage %6\n%63 = OpTypeSampledImage %9\n%68 = OpTypeSampledImage %12\n%74 = OpTypeSampledImage %15\n%77 = OpTypeVector %5 3\n%80 = OpTypeSampledImage %18\n%86 = OpTypeSampledImage %21\n%92 = OpTypeSampledImage %24\n%107 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%36 = OpLoad %24 %26\n%37 = OpLoad %21 %23\n%38 = OpLoad %18 %20\n%39 = OpLoad %15 %17\n%40 = OpLoad %12 %14\n%41 = OpLoad %9 %11\n%42 = OpLoad %6 %8\n%43 = OpLoad %27 %29\n%45 = OpAccessChain %44 %32 %47\n%48 = OpLoad %5 %45\n%49 = OpAccessChain %44 %32 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %44 %32 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %44 %32 %56\n%57 = OpLoad %5 %55\n%59 = OpSampledImage %58 %42 %43\n%60 = OpImageSampleImplicitLod %30 %59 %48 Bias %57\n%61 = OpCompositeExtract %5 %60 0\n%62 = OpCompositeExtract %5 %60 1\n%64 = OpSampledImage %63 %41 %43\n%66 = OpCompositeConstruct %33 %48 %51\n%65 = OpImageSampleImplicitLod %30 %64 %66 Bias %57\n%67 = OpCompositeExtract %5 %65 0\n%69 = OpSampledImage %68 %40 %43\n%71 = OpCompositeConstruct %33 %48 %51\n%70 = OpImageSampleImplicitLod %30 %69 %71 Bias %57\n%72 = OpCompositeExtract %5 %70 0\n%73 = OpCompositeExtract %5 %70 1\n%75 = OpSampledImage %74 %39 %43\n%78 = OpCompositeConstruct %77 %48 %51 %54\n%76 = OpImageSampleImplicitLod %30 %75 %78 Bias %57\n%79 = OpCompositeExtract %5 %76 0\n%81 = OpSampledImage %80 %38 %43\n%83 = OpCompositeConstruct %77 %48 %51 %54\n%82 = OpImageSampleImplicitLod %30 %81 %83 Bias %57\n%84 = OpCompositeExtract %5 %82 0\n%85 = OpCompositeExtract %5 %82 1\n%87 = OpSampledImage %86 %37 %43\n%89 = OpCompositeConstruct %77 %48 %51 %54\n%88 = OpImageSampleImplicitLod %30 %87 %89 Bias %57\n%90 = OpCompositeExtract %5 %88 0\n%91 = OpCompositeExtract %5 %88 1\n%93 = OpSampledImage %92 %36 %43\n%95 = OpCompositeConstruct %30 %48 %51 %54 %57\n%94 = OpImageSampleImplicitLod %30 %93 %95 Bias %57\n%96 = OpCompositeExtract %5 %94 0\n%97 = OpFAdd %5 %79 %67\n%98 = OpFAdd %5 %96 %97\n%99 = OpFAdd %5 %98 %61\n%100 = OpFAdd %5 %99 %72\n%101 = OpFAdd %5 %100 %84\n%102 = OpFAdd %5 %101 %90\n%103 = OpFAdd %5 %98 %62\n%104 = OpFAdd %5 %103 %73\n%105 = OpFAdd %5 %104 %85\n%106 = OpFAdd %5 %105 %91\n%108 = OpAccessChain %107 %35 %47\nOpStore %108 %102\n%109 = OpAccessChain %107 %35 %50\nOpStore %109 %106\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-bias-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    float _m1;\n};\n\nstruct _57\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 5) uniform textureCube _20;\nlayout(set = 0, binding = 0) uniform samplerShadow _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) in float DREF;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    uint _126;\n    float _127;\n    _126 = sparseTextureClampARB(sampler1DShadow(_8, _23), vec2(TEXCOORD.x, DREF), 1.5, _127, 0.0);\n    SparseTexel _54 = SparseTexel(_126, _127);\n    float _56 = _54._m1;\n    _57 _58 = _57(_56, _56, _56, _56, _54._m0);\n    uint _128;\n    float _129;\n    _128 = sparseTextureClampARB(sampler1DArrayShadow(_11, _23), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), 1.5, _129, 0.0);\n    SparseTexel _69 = SparseTexel(_128, _129);\n    float _73 = _69._m1;\n    _57 _74 = _57(_73, _73, _73, _73, _69._m0);\n    uint _130;\n    float _131;\n    _130 = sparseTextureClampARB(sampler2DShadow(_14, _23), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), 1.5, _131, 0.0);\n    SparseTexel _84 = SparseTexel(_130, _131);\n    float _87 = _84._m1;\n    _57 _88 = _57(_87, _87, _87, _87, _84._m0);\n    uint _132;\n    float _133;\n    _132 = sparseTextureClampARB(sampler2DArrayShadow(_17, _23), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), 1.5, _133, 0.0);\n    SparseTexel _98 = SparseTexel(_132, _133);\n    float _102 = _98._m1;\n    _57 _103 = _57(_102, _102, _102, _102, _98._m0);\n    uint _134;\n    float _135;\n    _134 = sparseTextureClampARB(samplerCubeShadow(_20, _23), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), 1.5, _135, 0.0);\n    SparseTexel _113 = SparseTexel(_134, _135);\n    float _116 = _113._m1;\n    _57 _117 = _57(_116, _116, _116, _116, _113._m0);\n    SV_Target = ((((((((float(sparseTexelsResidentARB(int(_58._m4))) + _58._m0) + _74._m0) + float(sparseTexelsResidentARB(int(_74._m4)))) + _88._m0) + float(sparseTexelsResidentARB(int(_88._m4)))) + _103._m0) + float(sparseTexelsResidentARB(int(_103._m4)))) + _117._m0) + float(sparseTexelsResidentARB(int(_117._m4)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 126\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability MinLod\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %28 %30\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %28 \"DREF\"\nOpName %30 \"SV_Target\"\nOpName %53 \"SparseTexel\"\nOpName %57 \"\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %28 Location 1\nOpDecorate %30 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypePointer Input %5\n%28 = OpVariable %27 Input\n%29 = OpTypePointer Output %5\n%30 = OpVariable %29 Output\n%39 = OpTypeInt 32 0\n%40 = OpConstant %39 0\n%43 = OpConstant %39 1\n%46 = OpConstant %39 2\n%48 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%49 = OpTypeSampledImage %48\n%51 = OpConstant %5 1.5\n%52 = OpConstant %5 0\n%53 = OpTypeStruct %39 %5\n%57 = OpTypeStruct %5 %5 %5 %5 %39\n%61 = OpTypeBool\n%64 = OpConstant %5 1\n%66 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%67 = OpTypeSampledImage %66\n%70 = OpTypeVector %5 2\n%81 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%82 = OpTypeSampledImage %81\n%95 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%96 = OpTypeSampledImage %95\n%99 = OpTypeVector %5 3\n%110 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%111 = OpTypeSampledImage %110\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %124\n%124 = OpLabel\n%31 = OpLoad %18 %20\n%32 = OpLoad %15 %17\n%33 = OpLoad %12 %14\n%34 = OpLoad %9 %11\n%35 = OpLoad %6 %8\n%36 = OpLoad %21 %23\n%37 = OpLoad %5 %28\n%38 = OpAccessChain %27 %26 %40\n%41 = OpLoad %5 %38\n%42 = OpAccessChain %27 %26 %43\n%44 = OpLoad %5 %42\n%45 = OpAccessChain %27 %26 %46\n%47 = OpLoad %5 %45\n%50 = OpSampledImage %49 %35 %36\n%54 = OpImageSparseSampleDrefImplicitLod %53 %50 %41 %37 Bias|MinLod %52 %51\n%55 = OpCompositeExtract %39 %54 0\n%56 = OpCompositeExtract %5 %54 1\n%58 = OpCompositeConstruct %57 %56 %56 %56 %56 %55\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpCompositeExtract %39 %58 4\n%62 = OpImageSparseTexelsResident %61 %60\n%63 = OpSelect %5 %62 %64 %52\n%65 = OpFAdd %5 %63 %59\n%68 = OpSampledImage %67 %34 %36\n%71 = OpCompositeConstruct %70 %41 %44\n%69 = OpImageSparseSampleDrefImplicitLod %53 %68 %71 %37 Bias|MinLod %52 %51\n%72 = OpCompositeExtract %39 %69 0\n%73 = OpCompositeExtract %5 %69 1\n%74 = OpCompositeConstruct %57 %73 %73 %73 %73 %72\n%75 = OpCompositeExtract %5 %74 0\n%76 = OpCompositeExtract %39 %74 4\n%77 = OpImageSparseTexelsResident %61 %76\n%78 = OpFAdd %5 %65 %75\n%79 = OpSelect %5 %77 %64 %52\n%80 = OpFAdd %5 %78 %79\n%83 = OpSampledImage %82 %33 %36\n%85 = OpCompositeConstruct %70 %41 %44\n%84 = OpImageSparseSampleDrefImplicitLod %53 %83 %85 %37 Bias|MinLod %52 %51\n%86 = OpCompositeExtract %39 %84 0\n%87 = OpCompositeExtract %5 %84 1\n%88 = OpCompositeConstruct %57 %87 %87 %87 %87 %86\n%89 = OpCompositeExtract %5 %88 0\n%90 = OpCompositeExtract %39 %88 4\n%91 = OpImageSparseTexelsResident %61 %90\n%92 = OpFAdd %5 %80 %89\n%93 = OpSelect %5 %91 %64 %52\n%94 = OpFAdd %5 %92 %93\n%97 = OpSampledImage %96 %32 %36\n%100 = OpCompositeConstruct %99 %41 %44 %47\n%98 = OpImageSparseSampleDrefImplicitLod %53 %97 %100 %37 Bias|MinLod %52 %51\n%101 = OpCompositeExtract %39 %98 0\n%102 = OpCompositeExtract %5 %98 1\n%103 = OpCompositeConstruct %57 %102 %102 %102 %102 %101\n%104 = OpCompositeExtract %5 %103 0\n%105 = OpCompositeExtract %39 %103 4\n%106 = OpImageSparseTexelsResident %61 %105\n%107 = OpFAdd %5 %94 %104\n%108 = OpSelect %5 %106 %64 %52\n%109 = OpFAdd %5 %107 %108\n%112 = OpSampledImage %111 %31 %36\n%114 = OpCompositeConstruct %99 %41 %44 %47\n%113 = OpImageSparseSampleDrefImplicitLod %53 %112 %114 %37 Bias|MinLod %52 %51\n%115 = OpCompositeExtract %39 %113 0\n%116 = OpCompositeExtract %5 %113 1\n%117 = OpCompositeConstruct %57 %116 %116 %116 %116 %115\n%118 = OpCompositeExtract %5 %117 0\n%119 = OpCompositeExtract %39 %117 4\n%120 = OpImageSparseTexelsResident %61 %119\n%121 = OpFAdd %5 %109 %118\n%122 = OpSelect %5 %120 %64 %52\n%123 = OpFAdd %5 %121 %122\nOpStore %30 %123\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-bias-offset.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 0) uniform samplerShadow _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) in float DREF;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = ((vec4(textureOffset(sampler1DArrayShadow(_11, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), 2, TEXCOORD.w)).x + vec4(textureOffset(sampler1DShadow(_8, _20), vec2(TEXCOORD.x, DREF), 1, TEXCOORD.w)).x) + vec4(textureOffset(sampler2DShadow(_14, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), ivec2(2, 3), TEXCOORD.w)).x) + vec4(textureOffset(sampler2DArrayShadow(_17, _20), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), ivec2(-1, -3), TEXCOORD.w)).x;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 90\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %25 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %25 \"DREF\"\nOpName %27 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %23 Location 0\nOpDecorate %25 Location 1\nOpDecorate %27 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypePointer Input %5\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Output %5\n%27 = OpVariable %26 Output\n%35 = OpTypeInt 32 0\n%36 = OpConstant %35 0\n%39 = OpConstant %35 1\n%42 = OpConstant %35 2\n%45 = OpConstant %35 3\n%47 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%48 = OpTypeSampledImage %47\n%50 = OpTypeInt 32 1\n%51 = OpConstant %50 1\n%55 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%56 = OpTypeSampledImage %55\n%58 = OpConstant %50 2\n%60 = OpTypeVector %5 2\n%65 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%66 = OpTypeSampledImage %65\n%68 = OpConstant %50 3\n%71 = OpTypeVector %50 2\n%72 = OpConstantComposite %71 %58 %68\n%76 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%77 = OpTypeSampledImage %76\n%79 = OpConstant %50 -1\n%80 = OpConstant %50 -3\n%82 = OpTypeVector %5 3\n%84 = OpConstantComposite %71 %79 %80\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %88\n%88 = OpLabel\n%28 = OpLoad %15 %17\n%29 = OpLoad %12 %14\n%30 = OpLoad %9 %11\n%31 = OpLoad %6 %8\n%32 = OpLoad %18 %20\n%33 = OpLoad %5 %25\n%34 = OpAccessChain %24 %23 %36\n%37 = OpLoad %5 %34\n%38 = OpAccessChain %24 %23 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %24 %23 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %24 %23 %45\n%46 = OpLoad %5 %44\n%49 = OpSampledImage %48 %31 %32\n%52 = OpImageSampleDrefImplicitLod %5 %49 %37 %33 Bias|ConstOffset %46 %51\n%53 = OpCompositeConstruct %21 %52 %52 %52 %52\n%54 = OpCompositeExtract %5 %53 0\n%57 = OpSampledImage %56 %30 %32\n%61 = OpCompositeConstruct %60 %37 %40\n%59 = OpImageSampleDrefImplicitLod %5 %57 %61 %33 Bias|ConstOffset %46 %58\n%62 = OpCompositeConstruct %21 %59 %59 %59 %59\n%63 = OpCompositeExtract %5 %62 0\n%64 = OpFAdd %5 %63 %54\n%67 = OpSampledImage %66 %29 %32\n%70 = OpCompositeConstruct %60 %37 %40\n%69 = OpImageSampleDrefImplicitLod %5 %67 %70 %33 Bias|ConstOffset %46 %72\n%73 = OpCompositeConstruct %21 %69 %69 %69 %69\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpFAdd %5 %64 %74\n%78 = OpSampledImage %77 %28 %32\n%83 = OpCompositeConstruct %82 %37 %40 %43\n%81 = OpImageSampleDrefImplicitLod %5 %78 %83 %33 Bias|ConstOffset %46 %84\n%85 = OpCompositeConstruct %21 %81 %81 %81 %81\n%86 = OpCompositeExtract %5 %85 0\n%87 = OpFAdd %5 %75 %86\nOpStore %27 %87\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-bias.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 5) uniform textureCube _20;\nlayout(set = 0, binding = 0) uniform samplerShadow _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) in float DREF;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (((vec4(texture(sampler1DArrayShadow(_11, _23), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), TEXCOORD.w)).x + vec4(texture(sampler1DShadow(_8, _23), vec2(TEXCOORD.x, DREF), TEXCOORD.w)).x) + vec4(texture(sampler2DShadow(_14, _23), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), TEXCOORD.w)).x) + vec4(texture(sampler2DArrayShadow(_17, _23), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), TEXCOORD.w)).x) + vec4(texture(samplerCubeShadow(_20, _23), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), TEXCOORD.w)).x;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 93\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %28 %30\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %28 \"DREF\"\nOpName %30 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %28 Location 1\nOpDecorate %30 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypePointer Input %5\n%28 = OpVariable %27 Input\n%29 = OpTypePointer Output %5\n%30 = OpVariable %29 Output\n%39 = OpTypeInt 32 0\n%40 = OpConstant %39 0\n%43 = OpConstant %39 1\n%46 = OpConstant %39 2\n%49 = OpConstant %39 3\n%51 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%52 = OpTypeSampledImage %51\n%57 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%58 = OpTypeSampledImage %57\n%61 = OpTypeVector %5 2\n%66 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%67 = OpTypeSampledImage %66\n%74 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%75 = OpTypeSampledImage %74\n%78 = OpTypeVector %5 3\n%83 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%84 = OpTypeSampledImage %83\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %91\n%91 = OpLabel\n%31 = OpLoad %18 %20\n%32 = OpLoad %15 %17\n%33 = OpLoad %12 %14\n%34 = OpLoad %9 %11\n%35 = OpLoad %6 %8\n%36 = OpLoad %21 %23\n%37 = OpLoad %5 %28\n%38 = OpAccessChain %27 %26 %40\n%41 = OpLoad %5 %38\n%42 = OpAccessChain %27 %26 %43\n%44 = OpLoad %5 %42\n%45 = OpAccessChain %27 %26 %46\n%47 = OpLoad %5 %45\n%48 = OpAccessChain %27 %26 %49\n%50 = OpLoad %5 %48\n%53 = OpSampledImage %52 %35 %36\n%54 = OpImageSampleDrefImplicitLod %5 %53 %41 %37 Bias %50\n%55 = OpCompositeConstruct %24 %54 %54 %54 %54\n%56 = OpCompositeExtract %5 %55 0\n%59 = OpSampledImage %58 %34 %36\n%62 = OpCompositeConstruct %61 %41 %44\n%60 = OpImageSampleDrefImplicitLod %5 %59 %62 %37 Bias %50\n%63 = OpCompositeConstruct %24 %60 %60 %60 %60\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpFAdd %5 %64 %56\n%68 = OpSampledImage %67 %33 %36\n%70 = OpCompositeConstruct %61 %41 %44\n%69 = OpImageSampleDrefImplicitLod %5 %68 %70 %37 Bias %50\n%71 = OpCompositeConstruct %24 %69 %69 %69 %69\n%72 = OpCompositeExtract %5 %71 0\n%73 = OpFAdd %5 %65 %72\n%76 = OpSampledImage %75 %32 %36\n%79 = OpCompositeConstruct %78 %41 %44 %47\n%77 = OpImageSampleDrefImplicitLod %5 %76 %79 %37 Bias %50\n%80 = OpCompositeConstruct %24 %77 %77 %77 %77\n%81 = OpCompositeExtract %5 %80 0\n%82 = OpFAdd %5 %73 %81\n%85 = OpSampledImage %84 %31 %36\n%87 = OpCompositeConstruct %78 %41 %44 %47\n%86 = OpImageSampleDrefImplicitLod %5 %85 %87 %37 Bias %50\n%88 = OpCompositeConstruct %24 %86 %86 %86 %86\n%89 = OpCompositeExtract %5 %88 0\n%90 = OpFAdd %5 %82 %89\nOpStore %30 %90\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    float _m1;\n};\n\nstruct _64\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 5) uniform textureCube _20;\nlayout(set = 1, binding = 6) uniform textureCubeArray _23;\nlayout(set = 0, binding = 0) uniform samplerShadow _26;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _152;\n    float _153;\n    _152 = sparseTextureOffsetARB(sampler1DShadow(_8, _26), vec2(TEXCOORD.x, TEXCOORD.w), 1, _153);\n    SparseTexel _61 = SparseTexel(_152, _153);\n    float _63 = _61._m1;\n    _64 _65 = _64(_63, _63, _63, _63, _61._m0);\n    uint _154;\n    float _155;\n    _154 = sparseTextureOffsetARB(sampler1DArrayShadow(_11, _26), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 2, _155);\n    SparseTexel _77 = SparseTexel(_154, _155);\n    float _80 = _77._m1;\n    _64 _81 = _64(_80, _80, _80, _80, _77._m0);\n    uint _156;\n    float _157;\n    _156 = sparseTextureOffsetARB(sampler2DShadow(_14, _26), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), ivec2(1, 2), _157);\n    SparseTexel _91 = SparseTexel(_156, _157);\n    float _96 = _91._m1;\n    _64 _97 = _64(_96, _96, _96, _96, _91._m0);\n    uint _158;\n    float _159;\n    _158 = sparseTextureOffsetARB(sampler2DArrayShadow(_17, _26), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w), ivec2(1, 2), _159);\n    SparseTexel _107 = SparseTexel(_158, _159);\n    float _111 = _107._m1;\n    _64 _112 = _64(_111, _111, _111, _111, _107._m0);\n    uint _160;\n    float _161;\n    _160 = sparseTextureARB(samplerCubeShadow(_20, _26), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w), _161);\n    SparseTexel _122 = SparseTexel(_160, _161);\n    float _125 = _122._m1;\n    _64 _126 = _64(_125, _125, _125, _125, _122._m0);\n    vec4 _137 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w);\n    uint _162;\n    float _163;\n    _162 = sparseTextureARB(samplerCubeArrayShadow(_23, _26), _137, TEXCOORD.w, _163);\n    SparseTexel _136 = SparseTexel(_162, _163);\n    float _139 = _136._m1;\n    _64 _140 = _64(_139, _139, _139, _139, _136._m0);\n    float _146 = ((((((((((float(sparseTexelsResidentARB(int(_65._m4))) + _65._m0) + _81._m0) + float(sparseTexelsResidentARB(int(_81._m4)))) + _97._m0) + float(sparseTexelsResidentARB(int(_97._m4)))) + _112._m0) + float(sparseTexelsResidentARB(int(_112._m4)))) + _126._m0) + float(sparseTexelsResidentARB(int(_126._m4)))) + _140._m0) + float(sparseTexelsResidentARB(int(_140._m4)));\n    SV_Target.x = _146;\n    SV_Target.y = _146;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 152\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %29 %32\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %29 \"TEXCOORD\"\nOpName %32 \"SV_Target\"\nOpName %60 \"SparseTexel\"\nOpName %64 \"\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %29 Location 0\nOpDecorate %32 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeSampler\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeVector %5 4\n%28 = OpTypePointer Input %27\n%29 = OpVariable %28 Input\n%30 = OpTypeVector %5 2\n%31 = OpTypePointer Output %30\n%32 = OpVariable %31 Output\n%40 = OpTypePointer Input %5\n%42 = OpTypeInt 32 0\n%43 = OpConstant %42 0\n%46 = OpConstant %42 1\n%49 = OpConstant %42 2\n%52 = OpConstant %42 3\n%54 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%55 = OpTypeSampledImage %54\n%57 = OpTypeInt 32 1\n%58 = OpConstant %57 1\n%59 = OpConstant %5 0\n%60 = OpTypeStruct %42 %5\n%64 = OpTypeStruct %5 %5 %5 %5 %42\n%68 = OpTypeBool\n%71 = OpConstant %5 1\n%73 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%74 = OpTypeSampledImage %73\n%76 = OpConstant %57 2\n%88 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%89 = OpTypeSampledImage %88\n%93 = OpTypeVector %57 2\n%94 = OpConstantComposite %93 %58 %76\n%104 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%105 = OpTypeSampledImage %104\n%108 = OpTypeVector %5 3\n%119 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%120 = OpTypeSampledImage %119\n%133 = OpTypeImage %5 Cube 1 1 0 1 Unknown\n%134 = OpTypeSampledImage %133\n%147 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %150\n%150 = OpLabel\n%33 = OpLoad %21 %23\n%34 = OpLoad %18 %20\n%35 = OpLoad %15 %17\n%36 = OpLoad %12 %14\n%37 = OpLoad %9 %11\n%38 = OpLoad %6 %8\n%39 = OpLoad %24 %26\n%41 = OpAccessChain %40 %29 %43\n%44 = OpLoad %5 %41\n%45 = OpAccessChain %40 %29 %46\n%47 = OpLoad %5 %45\n%48 = OpAccessChain %40 %29 %49\n%50 = OpLoad %5 %48\n%51 = OpAccessChain %40 %29 %52\n%53 = OpLoad %5 %51\n%56 = OpSampledImage %55 %38 %39\n%61 = OpImageSparseSampleDrefImplicitLod %60 %56 %44 %53 ConstOffset %58\n%62 = OpCompositeExtract %42 %61 0\n%63 = OpCompositeExtract %5 %61 1\n%65 = OpCompositeConstruct %64 %63 %63 %63 %63 %62\n%66 = OpCompositeExtract %5 %65 0\n%67 = OpCompositeExtract %42 %65 4\n%69 = OpImageSparseTexelsResident %68 %67\n%70 = OpSelect %5 %69 %71 %59\n%72 = OpFAdd %5 %70 %66\n%75 = OpSampledImage %74 %37 %39\n%78 = OpCompositeConstruct %30 %44 %47\n%77 = OpImageSparseSampleDrefImplicitLod %60 %75 %78 %53 ConstOffset %76\n%79 = OpCompositeExtract %42 %77 0\n%80 = OpCompositeExtract %5 %77 1\n%81 = OpCompositeConstruct %64 %80 %80 %80 %80 %79\n%82 = OpCompositeExtract %5 %81 0\n%83 = OpCompositeExtract %42 %81 4\n%84 = OpImageSparseTexelsResident %68 %83\n%85 = OpFAdd %5 %72 %82\n%86 = OpSelect %5 %84 %71 %59\n%87 = OpFAdd %5 %85 %86\n%90 = OpSampledImage %89 %36 %39\n%92 = OpCompositeConstruct %30 %44 %47\n%91 = OpImageSparseSampleDrefImplicitLod %60 %90 %92 %53 ConstOffset %94\n%95 = OpCompositeExtract %42 %91 0\n%96 = OpCompositeExtract %5 %91 1\n%97 = OpCompositeConstruct %64 %96 %96 %96 %96 %95\n%98 = OpCompositeExtract %5 %97 0\n%99 = OpCompositeExtract %42 %97 4\n%100 = OpImageSparseTexelsResident %68 %99\n%101 = OpFAdd %5 %87 %98\n%102 = OpSelect %5 %100 %71 %59\n%103 = OpFAdd %5 %101 %102\n%106 = OpSampledImage %105 %35 %39\n%109 = OpCompositeConstruct %108 %44 %47 %50\n%107 = OpImageSparseSampleDrefImplicitLod %60 %106 %109 %53 ConstOffset %94\n%110 = OpCompositeExtract %42 %107 0\n%111 = OpCompositeExtract %5 %107 1\n%112 = OpCompositeConstruct %64 %111 %111 %111 %111 %110\n%113 = OpCompositeExtract %5 %112 0\n%114 = OpCompositeExtract %42 %112 4\n%115 = OpImageSparseTexelsResident %68 %114\n%116 = OpFAdd %5 %103 %113\n%117 = OpSelect %5 %115 %71 %59\n%118 = OpFAdd %5 %116 %117\n%121 = OpSampledImage %120 %34 %39\n%123 = OpCompositeConstruct %108 %44 %47 %50\n%122 = OpImageSparseSampleDrefImplicitLod %60 %121 %123 %53 None\n%124 = OpCompositeExtract %42 %122 0\n%125 = OpCompositeExtract %5 %122 1\n%126 = OpCompositeConstruct %64 %125 %125 %125 %125 %124\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpCompositeExtract %42 %126 4\n%129 = OpImageSparseTexelsResident %68 %128\n%130 = OpFAdd %5 %118 %127\n%131 = OpSelect %5 %129 %71 %59\n%132 = OpFAdd %5 %130 %131\n%135 = OpSampledImage %134 %33 %39\n%137 = OpCompositeConstruct %27 %44 %47 %50 %53\n%136 = OpImageSparseSampleDrefImplicitLod %60 %135 %137 %53 None\n%138 = OpCompositeExtract %42 %136 0\n%139 = OpCompositeExtract %5 %136 1\n%140 = OpCompositeConstruct %64 %139 %139 %139 %139 %138\n%141 = OpCompositeExtract %5 %140 0\n%142 = OpCompositeExtract %42 %140 4\n%143 = OpImageSparseTexelsResident %68 %142\n%144 = OpFAdd %5 %132 %141\n%145 = OpSelect %5 %143 %71 %59\n%146 = OpFAdd %5 %144 %145\n%148 = OpAccessChain %147 %32 %43\nOpStore %148 %146\n%149 = OpAccessChain %147 %32 %46\nOpStore %149 %146\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-grad-offset-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    float _m1;\n};\n\nstruct _56\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 0) uniform samplerShadow _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) in float DREF;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    uint _124;\n    float _125;\n    _124 = sparseTextureGradOffsetARB(sampler1DShadow(_8, _20), vec2(TEXCOORD.x, DREF), TEXCOORD.z, TEXCOORD.w, 1, _125);\n    SparseTexel _53 = SparseTexel(_124, _125);\n    float _55 = _53._m1;\n    _56 _57 = _56(_55, _55, _55, _55, _53._m0);\n    uint _126;\n    float _127;\n    _126 = sparseTextureGradOffsetARB(sampler1DArrayShadow(_11, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), TEXCOORD.z, TEXCOORD.w, 2, _127);\n    SparseTexel _70 = SparseTexel(_126, _127);\n    float _74 = _70._m1;\n    _56 _75 = _56(_74, _74, _74, _74, _70._m0);\n    uint _128;\n    float _129;\n    _128 = sparseTextureGradOffsetARB(sampler2DShadow(_14, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(-3, -4), _129);\n    SparseTexel _87 = SparseTexel(_128, _129);\n    float _94 = _87._m1;\n    _56 _95 = _56(_94, _94, _94, _94, _87._m0);\n    uint _130;\n    float _131;\n    _130 = sparseTextureGradOffsetARB(sampler2DArrayShadow(_17, _20), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(4, -5), _131);\n    SparseTexel _107 = SparseTexel(_130, _131);\n    float _114 = _107._m1;\n    _56 _115 = _56(_114, _114, _114, _114, _107._m0);\n    SV_Target = ((((((float(sparseTexelsResidentARB(int(_57._m4))) + _57._m0) + _75._m0) + float(sparseTexelsResidentARB(int(_75._m4)))) + _95._m0) + float(sparseTexelsResidentARB(int(_95._m4)))) + _115._m0) + float(sparseTexelsResidentARB(int(_115._m4)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 124\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %25 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %25 \"DREF\"\nOpName %27 \"SV_Target\"\nOpName %52 \"SparseTexel\"\nOpName %56 \"\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %23 Location 0\nOpDecorate %25 Location 1\nOpDecorate %27 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypePointer Input %5\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Output %5\n%27 = OpVariable %26 Output\n%35 = OpTypeInt 32 0\n%36 = OpConstant %35 0\n%39 = OpConstant %35 1\n%42 = OpConstant %35 2\n%45 = OpConstant %35 3\n%47 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%48 = OpTypeSampledImage %47\n%50 = OpTypeInt 32 1\n%51 = OpConstant %50 1\n%52 = OpTypeStruct %35 %5\n%56 = OpTypeStruct %5 %5 %5 %5 %35\n%60 = OpTypeBool\n%63 = OpConstant %5 1\n%64 = OpConstant %5 0\n%66 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%67 = OpTypeSampledImage %66\n%69 = OpConstant %50 2\n%71 = OpTypeVector %5 2\n%82 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%83 = OpTypeSampledImage %82\n%85 = OpConstant %50 -3\n%86 = OpConstant %50 -4\n%91 = OpTypeVector %50 2\n%92 = OpConstantComposite %91 %85 %86\n%102 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%103 = OpTypeSampledImage %102\n%105 = OpConstant %50 4\n%106 = OpConstant %50 -5\n%108 = OpTypeVector %5 3\n%112 = OpConstantComposite %91 %105 %106\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %122\n%122 = OpLabel\n%28 = OpLoad %15 %17\n%29 = OpLoad %12 %14\n%30 = OpLoad %9 %11\n%31 = OpLoad %6 %8\n%32 = OpLoad %18 %20\n%33 = OpLoad %5 %25\n%34 = OpAccessChain %24 %23 %36\n%37 = OpLoad %5 %34\n%38 = OpAccessChain %24 %23 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %24 %23 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %24 %23 %45\n%46 = OpLoad %5 %44\n%49 = OpSampledImage %48 %31 %32\n%53 = OpImageSparseSampleDrefExplicitLod %52 %49 %37 %33 Grad|ConstOffset %43 %46 %51\n%54 = OpCompositeExtract %35 %53 0\n%55 = OpCompositeExtract %5 %53 1\n%57 = OpCompositeConstruct %56 %55 %55 %55 %55 %54\n%58 = OpCompositeExtract %5 %57 0\n%59 = OpCompositeExtract %35 %57 4\n%61 = OpImageSparseTexelsResident %60 %59\n%62 = OpSelect %5 %61 %63 %64\n%65 = OpFAdd %5 %62 %58\n%68 = OpSampledImage %67 %30 %32\n%72 = OpCompositeConstruct %71 %37 %40\n%70 = OpImageSparseSampleDrefExplicitLod %52 %68 %72 %33 Grad|ConstOffset %43 %46 %69\n%73 = OpCompositeExtract %35 %70 0\n%74 = OpCompositeExtract %5 %70 1\n%75 = OpCompositeConstruct %56 %74 %74 %74 %74 %73\n%76 = OpCompositeExtract %5 %75 0\n%77 = OpCompositeExtract %35 %75 4\n%78 = OpImageSparseTexelsResident %60 %77\n%79 = OpFAdd %5 %65 %76\n%80 = OpSelect %5 %78 %63 %64\n%81 = OpFAdd %5 %79 %80\n%84 = OpSampledImage %83 %29 %32\n%88 = OpCompositeConstruct %71 %37 %40\n%89 = OpCompositeConstruct %71 %43 %43\n%90 = OpCompositeConstruct %71 %46 %46\n%87 = OpImageSparseSampleDrefExplicitLod %52 %84 %88 %33 Grad|ConstOffset %89 %90 %92\n%93 = OpCompositeExtract %35 %87 0\n%94 = OpCompositeExtract %5 %87 1\n%95 = OpCompositeConstruct %56 %94 %94 %94 %94 %93\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpCompositeExtract %35 %95 4\n%98 = OpImageSparseTexelsResident %60 %97\n%99 = OpFAdd %5 %81 %96\n%100 = OpSelect %5 %98 %63 %64\n%101 = OpFAdd %5 %99 %100\n%104 = OpSampledImage %103 %28 %32\n%109 = OpCompositeConstruct %108 %37 %40 %43\n%110 = OpCompositeConstruct %71 %43 %43\n%111 = OpCompositeConstruct %71 %46 %46\n%107 = OpImageSparseSampleDrefExplicitLod %52 %104 %109 %33 Grad|ConstOffset %110 %111 %112\n%113 = OpCompositeExtract %35 %107 0\n%114 = OpCompositeExtract %5 %107 1\n%115 = OpCompositeConstruct %56 %114 %114 %114 %114 %113\n%116 = OpCompositeExtract %5 %115 0\n%117 = OpCompositeExtract %35 %115 4\n%118 = OpImageSparseTexelsResident %60 %117\n%119 = OpFAdd %5 %101 %116\n%120 = OpSelect %5 %118 %63 %64\n%121 = OpFAdd %5 %119 %120\nOpStore %27 %121\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-grad-offset.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 0) uniform samplerShadow _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) in float DREF;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = ((vec4(textureGradOffset(sampler1DArrayShadow(_11, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), TEXCOORD.z, TEXCOORD.w, 2)).x + vec4(textureGradOffset(sampler1DShadow(_8, _20), vec2(TEXCOORD.x, DREF), TEXCOORD.z, TEXCOORD.w, 1)).x) + vec4(textureGradOffset(sampler2DShadow(_14, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(-3, -4))).x) + vec4(textureGradOffset(sampler2DArrayShadow(_17, _20), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(4, -5))).x;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %25 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %25 \"DREF\"\nOpName %27 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %23 Location 0\nOpDecorate %25 Location 1\nOpDecorate %27 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypePointer Input %5\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Output %5\n%27 = OpVariable %26 Output\n%35 = OpTypeInt 32 0\n%36 = OpConstant %35 0\n%39 = OpConstant %35 1\n%42 = OpConstant %35 2\n%45 = OpConstant %35 3\n%47 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%48 = OpTypeSampledImage %47\n%50 = OpTypeInt 32 1\n%51 = OpConstant %50 1\n%55 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%56 = OpTypeSampledImage %55\n%58 = OpConstant %50 2\n%60 = OpTypeVector %5 2\n%65 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%66 = OpTypeSampledImage %65\n%68 = OpConstant %50 -3\n%69 = OpConstant %50 -4\n%74 = OpTypeVector %50 2\n%75 = OpConstantComposite %74 %68 %69\n%79 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%80 = OpTypeSampledImage %79\n%82 = OpConstant %50 4\n%83 = OpConstant %50 -5\n%85 = OpTypeVector %5 3\n%89 = OpConstantComposite %74 %82 %83\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%28 = OpLoad %15 %17\n%29 = OpLoad %12 %14\n%30 = OpLoad %9 %11\n%31 = OpLoad %6 %8\n%32 = OpLoad %18 %20\n%33 = OpLoad %5 %25\n%34 = OpAccessChain %24 %23 %36\n%37 = OpLoad %5 %34\n%38 = OpAccessChain %24 %23 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %24 %23 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %24 %23 %45\n%46 = OpLoad %5 %44\n%49 = OpSampledImage %48 %31 %32\n%52 = OpImageSampleDrefExplicitLod %5 %49 %37 %33 Grad|ConstOffset %43 %46 %51\n%53 = OpCompositeConstruct %21 %52 %52 %52 %52\n%54 = OpCompositeExtract %5 %53 0\n%57 = OpSampledImage %56 %30 %32\n%61 = OpCompositeConstruct %60 %37 %40\n%59 = OpImageSampleDrefExplicitLod %5 %57 %61 %33 Grad|ConstOffset %43 %46 %58\n%62 = OpCompositeConstruct %21 %59 %59 %59 %59\n%63 = OpCompositeExtract %5 %62 0\n%64 = OpFAdd %5 %63 %54\n%67 = OpSampledImage %66 %29 %32\n%71 = OpCompositeConstruct %60 %37 %40\n%72 = OpCompositeConstruct %60 %43 %43\n%73 = OpCompositeConstruct %60 %46 %46\n%70 = OpImageSampleDrefExplicitLod %5 %67 %71 %33 Grad|ConstOffset %72 %73 %75\n%76 = OpCompositeConstruct %21 %70 %70 %70 %70\n%77 = OpCompositeExtract %5 %76 0\n%78 = OpFAdd %5 %64 %77\n%81 = OpSampledImage %80 %28 %32\n%86 = OpCompositeConstruct %85 %37 %40 %43\n%87 = OpCompositeConstruct %60 %43 %43\n%88 = OpCompositeConstruct %60 %46 %46\n%84 = OpImageSampleDrefExplicitLod %5 %81 %86 %33 Grad|ConstOffset %87 %88 %89\n%90 = OpCompositeConstruct %21 %84 %84 %84 %84\n%91 = OpCompositeExtract %5 %90 0\n%92 = OpFAdd %5 %78 %91\nOpStore %27 %92\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-grad.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 5) uniform textureCube _20;\nlayout(set = 0, binding = 0) uniform samplerShadow _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) in float DREF;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (((vec4(textureGrad(sampler1DArrayShadow(_11, _23), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), TEXCOORD.z, TEXCOORD.w)).x + vec4(textureGrad(sampler1DShadow(_8, _23), vec2(TEXCOORD.x, DREF), TEXCOORD.z, TEXCOORD.w)).x) + vec4(textureGrad(sampler2DShadow(_14, _23), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DREF), vec2(TEXCOORD.z), vec2(TEXCOORD.w))).x) + vec4(textureGrad(sampler2DArrayShadow(_17, _23), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), vec2(TEXCOORD.z), vec2(TEXCOORD.w))).x) + vec4(textureGrad(samplerCubeShadow(_20, _23), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DREF), vec3(TEXCOORD.z), vec3(TEXCOORD.w))).x;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %28 %30\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %28 \"DREF\"\nOpName %30 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %28 Location 1\nOpDecorate %30 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypePointer Input %5\n%28 = OpVariable %27 Input\n%29 = OpTypePointer Output %5\n%30 = OpVariable %29 Output\n%39 = OpTypeInt 32 0\n%40 = OpConstant %39 0\n%43 = OpConstant %39 1\n%46 = OpConstant %39 2\n%49 = OpConstant %39 3\n%51 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%52 = OpTypeSampledImage %51\n%57 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%58 = OpTypeSampledImage %57\n%61 = OpTypeVector %5 2\n%66 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%67 = OpTypeSampledImage %66\n%76 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%77 = OpTypeSampledImage %76\n%80 = OpTypeVector %5 3\n%87 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%88 = OpTypeSampledImage %87\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %97\n%97 = OpLabel\n%31 = OpLoad %18 %20\n%32 = OpLoad %15 %17\n%33 = OpLoad %12 %14\n%34 = OpLoad %9 %11\n%35 = OpLoad %6 %8\n%36 = OpLoad %21 %23\n%37 = OpLoad %5 %28\n%38 = OpAccessChain %27 %26 %40\n%41 = OpLoad %5 %38\n%42 = OpAccessChain %27 %26 %43\n%44 = OpLoad %5 %42\n%45 = OpAccessChain %27 %26 %46\n%47 = OpLoad %5 %45\n%48 = OpAccessChain %27 %26 %49\n%50 = OpLoad %5 %48\n%53 = OpSampledImage %52 %35 %36\n%54 = OpImageSampleDrefExplicitLod %5 %53 %41 %37 Grad %47 %50\n%55 = OpCompositeConstruct %24 %54 %54 %54 %54\n%56 = OpCompositeExtract %5 %55 0\n%59 = OpSampledImage %58 %34 %36\n%62 = OpCompositeConstruct %61 %41 %44\n%60 = OpImageSampleDrefExplicitLod %5 %59 %62 %37 Grad %47 %50\n%63 = OpCompositeConstruct %24 %60 %60 %60 %60\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpFAdd %5 %64 %56\n%68 = OpSampledImage %67 %33 %36\n%70 = OpCompositeConstruct %61 %41 %44\n%71 = OpCompositeConstruct %61 %47 %47\n%72 = OpCompositeConstruct %61 %50 %50\n%69 = OpImageSampleDrefExplicitLod %5 %68 %70 %37 Grad %71 %72\n%73 = OpCompositeConstruct %24 %69 %69 %69 %69\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpFAdd %5 %65 %74\n%78 = OpSampledImage %77 %32 %36\n%81 = OpCompositeConstruct %80 %41 %44 %47\n%82 = OpCompositeConstruct %61 %47 %47\n%83 = OpCompositeConstruct %61 %50 %50\n%79 = OpImageSampleDrefExplicitLod %5 %78 %81 %37 Grad %82 %83\n%84 = OpCompositeConstruct %24 %79 %79 %79 %79\n%85 = OpCompositeExtract %5 %84 0\n%86 = OpFAdd %5 %75 %85\n%89 = OpSampledImage %88 %31 %36\n%91 = OpCompositeConstruct %80 %41 %44 %47\n%92 = OpCompositeConstruct %80 %47 %47 %47\n%93 = OpCompositeConstruct %80 %50 %50 %50\n%90 = OpImageSampleDrefExplicitLod %5 %89 %91 %37 Grad %92 %93\n%94 = OpCompositeConstruct %24 %90 %90 %90 %90\n%95 = OpCompositeExtract %5 %94 0\n%96 = OpFAdd %5 %86 %95\nOpStore %30 %96\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-level.sm67.noglsl.frag",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 112\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %29 %32\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %29 \"TEXCOORD\"\nOpName %32 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %29 Location 0\nOpDecorate %32 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeSampler\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeVector %5 4\n%28 = OpTypePointer Input %27\n%29 = OpVariable %28 Input\n%30 = OpTypeVector %5 2\n%31 = OpTypePointer Output %30\n%32 = OpVariable %31 Output\n%33 = OpTypePointer Input %5\n%35 = OpTypeInt 32 0\n%36 = OpConstant %35 0\n%39 = OpConstant %35 1\n%42 = OpConstant %35 2\n%45 = OpConstant %35 3\n%49 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%50 = OpTypeSampledImage %49\n%52 = OpConstant %5 0.25\n%57 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%58 = OpTypeSampledImage %57\n%60 = OpConstant %5 0.5\n%67 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%68 = OpTypeSampledImage %67\n%70 = OpConstant %5 1\n%77 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%78 = OpTypeSampledImage %77\n%80 = OpConstant %5 2\n%82 = OpTypeVector %5 3\n%88 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%89 = OpTypeSampledImage %88\n%91 = OpConstant %5 3\n%98 = OpTypeImage %5 Cube 1 1 0 1 Unknown\n%99 = OpTypeSampledImage %98\n%101 = OpConstant %5 4\n%107 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%34 = OpAccessChain %33 %29 %36\n%37 = OpLoad %5 %34\n%38 = OpAccessChain %33 %29 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %33 %29 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %33 %29 %45\n%46 = OpLoad %5 %44\n%47 = OpLoad %6 %8\n%48 = OpLoad %24 %26\n%51 = OpSampledImage %50 %47 %48\n%53 = OpImageSampleDrefExplicitLod %5 %51 %37 %46 Lod %52\n%54 = OpCompositeConstruct %27 %53 %53 %53 %53\n%55 = OpCompositeExtract %5 %54 0\n%56 = OpLoad %9 %11\n%59 = OpSampledImage %58 %56 %48\n%62 = OpCompositeConstruct %30 %37 %40\n%61 = OpImageSampleDrefExplicitLod %5 %59 %62 %46 Lod %60\n%63 = OpCompositeConstruct %27 %61 %61 %61 %61\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpFAdd %5 %64 %55\n%66 = OpLoad %12 %14\n%69 = OpSampledImage %68 %66 %48\n%72 = OpCompositeConstruct %30 %37 %40\n%71 = OpImageSampleDrefExplicitLod %5 %69 %72 %46 Lod %70\n%73 = OpCompositeConstruct %27 %71 %71 %71 %71\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpFAdd %5 %65 %74\n%76 = OpLoad %15 %17\n%79 = OpSampledImage %78 %76 %48\n%83 = OpCompositeConstruct %82 %37 %40 %43\n%81 = OpImageSampleDrefExplicitLod %5 %79 %83 %46 Lod %80\n%84 = OpCompositeConstruct %27 %81 %81 %81 %81\n%85 = OpCompositeExtract %5 %84 0\n%86 = OpFAdd %5 %75 %85\n%87 = OpLoad %18 %20\n%90 = OpSampledImage %89 %87 %48\n%93 = OpCompositeConstruct %82 %37 %40 %43\n%92 = OpImageSampleDrefExplicitLod %5 %90 %93 %46 Lod %91\n%94 = OpCompositeConstruct %27 %92 %92 %92 %92\n%95 = OpCompositeExtract %5 %94 0\n%96 = OpFAdd %5 %86 %95\n%97 = OpLoad %21 %23\n%100 = OpSampledImage %99 %97 %48\n%103 = OpCompositeConstruct %27 %37 %40 %43 %46\n%102 = OpImageSampleDrefExplicitLod %5 %100 %103 %46 Lod %101\n%104 = OpCompositeConstruct %27 %102 %102 %102 %102\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpFAdd %5 %96 %105\n%108 = OpAccessChain %107 %32 %36\nOpStore %108 %106\n%109 = OpAccessChain %107 %32 %39\nOpStore %109 %106\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-levelzero.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 5) uniform textureCube _20;\nlayout(set = 1, binding = 6) uniform textureCubeArray _23;\nlayout(set = 0, binding = 0) uniform samplerShadow _26;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _98 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w);\n    float _101 = ((((vec4(textureLod(sampler1DArrayShadow(_11, _26), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 0.0)).x + vec4(textureLod(sampler1DShadow(_8, _26), vec2(TEXCOORD.x, TEXCOORD.w), 0.0)).x) + vec4(textureLod(sampler2DShadow(_14, _26), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 0.0)).x) + vec4(textureGrad(sampler2DArrayShadow(_17, _26), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w), vec2(0.0), vec2(0.0))).x) + vec4(textureGrad(samplerCubeShadow(_20, _26), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w), vec3(0.0), vec3(0.0))).x) + vec4(textureGrad(samplerCubeArrayShadow(_23, _26), _98, TEXCOORD.w, vec3(0.0), vec3(0.0))).x;\n    SV_Target.x = _101;\n    SV_Target.y = _101;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %29 %32\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %29 \"TEXCOORD\"\nOpName %32 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %29 Location 0\nOpDecorate %32 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeSampler\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeVector %5 4\n%28 = OpTypePointer Input %27\n%29 = OpVariable %28 Input\n%30 = OpTypeVector %5 2\n%31 = OpTypePointer Output %30\n%32 = OpVariable %31 Output\n%40 = OpTypePointer Input %5\n%42 = OpTypeInt 32 0\n%43 = OpConstant %42 0\n%46 = OpConstant %42 1\n%49 = OpConstant %42 2\n%52 = OpConstant %42 3\n%54 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%55 = OpTypeSampledImage %54\n%57 = OpConstant %5 0\n%61 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%62 = OpTypeSampledImage %61\n%69 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%70 = OpTypeSampledImage %69\n%77 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%78 = OpTypeSampledImage %77\n%81 = OpTypeVector %5 3\n%86 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%87 = OpTypeSampledImage %86\n%94 = OpTypeImage %5 Cube 1 1 0 1 Unknown\n%95 = OpTypeSampledImage %94\n%102 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %105\n%105 = OpLabel\n%33 = OpLoad %21 %23\n%34 = OpLoad %18 %20\n%35 = OpLoad %15 %17\n%36 = OpLoad %12 %14\n%37 = OpLoad %9 %11\n%38 = OpLoad %6 %8\n%39 = OpLoad %24 %26\n%41 = OpAccessChain %40 %29 %43\n%44 = OpLoad %5 %41\n%45 = OpAccessChain %40 %29 %46\n%47 = OpLoad %5 %45\n%48 = OpAccessChain %40 %29 %49\n%50 = OpLoad %5 %48\n%51 = OpAccessChain %40 %29 %52\n%53 = OpLoad %5 %51\n%56 = OpSampledImage %55 %38 %39\n%58 = OpImageSampleDrefExplicitLod %5 %56 %44 %53 Lod %57\n%59 = OpCompositeConstruct %27 %58 %58 %58 %58\n%60 = OpCompositeExtract %5 %59 0\n%63 = OpSampledImage %62 %37 %39\n%65 = OpCompositeConstruct %30 %44 %47\n%64 = OpImageSampleDrefExplicitLod %5 %63 %65 %53 Lod %57\n%66 = OpCompositeConstruct %27 %64 %64 %64 %64\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpFAdd %5 %67 %60\n%71 = OpSampledImage %70 %36 %39\n%73 = OpCompositeConstruct %30 %44 %47\n%72 = OpImageSampleDrefExplicitLod %5 %71 %73 %53 Lod %57\n%74 = OpCompositeConstruct %27 %72 %72 %72 %72\n%75 = OpCompositeExtract %5 %74 0\n%76 = OpFAdd %5 %68 %75\n%79 = OpSampledImage %78 %35 %39\n%82 = OpCompositeConstruct %81 %44 %47 %50\n%80 = OpImageSampleDrefExplicitLod %5 %79 %82 %53 Lod %57\n%83 = OpCompositeConstruct %27 %80 %80 %80 %80\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpFAdd %5 %76 %84\n%88 = OpSampledImage %87 %34 %39\n%90 = OpCompositeConstruct %81 %44 %47 %50\n%89 = OpImageSampleDrefExplicitLod %5 %88 %90 %53 Lod %57\n%91 = OpCompositeConstruct %27 %89 %89 %89 %89\n%92 = OpCompositeExtract %5 %91 0\n%93 = OpFAdd %5 %85 %92\n%96 = OpSampledImage %95 %33 %39\n%98 = OpCompositeConstruct %27 %44 %47 %50 %53\n%97 = OpImageSampleDrefExplicitLod %5 %96 %98 %53 Lod %57\n%99 = OpCompositeConstruct %27 %97 %97 %97 %97\n%100 = OpCompositeExtract %5 %99 0\n%101 = OpFAdd %5 %93 %100\n%103 = OpAccessChain %102 %32 %43\nOpStore %103 %101\n%104 = OpAccessChain %102 %32 %46\nOpStore %104 %101\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-offset-levelzero-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    float _m1;\n};\n\nstruct _56\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 0) uniform samplerShadow _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _121;\n    float _122;\n    _121 = sparseTextureLodOffsetARB(sampler1DShadow(_8, _20), vec2(TEXCOORD.x, TEXCOORD.w), 0.0, 1, _122);\n    SparseTexel _53 = SparseTexel(_121, _122);\n    float _55 = _53._m1;\n    _56 _57 = _56(_55, _55, _55, _55, _53._m0);\n    uint _123;\n    float _124;\n    _123 = sparseTextureLodOffsetARB(sampler1DArrayShadow(_11, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 0.0, 2, _124);\n    SparseTexel _69 = SparseTexel(_123, _124);\n    float _72 = _69._m1;\n    _56 _73 = _56(_72, _72, _72, _72, _69._m0);\n    uint _125;\n    float _126;\n    _125 = sparseTextureLodOffsetARB(sampler2DShadow(_14, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 0.0, ivec2(-3, -2), _126);\n    SparseTexel _85 = SparseTexel(_125, _126);\n    float _90 = _85._m1;\n    _56 _91 = _56(_90, _90, _90, _90, _85._m0);\n    uint _127;\n    float _128;\n    _127 = sparseTextureGradOffsetARB(sampler2DArrayShadow(_17, _20), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w), vec2(0.0), vec2(0.0), ivec2(4, 5), _128);\n    SparseTexel _103 = SparseTexel(_127, _128);\n    float _108 = _103._m1;\n    _56 _109 = _56(_108, _108, _108, _108, _103._m0);\n    float _115 = ((((((float(sparseTexelsResidentARB(int(_57._m4))) + _57._m0) + _73._m0) + float(sparseTexelsResidentARB(int(_73._m4)))) + _91._m0) + float(sparseTexelsResidentARB(int(_91._m4)))) + _109._m0) + float(sparseTexelsResidentARB(int(_109._m4)));\n    SV_Target.x = _115;\n    SV_Target.y = _115;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 121\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %26\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %26 \"SV_Target\"\nOpName %52 \"SparseTexel\"\nOpName %56 \"\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %23 Location 0\nOpDecorate %26 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypeVector %5 2\n%25 = OpTypePointer Output %24\n%26 = OpVariable %25 Output\n%32 = OpTypePointer Input %5\n%34 = OpTypeInt 32 0\n%35 = OpConstant %34 0\n%38 = OpConstant %34 1\n%41 = OpConstant %34 2\n%44 = OpConstant %34 3\n%46 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%47 = OpTypeSampledImage %46\n%49 = OpTypeInt 32 1\n%50 = OpConstant %49 1\n%51 = OpConstant %5 0\n%52 = OpTypeStruct %34 %5\n%56 = OpTypeStruct %5 %5 %5 %5 %34\n%60 = OpTypeBool\n%63 = OpConstant %5 1\n%65 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%66 = OpTypeSampledImage %65\n%68 = OpConstant %49 2\n%80 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%81 = OpTypeSampledImage %80\n%83 = OpConstant %49 -3\n%84 = OpConstant %49 -2\n%87 = OpTypeVector %49 2\n%88 = OpConstantComposite %87 %83 %84\n%98 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%99 = OpTypeSampledImage %98\n%101 = OpConstant %49 4\n%102 = OpConstant %49 5\n%104 = OpTypeVector %5 3\n%106 = OpConstantComposite %87 %101 %102\n%116 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %119\n%119 = OpLabel\n%27 = OpLoad %15 %17\n%28 = OpLoad %12 %14\n%29 = OpLoad %9 %11\n%30 = OpLoad %6 %8\n%31 = OpLoad %18 %20\n%33 = OpAccessChain %32 %23 %35\n%36 = OpLoad %5 %33\n%37 = OpAccessChain %32 %23 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %32 %23 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %32 %23 %44\n%45 = OpLoad %5 %43\n%48 = OpSampledImage %47 %30 %31\n%53 = OpImageSparseSampleDrefExplicitLod %52 %48 %36 %45 Lod|ConstOffset %51 %50\n%54 = OpCompositeExtract %34 %53 0\n%55 = OpCompositeExtract %5 %53 1\n%57 = OpCompositeConstruct %56 %55 %55 %55 %55 %54\n%58 = OpCompositeExtract %5 %57 0\n%59 = OpCompositeExtract %34 %57 4\n%61 = OpImageSparseTexelsResident %60 %59\n%62 = OpSelect %5 %61 %63 %51\n%64 = OpFAdd %5 %62 %58\n%67 = OpSampledImage %66 %29 %31\n%70 = OpCompositeConstruct %24 %36 %39\n%69 = OpImageSparseSampleDrefExplicitLod %52 %67 %70 %45 Lod|ConstOffset %51 %68\n%71 = OpCompositeExtract %34 %69 0\n%72 = OpCompositeExtract %5 %69 1\n%73 = OpCompositeConstruct %56 %72 %72 %72 %72 %71\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpCompositeExtract %34 %73 4\n%76 = OpImageSparseTexelsResident %60 %75\n%77 = OpFAdd %5 %64 %74\n%78 = OpSelect %5 %76 %63 %51\n%79 = OpFAdd %5 %77 %78\n%82 = OpSampledImage %81 %28 %31\n%86 = OpCompositeConstruct %24 %36 %39\n%85 = OpImageSparseSampleDrefExplicitLod %52 %82 %86 %45 Lod|ConstOffset %51 %88\n%89 = OpCompositeExtract %34 %85 0\n%90 = OpCompositeExtract %5 %85 1\n%91 = OpCompositeConstruct %56 %90 %90 %90 %90 %89\n%92 = OpCompositeExtract %5 %91 0\n%93 = OpCompositeExtract %34 %91 4\n%94 = OpImageSparseTexelsResident %60 %93\n%95 = OpFAdd %5 %79 %92\n%96 = OpSelect %5 %94 %63 %51\n%97 = OpFAdd %5 %95 %96\n%100 = OpSampledImage %99 %27 %31\n%105 = OpCompositeConstruct %104 %36 %39 %42\n%103 = OpImageSparseSampleDrefExplicitLod %52 %100 %105 %45 Lod|ConstOffset %51 %106\n%107 = OpCompositeExtract %34 %103 0\n%108 = OpCompositeExtract %5 %103 1\n%109 = OpCompositeConstruct %56 %108 %108 %108 %108 %107\n%110 = OpCompositeExtract %5 %109 0\n%111 = OpCompositeExtract %34 %109 4\n%112 = OpImageSparseTexelsResident %60 %111\n%113 = OpFAdd %5 %97 %110\n%114 = OpSelect %5 %112 %63 %51\n%115 = OpFAdd %5 %113 %114\n%117 = OpAccessChain %116 %26 %35\nOpStore %117 %115\n%118 = OpAccessChain %116 %26 %38\nOpStore %118 %115\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-offset-levelzero.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 0) uniform samplerShadow _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    float _87 = ((vec4(textureLodOffset(sampler1DArrayShadow(_11, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 0.0, 2)).x + vec4(textureLodOffset(sampler1DShadow(_8, _20), vec2(TEXCOORD.x, TEXCOORD.w), 0.0, 1)).x) + vec4(textureLodOffset(sampler2DShadow(_14, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 0.0, ivec2(-3, -2))).x) + vec4(textureGradOffset(sampler2DArrayShadow(_17, _20), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w), vec2(0.0), vec2(0.0), ivec2(4, 5))).x;\n    SV_Target.x = _87;\n    SV_Target.y = _87;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 93\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %26\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %26 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %23 Location 0\nOpDecorate %26 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypeVector %5 2\n%25 = OpTypePointer Output %24\n%26 = OpVariable %25 Output\n%32 = OpTypePointer Input %5\n%34 = OpTypeInt 32 0\n%35 = OpConstant %34 0\n%38 = OpConstant %34 1\n%41 = OpConstant %34 2\n%44 = OpConstant %34 3\n%46 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%47 = OpTypeSampledImage %46\n%49 = OpTypeInt 32 1\n%50 = OpConstant %49 1\n%51 = OpConstant %5 0\n%55 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%56 = OpTypeSampledImage %55\n%58 = OpConstant %49 2\n%64 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%65 = OpTypeSampledImage %64\n%67 = OpConstant %49 -3\n%68 = OpConstant %49 -2\n%71 = OpTypeVector %49 2\n%72 = OpConstantComposite %71 %67 %68\n%76 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%77 = OpTypeSampledImage %76\n%79 = OpConstant %49 4\n%80 = OpConstant %49 5\n%82 = OpTypeVector %5 3\n%84 = OpConstantComposite %71 %79 %80\n%88 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %91\n%91 = OpLabel\n%27 = OpLoad %15 %17\n%28 = OpLoad %12 %14\n%29 = OpLoad %9 %11\n%30 = OpLoad %6 %8\n%31 = OpLoad %18 %20\n%33 = OpAccessChain %32 %23 %35\n%36 = OpLoad %5 %33\n%37 = OpAccessChain %32 %23 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %32 %23 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %32 %23 %44\n%45 = OpLoad %5 %43\n%48 = OpSampledImage %47 %30 %31\n%52 = OpImageSampleDrefExplicitLod %5 %48 %36 %45 Lod|ConstOffset %51 %50\n%53 = OpCompositeConstruct %21 %52 %52 %52 %52\n%54 = OpCompositeExtract %5 %53 0\n%57 = OpSampledImage %56 %29 %31\n%60 = OpCompositeConstruct %24 %36 %39\n%59 = OpImageSampleDrefExplicitLod %5 %57 %60 %45 Lod|ConstOffset %51 %58\n%61 = OpCompositeConstruct %21 %59 %59 %59 %59\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpFAdd %5 %62 %54\n%66 = OpSampledImage %65 %28 %31\n%70 = OpCompositeConstruct %24 %36 %39\n%69 = OpImageSampleDrefExplicitLod %5 %66 %70 %45 Lod|ConstOffset %51 %72\n%73 = OpCompositeConstruct %21 %69 %69 %69 %69\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpFAdd %5 %63 %74\n%78 = OpSampledImage %77 %27 %31\n%83 = OpCompositeConstruct %82 %36 %39 %42\n%81 = OpImageSampleDrefExplicitLod %5 %78 %83 %45 Lod|ConstOffset %51 %84\n%85 = OpCompositeConstruct %21 %81 %81 %81 %81\n%86 = OpCompositeExtract %5 %85 0\n%87 = OpFAdd %5 %75 %86\n%89 = OpAccessChain %88 %26 %35\nOpStore %89 %87\n%90 = OpAccessChain %88 %26 %38\nOpStore %90 %87\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp-offset.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 0, binding = 0) uniform samplerShadow _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    float _87 = ((vec4(textureOffset(sampler1DArrayShadow(_11, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), 2)).x + vec4(textureOffset(sampler1DShadow(_8, _20), vec2(TEXCOORD.x, TEXCOORD.w), 1)).x) + vec4(textureOffset(sampler2DShadow(_14, _20), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w), ivec2(-3, -2))).x) + vec4(textureOffset(sampler2DArrayShadow(_17, _20), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w), ivec2(4, 5))).x;\n    SV_Target.x = _87;\n    SV_Target.y = _87;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 93\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %26\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %26 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %23 Location 0\nOpDecorate %26 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypeVector %5 2\n%25 = OpTypePointer Output %24\n%26 = OpVariable %25 Output\n%32 = OpTypePointer Input %5\n%34 = OpTypeInt 32 0\n%35 = OpConstant %34 0\n%38 = OpConstant %34 1\n%41 = OpConstant %34 2\n%44 = OpConstant %34 3\n%46 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%47 = OpTypeSampledImage %46\n%49 = OpTypeInt 32 1\n%50 = OpConstant %49 1\n%51 = OpConstant %5 0\n%55 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%56 = OpTypeSampledImage %55\n%58 = OpConstant %49 2\n%64 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%65 = OpTypeSampledImage %64\n%67 = OpConstant %49 -3\n%68 = OpConstant %49 -2\n%71 = OpTypeVector %49 2\n%72 = OpConstantComposite %71 %67 %68\n%76 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%77 = OpTypeSampledImage %76\n%79 = OpConstant %49 4\n%80 = OpConstant %49 5\n%82 = OpTypeVector %5 3\n%84 = OpConstantComposite %71 %79 %80\n%88 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %91\n%91 = OpLabel\n%27 = OpLoad %15 %17\n%28 = OpLoad %12 %14\n%29 = OpLoad %9 %11\n%30 = OpLoad %6 %8\n%31 = OpLoad %18 %20\n%33 = OpAccessChain %32 %23 %35\n%36 = OpLoad %5 %33\n%37 = OpAccessChain %32 %23 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %32 %23 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %32 %23 %44\n%45 = OpLoad %5 %43\n%48 = OpSampledImage %47 %30 %31\n%52 = OpImageSampleDrefImplicitLod %5 %48 %36 %45 ConstOffset %50\n%53 = OpCompositeConstruct %21 %52 %52 %52 %52\n%54 = OpCompositeExtract %5 %53 0\n%57 = OpSampledImage %56 %29 %31\n%60 = OpCompositeConstruct %24 %36 %39\n%59 = OpImageSampleDrefImplicitLod %5 %57 %60 %45 ConstOffset %58\n%61 = OpCompositeConstruct %21 %59 %59 %59 %59\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpFAdd %5 %62 %54\n%66 = OpSampledImage %65 %28 %31\n%70 = OpCompositeConstruct %24 %36 %39\n%69 = OpImageSampleDrefImplicitLod %5 %66 %70 %45 ConstOffset %72\n%73 = OpCompositeConstruct %21 %69 %69 %69 %69\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpFAdd %5 %63 %74\n%78 = OpSampledImage %77 %27 %31\n%83 = OpCompositeConstruct %82 %36 %39 %42\n%81 = OpImageSampleDrefImplicitLod %5 %78 %83 %45 ConstOffset %84\n%85 = OpCompositeConstruct %21 %81 %81 %81 %81\n%86 = OpCompositeExtract %5 %85 0\n%87 = OpFAdd %5 %75 %86\n%89 = OpAccessChain %88 %26 %35\nOpStore %89 %87\n%90 = OpAccessChain %88 %26 %38\nOpStore %90 %87\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-cmp.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 5) uniform textureCube _20;\nlayout(set = 1, binding = 6) uniform textureCubeArray _23;\nlayout(set = 0, binding = 0) uniform samplerShadow _26;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _98 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w);\n    float _101 = ((((vec4(texture(sampler1DArrayShadow(_11, _26), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w))).x + vec4(texture(sampler1DShadow(_8, _26), vec2(TEXCOORD.x, TEXCOORD.w))).x) + vec4(texture(sampler2DShadow(_14, _26), vec3(vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w))).x) + vec4(texture(sampler2DArrayShadow(_17, _26), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w))).x) + vec4(texture(samplerCubeShadow(_20, _26), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w))).x) + vec4(texture(samplerCubeArrayShadow(_23, _26), _98, TEXCOORD.w)).x;\n    SV_Target.x = _101;\n    SV_Target.y = _101;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %29 %32\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %29 \"TEXCOORD\"\nOpName %32 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %29 Location 0\nOpDecorate %32 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeSampler\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeVector %5 4\n%28 = OpTypePointer Input %27\n%29 = OpVariable %28 Input\n%30 = OpTypeVector %5 2\n%31 = OpTypePointer Output %30\n%32 = OpVariable %31 Output\n%40 = OpTypePointer Input %5\n%42 = OpTypeInt 32 0\n%43 = OpConstant %42 0\n%46 = OpConstant %42 1\n%49 = OpConstant %42 2\n%52 = OpConstant %42 3\n%54 = OpTypeImage %5 1D 1 0 0 1 Unknown\n%55 = OpTypeSampledImage %54\n%57 = OpConstant %5 0\n%61 = OpTypeImage %5 1D 1 1 0 1 Unknown\n%62 = OpTypeSampledImage %61\n%69 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%70 = OpTypeSampledImage %69\n%77 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%78 = OpTypeSampledImage %77\n%81 = OpTypeVector %5 3\n%86 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%87 = OpTypeSampledImage %86\n%94 = OpTypeImage %5 Cube 1 1 0 1 Unknown\n%95 = OpTypeSampledImage %94\n%102 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %105\n%105 = OpLabel\n%33 = OpLoad %21 %23\n%34 = OpLoad %18 %20\n%35 = OpLoad %15 %17\n%36 = OpLoad %12 %14\n%37 = OpLoad %9 %11\n%38 = OpLoad %6 %8\n%39 = OpLoad %24 %26\n%41 = OpAccessChain %40 %29 %43\n%44 = OpLoad %5 %41\n%45 = OpAccessChain %40 %29 %46\n%47 = OpLoad %5 %45\n%48 = OpAccessChain %40 %29 %49\n%50 = OpLoad %5 %48\n%51 = OpAccessChain %40 %29 %52\n%53 = OpLoad %5 %51\n%56 = OpSampledImage %55 %38 %39\n%58 = OpImageSampleDrefImplicitLod %5 %56 %44 %53 None\n%59 = OpCompositeConstruct %27 %58 %58 %58 %58\n%60 = OpCompositeExtract %5 %59 0\n%63 = OpSampledImage %62 %37 %39\n%65 = OpCompositeConstruct %30 %44 %47\n%64 = OpImageSampleDrefImplicitLod %5 %63 %65 %53 None\n%66 = OpCompositeConstruct %27 %64 %64 %64 %64\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpFAdd %5 %67 %60\n%71 = OpSampledImage %70 %36 %39\n%73 = OpCompositeConstruct %30 %44 %47\n%72 = OpImageSampleDrefImplicitLod %5 %71 %73 %53 None\n%74 = OpCompositeConstruct %27 %72 %72 %72 %72\n%75 = OpCompositeExtract %5 %74 0\n%76 = OpFAdd %5 %68 %75\n%79 = OpSampledImage %78 %35 %39\n%82 = OpCompositeConstruct %81 %44 %47 %50\n%80 = OpImageSampleDrefImplicitLod %5 %79 %82 %53 None\n%83 = OpCompositeConstruct %27 %80 %80 %80 %80\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpFAdd %5 %76 %84\n%88 = OpSampledImage %87 %34 %39\n%90 = OpCompositeConstruct %81 %44 %47 %50\n%89 = OpImageSampleDrefImplicitLod %5 %88 %90 %53 None\n%91 = OpCompositeConstruct %27 %89 %89 %89 %89\n%92 = OpCompositeExtract %5 %91 0\n%93 = OpFAdd %5 %85 %92\n%96 = OpSampledImage %95 %33 %39\n%98 = OpCompositeConstruct %27 %44 %47 %50 %53\n%97 = OpImageSampleDrefImplicitLod %5 %96 %98 %53 None\n%99 = OpCompositeConstruct %27 %97 %97 %97 %97\n%100 = OpCompositeExtract %5 %99 0\n%101 = OpFAdd %5 %93 %100\n%103 = OpAccessChain %102 %32 %43\nOpStore %103 %101\n%104 = OpAccessChain %102 %32 %46\nOpStore %104 %101\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-grad-offset-dynamic.noglsl.invalid.sm67.frag",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 136\n; Schema: 0\nOpCapability Shader\nOpCapability ImageGatherExtended\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %25 \"\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %24 ArrayStride 16\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 0\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeInt 32 0\n%22 = OpConstant %21 2\n%23 = OpTypeVector %5 4\n%24 = OpTypeArray %23 %22\n%25 = OpTypeStruct %24\n%26 = OpTypePointer Uniform %25\n%27 = OpVariable %26 Uniform\n%28 = OpTypeSampler\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypePointer Input %23\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%36 = OpTypePointer Input %5\n%38 = OpConstant %21 0\n%41 = OpConstant %21 1\n%46 = OpConstant %21 3\n%48 = OpTypePointer Uniform %23\n%51 = OpTypeVector %21 4\n%56 = OpTypeSampledImage %6\n%58 = OpTypeInt 32 1\n%62 = OpConstant %58 0\n%63 = OpConstant %58 4\n%67 = OpTypeSampledImage %9\n%77 = OpTypeSampledImage %12\n%85 = OpTypeVector %58 2\n%91 = OpTypeSampledImage %15\n%96 = OpTypeVector %5 3\n%110 = OpTypeSampledImage %18\n%119 = OpTypeVector %58 3\n%131 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %134\n%134 = OpLabel\n%37 = OpAccessChain %36 %32 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %36 %32 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %36 %32 %22\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %36 %32 %46\n%47 = OpLoad %5 %45\n%49 = OpAccessChain %48 %27 %38 %38\n%50 = OpLoad %23 %49\n%52 = OpBitcast %51 %50\n%53 = OpCompositeExtract %21 %52 0\n%54 = OpLoad %6 %8\n%55 = OpLoad %28 %30\n%57 = OpSampledImage %56 %54 %55\n%59 = OpBitcast %58 %53\n%61 = OpBitFieldSExtract %58 %59 %62 %63\n%60 = OpImageSampleExplicitLod %23 %57 %39 Grad|Offset %44 %47 %61\n%64 = OpCompositeExtract %5 %60 0\n%65 = OpCompositeExtract %5 %60 1\n%66 = OpLoad %9 %11\n%68 = OpSampledImage %67 %66 %55\n%69 = OpBitcast %58 %53\n%71 = OpCompositeConstruct %33 %39 %42\n%72 = OpBitFieldSExtract %58 %69 %62 %63\n%70 = OpImageSampleExplicitLod %23 %68 %71 Grad|Offset %44 %42 %72\n%73 = OpCompositeExtract %5 %70 0\n%74 = OpCompositeExtract %21 %52 1\n%75 = OpCompositeExtract %21 %52 2\n%76 = OpLoad %12 %14\n%78 = OpSampledImage %77 %76 %55\n%79 = OpBitcast %58 %74\n%80 = OpBitcast %58 %75\n%82 = OpCompositeConstruct %33 %39 %42\n%83 = OpCompositeConstruct %33 %44 %44\n%84 = OpCompositeConstruct %33 %47 %47\n%86 = OpCompositeConstruct %85 %79 %80\n%87 = OpBitFieldSExtract %85 %86 %62 %63\n%81 = OpImageSampleExplicitLod %23 %78 %82 Grad|Offset %83 %84 %87\n%88 = OpCompositeExtract %5 %81 0\n%89 = OpCompositeExtract %5 %81 1\n%90 = OpLoad %15 %17\n%92 = OpSampledImage %91 %90 %55\n%93 = OpBitcast %58 %74\n%94 = OpBitcast %58 %75\n%97 = OpCompositeConstruct %96 %39 %42 %44\n%98 = OpCompositeConstruct %33 %44 %44\n%99 = OpCompositeConstruct %33 %47 %47\n%100 = OpCompositeConstruct %85 %93 %94\n%101 = OpBitFieldSExtract %85 %100 %62 %63\n%95 = OpImageSampleExplicitLod %23 %92 %97 Grad|Offset %98 %99 %101\n%102 = OpCompositeExtract %5 %95 0\n%103 = OpAccessChain %48 %27 %38 %41\n%104 = OpLoad %23 %103\n%105 = OpBitcast %51 %104\n%106 = OpCompositeExtract %21 %105 0\n%107 = OpCompositeExtract %21 %105 1\n%108 = OpCompositeExtract %21 %105 2\n%109 = OpLoad %18 %20\n%111 = OpSampledImage %110 %109 %55\n%112 = OpBitcast %58 %106\n%113 = OpBitcast %58 %107\n%114 = OpBitcast %58 %108\n%116 = OpCompositeConstruct %96 %39 %42 %44\n%117 = OpCompositeConstruct %96 %44 %44 %44\n%118 = OpCompositeConstruct %96 %47 %47 %47\n%120 = OpCompositeConstruct %119 %112 %113 %114\n%121 = OpBitFieldSExtract %119 %120 %62 %63\n%115 = OpImageSampleExplicitLod %23 %111 %116 Grad|Offset %117 %118 %121\n%122 = OpCompositeExtract %5 %115 0\n%123 = OpCompositeExtract %5 %115 1\n%124 = OpFAdd %5 %102 %73\n%125 = OpFAdd %5 %88 %64\n%126 = OpFAdd %5 %125 %124\n%127 = OpFAdd %5 %126 %122\n%128 = OpFAdd %5 %89 %65\n%129 = OpFAdd %5 %128 %124\n%130 = OpFAdd %5 %129 %123\n%132 = OpAccessChain %131 %35 %38\nOpStore %132 %127\n%133 = OpAccessChain %131 %35 %41\nOpStore %133 %130\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-grad-offset-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _62\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _175;\n    vec4 _176;\n    _175 = sparseTextureGradOffsetARB(sampler1D(_8, _23), TEXCOORD.x, TEXCOORD.z, TEXCOORD.w, 1, _176);\n    SparseTexel _55 = SparseTexel(_175, _176);\n    vec4 _57 = _55._m1;\n    _62 _63 = _62(_57.x, _57.y, _57.z, _57.w, _55._m0);\n    uint _177;\n    vec4 _178;\n    _177 = sparseTextureGradOffsetARB(sampler1DArray(_11, _23), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.z, TEXCOORD.y, 2, _178);\n    SparseTexel _75 = SparseTexel(_177, _178);\n    vec4 _78 = _75._m1;\n    _62 _83 = _62(_78.x, _78.y, _78.z, _78.w, _75._m0);\n    uint _179;\n    vec4 _180;\n    _179 = sparseTextureGradOffsetARB(sampler2D(_14, _23), vec2(TEXCOORD.x, TEXCOORD.y), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(-3, -4), _180);\n    SparseTexel _92 = SparseTexel(_179, _180);\n    vec4 _99 = _92._m1;\n    _62 _104 = _62(_99.x, _99.y, _99.z, _99.w, _92._m0);\n    float _109 = float(sparseTexelsResidentARB(int(_104._m4)));\n    uint _181;\n    vec4 _182;\n    _181 = sparseTextureGradOffsetARB(sampler2DArray(_17, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(4, -5), _182);\n    SparseTexel _114 = SparseTexel(_181, _182);\n    vec4 _121 = _114._m1;\n    _62 _126 = _62(_121.x, _121.y, _121.z, _121.w, _114._m0);\n    float _127 = _126._m0;\n    float _130 = float(sparseTexelsResidentARB(int(_126._m4)));\n    uint _183;\n    vec4 _184;\n    _183 = sparseTextureGradOffsetARB(sampler3D(_20, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(TEXCOORD.z), vec3(TEXCOORD.w), ivec3(5, 6, 7), _184);\n    SparseTexel _136 = SparseTexel(_183, _184);\n    vec4 _143 = _136._m1;\n    _62 _148 = _62(_143.x, _143.y, _143.z, _143.w, _136._m0);\n    float _153 = float(sparseTexelsResidentARB(int(_148._m4)));\n    float _155 = float(sparseTexelsResidentARB(int(_83._m4))) + (_83._m0 + float(sparseTexelsResidentARB(int(_63._m4))));\n    SV_Target.x = ((((((_155 + _63._m0) + _104._m0) + _109) + _127) + _130) + _148._m0) + _153;\n    SV_Target.y = ((((((_155 + _63._m1) + _104._m1) + _109) + _127) + _130) + _148._m1) + _153;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 175\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %29 \"SV_Target\"\nOpName %54 \"SparseTexel\"\nOpName %62 \"\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypeVector %5 2\n%28 = OpTypePointer Output %27\n%29 = OpVariable %28 Output\n%36 = OpTypePointer Input %5\n%38 = OpTypeInt 32 0\n%39 = OpConstant %38 0\n%42 = OpConstant %38 1\n%45 = OpConstant %38 2\n%48 = OpConstant %38 3\n%50 = OpTypeSampledImage %6\n%52 = OpTypeInt 32 1\n%53 = OpConstant %52 1\n%54 = OpTypeStruct %38 %24\n%62 = OpTypeStruct %5 %5 %5 %5 %38\n%67 = OpTypeBool\n%70 = OpConstant %5 1\n%71 = OpConstant %5 0\n%72 = OpTypeSampledImage %9\n%74 = OpConstant %52 2\n%88 = OpTypeSampledImage %12\n%90 = OpConstant %52 -3\n%91 = OpConstant %52 -4\n%96 = OpTypeVector %52 2\n%97 = OpConstantComposite %96 %90 %91\n%110 = OpTypeSampledImage %15\n%112 = OpConstant %52 4\n%113 = OpConstant %52 -5\n%115 = OpTypeVector %5 3\n%119 = OpConstantComposite %96 %112 %113\n%131 = OpTypeSampledImage %18\n%133 = OpConstant %52 5\n%134 = OpConstant %52 6\n%135 = OpConstant %52 7\n%140 = OpTypeVector %52 3\n%141 = OpConstantComposite %140 %133 %134 %135\n%170 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %173\n%173 = OpLabel\n%30 = OpLoad %18 %20\n%31 = OpLoad %15 %17\n%32 = OpLoad %12 %14\n%33 = OpLoad %9 %11\n%34 = OpLoad %6 %8\n%35 = OpLoad %21 %23\n%37 = OpAccessChain %36 %26 %39\n%40 = OpLoad %5 %37\n%41 = OpAccessChain %36 %26 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %36 %26 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %36 %26 %48\n%49 = OpLoad %5 %47\n%51 = OpSampledImage %50 %34 %35\n%55 = OpImageSparseSampleExplicitLod %54 %51 %40 Grad|ConstOffset %46 %49 %53\n%56 = OpCompositeExtract %38 %55 0\n%57 = OpCompositeExtract %24 %55 1\n%58 = OpCompositeExtract %5 %57 0\n%59 = OpCompositeExtract %5 %57 1\n%60 = OpCompositeExtract %5 %57 2\n%61 = OpCompositeExtract %5 %57 3\n%63 = OpCompositeConstruct %62 %58 %59 %60 %61 %56\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpCompositeExtract %5 %63 1\n%66 = OpCompositeExtract %38 %63 4\n%68 = OpImageSparseTexelsResident %67 %66\n%69 = OpSelect %5 %68 %70 %71\n%73 = OpSampledImage %72 %33 %35\n%76 = OpCompositeConstruct %27 %40 %43\n%75 = OpImageSparseSampleExplicitLod %54 %73 %76 Grad|ConstOffset %46 %43 %74\n%77 = OpCompositeExtract %38 %75 0\n%78 = OpCompositeExtract %24 %75 1\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpCompositeExtract %5 %78 1\n%81 = OpCompositeExtract %5 %78 2\n%82 = OpCompositeExtract %5 %78 3\n%83 = OpCompositeConstruct %62 %79 %80 %81 %82 %77\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpCompositeExtract %38 %83 4\n%86 = OpImageSparseTexelsResident %67 %85\n%87 = OpSelect %5 %86 %70 %71\n%89 = OpSampledImage %88 %32 %35\n%93 = OpCompositeConstruct %27 %40 %43\n%94 = OpCompositeConstruct %27 %46 %46\n%95 = OpCompositeConstruct %27 %49 %49\n%92 = OpImageSparseSampleExplicitLod %54 %89 %93 Grad|ConstOffset %94 %95 %97\n%98 = OpCompositeExtract %38 %92 0\n%99 = OpCompositeExtract %24 %92 1\n%100 = OpCompositeExtract %5 %99 0\n%101 = OpCompositeExtract %5 %99 1\n%102 = OpCompositeExtract %5 %99 2\n%103 = OpCompositeExtract %5 %99 3\n%104 = OpCompositeConstruct %62 %100 %101 %102 %103 %98\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpCompositeExtract %5 %104 1\n%107 = OpCompositeExtract %38 %104 4\n%108 = OpImageSparseTexelsResident %67 %107\n%109 = OpSelect %5 %108 %70 %71\n%111 = OpSampledImage %110 %31 %35\n%116 = OpCompositeConstruct %115 %40 %43 %46\n%117 = OpCompositeConstruct %27 %46 %46\n%118 = OpCompositeConstruct %27 %49 %49\n%114 = OpImageSparseSampleExplicitLod %54 %111 %116 Grad|ConstOffset %117 %118 %119\n%120 = OpCompositeExtract %38 %114 0\n%121 = OpCompositeExtract %24 %114 1\n%122 = OpCompositeExtract %5 %121 0\n%123 = OpCompositeExtract %5 %121 1\n%124 = OpCompositeExtract %5 %121 2\n%125 = OpCompositeExtract %5 %121 3\n%126 = OpCompositeConstruct %62 %122 %123 %124 %125 %120\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpCompositeExtract %38 %126 4\n%129 = OpImageSparseTexelsResident %67 %128\n%130 = OpSelect %5 %129 %70 %71\n%132 = OpSampledImage %131 %30 %35\n%137 = OpCompositeConstruct %115 %40 %43 %46\n%138 = OpCompositeConstruct %115 %46 %46 %46\n%139 = OpCompositeConstruct %115 %49 %49 %49\n%136 = OpImageSparseSampleExplicitLod %54 %132 %137 Grad|ConstOffset %138 %139 %141\n%142 = OpCompositeExtract %38 %136 0\n%143 = OpCompositeExtract %24 %136 1\n%144 = OpCompositeExtract %5 %143 0\n%145 = OpCompositeExtract %5 %143 1\n%146 = OpCompositeExtract %5 %143 2\n%147 = OpCompositeExtract %5 %143 3\n%148 = OpCompositeConstruct %62 %144 %145 %146 %147 %142\n%149 = OpCompositeExtract %5 %148 0\n%150 = OpCompositeExtract %5 %148 1\n%151 = OpCompositeExtract %38 %148 4\n%152 = OpImageSparseTexelsResident %67 %151\n%153 = OpSelect %5 %152 %70 %71\n%154 = OpFAdd %5 %84 %69\n%155 = OpFAdd %5 %87 %154\n%156 = OpFAdd %5 %155 %64\n%157 = OpFAdd %5 %156 %105\n%158 = OpFAdd %5 %157 %109\n%159 = OpFAdd %5 %158 %127\n%160 = OpFAdd %5 %159 %130\n%161 = OpFAdd %5 %160 %149\n%162 = OpFAdd %5 %161 %153\n%163 = OpFAdd %5 %155 %65\n%164 = OpFAdd %5 %163 %106\n%165 = OpFAdd %5 %164 %109\n%166 = OpFAdd %5 %165 %127\n%167 = OpFAdd %5 %166 %130\n%168 = OpFAdd %5 %167 %150\n%169 = OpFAdd %5 %168 %153\n%171 = OpAccessChain %170 %29 %39\nOpStore %171 %162\n%172 = OpAccessChain %170 %29 %42\nOpStore %172 %169\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-grad-offset.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _54 = textureGradOffset(sampler1D(_8, _23), TEXCOORD.x, TEXCOORD.z, TEXCOORD.w, 1);\n    vec4 _67 = textureGradOffset(sampler2D(_14, _23), vec2(TEXCOORD.x, TEXCOORD.y), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(-3, -4));\n    vec4 _91 = textureGradOffset(sampler3D(_20, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(TEXCOORD.z), vec3(TEXCOORD.w), ivec3(5, 6, 7));\n    float _99 = textureGradOffset(sampler2DArray(_17, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec2(TEXCOORD.z), vec2(TEXCOORD.w), ivec2(4, -5)).x + textureGradOffset(sampler1DArray(_11, _23), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.z, TEXCOORD.y, 2).x;\n    SV_Target.x = ((_67.x + _54.x) + _99) + _91.x;\n    SV_Target.y = ((_67.y + _54.y) + _99) + _91.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 111\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypeVector %5 2\n%28 = OpTypePointer Output %27\n%29 = OpVariable %28 Output\n%36 = OpTypePointer Input %5\n%38 = OpTypeInt 32 0\n%39 = OpConstant %38 0\n%42 = OpConstant %38 1\n%45 = OpConstant %38 2\n%48 = OpConstant %38 3\n%50 = OpTypeSampledImage %6\n%52 = OpTypeInt 32 1\n%53 = OpConstant %52 1\n%57 = OpTypeSampledImage %9\n%59 = OpConstant %52 2\n%63 = OpTypeSampledImage %12\n%65 = OpConstant %52 -3\n%66 = OpConstant %52 -4\n%71 = OpTypeVector %52 2\n%72 = OpConstantComposite %71 %65 %66\n%75 = OpTypeSampledImage %15\n%77 = OpConstant %52 4\n%78 = OpConstant %52 -5\n%80 = OpTypeVector %5 3\n%84 = OpConstantComposite %71 %77 %78\n%86 = OpTypeSampledImage %18\n%88 = OpConstant %52 5\n%89 = OpConstant %52 6\n%90 = OpConstant %52 7\n%95 = OpTypeVector %52 3\n%96 = OpConstantComposite %95 %88 %89 %90\n%106 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %109\n%109 = OpLabel\n%30 = OpLoad %18 %20\n%31 = OpLoad %15 %17\n%32 = OpLoad %12 %14\n%33 = OpLoad %9 %11\n%34 = OpLoad %6 %8\n%35 = OpLoad %21 %23\n%37 = OpAccessChain %36 %26 %39\n%40 = OpLoad %5 %37\n%41 = OpAccessChain %36 %26 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %36 %26 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %36 %26 %48\n%49 = OpLoad %5 %47\n%51 = OpSampledImage %50 %34 %35\n%54 = OpImageSampleExplicitLod %24 %51 %40 Grad|ConstOffset %46 %49 %53\n%55 = OpCompositeExtract %5 %54 0\n%56 = OpCompositeExtract %5 %54 1\n%58 = OpSampledImage %57 %33 %35\n%61 = OpCompositeConstruct %27 %40 %43\n%60 = OpImageSampleExplicitLod %24 %58 %61 Grad|ConstOffset %46 %43 %59\n%62 = OpCompositeExtract %5 %60 0\n%64 = OpSampledImage %63 %32 %35\n%68 = OpCompositeConstruct %27 %40 %43\n%69 = OpCompositeConstruct %27 %46 %46\n%70 = OpCompositeConstruct %27 %49 %49\n%67 = OpImageSampleExplicitLod %24 %64 %68 Grad|ConstOffset %69 %70 %72\n%73 = OpCompositeExtract %5 %67 0\n%74 = OpCompositeExtract %5 %67 1\n%76 = OpSampledImage %75 %31 %35\n%81 = OpCompositeConstruct %80 %40 %43 %46\n%82 = OpCompositeConstruct %27 %46 %46\n%83 = OpCompositeConstruct %27 %49 %49\n%79 = OpImageSampleExplicitLod %24 %76 %81 Grad|ConstOffset %82 %83 %84\n%85 = OpCompositeExtract %5 %79 0\n%87 = OpSampledImage %86 %30 %35\n%92 = OpCompositeConstruct %80 %40 %43 %46\n%93 = OpCompositeConstruct %80 %46 %46 %46\n%94 = OpCompositeConstruct %80 %49 %49 %49\n%91 = OpImageSampleExplicitLod %24 %87 %92 Grad|ConstOffset %93 %94 %96\n%97 = OpCompositeExtract %5 %91 0\n%98 = OpCompositeExtract %5 %91 1\n%99 = OpFAdd %5 %85 %62\n%100 = OpFAdd %5 %73 %55\n%101 = OpFAdd %5 %100 %99\n%102 = OpFAdd %5 %101 %97\n%103 = OpFAdd %5 %74 %56\n%104 = OpFAdd %5 %103 %99\n%105 = OpFAdd %5 %104 %98\n%107 = OpAccessChain %106 %29 %39\nOpStore %107 %102\n%108 = OpAccessChain %106 %29 %42\nOpStore %108 %105\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-grad.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 1, binding = 5) uniform textureCube _23;\nlayout(set = 1, binding = 6) uniform textureCubeArray _26;\nlayout(set = 0, binding = 0) uniform sampler _29;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _60 = textureGrad(sampler1D(_8, _29), TEXCOORD.x, TEXCOORD.z, TEXCOORD.w);\n    vec4 _70 = textureGrad(sampler2D(_14, _29), vec2(TEXCOORD.x, TEXCOORD.y), vec2(TEXCOORD.z), vec2(TEXCOORD.w));\n    vec4 _86 = textureGrad(sampler3D(_20, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(TEXCOORD.z), vec3(TEXCOORD.w));\n    vec4 _94 = textureGrad(samplerCube(_23, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(TEXCOORD.z), vec3(TEXCOORD.w));\n    float _108 = textureGrad(samplerCubeArray(_26, _29), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w), vec3(TEXCOORD.z), vec3(TEXCOORD.w)).x + (textureGrad(sampler2DArray(_17, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec2(TEXCOORD.z), vec2(TEXCOORD.w)).x + textureGrad(sampler1DArray(_11, _29), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.z, TEXCOORD.y).x);\n    SV_Target.x = (((_108 + _60.x) + _70.x) + _86.x) + _94.x;\n    SV_Target.y = (((_108 + _60.y) + _70.y) + _86.y) + _94.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 122\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeSampler\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeVector %5 4\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%44 = OpTypePointer Input %5\n%46 = OpTypeInt 32 0\n%47 = OpConstant %46 0\n%50 = OpConstant %46 1\n%53 = OpConstant %46 2\n%56 = OpConstant %46 3\n%58 = OpTypeSampledImage %6\n%63 = OpTypeSampledImage %9\n%68 = OpTypeSampledImage %12\n%76 = OpTypeSampledImage %15\n%79 = OpTypeVector %5 3\n%84 = OpTypeSampledImage %18\n%92 = OpTypeSampledImage %21\n%100 = OpTypeSampledImage %24\n%117 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %120\n%120 = OpLabel\n%36 = OpLoad %24 %26\n%37 = OpLoad %21 %23\n%38 = OpLoad %18 %20\n%39 = OpLoad %15 %17\n%40 = OpLoad %12 %14\n%41 = OpLoad %9 %11\n%42 = OpLoad %6 %8\n%43 = OpLoad %27 %29\n%45 = OpAccessChain %44 %32 %47\n%48 = OpLoad %5 %45\n%49 = OpAccessChain %44 %32 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %44 %32 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %44 %32 %56\n%57 = OpLoad %5 %55\n%59 = OpSampledImage %58 %42 %43\n%60 = OpImageSampleExplicitLod %30 %59 %48 Grad %54 %57\n%61 = OpCompositeExtract %5 %60 0\n%62 = OpCompositeExtract %5 %60 1\n%64 = OpSampledImage %63 %41 %43\n%66 = OpCompositeConstruct %33 %48 %51\n%65 = OpImageSampleExplicitLod %30 %64 %66 Grad %54 %51\n%67 = OpCompositeExtract %5 %65 0\n%69 = OpSampledImage %68 %40 %43\n%71 = OpCompositeConstruct %33 %48 %51\n%72 = OpCompositeConstruct %33 %54 %54\n%73 = OpCompositeConstruct %33 %57 %57\n%70 = OpImageSampleExplicitLod %30 %69 %71 Grad %72 %73\n%74 = OpCompositeExtract %5 %70 0\n%75 = OpCompositeExtract %5 %70 1\n%77 = OpSampledImage %76 %39 %43\n%80 = OpCompositeConstruct %79 %48 %51 %54\n%81 = OpCompositeConstruct %33 %54 %54\n%82 = OpCompositeConstruct %33 %57 %57\n%78 = OpImageSampleExplicitLod %30 %77 %80 Grad %81 %82\n%83 = OpCompositeExtract %5 %78 0\n%85 = OpSampledImage %84 %38 %43\n%87 = OpCompositeConstruct %79 %48 %51 %54\n%88 = OpCompositeConstruct %79 %54 %54 %54\n%89 = OpCompositeConstruct %79 %57 %57 %57\n%86 = OpImageSampleExplicitLod %30 %85 %87 Grad %88 %89\n%90 = OpCompositeExtract %5 %86 0\n%91 = OpCompositeExtract %5 %86 1\n%93 = OpSampledImage %92 %37 %43\n%95 = OpCompositeConstruct %79 %48 %51 %54\n%96 = OpCompositeConstruct %79 %54 %54 %54\n%97 = OpCompositeConstruct %79 %57 %57 %57\n%94 = OpImageSampleExplicitLod %30 %93 %95 Grad %96 %97\n%98 = OpCompositeExtract %5 %94 0\n%99 = OpCompositeExtract %5 %94 1\n%101 = OpSampledImage %100 %36 %43\n%103 = OpCompositeConstruct %30 %48 %51 %54 %57\n%104 = OpCompositeConstruct %79 %54 %54 %54\n%105 = OpCompositeConstruct %79 %57 %57 %57\n%102 = OpImageSampleExplicitLod %30 %101 %103 Grad %104 %105\n%106 = OpCompositeExtract %5 %102 0\n%107 = OpFAdd %5 %83 %67\n%108 = OpFAdd %5 %106 %107\n%109 = OpFAdd %5 %108 %61\n%110 = OpFAdd %5 %109 %74\n%111 = OpFAdd %5 %110 %90\n%112 = OpFAdd %5 %111 %98\n%113 = OpFAdd %5 %108 %62\n%114 = OpFAdd %5 %113 %75\n%115 = OpFAdd %5 %114 %91\n%116 = OpFAdd %5 %115 %99\n%118 = OpAccessChain %117 %35 %47\nOpStore %118 %112\n%119 = OpAccessChain %117 %35 %50\nOpStore %119 %116\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-id.frag",
    "content": "#version 460\n\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(gl_SampleID);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpCapability SampleRateShading\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_SampleIndex\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 BuiltIn SampleId\nOpDecorate %7 Flat\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-level-offset-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _62\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _167;\n    vec4 _168;\n    _167 = sparseTextureLodOffsetARB(sampler1D(_8, _23), TEXCOORD.x, TEXCOORD.w, 1, _168);\n    SparseTexel _55 = SparseTexel(_167, _168);\n    vec4 _57 = _55._m1;\n    _62 _63 = _62(_57.x, _57.y, _57.z, _57.w, _55._m0);\n    uint _169;\n    vec4 _170;\n    _169 = sparseTextureLodOffsetARB(sampler1DArray(_11, _23), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w, 2, _170);\n    SparseTexel _75 = SparseTexel(_169, _170);\n    vec4 _78 = _75._m1;\n    _62 _83 = _62(_78.x, _78.y, _78.z, _78.w, _75._m0);\n    uint _171;\n    vec4 _172;\n    _171 = sparseTextureLodOffsetARB(sampler2D(_14, _23), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w, ivec2(2, 3), _172);\n    SparseTexel _91 = SparseTexel(_171, _172);\n    vec4 _96 = _91._m1;\n    _62 _101 = _62(_96.x, _96.y, _96.z, _96.w, _91._m0);\n    float _106 = float(sparseTexelsResidentARB(int(_101._m4)));\n    uint _173;\n    vec4 _174;\n    _173 = sparseTextureLodOffsetARB(sampler2DArray(_17, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w, ivec2(-1, -3), _174);\n    SparseTexel _111 = SparseTexel(_173, _174);\n    vec4 _116 = _111._m1;\n    _62 _121 = _62(_116.x, _116.y, _116.z, _116.w, _111._m0);\n    float _122 = _121._m0;\n    float _125 = float(sparseTexelsResidentARB(int(_121._m4)));\n    uint _175;\n    vec4 _176;\n    _175 = sparseTextureLodOffsetARB(sampler3D(_20, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w, ivec3(-4, -5, 3), _176);\n    SparseTexel _130 = SparseTexel(_175, _176);\n    vec4 _135 = _130._m1;\n    _62 _140 = _62(_135.x, _135.y, _135.z, _135.w, _130._m0);\n    float _145 = float(sparseTexelsResidentARB(int(_140._m4)));\n    float _147 = float(sparseTexelsResidentARB(int(_83._m4))) + (_83._m0 + float(sparseTexelsResidentARB(int(_63._m4))));\n    SV_Target.x = ((((((_147 + _63._m0) + _101._m0) + _106) + _122) + _125) + _140._m0) + _145;\n    SV_Target.y = ((((((_147 + _63._m1) + _101._m1) + _106) + _122) + _125) + _140._m1) + _145;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 167\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %29 \"SV_Target\"\nOpName %54 \"SparseTexel\"\nOpName %62 \"\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypeVector %5 2\n%28 = OpTypePointer Output %27\n%29 = OpVariable %28 Output\n%36 = OpTypePointer Input %5\n%38 = OpTypeInt 32 0\n%39 = OpConstant %38 0\n%42 = OpConstant %38 1\n%45 = OpConstant %38 2\n%48 = OpConstant %38 3\n%50 = OpTypeSampledImage %6\n%52 = OpTypeInt 32 1\n%53 = OpConstant %52 1\n%54 = OpTypeStruct %38 %24\n%62 = OpTypeStruct %5 %5 %5 %5 %38\n%67 = OpTypeBool\n%70 = OpConstant %5 1\n%71 = OpConstant %5 0\n%72 = OpTypeSampledImage %9\n%74 = OpConstant %52 2\n%88 = OpTypeSampledImage %12\n%90 = OpConstant %52 3\n%93 = OpTypeVector %52 2\n%94 = OpConstantComposite %93 %74 %90\n%107 = OpTypeSampledImage %15\n%109 = OpConstant %52 -1\n%110 = OpConstant %52 -3\n%112 = OpTypeVector %5 3\n%114 = OpConstantComposite %93 %109 %110\n%126 = OpTypeSampledImage %18\n%128 = OpConstant %52 -4\n%129 = OpConstant %52 -5\n%132 = OpTypeVector %52 3\n%133 = OpConstantComposite %132 %128 %129 %90\n%162 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %165\n%165 = OpLabel\n%30 = OpLoad %18 %20\n%31 = OpLoad %15 %17\n%32 = OpLoad %12 %14\n%33 = OpLoad %9 %11\n%34 = OpLoad %6 %8\n%35 = OpLoad %21 %23\n%37 = OpAccessChain %36 %26 %39\n%40 = OpLoad %5 %37\n%41 = OpAccessChain %36 %26 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %36 %26 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %36 %26 %48\n%49 = OpLoad %5 %47\n%51 = OpSampledImage %50 %34 %35\n%55 = OpImageSparseSampleExplicitLod %54 %51 %40 Lod|ConstOffset %49 %53\n%56 = OpCompositeExtract %38 %55 0\n%57 = OpCompositeExtract %24 %55 1\n%58 = OpCompositeExtract %5 %57 0\n%59 = OpCompositeExtract %5 %57 1\n%60 = OpCompositeExtract %5 %57 2\n%61 = OpCompositeExtract %5 %57 3\n%63 = OpCompositeConstruct %62 %58 %59 %60 %61 %56\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpCompositeExtract %5 %63 1\n%66 = OpCompositeExtract %38 %63 4\n%68 = OpImageSparseTexelsResident %67 %66\n%69 = OpSelect %5 %68 %70 %71\n%73 = OpSampledImage %72 %33 %35\n%76 = OpCompositeConstruct %27 %40 %43\n%75 = OpImageSparseSampleExplicitLod %54 %73 %76 Lod|ConstOffset %49 %74\n%77 = OpCompositeExtract %38 %75 0\n%78 = OpCompositeExtract %24 %75 1\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpCompositeExtract %5 %78 1\n%81 = OpCompositeExtract %5 %78 2\n%82 = OpCompositeExtract %5 %78 3\n%83 = OpCompositeConstruct %62 %79 %80 %81 %82 %77\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpCompositeExtract %38 %83 4\n%86 = OpImageSparseTexelsResident %67 %85\n%87 = OpSelect %5 %86 %70 %71\n%89 = OpSampledImage %88 %32 %35\n%92 = OpCompositeConstruct %27 %40 %43\n%91 = OpImageSparseSampleExplicitLod %54 %89 %92 Lod|ConstOffset %49 %94\n%95 = OpCompositeExtract %38 %91 0\n%96 = OpCompositeExtract %24 %91 1\n%97 = OpCompositeExtract %5 %96 0\n%98 = OpCompositeExtract %5 %96 1\n%99 = OpCompositeExtract %5 %96 2\n%100 = OpCompositeExtract %5 %96 3\n%101 = OpCompositeConstruct %62 %97 %98 %99 %100 %95\n%102 = OpCompositeExtract %5 %101 0\n%103 = OpCompositeExtract %5 %101 1\n%104 = OpCompositeExtract %38 %101 4\n%105 = OpImageSparseTexelsResident %67 %104\n%106 = OpSelect %5 %105 %70 %71\n%108 = OpSampledImage %107 %31 %35\n%113 = OpCompositeConstruct %112 %40 %43 %46\n%111 = OpImageSparseSampleExplicitLod %54 %108 %113 Lod|ConstOffset %49 %114\n%115 = OpCompositeExtract %38 %111 0\n%116 = OpCompositeExtract %24 %111 1\n%117 = OpCompositeExtract %5 %116 0\n%118 = OpCompositeExtract %5 %116 1\n%119 = OpCompositeExtract %5 %116 2\n%120 = OpCompositeExtract %5 %116 3\n%121 = OpCompositeConstruct %62 %117 %118 %119 %120 %115\n%122 = OpCompositeExtract %5 %121 0\n%123 = OpCompositeExtract %38 %121 4\n%124 = OpImageSparseTexelsResident %67 %123\n%125 = OpSelect %5 %124 %70 %71\n%127 = OpSampledImage %126 %30 %35\n%131 = OpCompositeConstruct %112 %40 %43 %46\n%130 = OpImageSparseSampleExplicitLod %54 %127 %131 Lod|ConstOffset %49 %133\n%134 = OpCompositeExtract %38 %130 0\n%135 = OpCompositeExtract %24 %130 1\n%136 = OpCompositeExtract %5 %135 0\n%137 = OpCompositeExtract %5 %135 1\n%138 = OpCompositeExtract %5 %135 2\n%139 = OpCompositeExtract %5 %135 3\n%140 = OpCompositeConstruct %62 %136 %137 %138 %139 %134\n%141 = OpCompositeExtract %5 %140 0\n%142 = OpCompositeExtract %5 %140 1\n%143 = OpCompositeExtract %38 %140 4\n%144 = OpImageSparseTexelsResident %67 %143\n%145 = OpSelect %5 %144 %70 %71\n%146 = OpFAdd %5 %84 %69\n%147 = OpFAdd %5 %87 %146\n%148 = OpFAdd %5 %147 %64\n%149 = OpFAdd %5 %148 %102\n%150 = OpFAdd %5 %149 %106\n%151 = OpFAdd %5 %150 %122\n%152 = OpFAdd %5 %151 %125\n%153 = OpFAdd %5 %152 %141\n%154 = OpFAdd %5 %153 %145\n%155 = OpFAdd %5 %147 %65\n%156 = OpFAdd %5 %155 %103\n%157 = OpFAdd %5 %156 %106\n%158 = OpFAdd %5 %157 %122\n%159 = OpFAdd %5 %158 %125\n%160 = OpFAdd %5 %159 %142\n%161 = OpFAdd %5 %160 %145\n%163 = OpAccessChain %162 %29 %39\nOpStore %163 %154\n%164 = OpAccessChain %162 %29 %42\nOpStore %164 %161\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-level-offset.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _54 = textureLodOffset(sampler1D(_8, _23), TEXCOORD.x, TEXCOORD.w, 1);\n    vec4 _66 = textureLodOffset(sampler2D(_14, _23), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w, ivec2(2, 3));\n    vec4 _85 = textureLodOffset(sampler3D(_20, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w, ivec3(-4, -5, 3));\n    float _91 = textureLodOffset(sampler2DArray(_17, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w, ivec2(-1, -3)).x + textureLodOffset(sampler1DArray(_11, _23), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w, 2).x;\n    SV_Target.x = ((_66.x + _54.x) + _91) + _85.x;\n    SV_Target.y = ((_66.y + _54.y) + _91) + _85.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 103\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypeVector %5 2\n%28 = OpTypePointer Output %27\n%29 = OpVariable %28 Output\n%36 = OpTypePointer Input %5\n%38 = OpTypeInt 32 0\n%39 = OpConstant %38 0\n%42 = OpConstant %38 1\n%45 = OpConstant %38 2\n%48 = OpConstant %38 3\n%50 = OpTypeSampledImage %6\n%52 = OpTypeInt 32 1\n%53 = OpConstant %52 1\n%57 = OpTypeSampledImage %9\n%59 = OpConstant %52 2\n%63 = OpTypeSampledImage %12\n%65 = OpConstant %52 3\n%68 = OpTypeVector %52 2\n%69 = OpConstantComposite %68 %59 %65\n%72 = OpTypeSampledImage %15\n%74 = OpConstant %52 -1\n%75 = OpConstant %52 -3\n%77 = OpTypeVector %5 3\n%79 = OpConstantComposite %68 %74 %75\n%81 = OpTypeSampledImage %18\n%83 = OpConstant %52 -4\n%84 = OpConstant %52 -5\n%87 = OpTypeVector %52 3\n%88 = OpConstantComposite %87 %83 %84 %65\n%98 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %101\n%101 = OpLabel\n%30 = OpLoad %18 %20\n%31 = OpLoad %15 %17\n%32 = OpLoad %12 %14\n%33 = OpLoad %9 %11\n%34 = OpLoad %6 %8\n%35 = OpLoad %21 %23\n%37 = OpAccessChain %36 %26 %39\n%40 = OpLoad %5 %37\n%41 = OpAccessChain %36 %26 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %36 %26 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %36 %26 %48\n%49 = OpLoad %5 %47\n%51 = OpSampledImage %50 %34 %35\n%54 = OpImageSampleExplicitLod %24 %51 %40 Lod|ConstOffset %49 %53\n%55 = OpCompositeExtract %5 %54 0\n%56 = OpCompositeExtract %5 %54 1\n%58 = OpSampledImage %57 %33 %35\n%61 = OpCompositeConstruct %27 %40 %43\n%60 = OpImageSampleExplicitLod %24 %58 %61 Lod|ConstOffset %49 %59\n%62 = OpCompositeExtract %5 %60 0\n%64 = OpSampledImage %63 %32 %35\n%67 = OpCompositeConstruct %27 %40 %43\n%66 = OpImageSampleExplicitLod %24 %64 %67 Lod|ConstOffset %49 %69\n%70 = OpCompositeExtract %5 %66 0\n%71 = OpCompositeExtract %5 %66 1\n%73 = OpSampledImage %72 %31 %35\n%78 = OpCompositeConstruct %77 %40 %43 %46\n%76 = OpImageSampleExplicitLod %24 %73 %78 Lod|ConstOffset %49 %79\n%80 = OpCompositeExtract %5 %76 0\n%82 = OpSampledImage %81 %30 %35\n%86 = OpCompositeConstruct %77 %40 %43 %46\n%85 = OpImageSampleExplicitLod %24 %82 %86 Lod|ConstOffset %49 %88\n%89 = OpCompositeExtract %5 %85 0\n%90 = OpCompositeExtract %5 %85 1\n%91 = OpFAdd %5 %80 %62\n%92 = OpFAdd %5 %70 %55\n%93 = OpFAdd %5 %92 %91\n%94 = OpFAdd %5 %93 %89\n%95 = OpFAdd %5 %71 %56\n%96 = OpFAdd %5 %95 %91\n%97 = OpFAdd %5 %96 %90\n%99 = OpAccessChain %98 %29 %39\nOpStore %99 %94\n%100 = OpAccessChain %98 %29 %42\nOpStore %100 %97\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-level.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 1, binding = 5) uniform textureCube _23;\nlayout(set = 1, binding = 6) uniform textureCubeArray _26;\nlayout(set = 0, binding = 0) uniform sampler _29;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _60 = textureLod(sampler1D(_8, _29), TEXCOORD.x, TEXCOORD.w);\n    vec4 _70 = textureLod(sampler2D(_14, _29), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w);\n    vec4 _82 = textureLod(sampler3D(_20, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w);\n    vec4 _88 = textureLod(samplerCube(_23, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w);\n    float _98 = textureLod(samplerCubeArray(_26, _29), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w), TEXCOORD.w).x + (textureLod(sampler2DArray(_17, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), TEXCOORD.w).x + textureLod(sampler1DArray(_11, _29), vec2(TEXCOORD.x, TEXCOORD.y), TEXCOORD.w).x);\n    SV_Target.x = (((_98 + _60.x) + _70.x) + _82.x) + _88.x;\n    SV_Target.y = (((_98 + _60.y) + _70.y) + _82.y) + _88.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 112\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeSampler\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeVector %5 4\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%44 = OpTypePointer Input %5\n%46 = OpTypeInt 32 0\n%47 = OpConstant %46 0\n%50 = OpConstant %46 1\n%53 = OpConstant %46 2\n%56 = OpConstant %46 3\n%58 = OpTypeSampledImage %6\n%63 = OpTypeSampledImage %9\n%68 = OpTypeSampledImage %12\n%74 = OpTypeSampledImage %15\n%77 = OpTypeVector %5 3\n%80 = OpTypeSampledImage %18\n%86 = OpTypeSampledImage %21\n%92 = OpTypeSampledImage %24\n%107 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%36 = OpLoad %24 %26\n%37 = OpLoad %21 %23\n%38 = OpLoad %18 %20\n%39 = OpLoad %15 %17\n%40 = OpLoad %12 %14\n%41 = OpLoad %9 %11\n%42 = OpLoad %6 %8\n%43 = OpLoad %27 %29\n%45 = OpAccessChain %44 %32 %47\n%48 = OpLoad %5 %45\n%49 = OpAccessChain %44 %32 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %44 %32 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %44 %32 %56\n%57 = OpLoad %5 %55\n%59 = OpSampledImage %58 %42 %43\n%60 = OpImageSampleExplicitLod %30 %59 %48 Lod %57\n%61 = OpCompositeExtract %5 %60 0\n%62 = OpCompositeExtract %5 %60 1\n%64 = OpSampledImage %63 %41 %43\n%66 = OpCompositeConstruct %33 %48 %51\n%65 = OpImageSampleExplicitLod %30 %64 %66 Lod %57\n%67 = OpCompositeExtract %5 %65 0\n%69 = OpSampledImage %68 %40 %43\n%71 = OpCompositeConstruct %33 %48 %51\n%70 = OpImageSampleExplicitLod %30 %69 %71 Lod %57\n%72 = OpCompositeExtract %5 %70 0\n%73 = OpCompositeExtract %5 %70 1\n%75 = OpSampledImage %74 %39 %43\n%78 = OpCompositeConstruct %77 %48 %51 %54\n%76 = OpImageSampleExplicitLod %30 %75 %78 Lod %57\n%79 = OpCompositeExtract %5 %76 0\n%81 = OpSampledImage %80 %38 %43\n%83 = OpCompositeConstruct %77 %48 %51 %54\n%82 = OpImageSampleExplicitLod %30 %81 %83 Lod %57\n%84 = OpCompositeExtract %5 %82 0\n%85 = OpCompositeExtract %5 %82 1\n%87 = OpSampledImage %86 %37 %43\n%89 = OpCompositeConstruct %77 %48 %51 %54\n%88 = OpImageSampleExplicitLod %30 %87 %89 Lod %57\n%90 = OpCompositeExtract %5 %88 0\n%91 = OpCompositeExtract %5 %88 1\n%93 = OpSampledImage %92 %36 %43\n%95 = OpCompositeConstruct %30 %48 %51 %54 %57\n%94 = OpImageSampleExplicitLod %30 %93 %95 Lod %57\n%96 = OpCompositeExtract %5 %94 0\n%97 = OpFAdd %5 %79 %67\n%98 = OpFAdd %5 %96 %97\n%99 = OpFAdd %5 %98 %61\n%100 = OpFAdd %5 %99 %72\n%101 = OpFAdd %5 %100 %84\n%102 = OpFAdd %5 %101 %90\n%103 = OpFAdd %5 %98 %62\n%104 = OpFAdd %5 %103 %73\n%105 = OpFAdd %5 %104 %85\n%106 = OpFAdd %5 %105 %91\n%108 = OpAccessChain %107 %35 %47\nOpStore %108 %102\n%109 = OpAccessChain %107 %35 %50\nOpStore %109 %106\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-offset-dynamic.noglsl.invalid.sm67.frag",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 144\n; Schema: 0\nOpCapability Shader\nOpCapability ImageGatherExtended\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %25 \"\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %24 ArrayStride 16\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 0\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeInt 32 0\n%22 = OpConstant %21 2\n%23 = OpTypeVector %5 4\n%24 = OpTypeArray %23 %22\n%25 = OpTypeStruct %24\n%26 = OpTypePointer Uniform %25\n%27 = OpVariable %26 Uniform\n%28 = OpTypeSampler\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypePointer Input %23\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%36 = OpTypePointer Input %5\n%38 = OpConstant %21 0\n%41 = OpConstant %21 1\n%45 = OpTypePointer Uniform %23\n%48 = OpTypeVector %21 4\n%53 = OpTypeSampledImage %6\n%55 = OpTypeInt 32 1\n%57 = OpConstant %5 0\n%60 = OpConstant %55 0\n%61 = OpConstant %55 4\n%70 = OpTypeSampledImage %9\n%84 = OpTypeSampledImage %12\n%90 = OpTypeVector %55 2\n%102 = OpTypeSampledImage %15\n%107 = OpTypeVector %5 3\n%120 = OpTypeSampledImage %18\n%127 = OpTypeVector %55 3\n%139 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %142\n%142 = OpLabel\n%37 = OpAccessChain %36 %32 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %36 %32 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %36 %32 %22\n%44 = OpLoad %5 %43\n%46 = OpAccessChain %45 %27 %38 %38\n%47 = OpLoad %23 %46\n%49 = OpBitcast %48 %47\n%50 = OpCompositeExtract %21 %49 0\n%51 = OpLoad %6 %8\n%52 = OpLoad %28 %30\n%54 = OpSampledImage %53 %51 %52\n%56 = OpBitcast %55 %50\n%59 = OpBitFieldSExtract %55 %56 %60 %61\n%58 = OpImageSampleImplicitLod %23 %54 %39 Offset %59\n%62 = OpCompositeExtract %5 %58 0\n%63 = OpCompositeExtract %5 %58 1\n%64 = OpAccessChain %45 %27 %38 %38\n%65 = OpLoad %23 %64\n%66 = OpBitcast %48 %65\n%67 = OpCompositeExtract %21 %66 0\n%68 = OpLoad %9 %11\n%69 = OpLoad %28 %30\n%71 = OpSampledImage %70 %68 %69\n%72 = OpBitcast %55 %67\n%74 = OpCompositeConstruct %33 %39 %42\n%75 = OpBitFieldSExtract %55 %72 %60 %61\n%73 = OpImageSampleImplicitLod %23 %71 %74 Offset %75\n%76 = OpCompositeExtract %5 %73 0\n%77 = OpAccessChain %45 %27 %38 %38\n%78 = OpLoad %23 %77\n%79 = OpBitcast %48 %78\n%80 = OpCompositeExtract %21 %79 1\n%81 = OpCompositeExtract %21 %79 2\n%82 = OpLoad %12 %14\n%83 = OpLoad %28 %30\n%85 = OpSampledImage %84 %82 %83\n%86 = OpBitcast %55 %80\n%87 = OpBitcast %55 %81\n%89 = OpCompositeConstruct %33 %39 %42\n%91 = OpCompositeConstruct %90 %86 %87\n%92 = OpBitFieldSExtract %90 %91 %60 %61\n%88 = OpImageSampleImplicitLod %23 %85 %89 Offset %92\n%93 = OpCompositeExtract %5 %88 0\n%94 = OpCompositeExtract %5 %88 1\n%95 = OpAccessChain %45 %27 %38 %38\n%96 = OpLoad %23 %95\n%97 = OpBitcast %48 %96\n%98 = OpCompositeExtract %21 %97 1\n%99 = OpCompositeExtract %21 %97 2\n%100 = OpLoad %15 %17\n%101 = OpLoad %28 %30\n%103 = OpSampledImage %102 %100 %101\n%104 = OpBitcast %55 %98\n%105 = OpBitcast %55 %99\n%108 = OpCompositeConstruct %107 %39 %42 %44\n%109 = OpCompositeConstruct %90 %104 %105\n%110 = OpBitFieldSExtract %90 %109 %60 %61\n%106 = OpImageSampleImplicitLod %23 %103 %108 Offset %110\n%111 = OpCompositeExtract %5 %106 0\n%112 = OpAccessChain %45 %27 %38 %41\n%113 = OpLoad %23 %112\n%114 = OpBitcast %48 %113\n%115 = OpCompositeExtract %21 %114 0\n%116 = OpCompositeExtract %21 %114 1\n%117 = OpCompositeExtract %21 %114 2\n%118 = OpLoad %18 %20\n%119 = OpLoad %28 %30\n%121 = OpSampledImage %120 %118 %119\n%122 = OpBitcast %55 %115\n%123 = OpBitcast %55 %116\n%124 = OpBitcast %55 %117\n%126 = OpCompositeConstruct %107 %39 %42 %44\n%128 = OpCompositeConstruct %127 %122 %123 %124\n%129 = OpBitFieldSExtract %127 %128 %60 %61\n%125 = OpImageSampleImplicitLod %23 %121 %126 Offset %129\n%130 = OpCompositeExtract %5 %125 0\n%131 = OpCompositeExtract %5 %125 1\n%132 = OpFAdd %5 %111 %76\n%133 = OpFAdd %5 %93 %62\n%134 = OpFAdd %5 %133 %132\n%135 = OpFAdd %5 %134 %130\n%136 = OpFAdd %5 %94 %63\n%137 = OpFAdd %5 %136 %132\n%138 = OpFAdd %5 %137 %131\n%140 = OpAccessChain %139 %35 %38\nOpStore %140 %135\n%141 = OpAccessChain %139 %35 %41\nOpStore %141 %138\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample-offset.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 0, binding = 0) uniform sampler _23;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _52 = textureOffset(sampler1D(_8, _23), TEXCOORD.x, 1);\n    vec4 _65 = textureOffset(sampler2D(_14, _23), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(3, 4));\n    vec4 _83 = textureOffset(sampler3D(_20, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec3(7, 6, 5));\n    float _89 = textureOffset(sampler2DArray(_17, _23), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec2(5, 6)).x + textureOffset(sampler1DArray(_11, _23), vec2(TEXCOORD.x, TEXCOORD.y), 2).x;\n    SV_Target.x = ((_65.x + _52.x) + _89) + _83.x;\n    SV_Target.y = ((_65.y + _52.y) + _89) + _83.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 101\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %26 \"TEXCOORD\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 Location 0\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeSampler\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypeVector %5 2\n%28 = OpTypePointer Output %27\n%29 = OpVariable %28 Output\n%36 = OpTypePointer Input %5\n%38 = OpTypeInt 32 0\n%39 = OpConstant %38 0\n%42 = OpConstant %38 1\n%45 = OpConstant %38 2\n%47 = OpTypeSampledImage %6\n%49 = OpTypeInt 32 1\n%50 = OpConstant %49 1\n%51 = OpConstant %5 0\n%55 = OpTypeSampledImage %9\n%57 = OpConstant %49 2\n%61 = OpTypeSampledImage %12\n%63 = OpConstant %49 3\n%64 = OpConstant %49 4\n%67 = OpTypeVector %49 2\n%68 = OpConstantComposite %67 %63 %64\n%71 = OpTypeSampledImage %15\n%73 = OpConstant %49 5\n%74 = OpConstant %49 6\n%76 = OpTypeVector %5 3\n%78 = OpConstantComposite %67 %73 %74\n%80 = OpTypeSampledImage %18\n%82 = OpConstant %49 7\n%85 = OpTypeVector %49 3\n%86 = OpConstantComposite %85 %82 %74 %73\n%96 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %99\n%99 = OpLabel\n%30 = OpLoad %18 %20\n%31 = OpLoad %15 %17\n%32 = OpLoad %12 %14\n%33 = OpLoad %9 %11\n%34 = OpLoad %6 %8\n%35 = OpLoad %21 %23\n%37 = OpAccessChain %36 %26 %39\n%40 = OpLoad %5 %37\n%41 = OpAccessChain %36 %26 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %36 %26 %45\n%46 = OpLoad %5 %44\n%48 = OpSampledImage %47 %34 %35\n%52 = OpImageSampleImplicitLod %24 %48 %40 ConstOffset %50\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpCompositeExtract %5 %52 1\n%56 = OpSampledImage %55 %33 %35\n%59 = OpCompositeConstruct %27 %40 %43\n%58 = OpImageSampleImplicitLod %24 %56 %59 ConstOffset %57\n%60 = OpCompositeExtract %5 %58 0\n%62 = OpSampledImage %61 %32 %35\n%66 = OpCompositeConstruct %27 %40 %43\n%65 = OpImageSampleImplicitLod %24 %62 %66 ConstOffset %68\n%69 = OpCompositeExtract %5 %65 0\n%70 = OpCompositeExtract %5 %65 1\n%72 = OpSampledImage %71 %31 %35\n%77 = OpCompositeConstruct %76 %40 %43 %46\n%75 = OpImageSampleImplicitLod %24 %72 %77 ConstOffset %78\n%79 = OpCompositeExtract %5 %75 0\n%81 = OpSampledImage %80 %30 %35\n%84 = OpCompositeConstruct %76 %40 %43 %46\n%83 = OpImageSampleImplicitLod %24 %81 %84 ConstOffset %86\n%87 = OpCompositeExtract %5 %83 0\n%88 = OpCompositeExtract %5 %83 1\n%89 = OpFAdd %5 %79 %60\n%90 = OpFAdd %5 %69 %53\n%91 = OpFAdd %5 %90 %89\n%92 = OpFAdd %5 %91 %87\n%93 = OpFAdd %5 %70 %54\n%94 = OpFAdd %5 %93 %89\n%95 = OpFAdd %5 %94 %88\n%97 = OpAccessChain %96 %29 %39\nOpStore %97 %92\n%98 = OpAccessChain %96 %29 %42\nOpStore %98 %95\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sample.frag",
    "content": "#version 460\n\nlayout(set = 1, binding = 0) uniform texture1D _8;\nlayout(set = 1, binding = 1) uniform texture1DArray _11;\nlayout(set = 1, binding = 2) uniform texture2D _14;\nlayout(set = 1, binding = 3) uniform texture2DArray _17;\nlayout(set = 1, binding = 4) uniform texture3D _20;\nlayout(set = 1, binding = 5) uniform textureCube _23;\nlayout(set = 1, binding = 6) uniform textureCubeArray _26;\nlayout(set = 0, binding = 0) uniform sampler _29;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _61 = texture(sampler1D(_8, _29), TEXCOORD.x);\n    vec4 _71 = texture(sampler2D(_14, _29), vec2(TEXCOORD.x, TEXCOORD.y));\n    vec4 _83 = texture(sampler3D(_20, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    vec4 _89 = texture(samplerCube(_23, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    float _99 = texture(samplerCubeArray(_26, _29), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w)).x + (texture(sampler2DArray(_17, _29), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x + texture(sampler1DArray(_11, _29), vec2(TEXCOORD.x, TEXCOORD.y)).x);\n    SV_Target.x = (((_99 + _61.x) + _71.x) + _83.x) + _89.x;\n    SV_Target.y = (((_99 + _61.y) + _71.y) + _83.y) + _89.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 113\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %32 \"TEXCOORD\"\nOpName %35 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 2\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 3\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 4\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 5\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 6\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %32 Location 0\nOpDecorate %35 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeSampler\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeVector %5 4\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 2\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%44 = OpTypePointer Input %5\n%46 = OpTypeInt 32 0\n%47 = OpConstant %46 0\n%50 = OpConstant %46 1\n%53 = OpConstant %46 2\n%56 = OpConstant %46 3\n%58 = OpTypeSampledImage %6\n%60 = OpConstant %5 0\n%64 = OpTypeSampledImage %9\n%69 = OpTypeSampledImage %12\n%75 = OpTypeSampledImage %15\n%78 = OpTypeVector %5 3\n%81 = OpTypeSampledImage %18\n%87 = OpTypeSampledImage %21\n%93 = OpTypeSampledImage %24\n%108 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %111\n%111 = OpLabel\n%36 = OpLoad %24 %26\n%37 = OpLoad %21 %23\n%38 = OpLoad %18 %20\n%39 = OpLoad %15 %17\n%40 = OpLoad %12 %14\n%41 = OpLoad %9 %11\n%42 = OpLoad %6 %8\n%43 = OpLoad %27 %29\n%45 = OpAccessChain %44 %32 %47\n%48 = OpLoad %5 %45\n%49 = OpAccessChain %44 %32 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %44 %32 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %44 %32 %56\n%57 = OpLoad %5 %55\n%59 = OpSampledImage %58 %42 %43\n%61 = OpImageSampleImplicitLod %30 %59 %48 None\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpCompositeExtract %5 %61 1\n%65 = OpSampledImage %64 %41 %43\n%67 = OpCompositeConstruct %33 %48 %51\n%66 = OpImageSampleImplicitLod %30 %65 %67 None\n%68 = OpCompositeExtract %5 %66 0\n%70 = OpSampledImage %69 %40 %43\n%72 = OpCompositeConstruct %33 %48 %51\n%71 = OpImageSampleImplicitLod %30 %70 %72 None\n%73 = OpCompositeExtract %5 %71 0\n%74 = OpCompositeExtract %5 %71 1\n%76 = OpSampledImage %75 %39 %43\n%79 = OpCompositeConstruct %78 %48 %51 %54\n%77 = OpImageSampleImplicitLod %30 %76 %79 None\n%80 = OpCompositeExtract %5 %77 0\n%82 = OpSampledImage %81 %38 %43\n%84 = OpCompositeConstruct %78 %48 %51 %54\n%83 = OpImageSampleImplicitLod %30 %82 %84 None\n%85 = OpCompositeExtract %5 %83 0\n%86 = OpCompositeExtract %5 %83 1\n%88 = OpSampledImage %87 %37 %43\n%90 = OpCompositeConstruct %78 %48 %51 %54\n%89 = OpImageSampleImplicitLod %30 %88 %90 None\n%91 = OpCompositeExtract %5 %89 0\n%92 = OpCompositeExtract %5 %89 1\n%94 = OpSampledImage %93 %36 %43\n%96 = OpCompositeConstruct %30 %48 %51 %54 %57\n%95 = OpImageSampleImplicitLod %30 %94 %96 None\n%97 = OpCompositeExtract %5 %95 0\n%98 = OpFAdd %5 %80 %68\n%99 = OpFAdd %5 %97 %98\n%100 = OpFAdd %5 %99 %62\n%101 = OpFAdd %5 %100 %73\n%102 = OpFAdd %5 %101 %85\n%103 = OpFAdd %5 %102 %91\n%104 = OpFAdd %5 %99 %63\n%105 = OpFAdd %5 %104 %74\n%106 = OpFAdd %5 %105 %86\n%107 = OpFAdd %5 %106 %92\n%109 = OpAccessChain %108 %35 %47\nOpStore %109 %103\n%110 = OpAccessChain %108 %35 %50\nOpStore %110 %107\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/saturate.frag",
    "content": "#version 460\n#extension GL_EXT_spirv_intrinsics : require\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float spvNClamp(float, float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec2 spvNClamp(vec2, vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec3 spvNClamp(vec3, vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec4 spvNClamp(vec4, vec4, vec4);\n\nvoid main()\n{\n    SV_Target = spvNClamp(A, 0.0, 1.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 17\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%12 = OpConstant %5 0\n%13 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %15\n%15 = OpLabel\n%10 = OpLoad %5 %7\n%14 = OpExtInst %5 %11 NClamp %10 %12 %13\nOpStore %9 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sin.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = sin(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Sin %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sm64-packed-arithmetic.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nlayout(set = 0, binding = 2, std430) restrict readonly buffer _17_19\n{\n    u16vec2 _m0[];\n} _19;\n\nlayout(set = 0, binding = 3, std430) restrict readonly buffer _21_23\n{\n    u16vec2 _m0[];\n} _23;\n\nlayout(set = 0, binding = 0, std430) buffer _25_27\n{\n    uint _m0[];\n} _27;\n\nlayout(set = 0, binding = 1, std430) buffer _29_31\n{\n    uint _m0[];\n} _31;\n\nvoid main()\n{\n    _27._m0[gl_GlobalInvocationID.x] = (((_27._m0[gl_GlobalInvocationID.x] + (bitfieldExtract(_9._m0[gl_GlobalInvocationID.x], int(0u), int(8u)) * bitfieldExtract(_13._m0[gl_GlobalInvocationID.x], int(0u), int(8u)))) + (bitfieldExtract(_9._m0[gl_GlobalInvocationID.x], int(8u), int(8u)) * bitfieldExtract(_13._m0[gl_GlobalInvocationID.x], int(8u), int(8u)))) + (bitfieldExtract(_9._m0[gl_GlobalInvocationID.x], int(16u), int(8u)) * bitfieldExtract(_13._m0[gl_GlobalInvocationID.x], int(16u), int(8u)))) + (bitfieldExtract(_9._m0[gl_GlobalInvocationID.x], int(24u), int(8u)) * bitfieldExtract(_13._m0[gl_GlobalInvocationID.x], int(24u), int(8u)));\n    _27._m0[gl_GlobalInvocationID.x] = (((_27._m0[gl_GlobalInvocationID.x] + (uint(bitfieldExtract(int(_9._m0[gl_GlobalInvocationID.x]), int(0u), int(8u))) * uint(bitfieldExtract(int(_13._m0[gl_GlobalInvocationID.x]), int(0u), int(8u))))) + (uint(bitfieldExtract(int(_9._m0[gl_GlobalInvocationID.x]), int(8u), int(8u))) * uint(bitfieldExtract(int(_13._m0[gl_GlobalInvocationID.x]), int(8u), int(8u))))) + (uint(bitfieldExtract(int(_9._m0[gl_GlobalInvocationID.x]), int(16u), int(8u))) * uint(bitfieldExtract(int(_13._m0[gl_GlobalInvocationID.x]), int(16u), int(8u))))) + (uint(bitfieldExtract(int(_9._m0[gl_GlobalInvocationID.x]), int(24u), int(8u))) * uint(bitfieldExtract(int(_13._m0[gl_GlobalInvocationID.x]), int(24u), int(8u))));\n    f16vec2 _98 = uint16BitsToFloat16(_23._m0[gl_GlobalInvocationID.x]);\n    f16vec2 _106 = uint16BitsToFloat16(_19._m0[gl_GlobalInvocationID.x]);\n    vec2 _116 = vec2(f16vec2(_106.x * float16_t(2.0), _106.y * float16_t(2.0)) * f16vec2(_98.x * float16_t(3.0), _98.y * float16_t(3.0)));\n    _31._m0[gl_GlobalInvocationID.x] = floatBitsToUint(uintBitsToFloat(_31._m0[gl_GlobalInvocationID.x]) + (_116.x + _116.y));\n    f16vec2 _128 = uint16BitsToFloat16(_23._m0[gl_GlobalInvocationID.x]);\n    precise float16_t _131 = _128.x * float16_t(5.0);\n    precise float16_t _133 = _128.y * float16_t(5.0);\n    f16vec2 _136 = uint16BitsToFloat16(_19._m0[gl_GlobalInvocationID.x]);\n    precise float16_t _139 = _136.x * float16_t(4.0);\n    precise float16_t _141 = _136.y * float16_t(4.0);\n    precise f16vec2 _144 = f16vec2(_139, _141) * f16vec2(_131, _133);\n    vec2 _145 = vec2(_144);\n    precise float _148 = _145.x + _145.y;\n    precise float _149 = uintBitsToFloat(_31._m0[gl_GlobalInvocationID.x]) + _148;\n    _31._m0[gl_GlobalInvocationID.x] = floatBitsToUint(_149);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 154\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %34\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %25 \"SSBO\"\nOpName %29 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 ArrayStride 4\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 2\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 4\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 3\nOpDecorate %23 NonWritable\nOpDecorate %23 Restrict\nOpDecorate %24 ArrayStride 4\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 0\nOpDecorate %28 ArrayStride 4\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 1\nOpDecorate %34 BuiltIn GlobalInvocationId\nOpDecorate %131 NoContraction\nOpDecorate %133 NoContraction\nOpDecorate %139 NoContraction\nOpDecorate %141 NoContraction\nOpDecorate %144 NoContraction\nOpDecorate %148 NoContraction\nOpDecorate %149 NoContraction\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeVector %14 2\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %15\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeRuntimeArray %5\n%25 = OpTypeStruct %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeRuntimeArray %5\n%29 = OpTypeStruct %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeVector %5 3\n%33 = OpTypePointer Input %32\n%34 = OpVariable %33 Input\n%35 = OpTypePointer Input %5\n%37 = OpConstant %5 0\n%39 = OpTypePointer StorageBuffer %5\n%47 = OpConstant %5 8\n%56 = OpConstant %5 16\n%61 = OpConstant %5 24\n%91 = OpTypeFloat 32\n%93 = OpTypePointer StorageBuffer %15\n%96 = OpTypeFloat 16\n%97 = OpTypeVector %96 2\n%102 = OpConstant %96 0x1.8p+1\n%110 = OpConstant %96 0x1p+1\n%115 = OpTypeVector %91 2\n%132 = OpConstant %96 0x1.4p+2\n%140 = OpConstant %96 0x1p+2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %152\n%152 = OpLabel\n%36 = OpAccessChain %35 %34 %37\n%38 = OpLoad %5 %36\n%40 = OpAccessChain %39 %27 %37 %38\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %39 %13 %37 %38\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %39 %9 %37 %38\n%45 = OpLoad %5 %44\n%46 = OpBitFieldUExtract %5 %45 %37 %47\n%48 = OpBitFieldUExtract %5 %43 %37 %47\n%49 = OpIMul %5 %46 %48\n%50 = OpIAdd %5 %41 %49\n%51 = OpBitFieldUExtract %5 %45 %47 %47\n%52 = OpBitFieldUExtract %5 %43 %47 %47\n%53 = OpIMul %5 %51 %52\n%54 = OpIAdd %5 %50 %53\n%55 = OpBitFieldUExtract %5 %45 %56 %47\n%57 = OpBitFieldUExtract %5 %43 %56 %47\n%58 = OpIMul %5 %55 %57\n%59 = OpIAdd %5 %54 %58\n%60 = OpBitFieldUExtract %5 %45 %61 %47\n%62 = OpBitFieldUExtract %5 %43 %61 %47\n%63 = OpIMul %5 %60 %62\n%64 = OpIAdd %5 %59 %63\n%65 = OpAccessChain %39 %27 %37 %38\nOpStore %65 %64\n%66 = OpAccessChain %39 %27 %37 %38\n%67 = OpLoad %5 %66\n%68 = OpAccessChain %39 %13 %37 %38\n%69 = OpLoad %5 %68\n%70 = OpAccessChain %39 %9 %37 %38\n%71 = OpLoad %5 %70\n%72 = OpBitFieldSExtract %5 %71 %37 %47\n%73 = OpBitFieldSExtract %5 %69 %37 %47\n%74 = OpIMul %5 %72 %73\n%75 = OpIAdd %5 %67 %74\n%76 = OpBitFieldSExtract %5 %71 %47 %47\n%77 = OpBitFieldSExtract %5 %69 %47 %47\n%78 = OpIMul %5 %76 %77\n%79 = OpIAdd %5 %75 %78\n%80 = OpBitFieldSExtract %5 %71 %56 %47\n%81 = OpBitFieldSExtract %5 %69 %56 %47\n%82 = OpIMul %5 %80 %81\n%83 = OpIAdd %5 %79 %82\n%84 = OpBitFieldSExtract %5 %71 %61 %47\n%85 = OpBitFieldSExtract %5 %69 %61 %47\n%86 = OpIMul %5 %84 %85\n%87 = OpIAdd %5 %83 %86\n%88 = OpAccessChain %39 %27 %37 %38\nOpStore %88 %87\n%89 = OpAccessChain %39 %31 %37 %38\n%90 = OpLoad %5 %89\n%92 = OpBitcast %91 %90\n%94 = OpAccessChain %93 %23 %37 %38\n%95 = OpLoad %15 %94\n%98 = OpBitcast %97 %95\n%99 = OpCompositeExtract %96 %98 0\n%100 = OpCompositeExtract %96 %98 1\n%101 = OpFMul %96 %99 %102\n%103 = OpFMul %96 %100 %102\n%104 = OpAccessChain %93 %19 %37 %38\n%105 = OpLoad %15 %104\n%106 = OpBitcast %97 %105\n%107 = OpCompositeExtract %96 %106 0\n%108 = OpCompositeExtract %96 %106 1\n%109 = OpFMul %96 %107 %110\n%111 = OpFMul %96 %108 %110\n%112 = OpCompositeConstruct %97 %109 %111\n%113 = OpCompositeConstruct %97 %101 %103\n%114 = OpFMul %97 %112 %113\n%116 = OpFConvert %115 %114\n%117 = OpCompositeExtract %91 %116 0\n%118 = OpCompositeExtract %91 %116 1\n%119 = OpFAdd %91 %117 %118\n%120 = OpFAdd %91 %92 %119\n%121 = OpBitcast %5 %120\n%122 = OpAccessChain %39 %31 %37 %38\nOpStore %122 %121\n%123 = OpAccessChain %39 %31 %37 %38\n%124 = OpLoad %5 %123\n%125 = OpBitcast %91 %124\n%126 = OpAccessChain %93 %23 %37 %38\n%127 = OpLoad %15 %126\n%128 = OpBitcast %97 %127\n%129 = OpCompositeExtract %96 %128 0\n%130 = OpCompositeExtract %96 %128 1\n%131 = OpFMul %96 %129 %132\n%133 = OpFMul %96 %130 %132\n%134 = OpAccessChain %93 %19 %37 %38\n%135 = OpLoad %15 %134\n%136 = OpBitcast %97 %135\n%137 = OpCompositeExtract %96 %136 0\n%138 = OpCompositeExtract %96 %136 1\n%139 = OpFMul %96 %137 %140\n%141 = OpFMul %96 %138 %140\n%142 = OpCompositeConstruct %97 %139 %141\n%143 = OpCompositeConstruct %97 %131 %133\n%144 = OpFMul %97 %142 %143\n%145 = OpFConvert %115 %144\n%146 = OpCompositeExtract %91 %145 0\n%147 = OpCompositeExtract %91 %145 1\n%148 = OpFAdd %91 %146 %147\n%149 = OpFAdd %91 %125 %148\n%150 = OpBitcast %5 %149\n%151 = OpAccessChain %39 %31 %37 %38\nOpStore %151 %150\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sm64-packed-arithmetic.ssbo.i8dot.noglsl.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 123\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability DotProductInput4x8BitPacked\nOpCapability DotProduct\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_integer_dot_product\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %34\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %25 \"SSBO\"\nOpName %29 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 ArrayStride 4\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 2\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 4\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 3\nOpDecorate %23 NonWritable\nOpDecorate %23 Restrict\nOpDecorate %24 ArrayStride 4\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 0\nOpDecorate %28 ArrayStride 4\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 1\nOpDecorate %34 BuiltIn GlobalInvocationId\nOpDecorate %100 NoContraction\nOpDecorate %102 NoContraction\nOpDecorate %108 NoContraction\nOpDecorate %110 NoContraction\nOpDecorate %113 NoContraction\nOpDecorate %117 NoContraction\nOpDecorate %118 NoContraction\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeVector %14 2\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %15\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeRuntimeArray %5\n%25 = OpTypeStruct %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeRuntimeArray %5\n%29 = OpTypeStruct %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeVector %5 3\n%33 = OpTypePointer Input %32\n%34 = OpVariable %33 Input\n%35 = OpTypePointer Input %5\n%37 = OpConstant %5 0\n%39 = OpTypePointer StorageBuffer %5\n%60 = OpTypeFloat 32\n%62 = OpTypePointer StorageBuffer %15\n%65 = OpTypeFloat 16\n%66 = OpTypeVector %65 2\n%71 = OpConstant %65 0x1.8p+1\n%79 = OpConstant %65 0x1p+1\n%84 = OpTypeVector %60 2\n%101 = OpConstant %65 0x1.4p+2\n%109 = OpConstant %65 0x1p+2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %121\n%121 = OpLabel\n%36 = OpAccessChain %35 %34 %37\n%38 = OpLoad %5 %36\n%40 = OpAccessChain %39 %27 %37 %38\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %39 %13 %37 %38\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %39 %9 %37 %38\n%45 = OpLoad %5 %44\n%46 = OpUDot %5 %45 %43 PackedVectorFormat4x8Bit\n%47 = OpIAdd %5 %41 %46\n%48 = OpAccessChain %39 %27 %37 %38\nOpStore %48 %47\n%49 = OpAccessChain %39 %27 %37 %38\n%50 = OpLoad %5 %49\n%51 = OpAccessChain %39 %13 %37 %38\n%52 = OpLoad %5 %51\n%53 = OpAccessChain %39 %9 %37 %38\n%54 = OpLoad %5 %53\n%55 = OpSDot %5 %54 %52 PackedVectorFormat4x8Bit\n%56 = OpIAdd %5 %50 %55\n%57 = OpAccessChain %39 %27 %37 %38\nOpStore %57 %56\n%58 = OpAccessChain %39 %31 %37 %38\n%59 = OpLoad %5 %58\n%61 = OpBitcast %60 %59\n%63 = OpAccessChain %62 %23 %37 %38\n%64 = OpLoad %15 %63\n%67 = OpBitcast %66 %64\n%68 = OpCompositeExtract %65 %67 0\n%69 = OpCompositeExtract %65 %67 1\n%70 = OpFMul %65 %68 %71\n%72 = OpFMul %65 %69 %71\n%73 = OpAccessChain %62 %19 %37 %38\n%74 = OpLoad %15 %73\n%75 = OpBitcast %66 %74\n%76 = OpCompositeExtract %65 %75 0\n%77 = OpCompositeExtract %65 %75 1\n%78 = OpFMul %65 %76 %79\n%80 = OpFMul %65 %77 %79\n%81 = OpCompositeConstruct %66 %78 %80\n%82 = OpCompositeConstruct %66 %70 %72\n%83 = OpFMul %66 %81 %82\n%85 = OpFConvert %84 %83\n%86 = OpCompositeExtract %60 %85 0\n%87 = OpCompositeExtract %60 %85 1\n%88 = OpFAdd %60 %86 %87\n%89 = OpFAdd %60 %61 %88\n%90 = OpBitcast %5 %89\n%91 = OpAccessChain %39 %31 %37 %38\nOpStore %91 %90\n%92 = OpAccessChain %39 %31 %37 %38\n%93 = OpLoad %5 %92\n%94 = OpBitcast %60 %93\n%95 = OpAccessChain %62 %23 %37 %38\n%96 = OpLoad %15 %95\n%97 = OpBitcast %66 %96\n%98 = OpCompositeExtract %65 %97 0\n%99 = OpCompositeExtract %65 %97 1\n%100 = OpFMul %65 %98 %101\n%102 = OpFMul %65 %99 %101\n%103 = OpAccessChain %62 %19 %37 %38\n%104 = OpLoad %15 %103\n%105 = OpBitcast %66 %104\n%106 = OpCompositeExtract %65 %105 0\n%107 = OpCompositeExtract %65 %105 1\n%108 = OpFMul %65 %106 %109\n%110 = OpFMul %65 %107 %109\n%111 = OpCompositeConstruct %66 %108 %110\n%112 = OpCompositeConstruct %66 %100 %102\n%113 = OpFMul %66 %111 %112\n%114 = OpFConvert %84 %113\n%115 = OpCompositeExtract %60 %114 0\n%116 = OpCompositeExtract %60 %114 1\n%117 = OpFAdd %60 %115 %116\n%118 = OpFAdd %60 %94 %117\n%119 = OpBitcast %5 %118\n%120 = OpAccessChain %39 %31 %37 %38\nOpStore %120 %119\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sm64-packed-arithmetic.ssbo.mixed-float-dot-product.noglsl.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 143\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability DotProductFloat16AccFloat32VALVE\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_VALVE_mixed_float_dot_product\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %34\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %25 \"SSBO\"\nOpName %29 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 ArrayStride 4\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 2\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 4\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 3\nOpDecorate %23 NonWritable\nOpDecorate %23 Restrict\nOpDecorate %24 ArrayStride 4\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 0\nOpDecorate %28 ArrayStride 4\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 1\nOpDecorate %34 BuiltIn GlobalInvocationId\nOpDecorate %125 NoContraction\nOpDecorate %127 NoContraction\nOpDecorate %133 NoContraction\nOpDecorate %135 NoContraction\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeVector %14 2\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %15\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeRuntimeArray %5\n%25 = OpTypeStruct %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeRuntimeArray %5\n%29 = OpTypeStruct %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeVector %5 3\n%33 = OpTypePointer Input %32\n%34 = OpVariable %33 Input\n%35 = OpTypePointer Input %5\n%37 = OpConstant %5 0\n%39 = OpTypePointer StorageBuffer %5\n%47 = OpConstant %5 8\n%56 = OpConstant %5 16\n%61 = OpConstant %5 24\n%91 = OpTypeFloat 32\n%93 = OpTypePointer StorageBuffer %15\n%96 = OpTypeFloat 16\n%97 = OpTypeVector %96 2\n%102 = OpConstant %96 0x1.8p+1\n%110 = OpConstant %96 0x1p+1\n%126 = OpConstant %96 0x1.4p+2\n%134 = OpConstant %96 0x1p+2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %141\n%141 = OpLabel\n%36 = OpAccessChain %35 %34 %37\n%38 = OpLoad %5 %36\n%40 = OpAccessChain %39 %27 %37 %38\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %39 %13 %37 %38\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %39 %9 %37 %38\n%45 = OpLoad %5 %44\n%46 = OpBitFieldUExtract %5 %45 %37 %47\n%48 = OpBitFieldUExtract %5 %43 %37 %47\n%49 = OpIMul %5 %46 %48\n%50 = OpIAdd %5 %41 %49\n%51 = OpBitFieldUExtract %5 %45 %47 %47\n%52 = OpBitFieldUExtract %5 %43 %47 %47\n%53 = OpIMul %5 %51 %52\n%54 = OpIAdd %5 %50 %53\n%55 = OpBitFieldUExtract %5 %45 %56 %47\n%57 = OpBitFieldUExtract %5 %43 %56 %47\n%58 = OpIMul %5 %55 %57\n%59 = OpIAdd %5 %54 %58\n%60 = OpBitFieldUExtract %5 %45 %61 %47\n%62 = OpBitFieldUExtract %5 %43 %61 %47\n%63 = OpIMul %5 %60 %62\n%64 = OpIAdd %5 %59 %63\n%65 = OpAccessChain %39 %27 %37 %38\nOpStore %65 %64\n%66 = OpAccessChain %39 %27 %37 %38\n%67 = OpLoad %5 %66\n%68 = OpAccessChain %39 %13 %37 %38\n%69 = OpLoad %5 %68\n%70 = OpAccessChain %39 %9 %37 %38\n%71 = OpLoad %5 %70\n%72 = OpBitFieldSExtract %5 %71 %37 %47\n%73 = OpBitFieldSExtract %5 %69 %37 %47\n%74 = OpIMul %5 %72 %73\n%75 = OpIAdd %5 %67 %74\n%76 = OpBitFieldSExtract %5 %71 %47 %47\n%77 = OpBitFieldSExtract %5 %69 %47 %47\n%78 = OpIMul %5 %76 %77\n%79 = OpIAdd %5 %75 %78\n%80 = OpBitFieldSExtract %5 %71 %56 %47\n%81 = OpBitFieldSExtract %5 %69 %56 %47\n%82 = OpIMul %5 %80 %81\n%83 = OpIAdd %5 %79 %82\n%84 = OpBitFieldSExtract %5 %71 %61 %47\n%85 = OpBitFieldSExtract %5 %69 %61 %47\n%86 = OpIMul %5 %84 %85\n%87 = OpIAdd %5 %83 %86\n%88 = OpAccessChain %39 %27 %37 %38\nOpStore %88 %87\n%89 = OpAccessChain %39 %31 %37 %38\n%90 = OpLoad %5 %89\n%92 = OpBitcast %91 %90\n%94 = OpAccessChain %93 %23 %37 %38\n%95 = OpLoad %15 %94\n%98 = OpBitcast %97 %95\n%99 = OpCompositeExtract %96 %98 0\n%100 = OpCompositeExtract %96 %98 1\n%101 = OpFMul %96 %99 %102\n%103 = OpFMul %96 %100 %102\n%104 = OpAccessChain %93 %19 %37 %38\n%105 = OpLoad %15 %104\n%106 = OpBitcast %97 %105\n%107 = OpCompositeExtract %96 %106 0\n%108 = OpCompositeExtract %96 %106 1\n%109 = OpFMul %96 %107 %110\n%111 = OpFMul %96 %108 %110\n%112 = OpCompositeConstruct %97 %109 %111\n%113 = OpCompositeConstruct %97 %101 %103\n%114 = OpFDot2MixAcc32VALVE %91 %112 %113 %92\n%115 = OpBitcast %5 %114\n%116 = OpAccessChain %39 %31 %37 %38\nOpStore %116 %115\n%117 = OpAccessChain %39 %31 %37 %38\n%118 = OpLoad %5 %117\n%119 = OpBitcast %91 %118\n%120 = OpAccessChain %93 %23 %37 %38\n%121 = OpLoad %15 %120\n%122 = OpBitcast %97 %121\n%123 = OpCompositeExtract %96 %122 0\n%124 = OpCompositeExtract %96 %122 1\n%125 = OpFMul %96 %123 %126\n%127 = OpFMul %96 %124 %126\n%128 = OpAccessChain %93 %19 %37 %38\n%129 = OpLoad %15 %128\n%130 = OpBitcast %97 %129\n%131 = OpCompositeExtract %96 %130 0\n%132 = OpCompositeExtract %96 %130 1\n%133 = OpFMul %96 %131 %134\n%135 = OpFMul %96 %132 %134\n%136 = OpCompositeConstruct %97 %133 %135\n%137 = OpCompositeConstruct %97 %125 %127\n%138 = OpFDot2MixAcc32VALVE %91 %136 %137 %119\n%139 = OpBitcast %5 %138\n%140 = OpAccessChain %39 %31 %37 %38\nOpStore %140 %139\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/split-double.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out uvec2 SV_Target;\n\nvoid main()\n{\n    uvec2 _16 = unpackDouble2x32(double(A));\n    SV_Target.x = _16.x;\n    SV_Target.y = _16.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\n%15 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %11 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeInt 32 0\n%9 = OpTypeVector %8 2\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%13 = OpTypeFloat 64\n%19 = OpTypePointer Output %8\n%21 = OpConstant %8 0\n%23 = OpConstant %8 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%12 = OpLoad %5 %7\n%14 = OpFConvert %13 %12\n%16 = OpExtInst %9 %15 UnpackDouble2x32 %14\n%17 = OpCompositeExtract %8 %16 0\n%18 = OpCompositeExtract %8 %16 1\n%20 = OpAccessChain %19 %11 %21\nOpStore %20 %17\n%22 = OpAccessChain %19 %11 %23\nOpStore %22 %18\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/sqrt.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = sqrt(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Sqrt %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/tan.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = tan(A);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\nOpCapability Shader\n%11 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %13\n%13 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpExtInst %5 %11 Tan %10\nOpStore %9 %12\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather-4offset.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 3) uniform texture2D _8;\nlayout(set = 0, binding = 1) uniform sampler _11;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) flat in ivec2 OFF;\nlayout(location = 1, component = 2) flat in ivec2 OFF_2;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _29 = uint(OFF_2.x);\n    uint _33 = uint(OFF_2.y);\n    uint _36 = uint(OFF.x);\n    uint _39 = uint(OFF.y);\n    SV_Target.x = textureGatherOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(_36), int(_39))).x;\n    SV_Target.y = textureGatherOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(_36 + _29), int(_39 + _33))).y;\n    SV_Target.z = textureGatherOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(_36 - _29), int(_39 - _33))).z;\n    SV_Target.w = textureGatherOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(_29), int(_33))).w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 85\n; Schema: 0\nOpCapability Shader\nOpCapability ImageGatherExtended\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %18 %19 %21\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"TEXCOORD\"\nOpName %18 \"OFF\"\nOpName %19 \"OFF_2\"\nOpName %21 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 Location 0\nOpDecorate %18 Flat\nOpDecorate %18 Location 1\nOpDecorate %19 Flat\nOpDecorate %19 Location 1\nOpDecorate %19 Component 2\nOpDecorate %21 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeSampler\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeVector %5 4\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypeInt 32 1\n%16 = OpTypeVector %15 2\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpVariable %17 Input\n%20 = OpTypePointer Output %12\n%21 = OpVariable %20 Output\n%24 = OpTypePointer Input %15\n%26 = OpTypeInt 32 0\n%27 = OpConstant %26 0\n%31 = OpConstant %26 1\n%40 = OpTypePointer Input %5\n%49 = OpTypeSampledImage %6\n%51 = OpTypeVector %5 2\n%76 = OpTypePointer Output %5\n%80 = OpConstant %26 2\n%82 = OpConstant %26 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %83\n%83 = OpLabel\n%22 = OpLoad %6 %8\n%23 = OpLoad %9 %11\n%25 = OpAccessChain %24 %19 %27\n%28 = OpLoad %15 %25\n%29 = OpBitcast %26 %28\n%30 = OpAccessChain %24 %19 %31\n%32 = OpLoad %15 %30\n%33 = OpBitcast %26 %32\n%34 = OpAccessChain %24 %18 %27\n%35 = OpLoad %15 %34\n%36 = OpBitcast %26 %35\n%37 = OpAccessChain %24 %18 %31\n%38 = OpLoad %15 %37\n%39 = OpBitcast %26 %38\n%41 = OpAccessChain %40 %14 %27\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %40 %14 %31\n%44 = OpLoad %5 %43\n%45 = OpISub %26 %36 %29\n%46 = OpISub %26 %39 %33\n%47 = OpIAdd %26 %36 %29\n%48 = OpIAdd %26 %39 %33\n%50 = OpSampledImage %49 %22 %23\n%52 = OpCompositeConstruct %51 %42 %44\n%53 = OpBitcast %15 %36\n%54 = OpBitcast %15 %39\n%56 = OpCompositeConstruct %16 %53 %54\n%55 = OpImageGather %12 %50 %52 %27 Offset %56\n%57 = OpCompositeExtract %5 %55 0\n%58 = OpCompositeConstruct %51 %42 %44\n%59 = OpBitcast %15 %47\n%60 = OpBitcast %15 %48\n%62 = OpCompositeConstruct %16 %59 %60\n%61 = OpImageGather %12 %50 %58 %27 Offset %62\n%63 = OpCompositeExtract %5 %61 1\n%64 = OpCompositeConstruct %51 %42 %44\n%65 = OpBitcast %15 %45\n%66 = OpBitcast %15 %46\n%68 = OpCompositeConstruct %16 %65 %66\n%67 = OpImageGather %12 %50 %64 %27 Offset %68\n%69 = OpCompositeExtract %5 %67 2\n%70 = OpCompositeConstruct %51 %42 %44\n%71 = OpBitcast %15 %29\n%72 = OpBitcast %15 %33\n%74 = OpCompositeConstruct %16 %71 %72\n%73 = OpImageGather %12 %50 %70 %27 Offset %74\n%75 = OpCompositeExtract %5 %73 3\n%77 = OpAccessChain %76 %21 %27\nOpStore %77 %57\n%78 = OpAccessChain %76 %21 %31\nOpStore %78 %63\n%79 = OpAccessChain %76 %21 %80\nOpStore %79 %69\n%81 = OpAccessChain %76 %21 %82\nOpStore %81 %75\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather-cmp-offset-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _55\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 0, binding = 3) uniform texture2D _8;\nlayout(set = 0, binding = 4) uniform texture2DArray _11;\nlayout(set = 0, binding = 1) uniform samplerShadow _14;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec2 _41 = vec2(TEXCOORD.x, TEXCOORD.y);\n    uint _105;\n    vec4 _106;\n    _105 = sparseTextureGatherOffsetARB(sampler2DShadow(_8, _14), _41, TEXCOORD.z, ivec2(-3, -4), _106);\n    SparseTexel _46 = SparseTexel(_105, _106);\n    vec4 _50 = _46._m1;\n    _55 _56 = _55(_50.x, _50.y, _50.z, _50.w, _46._m0);\n    vec3 _71 = vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z);\n    uint _107;\n    vec4 _108;\n    _107 = sparseTextureGatherOffsetARB(sampler2DArrayShadow(_11, _14), _71, TEXCOORD.w, ivec2(-4, -5), _108);\n    SparseTexel _73 = SparseTexel(_107, _108);\n    vec4 _76 = _73._m1;\n    _55 _81 = _55(_76.x, _76.y, _76.z, _76.w, _73._m0);\n    float _89 = float(sparseTexelsResidentARB(int(_81._m4))) + float(sparseTexelsResidentARB(int(_56._m4)));\n    SV_Target.x = (_81._m0 + _56._m0) + _89;\n    SV_Target.y = (_81._m1 + _56._m1) + _89;\n    SV_Target.z = (_81._m2 + _56._m2) + _89;\n    SV_Target.w = (_81._m3 + _56._m3) + _89;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 105\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %17 \"TEXCOORD\"\nOpName %19 \"SV_Target\"\nOpName %45 \"SparseTexel\"\nOpName %55 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 4\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %17 Location 0\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeSampler\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeVector %5 4\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %15\n%19 = OpVariable %18 Output\n%23 = OpTypePointer Input %5\n%25 = OpTypeInt 32 0\n%26 = OpConstant %25 0\n%29 = OpConstant %25 1\n%32 = OpConstant %25 2\n%35 = OpConstant %25 3\n%37 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%38 = OpTypeSampledImage %37\n%40 = OpTypeVector %5 2\n%42 = OpTypeInt 32 1\n%43 = OpConstant %42 -3\n%44 = OpConstant %42 -4\n%45 = OpTypeStruct %25 %15\n%47 = OpTypeVector %42 2\n%48 = OpConstantComposite %47 %43 %44\n%55 = OpTypeStruct %5 %5 %5 %5 %25\n%62 = OpTypeBool\n%65 = OpConstant %5 1\n%66 = OpConstant %5 0\n%67 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%68 = OpTypeSampledImage %67\n%70 = OpTypeVector %5 3\n%72 = OpConstant %42 -5\n%74 = OpConstantComposite %47 %44 %72\n%98 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %103\n%103 = OpLabel\n%20 = OpLoad %9 %11\n%21 = OpLoad %6 %8\n%22 = OpLoad %12 %14\n%24 = OpAccessChain %23 %17 %26\n%27 = OpLoad %5 %24\n%28 = OpAccessChain %23 %17 %29\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %23 %17 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %23 %17 %35\n%36 = OpLoad %5 %34\n%39 = OpSampledImage %38 %21 %22\n%41 = OpCompositeConstruct %40 %27 %30\n%46 = OpImageSparseDrefGather %45 %39 %41 %33 ConstOffset %48\n%49 = OpCompositeExtract %25 %46 0\n%50 = OpCompositeExtract %15 %46 1\n%51 = OpCompositeExtract %5 %50 0\n%52 = OpCompositeExtract %5 %50 1\n%53 = OpCompositeExtract %5 %50 2\n%54 = OpCompositeExtract %5 %50 3\n%56 = OpCompositeConstruct %55 %51 %52 %53 %54 %49\n%57 = OpCompositeExtract %5 %56 0\n%58 = OpCompositeExtract %5 %56 1\n%59 = OpCompositeExtract %5 %56 2\n%60 = OpCompositeExtract %5 %56 3\n%61 = OpCompositeExtract %25 %56 4\n%63 = OpImageSparseTexelsResident %62 %61\n%64 = OpSelect %5 %63 %65 %66\n%69 = OpSampledImage %68 %20 %22\n%71 = OpCompositeConstruct %70 %27 %30 %33\n%73 = OpImageSparseDrefGather %45 %69 %71 %36 ConstOffset %74\n%75 = OpCompositeExtract %25 %73 0\n%76 = OpCompositeExtract %15 %73 1\n%77 = OpCompositeExtract %5 %76 0\n%78 = OpCompositeExtract %5 %76 1\n%79 = OpCompositeExtract %5 %76 2\n%80 = OpCompositeExtract %5 %76 3\n%81 = OpCompositeConstruct %55 %77 %78 %79 %80 %75\n%82 = OpCompositeExtract %5 %81 0\n%83 = OpCompositeExtract %5 %81 1\n%84 = OpCompositeExtract %5 %81 2\n%85 = OpCompositeExtract %5 %81 3\n%86 = OpCompositeExtract %25 %81 4\n%87 = OpImageSparseTexelsResident %62 %86\n%88 = OpSelect %5 %87 %65 %66\n%89 = OpFAdd %5 %88 %64\n%90 = OpFAdd %5 %82 %57\n%91 = OpFAdd %5 %90 %89\n%92 = OpFAdd %5 %83 %58\n%93 = OpFAdd %5 %92 %89\n%94 = OpFAdd %5 %84 %59\n%95 = OpFAdd %5 %94 %89\n%96 = OpFAdd %5 %85 %60\n%97 = OpFAdd %5 %96 %89\n%99 = OpAccessChain %98 %19 %26\nOpStore %99 %91\n%100 = OpAccessChain %98 %19 %29\nOpStore %100 %93\n%101 = OpAccessChain %98 %19 %32\nOpStore %101 %95\n%102 = OpAccessChain %98 %19 %35\nOpStore %102 %97\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather-cmp-offset.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 3) uniform texture2D _8;\nlayout(set = 0, binding = 4) uniform texture2DArray _11;\nlayout(set = 0, binding = 1) uniform samplerShadow _14;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec2 _41 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _45 = textureGatherOffset(sampler2DShadow(_8, _14), _41, TEXCOORD.z, ivec2(-3, -4));\n    vec3 _56 = vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z);\n    vec4 _58 = textureGatherOffset(sampler2DArrayShadow(_11, _14), _56, TEXCOORD.w, ivec2(-4, -5));\n    SV_Target.x = _58.x + _45.x;\n    SV_Target.y = _58.y + _45.y;\n    SV_Target.z = _58.z + _45.z;\n    SV_Target.w = _58.w + _45.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 75\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %17 \"TEXCOORD\"\nOpName %19 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 4\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %17 Location 0\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeSampler\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeVector %5 4\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %15\n%19 = OpVariable %18 Output\n%23 = OpTypePointer Input %5\n%25 = OpTypeInt 32 0\n%26 = OpConstant %25 0\n%29 = OpConstant %25 1\n%32 = OpConstant %25 2\n%35 = OpConstant %25 3\n%37 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%38 = OpTypeSampledImage %37\n%40 = OpTypeVector %5 2\n%42 = OpTypeInt 32 1\n%43 = OpConstant %42 -3\n%44 = OpConstant %42 -4\n%46 = OpTypeVector %42 2\n%47 = OpConstantComposite %46 %43 %44\n%52 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%53 = OpTypeSampledImage %52\n%55 = OpTypeVector %5 3\n%57 = OpConstant %42 -5\n%59 = OpConstantComposite %46 %44 %57\n%68 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%20 = OpLoad %9 %11\n%21 = OpLoad %6 %8\n%22 = OpLoad %12 %14\n%24 = OpAccessChain %23 %17 %26\n%27 = OpLoad %5 %24\n%28 = OpAccessChain %23 %17 %29\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %23 %17 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %23 %17 %35\n%36 = OpLoad %5 %34\n%39 = OpSampledImage %38 %21 %22\n%41 = OpCompositeConstruct %40 %27 %30\n%45 = OpImageDrefGather %15 %39 %41 %33 ConstOffset %47\n%48 = OpCompositeExtract %5 %45 0\n%49 = OpCompositeExtract %5 %45 1\n%50 = OpCompositeExtract %5 %45 2\n%51 = OpCompositeExtract %5 %45 3\n%54 = OpSampledImage %53 %20 %22\n%56 = OpCompositeConstruct %55 %27 %30 %33\n%58 = OpImageDrefGather %15 %54 %56 %36 ConstOffset %59\n%60 = OpCompositeExtract %5 %58 0\n%61 = OpCompositeExtract %5 %58 1\n%62 = OpCompositeExtract %5 %58 2\n%63 = OpCompositeExtract %5 %58 3\n%64 = OpFAdd %5 %60 %48\n%65 = OpFAdd %5 %61 %49\n%66 = OpFAdd %5 %62 %50\n%67 = OpFAdd %5 %63 %51\n%69 = OpAccessChain %68 %19 %26\nOpStore %69 %64\n%70 = OpAccessChain %68 %19 %29\nOpStore %70 %65\n%71 = OpAccessChain %68 %19 %32\nOpStore %71 %66\n%72 = OpAccessChain %68 %19 %35\nOpStore %72 %67\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather-cmp.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 3) uniform texture2D _8;\nlayout(set = 0, binding = 4) uniform texture2DArray _11;\nlayout(set = 0, binding = 6) uniform textureCube _14;\nlayout(set = 0, binding = 7) uniform textureCubeArray _17;\nlayout(set = 0, binding = 1) uniform samplerShadow _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) flat in ivec2 OFF;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec2 _60 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _61 = textureGather(sampler2DShadow(_8, _20), _60, TEXCOORD.z);\n    vec3 _70 = vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z);\n    vec4 _71 = textureGather(sampler2DArrayShadow(_11, _20), _70, TEXCOORD.w);\n    vec3 _83 = vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z);\n    vec4 _84 = textureGather(samplerCubeShadow(_14, _20), _83, TEXCOORD.w);\n    vec4 _96 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w);\n    vec4 _97 = textureGather(samplerCubeArrayShadow(_17, _20), _96, TEXCOORD.w);\n    vec2 _106 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _109 = textureGatherOffset(sampler2DShadow(_8, _20), _106, TEXCOORD.z, ivec2(int(uint(OFF.x)), int(uint(OFF.y))));\n    SV_Target.x = (((_71.x + _61.x) + _84.x) + _97.x) + _109.x;\n    SV_Target.y = (((_71.y + _61.y) + _84.y) + _97.y) + _109.y;\n    SV_Target.z = (((_71.z + _61.z) + _84.z) + _97.z) + _109.z;\n    SV_Target.w = (((_71.w + _61.w) + _84.w) + _97.w) + _109.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 126\n; Schema: 0\nOpCapability Shader\nOpCapability ImageGatherExtended\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %27 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %27 \"OFF\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 4\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 6\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 7\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %23 Location 0\nOpDecorate %27 Flat\nOpDecorate %27 Location 1\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypeInt 32 1\n%25 = OpTypeVector %24 2\n%26 = OpTypePointer Input %25\n%27 = OpVariable %26 Input\n%28 = OpTypePointer Output %21\n%29 = OpVariable %28 Output\n%35 = OpTypePointer Input %24\n%37 = OpTypeInt 32 0\n%38 = OpConstant %37 0\n%42 = OpConstant %37 1\n%45 = OpTypePointer Input %5\n%51 = OpConstant %37 2\n%54 = OpConstant %37 3\n%56 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%57 = OpTypeSampledImage %56\n%59 = OpTypeVector %5 2\n%66 = OpTypeImage %5 2D 1 1 0 1 Unknown\n%67 = OpTypeSampledImage %66\n%69 = OpTypeVector %5 3\n%80 = OpTypeImage %5 Cube 1 0 0 1 Unknown\n%81 = OpTypeSampledImage %80\n%93 = OpTypeImage %5 Cube 1 1 0 1 Unknown\n%94 = OpTypeSampledImage %93\n%119 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %124\n%124 = OpLabel\n%30 = OpLoad %15 %17\n%31 = OpLoad %12 %14\n%32 = OpLoad %9 %11\n%33 = OpLoad %6 %8\n%34 = OpLoad %18 %20\n%36 = OpAccessChain %35 %27 %38\n%39 = OpLoad %24 %36\n%40 = OpBitcast %37 %39\n%41 = OpAccessChain %35 %27 %42\n%43 = OpLoad %24 %41\n%44 = OpBitcast %37 %43\n%46 = OpAccessChain %45 %23 %38\n%47 = OpLoad %5 %46\n%48 = OpAccessChain %45 %23 %42\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %45 %23 %51\n%52 = OpLoad %5 %50\n%53 = OpAccessChain %45 %23 %54\n%55 = OpLoad %5 %53\n%58 = OpSampledImage %57 %33 %34\n%60 = OpCompositeConstruct %59 %47 %49\n%61 = OpImageDrefGather %21 %58 %60 %52\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpCompositeExtract %5 %61 1\n%64 = OpCompositeExtract %5 %61 2\n%65 = OpCompositeExtract %5 %61 3\n%68 = OpSampledImage %67 %32 %34\n%70 = OpCompositeConstruct %69 %47 %49 %52\n%71 = OpImageDrefGather %21 %68 %70 %55\n%72 = OpCompositeExtract %5 %71 0\n%73 = OpCompositeExtract %5 %71 1\n%74 = OpCompositeExtract %5 %71 2\n%75 = OpCompositeExtract %5 %71 3\n%76 = OpFAdd %5 %72 %62\n%77 = OpFAdd %5 %73 %63\n%78 = OpFAdd %5 %74 %64\n%79 = OpFAdd %5 %75 %65\n%82 = OpSampledImage %81 %31 %34\n%83 = OpCompositeConstruct %69 %47 %49 %52\n%84 = OpImageDrefGather %21 %82 %83 %55\n%85 = OpCompositeExtract %5 %84 0\n%86 = OpCompositeExtract %5 %84 1\n%87 = OpCompositeExtract %5 %84 2\n%88 = OpCompositeExtract %5 %84 3\n%89 = OpFAdd %5 %76 %85\n%90 = OpFAdd %5 %77 %86\n%91 = OpFAdd %5 %78 %87\n%92 = OpFAdd %5 %79 %88\n%95 = OpSampledImage %94 %30 %34\n%96 = OpCompositeConstruct %21 %47 %49 %52 %55\n%97 = OpImageDrefGather %21 %95 %96 %55\n%98 = OpCompositeExtract %5 %97 0\n%99 = OpCompositeExtract %5 %97 1\n%100 = OpCompositeExtract %5 %97 2\n%101 = OpCompositeExtract %5 %97 3\n%102 = OpFAdd %5 %89 %98\n%103 = OpFAdd %5 %90 %99\n%104 = OpFAdd %5 %91 %100\n%105 = OpFAdd %5 %92 %101\n%106 = OpCompositeConstruct %59 %47 %49\n%107 = OpBitcast %24 %40\n%108 = OpBitcast %24 %44\n%110 = OpCompositeConstruct %25 %107 %108\n%109 = OpImageDrefGather %21 %58 %106 %52 Offset %110\n%111 = OpCompositeExtract %5 %109 0\n%112 = OpCompositeExtract %5 %109 1\n%113 = OpCompositeExtract %5 %109 2\n%114 = OpCompositeExtract %5 %109 3\n%115 = OpFAdd %5 %102 %111\n%116 = OpFAdd %5 %103 %112\n%117 = OpFAdd %5 %104 %113\n%118 = OpFAdd %5 %105 %114\n%120 = OpAccessChain %119 %29 %38\nOpStore %120 %115\n%121 = OpAccessChain %119 %29 %42\nOpStore %121 %116\n%122 = OpAccessChain %119 %29 %51\nOpStore %122 %117\n%123 = OpAccessChain %119 %29 %54\nOpStore %123 %118\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather-offset.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 3) uniform texture2D _8;\nlayout(set = 0, binding = 4) uniform texture2DArray _11;\nlayout(set = 0, binding = 1) uniform sampler _14;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _41 = textureGatherOffset(sampler2D(_8, _14), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(1, 2));\n    vec4 _54 = textureGatherOffset(sampler2DArray(_11, _14), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec2(-2, -3), int(1u));\n    SV_Target.x = _54.x + _41.x;\n    SV_Target.y = _54.y + _41.y;\n    SV_Target.z = _54.z + _41.z;\n    SV_Target.w = _54.w + _41.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %17 \"TEXCOORD\"\nOpName %19 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 4\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %17 Location 0\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeSampler\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeVector %5 4\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %15\n%19 = OpVariable %18 Output\n%23 = OpTypePointer Input %5\n%25 = OpTypeInt 32 0\n%26 = OpConstant %25 0\n%29 = OpConstant %25 1\n%32 = OpConstant %25 2\n%34 = OpTypeSampledImage %6\n%36 = OpTypeVector %5 2\n%38 = OpTypeInt 32 1\n%39 = OpConstant %38 1\n%40 = OpConstant %38 2\n%42 = OpTypeVector %38 2\n%43 = OpConstantComposite %42 %39 %40\n%48 = OpTypeSampledImage %9\n%50 = OpTypeVector %5 3\n%52 = OpConstant %38 -2\n%53 = OpConstant %38 -3\n%55 = OpConstantComposite %42 %52 %53\n%64 = OpTypePointer Output %5\n%69 = OpConstant %25 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %70\n%70 = OpLabel\n%20 = OpLoad %9 %11\n%21 = OpLoad %6 %8\n%22 = OpLoad %12 %14\n%24 = OpAccessChain %23 %17 %26\n%27 = OpLoad %5 %24\n%28 = OpAccessChain %23 %17 %29\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %23 %17 %32\n%33 = OpLoad %5 %31\n%35 = OpSampledImage %34 %21 %22\n%37 = OpCompositeConstruct %36 %27 %30\n%41 = OpImageGather %15 %35 %37 %26 ConstOffset %43\n%44 = OpCompositeExtract %5 %41 0\n%45 = OpCompositeExtract %5 %41 1\n%46 = OpCompositeExtract %5 %41 2\n%47 = OpCompositeExtract %5 %41 3\n%49 = OpSampledImage %48 %20 %22\n%51 = OpCompositeConstruct %50 %27 %30 %33\n%54 = OpImageGather %15 %49 %51 %29 ConstOffset %55\n%56 = OpCompositeExtract %5 %54 0\n%57 = OpCompositeExtract %5 %54 1\n%58 = OpCompositeExtract %5 %54 2\n%59 = OpCompositeExtract %5 %54 3\n%60 = OpFAdd %5 %56 %44\n%61 = OpFAdd %5 %57 %45\n%62 = OpFAdd %5 %58 %46\n%63 = OpFAdd %5 %59 %47\n%65 = OpAccessChain %64 %19 %26\nOpStore %65 %60\n%66 = OpAccessChain %64 %19 %29\nOpStore %66 %61\n%67 = OpAccessChain %64 %19 %32\nOpStore %67 %62\n%68 = OpAccessChain %64 %19 %69\nOpStore %68 %63\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather-signed-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    ivec4 _m1;\n};\n\nstruct _65\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n};\n\nlayout(set = 0, binding = 3) uniform itexture2D _8;\nlayout(set = 0, binding = 4) uniform itexture2DArray _11;\nlayout(set = 0, binding = 6) uniform itextureCube _14;\nlayout(set = 0, binding = 7) uniform itextureCubeArray _17;\nlayout(set = 0, binding = 1) uniform sampler _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out ivec4 SV_Target;\n\nvoid main()\n{\n    uint _166;\n    ivec4 _167;\n    _166 = sparseTextureGatherOffsetARB(isampler2D(_8, _20), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(0, 1), _167);\n    SparseTexel _54 = SparseTexel(_166, _167);\n    uvec4 _60 = uvec4(_54._m1);\n    _65 _66 = _65(_60.x, _60.y, _60.z, _60.w, _54._m0);\n    uint _168;\n    ivec4 _169;\n    _168 = sparseTextureGatherOffsetARB(isampler2DArray(_11, _20), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec2(0, 1), _169, int(1u));\n    SparseTexel _79 = SparseTexel(_168, _169);\n    uvec4 _82 = uvec4(_79._m1);\n    _65 _87 = _65(_82.x, _82.y, _82.z, _82.w, _79._m0);\n    uint _170;\n    ivec4 _171;\n    _170 = sparseTextureGatherARB(isamplerCube(_14, _20), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), _171, int(2u));\n    SparseTexel _98 = SparseTexel(_170, _171);\n    uvec4 _101 = uvec4(_98._m1);\n    _65 _106 = _65(_101.x, _101.y, _101.z, _101.w, _98._m0);\n    uint _172;\n    ivec4 _173;\n    _172 = sparseTextureGatherARB(isamplerCubeArray(_17, _20), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w), _173, int(3u));\n    SparseTexel _117 = SparseTexel(_172, _173);\n    uvec4 _120 = uvec4(_117._m1);\n    _65 _125 = _65(_120.x, _120.y, _120.z, _120.w, _117._m0);\n    uint _132 = uint(sparseTexelsResidentARB(int(_125._m4)));\n    uint _134 = uint(sparseTexelsResidentARB(int(_106._m4))) + (uint(sparseTexelsResidentARB(int(_87._m4))) + uint(sparseTexelsResidentARB(int(_66._m4))));\n    SV_Target.x = int(((((_134 + _66._m0) + _87._m0) + _106._m0) + _125._m0) + _132);\n    SV_Target.y = int(((((_134 + _66._m1) + _87._m1) + _106._m1) + _125._m1) + _132);\n    SV_Target.z = int(((((_134 + _66._m2) + _87._m2) + _106._m2) + _125._m2) + _132);\n    SV_Target.w = int(((((_134 + _66._m3) + _87._m3) + _106._m3) + _125._m3) + _132);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 166\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %24 \"TEXCOORD\"\nOpName %27 \"SV_Target\"\nOpName %53 \"SparseTexel\"\nOpName %65 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 4\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 6\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 7\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %24 Location 0\nOpDecorate %27 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypeVector %5 4\n%26 = OpTypePointer Output %25\n%27 = OpVariable %26 Output\n%33 = OpTypePointer Input %21\n%35 = OpTypeInt 32 0\n%36 = OpConstant %35 0\n%39 = OpConstant %35 1\n%42 = OpConstant %35 2\n%45 = OpConstant %35 3\n%47 = OpTypeSampledImage %6\n%49 = OpTypeVector %21 2\n%51 = OpConstant %5 0\n%52 = OpConstant %5 1\n%53 = OpTypeStruct %35 %25\n%55 = OpTypeVector %5 2\n%56 = OpConstantComposite %55 %51 %52\n%59 = OpTypeVector %35 4\n%65 = OpTypeStruct %35 %35 %35 %35 %35\n%72 = OpTypeBool\n%75 = OpTypeSampledImage %9\n%77 = OpTypeVector %21 3\n%95 = OpTypeSampledImage %12\n%114 = OpTypeSampledImage %15\n%155 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %164\n%164 = OpLabel\n%28 = OpLoad %15 %17\n%29 = OpLoad %12 %14\n%30 = OpLoad %9 %11\n%31 = OpLoad %6 %8\n%32 = OpLoad %18 %20\n%34 = OpAccessChain %33 %24 %36\n%37 = OpLoad %21 %34\n%38 = OpAccessChain %33 %24 %39\n%40 = OpLoad %21 %38\n%41 = OpAccessChain %33 %24 %42\n%43 = OpLoad %21 %41\n%44 = OpAccessChain %33 %24 %45\n%46 = OpLoad %21 %44\n%48 = OpSampledImage %47 %31 %32\n%50 = OpCompositeConstruct %49 %37 %40\n%54 = OpImageSparseGather %53 %48 %50 %36 ConstOffset %56\n%57 = OpCompositeExtract %35 %54 0\n%58 = OpCompositeExtract %25 %54 1\n%60 = OpBitcast %59 %58\n%61 = OpCompositeExtract %35 %60 0\n%62 = OpCompositeExtract %35 %60 1\n%63 = OpCompositeExtract %35 %60 2\n%64 = OpCompositeExtract %35 %60 3\n%66 = OpCompositeConstruct %65 %61 %62 %63 %64 %57\n%67 = OpCompositeExtract %35 %66 0\n%68 = OpCompositeExtract %35 %66 1\n%69 = OpCompositeExtract %35 %66 2\n%70 = OpCompositeExtract %35 %66 3\n%71 = OpCompositeExtract %35 %66 4\n%73 = OpImageSparseTexelsResident %72 %71\n%74 = OpSelect %35 %73 %39 %36\n%76 = OpSampledImage %75 %30 %32\n%78 = OpCompositeConstruct %77 %37 %40 %43\n%79 = OpImageSparseGather %53 %76 %78 %39 ConstOffset %56\n%80 = OpCompositeExtract %35 %79 0\n%81 = OpCompositeExtract %25 %79 1\n%82 = OpBitcast %59 %81\n%83 = OpCompositeExtract %35 %82 0\n%84 = OpCompositeExtract %35 %82 1\n%85 = OpCompositeExtract %35 %82 2\n%86 = OpCompositeExtract %35 %82 3\n%87 = OpCompositeConstruct %65 %83 %84 %85 %86 %80\n%88 = OpCompositeExtract %35 %87 0\n%89 = OpCompositeExtract %35 %87 1\n%90 = OpCompositeExtract %35 %87 2\n%91 = OpCompositeExtract %35 %87 3\n%92 = OpCompositeExtract %35 %87 4\n%93 = OpImageSparseTexelsResident %72 %92\n%94 = OpSelect %35 %93 %39 %36\n%96 = OpSampledImage %95 %29 %32\n%97 = OpCompositeConstruct %77 %37 %40 %43\n%98 = OpImageSparseGather %53 %96 %97 %42\n%99 = OpCompositeExtract %35 %98 0\n%100 = OpCompositeExtract %25 %98 1\n%101 = OpBitcast %59 %100\n%102 = OpCompositeExtract %35 %101 0\n%103 = OpCompositeExtract %35 %101 1\n%104 = OpCompositeExtract %35 %101 2\n%105 = OpCompositeExtract %35 %101 3\n%106 = OpCompositeConstruct %65 %102 %103 %104 %105 %99\n%107 = OpCompositeExtract %35 %106 0\n%108 = OpCompositeExtract %35 %106 1\n%109 = OpCompositeExtract %35 %106 2\n%110 = OpCompositeExtract %35 %106 3\n%111 = OpCompositeExtract %35 %106 4\n%112 = OpImageSparseTexelsResident %72 %111\n%113 = OpSelect %35 %112 %39 %36\n%115 = OpSampledImage %114 %28 %32\n%116 = OpCompositeConstruct %22 %37 %40 %43 %46\n%117 = OpImageSparseGather %53 %115 %116 %45\n%118 = OpCompositeExtract %35 %117 0\n%119 = OpCompositeExtract %25 %117 1\n%120 = OpBitcast %59 %119\n%121 = OpCompositeExtract %35 %120 0\n%122 = OpCompositeExtract %35 %120 1\n%123 = OpCompositeExtract %35 %120 2\n%124 = OpCompositeExtract %35 %120 3\n%125 = OpCompositeConstruct %65 %121 %122 %123 %124 %118\n%126 = OpCompositeExtract %35 %125 0\n%127 = OpCompositeExtract %35 %125 1\n%128 = OpCompositeExtract %35 %125 2\n%129 = OpCompositeExtract %35 %125 3\n%130 = OpCompositeExtract %35 %125 4\n%131 = OpImageSparseTexelsResident %72 %130\n%132 = OpSelect %35 %131 %39 %36\n%133 = OpIAdd %35 %94 %74\n%134 = OpIAdd %35 %113 %133\n%135 = OpIAdd %35 %134 %67\n%136 = OpIAdd %35 %135 %88\n%137 = OpIAdd %35 %136 %107\n%138 = OpIAdd %35 %137 %126\n%139 = OpIAdd %35 %138 %132\n%140 = OpIAdd %35 %134 %68\n%141 = OpIAdd %35 %140 %89\n%142 = OpIAdd %35 %141 %108\n%143 = OpIAdd %35 %142 %127\n%144 = OpIAdd %35 %143 %132\n%145 = OpIAdd %35 %134 %69\n%146 = OpIAdd %35 %145 %90\n%147 = OpIAdd %35 %146 %109\n%148 = OpIAdd %35 %147 %128\n%149 = OpIAdd %35 %148 %132\n%150 = OpIAdd %35 %134 %70\n%151 = OpIAdd %35 %150 %91\n%152 = OpIAdd %35 %151 %110\n%153 = OpIAdd %35 %152 %129\n%154 = OpIAdd %35 %153 %132\n%156 = OpAccessChain %155 %27 %36\n%157 = OpBitcast %5 %139\nOpStore %156 %157\n%158 = OpAccessChain %155 %27 %39\n%159 = OpBitcast %5 %144\nOpStore %158 %159\n%160 = OpAccessChain %155 %27 %42\n%161 = OpBitcast %5 %149\nOpStore %160 %161\n%162 = OpAccessChain %155 %27 %45\n%163 = OpBitcast %5 %154\nOpStore %162 %163\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather-signed.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 3) uniform itexture2D _8;\nlayout(set = 0, binding = 4) uniform itexture2DArray _11;\nlayout(set = 0, binding = 6) uniform itextureCube _14;\nlayout(set = 0, binding = 7) uniform itextureCubeArray _17;\nlayout(set = 0, binding = 1) uniform sampler _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out ivec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _53 = uvec4(textureGather(isampler2D(_8, _20), vec2(TEXCOORD.x, TEXCOORD.y)));\n    uvec4 _63 = uvec4(textureGather(isampler2DArray(_11, _20), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(1u)));\n    uvec4 _76 = uvec4(textureGather(isamplerCube(_14, _20), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(2u)));\n    uvec4 _89 = uvec4(textureGather(isamplerCubeArray(_17, _20), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w), int(3u)));\n    SV_Target.x = int(((_63.x + _53.x) + _76.x) + _89.x);\n    SV_Target.y = int(((_63.y + _53.y) + _76.y) + _89.y);\n    SV_Target.z = int(((_63.z + _53.z) + _76.z) + _89.z);\n    SV_Target.w = int(((_63.w + _53.w) + _76.w) + _89.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 109\n; Schema: 0\nOpCapability Shader\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %27\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %24 \"TEXCOORD\"\nOpName %27 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 4\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 6\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 7\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %24 Location 0\nOpDecorate %27 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypeVector %5 4\n%26 = OpTypePointer Output %25\n%27 = OpVariable %26 Output\n%33 = OpTypePointer Input %21\n%35 = OpTypeInt 32 0\n%36 = OpConstant %35 0\n%39 = OpConstant %35 1\n%42 = OpConstant %35 2\n%45 = OpConstant %35 3\n%47 = OpTypeSampledImage %6\n%49 = OpTypeVector %21 2\n%52 = OpTypeVector %35 4\n%58 = OpTypeSampledImage %9\n%60 = OpTypeVector %21 3\n%72 = OpTypeSampledImage %12\n%85 = OpTypeSampledImage %15\n%98 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %107\n%107 = OpLabel\n%28 = OpLoad %15 %17\n%29 = OpLoad %12 %14\n%30 = OpLoad %9 %11\n%31 = OpLoad %6 %8\n%32 = OpLoad %18 %20\n%34 = OpAccessChain %33 %24 %36\n%37 = OpLoad %21 %34\n%38 = OpAccessChain %33 %24 %39\n%40 = OpLoad %21 %38\n%41 = OpAccessChain %33 %24 %42\n%43 = OpLoad %21 %41\n%44 = OpAccessChain %33 %24 %45\n%46 = OpLoad %21 %44\n%48 = OpSampledImage %47 %31 %32\n%50 = OpCompositeConstruct %49 %37 %40\n%51 = OpImageGather %25 %48 %50 %36\n%53 = OpBitcast %52 %51\n%54 = OpCompositeExtract %35 %53 0\n%55 = OpCompositeExtract %35 %53 1\n%56 = OpCompositeExtract %35 %53 2\n%57 = OpCompositeExtract %35 %53 3\n%59 = OpSampledImage %58 %30 %32\n%61 = OpCompositeConstruct %60 %37 %40 %43\n%62 = OpImageGather %25 %59 %61 %39\n%63 = OpBitcast %52 %62\n%64 = OpCompositeExtract %35 %63 0\n%65 = OpCompositeExtract %35 %63 1\n%66 = OpCompositeExtract %35 %63 2\n%67 = OpCompositeExtract %35 %63 3\n%68 = OpIAdd %35 %64 %54\n%69 = OpIAdd %35 %65 %55\n%70 = OpIAdd %35 %66 %56\n%71 = OpIAdd %35 %67 %57\n%73 = OpSampledImage %72 %29 %32\n%74 = OpCompositeConstruct %60 %37 %40 %43\n%75 = OpImageGather %25 %73 %74 %42\n%76 = OpBitcast %52 %75\n%77 = OpCompositeExtract %35 %76 0\n%78 = OpCompositeExtract %35 %76 1\n%79 = OpCompositeExtract %35 %76 2\n%80 = OpCompositeExtract %35 %76 3\n%81 = OpIAdd %35 %68 %77\n%82 = OpIAdd %35 %69 %78\n%83 = OpIAdd %35 %70 %79\n%84 = OpIAdd %35 %71 %80\n%86 = OpSampledImage %85 %28 %32\n%87 = OpCompositeConstruct %22 %37 %40 %43 %46\n%88 = OpImageGather %25 %86 %87 %45\n%89 = OpBitcast %52 %88\n%90 = OpCompositeExtract %35 %89 0\n%91 = OpCompositeExtract %35 %89 1\n%92 = OpCompositeExtract %35 %89 2\n%93 = OpCompositeExtract %35 %89 3\n%94 = OpIAdd %35 %81 %90\n%95 = OpIAdd %35 %82 %91\n%96 = OpIAdd %35 %83 %92\n%97 = OpIAdd %35 %84 %93\n%99 = OpAccessChain %98 %27 %36\n%100 = OpBitcast %5 %94\nOpStore %99 %100\n%101 = OpAccessChain %98 %27 %39\n%102 = OpBitcast %5 %95\nOpStore %101 %102\n%103 = OpAccessChain %98 %27 %42\n%104 = OpBitcast %5 %96\nOpStore %103 %104\n%105 = OpAccessChain %98 %27 %45\n%106 = OpBitcast %5 %97\nOpStore %105 %106\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-gather.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 3) uniform texture2D _8;\nlayout(set = 0, binding = 4) uniform texture2DArray _11;\nlayout(set = 0, binding = 6) uniform textureCube _14;\nlayout(set = 0, binding = 7) uniform textureCubeArray _17;\nlayout(set = 0, binding = 1) uniform sampler _20;\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 1) flat in ivec2 OFF;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _60 = textureGather(sampler2D(_8, _20), vec2(TEXCOORD.x, TEXCOORD.y));\n    vec4 _69 = textureGather(sampler2DArray(_11, _20), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(1u));\n    vec4 _81 = textureGather(samplerCube(_14, _20), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(2u));\n    vec4 _93 = textureGather(samplerCubeArray(_17, _20), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, TEXCOORD.w), int(3u));\n    vec4 _105 = textureGatherOffset(sampler2D(_8, _20), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(uint(OFF.x)), int(uint(OFF.y))));\n    SV_Target.x = (((_69.x + _60.x) + _81.x) + _93.x) + _105.x;\n    SV_Target.y = (((_69.y + _60.y) + _81.y) + _93.y) + _105.y;\n    SV_Target.z = (((_69.z + _60.z) + _81.z) + _93.z) + _105.z;\n    SV_Target.w = (((_69.w + _60.w) + _81.w) + _93.w) + _105.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 122\n; Schema: 0\nOpCapability Shader\nOpCapability ImageGatherExtended\nOpCapability SampledCubeArray\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %27 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpName %27 \"OFF\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 3\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 4\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 6\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 7\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %23 Location 0\nOpDecorate %27 Flat\nOpDecorate %27 Location 1\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 Cube 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 Cube 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeSampler\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 4\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypeInt 32 1\n%25 = OpTypeVector %24 2\n%26 = OpTypePointer Input %25\n%27 = OpVariable %26 Input\n%28 = OpTypePointer Output %21\n%29 = OpVariable %28 Output\n%35 = OpTypePointer Input %24\n%37 = OpTypeInt 32 0\n%38 = OpConstant %37 0\n%42 = OpConstant %37 1\n%45 = OpTypePointer Input %5\n%51 = OpConstant %37 2\n%54 = OpConstant %37 3\n%56 = OpTypeSampledImage %6\n%58 = OpTypeVector %5 2\n%65 = OpTypeSampledImage %9\n%67 = OpTypeVector %5 3\n%78 = OpTypeSampledImage %12\n%90 = OpTypeSampledImage %15\n%115 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %120\n%120 = OpLabel\n%30 = OpLoad %15 %17\n%31 = OpLoad %12 %14\n%32 = OpLoad %9 %11\n%33 = OpLoad %6 %8\n%34 = OpLoad %18 %20\n%36 = OpAccessChain %35 %27 %38\n%39 = OpLoad %24 %36\n%40 = OpBitcast %37 %39\n%41 = OpAccessChain %35 %27 %42\n%43 = OpLoad %24 %41\n%44 = OpBitcast %37 %43\n%46 = OpAccessChain %45 %23 %38\n%47 = OpLoad %5 %46\n%48 = OpAccessChain %45 %23 %42\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %45 %23 %51\n%52 = OpLoad %5 %50\n%53 = OpAccessChain %45 %23 %54\n%55 = OpLoad %5 %53\n%57 = OpSampledImage %56 %33 %34\n%59 = OpCompositeConstruct %58 %47 %49\n%60 = OpImageGather %21 %57 %59 %38\n%61 = OpCompositeExtract %5 %60 0\n%62 = OpCompositeExtract %5 %60 1\n%63 = OpCompositeExtract %5 %60 2\n%64 = OpCompositeExtract %5 %60 3\n%66 = OpSampledImage %65 %32 %34\n%68 = OpCompositeConstruct %67 %47 %49 %52\n%69 = OpImageGather %21 %66 %68 %42\n%70 = OpCompositeExtract %5 %69 0\n%71 = OpCompositeExtract %5 %69 1\n%72 = OpCompositeExtract %5 %69 2\n%73 = OpCompositeExtract %5 %69 3\n%74 = OpFAdd %5 %70 %61\n%75 = OpFAdd %5 %71 %62\n%76 = OpFAdd %5 %72 %63\n%77 = OpFAdd %5 %73 %64\n%79 = OpSampledImage %78 %31 %34\n%80 = OpCompositeConstruct %67 %47 %49 %52\n%81 = OpImageGather %21 %79 %80 %51\n%82 = OpCompositeExtract %5 %81 0\n%83 = OpCompositeExtract %5 %81 1\n%84 = OpCompositeExtract %5 %81 2\n%85 = OpCompositeExtract %5 %81 3\n%86 = OpFAdd %5 %74 %82\n%87 = OpFAdd %5 %75 %83\n%88 = OpFAdd %5 %76 %84\n%89 = OpFAdd %5 %77 %85\n%91 = OpSampledImage %90 %30 %34\n%92 = OpCompositeConstruct %21 %47 %49 %52 %55\n%93 = OpImageGather %21 %91 %92 %54\n%94 = OpCompositeExtract %5 %93 0\n%95 = OpCompositeExtract %5 %93 1\n%96 = OpCompositeExtract %5 %93 2\n%97 = OpCompositeExtract %5 %93 3\n%98 = OpFAdd %5 %86 %94\n%99 = OpFAdd %5 %87 %95\n%100 = OpFAdd %5 %88 %96\n%101 = OpFAdd %5 %89 %97\n%102 = OpCompositeConstruct %58 %47 %49\n%103 = OpBitcast %24 %40\n%104 = OpBitcast %24 %44\n%106 = OpCompositeConstruct %25 %103 %104\n%105 = OpImageGather %21 %57 %102 %38 Offset %106\n%107 = OpCompositeExtract %5 %105 0\n%108 = OpCompositeExtract %5 %105 1\n%109 = OpCompositeExtract %5 %105 2\n%110 = OpCompositeExtract %5 %105 3\n%111 = OpFAdd %5 %98 %107\n%112 = OpFAdd %5 %99 %108\n%113 = OpFAdd %5 %100 %109\n%114 = OpFAdd %5 %101 %110\n%116 = OpAccessChain %115 %29 %38\nOpStore %116 %111\n%117 = OpAccessChain %115 %29 %42\nOpStore %117 %112\n%118 = OpAccessChain %115 %29 %51\nOpStore %118 %113\n%119 = OpAccessChain %115 %29 %54\nOpStore %119 %114\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-load-feedback.frag",
    "content": "#version 460\n#extension GL_ARB_sparse_texture2 : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _83\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 0, binding = 1) uniform texture1D _8;\nlayout(set = 0, binding = 2) uniform texture1DArray _11;\nlayout(set = 0, binding = 3) uniform texture2D _14;\nlayout(set = 0, binding = 4) uniform texture2DArray _17;\nlayout(set = 0, binding = 5) uniform texture3D _20;\nlayout(set = 0, binding = 6) uniform texture2DMS _23;\nlayout(set = 0, binding = 7) uniform texture2DMSArray _26;\nlayout(set = 0, binding = 1, r32f) uniform readonly image1D _29;\nlayout(set = 0, binding = 2, r32f) uniform readonly image1DArray _32;\nlayout(set = 0, binding = 3, r32f) uniform readonly image2D _35;\nlayout(set = 0, binding = 4, r32f) uniform readonly image2DArray _38;\nlayout(set = 0, binding = 5, r32f) uniform readonly image3D _41;\n\nlayout(location = 0) flat in uvec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uint _299;\n    vec4 _300;\n    _299 = sparseTexelFetchARB(_8, int(TEXCOORD.x), int(TEXCOORD.y), _300);\n    SparseTexel _76 = SparseTexel(_299, _300);\n    vec4 _78 = _76._m1;\n    _83 _84 = _83(_78.x, _78.y, _78.z, _78.w, _76._m0);\n    float _90 = float(sparseTexelsResidentARB(int(_84._m4)));\n    uint _301;\n    vec4 _302;\n    _301 = sparseTexelFetchARB(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z), _302);\n    SparseTexel _95 = SparseTexel(_301, _302);\n    vec4 _99 = _95._m1;\n    _83 _104 = _83(_99.x, _99.y, _99.z, _99.w, _95._m0);\n    float _111 = float(sparseTexelsResidentARB(int(_104._m4)));\n    uint _303;\n    vec4 _304;\n    _303 = sparseTexelFetchARB(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z), _304);\n    SparseTexel _114 = SparseTexel(_303, _304);\n    vec4 _117 = _114._m1;\n    _83 _122 = _83(_117.x, _117.y, _117.z, _117.w, _114._m0);\n    float _129 = float(sparseTexelsResidentARB(int(_122._m4)));\n    uint _305;\n    vec4 _306;\n    _305 = sparseTexelFetchARB(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w), _306);\n    SparseTexel _132 = SparseTexel(_305, _306);\n    vec4 _136 = _132._m1;\n    _83 _141 = _83(_136.x, _136.y, _136.z, _136.w, _132._m0);\n    float _148 = float(sparseTexelsResidentARB(int(_141._m4)));\n    uint _307;\n    vec4 _308;\n    _307 = sparseTexelFetchARB(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w), _308);\n    SparseTexel _151 = SparseTexel(_307, _308);\n    vec4 _154 = _151._m1;\n    _83 _159 = _83(_154.x, _154.y, _154.z, _154.w, _151._m0);\n    float _166 = float(sparseTexelsResidentARB(int(_159._m4)));\n    uint _309;\n    vec4 _310;\n    _309 = sparseTexelFetchARB(_23, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z), _310);\n    SparseTexel _169 = SparseTexel(_309, _310);\n    vec4 _172 = _169._m1;\n    _83 _177 = _83(_172.x, _172.y, _172.z, _172.w, _169._m0);\n    float _184 = float(sparseTexelsResidentARB(int(_177._m4)));\n    uint _311;\n    vec4 _312;\n    _311 = sparseTexelFetchARB(_26, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w), _312);\n    SparseTexel _187 = SparseTexel(_311, _312);\n    vec4 _190 = _187._m1;\n    _83 _195 = _83(_190.x, _190.y, _190.z, _190.w, _187._m0);\n    float _202 = float(sparseTexelsResidentARB(int(_195._m4)));\n    uint _313;\n    vec4 _314;\n    _313 = sparseImageLoadARB(_29, int(TEXCOORD.x), _314);\n    SparseTexel _205 = SparseTexel(_313, _314);\n    vec4 _207 = _205._m1;\n    _83 _212 = _83(_207.x, _207.y, _207.z, _207.w, _205._m0);\n    float _219 = float(sparseTexelsResidentARB(int(_212._m4)));\n    uint _315;\n    vec4 _316;\n    _315 = sparseImageLoadARB(_32, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), _316);\n    SparseTexel _222 = SparseTexel(_315, _316);\n    vec4 _225 = _222._m1;\n    _83 _230 = _83(_225.x, _225.y, _225.z, _225.w, _222._m0);\n    float _237 = float(sparseTexelsResidentARB(int(_230._m4)));\n    uint _317;\n    vec4 _318;\n    _317 = sparseImageLoadARB(_35, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), _318);\n    SparseTexel _240 = SparseTexel(_317, _318);\n    vec4 _243 = _240._m1;\n    _83 _248 = _83(_243.x, _243.y, _243.z, _243.w, _240._m0);\n    float _255 = float(sparseTexelsResidentARB(int(_248._m4)));\n    uint _319;\n    vec4 _320;\n    _319 = sparseImageLoadARB(_38, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), _320);\n    SparseTexel _258 = SparseTexel(_319, _320);\n    vec4 _261 = _258._m1;\n    _83 _266 = _83(_261.x, _261.y, _261.z, _261.w, _258._m0);\n    float _273 = float(sparseTexelsResidentARB(int(_266._m4)));\n    uint _321;\n    vec4 _322;\n    _321 = sparseImageLoadARB(_41, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), _322);\n    SparseTexel _276 = SparseTexel(_321, _322);\n    vec4 _279 = _276._m1;\n    _83 _284 = _83(_279.x, _279.y, _279.z, _279.w, _276._m0);\n    float _291 = float(sparseTexelsResidentARB(int(_284._m4)));\n    SV_Target.x = ((((((((((((((((((((((_90 + _84._m0) + _104._m0) + _111) + _122._m0) + _129) + _141._m0) + _148) + _159._m0) + _166) + _177._m0) + _184) + _195._m0) + _202) + _212._m0) + _219) + _230._m0) + _237) + _248._m0) + _255) + _266._m0) + _273) + _284._m0) + _291;\n    SV_Target.y = ((((((((((((((((((((((_90 + _84._m1) + _104._m1) + _111) + _122._m1) + _129) + _141._m1) + _148) + _159._m1) + _166) + _177._m1) + _184) + _195._m1) + _202) + _212._m1) + _219) + _230._m1) + _237) + _248._m1) + _255) + _266._m1) + _273) + _284._m1) + _291;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 299\n; Schema: 0\nOpCapability Shader\nOpCapability SparseResidency\nOpCapability Sampled1D\nOpCapability Image1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %45 %48\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %45 \"TEXCOORD\"\nOpName %48 \"SV_Target\"\nOpName %75 \"SparseTexel\"\nOpName %83 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 2\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 4\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 7\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 1\nOpDecorate %29 NonWritable\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 2\nOpDecorate %32 NonWritable\nOpDecorate %35 DescriptorSet 0\nOpDecorate %35 Binding 3\nOpDecorate %35 NonWritable\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 4\nOpDecorate %38 NonWritable\nOpDecorate %41 DescriptorSet 0\nOpDecorate %41 Binding 5\nOpDecorate %41 NonWritable\nOpDecorate %45 Flat\nOpDecorate %45 Location 0\nOpDecorate %48 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %5 1D 0 0 0 2 R32f\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeImage %5 1D 0 1 0 2 R32f\n%31 = OpTypePointer UniformConstant %30\n%32 = OpVariable %31 UniformConstant\n%33 = OpTypeImage %5 2D 0 0 0 2 R32f\n%34 = OpTypePointer UniformConstant %33\n%35 = OpVariable %34 UniformConstant\n%36 = OpTypeImage %5 2D 0 1 0 2 R32f\n%37 = OpTypePointer UniformConstant %36\n%38 = OpVariable %37 UniformConstant\n%39 = OpTypeImage %5 3D 0 0 0 2 R32f\n%40 = OpTypePointer UniformConstant %39\n%41 = OpVariable %40 UniformConstant\n%42 = OpTypeInt 32 0\n%43 = OpTypeVector %42 4\n%44 = OpTypePointer Input %43\n%45 = OpVariable %44 Input\n%46 = OpTypeVector %5 2\n%47 = OpTypePointer Output %46\n%48 = OpVariable %47 Output\n%61 = OpTypePointer Input %42\n%63 = OpConstant %42 0\n%66 = OpConstant %42 1\n%69 = OpConstant %42 2\n%72 = OpConstant %42 3\n%74 = OpTypeVector %5 4\n%75 = OpTypeStruct %42 %74\n%83 = OpTypeStruct %5 %5 %5 %5 %42\n%88 = OpTypeBool\n%91 = OpConstant %5 1\n%92 = OpConstant %5 0\n%96 = OpTypeVector %42 2\n%133 = OpTypeVector %42 3\n%294 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %297\n%297 = OpLabel\n%49 = OpLoad %39 %41\n%50 = OpLoad %36 %38\n%51 = OpLoad %33 %35\n%52 = OpLoad %30 %32\n%53 = OpLoad %27 %29\n%54 = OpLoad %24 %26\n%55 = OpLoad %21 %23\n%56 = OpLoad %18 %20\n%57 = OpLoad %15 %17\n%58 = OpLoad %12 %14\n%59 = OpLoad %9 %11\n%60 = OpLoad %6 %8\n%62 = OpAccessChain %61 %45 %63\n%64 = OpLoad %42 %62\n%65 = OpAccessChain %61 %45 %66\n%67 = OpLoad %42 %65\n%68 = OpAccessChain %61 %45 %69\n%70 = OpLoad %42 %68\n%71 = OpAccessChain %61 %45 %72\n%73 = OpLoad %42 %71\n%76 = OpImageSparseFetch %75 %60 %64 Lod %67\n%77 = OpCompositeExtract %42 %76 0\n%78 = OpCompositeExtract %74 %76 1\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpCompositeExtract %5 %78 1\n%81 = OpCompositeExtract %5 %78 2\n%82 = OpCompositeExtract %5 %78 3\n%84 = OpCompositeConstruct %83 %79 %80 %81 %82 %77\n%85 = OpCompositeExtract %5 %84 0\n%86 = OpCompositeExtract %5 %84 1\n%87 = OpCompositeExtract %42 %84 4\n%89 = OpImageSparseTexelsResident %88 %87\n%90 = OpSelect %5 %89 %91 %92\n%93 = OpFAdd %5 %90 %85\n%94 = OpFAdd %5 %90 %86\n%97 = OpCompositeConstruct %96 %64 %67\n%95 = OpImageSparseFetch %75 %59 %97 Lod %70\n%98 = OpCompositeExtract %42 %95 0\n%99 = OpCompositeExtract %74 %95 1\n%100 = OpCompositeExtract %5 %99 0\n%101 = OpCompositeExtract %5 %99 1\n%102 = OpCompositeExtract %5 %99 2\n%103 = OpCompositeExtract %5 %99 3\n%104 = OpCompositeConstruct %83 %100 %101 %102 %103 %98\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpCompositeExtract %5 %104 1\n%107 = OpCompositeExtract %42 %104 4\n%108 = OpImageSparseTexelsResident %88 %107\n%109 = OpFAdd %5 %93 %105\n%110 = OpFAdd %5 %94 %106\n%111 = OpSelect %5 %108 %91 %92\n%112 = OpFAdd %5 %109 %111\n%113 = OpFAdd %5 %110 %111\n%115 = OpCompositeConstruct %96 %64 %67\n%114 = OpImageSparseFetch %75 %58 %115 Lod %70\n%116 = OpCompositeExtract %42 %114 0\n%117 = OpCompositeExtract %74 %114 1\n%118 = OpCompositeExtract %5 %117 0\n%119 = OpCompositeExtract %5 %117 1\n%120 = OpCompositeExtract %5 %117 2\n%121 = OpCompositeExtract %5 %117 3\n%122 = OpCompositeConstruct %83 %118 %119 %120 %121 %116\n%123 = OpCompositeExtract %5 %122 0\n%124 = OpCompositeExtract %5 %122 1\n%125 = OpCompositeExtract %42 %122 4\n%126 = OpImageSparseTexelsResident %88 %125\n%127 = OpFAdd %5 %112 %123\n%128 = OpFAdd %5 %113 %124\n%129 = OpSelect %5 %126 %91 %92\n%130 = OpFAdd %5 %127 %129\n%131 = OpFAdd %5 %128 %129\n%134 = OpCompositeConstruct %133 %64 %67 %70\n%132 = OpImageSparseFetch %75 %57 %134 Lod %73\n%135 = OpCompositeExtract %42 %132 0\n%136 = OpCompositeExtract %74 %132 1\n%137 = OpCompositeExtract %5 %136 0\n%138 = OpCompositeExtract %5 %136 1\n%139 = OpCompositeExtract %5 %136 2\n%140 = OpCompositeExtract %5 %136 3\n%141 = OpCompositeConstruct %83 %137 %138 %139 %140 %135\n%142 = OpCompositeExtract %5 %141 0\n%143 = OpCompositeExtract %5 %141 1\n%144 = OpCompositeExtract %42 %141 4\n%145 = OpImageSparseTexelsResident %88 %144\n%146 = OpFAdd %5 %130 %142\n%147 = OpFAdd %5 %131 %143\n%148 = OpSelect %5 %145 %91 %92\n%149 = OpFAdd %5 %146 %148\n%150 = OpFAdd %5 %147 %148\n%152 = OpCompositeConstruct %133 %64 %67 %70\n%151 = OpImageSparseFetch %75 %56 %152 Lod %73\n%153 = OpCompositeExtract %42 %151 0\n%154 = OpCompositeExtract %74 %151 1\n%155 = OpCompositeExtract %5 %154 0\n%156 = OpCompositeExtract %5 %154 1\n%157 = OpCompositeExtract %5 %154 2\n%158 = OpCompositeExtract %5 %154 3\n%159 = OpCompositeConstruct %83 %155 %156 %157 %158 %153\n%160 = OpCompositeExtract %5 %159 0\n%161 = OpCompositeExtract %5 %159 1\n%162 = OpCompositeExtract %42 %159 4\n%163 = OpImageSparseTexelsResident %88 %162\n%164 = OpFAdd %5 %149 %160\n%165 = OpFAdd %5 %150 %161\n%166 = OpSelect %5 %163 %91 %92\n%167 = OpFAdd %5 %164 %166\n%168 = OpFAdd %5 %165 %166\n%170 = OpCompositeConstruct %96 %64 %67\n%169 = OpImageSparseFetch %75 %55 %170 Sample %70\n%171 = OpCompositeExtract %42 %169 0\n%172 = OpCompositeExtract %74 %169 1\n%173 = OpCompositeExtract %5 %172 0\n%174 = OpCompositeExtract %5 %172 1\n%175 = OpCompositeExtract %5 %172 2\n%176 = OpCompositeExtract %5 %172 3\n%177 = OpCompositeConstruct %83 %173 %174 %175 %176 %171\n%178 = OpCompositeExtract %5 %177 0\n%179 = OpCompositeExtract %5 %177 1\n%180 = OpCompositeExtract %42 %177 4\n%181 = OpImageSparseTexelsResident %88 %180\n%182 = OpFAdd %5 %167 %178\n%183 = OpFAdd %5 %168 %179\n%184 = OpSelect %5 %181 %91 %92\n%185 = OpFAdd %5 %182 %184\n%186 = OpFAdd %5 %183 %184\n%188 = OpCompositeConstruct %133 %64 %67 %70\n%187 = OpImageSparseFetch %75 %54 %188 Sample %73\n%189 = OpCompositeExtract %42 %187 0\n%190 = OpCompositeExtract %74 %187 1\n%191 = OpCompositeExtract %5 %190 0\n%192 = OpCompositeExtract %5 %190 1\n%193 = OpCompositeExtract %5 %190 2\n%194 = OpCompositeExtract %5 %190 3\n%195 = OpCompositeConstruct %83 %191 %192 %193 %194 %189\n%196 = OpCompositeExtract %5 %195 0\n%197 = OpCompositeExtract %5 %195 1\n%198 = OpCompositeExtract %42 %195 4\n%199 = OpImageSparseTexelsResident %88 %198\n%200 = OpFAdd %5 %185 %196\n%201 = OpFAdd %5 %186 %197\n%202 = OpSelect %5 %199 %91 %92\n%203 = OpFAdd %5 %200 %202\n%204 = OpFAdd %5 %201 %202\n%205 = OpImageSparseRead %75 %53 %64 None\n%206 = OpCompositeExtract %42 %205 0\n%207 = OpCompositeExtract %74 %205 1\n%208 = OpCompositeExtract %5 %207 0\n%209 = OpCompositeExtract %5 %207 1\n%210 = OpCompositeExtract %5 %207 2\n%211 = OpCompositeExtract %5 %207 3\n%212 = OpCompositeConstruct %83 %208 %209 %210 %211 %206\n%213 = OpCompositeExtract %5 %212 0\n%214 = OpCompositeExtract %5 %212 1\n%215 = OpCompositeExtract %42 %212 4\n%216 = OpImageSparseTexelsResident %88 %215\n%217 = OpFAdd %5 %203 %213\n%218 = OpFAdd %5 %204 %214\n%219 = OpSelect %5 %216 %91 %92\n%220 = OpFAdd %5 %217 %219\n%221 = OpFAdd %5 %218 %219\n%223 = OpCompositeConstruct %96 %64 %67\n%222 = OpImageSparseRead %75 %52 %223 None\n%224 = OpCompositeExtract %42 %222 0\n%225 = OpCompositeExtract %74 %222 1\n%226 = OpCompositeExtract %5 %225 0\n%227 = OpCompositeExtract %5 %225 1\n%228 = OpCompositeExtract %5 %225 2\n%229 = OpCompositeExtract %5 %225 3\n%230 = OpCompositeConstruct %83 %226 %227 %228 %229 %224\n%231 = OpCompositeExtract %5 %230 0\n%232 = OpCompositeExtract %5 %230 1\n%233 = OpCompositeExtract %42 %230 4\n%234 = OpImageSparseTexelsResident %88 %233\n%235 = OpFAdd %5 %220 %231\n%236 = OpFAdd %5 %221 %232\n%237 = OpSelect %5 %234 %91 %92\n%238 = OpFAdd %5 %235 %237\n%239 = OpFAdd %5 %236 %237\n%241 = OpCompositeConstruct %96 %64 %67\n%240 = OpImageSparseRead %75 %51 %241 None\n%242 = OpCompositeExtract %42 %240 0\n%243 = OpCompositeExtract %74 %240 1\n%244 = OpCompositeExtract %5 %243 0\n%245 = OpCompositeExtract %5 %243 1\n%246 = OpCompositeExtract %5 %243 2\n%247 = OpCompositeExtract %5 %243 3\n%248 = OpCompositeConstruct %83 %244 %245 %246 %247 %242\n%249 = OpCompositeExtract %5 %248 0\n%250 = OpCompositeExtract %5 %248 1\n%251 = OpCompositeExtract %42 %248 4\n%252 = OpImageSparseTexelsResident %88 %251\n%253 = OpFAdd %5 %238 %249\n%254 = OpFAdd %5 %239 %250\n%255 = OpSelect %5 %252 %91 %92\n%256 = OpFAdd %5 %253 %255\n%257 = OpFAdd %5 %254 %255\n%259 = OpCompositeConstruct %133 %64 %67 %70\n%258 = OpImageSparseRead %75 %50 %259 None\n%260 = OpCompositeExtract %42 %258 0\n%261 = OpCompositeExtract %74 %258 1\n%262 = OpCompositeExtract %5 %261 0\n%263 = OpCompositeExtract %5 %261 1\n%264 = OpCompositeExtract %5 %261 2\n%265 = OpCompositeExtract %5 %261 3\n%266 = OpCompositeConstruct %83 %262 %263 %264 %265 %260\n%267 = OpCompositeExtract %5 %266 0\n%268 = OpCompositeExtract %5 %266 1\n%269 = OpCompositeExtract %42 %266 4\n%270 = OpImageSparseTexelsResident %88 %269\n%271 = OpFAdd %5 %256 %267\n%272 = OpFAdd %5 %257 %268\n%273 = OpSelect %5 %270 %91 %92\n%274 = OpFAdd %5 %271 %273\n%275 = OpFAdd %5 %272 %273\n%277 = OpCompositeConstruct %133 %64 %67 %70\n%276 = OpImageSparseRead %75 %49 %277 None\n%278 = OpCompositeExtract %42 %276 0\n%279 = OpCompositeExtract %74 %276 1\n%280 = OpCompositeExtract %5 %279 0\n%281 = OpCompositeExtract %5 %279 1\n%282 = OpCompositeExtract %5 %279 2\n%283 = OpCompositeExtract %5 %279 3\n%284 = OpCompositeConstruct %83 %280 %281 %282 %283 %278\n%285 = OpCompositeExtract %5 %284 0\n%286 = OpCompositeExtract %5 %284 1\n%287 = OpCompositeExtract %42 %284 4\n%288 = OpImageSparseTexelsResident %88 %287\n%289 = OpFAdd %5 %274 %285\n%290 = OpFAdd %5 %275 %286\n%291 = OpSelect %5 %288 %91 %92\n%292 = OpFAdd %5 %289 %291\n%293 = OpFAdd %5 %290 %291\n%295 = OpAccessChain %294 %48 %63\nOpStore %295 %292\n%296 = OpAccessChain %294 %48 %66\nOpStore %296 %293\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-load-offset-dynamic.sm67.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, std140) uniform _31_33\n{\n    vec4 _m0[2];\n} _33;\n\nlayout(set = 0, binding = 1) uniform texture1D _8;\nlayout(set = 0, binding = 2) uniform texture1DArray _11;\nlayout(set = 0, binding = 3) uniform texture2D _14;\nlayout(set = 0, binding = 4) uniform texture2DArray _17;\nlayout(set = 0, binding = 5) uniform texture3D _20;\nlayout(set = 0, binding = 6) uniform texture2DMS _23;\nlayout(set = 0, binding = 7) uniform texture2DMSArray _26;\n\nlayout(location = 0) flat in uvec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    uvec4 _55 = floatBitsToUint(_33._m0[0u]);\n    uint _56 = _55.x;\n    vec4 _60 = texelFetch(_8, int(TEXCOORD.x) + bitfieldExtract(int(_56), 0, 4), int(TEXCOORD.y));\n    vec4 _69 = texelFetch(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)) + bitfieldExtract(ivec2(int(_56), 0), 0, 4), int(TEXCOORD.z));\n    uint _80 = _55.y;\n    uint _81 = _55.z;\n    vec4 _85 = texelFetch(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)) + bitfieldExtract(ivec2(int(_80), int(_81)), 0, 4), int(TEXCOORD.z));\n    vec4 _97 = texelFetch(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)) + bitfieldExtract(ivec3(int(_80), int(_81), 0), 0, 4), int(TEXCOORD.w));\n    uvec4 _110 = floatBitsToUint(_33._m0[1u]);\n    vec4 _118 = texelFetch(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)) + bitfieldExtract(ivec3(int(_110.x), int(_110.y), int(_110.z)), 0, 4), int(TEXCOORD.w));\n    vec4 _130 = texelFetch(_23, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)) + bitfieldExtract(ivec2(int(_80), int(_81)), 0, 4), int(TEXCOORD.z));\n    vec4 _142 = texelFetch(_26, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)) + bitfieldExtract(ivec3(int(_80), int(_81), 0), 0, 4), int(TEXCOORD.w));\n    SV_Target.x = (((((_69.x + _60.x) + _85.x) + _97.x) + _118.x) + _130.x) + _142.x;\n    SV_Target.y = (((((_69.y + _60.y) + _85.y) + _97.y) + _118.y) + _130.y) + _142.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 156\n; Schema: 0\nOpCapability Shader\nOpCapability ImageGatherExtended\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %36 %39\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %31 \"\"\nOpName %36 \"TEXCOORD\"\nOpName %39 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 2\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 4\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 7\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %36 Flat\nOpDecorate %36 Location 0\nOpDecorate %39 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeInt 32 0\n%28 = OpConstant %27 2\n%29 = OpTypeVector %5 4\n%30 = OpTypeArray %29 %28\n%31 = OpTypeStruct %30\n%32 = OpTypePointer Uniform %31\n%33 = OpVariable %32 Uniform\n%34 = OpTypeVector %27 4\n%35 = OpTypePointer Input %34\n%36 = OpVariable %35 Input\n%37 = OpTypeVector %5 2\n%38 = OpTypePointer Output %37\n%39 = OpVariable %38 Output\n%40 = OpTypePointer Input %27\n%42 = OpConstant %27 0\n%45 = OpConstant %27 1\n%50 = OpConstant %27 3\n%52 = OpTypePointer Uniform %29\n%58 = OpTypeInt 32 1\n%63 = OpConstant %58 0\n%64 = OpConstant %58 4\n%70 = OpTypeVector %27 2\n%72 = OpTypeVector %58 2\n%98 = OpTypeVector %27 3\n%100 = OpTypeVector %58 3\n%151 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %154\n%154 = OpLabel\n%41 = OpAccessChain %40 %36 %42\n%43 = OpLoad %27 %41\n%44 = OpAccessChain %40 %36 %45\n%46 = OpLoad %27 %44\n%47 = OpAccessChain %40 %36 %28\n%48 = OpLoad %27 %47\n%49 = OpAccessChain %40 %36 %50\n%51 = OpLoad %27 %49\n%53 = OpAccessChain %52 %33 %42 %42\n%54 = OpLoad %29 %53\n%55 = OpBitcast %34 %54\n%56 = OpCompositeExtract %27 %55 0\n%57 = OpLoad %6 %8\n%59 = OpBitcast %58 %56\n%62 = OpBitFieldSExtract %58 %59 %63 %64\n%61 = OpIAdd %58 %43 %62\n%60 = OpImageFetch %29 %57 %61 Lod %46\n%65 = OpCompositeExtract %5 %60 0\n%66 = OpCompositeExtract %5 %60 1\n%67 = OpLoad %9 %11\n%68 = OpBitcast %58 %56\n%71 = OpCompositeConstruct %70 %43 %46\n%74 = OpCompositeConstruct %72 %68 %63\n%75 = OpBitFieldSExtract %72 %74 %63 %64\n%73 = OpIAdd %72 %71 %75\n%69 = OpImageFetch %29 %67 %73 Lod %48\n%76 = OpCompositeExtract %5 %69 0\n%77 = OpCompositeExtract %5 %69 1\n%78 = OpFAdd %5 %76 %65\n%79 = OpFAdd %5 %77 %66\n%80 = OpCompositeExtract %27 %55 1\n%81 = OpCompositeExtract %27 %55 2\n%82 = OpLoad %12 %14\n%83 = OpBitcast %58 %80\n%84 = OpBitcast %58 %81\n%86 = OpCompositeConstruct %70 %43 %46\n%88 = OpCompositeConstruct %72 %83 %84\n%89 = OpBitFieldSExtract %72 %88 %63 %64\n%87 = OpIAdd %72 %86 %89\n%85 = OpImageFetch %29 %82 %87 Lod %48\n%90 = OpCompositeExtract %5 %85 0\n%91 = OpCompositeExtract %5 %85 1\n%92 = OpFAdd %5 %78 %90\n%93 = OpFAdd %5 %79 %91\n%94 = OpLoad %15 %17\n%95 = OpBitcast %58 %80\n%96 = OpBitcast %58 %81\n%99 = OpCompositeConstruct %98 %43 %46 %48\n%102 = OpCompositeConstruct %100 %95 %96 %63\n%103 = OpBitFieldSExtract %100 %102 %63 %64\n%101 = OpIAdd %100 %99 %103\n%97 = OpImageFetch %29 %94 %101 Lod %51\n%104 = OpCompositeExtract %5 %97 0\n%105 = OpCompositeExtract %5 %97 1\n%106 = OpFAdd %5 %92 %104\n%107 = OpFAdd %5 %93 %105\n%108 = OpAccessChain %52 %33 %42 %45\n%109 = OpLoad %29 %108\n%110 = OpBitcast %34 %109\n%111 = OpCompositeExtract %27 %110 0\n%112 = OpCompositeExtract %27 %110 1\n%113 = OpCompositeExtract %27 %110 2\n%114 = OpLoad %18 %20\n%115 = OpBitcast %58 %111\n%116 = OpBitcast %58 %112\n%117 = OpBitcast %58 %113\n%119 = OpCompositeConstruct %98 %43 %46 %48\n%121 = OpCompositeConstruct %100 %115 %116 %117\n%122 = OpBitFieldSExtract %100 %121 %63 %64\n%120 = OpIAdd %100 %119 %122\n%118 = OpImageFetch %29 %114 %120 Lod %51\n%123 = OpCompositeExtract %5 %118 0\n%124 = OpCompositeExtract %5 %118 1\n%125 = OpFAdd %5 %106 %123\n%126 = OpFAdd %5 %107 %124\n%127 = OpLoad %21 %23\n%128 = OpBitcast %58 %80\n%129 = OpBitcast %58 %81\n%131 = OpCompositeConstruct %70 %43 %46\n%133 = OpCompositeConstruct %72 %128 %129\n%134 = OpBitFieldSExtract %72 %133 %63 %64\n%132 = OpIAdd %72 %131 %134\n%130 = OpImageFetch %29 %127 %132 Sample %48\n%135 = OpCompositeExtract %5 %130 0\n%136 = OpCompositeExtract %5 %130 1\n%137 = OpFAdd %5 %125 %135\n%138 = OpFAdd %5 %126 %136\n%139 = OpLoad %24 %26\n%140 = OpBitcast %58 %80\n%141 = OpBitcast %58 %81\n%143 = OpCompositeConstruct %98 %43 %46 %48\n%145 = OpCompositeConstruct %100 %140 %141 %63\n%146 = OpBitFieldSExtract %100 %145 %63 %64\n%144 = OpIAdd %100 %143 %146\n%142 = OpImageFetch %29 %139 %144 Sample %51\n%147 = OpCompositeExtract %5 %142 0\n%148 = OpCompositeExtract %5 %142 1\n%149 = OpFAdd %5 %137 %147\n%150 = OpFAdd %5 %138 %148\n%152 = OpAccessChain %151 %39 %42\nOpStore %152 %149\n%153 = OpAccessChain %151 %39 %45\nOpStore %153 %150\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-load-offset.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 1) uniform texture1D _8;\nlayout(set = 0, binding = 2) uniform texture1DArray _11;\nlayout(set = 0, binding = 3) uniform texture2D _14;\nlayout(set = 0, binding = 4) uniform texture2DArray _17;\nlayout(set = 0, binding = 5) uniform texture3D _20;\nlayout(set = 0, binding = 6) uniform texture2DMS _23;\nlayout(set = 0, binding = 7) uniform texture2DMSArray _26;\n\nlayout(location = 0) flat in uvec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _57 = texelFetchOffset(_8, int(TEXCOORD.x), int(TEXCOORD.y), 1);\n    vec4 _61 = texelFetchOffset(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z), 2);\n    vec4 _70 = texelFetchOffset(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z), ivec2(3, 4));\n    vec4 _80 = texelFetchOffset(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w), ivec2(-4, -3));\n    vec4 _88 = texelFetchOffset(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w), ivec3(-4, 2, 3));\n    vec4 _96 = texelFetchOffset(_23, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), ivec2(2, 3), int(TEXCOORD.z));\n    vec4 _104 = texelFetchOffset(_26, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), ivec2(4, 5), int(TEXCOORD.w));\n    SV_Target.x = (((((_61.x + _57.x) + _70.x) + _80.x) + _88.x) + _96.x) + _104.x;\n    SV_Target.y = (((((_61.y + _57.y) + _70.y) + _80.y) + _88.y) + _96.y) + _104.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 116\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %30 %33\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %30 \"TEXCOORD\"\nOpName %33 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 2\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 4\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 7\nOpDecorate %30 Flat\nOpDecorate %30 Location 0\nOpDecorate %33 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeInt 32 0\n%28 = OpTypeVector %27 4\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%31 = OpTypeVector %5 2\n%32 = OpTypePointer Output %31\n%33 = OpVariable %32 Output\n%41 = OpTypePointer Input %27\n%43 = OpConstant %27 0\n%46 = OpConstant %27 1\n%49 = OpConstant %27 2\n%52 = OpConstant %27 3\n%54 = OpTypeInt 32 1\n%55 = OpConstant %54 1\n%56 = OpTypeVector %5 4\n%60 = OpConstant %54 2\n%62 = OpTypeVector %27 2\n%68 = OpConstant %54 3\n%69 = OpConstant %54 4\n%72 = OpTypeVector %54 2\n%73 = OpConstantComposite %72 %68 %69\n%78 = OpConstant %54 -4\n%79 = OpConstant %54 -3\n%81 = OpTypeVector %27 3\n%83 = OpConstantComposite %72 %78 %79\n%90 = OpTypeVector %54 3\n%91 = OpConstantComposite %90 %78 %60 %68\n%98 = OpConstantComposite %72 %60 %68\n%103 = OpConstant %54 5\n%106 = OpConstantComposite %72 %69 %103\n%111 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%34 = OpLoad %24 %26\n%35 = OpLoad %21 %23\n%36 = OpLoad %18 %20\n%37 = OpLoad %15 %17\n%38 = OpLoad %12 %14\n%39 = OpLoad %9 %11\n%40 = OpLoad %6 %8\n%42 = OpAccessChain %41 %30 %43\n%44 = OpLoad %27 %42\n%45 = OpAccessChain %41 %30 %46\n%47 = OpLoad %27 %45\n%48 = OpAccessChain %41 %30 %49\n%50 = OpLoad %27 %48\n%51 = OpAccessChain %41 %30 %52\n%53 = OpLoad %27 %51\n%57 = OpImageFetch %56 %40 %44 Lod|ConstOffset %47 %55\n%58 = OpCompositeExtract %5 %57 0\n%59 = OpCompositeExtract %5 %57 1\n%63 = OpCompositeConstruct %62 %44 %47\n%61 = OpImageFetch %56 %39 %63 Lod|ConstOffset %50 %60\n%64 = OpCompositeExtract %5 %61 0\n%65 = OpCompositeExtract %5 %61 1\n%66 = OpFAdd %5 %64 %58\n%67 = OpFAdd %5 %65 %59\n%71 = OpCompositeConstruct %62 %44 %47\n%70 = OpImageFetch %56 %38 %71 Lod|ConstOffset %50 %73\n%74 = OpCompositeExtract %5 %70 0\n%75 = OpCompositeExtract %5 %70 1\n%76 = OpFAdd %5 %66 %74\n%77 = OpFAdd %5 %67 %75\n%82 = OpCompositeConstruct %81 %44 %47 %50\n%80 = OpImageFetch %56 %37 %82 Lod|ConstOffset %53 %83\n%84 = OpCompositeExtract %5 %80 0\n%85 = OpCompositeExtract %5 %80 1\n%86 = OpFAdd %5 %76 %84\n%87 = OpFAdd %5 %77 %85\n%89 = OpCompositeConstruct %81 %44 %47 %50\n%88 = OpImageFetch %56 %36 %89 Lod|ConstOffset %53 %91\n%92 = OpCompositeExtract %5 %88 0\n%93 = OpCompositeExtract %5 %88 1\n%94 = OpFAdd %5 %86 %92\n%95 = OpFAdd %5 %87 %93\n%97 = OpCompositeConstruct %62 %44 %47\n%96 = OpImageFetch %56 %35 %97 ConstOffset|Sample %98 %50\n%99 = OpCompositeExtract %5 %96 0\n%100 = OpCompositeExtract %5 %96 1\n%101 = OpFAdd %5 %94 %99\n%102 = OpFAdd %5 %95 %100\n%105 = OpCompositeConstruct %81 %44 %47 %50\n%104 = OpImageFetch %56 %34 %105 ConstOffset|Sample %106 %53\n%107 = OpCompositeExtract %5 %104 0\n%108 = OpCompositeExtract %5 %104 1\n%109 = OpFAdd %5 %101 %107\n%110 = OpFAdd %5 %102 %108\n%112 = OpAccessChain %111 %33 %43\nOpStore %112 %109\n%113 = OpAccessChain %111 %33 %46\nOpStore %113 %110\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-load-signed.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 1) uniform itexture1D _8;\nlayout(set = 0, binding = 2) uniform itexture1DArray _11;\nlayout(set = 0, binding = 3) uniform itexture2D _14;\nlayout(set = 0, binding = 4) uniform itexture2DArray _17;\nlayout(set = 0, binding = 5) uniform itexture3D _20;\nlayout(set = 0, binding = 6) uniform itexture2DMS _23;\nlayout(set = 0, binding = 7) uniform itexture2DMSArray _26;\nlayout(set = 0, binding = 1, r32i) uniform readonly iimage1D _29;\nlayout(set = 0, binding = 2, r32i) uniform readonly iimage1DArray _32;\nlayout(set = 0, binding = 3, r32i) uniform readonly iimage2D _35;\nlayout(set = 0, binding = 4, r32i) uniform readonly iimage2DArray _38;\nlayout(set = 0, binding = 5, r32i) uniform readonly iimage3D _41;\n\nlayout(location = 0) flat in uvec4 TEXCOORD;\nlayout(location = 0) out ivec2 SV_Target;\n\nvoid main()\n{\n    uvec4 _76 = uvec4(texelFetch(_8, int(TEXCOORD.x), int(TEXCOORD.y)));\n    uvec4 _82 = uvec4(texelFetch(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z)));\n    uvec4 _89 = uvec4(texelFetch(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z)));\n    uvec4 _97 = uvec4(texelFetch(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w)));\n    uvec4 _104 = uvec4(texelFetch(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w)));\n    uvec4 _111 = uvec4(texelFetch(_23, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z)));\n    uvec4 _118 = uvec4(texelFetch(_26, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w)));\n    uvec4 _124 = uvec4(imageLoad(_29, int(TEXCOORD.x)));\n    uvec4 _131 = uvec4(imageLoad(_32, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y))));\n    uvec4 _138 = uvec4(imageLoad(_35, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y))));\n    uvec4 _145 = uvec4(imageLoad(_38, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z))));\n    uvec4 _152 = uvec4(imageLoad(_41, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z))));\n    SV_Target.x = int(((((((((((_82.x + _76.x) + _89.x) + _97.x) + _104.x) + _111.x) + _118.x) + _124.x) + _131.x) + _138.x) + _145.x) + _152.x);\n    SV_Target.y = int(((((((((((_82.y + _76.y) + _89.y) + _97.y) + _104.y) + _111.y) + _118.y) + _124.y) + _131.y) + _138.y) + _145.y) + _152.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 164\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability Image1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %45 %48\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %45 \"TEXCOORD\"\nOpName %48 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 2\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 4\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 7\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 1\nOpDecorate %29 NonWritable\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 2\nOpDecorate %32 NonWritable\nOpDecorate %35 DescriptorSet 0\nOpDecorate %35 Binding 3\nOpDecorate %35 NonWritable\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 4\nOpDecorate %38 NonWritable\nOpDecorate %41 DescriptorSet 0\nOpDecorate %41 Binding 5\nOpDecorate %41 NonWritable\nOpDecorate %45 Flat\nOpDecorate %45 Location 0\nOpDecorate %48 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %5 1D 0 0 0 2 R32i\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeImage %5 1D 0 1 0 2 R32i\n%31 = OpTypePointer UniformConstant %30\n%32 = OpVariable %31 UniformConstant\n%33 = OpTypeImage %5 2D 0 0 0 2 R32i\n%34 = OpTypePointer UniformConstant %33\n%35 = OpVariable %34 UniformConstant\n%36 = OpTypeImage %5 2D 0 1 0 2 R32i\n%37 = OpTypePointer UniformConstant %36\n%38 = OpVariable %37 UniformConstant\n%39 = OpTypeImage %5 3D 0 0 0 2 R32i\n%40 = OpTypePointer UniformConstant %39\n%41 = OpVariable %40 UniformConstant\n%42 = OpTypeInt 32 0\n%43 = OpTypeVector %42 4\n%44 = OpTypePointer Input %43\n%45 = OpVariable %44 Input\n%46 = OpTypeVector %5 2\n%47 = OpTypePointer Output %46\n%48 = OpVariable %47 Output\n%61 = OpTypePointer Input %42\n%63 = OpConstant %42 0\n%66 = OpConstant %42 1\n%69 = OpConstant %42 2\n%72 = OpConstant %42 3\n%74 = OpTypeVector %5 4\n%80 = OpTypeVector %42 2\n%95 = OpTypeVector %42 3\n%157 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %162\n%162 = OpLabel\n%49 = OpLoad %39 %41\n%50 = OpLoad %36 %38\n%51 = OpLoad %33 %35\n%52 = OpLoad %30 %32\n%53 = OpLoad %27 %29\n%54 = OpLoad %24 %26\n%55 = OpLoad %21 %23\n%56 = OpLoad %18 %20\n%57 = OpLoad %15 %17\n%58 = OpLoad %12 %14\n%59 = OpLoad %9 %11\n%60 = OpLoad %6 %8\n%62 = OpAccessChain %61 %45 %63\n%64 = OpLoad %42 %62\n%65 = OpAccessChain %61 %45 %66\n%67 = OpLoad %42 %65\n%68 = OpAccessChain %61 %45 %69\n%70 = OpLoad %42 %68\n%71 = OpAccessChain %61 %45 %72\n%73 = OpLoad %42 %71\n%75 = OpImageFetch %74 %60 %64 Lod %67\n%76 = OpBitcast %43 %75\n%77 = OpCompositeExtract %42 %76 0\n%78 = OpCompositeExtract %42 %76 1\n%81 = OpCompositeConstruct %80 %64 %67\n%79 = OpImageFetch %74 %59 %81 Lod %70\n%82 = OpBitcast %43 %79\n%83 = OpCompositeExtract %42 %82 0\n%84 = OpCompositeExtract %42 %82 1\n%85 = OpIAdd %42 %83 %77\n%86 = OpIAdd %42 %84 %78\n%88 = OpCompositeConstruct %80 %64 %67\n%87 = OpImageFetch %74 %58 %88 Lod %70\n%89 = OpBitcast %43 %87\n%90 = OpCompositeExtract %42 %89 0\n%91 = OpCompositeExtract %42 %89 1\n%92 = OpIAdd %42 %85 %90\n%93 = OpIAdd %42 %86 %91\n%96 = OpCompositeConstruct %95 %64 %67 %70\n%94 = OpImageFetch %74 %57 %96 Lod %73\n%97 = OpBitcast %43 %94\n%98 = OpCompositeExtract %42 %97 0\n%99 = OpCompositeExtract %42 %97 1\n%100 = OpIAdd %42 %92 %98\n%101 = OpIAdd %42 %93 %99\n%103 = OpCompositeConstruct %95 %64 %67 %70\n%102 = OpImageFetch %74 %56 %103 Lod %73\n%104 = OpBitcast %43 %102\n%105 = OpCompositeExtract %42 %104 0\n%106 = OpCompositeExtract %42 %104 1\n%107 = OpIAdd %42 %100 %105\n%108 = OpIAdd %42 %101 %106\n%110 = OpCompositeConstruct %80 %64 %67\n%109 = OpImageFetch %74 %55 %110 Sample %70\n%111 = OpBitcast %43 %109\n%112 = OpCompositeExtract %42 %111 0\n%113 = OpCompositeExtract %42 %111 1\n%114 = OpIAdd %42 %107 %112\n%115 = OpIAdd %42 %108 %113\n%117 = OpCompositeConstruct %95 %64 %67 %70\n%116 = OpImageFetch %74 %54 %117 Sample %73\n%118 = OpBitcast %43 %116\n%119 = OpCompositeExtract %42 %118 0\n%120 = OpCompositeExtract %42 %118 1\n%121 = OpIAdd %42 %114 %119\n%122 = OpIAdd %42 %115 %120\n%123 = OpImageRead %74 %53 %64 None\n%124 = OpBitcast %43 %123\n%125 = OpCompositeExtract %42 %124 0\n%126 = OpCompositeExtract %42 %124 1\n%127 = OpIAdd %42 %121 %125\n%128 = OpIAdd %42 %122 %126\n%130 = OpCompositeConstruct %80 %64 %67\n%129 = OpImageRead %74 %52 %130 None\n%131 = OpBitcast %43 %129\n%132 = OpCompositeExtract %42 %131 0\n%133 = OpCompositeExtract %42 %131 1\n%134 = OpIAdd %42 %127 %132\n%135 = OpIAdd %42 %128 %133\n%137 = OpCompositeConstruct %80 %64 %67\n%136 = OpImageRead %74 %51 %137 None\n%138 = OpBitcast %43 %136\n%139 = OpCompositeExtract %42 %138 0\n%140 = OpCompositeExtract %42 %138 1\n%141 = OpIAdd %42 %134 %139\n%142 = OpIAdd %42 %135 %140\n%144 = OpCompositeConstruct %95 %64 %67 %70\n%143 = OpImageRead %74 %50 %144 None\n%145 = OpBitcast %43 %143\n%146 = OpCompositeExtract %42 %145 0\n%147 = OpCompositeExtract %42 %145 1\n%148 = OpIAdd %42 %141 %146\n%149 = OpIAdd %42 %142 %147\n%151 = OpCompositeConstruct %95 %64 %67 %70\n%150 = OpImageRead %74 %49 %151 None\n%152 = OpBitcast %43 %150\n%153 = OpCompositeExtract %42 %152 0\n%154 = OpCompositeExtract %42 %152 1\n%155 = OpIAdd %42 %148 %153\n%156 = OpIAdd %42 %149 %154\n%158 = OpAccessChain %157 %48 %63\n%159 = OpBitcast %5 %155\nOpStore %158 %159\n%160 = OpAccessChain %157 %48 %66\n%161 = OpBitcast %5 %156\nOpStore %160 %161\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-load.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 1) uniform texture1D _8;\nlayout(set = 0, binding = 2) uniform texture1DArray _11;\nlayout(set = 0, binding = 3) uniform texture2D _14;\nlayout(set = 0, binding = 4) uniform texture2DArray _17;\nlayout(set = 0, binding = 5) uniform texture3D _20;\nlayout(set = 0, binding = 6) uniform texture2DMS _23;\nlayout(set = 0, binding = 7) uniform texture2DMSArray _26;\nlayout(set = 0, binding = 1, r32f) uniform readonly image1D _29;\nlayout(set = 0, binding = 2, r32f) uniform readonly image1DArray _32;\nlayout(set = 0, binding = 3, r32f) uniform readonly image2D _35;\nlayout(set = 0, binding = 4, r32f) uniform readonly image2DArray _38;\nlayout(set = 0, binding = 5, r32f) uniform readonly image3D _41;\n\nlayout(location = 0) flat in uvec4 TEXCOORD;\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _75 = texelFetch(_8, int(TEXCOORD.x), int(TEXCOORD.y));\n    vec4 _78 = texelFetch(_11, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z));\n    vec4 _85 = texelFetch(_14, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z));\n    vec4 _91 = texelFetch(_17, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w));\n    vec4 _98 = texelFetch(_20, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w));\n    vec4 _104 = texelFetch(_23, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(TEXCOORD.z));\n    vec4 _110 = texelFetch(_26, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(TEXCOORD.w));\n    vec4 _116 = imageLoad(_29, int(TEXCOORD.x));\n    vec4 _121 = imageLoad(_32, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)));\n    vec4 _127 = imageLoad(_35, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)));\n    vec4 _133 = imageLoad(_38, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)));\n    vec4 _139 = imageLoad(_41, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)));\n    SV_Target.x = ((((((((((_78.x + _75.x) + _85.x) + _91.x) + _98.x) + _104.x) + _110.x) + _116.x) + _121.x) + _127.x) + _133.x) + _139.x;\n    SV_Target.y = ((((((((((_78.y + _75.y) + _85.y) + _91.y) + _98.y) + _104.y) + _110.y) + _116.y) + _121.y) + _127.y) + _133.y) + _139.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 150\n; Schema: 0\nOpCapability Shader\nOpCapability Sampled1D\nOpCapability Image1D\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %45 %48\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %45 \"TEXCOORD\"\nOpName %48 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 2\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 4\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 5\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 6\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 7\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 1\nOpDecorate %29 NonWritable\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 2\nOpDecorate %32 NonWritable\nOpDecorate %35 DescriptorSet 0\nOpDecorate %35 Binding 3\nOpDecorate %35 NonWritable\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 4\nOpDecorate %38 NonWritable\nOpDecorate %41 DescriptorSet 0\nOpDecorate %41 Binding 5\nOpDecorate %41 NonWritable\nOpDecorate %45 Flat\nOpDecorate %45 Location 0\nOpDecorate %48 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %5 2D 0 1 1 1 Unknown\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %5 1D 0 0 0 2 R32f\n%28 = OpTypePointer UniformConstant %27\n%29 = OpVariable %28 UniformConstant\n%30 = OpTypeImage %5 1D 0 1 0 2 R32f\n%31 = OpTypePointer UniformConstant %30\n%32 = OpVariable %31 UniformConstant\n%33 = OpTypeImage %5 2D 0 0 0 2 R32f\n%34 = OpTypePointer UniformConstant %33\n%35 = OpVariable %34 UniformConstant\n%36 = OpTypeImage %5 2D 0 1 0 2 R32f\n%37 = OpTypePointer UniformConstant %36\n%38 = OpVariable %37 UniformConstant\n%39 = OpTypeImage %5 3D 0 0 0 2 R32f\n%40 = OpTypePointer UniformConstant %39\n%41 = OpVariable %40 UniformConstant\n%42 = OpTypeInt 32 0\n%43 = OpTypeVector %42 4\n%44 = OpTypePointer Input %43\n%45 = OpVariable %44 Input\n%46 = OpTypeVector %5 2\n%47 = OpTypePointer Output %46\n%48 = OpVariable %47 Output\n%61 = OpTypePointer Input %42\n%63 = OpConstant %42 0\n%66 = OpConstant %42 1\n%69 = OpConstant %42 2\n%72 = OpConstant %42 3\n%74 = OpTypeVector %5 4\n%79 = OpTypeVector %42 2\n%92 = OpTypeVector %42 3\n%145 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %148\n%148 = OpLabel\n%49 = OpLoad %39 %41\n%50 = OpLoad %36 %38\n%51 = OpLoad %33 %35\n%52 = OpLoad %30 %32\n%53 = OpLoad %27 %29\n%54 = OpLoad %24 %26\n%55 = OpLoad %21 %23\n%56 = OpLoad %18 %20\n%57 = OpLoad %15 %17\n%58 = OpLoad %12 %14\n%59 = OpLoad %9 %11\n%60 = OpLoad %6 %8\n%62 = OpAccessChain %61 %45 %63\n%64 = OpLoad %42 %62\n%65 = OpAccessChain %61 %45 %66\n%67 = OpLoad %42 %65\n%68 = OpAccessChain %61 %45 %69\n%70 = OpLoad %42 %68\n%71 = OpAccessChain %61 %45 %72\n%73 = OpLoad %42 %71\n%75 = OpImageFetch %74 %60 %64 Lod %67\n%76 = OpCompositeExtract %5 %75 0\n%77 = OpCompositeExtract %5 %75 1\n%80 = OpCompositeConstruct %79 %64 %67\n%78 = OpImageFetch %74 %59 %80 Lod %70\n%81 = OpCompositeExtract %5 %78 0\n%82 = OpCompositeExtract %5 %78 1\n%83 = OpFAdd %5 %81 %76\n%84 = OpFAdd %5 %82 %77\n%86 = OpCompositeConstruct %79 %64 %67\n%85 = OpImageFetch %74 %58 %86 Lod %70\n%87 = OpCompositeExtract %5 %85 0\n%88 = OpCompositeExtract %5 %85 1\n%89 = OpFAdd %5 %83 %87\n%90 = OpFAdd %5 %84 %88\n%93 = OpCompositeConstruct %92 %64 %67 %70\n%91 = OpImageFetch %74 %57 %93 Lod %73\n%94 = OpCompositeExtract %5 %91 0\n%95 = OpCompositeExtract %5 %91 1\n%96 = OpFAdd %5 %89 %94\n%97 = OpFAdd %5 %90 %95\n%99 = OpCompositeConstruct %92 %64 %67 %70\n%98 = OpImageFetch %74 %56 %99 Lod %73\n%100 = OpCompositeExtract %5 %98 0\n%101 = OpCompositeExtract %5 %98 1\n%102 = OpFAdd %5 %96 %100\n%103 = OpFAdd %5 %97 %101\n%105 = OpCompositeConstruct %79 %64 %67\n%104 = OpImageFetch %74 %55 %105 Sample %70\n%106 = OpCompositeExtract %5 %104 0\n%107 = OpCompositeExtract %5 %104 1\n%108 = OpFAdd %5 %102 %106\n%109 = OpFAdd %5 %103 %107\n%111 = OpCompositeConstruct %92 %64 %67 %70\n%110 = OpImageFetch %74 %54 %111 Sample %73\n%112 = OpCompositeExtract %5 %110 0\n%113 = OpCompositeExtract %5 %110 1\n%114 = OpFAdd %5 %108 %112\n%115 = OpFAdd %5 %109 %113\n%116 = OpImageRead %74 %53 %64 None\n%117 = OpCompositeExtract %5 %116 0\n%118 = OpCompositeExtract %5 %116 1\n%119 = OpFAdd %5 %114 %117\n%120 = OpFAdd %5 %115 %118\n%122 = OpCompositeConstruct %79 %64 %67\n%121 = OpImageRead %74 %52 %122 None\n%123 = OpCompositeExtract %5 %121 0\n%124 = OpCompositeExtract %5 %121 1\n%125 = OpFAdd %5 %119 %123\n%126 = OpFAdd %5 %120 %124\n%128 = OpCompositeConstruct %79 %64 %67\n%127 = OpImageRead %74 %51 %128 None\n%129 = OpCompositeExtract %5 %127 0\n%130 = OpCompositeExtract %5 %127 1\n%131 = OpFAdd %5 %125 %129\n%132 = OpFAdd %5 %126 %130\n%134 = OpCompositeConstruct %92 %64 %67 %70\n%133 = OpImageRead %74 %50 %134 None\n%135 = OpCompositeExtract %5 %133 0\n%136 = OpCompositeExtract %5 %133 1\n%137 = OpFAdd %5 %131 %135\n%138 = OpFAdd %5 %132 %136\n%140 = OpCompositeConstruct %92 %64 %67 %70\n%139 = OpImageRead %74 %49 %140 None\n%141 = OpCompositeExtract %5 %139 0\n%142 = OpCompositeExtract %5 %139 1\n%143 = OpFAdd %5 %137 %141\n%144 = OpFAdd %5 %138 %142\n%146 = OpAccessChain %145 %48 %63\nOpStore %146 %143\n%147 = OpAccessChain %145 %48 %66\nOpStore %147 %144\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-store-signed.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 1) uniform writeonly iimage1D _8;\nlayout(set = 0, binding = 2) uniform coherent writeonly iimage1DArray _11;\nlayout(set = 0, binding = 3) uniform writeonly iimage2D _14;\nlayout(set = 0, binding = 4) uniform coherent writeonly iimage2DArray _17;\nlayout(set = 0, binding = 5) uniform writeonly iimage3D _20;\n\nlayout(location = 0) in vec3 TEXCOORD;\n\nvoid main()\n{\n    uint _41 = uint(int(TEXCOORD.x));\n    imageStore(_8, int(_41), ivec4(uvec4(1u, 2u, 1u, 1u)));\n    uint _46 = uint(int(TEXCOORD.y));\n    imageStore(_11, ivec2(uvec2(_41, _46)), ivec4(uvec4(3u, 4u, 3u, 3u)));\n    imageStore(_14, ivec2(uvec2(_41, _46)), ivec4(uvec4(5u, 6u, 5u, 5u)));\n    uint _58 = uint(int(TEXCOORD.z));\n    imageStore(_17, ivec3(uvec3(_41, _46, _58)), ivec4(uvec4(7u, 8u, 7u, 7u)));\n    imageStore(_20, ivec3(uvec3(_41, _46, _58)), ivec4(uvec4(9u, 4294967287u, 9u, 9u)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %24\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %24 \"TEXCOORD\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %8 NonReadable\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 2\nOpDecorate %11 NonReadable\nOpDecorate %11 Coherent\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %14 NonReadable\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 4\nOpDecorate %17 NonReadable\nOpDecorate %17 Coherent\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 5\nOpDecorate %20 NonReadable\nOpDecorate %24 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeImage %5 1D 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 2 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 2 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 2 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 3\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%30 = OpTypePointer Input %21\n%32 = OpTypeInt 32 0\n%33 = OpConstant %32 0\n%36 = OpConstant %32 1\n%39 = OpConstant %32 2\n%42 = OpTypeVector %32 4\n%44 = OpTypeVector %5 4\n%47 = OpConstant %32 3\n%48 = OpConstant %32 4\n%49 = OpTypeVector %32 2\n%53 = OpConstant %32 5\n%54 = OpConstant %32 6\n%59 = OpConstant %32 7\n%60 = OpConstant %32 8\n%61 = OpTypeVector %32 3\n%65 = OpConstant %32 9\n%66 = OpConstant %32 4294967287\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %70\n%70 = OpLabel\n%25 = OpLoad %18 %20\n%26 = OpLoad %15 %17\n%27 = OpLoad %12 %14\n%28 = OpLoad %9 %11\n%29 = OpLoad %6 %8\n%31 = OpAccessChain %30 %24 %33\n%34 = OpLoad %21 %31\n%35 = OpAccessChain %30 %24 %36\n%37 = OpLoad %21 %35\n%38 = OpAccessChain %30 %24 %39\n%40 = OpLoad %21 %38\n%41 = OpConvertFToS %32 %34\n%43 = OpCompositeConstruct %42 %36 %39 %36 %36\n%45 = OpBitcast %44 %43\nOpImageWrite %29 %41 %45\n%46 = OpConvertFToS %32 %37\n%50 = OpCompositeConstruct %49 %41 %46\n%51 = OpCompositeConstruct %42 %47 %48 %47 %47\n%52 = OpBitcast %44 %51\nOpImageWrite %28 %50 %52\n%55 = OpCompositeConstruct %49 %41 %46\n%56 = OpCompositeConstruct %42 %53 %54 %53 %53\n%57 = OpBitcast %44 %56\nOpImageWrite %27 %55 %57\n%58 = OpConvertFToS %32 %40\n%62 = OpCompositeConstruct %61 %41 %46 %58\n%63 = OpCompositeConstruct %42 %59 %60 %59 %59\n%64 = OpBitcast %44 %63\nOpImageWrite %26 %62 %64\n%67 = OpCompositeConstruct %61 %41 %46 %58\n%68 = OpCompositeConstruct %42 %65 %66 %65 %65\n%69 = OpBitcast %44 %68\nOpImageWrite %25 %67 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture-store.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 1) uniform writeonly image1D _8;\nlayout(set = 0, binding = 2) uniform coherent writeonly image1DArray _11;\nlayout(set = 0, binding = 3) uniform writeonly image2D _14;\nlayout(set = 0, binding = 4) uniform coherent writeonly image2DArray _17;\nlayout(set = 0, binding = 5) uniform writeonly image3D _20;\n\nlayout(location = 0) in vec3 TEXCOORD;\n\nvoid main()\n{\n    uint _40 = uint(int(TEXCOORD.x));\n    imageStore(_8, int(_40), vec4(1.0, 2.0, 1.0, 1.0));\n    uint _45 = uint(int(TEXCOORD.y));\n    imageStore(_11, ivec2(uvec2(_40, _45)), vec4(3.0, 4.0, 3.0, 3.0));\n    imageStore(_14, ivec2(uvec2(_40, _45)), vec4(5.0, 6.0, 5.0, 5.0));\n    uint _55 = uint(int(TEXCOORD.z));\n    imageStore(_17, ivec3(uvec3(_40, _45, _55)), vec4(7.0, 8.0, 7.0, 7.0));\n    imageStore(_20, ivec3(uvec3(_40, _45, _55)), vec4(9.0, -9.0, 9.0, 9.0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 67\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %23 \"TEXCOORD\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 1\nOpDecorate %8 NonReadable\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 2\nOpDecorate %11 NonReadable\nOpDecorate %11 Coherent\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 3\nOpDecorate %14 NonReadable\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 4\nOpDecorate %17 NonReadable\nOpDecorate %17 Coherent\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 5\nOpDecorate %20 NonReadable\nOpDecorate %23 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 1D 0 1 0 2 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeImage %5 2D 0 1 0 2 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 3D 0 0 0 2 Unknown\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeVector %5 3\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%29 = OpTypePointer Input %5\n%31 = OpTypeInt 32 0\n%32 = OpConstant %31 0\n%35 = OpConstant %31 1\n%38 = OpConstant %31 2\n%41 = OpConstant %5 1\n%42 = OpConstant %5 2\n%43 = OpTypeVector %5 4\n%46 = OpConstant %5 3\n%47 = OpConstant %5 4\n%48 = OpTypeVector %31 2\n%51 = OpConstant %5 5\n%52 = OpConstant %5 6\n%56 = OpConstant %5 7\n%57 = OpConstant %5 8\n%58 = OpTypeVector %31 3\n%61 = OpConstant %5 9\n%62 = OpConstant %5 -9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %65\n%65 = OpLabel\n%24 = OpLoad %18 %20\n%25 = OpLoad %15 %17\n%26 = OpLoad %12 %14\n%27 = OpLoad %9 %11\n%28 = OpLoad %6 %8\n%30 = OpAccessChain %29 %23 %32\n%33 = OpLoad %5 %30\n%34 = OpAccessChain %29 %23 %35\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %29 %23 %38\n%39 = OpLoad %5 %37\n%40 = OpConvertFToS %31 %33\n%44 = OpCompositeConstruct %43 %41 %42 %41 %41\nOpImageWrite %28 %40 %44\n%45 = OpConvertFToS %31 %36\n%49 = OpCompositeConstruct %48 %40 %45\n%50 = OpCompositeConstruct %43 %46 %47 %46 %46\nOpImageWrite %27 %49 %50\n%53 = OpCompositeConstruct %48 %40 %45\n%54 = OpCompositeConstruct %43 %51 %52 %51 %51\nOpImageWrite %26 %53 %54\n%55 = OpConvertFToS %31 %39\n%59 = OpCompositeConstruct %58 %40 %45 %55\n%60 = OpCompositeConstruct %43 %56 %57 %56 %56\nOpImageWrite %25 %59 %60\n%63 = OpCompositeConstruct %58 %40 %45 %55\n%64 = OpCompositeConstruct %43 %61 %62 %61 %61\nOpImageWrite %24 %63 %64\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/texture2dms-sample-position.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nconst vec2 _77[31] = vec2[](vec2(0.0), vec2(0.25), vec2(-0.25), vec2(-0.125, -0.375), vec2(0.375, -0.125), vec2(-0.375, 0.125), vec2(0.125, 0.375), vec2(0.0625, -0.1875), vec2(-0.0625, 0.1875), vec2(0.3125, 0.0625), vec2(-0.1875, -0.3125), vec2(-0.3125, 0.3125), vec2(-0.4375, -0.0625), vec2(0.1875, 0.4375), vec2(0.4375, -0.4375), vec2(0.0625), vec2(-0.0625, -0.1875), vec2(-0.1875, 0.125), vec2(0.25, -0.0625), vec2(-0.3125, -0.125), vec2(0.125, 0.3125), vec2(0.3125, 0.1875), vec2(0.1875, -0.3125), vec2(-0.125, 0.375), vec2(0.0, -0.4375), vec2(-0.25, -0.375), vec2(-0.375, 0.25), vec2(-0.5, 0.0), vec2(0.4375, -0.25), vec2(0.375, 0.4375), vec2(-0.4375, -0.5));\n\nlayout(set = 0, binding = 0, std140) uniform _13_15\n{\n    vec4 _m0[1];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DMS _8;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _24 = floatBitsToUint(_15._m0[0u]);\n    uint _25 = _24.x;\n    uint _26 = uint(textureSamples(_8));\n    uint _87 = ((_25 < _26) && (_26 <= 16u)) ? ((_26 - 1u) + _25) : 0u;\n    SV_Target.x = _77[_87].x;\n    SV_Target.y = _77[_87].y;\n    SV_Target.z = 0.0;\n    SV_Target.w = 0.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\nOpCapability Shader\nOpCapability ImageQuery\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"\"\nOpName %17 \"SV_Target\"\nOpName %79 \"Texture2DMSSamplePositionLUT\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 ArrayStride 16\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %17 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 1 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeVector %5 4\n%12 = OpTypeArray %11 %10\n%13 = OpTypeStruct %12\n%14 = OpTypePointer Uniform %13\n%15 = OpVariable %14 Uniform\n%16 = OpTypePointer Output %11\n%17 = OpVariable %16 Output\n%19 = OpConstant %9 0\n%20 = OpTypePointer Uniform %11\n%23 = OpTypeVector %9 4\n%27 = OpTypeVector %5 2\n%28 = OpConstant %5 0\n%29 = OpConstantComposite %27 %28 %28\n%30 = OpConstant %5 0.25\n%31 = OpConstantComposite %27 %30 %30\n%32 = OpConstant %5 -0.25\n%33 = OpConstantComposite %27 %32 %32\n%34 = OpConstant %5 -0.125\n%35 = OpConstant %5 -0.375\n%36 = OpConstantComposite %27 %34 %35\n%37 = OpConstant %5 0.375\n%38 = OpConstantComposite %27 %37 %34\n%39 = OpConstant %5 0.125\n%40 = OpConstantComposite %27 %35 %39\n%41 = OpConstantComposite %27 %39 %37\n%42 = OpConstant %5 0.0625\n%43 = OpConstant %5 -0.1875\n%44 = OpConstantComposite %27 %42 %43\n%45 = OpConstant %5 -0.0625\n%46 = OpConstant %5 0.1875\n%47 = OpConstantComposite %27 %45 %46\n%48 = OpConstant %5 0.3125\n%49 = OpConstantComposite %27 %48 %42\n%50 = OpConstant %5 -0.3125\n%51 = OpConstantComposite %27 %43 %50\n%52 = OpConstantComposite %27 %50 %48\n%53 = OpConstant %5 -0.4375\n%54 = OpConstantComposite %27 %53 %45\n%55 = OpConstant %5 0.4375\n%56 = OpConstantComposite %27 %46 %55\n%57 = OpConstantComposite %27 %55 %53\n%58 = OpConstantComposite %27 %42 %42\n%59 = OpConstantComposite %27 %45 %43\n%60 = OpConstantComposite %27 %43 %39\n%61 = OpConstantComposite %27 %30 %45\n%62 = OpConstantComposite %27 %50 %34\n%63 = OpConstantComposite %27 %39 %48\n%64 = OpConstantComposite %27 %48 %46\n%65 = OpConstantComposite %27 %46 %50\n%66 = OpConstantComposite %27 %34 %37\n%67 = OpConstantComposite %27 %28 %53\n%68 = OpConstantComposite %27 %32 %35\n%69 = OpConstantComposite %27 %35 %30\n%70 = OpConstant %5 -0.5\n%71 = OpConstantComposite %27 %70 %28\n%72 = OpConstantComposite %27 %55 %32\n%73 = OpConstantComposite %27 %37 %55\n%74 = OpConstantComposite %27 %53 %70\n%75 = OpConstant %9 31\n%76 = OpTypeArray %27 %75\n%77 = OpConstantComposite %76 %29 %31 %33 %36 %38 %40 %41 %44 %47 %49 %51 %52 %54 %56 %57 %58 %59 %60 %61 %62 %63 %64 %65 %66 %67 %68 %69 %71 %72 %73 %74\n%78 = OpTypePointer Private %76\n%79 = OpVariable %78 Private %77\n%82 = OpTypeBool\n%85 = OpConstant %9 16\n%88 = OpTypePointer Private %27\n%93 = OpTypePointer Output %5\n%97 = OpConstant %9 2\n%99 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %100\n%100 = OpLabel\n%18 = OpLoad %6 %8\n%21 = OpAccessChain %20 %15 %19 %19\n%22 = OpLoad %11 %21\n%24 = OpBitcast %23 %22\n%25 = OpCompositeExtract %9 %24 0\n%26 = OpImageQuerySamples %9 %18\n%80 = OpISub %9 %26 %10\n%81 = OpIAdd %9 %80 %25\n%83 = OpULessThan %82 %25 %26\n%84 = OpULessThanEqual %82 %26 %85\n%86 = OpLogicalAnd %82 %83 %84\n%87 = OpSelect %9 %86 %81 %19\n%89 = OpAccessChain %88 %79 %87\n%90 = OpLoad %27 %89\n%91 = OpCompositeExtract %5 %90 0\n%92 = OpCompositeExtract %5 %90 1\n%94 = OpAccessChain %93 %17 %19\nOpStore %94 %91\n%95 = OpAccessChain %93 %17 %10\nOpStore %95 %92\n%96 = OpAccessChain %93 %17 %97\nOpStore %96 %28\n%98 = OpAccessChain %93 %17 %99\nOpStore %98 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/thread_id.comp",
    "content": "#version 460\nlayout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(10.0)));\n    imageStore(_8, int(gl_GlobalInvocationID.y), uvec4(floatBitsToUint(20.0)));\n    imageStore(_8, int(gl_GlobalInvocationID.z), uvec4(floatBitsToUint(30.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 2 2 2\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeFloat 32\n%24 = OpConstant %23 10\n%26 = OpTypeVector %5 4\n%28 = OpConstant %23 20\n%31 = OpConstant %23 30\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%25 = OpBitcast %5 %24\n%27 = OpCompositeConstruct %26 %25 %25 %25 %25\nOpImageWrite %9 %16 %27\n%29 = OpBitcast %5 %28\n%30 = OpCompositeConstruct %26 %29 %29 %29 %29\nOpImageWrite %9 %19 %30\n%32 = OpBitcast %5 %31\n%33 = OpCompositeConstruct %26 %32 %32 %32 %32\nOpImageWrite %9 %22 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/thread_id_in_group.comp",
    "content": "#version 460\nlayout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(gl_LocalInvocationID.x), uvec4(floatBitsToUint(10.0)));\n    imageStore(_8, int(gl_LocalInvocationID.y), uvec4(floatBitsToUint(20.0)));\n    imageStore(_8, int(gl_LocalInvocationID.z), uvec4(floatBitsToUint(30.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 2 2 2\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn LocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeFloat 32\n%24 = OpConstant %23 10\n%26 = OpTypeVector %5 4\n%28 = OpConstant %23 20\n%31 = OpConstant %23 30\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%25 = OpBitcast %5 %24\n%27 = OpCompositeConstruct %26 %25 %25 %25 %25\nOpImageWrite %9 %16 %27\n%29 = OpBitcast %5 %28\n%30 = OpCompositeConstruct %26 %29 %29 %29 %29\nOpImageWrite %9 %19 %30\n%32 = OpBitcast %5 %31\n%33 = OpCompositeConstruct %26 %32 %32 %32 %32\nOpImageWrite %9 %22 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/trace-ray-flags-2.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\n\nstruct _20\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0, std140) uniform FlagsUBO\n{\n    vec4 _m0[1];\n} Flags;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT AS;\nlayout(set = 0, binding = 0) uniform writeonly image2D IMG;\nlayout(location = 0) rayPayloadEXT _20 _22;\n\nvoid main()\n{\n    traceRayEXT(AS, floatBitsToUint(Flags._m0[0u]).x, 0u, 1u, 2u, 3u, vec3(1.0, 2.0, 3.0), 7.0, vec3(4.0, 5.0, 6.0), 8.0, 0);\n    imageStore(IMG, ivec2(uvec2(0u)), vec4(_22._m0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 57\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %19 %22\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %12 \"IMG\"\nOpName %17 \"FlagsUBO\"\nOpName %19 \"Flags\"\nOpName %20 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %16 ArrayStride 16\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 1\n%15 = OpTypeVector %9 4\n%16 = OpTypeArray %15 %14\n%17 = OpTypeStruct %16\n%18 = OpTypePointer Uniform %17\n%19 = OpVariable %18 Uniform\n%20 = OpTypeStruct %15\n%21 = OpTypePointer RayPayloadKHR %20\n%22 = OpVariable %21 RayPayloadKHR\n%23 = OpConstant %13 0\n%24 = OpTypePointer Uniform %15\n%27 = OpTypeVector %13 4\n%31 = OpConstant %13 2\n%32 = OpConstant %13 3\n%33 = OpConstant %9 1\n%34 = OpConstant %9 4\n%35 = OpConstant %9 2\n%36 = OpConstant %9 5\n%37 = OpConstant %9 3\n%38 = OpConstant %9 6\n%39 = OpConstant %9 7\n%40 = OpConstant %9 8\n%41 = OpTypeVector %9 3\n%44 = OpTypePointer RayPayloadKHR %15\n%52 = OpTypeVector %13 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %55\n%55 = OpLabel\n%25 = OpAccessChain %24 %19 %23 %23\n%26 = OpLoad %15 %25\n%28 = OpBitcast %27 %26\n%29 = OpCompositeExtract %13 %28 0\n%30 = OpLoad %6 %8\n%42 = OpCompositeConstruct %41 %33 %35 %37\n%43 = OpCompositeConstruct %41 %34 %36 %38\nOpTraceRayKHR %30 %29 %23 %14 %31 %32 %42 %39 %43 %40 %22\n%45 = OpInBoundsAccessChain %44 %22 %23\n%46 = OpLoad %15 %45\n%47 = OpLoad %10 %12\n%48 = OpCompositeExtract %9 %46 0\n%49 = OpCompositeExtract %9 %46 1\n%50 = OpCompositeExtract %9 %46 2\n%51 = OpCompositeExtract %9 %46 3\n%53 = OpCompositeConstruct %52 %23 %23\n%54 = OpCompositeConstruct %15 %48 %49 %50 %51\nOpImageWrite %47 %53 %54\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/trace-ray-flags.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(primitive_culling);\n\nstruct _14\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT AS;\nlayout(set = 0, binding = 0) uniform writeonly image2D IMG;\nlayout(location = 0) rayPayloadEXT _14 _16;\n\nvoid main()\n{\n    traceRayEXT(AS, 273u, 0u, 1u, 2u, 3u, vec3(1.0, 2.0, 3.0), 7.0, vec3(4.0, 5.0, 6.0), 8.0, 0);\n    imageStore(IMG, ivec2(uvec2(0u)), vec4(_16._m0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %16\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %12 \"IMG\"\nOpName %14 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %9 4\n%14 = OpTypeStruct %13\n%15 = OpTypePointer RayPayloadKHR %14\n%16 = OpVariable %15 RayPayloadKHR\n%18 = OpTypeInt 32 0\n%19 = OpConstant %18 273\n%20 = OpConstant %18 0\n%21 = OpConstant %18 1\n%22 = OpConstant %18 2\n%23 = OpConstant %18 3\n%24 = OpConstant %9 1\n%25 = OpConstant %9 4\n%26 = OpConstant %9 2\n%27 = OpConstant %9 5\n%28 = OpConstant %9 3\n%29 = OpConstant %9 6\n%30 = OpConstant %9 7\n%31 = OpConstant %9 8\n%32 = OpTypeVector %9 3\n%35 = OpTypePointer RayPayloadKHR %13\n%43 = OpTypeVector %18 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%17 = OpLoad %6 %8\n%33 = OpCompositeConstruct %32 %24 %26 %28\n%34 = OpCompositeConstruct %32 %25 %27 %29\nOpTraceRayKHR %17 %19 %20 %21 %22 %23 %33 %30 %34 %31 %16\n%36 = OpInBoundsAccessChain %35 %16 %20\n%37 = OpLoad %13 %36\n%38 = OpLoad %10 %12\n%39 = OpCompositeExtract %9 %37 0\n%40 = OpCompositeExtract %9 %37 1\n%41 = OpCompositeExtract %9 %37 2\n%42 = OpCompositeExtract %9 %37 3\n%44 = OpCompositeConstruct %43 %20 %20\n%45 = OpCompositeConstruct %13 %39 %40 %41 %42\nOpImageWrite %38 %44 %45\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/trace-ray.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _14\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT AS;\nlayout(set = 0, binding = 0) uniform writeonly image2D IMG;\nlayout(location = 0) rayPayloadEXT _14 _16;\n\nvoid main()\n{\n    traceRayEXT(AS, 17u, 0u, 1u, 2u, 3u, vec3(1.0, 2.0, 3.0), 7.0, vec3(4.0, 5.0, 6.0), 8.0, 0);\n    imageStore(IMG, ivec2(uvec2(0u)), vec4(_16._m0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %16\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %12 \"IMG\"\nOpName %14 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %9 4\n%14 = OpTypeStruct %13\n%15 = OpTypePointer RayPayloadKHR %14\n%16 = OpVariable %15 RayPayloadKHR\n%18 = OpTypeInt 32 0\n%19 = OpConstant %18 17\n%20 = OpConstant %18 0\n%21 = OpConstant %18 1\n%22 = OpConstant %18 2\n%23 = OpConstant %18 3\n%24 = OpConstant %9 1\n%25 = OpConstant %9 4\n%26 = OpConstant %9 2\n%27 = OpConstant %9 5\n%28 = OpConstant %9 3\n%29 = OpConstant %9 6\n%30 = OpConstant %9 7\n%31 = OpConstant %9 8\n%32 = OpTypeVector %9 3\n%35 = OpTypePointer RayPayloadKHR %13\n%43 = OpTypeVector %18 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%17 = OpLoad %6 %8\n%33 = OpCompositeConstruct %32 %24 %26 %28\n%34 = OpCompositeConstruct %32 %25 %27 %29\nOpTraceRayKHR %17 %19 %20 %21 %22 %23 %33 %30 %34 %31 %16\n%36 = OpInBoundsAccessChain %35 %16 %20\n%37 = OpLoad %13 %36\n%38 = OpLoad %10 %12\n%39 = OpCompositeExtract %9 %37 0\n%40 = OpCompositeExtract %9 %37 1\n%41 = OpCompositeExtract %9 %37 2\n%42 = OpCompositeExtract %9 %37 3\n%44 = OpCompositeConstruct %43 %20 %20\n%45 = OpCompositeConstruct %13 %39 %40 %41 %42\nOpImageWrite %38 %44 %45\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/umad.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec3 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x * A.y) + A.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 25\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 3\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%19 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %23\n%23 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpIMul %5 %14 %17\n%22 = OpIAdd %5 %21 %20\nOpStore %10 %22\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/umax.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec2 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = max(A.x, A.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\n%18 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%19 = OpExtInst %5 %18 UMax %14 %17\nOpStore %10 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/umin.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec2 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = min(A.x, A.y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\n%18 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%19 = OpExtInst %5 %18 UMin %14 %17\nOpStore %10 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/vertex-id.vert",
    "content": "#version 460\n\nvoid main()\n{\n    float _16 = float(uint(gl_VertexIndex) - uint(gl_BaseVertex));\n    gl_Position.x = _16;\n    gl_Position.y = _16;\n    gl_Position.z = _16;\n    gl_Position.w = _16;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability DrawParameters\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"SV_VertexID\"\nOpName %11 \"SV_Position\"\nOpDecorate %7 BuiltIn VertexIndex\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn BaseVertex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%13 = OpVariable %6 Input\n%17 = OpTypePointer Output %8\n%19 = OpConstant %5 0\n%21 = OpConstant %5 1\n%23 = OpConstant %5 2\n%25 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%12 = OpLoad %5 %7\n%14 = OpLoad %5 %13\n%15 = OpISub %5 %12 %14\n%16 = OpConvertUToF %8 %15\n%18 = OpAccessChain %17 %11 %19\nOpStore %18 %16\n%20 = OpAccessChain %17 %11 %21\nOpStore %20 %16\n%22 = OpAccessChain %17 %11 %23\nOpStore %22 %16\n%24 = OpAccessChain %17 %11 %25\nOpStore %24 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-all-true.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    if (subgroupAll(gl_GlobalInvocationID.x < 100u))\n    {\n        imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(1u));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 31\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeBool\n%19 = OpConstant %5 100\n%21 = OpConstant %5 3\n%23 = OpConstant %5 2\n%24 = OpConstant %5 1\n%25 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpULessThan %17 %16 %19\n%20 = OpGroupNonUniformAll %17 %21 %18\nOpSelectionMerge %29 None\nOpBranchConditional %20 %28 %29\n%28 = OpLabel\n%22 = OpShiftLeftLogical %5 %16 %23\n%26 = OpCompositeConstruct %25 %24 %24 %24 %24\nOpImageWrite %9 %16 %26\nOpBranch %29\n%29 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-all-true.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_vote : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    if (subgroupAll((INDEX < 100u) || (gl_HelperInvocation || discard_state)))\n    {\n        imageStore(_8, int(INDEX), uvec4(1u));\n    }\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %10 %37\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"INDEX\"\nOpName %17 \"discard_state\"\nOpName %40 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %10 Flat\nOpDecorate %10 Location 0\nOpDecorate %37 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%13 = OpTypeBool\n%15 = OpConstant %5 40\n%16 = OpTypePointer Private %13\n%17 = OpVariable %16 Private\n%18 = OpConstantFalse %13\n%20 = OpConstant %5 100\n%22 = OpConstant %5 3\n%26 = OpConstant %5 2\n%27 = OpConstant %5 1\n%28 = OpTypeVector %5 4\n%35 = OpConstantTrue %13\n%36 = OpTypePointer Input %13\n%37 = OpVariable %36 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %17 %18\nOpBranch %30\n%30 = OpLabel\n%11 = OpLoad %6 %8\n%12 = OpLoad %5 %10\n%14 = OpIEqual %13 %12 %15\nOpSelectionMerge %32 None\nOpBranchConditional %14 %31 %32\n%31 = OpLabel\nOpStore %17 %35\nOpBranch %32\n%32 = OpLabel\n%19 = OpULessThan %13 %12 %20\n%38 = OpLoad %13 %37\n%39 = OpLoad %13 %17\n%23 = OpLogicalOr %13 %38 %39\n%24 = OpLogicalOr %13 %19 %23\n%21 = OpGroupNonUniformAll %13 %22 %24\nOpSelectionMerge %34 None\nOpBranchConditional %21 %33 %34\n%33 = OpLabel\n%25 = OpShiftLeftLogical %5 %12 %26\n%29 = OpCompositeConstruct %28 %27 %27 %27 %27\nOpImageWrite %11 %12 %29\nOpBranch %34\n%34 = OpLabel\n%46 = OpFunctionCall %1 %40\nOpReturn\nOpFunctionEnd\n%40 = OpFunction %1 None %2\n%41 = OpLabel\n%44 = OpLoad %13 %17\nOpSelectionMerge %43 None\nOpBranchConditional %44 %42 %43\n%42 = OpLabel\nOpKill\n%43 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-any-true.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    if (subgroupAny(gl_GlobalInvocationID.x < 100u))\n    {\n        imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(1u));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 31\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeBool\n%19 = OpConstant %5 100\n%21 = OpConstant %5 3\n%23 = OpConstant %5 2\n%24 = OpConstant %5 1\n%25 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpULessThan %17 %16 %19\n%20 = OpGroupNonUniformAny %17 %21 %18\nOpSelectionMerge %29 None\nOpBranchConditional %20 %28 %29\n%28 = OpLabel\n%22 = OpShiftLeftLogical %5 %16 %23\n%26 = OpCompositeConstruct %25 %24 %24 %24 %24\nOpImageWrite %9 %16 %26\nOpBranch %29\n%29 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-any-true.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_vote : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    if (subgroupAny((INDEX < 100u) && (!(gl_HelperInvocation || discard_state))))\n    {\n        imageStore(_8, int(INDEX), uvec4(1u));\n    }\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %10 %38\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"INDEX\"\nOpName %17 \"discard_state\"\nOpName %41 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %10 Flat\nOpDecorate %10 Location 0\nOpDecorate %38 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%13 = OpTypeBool\n%15 = OpConstant %5 40\n%16 = OpTypePointer Private %13\n%17 = OpVariable %16 Private\n%18 = OpConstantFalse %13\n%20 = OpConstant %5 100\n%22 = OpConstant %5 3\n%27 = OpConstant %5 2\n%28 = OpConstant %5 1\n%29 = OpTypeVector %5 4\n%36 = OpConstantTrue %13\n%37 = OpTypePointer Input %13\n%38 = OpVariable %37 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %17 %18\nOpBranch %31\n%31 = OpLabel\n%11 = OpLoad %6 %8\n%12 = OpLoad %5 %10\n%14 = OpIEqual %13 %12 %15\nOpSelectionMerge %33 None\nOpBranchConditional %14 %32 %33\n%32 = OpLabel\nOpStore %17 %36\nOpBranch %33\n%33 = OpLabel\n%19 = OpULessThan %13 %12 %20\n%39 = OpLoad %13 %38\n%40 = OpLoad %13 %17\n%23 = OpLogicalOr %13 %39 %40\n%24 = OpLogicalNot %13 %23\n%25 = OpLogicalAnd %13 %19 %24\n%21 = OpGroupNonUniformAny %13 %22 %25\nOpSelectionMerge %35 None\nOpBranchConditional %21 %34 %35\n%34 = OpLabel\n%26 = OpShiftLeftLogical %5 %12 %27\n%30 = OpCompositeConstruct %29 %28 %28 %28 %28\nOpImageWrite %11 %12 %30\nOpBranch %35\n%35 = OpLabel\n%47 = OpFunctionCall %1 %41\nOpReturn\nOpFunctionEnd\n%41 = OpFunction %1 None %2\n%42 = OpLabel\n%45 = OpLoad %13 %17\nOpSelectionMerge %44 None\nOpBranchConditional %45 %43 %44\n%43 = OpLabel\nOpKill\n%44 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-ballot-discard.demote-to-helper.frag",
    "content": "#version 460\n#extension GL_EXT_demote_to_helper_invocation : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out uvec4 SV_Target;\n\nvoid main()\n{\n    if (INDEX == 40u)\n    {\n        demote;\n    }\n    bool _17 = helperInvocationEXT();\n    uvec4 _20 = subgroupBallot((INDEX < 100u) && (!_17));\n    SV_Target.x = _20.x;\n    SV_Target.y = _20.y;\n    SV_Target.z = _20.z;\n    SV_Target.w = _20.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpCapability DemoteToHelperInvocation\nOpExtension \"SPV_EXT_demote_to_helper_invocation\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"INDEX\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 4\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%12 = OpTypeBool\n%14 = OpConstant %5 40\n%16 = OpConstant %5 100\n%21 = OpConstant %5 3\n%26 = OpTypePointer Output %5\n%28 = OpConstant %5 0\n%30 = OpConstant %5 1\n%32 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%11 = OpLoad %5 %7\n%13 = OpIEqual %12 %11 %14\nOpSelectionMerge %36 None\nOpBranchConditional %13 %35 %36\n%35 = OpLabel\nOpDemoteToHelperInvocation\nOpBranch %36\n%36 = OpLabel\n%15 = OpULessThan %12 %11 %16\n%17 = OpIsHelperInvocationEXT %12\n%18 = OpLogicalNot %12 %17\n%19 = OpLogicalAnd %12 %15 %18\n%20 = OpGroupNonUniformBallot %8 %21 %19\n%22 = OpCompositeExtract %5 %20 0\n%23 = OpCompositeExtract %5 %20 1\n%24 = OpCompositeExtract %5 %20 2\n%25 = OpCompositeExtract %5 %20 3\n%27 = OpAccessChain %26 %10 %28\nOpStore %27 %22\n%29 = OpAccessChain %26 %10 %30\nOpStore %29 %23\n%31 = OpAccessChain %26 %10 %32\nOpStore %31 %24\n%33 = OpAccessChain %26 %10 %21\nOpStore %33 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-ballot-discard.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out uvec4 SV_Target;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    uvec4 _23 = subgroupBallot((INDEX < 100u) && (!(gl_HelperInvocation || discard_state)));\n    SV_Target.x = _23.x;\n    SV_Target.y = _23.y;\n    SV_Target.z = _23.z;\n    SV_Target.w = _23.w;\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 53\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10 %42\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"INDEX\"\nOpName %10 \"SV_Target\"\nOpName %16 \"discard_state\"\nOpName %45 \"discard_exit\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\nOpDecorate %42 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 4\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%12 = OpTypeBool\n%14 = OpConstant %5 40\n%15 = OpTypePointer Private %12\n%16 = OpVariable %15 Private\n%17 = OpConstantFalse %12\n%19 = OpConstant %5 100\n%24 = OpConstant %5 3\n%29 = OpTypePointer Output %5\n%31 = OpConstant %5 0\n%33 = OpConstant %5 1\n%35 = OpConstant %5 2\n%40 = OpConstantTrue %12\n%41 = OpTypePointer Input %12\n%42 = OpVariable %41 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %16 %17\nOpBranch %37\n%37 = OpLabel\n%11 = OpLoad %5 %7\n%13 = OpIEqual %12 %11 %14\nOpSelectionMerge %39 None\nOpBranchConditional %13 %38 %39\n%38 = OpLabel\nOpStore %16 %40\nOpBranch %39\n%39 = OpLabel\n%18 = OpULessThan %12 %11 %19\n%43 = OpLoad %12 %42\n%44 = OpLoad %12 %16\n%20 = OpLogicalOr %12 %43 %44\n%21 = OpLogicalNot %12 %20\n%22 = OpLogicalAnd %12 %18 %21\n%23 = OpGroupNonUniformBallot %8 %24 %22\n%25 = OpCompositeExtract %5 %23 0\n%26 = OpCompositeExtract %5 %23 1\n%27 = OpCompositeExtract %5 %23 2\n%28 = OpCompositeExtract %5 %23 3\n%30 = OpAccessChain %29 %10 %31\nOpStore %30 %25\n%32 = OpAccessChain %29 %10 %33\nOpStore %32 %26\n%34 = OpAccessChain %29 %10 %35\nOpStore %34 %27\n%36 = OpAccessChain %29 %10 %24\nOpStore %36 %28\n%51 = OpFunctionCall %1 %45\nOpReturn\nOpFunctionEnd\n%45 = OpFunction %1 None %2\n%46 = OpLabel\n%49 = OpLoad %12 %16\nOpSelectionMerge %48 None\nOpBranchConditional %49 %47 %48\n%47 = OpLabel\nOpKill\n%48 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-ballot.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uvec4 _21 = subgroupBallot(gl_GlobalInvocationID.x < 100u);\n    uint _29 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_8, int(_29), uvec4(_21.x));\n    imageStore(_8, int(_29 + 1u), uvec4(_21.y));\n    imageStore(_8, int(_29 + 2u), uvec4(_21.z));\n    imageStore(_8, int(_29 + 3u), uvec4(_21.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeBool\n%19 = OpConstant %5 100\n%20 = OpTypeVector %5 4\n%22 = OpConstant %5 3\n%28 = OpConstant %5 4\n%33 = OpConstant %5 1\n%36 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpULessThan %17 %16 %19\n%21 = OpGroupNonUniformBallot %20 %22 %18\n%23 = OpCompositeExtract %5 %21 0\n%24 = OpCompositeExtract %5 %21 1\n%25 = OpCompositeExtract %5 %21 2\n%26 = OpCompositeExtract %5 %21 3\n%27 = OpShiftLeftLogical %5 %16 %28\n%29 = OpIMul %5 %16 %28\n%30 = OpCompositeConstruct %20 %23 %23 %23 %23\nOpImageWrite %9 %29 %30\n%31 = OpCompositeConstruct %20 %24 %24 %24 %24\n%32 = OpIAdd %5 %29 %33\nOpImageWrite %9 %32 %31\n%34 = OpCompositeConstruct %20 %25 %25 %25 %25\n%35 = OpIAdd %5 %29 %36\nOpImageWrite %9 %35 %34\n%37 = OpCompositeConstruct %20 %26 %26 %26 %26\n%38 = OpIAdd %5 %29 %22\nOpImageWrite %9 %38 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-ballot.demote-to-helper.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out uvec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _18 = subgroupBallot((INDEX < 100u) && (!gl_HelperInvocation));\n    SV_Target.x = _18.x;\n    SV_Target.y = _18.y;\n    SV_Target.z = _18.z;\n    SV_Target.w = _18.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10 %34\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"INDEX\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\nOpDecorate %34 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 4\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%12 = OpTypeBool\n%14 = OpConstant %5 100\n%19 = OpConstant %5 3\n%24 = OpTypePointer Output %5\n%26 = OpConstant %5 0\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%33 = OpTypePointer Input %12\n%34 = OpVariable %33 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%11 = OpLoad %5 %7\n%13 = OpULessThan %12 %11 %14\n%15 = OpLoad %12 %34\n%16 = OpLogicalNot %12 %15\n%17 = OpLogicalAnd %12 %13 %16\n%18 = OpGroupNonUniformBallot %8 %19 %17\n%20 = OpCompositeExtract %5 %18 0\n%21 = OpCompositeExtract %5 %18 1\n%22 = OpCompositeExtract %5 %18 2\n%23 = OpCompositeExtract %5 %18 3\n%25 = OpAccessChain %24 %10 %26\nOpStore %25 %20\n%27 = OpAccessChain %24 %10 %28\nOpStore %27 %21\n%29 = OpAccessChain %24 %10 %30\nOpStore %29 %22\n%31 = OpAccessChain %24 %10 %19\nOpStore %31 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-ballot.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out uvec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _18 = subgroupBallot((INDEX < 100u) && (!gl_HelperInvocation));\n    SV_Target.x = _18.x;\n    SV_Target.y = _18.y;\n    SV_Target.z = _18.z;\n    SV_Target.w = _18.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10 %34\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"INDEX\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\nOpDecorate %34 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 4\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%12 = OpTypeBool\n%14 = OpConstant %5 100\n%19 = OpConstant %5 3\n%24 = OpTypePointer Output %5\n%26 = OpConstant %5 0\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%33 = OpTypePointer Input %12\n%34 = OpVariable %33 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%11 = OpLoad %5 %7\n%13 = OpULessThan %12 %11 %14\n%15 = OpLoad %12 %34\n%16 = OpLogicalNot %12 %15\n%17 = OpLogicalAnd %12 %13 %16\n%18 = OpGroupNonUniformBallot %8 %19 %17\n%20 = OpCompositeExtract %5 %18 0\n%21 = OpCompositeExtract %5 %18 1\n%22 = OpCompositeExtract %5 %18 2\n%23 = OpCompositeExtract %5 %18 3\n%25 = OpAccessChain %24 %10 %26\nOpStore %25 %20\n%27 = OpAccessChain %24 %10 %28\nOpStore %27 %21\n%29 = OpAccessChain %24 %10 %30\nOpStore %29 %22\n%31 = OpAccessChain %24 %10 %19\nOpStore %31 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-count-bits.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(subgroupBallotBitCount(subgroupBallot(gl_GlobalInvocationID.x < 100u))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeBool\n%19 = OpConstant %5 100\n%20 = OpTypeVector %5 4\n%22 = OpConstant %5 3\n%25 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpULessThan %17 %16 %19\n%21 = OpGroupNonUniformBallot %20 %22 %18\n%23 = OpGroupNonUniformBallotBitCount %5 %22 Reduce %21\n%24 = OpShiftLeftLogical %5 %16 %25\n%26 = OpCompositeConstruct %20 %23 %23 %23 %23\nOpImageWrite %9 %16 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-active-count-bits.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    imageStore(_8, int(INDEX), uvec4(subgroupBallotBitCount(subgroupBallot((INDEX < 100u) && (!(gl_HelperInvocation || discard_state))))));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %10 %36\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"INDEX\"\nOpName %17 \"discard_state\"\nOpName %39 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %10 Flat\nOpDecorate %10 Location 0\nOpDecorate %36 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%13 = OpTypeBool\n%15 = OpConstant %5 40\n%16 = OpTypePointer Private %13\n%17 = OpVariable %16 Private\n%18 = OpConstantFalse %13\n%20 = OpConstant %5 100\n%21 = OpTypeVector %5 4\n%23 = OpConstant %5 3\n%29 = OpConstant %5 2\n%34 = OpConstantTrue %13\n%35 = OpTypePointer Input %13\n%36 = OpVariable %35 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %17 %18\nOpBranch %31\n%31 = OpLabel\n%11 = OpLoad %6 %8\n%12 = OpLoad %5 %10\n%14 = OpIEqual %13 %12 %15\nOpSelectionMerge %33 None\nOpBranchConditional %14 %32 %33\n%32 = OpLabel\nOpStore %17 %34\nOpBranch %33\n%33 = OpLabel\n%19 = OpULessThan %13 %12 %20\n%37 = OpLoad %13 %36\n%38 = OpLoad %13 %17\n%24 = OpLogicalOr %13 %37 %38\n%25 = OpLogicalNot %13 %24\n%26 = OpLogicalAnd %13 %19 %25\n%22 = OpGroupNonUniformBallot %21 %23 %26\n%27 = OpGroupNonUniformBallotBitCount %5 %23 Reduce %22\n%28 = OpShiftLeftLogical %5 %12 %29\n%30 = OpCompositeConstruct %21 %27 %27 %27 %27\nOpImageWrite %11 %12 %30\n%45 = OpFunctionCall %1 %39\nOpReturn\nOpFunctionEnd\n%39 = OpFunction %1 None %2\n%40 = OpLabel\n%43 = OpLoad %13 %17\nOpSelectionMerge %42 None\nOpBranchConditional %43 %41 %42\n%41 = OpLabel\nOpKill\n%42 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-all-equal.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    if (subgroupAllEqual(gl_GlobalInvocationID.x))\n    {\n        imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(1u));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeBool\n%19 = OpConstant %5 3\n%21 = OpConstant %5 2\n%22 = OpConstant %5 1\n%23 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpGroupNonUniformAllEqual %17 %19 %16\nOpSelectionMerge %27 None\nOpBranchConditional %18 %26 %27\n%26 = OpLabel\n%20 = OpShiftLeftLogical %5 %16 %21\n%24 = OpCompositeConstruct %23 %22 %22 %22 %22\nOpImageWrite %9 %16 %24\nOpBranch %27\n%27 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-all-equal.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_vote : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    if (subgroupAllEqual(INDEX))\n    {\n        imageStore(_8, int(INDEX), uvec4(1u));\n    }\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"INDEX\"\nOpName %17 \"discard_state\"\nOpName %32 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %10 Flat\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%13 = OpTypeBool\n%15 = OpConstant %5 40\n%16 = OpTypePointer Private %13\n%17 = OpVariable %16 Private\n%18 = OpConstantFalse %13\n%20 = OpConstant %5 3\n%22 = OpConstant %5 2\n%23 = OpConstant %5 1\n%24 = OpTypeVector %5 4\n%31 = OpConstantTrue %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %17 %18\nOpBranch %26\n%26 = OpLabel\n%11 = OpLoad %6 %8\n%12 = OpLoad %5 %10\n%14 = OpIEqual %13 %12 %15\nOpSelectionMerge %28 None\nOpBranchConditional %14 %27 %28\n%27 = OpLabel\nOpStore %17 %31\nOpBranch %28\n%28 = OpLabel\n%19 = OpGroupNonUniformAllEqual %13 %20 %12\nOpSelectionMerge %30 None\nOpBranchConditional %19 %29 %30\n%29 = OpLabel\n%21 = OpShiftLeftLogical %5 %12 %22\n%25 = OpCompositeConstruct %24 %23 %23 %23 %23\nOpImageWrite %11 %12 %25\nOpBranch %30\n%30 = OpLabel\n%38 = OpFunctionCall %1 %32\nOpReturn\nOpFunctionEnd\n%32 = OpFunction %1 None %2\n%33 = OpLabel\n%36 = OpLoad %13 %17\nOpSelectionMerge %35 None\nOpBranchConditional %36 %34 %35\n%34 = OpLabel\nOpKill\n%35 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-get-lane-count.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(0u), uvec4(gl_SubgroupSize));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 18\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %11\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 BuiltIn SubgroupSize\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%13 = OpConstant %5 0\n%14 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %16\n%16 = OpLabel\n%9 = OpLoad %6 %8\n%12 = OpLoad %5 %11\n%15 = OpCompositeConstruct %14 %12 %12 %12 %12\nOpImageWrite %9 %13 %15\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-get-lane-index.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(0u), uvec4(gl_SubgroupInvocationID));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 18\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %11\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%13 = OpConstant %5 0\n%14 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %16\n%16 = OpLabel\n%9 = OpLoad %6 %8\n%12 = OpLoad %5 %11\n%15 = OpCompositeConstruct %14 %12 %12 %12 %12\nOpImageWrite %9 %13 %15\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-is-first-lane.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    if (subgroupElect())\n    {\n        imageStore(_8, int(0u), uvec4(1u));\n    }\n    else\n    {\n        imageStore(_8, int(0u), uvec4(0u));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeBool\n%12 = OpConstant %5 3\n%13 = OpConstant %5 0\n%14 = OpConstant %5 1\n%15 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %18\n%18 = OpLabel\n%9 = OpLoad %6 %8\n%11 = OpGroupNonUniformElect %10 %12\nOpSelectionMerge %21 None\nOpBranchConditional %11 %20 %19\n%20 = OpLabel\n%16 = OpCompositeConstruct %15 %14 %14 %14 %14\nOpImageWrite %9 %13 %16\nOpBranch %21\n%19 = OpLabel\n%17 = OpCompositeConstruct %15 %13 %13 %13 %13\nOpImageWrite %9 %13 %17\nOpBranch %21\n%21 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-is-first-lane.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nlayout(location = 0) flat in uint THR;\nbool discard_state;\n\nbool WaveIsFirstLane(bool _21)\n{\n    bool _29;\n    if (_21)\n    {\n        _29 = false;\n    }\n    else\n    {\n        _29 = subgroupElect();\n    }\n    return _29;\n}\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (THR == 40u)\n    {\n        discard_state = true;\n    }\n    if (WaveIsFirstLane(gl_HelperInvocation || discard_state))\n    {\n        imageStore(_8, int(0u), uvec4(1u));\n    }\n    else\n    {\n        imageStore(_8, int(0u), uvec4(0u));\n    }\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %10 %45\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"THR\"\nOpName %17 \"discard_state\"\nOpName %22 \"WaveIsFirstLane\"\nOpName %48 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %10 Flat\nOpDecorate %10 Location 0\nOpDecorate %45 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%13 = OpTypeBool\n%15 = OpConstant %5 40\n%16 = OpTypePointer Private %13\n%17 = OpVariable %16 Private\n%18 = OpConstantFalse %13\n%20 = OpTypeFunction %13 %13\n%28 = OpConstant %5 3\n%32 = OpConstant %5 0\n%33 = OpConstant %5 1\n%34 = OpTypeVector %5 4\n%43 = OpConstantTrue %13\n%44 = OpTypePointer Input %13\n%45 = OpVariable %44 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %17 %18\nOpBranch %37\n%37 = OpLabel\n%11 = OpLoad %6 %8\n%12 = OpLoad %5 %10\n%14 = OpIEqual %13 %12 %15\nOpSelectionMerge %39 None\nOpBranchConditional %14 %38 %39\n%38 = OpLabel\nOpStore %17 %43\nOpBranch %39\n%39 = OpLabel\n%46 = OpLoad %13 %45\n%47 = OpLoad %13 %17\n%19 = OpLogicalOr %13 %46 %47\n%31 = OpFunctionCall %13 %22 %19\nOpSelectionMerge %42 None\nOpBranchConditional %31 %41 %40\n%41 = OpLabel\n%35 = OpCompositeConstruct %34 %33 %33 %33 %33\nOpImageWrite %11 %32 %35\nOpBranch %42\n%40 = OpLabel\n%36 = OpCompositeConstruct %34 %32 %32 %32 %32\nOpImageWrite %11 %32 %36\nOpBranch %42\n%42 = OpLabel\n%54 = OpFunctionCall %1 %48\nOpReturn\nOpFunctionEnd\n%22 = OpFunction %13 None %20\n%21 = OpFunctionParameter %13\n%23 = OpLabel\nOpSelectionMerge %26 None\nOpBranchConditional %21 %24 %25\n%24 = OpLabel\nOpBranch %26\n%25 = OpLabel\n%27 = OpGroupNonUniformElect %13 %28\nOpBranch %26\n%26 = OpLabel\n%29 = OpPhi %13 %27 %25 %18 %24\nOpReturnValue %29\nOpFunctionEnd\n%48 = OpFunction %1 None %2\n%49 = OpLabel\n%52 = OpLoad %13 %17\nOpSelectionMerge %51 None\nOpBranchConditional %52 %50 %51\n%50 = OpLabel\nOpKill\n%51 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-match.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _11;\n\nuvec4 WaveMatch(uint _26)\n{\n    uvec4 _35;\n    for (;;)\n    {\n        bool _34 = _26 == subgroupBroadcastFirst(_26);\n        _35 = subgroupBallot(_34);\n        if (_34)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _35;\n}\n\nvoid main()\n{\n    uvec4 _37 = WaveMatch(texelFetch(_8, int(gl_GlobalInvocationID.x)).x);\n    uvec4 _47 = WaveMatch(floatBitsToUint(uintBitsToFloat(texelFetch(_8, int(gl_GlobalInvocationID.x)).x)));\n    uvec4 _64 = WaveMatch(floatBitsToUint(float(texelFetch(_8, int(gl_GlobalInvocationID.x)).x != 20u)));\n    uint _73 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_11, int(_73), uvec4((_47.x | _37.x) | _64.x));\n    imageStore(_11, int(_73 + 1u), uvec4((_47.y | _37.y) | _64.y));\n    imageStore(_11, int(_73 + 2u), uvec4((_47.z | _37.z) | _64.z));\n    imageStore(_11, int(_73 + 3u), uvec4((_47.w | _37.w) | _64.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 86\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %27 \"WaveMatch\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%21 = OpTypeVector %5 4\n%24 = OpTypeBool\n%25 = OpTypeFunction %21 %5\n%33 = OpConstant %5 3\n%44 = OpTypeFloat 32\n%59 = OpConstant %5 20\n%60 = OpConstant %44 0\n%61 = OpConstant %44 1\n%74 = OpConstant %5 4\n%78 = OpConstant %5 1\n%81 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %84\n%84 = OpLabel\n%12 = OpLoad %9 %11\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%22 = OpImageFetch %21 %13 %20\n%23 = OpCompositeExtract %5 %22 0\n%37 = OpFunctionCall %21 %27 %23\n%38 = OpCompositeExtract %5 %37 0\n%39 = OpCompositeExtract %5 %37 1\n%40 = OpCompositeExtract %5 %37 2\n%41 = OpCompositeExtract %5 %37 3\n%42 = OpImageFetch %21 %13 %20\n%43 = OpCompositeExtract %5 %42 0\n%45 = OpBitcast %44 %43\n%46 = OpBitcast %5 %45\n%47 = OpFunctionCall %21 %27 %46\n%48 = OpCompositeExtract %5 %47 0\n%49 = OpCompositeExtract %5 %47 1\n%50 = OpCompositeExtract %5 %47 2\n%51 = OpCompositeExtract %5 %47 3\n%52 = OpBitwiseOr %5 %48 %38\n%53 = OpBitwiseOr %5 %49 %39\n%54 = OpBitwiseOr %5 %50 %40\n%55 = OpBitwiseOr %5 %51 %41\n%56 = OpImageFetch %21 %13 %20\n%57 = OpCompositeExtract %5 %56 0\n%58 = OpINotEqual %24 %57 %59\n%62 = OpSelect %44 %58 %61 %60\n%63 = OpBitcast %5 %62\n%64 = OpFunctionCall %21 %27 %63\n%65 = OpCompositeExtract %5 %64 0\n%66 = OpCompositeExtract %5 %64 1\n%67 = OpCompositeExtract %5 %64 2\n%68 = OpCompositeExtract %5 %64 3\n%69 = OpBitwiseOr %5 %52 %65\n%70 = OpBitwiseOr %5 %53 %66\n%71 = OpBitwiseOr %5 %54 %67\n%72 = OpBitwiseOr %5 %55 %68\n%73 = OpIMul %5 %20 %74\n%75 = OpCompositeConstruct %21 %69 %69 %69 %69\nOpImageWrite %12 %73 %75\n%76 = OpCompositeConstruct %21 %70 %70 %70 %70\n%77 = OpIAdd %5 %73 %78\nOpImageWrite %12 %77 %76\n%79 = OpCompositeConstruct %21 %71 %71 %71 %71\n%80 = OpIAdd %5 %73 %81\nOpImageWrite %12 %80 %79\n%82 = OpCompositeConstruct %21 %72 %72 %72 %72\n%83 = OpIAdd %5 %73 %33\nOpImageWrite %12 %83 %82\nOpReturn\nOpFunctionEnd\n%27 = OpFunction %21 None %25\n%26 = OpFunctionParameter %5\n%28 = OpLabel\nOpBranch %29\n%29 = OpLabel\nOpLoopMerge %31 %30 None\nOpBranch %30\n%30 = OpLabel\n%32 = OpGroupNonUniformBroadcastFirst %5 %33 %26\n%34 = OpIEqual %24 %26 %32\n%35 = OpGroupNonUniformBallot %21 %33 %34\nOpBranchConditional %34 %31 %29\n%31 = OpLabel\nOpReturnValue %35\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-match.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n\nuvec4 _36;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _11;\n\nlayout(location = 0) flat in uint THR;\nbool discard_state;\n\nuvec4 WaveMatch(uint _27, bool _28)\n{\n    uvec4 _41;\n    if (_28)\n    {\n        _41 = _36;\n    }\n    else\n    {\n        uvec4 _40;\n        for (;;)\n        {\n            bool _39 = _27 == subgroupBroadcastFirst(_27);\n            _40 = subgroupBallot(_39);\n            if (_39)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _41 = _40;\n    }\n    return _41;\n}\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (THR == 40u)\n    {\n        discard_state = true;\n    }\n    uvec4 _43 = WaveMatch(texelFetch(_8, int(THR)).x, gl_HelperInvocation || discard_state);\n    uvec4 _54 = WaveMatch(floatBitsToUint(uintBitsToFloat(texelFetch(_8, int(THR)).x)), gl_HelperInvocation || discard_state);\n    uvec4 _72 = WaveMatch(floatBitsToUint(float(texelFetch(_8, int(THR)).x != 20u)), gl_HelperInvocation || discard_state);\n    uint _82 = THR * 4u;\n    imageStore(_11, int(_82), uvec4((_54.x | _43.x) | _72.x));\n    imageStore(_11, int(_82 + 1u), uvec4((_54.y | _43.y) | _72.y));\n    imageStore(_11, int(_82 + 2u), uvec4((_54.z | _43.z) | _72.z));\n    imageStore(_11, int(_82 + 3u), uvec4((_54.w | _43.w) | _72.w));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 113\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %98\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"THR\"\nOpName %21 \"discard_state\"\nOpName %29 \"WaveMatch\"\nOpName %105 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %13 Flat\nOpDecorate %13 Location 0\nOpDecorate %98 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypePointer Input %5\n%13 = OpVariable %12 Input\n%17 = OpTypeBool\n%19 = OpConstant %5 40\n%20 = OpTypePointer Private %17\n%21 = OpVariable %20 Private\n%22 = OpConstantFalse %17\n%23 = OpTypeVector %5 4\n%26 = OpTypeFunction %23 %5 %17\n%38 = OpConstant %5 3\n%51 = OpTypeFloat 32\n%67 = OpConstant %5 20\n%68 = OpConstant %51 0\n%69 = OpConstant %51 1\n%83 = OpConstant %5 4\n%87 = OpConstant %5 1\n%90 = OpConstant %5 2\n%96 = OpConstantTrue %17\n%97 = OpTypePointer Input %17\n%98 = OpVariable %97 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %21 %22\nOpBranch %93\n%93 = OpLabel\n%14 = OpLoad %9 %11\n%15 = OpLoad %6 %8\n%16 = OpLoad %5 %13\n%18 = OpIEqual %17 %16 %19\nOpSelectionMerge %95 None\nOpBranchConditional %18 %94 %95\n%94 = OpLabel\nOpStore %21 %96\nOpBranch %95\n%95 = OpLabel\n%24 = OpImageFetch %23 %15 %16\n%25 = OpCompositeExtract %5 %24 0\n%99 = OpLoad %17 %98\n%100 = OpLoad %17 %21\n%44 = OpLogicalOr %17 %99 %100\n%43 = OpFunctionCall %23 %29 %25 %44\n%45 = OpCompositeExtract %5 %43 0\n%46 = OpCompositeExtract %5 %43 1\n%47 = OpCompositeExtract %5 %43 2\n%48 = OpCompositeExtract %5 %43 3\n%49 = OpImageFetch %23 %15 %16\n%50 = OpCompositeExtract %5 %49 0\n%52 = OpBitcast %51 %50\n%53 = OpBitcast %5 %52\n%101 = OpLoad %17 %98\n%102 = OpLoad %17 %21\n%55 = OpLogicalOr %17 %101 %102\n%54 = OpFunctionCall %23 %29 %53 %55\n%56 = OpCompositeExtract %5 %54 0\n%57 = OpCompositeExtract %5 %54 1\n%58 = OpCompositeExtract %5 %54 2\n%59 = OpCompositeExtract %5 %54 3\n%60 = OpBitwiseOr %5 %56 %45\n%61 = OpBitwiseOr %5 %57 %46\n%62 = OpBitwiseOr %5 %58 %47\n%63 = OpBitwiseOr %5 %59 %48\n%64 = OpImageFetch %23 %15 %16\n%65 = OpCompositeExtract %5 %64 0\n%66 = OpINotEqual %17 %65 %67\n%70 = OpSelect %51 %66 %69 %68\n%71 = OpBitcast %5 %70\n%103 = OpLoad %17 %98\n%104 = OpLoad %17 %21\n%73 = OpLogicalOr %17 %103 %104\n%72 = OpFunctionCall %23 %29 %71 %73\n%74 = OpCompositeExtract %5 %72 0\n%75 = OpCompositeExtract %5 %72 1\n%76 = OpCompositeExtract %5 %72 2\n%77 = OpCompositeExtract %5 %72 3\n%78 = OpBitwiseOr %5 %60 %74\n%79 = OpBitwiseOr %5 %61 %75\n%80 = OpBitwiseOr %5 %62 %76\n%81 = OpBitwiseOr %5 %63 %77\n%82 = OpIMul %5 %16 %83\n%84 = OpCompositeConstruct %23 %78 %78 %78 %78\nOpImageWrite %14 %82 %84\n%85 = OpCompositeConstruct %23 %79 %79 %79 %79\n%86 = OpIAdd %5 %82 %87\nOpImageWrite %14 %86 %85\n%88 = OpCompositeConstruct %23 %80 %80 %80 %80\n%89 = OpIAdd %5 %82 %90\nOpImageWrite %14 %89 %88\n%91 = OpCompositeConstruct %23 %81 %81 %81 %81\n%92 = OpIAdd %5 %82 %38\nOpImageWrite %14 %92 %91\n%111 = OpFunctionCall %1 %105\nOpReturn\nOpFunctionEnd\n%29 = OpFunction %23 None %26\n%27 = OpFunctionParameter %5\n%28 = OpFunctionParameter %17\n%30 = OpLabel\nOpBranch %31\n%31 = OpLabel\n%36 = OpUndef %23\nOpSelectionMerge %34 None\nOpBranchConditional %28 %34 %35\n%35 = OpLabel\nOpLoopMerge %33 %32 None\nOpBranch %32\n%32 = OpLabel\n%37 = OpGroupNonUniformBroadcastFirst %5 %38 %27\n%39 = OpIEqual %17 %27 %37\n%40 = OpGroupNonUniformBallot %23 %38 %39\nOpBranchConditional %39 %33 %35\n%33 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%41 = OpPhi %23 %40 %33 %36 %31\nOpReturnValue %41\nOpFunctionEnd\n%105 = OpFunction %1 None %2\n%106 = OpLabel\n%109 = OpLoad %17 %21\nOpSelectionMerge %108 None\nOpBranchConditional %109 %107 %108\n%107 = OpLabel\nOpKill\n%108 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-match.partitioned.noglsl.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 75\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformPartitionedEXT\nOpExtension \"SPV_NV_shader_subgroup_partitioned\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%21 = OpTypeVector %5 4\n%31 = OpTypeFloat 32\n%45 = OpTypeBool\n%47 = OpConstant %5 20\n%48 = OpConstant %31 0\n%49 = OpConstant %31 1\n%62 = OpConstant %5 4\n%66 = OpConstant %5 1\n%69 = OpConstant %5 2\n%72 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%12 = OpLoad %9 %11\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%22 = OpImageFetch %21 %13 %20\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpGroupNonUniformPartitionEXT %21 %23\n%25 = OpCompositeExtract %5 %24 0\n%26 = OpCompositeExtract %5 %24 1\n%27 = OpCompositeExtract %5 %24 2\n%28 = OpCompositeExtract %5 %24 3\n%29 = OpImageFetch %21 %13 %20\n%30 = OpCompositeExtract %5 %29 0\n%32 = OpBitcast %31 %30\n%33 = OpBitcast %5 %32\n%34 = OpGroupNonUniformPartitionEXT %21 %33\n%35 = OpCompositeExtract %5 %34 0\n%36 = OpCompositeExtract %5 %34 1\n%37 = OpCompositeExtract %5 %34 2\n%38 = OpCompositeExtract %5 %34 3\n%39 = OpBitwiseOr %5 %35 %25\n%40 = OpBitwiseOr %5 %36 %26\n%41 = OpBitwiseOr %5 %37 %27\n%42 = OpBitwiseOr %5 %38 %28\n%43 = OpImageFetch %21 %13 %20\n%44 = OpCompositeExtract %5 %43 0\n%46 = OpINotEqual %45 %44 %47\n%50 = OpSelect %31 %46 %49 %48\n%51 = OpBitcast %5 %50\n%52 = OpGroupNonUniformPartitionEXT %21 %51\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpCompositeExtract %5 %52 1\n%55 = OpCompositeExtract %5 %52 2\n%56 = OpCompositeExtract %5 %52 3\n%57 = OpBitwiseOr %5 %39 %53\n%58 = OpBitwiseOr %5 %40 %54\n%59 = OpBitwiseOr %5 %41 %55\n%60 = OpBitwiseOr %5 %42 %56\n%61 = OpIMul %5 %20 %62\n%63 = OpCompositeConstruct %21 %57 %57 %57 %57\nOpImageWrite %12 %61 %63\n%64 = OpCompositeConstruct %21 %58 %58 %58 %58\n%65 = OpIAdd %5 %61 %66\nOpImageWrite %12 %65 %64\n%67 = OpCompositeConstruct %21 %59 %59 %59 %59\n%68 = OpIAdd %5 %61 %69\nOpImageWrite %12 %68 %67\n%70 = OpCompositeConstruct %21 %60 %60 %60 %60\n%71 = OpIAdd %5 %61 %72\nOpImageWrite %12 %71 %70\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-match.partitioned.noglsl.frag",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 85\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpCapability GroupNonUniformPartitionedEXT\nOpExtension \"SPV_NV_shader_subgroup_partitioned\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %83\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"THR\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\nOpDecorate %13 Flat\nOpDecorate %13 Location 0\nOpDecorate %83 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypePointer Input %5\n%13 = OpVariable %12 Input\n%17 = OpTypeVector %5 4\n%21 = OpTypeBool\n%25 = OpConstant %5 3\n%33 = OpTypeFloat 32\n%52 = OpConstant %5 20\n%53 = OpConstant %33 0\n%54 = OpConstant %33 1\n%71 = OpConstant %5 4\n%75 = OpConstant %5 1\n%78 = OpConstant %5 2\n%82 = OpTypePointer Input %21\n%83 = OpVariable %82 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %81\n%81 = OpLabel\n%14 = OpLoad %9 %11\n%15 = OpLoad %6 %8\n%16 = OpLoad %5 %13\n%18 = OpImageFetch %17 %15 %16\n%19 = OpCompositeExtract %5 %18 0\n%20 = OpGroupNonUniformPartitionEXT %17 %19\n%22 = OpLoad %21 %83\n%23 = OpLogicalNot %21 %22\n%24 = OpGroupNonUniformBallot %17 %25 %23\n%26 = OpBitwiseAnd %17 %20 %24\n%27 = OpCompositeExtract %5 %26 0\n%28 = OpCompositeExtract %5 %26 1\n%29 = OpCompositeExtract %5 %26 2\n%30 = OpCompositeExtract %5 %26 3\n%31 = OpImageFetch %17 %15 %16\n%32 = OpCompositeExtract %5 %31 0\n%34 = OpBitcast %33 %32\n%35 = OpBitcast %5 %34\n%36 = OpGroupNonUniformPartitionEXT %17 %35\n%37 = OpLoad %21 %83\n%38 = OpLogicalNot %21 %37\n%39 = OpGroupNonUniformBallot %17 %25 %38\n%40 = OpBitwiseAnd %17 %36 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpBitwiseOr %5 %41 %27\n%46 = OpBitwiseOr %5 %42 %28\n%47 = OpBitwiseOr %5 %43 %29\n%48 = OpBitwiseOr %5 %44 %30\n%49 = OpImageFetch %17 %15 %16\n%50 = OpCompositeExtract %5 %49 0\n%51 = OpINotEqual %21 %50 %52\n%55 = OpSelect %33 %51 %54 %53\n%56 = OpBitcast %5 %55\n%57 = OpGroupNonUniformPartitionEXT %17 %56\n%58 = OpLoad %21 %83\n%59 = OpLogicalNot %21 %58\n%60 = OpGroupNonUniformBallot %17 %25 %59\n%61 = OpBitwiseAnd %17 %57 %60\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpCompositeExtract %5 %61 1\n%64 = OpCompositeExtract %5 %61 2\n%65 = OpCompositeExtract %5 %61 3\n%66 = OpBitwiseOr %5 %45 %62\n%67 = OpBitwiseOr %5 %46 %63\n%68 = OpBitwiseOr %5 %47 %64\n%69 = OpBitwiseOr %5 %48 %65\n%70 = OpIMul %5 %16 %71\n%72 = OpCompositeConstruct %17 %66 %66 %66 %66\nOpImageWrite %14 %70 %72\n%73 = OpCompositeConstruct %17 %67 %67 %67 %67\n%74 = OpIAdd %5 %70 %75\nOpImageWrite %14 %74 %73\n%76 = OpCompositeConstruct %17 %68 %68 %68 %68\n%77 = OpIAdd %5 %70 %78\nOpImageWrite %14 %77 %76\n%79 = OpCompositeConstruct %17 %69 %69 %69 %69\n%80 = OpIAdd %5 %70 %25\nOpImageWrite %14 %80 %79\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-multi-prefix-count-bits.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _9;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _12;\n\nuint WaveMultiPrefixCountBits(bool _52, uvec4 _53)\n{\n    uvec4 _59 = subgroupBallot(true);\n    uvec4 _61 = _59 & _53;\n    uint _67;\n    for (;;)\n    {\n        bool _64 = all(equal(_61, subgroupBroadcastFirst(_61)));\n        _67 = subgroupBallotExclusiveBitCount(subgroupBallot(_64 && _52));\n        if (_64)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _67;\n}\n\nvoid main()\n{\n    uint _23 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_12, int(gl_GlobalInvocationID.x), uvec4(WaveMultiPrefixCountBits(texelFetch(_8, int(gl_GlobalInvocationID.x)).x != 10u, uvec4(uvec4(texelFetch(_9, int(_23)).x, texelFetch(_9, int(_23 + 1u)).x, texelFetch(_9, int(_23 + 2u)).x, texelFetch(_9, int(_23 + 3u)).x)))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 74\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %54 \"WaveMultiPrefixCountBits\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%16 = OpTypeVector %5 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %5\n%21 = OpConstant %5 0\n%24 = OpConstant %5 4\n%25 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%34 = OpConstant %5 2\n%38 = OpConstant %5 3\n%47 = OpTypeBool\n%49 = OpConstant %5 10\n%50 = OpTypeVector %47 4\n%51 = OpTypeFunction %5 %47 %25\n%60 = OpConstantTrue %47\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %72\n%72 = OpLabel\n%13 = OpLoad %10 %12\n%14 = OpLoad %6 %9\n%15 = OpLoad %6 %8\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpIMul %5 %22 %24\n%26 = OpImageFetch %25 %14 %23\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpIAdd %5 %23 %30\n%28 = OpImageFetch %25 %14 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %23 %34\n%32 = OpImageFetch %25 %14 %33\n%35 = OpCompositeExtract %5 %32 0\n%37 = OpIAdd %5 %23 %38\n%36 = OpImageFetch %25 %14 %37\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeConstruct %25 %27 %31 %35 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpImageFetch %25 %15 %22\n%46 = OpCompositeExtract %5 %45 0\n%48 = OpINotEqual %47 %46 %49\n%70 = OpCompositeConstruct %25 %41 %42 %43 %44\n%69 = OpFunctionCall %5 %54 %48 %70\n%71 = OpCompositeConstruct %25 %69 %69 %69 %69\nOpImageWrite %13 %22 %71\nOpReturn\nOpFunctionEnd\n%54 = OpFunction %5 None %51\n%52 = OpFunctionParameter %47\n%53 = OpFunctionParameter %25\n%55 = OpLabel\n%59 = OpGroupNonUniformBallot %25 %38 %60\n%61 = OpBitwiseAnd %25 %59 %53\nOpBranch %56\n%56 = OpLabel\nOpLoopMerge %58 %57 None\nOpBranch %57\n%57 = OpLabel\n%62 = OpGroupNonUniformBroadcastFirst %25 %38 %61\n%63 = OpIEqual %50 %61 %62\n%64 = OpAll %47 %63\n%65 = OpLogicalAnd %47 %64 %52\n%66 = OpGroupNonUniformBallot %25 %38 %65\n%67 = OpGroupNonUniformBallotBitCount %5 %38 ExclusiveScan %66\nOpBranchConditional %64 %58 %56\n%58 = OpLabel\nOpReturnValue %67\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-multi-prefix-count-bits.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n\nuint _63;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _9;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _12;\n\nlayout(location = 0) flat in uint THR;\nbool discard_state;\n\nuint WaveMultiPrefixCountBits(bool _53, uvec4 _54, bool _55)\n{\n    uint _73;\n    if (_55)\n    {\n        _73 = _63;\n    }\n    else\n    {\n        uvec4 _64 = subgroupBallot(true);\n        uvec4 _66 = _64 & _54;\n        uint _72;\n        for (;;)\n        {\n            bool _69 = all(equal(_66, subgroupBroadcastFirst(_66)));\n            _72 = subgroupBallotExclusiveBitCount(subgroupBallot(_69 && _53));\n            if (_69)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _73 = _72;\n    }\n    return _73;\n}\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (THR == 40u)\n    {\n        discard_state = true;\n    }\n    uint _25 = THR * 4u;\n    imageStore(_12, int(THR), uvec4(WaveMultiPrefixCountBits(texelFetch(_8, int(THR)).x != 10u, uvec4(uvec4(texelFetch(_9, int(_25)).x, texelFetch(_9, int(_25 + 1u)).x, texelFetch(_9, int(_25 + 2u)).x, texelFetch(_9, int(_25 + 3u)).x)), gl_HelperInvocation || discard_state)));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 94\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %83\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"THR\"\nOpName %23 \"discard_state\"\nOpName %56 \"WaveMultiPrefixCountBits\"\nOpName %86 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %83 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%19 = OpTypeBool\n%21 = OpConstant %5 40\n%22 = OpTypePointer Private %19\n%23 = OpVariable %22 Private\n%24 = OpConstantFalse %19\n%26 = OpConstant %5 4\n%27 = OpTypeVector %5 4\n%32 = OpConstant %5 1\n%36 = OpConstant %5 2\n%40 = OpConstant %5 3\n%50 = OpConstant %5 10\n%51 = OpTypeVector %19 4\n%52 = OpTypeFunction %5 %19 %27 %19\n%65 = OpConstantTrue %19\n%82 = OpTypePointer Input %19\n%83 = OpVariable %82 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %23 %24\nOpBranch %79\n%79 = OpLabel\n%15 = OpLoad %10 %12\n%16 = OpLoad %6 %9\n%17 = OpLoad %6 %8\n%18 = OpLoad %5 %14\n%20 = OpIEqual %19 %18 %21\nOpSelectionMerge %81 None\nOpBranchConditional %20 %80 %81\n%80 = OpLabel\nOpStore %23 %65\nOpBranch %81\n%81 = OpLabel\n%25 = OpIMul %5 %18 %26\n%28 = OpImageFetch %27 %16 %25\n%29 = OpCompositeExtract %5 %28 0\n%31 = OpIAdd %5 %25 %32\n%30 = OpImageFetch %27 %16 %31\n%33 = OpCompositeExtract %5 %30 0\n%35 = OpIAdd %5 %25 %36\n%34 = OpImageFetch %27 %16 %35\n%37 = OpCompositeExtract %5 %34 0\n%39 = OpIAdd %5 %25 %40\n%38 = OpImageFetch %27 %16 %39\n%41 = OpCompositeExtract %5 %38 0\n%42 = OpCompositeConstruct %27 %29 %33 %37 %41\n%43 = OpCompositeExtract %5 %42 0\n%44 = OpCompositeExtract %5 %42 1\n%45 = OpCompositeExtract %5 %42 2\n%46 = OpCompositeExtract %5 %42 3\n%47 = OpImageFetch %27 %17 %18\n%48 = OpCompositeExtract %5 %47 0\n%49 = OpINotEqual %19 %48 %50\n%76 = OpCompositeConstruct %27 %43 %44 %45 %46\n%84 = OpLoad %19 %83\n%85 = OpLoad %19 %23\n%77 = OpLogicalOr %19 %84 %85\n%75 = OpFunctionCall %5 %56 %49 %76 %77\n%78 = OpCompositeConstruct %27 %75 %75 %75 %75\nOpImageWrite %15 %18 %78\n%92 = OpFunctionCall %1 %86\nOpReturn\nOpFunctionEnd\n%56 = OpFunction %5 None %52\n%53 = OpFunctionParameter %19\n%54 = OpFunctionParameter %27\n%55 = OpFunctionParameter %19\n%57 = OpLabel\n%63 = OpUndef %5\nOpSelectionMerge %61 None\nOpBranchConditional %55 %61 %62\n%62 = OpLabel\n%64 = OpGroupNonUniformBallot %27 %40 %65\n%66 = OpBitwiseAnd %27 %64 %54\nOpBranch %58\n%58 = OpLabel\nOpLoopMerge %60 %59 None\nOpBranch %59\n%59 = OpLabel\n%67 = OpGroupNonUniformBroadcastFirst %27 %40 %66\n%68 = OpIEqual %51 %66 %67\n%69 = OpAll %19 %68\n%70 = OpLogicalAnd %19 %69 %53\n%71 = OpGroupNonUniformBallot %27 %40 %70\n%72 = OpGroupNonUniformBallotBitCount %5 %40 ExclusiveScan %71\nOpBranchConditional %69 %60 %58\n%60 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%73 = OpPhi %5 %72 %60 %63 %57\nOpReturnValue %73\nOpFunctionEnd\n%86 = OpFunction %1 None %2\n%87 = OpLabel\n%90 = OpLoad %19 %23\nOpSelectionMerge %89 None\nOpBranchConditional %90 %88 %89\n%88 = OpLabel\nOpKill\n%89 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-multi-prefix-op.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nuint _54;\nfloat _101;\nuint _145;\nfloat _189;\nuint _233;\nuint _278;\nuint _324;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _9;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _12;\n\nuint WaveMultiPrefixSum(uint _50, uvec4 _51)\n{\n    uvec4 _60 = subgroupBallot(true);\n    uvec4 _62 = _60 & _51;\n    bool _65;\n    uint _67;\n    for (;;)\n    {\n        _65 = all(equal(_62, subgroupBroadcastFirst(_62)));\n        if (_65)\n        {\n            _67 = subgroupExclusiveAdd(_50);\n        }\n        else\n        {\n            _67 = _54;\n        }\n        if (_65)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _67;\n}\n\nfloat WaveMultiPrefixSum(float _97, uvec4 _98)\n{\n    uvec4 _107 = subgroupBallot(true);\n    uvec4 _108 = _107 & _98;\n    bool _111;\n    float _113;\n    for (;;)\n    {\n        _111 = all(equal(_108, subgroupBroadcastFirst(_108)));\n        if (_111)\n        {\n            _113 = subgroupExclusiveAdd(_97);\n        }\n        else\n        {\n            _113 = _101;\n        }\n        if (_111)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _113;\n}\n\nuint WaveMultiPrefixProduct(uint _141, uvec4 _142)\n{\n    uvec4 _151 = subgroupBallot(true);\n    uvec4 _152 = _151 & _142;\n    bool _155;\n    uint _157;\n    for (;;)\n    {\n        _155 = all(equal(_152, subgroupBroadcastFirst(_152)));\n        if (_155)\n        {\n            _157 = subgroupExclusiveMul(_141);\n        }\n        else\n        {\n            _157 = _145;\n        }\n        if (_155)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _157;\n}\n\nfloat WaveMultiPrefixProduct(float _185, uvec4 _186)\n{\n    uvec4 _195 = subgroupBallot(true);\n    uvec4 _196 = _195 & _186;\n    bool _199;\n    float _201;\n    for (;;)\n    {\n        _199 = all(equal(_196, subgroupBroadcastFirst(_196)));\n        if (_199)\n        {\n            _201 = subgroupExclusiveMul(_185);\n        }\n        else\n        {\n            _201 = _189;\n        }\n        if (_199)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _201;\n}\n\nuint WaveMultiPrefixBitOr(uint _229, uvec4 _230)\n{\n    uvec4 _239 = subgroupBallot(true);\n    uvec4 _240 = _239 & _230;\n    bool _243;\n    uint _245;\n    for (;;)\n    {\n        _243 = all(equal(_240, subgroupBroadcastFirst(_240)));\n        if (_243)\n        {\n            _245 = subgroupExclusiveOr(_229);\n        }\n        else\n        {\n            _245 = _233;\n        }\n        if (_243)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _245;\n}\n\nuint WaveMultiPrefixBitAnd(uint _274, uvec4 _275)\n{\n    uvec4 _284 = subgroupBallot(true);\n    uvec4 _285 = _284 & _275;\n    bool _288;\n    uint _290;\n    for (;;)\n    {\n        _288 = all(equal(_285, subgroupBroadcastFirst(_285)));\n        if (_288)\n        {\n            _290 = subgroupExclusiveAnd(_274);\n        }\n        else\n        {\n            _290 = _278;\n        }\n        if (_288)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _290;\n}\n\nuint WaveMultiPrefixBitXor(uint _320, uvec4 _321)\n{\n    uvec4 _330 = subgroupBallot(true);\n    uvec4 _331 = _330 & _321;\n    bool _334;\n    uint _336;\n    for (;;)\n    {\n        _334 = all(equal(_331, subgroupBroadcastFirst(_331)));\n        if (_334)\n        {\n            _336 = subgroupExclusiveXor(_320);\n        }\n        else\n        {\n            _336 = _324;\n        }\n        if (_334)\n        {\n            break;\n        }\n        else\n        {\n            continue;\n        }\n    }\n    return _336;\n}\n\nvoid main()\n{\n    uint _23 = gl_GlobalInvocationID.x * 4u;\n    uint _71 = gl_GlobalInvocationID.x * 7u;\n    imageStore(_12, int(gl_GlobalInvocationID.x * 7u), uvec4(WaveMultiPrefixSum(texelFetch(_8, int(gl_GlobalInvocationID.x)).x, uvec4(uvec4(texelFetch(_9, int(_23)).x, texelFetch(_9, int(_23 + 1u)).x, texelFetch(_9, int(_23 + 2u)).x, texelFetch(_9, int(_23 + 3u)).x)))));\n    uint _75 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_12, int((gl_GlobalInvocationID.x * 7u) + 1u), uvec4(uint(WaveMultiPrefixSum(uintBitsToFloat(texelFetch(_8, int(gl_GlobalInvocationID.x)).x), uvec4(uvec4(texelFetch(_9, int(_75)).x, texelFetch(_9, int(_75 + 1u)).x, texelFetch(_9, int(_75 + 2u)).x, texelFetch(_9, int(_75 + 3u)).x))))));\n    uint _122 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_12, int((gl_GlobalInvocationID.x * 7u) + 2u), uvec4(WaveMultiPrefixProduct(texelFetch(_8, int(gl_GlobalInvocationID.x)).x, uvec4(uvec4(texelFetch(_9, int(_122)).x, texelFetch(_9, int(_122 + 1u)).x, texelFetch(_9, int(_122 + 2u)).x, texelFetch(_9, int(_122 + 3u)).x)))));\n    uint _165 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_12, int((gl_GlobalInvocationID.x * 7u) + 3u), uvec4(uint(WaveMultiPrefixProduct(uintBitsToFloat(texelFetch(_8, int(gl_GlobalInvocationID.x)).x), uvec4(uvec4(texelFetch(_9, int(_165)).x, texelFetch(_9, int(_165 + 1u)).x, texelFetch(_9, int(_165 + 2u)).x, texelFetch(_9, int(_165 + 3u)).x))))));\n    uint _210 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_12, int((gl_GlobalInvocationID.x * 7u) + 4u), uvec4(WaveMultiPrefixBitOr(texelFetch(_8, int(gl_GlobalInvocationID.x)).x, uvec4(uvec4(texelFetch(_9, int(_210)).x, texelFetch(_9, int(_210 + 1u)).x, texelFetch(_9, int(_210 + 2u)).x, texelFetch(_9, int(_210 + 3u)).x)))));\n    uint _253 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_12, int((gl_GlobalInvocationID.x * 7u) + 5u), uvec4(WaveMultiPrefixBitAnd(uint(int(uintBitsToFloat(texelFetch(_8, int(gl_GlobalInvocationID.x)).x))), uvec4(uvec4(texelFetch(_9, int(_253)).x, texelFetch(_9, int(_253 + 1u)).x, texelFetch(_9, int(_253 + 2u)).x, texelFetch(_9, int(_253 + 3u)).x)))));\n    uint _299 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_12, int((gl_GlobalInvocationID.x * 7u) + 6u), uvec4(WaveMultiPrefixBitXor(uint(int(uintBitsToFloat(texelFetch(_8, int(gl_GlobalInvocationID.x)).x))), uvec4(uvec4(texelFetch(_9, int(_299)).x, texelFetch(_9, int(_299 + 1u)).x, texelFetch(_9, int(_299 + 2u)).x, texelFetch(_9, int(_299 + 3u)).x)))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 347\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %52 \"WaveMultiPrefixSum\"\nOpName %99 \"WaveMultiPrefixSum\"\nOpName %143 \"WaveMultiPrefixProduct\"\nOpName %187 \"WaveMultiPrefixProduct\"\nOpName %231 \"WaveMultiPrefixBitOr\"\nOpName %276 \"WaveMultiPrefixBitAnd\"\nOpName %322 \"WaveMultiPrefixBitXor\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%16 = OpTypeVector %5 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %5\n%21 = OpConstant %5 0\n%24 = OpConstant %5 4\n%25 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%34 = OpConstant %5 2\n%38 = OpConstant %5 3\n%47 = OpTypeBool\n%48 = OpTypeVector %47 4\n%49 = OpTypeFunction %5 %5 %25\n%61 = OpConstantTrue %47\n%72 = OpConstant %5 7\n%94 = OpTypeFloat 32\n%96 = OpTypeFunction %94 %94 %25\n%295 = OpConstant %5 5\n%341 = OpConstant %5 6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %345\n%345 = OpLabel\n%13 = OpLoad %10 %12\n%14 = OpLoad %6 %9\n%15 = OpLoad %6 %8\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpIMul %5 %22 %24\n%26 = OpImageFetch %25 %14 %23\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpIAdd %5 %23 %30\n%28 = OpImageFetch %25 %14 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %23 %34\n%32 = OpImageFetch %25 %14 %33\n%35 = OpCompositeExtract %5 %32 0\n%37 = OpIAdd %5 %23 %38\n%36 = OpImageFetch %25 %14 %37\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeConstruct %25 %27 %31 %35 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpImageFetch %25 %15 %22\n%46 = OpCompositeExtract %5 %45 0\n%70 = OpCompositeConstruct %25 %41 %42 %43 %44\n%69 = OpFunctionCall %5 %52 %46 %70\n%71 = OpIMul %5 %22 %72\n%73 = OpIMul %5 %22 %72\n%74 = OpCompositeConstruct %25 %69 %69 %69 %69\nOpImageWrite %13 %73 %74\n%75 = OpIMul %5 %22 %24\n%76 = OpImageFetch %25 %14 %75\n%77 = OpCompositeExtract %5 %76 0\n%79 = OpIAdd %5 %75 %30\n%78 = OpImageFetch %25 %14 %79\n%80 = OpCompositeExtract %5 %78 0\n%82 = OpIAdd %5 %75 %34\n%81 = OpImageFetch %25 %14 %82\n%83 = OpCompositeExtract %5 %81 0\n%85 = OpIAdd %5 %75 %38\n%84 = OpImageFetch %25 %14 %85\n%86 = OpCompositeExtract %5 %84 0\n%87 = OpCompositeConstruct %25 %77 %80 %83 %86\n%88 = OpCompositeExtract %5 %87 0\n%89 = OpCompositeExtract %5 %87 1\n%90 = OpCompositeExtract %5 %87 2\n%91 = OpCompositeExtract %5 %87 3\n%92 = OpImageFetch %25 %15 %22\n%93 = OpCompositeExtract %5 %92 0\n%95 = OpBitcast %94 %93\n%116 = OpCompositeConstruct %25 %88 %89 %90 %91\n%115 = OpFunctionCall %94 %99 %95 %116\n%117 = OpConvertFToU %5 %115\n%118 = OpIAdd %5 %71 %30\n%119 = OpIMul %5 %22 %72\n%120 = OpIAdd %5 %119 %30\n%121 = OpCompositeConstruct %25 %117 %117 %117 %117\nOpImageWrite %13 %120 %121\n%122 = OpIMul %5 %22 %24\n%123 = OpImageFetch %25 %14 %122\n%124 = OpCompositeExtract %5 %123 0\n%126 = OpIAdd %5 %122 %30\n%125 = OpImageFetch %25 %14 %126\n%127 = OpCompositeExtract %5 %125 0\n%129 = OpIAdd %5 %122 %34\n%128 = OpImageFetch %25 %14 %129\n%130 = OpCompositeExtract %5 %128 0\n%132 = OpIAdd %5 %122 %38\n%131 = OpImageFetch %25 %14 %132\n%133 = OpCompositeExtract %5 %131 0\n%134 = OpCompositeConstruct %25 %124 %127 %130 %133\n%135 = OpCompositeExtract %5 %134 0\n%136 = OpCompositeExtract %5 %134 1\n%137 = OpCompositeExtract %5 %134 2\n%138 = OpCompositeExtract %5 %134 3\n%139 = OpImageFetch %25 %15 %22\n%140 = OpCompositeExtract %5 %139 0\n%160 = OpCompositeConstruct %25 %135 %136 %137 %138\n%159 = OpFunctionCall %5 %143 %140 %160\n%161 = OpIAdd %5 %71 %34\n%162 = OpIMul %5 %22 %72\n%163 = OpIAdd %5 %162 %34\n%164 = OpCompositeConstruct %25 %159 %159 %159 %159\nOpImageWrite %13 %163 %164\n%165 = OpIMul %5 %22 %24\n%166 = OpImageFetch %25 %14 %165\n%167 = OpCompositeExtract %5 %166 0\n%169 = OpIAdd %5 %165 %30\n%168 = OpImageFetch %25 %14 %169\n%170 = OpCompositeExtract %5 %168 0\n%172 = OpIAdd %5 %165 %34\n%171 = OpImageFetch %25 %14 %172\n%173 = OpCompositeExtract %5 %171 0\n%175 = OpIAdd %5 %165 %38\n%174 = OpImageFetch %25 %14 %175\n%176 = OpCompositeExtract %5 %174 0\n%177 = OpCompositeConstruct %25 %167 %170 %173 %176\n%178 = OpCompositeExtract %5 %177 0\n%179 = OpCompositeExtract %5 %177 1\n%180 = OpCompositeExtract %5 %177 2\n%181 = OpCompositeExtract %5 %177 3\n%182 = OpImageFetch %25 %15 %22\n%183 = OpCompositeExtract %5 %182 0\n%184 = OpBitcast %94 %183\n%204 = OpCompositeConstruct %25 %178 %179 %180 %181\n%203 = OpFunctionCall %94 %187 %184 %204\n%205 = OpConvertFToU %5 %203\n%206 = OpIAdd %5 %71 %38\n%207 = OpIMul %5 %22 %72\n%208 = OpIAdd %5 %207 %38\n%209 = OpCompositeConstruct %25 %205 %205 %205 %205\nOpImageWrite %13 %208 %209\n%210 = OpIMul %5 %22 %24\n%211 = OpImageFetch %25 %14 %210\n%212 = OpCompositeExtract %5 %211 0\n%214 = OpIAdd %5 %210 %30\n%213 = OpImageFetch %25 %14 %214\n%215 = OpCompositeExtract %5 %213 0\n%217 = OpIAdd %5 %210 %34\n%216 = OpImageFetch %25 %14 %217\n%218 = OpCompositeExtract %5 %216 0\n%220 = OpIAdd %5 %210 %38\n%219 = OpImageFetch %25 %14 %220\n%221 = OpCompositeExtract %5 %219 0\n%222 = OpCompositeConstruct %25 %212 %215 %218 %221\n%223 = OpCompositeExtract %5 %222 0\n%224 = OpCompositeExtract %5 %222 1\n%225 = OpCompositeExtract %5 %222 2\n%226 = OpCompositeExtract %5 %222 3\n%227 = OpImageFetch %25 %15 %22\n%228 = OpCompositeExtract %5 %227 0\n%248 = OpCompositeConstruct %25 %223 %224 %225 %226\n%247 = OpFunctionCall %5 %231 %228 %248\n%249 = OpIAdd %5 %71 %24\n%250 = OpIMul %5 %22 %72\n%251 = OpIAdd %5 %250 %24\n%252 = OpCompositeConstruct %25 %247 %247 %247 %247\nOpImageWrite %13 %251 %252\n%253 = OpIMul %5 %22 %24\n%254 = OpImageFetch %25 %14 %253\n%255 = OpCompositeExtract %5 %254 0\n%257 = OpIAdd %5 %253 %30\n%256 = OpImageFetch %25 %14 %257\n%258 = OpCompositeExtract %5 %256 0\n%260 = OpIAdd %5 %253 %34\n%259 = OpImageFetch %25 %14 %260\n%261 = OpCompositeExtract %5 %259 0\n%263 = OpIAdd %5 %253 %38\n%262 = OpImageFetch %25 %14 %263\n%264 = OpCompositeExtract %5 %262 0\n%265 = OpCompositeConstruct %25 %255 %258 %261 %264\n%266 = OpCompositeExtract %5 %265 0\n%267 = OpCompositeExtract %5 %265 1\n%268 = OpCompositeExtract %5 %265 2\n%269 = OpCompositeExtract %5 %265 3\n%270 = OpImageFetch %25 %15 %22\n%271 = OpCompositeExtract %5 %270 0\n%272 = OpBitcast %94 %271\n%273 = OpConvertFToS %5 %272\n%293 = OpCompositeConstruct %25 %266 %267 %268 %269\n%292 = OpFunctionCall %5 %276 %273 %293\n%294 = OpIAdd %5 %71 %295\n%296 = OpIMul %5 %22 %72\n%297 = OpIAdd %5 %296 %295\n%298 = OpCompositeConstruct %25 %292 %292 %292 %292\nOpImageWrite %13 %297 %298\n%299 = OpIMul %5 %22 %24\n%300 = OpImageFetch %25 %14 %299\n%301 = OpCompositeExtract %5 %300 0\n%303 = OpIAdd %5 %299 %30\n%302 = OpImageFetch %25 %14 %303\n%304 = OpCompositeExtract %5 %302 0\n%306 = OpIAdd %5 %299 %34\n%305 = OpImageFetch %25 %14 %306\n%307 = OpCompositeExtract %5 %305 0\n%309 = OpIAdd %5 %299 %38\n%308 = OpImageFetch %25 %14 %309\n%310 = OpCompositeExtract %5 %308 0\n%311 = OpCompositeConstruct %25 %301 %304 %307 %310\n%312 = OpCompositeExtract %5 %311 0\n%313 = OpCompositeExtract %5 %311 1\n%314 = OpCompositeExtract %5 %311 2\n%315 = OpCompositeExtract %5 %311 3\n%316 = OpImageFetch %25 %15 %22\n%317 = OpCompositeExtract %5 %316 0\n%318 = OpBitcast %94 %317\n%319 = OpConvertFToS %5 %318\n%339 = OpCompositeConstruct %25 %312 %313 %314 %315\n%338 = OpFunctionCall %5 %322 %319 %339\n%340 = OpIAdd %5 %71 %341\n%342 = OpIMul %5 %22 %72\n%343 = OpIAdd %5 %342 %341\n%344 = OpCompositeConstruct %25 %338 %338 %338 %338\nOpImageWrite %13 %343 %344\nOpReturn\nOpFunctionEnd\n%52 = OpFunction %5 None %49\n%50 = OpFunctionParameter %5\n%51 = OpFunctionParameter %25\n%53 = OpLabel\n%54 = OpUndef %5\n%60 = OpGroupNonUniformBallot %25 %38 %61\n%62 = OpBitwiseAnd %25 %60 %51\nOpBranch %55\n%55 = OpLabel\nOpLoopMerge %57 %56 None\nOpBranch %56\n%56 = OpLabel\n%63 = OpGroupNonUniformBroadcastFirst %25 %38 %62\n%64 = OpIEqual %48 %62 %63\n%65 = OpAll %47 %64\nOpSelectionMerge %59 None\nOpBranchConditional %65 %58 %59\n%58 = OpLabel\n%66 = OpGroupNonUniformIAdd %5 %38 ExclusiveScan %50\nOpBranch %59\n%59 = OpLabel\n%67 = OpPhi %5 %66 %58 %54 %56\nOpBranchConditional %65 %57 %55\n%57 = OpLabel\nOpReturnValue %67\nOpFunctionEnd\n%99 = OpFunction %94 None %96\n%97 = OpFunctionParameter %94\n%98 = OpFunctionParameter %25\n%100 = OpLabel\n%101 = OpUndef %94\n%107 = OpGroupNonUniformBallot %25 %38 %61\n%108 = OpBitwiseAnd %25 %107 %98\nOpBranch %102\n%102 = OpLabel\nOpLoopMerge %104 %103 None\nOpBranch %103\n%103 = OpLabel\n%109 = OpGroupNonUniformBroadcastFirst %25 %38 %108\n%110 = OpIEqual %48 %108 %109\n%111 = OpAll %47 %110\nOpSelectionMerge %106 None\nOpBranchConditional %111 %105 %106\n%105 = OpLabel\n%112 = OpGroupNonUniformFAdd %94 %38 ExclusiveScan %97\nOpBranch %106\n%106 = OpLabel\n%113 = OpPhi %94 %112 %105 %101 %103\nOpBranchConditional %111 %104 %102\n%104 = OpLabel\nOpReturnValue %113\nOpFunctionEnd\n%143 = OpFunction %5 None %49\n%141 = OpFunctionParameter %5\n%142 = OpFunctionParameter %25\n%144 = OpLabel\n%145 = OpUndef %5\n%151 = OpGroupNonUniformBallot %25 %38 %61\n%152 = OpBitwiseAnd %25 %151 %142\nOpBranch %146\n%146 = OpLabel\nOpLoopMerge %148 %147 None\nOpBranch %147\n%147 = OpLabel\n%153 = OpGroupNonUniformBroadcastFirst %25 %38 %152\n%154 = OpIEqual %48 %152 %153\n%155 = OpAll %47 %154\nOpSelectionMerge %150 None\nOpBranchConditional %155 %149 %150\n%149 = OpLabel\n%156 = OpGroupNonUniformIMul %5 %38 ExclusiveScan %141\nOpBranch %150\n%150 = OpLabel\n%157 = OpPhi %5 %156 %149 %145 %147\nOpBranchConditional %155 %148 %146\n%148 = OpLabel\nOpReturnValue %157\nOpFunctionEnd\n%187 = OpFunction %94 None %96\n%185 = OpFunctionParameter %94\n%186 = OpFunctionParameter %25\n%188 = OpLabel\n%189 = OpUndef %94\n%195 = OpGroupNonUniformBallot %25 %38 %61\n%196 = OpBitwiseAnd %25 %195 %186\nOpBranch %190\n%190 = OpLabel\nOpLoopMerge %192 %191 None\nOpBranch %191\n%191 = OpLabel\n%197 = OpGroupNonUniformBroadcastFirst %25 %38 %196\n%198 = OpIEqual %48 %196 %197\n%199 = OpAll %47 %198\nOpSelectionMerge %194 None\nOpBranchConditional %199 %193 %194\n%193 = OpLabel\n%200 = OpGroupNonUniformFMul %94 %38 ExclusiveScan %185\nOpBranch %194\n%194 = OpLabel\n%201 = OpPhi %94 %200 %193 %189 %191\nOpBranchConditional %199 %192 %190\n%192 = OpLabel\nOpReturnValue %201\nOpFunctionEnd\n%231 = OpFunction %5 None %49\n%229 = OpFunctionParameter %5\n%230 = OpFunctionParameter %25\n%232 = OpLabel\n%233 = OpUndef %5\n%239 = OpGroupNonUniformBallot %25 %38 %61\n%240 = OpBitwiseAnd %25 %239 %230\nOpBranch %234\n%234 = OpLabel\nOpLoopMerge %236 %235 None\nOpBranch %235\n%235 = OpLabel\n%241 = OpGroupNonUniformBroadcastFirst %25 %38 %240\n%242 = OpIEqual %48 %240 %241\n%243 = OpAll %47 %242\nOpSelectionMerge %238 None\nOpBranchConditional %243 %237 %238\n%237 = OpLabel\n%244 = OpGroupNonUniformBitwiseOr %5 %38 ExclusiveScan %229\nOpBranch %238\n%238 = OpLabel\n%245 = OpPhi %5 %244 %237 %233 %235\nOpBranchConditional %243 %236 %234\n%236 = OpLabel\nOpReturnValue %245\nOpFunctionEnd\n%276 = OpFunction %5 None %49\n%274 = OpFunctionParameter %5\n%275 = OpFunctionParameter %25\n%277 = OpLabel\n%278 = OpUndef %5\n%284 = OpGroupNonUniformBallot %25 %38 %61\n%285 = OpBitwiseAnd %25 %284 %275\nOpBranch %279\n%279 = OpLabel\nOpLoopMerge %281 %280 None\nOpBranch %280\n%280 = OpLabel\n%286 = OpGroupNonUniformBroadcastFirst %25 %38 %285\n%287 = OpIEqual %48 %285 %286\n%288 = OpAll %47 %287\nOpSelectionMerge %283 None\nOpBranchConditional %288 %282 %283\n%282 = OpLabel\n%289 = OpGroupNonUniformBitwiseAnd %5 %38 ExclusiveScan %274\nOpBranch %283\n%283 = OpLabel\n%290 = OpPhi %5 %289 %282 %278 %280\nOpBranchConditional %288 %281 %279\n%281 = OpLabel\nOpReturnValue %290\nOpFunctionEnd\n%322 = OpFunction %5 None %49\n%320 = OpFunctionParameter %5\n%321 = OpFunctionParameter %25\n%323 = OpLabel\n%324 = OpUndef %5\n%330 = OpGroupNonUniformBallot %25 %38 %61\n%331 = OpBitwiseAnd %25 %330 %321\nOpBranch %325\n%325 = OpLabel\nOpLoopMerge %327 %326 None\nOpBranch %326\n%326 = OpLabel\n%332 = OpGroupNonUniformBroadcastFirst %25 %38 %331\n%333 = OpIEqual %48 %331 %332\n%334 = OpAll %47 %333\nOpSelectionMerge %329 None\nOpBranchConditional %334 %328 %329\n%328 = OpLabel\n%335 = OpGroupNonUniformBitwiseXor %5 %38 ExclusiveScan %320\nOpBranch %329\n%329 = OpLabel\n%336 = OpPhi %5 %335 %328 %324 %326\nOpBranchConditional %334 %327 %325\n%327 = OpLabel\nOpReturnValue %336\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-multi-prefix-op.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nuint _51;\nfloat _103;\nuint _152;\nfloat _201;\nuint _250;\nuint _300;\nuint _351;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _9;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _12;\n\nlayout(location = 0) flat in uint THR;\n\nuint WaveMultiPrefixSum(uint _46, uvec4 _47, bool _48)\n{\n    uint _67;\n    if (_48)\n    {\n        _67 = _51;\n    }\n    else\n    {\n        uvec4 _59 = subgroupBallot(true);\n        uvec4 _61 = _59 & _47;\n        bool _64;\n        uint _66;\n        for (;;)\n        {\n            _64 = all(equal(_61, subgroupBroadcastFirst(_61)));\n            if (_64)\n            {\n                _66 = subgroupExclusiveAdd(_46);\n            }\n            else\n            {\n                _66 = _51;\n            }\n            if (_64)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _67 = _66;\n    }\n    return _67;\n}\n\nfloat WaveMultiPrefixSum(float _98, uvec4 _99, bool _100)\n{\n    float _118;\n    if (_100)\n    {\n        _118 = _103;\n    }\n    else\n    {\n        uvec4 _111 = subgroupBallot(true);\n        uvec4 _112 = _111 & _99;\n        bool _115;\n        float _117;\n        for (;;)\n        {\n            _115 = all(equal(_112, subgroupBroadcastFirst(_112)));\n            if (_115)\n            {\n                _117 = subgroupExclusiveAdd(_98);\n            }\n            else\n            {\n                _117 = _103;\n            }\n            if (_115)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _118 = _117;\n    }\n    return _118;\n}\n\nuint WaveMultiPrefixProduct(uint _147, uvec4 _148, bool _149)\n{\n    uint _167;\n    if (_149)\n    {\n        _167 = _152;\n    }\n    else\n    {\n        uvec4 _160 = subgroupBallot(true);\n        uvec4 _161 = _160 & _148;\n        bool _164;\n        uint _166;\n        for (;;)\n        {\n            _164 = all(equal(_161, subgroupBroadcastFirst(_161)));\n            if (_164)\n            {\n                _166 = subgroupExclusiveMul(_147);\n            }\n            else\n            {\n                _166 = _152;\n            }\n            if (_164)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _167 = _166;\n    }\n    return _167;\n}\n\nfloat WaveMultiPrefixProduct(float _196, uvec4 _197, bool _198)\n{\n    float _216;\n    if (_198)\n    {\n        _216 = _201;\n    }\n    else\n    {\n        uvec4 _209 = subgroupBallot(true);\n        uvec4 _210 = _209 & _197;\n        bool _213;\n        float _215;\n        for (;;)\n        {\n            _213 = all(equal(_210, subgroupBroadcastFirst(_210)));\n            if (_213)\n            {\n                _215 = subgroupExclusiveMul(_196);\n            }\n            else\n            {\n                _215 = _201;\n            }\n            if (_213)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _216 = _215;\n    }\n    return _216;\n}\n\nuint WaveMultiPrefixBitOr(uint _245, uvec4 _246, bool _247)\n{\n    uint _265;\n    if (_247)\n    {\n        _265 = _250;\n    }\n    else\n    {\n        uvec4 _258 = subgroupBallot(true);\n        uvec4 _259 = _258 & _246;\n        bool _262;\n        uint _264;\n        for (;;)\n        {\n            _262 = all(equal(_259, subgroupBroadcastFirst(_259)));\n            if (_262)\n            {\n                _264 = subgroupExclusiveOr(_245);\n            }\n            else\n            {\n                _264 = _250;\n            }\n            if (_262)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _265 = _264;\n    }\n    return _265;\n}\n\nuint WaveMultiPrefixBitAnd(uint _295, uvec4 _296, bool _297)\n{\n    uint _315;\n    if (_297)\n    {\n        _315 = _300;\n    }\n    else\n    {\n        uvec4 _308 = subgroupBallot(true);\n        uvec4 _309 = _308 & _296;\n        bool _312;\n        uint _314;\n        for (;;)\n        {\n            _312 = all(equal(_309, subgroupBroadcastFirst(_309)));\n            if (_312)\n            {\n                _314 = subgroupExclusiveAnd(_295);\n            }\n            else\n            {\n                _314 = _300;\n            }\n            if (_312)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _315 = _314;\n    }\n    return _315;\n}\n\nuint WaveMultiPrefixBitXor(uint _346, uvec4 _347, bool _348)\n{\n    uint _366;\n    if (_348)\n    {\n        _366 = _351;\n    }\n    else\n    {\n        uvec4 _359 = subgroupBallot(true);\n        uvec4 _360 = _359 & _347;\n        bool _363;\n        uint _365;\n        for (;;)\n        {\n            _363 = all(equal(_360, subgroupBroadcastFirst(_360)));\n            if (_363)\n            {\n                _365 = subgroupExclusiveXor(_346);\n            }\n            else\n            {\n                _365 = _351;\n            }\n            if (_363)\n            {\n                break;\n            }\n            else\n            {\n                continue;\n            }\n        }\n        _366 = _365;\n    }\n    return _366;\n}\n\nvoid main()\n{\n    uint _19 = THR * 4u;\n    uint _72 = THR * 7u;\n    imageStore(_12, int(THR * 7u), uvec4(WaveMultiPrefixSum(texelFetch(_8, int(THR)).x, uvec4(uvec4(texelFetch(_9, int(_19)).x, texelFetch(_9, int(_19 + 1u)).x, texelFetch(_9, int(_19 + 2u)).x, texelFetch(_9, int(_19 + 3u)).x)), gl_HelperInvocation)));\n    uint _76 = THR * 4u;\n    imageStore(_12, int((THR * 7u) + 1u), uvec4(uint(WaveMultiPrefixSum(uintBitsToFloat(texelFetch(_8, int(THR)).x), uvec4(uvec4(texelFetch(_9, int(_76)).x, texelFetch(_9, int(_76 + 1u)).x, texelFetch(_9, int(_76 + 2u)).x, texelFetch(_9, int(_76 + 3u)).x)), gl_HelperInvocation))));\n    uint _128 = THR * 4u;\n    imageStore(_12, int((THR * 7u) + 2u), uvec4(WaveMultiPrefixProduct(texelFetch(_8, int(THR)).x, uvec4(uvec4(texelFetch(_9, int(_128)).x, texelFetch(_9, int(_128 + 1u)).x, texelFetch(_9, int(_128 + 2u)).x, texelFetch(_9, int(_128 + 3u)).x)), gl_HelperInvocation)));\n    uint _176 = THR * 4u;\n    imageStore(_12, int((THR * 7u) + 3u), uvec4(uint(WaveMultiPrefixProduct(uintBitsToFloat(texelFetch(_8, int(THR)).x), uvec4(uvec4(texelFetch(_9, int(_176)).x, texelFetch(_9, int(_176 + 1u)).x, texelFetch(_9, int(_176 + 2u)).x, texelFetch(_9, int(_176 + 3u)).x)), gl_HelperInvocation))));\n    uint _226 = THR * 4u;\n    imageStore(_12, int((THR * 7u) + 4u), uvec4(WaveMultiPrefixBitOr(texelFetch(_8, int(THR)).x, uvec4(uvec4(texelFetch(_9, int(_226)).x, texelFetch(_9, int(_226 + 1u)).x, texelFetch(_9, int(_226 + 2u)).x, texelFetch(_9, int(_226 + 3u)).x)), gl_HelperInvocation)));\n    uint _274 = THR * 4u;\n    imageStore(_12, int((THR * 7u) + 5u), uvec4(WaveMultiPrefixBitAnd(uint(int(uintBitsToFloat(texelFetch(_8, int(THR)).x))), uvec4(uvec4(texelFetch(_9, int(_274)).x, texelFetch(_9, int(_274 + 1u)).x, texelFetch(_9, int(_274 + 2u)).x, texelFetch(_9, int(_274 + 3u)).x)), gl_HelperInvocation)));\n    uint _325 = THR * 4u;\n    imageStore(_12, int((THR * 7u) + 6u), uvec4(WaveMultiPrefixBitXor(uint(int(uintBitsToFloat(texelFetch(_8, int(THR)).x))), uvec4(uvec4(texelFetch(_9, int(_325)).x, texelFetch(_9, int(_325 + 1u)).x, texelFetch(_9, int(_325 + 2u)).x, texelFetch(_9, int(_325 + 3u)).x)), gl_HelperInvocation)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 380\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %378\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"THR\"\nOpName %49 \"WaveMultiPrefixSum\"\nOpName %101 \"WaveMultiPrefixSum\"\nOpName %150 \"WaveMultiPrefixProduct\"\nOpName %199 \"WaveMultiPrefixProduct\"\nOpName %248 \"WaveMultiPrefixBitOr\"\nOpName %298 \"WaveMultiPrefixBitAnd\"\nOpName %349 \"WaveMultiPrefixBitXor\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %378 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%20 = OpConstant %5 4\n%21 = OpTypeVector %5 4\n%26 = OpConstant %5 1\n%30 = OpConstant %5 2\n%34 = OpConstant %5 3\n%43 = OpTypeBool\n%44 = OpTypeVector %43 4\n%45 = OpTypeFunction %5 %5 %21 %43\n%60 = OpConstantTrue %43\n%73 = OpConstant %5 7\n%95 = OpTypeFloat 32\n%97 = OpTypeFunction %95 %95 %21 %43\n%321 = OpConstant %5 5\n%372 = OpConstant %5 6\n%377 = OpTypePointer Input %43\n%378 = OpVariable %377 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %376\n%376 = OpLabel\n%15 = OpLoad %10 %12\n%16 = OpLoad %6 %9\n%17 = OpLoad %6 %8\n%18 = OpLoad %5 %14\n%19 = OpIMul %5 %18 %20\n%22 = OpImageFetch %21 %16 %19\n%23 = OpCompositeExtract %5 %22 0\n%25 = OpIAdd %5 %19 %26\n%24 = OpImageFetch %21 %16 %25\n%27 = OpCompositeExtract %5 %24 0\n%29 = OpIAdd %5 %19 %30\n%28 = OpImageFetch %21 %16 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %19 %34\n%32 = OpImageFetch %21 %16 %33\n%35 = OpCompositeExtract %5 %32 0\n%36 = OpCompositeConstruct %21 %23 %27 %31 %35\n%37 = OpCompositeExtract %5 %36 0\n%38 = OpCompositeExtract %5 %36 1\n%39 = OpCompositeExtract %5 %36 2\n%40 = OpCompositeExtract %5 %36 3\n%41 = OpImageFetch %21 %17 %18\n%42 = OpCompositeExtract %5 %41 0\n%70 = OpCompositeConstruct %21 %37 %38 %39 %40\n%71 = OpLoad %43 %378\n%69 = OpFunctionCall %5 %49 %42 %70 %71\n%72 = OpIMul %5 %18 %73\n%74 = OpIMul %5 %18 %73\n%75 = OpCompositeConstruct %21 %69 %69 %69 %69\nOpImageWrite %15 %74 %75\n%76 = OpIMul %5 %18 %20\n%77 = OpImageFetch %21 %16 %76\n%78 = OpCompositeExtract %5 %77 0\n%80 = OpIAdd %5 %76 %26\n%79 = OpImageFetch %21 %16 %80\n%81 = OpCompositeExtract %5 %79 0\n%83 = OpIAdd %5 %76 %30\n%82 = OpImageFetch %21 %16 %83\n%84 = OpCompositeExtract %5 %82 0\n%86 = OpIAdd %5 %76 %34\n%85 = OpImageFetch %21 %16 %86\n%87 = OpCompositeExtract %5 %85 0\n%88 = OpCompositeConstruct %21 %78 %81 %84 %87\n%89 = OpCompositeExtract %5 %88 0\n%90 = OpCompositeExtract %5 %88 1\n%91 = OpCompositeExtract %5 %88 2\n%92 = OpCompositeExtract %5 %88 3\n%93 = OpImageFetch %21 %17 %18\n%94 = OpCompositeExtract %5 %93 0\n%96 = OpBitcast %95 %94\n%121 = OpCompositeConstruct %21 %89 %90 %91 %92\n%122 = OpLoad %43 %378\n%120 = OpFunctionCall %95 %101 %96 %121 %122\n%123 = OpConvertFToU %5 %120\n%124 = OpIAdd %5 %72 %26\n%125 = OpIMul %5 %18 %73\n%126 = OpIAdd %5 %125 %26\n%127 = OpCompositeConstruct %21 %123 %123 %123 %123\nOpImageWrite %15 %126 %127\n%128 = OpIMul %5 %18 %20\n%129 = OpImageFetch %21 %16 %128\n%130 = OpCompositeExtract %5 %129 0\n%132 = OpIAdd %5 %128 %26\n%131 = OpImageFetch %21 %16 %132\n%133 = OpCompositeExtract %5 %131 0\n%135 = OpIAdd %5 %128 %30\n%134 = OpImageFetch %21 %16 %135\n%136 = OpCompositeExtract %5 %134 0\n%138 = OpIAdd %5 %128 %34\n%137 = OpImageFetch %21 %16 %138\n%139 = OpCompositeExtract %5 %137 0\n%140 = OpCompositeConstruct %21 %130 %133 %136 %139\n%141 = OpCompositeExtract %5 %140 0\n%142 = OpCompositeExtract %5 %140 1\n%143 = OpCompositeExtract %5 %140 2\n%144 = OpCompositeExtract %5 %140 3\n%145 = OpImageFetch %21 %17 %18\n%146 = OpCompositeExtract %5 %145 0\n%170 = OpCompositeConstruct %21 %141 %142 %143 %144\n%171 = OpLoad %43 %378\n%169 = OpFunctionCall %5 %150 %146 %170 %171\n%172 = OpIAdd %5 %72 %30\n%173 = OpIMul %5 %18 %73\n%174 = OpIAdd %5 %173 %30\n%175 = OpCompositeConstruct %21 %169 %169 %169 %169\nOpImageWrite %15 %174 %175\n%176 = OpIMul %5 %18 %20\n%177 = OpImageFetch %21 %16 %176\n%178 = OpCompositeExtract %5 %177 0\n%180 = OpIAdd %5 %176 %26\n%179 = OpImageFetch %21 %16 %180\n%181 = OpCompositeExtract %5 %179 0\n%183 = OpIAdd %5 %176 %30\n%182 = OpImageFetch %21 %16 %183\n%184 = OpCompositeExtract %5 %182 0\n%186 = OpIAdd %5 %176 %34\n%185 = OpImageFetch %21 %16 %186\n%187 = OpCompositeExtract %5 %185 0\n%188 = OpCompositeConstruct %21 %178 %181 %184 %187\n%189 = OpCompositeExtract %5 %188 0\n%190 = OpCompositeExtract %5 %188 1\n%191 = OpCompositeExtract %5 %188 2\n%192 = OpCompositeExtract %5 %188 3\n%193 = OpImageFetch %21 %17 %18\n%194 = OpCompositeExtract %5 %193 0\n%195 = OpBitcast %95 %194\n%219 = OpCompositeConstruct %21 %189 %190 %191 %192\n%220 = OpLoad %43 %378\n%218 = OpFunctionCall %95 %199 %195 %219 %220\n%221 = OpConvertFToU %5 %218\n%222 = OpIAdd %5 %72 %34\n%223 = OpIMul %5 %18 %73\n%224 = OpIAdd %5 %223 %34\n%225 = OpCompositeConstruct %21 %221 %221 %221 %221\nOpImageWrite %15 %224 %225\n%226 = OpIMul %5 %18 %20\n%227 = OpImageFetch %21 %16 %226\n%228 = OpCompositeExtract %5 %227 0\n%230 = OpIAdd %5 %226 %26\n%229 = OpImageFetch %21 %16 %230\n%231 = OpCompositeExtract %5 %229 0\n%233 = OpIAdd %5 %226 %30\n%232 = OpImageFetch %21 %16 %233\n%234 = OpCompositeExtract %5 %232 0\n%236 = OpIAdd %5 %226 %34\n%235 = OpImageFetch %21 %16 %236\n%237 = OpCompositeExtract %5 %235 0\n%238 = OpCompositeConstruct %21 %228 %231 %234 %237\n%239 = OpCompositeExtract %5 %238 0\n%240 = OpCompositeExtract %5 %238 1\n%241 = OpCompositeExtract %5 %238 2\n%242 = OpCompositeExtract %5 %238 3\n%243 = OpImageFetch %21 %17 %18\n%244 = OpCompositeExtract %5 %243 0\n%268 = OpCompositeConstruct %21 %239 %240 %241 %242\n%269 = OpLoad %43 %378\n%267 = OpFunctionCall %5 %248 %244 %268 %269\n%270 = OpIAdd %5 %72 %20\n%271 = OpIMul %5 %18 %73\n%272 = OpIAdd %5 %271 %20\n%273 = OpCompositeConstruct %21 %267 %267 %267 %267\nOpImageWrite %15 %272 %273\n%274 = OpIMul %5 %18 %20\n%275 = OpImageFetch %21 %16 %274\n%276 = OpCompositeExtract %5 %275 0\n%278 = OpIAdd %5 %274 %26\n%277 = OpImageFetch %21 %16 %278\n%279 = OpCompositeExtract %5 %277 0\n%281 = OpIAdd %5 %274 %30\n%280 = OpImageFetch %21 %16 %281\n%282 = OpCompositeExtract %5 %280 0\n%284 = OpIAdd %5 %274 %34\n%283 = OpImageFetch %21 %16 %284\n%285 = OpCompositeExtract %5 %283 0\n%286 = OpCompositeConstruct %21 %276 %279 %282 %285\n%287 = OpCompositeExtract %5 %286 0\n%288 = OpCompositeExtract %5 %286 1\n%289 = OpCompositeExtract %5 %286 2\n%290 = OpCompositeExtract %5 %286 3\n%291 = OpImageFetch %21 %17 %18\n%292 = OpCompositeExtract %5 %291 0\n%293 = OpBitcast %95 %292\n%294 = OpConvertFToS %5 %293\n%318 = OpCompositeConstruct %21 %287 %288 %289 %290\n%319 = OpLoad %43 %378\n%317 = OpFunctionCall %5 %298 %294 %318 %319\n%320 = OpIAdd %5 %72 %321\n%322 = OpIMul %5 %18 %73\n%323 = OpIAdd %5 %322 %321\n%324 = OpCompositeConstruct %21 %317 %317 %317 %317\nOpImageWrite %15 %323 %324\n%325 = OpIMul %5 %18 %20\n%326 = OpImageFetch %21 %16 %325\n%327 = OpCompositeExtract %5 %326 0\n%329 = OpIAdd %5 %325 %26\n%328 = OpImageFetch %21 %16 %329\n%330 = OpCompositeExtract %5 %328 0\n%332 = OpIAdd %5 %325 %30\n%331 = OpImageFetch %21 %16 %332\n%333 = OpCompositeExtract %5 %331 0\n%335 = OpIAdd %5 %325 %34\n%334 = OpImageFetch %21 %16 %335\n%336 = OpCompositeExtract %5 %334 0\n%337 = OpCompositeConstruct %21 %327 %330 %333 %336\n%338 = OpCompositeExtract %5 %337 0\n%339 = OpCompositeExtract %5 %337 1\n%340 = OpCompositeExtract %5 %337 2\n%341 = OpCompositeExtract %5 %337 3\n%342 = OpImageFetch %21 %17 %18\n%343 = OpCompositeExtract %5 %342 0\n%344 = OpBitcast %95 %343\n%345 = OpConvertFToS %5 %344\n%369 = OpCompositeConstruct %21 %338 %339 %340 %341\n%370 = OpLoad %43 %378\n%368 = OpFunctionCall %5 %349 %345 %369 %370\n%371 = OpIAdd %5 %72 %372\n%373 = OpIMul %5 %18 %73\n%374 = OpIAdd %5 %373 %372\n%375 = OpCompositeConstruct %21 %368 %368 %368 %368\nOpImageWrite %15 %374 %375\nOpReturn\nOpFunctionEnd\n%49 = OpFunction %5 None %45\n%46 = OpFunctionParameter %5\n%47 = OpFunctionParameter %21\n%48 = OpFunctionParameter %43\n%50 = OpLabel\n%51 = OpUndef %5\nOpSelectionMerge %57 None\nOpBranchConditional %48 %57 %58\n%58 = OpLabel\n%59 = OpGroupNonUniformBallot %21 %34 %60\n%61 = OpBitwiseAnd %21 %59 %47\nOpBranch %52\n%52 = OpLabel\nOpLoopMerge %54 %53 None\nOpBranch %53\n%53 = OpLabel\n%62 = OpGroupNonUniformBroadcastFirst %21 %34 %61\n%63 = OpIEqual %44 %61 %62\n%64 = OpAll %43 %63\nOpSelectionMerge %56 None\nOpBranchConditional %64 %55 %56\n%55 = OpLabel\n%65 = OpGroupNonUniformIAdd %5 %34 ExclusiveScan %46\nOpBranch %56\n%56 = OpLabel\n%66 = OpPhi %5 %65 %55 %51 %53\nOpBranchConditional %64 %54 %52\n%54 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%67 = OpPhi %5 %66 %54 %51 %50\nOpReturnValue %67\nOpFunctionEnd\n%101 = OpFunction %95 None %97\n%98 = OpFunctionParameter %95\n%99 = OpFunctionParameter %21\n%100 = OpFunctionParameter %43\n%102 = OpLabel\n%103 = OpUndef %95\nOpSelectionMerge %109 None\nOpBranchConditional %100 %109 %110\n%110 = OpLabel\n%111 = OpGroupNonUniformBallot %21 %34 %60\n%112 = OpBitwiseAnd %21 %111 %99\nOpBranch %104\n%104 = OpLabel\nOpLoopMerge %106 %105 None\nOpBranch %105\n%105 = OpLabel\n%113 = OpGroupNonUniformBroadcastFirst %21 %34 %112\n%114 = OpIEqual %44 %112 %113\n%115 = OpAll %43 %114\nOpSelectionMerge %108 None\nOpBranchConditional %115 %107 %108\n%107 = OpLabel\n%116 = OpGroupNonUniformFAdd %95 %34 ExclusiveScan %98\nOpBranch %108\n%108 = OpLabel\n%117 = OpPhi %95 %116 %107 %103 %105\nOpBranchConditional %115 %106 %104\n%106 = OpLabel\nOpBranch %109\n%109 = OpLabel\n%118 = OpPhi %95 %117 %106 %103 %102\nOpReturnValue %118\nOpFunctionEnd\n%150 = OpFunction %5 None %45\n%147 = OpFunctionParameter %5\n%148 = OpFunctionParameter %21\n%149 = OpFunctionParameter %43\n%151 = OpLabel\n%152 = OpUndef %5\nOpSelectionMerge %158 None\nOpBranchConditional %149 %158 %159\n%159 = OpLabel\n%160 = OpGroupNonUniformBallot %21 %34 %60\n%161 = OpBitwiseAnd %21 %160 %148\nOpBranch %153\n%153 = OpLabel\nOpLoopMerge %155 %154 None\nOpBranch %154\n%154 = OpLabel\n%162 = OpGroupNonUniformBroadcastFirst %21 %34 %161\n%163 = OpIEqual %44 %161 %162\n%164 = OpAll %43 %163\nOpSelectionMerge %157 None\nOpBranchConditional %164 %156 %157\n%156 = OpLabel\n%165 = OpGroupNonUniformIMul %5 %34 ExclusiveScan %147\nOpBranch %157\n%157 = OpLabel\n%166 = OpPhi %5 %165 %156 %152 %154\nOpBranchConditional %164 %155 %153\n%155 = OpLabel\nOpBranch %158\n%158 = OpLabel\n%167 = OpPhi %5 %166 %155 %152 %151\nOpReturnValue %167\nOpFunctionEnd\n%199 = OpFunction %95 None %97\n%196 = OpFunctionParameter %95\n%197 = OpFunctionParameter %21\n%198 = OpFunctionParameter %43\n%200 = OpLabel\n%201 = OpUndef %95\nOpSelectionMerge %207 None\nOpBranchConditional %198 %207 %208\n%208 = OpLabel\n%209 = OpGroupNonUniformBallot %21 %34 %60\n%210 = OpBitwiseAnd %21 %209 %197\nOpBranch %202\n%202 = OpLabel\nOpLoopMerge %204 %203 None\nOpBranch %203\n%203 = OpLabel\n%211 = OpGroupNonUniformBroadcastFirst %21 %34 %210\n%212 = OpIEqual %44 %210 %211\n%213 = OpAll %43 %212\nOpSelectionMerge %206 None\nOpBranchConditional %213 %205 %206\n%205 = OpLabel\n%214 = OpGroupNonUniformFMul %95 %34 ExclusiveScan %196\nOpBranch %206\n%206 = OpLabel\n%215 = OpPhi %95 %214 %205 %201 %203\nOpBranchConditional %213 %204 %202\n%204 = OpLabel\nOpBranch %207\n%207 = OpLabel\n%216 = OpPhi %95 %215 %204 %201 %200\nOpReturnValue %216\nOpFunctionEnd\n%248 = OpFunction %5 None %45\n%245 = OpFunctionParameter %5\n%246 = OpFunctionParameter %21\n%247 = OpFunctionParameter %43\n%249 = OpLabel\n%250 = OpUndef %5\nOpSelectionMerge %256 None\nOpBranchConditional %247 %256 %257\n%257 = OpLabel\n%258 = OpGroupNonUniformBallot %21 %34 %60\n%259 = OpBitwiseAnd %21 %258 %246\nOpBranch %251\n%251 = OpLabel\nOpLoopMerge %253 %252 None\nOpBranch %252\n%252 = OpLabel\n%260 = OpGroupNonUniformBroadcastFirst %21 %34 %259\n%261 = OpIEqual %44 %259 %260\n%262 = OpAll %43 %261\nOpSelectionMerge %255 None\nOpBranchConditional %262 %254 %255\n%254 = OpLabel\n%263 = OpGroupNonUniformBitwiseOr %5 %34 ExclusiveScan %245\nOpBranch %255\n%255 = OpLabel\n%264 = OpPhi %5 %263 %254 %250 %252\nOpBranchConditional %262 %253 %251\n%253 = OpLabel\nOpBranch %256\n%256 = OpLabel\n%265 = OpPhi %5 %264 %253 %250 %249\nOpReturnValue %265\nOpFunctionEnd\n%298 = OpFunction %5 None %45\n%295 = OpFunctionParameter %5\n%296 = OpFunctionParameter %21\n%297 = OpFunctionParameter %43\n%299 = OpLabel\n%300 = OpUndef %5\nOpSelectionMerge %306 None\nOpBranchConditional %297 %306 %307\n%307 = OpLabel\n%308 = OpGroupNonUniformBallot %21 %34 %60\n%309 = OpBitwiseAnd %21 %308 %296\nOpBranch %301\n%301 = OpLabel\nOpLoopMerge %303 %302 None\nOpBranch %302\n%302 = OpLabel\n%310 = OpGroupNonUniformBroadcastFirst %21 %34 %309\n%311 = OpIEqual %44 %309 %310\n%312 = OpAll %43 %311\nOpSelectionMerge %305 None\nOpBranchConditional %312 %304 %305\n%304 = OpLabel\n%313 = OpGroupNonUniformBitwiseAnd %5 %34 ExclusiveScan %295\nOpBranch %305\n%305 = OpLabel\n%314 = OpPhi %5 %313 %304 %300 %302\nOpBranchConditional %312 %303 %301\n%303 = OpLabel\nOpBranch %306\n%306 = OpLabel\n%315 = OpPhi %5 %314 %303 %300 %299\nOpReturnValue %315\nOpFunctionEnd\n%349 = OpFunction %5 None %45\n%346 = OpFunctionParameter %5\n%347 = OpFunctionParameter %21\n%348 = OpFunctionParameter %43\n%350 = OpLabel\n%351 = OpUndef %5\nOpSelectionMerge %357 None\nOpBranchConditional %348 %357 %358\n%358 = OpLabel\n%359 = OpGroupNonUniformBallot %21 %34 %60\n%360 = OpBitwiseAnd %21 %359 %347\nOpBranch %352\n%352 = OpLabel\nOpLoopMerge %354 %353 None\nOpBranch %353\n%353 = OpLabel\n%361 = OpGroupNonUniformBroadcastFirst %21 %34 %360\n%362 = OpIEqual %44 %360 %361\n%363 = OpAll %43 %362\nOpSelectionMerge %356 None\nOpBranchConditional %363 %355 %356\n%355 = OpLabel\n%364 = OpGroupNonUniformBitwiseXor %5 %34 ExclusiveScan %346\nOpBranch %356\n%356 = OpLabel\n%365 = OpPhi %5 %364 %355 %351 %353\nOpBranchConditional %363 %354 %352\n%354 = OpLabel\nOpBranch %357\n%357 = OpLabel\n%366 = OpPhi %5 %365 %354 %351 %350\nOpReturnValue %366\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-multi-prefix-op.partitioned.noglsl.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 232\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpCapability GroupNonUniformPartitionedEXT\nOpExtension \"SPV_NV_shader_subgroup_partitioned\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%16 = OpTypeVector %5 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %5\n%21 = OpConstant %5 0\n%24 = OpConstant %5 4\n%25 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%34 = OpConstant %5 2\n%38 = OpConstant %5 3\n%50 = OpTypeBool\n%51 = OpConstantTrue %50\n%54 = OpConstant %5 7\n%76 = OpTypeFloat 32\n%196 = OpConstant %5 5\n%226 = OpConstant %5 6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %230\n%230 = OpLabel\n%13 = OpLoad %10 %12\n%14 = OpLoad %6 %9\n%15 = OpLoad %6 %8\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpIMul %5 %22 %24\n%26 = OpImageFetch %25 %14 %23\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpIAdd %5 %23 %30\n%28 = OpImageFetch %25 %14 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %23 %34\n%32 = OpImageFetch %25 %14 %33\n%35 = OpCompositeExtract %5 %32 0\n%37 = OpIAdd %5 %23 %38\n%36 = OpImageFetch %25 %14 %37\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeConstruct %25 %27 %31 %35 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpImageFetch %25 %15 %22\n%46 = OpCompositeExtract %5 %45 0\n%48 = OpCompositeConstruct %25 %41 %42 %43 %44\n%49 = OpGroupNonUniformBallot %25 %38 %51\n%52 = OpBitwiseAnd %25 %48 %49\n%47 = OpGroupNonUniformIAdd %5 %38 PartitionedExclusiveScanEXT %46 %52\n%53 = OpIMul %5 %22 %54\n%55 = OpIMul %5 %22 %54\n%56 = OpCompositeConstruct %25 %47 %47 %47 %47\nOpImageWrite %13 %55 %56\n%57 = OpIMul %5 %22 %24\n%58 = OpImageFetch %25 %14 %57\n%59 = OpCompositeExtract %5 %58 0\n%61 = OpIAdd %5 %57 %30\n%60 = OpImageFetch %25 %14 %61\n%62 = OpCompositeExtract %5 %60 0\n%64 = OpIAdd %5 %57 %34\n%63 = OpImageFetch %25 %14 %64\n%65 = OpCompositeExtract %5 %63 0\n%67 = OpIAdd %5 %57 %38\n%66 = OpImageFetch %25 %14 %67\n%68 = OpCompositeExtract %5 %66 0\n%69 = OpCompositeConstruct %25 %59 %62 %65 %68\n%70 = OpCompositeExtract %5 %69 0\n%71 = OpCompositeExtract %5 %69 1\n%72 = OpCompositeExtract %5 %69 2\n%73 = OpCompositeExtract %5 %69 3\n%74 = OpImageFetch %25 %15 %22\n%75 = OpCompositeExtract %5 %74 0\n%77 = OpBitcast %76 %75\n%79 = OpCompositeConstruct %25 %70 %71 %72 %73\n%80 = OpGroupNonUniformBallot %25 %38 %51\n%81 = OpBitwiseAnd %25 %79 %80\n%78 = OpGroupNonUniformFAdd %76 %38 PartitionedExclusiveScanEXT %77 %81\n%82 = OpConvertFToU %5 %78\n%83 = OpIAdd %5 %53 %30\n%84 = OpIMul %5 %22 %54\n%85 = OpIAdd %5 %84 %30\n%86 = OpCompositeConstruct %25 %82 %82 %82 %82\nOpImageWrite %13 %85 %86\n%87 = OpIMul %5 %22 %24\n%88 = OpImageFetch %25 %14 %87\n%89 = OpCompositeExtract %5 %88 0\n%91 = OpIAdd %5 %87 %30\n%90 = OpImageFetch %25 %14 %91\n%92 = OpCompositeExtract %5 %90 0\n%94 = OpIAdd %5 %87 %34\n%93 = OpImageFetch %25 %14 %94\n%95 = OpCompositeExtract %5 %93 0\n%97 = OpIAdd %5 %87 %38\n%96 = OpImageFetch %25 %14 %97\n%98 = OpCompositeExtract %5 %96 0\n%99 = OpCompositeConstruct %25 %89 %92 %95 %98\n%100 = OpCompositeExtract %5 %99 0\n%101 = OpCompositeExtract %5 %99 1\n%102 = OpCompositeExtract %5 %99 2\n%103 = OpCompositeExtract %5 %99 3\n%104 = OpImageFetch %25 %15 %22\n%105 = OpCompositeExtract %5 %104 0\n%107 = OpCompositeConstruct %25 %100 %101 %102 %103\n%108 = OpGroupNonUniformBallot %25 %38 %51\n%109 = OpBitwiseAnd %25 %107 %108\n%106 = OpGroupNonUniformIMul %5 %38 PartitionedExclusiveScanEXT %105 %109\n%110 = OpIAdd %5 %53 %34\n%111 = OpIMul %5 %22 %54\n%112 = OpIAdd %5 %111 %34\n%113 = OpCompositeConstruct %25 %106 %106 %106 %106\nOpImageWrite %13 %112 %113\n%114 = OpIMul %5 %22 %24\n%115 = OpImageFetch %25 %14 %114\n%116 = OpCompositeExtract %5 %115 0\n%118 = OpIAdd %5 %114 %30\n%117 = OpImageFetch %25 %14 %118\n%119 = OpCompositeExtract %5 %117 0\n%121 = OpIAdd %5 %114 %34\n%120 = OpImageFetch %25 %14 %121\n%122 = OpCompositeExtract %5 %120 0\n%124 = OpIAdd %5 %114 %38\n%123 = OpImageFetch %25 %14 %124\n%125 = OpCompositeExtract %5 %123 0\n%126 = OpCompositeConstruct %25 %116 %119 %122 %125\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpCompositeExtract %5 %126 1\n%129 = OpCompositeExtract %5 %126 2\n%130 = OpCompositeExtract %5 %126 3\n%131 = OpImageFetch %25 %15 %22\n%132 = OpCompositeExtract %5 %131 0\n%133 = OpBitcast %76 %132\n%135 = OpCompositeConstruct %25 %127 %128 %129 %130\n%136 = OpGroupNonUniformBallot %25 %38 %51\n%137 = OpBitwiseAnd %25 %135 %136\n%134 = OpGroupNonUniformFMul %76 %38 PartitionedExclusiveScanEXT %133 %137\n%138 = OpConvertFToU %5 %134\n%139 = OpIAdd %5 %53 %38\n%140 = OpIMul %5 %22 %54\n%141 = OpIAdd %5 %140 %38\n%142 = OpCompositeConstruct %25 %138 %138 %138 %138\nOpImageWrite %13 %141 %142\n%143 = OpIMul %5 %22 %24\n%144 = OpImageFetch %25 %14 %143\n%145 = OpCompositeExtract %5 %144 0\n%147 = OpIAdd %5 %143 %30\n%146 = OpImageFetch %25 %14 %147\n%148 = OpCompositeExtract %5 %146 0\n%150 = OpIAdd %5 %143 %34\n%149 = OpImageFetch %25 %14 %150\n%151 = OpCompositeExtract %5 %149 0\n%153 = OpIAdd %5 %143 %38\n%152 = OpImageFetch %25 %14 %153\n%154 = OpCompositeExtract %5 %152 0\n%155 = OpCompositeConstruct %25 %145 %148 %151 %154\n%156 = OpCompositeExtract %5 %155 0\n%157 = OpCompositeExtract %5 %155 1\n%158 = OpCompositeExtract %5 %155 2\n%159 = OpCompositeExtract %5 %155 3\n%160 = OpImageFetch %25 %15 %22\n%161 = OpCompositeExtract %5 %160 0\n%163 = OpCompositeConstruct %25 %156 %157 %158 %159\n%164 = OpGroupNonUniformBallot %25 %38 %51\n%165 = OpBitwiseAnd %25 %163 %164\n%162 = OpGroupNonUniformBitwiseOr %5 %38 PartitionedExclusiveScanEXT %161 %165\n%166 = OpIAdd %5 %53 %24\n%167 = OpIMul %5 %22 %54\n%168 = OpIAdd %5 %167 %24\n%169 = OpCompositeConstruct %25 %162 %162 %162 %162\nOpImageWrite %13 %168 %169\n%170 = OpIMul %5 %22 %24\n%171 = OpImageFetch %25 %14 %170\n%172 = OpCompositeExtract %5 %171 0\n%174 = OpIAdd %5 %170 %30\n%173 = OpImageFetch %25 %14 %174\n%175 = OpCompositeExtract %5 %173 0\n%177 = OpIAdd %5 %170 %34\n%176 = OpImageFetch %25 %14 %177\n%178 = OpCompositeExtract %5 %176 0\n%180 = OpIAdd %5 %170 %38\n%179 = OpImageFetch %25 %14 %180\n%181 = OpCompositeExtract %5 %179 0\n%182 = OpCompositeConstruct %25 %172 %175 %178 %181\n%183 = OpCompositeExtract %5 %182 0\n%184 = OpCompositeExtract %5 %182 1\n%185 = OpCompositeExtract %5 %182 2\n%186 = OpCompositeExtract %5 %182 3\n%187 = OpImageFetch %25 %15 %22\n%188 = OpCompositeExtract %5 %187 0\n%189 = OpBitcast %76 %188\n%190 = OpConvertFToS %5 %189\n%192 = OpCompositeConstruct %25 %183 %184 %185 %186\n%193 = OpGroupNonUniformBallot %25 %38 %51\n%194 = OpBitwiseAnd %25 %192 %193\n%191 = OpGroupNonUniformBitwiseAnd %5 %38 PartitionedExclusiveScanEXT %190 %194\n%195 = OpIAdd %5 %53 %196\n%197 = OpIMul %5 %22 %54\n%198 = OpIAdd %5 %197 %196\n%199 = OpCompositeConstruct %25 %191 %191 %191 %191\nOpImageWrite %13 %198 %199\n%200 = OpIMul %5 %22 %24\n%201 = OpImageFetch %25 %14 %200\n%202 = OpCompositeExtract %5 %201 0\n%204 = OpIAdd %5 %200 %30\n%203 = OpImageFetch %25 %14 %204\n%205 = OpCompositeExtract %5 %203 0\n%207 = OpIAdd %5 %200 %34\n%206 = OpImageFetch %25 %14 %207\n%208 = OpCompositeExtract %5 %206 0\n%210 = OpIAdd %5 %200 %38\n%209 = OpImageFetch %25 %14 %210\n%211 = OpCompositeExtract %5 %209 0\n%212 = OpCompositeConstruct %25 %202 %205 %208 %211\n%213 = OpCompositeExtract %5 %212 0\n%214 = OpCompositeExtract %5 %212 1\n%215 = OpCompositeExtract %5 %212 2\n%216 = OpCompositeExtract %5 %212 3\n%217 = OpImageFetch %25 %15 %22\n%218 = OpCompositeExtract %5 %217 0\n%219 = OpBitcast %76 %218\n%220 = OpConvertFToS %5 %219\n%222 = OpCompositeConstruct %25 %213 %214 %215 %216\n%223 = OpGroupNonUniformBallot %25 %38 %51\n%224 = OpBitwiseAnd %25 %222 %223\n%221 = OpGroupNonUniformBitwiseXor %5 %38 PartitionedExclusiveScanEXT %220 %224\n%225 = OpIAdd %5 %53 %226\n%227 = OpIMul %5 %22 %54\n%228 = OpIAdd %5 %227 %226\n%229 = OpCompositeConstruct %25 %221 %221 %221 %221\nOpImageWrite %13 %228 %229\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-multi-prefix-op.partitioned.noglsl.frag",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 265\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpCapability GroupNonUniformPartitionedEXT\nOpExtension \"SPV_NV_shader_subgroup_partitioned\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %263\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"THR\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %263 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%20 = OpConstant %5 4\n%21 = OpTypeVector %5 4\n%26 = OpConstant %5 1\n%30 = OpConstant %5 2\n%34 = OpConstant %5 3\n%46 = OpTypeBool\n%51 = OpTypeVector %46 4\n%55 = OpConstant %5 7\n%77 = OpTypeFloat 32\n%222 = OpConstant %5 5\n%257 = OpConstant %5 6\n%262 = OpTypePointer Input %46\n%263 = OpVariable %262 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %261\n%261 = OpLabel\n%15 = OpLoad %10 %12\n%16 = OpLoad %6 %9\n%17 = OpLoad %6 %8\n%18 = OpLoad %5 %14\n%19 = OpIMul %5 %18 %20\n%22 = OpImageFetch %21 %16 %19\n%23 = OpCompositeExtract %5 %22 0\n%25 = OpIAdd %5 %19 %26\n%24 = OpImageFetch %21 %16 %25\n%27 = OpCompositeExtract %5 %24 0\n%29 = OpIAdd %5 %19 %30\n%28 = OpImageFetch %21 %16 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %19 %34\n%32 = OpImageFetch %21 %16 %33\n%35 = OpCompositeExtract %5 %32 0\n%36 = OpCompositeConstruct %21 %23 %27 %31 %35\n%37 = OpCompositeExtract %5 %36 0\n%38 = OpCompositeExtract %5 %36 1\n%39 = OpCompositeExtract %5 %36 2\n%40 = OpCompositeExtract %5 %36 3\n%41 = OpImageFetch %21 %17 %18\n%42 = OpCompositeExtract %5 %41 0\n%44 = OpCompositeConstruct %21 %37 %38 %39 %40\n%47 = OpLoad %46 %263\n%48 = OpGroupNonUniformBallot %21 %34 %47\n%49 = OpLogicalNot %46 %47\n%45 = OpGroupNonUniformBallot %21 %34 %49\n%50 = OpBitwiseAnd %21 %44 %45\n%52 = OpCompositeConstruct %51 %47 %47 %47 %47\n%53 = OpSelect %21 %52 %48 %50\n%43 = OpGroupNonUniformIAdd %5 %34 PartitionedExclusiveScanEXT %42 %53\n%54 = OpIMul %5 %18 %55\n%56 = OpIMul %5 %18 %55\n%57 = OpCompositeConstruct %21 %43 %43 %43 %43\nOpImageWrite %15 %56 %57\n%58 = OpIMul %5 %18 %20\n%59 = OpImageFetch %21 %16 %58\n%60 = OpCompositeExtract %5 %59 0\n%62 = OpIAdd %5 %58 %26\n%61 = OpImageFetch %21 %16 %62\n%63 = OpCompositeExtract %5 %61 0\n%65 = OpIAdd %5 %58 %30\n%64 = OpImageFetch %21 %16 %65\n%66 = OpCompositeExtract %5 %64 0\n%68 = OpIAdd %5 %58 %34\n%67 = OpImageFetch %21 %16 %68\n%69 = OpCompositeExtract %5 %67 0\n%70 = OpCompositeConstruct %21 %60 %63 %66 %69\n%71 = OpCompositeExtract %5 %70 0\n%72 = OpCompositeExtract %5 %70 1\n%73 = OpCompositeExtract %5 %70 2\n%74 = OpCompositeExtract %5 %70 3\n%75 = OpImageFetch %21 %17 %18\n%76 = OpCompositeExtract %5 %75 0\n%78 = OpBitcast %77 %76\n%80 = OpCompositeConstruct %21 %71 %72 %73 %74\n%82 = OpLoad %46 %263\n%83 = OpGroupNonUniformBallot %21 %34 %82\n%84 = OpLogicalNot %46 %82\n%81 = OpGroupNonUniformBallot %21 %34 %84\n%85 = OpBitwiseAnd %21 %80 %81\n%86 = OpCompositeConstruct %51 %82 %82 %82 %82\n%87 = OpSelect %21 %86 %83 %85\n%79 = OpGroupNonUniformFAdd %77 %34 PartitionedExclusiveScanEXT %78 %87\n%88 = OpConvertFToU %5 %79\n%89 = OpIAdd %5 %54 %26\n%90 = OpIMul %5 %18 %55\n%91 = OpIAdd %5 %90 %26\n%92 = OpCompositeConstruct %21 %88 %88 %88 %88\nOpImageWrite %15 %91 %92\n%93 = OpIMul %5 %18 %20\n%94 = OpImageFetch %21 %16 %93\n%95 = OpCompositeExtract %5 %94 0\n%97 = OpIAdd %5 %93 %26\n%96 = OpImageFetch %21 %16 %97\n%98 = OpCompositeExtract %5 %96 0\n%100 = OpIAdd %5 %93 %30\n%99 = OpImageFetch %21 %16 %100\n%101 = OpCompositeExtract %5 %99 0\n%103 = OpIAdd %5 %93 %34\n%102 = OpImageFetch %21 %16 %103\n%104 = OpCompositeExtract %5 %102 0\n%105 = OpCompositeConstruct %21 %95 %98 %101 %104\n%106 = OpCompositeExtract %5 %105 0\n%107 = OpCompositeExtract %5 %105 1\n%108 = OpCompositeExtract %5 %105 2\n%109 = OpCompositeExtract %5 %105 3\n%110 = OpImageFetch %21 %17 %18\n%111 = OpCompositeExtract %5 %110 0\n%113 = OpCompositeConstruct %21 %106 %107 %108 %109\n%115 = OpLoad %46 %263\n%116 = OpGroupNonUniformBallot %21 %34 %115\n%117 = OpLogicalNot %46 %115\n%114 = OpGroupNonUniformBallot %21 %34 %117\n%118 = OpBitwiseAnd %21 %113 %114\n%119 = OpCompositeConstruct %51 %115 %115 %115 %115\n%120 = OpSelect %21 %119 %116 %118\n%112 = OpGroupNonUniformIMul %5 %34 PartitionedExclusiveScanEXT %111 %120\n%121 = OpIAdd %5 %54 %30\n%122 = OpIMul %5 %18 %55\n%123 = OpIAdd %5 %122 %30\n%124 = OpCompositeConstruct %21 %112 %112 %112 %112\nOpImageWrite %15 %123 %124\n%125 = OpIMul %5 %18 %20\n%126 = OpImageFetch %21 %16 %125\n%127 = OpCompositeExtract %5 %126 0\n%129 = OpIAdd %5 %125 %26\n%128 = OpImageFetch %21 %16 %129\n%130 = OpCompositeExtract %5 %128 0\n%132 = OpIAdd %5 %125 %30\n%131 = OpImageFetch %21 %16 %132\n%133 = OpCompositeExtract %5 %131 0\n%135 = OpIAdd %5 %125 %34\n%134 = OpImageFetch %21 %16 %135\n%136 = OpCompositeExtract %5 %134 0\n%137 = OpCompositeConstruct %21 %127 %130 %133 %136\n%138 = OpCompositeExtract %5 %137 0\n%139 = OpCompositeExtract %5 %137 1\n%140 = OpCompositeExtract %5 %137 2\n%141 = OpCompositeExtract %5 %137 3\n%142 = OpImageFetch %21 %17 %18\n%143 = OpCompositeExtract %5 %142 0\n%144 = OpBitcast %77 %143\n%146 = OpCompositeConstruct %21 %138 %139 %140 %141\n%148 = OpLoad %46 %263\n%149 = OpGroupNonUniformBallot %21 %34 %148\n%150 = OpLogicalNot %46 %148\n%147 = OpGroupNonUniformBallot %21 %34 %150\n%151 = OpBitwiseAnd %21 %146 %147\n%152 = OpCompositeConstruct %51 %148 %148 %148 %148\n%153 = OpSelect %21 %152 %149 %151\n%145 = OpGroupNonUniformFMul %77 %34 PartitionedExclusiveScanEXT %144 %153\n%154 = OpConvertFToU %5 %145\n%155 = OpIAdd %5 %54 %34\n%156 = OpIMul %5 %18 %55\n%157 = OpIAdd %5 %156 %34\n%158 = OpCompositeConstruct %21 %154 %154 %154 %154\nOpImageWrite %15 %157 %158\n%159 = OpIMul %5 %18 %20\n%160 = OpImageFetch %21 %16 %159\n%161 = OpCompositeExtract %5 %160 0\n%163 = OpIAdd %5 %159 %26\n%162 = OpImageFetch %21 %16 %163\n%164 = OpCompositeExtract %5 %162 0\n%166 = OpIAdd %5 %159 %30\n%165 = OpImageFetch %21 %16 %166\n%167 = OpCompositeExtract %5 %165 0\n%169 = OpIAdd %5 %159 %34\n%168 = OpImageFetch %21 %16 %169\n%170 = OpCompositeExtract %5 %168 0\n%171 = OpCompositeConstruct %21 %161 %164 %167 %170\n%172 = OpCompositeExtract %5 %171 0\n%173 = OpCompositeExtract %5 %171 1\n%174 = OpCompositeExtract %5 %171 2\n%175 = OpCompositeExtract %5 %171 3\n%176 = OpImageFetch %21 %17 %18\n%177 = OpCompositeExtract %5 %176 0\n%179 = OpCompositeConstruct %21 %172 %173 %174 %175\n%181 = OpLoad %46 %263\n%182 = OpGroupNonUniformBallot %21 %34 %181\n%183 = OpLogicalNot %46 %181\n%180 = OpGroupNonUniformBallot %21 %34 %183\n%184 = OpBitwiseAnd %21 %179 %180\n%185 = OpCompositeConstruct %51 %181 %181 %181 %181\n%186 = OpSelect %21 %185 %182 %184\n%178 = OpGroupNonUniformBitwiseOr %5 %34 PartitionedExclusiveScanEXT %177 %186\n%187 = OpIAdd %5 %54 %20\n%188 = OpIMul %5 %18 %55\n%189 = OpIAdd %5 %188 %20\n%190 = OpCompositeConstruct %21 %178 %178 %178 %178\nOpImageWrite %15 %189 %190\n%191 = OpIMul %5 %18 %20\n%192 = OpImageFetch %21 %16 %191\n%193 = OpCompositeExtract %5 %192 0\n%195 = OpIAdd %5 %191 %26\n%194 = OpImageFetch %21 %16 %195\n%196 = OpCompositeExtract %5 %194 0\n%198 = OpIAdd %5 %191 %30\n%197 = OpImageFetch %21 %16 %198\n%199 = OpCompositeExtract %5 %197 0\n%201 = OpIAdd %5 %191 %34\n%200 = OpImageFetch %21 %16 %201\n%202 = OpCompositeExtract %5 %200 0\n%203 = OpCompositeConstruct %21 %193 %196 %199 %202\n%204 = OpCompositeExtract %5 %203 0\n%205 = OpCompositeExtract %5 %203 1\n%206 = OpCompositeExtract %5 %203 2\n%207 = OpCompositeExtract %5 %203 3\n%208 = OpImageFetch %21 %17 %18\n%209 = OpCompositeExtract %5 %208 0\n%210 = OpBitcast %77 %209\n%211 = OpConvertFToS %5 %210\n%213 = OpCompositeConstruct %21 %204 %205 %206 %207\n%215 = OpLoad %46 %263\n%216 = OpGroupNonUniformBallot %21 %34 %215\n%217 = OpLogicalNot %46 %215\n%214 = OpGroupNonUniformBallot %21 %34 %217\n%218 = OpBitwiseAnd %21 %213 %214\n%219 = OpCompositeConstruct %51 %215 %215 %215 %215\n%220 = OpSelect %21 %219 %216 %218\n%212 = OpGroupNonUniformBitwiseAnd %5 %34 PartitionedExclusiveScanEXT %211 %220\n%221 = OpIAdd %5 %54 %222\n%223 = OpIMul %5 %18 %55\n%224 = OpIAdd %5 %223 %222\n%225 = OpCompositeConstruct %21 %212 %212 %212 %212\nOpImageWrite %15 %224 %225\n%226 = OpIMul %5 %18 %20\n%227 = OpImageFetch %21 %16 %226\n%228 = OpCompositeExtract %5 %227 0\n%230 = OpIAdd %5 %226 %26\n%229 = OpImageFetch %21 %16 %230\n%231 = OpCompositeExtract %5 %229 0\n%233 = OpIAdd %5 %226 %30\n%232 = OpImageFetch %21 %16 %233\n%234 = OpCompositeExtract %5 %232 0\n%236 = OpIAdd %5 %226 %34\n%235 = OpImageFetch %21 %16 %236\n%237 = OpCompositeExtract %5 %235 0\n%238 = OpCompositeConstruct %21 %228 %231 %234 %237\n%239 = OpCompositeExtract %5 %238 0\n%240 = OpCompositeExtract %5 %238 1\n%241 = OpCompositeExtract %5 %238 2\n%242 = OpCompositeExtract %5 %238 3\n%243 = OpImageFetch %21 %17 %18\n%244 = OpCompositeExtract %5 %243 0\n%245 = OpBitcast %77 %244\n%246 = OpConvertFToS %5 %245\n%248 = OpCompositeConstruct %21 %239 %240 %241 %242\n%250 = OpLoad %46 %263\n%251 = OpGroupNonUniformBallot %21 %34 %250\n%252 = OpLogicalNot %46 %250\n%249 = OpGroupNonUniformBallot %21 %34 %252\n%253 = OpBitwiseAnd %21 %248 %249\n%254 = OpCompositeConstruct %51 %250 %250 %250 %250\n%255 = OpSelect %21 %254 %251 %253\n%247 = OpGroupNonUniformBitwiseXor %5 %34 PartitionedExclusiveScanEXT %246 %255\n%256 = OpIAdd %5 %54 %257\n%258 = OpIMul %5 %18 %55\n%259 = OpIAdd %5 %258 %257\n%260 = OpCompositeConstruct %21 %247 %247 %247 %247\nOpImageWrite %15 %259 %260\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-prefix.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _10;\n\nvoid main()\n{\n    imageStore(_8, int(gl_GlobalInvocationID.x * 2u), uvec4(subgroupBallotExclusiveBitCount(subgroupBallot(gl_GlobalInvocationID.x < 100u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x * 2u), uvec4(subgroupExclusiveAdd(gl_GlobalInvocationID.x)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 2u) + 1u), uvec4(subgroupExclusiveMul(gl_GlobalInvocationID.x)));\n    imageStore(_9, int(gl_GlobalInvocationID.x * 2u), uvec4(subgroupExclusiveAdd(gl_GlobalInvocationID.x)));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 2u) + 1u), uvec4(subgroupExclusiveMul(gl_GlobalInvocationID.x)));\n    float _50 = float(gl_GlobalInvocationID.x);\n    imageStore(_10, int(gl_GlobalInvocationID.x * 2u), uvec4(uint(subgroupExclusiveAdd(_50))));\n    imageStore(_10, int((gl_GlobalInvocationID.x * 2u) + 1u), uvec4(uint(subgroupExclusiveMul(_50))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %10 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%21 = OpTypeBool\n%23 = OpConstant %5 100\n%24 = OpTypeVector %5 4\n%26 = OpConstant %5 3\n%30 = OpConstant %5 2\n%37 = OpConstant %5 4\n%40 = OpConstant %5 1\n%49 = OpTypeFloat 32\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%11 = OpLoad %6 %10\n%12 = OpLoad %6 %9\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%22 = OpULessThan %21 %20 %23\n%25 = OpGroupNonUniformBallot %24 %26 %22\n%27 = OpGroupNonUniformBallotBitCount %5 %26 ExclusiveScan %25\n%28 = OpShiftLeftLogical %5 %20 %26\n%29 = OpIMul %5 %20 %30\n%31 = OpCompositeConstruct %24 %27 %27 %27 %27\nOpImageWrite %13 %29 %31\n%32 = OpGroupNonUniformIAdd %5 %26 ExclusiveScan %20\n%33 = OpIMul %5 %20 %30\n%34 = OpCompositeConstruct %24 %32 %32 %32 %32\nOpImageWrite %13 %33 %34\n%35 = OpGroupNonUniformIMul %5 %26 ExclusiveScan %20\n%36 = OpBitwiseOr %5 %28 %37\n%38 = OpIMul %5 %20 %30\n%39 = OpIAdd %5 %38 %40\n%41 = OpCompositeConstruct %24 %35 %35 %35 %35\nOpImageWrite %13 %39 %41\n%42 = OpGroupNonUniformIAdd %5 %26 ExclusiveScan %20\n%43 = OpIMul %5 %20 %30\n%44 = OpCompositeConstruct %24 %42 %42 %42 %42\nOpImageWrite %12 %43 %44\n%45 = OpGroupNonUniformIMul %5 %26 ExclusiveScan %20\n%46 = OpIMul %5 %20 %30\n%47 = OpIAdd %5 %46 %40\n%48 = OpCompositeConstruct %24 %45 %45 %45 %45\nOpImageWrite %12 %47 %48\n%50 = OpConvertUToF %49 %20\n%51 = OpGroupNonUniformFAdd %49 %26 ExclusiveScan %50\n%52 = OpConvertFToU %5 %51\n%53 = OpIMul %5 %20 %30\n%54 = OpCompositeConstruct %24 %52 %52 %52 %52\nOpImageWrite %11 %53 %54\n%55 = OpGroupNonUniformFMul %49 %26 ExclusiveScan %50\n%56 = OpConvertFToU %5 %55\n%57 = OpIMul %5 %20 %30\n%58 = OpIAdd %5 %57 %40\n%59 = OpCompositeConstruct %24 %56 %56 %56 %56\nOpImageWrite %11 %58 %59\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-prefix.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _10;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    imageStore(_8, int(INDEX * 2u), uvec4(subgroupBallotExclusiveBitCount(subgroupBallot((INDEX < 100u) && (!(gl_HelperInvocation || discard_state))))));\n    imageStore(_8, int(INDEX * 2u), uvec4(subgroupExclusiveAdd((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_8, int((INDEX * 2u) + 1u), uvec4(subgroupExclusiveMul((gl_HelperInvocation || discard_state) ? 1u : INDEX)));\n    imageStore(_9, int(INDEX * 2u), uvec4(subgroupExclusiveAdd((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_9, int((INDEX * 2u) + 1u), uvec4(subgroupExclusiveMul((gl_HelperInvocation || discard_state) ? 1u : INDEX)));\n    float _63 = float(INDEX);\n    imageStore(_10, int(INDEX * 2u), uvec4(uint(subgroupExclusiveAdd((gl_HelperInvocation || discard_state) ? 0.0 : _63))));\n    imageStore(_10, int((INDEX * 2u) + 1u), uvec4(uint(subgroupExclusiveMul((gl_HelperInvocation || discard_state) ? 1.0 : _63))));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %84\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %21 \"discard_state\"\nOpName %99 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %10 NonReadable\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %84 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypePointer Input %5\n%12 = OpVariable %11 Input\n%17 = OpTypeBool\n%19 = OpConstant %5 40\n%20 = OpTypePointer Private %17\n%21 = OpVariable %20 Private\n%22 = OpConstantFalse %17\n%24 = OpConstant %5 100\n%25 = OpTypeVector %5 4\n%27 = OpConstant %5 3\n%34 = OpConstant %5 2\n%38 = OpConstant %5 0\n%44 = OpConstant %5 1\n%47 = OpConstant %5 4\n%62 = OpTypeFloat 32\n%66 = OpConstant %62 0\n%73 = OpConstant %62 1\n%82 = OpConstantTrue %17\n%83 = OpTypePointer Input %17\n%84 = OpVariable %83 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %21 %22\nOpBranch %79\n%79 = OpLabel\n%13 = OpLoad %6 %10\n%14 = OpLoad %6 %9\n%15 = OpLoad %6 %8\n%16 = OpLoad %5 %12\n%18 = OpIEqual %17 %16 %19\nOpSelectionMerge %81 None\nOpBranchConditional %18 %80 %81\n%80 = OpLabel\nOpStore %21 %82\nOpBranch %81\n%81 = OpLabel\n%23 = OpULessThan %17 %16 %24\n%85 = OpLoad %17 %84\n%86 = OpLoad %17 %21\n%28 = OpLogicalOr %17 %85 %86\n%29 = OpLogicalNot %17 %28\n%30 = OpLogicalAnd %17 %23 %29\n%26 = OpGroupNonUniformBallot %25 %27 %30\n%31 = OpGroupNonUniformBallotBitCount %5 %27 ExclusiveScan %26\n%32 = OpShiftLeftLogical %5 %16 %27\n%33 = OpIMul %5 %16 %34\n%35 = OpCompositeConstruct %25 %31 %31 %31 %31\nOpImageWrite %15 %33 %35\n%87 = OpLoad %17 %84\n%88 = OpLoad %17 %21\n%37 = OpLogicalOr %17 %87 %88\n%39 = OpSelect %5 %37 %38 %16\n%36 = OpGroupNonUniformIAdd %5 %27 ExclusiveScan %39\n%40 = OpIMul %5 %16 %34\n%41 = OpCompositeConstruct %25 %36 %36 %36 %36\nOpImageWrite %15 %40 %41\n%89 = OpLoad %17 %84\n%90 = OpLoad %17 %21\n%43 = OpLogicalOr %17 %89 %90\n%45 = OpSelect %5 %43 %44 %16\n%42 = OpGroupNonUniformIMul %5 %27 ExclusiveScan %45\n%46 = OpBitwiseOr %5 %32 %47\n%48 = OpIMul %5 %16 %34\n%49 = OpIAdd %5 %48 %44\n%50 = OpCompositeConstruct %25 %42 %42 %42 %42\nOpImageWrite %15 %49 %50\n%91 = OpLoad %17 %84\n%92 = OpLoad %17 %21\n%52 = OpLogicalOr %17 %91 %92\n%53 = OpSelect %5 %52 %38 %16\n%51 = OpGroupNonUniformIAdd %5 %27 ExclusiveScan %53\n%54 = OpIMul %5 %16 %34\n%55 = OpCompositeConstruct %25 %51 %51 %51 %51\nOpImageWrite %14 %54 %55\n%93 = OpLoad %17 %84\n%94 = OpLoad %17 %21\n%57 = OpLogicalOr %17 %93 %94\n%58 = OpSelect %5 %57 %44 %16\n%56 = OpGroupNonUniformIMul %5 %27 ExclusiveScan %58\n%59 = OpIMul %5 %16 %34\n%60 = OpIAdd %5 %59 %44\n%61 = OpCompositeConstruct %25 %56 %56 %56 %56\nOpImageWrite %14 %60 %61\n%63 = OpConvertUToF %62 %16\n%95 = OpLoad %17 %84\n%96 = OpLoad %17 %21\n%65 = OpLogicalOr %17 %95 %96\n%67 = OpSelect %62 %65 %66 %63\n%64 = OpGroupNonUniformFAdd %62 %27 ExclusiveScan %67\n%68 = OpConvertFToU %5 %64\n%69 = OpIMul %5 %16 %34\n%70 = OpCompositeConstruct %25 %68 %68 %68 %68\nOpImageWrite %13 %69 %70\n%97 = OpLoad %17 %84\n%98 = OpLoad %17 %21\n%72 = OpLogicalOr %17 %97 %98\n%74 = OpSelect %62 %72 %73 %63\n%71 = OpGroupNonUniformFMul %62 %27 ExclusiveScan %74\n%75 = OpConvertFToU %5 %71\n%76 = OpIMul %5 %16 %34\n%77 = OpIAdd %5 %76 %44\n%78 = OpCompositeConstruct %25 %75 %75 %75 %75\nOpImageWrite %13 %77 %78\n%105 = OpFunctionCall %1 %99\nOpReturn\nOpFunctionEnd\n%99 = OpFunction %1 None %2\n%100 = OpLabel\n%103 = OpLoad %17 %21\nOpSelectionMerge %102 None\nOpBranchConditional %103 %101 %102\n%101 = OpLabel\nOpKill\n%102 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-read-lane-at-optimizations.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_quad : require\n#extension GL_KHR_shader_subgroup_shuffle : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uvec4 _18 = imageLoad(_8, int(gl_GlobalInvocationID.x));\n    float _21 = uintBitsToFloat(_18.x);\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 0u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 1u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 2u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 3u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupShuffle(_21, (gl_SubgroupInvocationID + 4u) & 4294967292u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 0u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 1u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 2u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 3u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupShuffle(_21, (gl_SubgroupInvocationID & 4294967288u) | 4u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 0u))));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(uintBitsToFloat(imageLoad(_8, int(gl_GlobalInvocationID.x)).x) + subgroupQuadBroadcast(_21, 3u))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 145\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformShuffle\nOpCapability GroupNonUniformQuad\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12 %22\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\nOpDecorate %22 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeVector %5 4\n%20 = OpTypeFloat 32\n%22 = OpVariable %13 Input\n%25 = OpConstant %5 4294967292\n%27 = OpConstant %5 3\n%37 = OpConstant %5 1\n%48 = OpConstant %5 2\n%67 = OpConstant %5 4\n%116 = OpConstant %5 4294967288\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %143\n%143 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpImageRead %17 %9 %16\n%19 = OpCompositeExtract %5 %18 0\n%21 = OpBitcast %20 %19\n%23 = OpLoad %5 %22\n%24 = OpBitwiseAnd %5 %23 %25\n%26 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %15\n%28 = OpImageRead %17 %9 %16\n%29 = OpCompositeExtract %5 %28 0\n%30 = OpBitcast %20 %29\n%31 = OpFAdd %20 %30 %26\n%32 = OpBitcast %5 %31\n%33 = OpCompositeConstruct %17 %32 %32 %32 %32\nOpImageWrite %9 %16 %33\n%34 = OpLoad %5 %22\n%35 = OpBitwiseAnd %5 %34 %25\n%36 = OpBitwiseOr %5 %35 %37\n%38 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %37\n%39 = OpImageRead %17 %9 %16\n%40 = OpCompositeExtract %5 %39 0\n%41 = OpBitcast %20 %40\n%42 = OpFAdd %20 %41 %38\n%43 = OpBitcast %5 %42\n%44 = OpCompositeConstruct %17 %43 %43 %43 %43\nOpImageWrite %9 %16 %44\n%45 = OpLoad %5 %22\n%46 = OpBitwiseAnd %5 %45 %25\n%47 = OpBitwiseOr %5 %46 %48\n%49 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %48\n%50 = OpImageRead %17 %9 %16\n%51 = OpCompositeExtract %5 %50 0\n%52 = OpBitcast %20 %51\n%53 = OpFAdd %20 %52 %49\n%54 = OpBitcast %5 %53\n%55 = OpCompositeConstruct %17 %54 %54 %54 %54\nOpImageWrite %9 %16 %55\n%56 = OpLoad %5 %22\n%57 = OpBitwiseOr %5 %56 %27\n%58 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %27\n%59 = OpImageRead %17 %9 %16\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpBitcast %20 %60\n%62 = OpFAdd %20 %61 %58\n%63 = OpBitcast %5 %62\n%64 = OpCompositeConstruct %17 %63 %63 %63 %63\nOpImageWrite %9 %16 %64\n%65 = OpLoad %5 %22\n%66 = OpIAdd %5 %65 %67\n%68 = OpBitwiseAnd %5 %66 %25\n%69 = OpGroupNonUniformShuffle %20 %27 %21 %68\n%70 = OpImageRead %17 %9 %16\n%71 = OpCompositeExtract %5 %70 0\n%72 = OpBitcast %20 %71\n%73 = OpFAdd %20 %72 %69\n%74 = OpBitcast %5 %73\n%75 = OpCompositeConstruct %17 %74 %74 %74 %74\nOpImageWrite %9 %16 %75\n%76 = OpLoad %5 %22\n%77 = OpBitwiseAnd %5 %76 %25\n%78 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %15\n%79 = OpImageRead %17 %9 %16\n%80 = OpCompositeExtract %5 %79 0\n%81 = OpBitcast %20 %80\n%82 = OpFAdd %20 %81 %78\n%83 = OpBitcast %5 %82\n%84 = OpCompositeConstruct %17 %83 %83 %83 %83\nOpImageWrite %9 %16 %84\n%85 = OpLoad %5 %22\n%86 = OpBitwiseAnd %5 %85 %25\n%87 = OpBitwiseOr %5 %86 %37\n%88 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %37\n%89 = OpImageRead %17 %9 %16\n%90 = OpCompositeExtract %5 %89 0\n%91 = OpBitcast %20 %90\n%92 = OpFAdd %20 %91 %88\n%93 = OpBitcast %5 %92\n%94 = OpCompositeConstruct %17 %93 %93 %93 %93\nOpImageWrite %9 %16 %94\n%95 = OpLoad %5 %22\n%96 = OpBitwiseAnd %5 %95 %25\n%97 = OpBitwiseOr %5 %96 %48\n%98 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %48\n%99 = OpImageRead %17 %9 %16\n%100 = OpCompositeExtract %5 %99 0\n%101 = OpBitcast %20 %100\n%102 = OpFAdd %20 %101 %98\n%103 = OpBitcast %5 %102\n%104 = OpCompositeConstruct %17 %103 %103 %103 %103\nOpImageWrite %9 %16 %104\n%105 = OpLoad %5 %22\n%106 = OpBitwiseOr %5 %105 %27\n%107 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %27\n%108 = OpImageRead %17 %9 %16\n%109 = OpCompositeExtract %5 %108 0\n%110 = OpBitcast %20 %109\n%111 = OpFAdd %20 %110 %107\n%112 = OpBitcast %5 %111\n%113 = OpCompositeConstruct %17 %112 %112 %112 %112\nOpImageWrite %9 %16 %113\n%114 = OpLoad %5 %22\n%115 = OpBitwiseAnd %5 %114 %116\n%117 = OpBitwiseOr %5 %115 %67\n%118 = OpGroupNonUniformShuffle %20 %27 %21 %117\n%119 = OpImageRead %17 %9 %16\n%120 = OpCompositeExtract %5 %119 0\n%121 = OpBitcast %20 %120\n%122 = OpFAdd %20 %121 %118\n%123 = OpBitcast %5 %122\n%124 = OpCompositeConstruct %17 %123 %123 %123 %123\nOpImageWrite %9 %16 %124\n%125 = OpLoad %5 %22\n%126 = OpBitwiseAnd %5 %125 %25\n%127 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %15\n%128 = OpImageRead %17 %9 %16\n%129 = OpCompositeExtract %5 %128 0\n%130 = OpBitcast %20 %129\n%131 = OpFAdd %20 %130 %127\n%132 = OpBitcast %5 %131\n%133 = OpCompositeConstruct %17 %132 %132 %132 %132\nOpImageWrite %9 %16 %133\n%134 = OpLoad %5 %22\n%135 = OpBitwiseOr %5 %134 %27\n%136 = OpGroupNonUniformQuadBroadcast %20 %27 %21 %27\n%137 = OpImageRead %17 %9 %16\n%138 = OpCompositeExtract %5 %137 0\n%139 = OpBitcast %20 %138\n%140 = OpFAdd %20 %139 %136\n%141 = OpBitcast %5 %140\n%142 = OpCompositeConstruct %17 %141 %141 %141 %141\nOpImageWrite %9 %16 %142\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-read-lane-at.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_shuffle : require\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_quad : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _27 = (gl_SubgroupSize + 4294967295u) & gl_GlobalInvocationID.x;\n    uint _102 = gl_GlobalInvocationID.x * 3u;\n    imageStore(_8, int(_102), uvec4((((((((subgroupBroadcast(gl_GlobalInvocationID.x, 11u) + subgroupShuffle(gl_GlobalInvocationID.x, _27)) + subgroupQuadSwapHorizontal(gl_GlobalInvocationID.x)) + subgroupQuadSwapVertical(gl_GlobalInvocationID.x)) + subgroupQuadSwapDiagonal(gl_GlobalInvocationID.x)) + subgroupShuffleXor(gl_GlobalInvocationID.x, 4u)) + subgroupShuffleXor(gl_GlobalInvocationID.x, 8u)) + subgroupShuffleXor(gl_GlobalInvocationID.x, 16u)) + subgroupShuffleXor(gl_GlobalInvocationID.x, 32u)));\n    imageStore(_8, int(_102 + 1u), uvec4((((((((subgroupBroadcast(gl_GlobalInvocationID.y, 11u) + subgroupShuffle(gl_GlobalInvocationID.y, _27)) + subgroupQuadSwapHorizontal(gl_GlobalInvocationID.y)) + subgroupQuadSwapVertical(gl_GlobalInvocationID.y)) + subgroupQuadSwapDiagonal(gl_GlobalInvocationID.y)) + subgroupShuffleXor(gl_GlobalInvocationID.y, 4u)) + subgroupShuffleXor(gl_GlobalInvocationID.y, 8u)) + subgroupShuffleXor(gl_GlobalInvocationID.y, 16u)) + subgroupShuffleXor(gl_GlobalInvocationID.y, 32u)));\n    imageStore(_8, int(_102 + 2u), uvec4((((((((subgroupBroadcast(gl_GlobalInvocationID.z, 11u) + subgroupShuffle(gl_GlobalInvocationID.z, _27)) + subgroupQuadSwapHorizontal(gl_GlobalInvocationID.z)) + subgroupQuadSwapVertical(gl_GlobalInvocationID.z)) + subgroupQuadSwapDiagonal(gl_GlobalInvocationID.z)) + subgroupShuffleXor(gl_GlobalInvocationID.z, 4u)) + subgroupShuffleXor(gl_GlobalInvocationID.z, 8u)) + subgroupShuffleXor(gl_GlobalInvocationID.z, 16u)) + subgroupShuffleXor(gl_GlobalInvocationID.z, 32u)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 111\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability GroupNonUniformShuffle\nOpCapability GroupNonUniformQuad\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12 %23 %39\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\nOpDecorate %23 BuiltIn SubgroupSize\nOpDecorate %39 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpVariable %13 Input\n%26 = OpConstant %5 4294967295\n%29 = OpConstant %5 3\n%33 = OpConstant %5 11\n%39 = OpVariable %13 Input\n%66 = OpConstant %5 4\n%75 = OpConstant %5 8\n%84 = OpConstant %5 16\n%93 = OpConstant %5 32\n%101 = OpConstant %5 12\n%103 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %109\n%109 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%24 = OpLoad %5 %23\n%25 = OpIAdd %5 %24 %26\n%27 = OpBitwiseAnd %5 %25 %16\n%28 = OpGroupNonUniformShuffle %5 %29 %16 %27\n%30 = OpGroupNonUniformShuffle %5 %29 %19 %27\n%31 = OpGroupNonUniformShuffle %5 %29 %22 %27\n%32 = OpGroupNonUniformBroadcast %5 %29 %16 %33\n%34 = OpGroupNonUniformBroadcast %5 %29 %19 %33\n%35 = OpGroupNonUniformBroadcast %5 %29 %22 %33\n%36 = OpIAdd %5 %32 %28\n%37 = OpIAdd %5 %34 %30\n%38 = OpIAdd %5 %35 %31\n%40 = OpLoad %5 %39\n%41 = OpBitwiseXor %5 %40 %18\n%42 = OpGroupNonUniformQuadSwap %5 %29 %16 %15\n%43 = OpGroupNonUniformQuadSwap %5 %29 %19 %15\n%44 = OpGroupNonUniformQuadSwap %5 %29 %22 %15\n%45 = OpIAdd %5 %36 %42\n%46 = OpIAdd %5 %37 %43\n%47 = OpIAdd %5 %38 %44\n%48 = OpLoad %5 %39\n%49 = OpBitwiseXor %5 %48 %21\n%50 = OpGroupNonUniformQuadSwap %5 %29 %16 %18\n%51 = OpGroupNonUniformQuadSwap %5 %29 %19 %18\n%52 = OpGroupNonUniformQuadSwap %5 %29 %22 %18\n%53 = OpIAdd %5 %45 %50\n%54 = OpIAdd %5 %46 %51\n%55 = OpIAdd %5 %47 %52\n%56 = OpLoad %5 %39\n%57 = OpBitwiseXor %5 %56 %29\n%58 = OpGroupNonUniformQuadSwap %5 %29 %16 %21\n%59 = OpGroupNonUniformQuadSwap %5 %29 %19 %21\n%60 = OpGroupNonUniformQuadSwap %5 %29 %22 %21\n%61 = OpIAdd %5 %53 %58\n%62 = OpIAdd %5 %54 %59\n%63 = OpIAdd %5 %55 %60\n%64 = OpLoad %5 %39\n%65 = OpBitwiseXor %5 %64 %66\n%67 = OpGroupNonUniformShuffleXor %5 %29 %16 %66\n%68 = OpGroupNonUniformShuffleXor %5 %29 %19 %66\n%69 = OpGroupNonUniformShuffleXor %5 %29 %22 %66\n%70 = OpIAdd %5 %61 %67\n%71 = OpIAdd %5 %62 %68\n%72 = OpIAdd %5 %63 %69\n%73 = OpLoad %5 %39\n%74 = OpBitwiseXor %5 %73 %75\n%76 = OpGroupNonUniformShuffleXor %5 %29 %16 %75\n%77 = OpGroupNonUniformShuffleXor %5 %29 %19 %75\n%78 = OpGroupNonUniformShuffleXor %5 %29 %22 %75\n%79 = OpIAdd %5 %70 %76\n%80 = OpIAdd %5 %71 %77\n%81 = OpIAdd %5 %72 %78\n%82 = OpLoad %5 %39\n%83 = OpBitwiseXor %5 %82 %84\n%85 = OpGroupNonUniformShuffleXor %5 %29 %16 %84\n%86 = OpGroupNonUniformShuffleXor %5 %29 %19 %84\n%87 = OpGroupNonUniformShuffleXor %5 %29 %22 %84\n%88 = OpIAdd %5 %79 %85\n%89 = OpIAdd %5 %80 %86\n%90 = OpIAdd %5 %81 %87\n%91 = OpLoad %5 %39\n%92 = OpBitwiseXor %5 %91 %93\n%94 = OpGroupNonUniformShuffleXor %5 %29 %16 %93\n%95 = OpGroupNonUniformShuffleXor %5 %29 %19 %93\n%96 = OpGroupNonUniformShuffleXor %5 %29 %22 %93\n%97 = OpIAdd %5 %88 %94\n%98 = OpIAdd %5 %89 %95\n%99 = OpIAdd %5 %90 %96\n%100 = OpIMul %5 %16 %101\n%102 = OpIMul %5 %16 %29\n%104 = OpCompositeConstruct %103 %97 %97 %97 %97\nOpImageWrite %9 %102 %104\n%105 = OpCompositeConstruct %103 %98 %98 %98 %98\n%106 = OpIAdd %5 %102 %18\nOpImageWrite %9 %106 %105\n%107 = OpCompositeConstruct %103 %99 %99 %99 %99\n%108 = OpIAdd %5 %102 %21\nOpImageWrite %9 %108 %107\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-read-lane-first.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    uint _29 = gl_GlobalInvocationID.x * 3u;\n    imageStore(_8, int(_29), uvec4(subgroupBroadcastFirst(gl_GlobalInvocationID.x)));\n    imageStore(_8, int(_29 + 1u), uvec4(subgroupBroadcastFirst(gl_GlobalInvocationID.y)));\n    imageStore(_8, int(_29 + 2u), uvec4(subgroupBroadcastFirst(gl_GlobalInvocationID.z)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%24 = OpConstant %5 3\n%28 = OpConstant %5 12\n%30 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %36\n%36 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %12 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %12 %21\n%22 = OpLoad %5 %20\n%23 = OpGroupNonUniformBroadcastFirst %5 %24 %16\n%25 = OpGroupNonUniformBroadcastFirst %5 %24 %19\n%26 = OpGroupNonUniformBroadcastFirst %5 %24 %22\n%27 = OpIMul %5 %16 %28\n%29 = OpIMul %5 %16 %24\n%31 = OpCompositeConstruct %30 %23 %23 %23 %23\nOpImageWrite %9 %29 %31\n%32 = OpCompositeConstruct %30 %25 %25 %25 %25\n%33 = OpIAdd %5 %29 %18\nOpImageWrite %9 %33 %32\n%34 = OpCompositeConstruct %30 %26 %26 %26 %26\n%35 = OpIAdd %5 %29 %21\nOpImageWrite %9 %35 %34\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-read-lane-first.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_shuffle : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nlayout(location = 0) flat in uvec3 INDEX;\nbool discard_state;\n\nuint WaveReadFirstLane(uint _31, bool _32)\n{\n    uvec4 _37 = subgroupBallot(!_32);\n    return (subgroupBallotBitCount(_37) != 0u) ? subgroupShuffle(_31, subgroupBallotFindLSB(_37)) : 0u;\n}\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX.x == 40u)\n    {\n        discard_state = true;\n    }\n    uint _53 = INDEX.x * 3u;\n    imageStore(_8, int(_53), uvec4(WaveReadFirstLane(INDEX.x, gl_HelperInvocation || discard_state)));\n    imageStore(_8, int(_53 + 1u), uvec4(WaveReadFirstLane(INDEX.y, gl_HelperInvocation || discard_state)));\n    imageStore(_8, int(_53 + 2u), uvec4(WaveReadFirstLane(INDEX.z, gl_HelperInvocation || discard_state)));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpCapability GroupNonUniformShuffle\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %64\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %27 \"discard_state\"\nOpName %33 \"WaveReadFirstLane\"\nOpName %71 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %64 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 3\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpTypeBool\n%25 = OpConstant %5 40\n%26 = OpTypePointer Private %23\n%27 = OpVariable %26 Private\n%28 = OpConstantFalse %23\n%30 = OpTypeFunction %5 %5 %23\n%35 = OpTypeVector %5 4\n%38 = OpConstant %5 3\n%44 = OpConstantNull %5\n%52 = OpConstant %5 12\n%62 = OpConstantTrue %23\n%63 = OpTypePointer Input %23\n%64 = OpVariable %63 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %27 %28\nOpBranch %59\n%59 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %11 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %11 %21\n%22 = OpLoad %5 %20\n%24 = OpIEqual %23 %16 %25\nOpSelectionMerge %61 None\nOpBranchConditional %24 %60 %61\n%60 = OpLabel\nOpStore %27 %62\nOpBranch %61\n%61 = OpLabel\n%65 = OpLoad %23 %64\n%66 = OpLoad %23 %27\n%29 = OpLogicalOr %23 %65 %66\n%46 = OpFunctionCall %5 %33 %16 %29\n%67 = OpLoad %23 %64\n%68 = OpLoad %23 %27\n%47 = OpLogicalOr %23 %67 %68\n%48 = OpFunctionCall %5 %33 %19 %47\n%69 = OpLoad %23 %64\n%70 = OpLoad %23 %27\n%49 = OpLogicalOr %23 %69 %70\n%50 = OpFunctionCall %5 %33 %22 %49\n%51 = OpIMul %5 %16 %52\n%53 = OpIMul %5 %16 %38\n%54 = OpCompositeConstruct %35 %46 %46 %46 %46\nOpImageWrite %12 %53 %54\n%55 = OpCompositeConstruct %35 %48 %48 %48 %48\n%56 = OpIAdd %5 %53 %18\nOpImageWrite %12 %56 %55\n%57 = OpCompositeConstruct %35 %50 %50 %50 %50\n%58 = OpIAdd %5 %53 %21\nOpImageWrite %12 %58 %57\n%77 = OpFunctionCall %1 %71\nOpReturn\nOpFunctionEnd\n%33 = OpFunction %5 None %30\n%31 = OpFunctionParameter %5\n%32 = OpFunctionParameter %23\n%34 = OpLabel\n%36 = OpLogicalNot %23 %32\n%37 = OpGroupNonUniformBallot %35 %38 %36\n%39 = OpGroupNonUniformBallotFindLSB %5 %38 %37\n%40 = OpGroupNonUniformShuffle %5 %38 %31 %39\n%41 = OpGroupNonUniformBallotBitCount %5 %38 Reduce %37\n%42 = OpINotEqual %23 %41 %15\n%43 = OpSelect %5 %42 %40 %44\nOpReturnValue %43\nOpFunctionEnd\n%71 = OpFunction %1 None %2\n%72 = OpLabel\n%75 = OpLoad %23 %27\nOpSelectionMerge %74 None\nOpBranchConditional %75 %73 %74\n%73 = OpLabel\nOpKill\n%74 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-reduce-helpers.sm67.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _10;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    uint _22 = INDEX * 28u;\n    imageStore(_8, int(INDEX * 7u), uvec4(subgroupAdd(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 1u), uvec4(subgroupMul(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 2u), uvec4(subgroupAnd(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 3u), uvec4(subgroupOr(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 4u), uvec4(subgroupXor(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 5u), uvec4(subgroupMin(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 6u), uvec4(subgroupMax(INDEX)));\n    imageStore(_9, int(INDEX * 7u), uvec4(subgroupAdd(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 1u), uvec4(subgroupMul(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 2u), uvec4(subgroupAnd(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 3u), uvec4(subgroupOr(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 4u), uvec4(subgroupXor(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 5u), uvec4(uint(subgroupMin(int(INDEX)))));\n    imageStore(_9, int((INDEX * 7u) + 6u), uvec4(uint(subgroupMax(int(INDEX)))));\n    float _110 = float(INDEX);\n    imageStore(_10, int(INDEX * 7u), uvec4(uint(subgroupAdd(_110))));\n    imageStore(_10, int((INDEX * 7u) + 1u), uvec4(uint(subgroupMul(_110))));\n    imageStore(_10, int((INDEX * 7u) + 5u), uvec4(uint(subgroupMin(_110))));\n    imageStore(_10, int((INDEX * 7u) + 6u), uvec4(uint(subgroupMax(_110))));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 146\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %18 \"discard_state\"\nOpName %138 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %10 NonReadable\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypePointer Input %5\n%12 = OpVariable %11 Input\n%14 = OpTypeBool\n%16 = OpConstant %5 40\n%17 = OpTypePointer Private %14\n%18 = OpVariable %17 Private\n%19 = OpConstantFalse %14\n%21 = OpConstant %5 3\n%23 = OpConstant %5 28\n%26 = OpConstant %5 7\n%27 = OpTypeVector %5 4\n%31 = OpConstant %5 4\n%35 = OpConstant %5 1\n%39 = OpConstant %5 8\n%43 = OpConstant %5 2\n%47 = OpConstant %5 12\n%54 = OpConstant %5 16\n%61 = OpConstant %5 20\n%65 = OpConstant %5 5\n%69 = OpConstant %5 24\n%73 = OpConstant %5 6\n%109 = OpTypeFloat 32\n%137 = OpConstantTrue %14\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %18 %19\nOpBranch %134\n%134 = OpLabel\n%13 = OpLoad %5 %12\n%15 = OpIEqual %14 %13 %16\nOpSelectionMerge %136 None\nOpBranchConditional %15 %135 %136\n%135 = OpLabel\nOpStore %18 %137\nOpBranch %136\n%136 = OpLabel\n%20 = OpGroupNonUniformIAdd %5 %21 Reduce %13\n%22 = OpIMul %5 %13 %23\n%24 = OpLoad %6 %8\n%25 = OpIMul %5 %13 %26\n%28 = OpCompositeConstruct %27 %20 %20 %20 %20\nOpImageWrite %24 %25 %28\n%29 = OpGroupNonUniformIMul %5 %21 Reduce %13\n%30 = OpIAdd %5 %22 %31\n%32 = OpLoad %6 %8\n%33 = OpIMul %5 %13 %26\n%34 = OpIAdd %5 %33 %35\n%36 = OpCompositeConstruct %27 %29 %29 %29 %29\nOpImageWrite %32 %34 %36\n%37 = OpGroupNonUniformBitwiseAnd %5 %21 Reduce %13\n%38 = OpIAdd %5 %22 %39\n%40 = OpLoad %6 %8\n%41 = OpIMul %5 %13 %26\n%42 = OpIAdd %5 %41 %43\n%44 = OpCompositeConstruct %27 %37 %37 %37 %37\nOpImageWrite %40 %42 %44\n%45 = OpGroupNonUniformBitwiseOr %5 %21 Reduce %13\n%46 = OpIAdd %5 %22 %47\n%48 = OpLoad %6 %8\n%49 = OpIMul %5 %13 %26\n%50 = OpIAdd %5 %49 %21\n%51 = OpCompositeConstruct %27 %45 %45 %45 %45\nOpImageWrite %48 %50 %51\n%52 = OpGroupNonUniformBitwiseXor %5 %21 Reduce %13\n%53 = OpIAdd %5 %22 %54\n%55 = OpLoad %6 %8\n%56 = OpIMul %5 %13 %26\n%57 = OpIAdd %5 %56 %31\n%58 = OpCompositeConstruct %27 %52 %52 %52 %52\nOpImageWrite %55 %57 %58\n%59 = OpGroupNonUniformUMin %5 %21 Reduce %13\n%60 = OpIAdd %5 %22 %61\n%62 = OpLoad %6 %8\n%63 = OpIMul %5 %13 %26\n%64 = OpIAdd %5 %63 %65\n%66 = OpCompositeConstruct %27 %59 %59 %59 %59\nOpImageWrite %62 %64 %66\n%67 = OpGroupNonUniformUMax %5 %21 Reduce %13\n%68 = OpIAdd %5 %22 %69\n%70 = OpLoad %6 %8\n%71 = OpIMul %5 %13 %26\n%72 = OpIAdd %5 %71 %73\n%74 = OpCompositeConstruct %27 %67 %67 %67 %67\nOpImageWrite %70 %72 %74\n%75 = OpGroupNonUniformIAdd %5 %21 Reduce %13\n%76 = OpLoad %6 %9\n%77 = OpIMul %5 %13 %26\n%78 = OpCompositeConstruct %27 %75 %75 %75 %75\nOpImageWrite %76 %77 %78\n%79 = OpGroupNonUniformIMul %5 %21 Reduce %13\n%80 = OpLoad %6 %9\n%81 = OpIMul %5 %13 %26\n%82 = OpIAdd %5 %81 %35\n%83 = OpCompositeConstruct %27 %79 %79 %79 %79\nOpImageWrite %80 %82 %83\n%84 = OpGroupNonUniformBitwiseAnd %5 %21 Reduce %13\n%85 = OpLoad %6 %9\n%86 = OpIMul %5 %13 %26\n%87 = OpIAdd %5 %86 %43\n%88 = OpCompositeConstruct %27 %84 %84 %84 %84\nOpImageWrite %85 %87 %88\n%89 = OpGroupNonUniformBitwiseOr %5 %21 Reduce %13\n%90 = OpLoad %6 %9\n%91 = OpIMul %5 %13 %26\n%92 = OpIAdd %5 %91 %21\n%93 = OpCompositeConstruct %27 %89 %89 %89 %89\nOpImageWrite %90 %92 %93\n%94 = OpGroupNonUniformBitwiseXor %5 %21 Reduce %13\n%95 = OpLoad %6 %9\n%96 = OpIMul %5 %13 %26\n%97 = OpIAdd %5 %96 %31\n%98 = OpCompositeConstruct %27 %94 %94 %94 %94\nOpImageWrite %95 %97 %98\n%99 = OpGroupNonUniformSMin %5 %21 Reduce %13\n%100 = OpLoad %6 %9\n%101 = OpIMul %5 %13 %26\n%102 = OpIAdd %5 %101 %65\n%103 = OpCompositeConstruct %27 %99 %99 %99 %99\nOpImageWrite %100 %102 %103\n%104 = OpGroupNonUniformSMax %5 %21 Reduce %13\n%105 = OpLoad %6 %9\n%106 = OpIMul %5 %13 %26\n%107 = OpIAdd %5 %106 %73\n%108 = OpCompositeConstruct %27 %104 %104 %104 %104\nOpImageWrite %105 %107 %108\n%110 = OpConvertUToF %109 %13\n%111 = OpGroupNonUniformFAdd %109 %21 Reduce %110\n%112 = OpConvertFToU %5 %111\n%113 = OpLoad %6 %10\n%114 = OpIMul %5 %13 %26\n%115 = OpCompositeConstruct %27 %112 %112 %112 %112\nOpImageWrite %113 %114 %115\n%116 = OpGroupNonUniformFMul %109 %21 Reduce %110\n%117 = OpConvertFToU %5 %116\n%118 = OpLoad %6 %10\n%119 = OpIMul %5 %13 %26\n%120 = OpIAdd %5 %119 %35\n%121 = OpCompositeConstruct %27 %117 %117 %117 %117\nOpImageWrite %118 %120 %121\n%122 = OpGroupNonUniformFMin %109 %21 Reduce %110\n%123 = OpConvertFToU %5 %122\n%124 = OpLoad %6 %10\n%125 = OpIMul %5 %13 %26\n%126 = OpIAdd %5 %125 %65\n%127 = OpCompositeConstruct %27 %123 %123 %123 %123\nOpImageWrite %124 %126 %127\n%128 = OpGroupNonUniformFMax %109 %21 Reduce %110\n%129 = OpConvertFToU %5 %128\n%130 = OpLoad %6 %10\n%131 = OpIMul %5 %13 %26\n%132 = OpIAdd %5 %131 %73\n%133 = OpCompositeConstruct %27 %129 %129 %129 %129\nOpImageWrite %130 %132 %133\n%144 = OpFunctionCall %1 %138\nOpReturn\nOpFunctionEnd\n%138 = OpFunction %1 None %2\n%139 = OpLabel\n%142 = OpLoad %14 %18\nOpSelectionMerge %141 None\nOpBranchConditional %142 %140 %141\n%140 = OpLabel\nOpKill\n%141 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-reduce-helpers.sm67.quad-maximal-reconvergence.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _10;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    uint _22 = INDEX * 28u;\n    imageStore(_8, int(INDEX * 7u), uvec4(subgroupAdd(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 1u), uvec4(subgroupMul(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 2u), uvec4(subgroupAnd(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 3u), uvec4(subgroupOr(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 4u), uvec4(subgroupXor(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 5u), uvec4(subgroupMin(INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 6u), uvec4(subgroupMax(INDEX)));\n    imageStore(_9, int(INDEX * 7u), uvec4(subgroupAdd(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 1u), uvec4(subgroupMul(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 2u), uvec4(subgroupAnd(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 3u), uvec4(subgroupOr(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 4u), uvec4(subgroupXor(INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 5u), uvec4(uint(subgroupMin(int(INDEX)))));\n    imageStore(_9, int((INDEX * 7u) + 6u), uvec4(uint(subgroupMax(int(INDEX)))));\n    float _110 = float(INDEX);\n    imageStore(_10, int(INDEX * 7u), uvec4(uint(subgroupAdd(_110))));\n    imageStore(_10, int((INDEX * 7u) + 1u), uvec4(uint(subgroupMul(_110))));\n    imageStore(_10, int((INDEX * 7u) + 5u), uvec4(uint(subgroupMin(_110))));\n    imageStore(_10, int((INDEX * 7u) + 6u), uvec4(uint(subgroupMax(_110))));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 146\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpExtension \"SPV_KHR_maximal_reconvergence\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 MaximallyReconvergesKHR\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %18 \"discard_state\"\nOpName %138 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %10 NonReadable\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypePointer Input %5\n%12 = OpVariable %11 Input\n%14 = OpTypeBool\n%16 = OpConstant %5 40\n%17 = OpTypePointer Private %14\n%18 = OpVariable %17 Private\n%19 = OpConstantFalse %14\n%21 = OpConstant %5 3\n%23 = OpConstant %5 28\n%26 = OpConstant %5 7\n%27 = OpTypeVector %5 4\n%31 = OpConstant %5 4\n%35 = OpConstant %5 1\n%39 = OpConstant %5 8\n%43 = OpConstant %5 2\n%47 = OpConstant %5 12\n%54 = OpConstant %5 16\n%61 = OpConstant %5 20\n%65 = OpConstant %5 5\n%69 = OpConstant %5 24\n%73 = OpConstant %5 6\n%109 = OpTypeFloat 32\n%137 = OpConstantTrue %14\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %18 %19\nOpBranch %134\n%134 = OpLabel\n%13 = OpLoad %5 %12\n%15 = OpIEqual %14 %13 %16\nOpSelectionMerge %136 None\nOpBranchConditional %15 %135 %136\n%135 = OpLabel\nOpStore %18 %137\nOpBranch %136\n%136 = OpLabel\n%20 = OpGroupNonUniformIAdd %5 %21 Reduce %13\n%22 = OpIMul %5 %13 %23\n%24 = OpLoad %6 %8\n%25 = OpIMul %5 %13 %26\n%28 = OpCompositeConstruct %27 %20 %20 %20 %20\nOpImageWrite %24 %25 %28\n%29 = OpGroupNonUniformIMul %5 %21 Reduce %13\n%30 = OpIAdd %5 %22 %31\n%32 = OpLoad %6 %8\n%33 = OpIMul %5 %13 %26\n%34 = OpIAdd %5 %33 %35\n%36 = OpCompositeConstruct %27 %29 %29 %29 %29\nOpImageWrite %32 %34 %36\n%37 = OpGroupNonUniformBitwiseAnd %5 %21 Reduce %13\n%38 = OpIAdd %5 %22 %39\n%40 = OpLoad %6 %8\n%41 = OpIMul %5 %13 %26\n%42 = OpIAdd %5 %41 %43\n%44 = OpCompositeConstruct %27 %37 %37 %37 %37\nOpImageWrite %40 %42 %44\n%45 = OpGroupNonUniformBitwiseOr %5 %21 Reduce %13\n%46 = OpIAdd %5 %22 %47\n%48 = OpLoad %6 %8\n%49 = OpIMul %5 %13 %26\n%50 = OpIAdd %5 %49 %21\n%51 = OpCompositeConstruct %27 %45 %45 %45 %45\nOpImageWrite %48 %50 %51\n%52 = OpGroupNonUniformBitwiseXor %5 %21 Reduce %13\n%53 = OpIAdd %5 %22 %54\n%55 = OpLoad %6 %8\n%56 = OpIMul %5 %13 %26\n%57 = OpIAdd %5 %56 %31\n%58 = OpCompositeConstruct %27 %52 %52 %52 %52\nOpImageWrite %55 %57 %58\n%59 = OpGroupNonUniformUMin %5 %21 Reduce %13\n%60 = OpIAdd %5 %22 %61\n%62 = OpLoad %6 %8\n%63 = OpIMul %5 %13 %26\n%64 = OpIAdd %5 %63 %65\n%66 = OpCompositeConstruct %27 %59 %59 %59 %59\nOpImageWrite %62 %64 %66\n%67 = OpGroupNonUniformUMax %5 %21 Reduce %13\n%68 = OpIAdd %5 %22 %69\n%70 = OpLoad %6 %8\n%71 = OpIMul %5 %13 %26\n%72 = OpIAdd %5 %71 %73\n%74 = OpCompositeConstruct %27 %67 %67 %67 %67\nOpImageWrite %70 %72 %74\n%75 = OpGroupNonUniformIAdd %5 %21 Reduce %13\n%76 = OpLoad %6 %9\n%77 = OpIMul %5 %13 %26\n%78 = OpCompositeConstruct %27 %75 %75 %75 %75\nOpImageWrite %76 %77 %78\n%79 = OpGroupNonUniformIMul %5 %21 Reduce %13\n%80 = OpLoad %6 %9\n%81 = OpIMul %5 %13 %26\n%82 = OpIAdd %5 %81 %35\n%83 = OpCompositeConstruct %27 %79 %79 %79 %79\nOpImageWrite %80 %82 %83\n%84 = OpGroupNonUniformBitwiseAnd %5 %21 Reduce %13\n%85 = OpLoad %6 %9\n%86 = OpIMul %5 %13 %26\n%87 = OpIAdd %5 %86 %43\n%88 = OpCompositeConstruct %27 %84 %84 %84 %84\nOpImageWrite %85 %87 %88\n%89 = OpGroupNonUniformBitwiseOr %5 %21 Reduce %13\n%90 = OpLoad %6 %9\n%91 = OpIMul %5 %13 %26\n%92 = OpIAdd %5 %91 %21\n%93 = OpCompositeConstruct %27 %89 %89 %89 %89\nOpImageWrite %90 %92 %93\n%94 = OpGroupNonUniformBitwiseXor %5 %21 Reduce %13\n%95 = OpLoad %6 %9\n%96 = OpIMul %5 %13 %26\n%97 = OpIAdd %5 %96 %31\n%98 = OpCompositeConstruct %27 %94 %94 %94 %94\nOpImageWrite %95 %97 %98\n%99 = OpGroupNonUniformSMin %5 %21 Reduce %13\n%100 = OpLoad %6 %9\n%101 = OpIMul %5 %13 %26\n%102 = OpIAdd %5 %101 %65\n%103 = OpCompositeConstruct %27 %99 %99 %99 %99\nOpImageWrite %100 %102 %103\n%104 = OpGroupNonUniformSMax %5 %21 Reduce %13\n%105 = OpLoad %6 %9\n%106 = OpIMul %5 %13 %26\n%107 = OpIAdd %5 %106 %73\n%108 = OpCompositeConstruct %27 %104 %104 %104 %104\nOpImageWrite %105 %107 %108\n%110 = OpConvertUToF %109 %13\n%111 = OpGroupNonUniformFAdd %109 %21 Reduce %110\n%112 = OpConvertFToU %5 %111\n%113 = OpLoad %6 %10\n%114 = OpIMul %5 %13 %26\n%115 = OpCompositeConstruct %27 %112 %112 %112 %112\nOpImageWrite %113 %114 %115\n%116 = OpGroupNonUniformFMul %109 %21 Reduce %110\n%117 = OpConvertFToU %5 %116\n%118 = OpLoad %6 %10\n%119 = OpIMul %5 %13 %26\n%120 = OpIAdd %5 %119 %35\n%121 = OpCompositeConstruct %27 %117 %117 %117 %117\nOpImageWrite %118 %120 %121\n%122 = OpGroupNonUniformFMin %109 %21 Reduce %110\n%123 = OpConvertFToU %5 %122\n%124 = OpLoad %6 %10\n%125 = OpIMul %5 %13 %26\n%126 = OpIAdd %5 %125 %65\n%127 = OpCompositeConstruct %27 %123 %123 %123 %123\nOpImageWrite %124 %126 %127\n%128 = OpGroupNonUniformFMax %109 %21 Reduce %110\n%129 = OpConvertFToU %5 %128\n%130 = OpLoad %6 %10\n%131 = OpIMul %5 %13 %26\n%132 = OpIAdd %5 %131 %73\n%133 = OpCompositeConstruct %27 %129 %129 %129 %129\nOpImageWrite %130 %132 %133\n%144 = OpFunctionCall %1 %138\nOpReturn\nOpFunctionEnd\n%138 = OpFunction %1 None %2\n%139 = OpLabel\n%142 = OpLoad %14 %18\nOpSelectionMerge %141 None\nOpBranchConditional %142 %140 %141\n%140 = OpLabel\nOpKill\n%141 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-reduce.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_arithmetic : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _10;\n\nvoid main()\n{\n    uint _23 = gl_GlobalInvocationID.x * 28u;\n    imageStore(_8, int(gl_GlobalInvocationID.x * 7u), uvec4(subgroupAdd(gl_GlobalInvocationID.x)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 7u) + 1u), uvec4(subgroupMul(gl_GlobalInvocationID.x)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 7u) + 2u), uvec4(subgroupAnd(gl_GlobalInvocationID.x)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 7u) + 3u), uvec4(subgroupOr(gl_GlobalInvocationID.x)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 7u) + 4u), uvec4(subgroupXor(gl_GlobalInvocationID.x)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 7u) + 5u), uvec4(subgroupMin(gl_GlobalInvocationID.x)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 7u) + 6u), uvec4(subgroupMax(gl_GlobalInvocationID.x)));\n    imageStore(_9, int(gl_GlobalInvocationID.x * 7u), uvec4(subgroupAdd(gl_GlobalInvocationID.x)));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 7u) + 1u), uvec4(subgroupMul(gl_GlobalInvocationID.x)));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 7u) + 2u), uvec4(subgroupAnd(gl_GlobalInvocationID.x)));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 7u) + 3u), uvec4(subgroupOr(gl_GlobalInvocationID.x)));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 7u) + 4u), uvec4(subgroupXor(gl_GlobalInvocationID.x)));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 7u) + 5u), uvec4(uint(subgroupMin(int(gl_GlobalInvocationID.x)))));\n    imageStore(_9, int((gl_GlobalInvocationID.x * 7u) + 6u), uvec4(uint(subgroupMax(int(gl_GlobalInvocationID.x)))));\n    float _97 = float(gl_GlobalInvocationID.x);\n    imageStore(_10, int(gl_GlobalInvocationID.x * 7u), uvec4(uint(subgroupAdd(_97))));\n    imageStore(_10, int((gl_GlobalInvocationID.x * 7u) + 1u), uvec4(uint(subgroupMul(_97))));\n    imageStore(_10, int((gl_GlobalInvocationID.x * 7u) + 5u), uvec4(uint(subgroupMin(_97))));\n    imageStore(_10, int((gl_GlobalInvocationID.x * 7u) + 6u), uvec4(uint(subgroupMax(_97))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 119\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %10 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 3\n%24 = OpConstant %5 28\n%26 = OpConstant %5 7\n%27 = OpTypeVector %5 4\n%31 = OpConstant %5 4\n%34 = OpConstant %5 1\n%38 = OpConstant %5 8\n%41 = OpConstant %5 2\n%45 = OpConstant %5 12\n%51 = OpConstant %5 16\n%57 = OpConstant %5 20\n%60 = OpConstant %5 5\n%64 = OpConstant %5 24\n%67 = OpConstant %5 6\n%96 = OpTypeFloat 32\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %117\n%117 = OpLabel\n%11 = OpLoad %6 %10\n%12 = OpLoad %6 %9\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%21 = OpGroupNonUniformIAdd %5 %22 Reduce %20\n%23 = OpIMul %5 %20 %24\n%25 = OpIMul %5 %20 %26\n%28 = OpCompositeConstruct %27 %21 %21 %21 %21\nOpImageWrite %13 %25 %28\n%29 = OpGroupNonUniformIMul %5 %22 Reduce %20\n%30 = OpIAdd %5 %23 %31\n%32 = OpIMul %5 %20 %26\n%33 = OpIAdd %5 %32 %34\n%35 = OpCompositeConstruct %27 %29 %29 %29 %29\nOpImageWrite %13 %33 %35\n%36 = OpGroupNonUniformBitwiseAnd %5 %22 Reduce %20\n%37 = OpIAdd %5 %23 %38\n%39 = OpIMul %5 %20 %26\n%40 = OpIAdd %5 %39 %41\n%42 = OpCompositeConstruct %27 %36 %36 %36 %36\nOpImageWrite %13 %40 %42\n%43 = OpGroupNonUniformBitwiseOr %5 %22 Reduce %20\n%44 = OpIAdd %5 %23 %45\n%46 = OpIMul %5 %20 %26\n%47 = OpIAdd %5 %46 %22\n%48 = OpCompositeConstruct %27 %43 %43 %43 %43\nOpImageWrite %13 %47 %48\n%49 = OpGroupNonUniformBitwiseXor %5 %22 Reduce %20\n%50 = OpIAdd %5 %23 %51\n%52 = OpIMul %5 %20 %26\n%53 = OpIAdd %5 %52 %31\n%54 = OpCompositeConstruct %27 %49 %49 %49 %49\nOpImageWrite %13 %53 %54\n%55 = OpGroupNonUniformUMin %5 %22 Reduce %20\n%56 = OpIAdd %5 %23 %57\n%58 = OpIMul %5 %20 %26\n%59 = OpIAdd %5 %58 %60\n%61 = OpCompositeConstruct %27 %55 %55 %55 %55\nOpImageWrite %13 %59 %61\n%62 = OpGroupNonUniformUMax %5 %22 Reduce %20\n%63 = OpIAdd %5 %23 %64\n%65 = OpIMul %5 %20 %26\n%66 = OpIAdd %5 %65 %67\n%68 = OpCompositeConstruct %27 %62 %62 %62 %62\nOpImageWrite %13 %66 %68\n%69 = OpGroupNonUniformIAdd %5 %22 Reduce %20\n%70 = OpIMul %5 %20 %26\n%71 = OpCompositeConstruct %27 %69 %69 %69 %69\nOpImageWrite %12 %70 %71\n%72 = OpGroupNonUniformIMul %5 %22 Reduce %20\n%73 = OpIMul %5 %20 %26\n%74 = OpIAdd %5 %73 %34\n%75 = OpCompositeConstruct %27 %72 %72 %72 %72\nOpImageWrite %12 %74 %75\n%76 = OpGroupNonUniformBitwiseAnd %5 %22 Reduce %20\n%77 = OpIMul %5 %20 %26\n%78 = OpIAdd %5 %77 %41\n%79 = OpCompositeConstruct %27 %76 %76 %76 %76\nOpImageWrite %12 %78 %79\n%80 = OpGroupNonUniformBitwiseOr %5 %22 Reduce %20\n%81 = OpIMul %5 %20 %26\n%82 = OpIAdd %5 %81 %22\n%83 = OpCompositeConstruct %27 %80 %80 %80 %80\nOpImageWrite %12 %82 %83\n%84 = OpGroupNonUniformBitwiseXor %5 %22 Reduce %20\n%85 = OpIMul %5 %20 %26\n%86 = OpIAdd %5 %85 %31\n%87 = OpCompositeConstruct %27 %84 %84 %84 %84\nOpImageWrite %12 %86 %87\n%88 = OpGroupNonUniformSMin %5 %22 Reduce %20\n%89 = OpIMul %5 %20 %26\n%90 = OpIAdd %5 %89 %60\n%91 = OpCompositeConstruct %27 %88 %88 %88 %88\nOpImageWrite %12 %90 %91\n%92 = OpGroupNonUniformSMax %5 %22 Reduce %20\n%93 = OpIMul %5 %20 %26\n%94 = OpIAdd %5 %93 %67\n%95 = OpCompositeConstruct %27 %92 %92 %92 %92\nOpImageWrite %12 %94 %95\n%97 = OpConvertUToF %96 %20\n%98 = OpGroupNonUniformFAdd %96 %22 Reduce %97\n%99 = OpConvertFToU %5 %98\n%100 = OpIMul %5 %20 %26\n%101 = OpCompositeConstruct %27 %99 %99 %99 %99\nOpImageWrite %11 %100 %101\n%102 = OpGroupNonUniformFMul %96 %22 Reduce %97\n%103 = OpConvertFToU %5 %102\n%104 = OpIMul %5 %20 %26\n%105 = OpIAdd %5 %104 %34\n%106 = OpCompositeConstruct %27 %103 %103 %103 %103\nOpImageWrite %11 %105 %106\n%107 = OpGroupNonUniformFMin %96 %22 Reduce %97\n%108 = OpConvertFToU %5 %107\n%109 = OpIMul %5 %20 %26\n%110 = OpIAdd %5 %109 %60\n%111 = OpCompositeConstruct %27 %108 %108 %108 %108\nOpImageWrite %11 %110 %111\n%112 = OpGroupNonUniformFMax %96 %22 Reduce %97\n%113 = OpConvertFToU %5 %112\n%114 = OpIMul %5 %20 %26\n%115 = OpIAdd %5 %114 %67\n%116 = OpCompositeConstruct %27 %113 %113 %113 %113\nOpImageWrite %11 %115 %116\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-reduce.frag",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_arithmetic : require\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _9;\nlayout(set = 0, binding = 2, r32ui) uniform writeonly uimageBuffer _10;\n\nlayout(location = 0) flat in uint INDEX;\nbool discard_state;\n\nvoid discard_exit()\n{\n    if (discard_state)\n    {\n        discard;\n    }\n}\n\nvoid main()\n{\n    discard_state = false;\n    if (INDEX == 40u)\n    {\n        discard_state = true;\n    }\n    uint _28 = INDEX * 28u;\n    imageStore(_8, int(INDEX * 7u), uvec4(subgroupAdd((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 1u), uvec4(subgroupMul((gl_HelperInvocation || discard_state) ? 1u : INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 2u), uvec4(subgroupAnd((gl_HelperInvocation || discard_state) ? 4294967295u : INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 3u), uvec4(subgroupOr((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 4u), uvec4(subgroupXor((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 5u), uvec4(subgroupMin((gl_HelperInvocation || discard_state) ? 4294967295u : INDEX)));\n    imageStore(_8, int((INDEX * 7u) + 6u), uvec4(subgroupMax((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_9, int(INDEX * 7u), uvec4(subgroupAdd((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 1u), uvec4(subgroupMul((gl_HelperInvocation || discard_state) ? 1u : INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 2u), uvec4(subgroupAnd((gl_HelperInvocation || discard_state) ? 4294967295u : INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 3u), uvec4(subgroupOr((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 4u), uvec4(subgroupXor((gl_HelperInvocation || discard_state) ? 0u : INDEX)));\n    imageStore(_9, int((INDEX * 7u) + 5u), uvec4(uint(subgroupMin(int((gl_HelperInvocation || discard_state) ? 2147483647u : INDEX)))));\n    imageStore(_9, int((INDEX * 7u) + 6u), uvec4(uint(subgroupMax(int((gl_HelperInvocation || discard_state) ? 2147483648u : INDEX)))));\n    float _131 = float(INDEX);\n    imageStore(_10, int(INDEX * 7u), uvec4(uint(subgroupAdd((gl_HelperInvocation || discard_state) ? 0.0 : _131))));\n    imageStore(_10, int((INDEX * 7u) + 1u), uvec4(uint(subgroupMul((gl_HelperInvocation || discard_state) ? 1.0 : _131))));\n    imageStore(_10, int((INDEX * 7u) + 5u), uvec4(uint(subgroupMin((gl_HelperInvocation || discard_state) ? uintBitsToFloat(0x7f800000u /* inf */) : _131))));\n    imageStore(_10, int((INDEX * 7u) + 6u), uvec4(uint(subgroupMax((gl_HelperInvocation || discard_state) ? uintBitsToFloat(0xff800000u /* -inf */) : _131))));\n    discard_exit();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 213\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability GroupNonUniformArithmetic\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %168\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %21 \"discard_state\"\nOpName %205 \"discard_exit\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 NonReadable\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %10 NonReadable\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %168 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypePointer Input %5\n%12 = OpVariable %11 Input\n%17 = OpTypeBool\n%19 = OpConstant %5 40\n%20 = OpTypePointer Private %17\n%21 = OpVariable %20 Private\n%22 = OpConstantFalse %17\n%24 = OpConstant %5 3\n%26 = OpConstant %5 0\n%29 = OpConstant %5 28\n%31 = OpConstant %5 7\n%32 = OpTypeVector %5 4\n%36 = OpConstant %5 1\n%39 = OpConstant %5 4\n%45 = OpConstant %5 4294967295\n%48 = OpConstant %5 8\n%51 = OpConstant %5 2\n%57 = OpConstant %5 12\n%65 = OpConstant %5 16\n%73 = OpConstant %5 20\n%76 = OpConstant %5 5\n%82 = OpConstant %5 24\n%85 = OpConstant %5 6\n%118 = OpConstant %5 2147483647\n%125 = OpConstant %5 2147483648\n%130 = OpTypeFloat 32\n%134 = OpConstant %130 0\n%141 = OpConstant %130 1\n%149 = OpConstant %130 0x1p+128\n%157 = OpConstant %130 -0x1p+128\n%166 = OpConstantTrue %17\n%167 = OpTypePointer Input %17\n%168 = OpVariable %167 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %21 %22\nOpBranch %163\n%163 = OpLabel\n%13 = OpLoad %6 %10\n%14 = OpLoad %6 %9\n%15 = OpLoad %6 %8\n%16 = OpLoad %5 %12\n%18 = OpIEqual %17 %16 %19\nOpSelectionMerge %165 None\nOpBranchConditional %18 %164 %165\n%164 = OpLabel\nOpStore %21 %166\nOpBranch %165\n%165 = OpLabel\n%169 = OpLoad %17 %168\n%170 = OpLoad %17 %21\n%25 = OpLogicalOr %17 %169 %170\n%27 = OpSelect %5 %25 %26 %16\n%23 = OpGroupNonUniformIAdd %5 %24 Reduce %27\n%28 = OpIMul %5 %16 %29\n%30 = OpIMul %5 %16 %31\n%33 = OpCompositeConstruct %32 %23 %23 %23 %23\nOpImageWrite %15 %30 %33\n%171 = OpLoad %17 %168\n%172 = OpLoad %17 %21\n%35 = OpLogicalOr %17 %171 %172\n%37 = OpSelect %5 %35 %36 %16\n%34 = OpGroupNonUniformIMul %5 %24 Reduce %37\n%38 = OpIAdd %5 %28 %39\n%40 = OpIMul %5 %16 %31\n%41 = OpIAdd %5 %40 %36\n%42 = OpCompositeConstruct %32 %34 %34 %34 %34\nOpImageWrite %15 %41 %42\n%173 = OpLoad %17 %168\n%174 = OpLoad %17 %21\n%44 = OpLogicalOr %17 %173 %174\n%46 = OpSelect %5 %44 %45 %16\n%43 = OpGroupNonUniformBitwiseAnd %5 %24 Reduce %46\n%47 = OpIAdd %5 %28 %48\n%49 = OpIMul %5 %16 %31\n%50 = OpIAdd %5 %49 %51\n%52 = OpCompositeConstruct %32 %43 %43 %43 %43\nOpImageWrite %15 %50 %52\n%175 = OpLoad %17 %168\n%176 = OpLoad %17 %21\n%54 = OpLogicalOr %17 %175 %176\n%55 = OpSelect %5 %54 %26 %16\n%53 = OpGroupNonUniformBitwiseOr %5 %24 Reduce %55\n%56 = OpIAdd %5 %28 %57\n%58 = OpIMul %5 %16 %31\n%59 = OpIAdd %5 %58 %24\n%60 = OpCompositeConstruct %32 %53 %53 %53 %53\nOpImageWrite %15 %59 %60\n%177 = OpLoad %17 %168\n%178 = OpLoad %17 %21\n%62 = OpLogicalOr %17 %177 %178\n%63 = OpSelect %5 %62 %26 %16\n%61 = OpGroupNonUniformBitwiseXor %5 %24 Reduce %63\n%64 = OpIAdd %5 %28 %65\n%66 = OpIMul %5 %16 %31\n%67 = OpIAdd %5 %66 %39\n%68 = OpCompositeConstruct %32 %61 %61 %61 %61\nOpImageWrite %15 %67 %68\n%179 = OpLoad %17 %168\n%180 = OpLoad %17 %21\n%70 = OpLogicalOr %17 %179 %180\n%71 = OpSelect %5 %70 %45 %16\n%69 = OpGroupNonUniformUMin %5 %24 Reduce %71\n%72 = OpIAdd %5 %28 %73\n%74 = OpIMul %5 %16 %31\n%75 = OpIAdd %5 %74 %76\n%77 = OpCompositeConstruct %32 %69 %69 %69 %69\nOpImageWrite %15 %75 %77\n%181 = OpLoad %17 %168\n%182 = OpLoad %17 %21\n%79 = OpLogicalOr %17 %181 %182\n%80 = OpSelect %5 %79 %26 %16\n%78 = OpGroupNonUniformUMax %5 %24 Reduce %80\n%81 = OpIAdd %5 %28 %82\n%83 = OpIMul %5 %16 %31\n%84 = OpIAdd %5 %83 %85\n%86 = OpCompositeConstruct %32 %78 %78 %78 %78\nOpImageWrite %15 %84 %86\n%183 = OpLoad %17 %168\n%184 = OpLoad %17 %21\n%88 = OpLogicalOr %17 %183 %184\n%89 = OpSelect %5 %88 %26 %16\n%87 = OpGroupNonUniformIAdd %5 %24 Reduce %89\n%90 = OpIMul %5 %16 %31\n%91 = OpCompositeConstruct %32 %87 %87 %87 %87\nOpImageWrite %14 %90 %91\n%185 = OpLoad %17 %168\n%186 = OpLoad %17 %21\n%93 = OpLogicalOr %17 %185 %186\n%94 = OpSelect %5 %93 %36 %16\n%92 = OpGroupNonUniformIMul %5 %24 Reduce %94\n%95 = OpIMul %5 %16 %31\n%96 = OpIAdd %5 %95 %36\n%97 = OpCompositeConstruct %32 %92 %92 %92 %92\nOpImageWrite %14 %96 %97\n%187 = OpLoad %17 %168\n%188 = OpLoad %17 %21\n%99 = OpLogicalOr %17 %187 %188\n%100 = OpSelect %5 %99 %45 %16\n%98 = OpGroupNonUniformBitwiseAnd %5 %24 Reduce %100\n%101 = OpIMul %5 %16 %31\n%102 = OpIAdd %5 %101 %51\n%103 = OpCompositeConstruct %32 %98 %98 %98 %98\nOpImageWrite %14 %102 %103\n%189 = OpLoad %17 %168\n%190 = OpLoad %17 %21\n%105 = OpLogicalOr %17 %189 %190\n%106 = OpSelect %5 %105 %26 %16\n%104 = OpGroupNonUniformBitwiseOr %5 %24 Reduce %106\n%107 = OpIMul %5 %16 %31\n%108 = OpIAdd %5 %107 %24\n%109 = OpCompositeConstruct %32 %104 %104 %104 %104\nOpImageWrite %14 %108 %109\n%191 = OpLoad %17 %168\n%192 = OpLoad %17 %21\n%111 = OpLogicalOr %17 %191 %192\n%112 = OpSelect %5 %111 %26 %16\n%110 = OpGroupNonUniformBitwiseXor %5 %24 Reduce %112\n%113 = OpIMul %5 %16 %31\n%114 = OpIAdd %5 %113 %39\n%115 = OpCompositeConstruct %32 %110 %110 %110 %110\nOpImageWrite %14 %114 %115\n%193 = OpLoad %17 %168\n%194 = OpLoad %17 %21\n%117 = OpLogicalOr %17 %193 %194\n%119 = OpSelect %5 %117 %118 %16\n%116 = OpGroupNonUniformSMin %5 %24 Reduce %119\n%120 = OpIMul %5 %16 %31\n%121 = OpIAdd %5 %120 %76\n%122 = OpCompositeConstruct %32 %116 %116 %116 %116\nOpImageWrite %14 %121 %122\n%195 = OpLoad %17 %168\n%196 = OpLoad %17 %21\n%124 = OpLogicalOr %17 %195 %196\n%126 = OpSelect %5 %124 %125 %16\n%123 = OpGroupNonUniformSMax %5 %24 Reduce %126\n%127 = OpIMul %5 %16 %31\n%128 = OpIAdd %5 %127 %85\n%129 = OpCompositeConstruct %32 %123 %123 %123 %123\nOpImageWrite %14 %128 %129\n%131 = OpConvertUToF %130 %16\n%197 = OpLoad %17 %168\n%198 = OpLoad %17 %21\n%133 = OpLogicalOr %17 %197 %198\n%135 = OpSelect %130 %133 %134 %131\n%132 = OpGroupNonUniformFAdd %130 %24 Reduce %135\n%136 = OpConvertFToU %5 %132\n%137 = OpIMul %5 %16 %31\n%138 = OpCompositeConstruct %32 %136 %136 %136 %136\nOpImageWrite %13 %137 %138\n%199 = OpLoad %17 %168\n%200 = OpLoad %17 %21\n%140 = OpLogicalOr %17 %199 %200\n%142 = OpSelect %130 %140 %141 %131\n%139 = OpGroupNonUniformFMul %130 %24 Reduce %142\n%143 = OpConvertFToU %5 %139\n%144 = OpIMul %5 %16 %31\n%145 = OpIAdd %5 %144 %36\n%146 = OpCompositeConstruct %32 %143 %143 %143 %143\nOpImageWrite %13 %145 %146\n%201 = OpLoad %17 %168\n%202 = OpLoad %17 %21\n%148 = OpLogicalOr %17 %201 %202\n%150 = OpSelect %130 %148 %149 %131\n%147 = OpGroupNonUniformFMin %130 %24 Reduce %150\n%151 = OpConvertFToU %5 %147\n%152 = OpIMul %5 %16 %31\n%153 = OpIAdd %5 %152 %76\n%154 = OpCompositeConstruct %32 %151 %151 %151 %151\nOpImageWrite %13 %153 %154\n%203 = OpLoad %17 %168\n%204 = OpLoad %17 %21\n%156 = OpLogicalOr %17 %203 %204\n%158 = OpSelect %130 %156 %157 %131\n%155 = OpGroupNonUniformFMax %130 %24 Reduce %158\n%159 = OpConvertFToU %5 %155\n%160 = OpIMul %5 %16 %31\n%161 = OpIAdd %5 %160 %85\n%162 = OpCompositeConstruct %32 %159 %159 %159 %159\nOpImageWrite %13 %161 %162\n%211 = OpFunctionCall %1 %205\nOpReturn\nOpFunctionEnd\n%205 = OpFunction %1 None %2\n%206 = OpLabel\n%209 = OpLoad %17 %21\nOpSelectionMerge %208 None\nOpBranchConditional %209 %207 %208\n%207 = OpLabel\nOpKill\n%208 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/wave-size.sm66.comp",
    "content": "#version 460\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(10.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(128)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 24\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %11\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %11 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 3\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %5\n%14 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpConstant %17 10\n%20 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %22\n%22 = OpLabel\n%13 = OpAccessChain %12 %11 %14\n%15 = OpLoad %5 %13\n%16 = OpLoad %6 %8\n%19 = OpBitcast %5 %18\n%21 = OpCompositeConstruct %20 %19 %19 %19 %19\nOpImageWrite %16 %15 %21\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/world-ray-direction.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _22;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _21;\n    _21.x = gl_WorldRayDirectionEXT.x;\n    _21.y = gl_WorldRayDirectionEXT.y;\n    _21.z = gl_WorldRayDirectionEXT.z;\n    payload._m0 = _21;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %15\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn WorldRayDirectionKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %6\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Input %5\n%18 = OpTypeInt 32 0\n%19 = OpConstant %18 0\n%24 = OpConstant %18 1\n%28 = OpConstant %18 2\n%31 = OpTypePointer IncomingRayPayloadKHR %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%22 = OpUndef %6\nOpBranch %33\n%33 = OpLabel\n%17 = OpAccessChain %16 %15 %19\n%20 = OpLoad %5 %17\n%21 = OpCompositeInsert %6 %20 %22 0\n%23 = OpAccessChain %16 %15 %24\n%25 = OpLoad %5 %23\n%26 = OpCompositeInsert %6 %25 %21 1\n%27 = OpAccessChain %16 %15 %28\n%29 = OpLoad %5 %27\n%30 = OpCompositeInsert %6 %29 %26 2\n%32 = OpInBoundsAccessChain %31 %9 %19\nOpStore %32 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/world-ray-origin.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _22;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _21;\n    _21.x = gl_WorldRayOriginEXT.x;\n    _21.y = gl_WorldRayOriginEXT.y;\n    _21.z = gl_WorldRayOriginEXT.z;\n    payload._m0 = _21;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %15\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %15 BuiltIn WorldRayOriginKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer Input %6\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Input %5\n%18 = OpTypeInt 32 0\n%19 = OpConstant %18 0\n%24 = OpConstant %18 1\n%28 = OpConstant %18 2\n%31 = OpTypePointer IncomingRayPayloadKHR %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%22 = OpUndef %6\nOpBranch %33\n%33 = OpLabel\n%17 = OpAccessChain %16 %15 %19\n%20 = OpLoad %5 %17\n%21 = OpCompositeInsert %6 %20 %22 0\n%23 = OpAccessChain %16 %15 %24\n%25 = OpLoad %5 %23\n%26 = OpCompositeInsert %6 %25 %21 1\n%27 = OpAccessChain %16 %15 %28\n%29 = OpLoad %5 %27\n%30 = OpCompositeInsert %6 %29 %26 2\n%32 = OpInBoundsAccessChain %31 %9 %19\nOpStore %32 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/world-to-object-3x4.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _59;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _58;\n    _58.x = fma(gl_WorldToObjectEXT[2u].x, payload._m0.z, fma(gl_WorldToObjectEXT[1u].x, payload._m0.y, gl_WorldToObjectEXT[0u].x * payload._m0.x)) + gl_WorldToObjectEXT[3u].x;\n    _58.y = fma(gl_WorldToObjectEXT[2u].y, payload._m0.z, fma(gl_WorldToObjectEXT[1u].y, payload._m0.y, gl_WorldToObjectEXT[0u].y * payload._m0.x)) + gl_WorldToObjectEXT[3u].y;\n    _58.z = fma(gl_WorldToObjectEXT[2u].z, payload._m0.z, fma(gl_WorldToObjectEXT[1u].z, payload._m0.y, gl_WorldToObjectEXT[0u].z * payload._m0.x)) + gl_WorldToObjectEXT[3u].z;\n    payload._m0 = _58;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\n%54 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %24\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %24 BuiltIn WorldToObjectKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer IncomingRayPayloadKHR %6\n%16 = OpTypeInt 32 0\n%17 = OpConstant %16 0\n%22 = OpTypeMatrix %6 4\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %5\n%29 = OpConstant %16 1\n%32 = OpConstant %16 2\n%35 = OpConstant %16 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%59 = OpUndef %6\nOpBranch %70\n%70 = OpLabel\n%15 = OpInBoundsAccessChain %14 %9 %17\n%18 = OpLoad %6 %15\n%19 = OpCompositeExtract %5 %18 0\n%20 = OpCompositeExtract %5 %18 1\n%21 = OpCompositeExtract %5 %18 2\n%26 = OpAccessChain %25 %24 %17 %17\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %25 %24 %29 %17\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %25 %24 %32 %17\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %25 %24 %35 %17\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %25 %24 %17 %29\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %25 %24 %29 %29\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %25 %24 %32 %29\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %25 %24 %35 %29\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %25 %24 %17 %32\n%46 = OpLoad %5 %45\n%47 = OpAccessChain %25 %24 %29 %32\n%48 = OpLoad %5 %47\n%49 = OpAccessChain %25 %24 %32 %32\n%50 = OpLoad %5 %49\n%51 = OpAccessChain %25 %24 %35 %32\n%52 = OpLoad %5 %51\n%53 = OpFMul %5 %27 %19\n%55 = OpExtInst %5 %54 Fma %30 %20 %53\n%56 = OpExtInst %5 %54 Fma %33 %21 %55\n%57 = OpFAdd %5 %56 %36\n%58 = OpCompositeInsert %6 %57 %59 0\n%60 = OpFMul %5 %38 %19\n%61 = OpExtInst %5 %54 Fma %40 %20 %60\n%62 = OpExtInst %5 %54 Fma %42 %21 %61\n%63 = OpFAdd %5 %62 %44\n%64 = OpCompositeInsert %6 %63 %58 1\n%65 = OpFMul %5 %46 %19\n%66 = OpExtInst %5 %54 Fma %48 %20 %65\n%67 = OpExtInst %5 %54 Fma %50 %21 %66\n%68 = OpFAdd %5 %67 %52\n%69 = OpCompositeInsert %6 %68 %64 2\nOpStore %15 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/dxil-builtin/world-to-object-4x3.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec3 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec3 _59;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    vec3 _58;\n    _58.x = fma(payload._m0.z, gl_WorldToObjectEXT[2u].x, fma(payload._m0.y, gl_WorldToObjectEXT[1u].x, payload._m0.x * gl_WorldToObjectEXT[0u].x)) + gl_WorldToObjectEXT[3u].x;\n    _58.y = fma(payload._m0.z, gl_WorldToObjectEXT[2u].y, fma(payload._m0.y, gl_WorldToObjectEXT[1u].y, payload._m0.x * gl_WorldToObjectEXT[0u].y)) + gl_WorldToObjectEXT[3u].y;\n    _58.z = fma(payload._m0.z, gl_WorldToObjectEXT[2u].z, fma(payload._m0.y, gl_WorldToObjectEXT[1u].z, payload._m0.x * gl_WorldToObjectEXT[0u].z)) + gl_WorldToObjectEXT[3u].z;\n    payload._m0 = _58;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\n%54 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %9 %13 %16\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %16 BuiltIn WorldToObjectKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypeMatrix %6 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpTypeInt 32 0\n%20 = OpConstant %19 0\n%23 = OpConstant %19 1\n%26 = OpConstant %19 2\n%41 = OpConstant %19 3\n%47 = OpTypePointer IncomingRayPayloadKHR %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%59 = OpUndef %6\nOpBranch %70\n%70 = OpLabel\n%18 = OpAccessChain %17 %16 %20 %20\n%21 = OpLoad %5 %18\n%22 = OpAccessChain %17 %16 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %17 %16 %20 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %17 %16 %23 %20\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %17 %16 %23 %23\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %17 %16 %23 %26\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %17 %16 %26 %20\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %17 %16 %26 %23\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %17 %16 %26 %26\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %17 %16 %41 %20\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %17 %16 %41 %23\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %17 %16 %41 %26\n%46 = OpLoad %5 %45\n%48 = OpInBoundsAccessChain %47 %9 %20\n%49 = OpLoad %6 %48\n%50 = OpCompositeExtract %5 %49 0\n%51 = OpCompositeExtract %5 %49 1\n%52 = OpCompositeExtract %5 %49 2\n%53 = OpFMul %5 %50 %21\n%55 = OpExtInst %5 %54 Fma %51 %29 %53\n%56 = OpExtInst %5 %54 Fma %52 %35 %55\n%57 = OpFAdd %5 %56 %42\n%58 = OpCompositeInsert %6 %57 %59 0\n%60 = OpFMul %5 %50 %24\n%61 = OpExtInst %5 %54 Fma %51 %31 %60\n%62 = OpExtInst %5 %54 Fma %52 %37 %61\n%63 = OpFAdd %5 %62 %44\n%64 = OpCompositeInsert %6 %63 %58 1\n%65 = OpFMul %5 %50 %27\n%66 = OpExtInst %5 %54 Fma %51 %33 %65\n%67 = OpExtInst %5 %54 Fma %52 %39 %66\n%68 = OpFAdd %5 %67 %46\n%69 = OpCompositeInsert %6 %68 %64 2\nOpStore %48 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/fp16/saturate.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_spirv_intrinsics : require\n\nlayout(location = 0) in mediump vec4 V;\nlayout(location = 0) out mediump vec4 SV_Target;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);\n\nvoid main()\n{\n    SV_Target.x = float(spvNClamp(float16_t(V.x), float16_t(0.0), float16_t(1.0)));\n    SV_Target.y = float(spvNClamp(float16_t(V.y), float16_t(0.0), float16_t(1.0)));\n    SV_Target.z = float(spvNClamp(float16_t(V.z), float16_t(0.0), float16_t(1.0)));\n    SV_Target.w = float(spvNClamp(float16_t(V.w), float16_t(0.0), float16_t(1.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\n%30 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"V\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 Location 0\nOpDecorate %10 RelaxedPrecision\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%16 = OpTypeFloat 16\n%19 = OpConstant %13 1\n%23 = OpConstant %13 2\n%27 = OpConstant %13 3\n%31 = OpConstant %16 0x0p+0\n%32 = OpConstant %16 0x1p+0\n%37 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%17 = OpFConvert %16 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpFConvert %16 %20\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpFConvert %16 %24\n%26 = OpAccessChain %11 %8 %27\n%28 = OpLoad %5 %26\n%29 = OpFConvert %16 %28\n%33 = OpExtInst %16 %30 NClamp %17 %31 %32\n%34 = OpExtInst %16 %30 NClamp %21 %31 %32\n%35 = OpExtInst %16 %30 NClamp %25 %31 %32\n%36 = OpExtInst %16 %30 NClamp %29 %31 %32\n%38 = OpAccessChain %37 %10 %14\n%39 = OpFConvert %5 %33\nOpStore %38 %39\n%40 = OpAccessChain %37 %10 %19\n%41 = OpFConvert %5 %34\nOpStore %40 %41\n%42 = OpAccessChain %37 %10 %23\n%43 = OpFConvert %5 %35\nOpStore %42 %43\n%44 = OpAccessChain %37 %10 %27\n%45 = OpFConvert %5 %36\nOpStore %44 %45\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/fp16/saturate.sm60.frag",
    "content": "#version 460\n#extension GL_EXT_spirv_intrinsics : require\n\nlayout(location = 0) in mediump vec4 V;\nlayout(location = 0) out mediump vec4 SV_Target;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float spvNClamp(float, float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec2 spvNClamp(vec2, vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec3 spvNClamp(vec3, vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec4 spvNClamp(vec4, vec4, vec4);\n\nmediump float spvNClampRelaxed(mediump float a, mediump float b, mediump float c)\n{\n    mediump float res = spvNClamp(a, b, c);\n    return res;\n}\n\nmediump vec2 spvNClampRelaxed(mediump vec2 a, mediump vec2 b, mediump vec2 c)\n{\n    mediump vec2 res = spvNClamp(a, b, c);\n    return res;\n}\n\nmediump vec3 spvNClampRelaxed(mediump vec3 a, mediump vec3 b, mediump vec3 c)\n{\n    mediump vec3 res = spvNClamp(a, b, c);\n    return res;\n}\n\nmediump vec4 spvNClampRelaxed(mediump vec4 a, mediump vec4 b, mediump vec4 c)\n{\n    mediump vec4 res = spvNClamp(a, b, c);\n    return res;\n}\n\nvoid main()\n{\n    SV_Target.x = spvNClampRelaxed(V.x, 0.0, 1.0);\n    SV_Target.y = spvNClampRelaxed(V.y, 0.0, 1.0);\n    SV_Target.z = spvNClampRelaxed(V.z, 0.0, 1.0);\n    SV_Target.w = spvNClampRelaxed(V.w, 0.0, 1.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\nOpCapability Shader\n%25 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"V\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 Location 0\nOpDecorate %10 RelaxedPrecision\nOpDecorate %10 Location 0\nOpDecorate %28 RelaxedPrecision\nOpDecorate %29 RelaxedPrecision\nOpDecorate %30 RelaxedPrecision\nOpDecorate %31 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%26 = OpConstant %5 0\n%27 = OpConstant %5 1\n%32 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%28 = OpExtInst %5 %25 NClamp %15 %26 %27\n%29 = OpExtInst %5 %25 NClamp %18 %26 %27\n%30 = OpExtInst %5 %25 NClamp %21 %26 %27\n%31 = OpExtInst %5 %25 NClamp %24 %26 %27\n%33 = OpAccessChain %32 %10 %14\nOpStore %33 %28\n%34 = OpAccessChain %32 %10 %17\nOpStore %34 %29\n%35 = OpAccessChain %32 %10 %20\nOpStore %35 %30\n%36 = OpAccessChain %32 %10 %23\nOpStore %36 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/fp16/saturate.sm60.native-fp16.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_spirv_intrinsics : require\n\nlayout(location = 0) in mediump vec4 V;\nlayout(location = 0) out mediump vec4 SV_Target;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);\n\nvoid main()\n{\n    SV_Target.x = float(spvNClamp(float16_t(V.x), float16_t(0.0), float16_t(1.0)));\n    SV_Target.y = float(spvNClamp(float16_t(V.y), float16_t(0.0), float16_t(1.0)));\n    SV_Target.z = float(spvNClamp(float16_t(V.z), float16_t(0.0), float16_t(1.0)));\n    SV_Target.w = float(spvNClamp(float16_t(V.w), float16_t(0.0), float16_t(1.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\n%30 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"V\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 Location 0\nOpDecorate %10 RelaxedPrecision\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%16 = OpTypeFloat 16\n%19 = OpConstant %13 1\n%23 = OpConstant %13 2\n%27 = OpConstant %13 3\n%31 = OpConstant %16 0x0p+0\n%32 = OpConstant %16 0x1p+0\n%37 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%17 = OpFConvert %16 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpFConvert %16 %20\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpFConvert %16 %24\n%26 = OpAccessChain %11 %8 %27\n%28 = OpLoad %5 %26\n%29 = OpFConvert %16 %28\n%33 = OpExtInst %16 %30 NClamp %17 %31 %32\n%34 = OpExtInst %16 %30 NClamp %21 %31 %32\n%35 = OpExtInst %16 %30 NClamp %25 %31 %32\n%36 = OpExtInst %16 %30 NClamp %29 %31 %32\n%38 = OpAccessChain %37 %10 %14\n%39 = OpFConvert %5 %33\nOpStore %38 %39\n%40 = OpAccessChain %37 %10 %19\n%41 = OpFConvert %5 %34\nOpStore %40 %41\n%42 = OpAccessChain %37 %10 %23\n%43 = OpFConvert %5 %35\nOpStore %42 %43\n%44 = OpAccessChain %37 %10 %27\n%45 = OpFConvert %5 %36\nOpStore %44 %45\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/heap-robustness/misc.bindless.heap-raw-va-cbv.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer DescriptorHeapRawBlock;\nlayout(buffer_reference) buffer uintPointer;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) readonly buffer DescriptorHeapRawBlock\n{\n    DescriptorHeapRawPayload descriptors[];\n};\n\nlayout(set = 10, binding = 21, std140) uniform DescriptorHeapRawPayloadPtr\n{\n    DescriptorHeapRawBlock ptr;\n} DescriptorHeapRaw;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _41[];\n\nlayout(set = 0, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _48[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _56_59\n{\n    uvec4 _m0[];\n} _59[];\n\nlayout(set = 5, binding = 0, std140) uniform _61_64\n{\n    vec4 _m0[4096];\n} _64[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 0, binding = 0) uniform sampler _17[];\nlayout(set = 0, binding = 0) uniform writeonly image2D _21[];\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _25[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _51[];\nlayout(set = 4, binding = 0) uniform writeonly imageBuffer _54[];\nlayout(set = 2, binding = 0) uniform sampler _67[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _208, uint _209, uint _210)\n{\n    uint _224;\n    if (any(notEqual(_208, uvec2(0u))))\n    {\n        uint _222 = atomicAdd(uintPointer(_208).value, _209);\n        _224 = _222 + _210;\n    }\n    else\n    {\n        _224 = 0u;\n    }\n    return _224;\n}\n\nvoid main()\n{\n    uint _75 = gl_GlobalInvocationID.x + 0u;\n    uint _83 = gl_GlobalInvocationID.x + 0u;\n    vec4 _95 = textureLod(nonuniformEXT(sampler2D(_13[registers._m0 + _75], _67[registers._m2 + _83])), vec2(0.5), 0.0);\n    _59[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_95.x), floatBitsToUint(_95.y), floatBitsToUint(_95.z), floatBitsToUint(_95.w));\n    barrier();\n    imageStore(_51[nonuniformEXT(registers._m3 + (gl_GlobalInvocationID.x + 0u))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[registers._m0 + _75], _67[registers._m2 + _83])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_54[nonuniformEXT(registers._m4 + (gl_GlobalInvocationID.x + 0u))], int(gl_GlobalInvocationID.x), vec4(_64[nonuniformEXT(registers._m5 + (gl_GlobalInvocationID.x + 0u))]._m0[0u]));\n    barrier();\n    vec4 _177 = textureLod(nonuniformEXT(sampler2D(_13[registers._m0 + _75], _67[registers._m2 + _83])), vec2(0.5), 0.0);\n    uint _183 = gl_GlobalInvocationID.x + 0u;\n    _59[nonuniformEXT(registers._m4 + _183)]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_177.x), floatBitsToUint(_177.y), floatBitsToUint(_177.z), floatBitsToUint(_177.w));\n    barrier();\n    uint _226 = RobustPhysicalAtomicCounter(DescriptorHeapRaw.ptr.descriptors[registers._m4 + _183]._m0[0u], 1u, 0u);\n    barrier();\n    uint _240 = gl_GlobalInvocationID.x + 400u;\n    vec4 _253 = textureLod(nonuniformEXT(sampler2D(_13[gl_GlobalInvocationID.x], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _59[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_253.x), floatBitsToUint(_253.y), floatBitsToUint(_253.z), floatBitsToUint(_253.w));\n    barrier();\n    imageStore(_21[nonuniformEXT(gl_GlobalInvocationID.x + 200u)], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[gl_GlobalInvocationID.x], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_25[nonuniformEXT(gl_GlobalInvocationID.x + 300u)], int(gl_GlobalInvocationID.x), vec4(_48[nonuniformEXT(gl_GlobalInvocationID.x + 500u)]._m0[0u]));\n    barrier();\n    vec4 _284 = textureLod(nonuniformEXT(sampler2D(_13[gl_GlobalInvocationID.x], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _41[nonuniformEXT(_240)]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_284.x), floatBitsToUint(_284.y), floatBitsToUint(_284.z), floatBitsToUint(_284.w));\n    barrier();\n    uint _296 = RobustPhysicalAtomicCounter(DescriptorHeapRaw.ptr.descriptors[_240]._m0[0u], 1u, 0u);\n    barrier();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 299\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %70\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %29 \"DescriptorHeapRawPayload\"\nOpName %31 \"DescriptorHeapRawBlock\"\nOpMemberName %31 0 \"descriptors\"\nOpName %33 \"DescriptorHeapRawPayloadPtr\"\nOpMemberName %33 0 \"ptr\"\nOpName %35 \"DescriptorHeapRaw\"\nOpName %38 \"SSBO\"\nOpName %45 \"BindlessCBV\"\nOpName %56 \"SSBO\"\nOpName %61 \"BindlessCBV\"\nOpName %211 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonReadable\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %28 ArrayStride 8\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %30 ArrayStride 8\nOpDecorate %31 Block\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 0 NonWritable\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %35 DescriptorSet 10\nOpDecorate %35 Binding 21\nOpDecorate %37 ArrayStride 16\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpDecorate %41 DescriptorSet 0\nOpDecorate %41 Binding 0\nOpDecorate %44 ArrayStride 16\nOpDecorate %45 Block\nOpMemberDecorate %45 0 Offset 0\nOpDecorate %48 DescriptorSet 0\nOpDecorate %48 Binding 0\nOpDecorate %51 DescriptorSet 3\nOpDecorate %51 Binding 0\nOpDecorate %51 NonReadable\nOpDecorate %54 DescriptorSet 4\nOpDecorate %54 Binding 0\nOpDecorate %54 NonReadable\nOpDecorate %55 ArrayStride 16\nOpMemberDecorate %56 0 Offset 0\nOpDecorate %56 Block\nOpDecorate %59 DescriptorSet 4\nOpDecorate %59 Binding 0\nOpDecorate %59 NonReadable\nOpDecorate %60 ArrayStride 16\nOpDecorate %61 Block\nOpMemberDecorate %61 0 Offset 0\nOpDecorate %64 DescriptorSet 5\nOpDecorate %64 Binding 0\nOpDecorate %67 DescriptorSet 2\nOpDecorate %67 Binding 0\nOpDecorate %70 BuiltIn GlobalInvocationId\nOpDecorate %81 NonUniform\nOpDecorate %82 NonUniform\nOpDecorate %89 NonUniform\nOpDecorate %90 NonUniform\nOpDecorate %92 NonUniform\nOpDecorate %120 NonUniform\nOpDecorate %121 NonUniform\nOpDecorate %125 NonUniform\nOpDecorate %126 NonUniform\nOpDecorate %127 NonUniform\nOpDecorate %140 NonUniform\nOpDecorate %141 NonUniform\nOpDecorate %150 NonUniform\nOpDecorate %146 NonUniform\nOpDecorate %152 NonUniform\nOpDecorate %163 NonUniform\nOpDecorate %164 NonUniform\nOpDecorate %169 NonUniform\nOpDecorate %170 NonUniform\nOpDecorate %174 NonUniform\nOpDecorate %175 NonUniform\nOpDecorate %176 NonUniform\nOpDecorate %187 NonUniform\nOpDecorate %184 NonUniform\nOpDecorate %193 NonUniform\nOpDecorate %197 NonUniform\nOpDecorate %194 NonUniform\nOpDecorate %74 NonUniform\nOpDecorate %228 NonUniform\nOpDecorate %229 NonUniform\nOpDecorate %231 NonUniform\nOpDecorate %232 NonUniform\nOpDecorate %235 NonUniform\nOpDecorate %236 NonUniform\nOpDecorate %239 NonUniform\nOpDecorate %240 NonUniform\nOpDecorate %243 NonUniform\nOpDecorate %248 NonUniform\nOpDecorate %251 NonUniform\nOpDecorate %252 NonUniform\nOpDecorate %277 NonUniform\nOpDecorate %295 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %5 2\n%27 = OpConstant %5 1\n%28 = OpTypeArray %26 %27\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypeStruct %30\n%32 = OpTypePointer PhysicalStorageBuffer %31\n%33 = OpTypeStruct %32\n%34 = OpTypePointer Uniform %33\n%35 = OpVariable %34 Uniform\n%36 = OpTypeVector %5 4\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypeStruct %37\n%39 = OpTypeRuntimeArray %38\n%40 = OpTypePointer StorageBuffer %39\n%41 = OpVariable %40 StorageBuffer\n%42 = OpTypeVector %9 4\n%43 = OpConstant %5 4096\n%44 = OpTypeArray %42 %43\n%45 = OpTypeStruct %44\n%46 = OpTypeRuntimeArray %45\n%47 = OpTypePointer Uniform %46\n%48 = OpVariable %47 Uniform\n%49 = OpTypeRuntimeArray %18\n%50 = OpTypePointer UniformConstant %49\n%51 = OpVariable %50 UniformConstant\n%52 = OpTypeRuntimeArray %22\n%53 = OpTypePointer UniformConstant %52\n%54 = OpVariable %53 UniformConstant\n%55 = OpTypeRuntimeArray %36\n%56 = OpTypeStruct %55\n%57 = OpTypeRuntimeArray %56\n%58 = OpTypePointer StorageBuffer %57\n%59 = OpVariable %58 StorageBuffer\n%60 = OpTypeArray %42 %43\n%61 = OpTypeStruct %60\n%62 = OpTypeRuntimeArray %61\n%63 = OpTypePointer Uniform %62\n%64 = OpVariable %63 Uniform\n%65 = OpTypeRuntimeArray %14\n%66 = OpTypePointer UniformConstant %65\n%67 = OpVariable %66 UniformConstant\n%68 = OpTypeVector %5 3\n%69 = OpTypePointer Input %68\n%70 = OpVariable %69 Input\n%71 = OpTypePointer Input %5\n%73 = OpConstant %5 0\n%76 = OpTypePointer UniformConstant %10\n%78 = OpTypePointer PushConstant %5\n%84 = OpTypePointer UniformConstant %14\n%87 = OpConstant %5 2\n%91 = OpTypeSampledImage %10\n%93 = OpConstant %9 0.5\n%94 = OpConstant %9 0\n%96 = OpTypeVector %9 2\n%102 = OpTypePointer StorageBuffer %56\n%105 = OpConstant %5 4\n%108 = OpConstant %5 100\n%114 = OpTypePointer StorageBuffer %36\n%116 = OpConstant %5 264\n%135 = OpTypePointer UniformConstant %18\n%138 = OpConstant %5 3\n%145 = OpTypePointer Uniform %61\n%148 = OpConstant %5 5\n%151 = OpTypePointer Uniform %42\n%159 = OpTypePointer UniformConstant %22\n%198 = OpTypePointer Uniform %32\n%201 = OpTypePointer PhysicalStorageBuffer %26\n%207 = OpTypeFunction %5 %26 %5 %5\n%215 = OpTypeBool\n%216 = OpTypeVector %215 2\n%217 = OpConstantNull %26\n%220 = OpTypePointer PhysicalStorageBuffer %5\n%233 = OpConstant %5 200\n%237 = OpConstant %5 300\n%241 = OpConstant %5 400\n%242 = OpTypePointer StorageBuffer %38\n%249 = OpConstant %5 500\n%250 = OpTypePointer Uniform %45\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %297\n%297 = OpLabel\n%72 = OpAccessChain %71 %70 %73\n%74 = OpLoad %5 %72\n%75 = OpIAdd %5 %74 %73\n%79 = OpAccessChain %78 %8 %73\n%80 = OpLoad %5 %79\n%81 = OpIAdd %5 %80 %75\n%77 = OpAccessChain %76 %13 %81\n%82 = OpLoad %10 %77\n%83 = OpIAdd %5 %74 %73\n%86 = OpAccessChain %78 %8 %87\n%88 = OpLoad %5 %86\n%89 = OpIAdd %5 %88 %83\n%85 = OpAccessChain %84 %67 %89\n%90 = OpLoad %14 %85\n%92 = OpSampledImage %91 %82 %90\n%97 = OpCompositeConstruct %96 %93 %93\n%95 = OpImageSampleExplicitLod %42 %92 %97 Lod %94\n%98 = OpCompositeExtract %9 %95 0\n%99 = OpCompositeExtract %9 %95 1\n%100 = OpCompositeExtract %9 %95 2\n%101 = OpCompositeExtract %9 %95 3\n%104 = OpAccessChain %78 %8 %105\n%106 = OpLoad %5 %104\n%107 = OpIAdd %5 %106 %108\n%103 = OpAccessChain %102 %59 %107\n%109 = OpBitcast %5 %98\n%110 = OpBitcast %5 %99\n%111 = OpBitcast %5 %100\n%112 = OpBitcast %5 %101\n%113 = OpCompositeConstruct %36 %109 %110 %111 %112\n%115 = OpAccessChain %114 %103 %73 %74\nOpStore %115 %113\nOpControlBarrier %87 %87 %116\n%118 = OpAccessChain %78 %8 %73\n%119 = OpLoad %5 %118\n%120 = OpIAdd %5 %119 %75\n%117 = OpAccessChain %76 %13 %120\n%121 = OpLoad %10 %117\n%123 = OpAccessChain %78 %8 %87\n%124 = OpLoad %5 %123\n%125 = OpIAdd %5 %124 %83\n%122 = OpAccessChain %84 %67 %125\n%126 = OpLoad %14 %122\n%127 = OpSampledImage %91 %121 %126\n%129 = OpCompositeConstruct %96 %93 %93\n%128 = OpImageSampleExplicitLod %42 %127 %129 Lod %94\n%130 = OpCompositeExtract %9 %128 0\n%131 = OpCompositeExtract %9 %128 1\n%132 = OpCompositeExtract %9 %128 2\n%133 = OpCompositeExtract %9 %128 3\n%134 = OpIAdd %5 %74 %73\n%137 = OpAccessChain %78 %8 %138\n%139 = OpLoad %5 %137\n%140 = OpIAdd %5 %139 %134\n%136 = OpAccessChain %135 %51 %140\n%141 = OpLoad %18 %136\n%142 = OpCompositeConstruct %26 %74 %73\n%143 = OpCompositeConstruct %42 %130 %131 %132 %133\nOpImageWrite %141 %142 %143\nOpControlBarrier %87 %87 %116\n%144 = OpIAdd %5 %74 %73\n%147 = OpAccessChain %78 %8 %148\n%149 = OpLoad %5 %147\n%150 = OpIAdd %5 %149 %144\n%146 = OpAccessChain %145 %64 %150\n%152 = OpAccessChain %151 %146 %73 %73\n%153 = OpLoad %42 %152\n%154 = OpCompositeExtract %9 %153 0\n%155 = OpCompositeExtract %9 %153 1\n%156 = OpCompositeExtract %9 %153 2\n%157 = OpCompositeExtract %9 %153 3\n%158 = OpIAdd %5 %74 %73\n%161 = OpAccessChain %78 %8 %105\n%162 = OpLoad %5 %161\n%163 = OpIAdd %5 %162 %158\n%160 = OpAccessChain %159 %54 %163\n%164 = OpLoad %22 %160\n%165 = OpCompositeConstruct %42 %154 %155 %156 %157\nOpImageWrite %164 %74 %165\nOpControlBarrier %87 %87 %116\n%167 = OpAccessChain %78 %8 %73\n%168 = OpLoad %5 %167\n%169 = OpIAdd %5 %168 %75\n%166 = OpAccessChain %76 %13 %169\n%170 = OpLoad %10 %166\n%172 = OpAccessChain %78 %8 %87\n%173 = OpLoad %5 %172\n%174 = OpIAdd %5 %173 %83\n%171 = OpAccessChain %84 %67 %174\n%175 = OpLoad %14 %171\n%176 = OpSampledImage %91 %170 %175\n%178 = OpCompositeConstruct %96 %93 %93\n%177 = OpImageSampleExplicitLod %42 %176 %178 Lod %94\n%179 = OpCompositeExtract %9 %177 0\n%180 = OpCompositeExtract %9 %177 1\n%181 = OpCompositeExtract %9 %177 2\n%182 = OpCompositeExtract %9 %177 3\n%183 = OpIAdd %5 %74 %73\n%185 = OpAccessChain %78 %8 %105\n%186 = OpLoad %5 %185\n%187 = OpIAdd %5 %186 %183\n%184 = OpAccessChain %102 %59 %187\n%188 = OpBitcast %5 %179\n%189 = OpBitcast %5 %180\n%190 = OpBitcast %5 %181\n%191 = OpBitcast %5 %182\n%192 = OpCompositeConstruct %36 %188 %189 %190 %191\n%193 = OpAccessChain %114 %184 %73 %74\nOpStore %193 %192\nOpControlBarrier %87 %87 %116\n%195 = OpAccessChain %78 %8 %105\n%196 = OpLoad %5 %195\n%197 = OpIAdd %5 %196 %183\n%194 = OpAccessChain %102 %59 %197\n%199 = OpAccessChain %198 %35 %73\n%200 = OpLoad %32 %199\n%203 = OpAccessChain %78 %8 %105\n%204 = OpLoad %5 %203\n%205 = OpIAdd %5 %204 %183\n%202 = OpInBoundsAccessChain %201 %200 %73 %205 %73 %73\n%206 = OpLoad %26 %202 Aligned 8\n%226 = OpFunctionCall %5 %211 %206 %27 %73\nOpControlBarrier %87 %87 %116\n%227 = OpAccessChain %76 %13 %74\n%228 = OpLoad %10 %227\n%229 = OpIAdd %5 %74 %108\n%230 = OpAccessChain %84 %17 %229\n%231 = OpLoad %14 %230\n%232 = OpIAdd %5 %74 %233\n%234 = OpAccessChain %135 %21 %232\n%235 = OpLoad %18 %234\n%236 = OpIAdd %5 %74 %237\n%238 = OpAccessChain %159 %25 %236\n%239 = OpLoad %22 %238\n%240 = OpIAdd %5 %74 %241\n%243 = OpAccessChain %242 %41 %240\n%244 = OpAccessChain %198 %35 %73\n%245 = OpLoad %32 %244\n%246 = OpInBoundsAccessChain %201 %245 %73 %240 %73 %73\n%247 = OpLoad %26 %246 Aligned 8\n%248 = OpIAdd %5 %74 %249\n%251 = OpAccessChain %250 %48 %248\n%252 = OpSampledImage %91 %228 %231\n%254 = OpCompositeConstruct %96 %93 %93\n%253 = OpImageSampleExplicitLod %42 %252 %254 Lod %94\n%255 = OpCompositeExtract %9 %253 0\n%256 = OpCompositeExtract %9 %253 1\n%257 = OpCompositeExtract %9 %253 2\n%258 = OpCompositeExtract %9 %253 3\n%260 = OpAccessChain %78 %8 %105\n%261 = OpLoad %5 %260\n%262 = OpIAdd %5 %261 %108\n%259 = OpAccessChain %102 %59 %262\n%263 = OpBitcast %5 %255\n%264 = OpBitcast %5 %256\n%265 = OpBitcast %5 %257\n%266 = OpBitcast %5 %258\n%267 = OpCompositeConstruct %36 %263 %264 %265 %266\n%268 = OpAccessChain %114 %259 %73 %74\nOpStore %268 %267\nOpControlBarrier %87 %87 %116\n%270 = OpCompositeConstruct %96 %93 %93\n%269 = OpImageSampleExplicitLod %42 %252 %270 Lod %94\n%271 = OpCompositeExtract %9 %269 0\n%272 = OpCompositeExtract %9 %269 1\n%273 = OpCompositeExtract %9 %269 2\n%274 = OpCompositeExtract %9 %269 3\n%275 = OpCompositeConstruct %26 %74 %73\n%276 = OpCompositeConstruct %42 %271 %272 %273 %274\nOpImageWrite %235 %275 %276\nOpControlBarrier %87 %87 %116\n%277 = OpAccessChain %151 %251 %73 %73\n%278 = OpLoad %42 %277\n%279 = OpCompositeExtract %9 %278 0\n%280 = OpCompositeExtract %9 %278 1\n%281 = OpCompositeExtract %9 %278 2\n%282 = OpCompositeExtract %9 %278 3\n%283 = OpCompositeConstruct %42 %279 %280 %281 %282\nOpImageWrite %239 %74 %283\nOpControlBarrier %87 %87 %116\n%285 = OpCompositeConstruct %96 %93 %93\n%284 = OpImageSampleExplicitLod %42 %252 %285 Lod %94\n%286 = OpCompositeExtract %9 %284 0\n%287 = OpCompositeExtract %9 %284 1\n%288 = OpCompositeExtract %9 %284 2\n%289 = OpCompositeExtract %9 %284 3\n%290 = OpBitcast %5 %286\n%291 = OpBitcast %5 %287\n%292 = OpBitcast %5 %288\n%293 = OpBitcast %5 %289\n%294 = OpCompositeConstruct %36 %290 %291 %292 %293\n%295 = OpAccessChain %114 %243 %73 %74\nOpStore %295 %294\nOpControlBarrier %87 %87 %116\n%296 = OpFunctionCall %5 %211 %247 %27 %73\nOpControlBarrier %87 %87 %116\nOpReturn\nOpFunctionEnd\n%211 = OpFunction %5 None %207\n%208 = OpFunctionParameter %26\n%209 = OpFunctionParameter %5\n%210 = OpFunctionParameter %5\n%212 = OpLabel\n%218 = OpINotEqual %216 %208 %217\n%219 = OpAny %215 %218\nOpSelectionMerge %214 None\nOpBranchConditional %219 %213 %214\n%213 = OpLabel\n%221 = OpBitcast %220 %208\n%222 = OpAtomicIAdd %5 %221 %27 %73 %209\n%223 = OpIAdd %5 %222 %210\nOpBranch %214\n%214 = OpLabel\n%224 = OpPhi %5 %73 %212 %223 %213\nOpReturnValue %224\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/heap-robustness/misc.bindless.heap-robustness.heap-robustness-cbv.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _30;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _36[];\n\nlayout(set = 0, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _43[];\n\nlayout(set = 10, binding = 20, std140) uniform DescriptorHeapSizeUBO\n{\n    uint count;\n} DescriptorHeapSize;\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _54_57\n{\n    uvec4 _m0[];\n} _57[];\n\nlayout(set = 5, binding = 0, std140) uniform _59_62\n{\n    vec4 _m0[4096];\n} _62[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 0, binding = 0) uniform sampler _17[];\nlayout(set = 0, binding = 0) uniform writeonly image2D _21[];\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _25[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _49[];\nlayout(set = 4, binding = 0) uniform writeonly imageBuffer _52[];\nlayout(set = 2, binding = 0) uniform sampler _65[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _232, uint _233, uint _234)\n{\n    uint _249;\n    if (any(notEqual(_232, uvec2(0u))))\n    {\n        uint _246 = atomicAdd(uintPointer(_232).value, _233);\n        _249 = _246 + _234;\n    }\n    else\n    {\n        _249 = 0u;\n    }\n    return _249;\n}\n\nvoid main()\n{\n    uint _73 = gl_GlobalInvocationID.x + 0u;\n    uint _86 = gl_GlobalInvocationID.x + 0u;\n    vec4 _98 = textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _73), DescriptorHeapSize.count)], _65[registers._m2 + _86])), vec2(0.5), 0.0);\n    _57[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_98.x), floatBitsToUint(_98.y), floatBitsToUint(_98.z), floatBitsToUint(_98.w));\n    barrier();\n    imageStore(_49[nonuniformEXT(min((registers._m3 + (gl_GlobalInvocationID.x + 0u)), DescriptorHeapSize.count))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _73), DescriptorHeapSize.count)], _65[registers._m2 + _86])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_52[nonuniformEXT(min((registers._m4 + (gl_GlobalInvocationID.x + 0u)), DescriptorHeapSize.count))], int(gl_GlobalInvocationID.x), vec4(_62[nonuniformEXT(min((registers._m5 + (gl_GlobalInvocationID.x + 0u)), DescriptorHeapSize.count))]._m0[0u]));\n    barrier();\n    vec4 _195 = textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _73), DescriptorHeapSize.count)], _65[registers._m2 + _86])), vec2(0.5), 0.0);\n    uint _201 = gl_GlobalInvocationID.x + 0u;\n    _57[nonuniformEXT(min((registers._m4 + _201), DescriptorHeapSize.count))]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_195.x), floatBitsToUint(_195.y), floatBitsToUint(_195.z), floatBitsToUint(_195.w));\n    barrier();\n    uvec2 _230 = _30.counters[min((registers._m4 + _201), DescriptorHeapSize.count)];\n    uint _251 = RobustPhysicalAtomicCounter(_230, 1u, 0u);\n    barrier();\n    uint _274 = gl_GlobalInvocationID.x + 400u;\n    uvec2 _285 = _30.counters[min(_274, DescriptorHeapSize.count)];\n    vec4 _294 = textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, DescriptorHeapSize.count)], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _57[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_294.x), floatBitsToUint(_294.y), floatBitsToUint(_294.z), floatBitsToUint(_294.w));\n    barrier();\n    imageStore(_21[nonuniformEXT(min((gl_GlobalInvocationID.x + 200u), DescriptorHeapSize.count))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, DescriptorHeapSize.count)], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_25[nonuniformEXT(min((gl_GlobalInvocationID.x + 300u), DescriptorHeapSize.count))], int(gl_GlobalInvocationID.x), vec4(_43[nonuniformEXT(min((gl_GlobalInvocationID.x + 500u), DescriptorHeapSize.count))]._m0[0u]));\n    barrier();\n    vec4 _325 = textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, DescriptorHeapSize.count)], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _36[nonuniformEXT(min(_274, DescriptorHeapSize.count))]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_325.x), floatBitsToUint(_325.y), floatBitsToUint(_325.z), floatBitsToUint(_325.w));\n    barrier();\n    uint _337 = RobustPhysicalAtomicCounter(_285, 1u, 0u);\n    barrier();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 340\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%83 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %68\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %28 \"AtomicCounters\"\nOpMemberName %28 0 \"counters\"\nOpName %33 \"SSBO\"\nOpName %40 \"BindlessCBV\"\nOpName %44 \"DescriptorHeapSizeUBO\"\nOpMemberName %44 0 \"count\"\nOpName %46 \"DescriptorHeapSize\"\nOpName %54 \"SSBO\"\nOpName %59 \"BindlessCBV\"\nOpName %235 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonReadable\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %27 ArrayStride 8\nOpDecorate %28 Block\nOpMemberDecorate %28 0 Offset 0\nOpMemberDecorate %28 0 NonWritable\nOpDecorate %30 DescriptorSet 7\nOpDecorate %30 Binding 0\nOpDecorate %30 AliasedPointer\nOpDecorate %32 ArrayStride 16\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %36 DescriptorSet 0\nOpDecorate %36 Binding 0\nOpDecorate %39 ArrayStride 16\nOpDecorate %40 Block\nOpMemberDecorate %40 0 Offset 0\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 0\nOpDecorate %44 Block\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %46 DescriptorSet 10\nOpDecorate %46 Binding 20\nOpDecorate %49 DescriptorSet 3\nOpDecorate %49 Binding 0\nOpDecorate %49 NonReadable\nOpDecorate %52 DescriptorSet 4\nOpDecorate %52 Binding 0\nOpDecorate %52 NonReadable\nOpDecorate %53 ArrayStride 16\nOpMemberDecorate %54 0 Offset 0\nOpDecorate %54 Block\nOpDecorate %57 DescriptorSet 4\nOpDecorate %57 Binding 0\nOpDecorate %57 NonReadable\nOpDecorate %58 ArrayStride 16\nOpDecorate %59 Block\nOpMemberDecorate %59 0 Offset 0\nOpDecorate %62 DescriptorSet 5\nOpDecorate %62 Binding 0\nOpDecorate %65 DescriptorSet 2\nOpDecorate %65 Binding 0\nOpDecorate %68 BuiltIn GlobalInvocationId\nOpDecorate %84 NonUniform\nOpDecorate %85 NonUniform\nOpDecorate %92 NonUniform\nOpDecorate %93 NonUniform\nOpDecorate %95 NonUniform\nOpDecorate %126 NonUniform\nOpDecorate %127 NonUniform\nOpDecorate %131 NonUniform\nOpDecorate %132 NonUniform\nOpDecorate %133 NonUniform\nOpDecorate %149 NonUniform\nOpDecorate %150 NonUniform\nOpDecorate %162 NonUniform\nOpDecorate %155 NonUniform\nOpDecorate %164 NonUniform\nOpDecorate %178 NonUniform\nOpDecorate %179 NonUniform\nOpDecorate %187 NonUniform\nOpDecorate %188 NonUniform\nOpDecorate %192 NonUniform\nOpDecorate %193 NonUniform\nOpDecorate %194 NonUniform\nOpDecorate %208 NonUniform\nOpDecorate %202 NonUniform\nOpDecorate %214 NonUniform\nOpDecorate %221 NonUniform\nOpDecorate %215 NonUniform\nOpDecorate %255 NonUniform\nOpDecorate %256 NonUniform\nOpDecorate %257 NonUniform\nOpDecorate %259 NonUniform\nOpDecorate %265 NonUniform\nOpDecorate %266 NonUniform\nOpDecorate %272 NonUniform\nOpDecorate %273 NonUniform\nOpDecorate %280 NonUniform\nOpDecorate %277 NonUniform\nOpDecorate %292 NonUniform\nOpDecorate %289 NonUniform\nOpDecorate %293 NonUniform\nOpDecorate %318 NonUniform\nOpDecorate %336 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %5 2\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypeStruct %27\n%29 = OpTypePointer StorageBuffer %28\n%30 = OpVariable %29 StorageBuffer\n%31 = OpTypeVector %5 4\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypeStruct %32\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypePointer StorageBuffer %34\n%36 = OpVariable %35 StorageBuffer\n%37 = OpTypeVector %9 4\n%38 = OpConstant %5 4096\n%39 = OpTypeArray %37 %38\n%40 = OpTypeStruct %39\n%41 = OpTypeRuntimeArray %40\n%42 = OpTypePointer Uniform %41\n%43 = OpVariable %42 Uniform\n%44 = OpTypeStruct %5\n%45 = OpTypePointer Uniform %44\n%46 = OpVariable %45 Uniform\n%47 = OpTypeRuntimeArray %18\n%48 = OpTypePointer UniformConstant %47\n%49 = OpVariable %48 UniformConstant\n%50 = OpTypeRuntimeArray %22\n%51 = OpTypePointer UniformConstant %50\n%52 = OpVariable %51 UniformConstant\n%53 = OpTypeRuntimeArray %31\n%54 = OpTypeStruct %53\n%55 = OpTypeRuntimeArray %54\n%56 = OpTypePointer StorageBuffer %55\n%57 = OpVariable %56 StorageBuffer\n%58 = OpTypeArray %37 %38\n%59 = OpTypeStruct %58\n%60 = OpTypeRuntimeArray %59\n%61 = OpTypePointer Uniform %60\n%62 = OpVariable %61 Uniform\n%63 = OpTypeRuntimeArray %14\n%64 = OpTypePointer UniformConstant %63\n%65 = OpVariable %64 UniformConstant\n%66 = OpTypeVector %5 3\n%67 = OpTypePointer Input %66\n%68 = OpVariable %67 Input\n%69 = OpTypePointer Input %5\n%71 = OpConstant %5 0\n%74 = OpTypePointer UniformConstant %10\n%76 = OpTypePointer PushConstant %5\n%80 = OpTypePointer Uniform %5\n%87 = OpTypePointer UniformConstant %14\n%90 = OpConstant %5 2\n%94 = OpTypeSampledImage %10\n%96 = OpConstant %9 0.5\n%97 = OpConstant %9 0\n%99 = OpTypeVector %9 2\n%105 = OpTypePointer StorageBuffer %54\n%108 = OpConstant %5 4\n%111 = OpConstant %5 100\n%117 = OpTypePointer StorageBuffer %31\n%119 = OpConstant %5 264\n%141 = OpTypePointer UniformConstant %18\n%144 = OpConstant %5 3\n%154 = OpTypePointer Uniform %59\n%157 = OpConstant %5 5\n%163 = OpTypePointer Uniform %37\n%171 = OpTypePointer UniformConstant %22\n%222 = OpTypePointer StorageBuffer %26\n%231 = OpTypeFunction %5 %26 %5 %5\n%239 = OpTypeBool\n%240 = OpTypeVector %239 2\n%241 = OpConstantNull %26\n%244 = OpTypePointer PhysicalStorageBuffer %5\n%247 = OpConstant %5 1\n%261 = OpConstant %5 200\n%268 = OpConstant %5 300\n%275 = OpConstant %5 400\n%276 = OpTypePointer StorageBuffer %33\n%287 = OpConstant %5 500\n%288 = OpTypePointer Uniform %40\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %338\n%338 = OpLabel\n%70 = OpAccessChain %69 %68 %71\n%72 = OpLoad %5 %70\n%73 = OpIAdd %5 %72 %71\n%77 = OpAccessChain %76 %8 %71\n%78 = OpLoad %5 %77\n%79 = OpIAdd %5 %78 %73\n%81 = OpAccessChain %80 %46 %71\n%82 = OpLoad %5 %81\n%84 = OpExtInst %5 %83 UMin %79 %82\n%75 = OpAccessChain %74 %13 %84\n%85 = OpLoad %10 %75\n%86 = OpIAdd %5 %72 %71\n%89 = OpAccessChain %76 %8 %90\n%91 = OpLoad %5 %89\n%92 = OpIAdd %5 %91 %86\n%88 = OpAccessChain %87 %65 %92\n%93 = OpLoad %14 %88\n%95 = OpSampledImage %94 %85 %93\n%100 = OpCompositeConstruct %99 %96 %96\n%98 = OpImageSampleExplicitLod %37 %95 %100 Lod %97\n%101 = OpCompositeExtract %9 %98 0\n%102 = OpCompositeExtract %9 %98 1\n%103 = OpCompositeExtract %9 %98 2\n%104 = OpCompositeExtract %9 %98 3\n%107 = OpAccessChain %76 %8 %108\n%109 = OpLoad %5 %107\n%110 = OpIAdd %5 %109 %111\n%106 = OpAccessChain %105 %57 %110\n%112 = OpBitcast %5 %101\n%113 = OpBitcast %5 %102\n%114 = OpBitcast %5 %103\n%115 = OpBitcast %5 %104\n%116 = OpCompositeConstruct %31 %112 %113 %114 %115\n%118 = OpAccessChain %117 %106 %71 %72\nOpStore %118 %116\nOpControlBarrier %90 %90 %119\n%121 = OpAccessChain %76 %8 %71\n%122 = OpLoad %5 %121\n%123 = OpIAdd %5 %122 %73\n%124 = OpAccessChain %80 %46 %71\n%125 = OpLoad %5 %124\n%126 = OpExtInst %5 %83 UMin %123 %125\n%120 = OpAccessChain %74 %13 %126\n%127 = OpLoad %10 %120\n%129 = OpAccessChain %76 %8 %90\n%130 = OpLoad %5 %129\n%131 = OpIAdd %5 %130 %86\n%128 = OpAccessChain %87 %65 %131\n%132 = OpLoad %14 %128\n%133 = OpSampledImage %94 %127 %132\n%135 = OpCompositeConstruct %99 %96 %96\n%134 = OpImageSampleExplicitLod %37 %133 %135 Lod %97\n%136 = OpCompositeExtract %9 %134 0\n%137 = OpCompositeExtract %9 %134 1\n%138 = OpCompositeExtract %9 %134 2\n%139 = OpCompositeExtract %9 %134 3\n%140 = OpIAdd %5 %72 %71\n%143 = OpAccessChain %76 %8 %144\n%145 = OpLoad %5 %143\n%146 = OpIAdd %5 %145 %140\n%147 = OpAccessChain %80 %46 %71\n%148 = OpLoad %5 %147\n%149 = OpExtInst %5 %83 UMin %146 %148\n%142 = OpAccessChain %141 %49 %149\n%150 = OpLoad %18 %142\n%151 = OpCompositeConstruct %26 %72 %71\n%152 = OpCompositeConstruct %37 %136 %137 %138 %139\nOpImageWrite %150 %151 %152\nOpControlBarrier %90 %90 %119\n%153 = OpIAdd %5 %72 %71\n%156 = OpAccessChain %76 %8 %157\n%158 = OpLoad %5 %156\n%159 = OpIAdd %5 %158 %153\n%160 = OpAccessChain %80 %46 %71\n%161 = OpLoad %5 %160\n%162 = OpExtInst %5 %83 UMin %159 %161\n%155 = OpAccessChain %154 %62 %162\n%164 = OpAccessChain %163 %155 %71 %71\n%165 = OpLoad %37 %164\n%166 = OpCompositeExtract %9 %165 0\n%167 = OpCompositeExtract %9 %165 1\n%168 = OpCompositeExtract %9 %165 2\n%169 = OpCompositeExtract %9 %165 3\n%170 = OpIAdd %5 %72 %71\n%173 = OpAccessChain %76 %8 %108\n%174 = OpLoad %5 %173\n%175 = OpIAdd %5 %174 %170\n%176 = OpAccessChain %80 %46 %71\n%177 = OpLoad %5 %176\n%178 = OpExtInst %5 %83 UMin %175 %177\n%172 = OpAccessChain %171 %52 %178\n%179 = OpLoad %22 %172\n%180 = OpCompositeConstruct %37 %166 %167 %168 %169\nOpImageWrite %179 %72 %180\nOpControlBarrier %90 %90 %119\n%182 = OpAccessChain %76 %8 %71\n%183 = OpLoad %5 %182\n%184 = OpIAdd %5 %183 %73\n%185 = OpAccessChain %80 %46 %71\n%186 = OpLoad %5 %185\n%187 = OpExtInst %5 %83 UMin %184 %186\n%181 = OpAccessChain %74 %13 %187\n%188 = OpLoad %10 %181\n%190 = OpAccessChain %76 %8 %90\n%191 = OpLoad %5 %190\n%192 = OpIAdd %5 %191 %86\n%189 = OpAccessChain %87 %65 %192\n%193 = OpLoad %14 %189\n%194 = OpSampledImage %94 %188 %193\n%196 = OpCompositeConstruct %99 %96 %96\n%195 = OpImageSampleExplicitLod %37 %194 %196 Lod %97\n%197 = OpCompositeExtract %9 %195 0\n%198 = OpCompositeExtract %9 %195 1\n%199 = OpCompositeExtract %9 %195 2\n%200 = OpCompositeExtract %9 %195 3\n%201 = OpIAdd %5 %72 %71\n%203 = OpAccessChain %76 %8 %108\n%204 = OpLoad %5 %203\n%205 = OpIAdd %5 %204 %201\n%206 = OpAccessChain %80 %46 %71\n%207 = OpLoad %5 %206\n%208 = OpExtInst %5 %83 UMin %205 %207\n%202 = OpAccessChain %105 %57 %208\n%209 = OpBitcast %5 %197\n%210 = OpBitcast %5 %198\n%211 = OpBitcast %5 %199\n%212 = OpBitcast %5 %200\n%213 = OpCompositeConstruct %31 %209 %210 %211 %212\n%214 = OpAccessChain %117 %202 %71 %72\nOpStore %214 %213\nOpControlBarrier %90 %90 %119\n%216 = OpAccessChain %76 %8 %108\n%217 = OpLoad %5 %216\n%218 = OpIAdd %5 %217 %201\n%219 = OpAccessChain %80 %46 %71\n%220 = OpLoad %5 %219\n%221 = OpExtInst %5 %83 UMin %218 %220\n%215 = OpAccessChain %105 %57 %221\n%224 = OpAccessChain %76 %8 %108\n%225 = OpLoad %5 %224\n%226 = OpIAdd %5 %225 %201\n%227 = OpAccessChain %80 %46 %71\n%228 = OpLoad %5 %227\n%229 = OpExtInst %5 %83 UMin %226 %228\n%223 = OpAccessChain %222 %30 %71 %229\n%230 = OpLoad %26 %223\n%251 = OpFunctionCall %5 %235 %230 %247 %71\nOpControlBarrier %90 %90 %119\n%253 = OpAccessChain %80 %46 %71\n%254 = OpLoad %5 %253\n%255 = OpExtInst %5 %83 UMin %72 %254\n%252 = OpAccessChain %74 %13 %255\n%256 = OpLoad %10 %252\n%257 = OpIAdd %5 %72 %111\n%258 = OpAccessChain %87 %17 %257\n%259 = OpLoad %14 %258\n%260 = OpIAdd %5 %72 %261\n%263 = OpAccessChain %80 %46 %71\n%264 = OpLoad %5 %263\n%265 = OpExtInst %5 %83 UMin %260 %264\n%262 = OpAccessChain %141 %21 %265\n%266 = OpLoad %18 %262\n%267 = OpIAdd %5 %72 %268\n%270 = OpAccessChain %80 %46 %71\n%271 = OpLoad %5 %270\n%272 = OpExtInst %5 %83 UMin %267 %271\n%269 = OpAccessChain %171 %25 %272\n%273 = OpLoad %22 %269\n%274 = OpIAdd %5 %72 %275\n%278 = OpAccessChain %80 %46 %71\n%279 = OpLoad %5 %278\n%280 = OpExtInst %5 %83 UMin %274 %279\n%277 = OpAccessChain %276 %36 %280\n%282 = OpAccessChain %80 %46 %71\n%283 = OpLoad %5 %282\n%284 = OpExtInst %5 %83 UMin %274 %283\n%281 = OpAccessChain %222 %30 %71 %284\n%285 = OpLoad %26 %281\n%286 = OpIAdd %5 %72 %287\n%290 = OpAccessChain %80 %46 %71\n%291 = OpLoad %5 %290\n%292 = OpExtInst %5 %83 UMin %286 %291\n%289 = OpAccessChain %288 %43 %292\n%293 = OpSampledImage %94 %256 %259\n%295 = OpCompositeConstruct %99 %96 %96\n%294 = OpImageSampleExplicitLod %37 %293 %295 Lod %97\n%296 = OpCompositeExtract %9 %294 0\n%297 = OpCompositeExtract %9 %294 1\n%298 = OpCompositeExtract %9 %294 2\n%299 = OpCompositeExtract %9 %294 3\n%301 = OpAccessChain %76 %8 %108\n%302 = OpLoad %5 %301\n%303 = OpIAdd %5 %302 %111\n%300 = OpAccessChain %105 %57 %303\n%304 = OpBitcast %5 %296\n%305 = OpBitcast %5 %297\n%306 = OpBitcast %5 %298\n%307 = OpBitcast %5 %299\n%308 = OpCompositeConstruct %31 %304 %305 %306 %307\n%309 = OpAccessChain %117 %300 %71 %72\nOpStore %309 %308\nOpControlBarrier %90 %90 %119\n%311 = OpCompositeConstruct %99 %96 %96\n%310 = OpImageSampleExplicitLod %37 %293 %311 Lod %97\n%312 = OpCompositeExtract %9 %310 0\n%313 = OpCompositeExtract %9 %310 1\n%314 = OpCompositeExtract %9 %310 2\n%315 = OpCompositeExtract %9 %310 3\n%316 = OpCompositeConstruct %26 %72 %71\n%317 = OpCompositeConstruct %37 %312 %313 %314 %315\nOpImageWrite %266 %316 %317\nOpControlBarrier %90 %90 %119\n%318 = OpAccessChain %163 %289 %71 %71\n%319 = OpLoad %37 %318\n%320 = OpCompositeExtract %9 %319 0\n%321 = OpCompositeExtract %9 %319 1\n%322 = OpCompositeExtract %9 %319 2\n%323 = OpCompositeExtract %9 %319 3\n%324 = OpCompositeConstruct %37 %320 %321 %322 %323\nOpImageWrite %273 %72 %324\nOpControlBarrier %90 %90 %119\n%326 = OpCompositeConstruct %99 %96 %96\n%325 = OpImageSampleExplicitLod %37 %293 %326 Lod %97\n%327 = OpCompositeExtract %9 %325 0\n%328 = OpCompositeExtract %9 %325 1\n%329 = OpCompositeExtract %9 %325 2\n%330 = OpCompositeExtract %9 %325 3\n%331 = OpBitcast %5 %327\n%332 = OpBitcast %5 %328\n%333 = OpBitcast %5 %329\n%334 = OpBitcast %5 %330\n%335 = OpCompositeConstruct %31 %331 %332 %333 %334\n%336 = OpAccessChain %117 %277 %71 %72\nOpStore %336 %335\nOpControlBarrier %90 %90 %119\n%337 = OpFunctionCall %5 %235 %285 %247 %71\nOpControlBarrier %90 %90 %119\nOpReturn\nOpFunctionEnd\n%235 = OpFunction %5 None %231\n%232 = OpFunctionParameter %26\n%233 = OpFunctionParameter %5\n%234 = OpFunctionParameter %5\n%236 = OpLabel\n%242 = OpINotEqual %240 %232 %241\n%243 = OpAny %239 %242\nOpSelectionMerge %238 None\nOpBranchConditional %243 %237 %238\n%237 = OpLabel\n%245 = OpBitcast %244 %232\n%246 = OpAtomicIAdd %5 %245 %247 %71 %233\n%248 = OpIAdd %5 %246 %234\nOpBranch %238\n%238 = OpLabel\n%249 = OpPhi %5 %71 %236 %248 %237\nOpReturnValue %249\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/heap-robustness/misc.bindless.heap-robustness.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nstruct DescriptorHeapRawPayload\n{\n    uint _m0[2];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _30;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _36[];\n\nlayout(set = 0, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _43[];\n\nlayout(set = 0, binding = 0, std430) writeonly readonly buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _58_61\n{\n    uvec4 _m0[];\n} _61[];\n\nlayout(set = 5, binding = 0, std140) uniform _63_66\n{\n    vec4 _m0[4096];\n} _66[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 0, binding = 0) uniform sampler _17[];\nlayout(set = 0, binding = 0) uniform writeonly image2D _21[];\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _25[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _53[];\nlayout(set = 4, binding = 0) uniform writeonly imageBuffer _56[];\nlayout(set = 2, binding = 0) uniform sampler _69[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _225, uint _226, uint _227)\n{\n    uint _242;\n    if (any(notEqual(_225, uvec2(0u))))\n    {\n        uint _239 = atomicAdd(uintPointer(_225).value, _226);\n        _242 = _239 + _227;\n    }\n    else\n    {\n        _242 = 0u;\n    }\n    return _242;\n}\n\nvoid main()\n{\n    uint _77 = gl_GlobalInvocationID.x + 0u;\n    uint _88 = gl_GlobalInvocationID.x + 0u;\n    vec4 _99 = textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _77), uint(DescriptorHeapRobustness.descriptors.length()))], _69[registers._m2 + _88])), vec2(0.5), 0.0);\n    _61[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_99.x), floatBitsToUint(_99.y), floatBitsToUint(_99.z), floatBitsToUint(_99.w));\n    barrier();\n    imageStore(_53[nonuniformEXT(min((registers._m3 + (gl_GlobalInvocationID.x + 0u)), uint(DescriptorHeapRobustness.descriptors.length())))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _77), uint(DescriptorHeapRobustness.descriptors.length()))], _69[registers._m2 + _88])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_56[nonuniformEXT(min((registers._m4 + (gl_GlobalInvocationID.x + 0u)), uint(DescriptorHeapRobustness.descriptors.length())))], int(gl_GlobalInvocationID.x), vec4(_66[nonuniformEXT(min((registers._m5 + (gl_GlobalInvocationID.x + 0u)), uint(DescriptorHeapRobustness.descriptors.length())))]._m0[0u]));\n    barrier();\n    vec4 _191 = textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _77), uint(DescriptorHeapRobustness.descriptors.length()))], _69[registers._m2 + _88])), vec2(0.5), 0.0);\n    uint _197 = gl_GlobalInvocationID.x + 0u;\n    _61[nonuniformEXT(min((registers._m4 + _197), uint(DescriptorHeapRobustness.descriptors.length())))]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_191.x), floatBitsToUint(_191.y), floatBitsToUint(_191.z), floatBitsToUint(_191.w));\n    barrier();\n    uvec2 _223 = _30.counters[min((registers._m4 + _197), uint(DescriptorHeapRobustness.descriptors.length()))];\n    uint _244 = RobustPhysicalAtomicCounter(_223, 1u, 0u);\n    barrier();\n    uint _264 = gl_GlobalInvocationID.x + 400u;\n    uvec2 _273 = _30.counters[min(_264, uint(DescriptorHeapRobustness.descriptors.length()))];\n    vec4 _281 = textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, uint(DescriptorHeapRobustness.descriptors.length()))], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _61[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_281.x), floatBitsToUint(_281.y), floatBitsToUint(_281.z), floatBitsToUint(_281.w));\n    barrier();\n    imageStore(_21[nonuniformEXT(min((gl_GlobalInvocationID.x + 200u), uint(DescriptorHeapRobustness.descriptors.length())))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, uint(DescriptorHeapRobustness.descriptors.length()))], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_25[nonuniformEXT(min((gl_GlobalInvocationID.x + 300u), uint(DescriptorHeapRobustness.descriptors.length())))], int(gl_GlobalInvocationID.x), vec4(_43[nonuniformEXT(min((gl_GlobalInvocationID.x + 500u), uint(DescriptorHeapRobustness.descriptors.length())))]._m0[0u]));\n    barrier();\n    vec4 _312 = textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, uint(DescriptorHeapRobustness.descriptors.length()))], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _36[nonuniformEXT(min(_264, uint(DescriptorHeapRobustness.descriptors.length())))]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_312.x), floatBitsToUint(_312.y), floatBitsToUint(_312.z), floatBitsToUint(_312.w));\n    barrier();\n    uint _324 = RobustPhysicalAtomicCounter(_273, 1u, 0u);\n    barrier();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 327\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%85 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %72\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %28 \"AtomicCounters\"\nOpMemberName %28 0 \"counters\"\nOpName %33 \"SSBO\"\nOpName %40 \"BindlessCBV\"\nOpName %46 \"DescriptorHeapRawPayload\"\nOpName %48 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %48 0 \"descriptors\"\nOpName %50 \"DescriptorHeapRobustness\"\nOpName %58 \"SSBO\"\nOpName %63 \"BindlessCBV\"\nOpName %228 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonReadable\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %27 ArrayStride 8\nOpDecorate %28 Block\nOpMemberDecorate %28 0 Offset 0\nOpMemberDecorate %28 0 NonWritable\nOpDecorate %30 DescriptorSet 7\nOpDecorate %30 Binding 0\nOpDecorate %30 AliasedPointer\nOpDecorate %32 ArrayStride 16\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %36 DescriptorSet 0\nOpDecorate %36 Binding 0\nOpDecorate %39 ArrayStride 16\nOpDecorate %40 Block\nOpMemberDecorate %40 0 Offset 0\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 0\nOpDecorate %45 ArrayStride 4\nOpMemberDecorate %46 0 Offset 0\nOpDecorate %47 ArrayStride 8\nOpDecorate %48 Block\nOpMemberDecorate %48 0 Offset 0\nOpMemberDecorate %48 0 NonWritable\nOpMemberDecorate %48 0 NonReadable\nOpDecorate %50 DescriptorSet 0\nOpDecorate %50 Binding 0\nOpDecorate %53 DescriptorSet 3\nOpDecorate %53 Binding 0\nOpDecorate %53 NonReadable\nOpDecorate %56 DescriptorSet 4\nOpDecorate %56 Binding 0\nOpDecorate %56 NonReadable\nOpDecorate %57 ArrayStride 16\nOpMemberDecorate %58 0 Offset 0\nOpDecorate %58 Block\nOpDecorate %61 DescriptorSet 4\nOpDecorate %61 Binding 0\nOpDecorate %61 NonReadable\nOpDecorate %62 ArrayStride 16\nOpDecorate %63 Block\nOpMemberDecorate %63 0 Offset 0\nOpDecorate %66 DescriptorSet 5\nOpDecorate %66 Binding 0\nOpDecorate %69 DescriptorSet 2\nOpDecorate %69 Binding 0\nOpDecorate %72 BuiltIn GlobalInvocationId\nOpDecorate %86 NonUniform\nOpDecorate %87 NonUniform\nOpDecorate %93 NonUniform\nOpDecorate %94 NonUniform\nOpDecorate %96 NonUniform\nOpDecorate %126 NonUniform\nOpDecorate %127 NonUniform\nOpDecorate %131 NonUniform\nOpDecorate %132 NonUniform\nOpDecorate %133 NonUniform\nOpDecorate %148 NonUniform\nOpDecorate %149 NonUniform\nOpDecorate %160 NonUniform\nOpDecorate %154 NonUniform\nOpDecorate %162 NonUniform\nOpDecorate %175 NonUniform\nOpDecorate %176 NonUniform\nOpDecorate %183 NonUniform\nOpDecorate %184 NonUniform\nOpDecorate %188 NonUniform\nOpDecorate %189 NonUniform\nOpDecorate %190 NonUniform\nOpDecorate %203 NonUniform\nOpDecorate %198 NonUniform\nOpDecorate %209 NonUniform\nOpDecorate %215 NonUniform\nOpDecorate %210 NonUniform\nOpDecorate %247 NonUniform\nOpDecorate %248 NonUniform\nOpDecorate %249 NonUniform\nOpDecorate %251 NonUniform\nOpDecorate %256 NonUniform\nOpDecorate %257 NonUniform\nOpDecorate %262 NonUniform\nOpDecorate %263 NonUniform\nOpDecorate %269 NonUniform\nOpDecorate %267 NonUniform\nOpDecorate %279 NonUniform\nOpDecorate %277 NonUniform\nOpDecorate %280 NonUniform\nOpDecorate %305 NonUniform\nOpDecorate %323 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %5 2\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypeStruct %27\n%29 = OpTypePointer StorageBuffer %28\n%30 = OpVariable %29 StorageBuffer\n%31 = OpTypeVector %5 4\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypeStruct %32\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypePointer StorageBuffer %34\n%36 = OpVariable %35 StorageBuffer\n%37 = OpTypeVector %9 4\n%38 = OpConstant %5 4096\n%39 = OpTypeArray %37 %38\n%40 = OpTypeStruct %39\n%41 = OpTypeRuntimeArray %40\n%42 = OpTypePointer Uniform %41\n%43 = OpVariable %42 Uniform\n%44 = OpConstant %5 2\n%45 = OpTypeArray %5 %44\n%46 = OpTypeStruct %45\n%47 = OpTypeRuntimeArray %46\n%48 = OpTypeStruct %47\n%49 = OpTypePointer StorageBuffer %48\n%50 = OpVariable %49 StorageBuffer\n%51 = OpTypeRuntimeArray %18\n%52 = OpTypePointer UniformConstant %51\n%53 = OpVariable %52 UniformConstant\n%54 = OpTypeRuntimeArray %22\n%55 = OpTypePointer UniformConstant %54\n%56 = OpVariable %55 UniformConstant\n%57 = OpTypeRuntimeArray %31\n%58 = OpTypeStruct %57\n%59 = OpTypeRuntimeArray %58\n%60 = OpTypePointer StorageBuffer %59\n%61 = OpVariable %60 StorageBuffer\n%62 = OpTypeArray %37 %38\n%63 = OpTypeStruct %62\n%64 = OpTypeRuntimeArray %63\n%65 = OpTypePointer Uniform %64\n%66 = OpVariable %65 Uniform\n%67 = OpTypeRuntimeArray %14\n%68 = OpTypePointer UniformConstant %67\n%69 = OpVariable %68 UniformConstant\n%70 = OpTypeVector %5 3\n%71 = OpTypePointer Input %70\n%72 = OpVariable %71 Input\n%73 = OpTypePointer Input %5\n%75 = OpConstant %5 0\n%78 = OpTypePointer UniformConstant %10\n%80 = OpTypePointer PushConstant %5\n%89 = OpTypePointer UniformConstant %14\n%95 = OpTypeSampledImage %10\n%97 = OpConstant %9 0.5\n%98 = OpConstant %9 0\n%100 = OpTypeVector %9 2\n%106 = OpTypePointer StorageBuffer %58\n%109 = OpConstant %5 4\n%112 = OpConstant %5 100\n%118 = OpTypePointer StorageBuffer %31\n%120 = OpConstant %5 264\n%141 = OpTypePointer UniformConstant %18\n%144 = OpConstant %5 3\n%153 = OpTypePointer Uniform %63\n%156 = OpConstant %5 5\n%161 = OpTypePointer Uniform %37\n%169 = OpTypePointer UniformConstant %22\n%216 = OpTypePointer StorageBuffer %26\n%224 = OpTypeFunction %5 %26 %5 %5\n%232 = OpTypeBool\n%233 = OpTypeVector %232 2\n%234 = OpConstantNull %26\n%237 = OpTypePointer PhysicalStorageBuffer %5\n%240 = OpConstant %5 1\n%253 = OpConstant %5 200\n%259 = OpConstant %5 300\n%265 = OpConstant %5 400\n%266 = OpTypePointer StorageBuffer %33\n%275 = OpConstant %5 500\n%276 = OpTypePointer Uniform %40\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %325\n%325 = OpLabel\n%74 = OpAccessChain %73 %72 %75\n%76 = OpLoad %5 %74\n%77 = OpIAdd %5 %76 %75\n%81 = OpAccessChain %80 %8 %75\n%82 = OpLoad %5 %81\n%83 = OpIAdd %5 %82 %77\n%84 = OpArrayLength %5 %50 0\n%86 = OpExtInst %5 %85 UMin %83 %84\n%79 = OpAccessChain %78 %13 %86\n%87 = OpLoad %10 %79\n%88 = OpIAdd %5 %76 %75\n%91 = OpAccessChain %80 %8 %44\n%92 = OpLoad %5 %91\n%93 = OpIAdd %5 %92 %88\n%90 = OpAccessChain %89 %69 %93\n%94 = OpLoad %14 %90\n%96 = OpSampledImage %95 %87 %94\n%101 = OpCompositeConstruct %100 %97 %97\n%99 = OpImageSampleExplicitLod %37 %96 %101 Lod %98\n%102 = OpCompositeExtract %9 %99 0\n%103 = OpCompositeExtract %9 %99 1\n%104 = OpCompositeExtract %9 %99 2\n%105 = OpCompositeExtract %9 %99 3\n%108 = OpAccessChain %80 %8 %109\n%110 = OpLoad %5 %108\n%111 = OpIAdd %5 %110 %112\n%107 = OpAccessChain %106 %61 %111\n%113 = OpBitcast %5 %102\n%114 = OpBitcast %5 %103\n%115 = OpBitcast %5 %104\n%116 = OpBitcast %5 %105\n%117 = OpCompositeConstruct %31 %113 %114 %115 %116\n%119 = OpAccessChain %118 %107 %75 %76\nOpStore %119 %117\nOpControlBarrier %44 %44 %120\n%122 = OpAccessChain %80 %8 %75\n%123 = OpLoad %5 %122\n%124 = OpIAdd %5 %123 %77\n%125 = OpArrayLength %5 %50 0\n%126 = OpExtInst %5 %85 UMin %124 %125\n%121 = OpAccessChain %78 %13 %126\n%127 = OpLoad %10 %121\n%129 = OpAccessChain %80 %8 %44\n%130 = OpLoad %5 %129\n%131 = OpIAdd %5 %130 %88\n%128 = OpAccessChain %89 %69 %131\n%132 = OpLoad %14 %128\n%133 = OpSampledImage %95 %127 %132\n%135 = OpCompositeConstruct %100 %97 %97\n%134 = OpImageSampleExplicitLod %37 %133 %135 Lod %98\n%136 = OpCompositeExtract %9 %134 0\n%137 = OpCompositeExtract %9 %134 1\n%138 = OpCompositeExtract %9 %134 2\n%139 = OpCompositeExtract %9 %134 3\n%140 = OpIAdd %5 %76 %75\n%143 = OpAccessChain %80 %8 %144\n%145 = OpLoad %5 %143\n%146 = OpIAdd %5 %145 %140\n%147 = OpArrayLength %5 %50 0\n%148 = OpExtInst %5 %85 UMin %146 %147\n%142 = OpAccessChain %141 %53 %148\n%149 = OpLoad %18 %142\n%150 = OpCompositeConstruct %26 %76 %75\n%151 = OpCompositeConstruct %37 %136 %137 %138 %139\nOpImageWrite %149 %150 %151\nOpControlBarrier %44 %44 %120\n%152 = OpIAdd %5 %76 %75\n%155 = OpAccessChain %80 %8 %156\n%157 = OpLoad %5 %155\n%158 = OpIAdd %5 %157 %152\n%159 = OpArrayLength %5 %50 0\n%160 = OpExtInst %5 %85 UMin %158 %159\n%154 = OpAccessChain %153 %66 %160\n%162 = OpAccessChain %161 %154 %75 %75\n%163 = OpLoad %37 %162\n%164 = OpCompositeExtract %9 %163 0\n%165 = OpCompositeExtract %9 %163 1\n%166 = OpCompositeExtract %9 %163 2\n%167 = OpCompositeExtract %9 %163 3\n%168 = OpIAdd %5 %76 %75\n%171 = OpAccessChain %80 %8 %109\n%172 = OpLoad %5 %171\n%173 = OpIAdd %5 %172 %168\n%174 = OpArrayLength %5 %50 0\n%175 = OpExtInst %5 %85 UMin %173 %174\n%170 = OpAccessChain %169 %56 %175\n%176 = OpLoad %22 %170\n%177 = OpCompositeConstruct %37 %164 %165 %166 %167\nOpImageWrite %176 %76 %177\nOpControlBarrier %44 %44 %120\n%179 = OpAccessChain %80 %8 %75\n%180 = OpLoad %5 %179\n%181 = OpIAdd %5 %180 %77\n%182 = OpArrayLength %5 %50 0\n%183 = OpExtInst %5 %85 UMin %181 %182\n%178 = OpAccessChain %78 %13 %183\n%184 = OpLoad %10 %178\n%186 = OpAccessChain %80 %8 %44\n%187 = OpLoad %5 %186\n%188 = OpIAdd %5 %187 %88\n%185 = OpAccessChain %89 %69 %188\n%189 = OpLoad %14 %185\n%190 = OpSampledImage %95 %184 %189\n%192 = OpCompositeConstruct %100 %97 %97\n%191 = OpImageSampleExplicitLod %37 %190 %192 Lod %98\n%193 = OpCompositeExtract %9 %191 0\n%194 = OpCompositeExtract %9 %191 1\n%195 = OpCompositeExtract %9 %191 2\n%196 = OpCompositeExtract %9 %191 3\n%197 = OpIAdd %5 %76 %75\n%199 = OpAccessChain %80 %8 %109\n%200 = OpLoad %5 %199\n%201 = OpIAdd %5 %200 %197\n%202 = OpArrayLength %5 %50 0\n%203 = OpExtInst %5 %85 UMin %201 %202\n%198 = OpAccessChain %106 %61 %203\n%204 = OpBitcast %5 %193\n%205 = OpBitcast %5 %194\n%206 = OpBitcast %5 %195\n%207 = OpBitcast %5 %196\n%208 = OpCompositeConstruct %31 %204 %205 %206 %207\n%209 = OpAccessChain %118 %198 %75 %76\nOpStore %209 %208\nOpControlBarrier %44 %44 %120\n%211 = OpAccessChain %80 %8 %109\n%212 = OpLoad %5 %211\n%213 = OpIAdd %5 %212 %197\n%214 = OpArrayLength %5 %50 0\n%215 = OpExtInst %5 %85 UMin %213 %214\n%210 = OpAccessChain %106 %61 %215\n%218 = OpAccessChain %80 %8 %109\n%219 = OpLoad %5 %218\n%220 = OpIAdd %5 %219 %197\n%221 = OpArrayLength %5 %50 0\n%222 = OpExtInst %5 %85 UMin %220 %221\n%217 = OpAccessChain %216 %30 %75 %222\n%223 = OpLoad %26 %217\n%244 = OpFunctionCall %5 %228 %223 %240 %75\nOpControlBarrier %44 %44 %120\n%246 = OpArrayLength %5 %50 0\n%247 = OpExtInst %5 %85 UMin %76 %246\n%245 = OpAccessChain %78 %13 %247\n%248 = OpLoad %10 %245\n%249 = OpIAdd %5 %76 %112\n%250 = OpAccessChain %89 %17 %249\n%251 = OpLoad %14 %250\n%252 = OpIAdd %5 %76 %253\n%255 = OpArrayLength %5 %50 0\n%256 = OpExtInst %5 %85 UMin %252 %255\n%254 = OpAccessChain %141 %21 %256\n%257 = OpLoad %18 %254\n%258 = OpIAdd %5 %76 %259\n%261 = OpArrayLength %5 %50 0\n%262 = OpExtInst %5 %85 UMin %258 %261\n%260 = OpAccessChain %169 %25 %262\n%263 = OpLoad %22 %260\n%264 = OpIAdd %5 %76 %265\n%268 = OpArrayLength %5 %50 0\n%269 = OpExtInst %5 %85 UMin %264 %268\n%267 = OpAccessChain %266 %36 %269\n%271 = OpArrayLength %5 %50 0\n%272 = OpExtInst %5 %85 UMin %264 %271\n%270 = OpAccessChain %216 %30 %75 %272\n%273 = OpLoad %26 %270\n%274 = OpIAdd %5 %76 %275\n%278 = OpArrayLength %5 %50 0\n%279 = OpExtInst %5 %85 UMin %274 %278\n%277 = OpAccessChain %276 %43 %279\n%280 = OpSampledImage %95 %248 %251\n%282 = OpCompositeConstruct %100 %97 %97\n%281 = OpImageSampleExplicitLod %37 %280 %282 Lod %98\n%283 = OpCompositeExtract %9 %281 0\n%284 = OpCompositeExtract %9 %281 1\n%285 = OpCompositeExtract %9 %281 2\n%286 = OpCompositeExtract %9 %281 3\n%288 = OpAccessChain %80 %8 %109\n%289 = OpLoad %5 %288\n%290 = OpIAdd %5 %289 %112\n%287 = OpAccessChain %106 %61 %290\n%291 = OpBitcast %5 %283\n%292 = OpBitcast %5 %284\n%293 = OpBitcast %5 %285\n%294 = OpBitcast %5 %286\n%295 = OpCompositeConstruct %31 %291 %292 %293 %294\n%296 = OpAccessChain %118 %287 %75 %76\nOpStore %296 %295\nOpControlBarrier %44 %44 %120\n%298 = OpCompositeConstruct %100 %97 %97\n%297 = OpImageSampleExplicitLod %37 %280 %298 Lod %98\n%299 = OpCompositeExtract %9 %297 0\n%300 = OpCompositeExtract %9 %297 1\n%301 = OpCompositeExtract %9 %297 2\n%302 = OpCompositeExtract %9 %297 3\n%303 = OpCompositeConstruct %26 %76 %75\n%304 = OpCompositeConstruct %37 %299 %300 %301 %302\nOpImageWrite %257 %303 %304\nOpControlBarrier %44 %44 %120\n%305 = OpAccessChain %161 %277 %75 %75\n%306 = OpLoad %37 %305\n%307 = OpCompositeExtract %9 %306 0\n%308 = OpCompositeExtract %9 %306 1\n%309 = OpCompositeExtract %9 %306 2\n%310 = OpCompositeExtract %9 %306 3\n%311 = OpCompositeConstruct %37 %307 %308 %309 %310\nOpImageWrite %263 %76 %311\nOpControlBarrier %44 %44 %120\n%313 = OpCompositeConstruct %100 %97 %97\n%312 = OpImageSampleExplicitLod %37 %280 %313 Lod %98\n%314 = OpCompositeExtract %9 %312 0\n%315 = OpCompositeExtract %9 %312 1\n%316 = OpCompositeExtract %9 %312 2\n%317 = OpCompositeExtract %9 %312 3\n%318 = OpBitcast %5 %314\n%319 = OpBitcast %5 %315\n%320 = OpBitcast %5 %316\n%321 = OpBitcast %5 %317\n%322 = OpCompositeConstruct %31 %318 %319 %320 %321\n%323 = OpAccessChain %118 %267 %75 %76\nOpStore %323 %322\nOpControlBarrier %44 %44 %120\n%324 = OpFunctionCall %5 %228 %273 %240 %75\nOpControlBarrier %44 %44 %120\nOpReturn\nOpFunctionEnd\n%228 = OpFunction %5 None %224\n%225 = OpFunctionParameter %26\n%226 = OpFunctionParameter %5\n%227 = OpFunctionParameter %5\n%229 = OpLabel\n%235 = OpINotEqual %233 %225 %234\n%236 = OpAny %232 %235\nOpSelectionMerge %231 None\nOpBranchConditional %236 %230 %231\n%230 = OpLabel\n%238 = OpBitcast %237 %225\n%239 = OpAtomicIAdd %5 %238 %240 %75 %226\n%241 = OpIAdd %5 %239 %227\nOpBranch %231\n%231 = OpLabel\n%242 = OpPhi %5 %75 %229 %241 %230\nOpReturnValue %242\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/heap-robustness/misc.bindless.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _30;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _36[];\n\nlayout(set = 0, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _43[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _51_54\n{\n    uvec4 _m0[];\n} _54[];\n\nlayout(set = 5, binding = 0, std140) uniform _56_59\n{\n    vec4 _m0[4096];\n} _59[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 0, binding = 0) uniform sampler _17[];\nlayout(set = 0, binding = 0) uniform writeonly image2D _21[];\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _25[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _46[];\nlayout(set = 4, binding = 0) uniform writeonly imageBuffer _49[];\nlayout(set = 2, binding = 0) uniform sampler _62[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _200, uint _201, uint _202)\n{\n    uint _217;\n    if (any(notEqual(_200, uvec2(0u))))\n    {\n        uint _214 = atomicAdd(uintPointer(_200).value, _201);\n        _217 = _214 + _202;\n    }\n    else\n    {\n        _217 = 0u;\n    }\n    return _217;\n}\n\nvoid main()\n{\n    uint _70 = gl_GlobalInvocationID.x + 0u;\n    uint _78 = gl_GlobalInvocationID.x + 0u;\n    vec4 _90 = textureLod(nonuniformEXT(sampler2D(_13[registers._m0 + _70], _62[registers._m2 + _78])), vec2(0.5), 0.0);\n    _54[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_90.x), floatBitsToUint(_90.y), floatBitsToUint(_90.z), floatBitsToUint(_90.w));\n    barrier();\n    imageStore(_46[nonuniformEXT(registers._m3 + (gl_GlobalInvocationID.x + 0u))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[registers._m0 + _70], _62[registers._m2 + _78])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_49[nonuniformEXT(registers._m4 + (gl_GlobalInvocationID.x + 0u))], int(gl_GlobalInvocationID.x), vec4(_59[nonuniformEXT(registers._m5 + (gl_GlobalInvocationID.x + 0u))]._m0[0u]));\n    barrier();\n    vec4 _172 = textureLod(nonuniformEXT(sampler2D(_13[registers._m0 + _70], _62[registers._m2 + _78])), vec2(0.5), 0.0);\n    uint _178 = gl_GlobalInvocationID.x + 0u;\n    _54[nonuniformEXT(registers._m4 + _178)]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_172.x), floatBitsToUint(_172.y), floatBitsToUint(_172.z), floatBitsToUint(_172.w));\n    barrier();\n    uvec2 _198 = _30.counters[registers._m4 + _178];\n    uint _219 = RobustPhysicalAtomicCounter(_198, 1u, 0u);\n    barrier();\n    uint _233 = gl_GlobalInvocationID.x + 400u;\n    uvec2 _238 = _30.counters[_233];\n    vec4 _244 = textureLod(nonuniformEXT(sampler2D(_13[gl_GlobalInvocationID.x], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _54[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_244.x), floatBitsToUint(_244.y), floatBitsToUint(_244.z), floatBitsToUint(_244.w));\n    barrier();\n    imageStore(_21[nonuniformEXT(gl_GlobalInvocationID.x + 200u)], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[gl_GlobalInvocationID.x], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_25[nonuniformEXT(gl_GlobalInvocationID.x + 300u)], int(gl_GlobalInvocationID.x), vec4(_43[nonuniformEXT(gl_GlobalInvocationID.x + 500u)]._m0[0u]));\n    barrier();\n    vec4 _275 = textureLod(nonuniformEXT(sampler2D(_13[gl_GlobalInvocationID.x], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _36[nonuniformEXT(_233)]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_275.x), floatBitsToUint(_275.y), floatBitsToUint(_275.z), floatBitsToUint(_275.w));\n    barrier();\n    uint _287 = RobustPhysicalAtomicCounter(_238, 1u, 0u);\n    barrier();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 290\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %65\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %28 \"AtomicCounters\"\nOpMemberName %28 0 \"counters\"\nOpName %33 \"SSBO\"\nOpName %40 \"BindlessCBV\"\nOpName %51 \"SSBO\"\nOpName %56 \"BindlessCBV\"\nOpName %203 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonReadable\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %27 ArrayStride 8\nOpDecorate %28 Block\nOpMemberDecorate %28 0 Offset 0\nOpMemberDecorate %28 0 NonWritable\nOpDecorate %30 DescriptorSet 7\nOpDecorate %30 Binding 0\nOpDecorate %30 AliasedPointer\nOpDecorate %32 ArrayStride 16\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %36 DescriptorSet 0\nOpDecorate %36 Binding 0\nOpDecorate %39 ArrayStride 16\nOpDecorate %40 Block\nOpMemberDecorate %40 0 Offset 0\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 0\nOpDecorate %46 DescriptorSet 3\nOpDecorate %46 Binding 0\nOpDecorate %46 NonReadable\nOpDecorate %49 DescriptorSet 4\nOpDecorate %49 Binding 0\nOpDecorate %49 NonReadable\nOpDecorate %50 ArrayStride 16\nOpMemberDecorate %51 0 Offset 0\nOpDecorate %51 Block\nOpDecorate %54 DescriptorSet 4\nOpDecorate %54 Binding 0\nOpDecorate %54 NonReadable\nOpDecorate %55 ArrayStride 16\nOpDecorate %56 Block\nOpMemberDecorate %56 0 Offset 0\nOpDecorate %59 DescriptorSet 5\nOpDecorate %59 Binding 0\nOpDecorate %62 DescriptorSet 2\nOpDecorate %62 Binding 0\nOpDecorate %65 BuiltIn GlobalInvocationId\nOpDecorate %76 NonUniform\nOpDecorate %77 NonUniform\nOpDecorate %84 NonUniform\nOpDecorate %85 NonUniform\nOpDecorate %87 NonUniform\nOpDecorate %115 NonUniform\nOpDecorate %116 NonUniform\nOpDecorate %120 NonUniform\nOpDecorate %121 NonUniform\nOpDecorate %122 NonUniform\nOpDecorate %135 NonUniform\nOpDecorate %136 NonUniform\nOpDecorate %145 NonUniform\nOpDecorate %141 NonUniform\nOpDecorate %147 NonUniform\nOpDecorate %158 NonUniform\nOpDecorate %159 NonUniform\nOpDecorate %164 NonUniform\nOpDecorate %165 NonUniform\nOpDecorate %169 NonUniform\nOpDecorate %170 NonUniform\nOpDecorate %171 NonUniform\nOpDecorate %182 NonUniform\nOpDecorate %179 NonUniform\nOpDecorate %188 NonUniform\nOpDecorate %192 NonUniform\nOpDecorate %189 NonUniform\nOpDecorate %69 NonUniform\nOpDecorate %221 NonUniform\nOpDecorate %222 NonUniform\nOpDecorate %224 NonUniform\nOpDecorate %225 NonUniform\nOpDecorate %228 NonUniform\nOpDecorate %229 NonUniform\nOpDecorate %232 NonUniform\nOpDecorate %233 NonUniform\nOpDecorate %236 NonUniform\nOpDecorate %239 NonUniform\nOpDecorate %242 NonUniform\nOpDecorate %243 NonUniform\nOpDecorate %268 NonUniform\nOpDecorate %286 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %5 2\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypeStruct %27\n%29 = OpTypePointer StorageBuffer %28\n%30 = OpVariable %29 StorageBuffer\n%31 = OpTypeVector %5 4\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypeStruct %32\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypePointer StorageBuffer %34\n%36 = OpVariable %35 StorageBuffer\n%37 = OpTypeVector %9 4\n%38 = OpConstant %5 4096\n%39 = OpTypeArray %37 %38\n%40 = OpTypeStruct %39\n%41 = OpTypeRuntimeArray %40\n%42 = OpTypePointer Uniform %41\n%43 = OpVariable %42 Uniform\n%44 = OpTypeRuntimeArray %18\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpTypeRuntimeArray %22\n%48 = OpTypePointer UniformConstant %47\n%49 = OpVariable %48 UniformConstant\n%50 = OpTypeRuntimeArray %31\n%51 = OpTypeStruct %50\n%52 = OpTypeRuntimeArray %51\n%53 = OpTypePointer StorageBuffer %52\n%54 = OpVariable %53 StorageBuffer\n%55 = OpTypeArray %37 %38\n%56 = OpTypeStruct %55\n%57 = OpTypeRuntimeArray %56\n%58 = OpTypePointer Uniform %57\n%59 = OpVariable %58 Uniform\n%60 = OpTypeRuntimeArray %14\n%61 = OpTypePointer UniformConstant %60\n%62 = OpVariable %61 UniformConstant\n%63 = OpTypeVector %5 3\n%64 = OpTypePointer Input %63\n%65 = OpVariable %64 Input\n%66 = OpTypePointer Input %5\n%68 = OpConstant %5 0\n%71 = OpTypePointer UniformConstant %10\n%73 = OpTypePointer PushConstant %5\n%79 = OpTypePointer UniformConstant %14\n%82 = OpConstant %5 2\n%86 = OpTypeSampledImage %10\n%88 = OpConstant %9 0.5\n%89 = OpConstant %9 0\n%91 = OpTypeVector %9 2\n%97 = OpTypePointer StorageBuffer %51\n%100 = OpConstant %5 4\n%103 = OpConstant %5 100\n%109 = OpTypePointer StorageBuffer %31\n%111 = OpConstant %5 264\n%130 = OpTypePointer UniformConstant %18\n%133 = OpConstant %5 3\n%140 = OpTypePointer Uniform %56\n%143 = OpConstant %5 5\n%146 = OpTypePointer Uniform %37\n%154 = OpTypePointer UniformConstant %22\n%193 = OpTypePointer StorageBuffer %26\n%199 = OpTypeFunction %5 %26 %5 %5\n%207 = OpTypeBool\n%208 = OpTypeVector %207 2\n%209 = OpConstantNull %26\n%212 = OpTypePointer PhysicalStorageBuffer %5\n%215 = OpConstant %5 1\n%226 = OpConstant %5 200\n%230 = OpConstant %5 300\n%234 = OpConstant %5 400\n%235 = OpTypePointer StorageBuffer %33\n%240 = OpConstant %5 500\n%241 = OpTypePointer Uniform %40\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %288\n%288 = OpLabel\n%67 = OpAccessChain %66 %65 %68\n%69 = OpLoad %5 %67\n%70 = OpIAdd %5 %69 %68\n%74 = OpAccessChain %73 %8 %68\n%75 = OpLoad %5 %74\n%76 = OpIAdd %5 %75 %70\n%72 = OpAccessChain %71 %13 %76\n%77 = OpLoad %10 %72\n%78 = OpIAdd %5 %69 %68\n%81 = OpAccessChain %73 %8 %82\n%83 = OpLoad %5 %81\n%84 = OpIAdd %5 %83 %78\n%80 = OpAccessChain %79 %62 %84\n%85 = OpLoad %14 %80\n%87 = OpSampledImage %86 %77 %85\n%92 = OpCompositeConstruct %91 %88 %88\n%90 = OpImageSampleExplicitLod %37 %87 %92 Lod %89\n%93 = OpCompositeExtract %9 %90 0\n%94 = OpCompositeExtract %9 %90 1\n%95 = OpCompositeExtract %9 %90 2\n%96 = OpCompositeExtract %9 %90 3\n%99 = OpAccessChain %73 %8 %100\n%101 = OpLoad %5 %99\n%102 = OpIAdd %5 %101 %103\n%98 = OpAccessChain %97 %54 %102\n%104 = OpBitcast %5 %93\n%105 = OpBitcast %5 %94\n%106 = OpBitcast %5 %95\n%107 = OpBitcast %5 %96\n%108 = OpCompositeConstruct %31 %104 %105 %106 %107\n%110 = OpAccessChain %109 %98 %68 %69\nOpStore %110 %108\nOpControlBarrier %82 %82 %111\n%113 = OpAccessChain %73 %8 %68\n%114 = OpLoad %5 %113\n%115 = OpIAdd %5 %114 %70\n%112 = OpAccessChain %71 %13 %115\n%116 = OpLoad %10 %112\n%118 = OpAccessChain %73 %8 %82\n%119 = OpLoad %5 %118\n%120 = OpIAdd %5 %119 %78\n%117 = OpAccessChain %79 %62 %120\n%121 = OpLoad %14 %117\n%122 = OpSampledImage %86 %116 %121\n%124 = OpCompositeConstruct %91 %88 %88\n%123 = OpImageSampleExplicitLod %37 %122 %124 Lod %89\n%125 = OpCompositeExtract %9 %123 0\n%126 = OpCompositeExtract %9 %123 1\n%127 = OpCompositeExtract %9 %123 2\n%128 = OpCompositeExtract %9 %123 3\n%129 = OpIAdd %5 %69 %68\n%132 = OpAccessChain %73 %8 %133\n%134 = OpLoad %5 %132\n%135 = OpIAdd %5 %134 %129\n%131 = OpAccessChain %130 %46 %135\n%136 = OpLoad %18 %131\n%137 = OpCompositeConstruct %26 %69 %68\n%138 = OpCompositeConstruct %37 %125 %126 %127 %128\nOpImageWrite %136 %137 %138\nOpControlBarrier %82 %82 %111\n%139 = OpIAdd %5 %69 %68\n%142 = OpAccessChain %73 %8 %143\n%144 = OpLoad %5 %142\n%145 = OpIAdd %5 %144 %139\n%141 = OpAccessChain %140 %59 %145\n%147 = OpAccessChain %146 %141 %68 %68\n%148 = OpLoad %37 %147\n%149 = OpCompositeExtract %9 %148 0\n%150 = OpCompositeExtract %9 %148 1\n%151 = OpCompositeExtract %9 %148 2\n%152 = OpCompositeExtract %9 %148 3\n%153 = OpIAdd %5 %69 %68\n%156 = OpAccessChain %73 %8 %100\n%157 = OpLoad %5 %156\n%158 = OpIAdd %5 %157 %153\n%155 = OpAccessChain %154 %49 %158\n%159 = OpLoad %22 %155\n%160 = OpCompositeConstruct %37 %149 %150 %151 %152\nOpImageWrite %159 %69 %160\nOpControlBarrier %82 %82 %111\n%162 = OpAccessChain %73 %8 %68\n%163 = OpLoad %5 %162\n%164 = OpIAdd %5 %163 %70\n%161 = OpAccessChain %71 %13 %164\n%165 = OpLoad %10 %161\n%167 = OpAccessChain %73 %8 %82\n%168 = OpLoad %5 %167\n%169 = OpIAdd %5 %168 %78\n%166 = OpAccessChain %79 %62 %169\n%170 = OpLoad %14 %166\n%171 = OpSampledImage %86 %165 %170\n%173 = OpCompositeConstruct %91 %88 %88\n%172 = OpImageSampleExplicitLod %37 %171 %173 Lod %89\n%174 = OpCompositeExtract %9 %172 0\n%175 = OpCompositeExtract %9 %172 1\n%176 = OpCompositeExtract %9 %172 2\n%177 = OpCompositeExtract %9 %172 3\n%178 = OpIAdd %5 %69 %68\n%180 = OpAccessChain %73 %8 %100\n%181 = OpLoad %5 %180\n%182 = OpIAdd %5 %181 %178\n%179 = OpAccessChain %97 %54 %182\n%183 = OpBitcast %5 %174\n%184 = OpBitcast %5 %175\n%185 = OpBitcast %5 %176\n%186 = OpBitcast %5 %177\n%187 = OpCompositeConstruct %31 %183 %184 %185 %186\n%188 = OpAccessChain %109 %179 %68 %69\nOpStore %188 %187\nOpControlBarrier %82 %82 %111\n%190 = OpAccessChain %73 %8 %100\n%191 = OpLoad %5 %190\n%192 = OpIAdd %5 %191 %178\n%189 = OpAccessChain %97 %54 %192\n%195 = OpAccessChain %73 %8 %100\n%196 = OpLoad %5 %195\n%197 = OpIAdd %5 %196 %178\n%194 = OpAccessChain %193 %30 %68 %197\n%198 = OpLoad %26 %194\n%219 = OpFunctionCall %5 %203 %198 %215 %68\nOpControlBarrier %82 %82 %111\n%220 = OpAccessChain %71 %13 %69\n%221 = OpLoad %10 %220\n%222 = OpIAdd %5 %69 %103\n%223 = OpAccessChain %79 %17 %222\n%224 = OpLoad %14 %223\n%225 = OpIAdd %5 %69 %226\n%227 = OpAccessChain %130 %21 %225\n%228 = OpLoad %18 %227\n%229 = OpIAdd %5 %69 %230\n%231 = OpAccessChain %154 %25 %229\n%232 = OpLoad %22 %231\n%233 = OpIAdd %5 %69 %234\n%236 = OpAccessChain %235 %36 %233\n%237 = OpAccessChain %193 %30 %68 %233\n%238 = OpLoad %26 %237\n%239 = OpIAdd %5 %69 %240\n%242 = OpAccessChain %241 %43 %239\n%243 = OpSampledImage %86 %221 %224\n%245 = OpCompositeConstruct %91 %88 %88\n%244 = OpImageSampleExplicitLod %37 %243 %245 Lod %89\n%246 = OpCompositeExtract %9 %244 0\n%247 = OpCompositeExtract %9 %244 1\n%248 = OpCompositeExtract %9 %244 2\n%249 = OpCompositeExtract %9 %244 3\n%251 = OpAccessChain %73 %8 %100\n%252 = OpLoad %5 %251\n%253 = OpIAdd %5 %252 %103\n%250 = OpAccessChain %97 %54 %253\n%254 = OpBitcast %5 %246\n%255 = OpBitcast %5 %247\n%256 = OpBitcast %5 %248\n%257 = OpBitcast %5 %249\n%258 = OpCompositeConstruct %31 %254 %255 %256 %257\n%259 = OpAccessChain %109 %250 %68 %69\nOpStore %259 %258\nOpControlBarrier %82 %82 %111\n%261 = OpCompositeConstruct %91 %88 %88\n%260 = OpImageSampleExplicitLod %37 %243 %261 Lod %89\n%262 = OpCompositeExtract %9 %260 0\n%263 = OpCompositeExtract %9 %260 1\n%264 = OpCompositeExtract %9 %260 2\n%265 = OpCompositeExtract %9 %260 3\n%266 = OpCompositeConstruct %26 %69 %68\n%267 = OpCompositeConstruct %37 %262 %263 %264 %265\nOpImageWrite %228 %266 %267\nOpControlBarrier %82 %82 %111\n%268 = OpAccessChain %146 %242 %68 %68\n%269 = OpLoad %37 %268\n%270 = OpCompositeExtract %9 %269 0\n%271 = OpCompositeExtract %9 %269 1\n%272 = OpCompositeExtract %9 %269 2\n%273 = OpCompositeExtract %9 %269 3\n%274 = OpCompositeConstruct %37 %270 %271 %272 %273\nOpImageWrite %232 %69 %274\nOpControlBarrier %82 %82 %111\n%276 = OpCompositeConstruct %91 %88 %88\n%275 = OpImageSampleExplicitLod %37 %243 %276 Lod %89\n%277 = OpCompositeExtract %9 %275 0\n%278 = OpCompositeExtract %9 %275 1\n%279 = OpCompositeExtract %9 %275 2\n%280 = OpCompositeExtract %9 %275 3\n%281 = OpBitcast %5 %277\n%282 = OpBitcast %5 %278\n%283 = OpBitcast %5 %279\n%284 = OpBitcast %5 %280\n%285 = OpCompositeConstruct %31 %281 %282 %283 %284\n%286 = OpAccessChain %109 %236 %68 %69\nOpStore %286 %285\nOpControlBarrier %82 %82 %111\n%287 = OpFunctionCall %5 %203 %238 %215 %68\nOpControlBarrier %82 %82 %111\nOpReturn\nOpFunctionEnd\n%203 = OpFunction %5 None %199\n%200 = OpFunctionParameter %26\n%201 = OpFunctionParameter %5\n%202 = OpFunctionParameter %5\n%204 = OpLabel\n%210 = OpINotEqual %208 %200 %209\n%211 = OpAny %207 %210\nOpSelectionMerge %206 None\nOpBranchConditional %211 %205 %206\n%205 = OpLabel\n%213 = OpBitcast %212 %200\n%214 = OpAtomicIAdd %5 %213 %215 %68 %201\n%216 = OpIAdd %5 %214 %202\nOpBranch %206\n%206 = OpLabel\n%217 = OpPhi %5 %68 %204 %216 %205\nOpReturnValue %217\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/heap-robustness/misc.heap-robustness.bindless.heap-robustness-cbv.heap-raw-va-cbv.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer DescriptorHeapRawBlock;\nlayout(buffer_reference) buffer uintPointer;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) readonly buffer DescriptorHeapRawBlock\n{\n    DescriptorHeapRawPayload descriptors[];\n};\n\nlayout(set = 10, binding = 21, std140) uniform DescriptorHeapRawPayloadPtr\n{\n    DescriptorHeapRawBlock ptr;\n} DescriptorHeapRaw;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _41[];\n\nlayout(set = 0, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _48[];\n\nlayout(set = 10, binding = 20, std140) uniform DescriptorHeapSizeUBO\n{\n    uint count;\n} DescriptorHeapSize;\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _59_62\n{\n    uvec4 _m0[];\n} _62[];\n\nlayout(set = 5, binding = 0, std140) uniform _64_67\n{\n    vec4 _m0[4096];\n} _67[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 0, binding = 0) uniform sampler _17[];\nlayout(set = 0, binding = 0) uniform writeonly image2D _21[];\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _25[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _54[];\nlayout(set = 4, binding = 0) uniform writeonly imageBuffer _57[];\nlayout(set = 2, binding = 0) uniform sampler _70[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _240, uint _241, uint _242)\n{\n    uint _256;\n    if (any(notEqual(_240, uvec2(0u))))\n    {\n        uint _254 = atomicAdd(uintPointer(_240).value, _241);\n        _256 = _254 + _242;\n    }\n    else\n    {\n        _256 = 0u;\n    }\n    return _256;\n}\n\nvoid main()\n{\n    uint _78 = gl_GlobalInvocationID.x + 0u;\n    uint _91 = gl_GlobalInvocationID.x + 0u;\n    vec4 _103 = textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _78), DescriptorHeapSize.count)], _70[registers._m2 + _91])), vec2(0.5), 0.0);\n    _62[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_103.x), floatBitsToUint(_103.y), floatBitsToUint(_103.z), floatBitsToUint(_103.w));\n    barrier();\n    imageStore(_54[nonuniformEXT(min((registers._m3 + (gl_GlobalInvocationID.x + 0u)), DescriptorHeapSize.count))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _78), DescriptorHeapSize.count)], _70[registers._m2 + _91])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_57[nonuniformEXT(min((registers._m4 + (gl_GlobalInvocationID.x + 0u)), DescriptorHeapSize.count))], int(gl_GlobalInvocationID.x), vec4(_67[nonuniformEXT(min((registers._m5 + (gl_GlobalInvocationID.x + 0u)), DescriptorHeapSize.count))]._m0[0u]));\n    barrier();\n    vec4 _200 = textureLod(nonuniformEXT(sampler2D(_13[min((registers._m0 + _78), DescriptorHeapSize.count)], _70[registers._m2 + _91])), vec2(0.5), 0.0);\n    uint _206 = gl_GlobalInvocationID.x + 0u;\n    _62[nonuniformEXT(min((registers._m4 + _206), DescriptorHeapSize.count))]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_200.x), floatBitsToUint(_200.y), floatBitsToUint(_200.z), floatBitsToUint(_200.w));\n    barrier();\n    uint _258 = RobustPhysicalAtomicCounter(DescriptorHeapRaw.ptr.descriptors[min((registers._m4 + _206), DescriptorHeapSize.count)]._m0[0u], 1u, 0u);\n    barrier();\n    uint _281 = gl_GlobalInvocationID.x + 400u;\n    vec4 _303 = textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, DescriptorHeapSize.count)], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _62[registers._m4 + 100u]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_303.x), floatBitsToUint(_303.y), floatBitsToUint(_303.z), floatBitsToUint(_303.w));\n    barrier();\n    imageStore(_21[nonuniformEXT(min((gl_GlobalInvocationID.x + 200u), DescriptorHeapSize.count))], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, DescriptorHeapSize.count)], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0)));\n    barrier();\n    imageStore(_25[nonuniformEXT(min((gl_GlobalInvocationID.x + 300u), DescriptorHeapSize.count))], int(gl_GlobalInvocationID.x), vec4(_48[nonuniformEXT(min((gl_GlobalInvocationID.x + 500u), DescriptorHeapSize.count))]._m0[0u]));\n    barrier();\n    vec4 _334 = textureLod(nonuniformEXT(sampler2D(_13[min(gl_GlobalInvocationID.x, DescriptorHeapSize.count)], _17[gl_GlobalInvocationID.x + 100u])), vec2(0.5), 0.0);\n    _41[nonuniformEXT(min(_281, DescriptorHeapSize.count))]._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_334.x), floatBitsToUint(_334.y), floatBitsToUint(_334.z), floatBitsToUint(_334.w));\n    barrier();\n    uint _346 = RobustPhysicalAtomicCounter(DescriptorHeapRaw.ptr.descriptors[min(_281, DescriptorHeapSize.count)]._m0[0u], 1u, 0u);\n    barrier();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 349\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%88 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %73\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %29 \"DescriptorHeapRawPayload\"\nOpName %31 \"DescriptorHeapRawBlock\"\nOpMemberName %31 0 \"descriptors\"\nOpName %33 \"DescriptorHeapRawPayloadPtr\"\nOpMemberName %33 0 \"ptr\"\nOpName %35 \"DescriptorHeapRaw\"\nOpName %38 \"SSBO\"\nOpName %45 \"BindlessCBV\"\nOpName %49 \"DescriptorHeapSizeUBO\"\nOpMemberName %49 0 \"count\"\nOpName %51 \"DescriptorHeapSize\"\nOpName %59 \"SSBO\"\nOpName %64 \"BindlessCBV\"\nOpName %243 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonReadable\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %28 ArrayStride 8\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %30 ArrayStride 8\nOpDecorate %31 Block\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 0 NonWritable\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %35 DescriptorSet 10\nOpDecorate %35 Binding 21\nOpDecorate %37 ArrayStride 16\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpDecorate %41 DescriptorSet 0\nOpDecorate %41 Binding 0\nOpDecorate %44 ArrayStride 16\nOpDecorate %45 Block\nOpMemberDecorate %45 0 Offset 0\nOpDecorate %48 DescriptorSet 0\nOpDecorate %48 Binding 0\nOpDecorate %49 Block\nOpMemberDecorate %49 0 Offset 0\nOpDecorate %51 DescriptorSet 10\nOpDecorate %51 Binding 20\nOpDecorate %54 DescriptorSet 3\nOpDecorate %54 Binding 0\nOpDecorate %54 NonReadable\nOpDecorate %57 DescriptorSet 4\nOpDecorate %57 Binding 0\nOpDecorate %57 NonReadable\nOpDecorate %58 ArrayStride 16\nOpMemberDecorate %59 0 Offset 0\nOpDecorate %59 Block\nOpDecorate %62 DescriptorSet 4\nOpDecorate %62 Binding 0\nOpDecorate %62 NonReadable\nOpDecorate %63 ArrayStride 16\nOpDecorate %64 Block\nOpMemberDecorate %64 0 Offset 0\nOpDecorate %67 DescriptorSet 5\nOpDecorate %67 Binding 0\nOpDecorate %70 DescriptorSet 2\nOpDecorate %70 Binding 0\nOpDecorate %73 BuiltIn GlobalInvocationId\nOpDecorate %89 NonUniform\nOpDecorate %90 NonUniform\nOpDecorate %97 NonUniform\nOpDecorate %98 NonUniform\nOpDecorate %100 NonUniform\nOpDecorate %131 NonUniform\nOpDecorate %132 NonUniform\nOpDecorate %136 NonUniform\nOpDecorate %137 NonUniform\nOpDecorate %138 NonUniform\nOpDecorate %154 NonUniform\nOpDecorate %155 NonUniform\nOpDecorate %167 NonUniform\nOpDecorate %160 NonUniform\nOpDecorate %169 NonUniform\nOpDecorate %183 NonUniform\nOpDecorate %184 NonUniform\nOpDecorate %192 NonUniform\nOpDecorate %193 NonUniform\nOpDecorate %197 NonUniform\nOpDecorate %198 NonUniform\nOpDecorate %199 NonUniform\nOpDecorate %213 NonUniform\nOpDecorate %207 NonUniform\nOpDecorate %219 NonUniform\nOpDecorate %226 NonUniform\nOpDecorate %220 NonUniform\nOpDecorate %262 NonUniform\nOpDecorate %263 NonUniform\nOpDecorate %264 NonUniform\nOpDecorate %266 NonUniform\nOpDecorate %272 NonUniform\nOpDecorate %273 NonUniform\nOpDecorate %279 NonUniform\nOpDecorate %280 NonUniform\nOpDecorate %287 NonUniform\nOpDecorate %284 NonUniform\nOpDecorate %301 NonUniform\nOpDecorate %298 NonUniform\nOpDecorate %302 NonUniform\nOpDecorate %327 NonUniform\nOpDecorate %345 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %5 2\n%27 = OpConstant %5 1\n%28 = OpTypeArray %26 %27\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypeStruct %30\n%32 = OpTypePointer PhysicalStorageBuffer %31\n%33 = OpTypeStruct %32\n%34 = OpTypePointer Uniform %33\n%35 = OpVariable %34 Uniform\n%36 = OpTypeVector %5 4\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypeStruct %37\n%39 = OpTypeRuntimeArray %38\n%40 = OpTypePointer StorageBuffer %39\n%41 = OpVariable %40 StorageBuffer\n%42 = OpTypeVector %9 4\n%43 = OpConstant %5 4096\n%44 = OpTypeArray %42 %43\n%45 = OpTypeStruct %44\n%46 = OpTypeRuntimeArray %45\n%47 = OpTypePointer Uniform %46\n%48 = OpVariable %47 Uniform\n%49 = OpTypeStruct %5\n%50 = OpTypePointer Uniform %49\n%51 = OpVariable %50 Uniform\n%52 = OpTypeRuntimeArray %18\n%53 = OpTypePointer UniformConstant %52\n%54 = OpVariable %53 UniformConstant\n%55 = OpTypeRuntimeArray %22\n%56 = OpTypePointer UniformConstant %55\n%57 = OpVariable %56 UniformConstant\n%58 = OpTypeRuntimeArray %36\n%59 = OpTypeStruct %58\n%60 = OpTypeRuntimeArray %59\n%61 = OpTypePointer StorageBuffer %60\n%62 = OpVariable %61 StorageBuffer\n%63 = OpTypeArray %42 %43\n%64 = OpTypeStruct %63\n%65 = OpTypeRuntimeArray %64\n%66 = OpTypePointer Uniform %65\n%67 = OpVariable %66 Uniform\n%68 = OpTypeRuntimeArray %14\n%69 = OpTypePointer UniformConstant %68\n%70 = OpVariable %69 UniformConstant\n%71 = OpTypeVector %5 3\n%72 = OpTypePointer Input %71\n%73 = OpVariable %72 Input\n%74 = OpTypePointer Input %5\n%76 = OpConstant %5 0\n%79 = OpTypePointer UniformConstant %10\n%81 = OpTypePointer PushConstant %5\n%85 = OpTypePointer Uniform %5\n%92 = OpTypePointer UniformConstant %14\n%95 = OpConstant %5 2\n%99 = OpTypeSampledImage %10\n%101 = OpConstant %9 0.5\n%102 = OpConstant %9 0\n%104 = OpTypeVector %9 2\n%110 = OpTypePointer StorageBuffer %59\n%113 = OpConstant %5 4\n%116 = OpConstant %5 100\n%122 = OpTypePointer StorageBuffer %36\n%124 = OpConstant %5 264\n%146 = OpTypePointer UniformConstant %18\n%149 = OpConstant %5 3\n%159 = OpTypePointer Uniform %64\n%162 = OpConstant %5 5\n%168 = OpTypePointer Uniform %42\n%176 = OpTypePointer UniformConstant %22\n%227 = OpTypePointer Uniform %32\n%230 = OpTypePointer PhysicalStorageBuffer %26\n%239 = OpTypeFunction %5 %26 %5 %5\n%247 = OpTypeBool\n%248 = OpTypeVector %247 2\n%249 = OpConstantNull %26\n%252 = OpTypePointer PhysicalStorageBuffer %5\n%268 = OpConstant %5 200\n%275 = OpConstant %5 300\n%282 = OpConstant %5 400\n%283 = OpTypePointer StorageBuffer %38\n%296 = OpConstant %5 500\n%297 = OpTypePointer Uniform %45\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %347\n%347 = OpLabel\n%75 = OpAccessChain %74 %73 %76\n%77 = OpLoad %5 %75\n%78 = OpIAdd %5 %77 %76\n%82 = OpAccessChain %81 %8 %76\n%83 = OpLoad %5 %82\n%84 = OpIAdd %5 %83 %78\n%86 = OpAccessChain %85 %51 %76\n%87 = OpLoad %5 %86\n%89 = OpExtInst %5 %88 UMin %84 %87\n%80 = OpAccessChain %79 %13 %89\n%90 = OpLoad %10 %80\n%91 = OpIAdd %5 %77 %76\n%94 = OpAccessChain %81 %8 %95\n%96 = OpLoad %5 %94\n%97 = OpIAdd %5 %96 %91\n%93 = OpAccessChain %92 %70 %97\n%98 = OpLoad %14 %93\n%100 = OpSampledImage %99 %90 %98\n%105 = OpCompositeConstruct %104 %101 %101\n%103 = OpImageSampleExplicitLod %42 %100 %105 Lod %102\n%106 = OpCompositeExtract %9 %103 0\n%107 = OpCompositeExtract %9 %103 1\n%108 = OpCompositeExtract %9 %103 2\n%109 = OpCompositeExtract %9 %103 3\n%112 = OpAccessChain %81 %8 %113\n%114 = OpLoad %5 %112\n%115 = OpIAdd %5 %114 %116\n%111 = OpAccessChain %110 %62 %115\n%117 = OpBitcast %5 %106\n%118 = OpBitcast %5 %107\n%119 = OpBitcast %5 %108\n%120 = OpBitcast %5 %109\n%121 = OpCompositeConstruct %36 %117 %118 %119 %120\n%123 = OpAccessChain %122 %111 %76 %77\nOpStore %123 %121\nOpControlBarrier %95 %95 %124\n%126 = OpAccessChain %81 %8 %76\n%127 = OpLoad %5 %126\n%128 = OpIAdd %5 %127 %78\n%129 = OpAccessChain %85 %51 %76\n%130 = OpLoad %5 %129\n%131 = OpExtInst %5 %88 UMin %128 %130\n%125 = OpAccessChain %79 %13 %131\n%132 = OpLoad %10 %125\n%134 = OpAccessChain %81 %8 %95\n%135 = OpLoad %5 %134\n%136 = OpIAdd %5 %135 %91\n%133 = OpAccessChain %92 %70 %136\n%137 = OpLoad %14 %133\n%138 = OpSampledImage %99 %132 %137\n%140 = OpCompositeConstruct %104 %101 %101\n%139 = OpImageSampleExplicitLod %42 %138 %140 Lod %102\n%141 = OpCompositeExtract %9 %139 0\n%142 = OpCompositeExtract %9 %139 1\n%143 = OpCompositeExtract %9 %139 2\n%144 = OpCompositeExtract %9 %139 3\n%145 = OpIAdd %5 %77 %76\n%148 = OpAccessChain %81 %8 %149\n%150 = OpLoad %5 %148\n%151 = OpIAdd %5 %150 %145\n%152 = OpAccessChain %85 %51 %76\n%153 = OpLoad %5 %152\n%154 = OpExtInst %5 %88 UMin %151 %153\n%147 = OpAccessChain %146 %54 %154\n%155 = OpLoad %18 %147\n%156 = OpCompositeConstruct %26 %77 %76\n%157 = OpCompositeConstruct %42 %141 %142 %143 %144\nOpImageWrite %155 %156 %157\nOpControlBarrier %95 %95 %124\n%158 = OpIAdd %5 %77 %76\n%161 = OpAccessChain %81 %8 %162\n%163 = OpLoad %5 %161\n%164 = OpIAdd %5 %163 %158\n%165 = OpAccessChain %85 %51 %76\n%166 = OpLoad %5 %165\n%167 = OpExtInst %5 %88 UMin %164 %166\n%160 = OpAccessChain %159 %67 %167\n%169 = OpAccessChain %168 %160 %76 %76\n%170 = OpLoad %42 %169\n%171 = OpCompositeExtract %9 %170 0\n%172 = OpCompositeExtract %9 %170 1\n%173 = OpCompositeExtract %9 %170 2\n%174 = OpCompositeExtract %9 %170 3\n%175 = OpIAdd %5 %77 %76\n%178 = OpAccessChain %81 %8 %113\n%179 = OpLoad %5 %178\n%180 = OpIAdd %5 %179 %175\n%181 = OpAccessChain %85 %51 %76\n%182 = OpLoad %5 %181\n%183 = OpExtInst %5 %88 UMin %180 %182\n%177 = OpAccessChain %176 %57 %183\n%184 = OpLoad %22 %177\n%185 = OpCompositeConstruct %42 %171 %172 %173 %174\nOpImageWrite %184 %77 %185\nOpControlBarrier %95 %95 %124\n%187 = OpAccessChain %81 %8 %76\n%188 = OpLoad %5 %187\n%189 = OpIAdd %5 %188 %78\n%190 = OpAccessChain %85 %51 %76\n%191 = OpLoad %5 %190\n%192 = OpExtInst %5 %88 UMin %189 %191\n%186 = OpAccessChain %79 %13 %192\n%193 = OpLoad %10 %186\n%195 = OpAccessChain %81 %8 %95\n%196 = OpLoad %5 %195\n%197 = OpIAdd %5 %196 %91\n%194 = OpAccessChain %92 %70 %197\n%198 = OpLoad %14 %194\n%199 = OpSampledImage %99 %193 %198\n%201 = OpCompositeConstruct %104 %101 %101\n%200 = OpImageSampleExplicitLod %42 %199 %201 Lod %102\n%202 = OpCompositeExtract %9 %200 0\n%203 = OpCompositeExtract %9 %200 1\n%204 = OpCompositeExtract %9 %200 2\n%205 = OpCompositeExtract %9 %200 3\n%206 = OpIAdd %5 %77 %76\n%208 = OpAccessChain %81 %8 %113\n%209 = OpLoad %5 %208\n%210 = OpIAdd %5 %209 %206\n%211 = OpAccessChain %85 %51 %76\n%212 = OpLoad %5 %211\n%213 = OpExtInst %5 %88 UMin %210 %212\n%207 = OpAccessChain %110 %62 %213\n%214 = OpBitcast %5 %202\n%215 = OpBitcast %5 %203\n%216 = OpBitcast %5 %204\n%217 = OpBitcast %5 %205\n%218 = OpCompositeConstruct %36 %214 %215 %216 %217\n%219 = OpAccessChain %122 %207 %76 %77\nOpStore %219 %218\nOpControlBarrier %95 %95 %124\n%221 = OpAccessChain %81 %8 %113\n%222 = OpLoad %5 %221\n%223 = OpIAdd %5 %222 %206\n%224 = OpAccessChain %85 %51 %76\n%225 = OpLoad %5 %224\n%226 = OpExtInst %5 %88 UMin %223 %225\n%220 = OpAccessChain %110 %62 %226\n%228 = OpAccessChain %227 %35 %76\n%229 = OpLoad %32 %228\n%232 = OpAccessChain %81 %8 %113\n%233 = OpLoad %5 %232\n%234 = OpIAdd %5 %233 %206\n%235 = OpAccessChain %85 %51 %76\n%236 = OpLoad %5 %235\n%237 = OpExtInst %5 %88 UMin %234 %236\n%231 = OpInBoundsAccessChain %230 %229 %76 %237 %76 %76\n%238 = OpLoad %26 %231 Aligned 8\n%258 = OpFunctionCall %5 %243 %238 %27 %76\nOpControlBarrier %95 %95 %124\n%260 = OpAccessChain %85 %51 %76\n%261 = OpLoad %5 %260\n%262 = OpExtInst %5 %88 UMin %77 %261\n%259 = OpAccessChain %79 %13 %262\n%263 = OpLoad %10 %259\n%264 = OpIAdd %5 %77 %116\n%265 = OpAccessChain %92 %17 %264\n%266 = OpLoad %14 %265\n%267 = OpIAdd %5 %77 %268\n%270 = OpAccessChain %85 %51 %76\n%271 = OpLoad %5 %270\n%272 = OpExtInst %5 %88 UMin %267 %271\n%269 = OpAccessChain %146 %21 %272\n%273 = OpLoad %18 %269\n%274 = OpIAdd %5 %77 %275\n%277 = OpAccessChain %85 %51 %76\n%278 = OpLoad %5 %277\n%279 = OpExtInst %5 %88 UMin %274 %278\n%276 = OpAccessChain %176 %25 %279\n%280 = OpLoad %22 %276\n%281 = OpIAdd %5 %77 %282\n%285 = OpAccessChain %85 %51 %76\n%286 = OpLoad %5 %285\n%287 = OpExtInst %5 %88 UMin %281 %286\n%284 = OpAccessChain %283 %41 %287\n%288 = OpAccessChain %227 %35 %76\n%289 = OpLoad %32 %288\n%291 = OpAccessChain %85 %51 %76\n%292 = OpLoad %5 %291\n%293 = OpExtInst %5 %88 UMin %281 %292\n%290 = OpInBoundsAccessChain %230 %289 %76 %293 %76 %76\n%294 = OpLoad %26 %290 Aligned 8\n%295 = OpIAdd %5 %77 %296\n%299 = OpAccessChain %85 %51 %76\n%300 = OpLoad %5 %299\n%301 = OpExtInst %5 %88 UMin %295 %300\n%298 = OpAccessChain %297 %48 %301\n%302 = OpSampledImage %99 %263 %266\n%304 = OpCompositeConstruct %104 %101 %101\n%303 = OpImageSampleExplicitLod %42 %302 %304 Lod %102\n%305 = OpCompositeExtract %9 %303 0\n%306 = OpCompositeExtract %9 %303 1\n%307 = OpCompositeExtract %9 %303 2\n%308 = OpCompositeExtract %9 %303 3\n%310 = OpAccessChain %81 %8 %113\n%311 = OpLoad %5 %310\n%312 = OpIAdd %5 %311 %116\n%309 = OpAccessChain %110 %62 %312\n%313 = OpBitcast %5 %305\n%314 = OpBitcast %5 %306\n%315 = OpBitcast %5 %307\n%316 = OpBitcast %5 %308\n%317 = OpCompositeConstruct %36 %313 %314 %315 %316\n%318 = OpAccessChain %122 %309 %76 %77\nOpStore %318 %317\nOpControlBarrier %95 %95 %124\n%320 = OpCompositeConstruct %104 %101 %101\n%319 = OpImageSampleExplicitLod %42 %302 %320 Lod %102\n%321 = OpCompositeExtract %9 %319 0\n%322 = OpCompositeExtract %9 %319 1\n%323 = OpCompositeExtract %9 %319 2\n%324 = OpCompositeExtract %9 %319 3\n%325 = OpCompositeConstruct %26 %77 %76\n%326 = OpCompositeConstruct %42 %321 %322 %323 %324\nOpImageWrite %273 %325 %326\nOpControlBarrier %95 %95 %124\n%327 = OpAccessChain %168 %298 %76 %76\n%328 = OpLoad %42 %327\n%329 = OpCompositeExtract %9 %328 0\n%330 = OpCompositeExtract %9 %328 1\n%331 = OpCompositeExtract %9 %328 2\n%332 = OpCompositeExtract %9 %328 3\n%333 = OpCompositeConstruct %42 %329 %330 %331 %332\nOpImageWrite %280 %77 %333\nOpControlBarrier %95 %95 %124\n%335 = OpCompositeConstruct %104 %101 %101\n%334 = OpImageSampleExplicitLod %42 %302 %335 Lod %102\n%336 = OpCompositeExtract %9 %334 0\n%337 = OpCompositeExtract %9 %334 1\n%338 = OpCompositeExtract %9 %334 2\n%339 = OpCompositeExtract %9 %334 3\n%340 = OpBitcast %5 %336\n%341 = OpBitcast %5 %337\n%342 = OpBitcast %5 %338\n%343 = OpBitcast %5 %339\n%344 = OpCompositeConstruct %36 %340 %341 %342 %343\n%345 = OpAccessChain %122 %284 %76 %77\nOpStore %345 %344\nOpControlBarrier %95 %95 %124\n%346 = OpFunctionCall %5 %243 %294 %27 %76\nOpControlBarrier %95 %95 %124\nOpReturn\nOpFunctionEnd\n%243 = OpFunction %5 None %239\n%240 = OpFunctionParameter %26\n%241 = OpFunctionParameter %5\n%242 = OpFunctionParameter %5\n%244 = OpLabel\n%250 = OpINotEqual %248 %240 %249\n%251 = OpAny %247 %250\nOpSelectionMerge %246 None\nOpBranchConditional %251 %245 %246\n%245 = OpLabel\n%253 = OpBitcast %252 %240\n%254 = OpAtomicIAdd %5 %253 %27 %76 %241\n%255 = OpIAdd %5 %254 %242\nOpBranch %246\n%246 = OpLabel\n%256 = OpPhi %5 %76 %244 %255 %245\nOpReturnValue %256\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/atomics-raw.bindless.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 4, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _23[];\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _36 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _36;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _71 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _72 = uvec2(prime);\n    uvec2 _79 = ((_71 >> uvec2(8u)) ^ _71.yx) * _72;\n    uvec2 _83 = ((_79 >> uvec2(8u)) ^ _79.yx) * _72;\n    uvec2 _87 = ((_83 >> uvec2(8u)) ^ _83.yx) * _72;\n    uvec2 _91 = ((_87 >> uvec2(8u)) ^ _87.yx) * _72;\n    uvec2 _95 = ((_91 >> uvec2(8u)) ^ _91.yx) * _72;\n    return (((_95 >> uvec2(8u)) ^ _95.yx) * _72).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _128;\n    _128._m0 = uaddCarry(BDA.x, offset, _128._m1);\n    uvec2 addr = uvec2(_128._m0, BDA.y + _128._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _482 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _484 = InstrumentationControlData.atomics[_482];\n        uint _490 = (((inst * 97u) ^ 43981u) ^ (_484 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _491 = _490 >> 4u;\n        uint _493 = 1u << (_490 & 15u);\n        uint _495 = atomicOr(InstrumentationControlData.atomics[_491], _493);\n        ShouldReportInstrumentation = false;\n        if ((_495 & _493) == 0u)\n        {\n            InstrumentationData.data[_490] = uvec4(43981u, 0u, inst, _484);\n            memoryBarrierBuffer();\n            uint _503 = atomicOr(InstrumentationControlData.atomics[_491], _493 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _39 = AllocateInvocationID();\n    InvocationID = _39;\n    uvec2 _48 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _53 = uint(_23[registers._m4]._m0.length()) * 4u;\n    uint _60 = gl_GlobalInvocationID.x << 2u;\n    uint _442 = InvocationID;\n    bool _441 = ValidateBDALoadStore(_48, _60, 4u, 2u, _442, _60 < _53);\n    AssumeTrue(_441, 1u);\n    uint _445 = atomicAdd(_23[registers._m4]._m0[gl_GlobalInvocationID.x], 1u);\n    uint _447 = InvocationID;\n    bool _446 = ValidateBDALoadStore(_48, _60, 4u, 2u, _447, _60 < _53);\n    AssumeTrue(_446, 2u);\n    uint _450 = atomicCompSwap(_23[registers._m4]._m0[gl_GlobalInvocationID.x], 5u, 6u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 509\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%152 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %56\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"SSBO\"\nOpName %25 \"BloomBufferInvocationSSBO\"\nOpMemberName %25 0 \"atomics\"\nOpName %27 \"BloomBufferInvocation\"\nOpName %29 \"AllocateInvocationID\"\nOpName %65 \"AddrHash\"\nOpName %63 \"addr\"\nOpName %64 \"prime\"\nOpName %105 \"BloomBufferSSBO\"\nOpMemberName %105 0 \"atomics\"\nOpName %107 \"BloomBuffer\"\nOpName %109 \"BloomBuffer32SSBO\"\nOpMemberName %109 0 \"atomics\"\nOpName %111 \"BloomBuffer32\"\nOpName %119 \"ValidateBDALoadStore\"\nOpName %113 \"BDA\"\nOpName %114 \"offset\"\nOpName %115 \"len\"\nOpName %116 \"type\"\nOpName %117 \"invocation_id\"\nOpName %118 \"in_bounds\"\nOpName %127 \"IAddCarryResult\"\nOpName %132 \"addr\"\nOpName %133 \"addr_lo\"\nOpName %137 \"byte_mask\"\nOpName %147 \"word_mask\"\nOpName %151 \"hash_mask\"\nOpName %156 \"hash_offset\"\nOpName %160 \"bloom_index\"\nOpName %164 \"bloom_index\"\nOpName %168 \"bloom_index\"\nOpName %171 \"bloom_index\"\nOpName %175 \"bloom_index\"\nOpName %179 \"bloom_index\"\nOpName %183 \"bloom_index\"\nOpName %187 \"bloom_index\"\nOpName %191 \"bloom_index\"\nOpName %195 \"bloom_index\"\nOpName %199 \"bloom_index\"\nOpName %203 \"bloom_index\"\nOpName %207 \"bloom_index\"\nOpName %211 \"bloom_index\"\nOpName %215 \"bloom_index\"\nOpName %219 \"bloom_index\"\nOpName %232 \"invalidation_mask\"\nOpName %235 \"prev_hazard_partial\"\nOpName %237 \"prev_hazard_partial\"\nOpName %240 \"prev_hazard_partial\"\nOpName %243 \"prev_hazard_partial\"\nOpName %246 \"prev_hazard_partial\"\nOpName %249 \"prev_hazard_partial\"\nOpName %252 \"prev_hazard_partial\"\nOpName %255 \"prev_hazard_partial\"\nOpName %258 \"prev_hazard_partial\"\nOpName %261 \"prev_hazard_partial\"\nOpName %264 \"prev_hazard_partial\"\nOpName %267 \"prev_hazard_partial\"\nOpName %270 \"prev_hazard_partial\"\nOpName %273 \"prev_hazard_partial\"\nOpName %276 \"prev_hazard_partial\"\nOpName %279 \"prev_hazard_partial\"\nOpName %281 \"prev_hazard\"\nOpName %282 \"prev_hazard_lo\"\nOpName %283 \"prev_hazard_hi\"\nOpName %286 \"has_exclusive_access\"\nOpName %301 \"lock_mask\"\nOpName %304 \"prev_lock\"\nOpName %317 \"lock_mask\"\nOpName %320 \"prev_lock\"\nOpName %334 \"lock_mask\"\nOpName %337 \"prev_lock\"\nOpName %351 \"lock_mask\"\nOpName %354 \"prev_lock\"\nOpName %368 \"lock_mask\"\nOpName %371 \"prev_lock\"\nOpName %382 \"lock_mask\"\nOpName %385 \"prev_lock\"\nOpName %398 \"lock_mask\"\nOpName %401 \"prev_lock\"\nOpName %415 \"lock_mask\"\nOpName %418 \"prev_lock\"\nOpName %421 \"has_complete_self_lock\"\nOpName %437 \"hazard\"\nOpName %455 \"ShouldReportInstrumentation\"\nOpName %458 \"InstrumentationControlDataSSBO\"\nOpMemberName %458 0 \"atomics\"\nOpName %460 \"InstrumentationControlData\"\nOpName %462 \"InstrumentationDataSSBO\"\nOpMemberName %462 0 \"data\"\nOpName %464 \"InstrumentationData\"\nOpName %468 \"AssumeTrue\"\nOpName %466 \"value\"\nOpName %467 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %23 DescriptorSet 4\nOpDecorate %23 Binding 0\nOpDecorate %24 ArrayStride 4\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 2\nOpDecorate %56 BuiltIn GlobalInvocationId\nOpDecorate %104 ArrayStride 8\nOpMemberDecorate %105 0 Offset 0\nOpDecorate %105 Block\nOpDecorate %107 DescriptorSet 0\nOpDecorate %107 Binding 2\nOpDecorate %108 ArrayStride 8\nOpMemberDecorate %109 0 Offset 0\nOpDecorate %109 Block\nOpDecorate %111 DescriptorSet 0\nOpDecorate %111 Binding 2\nOpDecorate %457 ArrayStride 4\nOpMemberDecorate %458 0 Offset 0\nOpDecorate %458 Block\nOpDecorate %460 DescriptorSet 0\nOpDecorate %460 Binding 2\nOpDecorate %461 ArrayStride 16\nOpMemberDecorate %462 0 Offset 0\nOpDecorate %462 Block\nOpDecorate %464 DescriptorSet 0\nOpDecorate %464 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeRuntimeArray %5\n%25 = OpTypeStruct %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeFunction %5\n%33 = OpTypePointer StorageBuffer %5\n%35 = OpConstant %5 0\n%37 = OpConstant %5 1103633207\n%40 = OpTypePointer StorageBuffer %20\n%42 = OpTypePointer PushConstant %5\n%44 = OpConstant %5 4\n%46 = OpTypePointer StorageBuffer %9\n%51 = OpConstant %5 16\n%54 = OpTypeVector %5 3\n%55 = OpTypePointer Input %54\n%56 = OpVariable %55 Input\n%57 = OpTypePointer Input %5\n%61 = OpConstant %5 2\n%62 = OpTypeFunction %5 %9 %5\n%73 = OpConstant %5 65535\n%74 = OpConstant %5 8\n%75 = OpConstantComposite %9 %74 %74\n%102 = OpTypeInt 64 0\n%103 = OpTypeBool\n%104 = OpTypeRuntimeArray %102\n%105 = OpTypeStruct %104\n%106 = OpTypePointer StorageBuffer %105\n%107 = OpVariable %106 StorageBuffer\n%108 = OpTypeRuntimeArray %9\n%109 = OpTypeStruct %108\n%110 = OpTypePointer StorageBuffer %109\n%111 = OpVariable %110 StorageBuffer\n%112 = OpTypeFunction %103 %9 %5 %5 %5 %5 %103\n%123 = OpConstantTrue %103\n%127 = OpTypeStruct %5 %5\n%138 = OpConstant %5 4294967295\n%139 = OpConstant %5 15\n%148 = OpConstant %5 3\n%158 = OpConstant %5 1103515245\n%162 = OpConstant %5 1103518333\n%166 = OpConstant %5 1103539331\n%173 = OpConstant %5 10006121\n%177 = OpConstant %5 4004951\n%181 = OpConstant %5 5005159\n%185 = OpConstant %5 6004811\n%189 = OpConstant %5 383\n%193 = OpConstant %5 821\n%197 = OpConstant %5 661\n%201 = OpConstant %5 1091\n%205 = OpConstant %5 1117\n%209 = OpConstant %5 3947\n%213 = OpConstant %5 4253\n%217 = OpConstant %5 7691\n%220 = OpTypeVector %102 4\n%221 = OpConstant %102 68719411200\n%222 = OpConstant %102 1099511627775\n%223 = OpConstant %102 1035087118335\n%224 = OpConstantComposite %220 %221 %222 %223 %221\n%233 = OpTypePointer StorageBuffer %102\n%288 = OpTypeInt 32 1\n%289 = OpConstant %288 0\n%290 = OpConstant %288 3\n%292 = OpConstant %5 256\n%295 = OpConstant %5 65536\n%298 = OpConstant %288 6\n%300 = OpConstant %5 16777216\n%308 = OpConstant %288 9\n%311 = OpConstant %288 12\n%315 = OpConstant %288 15\n%325 = OpConstant %288 18\n%328 = OpConstant %288 21\n%332 = OpConstant %288 24\n%342 = OpConstant %288 23\n%345 = OpConstant %288 26\n%349 = OpConstant %288 29\n%359 = OpConstant %288 1\n%362 = OpConstant %288 4\n%366 = OpConstant %288 7\n%390 = OpConstant %288 17\n%393 = OpConstant %288 20\n%406 = OpConstant %288 22\n%409 = OpConstant %288 25\n%413 = OpConstant %288 28\n%451 = OpConstant %5 5\n%452 = OpConstant %5 6\n%454 = OpTypePointer Private %103\n%455 = OpVariable %454 Private %123\n%456 = OpTypeVector %5 4\n%457 = OpTypeRuntimeArray %5\n%458 = OpTypeStruct %457\n%459 = OpTypePointer StorageBuffer %458\n%460 = OpVariable %459 StorageBuffer\n%461 = OpTypeRuntimeArray %456\n%462 = OpTypeStruct %461\n%463 = OpTypePointer StorageBuffer %462\n%464 = OpVariable %463 StorageBuffer\n%465 = OpTypeFunction %1 %103 %5\n%479 = OpConstant %5 97\n%480 = OpConstant %5 43981\n%486 = OpConstant %5 51329\n%498 = OpConstantFalse %103\n%501 = OpTypePointer StorageBuffer %456\n%504 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %453\n%453 = OpLabel\n%39 = OpFunctionCall %5 %29\nOpStore %18 %39\n%43 = OpAccessChain %42 %8 %44\n%45 = OpLoad %5 %43\n%47 = OpAccessChain %46 %16 %35 %45 %35 %35\n%48 = OpLoad %9 %47\n%49 = OpCompositeExtract %5 %48 1\n%50 = OpShiftRightLogical %5 %49 %51\n%41 = OpAccessChain %40 %23 %45\n%52 = OpArrayLength %5 %41 0\n%53 = OpIMul %5 %52 %44\n%58 = OpAccessChain %57 %56 %35\n%59 = OpLoad %5 %58\n%60 = OpShiftLeftLogical %5 %59 %61\n%442 = OpLoad %5 %18\n%443 = OpULessThan %103 %60 %53\n%441 = OpFunctionCall %103 %119 %48 %60 %44 %61 %442 %443\n%506 = OpFunctionCall %1 %468 %441 %10\n%444 = OpAccessChain %33 %41 %35 %59\n%445 = OpAtomicIAdd %5 %444 %10 %35 %10\n%447 = OpLoad %5 %18\n%448 = OpULessThan %103 %60 %53\n%446 = OpFunctionCall %103 %119 %48 %60 %44 %61 %447 %448\n%507 = OpFunctionCall %1 %468 %446 %61\n%449 = OpAccessChain %33 %41 %35 %59\n%450 = OpAtomicCompareExchange %5 %449 %10 %35 %35 %452 %451\nOpReturn\nOpFunctionEnd\n%29 = OpFunction %5 None %28\n%30 = OpLabel\n%31 = OpArrayLength %5 %27 0\n%32 = OpISub %5 %31 %10\n%34 = OpAccessChain %33 %27 %35 %32\n%36 = OpAtomicIAdd %5 %34 %10 %35 %37\nOpReturnValue %36\nOpFunctionEnd\n%65 = OpFunction %5 None %62\n%63 = OpFunctionParameter %9\n%64 = OpFunctionParameter %5\n%66 = OpLabel\n%67 = OpCompositeExtract %5 %63 0\n%68 = OpCompositeExtract %5 %63 1\n%69 = OpShiftRightLogical %5 %67 %44\n%70 = OpBitwiseAnd %5 %68 %73\n%71 = OpCompositeConstruct %9 %69 %70\n%72 = OpCompositeConstruct %9 %64 %64\n%76 = OpVectorShuffle %9 %71 %71 1 0\n%77 = OpShiftRightLogical %9 %71 %75\n%78 = OpBitwiseXor %9 %77 %76\n%79 = OpIMul %9 %78 %72\n%80 = OpVectorShuffle %9 %79 %79 1 0\n%81 = OpShiftRightLogical %9 %79 %75\n%82 = OpBitwiseXor %9 %81 %80\n%83 = OpIMul %9 %82 %72\n%84 = OpVectorShuffle %9 %83 %83 1 0\n%85 = OpShiftRightLogical %9 %83 %75\n%86 = OpBitwiseXor %9 %85 %84\n%87 = OpIMul %9 %86 %72\n%88 = OpVectorShuffle %9 %87 %87 1 0\n%89 = OpShiftRightLogical %9 %87 %75\n%90 = OpBitwiseXor %9 %89 %88\n%91 = OpIMul %9 %90 %72\n%92 = OpVectorShuffle %9 %91 %91 1 0\n%93 = OpShiftRightLogical %9 %91 %75\n%94 = OpBitwiseXor %9 %93 %92\n%95 = OpIMul %9 %94 %72\n%96 = OpVectorShuffle %9 %95 %95 1 0\n%97 = OpShiftRightLogical %9 %95 %75\n%98 = OpBitwiseXor %9 %97 %96\n%99 = OpIMul %9 %98 %72\n%100 = OpCompositeExtract %5 %99 0\nOpReturnValue %100\nOpFunctionEnd\n%119 = OpFunction %103 None %112\n%113 = OpFunctionParameter %9\n%114 = OpFunctionParameter %5\n%115 = OpFunctionParameter %5\n%116 = OpFunctionParameter %5\n%117 = OpFunctionParameter %5\n%118 = OpFunctionParameter %103\n%120 = OpLabel\nOpSelectionMerge %122 None\nOpBranchConditional %118 %122 %121\n%121 = OpLabel\nOpReturnValue %123\n%122 = OpLabel\n%125 = OpCompositeExtract %5 %113 0\n%126 = OpCompositeExtract %5 %113 1\n%128 = OpIAddCarry %127 %125 %114\n%129 = OpCompositeExtract %5 %128 0\n%130 = OpCompositeExtract %5 %128 1\n%131 = OpIAdd %5 %126 %130\n%132 = OpCompositeConstruct %9 %129 %131\n%133 = OpCompositeExtract %5 %132 0\n%134 = OpBitFieldUExtract %5 %138 %35 %115\n%135 = OpBitwiseAnd %5 %133 %139\n%136 = OpShiftLeftLogical %5 %134 %135\n%137 = OpBitwiseAnd %5 %136 %73\n%140 = OpBitwiseAnd %5 %133 %148\n%141 = OpIAdd %5 %140 %115\n%142 = OpIAdd %5 %141 %148\n%143 = OpShiftRightLogical %5 %142 %61\n%144 = OpBitFieldUExtract %5 %133 %61 %61\n%145 = OpBitFieldUExtract %5 %138 %35 %143\n%146 = OpShiftLeftLogical %5 %145 %144\n%147 = OpBitwiseAnd %5 %146 %139\n%149 = OpArrayLength %5 %107 0\n%150 = OpExtInst %5 %152 FindUMsb %149\n%151 = OpBitFieldUExtract %5 %138 %35 %150\n%153 = OpArrayLength %5 %107 0\n%154 = OpExtInst %5 %152 FindUMsb %153\n%155 = OpBitFieldUExtract %5 %153 %35 %154\n%156 = OpISub %5 %155 %10\n%157 = OpFunctionCall %5 %65 %132 %158\n%159 = OpBitwiseAnd %5 %157 %151\n%160 = OpIAdd %5 %159 %156\n%161 = OpFunctionCall %5 %65 %132 %162\n%163 = OpBitwiseAnd %5 %161 %151\n%164 = OpIAdd %5 %163 %156\n%165 = OpFunctionCall %5 %65 %132 %166\n%167 = OpBitwiseAnd %5 %165 %151\n%168 = OpIAdd %5 %167 %156\n%169 = OpFunctionCall %5 %65 %132 %37\n%170 = OpBitwiseAnd %5 %169 %151\n%171 = OpIAdd %5 %170 %156\n%172 = OpFunctionCall %5 %65 %132 %173\n%174 = OpBitwiseAnd %5 %172 %151\n%175 = OpIAdd %5 %174 %156\n%176 = OpFunctionCall %5 %65 %132 %177\n%178 = OpBitwiseAnd %5 %176 %151\n%179 = OpIAdd %5 %178 %156\n%180 = OpFunctionCall %5 %65 %132 %181\n%182 = OpBitwiseAnd %5 %180 %151\n%183 = OpIAdd %5 %182 %156\n%184 = OpFunctionCall %5 %65 %132 %185\n%186 = OpBitwiseAnd %5 %184 %151\n%187 = OpIAdd %5 %186 %156\n%188 = OpFunctionCall %5 %65 %132 %189\n%190 = OpBitwiseAnd %5 %188 %151\n%191 = OpIAdd %5 %190 %156\n%192 = OpFunctionCall %5 %65 %132 %193\n%194 = OpBitwiseAnd %5 %192 %151\n%195 = OpIAdd %5 %194 %156\n%196 = OpFunctionCall %5 %65 %132 %197\n%198 = OpBitwiseAnd %5 %196 %151\n%199 = OpIAdd %5 %198 %156\n%200 = OpFunctionCall %5 %65 %132 %201\n%202 = OpBitwiseAnd %5 %200 %151\n%203 = OpIAdd %5 %202 %156\n%204 = OpFunctionCall %5 %65 %132 %205\n%206 = OpBitwiseAnd %5 %204 %151\n%207 = OpIAdd %5 %206 %156\n%208 = OpFunctionCall %5 %65 %132 %209\n%210 = OpBitwiseAnd %5 %208 %151\n%211 = OpIAdd %5 %210 %156\n%212 = OpFunctionCall %5 %65 %132 %213\n%214 = OpBitwiseAnd %5 %212 %151\n%215 = OpIAdd %5 %214 %156\n%216 = OpFunctionCall %5 %65 %132 %217\n%218 = OpBitwiseAnd %5 %216 %151\n%219 = OpIAdd %5 %218 %156\n%225 = OpVectorExtractDynamic %102 %224 %116\n%226 = OpShiftLeftLogical %5 %137 %51\n%227 = OpShiftLeftLogical %5 %147 %44\n%228 = OpBitwiseOr %5 %137 %226\n%229 = OpBitwiseOr %5 %147 %227\n%230 = OpCompositeConstruct %9 %228 %229\n%231 = OpBitcast %102 %230\n%232 = OpBitwiseAnd %102 %225 %231\n%234 = OpInBoundsAccessChain %233 %107 %35 %160\n%235 = OpAtomicOr %102 %234 %10 %35 %232\n%236 = OpInBoundsAccessChain %233 %107 %35 %164\n%237 = OpAtomicOr %102 %236 %10 %35 %232\n%238 = OpBitwiseAnd %102 %235 %237\n%239 = OpInBoundsAccessChain %233 %107 %35 %168\n%240 = OpAtomicOr %102 %239 %10 %35 %232\n%241 = OpBitwiseAnd %102 %238 %240\n%242 = OpInBoundsAccessChain %233 %107 %35 %171\n%243 = OpAtomicOr %102 %242 %10 %35 %232\n%244 = OpBitwiseAnd %102 %241 %243\n%245 = OpInBoundsAccessChain %233 %107 %35 %175\n%246 = OpAtomicOr %102 %245 %10 %35 %232\n%247 = OpBitwiseAnd %102 %244 %246\n%248 = OpInBoundsAccessChain %233 %107 %35 %179\n%249 = OpAtomicOr %102 %248 %10 %35 %232\n%250 = OpBitwiseAnd %102 %247 %249\n%251 = OpInBoundsAccessChain %233 %107 %35 %183\n%252 = OpAtomicOr %102 %251 %10 %35 %232\n%253 = OpBitwiseAnd %102 %250 %252\n%254 = OpInBoundsAccessChain %233 %107 %35 %187\n%255 = OpAtomicOr %102 %254 %10 %35 %232\n%256 = OpBitwiseAnd %102 %253 %255\n%257 = OpInBoundsAccessChain %233 %107 %35 %191\n%258 = OpAtomicOr %102 %257 %10 %35 %232\n%259 = OpBitwiseAnd %102 %256 %258\n%260 = OpInBoundsAccessChain %233 %107 %35 %195\n%261 = OpAtomicOr %102 %260 %10 %35 %232\n%262 = OpBitwiseAnd %102 %259 %261\n%263 = OpInBoundsAccessChain %233 %107 %35 %199\n%264 = OpAtomicOr %102 %263 %10 %35 %232\n%265 = OpBitwiseAnd %102 %262 %264\n%266 = OpInBoundsAccessChain %233 %107 %35 %203\n%267 = OpAtomicOr %102 %266 %10 %35 %232\n%268 = OpBitwiseAnd %102 %265 %267\n%269 = OpInBoundsAccessChain %233 %107 %35 %207\n%270 = OpAtomicOr %102 %269 %10 %35 %232\n%271 = OpBitwiseAnd %102 %268 %270\n%272 = OpInBoundsAccessChain %233 %107 %35 %211\n%273 = OpAtomicOr %102 %272 %10 %35 %232\n%274 = OpBitwiseAnd %102 %271 %273\n%275 = OpInBoundsAccessChain %233 %107 %35 %215\n%276 = OpAtomicOr %102 %275 %10 %35 %232\n%277 = OpBitwiseAnd %102 %274 %276\n%278 = OpInBoundsAccessChain %233 %107 %35 %219\n%279 = OpAtomicOr %102 %278 %10 %35 %232\n%280 = OpBitwiseAnd %102 %277 %279\n%281 = OpBitcast %9 %280\n%282 = OpCompositeExtract %5 %281 0\n%283 = OpCompositeExtract %5 %281 1\n%284 = OpShiftRightLogical %5 %282 %51\n%285 = OpBitwiseAnd %5 %284 %137\n%286 = OpIEqual %103 %285 %35\n%287 = OpBitFieldUExtract %5 %117 %289 %290\n%291 = OpShiftLeftLogical %5 %292 %287\n%293 = OpBitFieldUExtract %5 %117 %290 %290\n%294 = OpShiftLeftLogical %5 %295 %293\n%296 = OpBitwiseOr %5 %291 %294\n%297 = OpBitFieldUExtract %5 %117 %298 %290\n%299 = OpShiftLeftLogical %5 %300 %297\n%301 = OpBitwiseOr %5 %296 %299\n%302 = OpSelect %5 %286 %301 %35\n%303 = OpInBoundsAccessChain %33 %111 %35 %160 %10\n%304 = OpAtomicOr %5 %303 %10 %35 %302\n%305 = OpBitwiseAnd %5 %304 %301\n%306 = OpIEqual %103 %305 %301\n%307 = OpBitFieldUExtract %5 %117 %308 %290\n%309 = OpShiftLeftLogical %5 %292 %307\n%310 = OpBitFieldUExtract %5 %117 %311 %290\n%312 = OpShiftLeftLogical %5 %295 %310\n%313 = OpBitwiseOr %5 %309 %312\n%314 = OpBitFieldUExtract %5 %117 %315 %290\n%316 = OpShiftLeftLogical %5 %300 %314\n%317 = OpBitwiseOr %5 %313 %316\n%318 = OpSelect %5 %286 %317 %35\n%319 = OpInBoundsAccessChain %33 %111 %35 %164 %10\n%320 = OpAtomicOr %5 %319 %10 %35 %318\n%321 = OpBitwiseAnd %5 %320 %317\n%322 = OpIEqual %103 %321 %317\n%323 = OpLogicalAnd %103 %306 %322\n%324 = OpBitFieldUExtract %5 %117 %325 %290\n%326 = OpShiftLeftLogical %5 %292 %324\n%327 = OpBitFieldUExtract %5 %117 %328 %290\n%329 = OpShiftLeftLogical %5 %295 %327\n%330 = OpBitwiseOr %5 %326 %329\n%331 = OpBitFieldUExtract %5 %117 %332 %290\n%333 = OpShiftLeftLogical %5 %300 %331\n%334 = OpBitwiseOr %5 %330 %333\n%335 = OpSelect %5 %286 %334 %35\n%336 = OpInBoundsAccessChain %33 %111 %35 %168 %10\n%337 = OpAtomicOr %5 %336 %10 %35 %335\n%338 = OpBitwiseAnd %5 %337 %334\n%339 = OpIEqual %103 %338 %334\n%340 = OpLogicalAnd %103 %323 %339\n%341 = OpBitFieldUExtract %5 %117 %342 %290\n%343 = OpShiftLeftLogical %5 %292 %341\n%344 = OpBitFieldUExtract %5 %117 %345 %290\n%346 = OpShiftLeftLogical %5 %295 %344\n%347 = OpBitwiseOr %5 %343 %346\n%348 = OpBitFieldUExtract %5 %117 %349 %290\n%350 = OpShiftLeftLogical %5 %300 %348\n%351 = OpBitwiseOr %5 %347 %350\n%352 = OpSelect %5 %286 %351 %35\n%353 = OpInBoundsAccessChain %33 %111 %35 %171 %10\n%354 = OpAtomicOr %5 %353 %10 %35 %352\n%355 = OpBitwiseAnd %5 %354 %351\n%356 = OpIEqual %103 %355 %351\n%357 = OpLogicalAnd %103 %340 %356\n%358 = OpBitFieldUExtract %5 %117 %359 %290\n%360 = OpShiftLeftLogical %5 %292 %358\n%361 = OpBitFieldUExtract %5 %117 %362 %290\n%363 = OpShiftLeftLogical %5 %295 %361\n%364 = OpBitwiseOr %5 %360 %363\n%365 = OpBitFieldUExtract %5 %117 %366 %290\n%367 = OpShiftLeftLogical %5 %300 %365\n%368 = OpBitwiseOr %5 %364 %367\n%369 = OpSelect %5 %286 %368 %35\n%370 = OpInBoundsAccessChain %33 %111 %35 %175 %10\n%371 = OpAtomicOr %5 %370 %10 %35 %369\n%372 = OpBitwiseAnd %5 %371 %368\n%373 = OpIEqual %103 %372 %368\n%374 = OpLogicalAnd %103 %357 %373\n%375 = OpBitFieldUExtract %5 %117 %308 %290\n%376 = OpShiftLeftLogical %5 %292 %375\n%377 = OpBitFieldUExtract %5 %117 %311 %290\n%378 = OpShiftLeftLogical %5 %295 %377\n%379 = OpBitwiseOr %5 %376 %378\n%380 = OpBitFieldUExtract %5 %117 %315 %290\n%381 = OpShiftLeftLogical %5 %300 %380\n%382 = OpBitwiseOr %5 %379 %381\n%383 = OpSelect %5 %286 %382 %35\n%384 = OpInBoundsAccessChain %33 %111 %35 %179 %10\n%385 = OpAtomicOr %5 %384 %10 %35 %383\n%386 = OpBitwiseAnd %5 %385 %382\n%387 = OpIEqual %103 %386 %382\n%388 = OpLogicalAnd %103 %374 %387\n%389 = OpBitFieldUExtract %5 %117 %390 %290\n%391 = OpShiftLeftLogical %5 %292 %389\n%392 = OpBitFieldUExtract %5 %117 %393 %290\n%394 = OpShiftLeftLogical %5 %295 %392\n%395 = OpBitwiseOr %5 %391 %394\n%396 = OpBitFieldUExtract %5 %117 %342 %290\n%397 = OpShiftLeftLogical %5 %300 %396\n%398 = OpBitwiseOr %5 %395 %397\n%399 = OpSelect %5 %286 %398 %35\n%400 = OpInBoundsAccessChain %33 %111 %35 %183 %10\n%401 = OpAtomicOr %5 %400 %10 %35 %399\n%402 = OpBitwiseAnd %5 %401 %398\n%403 = OpIEqual %103 %402 %398\n%404 = OpLogicalAnd %103 %388 %403\n%405 = OpBitFieldUExtract %5 %117 %406 %290\n%407 = OpShiftLeftLogical %5 %292 %405\n%408 = OpBitFieldUExtract %5 %117 %409 %290\n%410 = OpShiftLeftLogical %5 %295 %408\n%411 = OpBitwiseOr %5 %407 %410\n%412 = OpBitFieldUExtract %5 %117 %413 %290\n%414 = OpShiftLeftLogical %5 %300 %412\n%415 = OpBitwiseOr %5 %411 %414\n%416 = OpSelect %5 %286 %415 %35\n%417 = OpInBoundsAccessChain %33 %111 %35 %187 %10\n%418 = OpAtomicOr %5 %417 %10 %35 %416\n%419 = OpBitwiseAnd %5 %418 %415\n%420 = OpIEqual %103 %419 %415\n%421 = OpLogicalAnd %103 %404 %420\nOpSelectionMerge %426 None\nOpSwitch %116 %425 0 %422 1 %423 2 %424\n%425 = OpLabel\n%434 = OpShiftLeftLogical %5 %147 %44\n%435 = OpBitwiseAnd %5 %283 %434\n%436 = OpINotEqual %103 %435 %35\nOpBranch %426\n%422 = OpLabel\n%427 = OpBitwiseAnd %5 %282 %137\n%428 = OpINotEqual %103 %427 %35\nOpBranch %426\n%423 = OpLabel\n%429 = OpShiftLeftLogical %5 %137 %51\n%430 = OpBitwiseAnd %5 %282 %429\n%431 = OpINotEqual %103 %430 %35\nOpBranch %426\n%424 = OpLabel\n%432 = OpBitwiseAnd %5 %283 %147\n%433 = OpINotEqual %103 %432 %35\nOpBranch %426\n%426 = OpLabel\n%437 = OpPhi %103 %428 %422 %431 %423 %433 %424 %436 %425\n%438 = OpLogicalNot %103 %437\n%439 = OpLogicalOr %103 %438 %421\nOpReturnValue %439\nOpFunctionEnd\n%468 = OpFunction %1 None %465\n%466 = OpFunctionParameter %103\n%467 = OpFunctionParameter %5\n%469 = OpLabel\n%472 = OpLogicalNot %103 %466\n%473 = OpLoad %103 %455\n%474 = OpLogicalAnd %103 %472 %473\nOpSelectionMerge %470 None\nOpBranchConditional %474 %471 %470\n%471 = OpLabel\n%477 = OpIMul %5 %467 %479\n%478 = OpBitwiseXor %5 %477 %480\n%481 = OpArrayLength %5 %460 0\n%482 = OpISub %5 %481 %61\n%483 = OpAccessChain %33 %460 %35 %482\n%484 = OpLoad %5 %483\n%485 = OpIMul %5 %484 %486\n%487 = OpBitwiseXor %5 %478 %485\n%488 = OpArrayLength %5 %464 0\n%489 = OpISub %5 %488 %10\n%490 = OpBitwiseAnd %5 %487 %489\n%491 = OpShiftRightLogical %5 %490 %44\n%492 = OpBitwiseAnd %5 %490 %139\n%493 = OpShiftLeftLogical %5 %10 %492\n%494 = OpAccessChain %33 %460 %35 %491\n%495 = OpAtomicOr %5 %494 %10 %35 %493\n%496 = OpBitwiseAnd %5 %495 %493\n%497 = OpIEqual %103 %496 %35\nOpStore %455 %498\nOpSelectionMerge %476 None\nOpBranchConditional %497 %475 %476\n%475 = OpLabel\n%499 = OpCompositeConstruct %456 %480 %35 %467 %484\n%500 = OpShiftLeftLogical %5 %493 %51\n%502 = OpAccessChain %501 %464 %35 %490\nOpStore %502 %499\nOpMemoryBarrier %10 %504\n%503 = OpAtomicOr %5 %494 %10 %35 %500\nOpMemoryBarrier %10 %504\nOpBranch %476\n%476 = OpLabel\nOpBranch %470\n%470 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/atomics-raw.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerUintArray;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerUintArray\n{\n    uint value[];\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _31 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _31;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _56 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _57 = uvec2(prime);\n    uvec2 _64 = ((_56 >> uvec2(8u)) ^ _56.yx) * _57;\n    uvec2 _68 = ((_64 >> uvec2(8u)) ^ _64.yx) * _57;\n    uvec2 _72 = ((_68 >> uvec2(8u)) ^ _68.yx) * _57;\n    uvec2 _76 = ((_72 >> uvec2(8u)) ^ _72.yx) * _57;\n    uvec2 _80 = ((_76 >> uvec2(8u)) ^ _76.yx) * _57;\n    return (((_80 >> uvec2(8u)) ^ _80.yx) * _57).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _113;\n    _113._m0 = uaddCarry(BDA.x, offset, _113._m1);\n    uvec2 addr = uvec2(_113._m0, BDA.y + _113._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _472 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _474 = InstrumentationControlData.atomics[_472];\n        uint _480 = (((inst * 97u) ^ 43981u) ^ (_474 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _481 = _480 >> 4u;\n        uint _483 = 1u << (_480 & 15u);\n        uint _485 = atomicOr(InstrumentationControlData.atomics[_481], _483);\n        ShouldReportInstrumentation = false;\n        if ((_485 & _483) == 0u)\n        {\n            InstrumentationData.data[_480] = uvec4(43981u, 0u, inst, _474);\n            memoryBarrierBuffer();\n            uint _493 = atomicOr(InstrumentationControlData.atomics[_481], _483 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _34 = AllocateInvocationID();\n    InvocationID = _34;\n    uint _45 = gl_GlobalInvocationID.x << 2u;\n    uint _428 = InvocationID;\n    bool _427 = ValidateBDALoadStore(registers._m2, _45, 4u, 2u, _428, true);\n    AssumeTrue(_427, 1u);\n    uint _435 = atomicAdd(PhysicalPointerUintArray(registers._m2).value[gl_GlobalInvocationID.x], 1u);\n    uint _437 = InvocationID;\n    bool _436 = ValidateBDALoadStore(registers._m2, _45, 4u, 2u, _437, true);\n    AssumeTrue(_436, 2u);\n    uint _440 = atomicCompSwap(PhysicalPointerUintArray(registers._m2).value[gl_GlobalInvocationID.x], 5u, 6u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 499\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%137 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %41\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"BloomBufferInvocationSSBO\"\nOpMemberName %20 0 \"atomics\"\nOpName %22 \"BloomBufferInvocation\"\nOpName %24 \"AllocateInvocationID\"\nOpName %50 \"AddrHash\"\nOpName %48 \"addr\"\nOpName %49 \"prime\"\nOpName %90 \"BloomBufferSSBO\"\nOpMemberName %90 0 \"atomics\"\nOpName %92 \"BloomBuffer\"\nOpName %94 \"BloomBuffer32SSBO\"\nOpMemberName %94 0 \"atomics\"\nOpName %96 \"BloomBuffer32\"\nOpName %104 \"ValidateBDALoadStore\"\nOpName %98 \"BDA\"\nOpName %99 \"offset\"\nOpName %100 \"len\"\nOpName %101 \"type\"\nOpName %102 \"invocation_id\"\nOpName %103 \"in_bounds\"\nOpName %112 \"IAddCarryResult\"\nOpName %117 \"addr\"\nOpName %118 \"addr_lo\"\nOpName %122 \"byte_mask\"\nOpName %132 \"word_mask\"\nOpName %136 \"hash_mask\"\nOpName %141 \"hash_offset\"\nOpName %145 \"bloom_index\"\nOpName %149 \"bloom_index\"\nOpName %153 \"bloom_index\"\nOpName %156 \"bloom_index\"\nOpName %160 \"bloom_index\"\nOpName %164 \"bloom_index\"\nOpName %168 \"bloom_index\"\nOpName %172 \"bloom_index\"\nOpName %176 \"bloom_index\"\nOpName %180 \"bloom_index\"\nOpName %184 \"bloom_index\"\nOpName %188 \"bloom_index\"\nOpName %192 \"bloom_index\"\nOpName %196 \"bloom_index\"\nOpName %200 \"bloom_index\"\nOpName %204 \"bloom_index\"\nOpName %218 \"invalidation_mask\"\nOpName %221 \"prev_hazard_partial\"\nOpName %223 \"prev_hazard_partial\"\nOpName %226 \"prev_hazard_partial\"\nOpName %229 \"prev_hazard_partial\"\nOpName %232 \"prev_hazard_partial\"\nOpName %235 \"prev_hazard_partial\"\nOpName %238 \"prev_hazard_partial\"\nOpName %241 \"prev_hazard_partial\"\nOpName %244 \"prev_hazard_partial\"\nOpName %247 \"prev_hazard_partial\"\nOpName %250 \"prev_hazard_partial\"\nOpName %253 \"prev_hazard_partial\"\nOpName %256 \"prev_hazard_partial\"\nOpName %259 \"prev_hazard_partial\"\nOpName %262 \"prev_hazard_partial\"\nOpName %265 \"prev_hazard_partial\"\nOpName %267 \"prev_hazard\"\nOpName %268 \"prev_hazard_lo\"\nOpName %269 \"prev_hazard_hi\"\nOpName %272 \"has_exclusive_access\"\nOpName %287 \"lock_mask\"\nOpName %290 \"prev_lock\"\nOpName %303 \"lock_mask\"\nOpName %306 \"prev_lock\"\nOpName %320 \"lock_mask\"\nOpName %323 \"prev_lock\"\nOpName %337 \"lock_mask\"\nOpName %340 \"prev_lock\"\nOpName %354 \"lock_mask\"\nOpName %357 \"prev_lock\"\nOpName %368 \"lock_mask\"\nOpName %371 \"prev_lock\"\nOpName %384 \"lock_mask\"\nOpName %387 \"prev_lock\"\nOpName %401 \"lock_mask\"\nOpName %404 \"prev_lock\"\nOpName %407 \"has_complete_self_lock\"\nOpName %423 \"hazard\"\nOpName %430 \"PhysicalPointerUintArray\"\nOpMemberName %430 0 \"value\"\nOpName %445 \"ShouldReportInstrumentation\"\nOpName %448 \"InstrumentationControlDataSSBO\"\nOpMemberName %448 0 \"atomics\"\nOpName %450 \"InstrumentationControlData\"\nOpName %452 \"InstrumentationDataSSBO\"\nOpMemberName %452 0 \"data\"\nOpName %454 \"InstrumentationData\"\nOpName %458 \"AssumeTrue\"\nOpName %456 \"value\"\nOpName %457 \"inst\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 2\nOpDecorate %41 BuiltIn GlobalInvocationId\nOpDecorate %89 ArrayStride 8\nOpMemberDecorate %90 0 Offset 0\nOpDecorate %90 Block\nOpDecorate %92 DescriptorSet 0\nOpDecorate %92 Binding 2\nOpDecorate %93 ArrayStride 8\nOpMemberDecorate %94 0 Offset 0\nOpDecorate %94 Block\nOpDecorate %96 DescriptorSet 0\nOpDecorate %96 Binding 2\nOpDecorate %429 ArrayStride 4\nOpMemberDecorate %430 0 Offset 0\nOpDecorate %430 Block\nOpDecorate %447 ArrayStride 4\nOpMemberDecorate %448 0 Offset 0\nOpDecorate %448 Block\nOpDecorate %450 DescriptorSet 0\nOpDecorate %450 Binding 2\nOpDecorate %451 ArrayStride 16\nOpMemberDecorate %452 0 Offset 0\nOpDecorate %452 Block\nOpDecorate %454 DescriptorSet 0\nOpDecorate %454 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpConstant %5 1\n%11 = OpTypeArray %6 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeFunction %5\n%28 = OpTypePointer StorageBuffer %5\n%30 = OpConstant %5 0\n%32 = OpConstant %5 1103633207\n%35 = OpTypePointer PushConstant %6\n%37 = OpConstant %5 2\n%39 = OpTypeVector %5 3\n%40 = OpTypePointer Input %39\n%41 = OpVariable %40 Input\n%42 = OpTypePointer Input %5\n%46 = OpConstant %5 4\n%47 = OpTypeFunction %5 %6 %5\n%58 = OpConstant %5 65535\n%59 = OpConstant %5 8\n%60 = OpConstantComposite %6 %59 %59\n%87 = OpTypeInt 64 0\n%88 = OpTypeBool\n%89 = OpTypeRuntimeArray %87\n%90 = OpTypeStruct %89\n%91 = OpTypePointer StorageBuffer %90\n%92 = OpVariable %91 StorageBuffer\n%93 = OpTypeRuntimeArray %6\n%94 = OpTypeStruct %93\n%95 = OpTypePointer StorageBuffer %94\n%96 = OpVariable %95 StorageBuffer\n%97 = OpTypeFunction %88 %6 %5 %5 %5 %5 %88\n%108 = OpConstantTrue %88\n%112 = OpTypeStruct %5 %5\n%123 = OpConstant %5 4294967295\n%124 = OpConstant %5 15\n%133 = OpConstant %5 3\n%143 = OpConstant %5 1103515245\n%147 = OpConstant %5 1103518333\n%151 = OpConstant %5 1103539331\n%158 = OpConstant %5 10006121\n%162 = OpConstant %5 4004951\n%166 = OpConstant %5 5005159\n%170 = OpConstant %5 6004811\n%174 = OpConstant %5 383\n%178 = OpConstant %5 821\n%182 = OpConstant %5 661\n%186 = OpConstant %5 1091\n%190 = OpConstant %5 1117\n%194 = OpConstant %5 3947\n%198 = OpConstant %5 4253\n%202 = OpConstant %5 7691\n%205 = OpTypeVector %87 4\n%206 = OpConstant %87 68719411200\n%207 = OpConstant %87 1099511627775\n%208 = OpConstant %87 1035087118335\n%209 = OpConstantComposite %205 %206 %207 %208 %206\n%213 = OpConstant %5 16\n%219 = OpTypePointer StorageBuffer %87\n%274 = OpTypeInt 32 1\n%275 = OpConstant %274 0\n%276 = OpConstant %274 3\n%278 = OpConstant %5 256\n%281 = OpConstant %5 65536\n%284 = OpConstant %274 6\n%286 = OpConstant %5 16777216\n%294 = OpConstant %274 9\n%297 = OpConstant %274 12\n%301 = OpConstant %274 15\n%311 = OpConstant %274 18\n%314 = OpConstant %274 21\n%318 = OpConstant %274 24\n%328 = OpConstant %274 23\n%331 = OpConstant %274 26\n%335 = OpConstant %274 29\n%345 = OpConstant %274 1\n%348 = OpConstant %274 4\n%352 = OpConstant %274 7\n%376 = OpConstant %274 17\n%379 = OpConstant %274 20\n%392 = OpConstant %274 22\n%395 = OpConstant %274 25\n%399 = OpConstant %274 28\n%429 = OpTypeRuntimeArray %5\n%430 = OpTypeStruct %429\n%431 = OpTypePointer PhysicalStorageBuffer %430\n%433 = OpTypePointer PhysicalStorageBuffer %5\n%441 = OpConstant %5 5\n%442 = OpConstant %5 6\n%444 = OpTypePointer Private %88\n%445 = OpVariable %444 Private %108\n%446 = OpTypeVector %5 4\n%447 = OpTypeRuntimeArray %5\n%448 = OpTypeStruct %447\n%449 = OpTypePointer StorageBuffer %448\n%450 = OpVariable %449 StorageBuffer\n%451 = OpTypeRuntimeArray %446\n%452 = OpTypeStruct %451\n%453 = OpTypePointer StorageBuffer %452\n%454 = OpVariable %453 StorageBuffer\n%455 = OpTypeFunction %1 %88 %5\n%469 = OpConstant %5 97\n%470 = OpConstant %5 43981\n%476 = OpConstant %5 51329\n%488 = OpConstantFalse %88\n%491 = OpTypePointer StorageBuffer %446\n%494 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %443\n%443 = OpLabel\n%34 = OpFunctionCall %5 %24\nOpStore %18 %34\n%36 = OpAccessChain %35 %9 %37\n%38 = OpLoad %6 %36\n%43 = OpAccessChain %42 %41 %30\n%44 = OpLoad %5 %43\n%45 = OpShiftLeftLogical %5 %44 %37\n%428 = OpLoad %5 %18\n%427 = OpFunctionCall %88 %104 %38 %45 %46 %37 %428 %108\n%496 = OpFunctionCall %1 %458 %427 %10\n%432 = OpBitcast %431 %38\n%434 = OpAccessChain %433 %432 %30 %44\n%435 = OpAtomicIAdd %5 %434 %10 %30 %10\n%437 = OpLoad %5 %18\n%436 = OpFunctionCall %88 %104 %38 %45 %46 %37 %437 %108\n%497 = OpFunctionCall %1 %458 %436 %37\n%438 = OpBitcast %431 %38\n%439 = OpAccessChain %433 %438 %30 %44\n%440 = OpAtomicCompareExchange %5 %439 %10 %30 %30 %442 %441\nOpReturn\nOpFunctionEnd\n%24 = OpFunction %5 None %23\n%25 = OpLabel\n%26 = OpArrayLength %5 %22 0\n%27 = OpISub %5 %26 %10\n%29 = OpAccessChain %28 %22 %30 %27\n%31 = OpAtomicIAdd %5 %29 %10 %30 %32\nOpReturnValue %31\nOpFunctionEnd\n%50 = OpFunction %5 None %47\n%48 = OpFunctionParameter %6\n%49 = OpFunctionParameter %5\n%51 = OpLabel\n%52 = OpCompositeExtract %5 %48 0\n%53 = OpCompositeExtract %5 %48 1\n%54 = OpShiftRightLogical %5 %52 %46\n%55 = OpBitwiseAnd %5 %53 %58\n%56 = OpCompositeConstruct %6 %54 %55\n%57 = OpCompositeConstruct %6 %49 %49\n%61 = OpVectorShuffle %6 %56 %56 1 0\n%62 = OpShiftRightLogical %6 %56 %60\n%63 = OpBitwiseXor %6 %62 %61\n%64 = OpIMul %6 %63 %57\n%65 = OpVectorShuffle %6 %64 %64 1 0\n%66 = OpShiftRightLogical %6 %64 %60\n%67 = OpBitwiseXor %6 %66 %65\n%68 = OpIMul %6 %67 %57\n%69 = OpVectorShuffle %6 %68 %68 1 0\n%70 = OpShiftRightLogical %6 %68 %60\n%71 = OpBitwiseXor %6 %70 %69\n%72 = OpIMul %6 %71 %57\n%73 = OpVectorShuffle %6 %72 %72 1 0\n%74 = OpShiftRightLogical %6 %72 %60\n%75 = OpBitwiseXor %6 %74 %73\n%76 = OpIMul %6 %75 %57\n%77 = OpVectorShuffle %6 %76 %76 1 0\n%78 = OpShiftRightLogical %6 %76 %60\n%79 = OpBitwiseXor %6 %78 %77\n%80 = OpIMul %6 %79 %57\n%81 = OpVectorShuffle %6 %80 %80 1 0\n%82 = OpShiftRightLogical %6 %80 %60\n%83 = OpBitwiseXor %6 %82 %81\n%84 = OpIMul %6 %83 %57\n%85 = OpCompositeExtract %5 %84 0\nOpReturnValue %85\nOpFunctionEnd\n%104 = OpFunction %88 None %97\n%98 = OpFunctionParameter %6\n%99 = OpFunctionParameter %5\n%100 = OpFunctionParameter %5\n%101 = OpFunctionParameter %5\n%102 = OpFunctionParameter %5\n%103 = OpFunctionParameter %88\n%105 = OpLabel\nOpSelectionMerge %107 None\nOpBranchConditional %103 %107 %106\n%106 = OpLabel\nOpReturnValue %108\n%107 = OpLabel\n%110 = OpCompositeExtract %5 %98 0\n%111 = OpCompositeExtract %5 %98 1\n%113 = OpIAddCarry %112 %110 %99\n%114 = OpCompositeExtract %5 %113 0\n%115 = OpCompositeExtract %5 %113 1\n%116 = OpIAdd %5 %111 %115\n%117 = OpCompositeConstruct %6 %114 %116\n%118 = OpCompositeExtract %5 %117 0\n%119 = OpBitFieldUExtract %5 %123 %30 %100\n%120 = OpBitwiseAnd %5 %118 %124\n%121 = OpShiftLeftLogical %5 %119 %120\n%122 = OpBitwiseAnd %5 %121 %58\n%125 = OpBitwiseAnd %5 %118 %133\n%126 = OpIAdd %5 %125 %100\n%127 = OpIAdd %5 %126 %133\n%128 = OpShiftRightLogical %5 %127 %37\n%129 = OpBitFieldUExtract %5 %118 %37 %37\n%130 = OpBitFieldUExtract %5 %123 %30 %128\n%131 = OpShiftLeftLogical %5 %130 %129\n%132 = OpBitwiseAnd %5 %131 %124\n%134 = OpArrayLength %5 %92 0\n%135 = OpExtInst %5 %137 FindUMsb %134\n%136 = OpBitFieldUExtract %5 %123 %30 %135\n%138 = OpArrayLength %5 %92 0\n%139 = OpExtInst %5 %137 FindUMsb %138\n%140 = OpBitFieldUExtract %5 %138 %30 %139\n%141 = OpISub %5 %140 %10\n%142 = OpFunctionCall %5 %50 %117 %143\n%144 = OpBitwiseAnd %5 %142 %136\n%145 = OpIAdd %5 %144 %141\n%146 = OpFunctionCall %5 %50 %117 %147\n%148 = OpBitwiseAnd %5 %146 %136\n%149 = OpIAdd %5 %148 %141\n%150 = OpFunctionCall %5 %50 %117 %151\n%152 = OpBitwiseAnd %5 %150 %136\n%153 = OpIAdd %5 %152 %141\n%154 = OpFunctionCall %5 %50 %117 %32\n%155 = OpBitwiseAnd %5 %154 %136\n%156 = OpIAdd %5 %155 %141\n%157 = OpFunctionCall %5 %50 %117 %158\n%159 = OpBitwiseAnd %5 %157 %136\n%160 = OpIAdd %5 %159 %141\n%161 = OpFunctionCall %5 %50 %117 %162\n%163 = OpBitwiseAnd %5 %161 %136\n%164 = OpIAdd %5 %163 %141\n%165 = OpFunctionCall %5 %50 %117 %166\n%167 = OpBitwiseAnd %5 %165 %136\n%168 = OpIAdd %5 %167 %141\n%169 = OpFunctionCall %5 %50 %117 %170\n%171 = OpBitwiseAnd %5 %169 %136\n%172 = OpIAdd %5 %171 %141\n%173 = OpFunctionCall %5 %50 %117 %174\n%175 = OpBitwiseAnd %5 %173 %136\n%176 = OpIAdd %5 %175 %141\n%177 = OpFunctionCall %5 %50 %117 %178\n%179 = OpBitwiseAnd %5 %177 %136\n%180 = OpIAdd %5 %179 %141\n%181 = OpFunctionCall %5 %50 %117 %182\n%183 = OpBitwiseAnd %5 %181 %136\n%184 = OpIAdd %5 %183 %141\n%185 = OpFunctionCall %5 %50 %117 %186\n%187 = OpBitwiseAnd %5 %185 %136\n%188 = OpIAdd %5 %187 %141\n%189 = OpFunctionCall %5 %50 %117 %190\n%191 = OpBitwiseAnd %5 %189 %136\n%192 = OpIAdd %5 %191 %141\n%193 = OpFunctionCall %5 %50 %117 %194\n%195 = OpBitwiseAnd %5 %193 %136\n%196 = OpIAdd %5 %195 %141\n%197 = OpFunctionCall %5 %50 %117 %198\n%199 = OpBitwiseAnd %5 %197 %136\n%200 = OpIAdd %5 %199 %141\n%201 = OpFunctionCall %5 %50 %117 %202\n%203 = OpBitwiseAnd %5 %201 %136\n%204 = OpIAdd %5 %203 %141\n%210 = OpVectorExtractDynamic %87 %209 %101\n%211 = OpShiftLeftLogical %5 %122 %213\n%212 = OpShiftLeftLogical %5 %132 %46\n%214 = OpBitwiseOr %5 %122 %211\n%215 = OpBitwiseOr %5 %132 %212\n%216 = OpCompositeConstruct %6 %214 %215\n%217 = OpBitcast %87 %216\n%218 = OpBitwiseAnd %87 %210 %217\n%220 = OpInBoundsAccessChain %219 %92 %30 %145\n%221 = OpAtomicOr %87 %220 %10 %30 %218\n%222 = OpInBoundsAccessChain %219 %92 %30 %149\n%223 = OpAtomicOr %87 %222 %10 %30 %218\n%224 = OpBitwiseAnd %87 %221 %223\n%225 = OpInBoundsAccessChain %219 %92 %30 %153\n%226 = OpAtomicOr %87 %225 %10 %30 %218\n%227 = OpBitwiseAnd %87 %224 %226\n%228 = OpInBoundsAccessChain %219 %92 %30 %156\n%229 = OpAtomicOr %87 %228 %10 %30 %218\n%230 = OpBitwiseAnd %87 %227 %229\n%231 = OpInBoundsAccessChain %219 %92 %30 %160\n%232 = OpAtomicOr %87 %231 %10 %30 %218\n%233 = OpBitwiseAnd %87 %230 %232\n%234 = OpInBoundsAccessChain %219 %92 %30 %164\n%235 = OpAtomicOr %87 %234 %10 %30 %218\n%236 = OpBitwiseAnd %87 %233 %235\n%237 = OpInBoundsAccessChain %219 %92 %30 %168\n%238 = OpAtomicOr %87 %237 %10 %30 %218\n%239 = OpBitwiseAnd %87 %236 %238\n%240 = OpInBoundsAccessChain %219 %92 %30 %172\n%241 = OpAtomicOr %87 %240 %10 %30 %218\n%242 = OpBitwiseAnd %87 %239 %241\n%243 = OpInBoundsAccessChain %219 %92 %30 %176\n%244 = OpAtomicOr %87 %243 %10 %30 %218\n%245 = OpBitwiseAnd %87 %242 %244\n%246 = OpInBoundsAccessChain %219 %92 %30 %180\n%247 = OpAtomicOr %87 %246 %10 %30 %218\n%248 = OpBitwiseAnd %87 %245 %247\n%249 = OpInBoundsAccessChain %219 %92 %30 %184\n%250 = OpAtomicOr %87 %249 %10 %30 %218\n%251 = OpBitwiseAnd %87 %248 %250\n%252 = OpInBoundsAccessChain %219 %92 %30 %188\n%253 = OpAtomicOr %87 %252 %10 %30 %218\n%254 = OpBitwiseAnd %87 %251 %253\n%255 = OpInBoundsAccessChain %219 %92 %30 %192\n%256 = OpAtomicOr %87 %255 %10 %30 %218\n%257 = OpBitwiseAnd %87 %254 %256\n%258 = OpInBoundsAccessChain %219 %92 %30 %196\n%259 = OpAtomicOr %87 %258 %10 %30 %218\n%260 = OpBitwiseAnd %87 %257 %259\n%261 = OpInBoundsAccessChain %219 %92 %30 %200\n%262 = OpAtomicOr %87 %261 %10 %30 %218\n%263 = OpBitwiseAnd %87 %260 %262\n%264 = OpInBoundsAccessChain %219 %92 %30 %204\n%265 = OpAtomicOr %87 %264 %10 %30 %218\n%266 = OpBitwiseAnd %87 %263 %265\n%267 = OpBitcast %6 %266\n%268 = OpCompositeExtract %5 %267 0\n%269 = OpCompositeExtract %5 %267 1\n%270 = OpShiftRightLogical %5 %268 %213\n%271 = OpBitwiseAnd %5 %270 %122\n%272 = OpIEqual %88 %271 %30\n%273 = OpBitFieldUExtract %5 %102 %275 %276\n%277 = OpShiftLeftLogical %5 %278 %273\n%279 = OpBitFieldUExtract %5 %102 %276 %276\n%280 = OpShiftLeftLogical %5 %281 %279\n%282 = OpBitwiseOr %5 %277 %280\n%283 = OpBitFieldUExtract %5 %102 %284 %276\n%285 = OpShiftLeftLogical %5 %286 %283\n%287 = OpBitwiseOr %5 %282 %285\n%288 = OpSelect %5 %272 %287 %30\n%289 = OpInBoundsAccessChain %28 %96 %30 %145 %10\n%290 = OpAtomicOr %5 %289 %10 %30 %288\n%291 = OpBitwiseAnd %5 %290 %287\n%292 = OpIEqual %88 %291 %287\n%293 = OpBitFieldUExtract %5 %102 %294 %276\n%295 = OpShiftLeftLogical %5 %278 %293\n%296 = OpBitFieldUExtract %5 %102 %297 %276\n%298 = OpShiftLeftLogical %5 %281 %296\n%299 = OpBitwiseOr %5 %295 %298\n%300 = OpBitFieldUExtract %5 %102 %301 %276\n%302 = OpShiftLeftLogical %5 %286 %300\n%303 = OpBitwiseOr %5 %299 %302\n%304 = OpSelect %5 %272 %303 %30\n%305 = OpInBoundsAccessChain %28 %96 %30 %149 %10\n%306 = OpAtomicOr %5 %305 %10 %30 %304\n%307 = OpBitwiseAnd %5 %306 %303\n%308 = OpIEqual %88 %307 %303\n%309 = OpLogicalAnd %88 %292 %308\n%310 = OpBitFieldUExtract %5 %102 %311 %276\n%312 = OpShiftLeftLogical %5 %278 %310\n%313 = OpBitFieldUExtract %5 %102 %314 %276\n%315 = OpShiftLeftLogical %5 %281 %313\n%316 = OpBitwiseOr %5 %312 %315\n%317 = OpBitFieldUExtract %5 %102 %318 %276\n%319 = OpShiftLeftLogical %5 %286 %317\n%320 = OpBitwiseOr %5 %316 %319\n%321 = OpSelect %5 %272 %320 %30\n%322 = OpInBoundsAccessChain %28 %96 %30 %153 %10\n%323 = OpAtomicOr %5 %322 %10 %30 %321\n%324 = OpBitwiseAnd %5 %323 %320\n%325 = OpIEqual %88 %324 %320\n%326 = OpLogicalAnd %88 %309 %325\n%327 = OpBitFieldUExtract %5 %102 %328 %276\n%329 = OpShiftLeftLogical %5 %278 %327\n%330 = OpBitFieldUExtract %5 %102 %331 %276\n%332 = OpShiftLeftLogical %5 %281 %330\n%333 = OpBitwiseOr %5 %329 %332\n%334 = OpBitFieldUExtract %5 %102 %335 %276\n%336 = OpShiftLeftLogical %5 %286 %334\n%337 = OpBitwiseOr %5 %333 %336\n%338 = OpSelect %5 %272 %337 %30\n%339 = OpInBoundsAccessChain %28 %96 %30 %156 %10\n%340 = OpAtomicOr %5 %339 %10 %30 %338\n%341 = OpBitwiseAnd %5 %340 %337\n%342 = OpIEqual %88 %341 %337\n%343 = OpLogicalAnd %88 %326 %342\n%344 = OpBitFieldUExtract %5 %102 %345 %276\n%346 = OpShiftLeftLogical %5 %278 %344\n%347 = OpBitFieldUExtract %5 %102 %348 %276\n%349 = OpShiftLeftLogical %5 %281 %347\n%350 = OpBitwiseOr %5 %346 %349\n%351 = OpBitFieldUExtract %5 %102 %352 %276\n%353 = OpShiftLeftLogical %5 %286 %351\n%354 = OpBitwiseOr %5 %350 %353\n%355 = OpSelect %5 %272 %354 %30\n%356 = OpInBoundsAccessChain %28 %96 %30 %160 %10\n%357 = OpAtomicOr %5 %356 %10 %30 %355\n%358 = OpBitwiseAnd %5 %357 %354\n%359 = OpIEqual %88 %358 %354\n%360 = OpLogicalAnd %88 %343 %359\n%361 = OpBitFieldUExtract %5 %102 %294 %276\n%362 = OpShiftLeftLogical %5 %278 %361\n%363 = OpBitFieldUExtract %5 %102 %297 %276\n%364 = OpShiftLeftLogical %5 %281 %363\n%365 = OpBitwiseOr %5 %362 %364\n%366 = OpBitFieldUExtract %5 %102 %301 %276\n%367 = OpShiftLeftLogical %5 %286 %366\n%368 = OpBitwiseOr %5 %365 %367\n%369 = OpSelect %5 %272 %368 %30\n%370 = OpInBoundsAccessChain %28 %96 %30 %164 %10\n%371 = OpAtomicOr %5 %370 %10 %30 %369\n%372 = OpBitwiseAnd %5 %371 %368\n%373 = OpIEqual %88 %372 %368\n%374 = OpLogicalAnd %88 %360 %373\n%375 = OpBitFieldUExtract %5 %102 %376 %276\n%377 = OpShiftLeftLogical %5 %278 %375\n%378 = OpBitFieldUExtract %5 %102 %379 %276\n%380 = OpShiftLeftLogical %5 %281 %378\n%381 = OpBitwiseOr %5 %377 %380\n%382 = OpBitFieldUExtract %5 %102 %328 %276\n%383 = OpShiftLeftLogical %5 %286 %382\n%384 = OpBitwiseOr %5 %381 %383\n%385 = OpSelect %5 %272 %384 %30\n%386 = OpInBoundsAccessChain %28 %96 %30 %168 %10\n%387 = OpAtomicOr %5 %386 %10 %30 %385\n%388 = OpBitwiseAnd %5 %387 %384\n%389 = OpIEqual %88 %388 %384\n%390 = OpLogicalAnd %88 %374 %389\n%391 = OpBitFieldUExtract %5 %102 %392 %276\n%393 = OpShiftLeftLogical %5 %278 %391\n%394 = OpBitFieldUExtract %5 %102 %395 %276\n%396 = OpShiftLeftLogical %5 %281 %394\n%397 = OpBitwiseOr %5 %393 %396\n%398 = OpBitFieldUExtract %5 %102 %399 %276\n%400 = OpShiftLeftLogical %5 %286 %398\n%401 = OpBitwiseOr %5 %397 %400\n%402 = OpSelect %5 %272 %401 %30\n%403 = OpInBoundsAccessChain %28 %96 %30 %172 %10\n%404 = OpAtomicOr %5 %403 %10 %30 %402\n%405 = OpBitwiseAnd %5 %404 %401\n%406 = OpIEqual %88 %405 %401\n%407 = OpLogicalAnd %88 %390 %406\nOpSelectionMerge %412 None\nOpSwitch %101 %411 0 %408 1 %409 2 %410\n%411 = OpLabel\n%420 = OpShiftLeftLogical %5 %132 %46\n%421 = OpBitwiseAnd %5 %269 %420\n%422 = OpINotEqual %88 %421 %30\nOpBranch %412\n%408 = OpLabel\n%413 = OpBitwiseAnd %5 %268 %122\n%414 = OpINotEqual %88 %413 %30\nOpBranch %412\n%409 = OpLabel\n%415 = OpShiftLeftLogical %5 %122 %213\n%416 = OpBitwiseAnd %5 %268 %415\n%417 = OpINotEqual %88 %416 %30\nOpBranch %412\n%410 = OpLabel\n%418 = OpBitwiseAnd %5 %269 %132\n%419 = OpINotEqual %88 %418 %30\nOpBranch %412\n%412 = OpLabel\n%423 = OpPhi %88 %414 %408 %417 %409 %419 %410 %422 %411\n%424 = OpLogicalNot %88 %423\n%425 = OpLogicalOr %88 %424 %407\nOpReturnValue %425\nOpFunctionEnd\n%458 = OpFunction %1 None %455\n%456 = OpFunctionParameter %88\n%457 = OpFunctionParameter %5\n%459 = OpLabel\n%462 = OpLogicalNot %88 %456\n%463 = OpLoad %88 %445\n%464 = OpLogicalAnd %88 %462 %463\nOpSelectionMerge %460 None\nOpBranchConditional %464 %461 %460\n%461 = OpLabel\n%467 = OpIMul %5 %457 %469\n%468 = OpBitwiseXor %5 %467 %470\n%471 = OpArrayLength %5 %450 0\n%472 = OpISub %5 %471 %37\n%473 = OpAccessChain %28 %450 %30 %472\n%474 = OpLoad %5 %473\n%475 = OpIMul %5 %474 %476\n%477 = OpBitwiseXor %5 %468 %475\n%478 = OpArrayLength %5 %454 0\n%479 = OpISub %5 %478 %10\n%480 = OpBitwiseAnd %5 %477 %479\n%481 = OpShiftRightLogical %5 %480 %46\n%482 = OpBitwiseAnd %5 %480 %124\n%483 = OpShiftLeftLogical %5 %10 %482\n%484 = OpAccessChain %28 %450 %30 %481\n%485 = OpAtomicOr %5 %484 %10 %30 %483\n%486 = OpBitwiseAnd %5 %485 %483\n%487 = OpIEqual %88 %486 %30\nOpStore %445 %488\nOpSelectionMerge %466 None\nOpBranchConditional %487 %465 %466\n%465 = OpLabel\n%489 = OpCompositeConstruct %446 %470 %30 %457 %474\n%490 = OpShiftLeftLogical %5 %483 %213\n%492 = OpAccessChain %491 %454 %30 %480\nOpStore %492 %489\nOpMemoryBarrier %10 %494\n%493 = OpAtomicOr %5 %484 %10 %30 %490\nOpMemoryBarrier %10 %494\nOpBranch %466\n%466 = OpLabel\nOpBranch %460\n%460 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/atomics-structured-counter.bindless.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 4, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _23[];\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _27;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nuint InvocationID;\n\nuint AllocateInvocationID()\n{\n    uint _40 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _40;\n}\n\nuint RobustPhysicalAtomicCounter(uvec2 _74, uint _75, uint _76)\n{\n    uint _90;\n    if (any(notEqual(_74, uvec2(0u))))\n    {\n        uint _88 = atomicAdd(uintPointer(_74).value, _75);\n        _90 = _88 + _76;\n    }\n    else\n    {\n        _90 = 0u;\n    }\n    return _90;\n}\n\nvoid main()\n{\n    uint _43 = AllocateInvocationID();\n    InvocationID = _43;\n    uvec2 _61 = _27.counters[registers._m4];\n    uint _69 = atomicAdd(_23[registers._m4]._m0[gl_GlobalInvocationID.x], 1u);\n    uint _71 = atomicCompSwap(_23[registers._m4]._m0[gl_GlobalInvocationID.x], 1u, 2u);\n    uint _92 = RobustPhysicalAtomicCounter(_61, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %64\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"SSBO\"\nOpName %25 \"AtomicCounters\"\nOpMemberName %25 0 \"counters\"\nOpName %29 \"BloomBufferInvocationSSBO\"\nOpMemberName %29 0 \"atomics\"\nOpName %31 \"BloomBufferInvocation\"\nOpName %33 \"AllocateInvocationID\"\nOpName %77 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %23 DescriptorSet 4\nOpDecorate %23 Binding 0\nOpDecorate %24 ArrayStride 8\nOpDecorate %25 Block\nOpMemberDecorate %25 0 Offset 0\nOpMemberDecorate %25 0 NonWritable\nOpDecorate %27 DescriptorSet 7\nOpDecorate %27 Binding 0\nOpDecorate %27 AliasedPointer\nOpDecorate %28 ArrayStride 4\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 2\nOpDecorate %64 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeRuntimeArray %9\n%25 = OpTypeStruct %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeRuntimeArray %5\n%29 = OpTypeStruct %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeFunction %5\n%37 = OpTypePointer StorageBuffer %5\n%39 = OpConstant %5 0\n%41 = OpConstant %5 1103633207\n%44 = OpTypePointer StorageBuffer %20\n%46 = OpTypePointer PushConstant %5\n%48 = OpConstant %5 4\n%50 = OpTypePointer StorageBuffer %9\n%55 = OpConstant %5 16\n%62 = OpTypeVector %5 3\n%63 = OpTypePointer Input %62\n%64 = OpVariable %63 Input\n%65 = OpTypePointer Input %5\n%72 = OpConstant %5 2\n%73 = OpTypeFunction %5 %9 %5 %5\n%81 = OpTypeBool\n%82 = OpTypeVector %81 2\n%83 = OpConstantNull %9\n%86 = OpTypePointer PhysicalStorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%43 = OpFunctionCall %5 %33\nOpStore %18 %43\n%47 = OpAccessChain %46 %8 %48\n%49 = OpLoad %5 %47\n%51 = OpAccessChain %50 %16 %39 %49 %39 %39\n%52 = OpLoad %9 %51\n%53 = OpCompositeExtract %5 %52 1\n%54 = OpShiftRightLogical %5 %53 %55\n%45 = OpAccessChain %44 %23 %49\n%56 = OpArrayLength %5 %45 0\n%57 = OpIMul %5 %56 %48\n%59 = OpAccessChain %46 %8 %48\n%60 = OpLoad %5 %59\n%58 = OpAccessChain %50 %27 %39 %60\n%61 = OpLoad %9 %58\n%66 = OpAccessChain %65 %64 %39\n%67 = OpLoad %5 %66\n%68 = OpAccessChain %37 %45 %39 %67\n%69 = OpAtomicIAdd %5 %68 %10 %39 %10\n%70 = OpAccessChain %37 %45 %39 %67\n%71 = OpAtomicCompareExchange %5 %70 %10 %39 %39 %72 %10\n%92 = OpFunctionCall %5 %77 %61 %10 %39\nOpReturn\nOpFunctionEnd\n%33 = OpFunction %5 None %32\n%34 = OpLabel\n%35 = OpArrayLength %5 %31 0\n%36 = OpISub %5 %35 %10\n%38 = OpAccessChain %37 %31 %39 %36\n%40 = OpAtomicIAdd %5 %38 %10 %39 %41\nOpReturnValue %40\nOpFunctionEnd\n%77 = OpFunction %5 None %73\n%74 = OpFunctionParameter %9\n%75 = OpFunctionParameter %5\n%76 = OpFunctionParameter %5\n%78 = OpLabel\n%84 = OpINotEqual %82 %74 %83\n%85 = OpAny %81 %84\nOpSelectionMerge %80 None\nOpBranchConditional %85 %79 %80\n%79 = OpLabel\n%87 = OpBitcast %86 %74\n%88 = OpAtomicIAdd %5 %87 %10 %39 %75\n%89 = OpIAdd %5 %88 %76\nOpBranch %80\n%80 = OpLabel\n%90 = OpPhi %5 %39 %78 %89 %79\nOpReturnValue %90\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/atomics-structured.bindless.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 4, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _23[];\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _36 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _36;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _71 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _72 = uvec2(prime);\n    uvec2 _79 = ((_71 >> uvec2(8u)) ^ _71.yx) * _72;\n    uvec2 _83 = ((_79 >> uvec2(8u)) ^ _79.yx) * _72;\n    uvec2 _87 = ((_83 >> uvec2(8u)) ^ _83.yx) * _72;\n    uvec2 _91 = ((_87 >> uvec2(8u)) ^ _87.yx) * _72;\n    uvec2 _95 = ((_91 >> uvec2(8u)) ^ _91.yx) * _72;\n    return (((_95 >> uvec2(8u)) ^ _95.yx) * _72).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _128;\n    _128._m0 = uaddCarry(BDA.x, offset, _128._m1);\n    uvec2 addr = uvec2(_128._m0, BDA.y + _128._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _483 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _485 = InstrumentationControlData.atomics[_483];\n        uint _491 = (((inst * 97u) ^ 43981u) ^ (_485 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _492 = _491 >> 4u;\n        uint _494 = 1u << (_491 & 15u);\n        uint _496 = atomicOr(InstrumentationControlData.atomics[_492], _494);\n        ShouldReportInstrumentation = false;\n        if ((_496 & _494) == 0u)\n        {\n            InstrumentationData.data[_491] = uvec4(43981u, 0u, inst, _485);\n            memoryBarrierBuffer();\n            uint _504 = atomicOr(InstrumentationControlData.atomics[_492], _494 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _39 = AllocateInvocationID();\n    InvocationID = _39;\n    uvec2 _48 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _53 = uint(_23[registers._m4]._m0.length()) * 4u;\n    uint _61 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _443 = InvocationID;\n    bool _442 = ValidateBDALoadStore(_48, _61, 4u, 2u, _443, _61 < _53);\n    AssumeTrue(_442, 1u);\n    uint _446 = atomicAdd(_23[registers._m4]._m0[gl_GlobalInvocationID.x], 1u);\n    uint _448 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _450 = InvocationID;\n    bool _449 = ValidateBDALoadStore(_48, _448, 4u, 2u, _450, _448 < _53);\n    AssumeTrue(_449, 2u);\n    uint _453 = atomicCompSwap(_23[registers._m4]._m0[gl_GlobalInvocationID.x], 1u, 2u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 510\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%153 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %56\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"SSBO\"\nOpName %25 \"BloomBufferInvocationSSBO\"\nOpMemberName %25 0 \"atomics\"\nOpName %27 \"BloomBufferInvocation\"\nOpName %29 \"AllocateInvocationID\"\nOpName %65 \"AddrHash\"\nOpName %63 \"addr\"\nOpName %64 \"prime\"\nOpName %105 \"BloomBufferSSBO\"\nOpMemberName %105 0 \"atomics\"\nOpName %107 \"BloomBuffer\"\nOpName %109 \"BloomBuffer32SSBO\"\nOpMemberName %109 0 \"atomics\"\nOpName %111 \"BloomBuffer32\"\nOpName %119 \"ValidateBDALoadStore\"\nOpName %113 \"BDA\"\nOpName %114 \"offset\"\nOpName %115 \"len\"\nOpName %116 \"type\"\nOpName %117 \"invocation_id\"\nOpName %118 \"in_bounds\"\nOpName %127 \"IAddCarryResult\"\nOpName %132 \"addr\"\nOpName %133 \"addr_lo\"\nOpName %137 \"byte_mask\"\nOpName %147 \"word_mask\"\nOpName %152 \"hash_mask\"\nOpName %157 \"hash_offset\"\nOpName %161 \"bloom_index\"\nOpName %165 \"bloom_index\"\nOpName %169 \"bloom_index\"\nOpName %172 \"bloom_index\"\nOpName %176 \"bloom_index\"\nOpName %180 \"bloom_index\"\nOpName %184 \"bloom_index\"\nOpName %188 \"bloom_index\"\nOpName %192 \"bloom_index\"\nOpName %196 \"bloom_index\"\nOpName %200 \"bloom_index\"\nOpName %204 \"bloom_index\"\nOpName %208 \"bloom_index\"\nOpName %212 \"bloom_index\"\nOpName %216 \"bloom_index\"\nOpName %220 \"bloom_index\"\nOpName %233 \"invalidation_mask\"\nOpName %236 \"prev_hazard_partial\"\nOpName %238 \"prev_hazard_partial\"\nOpName %241 \"prev_hazard_partial\"\nOpName %244 \"prev_hazard_partial\"\nOpName %247 \"prev_hazard_partial\"\nOpName %250 \"prev_hazard_partial\"\nOpName %253 \"prev_hazard_partial\"\nOpName %256 \"prev_hazard_partial\"\nOpName %259 \"prev_hazard_partial\"\nOpName %262 \"prev_hazard_partial\"\nOpName %265 \"prev_hazard_partial\"\nOpName %268 \"prev_hazard_partial\"\nOpName %271 \"prev_hazard_partial\"\nOpName %274 \"prev_hazard_partial\"\nOpName %277 \"prev_hazard_partial\"\nOpName %280 \"prev_hazard_partial\"\nOpName %282 \"prev_hazard\"\nOpName %283 \"prev_hazard_lo\"\nOpName %284 \"prev_hazard_hi\"\nOpName %287 \"has_exclusive_access\"\nOpName %302 \"lock_mask\"\nOpName %305 \"prev_lock\"\nOpName %318 \"lock_mask\"\nOpName %321 \"prev_lock\"\nOpName %335 \"lock_mask\"\nOpName %338 \"prev_lock\"\nOpName %352 \"lock_mask\"\nOpName %355 \"prev_lock\"\nOpName %369 \"lock_mask\"\nOpName %372 \"prev_lock\"\nOpName %383 \"lock_mask\"\nOpName %386 \"prev_lock\"\nOpName %399 \"lock_mask\"\nOpName %402 \"prev_lock\"\nOpName %416 \"lock_mask\"\nOpName %419 \"prev_lock\"\nOpName %422 \"has_complete_self_lock\"\nOpName %438 \"hazard\"\nOpName %456 \"ShouldReportInstrumentation\"\nOpName %459 \"InstrumentationControlDataSSBO\"\nOpMemberName %459 0 \"atomics\"\nOpName %461 \"InstrumentationControlData\"\nOpName %463 \"InstrumentationDataSSBO\"\nOpMemberName %463 0 \"data\"\nOpName %465 \"InstrumentationData\"\nOpName %469 \"AssumeTrue\"\nOpName %467 \"value\"\nOpName %468 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %23 DescriptorSet 4\nOpDecorate %23 Binding 0\nOpDecorate %24 ArrayStride 4\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 2\nOpDecorate %56 BuiltIn GlobalInvocationId\nOpDecorate %104 ArrayStride 8\nOpMemberDecorate %105 0 Offset 0\nOpDecorate %105 Block\nOpDecorate %107 DescriptorSet 0\nOpDecorate %107 Binding 2\nOpDecorate %108 ArrayStride 8\nOpMemberDecorate %109 0 Offset 0\nOpDecorate %109 Block\nOpDecorate %111 DescriptorSet 0\nOpDecorate %111 Binding 2\nOpDecorate %458 ArrayStride 4\nOpMemberDecorate %459 0 Offset 0\nOpDecorate %459 Block\nOpDecorate %461 DescriptorSet 0\nOpDecorate %461 Binding 2\nOpDecorate %462 ArrayStride 16\nOpMemberDecorate %463 0 Offset 0\nOpDecorate %463 Block\nOpDecorate %465 DescriptorSet 0\nOpDecorate %465 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeRuntimeArray %5\n%25 = OpTypeStruct %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeFunction %5\n%33 = OpTypePointer StorageBuffer %5\n%35 = OpConstant %5 0\n%37 = OpConstant %5 1103633207\n%40 = OpTypePointer StorageBuffer %20\n%42 = OpTypePointer PushConstant %5\n%44 = OpConstant %5 4\n%46 = OpTypePointer StorageBuffer %9\n%51 = OpConstant %5 16\n%54 = OpTypeVector %5 3\n%55 = OpTypePointer Input %54\n%56 = OpVariable %55 Input\n%57 = OpTypePointer Input %5\n%62 = OpTypeFunction %5 %9 %5\n%73 = OpConstant %5 65535\n%74 = OpConstant %5 8\n%75 = OpConstantComposite %9 %74 %74\n%102 = OpTypeInt 64 0\n%103 = OpTypeBool\n%104 = OpTypeRuntimeArray %102\n%105 = OpTypeStruct %104\n%106 = OpTypePointer StorageBuffer %105\n%107 = OpVariable %106 StorageBuffer\n%108 = OpTypeRuntimeArray %9\n%109 = OpTypeStruct %108\n%110 = OpTypePointer StorageBuffer %109\n%111 = OpVariable %110 StorageBuffer\n%112 = OpTypeFunction %103 %9 %5 %5 %5 %5 %103\n%123 = OpConstantTrue %103\n%127 = OpTypeStruct %5 %5\n%138 = OpConstant %5 4294967295\n%139 = OpConstant %5 15\n%148 = OpConstant %5 3\n%149 = OpConstant %5 2\n%159 = OpConstant %5 1103515245\n%163 = OpConstant %5 1103518333\n%167 = OpConstant %5 1103539331\n%174 = OpConstant %5 10006121\n%178 = OpConstant %5 4004951\n%182 = OpConstant %5 5005159\n%186 = OpConstant %5 6004811\n%190 = OpConstant %5 383\n%194 = OpConstant %5 821\n%198 = OpConstant %5 661\n%202 = OpConstant %5 1091\n%206 = OpConstant %5 1117\n%210 = OpConstant %5 3947\n%214 = OpConstant %5 4253\n%218 = OpConstant %5 7691\n%221 = OpTypeVector %102 4\n%222 = OpConstant %102 68719411200\n%223 = OpConstant %102 1099511627775\n%224 = OpConstant %102 1035087118335\n%225 = OpConstantComposite %221 %222 %223 %224 %222\n%234 = OpTypePointer StorageBuffer %102\n%289 = OpTypeInt 32 1\n%290 = OpConstant %289 0\n%291 = OpConstant %289 3\n%293 = OpConstant %5 256\n%296 = OpConstant %5 65536\n%299 = OpConstant %289 6\n%301 = OpConstant %5 16777216\n%309 = OpConstant %289 9\n%312 = OpConstant %289 12\n%316 = OpConstant %289 15\n%326 = OpConstant %289 18\n%329 = OpConstant %289 21\n%333 = OpConstant %289 24\n%343 = OpConstant %289 23\n%346 = OpConstant %289 26\n%350 = OpConstant %289 29\n%360 = OpConstant %289 1\n%363 = OpConstant %289 4\n%367 = OpConstant %289 7\n%391 = OpConstant %289 17\n%394 = OpConstant %289 20\n%407 = OpConstant %289 22\n%410 = OpConstant %289 25\n%414 = OpConstant %289 28\n%455 = OpTypePointer Private %103\n%456 = OpVariable %455 Private %123\n%457 = OpTypeVector %5 4\n%458 = OpTypeRuntimeArray %5\n%459 = OpTypeStruct %458\n%460 = OpTypePointer StorageBuffer %459\n%461 = OpVariable %460 StorageBuffer\n%462 = OpTypeRuntimeArray %457\n%463 = OpTypeStruct %462\n%464 = OpTypePointer StorageBuffer %463\n%465 = OpVariable %464 StorageBuffer\n%466 = OpTypeFunction %1 %103 %5\n%480 = OpConstant %5 97\n%481 = OpConstant %5 43981\n%487 = OpConstant %5 51329\n%499 = OpConstantFalse %103\n%502 = OpTypePointer StorageBuffer %457\n%505 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %454\n%454 = OpLabel\n%39 = OpFunctionCall %5 %29\nOpStore %18 %39\n%43 = OpAccessChain %42 %8 %44\n%45 = OpLoad %5 %43\n%47 = OpAccessChain %46 %16 %35 %45 %35 %35\n%48 = OpLoad %9 %47\n%49 = OpCompositeExtract %5 %48 1\n%50 = OpShiftRightLogical %5 %49 %51\n%41 = OpAccessChain %40 %23 %45\n%52 = OpArrayLength %5 %41 0\n%53 = OpIMul %5 %52 %44\n%58 = OpAccessChain %57 %56 %35\n%59 = OpLoad %5 %58\n%60 = OpIMul %5 %59 %44\n%61 = OpIAdd %5 %60 %35\n%443 = OpLoad %5 %18\n%444 = OpULessThan %103 %61 %53\n%442 = OpFunctionCall %103 %119 %48 %61 %44 %149 %443 %444\n%507 = OpFunctionCall %1 %469 %442 %10\n%445 = OpAccessChain %33 %41 %35 %59\n%446 = OpAtomicIAdd %5 %445 %10 %35 %10\n%447 = OpIMul %5 %59 %44\n%448 = OpIAdd %5 %447 %35\n%450 = OpLoad %5 %18\n%451 = OpULessThan %103 %448 %53\n%449 = OpFunctionCall %103 %119 %48 %448 %44 %149 %450 %451\n%508 = OpFunctionCall %1 %469 %449 %149\n%452 = OpAccessChain %33 %41 %35 %59\n%453 = OpAtomicCompareExchange %5 %452 %10 %35 %35 %149 %10\nOpReturn\nOpFunctionEnd\n%29 = OpFunction %5 None %28\n%30 = OpLabel\n%31 = OpArrayLength %5 %27 0\n%32 = OpISub %5 %31 %10\n%34 = OpAccessChain %33 %27 %35 %32\n%36 = OpAtomicIAdd %5 %34 %10 %35 %37\nOpReturnValue %36\nOpFunctionEnd\n%65 = OpFunction %5 None %62\n%63 = OpFunctionParameter %9\n%64 = OpFunctionParameter %5\n%66 = OpLabel\n%67 = OpCompositeExtract %5 %63 0\n%68 = OpCompositeExtract %5 %63 1\n%69 = OpShiftRightLogical %5 %67 %44\n%70 = OpBitwiseAnd %5 %68 %73\n%71 = OpCompositeConstruct %9 %69 %70\n%72 = OpCompositeConstruct %9 %64 %64\n%76 = OpVectorShuffle %9 %71 %71 1 0\n%77 = OpShiftRightLogical %9 %71 %75\n%78 = OpBitwiseXor %9 %77 %76\n%79 = OpIMul %9 %78 %72\n%80 = OpVectorShuffle %9 %79 %79 1 0\n%81 = OpShiftRightLogical %9 %79 %75\n%82 = OpBitwiseXor %9 %81 %80\n%83 = OpIMul %9 %82 %72\n%84 = OpVectorShuffle %9 %83 %83 1 0\n%85 = OpShiftRightLogical %9 %83 %75\n%86 = OpBitwiseXor %9 %85 %84\n%87 = OpIMul %9 %86 %72\n%88 = OpVectorShuffle %9 %87 %87 1 0\n%89 = OpShiftRightLogical %9 %87 %75\n%90 = OpBitwiseXor %9 %89 %88\n%91 = OpIMul %9 %90 %72\n%92 = OpVectorShuffle %9 %91 %91 1 0\n%93 = OpShiftRightLogical %9 %91 %75\n%94 = OpBitwiseXor %9 %93 %92\n%95 = OpIMul %9 %94 %72\n%96 = OpVectorShuffle %9 %95 %95 1 0\n%97 = OpShiftRightLogical %9 %95 %75\n%98 = OpBitwiseXor %9 %97 %96\n%99 = OpIMul %9 %98 %72\n%100 = OpCompositeExtract %5 %99 0\nOpReturnValue %100\nOpFunctionEnd\n%119 = OpFunction %103 None %112\n%113 = OpFunctionParameter %9\n%114 = OpFunctionParameter %5\n%115 = OpFunctionParameter %5\n%116 = OpFunctionParameter %5\n%117 = OpFunctionParameter %5\n%118 = OpFunctionParameter %103\n%120 = OpLabel\nOpSelectionMerge %122 None\nOpBranchConditional %118 %122 %121\n%121 = OpLabel\nOpReturnValue %123\n%122 = OpLabel\n%125 = OpCompositeExtract %5 %113 0\n%126 = OpCompositeExtract %5 %113 1\n%128 = OpIAddCarry %127 %125 %114\n%129 = OpCompositeExtract %5 %128 0\n%130 = OpCompositeExtract %5 %128 1\n%131 = OpIAdd %5 %126 %130\n%132 = OpCompositeConstruct %9 %129 %131\n%133 = OpCompositeExtract %5 %132 0\n%134 = OpBitFieldUExtract %5 %138 %35 %115\n%135 = OpBitwiseAnd %5 %133 %139\n%136 = OpShiftLeftLogical %5 %134 %135\n%137 = OpBitwiseAnd %5 %136 %73\n%140 = OpBitwiseAnd %5 %133 %148\n%141 = OpIAdd %5 %140 %115\n%142 = OpIAdd %5 %141 %148\n%143 = OpShiftRightLogical %5 %142 %149\n%144 = OpBitFieldUExtract %5 %133 %149 %149\n%145 = OpBitFieldUExtract %5 %138 %35 %143\n%146 = OpShiftLeftLogical %5 %145 %144\n%147 = OpBitwiseAnd %5 %146 %139\n%150 = OpArrayLength %5 %107 0\n%151 = OpExtInst %5 %153 FindUMsb %150\n%152 = OpBitFieldUExtract %5 %138 %35 %151\n%154 = OpArrayLength %5 %107 0\n%155 = OpExtInst %5 %153 FindUMsb %154\n%156 = OpBitFieldUExtract %5 %154 %35 %155\n%157 = OpISub %5 %156 %10\n%158 = OpFunctionCall %5 %65 %132 %159\n%160 = OpBitwiseAnd %5 %158 %152\n%161 = OpIAdd %5 %160 %157\n%162 = OpFunctionCall %5 %65 %132 %163\n%164 = OpBitwiseAnd %5 %162 %152\n%165 = OpIAdd %5 %164 %157\n%166 = OpFunctionCall %5 %65 %132 %167\n%168 = OpBitwiseAnd %5 %166 %152\n%169 = OpIAdd %5 %168 %157\n%170 = OpFunctionCall %5 %65 %132 %37\n%171 = OpBitwiseAnd %5 %170 %152\n%172 = OpIAdd %5 %171 %157\n%173 = OpFunctionCall %5 %65 %132 %174\n%175 = OpBitwiseAnd %5 %173 %152\n%176 = OpIAdd %5 %175 %157\n%177 = OpFunctionCall %5 %65 %132 %178\n%179 = OpBitwiseAnd %5 %177 %152\n%180 = OpIAdd %5 %179 %157\n%181 = OpFunctionCall %5 %65 %132 %182\n%183 = OpBitwiseAnd %5 %181 %152\n%184 = OpIAdd %5 %183 %157\n%185 = OpFunctionCall %5 %65 %132 %186\n%187 = OpBitwiseAnd %5 %185 %152\n%188 = OpIAdd %5 %187 %157\n%189 = OpFunctionCall %5 %65 %132 %190\n%191 = OpBitwiseAnd %5 %189 %152\n%192 = OpIAdd %5 %191 %157\n%193 = OpFunctionCall %5 %65 %132 %194\n%195 = OpBitwiseAnd %5 %193 %152\n%196 = OpIAdd %5 %195 %157\n%197 = OpFunctionCall %5 %65 %132 %198\n%199 = OpBitwiseAnd %5 %197 %152\n%200 = OpIAdd %5 %199 %157\n%201 = OpFunctionCall %5 %65 %132 %202\n%203 = OpBitwiseAnd %5 %201 %152\n%204 = OpIAdd %5 %203 %157\n%205 = OpFunctionCall %5 %65 %132 %206\n%207 = OpBitwiseAnd %5 %205 %152\n%208 = OpIAdd %5 %207 %157\n%209 = OpFunctionCall %5 %65 %132 %210\n%211 = OpBitwiseAnd %5 %209 %152\n%212 = OpIAdd %5 %211 %157\n%213 = OpFunctionCall %5 %65 %132 %214\n%215 = OpBitwiseAnd %5 %213 %152\n%216 = OpIAdd %5 %215 %157\n%217 = OpFunctionCall %5 %65 %132 %218\n%219 = OpBitwiseAnd %5 %217 %152\n%220 = OpIAdd %5 %219 %157\n%226 = OpVectorExtractDynamic %102 %225 %116\n%227 = OpShiftLeftLogical %5 %137 %51\n%228 = OpShiftLeftLogical %5 %147 %44\n%229 = OpBitwiseOr %5 %137 %227\n%230 = OpBitwiseOr %5 %147 %228\n%231 = OpCompositeConstruct %9 %229 %230\n%232 = OpBitcast %102 %231\n%233 = OpBitwiseAnd %102 %226 %232\n%235 = OpInBoundsAccessChain %234 %107 %35 %161\n%236 = OpAtomicOr %102 %235 %10 %35 %233\n%237 = OpInBoundsAccessChain %234 %107 %35 %165\n%238 = OpAtomicOr %102 %237 %10 %35 %233\n%239 = OpBitwiseAnd %102 %236 %238\n%240 = OpInBoundsAccessChain %234 %107 %35 %169\n%241 = OpAtomicOr %102 %240 %10 %35 %233\n%242 = OpBitwiseAnd %102 %239 %241\n%243 = OpInBoundsAccessChain %234 %107 %35 %172\n%244 = OpAtomicOr %102 %243 %10 %35 %233\n%245 = OpBitwiseAnd %102 %242 %244\n%246 = OpInBoundsAccessChain %234 %107 %35 %176\n%247 = OpAtomicOr %102 %246 %10 %35 %233\n%248 = OpBitwiseAnd %102 %245 %247\n%249 = OpInBoundsAccessChain %234 %107 %35 %180\n%250 = OpAtomicOr %102 %249 %10 %35 %233\n%251 = OpBitwiseAnd %102 %248 %250\n%252 = OpInBoundsAccessChain %234 %107 %35 %184\n%253 = OpAtomicOr %102 %252 %10 %35 %233\n%254 = OpBitwiseAnd %102 %251 %253\n%255 = OpInBoundsAccessChain %234 %107 %35 %188\n%256 = OpAtomicOr %102 %255 %10 %35 %233\n%257 = OpBitwiseAnd %102 %254 %256\n%258 = OpInBoundsAccessChain %234 %107 %35 %192\n%259 = OpAtomicOr %102 %258 %10 %35 %233\n%260 = OpBitwiseAnd %102 %257 %259\n%261 = OpInBoundsAccessChain %234 %107 %35 %196\n%262 = OpAtomicOr %102 %261 %10 %35 %233\n%263 = OpBitwiseAnd %102 %260 %262\n%264 = OpInBoundsAccessChain %234 %107 %35 %200\n%265 = OpAtomicOr %102 %264 %10 %35 %233\n%266 = OpBitwiseAnd %102 %263 %265\n%267 = OpInBoundsAccessChain %234 %107 %35 %204\n%268 = OpAtomicOr %102 %267 %10 %35 %233\n%269 = OpBitwiseAnd %102 %266 %268\n%270 = OpInBoundsAccessChain %234 %107 %35 %208\n%271 = OpAtomicOr %102 %270 %10 %35 %233\n%272 = OpBitwiseAnd %102 %269 %271\n%273 = OpInBoundsAccessChain %234 %107 %35 %212\n%274 = OpAtomicOr %102 %273 %10 %35 %233\n%275 = OpBitwiseAnd %102 %272 %274\n%276 = OpInBoundsAccessChain %234 %107 %35 %216\n%277 = OpAtomicOr %102 %276 %10 %35 %233\n%278 = OpBitwiseAnd %102 %275 %277\n%279 = OpInBoundsAccessChain %234 %107 %35 %220\n%280 = OpAtomicOr %102 %279 %10 %35 %233\n%281 = OpBitwiseAnd %102 %278 %280\n%282 = OpBitcast %9 %281\n%283 = OpCompositeExtract %5 %282 0\n%284 = OpCompositeExtract %5 %282 1\n%285 = OpShiftRightLogical %5 %283 %51\n%286 = OpBitwiseAnd %5 %285 %137\n%287 = OpIEqual %103 %286 %35\n%288 = OpBitFieldUExtract %5 %117 %290 %291\n%292 = OpShiftLeftLogical %5 %293 %288\n%294 = OpBitFieldUExtract %5 %117 %291 %291\n%295 = OpShiftLeftLogical %5 %296 %294\n%297 = OpBitwiseOr %5 %292 %295\n%298 = OpBitFieldUExtract %5 %117 %299 %291\n%300 = OpShiftLeftLogical %5 %301 %298\n%302 = OpBitwiseOr %5 %297 %300\n%303 = OpSelect %5 %287 %302 %35\n%304 = OpInBoundsAccessChain %33 %111 %35 %161 %10\n%305 = OpAtomicOr %5 %304 %10 %35 %303\n%306 = OpBitwiseAnd %5 %305 %302\n%307 = OpIEqual %103 %306 %302\n%308 = OpBitFieldUExtract %5 %117 %309 %291\n%310 = OpShiftLeftLogical %5 %293 %308\n%311 = OpBitFieldUExtract %5 %117 %312 %291\n%313 = OpShiftLeftLogical %5 %296 %311\n%314 = OpBitwiseOr %5 %310 %313\n%315 = OpBitFieldUExtract %5 %117 %316 %291\n%317 = OpShiftLeftLogical %5 %301 %315\n%318 = OpBitwiseOr %5 %314 %317\n%319 = OpSelect %5 %287 %318 %35\n%320 = OpInBoundsAccessChain %33 %111 %35 %165 %10\n%321 = OpAtomicOr %5 %320 %10 %35 %319\n%322 = OpBitwiseAnd %5 %321 %318\n%323 = OpIEqual %103 %322 %318\n%324 = OpLogicalAnd %103 %307 %323\n%325 = OpBitFieldUExtract %5 %117 %326 %291\n%327 = OpShiftLeftLogical %5 %293 %325\n%328 = OpBitFieldUExtract %5 %117 %329 %291\n%330 = OpShiftLeftLogical %5 %296 %328\n%331 = OpBitwiseOr %5 %327 %330\n%332 = OpBitFieldUExtract %5 %117 %333 %291\n%334 = OpShiftLeftLogical %5 %301 %332\n%335 = OpBitwiseOr %5 %331 %334\n%336 = OpSelect %5 %287 %335 %35\n%337 = OpInBoundsAccessChain %33 %111 %35 %169 %10\n%338 = OpAtomicOr %5 %337 %10 %35 %336\n%339 = OpBitwiseAnd %5 %338 %335\n%340 = OpIEqual %103 %339 %335\n%341 = OpLogicalAnd %103 %324 %340\n%342 = OpBitFieldUExtract %5 %117 %343 %291\n%344 = OpShiftLeftLogical %5 %293 %342\n%345 = OpBitFieldUExtract %5 %117 %346 %291\n%347 = OpShiftLeftLogical %5 %296 %345\n%348 = OpBitwiseOr %5 %344 %347\n%349 = OpBitFieldUExtract %5 %117 %350 %291\n%351 = OpShiftLeftLogical %5 %301 %349\n%352 = OpBitwiseOr %5 %348 %351\n%353 = OpSelect %5 %287 %352 %35\n%354 = OpInBoundsAccessChain %33 %111 %35 %172 %10\n%355 = OpAtomicOr %5 %354 %10 %35 %353\n%356 = OpBitwiseAnd %5 %355 %352\n%357 = OpIEqual %103 %356 %352\n%358 = OpLogicalAnd %103 %341 %357\n%359 = OpBitFieldUExtract %5 %117 %360 %291\n%361 = OpShiftLeftLogical %5 %293 %359\n%362 = OpBitFieldUExtract %5 %117 %363 %291\n%364 = OpShiftLeftLogical %5 %296 %362\n%365 = OpBitwiseOr %5 %361 %364\n%366 = OpBitFieldUExtract %5 %117 %367 %291\n%368 = OpShiftLeftLogical %5 %301 %366\n%369 = OpBitwiseOr %5 %365 %368\n%370 = OpSelect %5 %287 %369 %35\n%371 = OpInBoundsAccessChain %33 %111 %35 %176 %10\n%372 = OpAtomicOr %5 %371 %10 %35 %370\n%373 = OpBitwiseAnd %5 %372 %369\n%374 = OpIEqual %103 %373 %369\n%375 = OpLogicalAnd %103 %358 %374\n%376 = OpBitFieldUExtract %5 %117 %309 %291\n%377 = OpShiftLeftLogical %5 %293 %376\n%378 = OpBitFieldUExtract %5 %117 %312 %291\n%379 = OpShiftLeftLogical %5 %296 %378\n%380 = OpBitwiseOr %5 %377 %379\n%381 = OpBitFieldUExtract %5 %117 %316 %291\n%382 = OpShiftLeftLogical %5 %301 %381\n%383 = OpBitwiseOr %5 %380 %382\n%384 = OpSelect %5 %287 %383 %35\n%385 = OpInBoundsAccessChain %33 %111 %35 %180 %10\n%386 = OpAtomicOr %5 %385 %10 %35 %384\n%387 = OpBitwiseAnd %5 %386 %383\n%388 = OpIEqual %103 %387 %383\n%389 = OpLogicalAnd %103 %375 %388\n%390 = OpBitFieldUExtract %5 %117 %391 %291\n%392 = OpShiftLeftLogical %5 %293 %390\n%393 = OpBitFieldUExtract %5 %117 %394 %291\n%395 = OpShiftLeftLogical %5 %296 %393\n%396 = OpBitwiseOr %5 %392 %395\n%397 = OpBitFieldUExtract %5 %117 %343 %291\n%398 = OpShiftLeftLogical %5 %301 %397\n%399 = OpBitwiseOr %5 %396 %398\n%400 = OpSelect %5 %287 %399 %35\n%401 = OpInBoundsAccessChain %33 %111 %35 %184 %10\n%402 = OpAtomicOr %5 %401 %10 %35 %400\n%403 = OpBitwiseAnd %5 %402 %399\n%404 = OpIEqual %103 %403 %399\n%405 = OpLogicalAnd %103 %389 %404\n%406 = OpBitFieldUExtract %5 %117 %407 %291\n%408 = OpShiftLeftLogical %5 %293 %406\n%409 = OpBitFieldUExtract %5 %117 %410 %291\n%411 = OpShiftLeftLogical %5 %296 %409\n%412 = OpBitwiseOr %5 %408 %411\n%413 = OpBitFieldUExtract %5 %117 %414 %291\n%415 = OpShiftLeftLogical %5 %301 %413\n%416 = OpBitwiseOr %5 %412 %415\n%417 = OpSelect %5 %287 %416 %35\n%418 = OpInBoundsAccessChain %33 %111 %35 %188 %10\n%419 = OpAtomicOr %5 %418 %10 %35 %417\n%420 = OpBitwiseAnd %5 %419 %416\n%421 = OpIEqual %103 %420 %416\n%422 = OpLogicalAnd %103 %405 %421\nOpSelectionMerge %427 None\nOpSwitch %116 %426 0 %423 1 %424 2 %425\n%426 = OpLabel\n%435 = OpShiftLeftLogical %5 %147 %44\n%436 = OpBitwiseAnd %5 %284 %435\n%437 = OpINotEqual %103 %436 %35\nOpBranch %427\n%423 = OpLabel\n%428 = OpBitwiseAnd %5 %283 %137\n%429 = OpINotEqual %103 %428 %35\nOpBranch %427\n%424 = OpLabel\n%430 = OpShiftLeftLogical %5 %137 %51\n%431 = OpBitwiseAnd %5 %283 %430\n%432 = OpINotEqual %103 %431 %35\nOpBranch %427\n%425 = OpLabel\n%433 = OpBitwiseAnd %5 %284 %147\n%434 = OpINotEqual %103 %433 %35\nOpBranch %427\n%427 = OpLabel\n%438 = OpPhi %103 %429 %423 %432 %424 %434 %425 %437 %426\n%439 = OpLogicalNot %103 %438\n%440 = OpLogicalOr %103 %439 %422\nOpReturnValue %440\nOpFunctionEnd\n%469 = OpFunction %1 None %466\n%467 = OpFunctionParameter %103\n%468 = OpFunctionParameter %5\n%470 = OpLabel\n%473 = OpLogicalNot %103 %467\n%474 = OpLoad %103 %456\n%475 = OpLogicalAnd %103 %473 %474\nOpSelectionMerge %471 None\nOpBranchConditional %475 %472 %471\n%472 = OpLabel\n%478 = OpIMul %5 %468 %480\n%479 = OpBitwiseXor %5 %478 %481\n%482 = OpArrayLength %5 %461 0\n%483 = OpISub %5 %482 %149\n%484 = OpAccessChain %33 %461 %35 %483\n%485 = OpLoad %5 %484\n%486 = OpIMul %5 %485 %487\n%488 = OpBitwiseXor %5 %479 %486\n%489 = OpArrayLength %5 %465 0\n%490 = OpISub %5 %489 %10\n%491 = OpBitwiseAnd %5 %488 %490\n%492 = OpShiftRightLogical %5 %491 %44\n%493 = OpBitwiseAnd %5 %491 %139\n%494 = OpShiftLeftLogical %5 %10 %493\n%495 = OpAccessChain %33 %461 %35 %492\n%496 = OpAtomicOr %5 %495 %10 %35 %494\n%497 = OpBitwiseAnd %5 %496 %494\n%498 = OpIEqual %103 %497 %35\nOpStore %456 %499\nOpSelectionMerge %477 None\nOpBranchConditional %498 %476 %477\n%476 = OpLabel\n%500 = OpCompositeConstruct %457 %481 %35 %468 %485\n%501 = OpShiftLeftLogical %5 %494 %51\n%503 = OpAccessChain %502 %465 %35 %491\nOpStore %503 %500\nOpMemoryBarrier %10 %505\n%504 = OpAtomicOr %5 %495 %10 %35 %501\nOpMemoryBarrier %10 %505\nOpBranch %477\n%477 = OpLabel\nOpBranch %471\n%471 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/atomics-structured.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerUintArray;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerUintArray\n{\n    uint value[];\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _31 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _31;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _57 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _58 = uvec2(prime);\n    uvec2 _65 = ((_57 >> uvec2(8u)) ^ _57.yx) * _58;\n    uvec2 _69 = ((_65 >> uvec2(8u)) ^ _65.yx) * _58;\n    uvec2 _73 = ((_69 >> uvec2(8u)) ^ _69.yx) * _58;\n    uvec2 _77 = ((_73 >> uvec2(8u)) ^ _73.yx) * _58;\n    uvec2 _81 = ((_77 >> uvec2(8u)) ^ _77.yx) * _58;\n    return (((_81 >> uvec2(8u)) ^ _81.yx) * _58).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _114;\n    _114._m0 = uaddCarry(BDA.x, offset, _114._m1);\n    uvec2 addr = uvec2(_114._m0, BDA.y + _114._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _473 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _475 = InstrumentationControlData.atomics[_473];\n        uint _481 = (((inst * 97u) ^ 43981u) ^ (_475 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _482 = _481 >> 4u;\n        uint _484 = 1u << (_481 & 15u);\n        uint _486 = atomicOr(InstrumentationControlData.atomics[_482], _484);\n        ShouldReportInstrumentation = false;\n        if ((_486 & _484) == 0u)\n        {\n            InstrumentationData.data[_481] = uvec4(43981u, 0u, inst, _475);\n            memoryBarrierBuffer();\n            uint _494 = atomicOr(InstrumentationControlData.atomics[_482], _484 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _34 = AllocateInvocationID();\n    InvocationID = _34;\n    uint _429 = InvocationID;\n    bool _428 = ValidateBDALoadStore(registers._m2, (gl_GlobalInvocationID.x * 4u) + 0u, 4u, 2u, _429, true);\n    AssumeTrue(_428, 1u);\n    uint _436 = atomicAdd(PhysicalPointerUintArray(registers._m2).value[gl_GlobalInvocationID.x], 1u);\n    uint _440 = InvocationID;\n    bool _439 = ValidateBDALoadStore(registers._m2, (gl_GlobalInvocationID.x * 4u) + 0u, 4u, 2u, _440, true);\n    AssumeTrue(_439, 2u);\n    uint _443 = atomicCompSwap(PhysicalPointerUintArray(registers._m2).value[gl_GlobalInvocationID.x], 1u, 2u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 500\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%138 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %41\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"BloomBufferInvocationSSBO\"\nOpMemberName %20 0 \"atomics\"\nOpName %22 \"BloomBufferInvocation\"\nOpName %24 \"AllocateInvocationID\"\nOpName %51 \"AddrHash\"\nOpName %49 \"addr\"\nOpName %50 \"prime\"\nOpName %91 \"BloomBufferSSBO\"\nOpMemberName %91 0 \"atomics\"\nOpName %93 \"BloomBuffer\"\nOpName %95 \"BloomBuffer32SSBO\"\nOpMemberName %95 0 \"atomics\"\nOpName %97 \"BloomBuffer32\"\nOpName %105 \"ValidateBDALoadStore\"\nOpName %99 \"BDA\"\nOpName %100 \"offset\"\nOpName %101 \"len\"\nOpName %102 \"type\"\nOpName %103 \"invocation_id\"\nOpName %104 \"in_bounds\"\nOpName %113 \"IAddCarryResult\"\nOpName %118 \"addr\"\nOpName %119 \"addr_lo\"\nOpName %123 \"byte_mask\"\nOpName %133 \"word_mask\"\nOpName %137 \"hash_mask\"\nOpName %142 \"hash_offset\"\nOpName %146 \"bloom_index\"\nOpName %150 \"bloom_index\"\nOpName %154 \"bloom_index\"\nOpName %157 \"bloom_index\"\nOpName %161 \"bloom_index\"\nOpName %165 \"bloom_index\"\nOpName %169 \"bloom_index\"\nOpName %173 \"bloom_index\"\nOpName %177 \"bloom_index\"\nOpName %181 \"bloom_index\"\nOpName %185 \"bloom_index\"\nOpName %189 \"bloom_index\"\nOpName %193 \"bloom_index\"\nOpName %197 \"bloom_index\"\nOpName %201 \"bloom_index\"\nOpName %205 \"bloom_index\"\nOpName %219 \"invalidation_mask\"\nOpName %222 \"prev_hazard_partial\"\nOpName %224 \"prev_hazard_partial\"\nOpName %227 \"prev_hazard_partial\"\nOpName %230 \"prev_hazard_partial\"\nOpName %233 \"prev_hazard_partial\"\nOpName %236 \"prev_hazard_partial\"\nOpName %239 \"prev_hazard_partial\"\nOpName %242 \"prev_hazard_partial\"\nOpName %245 \"prev_hazard_partial\"\nOpName %248 \"prev_hazard_partial\"\nOpName %251 \"prev_hazard_partial\"\nOpName %254 \"prev_hazard_partial\"\nOpName %257 \"prev_hazard_partial\"\nOpName %260 \"prev_hazard_partial\"\nOpName %263 \"prev_hazard_partial\"\nOpName %266 \"prev_hazard_partial\"\nOpName %268 \"prev_hazard\"\nOpName %269 \"prev_hazard_lo\"\nOpName %270 \"prev_hazard_hi\"\nOpName %273 \"has_exclusive_access\"\nOpName %288 \"lock_mask\"\nOpName %291 \"prev_lock\"\nOpName %304 \"lock_mask\"\nOpName %307 \"prev_lock\"\nOpName %321 \"lock_mask\"\nOpName %324 \"prev_lock\"\nOpName %338 \"lock_mask\"\nOpName %341 \"prev_lock\"\nOpName %355 \"lock_mask\"\nOpName %358 \"prev_lock\"\nOpName %369 \"lock_mask\"\nOpName %372 \"prev_lock\"\nOpName %385 \"lock_mask\"\nOpName %388 \"prev_lock\"\nOpName %402 \"lock_mask\"\nOpName %405 \"prev_lock\"\nOpName %408 \"has_complete_self_lock\"\nOpName %424 \"hazard\"\nOpName %431 \"PhysicalPointerUintArray\"\nOpMemberName %431 0 \"value\"\nOpName %446 \"ShouldReportInstrumentation\"\nOpName %449 \"InstrumentationControlDataSSBO\"\nOpMemberName %449 0 \"atomics\"\nOpName %451 \"InstrumentationControlData\"\nOpName %453 \"InstrumentationDataSSBO\"\nOpMemberName %453 0 \"data\"\nOpName %455 \"InstrumentationData\"\nOpName %459 \"AssumeTrue\"\nOpName %457 \"value\"\nOpName %458 \"inst\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 2\nOpDecorate %41 BuiltIn GlobalInvocationId\nOpDecorate %90 ArrayStride 8\nOpMemberDecorate %91 0 Offset 0\nOpDecorate %91 Block\nOpDecorate %93 DescriptorSet 0\nOpDecorate %93 Binding 2\nOpDecorate %94 ArrayStride 8\nOpMemberDecorate %95 0 Offset 0\nOpDecorate %95 Block\nOpDecorate %97 DescriptorSet 0\nOpDecorate %97 Binding 2\nOpDecorate %430 ArrayStride 4\nOpMemberDecorate %431 0 Offset 0\nOpDecorate %431 Block\nOpDecorate %448 ArrayStride 4\nOpMemberDecorate %449 0 Offset 0\nOpDecorate %449 Block\nOpDecorate %451 DescriptorSet 0\nOpDecorate %451 Binding 2\nOpDecorate %452 ArrayStride 16\nOpMemberDecorate %453 0 Offset 0\nOpDecorate %453 Block\nOpDecorate %455 DescriptorSet 0\nOpDecorate %455 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpConstant %5 1\n%11 = OpTypeArray %6 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeFunction %5\n%28 = OpTypePointer StorageBuffer %5\n%30 = OpConstant %5 0\n%32 = OpConstant %5 1103633207\n%35 = OpTypePointer PushConstant %6\n%37 = OpConstant %5 2\n%39 = OpTypeVector %5 3\n%40 = OpTypePointer Input %39\n%41 = OpVariable %40 Input\n%42 = OpTypePointer Input %5\n%45 = OpConstant %5 4\n%48 = OpTypeFunction %5 %6 %5\n%59 = OpConstant %5 65535\n%60 = OpConstant %5 8\n%61 = OpConstantComposite %6 %60 %60\n%88 = OpTypeInt 64 0\n%89 = OpTypeBool\n%90 = OpTypeRuntimeArray %88\n%91 = OpTypeStruct %90\n%92 = OpTypePointer StorageBuffer %91\n%93 = OpVariable %92 StorageBuffer\n%94 = OpTypeRuntimeArray %6\n%95 = OpTypeStruct %94\n%96 = OpTypePointer StorageBuffer %95\n%97 = OpVariable %96 StorageBuffer\n%98 = OpTypeFunction %89 %6 %5 %5 %5 %5 %89\n%109 = OpConstantTrue %89\n%113 = OpTypeStruct %5 %5\n%124 = OpConstant %5 4294967295\n%125 = OpConstant %5 15\n%134 = OpConstant %5 3\n%144 = OpConstant %5 1103515245\n%148 = OpConstant %5 1103518333\n%152 = OpConstant %5 1103539331\n%159 = OpConstant %5 10006121\n%163 = OpConstant %5 4004951\n%167 = OpConstant %5 5005159\n%171 = OpConstant %5 6004811\n%175 = OpConstant %5 383\n%179 = OpConstant %5 821\n%183 = OpConstant %5 661\n%187 = OpConstant %5 1091\n%191 = OpConstant %5 1117\n%195 = OpConstant %5 3947\n%199 = OpConstant %5 4253\n%203 = OpConstant %5 7691\n%206 = OpTypeVector %88 4\n%207 = OpConstant %88 68719411200\n%208 = OpConstant %88 1099511627775\n%209 = OpConstant %88 1035087118335\n%210 = OpConstantComposite %206 %207 %208 %209 %207\n%214 = OpConstant %5 16\n%220 = OpTypePointer StorageBuffer %88\n%275 = OpTypeInt 32 1\n%276 = OpConstant %275 0\n%277 = OpConstant %275 3\n%279 = OpConstant %5 256\n%282 = OpConstant %5 65536\n%285 = OpConstant %275 6\n%287 = OpConstant %5 16777216\n%295 = OpConstant %275 9\n%298 = OpConstant %275 12\n%302 = OpConstant %275 15\n%312 = OpConstant %275 18\n%315 = OpConstant %275 21\n%319 = OpConstant %275 24\n%329 = OpConstant %275 23\n%332 = OpConstant %275 26\n%336 = OpConstant %275 29\n%346 = OpConstant %275 1\n%349 = OpConstant %275 4\n%353 = OpConstant %275 7\n%377 = OpConstant %275 17\n%380 = OpConstant %275 20\n%393 = OpConstant %275 22\n%396 = OpConstant %275 25\n%400 = OpConstant %275 28\n%430 = OpTypeRuntimeArray %5\n%431 = OpTypeStruct %430\n%432 = OpTypePointer PhysicalStorageBuffer %431\n%434 = OpTypePointer PhysicalStorageBuffer %5\n%445 = OpTypePointer Private %89\n%446 = OpVariable %445 Private %109\n%447 = OpTypeVector %5 4\n%448 = OpTypeRuntimeArray %5\n%449 = OpTypeStruct %448\n%450 = OpTypePointer StorageBuffer %449\n%451 = OpVariable %450 StorageBuffer\n%452 = OpTypeRuntimeArray %447\n%453 = OpTypeStruct %452\n%454 = OpTypePointer StorageBuffer %453\n%455 = OpVariable %454 StorageBuffer\n%456 = OpTypeFunction %1 %89 %5\n%470 = OpConstant %5 97\n%471 = OpConstant %5 43981\n%477 = OpConstant %5 51329\n%489 = OpConstantFalse %89\n%492 = OpTypePointer StorageBuffer %447\n%495 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %444\n%444 = OpLabel\n%34 = OpFunctionCall %5 %24\nOpStore %18 %34\n%36 = OpAccessChain %35 %9 %37\n%38 = OpLoad %6 %36\n%43 = OpAccessChain %42 %41 %30\n%44 = OpLoad %5 %43\n%46 = OpIMul %5 %44 %45\n%47 = OpIAdd %5 %46 %30\n%429 = OpLoad %5 %18\n%428 = OpFunctionCall %89 %105 %38 %47 %45 %37 %429 %109\n%497 = OpFunctionCall %1 %459 %428 %10\n%433 = OpBitcast %432 %38\n%435 = OpAccessChain %434 %433 %30 %44\n%436 = OpAtomicIAdd %5 %435 %10 %30 %10\n%437 = OpIMul %5 %44 %45\n%438 = OpIAdd %5 %437 %30\n%440 = OpLoad %5 %18\n%439 = OpFunctionCall %89 %105 %38 %438 %45 %37 %440 %109\n%498 = OpFunctionCall %1 %459 %439 %37\n%441 = OpBitcast %432 %38\n%442 = OpAccessChain %434 %441 %30 %44\n%443 = OpAtomicCompareExchange %5 %442 %10 %30 %30 %37 %10\nOpReturn\nOpFunctionEnd\n%24 = OpFunction %5 None %23\n%25 = OpLabel\n%26 = OpArrayLength %5 %22 0\n%27 = OpISub %5 %26 %10\n%29 = OpAccessChain %28 %22 %30 %27\n%31 = OpAtomicIAdd %5 %29 %10 %30 %32\nOpReturnValue %31\nOpFunctionEnd\n%51 = OpFunction %5 None %48\n%49 = OpFunctionParameter %6\n%50 = OpFunctionParameter %5\n%52 = OpLabel\n%53 = OpCompositeExtract %5 %49 0\n%54 = OpCompositeExtract %5 %49 1\n%55 = OpShiftRightLogical %5 %53 %45\n%56 = OpBitwiseAnd %5 %54 %59\n%57 = OpCompositeConstruct %6 %55 %56\n%58 = OpCompositeConstruct %6 %50 %50\n%62 = OpVectorShuffle %6 %57 %57 1 0\n%63 = OpShiftRightLogical %6 %57 %61\n%64 = OpBitwiseXor %6 %63 %62\n%65 = OpIMul %6 %64 %58\n%66 = OpVectorShuffle %6 %65 %65 1 0\n%67 = OpShiftRightLogical %6 %65 %61\n%68 = OpBitwiseXor %6 %67 %66\n%69 = OpIMul %6 %68 %58\n%70 = OpVectorShuffle %6 %69 %69 1 0\n%71 = OpShiftRightLogical %6 %69 %61\n%72 = OpBitwiseXor %6 %71 %70\n%73 = OpIMul %6 %72 %58\n%74 = OpVectorShuffle %6 %73 %73 1 0\n%75 = OpShiftRightLogical %6 %73 %61\n%76 = OpBitwiseXor %6 %75 %74\n%77 = OpIMul %6 %76 %58\n%78 = OpVectorShuffle %6 %77 %77 1 0\n%79 = OpShiftRightLogical %6 %77 %61\n%80 = OpBitwiseXor %6 %79 %78\n%81 = OpIMul %6 %80 %58\n%82 = OpVectorShuffle %6 %81 %81 1 0\n%83 = OpShiftRightLogical %6 %81 %61\n%84 = OpBitwiseXor %6 %83 %82\n%85 = OpIMul %6 %84 %58\n%86 = OpCompositeExtract %5 %85 0\nOpReturnValue %86\nOpFunctionEnd\n%105 = OpFunction %89 None %98\n%99 = OpFunctionParameter %6\n%100 = OpFunctionParameter %5\n%101 = OpFunctionParameter %5\n%102 = OpFunctionParameter %5\n%103 = OpFunctionParameter %5\n%104 = OpFunctionParameter %89\n%106 = OpLabel\nOpSelectionMerge %108 None\nOpBranchConditional %104 %108 %107\n%107 = OpLabel\nOpReturnValue %109\n%108 = OpLabel\n%111 = OpCompositeExtract %5 %99 0\n%112 = OpCompositeExtract %5 %99 1\n%114 = OpIAddCarry %113 %111 %100\n%115 = OpCompositeExtract %5 %114 0\n%116 = OpCompositeExtract %5 %114 1\n%117 = OpIAdd %5 %112 %116\n%118 = OpCompositeConstruct %6 %115 %117\n%119 = OpCompositeExtract %5 %118 0\n%120 = OpBitFieldUExtract %5 %124 %30 %101\n%121 = OpBitwiseAnd %5 %119 %125\n%122 = OpShiftLeftLogical %5 %120 %121\n%123 = OpBitwiseAnd %5 %122 %59\n%126 = OpBitwiseAnd %5 %119 %134\n%127 = OpIAdd %5 %126 %101\n%128 = OpIAdd %5 %127 %134\n%129 = OpShiftRightLogical %5 %128 %37\n%130 = OpBitFieldUExtract %5 %119 %37 %37\n%131 = OpBitFieldUExtract %5 %124 %30 %129\n%132 = OpShiftLeftLogical %5 %131 %130\n%133 = OpBitwiseAnd %5 %132 %125\n%135 = OpArrayLength %5 %93 0\n%136 = OpExtInst %5 %138 FindUMsb %135\n%137 = OpBitFieldUExtract %5 %124 %30 %136\n%139 = OpArrayLength %5 %93 0\n%140 = OpExtInst %5 %138 FindUMsb %139\n%141 = OpBitFieldUExtract %5 %139 %30 %140\n%142 = OpISub %5 %141 %10\n%143 = OpFunctionCall %5 %51 %118 %144\n%145 = OpBitwiseAnd %5 %143 %137\n%146 = OpIAdd %5 %145 %142\n%147 = OpFunctionCall %5 %51 %118 %148\n%149 = OpBitwiseAnd %5 %147 %137\n%150 = OpIAdd %5 %149 %142\n%151 = OpFunctionCall %5 %51 %118 %152\n%153 = OpBitwiseAnd %5 %151 %137\n%154 = OpIAdd %5 %153 %142\n%155 = OpFunctionCall %5 %51 %118 %32\n%156 = OpBitwiseAnd %5 %155 %137\n%157 = OpIAdd %5 %156 %142\n%158 = OpFunctionCall %5 %51 %118 %159\n%160 = OpBitwiseAnd %5 %158 %137\n%161 = OpIAdd %5 %160 %142\n%162 = OpFunctionCall %5 %51 %118 %163\n%164 = OpBitwiseAnd %5 %162 %137\n%165 = OpIAdd %5 %164 %142\n%166 = OpFunctionCall %5 %51 %118 %167\n%168 = OpBitwiseAnd %5 %166 %137\n%169 = OpIAdd %5 %168 %142\n%170 = OpFunctionCall %5 %51 %118 %171\n%172 = OpBitwiseAnd %5 %170 %137\n%173 = OpIAdd %5 %172 %142\n%174 = OpFunctionCall %5 %51 %118 %175\n%176 = OpBitwiseAnd %5 %174 %137\n%177 = OpIAdd %5 %176 %142\n%178 = OpFunctionCall %5 %51 %118 %179\n%180 = OpBitwiseAnd %5 %178 %137\n%181 = OpIAdd %5 %180 %142\n%182 = OpFunctionCall %5 %51 %118 %183\n%184 = OpBitwiseAnd %5 %182 %137\n%185 = OpIAdd %5 %184 %142\n%186 = OpFunctionCall %5 %51 %118 %187\n%188 = OpBitwiseAnd %5 %186 %137\n%189 = OpIAdd %5 %188 %142\n%190 = OpFunctionCall %5 %51 %118 %191\n%192 = OpBitwiseAnd %5 %190 %137\n%193 = OpIAdd %5 %192 %142\n%194 = OpFunctionCall %5 %51 %118 %195\n%196 = OpBitwiseAnd %5 %194 %137\n%197 = OpIAdd %5 %196 %142\n%198 = OpFunctionCall %5 %51 %118 %199\n%200 = OpBitwiseAnd %5 %198 %137\n%201 = OpIAdd %5 %200 %142\n%202 = OpFunctionCall %5 %51 %118 %203\n%204 = OpBitwiseAnd %5 %202 %137\n%205 = OpIAdd %5 %204 %142\n%211 = OpVectorExtractDynamic %88 %210 %102\n%212 = OpShiftLeftLogical %5 %123 %214\n%213 = OpShiftLeftLogical %5 %133 %45\n%215 = OpBitwiseOr %5 %123 %212\n%216 = OpBitwiseOr %5 %133 %213\n%217 = OpCompositeConstruct %6 %215 %216\n%218 = OpBitcast %88 %217\n%219 = OpBitwiseAnd %88 %211 %218\n%221 = OpInBoundsAccessChain %220 %93 %30 %146\n%222 = OpAtomicOr %88 %221 %10 %30 %219\n%223 = OpInBoundsAccessChain %220 %93 %30 %150\n%224 = OpAtomicOr %88 %223 %10 %30 %219\n%225 = OpBitwiseAnd %88 %222 %224\n%226 = OpInBoundsAccessChain %220 %93 %30 %154\n%227 = OpAtomicOr %88 %226 %10 %30 %219\n%228 = OpBitwiseAnd %88 %225 %227\n%229 = OpInBoundsAccessChain %220 %93 %30 %157\n%230 = OpAtomicOr %88 %229 %10 %30 %219\n%231 = OpBitwiseAnd %88 %228 %230\n%232 = OpInBoundsAccessChain %220 %93 %30 %161\n%233 = OpAtomicOr %88 %232 %10 %30 %219\n%234 = OpBitwiseAnd %88 %231 %233\n%235 = OpInBoundsAccessChain %220 %93 %30 %165\n%236 = OpAtomicOr %88 %235 %10 %30 %219\n%237 = OpBitwiseAnd %88 %234 %236\n%238 = OpInBoundsAccessChain %220 %93 %30 %169\n%239 = OpAtomicOr %88 %238 %10 %30 %219\n%240 = OpBitwiseAnd %88 %237 %239\n%241 = OpInBoundsAccessChain %220 %93 %30 %173\n%242 = OpAtomicOr %88 %241 %10 %30 %219\n%243 = OpBitwiseAnd %88 %240 %242\n%244 = OpInBoundsAccessChain %220 %93 %30 %177\n%245 = OpAtomicOr %88 %244 %10 %30 %219\n%246 = OpBitwiseAnd %88 %243 %245\n%247 = OpInBoundsAccessChain %220 %93 %30 %181\n%248 = OpAtomicOr %88 %247 %10 %30 %219\n%249 = OpBitwiseAnd %88 %246 %248\n%250 = OpInBoundsAccessChain %220 %93 %30 %185\n%251 = OpAtomicOr %88 %250 %10 %30 %219\n%252 = OpBitwiseAnd %88 %249 %251\n%253 = OpInBoundsAccessChain %220 %93 %30 %189\n%254 = OpAtomicOr %88 %253 %10 %30 %219\n%255 = OpBitwiseAnd %88 %252 %254\n%256 = OpInBoundsAccessChain %220 %93 %30 %193\n%257 = OpAtomicOr %88 %256 %10 %30 %219\n%258 = OpBitwiseAnd %88 %255 %257\n%259 = OpInBoundsAccessChain %220 %93 %30 %197\n%260 = OpAtomicOr %88 %259 %10 %30 %219\n%261 = OpBitwiseAnd %88 %258 %260\n%262 = OpInBoundsAccessChain %220 %93 %30 %201\n%263 = OpAtomicOr %88 %262 %10 %30 %219\n%264 = OpBitwiseAnd %88 %261 %263\n%265 = OpInBoundsAccessChain %220 %93 %30 %205\n%266 = OpAtomicOr %88 %265 %10 %30 %219\n%267 = OpBitwiseAnd %88 %264 %266\n%268 = OpBitcast %6 %267\n%269 = OpCompositeExtract %5 %268 0\n%270 = OpCompositeExtract %5 %268 1\n%271 = OpShiftRightLogical %5 %269 %214\n%272 = OpBitwiseAnd %5 %271 %123\n%273 = OpIEqual %89 %272 %30\n%274 = OpBitFieldUExtract %5 %103 %276 %277\n%278 = OpShiftLeftLogical %5 %279 %274\n%280 = OpBitFieldUExtract %5 %103 %277 %277\n%281 = OpShiftLeftLogical %5 %282 %280\n%283 = OpBitwiseOr %5 %278 %281\n%284 = OpBitFieldUExtract %5 %103 %285 %277\n%286 = OpShiftLeftLogical %5 %287 %284\n%288 = OpBitwiseOr %5 %283 %286\n%289 = OpSelect %5 %273 %288 %30\n%290 = OpInBoundsAccessChain %28 %97 %30 %146 %10\n%291 = OpAtomicOr %5 %290 %10 %30 %289\n%292 = OpBitwiseAnd %5 %291 %288\n%293 = OpIEqual %89 %292 %288\n%294 = OpBitFieldUExtract %5 %103 %295 %277\n%296 = OpShiftLeftLogical %5 %279 %294\n%297 = OpBitFieldUExtract %5 %103 %298 %277\n%299 = OpShiftLeftLogical %5 %282 %297\n%300 = OpBitwiseOr %5 %296 %299\n%301 = OpBitFieldUExtract %5 %103 %302 %277\n%303 = OpShiftLeftLogical %5 %287 %301\n%304 = OpBitwiseOr %5 %300 %303\n%305 = OpSelect %5 %273 %304 %30\n%306 = OpInBoundsAccessChain %28 %97 %30 %150 %10\n%307 = OpAtomicOr %5 %306 %10 %30 %305\n%308 = OpBitwiseAnd %5 %307 %304\n%309 = OpIEqual %89 %308 %304\n%310 = OpLogicalAnd %89 %293 %309\n%311 = OpBitFieldUExtract %5 %103 %312 %277\n%313 = OpShiftLeftLogical %5 %279 %311\n%314 = OpBitFieldUExtract %5 %103 %315 %277\n%316 = OpShiftLeftLogical %5 %282 %314\n%317 = OpBitwiseOr %5 %313 %316\n%318 = OpBitFieldUExtract %5 %103 %319 %277\n%320 = OpShiftLeftLogical %5 %287 %318\n%321 = OpBitwiseOr %5 %317 %320\n%322 = OpSelect %5 %273 %321 %30\n%323 = OpInBoundsAccessChain %28 %97 %30 %154 %10\n%324 = OpAtomicOr %5 %323 %10 %30 %322\n%325 = OpBitwiseAnd %5 %324 %321\n%326 = OpIEqual %89 %325 %321\n%327 = OpLogicalAnd %89 %310 %326\n%328 = OpBitFieldUExtract %5 %103 %329 %277\n%330 = OpShiftLeftLogical %5 %279 %328\n%331 = OpBitFieldUExtract %5 %103 %332 %277\n%333 = OpShiftLeftLogical %5 %282 %331\n%334 = OpBitwiseOr %5 %330 %333\n%335 = OpBitFieldUExtract %5 %103 %336 %277\n%337 = OpShiftLeftLogical %5 %287 %335\n%338 = OpBitwiseOr %5 %334 %337\n%339 = OpSelect %5 %273 %338 %30\n%340 = OpInBoundsAccessChain %28 %97 %30 %157 %10\n%341 = OpAtomicOr %5 %340 %10 %30 %339\n%342 = OpBitwiseAnd %5 %341 %338\n%343 = OpIEqual %89 %342 %338\n%344 = OpLogicalAnd %89 %327 %343\n%345 = OpBitFieldUExtract %5 %103 %346 %277\n%347 = OpShiftLeftLogical %5 %279 %345\n%348 = OpBitFieldUExtract %5 %103 %349 %277\n%350 = OpShiftLeftLogical %5 %282 %348\n%351 = OpBitwiseOr %5 %347 %350\n%352 = OpBitFieldUExtract %5 %103 %353 %277\n%354 = OpShiftLeftLogical %5 %287 %352\n%355 = OpBitwiseOr %5 %351 %354\n%356 = OpSelect %5 %273 %355 %30\n%357 = OpInBoundsAccessChain %28 %97 %30 %161 %10\n%358 = OpAtomicOr %5 %357 %10 %30 %356\n%359 = OpBitwiseAnd %5 %358 %355\n%360 = OpIEqual %89 %359 %355\n%361 = OpLogicalAnd %89 %344 %360\n%362 = OpBitFieldUExtract %5 %103 %295 %277\n%363 = OpShiftLeftLogical %5 %279 %362\n%364 = OpBitFieldUExtract %5 %103 %298 %277\n%365 = OpShiftLeftLogical %5 %282 %364\n%366 = OpBitwiseOr %5 %363 %365\n%367 = OpBitFieldUExtract %5 %103 %302 %277\n%368 = OpShiftLeftLogical %5 %287 %367\n%369 = OpBitwiseOr %5 %366 %368\n%370 = OpSelect %5 %273 %369 %30\n%371 = OpInBoundsAccessChain %28 %97 %30 %165 %10\n%372 = OpAtomicOr %5 %371 %10 %30 %370\n%373 = OpBitwiseAnd %5 %372 %369\n%374 = OpIEqual %89 %373 %369\n%375 = OpLogicalAnd %89 %361 %374\n%376 = OpBitFieldUExtract %5 %103 %377 %277\n%378 = OpShiftLeftLogical %5 %279 %376\n%379 = OpBitFieldUExtract %5 %103 %380 %277\n%381 = OpShiftLeftLogical %5 %282 %379\n%382 = OpBitwiseOr %5 %378 %381\n%383 = OpBitFieldUExtract %5 %103 %329 %277\n%384 = OpShiftLeftLogical %5 %287 %383\n%385 = OpBitwiseOr %5 %382 %384\n%386 = OpSelect %5 %273 %385 %30\n%387 = OpInBoundsAccessChain %28 %97 %30 %169 %10\n%388 = OpAtomicOr %5 %387 %10 %30 %386\n%389 = OpBitwiseAnd %5 %388 %385\n%390 = OpIEqual %89 %389 %385\n%391 = OpLogicalAnd %89 %375 %390\n%392 = OpBitFieldUExtract %5 %103 %393 %277\n%394 = OpShiftLeftLogical %5 %279 %392\n%395 = OpBitFieldUExtract %5 %103 %396 %277\n%397 = OpShiftLeftLogical %5 %282 %395\n%398 = OpBitwiseOr %5 %394 %397\n%399 = OpBitFieldUExtract %5 %103 %400 %277\n%401 = OpShiftLeftLogical %5 %287 %399\n%402 = OpBitwiseOr %5 %398 %401\n%403 = OpSelect %5 %273 %402 %30\n%404 = OpInBoundsAccessChain %28 %97 %30 %173 %10\n%405 = OpAtomicOr %5 %404 %10 %30 %403\n%406 = OpBitwiseAnd %5 %405 %402\n%407 = OpIEqual %89 %406 %402\n%408 = OpLogicalAnd %89 %391 %407\nOpSelectionMerge %413 None\nOpSwitch %102 %412 0 %409 1 %410 2 %411\n%412 = OpLabel\n%421 = OpShiftLeftLogical %5 %133 %45\n%422 = OpBitwiseAnd %5 %270 %421\n%423 = OpINotEqual %89 %422 %30\nOpBranch %413\n%409 = OpLabel\n%414 = OpBitwiseAnd %5 %269 %123\n%415 = OpINotEqual %89 %414 %30\nOpBranch %413\n%410 = OpLabel\n%416 = OpShiftLeftLogical %5 %123 %214\n%417 = OpBitwiseAnd %5 %269 %416\n%418 = OpINotEqual %89 %417 %30\nOpBranch %413\n%411 = OpLabel\n%419 = OpBitwiseAnd %5 %270 %133\n%420 = OpINotEqual %89 %419 %30\nOpBranch %413\n%413 = OpLabel\n%424 = OpPhi %89 %415 %409 %418 %410 %420 %411 %423 %412\n%425 = OpLogicalNot %89 %424\n%426 = OpLogicalOr %89 %425 %408\nOpReturnValue %426\nOpFunctionEnd\n%459 = OpFunction %1 None %456\n%457 = OpFunctionParameter %89\n%458 = OpFunctionParameter %5\n%460 = OpLabel\n%463 = OpLogicalNot %89 %457\n%464 = OpLoad %89 %446\n%465 = OpLogicalAnd %89 %463 %464\nOpSelectionMerge %461 None\nOpBranchConditional %465 %462 %461\n%462 = OpLabel\n%468 = OpIMul %5 %458 %470\n%469 = OpBitwiseXor %5 %468 %471\n%472 = OpArrayLength %5 %451 0\n%473 = OpISub %5 %472 %37\n%474 = OpAccessChain %28 %451 %30 %473\n%475 = OpLoad %5 %474\n%476 = OpIMul %5 %475 %477\n%478 = OpBitwiseXor %5 %469 %476\n%479 = OpArrayLength %5 %455 0\n%480 = OpISub %5 %479 %10\n%481 = OpBitwiseAnd %5 %478 %480\n%482 = OpShiftRightLogical %5 %481 %45\n%483 = OpBitwiseAnd %5 %481 %125\n%484 = OpShiftLeftLogical %5 %10 %483\n%485 = OpAccessChain %28 %451 %30 %482\n%486 = OpAtomicOr %5 %485 %10 %30 %484\n%487 = OpBitwiseAnd %5 %486 %484\n%488 = OpIEqual %89 %487 %30\nOpStore %446 %489\nOpSelectionMerge %467 None\nOpBranchConditional %488 %466 %467\n%466 = OpLabel\n%490 = OpCompositeConstruct %447 %471 %30 %458 %475\n%491 = OpShiftLeftLogical %5 %484 %214\n%493 = OpAccessChain %492 %455 %30 %481\nOpStore %493 %490\nOpMemoryBarrier %10 %495\n%494 = OpAtomicOr %5 %485 %10 %30 %491\nOpMemoryBarrier %10 %495\nOpBranch %467\n%467 = OpLabel\nOpBranch %461\n%461 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/atomics-typed.bindless.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform uimageBuffer _22[];\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _35 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _35;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _69 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _70 = uvec2(prime);\n    uvec2 _77 = ((_69 >> uvec2(8u)) ^ _69.yx) * _70;\n    uvec2 _81 = ((_77 >> uvec2(8u)) ^ _77.yx) * _70;\n    uvec2 _85 = ((_81 >> uvec2(8u)) ^ _81.yx) * _70;\n    uvec2 _89 = ((_85 >> uvec2(8u)) ^ _85.yx) * _70;\n    uvec2 _93 = ((_89 >> uvec2(8u)) ^ _89.yx) * _70;\n    return (((_93 >> uvec2(8u)) ^ _93.yx) * _70).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _126;\n    _126._m0 = uaddCarry(BDA.x, offset, _126._m1);\n    uvec2 addr = uvec2(_126._m0, BDA.y + _126._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _481 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _483 = InstrumentationControlData.atomics[_481];\n        uint _489 = (((inst * 97u) ^ 43981u) ^ (_483 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _490 = _489 >> 4u;\n        uint _492 = 1u << (_489 & 15u);\n        uint _494 = atomicOr(InstrumentationControlData.atomics[_490], _492);\n        ShouldReportInstrumentation = false;\n        if ((_494 & _492) == 0u)\n        {\n            InstrumentationData.data[_489] = uvec4(43981u, 0u, inst, _483);\n            memoryBarrierBuffer();\n            uint _502 = atomicOr(InstrumentationControlData.atomics[_490], _492 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _38 = AllocateInvocationID();\n    InvocationID = _38;\n    uvec2 _47 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _49 = _47.y >> 16u;\n    uint _52 = uint(imageSize(_22[registers._m4]));\n    uint _441 = InvocationID;\n    bool _440 = ValidateBDALoadStore(_47, gl_GlobalInvocationID.x * _49, 4u, 2u, _441, gl_GlobalInvocationID.x < _52);\n    AssumeTrue(_440, 1u);\n    uint _445 = imageAtomicAdd(_22[registers._m4], int(gl_GlobalInvocationID.x), 1u);\n    uint _448 = InvocationID;\n    bool _447 = ValidateBDALoadStore(_47, gl_GlobalInvocationID.x * _49, 4u, 2u, _448, gl_GlobalInvocationID.x < _52);\n    AssumeTrue(_447, 2u);\n    uint _451 = imageAtomicCompSwap(_22[registers._m4], int(gl_GlobalInvocationID.x), 1u, 2u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 508\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%151 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %55\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %24 \"BloomBufferInvocationSSBO\"\nOpMemberName %24 0 \"atomics\"\nOpName %26 \"BloomBufferInvocation\"\nOpName %28 \"AllocateInvocationID\"\nOpName %63 \"AddrHash\"\nOpName %61 \"addr\"\nOpName %62 \"prime\"\nOpName %103 \"BloomBufferSSBO\"\nOpMemberName %103 0 \"atomics\"\nOpName %105 \"BloomBuffer\"\nOpName %107 \"BloomBuffer32SSBO\"\nOpMemberName %107 0 \"atomics\"\nOpName %109 \"BloomBuffer32\"\nOpName %117 \"ValidateBDALoadStore\"\nOpName %111 \"BDA\"\nOpName %112 \"offset\"\nOpName %113 \"len\"\nOpName %114 \"type\"\nOpName %115 \"invocation_id\"\nOpName %116 \"in_bounds\"\nOpName %125 \"IAddCarryResult\"\nOpName %130 \"addr\"\nOpName %131 \"addr_lo\"\nOpName %135 \"byte_mask\"\nOpName %145 \"word_mask\"\nOpName %150 \"hash_mask\"\nOpName %155 \"hash_offset\"\nOpName %159 \"bloom_index\"\nOpName %163 \"bloom_index\"\nOpName %167 \"bloom_index\"\nOpName %170 \"bloom_index\"\nOpName %174 \"bloom_index\"\nOpName %178 \"bloom_index\"\nOpName %182 \"bloom_index\"\nOpName %186 \"bloom_index\"\nOpName %190 \"bloom_index\"\nOpName %194 \"bloom_index\"\nOpName %198 \"bloom_index\"\nOpName %202 \"bloom_index\"\nOpName %206 \"bloom_index\"\nOpName %210 \"bloom_index\"\nOpName %214 \"bloom_index\"\nOpName %218 \"bloom_index\"\nOpName %231 \"invalidation_mask\"\nOpName %234 \"prev_hazard_partial\"\nOpName %236 \"prev_hazard_partial\"\nOpName %239 \"prev_hazard_partial\"\nOpName %242 \"prev_hazard_partial\"\nOpName %245 \"prev_hazard_partial\"\nOpName %248 \"prev_hazard_partial\"\nOpName %251 \"prev_hazard_partial\"\nOpName %254 \"prev_hazard_partial\"\nOpName %257 \"prev_hazard_partial\"\nOpName %260 \"prev_hazard_partial\"\nOpName %263 \"prev_hazard_partial\"\nOpName %266 \"prev_hazard_partial\"\nOpName %269 \"prev_hazard_partial\"\nOpName %272 \"prev_hazard_partial\"\nOpName %275 \"prev_hazard_partial\"\nOpName %278 \"prev_hazard_partial\"\nOpName %280 \"prev_hazard\"\nOpName %281 \"prev_hazard_lo\"\nOpName %282 \"prev_hazard_hi\"\nOpName %285 \"has_exclusive_access\"\nOpName %300 \"lock_mask\"\nOpName %303 \"prev_lock\"\nOpName %316 \"lock_mask\"\nOpName %319 \"prev_lock\"\nOpName %333 \"lock_mask\"\nOpName %336 \"prev_lock\"\nOpName %350 \"lock_mask\"\nOpName %353 \"prev_lock\"\nOpName %367 \"lock_mask\"\nOpName %370 \"prev_lock\"\nOpName %381 \"lock_mask\"\nOpName %384 \"prev_lock\"\nOpName %397 \"lock_mask\"\nOpName %400 \"prev_lock\"\nOpName %414 \"lock_mask\"\nOpName %417 \"prev_lock\"\nOpName %420 \"has_complete_self_lock\"\nOpName %436 \"hazard\"\nOpName %454 \"ShouldReportInstrumentation\"\nOpName %457 \"InstrumentationControlDataSSBO\"\nOpMemberName %457 0 \"atomics\"\nOpName %459 \"InstrumentationControlData\"\nOpName %461 \"InstrumentationDataSSBO\"\nOpMemberName %461 0 \"data\"\nOpName %463 \"InstrumentationData\"\nOpName %467 \"AssumeTrue\"\nOpName %465 \"value\"\nOpName %466 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %22 DescriptorSet 4\nOpDecorate %22 Binding 0\nOpDecorate %23 ArrayStride 4\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 2\nOpDecorate %55 BuiltIn GlobalInvocationId\nOpDecorate %102 ArrayStride 8\nOpMemberDecorate %103 0 Offset 0\nOpDecorate %103 Block\nOpDecorate %105 DescriptorSet 0\nOpDecorate %105 Binding 2\nOpDecorate %106 ArrayStride 8\nOpMemberDecorate %107 0 Offset 0\nOpDecorate %107 Block\nOpDecorate %109 DescriptorSet 0\nOpDecorate %109 Binding 2\nOpDecorate %456 ArrayStride 4\nOpMemberDecorate %457 0 Offset 0\nOpDecorate %457 Block\nOpDecorate %459 DescriptorSet 0\nOpDecorate %459 Binding 2\nOpDecorate %460 ArrayStride 16\nOpMemberDecorate %461 0 Offset 0\nOpDecorate %461 Block\nOpDecorate %463 DescriptorSet 0\nOpDecorate %463 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeRuntimeArray %5\n%24 = OpTypeStruct %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeFunction %5\n%32 = OpTypePointer StorageBuffer %5\n%34 = OpConstant %5 0\n%36 = OpConstant %5 1103633207\n%39 = OpTypePointer UniformConstant %19\n%41 = OpTypePointer PushConstant %5\n%43 = OpConstant %5 4\n%45 = OpTypePointer StorageBuffer %9\n%50 = OpConstant %5 16\n%53 = OpTypeVector %5 3\n%54 = OpTypePointer Input %53\n%55 = OpVariable %54 Input\n%56 = OpTypePointer Input %5\n%60 = OpTypeFunction %5 %9 %5\n%71 = OpConstant %5 65535\n%72 = OpConstant %5 8\n%73 = OpConstantComposite %9 %72 %72\n%100 = OpTypeInt 64 0\n%101 = OpTypeBool\n%102 = OpTypeRuntimeArray %100\n%103 = OpTypeStruct %102\n%104 = OpTypePointer StorageBuffer %103\n%105 = OpVariable %104 StorageBuffer\n%106 = OpTypeRuntimeArray %9\n%107 = OpTypeStruct %106\n%108 = OpTypePointer StorageBuffer %107\n%109 = OpVariable %108 StorageBuffer\n%110 = OpTypeFunction %101 %9 %5 %5 %5 %5 %101\n%121 = OpConstantTrue %101\n%125 = OpTypeStruct %5 %5\n%136 = OpConstant %5 4294967295\n%137 = OpConstant %5 15\n%146 = OpConstant %5 3\n%147 = OpConstant %5 2\n%157 = OpConstant %5 1103515245\n%161 = OpConstant %5 1103518333\n%165 = OpConstant %5 1103539331\n%172 = OpConstant %5 10006121\n%176 = OpConstant %5 4004951\n%180 = OpConstant %5 5005159\n%184 = OpConstant %5 6004811\n%188 = OpConstant %5 383\n%192 = OpConstant %5 821\n%196 = OpConstant %5 661\n%200 = OpConstant %5 1091\n%204 = OpConstant %5 1117\n%208 = OpConstant %5 3947\n%212 = OpConstant %5 4253\n%216 = OpConstant %5 7691\n%219 = OpTypeVector %100 4\n%220 = OpConstant %100 68719411200\n%221 = OpConstant %100 1099511627775\n%222 = OpConstant %100 1035087118335\n%223 = OpConstantComposite %219 %220 %221 %222 %220\n%232 = OpTypePointer StorageBuffer %100\n%287 = OpTypeInt 32 1\n%288 = OpConstant %287 0\n%289 = OpConstant %287 3\n%291 = OpConstant %5 256\n%294 = OpConstant %5 65536\n%297 = OpConstant %287 6\n%299 = OpConstant %5 16777216\n%307 = OpConstant %287 9\n%310 = OpConstant %287 12\n%314 = OpConstant %287 15\n%324 = OpConstant %287 18\n%327 = OpConstant %287 21\n%331 = OpConstant %287 24\n%341 = OpConstant %287 23\n%344 = OpConstant %287 26\n%348 = OpConstant %287 29\n%358 = OpConstant %287 1\n%361 = OpConstant %287 4\n%365 = OpConstant %287 7\n%389 = OpConstant %287 17\n%392 = OpConstant %287 20\n%405 = OpConstant %287 22\n%408 = OpConstant %287 25\n%412 = OpConstant %287 28\n%443 = OpTypePointer Image %5\n%453 = OpTypePointer Private %101\n%454 = OpVariable %453 Private %121\n%455 = OpTypeVector %5 4\n%456 = OpTypeRuntimeArray %5\n%457 = OpTypeStruct %456\n%458 = OpTypePointer StorageBuffer %457\n%459 = OpVariable %458 StorageBuffer\n%460 = OpTypeRuntimeArray %455\n%461 = OpTypeStruct %460\n%462 = OpTypePointer StorageBuffer %461\n%463 = OpVariable %462 StorageBuffer\n%464 = OpTypeFunction %1 %101 %5\n%478 = OpConstant %5 97\n%479 = OpConstant %5 43981\n%485 = OpConstant %5 51329\n%497 = OpConstantFalse %101\n%500 = OpTypePointer StorageBuffer %455\n%503 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %452\n%452 = OpLabel\n%38 = OpFunctionCall %5 %28\nOpStore %18 %38\n%42 = OpAccessChain %41 %8 %43\n%44 = OpLoad %5 %42\n%46 = OpAccessChain %45 %16 %34 %44 %34 %34\n%47 = OpLoad %9 %46\n%48 = OpCompositeExtract %5 %47 1\n%49 = OpShiftRightLogical %5 %48 %50\n%40 = OpAccessChain %39 %22 %44\n%51 = OpLoad %19 %40\n%52 = OpImageQuerySize %5 %51\n%57 = OpAccessChain %56 %55 %34\n%58 = OpLoad %5 %57\n%59 = OpIMul %5 %58 %49\n%441 = OpLoad %5 %18\n%442 = OpULessThan %101 %58 %52\n%440 = OpFunctionCall %101 %117 %47 %59 %43 %147 %441 %442\n%505 = OpFunctionCall %1 %467 %440 %10\n%444 = OpImageTexelPointer %443 %40 %58 %34\n%445 = OpAtomicIAdd %5 %444 %10 %34 %10\n%446 = OpIMul %5 %58 %49\n%448 = OpLoad %5 %18\n%449 = OpULessThan %101 %58 %52\n%447 = OpFunctionCall %101 %117 %47 %446 %43 %147 %448 %449\n%506 = OpFunctionCall %1 %467 %447 %147\n%450 = OpImageTexelPointer %443 %40 %58 %34\n%451 = OpAtomicCompareExchange %5 %450 %10 %34 %34 %147 %10\nOpReturn\nOpFunctionEnd\n%28 = OpFunction %5 None %27\n%29 = OpLabel\n%30 = OpArrayLength %5 %26 0\n%31 = OpISub %5 %30 %10\n%33 = OpAccessChain %32 %26 %34 %31\n%35 = OpAtomicIAdd %5 %33 %10 %34 %36\nOpReturnValue %35\nOpFunctionEnd\n%63 = OpFunction %5 None %60\n%61 = OpFunctionParameter %9\n%62 = OpFunctionParameter %5\n%64 = OpLabel\n%65 = OpCompositeExtract %5 %61 0\n%66 = OpCompositeExtract %5 %61 1\n%67 = OpShiftRightLogical %5 %65 %43\n%68 = OpBitwiseAnd %5 %66 %71\n%69 = OpCompositeConstruct %9 %67 %68\n%70 = OpCompositeConstruct %9 %62 %62\n%74 = OpVectorShuffle %9 %69 %69 1 0\n%75 = OpShiftRightLogical %9 %69 %73\n%76 = OpBitwiseXor %9 %75 %74\n%77 = OpIMul %9 %76 %70\n%78 = OpVectorShuffle %9 %77 %77 1 0\n%79 = OpShiftRightLogical %9 %77 %73\n%80 = OpBitwiseXor %9 %79 %78\n%81 = OpIMul %9 %80 %70\n%82 = OpVectorShuffle %9 %81 %81 1 0\n%83 = OpShiftRightLogical %9 %81 %73\n%84 = OpBitwiseXor %9 %83 %82\n%85 = OpIMul %9 %84 %70\n%86 = OpVectorShuffle %9 %85 %85 1 0\n%87 = OpShiftRightLogical %9 %85 %73\n%88 = OpBitwiseXor %9 %87 %86\n%89 = OpIMul %9 %88 %70\n%90 = OpVectorShuffle %9 %89 %89 1 0\n%91 = OpShiftRightLogical %9 %89 %73\n%92 = OpBitwiseXor %9 %91 %90\n%93 = OpIMul %9 %92 %70\n%94 = OpVectorShuffle %9 %93 %93 1 0\n%95 = OpShiftRightLogical %9 %93 %73\n%96 = OpBitwiseXor %9 %95 %94\n%97 = OpIMul %9 %96 %70\n%98 = OpCompositeExtract %5 %97 0\nOpReturnValue %98\nOpFunctionEnd\n%117 = OpFunction %101 None %110\n%111 = OpFunctionParameter %9\n%112 = OpFunctionParameter %5\n%113 = OpFunctionParameter %5\n%114 = OpFunctionParameter %5\n%115 = OpFunctionParameter %5\n%116 = OpFunctionParameter %101\n%118 = OpLabel\nOpSelectionMerge %120 None\nOpBranchConditional %116 %120 %119\n%119 = OpLabel\nOpReturnValue %121\n%120 = OpLabel\n%123 = OpCompositeExtract %5 %111 0\n%124 = OpCompositeExtract %5 %111 1\n%126 = OpIAddCarry %125 %123 %112\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpCompositeExtract %5 %126 1\n%129 = OpIAdd %5 %124 %128\n%130 = OpCompositeConstruct %9 %127 %129\n%131 = OpCompositeExtract %5 %130 0\n%132 = OpBitFieldUExtract %5 %136 %34 %113\n%133 = OpBitwiseAnd %5 %131 %137\n%134 = OpShiftLeftLogical %5 %132 %133\n%135 = OpBitwiseAnd %5 %134 %71\n%138 = OpBitwiseAnd %5 %131 %146\n%139 = OpIAdd %5 %138 %113\n%140 = OpIAdd %5 %139 %146\n%141 = OpShiftRightLogical %5 %140 %147\n%142 = OpBitFieldUExtract %5 %131 %147 %147\n%143 = OpBitFieldUExtract %5 %136 %34 %141\n%144 = OpShiftLeftLogical %5 %143 %142\n%145 = OpBitwiseAnd %5 %144 %137\n%148 = OpArrayLength %5 %105 0\n%149 = OpExtInst %5 %151 FindUMsb %148\n%150 = OpBitFieldUExtract %5 %136 %34 %149\n%152 = OpArrayLength %5 %105 0\n%153 = OpExtInst %5 %151 FindUMsb %152\n%154 = OpBitFieldUExtract %5 %152 %34 %153\n%155 = OpISub %5 %154 %10\n%156 = OpFunctionCall %5 %63 %130 %157\n%158 = OpBitwiseAnd %5 %156 %150\n%159 = OpIAdd %5 %158 %155\n%160 = OpFunctionCall %5 %63 %130 %161\n%162 = OpBitwiseAnd %5 %160 %150\n%163 = OpIAdd %5 %162 %155\n%164 = OpFunctionCall %5 %63 %130 %165\n%166 = OpBitwiseAnd %5 %164 %150\n%167 = OpIAdd %5 %166 %155\n%168 = OpFunctionCall %5 %63 %130 %36\n%169 = OpBitwiseAnd %5 %168 %150\n%170 = OpIAdd %5 %169 %155\n%171 = OpFunctionCall %5 %63 %130 %172\n%173 = OpBitwiseAnd %5 %171 %150\n%174 = OpIAdd %5 %173 %155\n%175 = OpFunctionCall %5 %63 %130 %176\n%177 = OpBitwiseAnd %5 %175 %150\n%178 = OpIAdd %5 %177 %155\n%179 = OpFunctionCall %5 %63 %130 %180\n%181 = OpBitwiseAnd %5 %179 %150\n%182 = OpIAdd %5 %181 %155\n%183 = OpFunctionCall %5 %63 %130 %184\n%185 = OpBitwiseAnd %5 %183 %150\n%186 = OpIAdd %5 %185 %155\n%187 = OpFunctionCall %5 %63 %130 %188\n%189 = OpBitwiseAnd %5 %187 %150\n%190 = OpIAdd %5 %189 %155\n%191 = OpFunctionCall %5 %63 %130 %192\n%193 = OpBitwiseAnd %5 %191 %150\n%194 = OpIAdd %5 %193 %155\n%195 = OpFunctionCall %5 %63 %130 %196\n%197 = OpBitwiseAnd %5 %195 %150\n%198 = OpIAdd %5 %197 %155\n%199 = OpFunctionCall %5 %63 %130 %200\n%201 = OpBitwiseAnd %5 %199 %150\n%202 = OpIAdd %5 %201 %155\n%203 = OpFunctionCall %5 %63 %130 %204\n%205 = OpBitwiseAnd %5 %203 %150\n%206 = OpIAdd %5 %205 %155\n%207 = OpFunctionCall %5 %63 %130 %208\n%209 = OpBitwiseAnd %5 %207 %150\n%210 = OpIAdd %5 %209 %155\n%211 = OpFunctionCall %5 %63 %130 %212\n%213 = OpBitwiseAnd %5 %211 %150\n%214 = OpIAdd %5 %213 %155\n%215 = OpFunctionCall %5 %63 %130 %216\n%217 = OpBitwiseAnd %5 %215 %150\n%218 = OpIAdd %5 %217 %155\n%224 = OpVectorExtractDynamic %100 %223 %114\n%225 = OpShiftLeftLogical %5 %135 %50\n%226 = OpShiftLeftLogical %5 %145 %43\n%227 = OpBitwiseOr %5 %135 %225\n%228 = OpBitwiseOr %5 %145 %226\n%229 = OpCompositeConstruct %9 %227 %228\n%230 = OpBitcast %100 %229\n%231 = OpBitwiseAnd %100 %224 %230\n%233 = OpInBoundsAccessChain %232 %105 %34 %159\n%234 = OpAtomicOr %100 %233 %10 %34 %231\n%235 = OpInBoundsAccessChain %232 %105 %34 %163\n%236 = OpAtomicOr %100 %235 %10 %34 %231\n%237 = OpBitwiseAnd %100 %234 %236\n%238 = OpInBoundsAccessChain %232 %105 %34 %167\n%239 = OpAtomicOr %100 %238 %10 %34 %231\n%240 = OpBitwiseAnd %100 %237 %239\n%241 = OpInBoundsAccessChain %232 %105 %34 %170\n%242 = OpAtomicOr %100 %241 %10 %34 %231\n%243 = OpBitwiseAnd %100 %240 %242\n%244 = OpInBoundsAccessChain %232 %105 %34 %174\n%245 = OpAtomicOr %100 %244 %10 %34 %231\n%246 = OpBitwiseAnd %100 %243 %245\n%247 = OpInBoundsAccessChain %232 %105 %34 %178\n%248 = OpAtomicOr %100 %247 %10 %34 %231\n%249 = OpBitwiseAnd %100 %246 %248\n%250 = OpInBoundsAccessChain %232 %105 %34 %182\n%251 = OpAtomicOr %100 %250 %10 %34 %231\n%252 = OpBitwiseAnd %100 %249 %251\n%253 = OpInBoundsAccessChain %232 %105 %34 %186\n%254 = OpAtomicOr %100 %253 %10 %34 %231\n%255 = OpBitwiseAnd %100 %252 %254\n%256 = OpInBoundsAccessChain %232 %105 %34 %190\n%257 = OpAtomicOr %100 %256 %10 %34 %231\n%258 = OpBitwiseAnd %100 %255 %257\n%259 = OpInBoundsAccessChain %232 %105 %34 %194\n%260 = OpAtomicOr %100 %259 %10 %34 %231\n%261 = OpBitwiseAnd %100 %258 %260\n%262 = OpInBoundsAccessChain %232 %105 %34 %198\n%263 = OpAtomicOr %100 %262 %10 %34 %231\n%264 = OpBitwiseAnd %100 %261 %263\n%265 = OpInBoundsAccessChain %232 %105 %34 %202\n%266 = OpAtomicOr %100 %265 %10 %34 %231\n%267 = OpBitwiseAnd %100 %264 %266\n%268 = OpInBoundsAccessChain %232 %105 %34 %206\n%269 = OpAtomicOr %100 %268 %10 %34 %231\n%270 = OpBitwiseAnd %100 %267 %269\n%271 = OpInBoundsAccessChain %232 %105 %34 %210\n%272 = OpAtomicOr %100 %271 %10 %34 %231\n%273 = OpBitwiseAnd %100 %270 %272\n%274 = OpInBoundsAccessChain %232 %105 %34 %214\n%275 = OpAtomicOr %100 %274 %10 %34 %231\n%276 = OpBitwiseAnd %100 %273 %275\n%277 = OpInBoundsAccessChain %232 %105 %34 %218\n%278 = OpAtomicOr %100 %277 %10 %34 %231\n%279 = OpBitwiseAnd %100 %276 %278\n%280 = OpBitcast %9 %279\n%281 = OpCompositeExtract %5 %280 0\n%282 = OpCompositeExtract %5 %280 1\n%283 = OpShiftRightLogical %5 %281 %50\n%284 = OpBitwiseAnd %5 %283 %135\n%285 = OpIEqual %101 %284 %34\n%286 = OpBitFieldUExtract %5 %115 %288 %289\n%290 = OpShiftLeftLogical %5 %291 %286\n%292 = OpBitFieldUExtract %5 %115 %289 %289\n%293 = OpShiftLeftLogical %5 %294 %292\n%295 = OpBitwiseOr %5 %290 %293\n%296 = OpBitFieldUExtract %5 %115 %297 %289\n%298 = OpShiftLeftLogical %5 %299 %296\n%300 = OpBitwiseOr %5 %295 %298\n%301 = OpSelect %5 %285 %300 %34\n%302 = OpInBoundsAccessChain %32 %109 %34 %159 %10\n%303 = OpAtomicOr %5 %302 %10 %34 %301\n%304 = OpBitwiseAnd %5 %303 %300\n%305 = OpIEqual %101 %304 %300\n%306 = OpBitFieldUExtract %5 %115 %307 %289\n%308 = OpShiftLeftLogical %5 %291 %306\n%309 = OpBitFieldUExtract %5 %115 %310 %289\n%311 = OpShiftLeftLogical %5 %294 %309\n%312 = OpBitwiseOr %5 %308 %311\n%313 = OpBitFieldUExtract %5 %115 %314 %289\n%315 = OpShiftLeftLogical %5 %299 %313\n%316 = OpBitwiseOr %5 %312 %315\n%317 = OpSelect %5 %285 %316 %34\n%318 = OpInBoundsAccessChain %32 %109 %34 %163 %10\n%319 = OpAtomicOr %5 %318 %10 %34 %317\n%320 = OpBitwiseAnd %5 %319 %316\n%321 = OpIEqual %101 %320 %316\n%322 = OpLogicalAnd %101 %305 %321\n%323 = OpBitFieldUExtract %5 %115 %324 %289\n%325 = OpShiftLeftLogical %5 %291 %323\n%326 = OpBitFieldUExtract %5 %115 %327 %289\n%328 = OpShiftLeftLogical %5 %294 %326\n%329 = OpBitwiseOr %5 %325 %328\n%330 = OpBitFieldUExtract %5 %115 %331 %289\n%332 = OpShiftLeftLogical %5 %299 %330\n%333 = OpBitwiseOr %5 %329 %332\n%334 = OpSelect %5 %285 %333 %34\n%335 = OpInBoundsAccessChain %32 %109 %34 %167 %10\n%336 = OpAtomicOr %5 %335 %10 %34 %334\n%337 = OpBitwiseAnd %5 %336 %333\n%338 = OpIEqual %101 %337 %333\n%339 = OpLogicalAnd %101 %322 %338\n%340 = OpBitFieldUExtract %5 %115 %341 %289\n%342 = OpShiftLeftLogical %5 %291 %340\n%343 = OpBitFieldUExtract %5 %115 %344 %289\n%345 = OpShiftLeftLogical %5 %294 %343\n%346 = OpBitwiseOr %5 %342 %345\n%347 = OpBitFieldUExtract %5 %115 %348 %289\n%349 = OpShiftLeftLogical %5 %299 %347\n%350 = OpBitwiseOr %5 %346 %349\n%351 = OpSelect %5 %285 %350 %34\n%352 = OpInBoundsAccessChain %32 %109 %34 %170 %10\n%353 = OpAtomicOr %5 %352 %10 %34 %351\n%354 = OpBitwiseAnd %5 %353 %350\n%355 = OpIEqual %101 %354 %350\n%356 = OpLogicalAnd %101 %339 %355\n%357 = OpBitFieldUExtract %5 %115 %358 %289\n%359 = OpShiftLeftLogical %5 %291 %357\n%360 = OpBitFieldUExtract %5 %115 %361 %289\n%362 = OpShiftLeftLogical %5 %294 %360\n%363 = OpBitwiseOr %5 %359 %362\n%364 = OpBitFieldUExtract %5 %115 %365 %289\n%366 = OpShiftLeftLogical %5 %299 %364\n%367 = OpBitwiseOr %5 %363 %366\n%368 = OpSelect %5 %285 %367 %34\n%369 = OpInBoundsAccessChain %32 %109 %34 %174 %10\n%370 = OpAtomicOr %5 %369 %10 %34 %368\n%371 = OpBitwiseAnd %5 %370 %367\n%372 = OpIEqual %101 %371 %367\n%373 = OpLogicalAnd %101 %356 %372\n%374 = OpBitFieldUExtract %5 %115 %307 %289\n%375 = OpShiftLeftLogical %5 %291 %374\n%376 = OpBitFieldUExtract %5 %115 %310 %289\n%377 = OpShiftLeftLogical %5 %294 %376\n%378 = OpBitwiseOr %5 %375 %377\n%379 = OpBitFieldUExtract %5 %115 %314 %289\n%380 = OpShiftLeftLogical %5 %299 %379\n%381 = OpBitwiseOr %5 %378 %380\n%382 = OpSelect %5 %285 %381 %34\n%383 = OpInBoundsAccessChain %32 %109 %34 %178 %10\n%384 = OpAtomicOr %5 %383 %10 %34 %382\n%385 = OpBitwiseAnd %5 %384 %381\n%386 = OpIEqual %101 %385 %381\n%387 = OpLogicalAnd %101 %373 %386\n%388 = OpBitFieldUExtract %5 %115 %389 %289\n%390 = OpShiftLeftLogical %5 %291 %388\n%391 = OpBitFieldUExtract %5 %115 %392 %289\n%393 = OpShiftLeftLogical %5 %294 %391\n%394 = OpBitwiseOr %5 %390 %393\n%395 = OpBitFieldUExtract %5 %115 %341 %289\n%396 = OpShiftLeftLogical %5 %299 %395\n%397 = OpBitwiseOr %5 %394 %396\n%398 = OpSelect %5 %285 %397 %34\n%399 = OpInBoundsAccessChain %32 %109 %34 %182 %10\n%400 = OpAtomicOr %5 %399 %10 %34 %398\n%401 = OpBitwiseAnd %5 %400 %397\n%402 = OpIEqual %101 %401 %397\n%403 = OpLogicalAnd %101 %387 %402\n%404 = OpBitFieldUExtract %5 %115 %405 %289\n%406 = OpShiftLeftLogical %5 %291 %404\n%407 = OpBitFieldUExtract %5 %115 %408 %289\n%409 = OpShiftLeftLogical %5 %294 %407\n%410 = OpBitwiseOr %5 %406 %409\n%411 = OpBitFieldUExtract %5 %115 %412 %289\n%413 = OpShiftLeftLogical %5 %299 %411\n%414 = OpBitwiseOr %5 %410 %413\n%415 = OpSelect %5 %285 %414 %34\n%416 = OpInBoundsAccessChain %32 %109 %34 %186 %10\n%417 = OpAtomicOr %5 %416 %10 %34 %415\n%418 = OpBitwiseAnd %5 %417 %414\n%419 = OpIEqual %101 %418 %414\n%420 = OpLogicalAnd %101 %403 %419\nOpSelectionMerge %425 None\nOpSwitch %114 %424 0 %421 1 %422 2 %423\n%424 = OpLabel\n%433 = OpShiftLeftLogical %5 %145 %43\n%434 = OpBitwiseAnd %5 %282 %433\n%435 = OpINotEqual %101 %434 %34\nOpBranch %425\n%421 = OpLabel\n%426 = OpBitwiseAnd %5 %281 %135\n%427 = OpINotEqual %101 %426 %34\nOpBranch %425\n%422 = OpLabel\n%428 = OpShiftLeftLogical %5 %135 %50\n%429 = OpBitwiseAnd %5 %281 %428\n%430 = OpINotEqual %101 %429 %34\nOpBranch %425\n%423 = OpLabel\n%431 = OpBitwiseAnd %5 %282 %145\n%432 = OpINotEqual %101 %431 %34\nOpBranch %425\n%425 = OpLabel\n%436 = OpPhi %101 %427 %421 %430 %422 %432 %423 %435 %424\n%437 = OpLogicalNot %101 %436\n%438 = OpLogicalOr %101 %437 %420\nOpReturnValue %438\nOpFunctionEnd\n%467 = OpFunction %1 None %464\n%465 = OpFunctionParameter %101\n%466 = OpFunctionParameter %5\n%468 = OpLabel\n%471 = OpLogicalNot %101 %465\n%472 = OpLoad %101 %454\n%473 = OpLogicalAnd %101 %471 %472\nOpSelectionMerge %469 None\nOpBranchConditional %473 %470 %469\n%470 = OpLabel\n%476 = OpIMul %5 %466 %478\n%477 = OpBitwiseXor %5 %476 %479\n%480 = OpArrayLength %5 %459 0\n%481 = OpISub %5 %480 %147\n%482 = OpAccessChain %32 %459 %34 %481\n%483 = OpLoad %5 %482\n%484 = OpIMul %5 %483 %485\n%486 = OpBitwiseXor %5 %477 %484\n%487 = OpArrayLength %5 %463 0\n%488 = OpISub %5 %487 %10\n%489 = OpBitwiseAnd %5 %486 %488\n%490 = OpShiftRightLogical %5 %489 %43\n%491 = OpBitwiseAnd %5 %489 %137\n%492 = OpShiftLeftLogical %5 %10 %491\n%493 = OpAccessChain %32 %459 %34 %490\n%494 = OpAtomicOr %5 %493 %10 %34 %492\n%495 = OpBitwiseAnd %5 %494 %492\n%496 = OpIEqual %101 %495 %34\nOpStore %454 %497\nOpSelectionMerge %475 None\nOpBranchConditional %496 %474 %475\n%474 = OpLabel\n%498 = OpCompositeConstruct %455 %479 %34 %466 %483\n%499 = OpShiftLeftLogical %5 %492 %50\n%501 = OpAccessChain %500 %463 %34 %489\nOpStore %501 %498\nOpMemoryBarrier %10 %503\n%502 = OpAtomicOr %5 %493 %10 %34 %499\nOpMemoryBarrier %10 %503\nOpBranch %475\n%475 = OpLabel\nOpBranch %469\n%469 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/cbv.bindless.bda-instrumentation.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _30[];\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform uimageBuffer _22[];\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _43 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _43;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _91 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _92 = uvec2(prime);\n    uvec2 _99 = ((_91 >> uvec2(8u)) ^ _91.yx) * _92;\n    uvec2 _103 = ((_99 >> uvec2(8u)) ^ _99.yx) * _92;\n    uvec2 _107 = ((_103 >> uvec2(8u)) ^ _103.yx) * _92;\n    uvec2 _111 = ((_107 >> uvec2(8u)) ^ _107.yx) * _92;\n    uvec2 _115 = ((_111 >> uvec2(8u)) ^ _111.yx) * _92;\n    return (((_115 >> uvec2(8u)) ^ _115.yx) * _92).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _148;\n    _148._m0 = uaddCarry(BDA.x, offset, _148._m1);\n    uvec2 addr = uvec2(_148._m0, BDA.y + _148._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _517 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _519 = InstrumentationControlData.atomics[_517];\n        uint _525 = (((inst * 97u) ^ 43981u) ^ (_519 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _526 = _525 >> 4u;\n        uint _528 = 1u << (_525 & 15u);\n        uint _530 = atomicOr(InstrumentationControlData.atomics[_526], _528);\n        ShouldReportInstrumentation = false;\n        if ((_530 & _528) == 0u)\n        {\n            InstrumentationData.data[_525] = uvec4(43981u, 0u, inst, _519);\n            memoryBarrierBuffer();\n            uint _538 = atomicOr(InstrumentationControlData.atomics[_526], _528 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _46 = AllocateInvocationID();\n    InvocationID = _46;\n    uvec2 _55 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _61 = uint(imageSize(_22[registers._m4])) * 4u;\n    uint _68 = gl_GlobalInvocationID.x >> 4u;\n    uint _75 = registers._m5 + (gl_GlobalInvocationID.x + 0u);\n    uvec2 _77 = DescriptorHeapRobustness.descriptors[_75]._m0[0u];\n    uint _81 = _68 * 16u;\n    uint _462 = InvocationID;\n    bool _461 = ValidateBDALoadStore(_77, _81, 16u, 0u, _462, _81 < 65536u);\n    AssumeTrue(_461, 1u);\n    uint _473 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _475 = InvocationID;\n    bool _474 = ValidateBDALoadStore(_55, _473, 4u, 0u, _475, _473 < _61);\n    AssumeTrue(_474, 2u);\n    uvec4 _478 = imageLoad(_22[registers._m4], int(gl_GlobalInvocationID.x));\n    uint _483 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _485 = InvocationID;\n    bool _484 = ValidateBDALoadStore(_55, _483, 4u, 1u, _485, _483 < _61);\n    AssumeTrue(_484, 3u);\n    imageStore(_22[registers._m4], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(((_30[_75]._m0[_68].x + 40.0) + _30[_75]._m0[_68].z) + uintBitsToFloat(_478.x))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 545\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%173 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %64\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %27 \"BindlessCBV\"\nOpName %32 \"BloomBufferInvocationSSBO\"\nOpMemberName %32 0 \"atomics\"\nOpName %34 \"BloomBufferInvocation\"\nOpName %36 \"AllocateInvocationID\"\nOpName %85 \"AddrHash\"\nOpName %83 \"addr\"\nOpName %84 \"prime\"\nOpName %125 \"BloomBufferSSBO\"\nOpMemberName %125 0 \"atomics\"\nOpName %127 \"BloomBuffer\"\nOpName %129 \"BloomBuffer32SSBO\"\nOpMemberName %129 0 \"atomics\"\nOpName %131 \"BloomBuffer32\"\nOpName %139 \"ValidateBDALoadStore\"\nOpName %133 \"BDA\"\nOpName %134 \"offset\"\nOpName %135 \"len\"\nOpName %136 \"type\"\nOpName %137 \"invocation_id\"\nOpName %138 \"in_bounds\"\nOpName %147 \"IAddCarryResult\"\nOpName %152 \"addr\"\nOpName %153 \"addr_lo\"\nOpName %157 \"byte_mask\"\nOpName %167 \"word_mask\"\nOpName %172 \"hash_mask\"\nOpName %177 \"hash_offset\"\nOpName %181 \"bloom_index\"\nOpName %185 \"bloom_index\"\nOpName %189 \"bloom_index\"\nOpName %192 \"bloom_index\"\nOpName %196 \"bloom_index\"\nOpName %200 \"bloom_index\"\nOpName %204 \"bloom_index\"\nOpName %208 \"bloom_index\"\nOpName %212 \"bloom_index\"\nOpName %216 \"bloom_index\"\nOpName %220 \"bloom_index\"\nOpName %224 \"bloom_index\"\nOpName %228 \"bloom_index\"\nOpName %232 \"bloom_index\"\nOpName %236 \"bloom_index\"\nOpName %240 \"bloom_index\"\nOpName %253 \"invalidation_mask\"\nOpName %256 \"prev_hazard_partial\"\nOpName %258 \"prev_hazard_partial\"\nOpName %261 \"prev_hazard_partial\"\nOpName %264 \"prev_hazard_partial\"\nOpName %267 \"prev_hazard_partial\"\nOpName %270 \"prev_hazard_partial\"\nOpName %273 \"prev_hazard_partial\"\nOpName %276 \"prev_hazard_partial\"\nOpName %279 \"prev_hazard_partial\"\nOpName %282 \"prev_hazard_partial\"\nOpName %285 \"prev_hazard_partial\"\nOpName %288 \"prev_hazard_partial\"\nOpName %291 \"prev_hazard_partial\"\nOpName %294 \"prev_hazard_partial\"\nOpName %297 \"prev_hazard_partial\"\nOpName %300 \"prev_hazard_partial\"\nOpName %302 \"prev_hazard\"\nOpName %303 \"prev_hazard_lo\"\nOpName %304 \"prev_hazard_hi\"\nOpName %307 \"has_exclusive_access\"\nOpName %321 \"lock_mask\"\nOpName %324 \"prev_lock\"\nOpName %337 \"lock_mask\"\nOpName %340 \"prev_lock\"\nOpName %354 \"lock_mask\"\nOpName %357 \"prev_lock\"\nOpName %371 \"lock_mask\"\nOpName %374 \"prev_lock\"\nOpName %388 \"lock_mask\"\nOpName %391 \"prev_lock\"\nOpName %402 \"lock_mask\"\nOpName %405 \"prev_lock\"\nOpName %418 \"lock_mask\"\nOpName %421 \"prev_lock\"\nOpName %435 \"lock_mask\"\nOpName %438 \"prev_lock\"\nOpName %441 \"has_complete_self_lock\"\nOpName %457 \"hazard\"\nOpName %491 \"ShouldReportInstrumentation\"\nOpName %493 \"InstrumentationControlDataSSBO\"\nOpMemberName %493 0 \"atomics\"\nOpName %495 \"InstrumentationControlData\"\nOpName %497 \"InstrumentationDataSSBO\"\nOpMemberName %497 0 \"data\"\nOpName %499 \"InstrumentationData\"\nOpName %503 \"AssumeTrue\"\nOpName %501 \"value\"\nOpName %502 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %22 DescriptorSet 4\nOpDecorate %22 Binding 0\nOpDecorate %26 ArrayStride 16\nOpDecorate %27 Block\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %30 DescriptorSet 5\nOpDecorate %30 Binding 0\nOpDecorate %31 ArrayStride 4\nOpMemberDecorate %32 0 Offset 0\nOpDecorate %32 Block\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 2\nOpDecorate %64 BuiltIn GlobalInvocationId\nOpDecorate %124 ArrayStride 8\nOpMemberDecorate %125 0 Offset 0\nOpDecorate %125 Block\nOpDecorate %127 DescriptorSet 0\nOpDecorate %127 Binding 2\nOpDecorate %128 ArrayStride 8\nOpMemberDecorate %129 0 Offset 0\nOpDecorate %129 Block\nOpDecorate %131 DescriptorSet 0\nOpDecorate %131 Binding 2\nOpDecorate %492 ArrayStride 4\nOpMemberDecorate %493 0 Offset 0\nOpDecorate %493 Block\nOpDecorate %495 DescriptorSet 0\nOpDecorate %495 Binding 2\nOpDecorate %496 ArrayStride 16\nOpMemberDecorate %497 0 Offset 0\nOpDecorate %497 Block\nOpDecorate %499 DescriptorSet 0\nOpDecorate %499 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeFloat 32\n%24 = OpTypeVector %23 4\n%25 = OpConstant %5 4096\n%26 = OpTypeArray %24 %25\n%27 = OpTypeStruct %26\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%31 = OpTypeRuntimeArray %5\n%32 = OpTypeStruct %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeFunction %5\n%40 = OpTypePointer StorageBuffer %5\n%42 = OpConstant %5 0\n%44 = OpConstant %5 1103633207\n%47 = OpTypePointer UniformConstant %19\n%49 = OpTypePointer PushConstant %5\n%51 = OpConstant %5 4\n%53 = OpTypePointer StorageBuffer %9\n%58 = OpConstant %5 16\n%62 = OpTypeVector %5 3\n%63 = OpTypePointer Input %62\n%64 = OpVariable %63 Input\n%65 = OpTypePointer Input %5\n%70 = OpTypePointer Uniform %27\n%73 = OpConstant %5 5\n%80 = OpConstant %5 65536\n%82 = OpTypeFunction %5 %9 %5\n%93 = OpConstant %5 65535\n%94 = OpConstant %5 8\n%95 = OpConstantComposite %9 %94 %94\n%122 = OpTypeInt 64 0\n%123 = OpTypeBool\n%124 = OpTypeRuntimeArray %122\n%125 = OpTypeStruct %124\n%126 = OpTypePointer StorageBuffer %125\n%127 = OpVariable %126 StorageBuffer\n%128 = OpTypeRuntimeArray %9\n%129 = OpTypeStruct %128\n%130 = OpTypePointer StorageBuffer %129\n%131 = OpVariable %130 StorageBuffer\n%132 = OpTypeFunction %123 %9 %5 %5 %5 %5 %123\n%143 = OpConstantTrue %123\n%147 = OpTypeStruct %5 %5\n%158 = OpConstant %5 4294967295\n%159 = OpConstant %5 15\n%168 = OpConstant %5 3\n%169 = OpConstant %5 2\n%179 = OpConstant %5 1103515245\n%183 = OpConstant %5 1103518333\n%187 = OpConstant %5 1103539331\n%194 = OpConstant %5 10006121\n%198 = OpConstant %5 4004951\n%202 = OpConstant %5 5005159\n%206 = OpConstant %5 6004811\n%210 = OpConstant %5 383\n%214 = OpConstant %5 821\n%218 = OpConstant %5 661\n%222 = OpConstant %5 1091\n%226 = OpConstant %5 1117\n%230 = OpConstant %5 3947\n%234 = OpConstant %5 4253\n%238 = OpConstant %5 7691\n%241 = OpTypeVector %122 4\n%242 = OpConstant %122 68719411200\n%243 = OpConstant %122 1099511627775\n%244 = OpConstant %122 1035087118335\n%245 = OpConstantComposite %241 %242 %243 %244 %242\n%254 = OpTypePointer StorageBuffer %122\n%309 = OpTypeInt 32 1\n%310 = OpConstant %309 0\n%311 = OpConstant %309 3\n%313 = OpConstant %5 256\n%318 = OpConstant %309 6\n%320 = OpConstant %5 16777216\n%328 = OpConstant %309 9\n%331 = OpConstant %309 12\n%335 = OpConstant %309 15\n%345 = OpConstant %309 18\n%348 = OpConstant %309 21\n%352 = OpConstant %309 24\n%362 = OpConstant %309 23\n%365 = OpConstant %309 26\n%369 = OpConstant %309 29\n%379 = OpConstant %309 1\n%382 = OpConstant %309 4\n%386 = OpConstant %309 7\n%410 = OpConstant %309 17\n%413 = OpConstant %309 20\n%426 = OpConstant %309 22\n%429 = OpConstant %309 25\n%433 = OpConstant %309 28\n%464 = OpTypePointer Uniform %24\n%470 = OpConstant %23 40\n%477 = OpTypeVector %5 4\n%490 = OpTypePointer Private %123\n%491 = OpVariable %490 Private %143\n%492 = OpTypeRuntimeArray %5\n%493 = OpTypeStruct %492\n%494 = OpTypePointer StorageBuffer %493\n%495 = OpVariable %494 StorageBuffer\n%496 = OpTypeRuntimeArray %477\n%497 = OpTypeStruct %496\n%498 = OpTypePointer StorageBuffer %497\n%499 = OpVariable %498 StorageBuffer\n%500 = OpTypeFunction %1 %123 %5\n%514 = OpConstant %5 97\n%515 = OpConstant %5 43981\n%521 = OpConstant %5 51329\n%533 = OpConstantFalse %123\n%536 = OpTypePointer StorageBuffer %477\n%539 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %489\n%489 = OpLabel\n%46 = OpFunctionCall %5 %36\nOpStore %18 %46\n%50 = OpAccessChain %49 %8 %51\n%52 = OpLoad %5 %50\n%54 = OpAccessChain %53 %16 %42 %52 %42 %42\n%55 = OpLoad %9 %54\n%56 = OpCompositeExtract %5 %55 1\n%57 = OpShiftRightLogical %5 %56 %58\n%48 = OpAccessChain %47 %22 %52\n%59 = OpLoad %19 %48\n%60 = OpImageQuerySize %5 %59\n%61 = OpIMul %5 %60 %51\n%66 = OpAccessChain %65 %64 %42\n%67 = OpLoad %5 %66\n%68 = OpShiftRightLogical %5 %67 %51\n%69 = OpIAdd %5 %67 %42\n%72 = OpAccessChain %49 %8 %73\n%74 = OpLoad %5 %72\n%75 = OpIAdd %5 %74 %69\n%76 = OpAccessChain %53 %16 %42 %75 %42 %42\n%77 = OpLoad %9 %76\n%78 = OpCompositeExtract %5 %77 1\n%79 = OpShiftRightLogical %5 %78 %58\n%71 = OpAccessChain %70 %30 %75\n%81 = OpIMul %5 %68 %58\n%462 = OpLoad %5 %18\n%463 = OpULessThan %123 %81 %80\n%461 = OpFunctionCall %123 %139 %77 %81 %58 %42 %462 %463\n%541 = OpFunctionCall %1 %503 %461 %10\n%465 = OpAccessChain %464 %71 %42 %68\n%466 = OpLoad %24 %465\n%467 = OpCompositeExtract %23 %466 0\n%468 = OpCompositeExtract %23 %466 2\n%469 = OpFAdd %23 %467 %470\n%471 = OpFAdd %23 %469 %468\n%472 = OpIMul %5 %67 %51\n%473 = OpIAdd %5 %472 %42\n%475 = OpLoad %5 %18\n%476 = OpULessThan %123 %473 %61\n%474 = OpFunctionCall %123 %139 %55 %473 %51 %42 %475 %476\n%542 = OpFunctionCall %1 %503 %474 %169\n%478 = OpImageRead %477 %59 %67\n%479 = OpCompositeExtract %5 %478 0\n%480 = OpBitcast %23 %479\n%481 = OpFAdd %23 %471 %480\n%482 = OpIMul %5 %67 %51\n%483 = OpIAdd %5 %482 %42\n%485 = OpLoad %5 %18\n%486 = OpULessThan %123 %483 %61\n%484 = OpFunctionCall %123 %139 %55 %483 %51 %10 %485 %486\n%543 = OpFunctionCall %1 %503 %484 %168\n%487 = OpBitcast %5 %481\n%488 = OpCompositeConstruct %477 %487 %487 %487 %487\nOpImageWrite %59 %67 %488\nOpReturn\nOpFunctionEnd\n%36 = OpFunction %5 None %35\n%37 = OpLabel\n%38 = OpArrayLength %5 %34 0\n%39 = OpISub %5 %38 %10\n%41 = OpAccessChain %40 %34 %42 %39\n%43 = OpAtomicIAdd %5 %41 %10 %42 %44\nOpReturnValue %43\nOpFunctionEnd\n%85 = OpFunction %5 None %82\n%83 = OpFunctionParameter %9\n%84 = OpFunctionParameter %5\n%86 = OpLabel\n%87 = OpCompositeExtract %5 %83 0\n%88 = OpCompositeExtract %5 %83 1\n%89 = OpShiftRightLogical %5 %87 %51\n%90 = OpBitwiseAnd %5 %88 %93\n%91 = OpCompositeConstruct %9 %89 %90\n%92 = OpCompositeConstruct %9 %84 %84\n%96 = OpVectorShuffle %9 %91 %91 1 0\n%97 = OpShiftRightLogical %9 %91 %95\n%98 = OpBitwiseXor %9 %97 %96\n%99 = OpIMul %9 %98 %92\n%100 = OpVectorShuffle %9 %99 %99 1 0\n%101 = OpShiftRightLogical %9 %99 %95\n%102 = OpBitwiseXor %9 %101 %100\n%103 = OpIMul %9 %102 %92\n%104 = OpVectorShuffle %9 %103 %103 1 0\n%105 = OpShiftRightLogical %9 %103 %95\n%106 = OpBitwiseXor %9 %105 %104\n%107 = OpIMul %9 %106 %92\n%108 = OpVectorShuffle %9 %107 %107 1 0\n%109 = OpShiftRightLogical %9 %107 %95\n%110 = OpBitwiseXor %9 %109 %108\n%111 = OpIMul %9 %110 %92\n%112 = OpVectorShuffle %9 %111 %111 1 0\n%113 = OpShiftRightLogical %9 %111 %95\n%114 = OpBitwiseXor %9 %113 %112\n%115 = OpIMul %9 %114 %92\n%116 = OpVectorShuffle %9 %115 %115 1 0\n%117 = OpShiftRightLogical %9 %115 %95\n%118 = OpBitwiseXor %9 %117 %116\n%119 = OpIMul %9 %118 %92\n%120 = OpCompositeExtract %5 %119 0\nOpReturnValue %120\nOpFunctionEnd\n%139 = OpFunction %123 None %132\n%133 = OpFunctionParameter %9\n%134 = OpFunctionParameter %5\n%135 = OpFunctionParameter %5\n%136 = OpFunctionParameter %5\n%137 = OpFunctionParameter %5\n%138 = OpFunctionParameter %123\n%140 = OpLabel\nOpSelectionMerge %142 None\nOpBranchConditional %138 %142 %141\n%141 = OpLabel\nOpReturnValue %143\n%142 = OpLabel\n%145 = OpCompositeExtract %5 %133 0\n%146 = OpCompositeExtract %5 %133 1\n%148 = OpIAddCarry %147 %145 %134\n%149 = OpCompositeExtract %5 %148 0\n%150 = OpCompositeExtract %5 %148 1\n%151 = OpIAdd %5 %146 %150\n%152 = OpCompositeConstruct %9 %149 %151\n%153 = OpCompositeExtract %5 %152 0\n%154 = OpBitFieldUExtract %5 %158 %42 %135\n%155 = OpBitwiseAnd %5 %153 %159\n%156 = OpShiftLeftLogical %5 %154 %155\n%157 = OpBitwiseAnd %5 %156 %93\n%160 = OpBitwiseAnd %5 %153 %168\n%161 = OpIAdd %5 %160 %135\n%162 = OpIAdd %5 %161 %168\n%163 = OpShiftRightLogical %5 %162 %169\n%164 = OpBitFieldUExtract %5 %153 %169 %169\n%165 = OpBitFieldUExtract %5 %158 %42 %163\n%166 = OpShiftLeftLogical %5 %165 %164\n%167 = OpBitwiseAnd %5 %166 %159\n%170 = OpArrayLength %5 %127 0\n%171 = OpExtInst %5 %173 FindUMsb %170\n%172 = OpBitFieldUExtract %5 %158 %42 %171\n%174 = OpArrayLength %5 %127 0\n%175 = OpExtInst %5 %173 FindUMsb %174\n%176 = OpBitFieldUExtract %5 %174 %42 %175\n%177 = OpISub %5 %176 %10\n%178 = OpFunctionCall %5 %85 %152 %179\n%180 = OpBitwiseAnd %5 %178 %172\n%181 = OpIAdd %5 %180 %177\n%182 = OpFunctionCall %5 %85 %152 %183\n%184 = OpBitwiseAnd %5 %182 %172\n%185 = OpIAdd %5 %184 %177\n%186 = OpFunctionCall %5 %85 %152 %187\n%188 = OpBitwiseAnd %5 %186 %172\n%189 = OpIAdd %5 %188 %177\n%190 = OpFunctionCall %5 %85 %152 %44\n%191 = OpBitwiseAnd %5 %190 %172\n%192 = OpIAdd %5 %191 %177\n%193 = OpFunctionCall %5 %85 %152 %194\n%195 = OpBitwiseAnd %5 %193 %172\n%196 = OpIAdd %5 %195 %177\n%197 = OpFunctionCall %5 %85 %152 %198\n%199 = OpBitwiseAnd %5 %197 %172\n%200 = OpIAdd %5 %199 %177\n%201 = OpFunctionCall %5 %85 %152 %202\n%203 = OpBitwiseAnd %5 %201 %172\n%204 = OpIAdd %5 %203 %177\n%205 = OpFunctionCall %5 %85 %152 %206\n%207 = OpBitwiseAnd %5 %205 %172\n%208 = OpIAdd %5 %207 %177\n%209 = OpFunctionCall %5 %85 %152 %210\n%211 = OpBitwiseAnd %5 %209 %172\n%212 = OpIAdd %5 %211 %177\n%213 = OpFunctionCall %5 %85 %152 %214\n%215 = OpBitwiseAnd %5 %213 %172\n%216 = OpIAdd %5 %215 %177\n%217 = OpFunctionCall %5 %85 %152 %218\n%219 = OpBitwiseAnd %5 %217 %172\n%220 = OpIAdd %5 %219 %177\n%221 = OpFunctionCall %5 %85 %152 %222\n%223 = OpBitwiseAnd %5 %221 %172\n%224 = OpIAdd %5 %223 %177\n%225 = OpFunctionCall %5 %85 %152 %226\n%227 = OpBitwiseAnd %5 %225 %172\n%228 = OpIAdd %5 %227 %177\n%229 = OpFunctionCall %5 %85 %152 %230\n%231 = OpBitwiseAnd %5 %229 %172\n%232 = OpIAdd %5 %231 %177\n%233 = OpFunctionCall %5 %85 %152 %234\n%235 = OpBitwiseAnd %5 %233 %172\n%236 = OpIAdd %5 %235 %177\n%237 = OpFunctionCall %5 %85 %152 %238\n%239 = OpBitwiseAnd %5 %237 %172\n%240 = OpIAdd %5 %239 %177\n%246 = OpVectorExtractDynamic %122 %245 %136\n%247 = OpShiftLeftLogical %5 %157 %58\n%248 = OpShiftLeftLogical %5 %167 %51\n%249 = OpBitwiseOr %5 %157 %247\n%250 = OpBitwiseOr %5 %167 %248\n%251 = OpCompositeConstruct %9 %249 %250\n%252 = OpBitcast %122 %251\n%253 = OpBitwiseAnd %122 %246 %252\n%255 = OpInBoundsAccessChain %254 %127 %42 %181\n%256 = OpAtomicOr %122 %255 %10 %42 %253\n%257 = OpInBoundsAccessChain %254 %127 %42 %185\n%258 = OpAtomicOr %122 %257 %10 %42 %253\n%259 = OpBitwiseAnd %122 %256 %258\n%260 = OpInBoundsAccessChain %254 %127 %42 %189\n%261 = OpAtomicOr %122 %260 %10 %42 %253\n%262 = OpBitwiseAnd %122 %259 %261\n%263 = OpInBoundsAccessChain %254 %127 %42 %192\n%264 = OpAtomicOr %122 %263 %10 %42 %253\n%265 = OpBitwiseAnd %122 %262 %264\n%266 = OpInBoundsAccessChain %254 %127 %42 %196\n%267 = OpAtomicOr %122 %266 %10 %42 %253\n%268 = OpBitwiseAnd %122 %265 %267\n%269 = OpInBoundsAccessChain %254 %127 %42 %200\n%270 = OpAtomicOr %122 %269 %10 %42 %253\n%271 = OpBitwiseAnd %122 %268 %270\n%272 = OpInBoundsAccessChain %254 %127 %42 %204\n%273 = OpAtomicOr %122 %272 %10 %42 %253\n%274 = OpBitwiseAnd %122 %271 %273\n%275 = OpInBoundsAccessChain %254 %127 %42 %208\n%276 = OpAtomicOr %122 %275 %10 %42 %253\n%277 = OpBitwiseAnd %122 %274 %276\n%278 = OpInBoundsAccessChain %254 %127 %42 %212\n%279 = OpAtomicOr %122 %278 %10 %42 %253\n%280 = OpBitwiseAnd %122 %277 %279\n%281 = OpInBoundsAccessChain %254 %127 %42 %216\n%282 = OpAtomicOr %122 %281 %10 %42 %253\n%283 = OpBitwiseAnd %122 %280 %282\n%284 = OpInBoundsAccessChain %254 %127 %42 %220\n%285 = OpAtomicOr %122 %284 %10 %42 %253\n%286 = OpBitwiseAnd %122 %283 %285\n%287 = OpInBoundsAccessChain %254 %127 %42 %224\n%288 = OpAtomicOr %122 %287 %10 %42 %253\n%289 = OpBitwiseAnd %122 %286 %288\n%290 = OpInBoundsAccessChain %254 %127 %42 %228\n%291 = OpAtomicOr %122 %290 %10 %42 %253\n%292 = OpBitwiseAnd %122 %289 %291\n%293 = OpInBoundsAccessChain %254 %127 %42 %232\n%294 = OpAtomicOr %122 %293 %10 %42 %253\n%295 = OpBitwiseAnd %122 %292 %294\n%296 = OpInBoundsAccessChain %254 %127 %42 %236\n%297 = OpAtomicOr %122 %296 %10 %42 %253\n%298 = OpBitwiseAnd %122 %295 %297\n%299 = OpInBoundsAccessChain %254 %127 %42 %240\n%300 = OpAtomicOr %122 %299 %10 %42 %253\n%301 = OpBitwiseAnd %122 %298 %300\n%302 = OpBitcast %9 %301\n%303 = OpCompositeExtract %5 %302 0\n%304 = OpCompositeExtract %5 %302 1\n%305 = OpShiftRightLogical %5 %303 %58\n%306 = OpBitwiseAnd %5 %305 %157\n%307 = OpIEqual %123 %306 %42\n%308 = OpBitFieldUExtract %5 %137 %310 %311\n%312 = OpShiftLeftLogical %5 %313 %308\n%314 = OpBitFieldUExtract %5 %137 %311 %311\n%315 = OpShiftLeftLogical %5 %80 %314\n%316 = OpBitwiseOr %5 %312 %315\n%317 = OpBitFieldUExtract %5 %137 %318 %311\n%319 = OpShiftLeftLogical %5 %320 %317\n%321 = OpBitwiseOr %5 %316 %319\n%322 = OpSelect %5 %307 %321 %42\n%323 = OpInBoundsAccessChain %40 %131 %42 %181 %10\n%324 = OpAtomicOr %5 %323 %10 %42 %322\n%325 = OpBitwiseAnd %5 %324 %321\n%326 = OpIEqual %123 %325 %321\n%327 = OpBitFieldUExtract %5 %137 %328 %311\n%329 = OpShiftLeftLogical %5 %313 %327\n%330 = OpBitFieldUExtract %5 %137 %331 %311\n%332 = OpShiftLeftLogical %5 %80 %330\n%333 = OpBitwiseOr %5 %329 %332\n%334 = OpBitFieldUExtract %5 %137 %335 %311\n%336 = OpShiftLeftLogical %5 %320 %334\n%337 = OpBitwiseOr %5 %333 %336\n%338 = OpSelect %5 %307 %337 %42\n%339 = OpInBoundsAccessChain %40 %131 %42 %185 %10\n%340 = OpAtomicOr %5 %339 %10 %42 %338\n%341 = OpBitwiseAnd %5 %340 %337\n%342 = OpIEqual %123 %341 %337\n%343 = OpLogicalAnd %123 %326 %342\n%344 = OpBitFieldUExtract %5 %137 %345 %311\n%346 = OpShiftLeftLogical %5 %313 %344\n%347 = OpBitFieldUExtract %5 %137 %348 %311\n%349 = OpShiftLeftLogical %5 %80 %347\n%350 = OpBitwiseOr %5 %346 %349\n%351 = OpBitFieldUExtract %5 %137 %352 %311\n%353 = OpShiftLeftLogical %5 %320 %351\n%354 = OpBitwiseOr %5 %350 %353\n%355 = OpSelect %5 %307 %354 %42\n%356 = OpInBoundsAccessChain %40 %131 %42 %189 %10\n%357 = OpAtomicOr %5 %356 %10 %42 %355\n%358 = OpBitwiseAnd %5 %357 %354\n%359 = OpIEqual %123 %358 %354\n%360 = OpLogicalAnd %123 %343 %359\n%361 = OpBitFieldUExtract %5 %137 %362 %311\n%363 = OpShiftLeftLogical %5 %313 %361\n%364 = OpBitFieldUExtract %5 %137 %365 %311\n%366 = OpShiftLeftLogical %5 %80 %364\n%367 = OpBitwiseOr %5 %363 %366\n%368 = OpBitFieldUExtract %5 %137 %369 %311\n%370 = OpShiftLeftLogical %5 %320 %368\n%371 = OpBitwiseOr %5 %367 %370\n%372 = OpSelect %5 %307 %371 %42\n%373 = OpInBoundsAccessChain %40 %131 %42 %192 %10\n%374 = OpAtomicOr %5 %373 %10 %42 %372\n%375 = OpBitwiseAnd %5 %374 %371\n%376 = OpIEqual %123 %375 %371\n%377 = OpLogicalAnd %123 %360 %376\n%378 = OpBitFieldUExtract %5 %137 %379 %311\n%380 = OpShiftLeftLogical %5 %313 %378\n%381 = OpBitFieldUExtract %5 %137 %382 %311\n%383 = OpShiftLeftLogical %5 %80 %381\n%384 = OpBitwiseOr %5 %380 %383\n%385 = OpBitFieldUExtract %5 %137 %386 %311\n%387 = OpShiftLeftLogical %5 %320 %385\n%388 = OpBitwiseOr %5 %384 %387\n%389 = OpSelect %5 %307 %388 %42\n%390 = OpInBoundsAccessChain %40 %131 %42 %196 %10\n%391 = OpAtomicOr %5 %390 %10 %42 %389\n%392 = OpBitwiseAnd %5 %391 %388\n%393 = OpIEqual %123 %392 %388\n%394 = OpLogicalAnd %123 %377 %393\n%395 = OpBitFieldUExtract %5 %137 %328 %311\n%396 = OpShiftLeftLogical %5 %313 %395\n%397 = OpBitFieldUExtract %5 %137 %331 %311\n%398 = OpShiftLeftLogical %5 %80 %397\n%399 = OpBitwiseOr %5 %396 %398\n%400 = OpBitFieldUExtract %5 %137 %335 %311\n%401 = OpShiftLeftLogical %5 %320 %400\n%402 = OpBitwiseOr %5 %399 %401\n%403 = OpSelect %5 %307 %402 %42\n%404 = OpInBoundsAccessChain %40 %131 %42 %200 %10\n%405 = OpAtomicOr %5 %404 %10 %42 %403\n%406 = OpBitwiseAnd %5 %405 %402\n%407 = OpIEqual %123 %406 %402\n%408 = OpLogicalAnd %123 %394 %407\n%409 = OpBitFieldUExtract %5 %137 %410 %311\n%411 = OpShiftLeftLogical %5 %313 %409\n%412 = OpBitFieldUExtract %5 %137 %413 %311\n%414 = OpShiftLeftLogical %5 %80 %412\n%415 = OpBitwiseOr %5 %411 %414\n%416 = OpBitFieldUExtract %5 %137 %362 %311\n%417 = OpShiftLeftLogical %5 %320 %416\n%418 = OpBitwiseOr %5 %415 %417\n%419 = OpSelect %5 %307 %418 %42\n%420 = OpInBoundsAccessChain %40 %131 %42 %204 %10\n%421 = OpAtomicOr %5 %420 %10 %42 %419\n%422 = OpBitwiseAnd %5 %421 %418\n%423 = OpIEqual %123 %422 %418\n%424 = OpLogicalAnd %123 %408 %423\n%425 = OpBitFieldUExtract %5 %137 %426 %311\n%427 = OpShiftLeftLogical %5 %313 %425\n%428 = OpBitFieldUExtract %5 %137 %429 %311\n%430 = OpShiftLeftLogical %5 %80 %428\n%431 = OpBitwiseOr %5 %427 %430\n%432 = OpBitFieldUExtract %5 %137 %433 %311\n%434 = OpShiftLeftLogical %5 %320 %432\n%435 = OpBitwiseOr %5 %431 %434\n%436 = OpSelect %5 %307 %435 %42\n%437 = OpInBoundsAccessChain %40 %131 %42 %208 %10\n%438 = OpAtomicOr %5 %437 %10 %42 %436\n%439 = OpBitwiseAnd %5 %438 %435\n%440 = OpIEqual %123 %439 %435\n%441 = OpLogicalAnd %123 %424 %440\nOpSelectionMerge %446 None\nOpSwitch %136 %445 0 %442 1 %443 2 %444\n%445 = OpLabel\n%454 = OpShiftLeftLogical %5 %167 %51\n%455 = OpBitwiseAnd %5 %304 %454\n%456 = OpINotEqual %123 %455 %42\nOpBranch %446\n%442 = OpLabel\n%447 = OpBitwiseAnd %5 %303 %157\n%448 = OpINotEqual %123 %447 %42\nOpBranch %446\n%443 = OpLabel\n%449 = OpShiftLeftLogical %5 %157 %58\n%450 = OpBitwiseAnd %5 %303 %449\n%451 = OpINotEqual %123 %450 %42\nOpBranch %446\n%444 = OpLabel\n%452 = OpBitwiseAnd %5 %304 %167\n%453 = OpINotEqual %123 %452 %42\nOpBranch %446\n%446 = OpLabel\n%457 = OpPhi %123 %448 %442 %451 %443 %453 %444 %456 %445\n%458 = OpLogicalNot %123 %457\n%459 = OpLogicalOr %123 %458 %441\nOpReturnValue %459\nOpFunctionEnd\n%503 = OpFunction %1 None %500\n%501 = OpFunctionParameter %123\n%502 = OpFunctionParameter %5\n%504 = OpLabel\n%507 = OpLogicalNot %123 %501\n%508 = OpLoad %123 %491\n%509 = OpLogicalAnd %123 %507 %508\nOpSelectionMerge %505 None\nOpBranchConditional %509 %506 %505\n%506 = OpLabel\n%512 = OpIMul %5 %502 %514\n%513 = OpBitwiseXor %5 %512 %515\n%516 = OpArrayLength %5 %495 0\n%517 = OpISub %5 %516 %169\n%518 = OpAccessChain %40 %495 %42 %517\n%519 = OpLoad %5 %518\n%520 = OpIMul %5 %519 %521\n%522 = OpBitwiseXor %5 %513 %520\n%523 = OpArrayLength %5 %499 0\n%524 = OpISub %5 %523 %10\n%525 = OpBitwiseAnd %5 %522 %524\n%526 = OpShiftRightLogical %5 %525 %51\n%527 = OpBitwiseAnd %5 %525 %159\n%528 = OpShiftLeftLogical %5 %10 %527\n%529 = OpAccessChain %40 %495 %42 %526\n%530 = OpAtomicOr %5 %529 %10 %42 %528\n%531 = OpBitwiseAnd %5 %530 %528\n%532 = OpIEqual %123 %531 %42\nOpStore %491 %533\nOpSelectionMerge %511 None\nOpBranchConditional %532 %510 %511\n%510 = OpLabel\n%534 = OpCompositeConstruct %477 %515 %42 %502 %519\n%535 = OpShiftLeftLogical %5 %528 %58\n%537 = OpAccessChain %536 %499 %42 %525\nOpStore %537 %534\nOpMemoryBarrier %10 %539\n%538 = OpAtomicOr %5 %529 %10 %42 %535\nOpMemoryBarrier %10 %539\nOpBranch %511\n%511 = OpLabel\nOpBranch %505\n%505 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/cbv.root-descriptor.bda-instrumentation.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatArray;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nfloat _465;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerFloatArray\n{\n    float value[];\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _31 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _31;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _60 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _61 = uvec2(prime);\n    uvec2 _68 = ((_60 >> uvec2(8u)) ^ _60.yx) * _61;\n    uvec2 _72 = ((_68 >> uvec2(8u)) ^ _68.yx) * _61;\n    uvec2 _76 = ((_72 >> uvec2(8u)) ^ _72.yx) * _61;\n    uvec2 _80 = ((_76 >> uvec2(8u)) ^ _76.yx) * _61;\n    uvec2 _84 = ((_80 >> uvec2(8u)) ^ _80.yx) * _61;\n    return (((_84 >> uvec2(8u)) ^ _84.yx) * _61).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _117;\n    _117._m0 = uaddCarry(BDA.x, offset, _117._m1);\n    uvec2 addr = uvec2(_117._m0, BDA.y + _117._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _495 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _497 = InstrumentationControlData.atomics[_495];\n        uint _503 = (((inst * 97u) ^ 43981u) ^ (_497 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _504 = _503 >> 4u;\n        uint _506 = 1u << (_503 & 15u);\n        uint _508 = atomicOr(InstrumentationControlData.atomics[_504], _506);\n        ShouldReportInstrumentation = false;\n        if ((_508 & _506) == 0u)\n        {\n            InstrumentationData.data[_503] = uvec4(43981u, 0u, inst, _497);\n            memoryBarrierBuffer();\n            uint _516 = atomicOr(InstrumentationControlData.atomics[_504], _506 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _34 = AllocateInvocationID();\n    InvocationID = _34;\n    uint _47 = gl_GlobalInvocationID.x >> 4u;\n    uint _431 = InvocationID;\n    bool _430 = ValidateBDALoadStore(registers._m0, _47 * 16u, 16u, 0u, _431, true);\n    AssumeTrue(_430, 1u);\n    PhysicalPointerFloat4NonWriteCBVArray _438 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    uint _453 = InvocationID;\n    bool _452 = ValidateBDALoadStore(registers._m2, (gl_GlobalInvocationID.x * 4u) + 0u, 4u, 0u, _453, true);\n    AssumeTrue(_452, 2u);\n    uint _462 = InvocationID;\n    bool _461 = ValidateBDALoadStore(registers._m2, (gl_GlobalInvocationID.x * 4u) + 0u, 4u, 1u, _462, true);\n    AssumeTrue(_461, 3u);\n    PhysicalPointerFloatArray(registers._m2).value[gl_GlobalInvocationID.x] = ((_438.value[_47].x + 40.0) + _438.value[_47].z) + PhysicalPointerFloatArray(registers._m2).value[gl_GlobalInvocationID.x];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 523\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%141 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %43\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"BloomBufferInvocationSSBO\"\nOpMemberName %20 0 \"atomics\"\nOpName %22 \"BloomBufferInvocation\"\nOpName %24 \"AllocateInvocationID\"\nOpName %54 \"AddrHash\"\nOpName %52 \"addr\"\nOpName %53 \"prime\"\nOpName %94 \"BloomBufferSSBO\"\nOpMemberName %94 0 \"atomics\"\nOpName %96 \"BloomBuffer\"\nOpName %98 \"BloomBuffer32SSBO\"\nOpMemberName %98 0 \"atomics\"\nOpName %100 \"BloomBuffer32\"\nOpName %108 \"ValidateBDALoadStore\"\nOpName %102 \"BDA\"\nOpName %103 \"offset\"\nOpName %104 \"len\"\nOpName %105 \"type\"\nOpName %106 \"invocation_id\"\nOpName %107 \"in_bounds\"\nOpName %116 \"IAddCarryResult\"\nOpName %121 \"addr\"\nOpName %122 \"addr_lo\"\nOpName %126 \"byte_mask\"\nOpName %136 \"word_mask\"\nOpName %140 \"hash_mask\"\nOpName %145 \"hash_offset\"\nOpName %149 \"bloom_index\"\nOpName %153 \"bloom_index\"\nOpName %157 \"bloom_index\"\nOpName %160 \"bloom_index\"\nOpName %164 \"bloom_index\"\nOpName %168 \"bloom_index\"\nOpName %172 \"bloom_index\"\nOpName %176 \"bloom_index\"\nOpName %180 \"bloom_index\"\nOpName %184 \"bloom_index\"\nOpName %188 \"bloom_index\"\nOpName %192 \"bloom_index\"\nOpName %196 \"bloom_index\"\nOpName %200 \"bloom_index\"\nOpName %204 \"bloom_index\"\nOpName %208 \"bloom_index\"\nOpName %221 \"invalidation_mask\"\nOpName %224 \"prev_hazard_partial\"\nOpName %226 \"prev_hazard_partial\"\nOpName %229 \"prev_hazard_partial\"\nOpName %232 \"prev_hazard_partial\"\nOpName %235 \"prev_hazard_partial\"\nOpName %238 \"prev_hazard_partial\"\nOpName %241 \"prev_hazard_partial\"\nOpName %244 \"prev_hazard_partial\"\nOpName %247 \"prev_hazard_partial\"\nOpName %250 \"prev_hazard_partial\"\nOpName %253 \"prev_hazard_partial\"\nOpName %256 \"prev_hazard_partial\"\nOpName %259 \"prev_hazard_partial\"\nOpName %262 \"prev_hazard_partial\"\nOpName %265 \"prev_hazard_partial\"\nOpName %268 \"prev_hazard_partial\"\nOpName %270 \"prev_hazard\"\nOpName %271 \"prev_hazard_lo\"\nOpName %272 \"prev_hazard_hi\"\nOpName %275 \"has_exclusive_access\"\nOpName %290 \"lock_mask\"\nOpName %293 \"prev_lock\"\nOpName %306 \"lock_mask\"\nOpName %309 \"prev_lock\"\nOpName %323 \"lock_mask\"\nOpName %326 \"prev_lock\"\nOpName %340 \"lock_mask\"\nOpName %343 \"prev_lock\"\nOpName %357 \"lock_mask\"\nOpName %360 \"prev_lock\"\nOpName %371 \"lock_mask\"\nOpName %374 \"prev_lock\"\nOpName %387 \"lock_mask\"\nOpName %390 \"prev_lock\"\nOpName %404 \"lock_mask\"\nOpName %407 \"prev_lock\"\nOpName %410 \"has_complete_self_lock\"\nOpName %426 \"hazard\"\nOpName %436 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %436 0 \"value\"\nOpName %448 \"PhysicalPointerFloatArray\"\nOpMemberName %448 0 \"value\"\nOpName %468 \"ShouldReportInstrumentation\"\nOpName %471 \"InstrumentationControlDataSSBO\"\nOpMemberName %471 0 \"atomics\"\nOpName %473 \"InstrumentationControlData\"\nOpName %475 \"InstrumentationDataSSBO\"\nOpMemberName %475 0 \"data\"\nOpName %477 \"InstrumentationData\"\nOpName %481 \"AssumeTrue\"\nOpName %479 \"value\"\nOpName %480 \"inst\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 2\nOpDecorate %43 BuiltIn GlobalInvocationId\nOpDecorate %93 ArrayStride 8\nOpMemberDecorate %94 0 Offset 0\nOpDecorate %94 Block\nOpDecorate %96 DescriptorSet 0\nOpDecorate %96 Binding 2\nOpDecorate %97 ArrayStride 8\nOpMemberDecorate %98 0 Offset 0\nOpDecorate %98 Block\nOpDecorate %100 DescriptorSet 0\nOpDecorate %100 Binding 2\nOpDecorate %435 ArrayStride 16\nOpMemberDecorate %436 0 Offset 0\nOpDecorate %436 Block\nOpMemberDecorate %436 0 NonWritable\nOpDecorate %447 ArrayStride 4\nOpMemberDecorate %448 0 Offset 0\nOpDecorate %448 Block\nOpDecorate %470 ArrayStride 4\nOpMemberDecorate %471 0 Offset 0\nOpDecorate %471 Block\nOpDecorate %473 DescriptorSet 0\nOpDecorate %473 Binding 2\nOpDecorate %474 ArrayStride 16\nOpMemberDecorate %475 0 Offset 0\nOpDecorate %475 Block\nOpDecorate %477 DescriptorSet 0\nOpDecorate %477 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpConstant %5 1\n%11 = OpTypeArray %6 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeFunction %5\n%28 = OpTypePointer StorageBuffer %5\n%30 = OpConstant %5 0\n%32 = OpConstant %5 1103633207\n%35 = OpTypePointer PushConstant %6\n%37 = OpConstant %5 2\n%41 = OpTypeVector %5 3\n%42 = OpTypePointer Input %41\n%43 = OpVariable %42 Input\n%44 = OpTypePointer Input %5\n%48 = OpConstant %5 4\n%49 = OpConstant %5 16\n%51 = OpTypeFunction %5 %6 %5\n%62 = OpConstant %5 65535\n%63 = OpConstant %5 8\n%64 = OpConstantComposite %6 %63 %63\n%91 = OpTypeInt 64 0\n%92 = OpTypeBool\n%93 = OpTypeRuntimeArray %91\n%94 = OpTypeStruct %93\n%95 = OpTypePointer StorageBuffer %94\n%96 = OpVariable %95 StorageBuffer\n%97 = OpTypeRuntimeArray %6\n%98 = OpTypeStruct %97\n%99 = OpTypePointer StorageBuffer %98\n%100 = OpVariable %99 StorageBuffer\n%101 = OpTypeFunction %92 %6 %5 %5 %5 %5 %92\n%112 = OpConstantTrue %92\n%116 = OpTypeStruct %5 %5\n%127 = OpConstant %5 4294967295\n%128 = OpConstant %5 15\n%137 = OpConstant %5 3\n%147 = OpConstant %5 1103515245\n%151 = OpConstant %5 1103518333\n%155 = OpConstant %5 1103539331\n%162 = OpConstant %5 10006121\n%166 = OpConstant %5 4004951\n%170 = OpConstant %5 5005159\n%174 = OpConstant %5 6004811\n%178 = OpConstant %5 383\n%182 = OpConstant %5 821\n%186 = OpConstant %5 661\n%190 = OpConstant %5 1091\n%194 = OpConstant %5 1117\n%198 = OpConstant %5 3947\n%202 = OpConstant %5 4253\n%206 = OpConstant %5 7691\n%209 = OpTypeVector %91 4\n%210 = OpConstant %91 68719411200\n%211 = OpConstant %91 1099511627775\n%212 = OpConstant %91 1035087118335\n%213 = OpConstantComposite %209 %210 %211 %212 %210\n%222 = OpTypePointer StorageBuffer %91\n%277 = OpTypeInt 32 1\n%278 = OpConstant %277 0\n%279 = OpConstant %277 3\n%281 = OpConstant %5 256\n%284 = OpConstant %5 65536\n%287 = OpConstant %277 6\n%289 = OpConstant %5 16777216\n%297 = OpConstant %277 9\n%300 = OpConstant %277 12\n%304 = OpConstant %277 15\n%314 = OpConstant %277 18\n%317 = OpConstant %277 21\n%321 = OpConstant %277 24\n%331 = OpConstant %277 23\n%334 = OpConstant %277 26\n%338 = OpConstant %277 29\n%348 = OpConstant %277 1\n%351 = OpConstant %277 4\n%355 = OpConstant %277 7\n%379 = OpConstant %277 17\n%382 = OpConstant %277 20\n%395 = OpConstant %277 22\n%398 = OpConstant %277 25\n%402 = OpConstant %277 28\n%432 = OpTypeFloat 32\n%433 = OpTypeVector %432 4\n%434 = OpConstant %5 4096\n%435 = OpTypeArray %433 %434\n%436 = OpTypeStruct %435\n%437 = OpTypePointer PhysicalStorageBuffer %436\n%439 = OpTypePointer PhysicalStorageBuffer %433\n%445 = OpConstant %432 40\n%447 = OpTypeRuntimeArray %432\n%448 = OpTypeStruct %447\n%449 = OpTypePointer PhysicalStorageBuffer %448\n%455 = OpTypePointer PhysicalStorageBuffer %432\n%467 = OpTypePointer Private %92\n%468 = OpVariable %467 Private %112\n%469 = OpTypeVector %5 4\n%470 = OpTypeRuntimeArray %5\n%471 = OpTypeStruct %470\n%472 = OpTypePointer StorageBuffer %471\n%473 = OpVariable %472 StorageBuffer\n%474 = OpTypeRuntimeArray %469\n%475 = OpTypeStruct %474\n%476 = OpTypePointer StorageBuffer %475\n%477 = OpVariable %476 StorageBuffer\n%478 = OpTypeFunction %1 %92 %5\n%492 = OpConstant %5 97\n%493 = OpConstant %5 43981\n%499 = OpConstant %5 51329\n%511 = OpConstantFalse %92\n%514 = OpTypePointer StorageBuffer %469\n%517 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%465 = OpUndef %432\nOpBranch %466\n%466 = OpLabel\n%34 = OpFunctionCall %5 %24\nOpStore %18 %34\n%36 = OpAccessChain %35 %9 %37\n%38 = OpLoad %6 %36\n%39 = OpAccessChain %35 %9 %30\n%40 = OpLoad %6 %39\n%45 = OpAccessChain %44 %43 %30\n%46 = OpLoad %5 %45\n%47 = OpShiftRightLogical %5 %46 %48\n%50 = OpIMul %5 %47 %49\n%431 = OpLoad %5 %18\n%430 = OpFunctionCall %92 %108 %40 %50 %49 %30 %431 %112\n%519 = OpFunctionCall %1 %481 %430 %10\n%438 = OpBitcast %437 %40\n%440 = OpInBoundsAccessChain %439 %438 %30 %47\n%441 = OpLoad %433 %440 Aligned 16\n%442 = OpCompositeExtract %432 %441 0\n%443 = OpCompositeExtract %432 %441 2\n%444 = OpFAdd %432 %442 %445\n%446 = OpFAdd %432 %444 %443\n%450 = OpIMul %5 %46 %48\n%451 = OpIAdd %5 %450 %30\n%453 = OpLoad %5 %18\n%452 = OpFunctionCall %92 %108 %38 %451 %48 %30 %453 %112\n%520 = OpFunctionCall %1 %481 %452 %37\n%454 = OpBitcast %449 %38\n%456 = OpInBoundsAccessChain %455 %454 %30 %46\n%457 = OpLoad %432 %456 Aligned 4\n%458 = OpFAdd %432 %446 %457\n%459 = OpIMul %5 %46 %48\n%460 = OpIAdd %5 %459 %30\n%462 = OpLoad %5 %18\n%461 = OpFunctionCall %92 %108 %38 %460 %48 %10 %462 %112\n%521 = OpFunctionCall %1 %481 %461 %137\n%463 = OpBitcast %449 %38\n%464 = OpInBoundsAccessChain %455 %463 %30 %46\nOpStore %464 %458 Aligned 4\nOpReturn\nOpFunctionEnd\n%24 = OpFunction %5 None %23\n%25 = OpLabel\n%26 = OpArrayLength %5 %22 0\n%27 = OpISub %5 %26 %10\n%29 = OpAccessChain %28 %22 %30 %27\n%31 = OpAtomicIAdd %5 %29 %10 %30 %32\nOpReturnValue %31\nOpFunctionEnd\n%54 = OpFunction %5 None %51\n%52 = OpFunctionParameter %6\n%53 = OpFunctionParameter %5\n%55 = OpLabel\n%56 = OpCompositeExtract %5 %52 0\n%57 = OpCompositeExtract %5 %52 1\n%58 = OpShiftRightLogical %5 %56 %48\n%59 = OpBitwiseAnd %5 %57 %62\n%60 = OpCompositeConstruct %6 %58 %59\n%61 = OpCompositeConstruct %6 %53 %53\n%65 = OpVectorShuffle %6 %60 %60 1 0\n%66 = OpShiftRightLogical %6 %60 %64\n%67 = OpBitwiseXor %6 %66 %65\n%68 = OpIMul %6 %67 %61\n%69 = OpVectorShuffle %6 %68 %68 1 0\n%70 = OpShiftRightLogical %6 %68 %64\n%71 = OpBitwiseXor %6 %70 %69\n%72 = OpIMul %6 %71 %61\n%73 = OpVectorShuffle %6 %72 %72 1 0\n%74 = OpShiftRightLogical %6 %72 %64\n%75 = OpBitwiseXor %6 %74 %73\n%76 = OpIMul %6 %75 %61\n%77 = OpVectorShuffle %6 %76 %76 1 0\n%78 = OpShiftRightLogical %6 %76 %64\n%79 = OpBitwiseXor %6 %78 %77\n%80 = OpIMul %6 %79 %61\n%81 = OpVectorShuffle %6 %80 %80 1 0\n%82 = OpShiftRightLogical %6 %80 %64\n%83 = OpBitwiseXor %6 %82 %81\n%84 = OpIMul %6 %83 %61\n%85 = OpVectorShuffle %6 %84 %84 1 0\n%86 = OpShiftRightLogical %6 %84 %64\n%87 = OpBitwiseXor %6 %86 %85\n%88 = OpIMul %6 %87 %61\n%89 = OpCompositeExtract %5 %88 0\nOpReturnValue %89\nOpFunctionEnd\n%108 = OpFunction %92 None %101\n%102 = OpFunctionParameter %6\n%103 = OpFunctionParameter %5\n%104 = OpFunctionParameter %5\n%105 = OpFunctionParameter %5\n%106 = OpFunctionParameter %5\n%107 = OpFunctionParameter %92\n%109 = OpLabel\nOpSelectionMerge %111 None\nOpBranchConditional %107 %111 %110\n%110 = OpLabel\nOpReturnValue %112\n%111 = OpLabel\n%114 = OpCompositeExtract %5 %102 0\n%115 = OpCompositeExtract %5 %102 1\n%117 = OpIAddCarry %116 %114 %103\n%118 = OpCompositeExtract %5 %117 0\n%119 = OpCompositeExtract %5 %117 1\n%120 = OpIAdd %5 %115 %119\n%121 = OpCompositeConstruct %6 %118 %120\n%122 = OpCompositeExtract %5 %121 0\n%123 = OpBitFieldUExtract %5 %127 %30 %104\n%124 = OpBitwiseAnd %5 %122 %128\n%125 = OpShiftLeftLogical %5 %123 %124\n%126 = OpBitwiseAnd %5 %125 %62\n%129 = OpBitwiseAnd %5 %122 %137\n%130 = OpIAdd %5 %129 %104\n%131 = OpIAdd %5 %130 %137\n%132 = OpShiftRightLogical %5 %131 %37\n%133 = OpBitFieldUExtract %5 %122 %37 %37\n%134 = OpBitFieldUExtract %5 %127 %30 %132\n%135 = OpShiftLeftLogical %5 %134 %133\n%136 = OpBitwiseAnd %5 %135 %128\n%138 = OpArrayLength %5 %96 0\n%139 = OpExtInst %5 %141 FindUMsb %138\n%140 = OpBitFieldUExtract %5 %127 %30 %139\n%142 = OpArrayLength %5 %96 0\n%143 = OpExtInst %5 %141 FindUMsb %142\n%144 = OpBitFieldUExtract %5 %142 %30 %143\n%145 = OpISub %5 %144 %10\n%146 = OpFunctionCall %5 %54 %121 %147\n%148 = OpBitwiseAnd %5 %146 %140\n%149 = OpIAdd %5 %148 %145\n%150 = OpFunctionCall %5 %54 %121 %151\n%152 = OpBitwiseAnd %5 %150 %140\n%153 = OpIAdd %5 %152 %145\n%154 = OpFunctionCall %5 %54 %121 %155\n%156 = OpBitwiseAnd %5 %154 %140\n%157 = OpIAdd %5 %156 %145\n%158 = OpFunctionCall %5 %54 %121 %32\n%159 = OpBitwiseAnd %5 %158 %140\n%160 = OpIAdd %5 %159 %145\n%161 = OpFunctionCall %5 %54 %121 %162\n%163 = OpBitwiseAnd %5 %161 %140\n%164 = OpIAdd %5 %163 %145\n%165 = OpFunctionCall %5 %54 %121 %166\n%167 = OpBitwiseAnd %5 %165 %140\n%168 = OpIAdd %5 %167 %145\n%169 = OpFunctionCall %5 %54 %121 %170\n%171 = OpBitwiseAnd %5 %169 %140\n%172 = OpIAdd %5 %171 %145\n%173 = OpFunctionCall %5 %54 %121 %174\n%175 = OpBitwiseAnd %5 %173 %140\n%176 = OpIAdd %5 %175 %145\n%177 = OpFunctionCall %5 %54 %121 %178\n%179 = OpBitwiseAnd %5 %177 %140\n%180 = OpIAdd %5 %179 %145\n%181 = OpFunctionCall %5 %54 %121 %182\n%183 = OpBitwiseAnd %5 %181 %140\n%184 = OpIAdd %5 %183 %145\n%185 = OpFunctionCall %5 %54 %121 %186\n%187 = OpBitwiseAnd %5 %185 %140\n%188 = OpIAdd %5 %187 %145\n%189 = OpFunctionCall %5 %54 %121 %190\n%191 = OpBitwiseAnd %5 %189 %140\n%192 = OpIAdd %5 %191 %145\n%193 = OpFunctionCall %5 %54 %121 %194\n%195 = OpBitwiseAnd %5 %193 %140\n%196 = OpIAdd %5 %195 %145\n%197 = OpFunctionCall %5 %54 %121 %198\n%199 = OpBitwiseAnd %5 %197 %140\n%200 = OpIAdd %5 %199 %145\n%201 = OpFunctionCall %5 %54 %121 %202\n%203 = OpBitwiseAnd %5 %201 %140\n%204 = OpIAdd %5 %203 %145\n%205 = OpFunctionCall %5 %54 %121 %206\n%207 = OpBitwiseAnd %5 %205 %140\n%208 = OpIAdd %5 %207 %145\n%214 = OpVectorExtractDynamic %91 %213 %105\n%215 = OpShiftLeftLogical %5 %126 %49\n%216 = OpShiftLeftLogical %5 %136 %48\n%217 = OpBitwiseOr %5 %126 %215\n%218 = OpBitwiseOr %5 %136 %216\n%219 = OpCompositeConstruct %6 %217 %218\n%220 = OpBitcast %91 %219\n%221 = OpBitwiseAnd %91 %214 %220\n%223 = OpInBoundsAccessChain %222 %96 %30 %149\n%224 = OpAtomicOr %91 %223 %10 %30 %221\n%225 = OpInBoundsAccessChain %222 %96 %30 %153\n%226 = OpAtomicOr %91 %225 %10 %30 %221\n%227 = OpBitwiseAnd %91 %224 %226\n%228 = OpInBoundsAccessChain %222 %96 %30 %157\n%229 = OpAtomicOr %91 %228 %10 %30 %221\n%230 = OpBitwiseAnd %91 %227 %229\n%231 = OpInBoundsAccessChain %222 %96 %30 %160\n%232 = OpAtomicOr %91 %231 %10 %30 %221\n%233 = OpBitwiseAnd %91 %230 %232\n%234 = OpInBoundsAccessChain %222 %96 %30 %164\n%235 = OpAtomicOr %91 %234 %10 %30 %221\n%236 = OpBitwiseAnd %91 %233 %235\n%237 = OpInBoundsAccessChain %222 %96 %30 %168\n%238 = OpAtomicOr %91 %237 %10 %30 %221\n%239 = OpBitwiseAnd %91 %236 %238\n%240 = OpInBoundsAccessChain %222 %96 %30 %172\n%241 = OpAtomicOr %91 %240 %10 %30 %221\n%242 = OpBitwiseAnd %91 %239 %241\n%243 = OpInBoundsAccessChain %222 %96 %30 %176\n%244 = OpAtomicOr %91 %243 %10 %30 %221\n%245 = OpBitwiseAnd %91 %242 %244\n%246 = OpInBoundsAccessChain %222 %96 %30 %180\n%247 = OpAtomicOr %91 %246 %10 %30 %221\n%248 = OpBitwiseAnd %91 %245 %247\n%249 = OpInBoundsAccessChain %222 %96 %30 %184\n%250 = OpAtomicOr %91 %249 %10 %30 %221\n%251 = OpBitwiseAnd %91 %248 %250\n%252 = OpInBoundsAccessChain %222 %96 %30 %188\n%253 = OpAtomicOr %91 %252 %10 %30 %221\n%254 = OpBitwiseAnd %91 %251 %253\n%255 = OpInBoundsAccessChain %222 %96 %30 %192\n%256 = OpAtomicOr %91 %255 %10 %30 %221\n%257 = OpBitwiseAnd %91 %254 %256\n%258 = OpInBoundsAccessChain %222 %96 %30 %196\n%259 = OpAtomicOr %91 %258 %10 %30 %221\n%260 = OpBitwiseAnd %91 %257 %259\n%261 = OpInBoundsAccessChain %222 %96 %30 %200\n%262 = OpAtomicOr %91 %261 %10 %30 %221\n%263 = OpBitwiseAnd %91 %260 %262\n%264 = OpInBoundsAccessChain %222 %96 %30 %204\n%265 = OpAtomicOr %91 %264 %10 %30 %221\n%266 = OpBitwiseAnd %91 %263 %265\n%267 = OpInBoundsAccessChain %222 %96 %30 %208\n%268 = OpAtomicOr %91 %267 %10 %30 %221\n%269 = OpBitwiseAnd %91 %266 %268\n%270 = OpBitcast %6 %269\n%271 = OpCompositeExtract %5 %270 0\n%272 = OpCompositeExtract %5 %270 1\n%273 = OpShiftRightLogical %5 %271 %49\n%274 = OpBitwiseAnd %5 %273 %126\n%275 = OpIEqual %92 %274 %30\n%276 = OpBitFieldUExtract %5 %106 %278 %279\n%280 = OpShiftLeftLogical %5 %281 %276\n%282 = OpBitFieldUExtract %5 %106 %279 %279\n%283 = OpShiftLeftLogical %5 %284 %282\n%285 = OpBitwiseOr %5 %280 %283\n%286 = OpBitFieldUExtract %5 %106 %287 %279\n%288 = OpShiftLeftLogical %5 %289 %286\n%290 = OpBitwiseOr %5 %285 %288\n%291 = OpSelect %5 %275 %290 %30\n%292 = OpInBoundsAccessChain %28 %100 %30 %149 %10\n%293 = OpAtomicOr %5 %292 %10 %30 %291\n%294 = OpBitwiseAnd %5 %293 %290\n%295 = OpIEqual %92 %294 %290\n%296 = OpBitFieldUExtract %5 %106 %297 %279\n%298 = OpShiftLeftLogical %5 %281 %296\n%299 = OpBitFieldUExtract %5 %106 %300 %279\n%301 = OpShiftLeftLogical %5 %284 %299\n%302 = OpBitwiseOr %5 %298 %301\n%303 = OpBitFieldUExtract %5 %106 %304 %279\n%305 = OpShiftLeftLogical %5 %289 %303\n%306 = OpBitwiseOr %5 %302 %305\n%307 = OpSelect %5 %275 %306 %30\n%308 = OpInBoundsAccessChain %28 %100 %30 %153 %10\n%309 = OpAtomicOr %5 %308 %10 %30 %307\n%310 = OpBitwiseAnd %5 %309 %306\n%311 = OpIEqual %92 %310 %306\n%312 = OpLogicalAnd %92 %295 %311\n%313 = OpBitFieldUExtract %5 %106 %314 %279\n%315 = OpShiftLeftLogical %5 %281 %313\n%316 = OpBitFieldUExtract %5 %106 %317 %279\n%318 = OpShiftLeftLogical %5 %284 %316\n%319 = OpBitwiseOr %5 %315 %318\n%320 = OpBitFieldUExtract %5 %106 %321 %279\n%322 = OpShiftLeftLogical %5 %289 %320\n%323 = OpBitwiseOr %5 %319 %322\n%324 = OpSelect %5 %275 %323 %30\n%325 = OpInBoundsAccessChain %28 %100 %30 %157 %10\n%326 = OpAtomicOr %5 %325 %10 %30 %324\n%327 = OpBitwiseAnd %5 %326 %323\n%328 = OpIEqual %92 %327 %323\n%329 = OpLogicalAnd %92 %312 %328\n%330 = OpBitFieldUExtract %5 %106 %331 %279\n%332 = OpShiftLeftLogical %5 %281 %330\n%333 = OpBitFieldUExtract %5 %106 %334 %279\n%335 = OpShiftLeftLogical %5 %284 %333\n%336 = OpBitwiseOr %5 %332 %335\n%337 = OpBitFieldUExtract %5 %106 %338 %279\n%339 = OpShiftLeftLogical %5 %289 %337\n%340 = OpBitwiseOr %5 %336 %339\n%341 = OpSelect %5 %275 %340 %30\n%342 = OpInBoundsAccessChain %28 %100 %30 %160 %10\n%343 = OpAtomicOr %5 %342 %10 %30 %341\n%344 = OpBitwiseAnd %5 %343 %340\n%345 = OpIEqual %92 %344 %340\n%346 = OpLogicalAnd %92 %329 %345\n%347 = OpBitFieldUExtract %5 %106 %348 %279\n%349 = OpShiftLeftLogical %5 %281 %347\n%350 = OpBitFieldUExtract %5 %106 %351 %279\n%352 = OpShiftLeftLogical %5 %284 %350\n%353 = OpBitwiseOr %5 %349 %352\n%354 = OpBitFieldUExtract %5 %106 %355 %279\n%356 = OpShiftLeftLogical %5 %289 %354\n%357 = OpBitwiseOr %5 %353 %356\n%358 = OpSelect %5 %275 %357 %30\n%359 = OpInBoundsAccessChain %28 %100 %30 %164 %10\n%360 = OpAtomicOr %5 %359 %10 %30 %358\n%361 = OpBitwiseAnd %5 %360 %357\n%362 = OpIEqual %92 %361 %357\n%363 = OpLogicalAnd %92 %346 %362\n%364 = OpBitFieldUExtract %5 %106 %297 %279\n%365 = OpShiftLeftLogical %5 %281 %364\n%366 = OpBitFieldUExtract %5 %106 %300 %279\n%367 = OpShiftLeftLogical %5 %284 %366\n%368 = OpBitwiseOr %5 %365 %367\n%369 = OpBitFieldUExtract %5 %106 %304 %279\n%370 = OpShiftLeftLogical %5 %289 %369\n%371 = OpBitwiseOr %5 %368 %370\n%372 = OpSelect %5 %275 %371 %30\n%373 = OpInBoundsAccessChain %28 %100 %30 %168 %10\n%374 = OpAtomicOr %5 %373 %10 %30 %372\n%375 = OpBitwiseAnd %5 %374 %371\n%376 = OpIEqual %92 %375 %371\n%377 = OpLogicalAnd %92 %363 %376\n%378 = OpBitFieldUExtract %5 %106 %379 %279\n%380 = OpShiftLeftLogical %5 %281 %378\n%381 = OpBitFieldUExtract %5 %106 %382 %279\n%383 = OpShiftLeftLogical %5 %284 %381\n%384 = OpBitwiseOr %5 %380 %383\n%385 = OpBitFieldUExtract %5 %106 %331 %279\n%386 = OpShiftLeftLogical %5 %289 %385\n%387 = OpBitwiseOr %5 %384 %386\n%388 = OpSelect %5 %275 %387 %30\n%389 = OpInBoundsAccessChain %28 %100 %30 %172 %10\n%390 = OpAtomicOr %5 %389 %10 %30 %388\n%391 = OpBitwiseAnd %5 %390 %387\n%392 = OpIEqual %92 %391 %387\n%393 = OpLogicalAnd %92 %377 %392\n%394 = OpBitFieldUExtract %5 %106 %395 %279\n%396 = OpShiftLeftLogical %5 %281 %394\n%397 = OpBitFieldUExtract %5 %106 %398 %279\n%399 = OpShiftLeftLogical %5 %284 %397\n%400 = OpBitwiseOr %5 %396 %399\n%401 = OpBitFieldUExtract %5 %106 %402 %279\n%403 = OpShiftLeftLogical %5 %289 %401\n%404 = OpBitwiseOr %5 %400 %403\n%405 = OpSelect %5 %275 %404 %30\n%406 = OpInBoundsAccessChain %28 %100 %30 %176 %10\n%407 = OpAtomicOr %5 %406 %10 %30 %405\n%408 = OpBitwiseAnd %5 %407 %404\n%409 = OpIEqual %92 %408 %404\n%410 = OpLogicalAnd %92 %393 %409\nOpSelectionMerge %415 None\nOpSwitch %105 %414 0 %411 1 %412 2 %413\n%414 = OpLabel\n%423 = OpShiftLeftLogical %5 %136 %48\n%424 = OpBitwiseAnd %5 %272 %423\n%425 = OpINotEqual %92 %424 %30\nOpBranch %415\n%411 = OpLabel\n%416 = OpBitwiseAnd %5 %271 %126\n%417 = OpINotEqual %92 %416 %30\nOpBranch %415\n%412 = OpLabel\n%418 = OpShiftLeftLogical %5 %126 %49\n%419 = OpBitwiseAnd %5 %271 %418\n%420 = OpINotEqual %92 %419 %30\nOpBranch %415\n%413 = OpLabel\n%421 = OpBitwiseAnd %5 %272 %136\n%422 = OpINotEqual %92 %421 %30\nOpBranch %415\n%415 = OpLabel\n%426 = OpPhi %92 %417 %411 %420 %412 %422 %413 %425 %414\n%427 = OpLogicalNot %92 %426\n%428 = OpLogicalOr %92 %427 %410\nOpReturnValue %428\nOpFunctionEnd\n%481 = OpFunction %1 None %478\n%479 = OpFunctionParameter %92\n%480 = OpFunctionParameter %5\n%482 = OpLabel\n%485 = OpLogicalNot %92 %479\n%486 = OpLoad %92 %468\n%487 = OpLogicalAnd %92 %485 %486\nOpSelectionMerge %483 None\nOpBranchConditional %487 %484 %483\n%484 = OpLabel\n%490 = OpIMul %5 %480 %492\n%491 = OpBitwiseXor %5 %490 %493\n%494 = OpArrayLength %5 %473 0\n%495 = OpISub %5 %494 %37\n%496 = OpAccessChain %28 %473 %30 %495\n%497 = OpLoad %5 %496\n%498 = OpIMul %5 %497 %499\n%500 = OpBitwiseXor %5 %491 %498\n%501 = OpArrayLength %5 %477 0\n%502 = OpISub %5 %501 %10\n%503 = OpBitwiseAnd %5 %500 %502\n%504 = OpShiftRightLogical %5 %503 %48\n%505 = OpBitwiseAnd %5 %503 %128\n%506 = OpShiftLeftLogical %5 %10 %505\n%507 = OpAccessChain %28 %473 %30 %504\n%508 = OpAtomicOr %5 %507 %10 %30 %506\n%509 = OpBitwiseAnd %5 %508 %506\n%510 = OpIEqual %92 %509 %30\nOpStore %468 %511\nOpSelectionMerge %489 None\nOpBranchConditional %510 %488 %489\n%488 = OpLabel\n%512 = OpCompositeConstruct %469 %493 %30 %480 %497\n%513 = OpShiftLeftLogical %5 %506 %49\n%515 = OpAccessChain %514 %477 %30 %503\nOpStore %515 %512\nOpMemoryBarrier %10 %517\n%516 = OpAtomicOr %5 %507 %10 %30 %513\nOpMemoryBarrier %10 %517\nOpBranch %489\n%489 = OpLabel\nOpBranch %483\n%483 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/raw.bindless.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 1, binding = 0, scalar) restrict readonly buffer SSBO\n{\n    uvec3 _m0[];\n} _24[];\n\nlayout(set = 4, binding = 0, std430) buffer _26_29\n{\n    uint _m0[];\n} _29[];\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _42 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _42;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _86 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _87 = uvec2(prime);\n    uvec2 _94 = ((_86 >> uvec2(8u)) ^ _86.yx) * _87;\n    uvec2 _98 = ((_94 >> uvec2(8u)) ^ _94.yx) * _87;\n    uvec2 _102 = ((_98 >> uvec2(8u)) ^ _98.yx) * _87;\n    uvec2 _106 = ((_102 >> uvec2(8u)) ^ _102.yx) * _87;\n    uvec2 _110 = ((_106 >> uvec2(8u)) ^ _106.yx) * _87;\n    return (((_110 >> uvec2(8u)) ^ _110.yx) * _87).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _143;\n    _143._m0 = uaddCarry(BDA.x, offset, _143._m1);\n    uvec2 addr = uvec2(_143._m0, BDA.y + _143._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _513 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _515 = InstrumentationControlData.atomics[_513];\n        uint _521 = (((inst * 97u) ^ 43981u) ^ (_515 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _522 = _521 >> 4u;\n        uint _524 = 1u << (_521 & 15u);\n        uint _526 = atomicOr(InstrumentationControlData.atomics[_522], _524);\n        ShouldReportInstrumentation = false;\n        if ((_526 & _524) == 0u)\n        {\n            InstrumentationData.data[_521] = uvec4(43981u, 0u, inst, _515);\n            memoryBarrierBuffer();\n            uint _534 = atomicOr(InstrumentationControlData.atomics[_522], _524 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _45 = AllocateInvocationID();\n    InvocationID = _45;\n    uvec2 _54 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _59 = uint(_29[registers._m4]._m0.length()) * 4u;\n    uvec2 _65 = DescriptorHeapRobustness.descriptors[registers._m1]._m0[0u];\n    uint _76 = gl_GlobalInvocationID.x * 12u;\n    uint _458 = InvocationID;\n    bool _457 = ValidateBDALoadStore(_65, _76, 12u, 0u, _458, _76 < (uint(_24[registers._m1]._m0.length()) * 12u));\n    AssumeTrue(_457, 1u);\n    vec3 _465 = uintBitsToFloat(_24[registers._m1]._m0[gl_GlobalInvocationID.x]);\n    uint _468 = gl_GlobalInvocationID.x << 2u;\n    uint _470 = InvocationID;\n    bool _469 = ValidateBDALoadStore(_54, _468, 4u, 0u, _470, _468 < _59);\n    AssumeTrue(_469, 2u);\n    uint _473 = _29[registers._m4]._m0[gl_GlobalInvocationID.x];\n    uint _480 = InvocationID;\n    bool _479 = ValidateBDALoadStore(_54, _468, 4u, 1u, _480, _468 < _59);\n    AssumeTrue(_479, 3u);\n    _29[registers._m4]._m0[gl_GlobalInvocationID.x] = floatBitsToUint(((_465.x + 40.0) + _465.z) + uintBitsToFloat(_473));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 541\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%168 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %72\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %21 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %31 \"BloomBufferInvocationSSBO\"\nOpMemberName %31 0 \"atomics\"\nOpName %33 \"BloomBufferInvocation\"\nOpName %35 \"AllocateInvocationID\"\nOpName %80 \"AddrHash\"\nOpName %78 \"addr\"\nOpName %79 \"prime\"\nOpName %120 \"BloomBufferSSBO\"\nOpMemberName %120 0 \"atomics\"\nOpName %122 \"BloomBuffer\"\nOpName %124 \"BloomBuffer32SSBO\"\nOpMemberName %124 0 \"atomics\"\nOpName %126 \"BloomBuffer32\"\nOpName %134 \"ValidateBDALoadStore\"\nOpName %128 \"BDA\"\nOpName %129 \"offset\"\nOpName %130 \"len\"\nOpName %131 \"type\"\nOpName %132 \"invocation_id\"\nOpName %133 \"in_bounds\"\nOpName %142 \"IAddCarryResult\"\nOpName %147 \"addr\"\nOpName %148 \"addr_lo\"\nOpName %152 \"byte_mask\"\nOpName %162 \"word_mask\"\nOpName %167 \"hash_mask\"\nOpName %172 \"hash_offset\"\nOpName %176 \"bloom_index\"\nOpName %180 \"bloom_index\"\nOpName %184 \"bloom_index\"\nOpName %187 \"bloom_index\"\nOpName %191 \"bloom_index\"\nOpName %195 \"bloom_index\"\nOpName %199 \"bloom_index\"\nOpName %203 \"bloom_index\"\nOpName %207 \"bloom_index\"\nOpName %211 \"bloom_index\"\nOpName %215 \"bloom_index\"\nOpName %219 \"bloom_index\"\nOpName %223 \"bloom_index\"\nOpName %227 \"bloom_index\"\nOpName %231 \"bloom_index\"\nOpName %235 \"bloom_index\"\nOpName %248 \"invalidation_mask\"\nOpName %251 \"prev_hazard_partial\"\nOpName %253 \"prev_hazard_partial\"\nOpName %256 \"prev_hazard_partial\"\nOpName %259 \"prev_hazard_partial\"\nOpName %262 \"prev_hazard_partial\"\nOpName %265 \"prev_hazard_partial\"\nOpName %268 \"prev_hazard_partial\"\nOpName %271 \"prev_hazard_partial\"\nOpName %274 \"prev_hazard_partial\"\nOpName %277 \"prev_hazard_partial\"\nOpName %280 \"prev_hazard_partial\"\nOpName %283 \"prev_hazard_partial\"\nOpName %286 \"prev_hazard_partial\"\nOpName %289 \"prev_hazard_partial\"\nOpName %292 \"prev_hazard_partial\"\nOpName %295 \"prev_hazard_partial\"\nOpName %297 \"prev_hazard\"\nOpName %298 \"prev_hazard_lo\"\nOpName %299 \"prev_hazard_hi\"\nOpName %302 \"has_exclusive_access\"\nOpName %317 \"lock_mask\"\nOpName %320 \"prev_lock\"\nOpName %333 \"lock_mask\"\nOpName %336 \"prev_lock\"\nOpName %350 \"lock_mask\"\nOpName %353 \"prev_lock\"\nOpName %367 \"lock_mask\"\nOpName %370 \"prev_lock\"\nOpName %384 \"lock_mask\"\nOpName %387 \"prev_lock\"\nOpName %398 \"lock_mask\"\nOpName %401 \"prev_lock\"\nOpName %414 \"lock_mask\"\nOpName %417 \"prev_lock\"\nOpName %431 \"lock_mask\"\nOpName %434 \"prev_lock\"\nOpName %437 \"has_complete_self_lock\"\nOpName %453 \"hazard\"\nOpName %486 \"ShouldReportInstrumentation\"\nOpName %489 \"InstrumentationControlDataSSBO\"\nOpMemberName %489 0 \"atomics\"\nOpName %491 \"InstrumentationControlData\"\nOpName %493 \"InstrumentationDataSSBO\"\nOpMemberName %493 0 \"data\"\nOpName %495 \"InstrumentationData\"\nOpName %499 \"AssumeTrue\"\nOpName %497 \"value\"\nOpName %498 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %20 ArrayStride 12\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %25 ArrayStride 4\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 DescriptorSet 4\nOpDecorate %29 Binding 0\nOpDecorate %30 ArrayStride 4\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 2\nOpDecorate %72 BuiltIn GlobalInvocationId\nOpDecorate %119 ArrayStride 8\nOpMemberDecorate %120 0 Offset 0\nOpDecorate %120 Block\nOpDecorate %122 DescriptorSet 0\nOpDecorate %122 Binding 2\nOpDecorate %123 ArrayStride 8\nOpMemberDecorate %124 0 Offset 0\nOpDecorate %124 Block\nOpDecorate %126 DescriptorSet 0\nOpDecorate %126 Binding 2\nOpDecorate %488 ArrayStride 4\nOpMemberDecorate %489 0 Offset 0\nOpDecorate %489 Block\nOpDecorate %491 DescriptorSet 0\nOpDecorate %491 Binding 2\nOpDecorate %492 ArrayStride 16\nOpMemberDecorate %493 0 Offset 0\nOpDecorate %493 Block\nOpDecorate %495 DescriptorSet 0\nOpDecorate %495 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeVector %5 3\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %5\n%26 = OpTypeStruct %25\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeRuntimeArray %5\n%31 = OpTypeStruct %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeFunction %5\n%39 = OpTypePointer StorageBuffer %5\n%41 = OpConstant %5 0\n%43 = OpConstant %5 1103633207\n%46 = OpTypePointer StorageBuffer %26\n%48 = OpTypePointer PushConstant %5\n%50 = OpConstant %5 4\n%52 = OpTypePointer StorageBuffer %9\n%57 = OpConstant %5 16\n%60 = OpTypePointer StorageBuffer %21\n%70 = OpConstant %5 12\n%71 = OpTypePointer Input %19\n%72 = OpVariable %71 Input\n%73 = OpTypePointer Input %5\n%77 = OpTypeFunction %5 %9 %5\n%88 = OpConstant %5 65535\n%89 = OpConstant %5 8\n%90 = OpConstantComposite %9 %89 %89\n%117 = OpTypeInt 64 0\n%118 = OpTypeBool\n%119 = OpTypeRuntimeArray %117\n%120 = OpTypeStruct %119\n%121 = OpTypePointer StorageBuffer %120\n%122 = OpVariable %121 StorageBuffer\n%123 = OpTypeRuntimeArray %9\n%124 = OpTypeStruct %123\n%125 = OpTypePointer StorageBuffer %124\n%126 = OpVariable %125 StorageBuffer\n%127 = OpTypeFunction %118 %9 %5 %5 %5 %5 %118\n%138 = OpConstantTrue %118\n%142 = OpTypeStruct %5 %5\n%153 = OpConstant %5 4294967295\n%154 = OpConstant %5 15\n%163 = OpConstant %5 3\n%164 = OpConstant %5 2\n%174 = OpConstant %5 1103515245\n%178 = OpConstant %5 1103518333\n%182 = OpConstant %5 1103539331\n%189 = OpConstant %5 10006121\n%193 = OpConstant %5 4004951\n%197 = OpConstant %5 5005159\n%201 = OpConstant %5 6004811\n%205 = OpConstant %5 383\n%209 = OpConstant %5 821\n%213 = OpConstant %5 661\n%217 = OpConstant %5 1091\n%221 = OpConstant %5 1117\n%225 = OpConstant %5 3947\n%229 = OpConstant %5 4253\n%233 = OpConstant %5 7691\n%236 = OpTypeVector %117 4\n%237 = OpConstant %117 68719411200\n%238 = OpConstant %117 1099511627775\n%239 = OpConstant %117 1035087118335\n%240 = OpConstantComposite %236 %237 %238 %239 %237\n%249 = OpTypePointer StorageBuffer %117\n%304 = OpTypeInt 32 1\n%305 = OpConstant %304 0\n%306 = OpConstant %304 3\n%308 = OpConstant %5 256\n%311 = OpConstant %5 65536\n%314 = OpConstant %304 6\n%316 = OpConstant %5 16777216\n%324 = OpConstant %304 9\n%327 = OpConstant %304 12\n%331 = OpConstant %304 15\n%341 = OpConstant %304 18\n%344 = OpConstant %304 21\n%348 = OpConstant %304 24\n%358 = OpConstant %304 23\n%361 = OpConstant %304 26\n%365 = OpConstant %304 29\n%375 = OpConstant %304 1\n%378 = OpConstant %304 4\n%382 = OpConstant %304 7\n%406 = OpConstant %304 17\n%409 = OpConstant %304 20\n%422 = OpConstant %304 22\n%425 = OpConstant %304 25\n%429 = OpConstant %304 28\n%460 = OpTypePointer StorageBuffer %19\n%463 = OpTypeFloat 32\n%464 = OpTypeVector %463 3\n%476 = OpConstant %463 40\n%485 = OpTypePointer Private %118\n%486 = OpVariable %485 Private %138\n%487 = OpTypeVector %5 4\n%488 = OpTypeRuntimeArray %5\n%489 = OpTypeStruct %488\n%490 = OpTypePointer StorageBuffer %489\n%491 = OpVariable %490 StorageBuffer\n%492 = OpTypeRuntimeArray %487\n%493 = OpTypeStruct %492\n%494 = OpTypePointer StorageBuffer %493\n%495 = OpVariable %494 StorageBuffer\n%496 = OpTypeFunction %1 %118 %5\n%510 = OpConstant %5 97\n%511 = OpConstant %5 43981\n%517 = OpConstant %5 51329\n%529 = OpConstantFalse %118\n%532 = OpTypePointer StorageBuffer %487\n%535 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %484\n%484 = OpLabel\n%45 = OpFunctionCall %5 %35\nOpStore %18 %45\n%49 = OpAccessChain %48 %8 %50\n%51 = OpLoad %5 %49\n%53 = OpAccessChain %52 %16 %41 %51 %41 %41\n%54 = OpLoad %9 %53\n%55 = OpCompositeExtract %5 %54 1\n%56 = OpShiftRightLogical %5 %55 %57\n%47 = OpAccessChain %46 %29 %51\n%58 = OpArrayLength %5 %47 0\n%59 = OpIMul %5 %58 %50\n%62 = OpAccessChain %48 %8 %10\n%63 = OpLoad %5 %62\n%64 = OpAccessChain %52 %16 %41 %63 %41 %41\n%65 = OpLoad %9 %64\n%66 = OpCompositeExtract %5 %65 1\n%67 = OpShiftRightLogical %5 %66 %57\n%61 = OpAccessChain %60 %24 %63\n%68 = OpArrayLength %5 %61 0\n%69 = OpIMul %5 %68 %70\n%74 = OpAccessChain %73 %72 %41\n%75 = OpLoad %5 %74\n%76 = OpIMul %5 %75 %70\n%458 = OpLoad %5 %18\n%459 = OpULessThan %118 %76 %69\n%457 = OpFunctionCall %118 %134 %65 %76 %70 %41 %458 %459\n%537 = OpFunctionCall %1 %499 %457 %10\n%461 = OpAccessChain %460 %61 %41 %75\n%462 = OpLoad %19 %461\n%465 = OpBitcast %464 %462\n%466 = OpCompositeExtract %463 %465 0\n%467 = OpCompositeExtract %463 %465 2\n%468 = OpShiftLeftLogical %5 %75 %164\n%470 = OpLoad %5 %18\n%471 = OpULessThan %118 %468 %59\n%469 = OpFunctionCall %118 %134 %54 %468 %50 %41 %470 %471\n%538 = OpFunctionCall %1 %499 %469 %164\n%472 = OpAccessChain %39 %47 %41 %75\n%473 = OpLoad %5 %472\n%474 = OpBitcast %463 %473\n%475 = OpFAdd %463 %466 %476\n%477 = OpFAdd %463 %475 %467\n%478 = OpFAdd %463 %477 %474\n%480 = OpLoad %5 %18\n%481 = OpULessThan %118 %468 %59\n%479 = OpFunctionCall %118 %134 %54 %468 %50 %10 %480 %481\n%539 = OpFunctionCall %1 %499 %479 %163\n%482 = OpBitcast %5 %478\n%483 = OpAccessChain %39 %47 %41 %75\nOpStore %483 %482\nOpReturn\nOpFunctionEnd\n%35 = OpFunction %5 None %34\n%36 = OpLabel\n%37 = OpArrayLength %5 %33 0\n%38 = OpISub %5 %37 %10\n%40 = OpAccessChain %39 %33 %41 %38\n%42 = OpAtomicIAdd %5 %40 %10 %41 %43\nOpReturnValue %42\nOpFunctionEnd\n%80 = OpFunction %5 None %77\n%78 = OpFunctionParameter %9\n%79 = OpFunctionParameter %5\n%81 = OpLabel\n%82 = OpCompositeExtract %5 %78 0\n%83 = OpCompositeExtract %5 %78 1\n%84 = OpShiftRightLogical %5 %82 %50\n%85 = OpBitwiseAnd %5 %83 %88\n%86 = OpCompositeConstruct %9 %84 %85\n%87 = OpCompositeConstruct %9 %79 %79\n%91 = OpVectorShuffle %9 %86 %86 1 0\n%92 = OpShiftRightLogical %9 %86 %90\n%93 = OpBitwiseXor %9 %92 %91\n%94 = OpIMul %9 %93 %87\n%95 = OpVectorShuffle %9 %94 %94 1 0\n%96 = OpShiftRightLogical %9 %94 %90\n%97 = OpBitwiseXor %9 %96 %95\n%98 = OpIMul %9 %97 %87\n%99 = OpVectorShuffle %9 %98 %98 1 0\n%100 = OpShiftRightLogical %9 %98 %90\n%101 = OpBitwiseXor %9 %100 %99\n%102 = OpIMul %9 %101 %87\n%103 = OpVectorShuffle %9 %102 %102 1 0\n%104 = OpShiftRightLogical %9 %102 %90\n%105 = OpBitwiseXor %9 %104 %103\n%106 = OpIMul %9 %105 %87\n%107 = OpVectorShuffle %9 %106 %106 1 0\n%108 = OpShiftRightLogical %9 %106 %90\n%109 = OpBitwiseXor %9 %108 %107\n%110 = OpIMul %9 %109 %87\n%111 = OpVectorShuffle %9 %110 %110 1 0\n%112 = OpShiftRightLogical %9 %110 %90\n%113 = OpBitwiseXor %9 %112 %111\n%114 = OpIMul %9 %113 %87\n%115 = OpCompositeExtract %5 %114 0\nOpReturnValue %115\nOpFunctionEnd\n%134 = OpFunction %118 None %127\n%128 = OpFunctionParameter %9\n%129 = OpFunctionParameter %5\n%130 = OpFunctionParameter %5\n%131 = OpFunctionParameter %5\n%132 = OpFunctionParameter %5\n%133 = OpFunctionParameter %118\n%135 = OpLabel\nOpSelectionMerge %137 None\nOpBranchConditional %133 %137 %136\n%136 = OpLabel\nOpReturnValue %138\n%137 = OpLabel\n%140 = OpCompositeExtract %5 %128 0\n%141 = OpCompositeExtract %5 %128 1\n%143 = OpIAddCarry %142 %140 %129\n%144 = OpCompositeExtract %5 %143 0\n%145 = OpCompositeExtract %5 %143 1\n%146 = OpIAdd %5 %141 %145\n%147 = OpCompositeConstruct %9 %144 %146\n%148 = OpCompositeExtract %5 %147 0\n%149 = OpBitFieldUExtract %5 %153 %41 %130\n%150 = OpBitwiseAnd %5 %148 %154\n%151 = OpShiftLeftLogical %5 %149 %150\n%152 = OpBitwiseAnd %5 %151 %88\n%155 = OpBitwiseAnd %5 %148 %163\n%156 = OpIAdd %5 %155 %130\n%157 = OpIAdd %5 %156 %163\n%158 = OpShiftRightLogical %5 %157 %164\n%159 = OpBitFieldUExtract %5 %148 %164 %164\n%160 = OpBitFieldUExtract %5 %153 %41 %158\n%161 = OpShiftLeftLogical %5 %160 %159\n%162 = OpBitwiseAnd %5 %161 %154\n%165 = OpArrayLength %5 %122 0\n%166 = OpExtInst %5 %168 FindUMsb %165\n%167 = OpBitFieldUExtract %5 %153 %41 %166\n%169 = OpArrayLength %5 %122 0\n%170 = OpExtInst %5 %168 FindUMsb %169\n%171 = OpBitFieldUExtract %5 %169 %41 %170\n%172 = OpISub %5 %171 %10\n%173 = OpFunctionCall %5 %80 %147 %174\n%175 = OpBitwiseAnd %5 %173 %167\n%176 = OpIAdd %5 %175 %172\n%177 = OpFunctionCall %5 %80 %147 %178\n%179 = OpBitwiseAnd %5 %177 %167\n%180 = OpIAdd %5 %179 %172\n%181 = OpFunctionCall %5 %80 %147 %182\n%183 = OpBitwiseAnd %5 %181 %167\n%184 = OpIAdd %5 %183 %172\n%185 = OpFunctionCall %5 %80 %147 %43\n%186 = OpBitwiseAnd %5 %185 %167\n%187 = OpIAdd %5 %186 %172\n%188 = OpFunctionCall %5 %80 %147 %189\n%190 = OpBitwiseAnd %5 %188 %167\n%191 = OpIAdd %5 %190 %172\n%192 = OpFunctionCall %5 %80 %147 %193\n%194 = OpBitwiseAnd %5 %192 %167\n%195 = OpIAdd %5 %194 %172\n%196 = OpFunctionCall %5 %80 %147 %197\n%198 = OpBitwiseAnd %5 %196 %167\n%199 = OpIAdd %5 %198 %172\n%200 = OpFunctionCall %5 %80 %147 %201\n%202 = OpBitwiseAnd %5 %200 %167\n%203 = OpIAdd %5 %202 %172\n%204 = OpFunctionCall %5 %80 %147 %205\n%206 = OpBitwiseAnd %5 %204 %167\n%207 = OpIAdd %5 %206 %172\n%208 = OpFunctionCall %5 %80 %147 %209\n%210 = OpBitwiseAnd %5 %208 %167\n%211 = OpIAdd %5 %210 %172\n%212 = OpFunctionCall %5 %80 %147 %213\n%214 = OpBitwiseAnd %5 %212 %167\n%215 = OpIAdd %5 %214 %172\n%216 = OpFunctionCall %5 %80 %147 %217\n%218 = OpBitwiseAnd %5 %216 %167\n%219 = OpIAdd %5 %218 %172\n%220 = OpFunctionCall %5 %80 %147 %221\n%222 = OpBitwiseAnd %5 %220 %167\n%223 = OpIAdd %5 %222 %172\n%224 = OpFunctionCall %5 %80 %147 %225\n%226 = OpBitwiseAnd %5 %224 %167\n%227 = OpIAdd %5 %226 %172\n%228 = OpFunctionCall %5 %80 %147 %229\n%230 = OpBitwiseAnd %5 %228 %167\n%231 = OpIAdd %5 %230 %172\n%232 = OpFunctionCall %5 %80 %147 %233\n%234 = OpBitwiseAnd %5 %232 %167\n%235 = OpIAdd %5 %234 %172\n%241 = OpVectorExtractDynamic %117 %240 %131\n%242 = OpShiftLeftLogical %5 %152 %57\n%243 = OpShiftLeftLogical %5 %162 %50\n%244 = OpBitwiseOr %5 %152 %242\n%245 = OpBitwiseOr %5 %162 %243\n%246 = OpCompositeConstruct %9 %244 %245\n%247 = OpBitcast %117 %246\n%248 = OpBitwiseAnd %117 %241 %247\n%250 = OpInBoundsAccessChain %249 %122 %41 %176\n%251 = OpAtomicOr %117 %250 %10 %41 %248\n%252 = OpInBoundsAccessChain %249 %122 %41 %180\n%253 = OpAtomicOr %117 %252 %10 %41 %248\n%254 = OpBitwiseAnd %117 %251 %253\n%255 = OpInBoundsAccessChain %249 %122 %41 %184\n%256 = OpAtomicOr %117 %255 %10 %41 %248\n%257 = OpBitwiseAnd %117 %254 %256\n%258 = OpInBoundsAccessChain %249 %122 %41 %187\n%259 = OpAtomicOr %117 %258 %10 %41 %248\n%260 = OpBitwiseAnd %117 %257 %259\n%261 = OpInBoundsAccessChain %249 %122 %41 %191\n%262 = OpAtomicOr %117 %261 %10 %41 %248\n%263 = OpBitwiseAnd %117 %260 %262\n%264 = OpInBoundsAccessChain %249 %122 %41 %195\n%265 = OpAtomicOr %117 %264 %10 %41 %248\n%266 = OpBitwiseAnd %117 %263 %265\n%267 = OpInBoundsAccessChain %249 %122 %41 %199\n%268 = OpAtomicOr %117 %267 %10 %41 %248\n%269 = OpBitwiseAnd %117 %266 %268\n%270 = OpInBoundsAccessChain %249 %122 %41 %203\n%271 = OpAtomicOr %117 %270 %10 %41 %248\n%272 = OpBitwiseAnd %117 %269 %271\n%273 = OpInBoundsAccessChain %249 %122 %41 %207\n%274 = OpAtomicOr %117 %273 %10 %41 %248\n%275 = OpBitwiseAnd %117 %272 %274\n%276 = OpInBoundsAccessChain %249 %122 %41 %211\n%277 = OpAtomicOr %117 %276 %10 %41 %248\n%278 = OpBitwiseAnd %117 %275 %277\n%279 = OpInBoundsAccessChain %249 %122 %41 %215\n%280 = OpAtomicOr %117 %279 %10 %41 %248\n%281 = OpBitwiseAnd %117 %278 %280\n%282 = OpInBoundsAccessChain %249 %122 %41 %219\n%283 = OpAtomicOr %117 %282 %10 %41 %248\n%284 = OpBitwiseAnd %117 %281 %283\n%285 = OpInBoundsAccessChain %249 %122 %41 %223\n%286 = OpAtomicOr %117 %285 %10 %41 %248\n%287 = OpBitwiseAnd %117 %284 %286\n%288 = OpInBoundsAccessChain %249 %122 %41 %227\n%289 = OpAtomicOr %117 %288 %10 %41 %248\n%290 = OpBitwiseAnd %117 %287 %289\n%291 = OpInBoundsAccessChain %249 %122 %41 %231\n%292 = OpAtomicOr %117 %291 %10 %41 %248\n%293 = OpBitwiseAnd %117 %290 %292\n%294 = OpInBoundsAccessChain %249 %122 %41 %235\n%295 = OpAtomicOr %117 %294 %10 %41 %248\n%296 = OpBitwiseAnd %117 %293 %295\n%297 = OpBitcast %9 %296\n%298 = OpCompositeExtract %5 %297 0\n%299 = OpCompositeExtract %5 %297 1\n%300 = OpShiftRightLogical %5 %298 %57\n%301 = OpBitwiseAnd %5 %300 %152\n%302 = OpIEqual %118 %301 %41\n%303 = OpBitFieldUExtract %5 %132 %305 %306\n%307 = OpShiftLeftLogical %5 %308 %303\n%309 = OpBitFieldUExtract %5 %132 %306 %306\n%310 = OpShiftLeftLogical %5 %311 %309\n%312 = OpBitwiseOr %5 %307 %310\n%313 = OpBitFieldUExtract %5 %132 %314 %306\n%315 = OpShiftLeftLogical %5 %316 %313\n%317 = OpBitwiseOr %5 %312 %315\n%318 = OpSelect %5 %302 %317 %41\n%319 = OpInBoundsAccessChain %39 %126 %41 %176 %10\n%320 = OpAtomicOr %5 %319 %10 %41 %318\n%321 = OpBitwiseAnd %5 %320 %317\n%322 = OpIEqual %118 %321 %317\n%323 = OpBitFieldUExtract %5 %132 %324 %306\n%325 = OpShiftLeftLogical %5 %308 %323\n%326 = OpBitFieldUExtract %5 %132 %327 %306\n%328 = OpShiftLeftLogical %5 %311 %326\n%329 = OpBitwiseOr %5 %325 %328\n%330 = OpBitFieldUExtract %5 %132 %331 %306\n%332 = OpShiftLeftLogical %5 %316 %330\n%333 = OpBitwiseOr %5 %329 %332\n%334 = OpSelect %5 %302 %333 %41\n%335 = OpInBoundsAccessChain %39 %126 %41 %180 %10\n%336 = OpAtomicOr %5 %335 %10 %41 %334\n%337 = OpBitwiseAnd %5 %336 %333\n%338 = OpIEqual %118 %337 %333\n%339 = OpLogicalAnd %118 %322 %338\n%340 = OpBitFieldUExtract %5 %132 %341 %306\n%342 = OpShiftLeftLogical %5 %308 %340\n%343 = OpBitFieldUExtract %5 %132 %344 %306\n%345 = OpShiftLeftLogical %5 %311 %343\n%346 = OpBitwiseOr %5 %342 %345\n%347 = OpBitFieldUExtract %5 %132 %348 %306\n%349 = OpShiftLeftLogical %5 %316 %347\n%350 = OpBitwiseOr %5 %346 %349\n%351 = OpSelect %5 %302 %350 %41\n%352 = OpInBoundsAccessChain %39 %126 %41 %184 %10\n%353 = OpAtomicOr %5 %352 %10 %41 %351\n%354 = OpBitwiseAnd %5 %353 %350\n%355 = OpIEqual %118 %354 %350\n%356 = OpLogicalAnd %118 %339 %355\n%357 = OpBitFieldUExtract %5 %132 %358 %306\n%359 = OpShiftLeftLogical %5 %308 %357\n%360 = OpBitFieldUExtract %5 %132 %361 %306\n%362 = OpShiftLeftLogical %5 %311 %360\n%363 = OpBitwiseOr %5 %359 %362\n%364 = OpBitFieldUExtract %5 %132 %365 %306\n%366 = OpShiftLeftLogical %5 %316 %364\n%367 = OpBitwiseOr %5 %363 %366\n%368 = OpSelect %5 %302 %367 %41\n%369 = OpInBoundsAccessChain %39 %126 %41 %187 %10\n%370 = OpAtomicOr %5 %369 %10 %41 %368\n%371 = OpBitwiseAnd %5 %370 %367\n%372 = OpIEqual %118 %371 %367\n%373 = OpLogicalAnd %118 %356 %372\n%374 = OpBitFieldUExtract %5 %132 %375 %306\n%376 = OpShiftLeftLogical %5 %308 %374\n%377 = OpBitFieldUExtract %5 %132 %378 %306\n%379 = OpShiftLeftLogical %5 %311 %377\n%380 = OpBitwiseOr %5 %376 %379\n%381 = OpBitFieldUExtract %5 %132 %382 %306\n%383 = OpShiftLeftLogical %5 %316 %381\n%384 = OpBitwiseOr %5 %380 %383\n%385 = OpSelect %5 %302 %384 %41\n%386 = OpInBoundsAccessChain %39 %126 %41 %191 %10\n%387 = OpAtomicOr %5 %386 %10 %41 %385\n%388 = OpBitwiseAnd %5 %387 %384\n%389 = OpIEqual %118 %388 %384\n%390 = OpLogicalAnd %118 %373 %389\n%391 = OpBitFieldUExtract %5 %132 %324 %306\n%392 = OpShiftLeftLogical %5 %308 %391\n%393 = OpBitFieldUExtract %5 %132 %327 %306\n%394 = OpShiftLeftLogical %5 %311 %393\n%395 = OpBitwiseOr %5 %392 %394\n%396 = OpBitFieldUExtract %5 %132 %331 %306\n%397 = OpShiftLeftLogical %5 %316 %396\n%398 = OpBitwiseOr %5 %395 %397\n%399 = OpSelect %5 %302 %398 %41\n%400 = OpInBoundsAccessChain %39 %126 %41 %195 %10\n%401 = OpAtomicOr %5 %400 %10 %41 %399\n%402 = OpBitwiseAnd %5 %401 %398\n%403 = OpIEqual %118 %402 %398\n%404 = OpLogicalAnd %118 %390 %403\n%405 = OpBitFieldUExtract %5 %132 %406 %306\n%407 = OpShiftLeftLogical %5 %308 %405\n%408 = OpBitFieldUExtract %5 %132 %409 %306\n%410 = OpShiftLeftLogical %5 %311 %408\n%411 = OpBitwiseOr %5 %407 %410\n%412 = OpBitFieldUExtract %5 %132 %358 %306\n%413 = OpShiftLeftLogical %5 %316 %412\n%414 = OpBitwiseOr %5 %411 %413\n%415 = OpSelect %5 %302 %414 %41\n%416 = OpInBoundsAccessChain %39 %126 %41 %199 %10\n%417 = OpAtomicOr %5 %416 %10 %41 %415\n%418 = OpBitwiseAnd %5 %417 %414\n%419 = OpIEqual %118 %418 %414\n%420 = OpLogicalAnd %118 %404 %419\n%421 = OpBitFieldUExtract %5 %132 %422 %306\n%423 = OpShiftLeftLogical %5 %308 %421\n%424 = OpBitFieldUExtract %5 %132 %425 %306\n%426 = OpShiftLeftLogical %5 %311 %424\n%427 = OpBitwiseOr %5 %423 %426\n%428 = OpBitFieldUExtract %5 %132 %429 %306\n%430 = OpShiftLeftLogical %5 %316 %428\n%431 = OpBitwiseOr %5 %427 %430\n%432 = OpSelect %5 %302 %431 %41\n%433 = OpInBoundsAccessChain %39 %126 %41 %203 %10\n%434 = OpAtomicOr %5 %433 %10 %41 %432\n%435 = OpBitwiseAnd %5 %434 %431\n%436 = OpIEqual %118 %435 %431\n%437 = OpLogicalAnd %118 %420 %436\nOpSelectionMerge %442 None\nOpSwitch %131 %441 0 %438 1 %439 2 %440\n%441 = OpLabel\n%450 = OpShiftLeftLogical %5 %162 %50\n%451 = OpBitwiseAnd %5 %299 %450\n%452 = OpINotEqual %118 %451 %41\nOpBranch %442\n%438 = OpLabel\n%443 = OpBitwiseAnd %5 %298 %152\n%444 = OpINotEqual %118 %443 %41\nOpBranch %442\n%439 = OpLabel\n%445 = OpShiftLeftLogical %5 %152 %57\n%446 = OpBitwiseAnd %5 %298 %445\n%447 = OpINotEqual %118 %446 %41\nOpBranch %442\n%440 = OpLabel\n%448 = OpBitwiseAnd %5 %299 %162\n%449 = OpINotEqual %118 %448 %41\nOpBranch %442\n%442 = OpLabel\n%453 = OpPhi %118 %444 %438 %447 %439 %449 %440 %452 %441\n%454 = OpLogicalNot %118 %453\n%455 = OpLogicalOr %118 %454 %437\nOpReturnValue %455\nOpFunctionEnd\n%499 = OpFunction %1 None %496\n%497 = OpFunctionParameter %118\n%498 = OpFunctionParameter %5\n%500 = OpLabel\n%503 = OpLogicalNot %118 %497\n%504 = OpLoad %118 %486\n%505 = OpLogicalAnd %118 %503 %504\nOpSelectionMerge %501 None\nOpBranchConditional %505 %502 %501\n%502 = OpLabel\n%508 = OpIMul %5 %498 %510\n%509 = OpBitwiseXor %5 %508 %511\n%512 = OpArrayLength %5 %491 0\n%513 = OpISub %5 %512 %164\n%514 = OpAccessChain %39 %491 %41 %513\n%515 = OpLoad %5 %514\n%516 = OpIMul %5 %515 %517\n%518 = OpBitwiseXor %5 %509 %516\n%519 = OpArrayLength %5 %495 0\n%520 = OpISub %5 %519 %10\n%521 = OpBitwiseAnd %5 %518 %520\n%522 = OpShiftRightLogical %5 %521 %50\n%523 = OpBitwiseAnd %5 %521 %154\n%524 = OpShiftLeftLogical %5 %10 %523\n%525 = OpAccessChain %39 %491 %41 %522\n%526 = OpAtomicOr %5 %525 %10 %41 %524\n%527 = OpBitwiseAnd %5 %526 %524\n%528 = OpIEqual %118 %527 %41\nOpStore %486 %529\nOpSelectionMerge %507 None\nOpBranchConditional %528 %506 %507\n%506 = OpLabel\n%530 = OpCompositeConstruct %487 %511 %41 %498 %515\n%531 = OpShiftLeftLogical %5 %524 %57\n%533 = OpAccessChain %532 %495 %41 %521\nOpStore %533 %530\nOpMemoryBarrier %10 %535\n%534 = OpAtomicOr %5 %525 %10 %41 %531\nOpMemoryBarrier %10 %535\nOpBranch %507\n%507 = OpLabel\nOpBranch %501\n%501 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/raw.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat3NonWrite;\nlayout(buffer_reference) buffer PhysicalPointerFloatArray;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct AddCarry\n{\n    uint _m0;\n    uint _m1;\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nfloat _468;\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerFloat3NonWrite\n{\n    vec3 value;\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerFloatArray\n{\n    float value[];\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _31 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _31;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _71 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _72 = uvec2(prime);\n    uvec2 _80 = ((_71 >> uvec2(8u)) ^ _71.yx) * _72;\n    uvec2 _84 = ((_80 >> uvec2(8u)) ^ _80.yx) * _72;\n    uvec2 _88 = ((_84 >> uvec2(8u)) ^ _84.yx) * _72;\n    uvec2 _92 = ((_88 >> uvec2(8u)) ^ _88.yx) * _72;\n    uvec2 _96 = ((_92 >> uvec2(8u)) ^ _92.yx) * _72;\n    return (((_96 >> uvec2(8u)) ^ _96.yx) * _72).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _129;\n    _129._m0 = uaddCarry(BDA.x, offset, _129._m1);\n    uvec2 addr = uvec2(_129._m0, BDA.y + _129._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _498 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _500 = InstrumentationControlData.atomics[_498];\n        uint _506 = (((inst * 97u) ^ 43981u) ^ (_500 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _507 = _506 >> 4u;\n        uint _509 = 1u << (_506 & 15u);\n        uint _511 = atomicOr(InstrumentationControlData.atomics[_507], _509);\n        ShouldReportInstrumentation = false;\n        if ((_511 & _509) == 0u)\n        {\n            InstrumentationData.data[_506] = uvec4(43981u, 0u, inst, _500);\n            memoryBarrierBuffer();\n            uint _519 = atomicOr(InstrumentationControlData.atomics[_507], _509 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _34 = AllocateInvocationID();\n    InvocationID = _34;\n    uint _47 = gl_GlobalInvocationID.x << 3u;\n    AddCarry _56;\n    _56._m0 = uaddCarry(registers._m1.x, _47, _56._m1);\n    uint _443 = InvocationID;\n    bool _442 = ValidateBDALoadStore(registers._m1, _47, 12u, 0u, _443, true);\n    AssumeTrue(_442, 1u);\n    PhysicalPointerFloat3NonWrite _444 = PhysicalPointerFloat3NonWrite(uvec2(_56._m0, registers._m1.y + _56._m1));\n    uint _450 = gl_GlobalInvocationID.x << 2u;\n    uint _455 = InvocationID;\n    bool _454 = ValidateBDALoadStore(registers._m2, _450, 4u, 0u, _455, true);\n    AssumeTrue(_454, 2u);\n    uint _465 = InvocationID;\n    bool _464 = ValidateBDALoadStore(registers._m2, _450, 4u, 1u, _465, true);\n    AssumeTrue(_464, 3u);\n    PhysicalPointerFloatArray(registers._m2).value[gl_GlobalInvocationID.x] = ((_444.value.x + 40.0) + _444.value.z) + PhysicalPointerFloatArray(registers._m2).value[gl_GlobalInvocationID.x];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 526\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%152 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %43\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"BloomBufferInvocationSSBO\"\nOpMemberName %20 0 \"atomics\"\nOpName %22 \"BloomBufferInvocation\"\nOpName %24 \"AllocateInvocationID\"\nOpName %51 \"PhysicalPointerFloat3NonWrite\"\nOpMemberName %51 0 \"value\"\nOpName %55 \"AddCarry\"\nOpName %65 \"AddrHash\"\nOpName %63 \"addr\"\nOpName %64 \"prime\"\nOpName %106 \"BloomBufferSSBO\"\nOpMemberName %106 0 \"atomics\"\nOpName %108 \"BloomBuffer\"\nOpName %110 \"BloomBuffer32SSBO\"\nOpMemberName %110 0 \"atomics\"\nOpName %112 \"BloomBuffer32\"\nOpName %120 \"ValidateBDALoadStore\"\nOpName %114 \"BDA\"\nOpName %115 \"offset\"\nOpName %116 \"len\"\nOpName %117 \"type\"\nOpName %118 \"invocation_id\"\nOpName %119 \"in_bounds\"\nOpName %128 \"IAddCarryResult\"\nOpName %133 \"addr\"\nOpName %134 \"addr_lo\"\nOpName %138 \"byte_mask\"\nOpName %148 \"word_mask\"\nOpName %151 \"hash_mask\"\nOpName %156 \"hash_offset\"\nOpName %160 \"bloom_index\"\nOpName %164 \"bloom_index\"\nOpName %168 \"bloom_index\"\nOpName %171 \"bloom_index\"\nOpName %175 \"bloom_index\"\nOpName %179 \"bloom_index\"\nOpName %183 \"bloom_index\"\nOpName %187 \"bloom_index\"\nOpName %191 \"bloom_index\"\nOpName %195 \"bloom_index\"\nOpName %199 \"bloom_index\"\nOpName %203 \"bloom_index\"\nOpName %207 \"bloom_index\"\nOpName %211 \"bloom_index\"\nOpName %215 \"bloom_index\"\nOpName %219 \"bloom_index\"\nOpName %233 \"invalidation_mask\"\nOpName %236 \"prev_hazard_partial\"\nOpName %238 \"prev_hazard_partial\"\nOpName %241 \"prev_hazard_partial\"\nOpName %244 \"prev_hazard_partial\"\nOpName %247 \"prev_hazard_partial\"\nOpName %250 \"prev_hazard_partial\"\nOpName %253 \"prev_hazard_partial\"\nOpName %256 \"prev_hazard_partial\"\nOpName %259 \"prev_hazard_partial\"\nOpName %262 \"prev_hazard_partial\"\nOpName %265 \"prev_hazard_partial\"\nOpName %268 \"prev_hazard_partial\"\nOpName %271 \"prev_hazard_partial\"\nOpName %274 \"prev_hazard_partial\"\nOpName %277 \"prev_hazard_partial\"\nOpName %280 \"prev_hazard_partial\"\nOpName %282 \"prev_hazard\"\nOpName %283 \"prev_hazard_lo\"\nOpName %284 \"prev_hazard_hi\"\nOpName %287 \"has_exclusive_access\"\nOpName %302 \"lock_mask\"\nOpName %305 \"prev_lock\"\nOpName %318 \"lock_mask\"\nOpName %321 \"prev_lock\"\nOpName %335 \"lock_mask\"\nOpName %338 \"prev_lock\"\nOpName %352 \"lock_mask\"\nOpName %355 \"prev_lock\"\nOpName %369 \"lock_mask\"\nOpName %372 \"prev_lock\"\nOpName %383 \"lock_mask\"\nOpName %386 \"prev_lock\"\nOpName %399 \"lock_mask\"\nOpName %402 \"prev_lock\"\nOpName %416 \"lock_mask\"\nOpName %419 \"prev_lock\"\nOpName %422 \"has_complete_self_lock\"\nOpName %438 \"hazard\"\nOpName %452 \"PhysicalPointerFloatArray\"\nOpMemberName %452 0 \"value\"\nOpName %471 \"ShouldReportInstrumentation\"\nOpName %474 \"InstrumentationControlDataSSBO\"\nOpMemberName %474 0 \"atomics\"\nOpName %476 \"InstrumentationControlData\"\nOpName %478 \"InstrumentationDataSSBO\"\nOpMemberName %478 0 \"data\"\nOpName %480 \"InstrumentationData\"\nOpName %484 \"AssumeTrue\"\nOpName %482 \"value\"\nOpName %483 \"inst\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 2\nOpDecorate %43 BuiltIn GlobalInvocationId\nOpMemberDecorate %51 0 Offset 0\nOpDecorate %51 Block\nOpMemberDecorate %51 0 NonWritable\nOpDecorate %105 ArrayStride 8\nOpMemberDecorate %106 0 Offset 0\nOpDecorate %106 Block\nOpDecorate %108 DescriptorSet 0\nOpDecorate %108 Binding 2\nOpDecorate %109 ArrayStride 8\nOpMemberDecorate %110 0 Offset 0\nOpDecorate %110 Block\nOpDecorate %112 DescriptorSet 0\nOpDecorate %112 Binding 2\nOpDecorate %451 ArrayStride 4\nOpMemberDecorate %452 0 Offset 0\nOpDecorate %452 Block\nOpDecorate %473 ArrayStride 4\nOpMemberDecorate %474 0 Offset 0\nOpDecorate %474 Block\nOpDecorate %476 DescriptorSet 0\nOpDecorate %476 Binding 2\nOpDecorate %477 ArrayStride 16\nOpMemberDecorate %478 0 Offset 0\nOpDecorate %478 Block\nOpDecorate %480 DescriptorSet 0\nOpDecorate %480 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpConstant %5 1\n%11 = OpTypeArray %6 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeFunction %5\n%28 = OpTypePointer StorageBuffer %5\n%30 = OpConstant %5 0\n%32 = OpConstant %5 1103633207\n%35 = OpTypePointer PushConstant %6\n%37 = OpConstant %5 2\n%41 = OpTypeVector %5 3\n%42 = OpTypePointer Input %41\n%43 = OpVariable %42 Input\n%44 = OpTypePointer Input %5\n%48 = OpConstant %5 3\n%49 = OpTypeFloat 32\n%50 = OpTypeVector %49 3\n%51 = OpTypeStruct %50\n%52 = OpTypePointer PhysicalStorageBuffer %51\n%55 = OpTypeStruct %5 %5\n%61 = OpConstant %5 12\n%62 = OpTypeFunction %5 %6 %5\n%73 = OpConstant %5 4\n%74 = OpConstant %5 65535\n%75 = OpConstant %5 8\n%76 = OpConstantComposite %6 %75 %75\n%103 = OpTypeInt 64 0\n%104 = OpTypeBool\n%105 = OpTypeRuntimeArray %103\n%106 = OpTypeStruct %105\n%107 = OpTypePointer StorageBuffer %106\n%108 = OpVariable %107 StorageBuffer\n%109 = OpTypeRuntimeArray %6\n%110 = OpTypeStruct %109\n%111 = OpTypePointer StorageBuffer %110\n%112 = OpVariable %111 StorageBuffer\n%113 = OpTypeFunction %104 %6 %5 %5 %5 %5 %104\n%124 = OpConstantTrue %104\n%128 = OpTypeStruct %5 %5\n%139 = OpConstant %5 4294967295\n%140 = OpConstant %5 15\n%158 = OpConstant %5 1103515245\n%162 = OpConstant %5 1103518333\n%166 = OpConstant %5 1103539331\n%173 = OpConstant %5 10006121\n%177 = OpConstant %5 4004951\n%181 = OpConstant %5 5005159\n%185 = OpConstant %5 6004811\n%189 = OpConstant %5 383\n%193 = OpConstant %5 821\n%197 = OpConstant %5 661\n%201 = OpConstant %5 1091\n%205 = OpConstant %5 1117\n%209 = OpConstant %5 3947\n%213 = OpConstant %5 4253\n%217 = OpConstant %5 7691\n%220 = OpTypeVector %103 4\n%221 = OpConstant %103 68719411200\n%222 = OpConstant %103 1099511627775\n%223 = OpConstant %103 1035087118335\n%224 = OpConstantComposite %220 %221 %222 %223 %221\n%228 = OpConstant %5 16\n%234 = OpTypePointer StorageBuffer %103\n%289 = OpTypeInt 32 1\n%290 = OpConstant %289 0\n%291 = OpConstant %289 3\n%293 = OpConstant %5 256\n%296 = OpConstant %5 65536\n%299 = OpConstant %289 6\n%301 = OpConstant %5 16777216\n%309 = OpConstant %289 9\n%312 = OpConstant %289 12\n%316 = OpConstant %289 15\n%326 = OpConstant %289 18\n%329 = OpConstant %289 21\n%333 = OpConstant %289 24\n%343 = OpConstant %289 23\n%346 = OpConstant %289 26\n%350 = OpConstant %289 29\n%360 = OpConstant %289 1\n%363 = OpConstant %289 4\n%367 = OpConstant %289 7\n%391 = OpConstant %289 17\n%394 = OpConstant %289 20\n%407 = OpConstant %289 22\n%410 = OpConstant %289 25\n%414 = OpConstant %289 28\n%445 = OpTypePointer PhysicalStorageBuffer %50\n%451 = OpTypeRuntimeArray %49\n%452 = OpTypeStruct %451\n%453 = OpTypePointer PhysicalStorageBuffer %452\n%457 = OpTypePointer PhysicalStorageBuffer %49\n%461 = OpConstant %49 40\n%470 = OpTypePointer Private %104\n%471 = OpVariable %470 Private %124\n%472 = OpTypeVector %5 4\n%473 = OpTypeRuntimeArray %5\n%474 = OpTypeStruct %473\n%475 = OpTypePointer StorageBuffer %474\n%476 = OpVariable %475 StorageBuffer\n%477 = OpTypeRuntimeArray %472\n%478 = OpTypeStruct %477\n%479 = OpTypePointer StorageBuffer %478\n%480 = OpVariable %479 StorageBuffer\n%481 = OpTypeFunction %1 %104 %5\n%495 = OpConstant %5 97\n%496 = OpConstant %5 43981\n%502 = OpConstant %5 51329\n%514 = OpConstantFalse %104\n%517 = OpTypePointer StorageBuffer %472\n%520 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%468 = OpUndef %49\nOpBranch %469\n%469 = OpLabel\n%34 = OpFunctionCall %5 %24\nOpStore %18 %34\n%36 = OpAccessChain %35 %9 %37\n%38 = OpLoad %6 %36\n%39 = OpAccessChain %35 %9 %10\n%40 = OpLoad %6 %39\n%45 = OpAccessChain %44 %43 %30\n%46 = OpLoad %5 %45\n%47 = OpShiftLeftLogical %5 %46 %48\n%53 = OpCompositeExtract %5 %40 0\n%54 = OpCompositeExtract %5 %40 1\n%56 = OpIAddCarry %55 %53 %47\n%57 = OpCompositeExtract %5 %56 0\n%58 = OpCompositeExtract %5 %56 1\n%59 = OpIAdd %5 %54 %58\n%60 = OpCompositeConstruct %6 %57 %59\n%443 = OpLoad %5 %18\n%442 = OpFunctionCall %104 %120 %40 %47 %61 %30 %443 %124\n%522 = OpFunctionCall %1 %484 %442 %10\n%444 = OpBitcast %52 %60\n%446 = OpInBoundsAccessChain %445 %444 %30\n%447 = OpLoad %50 %446 Aligned 4\n%448 = OpCompositeExtract %49 %447 0\n%449 = OpCompositeExtract %49 %447 2\n%450 = OpShiftLeftLogical %5 %46 %37\n%455 = OpLoad %5 %18\n%454 = OpFunctionCall %104 %120 %38 %450 %73 %30 %455 %124\n%523 = OpFunctionCall %1 %484 %454 %37\n%456 = OpBitcast %453 %38\n%458 = OpInBoundsAccessChain %457 %456 %30 %46\n%459 = OpLoad %49 %458 Aligned 4\n%460 = OpFAdd %49 %448 %461\n%462 = OpFAdd %49 %460 %449\n%463 = OpFAdd %49 %462 %459\n%465 = OpLoad %5 %18\n%464 = OpFunctionCall %104 %120 %38 %450 %73 %10 %465 %124\n%524 = OpFunctionCall %1 %484 %464 %48\n%466 = OpBitcast %453 %38\n%467 = OpInBoundsAccessChain %457 %466 %30 %46\nOpStore %467 %463 Aligned 4\nOpReturn\nOpFunctionEnd\n%24 = OpFunction %5 None %23\n%25 = OpLabel\n%26 = OpArrayLength %5 %22 0\n%27 = OpISub %5 %26 %10\n%29 = OpAccessChain %28 %22 %30 %27\n%31 = OpAtomicIAdd %5 %29 %10 %30 %32\nOpReturnValue %31\nOpFunctionEnd\n%65 = OpFunction %5 None %62\n%63 = OpFunctionParameter %6\n%64 = OpFunctionParameter %5\n%66 = OpLabel\n%67 = OpCompositeExtract %5 %63 0\n%68 = OpCompositeExtract %5 %63 1\n%69 = OpShiftRightLogical %5 %67 %73\n%70 = OpBitwiseAnd %5 %68 %74\n%71 = OpCompositeConstruct %6 %69 %70\n%72 = OpCompositeConstruct %6 %64 %64\n%77 = OpVectorShuffle %6 %71 %71 1 0\n%78 = OpShiftRightLogical %6 %71 %76\n%79 = OpBitwiseXor %6 %78 %77\n%80 = OpIMul %6 %79 %72\n%81 = OpVectorShuffle %6 %80 %80 1 0\n%82 = OpShiftRightLogical %6 %80 %76\n%83 = OpBitwiseXor %6 %82 %81\n%84 = OpIMul %6 %83 %72\n%85 = OpVectorShuffle %6 %84 %84 1 0\n%86 = OpShiftRightLogical %6 %84 %76\n%87 = OpBitwiseXor %6 %86 %85\n%88 = OpIMul %6 %87 %72\n%89 = OpVectorShuffle %6 %88 %88 1 0\n%90 = OpShiftRightLogical %6 %88 %76\n%91 = OpBitwiseXor %6 %90 %89\n%92 = OpIMul %6 %91 %72\n%93 = OpVectorShuffle %6 %92 %92 1 0\n%94 = OpShiftRightLogical %6 %92 %76\n%95 = OpBitwiseXor %6 %94 %93\n%96 = OpIMul %6 %95 %72\n%97 = OpVectorShuffle %6 %96 %96 1 0\n%98 = OpShiftRightLogical %6 %96 %76\n%99 = OpBitwiseXor %6 %98 %97\n%100 = OpIMul %6 %99 %72\n%101 = OpCompositeExtract %5 %100 0\nOpReturnValue %101\nOpFunctionEnd\n%120 = OpFunction %104 None %113\n%114 = OpFunctionParameter %6\n%115 = OpFunctionParameter %5\n%116 = OpFunctionParameter %5\n%117 = OpFunctionParameter %5\n%118 = OpFunctionParameter %5\n%119 = OpFunctionParameter %104\n%121 = OpLabel\nOpSelectionMerge %123 None\nOpBranchConditional %119 %123 %122\n%122 = OpLabel\nOpReturnValue %124\n%123 = OpLabel\n%126 = OpCompositeExtract %5 %114 0\n%127 = OpCompositeExtract %5 %114 1\n%129 = OpIAddCarry %128 %126 %115\n%130 = OpCompositeExtract %5 %129 0\n%131 = OpCompositeExtract %5 %129 1\n%132 = OpIAdd %5 %127 %131\n%133 = OpCompositeConstruct %6 %130 %132\n%134 = OpCompositeExtract %5 %133 0\n%135 = OpBitFieldUExtract %5 %139 %30 %116\n%136 = OpBitwiseAnd %5 %134 %140\n%137 = OpShiftLeftLogical %5 %135 %136\n%138 = OpBitwiseAnd %5 %137 %74\n%141 = OpBitwiseAnd %5 %134 %48\n%142 = OpIAdd %5 %141 %116\n%143 = OpIAdd %5 %142 %48\n%144 = OpShiftRightLogical %5 %143 %37\n%145 = OpBitFieldUExtract %5 %134 %37 %37\n%146 = OpBitFieldUExtract %5 %139 %30 %144\n%147 = OpShiftLeftLogical %5 %146 %145\n%148 = OpBitwiseAnd %5 %147 %140\n%149 = OpArrayLength %5 %108 0\n%150 = OpExtInst %5 %152 FindUMsb %149\n%151 = OpBitFieldUExtract %5 %139 %30 %150\n%153 = OpArrayLength %5 %108 0\n%154 = OpExtInst %5 %152 FindUMsb %153\n%155 = OpBitFieldUExtract %5 %153 %30 %154\n%156 = OpISub %5 %155 %10\n%157 = OpFunctionCall %5 %65 %133 %158\n%159 = OpBitwiseAnd %5 %157 %151\n%160 = OpIAdd %5 %159 %156\n%161 = OpFunctionCall %5 %65 %133 %162\n%163 = OpBitwiseAnd %5 %161 %151\n%164 = OpIAdd %5 %163 %156\n%165 = OpFunctionCall %5 %65 %133 %166\n%167 = OpBitwiseAnd %5 %165 %151\n%168 = OpIAdd %5 %167 %156\n%169 = OpFunctionCall %5 %65 %133 %32\n%170 = OpBitwiseAnd %5 %169 %151\n%171 = OpIAdd %5 %170 %156\n%172 = OpFunctionCall %5 %65 %133 %173\n%174 = OpBitwiseAnd %5 %172 %151\n%175 = OpIAdd %5 %174 %156\n%176 = OpFunctionCall %5 %65 %133 %177\n%178 = OpBitwiseAnd %5 %176 %151\n%179 = OpIAdd %5 %178 %156\n%180 = OpFunctionCall %5 %65 %133 %181\n%182 = OpBitwiseAnd %5 %180 %151\n%183 = OpIAdd %5 %182 %156\n%184 = OpFunctionCall %5 %65 %133 %185\n%186 = OpBitwiseAnd %5 %184 %151\n%187 = OpIAdd %5 %186 %156\n%188 = OpFunctionCall %5 %65 %133 %189\n%190 = OpBitwiseAnd %5 %188 %151\n%191 = OpIAdd %5 %190 %156\n%192 = OpFunctionCall %5 %65 %133 %193\n%194 = OpBitwiseAnd %5 %192 %151\n%195 = OpIAdd %5 %194 %156\n%196 = OpFunctionCall %5 %65 %133 %197\n%198 = OpBitwiseAnd %5 %196 %151\n%199 = OpIAdd %5 %198 %156\n%200 = OpFunctionCall %5 %65 %133 %201\n%202 = OpBitwiseAnd %5 %200 %151\n%203 = OpIAdd %5 %202 %156\n%204 = OpFunctionCall %5 %65 %133 %205\n%206 = OpBitwiseAnd %5 %204 %151\n%207 = OpIAdd %5 %206 %156\n%208 = OpFunctionCall %5 %65 %133 %209\n%210 = OpBitwiseAnd %5 %208 %151\n%211 = OpIAdd %5 %210 %156\n%212 = OpFunctionCall %5 %65 %133 %213\n%214 = OpBitwiseAnd %5 %212 %151\n%215 = OpIAdd %5 %214 %156\n%216 = OpFunctionCall %5 %65 %133 %217\n%218 = OpBitwiseAnd %5 %216 %151\n%219 = OpIAdd %5 %218 %156\n%225 = OpVectorExtractDynamic %103 %224 %117\n%226 = OpShiftLeftLogical %5 %138 %228\n%227 = OpShiftLeftLogical %5 %148 %73\n%229 = OpBitwiseOr %5 %138 %226\n%230 = OpBitwiseOr %5 %148 %227\n%231 = OpCompositeConstruct %6 %229 %230\n%232 = OpBitcast %103 %231\n%233 = OpBitwiseAnd %103 %225 %232\n%235 = OpInBoundsAccessChain %234 %108 %30 %160\n%236 = OpAtomicOr %103 %235 %10 %30 %233\n%237 = OpInBoundsAccessChain %234 %108 %30 %164\n%238 = OpAtomicOr %103 %237 %10 %30 %233\n%239 = OpBitwiseAnd %103 %236 %238\n%240 = OpInBoundsAccessChain %234 %108 %30 %168\n%241 = OpAtomicOr %103 %240 %10 %30 %233\n%242 = OpBitwiseAnd %103 %239 %241\n%243 = OpInBoundsAccessChain %234 %108 %30 %171\n%244 = OpAtomicOr %103 %243 %10 %30 %233\n%245 = OpBitwiseAnd %103 %242 %244\n%246 = OpInBoundsAccessChain %234 %108 %30 %175\n%247 = OpAtomicOr %103 %246 %10 %30 %233\n%248 = OpBitwiseAnd %103 %245 %247\n%249 = OpInBoundsAccessChain %234 %108 %30 %179\n%250 = OpAtomicOr %103 %249 %10 %30 %233\n%251 = OpBitwiseAnd %103 %248 %250\n%252 = OpInBoundsAccessChain %234 %108 %30 %183\n%253 = OpAtomicOr %103 %252 %10 %30 %233\n%254 = OpBitwiseAnd %103 %251 %253\n%255 = OpInBoundsAccessChain %234 %108 %30 %187\n%256 = OpAtomicOr %103 %255 %10 %30 %233\n%257 = OpBitwiseAnd %103 %254 %256\n%258 = OpInBoundsAccessChain %234 %108 %30 %191\n%259 = OpAtomicOr %103 %258 %10 %30 %233\n%260 = OpBitwiseAnd %103 %257 %259\n%261 = OpInBoundsAccessChain %234 %108 %30 %195\n%262 = OpAtomicOr %103 %261 %10 %30 %233\n%263 = OpBitwiseAnd %103 %260 %262\n%264 = OpInBoundsAccessChain %234 %108 %30 %199\n%265 = OpAtomicOr %103 %264 %10 %30 %233\n%266 = OpBitwiseAnd %103 %263 %265\n%267 = OpInBoundsAccessChain %234 %108 %30 %203\n%268 = OpAtomicOr %103 %267 %10 %30 %233\n%269 = OpBitwiseAnd %103 %266 %268\n%270 = OpInBoundsAccessChain %234 %108 %30 %207\n%271 = OpAtomicOr %103 %270 %10 %30 %233\n%272 = OpBitwiseAnd %103 %269 %271\n%273 = OpInBoundsAccessChain %234 %108 %30 %211\n%274 = OpAtomicOr %103 %273 %10 %30 %233\n%275 = OpBitwiseAnd %103 %272 %274\n%276 = OpInBoundsAccessChain %234 %108 %30 %215\n%277 = OpAtomicOr %103 %276 %10 %30 %233\n%278 = OpBitwiseAnd %103 %275 %277\n%279 = OpInBoundsAccessChain %234 %108 %30 %219\n%280 = OpAtomicOr %103 %279 %10 %30 %233\n%281 = OpBitwiseAnd %103 %278 %280\n%282 = OpBitcast %6 %281\n%283 = OpCompositeExtract %5 %282 0\n%284 = OpCompositeExtract %5 %282 1\n%285 = OpShiftRightLogical %5 %283 %228\n%286 = OpBitwiseAnd %5 %285 %138\n%287 = OpIEqual %104 %286 %30\n%288 = OpBitFieldUExtract %5 %118 %290 %291\n%292 = OpShiftLeftLogical %5 %293 %288\n%294 = OpBitFieldUExtract %5 %118 %291 %291\n%295 = OpShiftLeftLogical %5 %296 %294\n%297 = OpBitwiseOr %5 %292 %295\n%298 = OpBitFieldUExtract %5 %118 %299 %291\n%300 = OpShiftLeftLogical %5 %301 %298\n%302 = OpBitwiseOr %5 %297 %300\n%303 = OpSelect %5 %287 %302 %30\n%304 = OpInBoundsAccessChain %28 %112 %30 %160 %10\n%305 = OpAtomicOr %5 %304 %10 %30 %303\n%306 = OpBitwiseAnd %5 %305 %302\n%307 = OpIEqual %104 %306 %302\n%308 = OpBitFieldUExtract %5 %118 %309 %291\n%310 = OpShiftLeftLogical %5 %293 %308\n%311 = OpBitFieldUExtract %5 %118 %312 %291\n%313 = OpShiftLeftLogical %5 %296 %311\n%314 = OpBitwiseOr %5 %310 %313\n%315 = OpBitFieldUExtract %5 %118 %316 %291\n%317 = OpShiftLeftLogical %5 %301 %315\n%318 = OpBitwiseOr %5 %314 %317\n%319 = OpSelect %5 %287 %318 %30\n%320 = OpInBoundsAccessChain %28 %112 %30 %164 %10\n%321 = OpAtomicOr %5 %320 %10 %30 %319\n%322 = OpBitwiseAnd %5 %321 %318\n%323 = OpIEqual %104 %322 %318\n%324 = OpLogicalAnd %104 %307 %323\n%325 = OpBitFieldUExtract %5 %118 %326 %291\n%327 = OpShiftLeftLogical %5 %293 %325\n%328 = OpBitFieldUExtract %5 %118 %329 %291\n%330 = OpShiftLeftLogical %5 %296 %328\n%331 = OpBitwiseOr %5 %327 %330\n%332 = OpBitFieldUExtract %5 %118 %333 %291\n%334 = OpShiftLeftLogical %5 %301 %332\n%335 = OpBitwiseOr %5 %331 %334\n%336 = OpSelect %5 %287 %335 %30\n%337 = OpInBoundsAccessChain %28 %112 %30 %168 %10\n%338 = OpAtomicOr %5 %337 %10 %30 %336\n%339 = OpBitwiseAnd %5 %338 %335\n%340 = OpIEqual %104 %339 %335\n%341 = OpLogicalAnd %104 %324 %340\n%342 = OpBitFieldUExtract %5 %118 %343 %291\n%344 = OpShiftLeftLogical %5 %293 %342\n%345 = OpBitFieldUExtract %5 %118 %346 %291\n%347 = OpShiftLeftLogical %5 %296 %345\n%348 = OpBitwiseOr %5 %344 %347\n%349 = OpBitFieldUExtract %5 %118 %350 %291\n%351 = OpShiftLeftLogical %5 %301 %349\n%352 = OpBitwiseOr %5 %348 %351\n%353 = OpSelect %5 %287 %352 %30\n%354 = OpInBoundsAccessChain %28 %112 %30 %171 %10\n%355 = OpAtomicOr %5 %354 %10 %30 %353\n%356 = OpBitwiseAnd %5 %355 %352\n%357 = OpIEqual %104 %356 %352\n%358 = OpLogicalAnd %104 %341 %357\n%359 = OpBitFieldUExtract %5 %118 %360 %291\n%361 = OpShiftLeftLogical %5 %293 %359\n%362 = OpBitFieldUExtract %5 %118 %363 %291\n%364 = OpShiftLeftLogical %5 %296 %362\n%365 = OpBitwiseOr %5 %361 %364\n%366 = OpBitFieldUExtract %5 %118 %367 %291\n%368 = OpShiftLeftLogical %5 %301 %366\n%369 = OpBitwiseOr %5 %365 %368\n%370 = OpSelect %5 %287 %369 %30\n%371 = OpInBoundsAccessChain %28 %112 %30 %175 %10\n%372 = OpAtomicOr %5 %371 %10 %30 %370\n%373 = OpBitwiseAnd %5 %372 %369\n%374 = OpIEqual %104 %373 %369\n%375 = OpLogicalAnd %104 %358 %374\n%376 = OpBitFieldUExtract %5 %118 %309 %291\n%377 = OpShiftLeftLogical %5 %293 %376\n%378 = OpBitFieldUExtract %5 %118 %312 %291\n%379 = OpShiftLeftLogical %5 %296 %378\n%380 = OpBitwiseOr %5 %377 %379\n%381 = OpBitFieldUExtract %5 %118 %316 %291\n%382 = OpShiftLeftLogical %5 %301 %381\n%383 = OpBitwiseOr %5 %380 %382\n%384 = OpSelect %5 %287 %383 %30\n%385 = OpInBoundsAccessChain %28 %112 %30 %179 %10\n%386 = OpAtomicOr %5 %385 %10 %30 %384\n%387 = OpBitwiseAnd %5 %386 %383\n%388 = OpIEqual %104 %387 %383\n%389 = OpLogicalAnd %104 %375 %388\n%390 = OpBitFieldUExtract %5 %118 %391 %291\n%392 = OpShiftLeftLogical %5 %293 %390\n%393 = OpBitFieldUExtract %5 %118 %394 %291\n%395 = OpShiftLeftLogical %5 %296 %393\n%396 = OpBitwiseOr %5 %392 %395\n%397 = OpBitFieldUExtract %5 %118 %343 %291\n%398 = OpShiftLeftLogical %5 %301 %397\n%399 = OpBitwiseOr %5 %396 %398\n%400 = OpSelect %5 %287 %399 %30\n%401 = OpInBoundsAccessChain %28 %112 %30 %183 %10\n%402 = OpAtomicOr %5 %401 %10 %30 %400\n%403 = OpBitwiseAnd %5 %402 %399\n%404 = OpIEqual %104 %403 %399\n%405 = OpLogicalAnd %104 %389 %404\n%406 = OpBitFieldUExtract %5 %118 %407 %291\n%408 = OpShiftLeftLogical %5 %293 %406\n%409 = OpBitFieldUExtract %5 %118 %410 %291\n%411 = OpShiftLeftLogical %5 %296 %409\n%412 = OpBitwiseOr %5 %408 %411\n%413 = OpBitFieldUExtract %5 %118 %414 %291\n%415 = OpShiftLeftLogical %5 %301 %413\n%416 = OpBitwiseOr %5 %412 %415\n%417 = OpSelect %5 %287 %416 %30\n%418 = OpInBoundsAccessChain %28 %112 %30 %187 %10\n%419 = OpAtomicOr %5 %418 %10 %30 %417\n%420 = OpBitwiseAnd %5 %419 %416\n%421 = OpIEqual %104 %420 %416\n%422 = OpLogicalAnd %104 %405 %421\nOpSelectionMerge %427 None\nOpSwitch %117 %426 0 %423 1 %424 2 %425\n%426 = OpLabel\n%435 = OpShiftLeftLogical %5 %148 %73\n%436 = OpBitwiseAnd %5 %284 %435\n%437 = OpINotEqual %104 %436 %30\nOpBranch %427\n%423 = OpLabel\n%428 = OpBitwiseAnd %5 %283 %138\n%429 = OpINotEqual %104 %428 %30\nOpBranch %427\n%424 = OpLabel\n%430 = OpShiftLeftLogical %5 %138 %228\n%431 = OpBitwiseAnd %5 %283 %430\n%432 = OpINotEqual %104 %431 %30\nOpBranch %427\n%425 = OpLabel\n%433 = OpBitwiseAnd %5 %284 %148\n%434 = OpINotEqual %104 %433 %30\nOpBranch %427\n%427 = OpLabel\n%438 = OpPhi %104 %429 %423 %432 %424 %434 %425 %437 %426\n%439 = OpLogicalNot %104 %438\n%440 = OpLogicalOr %104 %439 %422\nOpReturnValue %440\nOpFunctionEnd\n%484 = OpFunction %1 None %481\n%482 = OpFunctionParameter %104\n%483 = OpFunctionParameter %5\n%485 = OpLabel\n%488 = OpLogicalNot %104 %482\n%489 = OpLoad %104 %471\n%490 = OpLogicalAnd %104 %488 %489\nOpSelectionMerge %486 None\nOpBranchConditional %490 %487 %486\n%487 = OpLabel\n%493 = OpIMul %5 %483 %495\n%494 = OpBitwiseXor %5 %493 %496\n%497 = OpArrayLength %5 %476 0\n%498 = OpISub %5 %497 %37\n%499 = OpAccessChain %28 %476 %30 %498\n%500 = OpLoad %5 %499\n%501 = OpIMul %5 %500 %502\n%503 = OpBitwiseXor %5 %494 %501\n%504 = OpArrayLength %5 %480 0\n%505 = OpISub %5 %504 %10\n%506 = OpBitwiseAnd %5 %503 %505\n%507 = OpShiftRightLogical %5 %506 %73\n%508 = OpBitwiseAnd %5 %506 %140\n%509 = OpShiftLeftLogical %5 %10 %508\n%510 = OpAccessChain %28 %476 %30 %507\n%511 = OpAtomicOr %5 %510 %10 %30 %509\n%512 = OpBitwiseAnd %5 %511 %509\n%513 = OpIEqual %104 %512 %30\nOpStore %471 %514\nOpSelectionMerge %492 None\nOpBranchConditional %513 %491 %492\n%491 = OpLabel\n%515 = OpCompositeConstruct %472 %496 %30 %483 %500\n%516 = OpShiftLeftLogical %5 %509 %228\n%518 = OpAccessChain %517 %480 %30 %506\nOpStore %518 %515\nOpMemoryBarrier %10 %520\n%519 = OpAtomicOr %5 %510 %10 %30 %516\nOpMemoryBarrier %10 %520\nOpBranch %492\n%492 = OpLabel\nOpBranch %486\n%486 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/structured.bindless.bda-instrumentation.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nuint _465;\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 1, binding = 0) uniform usamplerBuffer _22[];\nlayout(set = 4, binding = 0, r32ui) uniform uimageBuffer _26[];\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _39 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _39;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _87 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _88 = uvec2(prime);\n    uvec2 _95 = ((_87 >> uvec2(8u)) ^ _87.yx) * _88;\n    uvec2 _99 = ((_95 >> uvec2(8u)) ^ _95.yx) * _88;\n    uvec2 _103 = ((_99 >> uvec2(8u)) ^ _99.yx) * _88;\n    uvec2 _107 = ((_103 >> uvec2(8u)) ^ _103.yx) * _88;\n    uvec2 _111 = ((_107 >> uvec2(8u)) ^ _107.yx) * _88;\n    return (((_111 >> uvec2(8u)) ^ _111.yx) * _88).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _144;\n    _144._m0 = uaddCarry(BDA.x, offset, _144._m1);\n    uvec2 addr = uvec2(_144._m0, BDA.y + _144._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _522 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _524 = InstrumentationControlData.atomics[_522];\n        uint _530 = (((inst * 97u) ^ 43981u) ^ (_524 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _531 = _530 >> 4u;\n        uint _533 = 1u << (_530 & 15u);\n        uint _535 = atomicOr(InstrumentationControlData.atomics[_531], _533);\n        ShouldReportInstrumentation = false;\n        if ((_535 & _533) == 0u)\n        {\n            InstrumentationData.data[_530] = uvec4(43981u, 0u, inst, _524);\n            memoryBarrierBuffer();\n            uint _543 = atomicOr(InstrumentationControlData.atomics[_531], _533 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _42 = AllocateInvocationID();\n    InvocationID = _42;\n    uvec2 _51 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _57 = uint(imageSize(_26[registers._m4])) * 4u;\n    uvec2 _63 = DescriptorHeapRobustness.descriptors[registers._m1]._m0[0u];\n    uint _77 = (gl_GlobalInvocationID.x * 12u) + 0u;\n    uint _459 = InvocationID;\n    bool _458 = ValidateBDALoadStore(_63, _77, 12u, 0u, _459, _77 < (uint(textureSize(_22[registers._m1])) * 4u));\n    AssumeTrue(_458, 1u);\n    uint _461 = gl_GlobalInvocationID.x * 3u;\n    vec3 _472 = uintBitsToFloat(uvec3(texelFetch(_22[registers._m1], int(_461)).x, _465, texelFetch(_22[registers._m1], int(_461 + 2u)).x));\n    uint _479 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _481 = InvocationID;\n    bool _480 = ValidateBDALoadStore(_51, _479, 4u, 0u, _481, _479 < _57);\n    AssumeTrue(_480, 2u);\n    uvec4 _483 = imageLoad(_26[registers._m4], int(gl_GlobalInvocationID.x));\n    uint _488 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _490 = InvocationID;\n    bool _489 = ValidateBDALoadStore(_51, _488, 4u, 1u, _490, _488 < _57);\n    AssumeTrue(_489, 3u);\n    imageStore(_26[registers._m4], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(((_472.x + 40.0) + _472.z) + uintBitsToFloat(_483.x))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 550\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%169 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %71\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %28 \"BloomBufferInvocationSSBO\"\nOpMemberName %28 0 \"atomics\"\nOpName %30 \"BloomBufferInvocation\"\nOpName %32 \"AllocateInvocationID\"\nOpName %81 \"AddrHash\"\nOpName %79 \"addr\"\nOpName %80 \"prime\"\nOpName %121 \"BloomBufferSSBO\"\nOpMemberName %121 0 \"atomics\"\nOpName %123 \"BloomBuffer\"\nOpName %125 \"BloomBuffer32SSBO\"\nOpMemberName %125 0 \"atomics\"\nOpName %127 \"BloomBuffer32\"\nOpName %135 \"ValidateBDALoadStore\"\nOpName %129 \"BDA\"\nOpName %130 \"offset\"\nOpName %131 \"len\"\nOpName %132 \"type\"\nOpName %133 \"invocation_id\"\nOpName %134 \"in_bounds\"\nOpName %143 \"IAddCarryResult\"\nOpName %148 \"addr\"\nOpName %149 \"addr_lo\"\nOpName %153 \"byte_mask\"\nOpName %163 \"word_mask\"\nOpName %168 \"hash_mask\"\nOpName %173 \"hash_offset\"\nOpName %177 \"bloom_index\"\nOpName %181 \"bloom_index\"\nOpName %185 \"bloom_index\"\nOpName %188 \"bloom_index\"\nOpName %192 \"bloom_index\"\nOpName %196 \"bloom_index\"\nOpName %200 \"bloom_index\"\nOpName %204 \"bloom_index\"\nOpName %208 \"bloom_index\"\nOpName %212 \"bloom_index\"\nOpName %216 \"bloom_index\"\nOpName %220 \"bloom_index\"\nOpName %224 \"bloom_index\"\nOpName %228 \"bloom_index\"\nOpName %232 \"bloom_index\"\nOpName %236 \"bloom_index\"\nOpName %249 \"invalidation_mask\"\nOpName %252 \"prev_hazard_partial\"\nOpName %254 \"prev_hazard_partial\"\nOpName %257 \"prev_hazard_partial\"\nOpName %260 \"prev_hazard_partial\"\nOpName %263 \"prev_hazard_partial\"\nOpName %266 \"prev_hazard_partial\"\nOpName %269 \"prev_hazard_partial\"\nOpName %272 \"prev_hazard_partial\"\nOpName %275 \"prev_hazard_partial\"\nOpName %278 \"prev_hazard_partial\"\nOpName %281 \"prev_hazard_partial\"\nOpName %284 \"prev_hazard_partial\"\nOpName %287 \"prev_hazard_partial\"\nOpName %290 \"prev_hazard_partial\"\nOpName %293 \"prev_hazard_partial\"\nOpName %296 \"prev_hazard_partial\"\nOpName %298 \"prev_hazard\"\nOpName %299 \"prev_hazard_lo\"\nOpName %300 \"prev_hazard_hi\"\nOpName %303 \"has_exclusive_access\"\nOpName %318 \"lock_mask\"\nOpName %321 \"prev_lock\"\nOpName %334 \"lock_mask\"\nOpName %337 \"prev_lock\"\nOpName %351 \"lock_mask\"\nOpName %354 \"prev_lock\"\nOpName %368 \"lock_mask\"\nOpName %371 \"prev_lock\"\nOpName %385 \"lock_mask\"\nOpName %388 \"prev_lock\"\nOpName %399 \"lock_mask\"\nOpName %402 \"prev_lock\"\nOpName %415 \"lock_mask\"\nOpName %418 \"prev_lock\"\nOpName %432 \"lock_mask\"\nOpName %435 \"prev_lock\"\nOpName %438 \"has_complete_self_lock\"\nOpName %454 \"hazard\"\nOpName %496 \"ShouldReportInstrumentation\"\nOpName %498 \"InstrumentationControlDataSSBO\"\nOpMemberName %498 0 \"atomics\"\nOpName %500 \"InstrumentationControlData\"\nOpName %502 \"InstrumentationDataSSBO\"\nOpMemberName %502 0 \"data\"\nOpName %504 \"InstrumentationData\"\nOpName %508 \"AssumeTrue\"\nOpName %506 \"value\"\nOpName %507 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %22 DescriptorSet 1\nOpDecorate %22 Binding 0\nOpDecorate %26 DescriptorSet 4\nOpDecorate %26 Binding 0\nOpDecorate %27 ArrayStride 4\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 2\nOpDecorate %71 BuiltIn GlobalInvocationId\nOpDecorate %120 ArrayStride 8\nOpMemberDecorate %121 0 Offset 0\nOpDecorate %121 Block\nOpDecorate %123 DescriptorSet 0\nOpDecorate %123 Binding 2\nOpDecorate %124 ArrayStride 8\nOpMemberDecorate %125 0 Offset 0\nOpDecorate %125 Block\nOpDecorate %127 DescriptorSet 0\nOpDecorate %127 Binding 2\nOpDecorate %497 ArrayStride 4\nOpMemberDecorate %498 0 Offset 0\nOpDecorate %498 Block\nOpDecorate %500 DescriptorSet 0\nOpDecorate %500 Binding 2\nOpDecorate %501 ArrayStride 16\nOpMemberDecorate %502 0 Offset 0\nOpDecorate %502 Block\nOpDecorate %504 DescriptorSet 0\nOpDecorate %504 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeRuntimeArray %5\n%28 = OpTypeStruct %27\n%29 = OpTypePointer StorageBuffer %28\n%30 = OpVariable %29 StorageBuffer\n%31 = OpTypeFunction %5\n%36 = OpTypePointer StorageBuffer %5\n%38 = OpConstant %5 0\n%40 = OpConstant %5 1103633207\n%43 = OpTypePointer UniformConstant %23\n%45 = OpTypePointer PushConstant %5\n%47 = OpConstant %5 4\n%49 = OpTypePointer StorageBuffer %9\n%54 = OpConstant %5 16\n%58 = OpTypePointer UniformConstant %19\n%69 = OpTypeVector %5 3\n%70 = OpTypePointer Input %69\n%71 = OpVariable %70 Input\n%72 = OpTypePointer Input %5\n%75 = OpConstant %5 12\n%78 = OpTypeFunction %5 %9 %5\n%89 = OpConstant %5 65535\n%90 = OpConstant %5 8\n%91 = OpConstantComposite %9 %90 %90\n%118 = OpTypeInt 64 0\n%119 = OpTypeBool\n%120 = OpTypeRuntimeArray %118\n%121 = OpTypeStruct %120\n%122 = OpTypePointer StorageBuffer %121\n%123 = OpVariable %122 StorageBuffer\n%124 = OpTypeRuntimeArray %9\n%125 = OpTypeStruct %124\n%126 = OpTypePointer StorageBuffer %125\n%127 = OpVariable %126 StorageBuffer\n%128 = OpTypeFunction %119 %9 %5 %5 %5 %5 %119\n%139 = OpConstantTrue %119\n%143 = OpTypeStruct %5 %5\n%154 = OpConstant %5 4294967295\n%155 = OpConstant %5 15\n%164 = OpConstant %5 3\n%165 = OpConstant %5 2\n%175 = OpConstant %5 1103515245\n%179 = OpConstant %5 1103518333\n%183 = OpConstant %5 1103539331\n%190 = OpConstant %5 10006121\n%194 = OpConstant %5 4004951\n%198 = OpConstant %5 5005159\n%202 = OpConstant %5 6004811\n%206 = OpConstant %5 383\n%210 = OpConstant %5 821\n%214 = OpConstant %5 661\n%218 = OpConstant %5 1091\n%222 = OpConstant %5 1117\n%226 = OpConstant %5 3947\n%230 = OpConstant %5 4253\n%234 = OpConstant %5 7691\n%237 = OpTypeVector %118 4\n%238 = OpConstant %118 68719411200\n%239 = OpConstant %118 1099511627775\n%240 = OpConstant %118 1035087118335\n%241 = OpConstantComposite %237 %238 %239 %240 %238\n%250 = OpTypePointer StorageBuffer %118\n%305 = OpTypeInt 32 1\n%306 = OpConstant %305 0\n%307 = OpConstant %305 3\n%309 = OpConstant %5 256\n%312 = OpConstant %5 65536\n%315 = OpConstant %305 6\n%317 = OpConstant %5 16777216\n%325 = OpConstant %305 9\n%328 = OpConstant %305 12\n%332 = OpConstant %305 15\n%342 = OpConstant %305 18\n%345 = OpConstant %305 21\n%349 = OpConstant %305 24\n%359 = OpConstant %305 23\n%362 = OpConstant %305 26\n%366 = OpConstant %305 29\n%376 = OpConstant %305 1\n%379 = OpConstant %305 4\n%383 = OpConstant %305 7\n%407 = OpConstant %305 17\n%410 = OpConstant %305 20\n%423 = OpConstant %305 22\n%426 = OpConstant %305 25\n%430 = OpConstant %305 28\n%462 = OpTypeVector %5 4\n%470 = OpTypeFloat 32\n%471 = OpTypeVector %470 3\n%476 = OpConstant %470 40\n%495 = OpTypePointer Private %119\n%496 = OpVariable %495 Private %139\n%497 = OpTypeRuntimeArray %5\n%498 = OpTypeStruct %497\n%499 = OpTypePointer StorageBuffer %498\n%500 = OpVariable %499 StorageBuffer\n%501 = OpTypeRuntimeArray %462\n%502 = OpTypeStruct %501\n%503 = OpTypePointer StorageBuffer %502\n%504 = OpVariable %503 StorageBuffer\n%505 = OpTypeFunction %1 %119 %5\n%519 = OpConstant %5 97\n%520 = OpConstant %5 43981\n%526 = OpConstant %5 51329\n%538 = OpConstantFalse %119\n%541 = OpTypePointer StorageBuffer %462\n%544 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%465 = OpUndef %5\nOpBranch %494\n%494 = OpLabel\n%42 = OpFunctionCall %5 %32\nOpStore %18 %42\n%46 = OpAccessChain %45 %8 %47\n%48 = OpLoad %5 %46\n%50 = OpAccessChain %49 %16 %38 %48 %38 %38\n%51 = OpLoad %9 %50\n%52 = OpCompositeExtract %5 %51 1\n%53 = OpShiftRightLogical %5 %52 %54\n%44 = OpAccessChain %43 %26 %48\n%55 = OpLoad %23 %44\n%56 = OpImageQuerySize %5 %55\n%57 = OpIMul %5 %56 %47\n%60 = OpAccessChain %45 %8 %10\n%61 = OpLoad %5 %60\n%62 = OpAccessChain %49 %16 %38 %61 %38 %38\n%63 = OpLoad %9 %62\n%64 = OpCompositeExtract %5 %63 1\n%65 = OpShiftRightLogical %5 %64 %54\n%59 = OpAccessChain %58 %22 %61\n%66 = OpLoad %19 %59\n%67 = OpImageQuerySize %5 %66\n%68 = OpIMul %5 %67 %47\n%73 = OpAccessChain %72 %71 %38\n%74 = OpLoad %5 %73\n%76 = OpIMul %5 %74 %75\n%77 = OpIAdd %5 %76 %38\n%459 = OpLoad %5 %18\n%460 = OpULessThan %119 %77 %68\n%458 = OpFunctionCall %119 %135 %63 %77 %75 %38 %459 %460\n%546 = OpFunctionCall %1 %508 %458 %10\n%461 = OpIMul %5 %74 %164\n%463 = OpImageFetch %462 %66 %461\n%464 = OpCompositeExtract %5 %463 0\n%467 = OpIAdd %5 %461 %165\n%466 = OpImageFetch %462 %66 %467\n%468 = OpCompositeExtract %5 %466 0\n%469 = OpCompositeConstruct %69 %464 %465 %468\n%472 = OpBitcast %471 %469\n%473 = OpCompositeExtract %470 %472 0\n%474 = OpCompositeExtract %470 %472 2\n%475 = OpFAdd %470 %473 %476\n%477 = OpFAdd %470 %475 %474\n%478 = OpIMul %5 %74 %47\n%479 = OpIAdd %5 %478 %38\n%481 = OpLoad %5 %18\n%482 = OpULessThan %119 %479 %57\n%480 = OpFunctionCall %119 %135 %51 %479 %47 %38 %481 %482\n%547 = OpFunctionCall %1 %508 %480 %165\n%483 = OpImageRead %462 %55 %74\n%484 = OpCompositeExtract %5 %483 0\n%485 = OpBitcast %470 %484\n%486 = OpFAdd %470 %477 %485\n%487 = OpIMul %5 %74 %47\n%488 = OpIAdd %5 %487 %38\n%490 = OpLoad %5 %18\n%491 = OpULessThan %119 %488 %57\n%489 = OpFunctionCall %119 %135 %51 %488 %47 %10 %490 %491\n%548 = OpFunctionCall %1 %508 %489 %164\n%492 = OpBitcast %5 %486\n%493 = OpCompositeConstruct %462 %492 %492 %492 %492\nOpImageWrite %55 %74 %493\nOpReturn\nOpFunctionEnd\n%32 = OpFunction %5 None %31\n%33 = OpLabel\n%34 = OpArrayLength %5 %30 0\n%35 = OpISub %5 %34 %10\n%37 = OpAccessChain %36 %30 %38 %35\n%39 = OpAtomicIAdd %5 %37 %10 %38 %40\nOpReturnValue %39\nOpFunctionEnd\n%81 = OpFunction %5 None %78\n%79 = OpFunctionParameter %9\n%80 = OpFunctionParameter %5\n%82 = OpLabel\n%83 = OpCompositeExtract %5 %79 0\n%84 = OpCompositeExtract %5 %79 1\n%85 = OpShiftRightLogical %5 %83 %47\n%86 = OpBitwiseAnd %5 %84 %89\n%87 = OpCompositeConstruct %9 %85 %86\n%88 = OpCompositeConstruct %9 %80 %80\n%92 = OpVectorShuffle %9 %87 %87 1 0\n%93 = OpShiftRightLogical %9 %87 %91\n%94 = OpBitwiseXor %9 %93 %92\n%95 = OpIMul %9 %94 %88\n%96 = OpVectorShuffle %9 %95 %95 1 0\n%97 = OpShiftRightLogical %9 %95 %91\n%98 = OpBitwiseXor %9 %97 %96\n%99 = OpIMul %9 %98 %88\n%100 = OpVectorShuffle %9 %99 %99 1 0\n%101 = OpShiftRightLogical %9 %99 %91\n%102 = OpBitwiseXor %9 %101 %100\n%103 = OpIMul %9 %102 %88\n%104 = OpVectorShuffle %9 %103 %103 1 0\n%105 = OpShiftRightLogical %9 %103 %91\n%106 = OpBitwiseXor %9 %105 %104\n%107 = OpIMul %9 %106 %88\n%108 = OpVectorShuffle %9 %107 %107 1 0\n%109 = OpShiftRightLogical %9 %107 %91\n%110 = OpBitwiseXor %9 %109 %108\n%111 = OpIMul %9 %110 %88\n%112 = OpVectorShuffle %9 %111 %111 1 0\n%113 = OpShiftRightLogical %9 %111 %91\n%114 = OpBitwiseXor %9 %113 %112\n%115 = OpIMul %9 %114 %88\n%116 = OpCompositeExtract %5 %115 0\nOpReturnValue %116\nOpFunctionEnd\n%135 = OpFunction %119 None %128\n%129 = OpFunctionParameter %9\n%130 = OpFunctionParameter %5\n%131 = OpFunctionParameter %5\n%132 = OpFunctionParameter %5\n%133 = OpFunctionParameter %5\n%134 = OpFunctionParameter %119\n%136 = OpLabel\nOpSelectionMerge %138 None\nOpBranchConditional %134 %138 %137\n%137 = OpLabel\nOpReturnValue %139\n%138 = OpLabel\n%141 = OpCompositeExtract %5 %129 0\n%142 = OpCompositeExtract %5 %129 1\n%144 = OpIAddCarry %143 %141 %130\n%145 = OpCompositeExtract %5 %144 0\n%146 = OpCompositeExtract %5 %144 1\n%147 = OpIAdd %5 %142 %146\n%148 = OpCompositeConstruct %9 %145 %147\n%149 = OpCompositeExtract %5 %148 0\n%150 = OpBitFieldUExtract %5 %154 %38 %131\n%151 = OpBitwiseAnd %5 %149 %155\n%152 = OpShiftLeftLogical %5 %150 %151\n%153 = OpBitwiseAnd %5 %152 %89\n%156 = OpBitwiseAnd %5 %149 %164\n%157 = OpIAdd %5 %156 %131\n%158 = OpIAdd %5 %157 %164\n%159 = OpShiftRightLogical %5 %158 %165\n%160 = OpBitFieldUExtract %5 %149 %165 %165\n%161 = OpBitFieldUExtract %5 %154 %38 %159\n%162 = OpShiftLeftLogical %5 %161 %160\n%163 = OpBitwiseAnd %5 %162 %155\n%166 = OpArrayLength %5 %123 0\n%167 = OpExtInst %5 %169 FindUMsb %166\n%168 = OpBitFieldUExtract %5 %154 %38 %167\n%170 = OpArrayLength %5 %123 0\n%171 = OpExtInst %5 %169 FindUMsb %170\n%172 = OpBitFieldUExtract %5 %170 %38 %171\n%173 = OpISub %5 %172 %10\n%174 = OpFunctionCall %5 %81 %148 %175\n%176 = OpBitwiseAnd %5 %174 %168\n%177 = OpIAdd %5 %176 %173\n%178 = OpFunctionCall %5 %81 %148 %179\n%180 = OpBitwiseAnd %5 %178 %168\n%181 = OpIAdd %5 %180 %173\n%182 = OpFunctionCall %5 %81 %148 %183\n%184 = OpBitwiseAnd %5 %182 %168\n%185 = OpIAdd %5 %184 %173\n%186 = OpFunctionCall %5 %81 %148 %40\n%187 = OpBitwiseAnd %5 %186 %168\n%188 = OpIAdd %5 %187 %173\n%189 = OpFunctionCall %5 %81 %148 %190\n%191 = OpBitwiseAnd %5 %189 %168\n%192 = OpIAdd %5 %191 %173\n%193 = OpFunctionCall %5 %81 %148 %194\n%195 = OpBitwiseAnd %5 %193 %168\n%196 = OpIAdd %5 %195 %173\n%197 = OpFunctionCall %5 %81 %148 %198\n%199 = OpBitwiseAnd %5 %197 %168\n%200 = OpIAdd %5 %199 %173\n%201 = OpFunctionCall %5 %81 %148 %202\n%203 = OpBitwiseAnd %5 %201 %168\n%204 = OpIAdd %5 %203 %173\n%205 = OpFunctionCall %5 %81 %148 %206\n%207 = OpBitwiseAnd %5 %205 %168\n%208 = OpIAdd %5 %207 %173\n%209 = OpFunctionCall %5 %81 %148 %210\n%211 = OpBitwiseAnd %5 %209 %168\n%212 = OpIAdd %5 %211 %173\n%213 = OpFunctionCall %5 %81 %148 %214\n%215 = OpBitwiseAnd %5 %213 %168\n%216 = OpIAdd %5 %215 %173\n%217 = OpFunctionCall %5 %81 %148 %218\n%219 = OpBitwiseAnd %5 %217 %168\n%220 = OpIAdd %5 %219 %173\n%221 = OpFunctionCall %5 %81 %148 %222\n%223 = OpBitwiseAnd %5 %221 %168\n%224 = OpIAdd %5 %223 %173\n%225 = OpFunctionCall %5 %81 %148 %226\n%227 = OpBitwiseAnd %5 %225 %168\n%228 = OpIAdd %5 %227 %173\n%229 = OpFunctionCall %5 %81 %148 %230\n%231 = OpBitwiseAnd %5 %229 %168\n%232 = OpIAdd %5 %231 %173\n%233 = OpFunctionCall %5 %81 %148 %234\n%235 = OpBitwiseAnd %5 %233 %168\n%236 = OpIAdd %5 %235 %173\n%242 = OpVectorExtractDynamic %118 %241 %132\n%243 = OpShiftLeftLogical %5 %153 %54\n%244 = OpShiftLeftLogical %5 %163 %47\n%245 = OpBitwiseOr %5 %153 %243\n%246 = OpBitwiseOr %5 %163 %244\n%247 = OpCompositeConstruct %9 %245 %246\n%248 = OpBitcast %118 %247\n%249 = OpBitwiseAnd %118 %242 %248\n%251 = OpInBoundsAccessChain %250 %123 %38 %177\n%252 = OpAtomicOr %118 %251 %10 %38 %249\n%253 = OpInBoundsAccessChain %250 %123 %38 %181\n%254 = OpAtomicOr %118 %253 %10 %38 %249\n%255 = OpBitwiseAnd %118 %252 %254\n%256 = OpInBoundsAccessChain %250 %123 %38 %185\n%257 = OpAtomicOr %118 %256 %10 %38 %249\n%258 = OpBitwiseAnd %118 %255 %257\n%259 = OpInBoundsAccessChain %250 %123 %38 %188\n%260 = OpAtomicOr %118 %259 %10 %38 %249\n%261 = OpBitwiseAnd %118 %258 %260\n%262 = OpInBoundsAccessChain %250 %123 %38 %192\n%263 = OpAtomicOr %118 %262 %10 %38 %249\n%264 = OpBitwiseAnd %118 %261 %263\n%265 = OpInBoundsAccessChain %250 %123 %38 %196\n%266 = OpAtomicOr %118 %265 %10 %38 %249\n%267 = OpBitwiseAnd %118 %264 %266\n%268 = OpInBoundsAccessChain %250 %123 %38 %200\n%269 = OpAtomicOr %118 %268 %10 %38 %249\n%270 = OpBitwiseAnd %118 %267 %269\n%271 = OpInBoundsAccessChain %250 %123 %38 %204\n%272 = OpAtomicOr %118 %271 %10 %38 %249\n%273 = OpBitwiseAnd %118 %270 %272\n%274 = OpInBoundsAccessChain %250 %123 %38 %208\n%275 = OpAtomicOr %118 %274 %10 %38 %249\n%276 = OpBitwiseAnd %118 %273 %275\n%277 = OpInBoundsAccessChain %250 %123 %38 %212\n%278 = OpAtomicOr %118 %277 %10 %38 %249\n%279 = OpBitwiseAnd %118 %276 %278\n%280 = OpInBoundsAccessChain %250 %123 %38 %216\n%281 = OpAtomicOr %118 %280 %10 %38 %249\n%282 = OpBitwiseAnd %118 %279 %281\n%283 = OpInBoundsAccessChain %250 %123 %38 %220\n%284 = OpAtomicOr %118 %283 %10 %38 %249\n%285 = OpBitwiseAnd %118 %282 %284\n%286 = OpInBoundsAccessChain %250 %123 %38 %224\n%287 = OpAtomicOr %118 %286 %10 %38 %249\n%288 = OpBitwiseAnd %118 %285 %287\n%289 = OpInBoundsAccessChain %250 %123 %38 %228\n%290 = OpAtomicOr %118 %289 %10 %38 %249\n%291 = OpBitwiseAnd %118 %288 %290\n%292 = OpInBoundsAccessChain %250 %123 %38 %232\n%293 = OpAtomicOr %118 %292 %10 %38 %249\n%294 = OpBitwiseAnd %118 %291 %293\n%295 = OpInBoundsAccessChain %250 %123 %38 %236\n%296 = OpAtomicOr %118 %295 %10 %38 %249\n%297 = OpBitwiseAnd %118 %294 %296\n%298 = OpBitcast %9 %297\n%299 = OpCompositeExtract %5 %298 0\n%300 = OpCompositeExtract %5 %298 1\n%301 = OpShiftRightLogical %5 %299 %54\n%302 = OpBitwiseAnd %5 %301 %153\n%303 = OpIEqual %119 %302 %38\n%304 = OpBitFieldUExtract %5 %133 %306 %307\n%308 = OpShiftLeftLogical %5 %309 %304\n%310 = OpBitFieldUExtract %5 %133 %307 %307\n%311 = OpShiftLeftLogical %5 %312 %310\n%313 = OpBitwiseOr %5 %308 %311\n%314 = OpBitFieldUExtract %5 %133 %315 %307\n%316 = OpShiftLeftLogical %5 %317 %314\n%318 = OpBitwiseOr %5 %313 %316\n%319 = OpSelect %5 %303 %318 %38\n%320 = OpInBoundsAccessChain %36 %127 %38 %177 %10\n%321 = OpAtomicOr %5 %320 %10 %38 %319\n%322 = OpBitwiseAnd %5 %321 %318\n%323 = OpIEqual %119 %322 %318\n%324 = OpBitFieldUExtract %5 %133 %325 %307\n%326 = OpShiftLeftLogical %5 %309 %324\n%327 = OpBitFieldUExtract %5 %133 %328 %307\n%329 = OpShiftLeftLogical %5 %312 %327\n%330 = OpBitwiseOr %5 %326 %329\n%331 = OpBitFieldUExtract %5 %133 %332 %307\n%333 = OpShiftLeftLogical %5 %317 %331\n%334 = OpBitwiseOr %5 %330 %333\n%335 = OpSelect %5 %303 %334 %38\n%336 = OpInBoundsAccessChain %36 %127 %38 %181 %10\n%337 = OpAtomicOr %5 %336 %10 %38 %335\n%338 = OpBitwiseAnd %5 %337 %334\n%339 = OpIEqual %119 %338 %334\n%340 = OpLogicalAnd %119 %323 %339\n%341 = OpBitFieldUExtract %5 %133 %342 %307\n%343 = OpShiftLeftLogical %5 %309 %341\n%344 = OpBitFieldUExtract %5 %133 %345 %307\n%346 = OpShiftLeftLogical %5 %312 %344\n%347 = OpBitwiseOr %5 %343 %346\n%348 = OpBitFieldUExtract %5 %133 %349 %307\n%350 = OpShiftLeftLogical %5 %317 %348\n%351 = OpBitwiseOr %5 %347 %350\n%352 = OpSelect %5 %303 %351 %38\n%353 = OpInBoundsAccessChain %36 %127 %38 %185 %10\n%354 = OpAtomicOr %5 %353 %10 %38 %352\n%355 = OpBitwiseAnd %5 %354 %351\n%356 = OpIEqual %119 %355 %351\n%357 = OpLogicalAnd %119 %340 %356\n%358 = OpBitFieldUExtract %5 %133 %359 %307\n%360 = OpShiftLeftLogical %5 %309 %358\n%361 = OpBitFieldUExtract %5 %133 %362 %307\n%363 = OpShiftLeftLogical %5 %312 %361\n%364 = OpBitwiseOr %5 %360 %363\n%365 = OpBitFieldUExtract %5 %133 %366 %307\n%367 = OpShiftLeftLogical %5 %317 %365\n%368 = OpBitwiseOr %5 %364 %367\n%369 = OpSelect %5 %303 %368 %38\n%370 = OpInBoundsAccessChain %36 %127 %38 %188 %10\n%371 = OpAtomicOr %5 %370 %10 %38 %369\n%372 = OpBitwiseAnd %5 %371 %368\n%373 = OpIEqual %119 %372 %368\n%374 = OpLogicalAnd %119 %357 %373\n%375 = OpBitFieldUExtract %5 %133 %376 %307\n%377 = OpShiftLeftLogical %5 %309 %375\n%378 = OpBitFieldUExtract %5 %133 %379 %307\n%380 = OpShiftLeftLogical %5 %312 %378\n%381 = OpBitwiseOr %5 %377 %380\n%382 = OpBitFieldUExtract %5 %133 %383 %307\n%384 = OpShiftLeftLogical %5 %317 %382\n%385 = OpBitwiseOr %5 %381 %384\n%386 = OpSelect %5 %303 %385 %38\n%387 = OpInBoundsAccessChain %36 %127 %38 %192 %10\n%388 = OpAtomicOr %5 %387 %10 %38 %386\n%389 = OpBitwiseAnd %5 %388 %385\n%390 = OpIEqual %119 %389 %385\n%391 = OpLogicalAnd %119 %374 %390\n%392 = OpBitFieldUExtract %5 %133 %325 %307\n%393 = OpShiftLeftLogical %5 %309 %392\n%394 = OpBitFieldUExtract %5 %133 %328 %307\n%395 = OpShiftLeftLogical %5 %312 %394\n%396 = OpBitwiseOr %5 %393 %395\n%397 = OpBitFieldUExtract %5 %133 %332 %307\n%398 = OpShiftLeftLogical %5 %317 %397\n%399 = OpBitwiseOr %5 %396 %398\n%400 = OpSelect %5 %303 %399 %38\n%401 = OpInBoundsAccessChain %36 %127 %38 %196 %10\n%402 = OpAtomicOr %5 %401 %10 %38 %400\n%403 = OpBitwiseAnd %5 %402 %399\n%404 = OpIEqual %119 %403 %399\n%405 = OpLogicalAnd %119 %391 %404\n%406 = OpBitFieldUExtract %5 %133 %407 %307\n%408 = OpShiftLeftLogical %5 %309 %406\n%409 = OpBitFieldUExtract %5 %133 %410 %307\n%411 = OpShiftLeftLogical %5 %312 %409\n%412 = OpBitwiseOr %5 %408 %411\n%413 = OpBitFieldUExtract %5 %133 %359 %307\n%414 = OpShiftLeftLogical %5 %317 %413\n%415 = OpBitwiseOr %5 %412 %414\n%416 = OpSelect %5 %303 %415 %38\n%417 = OpInBoundsAccessChain %36 %127 %38 %200 %10\n%418 = OpAtomicOr %5 %417 %10 %38 %416\n%419 = OpBitwiseAnd %5 %418 %415\n%420 = OpIEqual %119 %419 %415\n%421 = OpLogicalAnd %119 %405 %420\n%422 = OpBitFieldUExtract %5 %133 %423 %307\n%424 = OpShiftLeftLogical %5 %309 %422\n%425 = OpBitFieldUExtract %5 %133 %426 %307\n%427 = OpShiftLeftLogical %5 %312 %425\n%428 = OpBitwiseOr %5 %424 %427\n%429 = OpBitFieldUExtract %5 %133 %430 %307\n%431 = OpShiftLeftLogical %5 %317 %429\n%432 = OpBitwiseOr %5 %428 %431\n%433 = OpSelect %5 %303 %432 %38\n%434 = OpInBoundsAccessChain %36 %127 %38 %204 %10\n%435 = OpAtomicOr %5 %434 %10 %38 %433\n%436 = OpBitwiseAnd %5 %435 %432\n%437 = OpIEqual %119 %436 %432\n%438 = OpLogicalAnd %119 %421 %437\nOpSelectionMerge %443 None\nOpSwitch %132 %442 0 %439 1 %440 2 %441\n%442 = OpLabel\n%451 = OpShiftLeftLogical %5 %163 %47\n%452 = OpBitwiseAnd %5 %300 %451\n%453 = OpINotEqual %119 %452 %38\nOpBranch %443\n%439 = OpLabel\n%444 = OpBitwiseAnd %5 %299 %153\n%445 = OpINotEqual %119 %444 %38\nOpBranch %443\n%440 = OpLabel\n%446 = OpShiftLeftLogical %5 %153 %54\n%447 = OpBitwiseAnd %5 %299 %446\n%448 = OpINotEqual %119 %447 %38\nOpBranch %443\n%441 = OpLabel\n%449 = OpBitwiseAnd %5 %300 %163\n%450 = OpINotEqual %119 %449 %38\nOpBranch %443\n%443 = OpLabel\n%454 = OpPhi %119 %445 %439 %448 %440 %450 %441 %453 %442\n%455 = OpLogicalNot %119 %454\n%456 = OpLogicalOr %119 %455 %438\nOpReturnValue %456\nOpFunctionEnd\n%508 = OpFunction %1 None %505\n%506 = OpFunctionParameter %119\n%507 = OpFunctionParameter %5\n%509 = OpLabel\n%512 = OpLogicalNot %119 %506\n%513 = OpLoad %119 %496\n%514 = OpLogicalAnd %119 %512 %513\nOpSelectionMerge %510 None\nOpBranchConditional %514 %511 %510\n%511 = OpLabel\n%517 = OpIMul %5 %507 %519\n%518 = OpBitwiseXor %5 %517 %520\n%521 = OpArrayLength %5 %500 0\n%522 = OpISub %5 %521 %165\n%523 = OpAccessChain %36 %500 %38 %522\n%524 = OpLoad %5 %523\n%525 = OpIMul %5 %524 %526\n%527 = OpBitwiseXor %5 %518 %525\n%528 = OpArrayLength %5 %504 0\n%529 = OpISub %5 %528 %10\n%530 = OpBitwiseAnd %5 %527 %529\n%531 = OpShiftRightLogical %5 %530 %47\n%532 = OpBitwiseAnd %5 %530 %155\n%533 = OpShiftLeftLogical %5 %10 %532\n%534 = OpAccessChain %36 %500 %38 %531\n%535 = OpAtomicOr %5 %534 %10 %38 %533\n%536 = OpBitwiseAnd %5 %535 %533\n%537 = OpIEqual %119 %536 %38\nOpStore %496 %538\nOpSelectionMerge %516 None\nOpBranchConditional %537 %515 %516\n%515 = OpLabel\n%539 = OpCompositeConstruct %462 %520 %38 %507 %524\n%540 = OpShiftLeftLogical %5 %533 %54\n%542 = OpAccessChain %541 %504 %38 %530\nOpStore %542 %539\nOpMemoryBarrier %10 %544\n%543 = OpAtomicOr %5 %534 %10 %38 %540\nOpMemoryBarrier %10 %544\nOpBranch %516\n%516 = OpLabel\nOpBranch %510\n%510 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/structured.bindless.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 1, binding = 0, scalar) restrict readonly buffer SSBO\n{\n    uvec3 _m0[];\n} _24[];\n\nlayout(set = 4, binding = 0, std430) buffer _26_29\n{\n    uint _m0[];\n} _29[];\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _42 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _42;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _87 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _88 = uvec2(prime);\n    uvec2 _95 = ((_87 >> uvec2(8u)) ^ _87.yx) * _88;\n    uvec2 _99 = ((_95 >> uvec2(8u)) ^ _95.yx) * _88;\n    uvec2 _103 = ((_99 >> uvec2(8u)) ^ _99.yx) * _88;\n    uvec2 _107 = ((_103 >> uvec2(8u)) ^ _103.yx) * _88;\n    uvec2 _111 = ((_107 >> uvec2(8u)) ^ _107.yx) * _88;\n    return (((_111 >> uvec2(8u)) ^ _111.yx) * _88).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _144;\n    _144._m0 = uaddCarry(BDA.x, offset, _144._m1);\n    uvec2 addr = uvec2(_144._m0, BDA.y + _144._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _517 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _519 = InstrumentationControlData.atomics[_517];\n        uint _525 = (((inst * 97u) ^ 43981u) ^ (_519 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _526 = _525 >> 4u;\n        uint _528 = 1u << (_525 & 15u);\n        uint _530 = atomicOr(InstrumentationControlData.atomics[_526], _528);\n        ShouldReportInstrumentation = false;\n        if ((_530 & _528) == 0u)\n        {\n            InstrumentationData.data[_525] = uvec4(43981u, 0u, inst, _519);\n            memoryBarrierBuffer();\n            uint _538 = atomicOr(InstrumentationControlData.atomics[_526], _528 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _45 = AllocateInvocationID();\n    InvocationID = _45;\n    uvec2 _54 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _59 = uint(_29[registers._m4]._m0.length()) * 4u;\n    uvec2 _65 = DescriptorHeapRobustness.descriptors[registers._m1]._m0[0u];\n    uint _77 = (gl_GlobalInvocationID.x * 12u) + 0u;\n    uint _459 = InvocationID;\n    bool _458 = ValidateBDALoadStore(_65, _77, 12u, 0u, _459, _77 < (uint(_24[registers._m1]._m0.length()) * 12u));\n    AssumeTrue(_458, 1u);\n    vec3 _466 = uintBitsToFloat(_24[registers._m1]._m0[gl_GlobalInvocationID.x]);\n    uint _473 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _475 = InvocationID;\n    bool _474 = ValidateBDALoadStore(_54, _473, 4u, 0u, _475, _473 < _59);\n    AssumeTrue(_474, 2u);\n    uint _478 = _29[registers._m4]._m0[gl_GlobalInvocationID.x];\n    uint _482 = (gl_GlobalInvocationID.x * 4u) + 0u;\n    uint _484 = InvocationID;\n    bool _483 = ValidateBDALoadStore(_54, _482, 4u, 1u, _484, _482 < _59);\n    AssumeTrue(_483, 3u);\n    _29[registers._m4]._m0[gl_GlobalInvocationID.x] = floatBitsToUint(((_466.x + 40.0) + _466.z) + uintBitsToFloat(_478));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 545\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%169 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %72\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %21 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %31 \"BloomBufferInvocationSSBO\"\nOpMemberName %31 0 \"atomics\"\nOpName %33 \"BloomBufferInvocation\"\nOpName %35 \"AllocateInvocationID\"\nOpName %81 \"AddrHash\"\nOpName %79 \"addr\"\nOpName %80 \"prime\"\nOpName %121 \"BloomBufferSSBO\"\nOpMemberName %121 0 \"atomics\"\nOpName %123 \"BloomBuffer\"\nOpName %125 \"BloomBuffer32SSBO\"\nOpMemberName %125 0 \"atomics\"\nOpName %127 \"BloomBuffer32\"\nOpName %135 \"ValidateBDALoadStore\"\nOpName %129 \"BDA\"\nOpName %130 \"offset\"\nOpName %131 \"len\"\nOpName %132 \"type\"\nOpName %133 \"invocation_id\"\nOpName %134 \"in_bounds\"\nOpName %143 \"IAddCarryResult\"\nOpName %148 \"addr\"\nOpName %149 \"addr_lo\"\nOpName %153 \"byte_mask\"\nOpName %163 \"word_mask\"\nOpName %168 \"hash_mask\"\nOpName %173 \"hash_offset\"\nOpName %177 \"bloom_index\"\nOpName %181 \"bloom_index\"\nOpName %185 \"bloom_index\"\nOpName %188 \"bloom_index\"\nOpName %192 \"bloom_index\"\nOpName %196 \"bloom_index\"\nOpName %200 \"bloom_index\"\nOpName %204 \"bloom_index\"\nOpName %208 \"bloom_index\"\nOpName %212 \"bloom_index\"\nOpName %216 \"bloom_index\"\nOpName %220 \"bloom_index\"\nOpName %224 \"bloom_index\"\nOpName %228 \"bloom_index\"\nOpName %232 \"bloom_index\"\nOpName %236 \"bloom_index\"\nOpName %249 \"invalidation_mask\"\nOpName %252 \"prev_hazard_partial\"\nOpName %254 \"prev_hazard_partial\"\nOpName %257 \"prev_hazard_partial\"\nOpName %260 \"prev_hazard_partial\"\nOpName %263 \"prev_hazard_partial\"\nOpName %266 \"prev_hazard_partial\"\nOpName %269 \"prev_hazard_partial\"\nOpName %272 \"prev_hazard_partial\"\nOpName %275 \"prev_hazard_partial\"\nOpName %278 \"prev_hazard_partial\"\nOpName %281 \"prev_hazard_partial\"\nOpName %284 \"prev_hazard_partial\"\nOpName %287 \"prev_hazard_partial\"\nOpName %290 \"prev_hazard_partial\"\nOpName %293 \"prev_hazard_partial\"\nOpName %296 \"prev_hazard_partial\"\nOpName %298 \"prev_hazard\"\nOpName %299 \"prev_hazard_lo\"\nOpName %300 \"prev_hazard_hi\"\nOpName %303 \"has_exclusive_access\"\nOpName %318 \"lock_mask\"\nOpName %321 \"prev_lock\"\nOpName %334 \"lock_mask\"\nOpName %337 \"prev_lock\"\nOpName %351 \"lock_mask\"\nOpName %354 \"prev_lock\"\nOpName %368 \"lock_mask\"\nOpName %371 \"prev_lock\"\nOpName %385 \"lock_mask\"\nOpName %388 \"prev_lock\"\nOpName %399 \"lock_mask\"\nOpName %402 \"prev_lock\"\nOpName %415 \"lock_mask\"\nOpName %418 \"prev_lock\"\nOpName %432 \"lock_mask\"\nOpName %435 \"prev_lock\"\nOpName %438 \"has_complete_self_lock\"\nOpName %454 \"hazard\"\nOpName %490 \"ShouldReportInstrumentation\"\nOpName %493 \"InstrumentationControlDataSSBO\"\nOpMemberName %493 0 \"atomics\"\nOpName %495 \"InstrumentationControlData\"\nOpName %497 \"InstrumentationDataSSBO\"\nOpMemberName %497 0 \"data\"\nOpName %499 \"InstrumentationData\"\nOpName %503 \"AssumeTrue\"\nOpName %501 \"value\"\nOpName %502 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %20 ArrayStride 12\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %25 ArrayStride 4\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 DescriptorSet 4\nOpDecorate %29 Binding 0\nOpDecorate %30 ArrayStride 4\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 2\nOpDecorate %72 BuiltIn GlobalInvocationId\nOpDecorate %120 ArrayStride 8\nOpMemberDecorate %121 0 Offset 0\nOpDecorate %121 Block\nOpDecorate %123 DescriptorSet 0\nOpDecorate %123 Binding 2\nOpDecorate %124 ArrayStride 8\nOpMemberDecorate %125 0 Offset 0\nOpDecorate %125 Block\nOpDecorate %127 DescriptorSet 0\nOpDecorate %127 Binding 2\nOpDecorate %492 ArrayStride 4\nOpMemberDecorate %493 0 Offset 0\nOpDecorate %493 Block\nOpDecorate %495 DescriptorSet 0\nOpDecorate %495 Binding 2\nOpDecorate %496 ArrayStride 16\nOpMemberDecorate %497 0 Offset 0\nOpDecorate %497 Block\nOpDecorate %499 DescriptorSet 0\nOpDecorate %499 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeVector %5 3\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %5\n%26 = OpTypeStruct %25\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeRuntimeArray %5\n%31 = OpTypeStruct %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeFunction %5\n%39 = OpTypePointer StorageBuffer %5\n%41 = OpConstant %5 0\n%43 = OpConstant %5 1103633207\n%46 = OpTypePointer StorageBuffer %26\n%48 = OpTypePointer PushConstant %5\n%50 = OpConstant %5 4\n%52 = OpTypePointer StorageBuffer %9\n%57 = OpConstant %5 16\n%60 = OpTypePointer StorageBuffer %21\n%70 = OpConstant %5 12\n%71 = OpTypePointer Input %19\n%72 = OpVariable %71 Input\n%73 = OpTypePointer Input %5\n%78 = OpTypeFunction %5 %9 %5\n%89 = OpConstant %5 65535\n%90 = OpConstant %5 8\n%91 = OpConstantComposite %9 %90 %90\n%118 = OpTypeInt 64 0\n%119 = OpTypeBool\n%120 = OpTypeRuntimeArray %118\n%121 = OpTypeStruct %120\n%122 = OpTypePointer StorageBuffer %121\n%123 = OpVariable %122 StorageBuffer\n%124 = OpTypeRuntimeArray %9\n%125 = OpTypeStruct %124\n%126 = OpTypePointer StorageBuffer %125\n%127 = OpVariable %126 StorageBuffer\n%128 = OpTypeFunction %119 %9 %5 %5 %5 %5 %119\n%139 = OpConstantTrue %119\n%143 = OpTypeStruct %5 %5\n%154 = OpConstant %5 4294967295\n%155 = OpConstant %5 15\n%164 = OpConstant %5 3\n%165 = OpConstant %5 2\n%175 = OpConstant %5 1103515245\n%179 = OpConstant %5 1103518333\n%183 = OpConstant %5 1103539331\n%190 = OpConstant %5 10006121\n%194 = OpConstant %5 4004951\n%198 = OpConstant %5 5005159\n%202 = OpConstant %5 6004811\n%206 = OpConstant %5 383\n%210 = OpConstant %5 821\n%214 = OpConstant %5 661\n%218 = OpConstant %5 1091\n%222 = OpConstant %5 1117\n%226 = OpConstant %5 3947\n%230 = OpConstant %5 4253\n%234 = OpConstant %5 7691\n%237 = OpTypeVector %118 4\n%238 = OpConstant %118 68719411200\n%239 = OpConstant %118 1099511627775\n%240 = OpConstant %118 1035087118335\n%241 = OpConstantComposite %237 %238 %239 %240 %238\n%250 = OpTypePointer StorageBuffer %118\n%305 = OpTypeInt 32 1\n%306 = OpConstant %305 0\n%307 = OpConstant %305 3\n%309 = OpConstant %5 256\n%312 = OpConstant %5 65536\n%315 = OpConstant %305 6\n%317 = OpConstant %5 16777216\n%325 = OpConstant %305 9\n%328 = OpConstant %305 12\n%332 = OpConstant %305 15\n%342 = OpConstant %305 18\n%345 = OpConstant %305 21\n%349 = OpConstant %305 24\n%359 = OpConstant %305 23\n%362 = OpConstant %305 26\n%366 = OpConstant %305 29\n%376 = OpConstant %305 1\n%379 = OpConstant %305 4\n%383 = OpConstant %305 7\n%407 = OpConstant %305 17\n%410 = OpConstant %305 20\n%423 = OpConstant %305 22\n%426 = OpConstant %305 25\n%430 = OpConstant %305 28\n%461 = OpTypePointer StorageBuffer %19\n%464 = OpTypeFloat 32\n%465 = OpTypeVector %464 3\n%470 = OpConstant %464 40\n%489 = OpTypePointer Private %119\n%490 = OpVariable %489 Private %139\n%491 = OpTypeVector %5 4\n%492 = OpTypeRuntimeArray %5\n%493 = OpTypeStruct %492\n%494 = OpTypePointer StorageBuffer %493\n%495 = OpVariable %494 StorageBuffer\n%496 = OpTypeRuntimeArray %491\n%497 = OpTypeStruct %496\n%498 = OpTypePointer StorageBuffer %497\n%499 = OpVariable %498 StorageBuffer\n%500 = OpTypeFunction %1 %119 %5\n%514 = OpConstant %5 97\n%515 = OpConstant %5 43981\n%521 = OpConstant %5 51329\n%533 = OpConstantFalse %119\n%536 = OpTypePointer StorageBuffer %491\n%539 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %488\n%488 = OpLabel\n%45 = OpFunctionCall %5 %35\nOpStore %18 %45\n%49 = OpAccessChain %48 %8 %50\n%51 = OpLoad %5 %49\n%53 = OpAccessChain %52 %16 %41 %51 %41 %41\n%54 = OpLoad %9 %53\n%55 = OpCompositeExtract %5 %54 1\n%56 = OpShiftRightLogical %5 %55 %57\n%47 = OpAccessChain %46 %29 %51\n%58 = OpArrayLength %5 %47 0\n%59 = OpIMul %5 %58 %50\n%62 = OpAccessChain %48 %8 %10\n%63 = OpLoad %5 %62\n%64 = OpAccessChain %52 %16 %41 %63 %41 %41\n%65 = OpLoad %9 %64\n%66 = OpCompositeExtract %5 %65 1\n%67 = OpShiftRightLogical %5 %66 %57\n%61 = OpAccessChain %60 %24 %63\n%68 = OpArrayLength %5 %61 0\n%69 = OpIMul %5 %68 %70\n%74 = OpAccessChain %73 %72 %41\n%75 = OpLoad %5 %74\n%76 = OpIMul %5 %75 %70\n%77 = OpIAdd %5 %76 %41\n%459 = OpLoad %5 %18\n%460 = OpULessThan %119 %77 %69\n%458 = OpFunctionCall %119 %135 %65 %77 %70 %41 %459 %460\n%541 = OpFunctionCall %1 %503 %458 %10\n%462 = OpAccessChain %461 %61 %41 %75\n%463 = OpLoad %19 %462\n%466 = OpBitcast %465 %463\n%467 = OpCompositeExtract %464 %466 0\n%468 = OpCompositeExtract %464 %466 2\n%469 = OpFAdd %464 %467 %470\n%471 = OpFAdd %464 %469 %468\n%472 = OpIMul %5 %75 %50\n%473 = OpIAdd %5 %472 %41\n%475 = OpLoad %5 %18\n%476 = OpULessThan %119 %473 %59\n%474 = OpFunctionCall %119 %135 %54 %473 %50 %41 %475 %476\n%542 = OpFunctionCall %1 %503 %474 %165\n%477 = OpAccessChain %39 %47 %41 %75\n%478 = OpLoad %5 %477\n%479 = OpBitcast %464 %478\n%480 = OpFAdd %464 %471 %479\n%481 = OpIMul %5 %75 %50\n%482 = OpIAdd %5 %481 %41\n%484 = OpLoad %5 %18\n%485 = OpULessThan %119 %482 %59\n%483 = OpFunctionCall %119 %135 %54 %482 %50 %10 %484 %485\n%543 = OpFunctionCall %1 %503 %483 %164\n%486 = OpBitcast %5 %480\n%487 = OpAccessChain %39 %47 %41 %75\nOpStore %487 %486\nOpReturn\nOpFunctionEnd\n%35 = OpFunction %5 None %34\n%36 = OpLabel\n%37 = OpArrayLength %5 %33 0\n%38 = OpISub %5 %37 %10\n%40 = OpAccessChain %39 %33 %41 %38\n%42 = OpAtomicIAdd %5 %40 %10 %41 %43\nOpReturnValue %42\nOpFunctionEnd\n%81 = OpFunction %5 None %78\n%79 = OpFunctionParameter %9\n%80 = OpFunctionParameter %5\n%82 = OpLabel\n%83 = OpCompositeExtract %5 %79 0\n%84 = OpCompositeExtract %5 %79 1\n%85 = OpShiftRightLogical %5 %83 %50\n%86 = OpBitwiseAnd %5 %84 %89\n%87 = OpCompositeConstruct %9 %85 %86\n%88 = OpCompositeConstruct %9 %80 %80\n%92 = OpVectorShuffle %9 %87 %87 1 0\n%93 = OpShiftRightLogical %9 %87 %91\n%94 = OpBitwiseXor %9 %93 %92\n%95 = OpIMul %9 %94 %88\n%96 = OpVectorShuffle %9 %95 %95 1 0\n%97 = OpShiftRightLogical %9 %95 %91\n%98 = OpBitwiseXor %9 %97 %96\n%99 = OpIMul %9 %98 %88\n%100 = OpVectorShuffle %9 %99 %99 1 0\n%101 = OpShiftRightLogical %9 %99 %91\n%102 = OpBitwiseXor %9 %101 %100\n%103 = OpIMul %9 %102 %88\n%104 = OpVectorShuffle %9 %103 %103 1 0\n%105 = OpShiftRightLogical %9 %103 %91\n%106 = OpBitwiseXor %9 %105 %104\n%107 = OpIMul %9 %106 %88\n%108 = OpVectorShuffle %9 %107 %107 1 0\n%109 = OpShiftRightLogical %9 %107 %91\n%110 = OpBitwiseXor %9 %109 %108\n%111 = OpIMul %9 %110 %88\n%112 = OpVectorShuffle %9 %111 %111 1 0\n%113 = OpShiftRightLogical %9 %111 %91\n%114 = OpBitwiseXor %9 %113 %112\n%115 = OpIMul %9 %114 %88\n%116 = OpCompositeExtract %5 %115 0\nOpReturnValue %116\nOpFunctionEnd\n%135 = OpFunction %119 None %128\n%129 = OpFunctionParameter %9\n%130 = OpFunctionParameter %5\n%131 = OpFunctionParameter %5\n%132 = OpFunctionParameter %5\n%133 = OpFunctionParameter %5\n%134 = OpFunctionParameter %119\n%136 = OpLabel\nOpSelectionMerge %138 None\nOpBranchConditional %134 %138 %137\n%137 = OpLabel\nOpReturnValue %139\n%138 = OpLabel\n%141 = OpCompositeExtract %5 %129 0\n%142 = OpCompositeExtract %5 %129 1\n%144 = OpIAddCarry %143 %141 %130\n%145 = OpCompositeExtract %5 %144 0\n%146 = OpCompositeExtract %5 %144 1\n%147 = OpIAdd %5 %142 %146\n%148 = OpCompositeConstruct %9 %145 %147\n%149 = OpCompositeExtract %5 %148 0\n%150 = OpBitFieldUExtract %5 %154 %41 %131\n%151 = OpBitwiseAnd %5 %149 %155\n%152 = OpShiftLeftLogical %5 %150 %151\n%153 = OpBitwiseAnd %5 %152 %89\n%156 = OpBitwiseAnd %5 %149 %164\n%157 = OpIAdd %5 %156 %131\n%158 = OpIAdd %5 %157 %164\n%159 = OpShiftRightLogical %5 %158 %165\n%160 = OpBitFieldUExtract %5 %149 %165 %165\n%161 = OpBitFieldUExtract %5 %154 %41 %159\n%162 = OpShiftLeftLogical %5 %161 %160\n%163 = OpBitwiseAnd %5 %162 %155\n%166 = OpArrayLength %5 %123 0\n%167 = OpExtInst %5 %169 FindUMsb %166\n%168 = OpBitFieldUExtract %5 %154 %41 %167\n%170 = OpArrayLength %5 %123 0\n%171 = OpExtInst %5 %169 FindUMsb %170\n%172 = OpBitFieldUExtract %5 %170 %41 %171\n%173 = OpISub %5 %172 %10\n%174 = OpFunctionCall %5 %81 %148 %175\n%176 = OpBitwiseAnd %5 %174 %168\n%177 = OpIAdd %5 %176 %173\n%178 = OpFunctionCall %5 %81 %148 %179\n%180 = OpBitwiseAnd %5 %178 %168\n%181 = OpIAdd %5 %180 %173\n%182 = OpFunctionCall %5 %81 %148 %183\n%184 = OpBitwiseAnd %5 %182 %168\n%185 = OpIAdd %5 %184 %173\n%186 = OpFunctionCall %5 %81 %148 %43\n%187 = OpBitwiseAnd %5 %186 %168\n%188 = OpIAdd %5 %187 %173\n%189 = OpFunctionCall %5 %81 %148 %190\n%191 = OpBitwiseAnd %5 %189 %168\n%192 = OpIAdd %5 %191 %173\n%193 = OpFunctionCall %5 %81 %148 %194\n%195 = OpBitwiseAnd %5 %193 %168\n%196 = OpIAdd %5 %195 %173\n%197 = OpFunctionCall %5 %81 %148 %198\n%199 = OpBitwiseAnd %5 %197 %168\n%200 = OpIAdd %5 %199 %173\n%201 = OpFunctionCall %5 %81 %148 %202\n%203 = OpBitwiseAnd %5 %201 %168\n%204 = OpIAdd %5 %203 %173\n%205 = OpFunctionCall %5 %81 %148 %206\n%207 = OpBitwiseAnd %5 %205 %168\n%208 = OpIAdd %5 %207 %173\n%209 = OpFunctionCall %5 %81 %148 %210\n%211 = OpBitwiseAnd %5 %209 %168\n%212 = OpIAdd %5 %211 %173\n%213 = OpFunctionCall %5 %81 %148 %214\n%215 = OpBitwiseAnd %5 %213 %168\n%216 = OpIAdd %5 %215 %173\n%217 = OpFunctionCall %5 %81 %148 %218\n%219 = OpBitwiseAnd %5 %217 %168\n%220 = OpIAdd %5 %219 %173\n%221 = OpFunctionCall %5 %81 %148 %222\n%223 = OpBitwiseAnd %5 %221 %168\n%224 = OpIAdd %5 %223 %173\n%225 = OpFunctionCall %5 %81 %148 %226\n%227 = OpBitwiseAnd %5 %225 %168\n%228 = OpIAdd %5 %227 %173\n%229 = OpFunctionCall %5 %81 %148 %230\n%231 = OpBitwiseAnd %5 %229 %168\n%232 = OpIAdd %5 %231 %173\n%233 = OpFunctionCall %5 %81 %148 %234\n%235 = OpBitwiseAnd %5 %233 %168\n%236 = OpIAdd %5 %235 %173\n%242 = OpVectorExtractDynamic %118 %241 %132\n%243 = OpShiftLeftLogical %5 %153 %57\n%244 = OpShiftLeftLogical %5 %163 %50\n%245 = OpBitwiseOr %5 %153 %243\n%246 = OpBitwiseOr %5 %163 %244\n%247 = OpCompositeConstruct %9 %245 %246\n%248 = OpBitcast %118 %247\n%249 = OpBitwiseAnd %118 %242 %248\n%251 = OpInBoundsAccessChain %250 %123 %41 %177\n%252 = OpAtomicOr %118 %251 %10 %41 %249\n%253 = OpInBoundsAccessChain %250 %123 %41 %181\n%254 = OpAtomicOr %118 %253 %10 %41 %249\n%255 = OpBitwiseAnd %118 %252 %254\n%256 = OpInBoundsAccessChain %250 %123 %41 %185\n%257 = OpAtomicOr %118 %256 %10 %41 %249\n%258 = OpBitwiseAnd %118 %255 %257\n%259 = OpInBoundsAccessChain %250 %123 %41 %188\n%260 = OpAtomicOr %118 %259 %10 %41 %249\n%261 = OpBitwiseAnd %118 %258 %260\n%262 = OpInBoundsAccessChain %250 %123 %41 %192\n%263 = OpAtomicOr %118 %262 %10 %41 %249\n%264 = OpBitwiseAnd %118 %261 %263\n%265 = OpInBoundsAccessChain %250 %123 %41 %196\n%266 = OpAtomicOr %118 %265 %10 %41 %249\n%267 = OpBitwiseAnd %118 %264 %266\n%268 = OpInBoundsAccessChain %250 %123 %41 %200\n%269 = OpAtomicOr %118 %268 %10 %41 %249\n%270 = OpBitwiseAnd %118 %267 %269\n%271 = OpInBoundsAccessChain %250 %123 %41 %204\n%272 = OpAtomicOr %118 %271 %10 %41 %249\n%273 = OpBitwiseAnd %118 %270 %272\n%274 = OpInBoundsAccessChain %250 %123 %41 %208\n%275 = OpAtomicOr %118 %274 %10 %41 %249\n%276 = OpBitwiseAnd %118 %273 %275\n%277 = OpInBoundsAccessChain %250 %123 %41 %212\n%278 = OpAtomicOr %118 %277 %10 %41 %249\n%279 = OpBitwiseAnd %118 %276 %278\n%280 = OpInBoundsAccessChain %250 %123 %41 %216\n%281 = OpAtomicOr %118 %280 %10 %41 %249\n%282 = OpBitwiseAnd %118 %279 %281\n%283 = OpInBoundsAccessChain %250 %123 %41 %220\n%284 = OpAtomicOr %118 %283 %10 %41 %249\n%285 = OpBitwiseAnd %118 %282 %284\n%286 = OpInBoundsAccessChain %250 %123 %41 %224\n%287 = OpAtomicOr %118 %286 %10 %41 %249\n%288 = OpBitwiseAnd %118 %285 %287\n%289 = OpInBoundsAccessChain %250 %123 %41 %228\n%290 = OpAtomicOr %118 %289 %10 %41 %249\n%291 = OpBitwiseAnd %118 %288 %290\n%292 = OpInBoundsAccessChain %250 %123 %41 %232\n%293 = OpAtomicOr %118 %292 %10 %41 %249\n%294 = OpBitwiseAnd %118 %291 %293\n%295 = OpInBoundsAccessChain %250 %123 %41 %236\n%296 = OpAtomicOr %118 %295 %10 %41 %249\n%297 = OpBitwiseAnd %118 %294 %296\n%298 = OpBitcast %9 %297\n%299 = OpCompositeExtract %5 %298 0\n%300 = OpCompositeExtract %5 %298 1\n%301 = OpShiftRightLogical %5 %299 %57\n%302 = OpBitwiseAnd %5 %301 %153\n%303 = OpIEqual %119 %302 %41\n%304 = OpBitFieldUExtract %5 %133 %306 %307\n%308 = OpShiftLeftLogical %5 %309 %304\n%310 = OpBitFieldUExtract %5 %133 %307 %307\n%311 = OpShiftLeftLogical %5 %312 %310\n%313 = OpBitwiseOr %5 %308 %311\n%314 = OpBitFieldUExtract %5 %133 %315 %307\n%316 = OpShiftLeftLogical %5 %317 %314\n%318 = OpBitwiseOr %5 %313 %316\n%319 = OpSelect %5 %303 %318 %41\n%320 = OpInBoundsAccessChain %39 %127 %41 %177 %10\n%321 = OpAtomicOr %5 %320 %10 %41 %319\n%322 = OpBitwiseAnd %5 %321 %318\n%323 = OpIEqual %119 %322 %318\n%324 = OpBitFieldUExtract %5 %133 %325 %307\n%326 = OpShiftLeftLogical %5 %309 %324\n%327 = OpBitFieldUExtract %5 %133 %328 %307\n%329 = OpShiftLeftLogical %5 %312 %327\n%330 = OpBitwiseOr %5 %326 %329\n%331 = OpBitFieldUExtract %5 %133 %332 %307\n%333 = OpShiftLeftLogical %5 %317 %331\n%334 = OpBitwiseOr %5 %330 %333\n%335 = OpSelect %5 %303 %334 %41\n%336 = OpInBoundsAccessChain %39 %127 %41 %181 %10\n%337 = OpAtomicOr %5 %336 %10 %41 %335\n%338 = OpBitwiseAnd %5 %337 %334\n%339 = OpIEqual %119 %338 %334\n%340 = OpLogicalAnd %119 %323 %339\n%341 = OpBitFieldUExtract %5 %133 %342 %307\n%343 = OpShiftLeftLogical %5 %309 %341\n%344 = OpBitFieldUExtract %5 %133 %345 %307\n%346 = OpShiftLeftLogical %5 %312 %344\n%347 = OpBitwiseOr %5 %343 %346\n%348 = OpBitFieldUExtract %5 %133 %349 %307\n%350 = OpShiftLeftLogical %5 %317 %348\n%351 = OpBitwiseOr %5 %347 %350\n%352 = OpSelect %5 %303 %351 %41\n%353 = OpInBoundsAccessChain %39 %127 %41 %185 %10\n%354 = OpAtomicOr %5 %353 %10 %41 %352\n%355 = OpBitwiseAnd %5 %354 %351\n%356 = OpIEqual %119 %355 %351\n%357 = OpLogicalAnd %119 %340 %356\n%358 = OpBitFieldUExtract %5 %133 %359 %307\n%360 = OpShiftLeftLogical %5 %309 %358\n%361 = OpBitFieldUExtract %5 %133 %362 %307\n%363 = OpShiftLeftLogical %5 %312 %361\n%364 = OpBitwiseOr %5 %360 %363\n%365 = OpBitFieldUExtract %5 %133 %366 %307\n%367 = OpShiftLeftLogical %5 %317 %365\n%368 = OpBitwiseOr %5 %364 %367\n%369 = OpSelect %5 %303 %368 %41\n%370 = OpInBoundsAccessChain %39 %127 %41 %188 %10\n%371 = OpAtomicOr %5 %370 %10 %41 %369\n%372 = OpBitwiseAnd %5 %371 %368\n%373 = OpIEqual %119 %372 %368\n%374 = OpLogicalAnd %119 %357 %373\n%375 = OpBitFieldUExtract %5 %133 %376 %307\n%377 = OpShiftLeftLogical %5 %309 %375\n%378 = OpBitFieldUExtract %5 %133 %379 %307\n%380 = OpShiftLeftLogical %5 %312 %378\n%381 = OpBitwiseOr %5 %377 %380\n%382 = OpBitFieldUExtract %5 %133 %383 %307\n%384 = OpShiftLeftLogical %5 %317 %382\n%385 = OpBitwiseOr %5 %381 %384\n%386 = OpSelect %5 %303 %385 %41\n%387 = OpInBoundsAccessChain %39 %127 %41 %192 %10\n%388 = OpAtomicOr %5 %387 %10 %41 %386\n%389 = OpBitwiseAnd %5 %388 %385\n%390 = OpIEqual %119 %389 %385\n%391 = OpLogicalAnd %119 %374 %390\n%392 = OpBitFieldUExtract %5 %133 %325 %307\n%393 = OpShiftLeftLogical %5 %309 %392\n%394 = OpBitFieldUExtract %5 %133 %328 %307\n%395 = OpShiftLeftLogical %5 %312 %394\n%396 = OpBitwiseOr %5 %393 %395\n%397 = OpBitFieldUExtract %5 %133 %332 %307\n%398 = OpShiftLeftLogical %5 %317 %397\n%399 = OpBitwiseOr %5 %396 %398\n%400 = OpSelect %5 %303 %399 %41\n%401 = OpInBoundsAccessChain %39 %127 %41 %196 %10\n%402 = OpAtomicOr %5 %401 %10 %41 %400\n%403 = OpBitwiseAnd %5 %402 %399\n%404 = OpIEqual %119 %403 %399\n%405 = OpLogicalAnd %119 %391 %404\n%406 = OpBitFieldUExtract %5 %133 %407 %307\n%408 = OpShiftLeftLogical %5 %309 %406\n%409 = OpBitFieldUExtract %5 %133 %410 %307\n%411 = OpShiftLeftLogical %5 %312 %409\n%412 = OpBitwiseOr %5 %408 %411\n%413 = OpBitFieldUExtract %5 %133 %359 %307\n%414 = OpShiftLeftLogical %5 %317 %413\n%415 = OpBitwiseOr %5 %412 %414\n%416 = OpSelect %5 %303 %415 %41\n%417 = OpInBoundsAccessChain %39 %127 %41 %200 %10\n%418 = OpAtomicOr %5 %417 %10 %41 %416\n%419 = OpBitwiseAnd %5 %418 %415\n%420 = OpIEqual %119 %419 %415\n%421 = OpLogicalAnd %119 %405 %420\n%422 = OpBitFieldUExtract %5 %133 %423 %307\n%424 = OpShiftLeftLogical %5 %309 %422\n%425 = OpBitFieldUExtract %5 %133 %426 %307\n%427 = OpShiftLeftLogical %5 %312 %425\n%428 = OpBitwiseOr %5 %424 %427\n%429 = OpBitFieldUExtract %5 %133 %430 %307\n%431 = OpShiftLeftLogical %5 %317 %429\n%432 = OpBitwiseOr %5 %428 %431\n%433 = OpSelect %5 %303 %432 %41\n%434 = OpInBoundsAccessChain %39 %127 %41 %204 %10\n%435 = OpAtomicOr %5 %434 %10 %41 %433\n%436 = OpBitwiseAnd %5 %435 %432\n%437 = OpIEqual %119 %436 %432\n%438 = OpLogicalAnd %119 %421 %437\nOpSelectionMerge %443 None\nOpSwitch %132 %442 0 %439 1 %440 2 %441\n%442 = OpLabel\n%451 = OpShiftLeftLogical %5 %163 %50\n%452 = OpBitwiseAnd %5 %300 %451\n%453 = OpINotEqual %119 %452 %41\nOpBranch %443\n%439 = OpLabel\n%444 = OpBitwiseAnd %5 %299 %153\n%445 = OpINotEqual %119 %444 %41\nOpBranch %443\n%440 = OpLabel\n%446 = OpShiftLeftLogical %5 %153 %57\n%447 = OpBitwiseAnd %5 %299 %446\n%448 = OpINotEqual %119 %447 %41\nOpBranch %443\n%441 = OpLabel\n%449 = OpBitwiseAnd %5 %300 %163\n%450 = OpINotEqual %119 %449 %41\nOpBranch %443\n%443 = OpLabel\n%454 = OpPhi %119 %445 %439 %448 %440 %450 %441 %453 %442\n%455 = OpLogicalNot %119 %454\n%456 = OpLogicalOr %119 %455 %438\nOpReturnValue %456\nOpFunctionEnd\n%503 = OpFunction %1 None %500\n%501 = OpFunctionParameter %119\n%502 = OpFunctionParameter %5\n%504 = OpLabel\n%507 = OpLogicalNot %119 %501\n%508 = OpLoad %119 %490\n%509 = OpLogicalAnd %119 %507 %508\nOpSelectionMerge %505 None\nOpBranchConditional %509 %506 %505\n%506 = OpLabel\n%512 = OpIMul %5 %502 %514\n%513 = OpBitwiseXor %5 %512 %515\n%516 = OpArrayLength %5 %495 0\n%517 = OpISub %5 %516 %165\n%518 = OpAccessChain %39 %495 %41 %517\n%519 = OpLoad %5 %518\n%520 = OpIMul %5 %519 %521\n%522 = OpBitwiseXor %5 %513 %520\n%523 = OpArrayLength %5 %499 0\n%524 = OpISub %5 %523 %10\n%525 = OpBitwiseAnd %5 %522 %524\n%526 = OpShiftRightLogical %5 %525 %50\n%527 = OpBitwiseAnd %5 %525 %155\n%528 = OpShiftLeftLogical %5 %10 %527\n%529 = OpAccessChain %39 %495 %41 %526\n%530 = OpAtomicOr %5 %529 %10 %41 %528\n%531 = OpBitwiseAnd %5 %530 %528\n%532 = OpIEqual %119 %531 %41\nOpStore %490 %533\nOpSelectionMerge %511 None\nOpBranchConditional %532 %510 %511\n%510 = OpLabel\n%534 = OpCompositeConstruct %491 %515 %41 %502 %519\n%535 = OpShiftLeftLogical %5 %528 %57\n%537 = OpAccessChain %536 %499 %41 %525\nOpStore %537 %534\nOpMemoryBarrier %10 %539\n%538 = OpAtomicOr %5 %529 %10 %41 %535\nOpMemoryBarrier %10 %539\nOpBranch %511\n%511 = OpLabel\nOpBranch %505\n%505 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/structured.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat3NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatArray;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nfloat _465;\n\nlayout(buffer_reference, buffer_reference_align = 4, scalar) readonly buffer PhysicalPointerFloat3NonWriteArray\n{\n    vec3 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerFloatArray\n{\n    float value[];\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _31 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _31;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _64 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _65 = uvec2(prime);\n    uvec2 _73 = ((_64 >> uvec2(8u)) ^ _64.yx) * _65;\n    uvec2 _77 = ((_73 >> uvec2(8u)) ^ _73.yx) * _65;\n    uvec2 _81 = ((_77 >> uvec2(8u)) ^ _77.yx) * _65;\n    uvec2 _85 = ((_81 >> uvec2(8u)) ^ _81.yx) * _65;\n    uvec2 _89 = ((_85 >> uvec2(8u)) ^ _85.yx) * _65;\n    return (((_89 >> uvec2(8u)) ^ _89.yx) * _65).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _122;\n    _122._m0 = uaddCarry(BDA.x, offset, _122._m1);\n    uvec2 addr = uvec2(_122._m0, BDA.y + _122._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _495 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _497 = InstrumentationControlData.atomics[_495];\n        uint _503 = (((inst * 97u) ^ 43981u) ^ (_497 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _504 = _503 >> 4u;\n        uint _506 = 1u << (_503 & 15u);\n        uint _508 = atomicOr(InstrumentationControlData.atomics[_504], _506);\n        ShouldReportInstrumentation = false;\n        if ((_508 & _506) == 0u)\n        {\n            InstrumentationData.data[_503] = uvec4(43981u, 0u, inst, _497);\n            memoryBarrierBuffer();\n            uint _516 = atomicOr(InstrumentationControlData.atomics[_504], _506 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _34 = AllocateInvocationID();\n    InvocationID = _34;\n    uint _437 = InvocationID;\n    bool _436 = ValidateBDALoadStore(registers._m1, (gl_GlobalInvocationID.x * 12u) + 0u, 12u, 0u, _437, true);\n    AssumeTrue(_436, 1u);\n    PhysicalPointerFloat3NonWriteArray _438 = PhysicalPointerFloat3NonWriteArray(registers._m1);\n    uint _453 = InvocationID;\n    bool _452 = ValidateBDALoadStore(registers._m2, (gl_GlobalInvocationID.x * 4u) + 0u, 4u, 0u, _453, true);\n    AssumeTrue(_452, 2u);\n    uint _462 = InvocationID;\n    bool _461 = ValidateBDALoadStore(registers._m2, (gl_GlobalInvocationID.x * 4u) + 0u, 4u, 1u, _462, true);\n    AssumeTrue(_461, 3u);\n    PhysicalPointerFloatArray(registers._m2).value[gl_GlobalInvocationID.x] = ((_438.value[gl_GlobalInvocationID.x].x + 40.0) + _438.value[gl_GlobalInvocationID.x].z) + PhysicalPointerFloatArray(registers._m2).value[gl_GlobalInvocationID.x];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 523\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SignedZeroInfNanPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%146 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %43\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %20 \"BloomBufferInvocationSSBO\"\nOpMemberName %20 0 \"atomics\"\nOpName %22 \"BloomBufferInvocation\"\nOpName %24 \"AllocateInvocationID\"\nOpName %50 \"PhysicalPointerFloat3NonWriteArray\"\nOpMemberName %50 0 \"value\"\nOpName %58 \"AddrHash\"\nOpName %56 \"addr\"\nOpName %57 \"prime\"\nOpName %99 \"BloomBufferSSBO\"\nOpMemberName %99 0 \"atomics\"\nOpName %101 \"BloomBuffer\"\nOpName %103 \"BloomBuffer32SSBO\"\nOpMemberName %103 0 \"atomics\"\nOpName %105 \"BloomBuffer32\"\nOpName %113 \"ValidateBDALoadStore\"\nOpName %107 \"BDA\"\nOpName %108 \"offset\"\nOpName %109 \"len\"\nOpName %110 \"type\"\nOpName %111 \"invocation_id\"\nOpName %112 \"in_bounds\"\nOpName %121 \"IAddCarryResult\"\nOpName %126 \"addr\"\nOpName %127 \"addr_lo\"\nOpName %131 \"byte_mask\"\nOpName %141 \"word_mask\"\nOpName %145 \"hash_mask\"\nOpName %150 \"hash_offset\"\nOpName %154 \"bloom_index\"\nOpName %158 \"bloom_index\"\nOpName %162 \"bloom_index\"\nOpName %165 \"bloom_index\"\nOpName %169 \"bloom_index\"\nOpName %173 \"bloom_index\"\nOpName %177 \"bloom_index\"\nOpName %181 \"bloom_index\"\nOpName %185 \"bloom_index\"\nOpName %189 \"bloom_index\"\nOpName %193 \"bloom_index\"\nOpName %197 \"bloom_index\"\nOpName %201 \"bloom_index\"\nOpName %205 \"bloom_index\"\nOpName %209 \"bloom_index\"\nOpName %213 \"bloom_index\"\nOpName %227 \"invalidation_mask\"\nOpName %230 \"prev_hazard_partial\"\nOpName %232 \"prev_hazard_partial\"\nOpName %235 \"prev_hazard_partial\"\nOpName %238 \"prev_hazard_partial\"\nOpName %241 \"prev_hazard_partial\"\nOpName %244 \"prev_hazard_partial\"\nOpName %247 \"prev_hazard_partial\"\nOpName %250 \"prev_hazard_partial\"\nOpName %253 \"prev_hazard_partial\"\nOpName %256 \"prev_hazard_partial\"\nOpName %259 \"prev_hazard_partial\"\nOpName %262 \"prev_hazard_partial\"\nOpName %265 \"prev_hazard_partial\"\nOpName %268 \"prev_hazard_partial\"\nOpName %271 \"prev_hazard_partial\"\nOpName %274 \"prev_hazard_partial\"\nOpName %276 \"prev_hazard\"\nOpName %277 \"prev_hazard_lo\"\nOpName %278 \"prev_hazard_hi\"\nOpName %281 \"has_exclusive_access\"\nOpName %296 \"lock_mask\"\nOpName %299 \"prev_lock\"\nOpName %312 \"lock_mask\"\nOpName %315 \"prev_lock\"\nOpName %329 \"lock_mask\"\nOpName %332 \"prev_lock\"\nOpName %346 \"lock_mask\"\nOpName %349 \"prev_lock\"\nOpName %363 \"lock_mask\"\nOpName %366 \"prev_lock\"\nOpName %377 \"lock_mask\"\nOpName %380 \"prev_lock\"\nOpName %393 \"lock_mask\"\nOpName %396 \"prev_lock\"\nOpName %410 \"lock_mask\"\nOpName %413 \"prev_lock\"\nOpName %416 \"has_complete_self_lock\"\nOpName %432 \"hazard\"\nOpName %448 \"PhysicalPointerFloatArray\"\nOpMemberName %448 0 \"value\"\nOpName %468 \"ShouldReportInstrumentation\"\nOpName %471 \"InstrumentationControlDataSSBO\"\nOpMemberName %471 0 \"atomics\"\nOpName %473 \"InstrumentationControlData\"\nOpName %475 \"InstrumentationDataSSBO\"\nOpMemberName %475 0 \"data\"\nOpName %477 \"InstrumentationData\"\nOpName %481 \"AssumeTrue\"\nOpName %479 \"value\"\nOpName %480 \"inst\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 2\nOpDecorate %43 BuiltIn GlobalInvocationId\nOpDecorate %49 ArrayStride 12\nOpMemberDecorate %50 0 Offset 0\nOpDecorate %50 Block\nOpMemberDecorate %50 0 NonWritable\nOpDecorate %98 ArrayStride 8\nOpMemberDecorate %99 0 Offset 0\nOpDecorate %99 Block\nOpDecorate %101 DescriptorSet 0\nOpDecorate %101 Binding 2\nOpDecorate %102 ArrayStride 8\nOpMemberDecorate %103 0 Offset 0\nOpDecorate %103 Block\nOpDecorate %105 DescriptorSet 0\nOpDecorate %105 Binding 2\nOpDecorate %447 ArrayStride 4\nOpMemberDecorate %448 0 Offset 0\nOpDecorate %448 Block\nOpDecorate %470 ArrayStride 4\nOpMemberDecorate %471 0 Offset 0\nOpDecorate %471 Block\nOpDecorate %473 DescriptorSet 0\nOpDecorate %473 Binding 2\nOpDecorate %474 ArrayStride 16\nOpMemberDecorate %475 0 Offset 0\nOpDecorate %475 Block\nOpDecorate %477 DescriptorSet 0\nOpDecorate %477 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpConstant %5 1\n%11 = OpTypeArray %6 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeFunction %5\n%28 = OpTypePointer StorageBuffer %5\n%30 = OpConstant %5 0\n%32 = OpConstant %5 1103633207\n%35 = OpTypePointer PushConstant %6\n%37 = OpConstant %5 2\n%41 = OpTypeVector %5 3\n%42 = OpTypePointer Input %41\n%43 = OpVariable %42 Input\n%44 = OpTypePointer Input %5\n%47 = OpTypeFloat 32\n%48 = OpTypeVector %47 3\n%49 = OpTypeRuntimeArray %48\n%50 = OpTypeStruct %49\n%51 = OpTypePointer PhysicalStorageBuffer %50\n%52 = OpConstant %5 12\n%55 = OpTypeFunction %5 %6 %5\n%66 = OpConstant %5 4\n%67 = OpConstant %5 65535\n%68 = OpConstant %5 8\n%69 = OpConstantComposite %6 %68 %68\n%96 = OpTypeInt 64 0\n%97 = OpTypeBool\n%98 = OpTypeRuntimeArray %96\n%99 = OpTypeStruct %98\n%100 = OpTypePointer StorageBuffer %99\n%101 = OpVariable %100 StorageBuffer\n%102 = OpTypeRuntimeArray %6\n%103 = OpTypeStruct %102\n%104 = OpTypePointer StorageBuffer %103\n%105 = OpVariable %104 StorageBuffer\n%106 = OpTypeFunction %97 %6 %5 %5 %5 %5 %97\n%117 = OpConstantTrue %97\n%121 = OpTypeStruct %5 %5\n%132 = OpConstant %5 4294967295\n%133 = OpConstant %5 15\n%142 = OpConstant %5 3\n%152 = OpConstant %5 1103515245\n%156 = OpConstant %5 1103518333\n%160 = OpConstant %5 1103539331\n%167 = OpConstant %5 10006121\n%171 = OpConstant %5 4004951\n%175 = OpConstant %5 5005159\n%179 = OpConstant %5 6004811\n%183 = OpConstant %5 383\n%187 = OpConstant %5 821\n%191 = OpConstant %5 661\n%195 = OpConstant %5 1091\n%199 = OpConstant %5 1117\n%203 = OpConstant %5 3947\n%207 = OpConstant %5 4253\n%211 = OpConstant %5 7691\n%214 = OpTypeVector %96 4\n%215 = OpConstant %96 68719411200\n%216 = OpConstant %96 1099511627775\n%217 = OpConstant %96 1035087118335\n%218 = OpConstantComposite %214 %215 %216 %217 %215\n%222 = OpConstant %5 16\n%228 = OpTypePointer StorageBuffer %96\n%283 = OpTypeInt 32 1\n%284 = OpConstant %283 0\n%285 = OpConstant %283 3\n%287 = OpConstant %5 256\n%290 = OpConstant %5 65536\n%293 = OpConstant %283 6\n%295 = OpConstant %5 16777216\n%303 = OpConstant %283 9\n%306 = OpConstant %283 12\n%310 = OpConstant %283 15\n%320 = OpConstant %283 18\n%323 = OpConstant %283 21\n%327 = OpConstant %283 24\n%337 = OpConstant %283 23\n%340 = OpConstant %283 26\n%344 = OpConstant %283 29\n%354 = OpConstant %283 1\n%357 = OpConstant %283 4\n%361 = OpConstant %283 7\n%385 = OpConstant %283 17\n%388 = OpConstant %283 20\n%401 = OpConstant %283 22\n%404 = OpConstant %283 25\n%408 = OpConstant %283 28\n%439 = OpTypePointer PhysicalStorageBuffer %48\n%445 = OpConstant %47 40\n%447 = OpTypeRuntimeArray %47\n%448 = OpTypeStruct %447\n%449 = OpTypePointer PhysicalStorageBuffer %448\n%455 = OpTypePointer PhysicalStorageBuffer %47\n%467 = OpTypePointer Private %97\n%468 = OpVariable %467 Private %117\n%469 = OpTypeVector %5 4\n%470 = OpTypeRuntimeArray %5\n%471 = OpTypeStruct %470\n%472 = OpTypePointer StorageBuffer %471\n%473 = OpVariable %472 StorageBuffer\n%474 = OpTypeRuntimeArray %469\n%475 = OpTypeStruct %474\n%476 = OpTypePointer StorageBuffer %475\n%477 = OpVariable %476 StorageBuffer\n%478 = OpTypeFunction %1 %97 %5\n%492 = OpConstant %5 97\n%493 = OpConstant %5 43981\n%499 = OpConstant %5 51329\n%511 = OpConstantFalse %97\n%514 = OpTypePointer StorageBuffer %469\n%517 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%465 = OpUndef %47\nOpBranch %466\n%466 = OpLabel\n%34 = OpFunctionCall %5 %24\nOpStore %18 %34\n%36 = OpAccessChain %35 %9 %37\n%38 = OpLoad %6 %36\n%39 = OpAccessChain %35 %9 %10\n%40 = OpLoad %6 %39\n%45 = OpAccessChain %44 %43 %30\n%46 = OpLoad %5 %45\n%53 = OpIMul %5 %46 %52\n%54 = OpIAdd %5 %53 %30\n%437 = OpLoad %5 %18\n%436 = OpFunctionCall %97 %113 %40 %54 %52 %30 %437 %117\n%519 = OpFunctionCall %1 %481 %436 %10\n%438 = OpBitcast %51 %40\n%440 = OpInBoundsAccessChain %439 %438 %30 %46\n%441 = OpLoad %48 %440 Aligned 4\n%442 = OpCompositeExtract %47 %441 0\n%443 = OpCompositeExtract %47 %441 2\n%444 = OpFAdd %47 %442 %445\n%446 = OpFAdd %47 %444 %443\n%450 = OpIMul %5 %46 %66\n%451 = OpIAdd %5 %450 %30\n%453 = OpLoad %5 %18\n%452 = OpFunctionCall %97 %113 %38 %451 %66 %30 %453 %117\n%520 = OpFunctionCall %1 %481 %452 %37\n%454 = OpBitcast %449 %38\n%456 = OpInBoundsAccessChain %455 %454 %30 %46\n%457 = OpLoad %47 %456 Aligned 4\n%458 = OpFAdd %47 %446 %457\n%459 = OpIMul %5 %46 %66\n%460 = OpIAdd %5 %459 %30\n%462 = OpLoad %5 %18\n%461 = OpFunctionCall %97 %113 %38 %460 %66 %10 %462 %117\n%521 = OpFunctionCall %1 %481 %461 %142\n%463 = OpBitcast %449 %38\n%464 = OpInBoundsAccessChain %455 %463 %30 %46\nOpStore %464 %458 Aligned 4\nOpReturn\nOpFunctionEnd\n%24 = OpFunction %5 None %23\n%25 = OpLabel\n%26 = OpArrayLength %5 %22 0\n%27 = OpISub %5 %26 %10\n%29 = OpAccessChain %28 %22 %30 %27\n%31 = OpAtomicIAdd %5 %29 %10 %30 %32\nOpReturnValue %31\nOpFunctionEnd\n%58 = OpFunction %5 None %55\n%56 = OpFunctionParameter %6\n%57 = OpFunctionParameter %5\n%59 = OpLabel\n%60 = OpCompositeExtract %5 %56 0\n%61 = OpCompositeExtract %5 %56 1\n%62 = OpShiftRightLogical %5 %60 %66\n%63 = OpBitwiseAnd %5 %61 %67\n%64 = OpCompositeConstruct %6 %62 %63\n%65 = OpCompositeConstruct %6 %57 %57\n%70 = OpVectorShuffle %6 %64 %64 1 0\n%71 = OpShiftRightLogical %6 %64 %69\n%72 = OpBitwiseXor %6 %71 %70\n%73 = OpIMul %6 %72 %65\n%74 = OpVectorShuffle %6 %73 %73 1 0\n%75 = OpShiftRightLogical %6 %73 %69\n%76 = OpBitwiseXor %6 %75 %74\n%77 = OpIMul %6 %76 %65\n%78 = OpVectorShuffle %6 %77 %77 1 0\n%79 = OpShiftRightLogical %6 %77 %69\n%80 = OpBitwiseXor %6 %79 %78\n%81 = OpIMul %6 %80 %65\n%82 = OpVectorShuffle %6 %81 %81 1 0\n%83 = OpShiftRightLogical %6 %81 %69\n%84 = OpBitwiseXor %6 %83 %82\n%85 = OpIMul %6 %84 %65\n%86 = OpVectorShuffle %6 %85 %85 1 0\n%87 = OpShiftRightLogical %6 %85 %69\n%88 = OpBitwiseXor %6 %87 %86\n%89 = OpIMul %6 %88 %65\n%90 = OpVectorShuffle %6 %89 %89 1 0\n%91 = OpShiftRightLogical %6 %89 %69\n%92 = OpBitwiseXor %6 %91 %90\n%93 = OpIMul %6 %92 %65\n%94 = OpCompositeExtract %5 %93 0\nOpReturnValue %94\nOpFunctionEnd\n%113 = OpFunction %97 None %106\n%107 = OpFunctionParameter %6\n%108 = OpFunctionParameter %5\n%109 = OpFunctionParameter %5\n%110 = OpFunctionParameter %5\n%111 = OpFunctionParameter %5\n%112 = OpFunctionParameter %97\n%114 = OpLabel\nOpSelectionMerge %116 None\nOpBranchConditional %112 %116 %115\n%115 = OpLabel\nOpReturnValue %117\n%116 = OpLabel\n%119 = OpCompositeExtract %5 %107 0\n%120 = OpCompositeExtract %5 %107 1\n%122 = OpIAddCarry %121 %119 %108\n%123 = OpCompositeExtract %5 %122 0\n%124 = OpCompositeExtract %5 %122 1\n%125 = OpIAdd %5 %120 %124\n%126 = OpCompositeConstruct %6 %123 %125\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpBitFieldUExtract %5 %132 %30 %109\n%129 = OpBitwiseAnd %5 %127 %133\n%130 = OpShiftLeftLogical %5 %128 %129\n%131 = OpBitwiseAnd %5 %130 %67\n%134 = OpBitwiseAnd %5 %127 %142\n%135 = OpIAdd %5 %134 %109\n%136 = OpIAdd %5 %135 %142\n%137 = OpShiftRightLogical %5 %136 %37\n%138 = OpBitFieldUExtract %5 %127 %37 %37\n%139 = OpBitFieldUExtract %5 %132 %30 %137\n%140 = OpShiftLeftLogical %5 %139 %138\n%141 = OpBitwiseAnd %5 %140 %133\n%143 = OpArrayLength %5 %101 0\n%144 = OpExtInst %5 %146 FindUMsb %143\n%145 = OpBitFieldUExtract %5 %132 %30 %144\n%147 = OpArrayLength %5 %101 0\n%148 = OpExtInst %5 %146 FindUMsb %147\n%149 = OpBitFieldUExtract %5 %147 %30 %148\n%150 = OpISub %5 %149 %10\n%151 = OpFunctionCall %5 %58 %126 %152\n%153 = OpBitwiseAnd %5 %151 %145\n%154 = OpIAdd %5 %153 %150\n%155 = OpFunctionCall %5 %58 %126 %156\n%157 = OpBitwiseAnd %5 %155 %145\n%158 = OpIAdd %5 %157 %150\n%159 = OpFunctionCall %5 %58 %126 %160\n%161 = OpBitwiseAnd %5 %159 %145\n%162 = OpIAdd %5 %161 %150\n%163 = OpFunctionCall %5 %58 %126 %32\n%164 = OpBitwiseAnd %5 %163 %145\n%165 = OpIAdd %5 %164 %150\n%166 = OpFunctionCall %5 %58 %126 %167\n%168 = OpBitwiseAnd %5 %166 %145\n%169 = OpIAdd %5 %168 %150\n%170 = OpFunctionCall %5 %58 %126 %171\n%172 = OpBitwiseAnd %5 %170 %145\n%173 = OpIAdd %5 %172 %150\n%174 = OpFunctionCall %5 %58 %126 %175\n%176 = OpBitwiseAnd %5 %174 %145\n%177 = OpIAdd %5 %176 %150\n%178 = OpFunctionCall %5 %58 %126 %179\n%180 = OpBitwiseAnd %5 %178 %145\n%181 = OpIAdd %5 %180 %150\n%182 = OpFunctionCall %5 %58 %126 %183\n%184 = OpBitwiseAnd %5 %182 %145\n%185 = OpIAdd %5 %184 %150\n%186 = OpFunctionCall %5 %58 %126 %187\n%188 = OpBitwiseAnd %5 %186 %145\n%189 = OpIAdd %5 %188 %150\n%190 = OpFunctionCall %5 %58 %126 %191\n%192 = OpBitwiseAnd %5 %190 %145\n%193 = OpIAdd %5 %192 %150\n%194 = OpFunctionCall %5 %58 %126 %195\n%196 = OpBitwiseAnd %5 %194 %145\n%197 = OpIAdd %5 %196 %150\n%198 = OpFunctionCall %5 %58 %126 %199\n%200 = OpBitwiseAnd %5 %198 %145\n%201 = OpIAdd %5 %200 %150\n%202 = OpFunctionCall %5 %58 %126 %203\n%204 = OpBitwiseAnd %5 %202 %145\n%205 = OpIAdd %5 %204 %150\n%206 = OpFunctionCall %5 %58 %126 %207\n%208 = OpBitwiseAnd %5 %206 %145\n%209 = OpIAdd %5 %208 %150\n%210 = OpFunctionCall %5 %58 %126 %211\n%212 = OpBitwiseAnd %5 %210 %145\n%213 = OpIAdd %5 %212 %150\n%219 = OpVectorExtractDynamic %96 %218 %110\n%220 = OpShiftLeftLogical %5 %131 %222\n%221 = OpShiftLeftLogical %5 %141 %66\n%223 = OpBitwiseOr %5 %131 %220\n%224 = OpBitwiseOr %5 %141 %221\n%225 = OpCompositeConstruct %6 %223 %224\n%226 = OpBitcast %96 %225\n%227 = OpBitwiseAnd %96 %219 %226\n%229 = OpInBoundsAccessChain %228 %101 %30 %154\n%230 = OpAtomicOr %96 %229 %10 %30 %227\n%231 = OpInBoundsAccessChain %228 %101 %30 %158\n%232 = OpAtomicOr %96 %231 %10 %30 %227\n%233 = OpBitwiseAnd %96 %230 %232\n%234 = OpInBoundsAccessChain %228 %101 %30 %162\n%235 = OpAtomicOr %96 %234 %10 %30 %227\n%236 = OpBitwiseAnd %96 %233 %235\n%237 = OpInBoundsAccessChain %228 %101 %30 %165\n%238 = OpAtomicOr %96 %237 %10 %30 %227\n%239 = OpBitwiseAnd %96 %236 %238\n%240 = OpInBoundsAccessChain %228 %101 %30 %169\n%241 = OpAtomicOr %96 %240 %10 %30 %227\n%242 = OpBitwiseAnd %96 %239 %241\n%243 = OpInBoundsAccessChain %228 %101 %30 %173\n%244 = OpAtomicOr %96 %243 %10 %30 %227\n%245 = OpBitwiseAnd %96 %242 %244\n%246 = OpInBoundsAccessChain %228 %101 %30 %177\n%247 = OpAtomicOr %96 %246 %10 %30 %227\n%248 = OpBitwiseAnd %96 %245 %247\n%249 = OpInBoundsAccessChain %228 %101 %30 %181\n%250 = OpAtomicOr %96 %249 %10 %30 %227\n%251 = OpBitwiseAnd %96 %248 %250\n%252 = OpInBoundsAccessChain %228 %101 %30 %185\n%253 = OpAtomicOr %96 %252 %10 %30 %227\n%254 = OpBitwiseAnd %96 %251 %253\n%255 = OpInBoundsAccessChain %228 %101 %30 %189\n%256 = OpAtomicOr %96 %255 %10 %30 %227\n%257 = OpBitwiseAnd %96 %254 %256\n%258 = OpInBoundsAccessChain %228 %101 %30 %193\n%259 = OpAtomicOr %96 %258 %10 %30 %227\n%260 = OpBitwiseAnd %96 %257 %259\n%261 = OpInBoundsAccessChain %228 %101 %30 %197\n%262 = OpAtomicOr %96 %261 %10 %30 %227\n%263 = OpBitwiseAnd %96 %260 %262\n%264 = OpInBoundsAccessChain %228 %101 %30 %201\n%265 = OpAtomicOr %96 %264 %10 %30 %227\n%266 = OpBitwiseAnd %96 %263 %265\n%267 = OpInBoundsAccessChain %228 %101 %30 %205\n%268 = OpAtomicOr %96 %267 %10 %30 %227\n%269 = OpBitwiseAnd %96 %266 %268\n%270 = OpInBoundsAccessChain %228 %101 %30 %209\n%271 = OpAtomicOr %96 %270 %10 %30 %227\n%272 = OpBitwiseAnd %96 %269 %271\n%273 = OpInBoundsAccessChain %228 %101 %30 %213\n%274 = OpAtomicOr %96 %273 %10 %30 %227\n%275 = OpBitwiseAnd %96 %272 %274\n%276 = OpBitcast %6 %275\n%277 = OpCompositeExtract %5 %276 0\n%278 = OpCompositeExtract %5 %276 1\n%279 = OpShiftRightLogical %5 %277 %222\n%280 = OpBitwiseAnd %5 %279 %131\n%281 = OpIEqual %97 %280 %30\n%282 = OpBitFieldUExtract %5 %111 %284 %285\n%286 = OpShiftLeftLogical %5 %287 %282\n%288 = OpBitFieldUExtract %5 %111 %285 %285\n%289 = OpShiftLeftLogical %5 %290 %288\n%291 = OpBitwiseOr %5 %286 %289\n%292 = OpBitFieldUExtract %5 %111 %293 %285\n%294 = OpShiftLeftLogical %5 %295 %292\n%296 = OpBitwiseOr %5 %291 %294\n%297 = OpSelect %5 %281 %296 %30\n%298 = OpInBoundsAccessChain %28 %105 %30 %154 %10\n%299 = OpAtomicOr %5 %298 %10 %30 %297\n%300 = OpBitwiseAnd %5 %299 %296\n%301 = OpIEqual %97 %300 %296\n%302 = OpBitFieldUExtract %5 %111 %303 %285\n%304 = OpShiftLeftLogical %5 %287 %302\n%305 = OpBitFieldUExtract %5 %111 %306 %285\n%307 = OpShiftLeftLogical %5 %290 %305\n%308 = OpBitwiseOr %5 %304 %307\n%309 = OpBitFieldUExtract %5 %111 %310 %285\n%311 = OpShiftLeftLogical %5 %295 %309\n%312 = OpBitwiseOr %5 %308 %311\n%313 = OpSelect %5 %281 %312 %30\n%314 = OpInBoundsAccessChain %28 %105 %30 %158 %10\n%315 = OpAtomicOr %5 %314 %10 %30 %313\n%316 = OpBitwiseAnd %5 %315 %312\n%317 = OpIEqual %97 %316 %312\n%318 = OpLogicalAnd %97 %301 %317\n%319 = OpBitFieldUExtract %5 %111 %320 %285\n%321 = OpShiftLeftLogical %5 %287 %319\n%322 = OpBitFieldUExtract %5 %111 %323 %285\n%324 = OpShiftLeftLogical %5 %290 %322\n%325 = OpBitwiseOr %5 %321 %324\n%326 = OpBitFieldUExtract %5 %111 %327 %285\n%328 = OpShiftLeftLogical %5 %295 %326\n%329 = OpBitwiseOr %5 %325 %328\n%330 = OpSelect %5 %281 %329 %30\n%331 = OpInBoundsAccessChain %28 %105 %30 %162 %10\n%332 = OpAtomicOr %5 %331 %10 %30 %330\n%333 = OpBitwiseAnd %5 %332 %329\n%334 = OpIEqual %97 %333 %329\n%335 = OpLogicalAnd %97 %318 %334\n%336 = OpBitFieldUExtract %5 %111 %337 %285\n%338 = OpShiftLeftLogical %5 %287 %336\n%339 = OpBitFieldUExtract %5 %111 %340 %285\n%341 = OpShiftLeftLogical %5 %290 %339\n%342 = OpBitwiseOr %5 %338 %341\n%343 = OpBitFieldUExtract %5 %111 %344 %285\n%345 = OpShiftLeftLogical %5 %295 %343\n%346 = OpBitwiseOr %5 %342 %345\n%347 = OpSelect %5 %281 %346 %30\n%348 = OpInBoundsAccessChain %28 %105 %30 %165 %10\n%349 = OpAtomicOr %5 %348 %10 %30 %347\n%350 = OpBitwiseAnd %5 %349 %346\n%351 = OpIEqual %97 %350 %346\n%352 = OpLogicalAnd %97 %335 %351\n%353 = OpBitFieldUExtract %5 %111 %354 %285\n%355 = OpShiftLeftLogical %5 %287 %353\n%356 = OpBitFieldUExtract %5 %111 %357 %285\n%358 = OpShiftLeftLogical %5 %290 %356\n%359 = OpBitwiseOr %5 %355 %358\n%360 = OpBitFieldUExtract %5 %111 %361 %285\n%362 = OpShiftLeftLogical %5 %295 %360\n%363 = OpBitwiseOr %5 %359 %362\n%364 = OpSelect %5 %281 %363 %30\n%365 = OpInBoundsAccessChain %28 %105 %30 %169 %10\n%366 = OpAtomicOr %5 %365 %10 %30 %364\n%367 = OpBitwiseAnd %5 %366 %363\n%368 = OpIEqual %97 %367 %363\n%369 = OpLogicalAnd %97 %352 %368\n%370 = OpBitFieldUExtract %5 %111 %303 %285\n%371 = OpShiftLeftLogical %5 %287 %370\n%372 = OpBitFieldUExtract %5 %111 %306 %285\n%373 = OpShiftLeftLogical %5 %290 %372\n%374 = OpBitwiseOr %5 %371 %373\n%375 = OpBitFieldUExtract %5 %111 %310 %285\n%376 = OpShiftLeftLogical %5 %295 %375\n%377 = OpBitwiseOr %5 %374 %376\n%378 = OpSelect %5 %281 %377 %30\n%379 = OpInBoundsAccessChain %28 %105 %30 %173 %10\n%380 = OpAtomicOr %5 %379 %10 %30 %378\n%381 = OpBitwiseAnd %5 %380 %377\n%382 = OpIEqual %97 %381 %377\n%383 = OpLogicalAnd %97 %369 %382\n%384 = OpBitFieldUExtract %5 %111 %385 %285\n%386 = OpShiftLeftLogical %5 %287 %384\n%387 = OpBitFieldUExtract %5 %111 %388 %285\n%389 = OpShiftLeftLogical %5 %290 %387\n%390 = OpBitwiseOr %5 %386 %389\n%391 = OpBitFieldUExtract %5 %111 %337 %285\n%392 = OpShiftLeftLogical %5 %295 %391\n%393 = OpBitwiseOr %5 %390 %392\n%394 = OpSelect %5 %281 %393 %30\n%395 = OpInBoundsAccessChain %28 %105 %30 %177 %10\n%396 = OpAtomicOr %5 %395 %10 %30 %394\n%397 = OpBitwiseAnd %5 %396 %393\n%398 = OpIEqual %97 %397 %393\n%399 = OpLogicalAnd %97 %383 %398\n%400 = OpBitFieldUExtract %5 %111 %401 %285\n%402 = OpShiftLeftLogical %5 %287 %400\n%403 = OpBitFieldUExtract %5 %111 %404 %285\n%405 = OpShiftLeftLogical %5 %290 %403\n%406 = OpBitwiseOr %5 %402 %405\n%407 = OpBitFieldUExtract %5 %111 %408 %285\n%409 = OpShiftLeftLogical %5 %295 %407\n%410 = OpBitwiseOr %5 %406 %409\n%411 = OpSelect %5 %281 %410 %30\n%412 = OpInBoundsAccessChain %28 %105 %30 %181 %10\n%413 = OpAtomicOr %5 %412 %10 %30 %411\n%414 = OpBitwiseAnd %5 %413 %410\n%415 = OpIEqual %97 %414 %410\n%416 = OpLogicalAnd %97 %399 %415\nOpSelectionMerge %421 None\nOpSwitch %110 %420 0 %417 1 %418 2 %419\n%420 = OpLabel\n%429 = OpShiftLeftLogical %5 %141 %66\n%430 = OpBitwiseAnd %5 %278 %429\n%431 = OpINotEqual %97 %430 %30\nOpBranch %421\n%417 = OpLabel\n%422 = OpBitwiseAnd %5 %277 %131\n%423 = OpINotEqual %97 %422 %30\nOpBranch %421\n%418 = OpLabel\n%424 = OpShiftLeftLogical %5 %131 %222\n%425 = OpBitwiseAnd %5 %277 %424\n%426 = OpINotEqual %97 %425 %30\nOpBranch %421\n%419 = OpLabel\n%427 = OpBitwiseAnd %5 %278 %141\n%428 = OpINotEqual %97 %427 %30\nOpBranch %421\n%421 = OpLabel\n%432 = OpPhi %97 %423 %417 %426 %418 %428 %419 %431 %420\n%433 = OpLogicalNot %97 %432\n%434 = OpLogicalOr %97 %433 %416\nOpReturnValue %434\nOpFunctionEnd\n%481 = OpFunction %1 None %478\n%479 = OpFunctionParameter %97\n%480 = OpFunctionParameter %5\n%482 = OpLabel\n%485 = OpLogicalNot %97 %479\n%486 = OpLoad %97 %468\n%487 = OpLogicalAnd %97 %485 %486\nOpSelectionMerge %483 None\nOpBranchConditional %487 %484 %483\n%484 = OpLabel\n%490 = OpIMul %5 %480 %492\n%491 = OpBitwiseXor %5 %490 %493\n%494 = OpArrayLength %5 %473 0\n%495 = OpISub %5 %494 %37\n%496 = OpAccessChain %28 %473 %30 %495\n%497 = OpLoad %5 %496\n%498 = OpIMul %5 %497 %499\n%500 = OpBitwiseXor %5 %491 %498\n%501 = OpArrayLength %5 %477 0\n%502 = OpISub %5 %501 %10\n%503 = OpBitwiseAnd %5 %500 %502\n%504 = OpShiftRightLogical %5 %503 %66\n%505 = OpBitwiseAnd %5 %503 %133\n%506 = OpShiftLeftLogical %5 %10 %505\n%507 = OpAccessChain %28 %473 %30 %504\n%508 = OpAtomicOr %5 %507 %10 %30 %506\n%509 = OpBitwiseAnd %5 %508 %506\n%510 = OpIEqual %97 %509 %30\nOpStore %468 %511\nOpSelectionMerge %489 None\nOpBranchConditional %510 %488 %489\n%488 = OpLabel\n%512 = OpCompositeConstruct %469 %493 %30 %480 %497\n%513 = OpShiftLeftLogical %5 %506 %222\n%515 = OpAccessChain %514 %477 %30 %503\nOpStore %515 %512\nOpMemoryBarrier %10 %517\n%516 = OpAtomicOr %5 %507 %10 %30 %513\nOpMemoryBarrier %10 %517\nOpBranch %489\n%489 = OpLabel\nOpBranch %483\n%483 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/instrumentation/typed.bindless.bda-instrumentation.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[1];\n};\n\nstruct IAddCarryResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) buffer DescriptorHeapRobustnessSSBO\n{\n    DescriptorHeapRawPayload descriptors[];\n} DescriptorHeapRobustness;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferInvocationSSBO\n{\n    uint atomics[];\n} BloomBufferInvocation;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBufferSSBO\n{\n    uint64_t atomics[];\n} BloomBuffer;\n\nlayout(set = 0, binding = 2, std430) buffer BloomBuffer32SSBO\n{\n    uvec2 atomics[];\n} BloomBuffer32;\n\nlayout(set = 0, binding = 2, std430) buffer InstrumentationControlDataSSBO\n{\n    uint atomics[];\n} InstrumentationControlData;\n\nlayout(set = 0, binding = 3, std430) buffer InstrumentationDataSSBO\n{\n    uvec4 data[];\n} InstrumentationData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 1, binding = 0) uniform samplerBuffer _23[];\nlayout(set = 4, binding = 0, r32f) uniform imageBuffer _27[];\n\nuint InvocationID;\nbool ShouldReportInstrumentation = true;\n\nuint AllocateInvocationID()\n{\n    uint _40 = atomicAdd(BloomBufferInvocation.atomics[uint(BloomBufferInvocation.atomics.length()) - 1u], 1103633207u);\n    return _40;\n}\n\nuint AddrHash(uvec2 addr, uint prime)\n{\n    uvec2 _84 = uvec2(addr.x >> 4u, addr.y & 65535u);\n    uvec2 _85 = uvec2(prime);\n    uvec2 _92 = ((_84 >> uvec2(8u)) ^ _84.yx) * _85;\n    uvec2 _96 = ((_92 >> uvec2(8u)) ^ _92.yx) * _85;\n    uvec2 _100 = ((_96 >> uvec2(8u)) ^ _96.yx) * _85;\n    uvec2 _104 = ((_100 >> uvec2(8u)) ^ _100.yx) * _85;\n    uvec2 _108 = ((_104 >> uvec2(8u)) ^ _104.yx) * _85;\n    return (((_108 >> uvec2(8u)) ^ _108.yx) * _85).x;\n}\n\nbool ValidateBDALoadStore(uvec2 BDA, uint offset, uint len, uint type, uint invocation_id, bool in_bounds)\n{\n    if (!in_bounds)\n    {\n        return true;\n    }\n    IAddCarryResult _141;\n    _141._m0 = uaddCarry(BDA.x, offset, _141._m1);\n    uvec2 addr = uvec2(_141._m0, BDA.y + _141._m1);\n    uint addr_lo = addr.x;\n    uint byte_mask = (bitfieldExtract(4294967295u, int(0u), int(len)) << (addr_lo & 15u)) & 65535u;\n    uint word_mask = (bitfieldExtract(4294967295u, int(0u), int((((addr_lo & 3u) + len) + 3u) >> 2u)) << bitfieldExtract(addr_lo, int(2u), int(2u))) & 15u;\n    uint hash_mask = bitfieldExtract(4294967295u, int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length())))));\n    uint hash_offset = bitfieldExtract(uint(BloomBuffer.atomics.length()), int(0u), int(uint(findMSB(uint(BloomBuffer.atomics.length()))))) - 1u;\n    uint bloom_index = (AddrHash(addr, 1103515245u) & hash_mask) + hash_offset;\n    uint bloom_index_1 = (AddrHash(addr, 1103518333u) & hash_mask) + hash_offset;\n    uint bloom_index_2 = (AddrHash(addr, 1103539331u) & hash_mask) + hash_offset;\n    uint bloom_index_3 = (AddrHash(addr, 1103633207u) & hash_mask) + hash_offset;\n    uint bloom_index_4 = (AddrHash(addr, 10006121u) & hash_mask) + hash_offset;\n    uint bloom_index_5 = (AddrHash(addr, 4004951u) & hash_mask) + hash_offset;\n    uint bloom_index_6 = (AddrHash(addr, 5005159u) & hash_mask) + hash_offset;\n    uint bloom_index_7 = (AddrHash(addr, 6004811u) & hash_mask) + hash_offset;\n    uint64_t invalidation_mask = u64vec4(68719411200ul, 1099511627775ul, 1035087118335ul, 68719411200ul)[type] & packUint2x32(uvec2(byte_mask | (byte_mask << 16u), word_mask | (word_mask << 4u)));\n    uint64_t prev_hazard_partial = atomicOr(BloomBuffer.atomics[bloom_index], invalidation_mask);\n    uint64_t prev_hazard_partial_1 = atomicOr(BloomBuffer.atomics[bloom_index_1], invalidation_mask);\n    uint64_t prev_hazard_partial_2 = atomicOr(BloomBuffer.atomics[bloom_index_2], invalidation_mask);\n    uint64_t prev_hazard_partial_3 = atomicOr(BloomBuffer.atomics[bloom_index_3], invalidation_mask);\n    uint64_t prev_hazard_partial_4 = atomicOr(BloomBuffer.atomics[bloom_index_4], invalidation_mask);\n    uint64_t prev_hazard_partial_5 = atomicOr(BloomBuffer.atomics[bloom_index_5], invalidation_mask);\n    uint64_t prev_hazard_partial_6 = atomicOr(BloomBuffer.atomics[bloom_index_6], invalidation_mask);\n    uint64_t prev_hazard_partial_7 = atomicOr(BloomBuffer.atomics[bloom_index_7], invalidation_mask);\n    uint64_t prev_hazard_partial_8 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 383u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_9 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 821u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_10 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 661u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_11 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1091u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_12 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 1117u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_13 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 3947u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_14 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 4253u) & hash_mask) + hash_offset], invalidation_mask);\n    uint64_t prev_hazard_partial_15 = atomicOr(BloomBuffer.atomics[(AddrHash(addr, 7691u) & hash_mask) + hash_offset], invalidation_mask);\n    uvec2 prev_hazard = unpackUint2x32(((((((((((((((prev_hazard_partial & prev_hazard_partial_1) & prev_hazard_partial_2) & prev_hazard_partial_3) & prev_hazard_partial_4) & prev_hazard_partial_5) & prev_hazard_partial_6) & prev_hazard_partial_7) & prev_hazard_partial_8) & prev_hazard_partial_9) & prev_hazard_partial_10) & prev_hazard_partial_11) & prev_hazard_partial_12) & prev_hazard_partial_13) & prev_hazard_partial_14) & prev_hazard_partial_15);\n    uint prev_hazard_lo = prev_hazard.x;\n    uint prev_hazard_hi = prev_hazard.y;\n    bool has_exclusive_access = ((prev_hazard_lo >> 16u) & byte_mask) == 0u;\n    uint lock_mask = ((256u << bitfieldExtract(invocation_id, 0, 3)) | (65536u << bitfieldExtract(invocation_id, 3, 3))) | (16777216u << bitfieldExtract(invocation_id, 6, 3));\n    uint prev_lock = atomicOr(BloomBuffer32.atomics[bloom_index].y, has_exclusive_access ? lock_mask : 0u);\n    uint lock_mask_1 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_1 = atomicOr(BloomBuffer32.atomics[bloom_index_1].y, has_exclusive_access ? lock_mask_1 : 0u);\n    uint lock_mask_2 = ((256u << bitfieldExtract(invocation_id, 18, 3)) | (65536u << bitfieldExtract(invocation_id, 21, 3))) | (16777216u << bitfieldExtract(invocation_id, 24, 3));\n    uint prev_lock_2 = atomicOr(BloomBuffer32.atomics[bloom_index_2].y, has_exclusive_access ? lock_mask_2 : 0u);\n    uint lock_mask_3 = ((256u << bitfieldExtract(invocation_id, 23, 3)) | (65536u << bitfieldExtract(invocation_id, 26, 3))) | (16777216u << bitfieldExtract(invocation_id, 29, 3));\n    uint prev_lock_3 = atomicOr(BloomBuffer32.atomics[bloom_index_3].y, has_exclusive_access ? lock_mask_3 : 0u);\n    uint lock_mask_4 = ((256u << bitfieldExtract(invocation_id, 1, 3)) | (65536u << bitfieldExtract(invocation_id, 4, 3))) | (16777216u << bitfieldExtract(invocation_id, 7, 3));\n    uint prev_lock_4 = atomicOr(BloomBuffer32.atomics[bloom_index_4].y, has_exclusive_access ? lock_mask_4 : 0u);\n    uint lock_mask_5 = ((256u << bitfieldExtract(invocation_id, 9, 3)) | (65536u << bitfieldExtract(invocation_id, 12, 3))) | (16777216u << bitfieldExtract(invocation_id, 15, 3));\n    uint prev_lock_5 = atomicOr(BloomBuffer32.atomics[bloom_index_5].y, has_exclusive_access ? lock_mask_5 : 0u);\n    uint lock_mask_6 = ((256u << bitfieldExtract(invocation_id, 17, 3)) | (65536u << bitfieldExtract(invocation_id, 20, 3))) | (16777216u << bitfieldExtract(invocation_id, 23, 3));\n    uint prev_lock_6 = atomicOr(BloomBuffer32.atomics[bloom_index_6].y, has_exclusive_access ? lock_mask_6 : 0u);\n    uint lock_mask_7 = ((256u << bitfieldExtract(invocation_id, 22, 3)) | (65536u << bitfieldExtract(invocation_id, 25, 3))) | (16777216u << bitfieldExtract(invocation_id, 28, 3));\n    uint prev_lock_7 = atomicOr(BloomBuffer32.atomics[bloom_index_7].y, has_exclusive_access ? lock_mask_7 : 0u);\n    bool hazard;\n    switch (type)\n    {\n        case 0u:\n        {\n            hazard = (prev_hazard_lo & byte_mask) != 0u;\n            break;\n        }\n        case 1u:\n        {\n            hazard = (prev_hazard_lo & (byte_mask << 16u)) != 0u;\n            break;\n        }\n        case 2u:\n        {\n            hazard = (prev_hazard_hi & word_mask) != 0u;\n            break;\n        }\n        default:\n        {\n            hazard = (prev_hazard_hi & (word_mask << 4u)) != 0u;\n            break;\n        }\n    }\n    return (!hazard) || (((((((((prev_lock & lock_mask) == lock_mask) && ((prev_lock_1 & lock_mask_1) == lock_mask_1)) && ((prev_lock_2 & lock_mask_2) == lock_mask_2)) && ((prev_lock_3 & lock_mask_3) == lock_mask_3)) && ((prev_lock_4 & lock_mask_4) == lock_mask_4)) && ((prev_lock_5 & lock_mask_5) == lock_mask_5)) && ((prev_lock_6 & lock_mask_6) == lock_mask_6)) && ((prev_lock_7 & lock_mask_7) == lock_mask_7));\n}\n\nvoid AssumeTrue(bool value, uint inst)\n{\n    if ((!value) && ShouldReportInstrumentation)\n    {\n        uint _506 = uint(InstrumentationControlData.atomics.length()) - 2u;\n        uint _508 = InstrumentationControlData.atomics[_506];\n        uint _514 = (((inst * 97u) ^ 43981u) ^ (_508 * 51329u)) & (uint(InstrumentationData.data.length()) - 1u);\n        uint _515 = _514 >> 4u;\n        uint _517 = 1u << (_514 & 15u);\n        uint _519 = atomicOr(InstrumentationControlData.atomics[_515], _517);\n        ShouldReportInstrumentation = false;\n        if ((_519 & _517) == 0u)\n        {\n            InstrumentationData.data[_514] = uvec4(43981u, 0u, inst, _508);\n            memoryBarrierBuffer();\n            uint _527 = atomicOr(InstrumentationControlData.atomics[_515], _517 << 16u);\n            memoryBarrierBuffer();\n        }\n    }\n}\n\nvoid main()\n{\n    uint _43 = AllocateInvocationID();\n    InvocationID = _43;\n    uvec2 _52 = DescriptorHeapRobustness.descriptors[registers._m4]._m0[0u];\n    uint _54 = _52.y >> 16u;\n    uint _57 = uint(imageSize(_27[registers._m4]));\n    uvec2 _63 = DescriptorHeapRobustness.descriptors[registers._m1]._m0[0u];\n    uint _65 = _63.y >> 16u;\n    uint _456 = InvocationID;\n    bool _455 = ValidateBDALoadStore(_63, gl_GlobalInvocationID.x * _65, _65, 0u, _456, gl_GlobalInvocationID.x < uint(textureSize(_23[registers._m1])));\n    AssumeTrue(_455, 1u);\n    vec4 _459 = texelFetch(_23[registers._m1], int(gl_GlobalInvocationID.x));\n    uint _467 = InvocationID;\n    bool _466 = ValidateBDALoadStore(_52, gl_GlobalInvocationID.x * _54, _54, 0u, _467, gl_GlobalInvocationID.x < _57);\n    AssumeTrue(_466, 2u);\n    vec4 _469 = imageLoad(_27[registers._m4], int(gl_GlobalInvocationID.x));\n    uint _474 = InvocationID;\n    bool _473 = ValidateBDALoadStore(_52, gl_GlobalInvocationID.x * _54, _54, 1u, _474, gl_GlobalInvocationID.x < _57);\n    AssumeTrue(_473, 3u);\n    imageStore(_27[registers._m4], int(gl_GlobalInvocationID.x), vec4(((_459.x + 40.0) + _459.z) + _469.x));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 534\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability StorageImageWriteWithoutFormat\nOpCapability SignedZeroInfNanPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%166 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %70\nOpExecutionMode %3 SignedZeroInfNanPreserve 32\nOpExecutionMode %3 SignedZeroInfNanPreserve 64\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"DescriptorHeapRawPayload\"\nOpName %14 \"DescriptorHeapRobustnessSSBO\"\nOpMemberName %14 0 \"descriptors\"\nOpName %16 \"DescriptorHeapRobustness\"\nOpName %18 \"InvocationID\"\nOpName %29 \"BloomBufferInvocationSSBO\"\nOpMemberName %29 0 \"atomics\"\nOpName %31 \"BloomBufferInvocation\"\nOpName %33 \"AllocateInvocationID\"\nOpName %78 \"AddrHash\"\nOpName %76 \"addr\"\nOpName %77 \"prime\"\nOpName %118 \"BloomBufferSSBO\"\nOpMemberName %118 0 \"atomics\"\nOpName %120 \"BloomBuffer\"\nOpName %122 \"BloomBuffer32SSBO\"\nOpMemberName %122 0 \"atomics\"\nOpName %124 \"BloomBuffer32\"\nOpName %132 \"ValidateBDALoadStore\"\nOpName %126 \"BDA\"\nOpName %127 \"offset\"\nOpName %128 \"len\"\nOpName %129 \"type\"\nOpName %130 \"invocation_id\"\nOpName %131 \"in_bounds\"\nOpName %140 \"IAddCarryResult\"\nOpName %145 \"addr\"\nOpName %146 \"addr_lo\"\nOpName %150 \"byte_mask\"\nOpName %160 \"word_mask\"\nOpName %165 \"hash_mask\"\nOpName %170 \"hash_offset\"\nOpName %174 \"bloom_index\"\nOpName %178 \"bloom_index\"\nOpName %182 \"bloom_index\"\nOpName %185 \"bloom_index\"\nOpName %189 \"bloom_index\"\nOpName %193 \"bloom_index\"\nOpName %197 \"bloom_index\"\nOpName %201 \"bloom_index\"\nOpName %205 \"bloom_index\"\nOpName %209 \"bloom_index\"\nOpName %213 \"bloom_index\"\nOpName %217 \"bloom_index\"\nOpName %221 \"bloom_index\"\nOpName %225 \"bloom_index\"\nOpName %229 \"bloom_index\"\nOpName %233 \"bloom_index\"\nOpName %246 \"invalidation_mask\"\nOpName %249 \"prev_hazard_partial\"\nOpName %251 \"prev_hazard_partial\"\nOpName %254 \"prev_hazard_partial\"\nOpName %257 \"prev_hazard_partial\"\nOpName %260 \"prev_hazard_partial\"\nOpName %263 \"prev_hazard_partial\"\nOpName %266 \"prev_hazard_partial\"\nOpName %269 \"prev_hazard_partial\"\nOpName %272 \"prev_hazard_partial\"\nOpName %275 \"prev_hazard_partial\"\nOpName %278 \"prev_hazard_partial\"\nOpName %281 \"prev_hazard_partial\"\nOpName %284 \"prev_hazard_partial\"\nOpName %287 \"prev_hazard_partial\"\nOpName %290 \"prev_hazard_partial\"\nOpName %293 \"prev_hazard_partial\"\nOpName %295 \"prev_hazard\"\nOpName %296 \"prev_hazard_lo\"\nOpName %297 \"prev_hazard_hi\"\nOpName %300 \"has_exclusive_access\"\nOpName %315 \"lock_mask\"\nOpName %318 \"prev_lock\"\nOpName %331 \"lock_mask\"\nOpName %334 \"prev_lock\"\nOpName %348 \"lock_mask\"\nOpName %351 \"prev_lock\"\nOpName %365 \"lock_mask\"\nOpName %368 \"prev_lock\"\nOpName %382 \"lock_mask\"\nOpName %385 \"prev_lock\"\nOpName %396 \"lock_mask\"\nOpName %399 \"prev_lock\"\nOpName %412 \"lock_mask\"\nOpName %415 \"prev_lock\"\nOpName %429 \"lock_mask\"\nOpName %432 \"prev_lock\"\nOpName %435 \"has_complete_self_lock\"\nOpName %451 \"hazard\"\nOpName %479 \"ShouldReportInstrumentation\"\nOpName %482 \"InstrumentationControlDataSSBO\"\nOpMemberName %482 0 \"atomics\"\nOpName %484 \"InstrumentationControlData\"\nOpName %486 \"InstrumentationDataSSBO\"\nOpMemberName %486 0 \"data\"\nOpName %488 \"InstrumentationData\"\nOpName %492 \"AssumeTrue\"\nOpName %490 \"value\"\nOpName %491 \"inst\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %13 ArrayStride 8\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %23 DescriptorSet 1\nOpDecorate %23 Binding 0\nOpDecorate %27 DescriptorSet 4\nOpDecorate %27 Binding 0\nOpDecorate %28 ArrayStride 4\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 2\nOpDecorate %70 BuiltIn GlobalInvocationId\nOpDecorate %117 ArrayStride 8\nOpMemberDecorate %118 0 Offset 0\nOpDecorate %118 Block\nOpDecorate %120 DescriptorSet 0\nOpDecorate %120 Binding 2\nOpDecorate %121 ArrayStride 8\nOpMemberDecorate %122 0 Offset 0\nOpDecorate %122 Block\nOpDecorate %124 DescriptorSet 0\nOpDecorate %124 Binding 2\nOpDecorate %481 ArrayStride 4\nOpMemberDecorate %482 0 Offset 0\nOpDecorate %482 Block\nOpDecorate %484 DescriptorSet 0\nOpDecorate %484 Binding 2\nOpDecorate %485 ArrayStride 16\nOpMemberDecorate %486 0 Offset 0\nOpDecorate %486 Block\nOpDecorate %488 DescriptorSet 0\nOpDecorate %488 Binding 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpConstant %5 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Private %5\n%18 = OpVariable %17 Private\n%19 = OpTypeFloat 32\n%20 = OpTypeImage %19 Buffer 0 0 0 1 Unknown\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %19 Buffer 0 0 0 2 R32f\n%25 = OpTypeRuntimeArray %24\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeRuntimeArray %5\n%29 = OpTypeStruct %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeFunction %5\n%37 = OpTypePointer StorageBuffer %5\n%39 = OpConstant %5 0\n%41 = OpConstant %5 1103633207\n%44 = OpTypePointer UniformConstant %24\n%46 = OpTypePointer PushConstant %5\n%48 = OpConstant %5 4\n%50 = OpTypePointer StorageBuffer %9\n%55 = OpConstant %5 16\n%58 = OpTypePointer UniformConstant %20\n%68 = OpTypeVector %5 3\n%69 = OpTypePointer Input %68\n%70 = OpVariable %69 Input\n%71 = OpTypePointer Input %5\n%75 = OpTypeFunction %5 %9 %5\n%86 = OpConstant %5 65535\n%87 = OpConstant %5 8\n%88 = OpConstantComposite %9 %87 %87\n%115 = OpTypeInt 64 0\n%116 = OpTypeBool\n%117 = OpTypeRuntimeArray %115\n%118 = OpTypeStruct %117\n%119 = OpTypePointer StorageBuffer %118\n%120 = OpVariable %119 StorageBuffer\n%121 = OpTypeRuntimeArray %9\n%122 = OpTypeStruct %121\n%123 = OpTypePointer StorageBuffer %122\n%124 = OpVariable %123 StorageBuffer\n%125 = OpTypeFunction %116 %9 %5 %5 %5 %5 %116\n%136 = OpConstantTrue %116\n%140 = OpTypeStruct %5 %5\n%151 = OpConstant %5 4294967295\n%152 = OpConstant %5 15\n%161 = OpConstant %5 3\n%162 = OpConstant %5 2\n%172 = OpConstant %5 1103515245\n%176 = OpConstant %5 1103518333\n%180 = OpConstant %5 1103539331\n%187 = OpConstant %5 10006121\n%191 = OpConstant %5 4004951\n%195 = OpConstant %5 5005159\n%199 = OpConstant %5 6004811\n%203 = OpConstant %5 383\n%207 = OpConstant %5 821\n%211 = OpConstant %5 661\n%215 = OpConstant %5 1091\n%219 = OpConstant %5 1117\n%223 = OpConstant %5 3947\n%227 = OpConstant %5 4253\n%231 = OpConstant %5 7691\n%234 = OpTypeVector %115 4\n%235 = OpConstant %115 68719411200\n%236 = OpConstant %115 1099511627775\n%237 = OpConstant %115 1035087118335\n%238 = OpConstantComposite %234 %235 %236 %237 %235\n%247 = OpTypePointer StorageBuffer %115\n%302 = OpTypeInt 32 1\n%303 = OpConstant %302 0\n%304 = OpConstant %302 3\n%306 = OpConstant %5 256\n%309 = OpConstant %5 65536\n%312 = OpConstant %302 6\n%314 = OpConstant %5 16777216\n%322 = OpConstant %302 9\n%325 = OpConstant %302 12\n%329 = OpConstant %302 15\n%339 = OpConstant %302 18\n%342 = OpConstant %302 21\n%346 = OpConstant %302 24\n%356 = OpConstant %302 23\n%359 = OpConstant %302 26\n%363 = OpConstant %302 29\n%373 = OpConstant %302 1\n%376 = OpConstant %302 4\n%380 = OpConstant %302 7\n%404 = OpConstant %302 17\n%407 = OpConstant %302 20\n%420 = OpConstant %302 22\n%423 = OpConstant %302 25\n%427 = OpConstant %302 28\n%458 = OpTypeVector %19 4\n%463 = OpConstant %19 40\n%478 = OpTypePointer Private %116\n%479 = OpVariable %478 Private %136\n%480 = OpTypeVector %5 4\n%481 = OpTypeRuntimeArray %5\n%482 = OpTypeStruct %481\n%483 = OpTypePointer StorageBuffer %482\n%484 = OpVariable %483 StorageBuffer\n%485 = OpTypeRuntimeArray %480\n%486 = OpTypeStruct %485\n%487 = OpTypePointer StorageBuffer %486\n%488 = OpVariable %487 StorageBuffer\n%489 = OpTypeFunction %1 %116 %5\n%503 = OpConstant %5 97\n%504 = OpConstant %5 43981\n%510 = OpConstant %5 51329\n%522 = OpConstantFalse %116\n%525 = OpTypePointer StorageBuffer %480\n%528 = OpConstant %5 72\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %477\n%477 = OpLabel\n%43 = OpFunctionCall %5 %33\nOpStore %18 %43\n%47 = OpAccessChain %46 %8 %48\n%49 = OpLoad %5 %47\n%51 = OpAccessChain %50 %16 %39 %49 %39 %39\n%52 = OpLoad %9 %51\n%53 = OpCompositeExtract %5 %52 1\n%54 = OpShiftRightLogical %5 %53 %55\n%45 = OpAccessChain %44 %27 %49\n%56 = OpLoad %24 %45\n%57 = OpImageQuerySize %5 %56\n%60 = OpAccessChain %46 %8 %10\n%61 = OpLoad %5 %60\n%62 = OpAccessChain %50 %16 %39 %61 %39 %39\n%63 = OpLoad %9 %62\n%64 = OpCompositeExtract %5 %63 1\n%65 = OpShiftRightLogical %5 %64 %55\n%59 = OpAccessChain %58 %23 %61\n%66 = OpLoad %20 %59\n%67 = OpImageQuerySize %5 %66\n%72 = OpAccessChain %71 %70 %39\n%73 = OpLoad %5 %72\n%74 = OpIMul %5 %73 %65\n%456 = OpLoad %5 %18\n%457 = OpULessThan %116 %73 %67\n%455 = OpFunctionCall %116 %132 %63 %74 %65 %39 %456 %457\n%530 = OpFunctionCall %1 %492 %455 %10\n%459 = OpImageFetch %458 %66 %73\n%460 = OpCompositeExtract %19 %459 0\n%461 = OpCompositeExtract %19 %459 2\n%462 = OpFAdd %19 %460 %463\n%464 = OpFAdd %19 %462 %461\n%465 = OpIMul %5 %73 %54\n%467 = OpLoad %5 %18\n%468 = OpULessThan %116 %73 %57\n%466 = OpFunctionCall %116 %132 %52 %465 %54 %39 %467 %468\n%531 = OpFunctionCall %1 %492 %466 %162\n%469 = OpImageRead %458 %56 %73\n%470 = OpCompositeExtract %19 %469 0\n%471 = OpFAdd %19 %464 %470\n%472 = OpIMul %5 %73 %54\n%474 = OpLoad %5 %18\n%475 = OpULessThan %116 %73 %57\n%473 = OpFunctionCall %116 %132 %52 %472 %54 %10 %474 %475\n%532 = OpFunctionCall %1 %492 %473 %161\n%476 = OpCompositeConstruct %458 %471 %471 %471 %471\nOpImageWrite %56 %73 %476\nOpReturn\nOpFunctionEnd\n%33 = OpFunction %5 None %32\n%34 = OpLabel\n%35 = OpArrayLength %5 %31 0\n%36 = OpISub %5 %35 %10\n%38 = OpAccessChain %37 %31 %39 %36\n%40 = OpAtomicIAdd %5 %38 %10 %39 %41\nOpReturnValue %40\nOpFunctionEnd\n%78 = OpFunction %5 None %75\n%76 = OpFunctionParameter %9\n%77 = OpFunctionParameter %5\n%79 = OpLabel\n%80 = OpCompositeExtract %5 %76 0\n%81 = OpCompositeExtract %5 %76 1\n%82 = OpShiftRightLogical %5 %80 %48\n%83 = OpBitwiseAnd %5 %81 %86\n%84 = OpCompositeConstruct %9 %82 %83\n%85 = OpCompositeConstruct %9 %77 %77\n%89 = OpVectorShuffle %9 %84 %84 1 0\n%90 = OpShiftRightLogical %9 %84 %88\n%91 = OpBitwiseXor %9 %90 %89\n%92 = OpIMul %9 %91 %85\n%93 = OpVectorShuffle %9 %92 %92 1 0\n%94 = OpShiftRightLogical %9 %92 %88\n%95 = OpBitwiseXor %9 %94 %93\n%96 = OpIMul %9 %95 %85\n%97 = OpVectorShuffle %9 %96 %96 1 0\n%98 = OpShiftRightLogical %9 %96 %88\n%99 = OpBitwiseXor %9 %98 %97\n%100 = OpIMul %9 %99 %85\n%101 = OpVectorShuffle %9 %100 %100 1 0\n%102 = OpShiftRightLogical %9 %100 %88\n%103 = OpBitwiseXor %9 %102 %101\n%104 = OpIMul %9 %103 %85\n%105 = OpVectorShuffle %9 %104 %104 1 0\n%106 = OpShiftRightLogical %9 %104 %88\n%107 = OpBitwiseXor %9 %106 %105\n%108 = OpIMul %9 %107 %85\n%109 = OpVectorShuffle %9 %108 %108 1 0\n%110 = OpShiftRightLogical %9 %108 %88\n%111 = OpBitwiseXor %9 %110 %109\n%112 = OpIMul %9 %111 %85\n%113 = OpCompositeExtract %5 %112 0\nOpReturnValue %113\nOpFunctionEnd\n%132 = OpFunction %116 None %125\n%126 = OpFunctionParameter %9\n%127 = OpFunctionParameter %5\n%128 = OpFunctionParameter %5\n%129 = OpFunctionParameter %5\n%130 = OpFunctionParameter %5\n%131 = OpFunctionParameter %116\n%133 = OpLabel\nOpSelectionMerge %135 None\nOpBranchConditional %131 %135 %134\n%134 = OpLabel\nOpReturnValue %136\n%135 = OpLabel\n%138 = OpCompositeExtract %5 %126 0\n%139 = OpCompositeExtract %5 %126 1\n%141 = OpIAddCarry %140 %138 %127\n%142 = OpCompositeExtract %5 %141 0\n%143 = OpCompositeExtract %5 %141 1\n%144 = OpIAdd %5 %139 %143\n%145 = OpCompositeConstruct %9 %142 %144\n%146 = OpCompositeExtract %5 %145 0\n%147 = OpBitFieldUExtract %5 %151 %39 %128\n%148 = OpBitwiseAnd %5 %146 %152\n%149 = OpShiftLeftLogical %5 %147 %148\n%150 = OpBitwiseAnd %5 %149 %86\n%153 = OpBitwiseAnd %5 %146 %161\n%154 = OpIAdd %5 %153 %128\n%155 = OpIAdd %5 %154 %161\n%156 = OpShiftRightLogical %5 %155 %162\n%157 = OpBitFieldUExtract %5 %146 %162 %162\n%158 = OpBitFieldUExtract %5 %151 %39 %156\n%159 = OpShiftLeftLogical %5 %158 %157\n%160 = OpBitwiseAnd %5 %159 %152\n%163 = OpArrayLength %5 %120 0\n%164 = OpExtInst %5 %166 FindUMsb %163\n%165 = OpBitFieldUExtract %5 %151 %39 %164\n%167 = OpArrayLength %5 %120 0\n%168 = OpExtInst %5 %166 FindUMsb %167\n%169 = OpBitFieldUExtract %5 %167 %39 %168\n%170 = OpISub %5 %169 %10\n%171 = OpFunctionCall %5 %78 %145 %172\n%173 = OpBitwiseAnd %5 %171 %165\n%174 = OpIAdd %5 %173 %170\n%175 = OpFunctionCall %5 %78 %145 %176\n%177 = OpBitwiseAnd %5 %175 %165\n%178 = OpIAdd %5 %177 %170\n%179 = OpFunctionCall %5 %78 %145 %180\n%181 = OpBitwiseAnd %5 %179 %165\n%182 = OpIAdd %5 %181 %170\n%183 = OpFunctionCall %5 %78 %145 %41\n%184 = OpBitwiseAnd %5 %183 %165\n%185 = OpIAdd %5 %184 %170\n%186 = OpFunctionCall %5 %78 %145 %187\n%188 = OpBitwiseAnd %5 %186 %165\n%189 = OpIAdd %5 %188 %170\n%190 = OpFunctionCall %5 %78 %145 %191\n%192 = OpBitwiseAnd %5 %190 %165\n%193 = OpIAdd %5 %192 %170\n%194 = OpFunctionCall %5 %78 %145 %195\n%196 = OpBitwiseAnd %5 %194 %165\n%197 = OpIAdd %5 %196 %170\n%198 = OpFunctionCall %5 %78 %145 %199\n%200 = OpBitwiseAnd %5 %198 %165\n%201 = OpIAdd %5 %200 %170\n%202 = OpFunctionCall %5 %78 %145 %203\n%204 = OpBitwiseAnd %5 %202 %165\n%205 = OpIAdd %5 %204 %170\n%206 = OpFunctionCall %5 %78 %145 %207\n%208 = OpBitwiseAnd %5 %206 %165\n%209 = OpIAdd %5 %208 %170\n%210 = OpFunctionCall %5 %78 %145 %211\n%212 = OpBitwiseAnd %5 %210 %165\n%213 = OpIAdd %5 %212 %170\n%214 = OpFunctionCall %5 %78 %145 %215\n%216 = OpBitwiseAnd %5 %214 %165\n%217 = OpIAdd %5 %216 %170\n%218 = OpFunctionCall %5 %78 %145 %219\n%220 = OpBitwiseAnd %5 %218 %165\n%221 = OpIAdd %5 %220 %170\n%222 = OpFunctionCall %5 %78 %145 %223\n%224 = OpBitwiseAnd %5 %222 %165\n%225 = OpIAdd %5 %224 %170\n%226 = OpFunctionCall %5 %78 %145 %227\n%228 = OpBitwiseAnd %5 %226 %165\n%229 = OpIAdd %5 %228 %170\n%230 = OpFunctionCall %5 %78 %145 %231\n%232 = OpBitwiseAnd %5 %230 %165\n%233 = OpIAdd %5 %232 %170\n%239 = OpVectorExtractDynamic %115 %238 %129\n%240 = OpShiftLeftLogical %5 %150 %55\n%241 = OpShiftLeftLogical %5 %160 %48\n%242 = OpBitwiseOr %5 %150 %240\n%243 = OpBitwiseOr %5 %160 %241\n%244 = OpCompositeConstruct %9 %242 %243\n%245 = OpBitcast %115 %244\n%246 = OpBitwiseAnd %115 %239 %245\n%248 = OpInBoundsAccessChain %247 %120 %39 %174\n%249 = OpAtomicOr %115 %248 %10 %39 %246\n%250 = OpInBoundsAccessChain %247 %120 %39 %178\n%251 = OpAtomicOr %115 %250 %10 %39 %246\n%252 = OpBitwiseAnd %115 %249 %251\n%253 = OpInBoundsAccessChain %247 %120 %39 %182\n%254 = OpAtomicOr %115 %253 %10 %39 %246\n%255 = OpBitwiseAnd %115 %252 %254\n%256 = OpInBoundsAccessChain %247 %120 %39 %185\n%257 = OpAtomicOr %115 %256 %10 %39 %246\n%258 = OpBitwiseAnd %115 %255 %257\n%259 = OpInBoundsAccessChain %247 %120 %39 %189\n%260 = OpAtomicOr %115 %259 %10 %39 %246\n%261 = OpBitwiseAnd %115 %258 %260\n%262 = OpInBoundsAccessChain %247 %120 %39 %193\n%263 = OpAtomicOr %115 %262 %10 %39 %246\n%264 = OpBitwiseAnd %115 %261 %263\n%265 = OpInBoundsAccessChain %247 %120 %39 %197\n%266 = OpAtomicOr %115 %265 %10 %39 %246\n%267 = OpBitwiseAnd %115 %264 %266\n%268 = OpInBoundsAccessChain %247 %120 %39 %201\n%269 = OpAtomicOr %115 %268 %10 %39 %246\n%270 = OpBitwiseAnd %115 %267 %269\n%271 = OpInBoundsAccessChain %247 %120 %39 %205\n%272 = OpAtomicOr %115 %271 %10 %39 %246\n%273 = OpBitwiseAnd %115 %270 %272\n%274 = OpInBoundsAccessChain %247 %120 %39 %209\n%275 = OpAtomicOr %115 %274 %10 %39 %246\n%276 = OpBitwiseAnd %115 %273 %275\n%277 = OpInBoundsAccessChain %247 %120 %39 %213\n%278 = OpAtomicOr %115 %277 %10 %39 %246\n%279 = OpBitwiseAnd %115 %276 %278\n%280 = OpInBoundsAccessChain %247 %120 %39 %217\n%281 = OpAtomicOr %115 %280 %10 %39 %246\n%282 = OpBitwiseAnd %115 %279 %281\n%283 = OpInBoundsAccessChain %247 %120 %39 %221\n%284 = OpAtomicOr %115 %283 %10 %39 %246\n%285 = OpBitwiseAnd %115 %282 %284\n%286 = OpInBoundsAccessChain %247 %120 %39 %225\n%287 = OpAtomicOr %115 %286 %10 %39 %246\n%288 = OpBitwiseAnd %115 %285 %287\n%289 = OpInBoundsAccessChain %247 %120 %39 %229\n%290 = OpAtomicOr %115 %289 %10 %39 %246\n%291 = OpBitwiseAnd %115 %288 %290\n%292 = OpInBoundsAccessChain %247 %120 %39 %233\n%293 = OpAtomicOr %115 %292 %10 %39 %246\n%294 = OpBitwiseAnd %115 %291 %293\n%295 = OpBitcast %9 %294\n%296 = OpCompositeExtract %5 %295 0\n%297 = OpCompositeExtract %5 %295 1\n%298 = OpShiftRightLogical %5 %296 %55\n%299 = OpBitwiseAnd %5 %298 %150\n%300 = OpIEqual %116 %299 %39\n%301 = OpBitFieldUExtract %5 %130 %303 %304\n%305 = OpShiftLeftLogical %5 %306 %301\n%307 = OpBitFieldUExtract %5 %130 %304 %304\n%308 = OpShiftLeftLogical %5 %309 %307\n%310 = OpBitwiseOr %5 %305 %308\n%311 = OpBitFieldUExtract %5 %130 %312 %304\n%313 = OpShiftLeftLogical %5 %314 %311\n%315 = OpBitwiseOr %5 %310 %313\n%316 = OpSelect %5 %300 %315 %39\n%317 = OpInBoundsAccessChain %37 %124 %39 %174 %10\n%318 = OpAtomicOr %5 %317 %10 %39 %316\n%319 = OpBitwiseAnd %5 %318 %315\n%320 = OpIEqual %116 %319 %315\n%321 = OpBitFieldUExtract %5 %130 %322 %304\n%323 = OpShiftLeftLogical %5 %306 %321\n%324 = OpBitFieldUExtract %5 %130 %325 %304\n%326 = OpShiftLeftLogical %5 %309 %324\n%327 = OpBitwiseOr %5 %323 %326\n%328 = OpBitFieldUExtract %5 %130 %329 %304\n%330 = OpShiftLeftLogical %5 %314 %328\n%331 = OpBitwiseOr %5 %327 %330\n%332 = OpSelect %5 %300 %331 %39\n%333 = OpInBoundsAccessChain %37 %124 %39 %178 %10\n%334 = OpAtomicOr %5 %333 %10 %39 %332\n%335 = OpBitwiseAnd %5 %334 %331\n%336 = OpIEqual %116 %335 %331\n%337 = OpLogicalAnd %116 %320 %336\n%338 = OpBitFieldUExtract %5 %130 %339 %304\n%340 = OpShiftLeftLogical %5 %306 %338\n%341 = OpBitFieldUExtract %5 %130 %342 %304\n%343 = OpShiftLeftLogical %5 %309 %341\n%344 = OpBitwiseOr %5 %340 %343\n%345 = OpBitFieldUExtract %5 %130 %346 %304\n%347 = OpShiftLeftLogical %5 %314 %345\n%348 = OpBitwiseOr %5 %344 %347\n%349 = OpSelect %5 %300 %348 %39\n%350 = OpInBoundsAccessChain %37 %124 %39 %182 %10\n%351 = OpAtomicOr %5 %350 %10 %39 %349\n%352 = OpBitwiseAnd %5 %351 %348\n%353 = OpIEqual %116 %352 %348\n%354 = OpLogicalAnd %116 %337 %353\n%355 = OpBitFieldUExtract %5 %130 %356 %304\n%357 = OpShiftLeftLogical %5 %306 %355\n%358 = OpBitFieldUExtract %5 %130 %359 %304\n%360 = OpShiftLeftLogical %5 %309 %358\n%361 = OpBitwiseOr %5 %357 %360\n%362 = OpBitFieldUExtract %5 %130 %363 %304\n%364 = OpShiftLeftLogical %5 %314 %362\n%365 = OpBitwiseOr %5 %361 %364\n%366 = OpSelect %5 %300 %365 %39\n%367 = OpInBoundsAccessChain %37 %124 %39 %185 %10\n%368 = OpAtomicOr %5 %367 %10 %39 %366\n%369 = OpBitwiseAnd %5 %368 %365\n%370 = OpIEqual %116 %369 %365\n%371 = OpLogicalAnd %116 %354 %370\n%372 = OpBitFieldUExtract %5 %130 %373 %304\n%374 = OpShiftLeftLogical %5 %306 %372\n%375 = OpBitFieldUExtract %5 %130 %376 %304\n%377 = OpShiftLeftLogical %5 %309 %375\n%378 = OpBitwiseOr %5 %374 %377\n%379 = OpBitFieldUExtract %5 %130 %380 %304\n%381 = OpShiftLeftLogical %5 %314 %379\n%382 = OpBitwiseOr %5 %378 %381\n%383 = OpSelect %5 %300 %382 %39\n%384 = OpInBoundsAccessChain %37 %124 %39 %189 %10\n%385 = OpAtomicOr %5 %384 %10 %39 %383\n%386 = OpBitwiseAnd %5 %385 %382\n%387 = OpIEqual %116 %386 %382\n%388 = OpLogicalAnd %116 %371 %387\n%389 = OpBitFieldUExtract %5 %130 %322 %304\n%390 = OpShiftLeftLogical %5 %306 %389\n%391 = OpBitFieldUExtract %5 %130 %325 %304\n%392 = OpShiftLeftLogical %5 %309 %391\n%393 = OpBitwiseOr %5 %390 %392\n%394 = OpBitFieldUExtract %5 %130 %329 %304\n%395 = OpShiftLeftLogical %5 %314 %394\n%396 = OpBitwiseOr %5 %393 %395\n%397 = OpSelect %5 %300 %396 %39\n%398 = OpInBoundsAccessChain %37 %124 %39 %193 %10\n%399 = OpAtomicOr %5 %398 %10 %39 %397\n%400 = OpBitwiseAnd %5 %399 %396\n%401 = OpIEqual %116 %400 %396\n%402 = OpLogicalAnd %116 %388 %401\n%403 = OpBitFieldUExtract %5 %130 %404 %304\n%405 = OpShiftLeftLogical %5 %306 %403\n%406 = OpBitFieldUExtract %5 %130 %407 %304\n%408 = OpShiftLeftLogical %5 %309 %406\n%409 = OpBitwiseOr %5 %405 %408\n%410 = OpBitFieldUExtract %5 %130 %356 %304\n%411 = OpShiftLeftLogical %5 %314 %410\n%412 = OpBitwiseOr %5 %409 %411\n%413 = OpSelect %5 %300 %412 %39\n%414 = OpInBoundsAccessChain %37 %124 %39 %197 %10\n%415 = OpAtomicOr %5 %414 %10 %39 %413\n%416 = OpBitwiseAnd %5 %415 %412\n%417 = OpIEqual %116 %416 %412\n%418 = OpLogicalAnd %116 %402 %417\n%419 = OpBitFieldUExtract %5 %130 %420 %304\n%421 = OpShiftLeftLogical %5 %306 %419\n%422 = OpBitFieldUExtract %5 %130 %423 %304\n%424 = OpShiftLeftLogical %5 %309 %422\n%425 = OpBitwiseOr %5 %421 %424\n%426 = OpBitFieldUExtract %5 %130 %427 %304\n%428 = OpShiftLeftLogical %5 %314 %426\n%429 = OpBitwiseOr %5 %425 %428\n%430 = OpSelect %5 %300 %429 %39\n%431 = OpInBoundsAccessChain %37 %124 %39 %201 %10\n%432 = OpAtomicOr %5 %431 %10 %39 %430\n%433 = OpBitwiseAnd %5 %432 %429\n%434 = OpIEqual %116 %433 %429\n%435 = OpLogicalAnd %116 %418 %434\nOpSelectionMerge %440 None\nOpSwitch %129 %439 0 %436 1 %437 2 %438\n%439 = OpLabel\n%448 = OpShiftLeftLogical %5 %160 %48\n%449 = OpBitwiseAnd %5 %297 %448\n%450 = OpINotEqual %116 %449 %39\nOpBranch %440\n%436 = OpLabel\n%441 = OpBitwiseAnd %5 %296 %150\n%442 = OpINotEqual %116 %441 %39\nOpBranch %440\n%437 = OpLabel\n%443 = OpShiftLeftLogical %5 %150 %55\n%444 = OpBitwiseAnd %5 %296 %443\n%445 = OpINotEqual %116 %444 %39\nOpBranch %440\n%438 = OpLabel\n%446 = OpBitwiseAnd %5 %297 %160\n%447 = OpINotEqual %116 %446 %39\nOpBranch %440\n%440 = OpLabel\n%451 = OpPhi %116 %442 %436 %445 %437 %447 %438 %450 %439\n%452 = OpLogicalNot %116 %451\n%453 = OpLogicalOr %116 %452 %435\nOpReturnValue %453\nOpFunctionEnd\n%492 = OpFunction %1 None %489\n%490 = OpFunctionParameter %116\n%491 = OpFunctionParameter %5\n%493 = OpLabel\n%496 = OpLogicalNot %116 %490\n%497 = OpLoad %116 %479\n%498 = OpLogicalAnd %116 %496 %497\nOpSelectionMerge %494 None\nOpBranchConditional %498 %495 %494\n%495 = OpLabel\n%501 = OpIMul %5 %491 %503\n%502 = OpBitwiseXor %5 %501 %504\n%505 = OpArrayLength %5 %484 0\n%506 = OpISub %5 %505 %162\n%507 = OpAccessChain %37 %484 %39 %506\n%508 = OpLoad %5 %507\n%509 = OpIMul %5 %508 %510\n%511 = OpBitwiseXor %5 %502 %509\n%512 = OpArrayLength %5 %488 0\n%513 = OpISub %5 %512 %10\n%514 = OpBitwiseAnd %5 %511 %513\n%515 = OpShiftRightLogical %5 %514 %48\n%516 = OpBitwiseAnd %5 %514 %152\n%517 = OpShiftLeftLogical %5 %10 %516\n%518 = OpAccessChain %37 %484 %39 %515\n%519 = OpAtomicOr %5 %518 %10 %39 %517\n%520 = OpBitwiseAnd %5 %519 %517\n%521 = OpIEqual %116 %520 %39\nOpStore %479 %522\nOpSelectionMerge %500 None\nOpBranchConditional %521 %499 %500\n%499 = OpLabel\n%523 = OpCompositeConstruct %480 %504 %39 %491 %508\n%524 = OpShiftLeftLogical %5 %517 %55\n%526 = OpAccessChain %525 %488 %39 %514\nOpStore %526 %523\nOpMemoryBarrier %10 %528\n%527 = OpAtomicOr %5 %518 %10 %39 %524\nOpMemoryBarrier %10 %528\nOpBranch %500\n%500 = OpLabel\nOpBranch %494\n%494 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/alloca-robustness-cases.extended-robustness.vert",
    "content": "#version 460\n\nconst float _23[5] = float[](1.0, 2.0, 3.0, 4.0, 0.0);\n\nlayout(location = 2) in uvec4 A;\nfloat _34[4] = float[](5.0, 6.0, 7.0, 8.0);\n\nvoid main()\n{\n    float _56[4];\n    _56[0u] = 0.0;\n    _56[1u] = 0.0;\n    _56[2u] = 0.0;\n    _56[3u] = 0.0;\n    float _63 = float(uint(gl_VertexIndex) - uint(gl_BaseVertex));\n    bool _66 = A.x < 4u;\n    if (_66)\n    {\n        _56[A.x] = _63;\n    }\n    if (A.y < 4u)\n    {\n        _34[A.y] = float(uint(gl_InstanceIndex) - uint(gl_BaseInstance));\n    }\n    float _72;\n    if (A.w == 0u)\n    {\n        _72 = _63;\n    }\n    else\n    {\n        uint _86;\n        _86 = 0u;\n        float _91;\n        uint _88;\n        bool _90;\n        for (;;)\n        {\n            _88 = _86 ^ 2u;\n            _90 = _88 < 4u;\n            if (_90)\n            {\n                _91 = _34[_88];\n            }\n            else\n            {\n                _91 = 0.0;\n            }\n            if (_90)\n            {\n                _34[_88] = _91 + 60.0;\n            }\n            uint _87 = _86 + 1u;\n            bool _95 = _87 < 4u;\n            float _96;\n            if (_95)\n            {\n                _96 = _56[_87];\n            }\n            else\n            {\n                _96 = 0.0;\n            }\n            if (_95)\n            {\n                _56[_87] = _96 + 50.0;\n            }\n            if (_87 == A.w)\n            {\n                break;\n            }\n            else\n            {\n                _86 = _87;\n                continue;\n            }\n        }\n        float _73;\n        if (_66)\n        {\n            _73 = _56[A.x];\n        }\n        else\n        {\n            _73 = 0.0;\n        }\n        _72 = _73;\n    }\n    float _80;\n    if (A.w < 4u)\n    {\n        _80 = _34[A.w];\n    }\n    else\n    {\n        _80 = 0.0;\n    }\n    gl_Position.x = _23[min(A.z, 4u)];\n    gl_Position.y = _80;\n    gl_Position.z = _72;\n    gl_Position.w = 1.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 131\n; Schema: 0\nOpCapability Shader\nOpCapability DrawParameters\n%75 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %8 %11 %15 %48 %52\nOpName %3 \"main\"\nOpName %7 \"SV_VertexID\"\nOpName %8 \"SV_InstanceID\"\nOpName %11 \"A\"\nOpName %15 \"SV_Position\"\nOpDecorate %7 BuiltIn VertexIndex\nOpDecorate %8 BuiltIn InstanceIndex\nOpDecorate %11 Location 2\nOpDecorate %15 BuiltIn Position\nOpDecorate %48 BuiltIn BaseInstance\nOpDecorate %52 BuiltIn BaseVertex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%16 = OpConstant %5 5\n%17 = OpTypeArray %12 %16\n%18 = OpConstant %12 1\n%19 = OpConstant %12 2\n%20 = OpConstant %12 3\n%21 = OpConstant %12 4\n%22 = OpConstantNull %12\n%23 = OpConstantComposite %17 %18 %19 %20 %21 %22\n%24 = OpTypePointer Private %17\n%25 = OpVariable %24 Private %23\n%26 = OpConstant %5 4\n%27 = OpTypeArray %12 %26\n%28 = OpConstant %12 5\n%29 = OpConstant %12 6\n%30 = OpConstant %12 7\n%31 = OpConstant %12 8\n%32 = OpConstantComposite %27 %28 %29 %30 %31\n%33 = OpTypePointer Private %27\n%34 = OpVariable %33 Private %32\n%36 = OpConstant %5 0\n%39 = OpConstant %5 1\n%42 = OpConstant %5 2\n%45 = OpConstant %5 3\n%48 = OpVariable %6 Input\n%52 = OpVariable %6 Input\n%55 = OpTypePointer Function %27\n%57 = OpTypePointer Function %12\n%59 = OpConstant %12 0\n%65 = OpTypeBool\n%68 = OpTypePointer Private %12\n%81 = OpTypePointer Output %12\n%93 = OpConstant %12 60\n%98 = OpConstant %12 50\n%113 = OpConstantNull %12\n%119 = OpConstantNull %12\n%125 = OpConstantNull %12\n%129 = OpConstantNull %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%56 = OpVariable %55 Function\nOpBranch %100\n%100 = OpLabel\n%35 = OpAccessChain %6 %11 %36\n%37 = OpLoad %5 %35\n%38 = OpAccessChain %6 %11 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %6 %11 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %6 %11 %45\n%46 = OpLoad %5 %44\n%47 = OpLoad %5 %8\n%49 = OpLoad %5 %48\n%50 = OpISub %5 %47 %49\n%51 = OpLoad %5 %7\n%53 = OpLoad %5 %52\n%54 = OpISub %5 %51 %53\n%58 = OpInBoundsAccessChain %57 %56 %36\nOpStore %58 %59\n%60 = OpInBoundsAccessChain %57 %56 %39\nOpStore %60 %59\n%61 = OpInBoundsAccessChain %57 %56 %42\nOpStore %61 %59\n%62 = OpInBoundsAccessChain %57 %56 %45\nOpStore %62 %59\n%63 = OpConvertUToF %12 %54\n%66 = OpULessThan %65 %37 %26\n%64 = OpInBoundsAccessChain %57 %56 %37\nOpSelectionMerge %106 None\nOpBranchConditional %66 %105 %106\n%105 = OpLabel\nOpStore %64 %63\nOpBranch %106\n%106 = OpLabel\n%67 = OpConvertUToF %12 %50\n%70 = OpULessThan %65 %40 %26\n%69 = OpInBoundsAccessChain %68 %34 %40\nOpSelectionMerge %108 None\nOpBranchConditional %70 %107 %108\n%107 = OpLabel\nOpStore %69 %67\nOpBranch %108\n%108 = OpLabel\n%71 = OpIEqual %65 %46 %36\nOpSelectionMerge %104 None\nOpBranchConditional %71 %104 %101\n%101 = OpLabel\nOpBranch %102\n%102 = OpLabel\n%86 = OpPhi %5 %36 %101 %87 %121\n%88 = OpBitwiseXor %5 %86 %42\n%90 = OpULessThan %65 %88 %26\n%89 = OpInBoundsAccessChain %68 %34 %88\nOpLoopMerge %103 %109 None\nOpBranch %109\n%109 = OpLabel\nOpSelectionMerge %111 None\nOpBranchConditional %90 %110 %111\n%110 = OpLabel\n%112 = OpLoad %12 %89\nOpBranch %111\n%111 = OpLabel\n%91 = OpPhi %12 %112 %110 %113 %109\n%92 = OpFAdd %12 %91 %93\nOpSelectionMerge %115 None\nOpBranchConditional %90 %114 %115\n%114 = OpLabel\nOpStore %89 %92\nOpBranch %115\n%115 = OpLabel\n%87 = OpIAdd %5 %86 %39\n%95 = OpULessThan %65 %87 %26\n%94 = OpInBoundsAccessChain %57 %56 %87\nOpSelectionMerge %117 None\nOpBranchConditional %95 %116 %117\n%116 = OpLabel\n%118 = OpLoad %12 %94\nOpBranch %117\n%117 = OpLabel\n%96 = OpPhi %12 %118 %116 %119 %115\n%97 = OpFAdd %12 %96 %98\nOpSelectionMerge %121 None\nOpBranchConditional %95 %120 %121\n%120 = OpLabel\nOpStore %94 %97\nOpBranch %121\n%121 = OpLabel\n%99 = OpIEqual %65 %87 %46\nOpBranchConditional %99 %103 %102\n%103 = OpLabel\nOpSelectionMerge %123 None\nOpBranchConditional %66 %122 %123\n%122 = OpLabel\n%124 = OpLoad %12 %64\nOpBranch %123\n%123 = OpLabel\n%73 = OpPhi %12 %124 %122 %125 %103\nOpBranch %104\n%104 = OpLabel\n%72 = OpPhi %12 %63 %108 %73 %123\n%76 = OpExtInst %5 %75 UMin %43 %26\n%74 = OpInBoundsAccessChain %68 %25 %76\n%77 = OpLoad %12 %74\n%79 = OpULessThan %65 %46 %26\n%78 = OpInBoundsAccessChain %68 %34 %46\nOpSelectionMerge %127 None\nOpBranchConditional %79 %126 %127\n%126 = OpLabel\n%128 = OpLoad %12 %78\nOpBranch %127\n%127 = OpLabel\n%80 = OpPhi %12 %128 %126 %129 %104\n%82 = OpAccessChain %81 %15 %36\nOpStore %82 %77\n%83 = OpAccessChain %81 %15 %39\nOpStore %83 %80\n%84 = OpAccessChain %81 %15 %42\nOpStore %84 %72\n%85 = OpAccessChain %81 %15 %45\nOpStore %85 %18\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/alloca.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint TEXCOORD;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _14[4];\n    _14[0u] = 1u;\n    _14[1u] = 2u;\n    _14[2u] = 3u;\n    _14[3u] = 4u;\n    _14[TEXCOORD & 3u] = TEXCOORD;\n    SV_Target = ((_14[1u] + _14[0u]) + _14[2u]) + _14[3u];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"TEXCOORD\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%11 = OpConstant %5 4\n%12 = OpTypeArray %5 %11\n%13 = OpTypePointer Function %12\n%15 = OpTypePointer Function %5\n%17 = OpConstant %5 0\n%18 = OpConstant %5 1\n%20 = OpConstant %5 2\n%22 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%14 = OpVariable %13 Function\nOpBranch %33\n%33 = OpLabel\n%10 = OpLoad %5 %7\n%16 = OpInBoundsAccessChain %15 %14 %17\nOpStore %16 %18\n%19 = OpInBoundsAccessChain %15 %14 %18\nOpStore %19 %20\n%21 = OpInBoundsAccessChain %15 %14 %20\nOpStore %21 %22\n%23 = OpInBoundsAccessChain %15 %14 %22\nOpStore %23 %11\n%24 = OpBitwiseAnd %5 %10 %22\n%25 = OpInBoundsAccessChain %15 %14 %24\nOpStore %25 %10\n%26 = OpLoad %5 %16\n%27 = OpLoad %5 %19\n%28 = OpIAdd %5 %27 %26\n%29 = OpLoad %5 %21\n%30 = OpIAdd %5 %28 %29\n%31 = OpLoad %5 %23\n%32 = OpIAdd %5 %30 %31\nOpStore %9 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/atomic-bin-op.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nshared uint _9[64];\nshared uint _10[64];\n\nvoid main()\n{\n    uint _20 = atomicAdd(_9[gl_GlobalInvocationID.x], 1u);\n    uint _23 = atomicAnd(_9[gl_GlobalInvocationID.x], 2u);\n    uint _24 = atomicExchange(_9[gl_GlobalInvocationID.x], 3u);\n    uint _26 = atomicMax(_9[gl_GlobalInvocationID.x], 4u);\n    uint _28 = atomicMin(_9[gl_GlobalInvocationID.x], 5u);\n    uint _30 = atomicOr(_9[gl_GlobalInvocationID.x], 6u);\n    uint _32 = atomicXor(_9[gl_GlobalInvocationID.x], 7u);\n    uint _35 = atomicMin(_10[gl_GlobalInvocationID.x], 8u);\n    uint _37 = atomicMax(_10[gl_GlobalInvocationID.x], 9u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %13\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %13 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 64\n%7 = OpTypeArray %5 %6\n%8 = OpTypePointer Workgroup %7\n%9 = OpVariable %8 Workgroup\n%10 = OpVariable %8 Workgroup\n%11 = OpTypeVector %5 3\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%14 = OpTypePointer Input %5\n%16 = OpConstant %5 0\n%18 = OpTypePointer Workgroup %5\n%21 = OpConstant %5 2\n%22 = OpConstant %5 1\n%25 = OpConstant %5 3\n%27 = OpConstant %5 4\n%29 = OpConstant %5 5\n%31 = OpConstant %5 6\n%33 = OpConstant %5 7\n%36 = OpConstant %5 8\n%38 = OpConstant %5 9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%15 = OpAccessChain %14 %13 %16\n%17 = OpLoad %5 %15\n%19 = OpAccessChain %18 %9 %17\n%20 = OpAtomicIAdd %5 %19 %21 %16 %22\n%23 = OpAtomicAnd %5 %19 %21 %16 %21\n%24 = OpAtomicExchange %5 %19 %21 %16 %25\n%26 = OpAtomicUMax %5 %19 %21 %16 %27\n%28 = OpAtomicUMin %5 %19 %21 %16 %29\n%30 = OpAtomicOr %5 %19 %21 %16 %31\n%32 = OpAtomicXor %5 %19 %21 %16 %33\n%34 = OpAccessChain %18 %10 %17\n%35 = OpAtomicSMin %5 %34 %21 %16 %36\n%37 = OpAtomicSMax %5 %34 %21 %16 %38\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/atomic-compare-exchange.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nstruct CmpXchgResult\n{\n    uint _m0;\n    bool _m1;\n};\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared uint _12[64];\n\nvoid main()\n{\n    uint _23 = atomicCompSwap(_12[gl_GlobalInvocationID.x], 20u, 30u);\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(CmpXchgResult(_23, _23 == 20u)._m0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %29 \"CmpXchgResult\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 64\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%21 = OpTypePointer Workgroup %5\n%24 = OpConstant %5 2\n%25 = OpConstant %5 30\n%26 = OpConstant %5 20\n%27 = OpTypeBool\n%29 = OpTypeStruct %5 %27\n%33 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%22 = OpAccessChain %21 %12 %20\n%23 = OpAtomicCompareExchange %5 %22 %24 %19 %19 %25 %26\n%28 = OpIEqual %27 %23 %26\n%30 = OpCompositeConstruct %29 %23 %28\n%31 = OpCompositeExtract %5 %30 0\n%32 = OpShiftLeftLogical %5 %20 %24\n%34 = OpCompositeConstruct %33 %31 %31 %31 %31\nOpImageWrite %13 %20 %34\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/atomic-compare-exchange.sm66.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nstruct CmpXchgResult\n{\n    uint _m0;\n    bool _m1;\n};\n\nstruct CmpXchgResult_1\n{\n    uint64_t _m0;\n    bool _m1;\n};\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    uint64_t _m0[];\n} _14;\n\nshared uint _18[64];\nshared uint64_t _21[64];\n\nvoid main()\n{\n    uint _31 = atomicCompSwap(_18[gl_GlobalInvocationID.x], 20u, 30u);\n    uint _40 = atomicCompSwap(_18[gl_GlobalInvocationID.x], 20u, 30u);\n    _9._m0[gl_GlobalInvocationID.x] = CmpXchgResult(_31, _31 == 20u)._m0;\n    uint64_t _48 = atomicCompSwap(_21[gl_GlobalInvocationID.x], 20ul, 30ul);\n    uint64_t _55 = atomicCompSwap(_21[gl_GlobalInvocationID.x], 20ul, 30ul);\n    _14._m0[gl_GlobalInvocationID.x] = CmpXchgResult_1(_48, _48 == 20ul)._m0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %24\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %37 \"CmpXchgResult\"\nOpName %52 \"CmpXchgResult\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %24 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeInt 64 0\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpConstant %5 64\n%16 = OpTypeArray %5 %15\n%17 = OpTypePointer Workgroup %16\n%18 = OpVariable %17 Workgroup\n%19 = OpTypeArray %10 %15\n%20 = OpTypePointer Workgroup %19\n%21 = OpVariable %20 Workgroup\n%22 = OpTypeVector %5 3\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Input %5\n%27 = OpConstant %5 0\n%29 = OpTypePointer Workgroup %5\n%32 = OpConstant %5 2\n%33 = OpConstant %5 30\n%34 = OpConstant %5 20\n%35 = OpTypeBool\n%37 = OpTypeStruct %5 %35\n%44 = OpTypePointer StorageBuffer %5\n%46 = OpTypePointer Workgroup %10\n%49 = OpConstant %10 30\n%50 = OpConstant %10 20\n%52 = OpTypeStruct %10 %35\n%59 = OpConstant %5 3\n%60 = OpTypePointer StorageBuffer %10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%26 = OpAccessChain %25 %24 %27\n%28 = OpLoad %5 %26\n%30 = OpAccessChain %29 %18 %28\n%31 = OpAtomicCompareExchange %5 %30 %32 %27 %27 %33 %34\n%36 = OpIEqual %35 %31 %34\n%38 = OpCompositeConstruct %37 %31 %36\n%39 = OpCompositeExtract %5 %38 0\n%40 = OpAtomicCompareExchange %5 %30 %32 %27 %27 %33 %34\n%41 = OpIEqual %35 %40 %34\n%42 = OpCompositeConstruct %37 %40 %41\n%43 = OpShiftLeftLogical %5 %28 %32\n%45 = OpAccessChain %44 %9 %27 %28\nOpStore %45 %39\n%47 = OpAccessChain %46 %21 %28\n%48 = OpAtomicCompareExchange %10 %47 %32 %27 %27 %49 %50\n%51 = OpIEqual %35 %48 %50\n%53 = OpCompositeConstruct %52 %48 %51\n%54 = OpCompositeExtract %10 %53 0\n%55 = OpAtomicCompareExchange %10 %47 %32 %27 %27 %49 %50\n%56 = OpIEqual %35 %55 %50\n%57 = OpCompositeConstruct %52 %55 %56\n%58 = OpShiftLeftLogical %5 %28 %59\n%61 = OpAccessChain %60 %14 %27 %28\nOpStore %61 %54\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/bool-to-fp.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = float(V != 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 20\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"V\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%12 = OpTypeBool\n%14 = OpConstant %5 0\n%15 = OpConstant %8 0\n%16 = OpConstant %8 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %18\n%18 = OpLabel\n%11 = OpLoad %5 %7\n%13 = OpINotEqual %12 %11 %14\n%17 = OpSelect %8 %13 %16 %15\nOpStore %10 %17\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/constant-expression-cast.comp",
    "content": "#version 460\nlayout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared uint _12[4];\n\nvoid main()\n{\n    imageStore(_8, int(0u), uvec4(floatBitsToUint(uintBitsToFloat(_12[2u]))));\n}\n\n/* WARNINGS:\n- Has group shared access, but no group shared barrier anywhere.\n*/\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 4 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 4\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypePointer Workgroup %5\n%16 = OpConstant %5 2\n%18 = OpTypeFloat 32\n%20 = OpConstant %5 0\n%22 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%13 = OpLoad %6 %8\n%15 = OpAccessChain %14 %12 %16\n%17 = OpLoad %5 %15\n%19 = OpBitcast %18 %17\n%21 = OpBitcast %5 %19\n%23 = OpCompositeConstruct %22 %21 %21 %21 %21\nOpImageWrite %13 %20 %23\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/constant-expression-gep.comp",
    "content": "#version 460\nlayout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n\nstruct CmpXchgResult\n{\n    uint _m0;\n    bool _m1;\n};\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared uint _12[4];\n\nvoid main()\n{\n    _12[0u] = gl_GlobalInvocationID.x;\n    _12[1u] = gl_GlobalInvocationID.y;\n    _12[2u] = gl_GlobalInvocationID.z;\n    _12[3u] = 10u;\n    barrier();\n    uint _35 = atomicAdd(_12[3u], 10u);\n    uint _37 = atomicCompSwap(_12[2u], 10u, _35);\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(_12[gl_GlobalInvocationID.y & 3u]));\n    imageStore(_8, int(gl_GlobalInvocationID.z), uvec4(_12[1u] + CmpXchgResult(_37, _37 == 10u)._m0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 4 1 1\nOpName %3 \"main\"\nOpName %41 \"CmpXchgResult\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 4\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypeVector %5 3\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 1\n%25 = OpConstant %5 2\n%27 = OpTypePointer Workgroup %5\n%32 = OpConstant %5 3\n%33 = OpConstant %5 10\n%34 = OpConstant %5 264\n%39 = OpTypeBool\n%41 = OpTypeStruct %5 %39\n%47 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%13 = OpLoad %6 %8\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %17 %16 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %17 %16 %25\n%26 = OpLoad %5 %24\n%28 = OpAccessChain %27 %12 %19\nOpStore %28 %20\n%29 = OpAccessChain %27 %12 %22\nOpStore %29 %23\n%30 = OpAccessChain %27 %12 %25\nOpStore %30 %26\n%31 = OpAccessChain %27 %12 %32\nOpStore %31 %33\nOpControlBarrier %25 %25 %34\n%36 = OpAccessChain %27 %12 %32\n%35 = OpAtomicIAdd %5 %36 %25 %19 %33\n%38 = OpAccessChain %27 %12 %25\n%37 = OpAtomicCompareExchange %5 %38 %25 %19 %19 %35 %33\n%40 = OpIEqual %39 %37 %33\n%42 = OpCompositeConstruct %41 %37 %40\n%43 = OpCompositeExtract %5 %42 0\n%44 = OpBitwiseAnd %5 %23 %32\n%45 = OpAccessChain %27 %12 %44\n%46 = OpLoad %5 %45\n%48 = OpCompositeConstruct %47 %46 %46 %46 %46\nOpImageWrite %13 %20 %48\n%49 = OpAccessChain %27 %12 %22\n%50 = OpLoad %5 %49\n%51 = OpIAdd %5 %50 %43\n%52 = OpCompositeConstruct %47 %51 %51 %51 %51\nOpImageWrite %13 %26 %52\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fadd.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 1) in vec4 B;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = A.x + B.x;\n    SV_Target.y = A.y + B.y;\n    SV_Target.z = A.z + B.z;\n    SV_Target.w = A.w + B.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %6\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%24 = OpConstant %14 3\n%38 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %9 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %12 %8 %15\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %12 %8 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %12 %8 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %12 %8 %24\n%33 = OpLoad %5 %32\n%34 = OpFAdd %5 %27 %16\n%35 = OpFAdd %5 %29 %19\n%36 = OpFAdd %5 %31 %22\n%37 = OpFAdd %5 %33 %25\n%39 = OpAccessChain %38 %11 %15\nOpStore %39 %34\n%40 = OpAccessChain %38 %11 %18\nOpStore %40 %35\n%41 = OpAccessChain %38 %11 %21\nOpStore %41 %36\n%42 = OpAccessChain %38 %11 %24\nOpStore %42 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fast-mul-div-pair.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _11;\n\nvoid main()\n{\n    float _19 = uintBitsToFloat(texelFetch(_8, int(1u)).x);\n    float _23 = uintBitsToFloat(texelFetch(_8, int(2u)).x);\n    imageStore(_11, int(0u), uvec4(floatBitsToUint(_23)));\n    float _31 = uintBitsToFloat(texelFetch(_8, int(3u)).x);\n    imageStore(_11, int(1u), uvec4(floatBitsToUint(_31)));\n    imageStore(_11, int(2u), uvec4(floatBitsToUint(_19 / (uintBitsToFloat(texelFetch(_8, int(4u)).x) * _19))));\n    imageStore(_11, int(3u), uvec4(floatBitsToUint(_19 / (uintBitsToFloat(texelFetch(_8, int(5u)).x) * _19))));\n    float _54 = uintBitsToFloat(texelFetch(_8, int(6u)).x);\n    imageStore(_11, int(4u), uvec4(floatBitsToUint(_54)));\n    float _61 = uintBitsToFloat(texelFetch(_8, int(7u)).x);\n    imageStore(_11, int(5u), uvec4(floatBitsToUint(_61)));\n    imageStore(_11, int(6u), uvec4(floatBitsToUint((_19 / uintBitsToFloat(texelFetch(_8, int(8u)).x)) * _19)));\n    imageStore(_11, int(7u), uvec4(floatBitsToUint((_19 / uintBitsToFloat(texelFetch(_8, int(9u)).x)) * _19)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 83\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%14 = OpConstant %5 1\n%15 = OpTypeVector %5 4\n%18 = OpTypeFloat 32\n%20 = OpConstant %5 2\n%25 = OpConstant %5 0\n%28 = OpConstant %5 3\n%35 = OpConstant %5 4\n%43 = OpConstant %5 5\n%51 = OpConstant %5 6\n%58 = OpConstant %5 7\n%65 = OpConstant %5 8\n%73 = OpConstant %5 9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %81\n%81 = OpLabel\n%12 = OpLoad %9 %11\n%13 = OpLoad %6 %8\n%16 = OpImageFetch %15 %13 %14\n%17 = OpCompositeExtract %5 %16 0\n%19 = OpBitcast %18 %17\n%21 = OpImageFetch %15 %13 %20\n%22 = OpCompositeExtract %5 %21 0\n%23 = OpBitcast %18 %22\n%24 = OpFMul %18 %23 %19\n%26 = OpBitcast %5 %23\n%27 = OpCompositeConstruct %15 %26 %26 %26 %26\nOpImageWrite %12 %25 %27\n%29 = OpImageFetch %15 %13 %28\n%30 = OpCompositeExtract %5 %29 0\n%31 = OpBitcast %18 %30\n%32 = OpFMul %18 %31 %19\n%33 = OpBitcast %5 %31\n%34 = OpCompositeConstruct %15 %33 %33 %33 %33\nOpImageWrite %12 %14 %34\n%36 = OpImageFetch %15 %13 %35\n%37 = OpCompositeExtract %5 %36 0\n%38 = OpBitcast %18 %37\n%39 = OpFMul %18 %38 %19\n%40 = OpFDiv %18 %19 %39\n%41 = OpBitcast %5 %40\n%42 = OpCompositeConstruct %15 %41 %41 %41 %41\nOpImageWrite %12 %20 %42\n%44 = OpImageFetch %15 %13 %43\n%45 = OpCompositeExtract %5 %44 0\n%46 = OpBitcast %18 %45\n%47 = OpFMul %18 %46 %19\n%48 = OpFDiv %18 %19 %47\n%49 = OpBitcast %5 %48\n%50 = OpCompositeConstruct %15 %49 %49 %49 %49\nOpImageWrite %12 %28 %50\n%52 = OpImageFetch %15 %13 %51\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpBitcast %18 %53\n%55 = OpFDiv %18 %54 %19\n%56 = OpBitcast %5 %54\n%57 = OpCompositeConstruct %15 %56 %56 %56 %56\nOpImageWrite %12 %35 %57\n%59 = OpImageFetch %15 %13 %58\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpBitcast %18 %60\n%62 = OpFDiv %18 %61 %19\n%63 = OpBitcast %5 %61\n%64 = OpCompositeConstruct %15 %63 %63 %63 %63\nOpImageWrite %12 %43 %64\n%66 = OpImageFetch %15 %13 %65\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpBitcast %18 %67\n%69 = OpFDiv %18 %19 %68\n%70 = OpFMul %18 %69 %19\n%71 = OpBitcast %5 %70\n%72 = OpCompositeConstruct %15 %71 %71 %71 %71\nOpImageWrite %12 %51 %72\n%74 = OpImageFetch %15 %13 %73\n%75 = OpCompositeExtract %5 %74 0\n%76 = OpBitcast %18 %75\n%77 = OpFDiv %18 %19 %76\n%78 = OpFMul %18 %77 %19\n%79 = OpBitcast %5 %78\n%80 = OpCompositeConstruct %15 %79 %79 %79 %79\nOpImageWrite %12 %58 %80\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fcmp_eq.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x == A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpFOrdEqual %25 %15 %18\n%27 = OpSelect %5 %26 %21 %24\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fcmp_ge.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x >= A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpFOrdGreaterThanEqual %25 %15 %18\n%27 = OpSelect %5 %26 %21 %24\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fcmp_gt.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x > A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpFOrdGreaterThan %25 %15 %18\n%27 = OpSelect %5 %26 %21 %24\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fcmp_le.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x <= A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpFOrdLessThanEqual %25 %15 %18\n%27 = OpSelect %5 %26 %21 %24\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fcmp_lt.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x < A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpFOrdLessThan %25 %15 %18\n%27 = OpSelect %5 %26 %21 %24\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fcmp_ne.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x != A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpFUnordNotEqual %25 %15 %18\n%27 = OpSelect %5 %26 %21 %24\nOpStore %10 %27\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fdiv.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 1) in vec4 B;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = A.x / B.x;\n    SV_Target.y = A.y / B.y;\n    SV_Target.z = A.z / B.z;\n    SV_Target.w = A.w / B.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %6\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%24 = OpConstant %14 3\n%38 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %9 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %12 %8 %15\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %12 %8 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %12 %8 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %12 %8 %24\n%33 = OpLoad %5 %32\n%34 = OpFDiv %5 %27 %16\n%35 = OpFDiv %5 %29 %19\n%36 = OpFDiv %5 %31 %22\n%37 = OpFDiv %5 %33 %25\n%39 = OpAccessChain %38 %11 %15\nOpStore %39 %34\n%40 = OpAccessChain %38 %11 %18\nOpStore %40 %35\n%41 = OpAccessChain %38 %11 %21\nOpStore %41 %36\n%42 = OpAccessChain %38 %11 %24\nOpStore %42 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fmul.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 1) in vec4 B;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = A.x * B.x;\n    SV_Target.y = A.y * B.y;\n    SV_Target.z = A.z * B.z;\n    SV_Target.w = A.w * B.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %6\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%24 = OpConstant %14 3\n%38 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %9 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %12 %8 %15\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %12 %8 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %12 %8 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %12 %8 %24\n%33 = OpLoad %5 %32\n%34 = OpFMul %5 %27 %16\n%35 = OpFMul %5 %29 %19\n%36 = OpFMul %5 %31 %22\n%37 = OpFMul %5 %33 %25\n%39 = OpAccessChain %38 %11 %15\nOpStore %39 %34\n%40 = OpAccessChain %38 %11 %18\nOpStore %40 %35\n%41 = OpAccessChain %38 %11 %21\nOpStore %41 %36\n%42 = OpAccessChain %38 %11 %24\nOpStore %42 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/frem.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 1) in vec4 B;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = A.x - B.x * trunc(A.x / B.x);\n    SV_Target.y = A.y - B.y * trunc(A.y / B.y);\n    SV_Target.z = A.z - B.z * trunc(A.z / B.z);\n    SV_Target.w = A.w - B.w * trunc(A.w / B.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %6\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%24 = OpConstant %14 3\n%38 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %9 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %12 %8 %15\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %12 %8 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %12 %8 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %12 %8 %24\n%33 = OpLoad %5 %32\n%34 = OpFRem %5 %27 %16\n%35 = OpFRem %5 %29 %19\n%36 = OpFRem %5 %31 %22\n%37 = OpFRem %5 %33 %25\n%39 = OpAccessChain %38 %11 %15\nOpStore %39 %34\n%40 = OpAccessChain %38 %11 %18\nOpStore %40 %35\n%41 = OpAccessChain %38 %11 %21\nOpStore %41 %36\n%42 = OpAccessChain %38 %11 %24\nOpStore %42 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/fsub.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 1) in vec4 B;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = A.x - B.x;\n    SV_Target.y = A.y - B.y;\n    SV_Target.z = A.z - B.z;\n    SV_Target.w = A.w - B.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpTypePointer Output %6\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%24 = OpConstant %14 3\n%38 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %43\n%43 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %9 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %12 %8 %15\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %12 %8 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %12 %8 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %12 %8 %24\n%33 = OpLoad %5 %32\n%34 = OpFSub %5 %27 %16\n%35 = OpFSub %5 %29 %19\n%36 = OpFSub %5 %31 %22\n%37 = OpFSub %5 %33 %25\n%39 = OpAccessChain %38 %11 %15\nOpStore %39 %34\n%40 = OpAccessChain %38 %11 %18\nOpStore %40 %35\n%41 = OpAccessChain %38 %11 %21\nOpStore %41 %36\n%42 = OpAccessChain %38 %11 %24\nOpStore %42 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/glitched-integer-width.comp",
    "content": "#version 460\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _13_15\n{\n    vec4 _m0[1];\n} _15;\n\nlayout(set = 0, binding = 0) uniform writeonly image2DArray _8;\n\nvoid main()\n{\n    uint _24 = floatBitsToUint(_15._m0[0u]).x + 4294967295u;\n    bool _38;\n    if (_24 < 11u)\n    {\n        _38 = bitfieldExtract((bitfieldExtract(440u, int(0u), int(11u)) >> bitfieldExtract(bitfieldExtract(_24, int(0u), int(11u)), int(0u), int(11u))) & 1u, int(0u), int(11u)) != bitfieldExtract(0u, int(0u), int(11u));\n    }\n    else\n    {\n        _38 = true;\n    }\n    if (_38)\n    {\n        imageStore(_8, ivec3(uvec3(1u)), vec4(0.0));\n    }\n    else\n    {\n        imageStore(_8, ivec3(uvec3(1u)), vec4(1.0));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpName %13 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 ArrayStride 16\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 1 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeVector %5 4\n%12 = OpTypeArray %11 %10\n%13 = OpTypeStruct %12\n%14 = OpTypePointer Uniform %13\n%15 = OpVariable %14 Uniform\n%17 = OpConstant %9 0\n%18 = OpTypePointer Uniform %11\n%21 = OpTypeVector %9 4\n%25 = OpConstant %9 4294967295\n%26 = OpTypeBool\n%28 = OpConstant %9 11\n%31 = OpConstant %9 440\n%39 = OpConstantTrue %26\n%40 = OpConstant %5 0\n%41 = OpTypeVector %9 3\n%44 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %47\n%47 = OpLabel\n%16 = OpLoad %6 %8\n%19 = OpAccessChain %18 %15 %17 %17\n%20 = OpLoad %11 %19\n%22 = OpBitcast %21 %20\n%23 = OpCompositeExtract %9 %22 0\n%24 = OpIAdd %9 %23 %25\n%27 = OpULessThan %26 %24 %28\nOpSelectionMerge %49 None\nOpBranchConditional %27 %48 %49\n%48 = OpLabel\n%29 = OpBitFieldUExtract %9 %24 %17 %28\n%32 = OpBitFieldUExtract %9 %31 %17 %28\n%33 = OpBitFieldUExtract %9 %29 %17 %28\n%30 = OpShiftRightLogical %9 %32 %33\n%34 = OpBitwiseAnd %9 %30 %10\n%36 = OpBitFieldUExtract %9 %34 %17 %28\n%37 = OpBitFieldUExtract %9 %17 %17 %28\n%35 = OpINotEqual %26 %36 %37\nOpBranch %49\n%49 = OpLabel\n%38 = OpPhi %26 %39 %47 %35 %48\nOpSelectionMerge %52 None\nOpBranchConditional %38 %51 %50\n%51 = OpLabel\n%42 = OpCompositeConstruct %41 %10 %10 %10\n%43 = OpCompositeConstruct %11 %40 %40 %40 %40\nOpImageWrite %16 %42 %43\nOpBranch %52\n%50 = OpLabel\n%45 = OpCompositeConstruct %41 %10 %10 %10\n%46 = OpCompositeConstruct %11 %44 %44 %44 %44\nOpImageWrite %16 %45 %46\nOpBranch %52\n%52 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/groupshared.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared float _13[256];\nshared float _17[128];\n\nvoid main()\n{\n    float _25 = float(gl_LocalInvocationIndex + 1u);\n    _13[0u + ((0u + (gl_LocalInvocationIndex * 2u)) * 2u)] = float(gl_LocalInvocationIndex);\n    _13[1u + ((0u + (gl_LocalInvocationIndex * 2u)) * 2u)] = _25;\n    float _40 = float(gl_LocalInvocationIndex + 2u);\n    _13[0u + ((1u + (gl_LocalInvocationIndex * 2u)) * 2u)] = _25;\n    _13[1u + ((1u + (gl_LocalInvocationIndex * 2u)) * 2u)] = _40;\n    _17[0u + (gl_LocalInvocationIndex * 2u)] = _40;\n    _17[1u + (gl_LocalInvocationIndex * 2u)] = float(gl_LocalInvocationIndex + 3u);\n    barrier();\n    uint _61 = gl_LocalInvocationIndex ^ 1u;\n    uint _74 = gl_LocalInvocationIndex ^ 2u;\n    uint _89 = gl_LocalInvocationIndex ^ 4u;\n    uint _101 = gl_LocalInvocationIndex * 2u;\n    imageStore(_8, int(_101), uvec4(floatBitsToUint((_13[0u + ((1u + (_74 * 2u)) * 2u)] * _13[0u + ((0u + (_61 * 2u)) * 2u)]) * _17[0u + (_89 * 2u)])));\n    imageStore(_8, int(_101 + 1u), uvec4(floatBitsToUint((_13[1u + ((1u + (_74 * 2u)) * 2u)] * _13[1u + ((0u + (_61 * 2u)) * 2u)]) * _17[1u + (_89 * 2u)])));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 110\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %20\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %20 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 256\n%10 = OpTypeFloat 32\n%11 = OpTypeArray %10 %9\n%12 = OpTypePointer Workgroup %11\n%13 = OpVariable %12 Workgroup\n%14 = OpConstant %5 128\n%15 = OpTypeArray %10 %14\n%16 = OpTypePointer Workgroup %15\n%17 = OpVariable %16 Workgroup\n%19 = OpTypePointer Input %5\n%20 = OpVariable %19 Input\n%24 = OpConstant %5 1\n%27 = OpConstant %5 2\n%29 = OpConstant %5 0\n%32 = OpTypePointer Workgroup %10\n%52 = OpConstant %5 3\n%60 = OpConstant %5 264\n%90 = OpConstant %5 4\n%104 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %108\n%108 = OpLabel\n%18 = OpLoad %6 %8\n%21 = OpLoad %5 %20\n%22 = OpConvertUToF %10 %21\n%23 = OpIAdd %5 %21 %24\n%25 = OpConvertUToF %10 %23\n%26 = OpIMul %5 %21 %27\n%28 = OpIAdd %5 %29 %26\n%30 = OpIMul %5 %28 %27\n%31 = OpIAdd %5 %29 %30\n%33 = OpAccessChain %32 %13 %31\nOpStore %33 %22\n%34 = OpIMul %5 %21 %27\n%35 = OpIAdd %5 %29 %34\n%36 = OpIMul %5 %35 %27\n%37 = OpIAdd %5 %24 %36\n%38 = OpAccessChain %32 %13 %37\nOpStore %38 %25\n%39 = OpIAdd %5 %21 %27\n%40 = OpConvertUToF %10 %39\n%41 = OpIMul %5 %21 %27\n%42 = OpIAdd %5 %24 %41\n%43 = OpIMul %5 %42 %27\n%44 = OpIAdd %5 %29 %43\n%45 = OpAccessChain %32 %13 %44\nOpStore %45 %25\n%46 = OpIMul %5 %21 %27\n%47 = OpIAdd %5 %24 %46\n%48 = OpIMul %5 %47 %27\n%49 = OpIAdd %5 %24 %48\n%50 = OpAccessChain %32 %13 %49\nOpStore %50 %40\n%51 = OpIAdd %5 %21 %52\n%53 = OpConvertUToF %10 %51\n%54 = OpIMul %5 %21 %27\n%55 = OpIAdd %5 %29 %54\n%56 = OpAccessChain %32 %17 %55\nOpStore %56 %40\n%57 = OpIMul %5 %21 %27\n%58 = OpIAdd %5 %24 %57\n%59 = OpAccessChain %32 %17 %58\nOpStore %59 %53\nOpControlBarrier %27 %27 %60\n%61 = OpBitwiseXor %5 %21 %24\n%62 = OpIMul %5 %61 %27\n%63 = OpIAdd %5 %29 %62\n%64 = OpIMul %5 %63 %27\n%65 = OpIAdd %5 %29 %64\n%66 = OpAccessChain %32 %13 %65\n%67 = OpLoad %10 %66\n%68 = OpIMul %5 %61 %27\n%69 = OpIAdd %5 %29 %68\n%70 = OpIMul %5 %69 %27\n%71 = OpIAdd %5 %24 %70\n%72 = OpAccessChain %32 %13 %71\n%73 = OpLoad %10 %72\n%74 = OpBitwiseXor %5 %21 %27\n%75 = OpIMul %5 %74 %27\n%76 = OpIAdd %5 %24 %75\n%77 = OpIMul %5 %76 %27\n%78 = OpIAdd %5 %29 %77\n%79 = OpAccessChain %32 %13 %78\n%80 = OpLoad %10 %79\n%81 = OpIMul %5 %74 %27\n%82 = OpIAdd %5 %24 %81\n%83 = OpIMul %5 %82 %27\n%84 = OpIAdd %5 %24 %83\n%85 = OpAccessChain %32 %13 %84\n%86 = OpLoad %10 %85\n%87 = OpFMul %10 %80 %67\n%88 = OpFMul %10 %86 %73\n%89 = OpBitwiseXor %5 %21 %90\n%91 = OpIMul %5 %89 %27\n%92 = OpIAdd %5 %29 %91\n%93 = OpAccessChain %32 %17 %92\n%94 = OpLoad %10 %93\n%95 = OpIMul %5 %89 %27\n%96 = OpIAdd %5 %24 %95\n%97 = OpAccessChain %32 %17 %96\n%98 = OpLoad %10 %97\n%99 = OpFMul %10 %87 %94\n%100 = OpFMul %10 %88 %98\n%101 = OpIMul %5 %21 %27\n%102 = OpBitcast %5 %99\n%103 = OpBitcast %5 %100\n%105 = OpCompositeConstruct %104 %102 %102 %102 %102\nOpImageWrite %18 %101 %105\n%106 = OpCompositeConstruct %104 %103 %103 %103 %103\n%107 = OpIAdd %5 %101 %24\nOpImageWrite %18 %107 %106\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_eq.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec4 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x == A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%19 = OpConstant %5 2\n%22 = OpConstant %5 3\n%24 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%25 = OpIEqual %24 %14 %17\n%26 = OpSelect %5 %25 %20 %23\nOpStore %10 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_ne.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec4 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x != A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%19 = OpConstant %5 2\n%22 = OpConstant %5 3\n%24 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%25 = OpINotEqual %24 %14 %17\n%26 = OpSelect %5 %25 %20 %23\nOpStore %10 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_sge.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec4 A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    SV_Target = int((int(uint(A.x)) >= int(uint(A.y))) ? uint(A.z) : uint(A.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%22 = OpConstant %13 2\n%26 = OpConstant %13 3\n%29 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %13 %23\n%25 = OpAccessChain %11 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpBitcast %13 %27\n%30 = OpSGreaterThanEqual %29 %16 %20\n%31 = OpSelect %13 %30 %24 %28\n%32 = OpBitcast %5 %31\nOpStore %10 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_sgt.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec4 A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    SV_Target = int((int(uint(A.x)) > int(uint(A.y))) ? uint(A.z) : uint(A.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%22 = OpConstant %13 2\n%26 = OpConstant %13 3\n%29 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %13 %23\n%25 = OpAccessChain %11 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpBitcast %13 %27\n%30 = OpSGreaterThan %29 %16 %20\n%31 = OpSelect %13 %30 %24 %28\n%32 = OpBitcast %5 %31\nOpStore %10 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_sle.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec4 A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    SV_Target = int((int(uint(A.x)) <= int(uint(A.y))) ? uint(A.z) : uint(A.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%22 = OpConstant %13 2\n%26 = OpConstant %13 3\n%29 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %13 %23\n%25 = OpAccessChain %11 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpBitcast %13 %27\n%30 = OpSLessThanEqual %29 %16 %20\n%31 = OpSelect %13 %30 %24 %28\n%32 = OpBitcast %5 %31\nOpStore %10 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_slt.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec4 A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    SV_Target = int((int(uint(A.x)) < int(uint(A.y))) ? uint(A.z) : uint(A.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%22 = OpConstant %13 2\n%26 = OpConstant %13 3\n%29 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %13 %23\n%25 = OpAccessChain %11 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpBitcast %13 %27\n%30 = OpSLessThan %29 %16 %20\n%31 = OpSelect %13 %30 %24 %28\n%32 = OpBitcast %5 %31\nOpStore %10 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_uge.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec4 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x >= A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%19 = OpConstant %5 2\n%22 = OpConstant %5 3\n%24 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%25 = OpUGreaterThanEqual %24 %14 %17\n%26 = OpSelect %5 %25 %20 %23\nOpStore %10 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_ugt.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec4 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x > A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%19 = OpConstant %5 2\n%22 = OpConstant %5 3\n%24 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%25 = OpUGreaterThan %24 %14 %17\n%26 = OpSelect %5 %25 %20 %23\nOpStore %10 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_ule.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec4 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x <= A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%19 = OpConstant %5 2\n%22 = OpConstant %5 3\n%24 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%25 = OpULessThanEqual %24 %14 %17\n%26 = OpSelect %5 %25 %20 %23\nOpStore %10 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/icmp_ult.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uvec4 A;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = (A.x < A.y) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpConstant %5 0\n%16 = OpConstant %5 1\n%19 = OpConstant %5 2\n%22 = OpConstant %5 3\n%24 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%12 = OpAccessChain %11 %8 %13\n%14 = OpLoad %5 %12\n%15 = OpAccessChain %11 %8 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %11 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%25 = OpULessThan %24 %14 %17\n%26 = OpSelect %5 %25 %20 %23\nOpStore %10 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/logical-and.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    float _28;\n    if (isnan(A.x))\n    {\n        float frontier_phi_3_1_ladder;\n        if (isnan(A.y))\n        {\n            frontier_phi_3_1_ladder = A.z;\n        }\n        else\n        {\n            frontier_phi_3_1_ladder = A.w;\n        }\n        _28 = frontier_phi_3_1_ladder;\n    }\n    else\n    {\n        _28 = A.w;\n    }\n    SV_Target = _28;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpName %29 \"frontier_phi_3.1.ladder\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 3\n%19 = OpTypeBool\n%22 = OpConstant %13 2\n%25 = OpConstant %13 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%20 = OpIsNan %19 %15\nOpSelectionMerge %35 None\nOpBranchConditional %20 %32 %31\n%32 = OpLabel\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %11 %8 %25\n%26 = OpLoad %5 %24\n%27 = OpIsNan %19 %26\nOpSelectionMerge %34 None\nOpBranchConditional %27 %34 %33\n%33 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%29 = OpPhi %5 %23 %32 %18 %33\nOpBranch %35\n%31 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%28 = OpPhi %5 %18 %31 %29 %34\nOpStore %10 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/logical-equal.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (isnan(A.x) != isnan(A.y)) ? A.w : A.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpIsNan %25 %15\n%27 = OpIsNan %25 %18\n%28 = OpLogicalNotEqual %25 %26 %27\n%29 = OpSelect %5 %28 %24 %21\nOpStore %10 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/logical-not-equal.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = (isnan(A.x) != isnan(A.y)) ? A.z : A.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%25 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%26 = OpIsNan %25 %15\n%27 = OpIsNan %25 %18\n%28 = OpLogicalNotEqual %25 %26 %27\n%29 = OpSelect %5 %28 %21 %24\nOpStore %10 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/logical-or.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 A;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    float _21;\n    if (isnan(A.x))\n    {\n        _21 = A.z;\n    }\n    else\n    {\n        _21 = isnan(A.y) ? A.z : A.w;\n    }\n    SV_Target = _21;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %5\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 2\n%19 = OpTypeBool\n%24 = OpConstant %13 3\n%27 = OpConstant %13 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%20 = OpIsNan %19 %15\nOpSelectionMerge %32 None\nOpBranchConditional %20 %32 %31\n%31 = OpLabel\n%23 = OpAccessChain %11 %8 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %11 %8 %27\n%28 = OpLoad %5 %26\n%29 = OpIsNan %19 %28\n%22 = OpSelect %5 %29 %18 %25\nOpBranch %32\n%32 = OpLabel\n%21 = OpPhi %5 %18 %30 %22 %31\nOpStore %10 %21\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/lut.frag",
    "content": "#version 460\n\nconst uint _29[16] = uint[](1u, 4294967295u, 2u, 4294967294u, 3u, 4294967293u, 5u, 4294967291u, 7u, 4294967289u, 11u, 4294967285u, 13u, 4294967283u, 17u, 4294967279u);\n\nlayout(location = 0) flat in uint TEXCOORD;\nlayout(location = 0) out uvec2 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = _29[0u + (TEXCOORD * 2u)];\n    SV_Target.y = _29[1u + (TEXCOORD * 2u)];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"TEXCOORD\"\nOpName %10 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 2\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%11 = OpConstant %5 16\n%12 = OpTypeArray %5 %11\n%13 = OpConstant %5 1\n%14 = OpConstant %5 4294967295\n%15 = OpConstant %5 2\n%16 = OpConstant %5 4294967294\n%17 = OpConstant %5 3\n%18 = OpConstant %5 4294967293\n%19 = OpConstant %5 5\n%20 = OpConstant %5 4294967291\n%21 = OpConstant %5 7\n%22 = OpConstant %5 4294967289\n%23 = OpConstant %5 11\n%24 = OpConstant %5 4294967285\n%25 = OpConstant %5 13\n%26 = OpConstant %5 4294967283\n%27 = OpConstant %5 17\n%28 = OpConstant %5 4294967279\n%29 = OpConstantComposite %12 %13 %14 %15 %16 %17 %18 %19 %20 %21 %22 %23 %24 %25 %26 %27 %28\n%30 = OpTypePointer Private %12\n%31 = OpVariable %30 Private %29\n%35 = OpConstant %5 0\n%36 = OpTypePointer Private %5\n%43 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%32 = OpLoad %5 %7\n%33 = OpIMul %5 %32 %15\n%34 = OpIAdd %5 %35 %33\n%37 = OpAccessChain %36 %31 %34\n%38 = OpLoad %5 %37\n%39 = OpIMul %5 %32 %15\n%40 = OpIAdd %5 %13 %39\n%41 = OpAccessChain %36 %31 %40\n%42 = OpLoad %5 %41\n%44 = OpAccessChain %43 %10 %35\nOpStore %44 %38\n%45 = OpAccessChain %43 %10 %13\nOpStore %45 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/min16-phi.sm60.comp",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _8;\nlayout(set = 0, binding = 1) uniform mediump texture2D _9;\nlayout(set = 0, binding = 2) uniform mediump texture2D _10;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _14;\n\nvoid main()\n{\n    mediump float _45;\n    mediump float _48;\n    mediump float _51;\n    mediump float _54;\n    if (gl_GlobalInvocationID.x < 20u)\n    {\n        mediump vec4 _36 = texelFetch(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), int(gl_GlobalInvocationID.z));\n        _45 = _36.x;\n        _48 = _36.y;\n        _51 = _36.z;\n        _54 = _36.w;\n    }\n    else\n    {\n        mediump float frontier_phi_3_2_ladder;\n        mediump float frontier_phi_3_2_ladder_1;\n        mediump float frontier_phi_3_2_ladder_2;\n        mediump float frontier_phi_3_2_ladder_3;\n        if (gl_GlobalInvocationID.y < 40u)\n        {\n            mediump vec4 _72 = texelFetch(_9, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), int(gl_GlobalInvocationID.z));\n            frontier_phi_3_2_ladder = _72.x;\n            frontier_phi_3_2_ladder_1 = _72.y;\n            frontier_phi_3_2_ladder_2 = _72.z;\n            frontier_phi_3_2_ladder_3 = _72.w;\n        }\n        else\n        {\n            mediump vec4 _74 = texelFetch(_10, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), int(gl_GlobalInvocationID.z));\n            frontier_phi_3_2_ladder = _74.x;\n            frontier_phi_3_2_ladder_1 = _74.y;\n            frontier_phi_3_2_ladder_2 = _74.z;\n            frontier_phi_3_2_ladder_3 = _74.w;\n        }\n        _45 = frontier_phi_3_2_ladder;\n        _48 = frontier_phi_3_2_ladder_1;\n        _51 = frontier_phi_3_2_ladder_2;\n        _54 = frontier_phi_3_2_ladder_3;\n    }\n    uint _57 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_14, int(_57), uvec4(floatBitsToUint(_45)));\n    imageStore(_14, int(_57 + 1u), uvec4(floatBitsToUint(_48)));\n    imageStore(_14, int(_57 + 2u), uvec4(floatBitsToUint(_51)));\n    imageStore(_14, int(_57 + 3u), uvec4(floatBitsToUint(_54)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 88\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %21\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %76 \"frontier_phi_3.2.ladder\"\nOpName %77 \"frontier_phi_3.2.ladder\"\nOpName %78 \"frontier_phi_3.2.ladder\"\nOpName %79 \"frontier_phi_3.2.ladder\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 RelaxedPrecision\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %10 RelaxedPrecision\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonReadable\nOpDecorate %21 BuiltIn GlobalInvocationId\nOpDecorate %36 RelaxedPrecision\nOpDecorate %39 RelaxedPrecision\nOpDecorate %40 RelaxedPrecision\nOpDecorate %41 RelaxedPrecision\nOpDecorate %42 RelaxedPrecision\nOpDecorate %72 RelaxedPrecision\nOpDecorate %46 RelaxedPrecision\nOpDecorate %49 RelaxedPrecision\nOpDecorate %52 RelaxedPrecision\nOpDecorate %55 RelaxedPrecision\nOpDecorate %74 RelaxedPrecision\nOpDecorate %47 RelaxedPrecision\nOpDecorate %50 RelaxedPrecision\nOpDecorate %53 RelaxedPrecision\nOpDecorate %56 RelaxedPrecision\nOpDecorate %76 RelaxedPrecision\nOpDecorate %77 RelaxedPrecision\nOpDecorate %78 RelaxedPrecision\nOpDecorate %79 RelaxedPrecision\nOpDecorate %45 RelaxedPrecision\nOpDecorate %48 RelaxedPrecision\nOpDecorate %51 RelaxedPrecision\nOpDecorate %54 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypeInt 32 0\n%12 = OpTypeImage %11 Buffer 0 0 0 2 R32ui\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%19 = OpTypeVector %11 3\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Input %11\n%24 = OpConstant %11 0\n%27 = OpConstant %11 1\n%30 = OpConstant %11 2\n%32 = OpTypeBool\n%34 = OpConstant %11 20\n%35 = OpTypeVector %5 4\n%37 = OpTypeVector %11 2\n%44 = OpConstant %11 40\n%58 = OpConstant %11 4\n%63 = OpTypeVector %11 4\n%71 = OpConstant %11 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %80\n%80 = OpLabel\n%15 = OpLoad %12 %14\n%16 = OpLoad %6 %10\n%17 = OpLoad %6 %9\n%18 = OpLoad %6 %8\n%23 = OpAccessChain %22 %21 %24\n%25 = OpLoad %11 %23\n%26 = OpAccessChain %22 %21 %27\n%28 = OpLoad %11 %26\n%29 = OpAccessChain %22 %21 %30\n%31 = OpLoad %11 %29\n%33 = OpULessThan %32 %25 %34\nOpSelectionMerge %86 None\nOpBranchConditional %33 %85 %81\n%85 = OpLabel\n%38 = OpCompositeConstruct %37 %25 %28\n%36 = OpImageFetch %35 %18 %38 Lod %31\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeExtract %5 %36 1\n%41 = OpCompositeExtract %5 %36 2\n%42 = OpCompositeExtract %5 %36 3\nOpBranch %86\n%81 = OpLabel\n%43 = OpULessThan %32 %28 %44\nOpSelectionMerge %84 None\nOpBranchConditional %43 %83 %82\n%83 = OpLabel\n%73 = OpCompositeConstruct %37 %25 %28\n%72 = OpImageFetch %35 %17 %73 Lod %31\n%46 = OpCompositeExtract %5 %72 0\n%49 = OpCompositeExtract %5 %72 1\n%52 = OpCompositeExtract %5 %72 2\n%55 = OpCompositeExtract %5 %72 3\nOpBranch %84\n%82 = OpLabel\n%75 = OpCompositeConstruct %37 %25 %28\n%74 = OpImageFetch %35 %16 %75 Lod %31\n%47 = OpCompositeExtract %5 %74 0\n%50 = OpCompositeExtract %5 %74 1\n%53 = OpCompositeExtract %5 %74 2\n%56 = OpCompositeExtract %5 %74 3\nOpBranch %84\n%84 = OpLabel\n%76 = OpPhi %5 %46 %83 %47 %82\n%77 = OpPhi %5 %49 %83 %50 %82\n%78 = OpPhi %5 %52 %83 %53 %82\n%79 = OpPhi %5 %55 %83 %56 %82\nOpBranch %86\n%86 = OpLabel\n%45 = OpPhi %5 %39 %85 %76 %84\n%48 = OpPhi %5 %40 %85 %77 %84\n%51 = OpPhi %5 %41 %85 %78 %84\n%54 = OpPhi %5 %42 %85 %79 %84\n%57 = OpIMul %11 %25 %58\n%59 = OpBitcast %11 %45\n%60 = OpBitcast %11 %48\n%61 = OpBitcast %11 %51\n%62 = OpBitcast %11 %54\n%64 = OpCompositeConstruct %63 %59 %59 %59 %59\nOpImageWrite %15 %57 %64\n%65 = OpCompositeConstruct %63 %60 %60 %60 %60\n%66 = OpIAdd %11 %57 %27\nOpImageWrite %15 %66 %65\n%67 = OpCompositeConstruct %63 %61 %61 %61 %61\n%68 = OpIAdd %11 %57 %30\nOpImageWrite %15 %68 %67\n%69 = OpCompositeConstruct %63 %62 %62 %62 %62\n%70 = OpIAdd %11 %57 %71\nOpImageWrite %15 %70 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/precise_math.frag",
    "content": "#version 460\n\nlayout(location = 0) in float A;\nlayout(location = 0, component = 1) in float B;\nlayout(location = 0, component = 2) in float C;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    precise float _15 = B * A;\n    precise float _16 = C + _15;\n    precise float _17 = A + _16;\n    precise float _18 = _17 - B;\n    precise float _19 = C * _18;\n    SV_Target = _19;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %8 %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %8 \"B\"\nOpName %9 \"C\"\nOpName %11 \"SV_Target\"\nOpDecorate %7 Location 0\nOpDecorate %8 Location 0\nOpDecorate %8 Component 1\nOpDecorate %9 Location 0\nOpDecorate %9 Component 2\nOpDecorate %11 Location 0\nOpDecorate %15 NoContraction\nOpDecorate %16 NoContraction\nOpDecorate %17 NoContraction\nOpDecorate %18 NoContraction\nOpDecorate %19 NoContraction\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpVariable %6 Input\n%10 = OpTypePointer Output %5\n%11 = OpVariable %10 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%12 = OpLoad %5 %9\n%13 = OpLoad %5 %8\n%14 = OpLoad %5 %7\n%15 = OpFMul %5 %13 %14\n%16 = OpFAdd %5 %12 %15\n%17 = OpFAdd %5 %14 %16\n%18 = OpFSub %5 %17 %13\n%19 = OpFMul %5 %12 %18\nOpStore %11 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/llvm-builtin/zext-bool.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(V != 40u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 19\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"V\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 Flat\nOpDecorate %7 Location 0\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%11 = OpTypeBool\n%13 = OpConstant %5 40\n%14 = OpConstant %5 0\n%15 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %17\n%17 = OpLabel\n%10 = OpLoad %5 %7\n%12 = OpINotEqual %11 %10 %13\n%16 = OpSelect %5 %12 %15 %14\nOpStore %9 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent-promotion.bindless.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _13[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _16_19\n{\n    uvec4 _m0[];\n} _19[];\n\nlayout(set = 4, binding = 0, std430) coherent buffer _21_24\n{\n    uvec4 _m0[];\n} _24[];\n\nlayout(set = 4, binding = 0, std430) readonly buffer _26_29\n{\n    uvec4 _m0[];\n} _29[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _31_34\n{\n    uvec4 _m0[];\n} _34[];\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _42[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _65 = registers._m1 + 1u;\n    _24[registers._m4]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_42[registers._m5]._m0[0u]).x == 0u))\n    {\n        uint _107 = 0u;\n        uint _111;\n        uint _114;\n        bool _116;\n        for (;;)\n        {\n            _111 = (_107 << 8u) + gl_LocalInvocationIndex;\n            _114 = _13[registers._m1]._m0[_111];\n            groupMemoryBarrier();\n            barrier();\n            _116 = _114 < 256u;\n            if (_116)\n            {\n                vec4 _120 = uintBitsToFloat(_19[_65]._m0[_111]);\n                vec4 _127 = uintBitsToFloat(_24[registers._m4]._m0[_114]);\n                _24[registers._m4]._m0[_114] = uvec4(floatBitsToUint(_127.x + _120.x), floatBitsToUint(_127.y + _120.y), floatBitsToUint(_127.z + _120.z), floatBitsToUint(_127.w + _120.w));\n            }\n            uint _108 = _107 + 1u;\n            if (_108 < floatBitsToUint(_42[registers._m5]._m0[0u]).x)\n            {\n                _107 = _108;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _96 = uintBitsToFloat(_29[registers._m4 + 1u]._m0[gl_LocalInvocationIndex]);\n    _34[registers._m4 + 2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_96.x), floatBitsToUint(_96.y), floatBitsToUint(_96.z), floatBitsToUint(_96.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 157\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %76\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %10 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %31 \"SSBO\"\nOpName %39 \"BindlessCBV\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %9 ArrayStride 4\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %13 DescriptorSet 1\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 16\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 4\nOpDecorate %24 Binding 0\nOpDecorate %24 Coherent\nOpDecorate %25 ArrayStride 16\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 DescriptorSet 4\nOpDecorate %29 Binding 0\nOpDecorate %29 NonWritable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %34 DescriptorSet 4\nOpDecorate %34 Binding 0\nOpDecorate %34 NonReadable\nOpDecorate %38 ArrayStride 16\nOpDecorate %39 Block\nOpMemberDecorate %39 0 Offset 0\nOpDecorate %42 DescriptorSet 5\nOpDecorate %42 Binding 0\nOpDecorate %76 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeRuntimeArray %5\n%10 = OpTypeStruct %9\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeVector %5 4\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %14\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %14\n%26 = OpTypeStruct %25\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeRuntimeArray %14\n%31 = OpTypeStruct %30\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeFloat 32\n%36 = OpTypeVector %35 4\n%37 = OpConstant %5 4096\n%38 = OpTypeArray %36 %37\n%39 = OpTypeStruct %38\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer Uniform %40\n%42 = OpVariable %41 Uniform\n%43 = OpTypePointer StorageBuffer %31\n%45 = OpTypePointer PushConstant %5\n%47 = OpConstant %5 4\n%50 = OpConstant %5 2\n%51 = OpTypePointer StorageBuffer %26\n%56 = OpConstant %5 1\n%57 = OpTypePointer StorageBuffer %21\n%61 = OpTypePointer StorageBuffer %16\n%66 = OpTypePointer StorageBuffer %10\n%70 = OpTypePointer Uniform %39\n%73 = OpConstant %5 5\n%75 = OpTypePointer Input %5\n%76 = OpVariable %75 Input\n%78 = OpConstant %35 0\n%84 = OpTypePointer StorageBuffer %14\n%86 = OpConstant %5 0\n%87 = OpTypePointer Uniform %36\n%92 = OpTypeBool\n%110 = OpConstant %5 8\n%112 = OpTypePointer StorageBuffer %5\n%115 = OpConstant %5 2120\n%117 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %147\n%147 = OpLabel\n%46 = OpAccessChain %45 %8 %47\n%48 = OpLoad %5 %46\n%49 = OpIAdd %5 %48 %50\n%44 = OpAccessChain %43 %34 %49\n%53 = OpAccessChain %45 %8 %47\n%54 = OpLoad %5 %53\n%55 = OpIAdd %5 %54 %56\n%52 = OpAccessChain %51 %29 %55\n%59 = OpAccessChain %45 %8 %47\n%60 = OpLoad %5 %59\n%58 = OpAccessChain %57 %24 %60\n%63 = OpAccessChain %45 %8 %56\n%64 = OpLoad %5 %63\n%65 = OpIAdd %5 %64 %56\n%62 = OpAccessChain %61 %19 %65\n%68 = OpAccessChain %45 %8 %56\n%69 = OpLoad %5 %68\n%67 = OpAccessChain %66 %13 %69\n%72 = OpAccessChain %45 %8 %73\n%74 = OpLoad %5 %72\n%71 = OpAccessChain %70 %42 %74\n%77 = OpLoad %5 %76\n%79 = OpBitcast %5 %78\n%80 = OpBitcast %5 %78\n%81 = OpBitcast %5 %78\n%82 = OpBitcast %5 %78\n%83 = OpCompositeConstruct %14 %79 %80 %81 %82\n%85 = OpAccessChain %84 %58 %86 %77\nOpStore %85 %83\n%88 = OpAccessChain %87 %71 %86 %86\n%89 = OpLoad %36 %88\n%90 = OpBitcast %14 %89\n%91 = OpCompositeExtract %5 %90 0\n%93 = OpIEqual %92 %91 %86\nOpSelectionMerge %155 None\nOpBranchConditional %93 %155 %148\n%148 = OpLabel\nOpBranch %149\n%149 = OpLabel\n%107 = OpPhi %5 %86 %148 %108 %153\n%109 = OpShiftLeftLogical %5 %107 %110\n%111 = OpIAdd %5 %109 %77\n%113 = OpAccessChain %112 %67 %86 %111\n%114 = OpLoad %5 %113\nOpControlBarrier %50 %50 %115\n%116 = OpULessThan %92 %114 %117\nOpLoopMerge %154 %153 None\nOpBranch %150\n%150 = OpLabel\nOpSelectionMerge %152 None\nOpBranchConditional %116 %151 %152\n%151 = OpLabel\n%118 = OpAccessChain %84 %62 %86 %111\n%119 = OpLoad %14 %118\n%120 = OpBitcast %36 %119\n%121 = OpCompositeExtract %35 %120 0\n%122 = OpCompositeExtract %35 %120 1\n%123 = OpCompositeExtract %35 %120 2\n%124 = OpCompositeExtract %35 %120 3\n%125 = OpAccessChain %84 %58 %86 %114\n%126 = OpLoad %14 %125\n%127 = OpBitcast %36 %126\n%128 = OpCompositeExtract %35 %127 0\n%129 = OpCompositeExtract %35 %127 1\n%130 = OpCompositeExtract %35 %127 2\n%131 = OpCompositeExtract %35 %127 3\n%132 = OpFAdd %35 %128 %121\n%133 = OpFAdd %35 %129 %122\n%134 = OpFAdd %35 %130 %123\n%135 = OpFAdd %35 %131 %124\n%136 = OpBitcast %5 %132\n%137 = OpBitcast %5 %133\n%138 = OpBitcast %5 %134\n%139 = OpBitcast %5 %135\n%140 = OpCompositeConstruct %14 %136 %137 %138 %139\n%141 = OpAccessChain %84 %58 %86 %114\nOpStore %141 %140\nOpBranch %152\n%152 = OpLabel\nOpBranch %153\n%153 = OpLabel\n%108 = OpIAdd %5 %107 %56\n%142 = OpAccessChain %87 %71 %86 %86\n%143 = OpLoad %36 %142\n%144 = OpBitcast %14 %143\n%145 = OpCompositeExtract %5 %144 0\n%146 = OpULessThan %92 %108 %145\nOpBranchConditional %146 %149 %154\n%154 = OpLabel\nOpBranch %155\n%155 = OpLabel\n%94 = OpAccessChain %84 %52 %86 %77\n%95 = OpLoad %14 %94\n%96 = OpBitcast %36 %95\n%97 = OpCompositeExtract %35 %96 0\n%98 = OpCompositeExtract %35 %96 1\n%99 = OpCompositeExtract %35 %96 2\n%100 = OpCompositeExtract %35 %96 3\n%101 = OpBitcast %5 %97\n%102 = OpBitcast %5 %98\n%103 = OpBitcast %5 %99\n%104 = OpBitcast %5 %100\n%105 = OpCompositeConstruct %14 %101 %102 %103 %104\n%106 = OpAccessChain %84 %44 %86 %77\nOpStore %106 %105\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent-promotion.root-descriptor.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4CoherentArray;\nlayout(buffer_reference) buffer PhysicalPointerUint4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4Array;\nlayout(buffer_reference) buffer PhysicalPointerUintNonWriteArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) coherent buffer PhysicalPointerFloat4CoherentArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint4NonWriteCBVArray\n{\n    uvec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) buffer PhysicalPointerFloat4Array\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerUintNonWriteArray\n{\n    uint value[];\n};\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    PhysicalPointerFloat4CoherentArray(registers._m2).value[gl_LocalInvocationIndex] = vec4(0.0);\n    if (!(PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x == 0u))\n    {\n        uint _73 = 0u;\n        uint _77;\n        uint _84;\n        bool _86;\n        for (;;)\n        {\n            _77 = (_73 << 8u) + gl_LocalInvocationIndex;\n            _84 = PhysicalPointerUintNonWriteArray(registers._m1).value[_77];\n            groupMemoryBarrier();\n            barrier();\n            _86 = _84 < 256u;\n            if (_86)\n            {\n                vec4 _90 = uintBitsToFloat(_14._m0[_77]);\n                PhysicalPointerFloat4CoherentArray _95 = PhysicalPointerFloat4CoherentArray(registers._m2);\n                PhysicalPointerFloat4CoherentArray(registers._m2).value[_84] = vec4(_95.value[_84].x + _90.x, _95.value[_84].y + _90.y, _95.value[_84].z + _90.z, _95.value[_84].w + _90.w);\n            }\n            uint _74 = _73 + 1u;\n            if (_74 < PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x)\n            {\n                _73 = _74;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    PhysicalPointerFloat4Array _59 = PhysicalPointerFloat4Array(registers._m3);\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_59.value[gl_LocalInvocationIndex].x), floatBitsToUint(_59.value[gl_LocalInvocationIndex].y), floatBitsToUint(_59.value[gl_LocalInvocationIndex].z), floatBitsToUint(_59.value[gl_LocalInvocationIndex].w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 124\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %33\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %38 \"PhysicalPointerFloat4CoherentArray\"\nOpMemberName %38 0 \"value\"\nOpName %47 \"PhysicalPointerUint4NonWriteCBVArray\"\nOpMemberName %47 0 \"value\"\nOpName %57 \"PhysicalPointerFloat4Array\"\nOpMemberName %57 0 \"value\"\nOpName %79 \"PhysicalPointerUintNonWriteArray\"\nOpMemberName %79 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 2\nOpDecorate %18 NonReadable\nOpDecorate %33 BuiltIn LocalInvocationIndex\nOpDecorate %37 ArrayStride 16\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpMemberDecorate %38 0 Coherent\nOpDecorate %46 ArrayStride 16\nOpMemberDecorate %47 0 Offset 0\nOpDecorate %47 Block\nOpMemberDecorate %47 0 NonWritable\nOpDecorate %56 ArrayStride 16\nOpMemberDecorate %57 0 Offset 0\nOpDecorate %57 Block\nOpDecorate %78 ArrayStride 4\nOpMemberDecorate %79 0 Offset 0\nOpDecorate %79 Block\nOpMemberDecorate %79 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypePointer PushConstant %6\n%21 = OpConstant %5 3\n%24 = OpConstant %5 2\n%27 = OpConstant %5 1\n%30 = OpConstant %5 0\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%35 = OpTypeFloat 32\n%36 = OpTypeVector %35 4\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypeStruct %37\n%39 = OpTypePointer PhysicalStorageBuffer %38\n%41 = OpTypePointer PhysicalStorageBuffer %36\n%43 = OpConstant %35 0\n%45 = OpConstant %5 4096\n%46 = OpTypeArray %10 %45\n%47 = OpTypeStruct %46\n%48 = OpTypePointer PhysicalStorageBuffer %47\n%50 = OpTypePointer PhysicalStorageBuffer %10\n%54 = OpTypeBool\n%56 = OpTypeRuntimeArray %36\n%57 = OpTypeStruct %56\n%58 = OpTypePointer PhysicalStorageBuffer %57\n%71 = OpTypePointer StorageBuffer %10\n%76 = OpConstant %5 8\n%78 = OpTypeRuntimeArray %5\n%79 = OpTypeStruct %78\n%80 = OpTypePointer PhysicalStorageBuffer %79\n%82 = OpTypePointer PhysicalStorageBuffer %5\n%85 = OpConstant %5 2120\n%87 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%20 = OpAccessChain %19 %9 %21\n%22 = OpLoad %6 %20\n%23 = OpAccessChain %19 %9 %24\n%25 = OpLoad %6 %23\n%26 = OpAccessChain %19 %9 %27\n%28 = OpLoad %6 %26\n%29 = OpAccessChain %19 %9 %30\n%31 = OpLoad %6 %29\n%34 = OpLoad %5 %33\n%40 = OpBitcast %39 %25\n%42 = OpInBoundsAccessChain %41 %40 %30 %34\n%44 = OpCompositeConstruct %36 %43 %43 %43 %43\nOpStore %42 %44 Aligned 16\n%49 = OpBitcast %48 %31\n%51 = OpInBoundsAccessChain %50 %49 %30 %30\n%52 = OpLoad %10 %51 Aligned 16\n%53 = OpCompositeExtract %5 %52 0\n%55 = OpIEqual %54 %53 %30\nOpSelectionMerge %122 None\nOpBranchConditional %55 %122 %115\n%115 = OpLabel\nOpBranch %116\n%116 = OpLabel\n%73 = OpPhi %5 %30 %115 %74 %120\n%75 = OpShiftLeftLogical %5 %73 %76\n%77 = OpIAdd %5 %75 %34\n%81 = OpBitcast %80 %28\n%83 = OpInBoundsAccessChain %82 %81 %30 %77\n%84 = OpLoad %5 %83 Aligned 4\nOpControlBarrier %24 %24 %85\n%86 = OpULessThan %54 %84 %87\nOpLoopMerge %121 %120 None\nOpBranch %117\n%117 = OpLabel\nOpSelectionMerge %119 None\nOpBranchConditional %86 %118 %119\n%118 = OpLabel\n%88 = OpAccessChain %71 %14 %30 %77\n%89 = OpLoad %10 %88\n%90 = OpBitcast %36 %89\n%91 = OpCompositeExtract %35 %90 0\n%92 = OpCompositeExtract %35 %90 1\n%93 = OpCompositeExtract %35 %90 2\n%94 = OpCompositeExtract %35 %90 3\n%95 = OpBitcast %39 %25\n%96 = OpInBoundsAccessChain %41 %95 %30 %84\n%97 = OpLoad %36 %96 Aligned 16\n%98 = OpCompositeExtract %35 %97 0\n%99 = OpCompositeExtract %35 %97 1\n%100 = OpCompositeExtract %35 %97 2\n%101 = OpCompositeExtract %35 %97 3\n%102 = OpFAdd %35 %98 %91\n%103 = OpFAdd %35 %99 %92\n%104 = OpFAdd %35 %100 %93\n%105 = OpFAdd %35 %101 %94\n%106 = OpBitcast %39 %25\n%107 = OpInBoundsAccessChain %41 %106 %30 %84\n%108 = OpCompositeConstruct %36 %102 %103 %104 %105\nOpStore %107 %108 Aligned 16\nOpBranch %119\n%119 = OpLabel\nOpBranch %120\n%120 = OpLabel\n%74 = OpIAdd %5 %73 %27\n%109 = OpBitcast %48 %31\n%110 = OpInBoundsAccessChain %50 %109 %30 %30\n%111 = OpLoad %10 %110 Aligned 16\n%112 = OpCompositeExtract %5 %111 0\n%113 = OpULessThan %54 %74 %112\nOpBranchConditional %113 %116 %121\n%121 = OpLabel\nOpBranch %122\n%122 = OpLabel\n%59 = OpBitcast %58 %22\n%60 = OpInBoundsAccessChain %41 %59 %30 %34\n%61 = OpLoad %36 %60 Aligned 16\n%62 = OpCompositeExtract %35 %61 0\n%63 = OpCompositeExtract %35 %61 1\n%64 = OpCompositeExtract %35 %61 2\n%65 = OpCompositeExtract %35 %61 3\n%66 = OpBitcast %5 %62\n%67 = OpBitcast %5 %63\n%68 = OpBitcast %5 %64\n%69 = OpBitcast %5 %65\n%70 = OpCompositeConstruct %10 %66 %67 %68 %69\n%72 = OpAccessChain %71 %18 %30 %34\nOpStore %72 %70\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent-promotion.sm66.bindless.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) coherent buffer SSBO\n{\n    uvec4 _m0[];\n} _14[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _16_19\n{\n    uint _m0[];\n} _19[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _21_24\n{\n    uvec4 _m0[];\n} _24[];\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _32[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    _14[0u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_32[registers._m5]._m0[0u]).x == 0u))\n    {\n        uint _77 = 0u;\n        uint _81;\n        uint _88;\n        bool _90;\n        for (;;)\n        {\n            _81 = (_77 << 8u) + gl_LocalInvocationIndex;\n            _88 = _19[registers._m1]._m0[_81];\n            groupMemoryBarrier();\n            barrier();\n            _90 = _88 < 256u;\n            if (_90)\n            {\n                vec4 _99 = uintBitsToFloat(_24[registers._m1 + 1u]._m0[_81]);\n                vec4 _106 = uintBitsToFloat(_14[0u]._m0[_88]);\n                _14[0u]._m0[_88] = uvec4(floatBitsToUint(_106.x + _99.x), floatBitsToUint(_106.y + _99.y), floatBitsToUint(_106.z + _99.z), floatBitsToUint(_106.w + _99.w));\n            }\n            uint _78 = _77 + 1u;\n            if (_78 < floatBitsToUint(_32[registers._m5]._m0[0u]).x)\n            {\n                _77 = _78;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _66 = uintBitsToFloat(_14[1u]._m0[gl_LocalInvocationIndex]);\n    _14[2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_66.x), floatBitsToUint(_66.y), floatBitsToUint(_66.z), floatBitsToUint(_66.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 136\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %40\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %29 \"BindlessCBV\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 16\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 Coherent\nOpDecorate %15 ArrayStride 4\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 16\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %28 ArrayStride 16\nOpDecorate %29 Block\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %32 DescriptorSet 5\nOpDecorate %32 Binding 0\nOpDecorate %40 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %5\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %9\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeFloat 32\n%26 = OpTypeVector %25 4\n%27 = OpConstant %5 4096\n%28 = OpTypeArray %26 %27\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer Uniform %30\n%32 = OpVariable %31 Uniform\n%33 = OpTypePointer Uniform %29\n%35 = OpTypePointer PushConstant %5\n%37 = OpConstant %5 5\n%39 = OpTypePointer Input %5\n%40 = OpVariable %39 Input\n%42 = OpTypePointer StorageBuffer %11\n%44 = OpConstant %5 0\n%46 = OpConstant %5 1\n%48 = OpConstant %5 2\n%49 = OpConstant %25 0\n%55 = OpTypePointer StorageBuffer %9\n%57 = OpTypePointer Uniform %26\n%62 = OpTypeBool\n%80 = OpConstant %5 8\n%82 = OpTypePointer StorageBuffer %16\n%86 = OpTypePointer StorageBuffer %5\n%89 = OpConstant %5 2120\n%91 = OpConstant %5 256\n%92 = OpTypePointer StorageBuffer %21\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %126\n%126 = OpLabel\n%36 = OpAccessChain %35 %8 %37\n%38 = OpLoad %5 %36\n%34 = OpAccessChain %33 %32 %38\n%41 = OpLoad %5 %40\n%43 = OpAccessChain %42 %14 %44\n%45 = OpAccessChain %42 %14 %46\n%47 = OpAccessChain %42 %14 %48\n%50 = OpBitcast %5 %49\n%51 = OpBitcast %5 %49\n%52 = OpBitcast %5 %49\n%53 = OpBitcast %5 %49\n%54 = OpCompositeConstruct %9 %50 %51 %52 %53\n%56 = OpAccessChain %55 %43 %44 %41\nOpStore %56 %54\n%58 = OpAccessChain %57 %34 %44 %44\n%59 = OpLoad %26 %58\n%60 = OpBitcast %9 %59\n%61 = OpCompositeExtract %5 %60 0\n%63 = OpIEqual %62 %61 %44\nOpSelectionMerge %134 None\nOpBranchConditional %63 %134 %127\n%127 = OpLabel\nOpBranch %128\n%128 = OpLabel\n%77 = OpPhi %5 %44 %127 %78 %132\n%79 = OpShiftLeftLogical %5 %77 %80\n%81 = OpIAdd %5 %79 %41\n%84 = OpAccessChain %35 %8 %46\n%85 = OpLoad %5 %84\n%83 = OpAccessChain %82 %19 %85\n%87 = OpAccessChain %86 %83 %44 %81\n%88 = OpLoad %5 %87\nOpControlBarrier %48 %48 %89\n%90 = OpULessThan %62 %88 %91\nOpLoopMerge %133 %132 None\nOpBranch %129\n%129 = OpLabel\nOpSelectionMerge %131 None\nOpBranchConditional %90 %130 %131\n%130 = OpLabel\n%94 = OpAccessChain %35 %8 %46\n%95 = OpLoad %5 %94\n%96 = OpIAdd %5 %95 %46\n%93 = OpAccessChain %92 %24 %96\n%97 = OpAccessChain %55 %93 %44 %81\n%98 = OpLoad %9 %97\n%99 = OpBitcast %26 %98\n%100 = OpCompositeExtract %25 %99 0\n%101 = OpCompositeExtract %25 %99 1\n%102 = OpCompositeExtract %25 %99 2\n%103 = OpCompositeExtract %25 %99 3\n%104 = OpAccessChain %55 %43 %44 %88\n%105 = OpLoad %9 %104\n%106 = OpBitcast %26 %105\n%107 = OpCompositeExtract %25 %106 0\n%108 = OpCompositeExtract %25 %106 1\n%109 = OpCompositeExtract %25 %106 2\n%110 = OpCompositeExtract %25 %106 3\n%111 = OpFAdd %25 %107 %100\n%112 = OpFAdd %25 %108 %101\n%113 = OpFAdd %25 %109 %102\n%114 = OpFAdd %25 %110 %103\n%115 = OpBitcast %5 %111\n%116 = OpBitcast %5 %112\n%117 = OpBitcast %5 %113\n%118 = OpBitcast %5 %114\n%119 = OpCompositeConstruct %9 %115 %116 %117 %118\n%120 = OpAccessChain %55 %43 %44 %88\nOpStore %120 %119\nOpBranch %131\n%131 = OpLabel\nOpBranch %132\n%132 = OpLabel\n%78 = OpIAdd %5 %77 %46\n%121 = OpAccessChain %57 %34 %44 %44\n%122 = OpLoad %26 %121\n%123 = OpBitcast %9 %122\n%124 = OpCompositeExtract %5 %123 0\n%125 = OpULessThan %62 %78 %124\nOpBranchConditional %125 %128 %133\n%133 = OpLabel\nOpBranch %134\n%134 = OpLabel\n%64 = OpAccessChain %55 %45 %44 %41\n%65 = OpLoad %9 %64\n%66 = OpBitcast %26 %65\n%67 = OpCompositeExtract %25 %66 0\n%68 = OpCompositeExtract %25 %66 1\n%69 = OpCompositeExtract %25 %66 2\n%70 = OpCompositeExtract %25 %66 3\n%71 = OpBitcast %5 %67\n%72 = OpBitcast %5 %68\n%73 = OpBitcast %5 %69\n%74 = OpBitcast %5 %70\n%75 = OpCompositeConstruct %9 %71 %72 %73 %74\n%76 = OpAccessChain %55 %47 %44 %41\nOpStore %76 %75\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent-promotion.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) coherent buffer SSBO\n{\n    uvec4 _m0[];\n} _11[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _13_15\n{\n    uint _m0[];\n} _15;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _17_19\n{\n    uvec4 _m0[];\n} _19;\n\nlayout(set = 0, binding = 0, std140) uniform _24_26\n{\n    vec4 _m0[1];\n} _26;\n\nvoid main()\n{\n    _11[0u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_26._m0[0u]).x == 0u))\n    {\n        uint _64 = 0u;\n        uint _68;\n        uint _71;\n        bool _73;\n        for (;;)\n        {\n            _68 = (_64 << 8u) + gl_LocalInvocationIndex;\n            _71 = _15._m0[_68];\n            groupMemoryBarrier();\n            barrier();\n            _73 = _71 < 256u;\n            if (_73)\n            {\n                vec4 _77 = uintBitsToFloat(_19._m0[_68]);\n                vec4 _84 = uintBitsToFloat(_11[0u]._m0[_71]);\n                _11[0u]._m0[_71] = uvec4(floatBitsToUint(_84.x + _77.x), floatBitsToUint(_84.y + _77.y), floatBitsToUint(_84.z + _77.z), floatBitsToUint(_84.w + _77.w));\n            }\n            uint _65 = _64 + 1u;\n            if (_65 < floatBitsToUint(_26._m0[0u]).x)\n            {\n                _64 = _65;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _53 = uintBitsToFloat(_11[1u]._m0[gl_LocalInvocationIndex]);\n    _11[2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_53.x), floatBitsToUint(_53.y), floatBitsToUint(_53.z), floatBitsToUint(_53.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 114\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %28\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %24 \"\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 Coherent\nOpDecorate %12 ArrayStride 4\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %16 ArrayStride 16\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 1\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %23 ArrayStride 16\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %28 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeRuntimeArray %5\n%13 = OpTypeStruct %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeRuntimeArray %6\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpConstant %5 1\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypeArray %22 %20\n%24 = OpTypeStruct %23\n%25 = OpTypePointer Uniform %24\n%26 = OpVariable %25 Uniform\n%27 = OpTypePointer Input %5\n%28 = OpVariable %27 Input\n%30 = OpTypePointer StorageBuffer %8\n%32 = OpConstant %5 0\n%35 = OpConstant %5 2\n%36 = OpConstant %21 0\n%42 = OpTypePointer StorageBuffer %6\n%44 = OpTypePointer Uniform %22\n%49 = OpTypeBool\n%67 = OpConstant %5 8\n%69 = OpTypePointer StorageBuffer %5\n%72 = OpConstant %5 2120\n%74 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %104\n%104 = OpLabel\n%29 = OpLoad %5 %28\n%31 = OpAccessChain %30 %11 %32\n%33 = OpAccessChain %30 %11 %20\n%34 = OpAccessChain %30 %11 %35\n%37 = OpBitcast %5 %36\n%38 = OpBitcast %5 %36\n%39 = OpBitcast %5 %36\n%40 = OpBitcast %5 %36\n%41 = OpCompositeConstruct %6 %37 %38 %39 %40\n%43 = OpAccessChain %42 %31 %32 %29\nOpStore %43 %41\n%45 = OpAccessChain %44 %26 %32 %32\n%46 = OpLoad %22 %45\n%47 = OpBitcast %6 %46\n%48 = OpCompositeExtract %5 %47 0\n%50 = OpIEqual %49 %48 %32\nOpSelectionMerge %112 None\nOpBranchConditional %50 %112 %105\n%105 = OpLabel\nOpBranch %106\n%106 = OpLabel\n%64 = OpPhi %5 %32 %105 %65 %110\n%66 = OpShiftLeftLogical %5 %64 %67\n%68 = OpIAdd %5 %66 %29\n%70 = OpAccessChain %69 %15 %32 %68\n%71 = OpLoad %5 %70\nOpControlBarrier %35 %35 %72\n%73 = OpULessThan %49 %71 %74\nOpLoopMerge %111 %110 None\nOpBranch %107\n%107 = OpLabel\nOpSelectionMerge %109 None\nOpBranchConditional %73 %108 %109\n%108 = OpLabel\n%75 = OpAccessChain %42 %19 %32 %68\n%76 = OpLoad %6 %75\n%77 = OpBitcast %22 %76\n%78 = OpCompositeExtract %21 %77 0\n%79 = OpCompositeExtract %21 %77 1\n%80 = OpCompositeExtract %21 %77 2\n%81 = OpCompositeExtract %21 %77 3\n%82 = OpAccessChain %42 %31 %32 %71\n%83 = OpLoad %6 %82\n%84 = OpBitcast %22 %83\n%85 = OpCompositeExtract %21 %84 0\n%86 = OpCompositeExtract %21 %84 1\n%87 = OpCompositeExtract %21 %84 2\n%88 = OpCompositeExtract %21 %84 3\n%89 = OpFAdd %21 %85 %78\n%90 = OpFAdd %21 %86 %79\n%91 = OpFAdd %21 %87 %80\n%92 = OpFAdd %21 %88 %81\n%93 = OpBitcast %5 %89\n%94 = OpBitcast %5 %90\n%95 = OpBitcast %5 %91\n%96 = OpBitcast %5 %92\n%97 = OpCompositeConstruct %6 %93 %94 %95 %96\n%98 = OpAccessChain %42 %31 %32 %71\nOpStore %98 %97\nOpBranch %109\n%109 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%65 = OpIAdd %5 %64 %20\n%99 = OpAccessChain %44 %26 %32 %32\n%100 = OpLoad %22 %99\n%101 = OpBitcast %6 %100\n%102 = OpCompositeExtract %5 %101 0\n%103 = OpULessThan %49 %65 %102\nOpBranchConditional %103 %106 %111\n%111 = OpLabel\nOpBranch %112\n%112 = OpLabel\n%51 = OpAccessChain %42 %33 %32 %29\n%52 = OpLoad %6 %51\n%53 = OpBitcast %22 %52\n%54 = OpCompositeExtract %21 %53 0\n%55 = OpCompositeExtract %21 %53 1\n%56 = OpCompositeExtract %21 %53 2\n%57 = OpCompositeExtract %21 %53 3\n%58 = OpBitcast %5 %54\n%59 = OpBitcast %5 %55\n%60 = OpBitcast %5 %56\n%61 = OpBitcast %5 %57\n%62 = OpCompositeConstruct %6 %58 %59 %60 %61\n%63 = OpAccessChain %42 %34 %32 %29\nOpStore %63 %62\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent-promotion.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, std430) coherent buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(set = 0, binding = 1, std430) readonly buffer _20_22\n{\n    uvec4 _m0[];\n} _22;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _24_26\n{\n    uvec4 _m0[];\n} _26;\n\nlayout(set = 0, binding = 0, std140) uniform _31_33\n{\n    vec4 _m0[1];\n} _33;\n\nvoid main()\n{\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_33._m0[0u]).x == 0u))\n    {\n        uint _66 = 0u;\n        uint _70;\n        uint _73;\n        bool _76;\n        for (;;)\n        {\n            _70 = (_66 << 8u) + gl_LocalInvocationIndex;\n            _73 = _9._m0[_70];\n            groupMemoryBarrier();\n            barrier();\n            _76 = _73 < 256u;\n            if (_76)\n            {\n                vec4 _80 = uintBitsToFloat(_14._m0[_70]);\n                vec4 _87 = uintBitsToFloat(_18._m0[_73]);\n                _18._m0[_73] = uvec4(floatBitsToUint(_87.x + _80.x), floatBitsToUint(_87.y + _80.y), floatBitsToUint(_87.z + _80.z), floatBitsToUint(_87.w + _80.w));\n            }\n            uint _67 = _66 + 1u;\n            if (_67 < floatBitsToUint(_33._m0[0u]).x)\n            {\n                _66 = _67;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _55 = uintBitsToFloat(_22._m0[gl_LocalInvocationIndex]);\n    _26._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_55.x), floatBitsToUint(_55.y), floatBitsToUint(_55.z), floatBitsToUint(_55.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 117\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %35\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %20 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %31 \"\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %18 Coherent\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 1\nOpDecorate %22 NonWritable\nOpDecorate %23 ArrayStride 16\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 2\nOpDecorate %26 NonReadable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %35 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %10\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %10\n%24 = OpTypeStruct %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpConstant %5 1\n%28 = OpTypeFloat 32\n%29 = OpTypeVector %28 4\n%30 = OpTypeArray %29 %27\n%31 = OpTypeStruct %30\n%32 = OpTypePointer Uniform %31\n%33 = OpVariable %32 Uniform\n%34 = OpTypePointer Input %5\n%35 = OpVariable %34 Input\n%37 = OpConstant %28 0\n%43 = OpTypePointer StorageBuffer %10\n%45 = OpConstant %5 0\n%46 = OpTypePointer Uniform %29\n%51 = OpTypeBool\n%69 = OpConstant %5 8\n%71 = OpTypePointer StorageBuffer %5\n%74 = OpConstant %5 2\n%75 = OpConstant %5 2120\n%77 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %107\n%107 = OpLabel\n%36 = OpLoad %5 %35\n%38 = OpBitcast %5 %37\n%39 = OpBitcast %5 %37\n%40 = OpBitcast %5 %37\n%41 = OpBitcast %5 %37\n%42 = OpCompositeConstruct %10 %38 %39 %40 %41\n%44 = OpAccessChain %43 %18 %45 %36\nOpStore %44 %42\n%47 = OpAccessChain %46 %33 %45 %45\n%48 = OpLoad %29 %47\n%49 = OpBitcast %10 %48\n%50 = OpCompositeExtract %5 %49 0\n%52 = OpIEqual %51 %50 %45\nOpSelectionMerge %115 None\nOpBranchConditional %52 %115 %108\n%108 = OpLabel\nOpBranch %109\n%109 = OpLabel\n%66 = OpPhi %5 %45 %108 %67 %113\n%68 = OpShiftLeftLogical %5 %66 %69\n%70 = OpIAdd %5 %68 %36\n%72 = OpAccessChain %71 %9 %45 %70\n%73 = OpLoad %5 %72\nOpControlBarrier %74 %74 %75\n%76 = OpULessThan %51 %73 %77\nOpLoopMerge %114 %113 None\nOpBranch %110\n%110 = OpLabel\nOpSelectionMerge %112 None\nOpBranchConditional %76 %111 %112\n%111 = OpLabel\n%78 = OpAccessChain %43 %14 %45 %70\n%79 = OpLoad %10 %78\n%80 = OpBitcast %29 %79\n%81 = OpCompositeExtract %28 %80 0\n%82 = OpCompositeExtract %28 %80 1\n%83 = OpCompositeExtract %28 %80 2\n%84 = OpCompositeExtract %28 %80 3\n%85 = OpAccessChain %43 %18 %45 %73\n%86 = OpLoad %10 %85\n%87 = OpBitcast %29 %86\n%88 = OpCompositeExtract %28 %87 0\n%89 = OpCompositeExtract %28 %87 1\n%90 = OpCompositeExtract %28 %87 2\n%91 = OpCompositeExtract %28 %87 3\n%92 = OpFAdd %28 %88 %81\n%93 = OpFAdd %28 %89 %82\n%94 = OpFAdd %28 %90 %83\n%95 = OpFAdd %28 %91 %84\n%96 = OpBitcast %5 %92\n%97 = OpBitcast %5 %93\n%98 = OpBitcast %5 %94\n%99 = OpBitcast %5 %95\n%100 = OpCompositeConstruct %10 %96 %97 %98 %99\n%101 = OpAccessChain %43 %18 %45 %73\nOpStore %101 %100\nOpBranch %112\n%112 = OpLabel\nOpBranch %113\n%113 = OpLabel\n%67 = OpIAdd %5 %66 %27\n%102 = OpAccessChain %46 %33 %45 %45\n%103 = OpLoad %29 %102\n%104 = OpBitcast %10 %103\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpULessThan %51 %67 %105\nOpBranchConditional %106 %109 %114\n%114 = OpLabel\nOpBranch %115\n%115 = OpLabel\n%53 = OpAccessChain %43 %22 %45 %36\n%54 = OpLoad %10 %53\n%55 = OpBitcast %29 %54\n%56 = OpCompositeExtract %28 %55 0\n%57 = OpCompositeExtract %28 %55 1\n%58 = OpCompositeExtract %28 %55 2\n%59 = OpCompositeExtract %28 %55 3\n%60 = OpBitcast %5 %56\n%61 = OpBitcast %5 %57\n%62 = OpBitcast %5 %58\n%63 = OpBitcast %5 %59\n%64 = OpCompositeConstruct %10 %60 %61 %62 %63\n%65 = OpAccessChain %43 %26 %45 %36\nOpStore %65 %64\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent.root-descriptor.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4CoherentArray;\nlayout(buffer_reference) buffer PhysicalPointerUint4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4Array;\nlayout(buffer_reference) buffer PhysicalPointerUintNonWriteArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) coherent buffer PhysicalPointerFloat4CoherentArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint4NonWriteCBVArray\n{\n    uvec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) buffer PhysicalPointerFloat4Array\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerUintNonWriteArray\n{\n    uint value[];\n};\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    PhysicalPointerFloat4CoherentArray(registers._m2).value[gl_LocalInvocationIndex] = vec4(0.0);\n    if (!(PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x == 0u))\n    {\n        uint _73 = 0u;\n        uint _77;\n        uint _84;\n        bool _86;\n        for (;;)\n        {\n            _77 = (_73 << 8u) + gl_LocalInvocationIndex;\n            _84 = PhysicalPointerUintNonWriteArray(registers._m1).value[_77];\n            memoryBarrierBuffer();\n            memoryBarrierImage();\n            barrier();\n            _86 = _84 < 256u;\n            if (_86)\n            {\n                vec4 _90 = uintBitsToFloat(_14._m0[_77]);\n                PhysicalPointerFloat4CoherentArray _95 = PhysicalPointerFloat4CoherentArray(registers._m2);\n                PhysicalPointerFloat4CoherentArray(registers._m2).value[_84] = vec4(_95.value[_84].x + _90.x, _95.value[_84].y + _90.y, _95.value[_84].z + _90.z, _95.value[_84].w + _90.w);\n            }\n            uint _74 = _73 + 1u;\n            if (_74 < PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x)\n            {\n                _73 = _74;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    PhysicalPointerFloat4Array _59 = PhysicalPointerFloat4Array(registers._m3);\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_59.value[gl_LocalInvocationIndex].x), floatBitsToUint(_59.value[gl_LocalInvocationIndex].y), floatBitsToUint(_59.value[gl_LocalInvocationIndex].z), floatBitsToUint(_59.value[gl_LocalInvocationIndex].w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 124\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %33\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %38 \"PhysicalPointerFloat4CoherentArray\"\nOpMemberName %38 0 \"value\"\nOpName %47 \"PhysicalPointerUint4NonWriteCBVArray\"\nOpMemberName %47 0 \"value\"\nOpName %57 \"PhysicalPointerFloat4Array\"\nOpMemberName %57 0 \"value\"\nOpName %79 \"PhysicalPointerUintNonWriteArray\"\nOpMemberName %79 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 2\nOpDecorate %18 NonReadable\nOpDecorate %33 BuiltIn LocalInvocationIndex\nOpDecorate %37 ArrayStride 16\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpMemberDecorate %38 0 Coherent\nOpDecorate %46 ArrayStride 16\nOpMemberDecorate %47 0 Offset 0\nOpDecorate %47 Block\nOpMemberDecorate %47 0 NonWritable\nOpDecorate %56 ArrayStride 16\nOpMemberDecorate %57 0 Offset 0\nOpDecorate %57 Block\nOpDecorate %78 ArrayStride 4\nOpMemberDecorate %79 0 Offset 0\nOpDecorate %79 Block\nOpMemberDecorate %79 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypePointer PushConstant %6\n%21 = OpConstant %5 3\n%24 = OpConstant %5 2\n%27 = OpConstant %5 1\n%30 = OpConstant %5 0\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%35 = OpTypeFloat 32\n%36 = OpTypeVector %35 4\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypeStruct %37\n%39 = OpTypePointer PhysicalStorageBuffer %38\n%41 = OpTypePointer PhysicalStorageBuffer %36\n%43 = OpConstant %35 0\n%45 = OpConstant %5 4096\n%46 = OpTypeArray %10 %45\n%47 = OpTypeStruct %46\n%48 = OpTypePointer PhysicalStorageBuffer %47\n%50 = OpTypePointer PhysicalStorageBuffer %10\n%54 = OpTypeBool\n%56 = OpTypeRuntimeArray %36\n%57 = OpTypeStruct %56\n%58 = OpTypePointer PhysicalStorageBuffer %57\n%71 = OpTypePointer StorageBuffer %10\n%76 = OpConstant %5 8\n%78 = OpTypeRuntimeArray %5\n%79 = OpTypeStruct %78\n%80 = OpTypePointer PhysicalStorageBuffer %79\n%82 = OpTypePointer PhysicalStorageBuffer %5\n%85 = OpConstant %5 2120\n%87 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%20 = OpAccessChain %19 %9 %21\n%22 = OpLoad %6 %20\n%23 = OpAccessChain %19 %9 %24\n%25 = OpLoad %6 %23\n%26 = OpAccessChain %19 %9 %27\n%28 = OpLoad %6 %26\n%29 = OpAccessChain %19 %9 %30\n%31 = OpLoad %6 %29\n%34 = OpLoad %5 %33\n%40 = OpBitcast %39 %25\n%42 = OpInBoundsAccessChain %41 %40 %30 %34\n%44 = OpCompositeConstruct %36 %43 %43 %43 %43\nOpStore %42 %44 Aligned 16\n%49 = OpBitcast %48 %31\n%51 = OpInBoundsAccessChain %50 %49 %30 %30\n%52 = OpLoad %10 %51 Aligned 16\n%53 = OpCompositeExtract %5 %52 0\n%55 = OpIEqual %54 %53 %30\nOpSelectionMerge %122 None\nOpBranchConditional %55 %122 %115\n%115 = OpLabel\nOpBranch %116\n%116 = OpLabel\n%73 = OpPhi %5 %30 %115 %74 %120\n%75 = OpShiftLeftLogical %5 %73 %76\n%77 = OpIAdd %5 %75 %34\n%81 = OpBitcast %80 %28\n%83 = OpInBoundsAccessChain %82 %81 %30 %77\n%84 = OpLoad %5 %83 Aligned 4\nOpControlBarrier %24 %27 %85\n%86 = OpULessThan %54 %84 %87\nOpLoopMerge %121 %120 None\nOpBranch %117\n%117 = OpLabel\nOpSelectionMerge %119 None\nOpBranchConditional %86 %118 %119\n%118 = OpLabel\n%88 = OpAccessChain %71 %14 %30 %77\n%89 = OpLoad %10 %88\n%90 = OpBitcast %36 %89\n%91 = OpCompositeExtract %35 %90 0\n%92 = OpCompositeExtract %35 %90 1\n%93 = OpCompositeExtract %35 %90 2\n%94 = OpCompositeExtract %35 %90 3\n%95 = OpBitcast %39 %25\n%96 = OpInBoundsAccessChain %41 %95 %30 %84\n%97 = OpLoad %36 %96 Aligned 16\n%98 = OpCompositeExtract %35 %97 0\n%99 = OpCompositeExtract %35 %97 1\n%100 = OpCompositeExtract %35 %97 2\n%101 = OpCompositeExtract %35 %97 3\n%102 = OpFAdd %35 %98 %91\n%103 = OpFAdd %35 %99 %92\n%104 = OpFAdd %35 %100 %93\n%105 = OpFAdd %35 %101 %94\n%106 = OpBitcast %39 %25\n%107 = OpInBoundsAccessChain %41 %106 %30 %84\n%108 = OpCompositeConstruct %36 %102 %103 %104 %105\nOpStore %107 %108 Aligned 16\nOpBranch %119\n%119 = OpLabel\nOpBranch %120\n%120 = OpLabel\n%74 = OpIAdd %5 %73 %27\n%109 = OpBitcast %48 %31\n%110 = OpInBoundsAccessChain %50 %109 %30 %30\n%111 = OpLoad %10 %110 Aligned 16\n%112 = OpCompositeExtract %5 %111 0\n%113 = OpULessThan %54 %74 %112\nOpBranchConditional %113 %116 %121\n%121 = OpLabel\nOpBranch %122\n%122 = OpLabel\n%59 = OpBitcast %58 %22\n%60 = OpInBoundsAccessChain %41 %59 %30 %34\n%61 = OpLoad %36 %60 Aligned 16\n%62 = OpCompositeExtract %35 %61 0\n%63 = OpCompositeExtract %35 %61 1\n%64 = OpCompositeExtract %35 %61 2\n%65 = OpCompositeExtract %35 %61 3\n%66 = OpBitcast %5 %62\n%67 = OpBitcast %5 %63\n%68 = OpBitcast %5 %64\n%69 = OpBitcast %5 %65\n%70 = OpCompositeConstruct %10 %66 %67 %68 %69\n%72 = OpAccessChain %71 %18 %30 %34\nOpStore %72 %70\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent.sm66.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) coherent buffer SSBO\n{\n    uvec4 _m0[];\n} _11[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _13_15\n{\n    uint _m0[];\n} _15;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _17_19\n{\n    uvec4 _m0[];\n} _19;\n\nlayout(set = 0, binding = 0, std140) uniform _24_26\n{\n    vec4 _m0[1];\n} _26;\n\nvoid main()\n{\n    _11[0u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_26._m0[0u]).x == 0u))\n    {\n        uint _64 = 0u;\n        uint _68;\n        uint _71;\n        bool _73;\n        for (;;)\n        {\n            _68 = (_64 << 8u) + gl_LocalInvocationIndex;\n            _71 = _15._m0[_68];\n            memoryBarrierBuffer();\n            memoryBarrierImage();\n            barrier();\n            _73 = _71 < 256u;\n            if (_73)\n            {\n                vec4 _77 = uintBitsToFloat(_19._m0[_68]);\n                vec4 _84 = uintBitsToFloat(_11[0u]._m0[_71]);\n                _11[0u]._m0[_71] = uvec4(floatBitsToUint(_84.x + _77.x), floatBitsToUint(_84.y + _77.y), floatBitsToUint(_84.z + _77.z), floatBitsToUint(_84.w + _77.w));\n            }\n            uint _65 = _64 + 1u;\n            if (_65 < floatBitsToUint(_26._m0[0u]).x)\n            {\n                _64 = _65;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _53 = uintBitsToFloat(_11[1u]._m0[gl_LocalInvocationIndex]);\n    _11[2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_53.x), floatBitsToUint(_53.y), floatBitsToUint(_53.z), floatBitsToUint(_53.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 114\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %28\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %24 \"\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 Coherent\nOpDecorate %12 ArrayStride 4\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %16 ArrayStride 16\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 1\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %23 ArrayStride 16\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %28 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeRuntimeArray %5\n%13 = OpTypeStruct %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeRuntimeArray %6\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpConstant %5 1\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypeArray %22 %20\n%24 = OpTypeStruct %23\n%25 = OpTypePointer Uniform %24\n%26 = OpVariable %25 Uniform\n%27 = OpTypePointer Input %5\n%28 = OpVariable %27 Input\n%30 = OpTypePointer StorageBuffer %8\n%32 = OpConstant %5 0\n%35 = OpConstant %5 2\n%36 = OpConstant %21 0\n%42 = OpTypePointer StorageBuffer %6\n%44 = OpTypePointer Uniform %22\n%49 = OpTypeBool\n%67 = OpConstant %5 8\n%69 = OpTypePointer StorageBuffer %5\n%72 = OpConstant %5 2120\n%74 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %104\n%104 = OpLabel\n%29 = OpLoad %5 %28\n%31 = OpAccessChain %30 %11 %32\n%33 = OpAccessChain %30 %11 %20\n%34 = OpAccessChain %30 %11 %35\n%37 = OpBitcast %5 %36\n%38 = OpBitcast %5 %36\n%39 = OpBitcast %5 %36\n%40 = OpBitcast %5 %36\n%41 = OpCompositeConstruct %6 %37 %38 %39 %40\n%43 = OpAccessChain %42 %31 %32 %29\nOpStore %43 %41\n%45 = OpAccessChain %44 %26 %32 %32\n%46 = OpLoad %22 %45\n%47 = OpBitcast %6 %46\n%48 = OpCompositeExtract %5 %47 0\n%50 = OpIEqual %49 %48 %32\nOpSelectionMerge %112 None\nOpBranchConditional %50 %112 %105\n%105 = OpLabel\nOpBranch %106\n%106 = OpLabel\n%64 = OpPhi %5 %32 %105 %65 %110\n%66 = OpShiftLeftLogical %5 %64 %67\n%68 = OpIAdd %5 %66 %29\n%70 = OpAccessChain %69 %15 %32 %68\n%71 = OpLoad %5 %70\nOpControlBarrier %35 %20 %72\n%73 = OpULessThan %49 %71 %74\nOpLoopMerge %111 %110 None\nOpBranch %107\n%107 = OpLabel\nOpSelectionMerge %109 None\nOpBranchConditional %73 %108 %109\n%108 = OpLabel\n%75 = OpAccessChain %42 %19 %32 %68\n%76 = OpLoad %6 %75\n%77 = OpBitcast %22 %76\n%78 = OpCompositeExtract %21 %77 0\n%79 = OpCompositeExtract %21 %77 1\n%80 = OpCompositeExtract %21 %77 2\n%81 = OpCompositeExtract %21 %77 3\n%82 = OpAccessChain %42 %31 %32 %71\n%83 = OpLoad %6 %82\n%84 = OpBitcast %22 %83\n%85 = OpCompositeExtract %21 %84 0\n%86 = OpCompositeExtract %21 %84 1\n%87 = OpCompositeExtract %21 %84 2\n%88 = OpCompositeExtract %21 %84 3\n%89 = OpFAdd %21 %85 %78\n%90 = OpFAdd %21 %86 %79\n%91 = OpFAdd %21 %87 %80\n%92 = OpFAdd %21 %88 %81\n%93 = OpBitcast %5 %89\n%94 = OpBitcast %5 %90\n%95 = OpBitcast %5 %91\n%96 = OpBitcast %5 %92\n%97 = OpCompositeConstruct %6 %93 %94 %95 %96\n%98 = OpAccessChain %42 %31 %32 %71\nOpStore %98 %97\nOpBranch %109\n%109 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%65 = OpIAdd %5 %64 %20\n%99 = OpAccessChain %44 %26 %32 %32\n%100 = OpLoad %22 %99\n%101 = OpBitcast %6 %100\n%102 = OpCompositeExtract %5 %101 0\n%103 = OpULessThan %49 %65 %102\nOpBranchConditional %103 %106 %111\n%111 = OpLabel\nOpBranch %112\n%112 = OpLabel\n%51 = OpAccessChain %42 %33 %32 %29\n%52 = OpLoad %6 %51\n%53 = OpBitcast %22 %52\n%54 = OpCompositeExtract %21 %53 0\n%55 = OpCompositeExtract %21 %53 1\n%56 = OpCompositeExtract %21 %53 2\n%57 = OpCompositeExtract %21 %53 3\n%58 = OpBitcast %5 %54\n%59 = OpBitcast %5 %55\n%60 = OpBitcast %5 %56\n%61 = OpBitcast %5 %57\n%62 = OpCompositeConstruct %6 %58 %59 %60 %61\n%63 = OpAccessChain %42 %34 %32 %29\nOpStore %63 %62\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/memory-model/uav-coherent.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, std430) coherent buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(set = 0, binding = 1, std430) readonly buffer _20_22\n{\n    uvec4 _m0[];\n} _22;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _24_26\n{\n    uvec4 _m0[];\n} _26;\n\nlayout(set = 0, binding = 0, std140) uniform _31_33\n{\n    vec4 _m0[1];\n} _33;\n\nvoid main()\n{\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_33._m0[0u]).x == 0u))\n    {\n        uint _66 = 0u;\n        uint _70;\n        uint _73;\n        bool _76;\n        for (;;)\n        {\n            _70 = (_66 << 8u) + gl_LocalInvocationIndex;\n            _73 = _9._m0[_70];\n            memoryBarrierBuffer();\n            memoryBarrierImage();\n            barrier();\n            _76 = _73 < 256u;\n            if (_76)\n            {\n                vec4 _80 = uintBitsToFloat(_14._m0[_70]);\n                vec4 _87 = uintBitsToFloat(_18._m0[_73]);\n                _18._m0[_73] = uvec4(floatBitsToUint(_87.x + _80.x), floatBitsToUint(_87.y + _80.y), floatBitsToUint(_87.z + _80.z), floatBitsToUint(_87.w + _80.w));\n            }\n            uint _67 = _66 + 1u;\n            if (_67 < floatBitsToUint(_33._m0[0u]).x)\n            {\n                _66 = _67;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _55 = uintBitsToFloat(_22._m0[gl_LocalInvocationIndex]);\n    _26._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_55.x), floatBitsToUint(_55.y), floatBitsToUint(_55.z), floatBitsToUint(_55.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 117\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %35\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %20 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %31 \"\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %18 Coherent\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 1\nOpDecorate %22 NonWritable\nOpDecorate %23 ArrayStride 16\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 2\nOpDecorate %26 NonReadable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %35 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %10\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %10\n%24 = OpTypeStruct %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpConstant %5 1\n%28 = OpTypeFloat 32\n%29 = OpTypeVector %28 4\n%30 = OpTypeArray %29 %27\n%31 = OpTypeStruct %30\n%32 = OpTypePointer Uniform %31\n%33 = OpVariable %32 Uniform\n%34 = OpTypePointer Input %5\n%35 = OpVariable %34 Input\n%37 = OpConstant %28 0\n%43 = OpTypePointer StorageBuffer %10\n%45 = OpConstant %5 0\n%46 = OpTypePointer Uniform %29\n%51 = OpTypeBool\n%69 = OpConstant %5 8\n%71 = OpTypePointer StorageBuffer %5\n%74 = OpConstant %5 2\n%75 = OpConstant %5 2120\n%77 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %107\n%107 = OpLabel\n%36 = OpLoad %5 %35\n%38 = OpBitcast %5 %37\n%39 = OpBitcast %5 %37\n%40 = OpBitcast %5 %37\n%41 = OpBitcast %5 %37\n%42 = OpCompositeConstruct %10 %38 %39 %40 %41\n%44 = OpAccessChain %43 %18 %45 %36\nOpStore %44 %42\n%47 = OpAccessChain %46 %33 %45 %45\n%48 = OpLoad %29 %47\n%49 = OpBitcast %10 %48\n%50 = OpCompositeExtract %5 %49 0\n%52 = OpIEqual %51 %50 %45\nOpSelectionMerge %115 None\nOpBranchConditional %52 %115 %108\n%108 = OpLabel\nOpBranch %109\n%109 = OpLabel\n%66 = OpPhi %5 %45 %108 %67 %113\n%68 = OpShiftLeftLogical %5 %66 %69\n%70 = OpIAdd %5 %68 %36\n%72 = OpAccessChain %71 %9 %45 %70\n%73 = OpLoad %5 %72\nOpControlBarrier %74 %27 %75\n%76 = OpULessThan %51 %73 %77\nOpLoopMerge %114 %113 None\nOpBranch %110\n%110 = OpLabel\nOpSelectionMerge %112 None\nOpBranchConditional %76 %111 %112\n%111 = OpLabel\n%78 = OpAccessChain %43 %14 %45 %70\n%79 = OpLoad %10 %78\n%80 = OpBitcast %29 %79\n%81 = OpCompositeExtract %28 %80 0\n%82 = OpCompositeExtract %28 %80 1\n%83 = OpCompositeExtract %28 %80 2\n%84 = OpCompositeExtract %28 %80 3\n%85 = OpAccessChain %43 %18 %45 %73\n%86 = OpLoad %10 %85\n%87 = OpBitcast %29 %86\n%88 = OpCompositeExtract %28 %87 0\n%89 = OpCompositeExtract %28 %87 1\n%90 = OpCompositeExtract %28 %87 2\n%91 = OpCompositeExtract %28 %87 3\n%92 = OpFAdd %28 %88 %81\n%93 = OpFAdd %28 %89 %82\n%94 = OpFAdd %28 %90 %83\n%95 = OpFAdd %28 %91 %84\n%96 = OpBitcast %5 %92\n%97 = OpBitcast %5 %93\n%98 = OpBitcast %5 %94\n%99 = OpBitcast %5 %95\n%100 = OpCompositeConstruct %10 %96 %97 %98 %99\n%101 = OpAccessChain %43 %18 %45 %73\nOpStore %101 %100\nOpBranch %112\n%112 = OpLabel\nOpBranch %113\n%113 = OpLabel\n%67 = OpIAdd %5 %66 %27\n%102 = OpAccessChain %46 %33 %45 %45\n%103 = OpLoad %29 %102\n%104 = OpBitcast %10 %103\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpULessThan %51 %67 %105\nOpBranchConditional %106 %109 %114\n%114 = OpLabel\nOpBranch %115\n%115 = OpLabel\n%53 = OpAccessChain %43 %22 %45 %36\n%54 = OpLoad %10 %53\n%55 = OpBitcast %29 %54\n%56 = OpCompositeExtract %28 %55 0\n%57 = OpCompositeExtract %28 %55 1\n%58 = OpCompositeExtract %28 %55 2\n%59 = OpCompositeExtract %28 %55 3\n%60 = OpBitcast %5 %56\n%61 = OpBitcast %5 %57\n%62 = OpBitcast %5 %58\n%63 = OpBitcast %5 %59\n%64 = OpCompositeConstruct %10 %60 %61 %62 %63\n%65 = OpAccessChain %43 %26 %45 %36\nOpStore %65 %64\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/nvapi/bringup.nvapi.ssbo.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_shuffle : require\n\nlayout(set = 0, binding = 0, std430) writeonly buffer BlahSSBO\n{\n    uint _m0[];\n} Blah;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer BABSSBO\n{\n    uint _m0[];\n} BAB;\n\nlayout(set = 0, binding = 2) uniform writeonly image1D RWTex;\n\nvoid main()\n{\n    Blah._m0[gl_LaunchIDEXT.x] = subgroupShuffle(gl_LaunchIDEXT.x, 9u);\n    uint _33 = atomicAdd(BAB._m0[64u], 9u);\n    Blah._m0[100u] = _33;\n    imageStore(RWTex, int(gl_LaunchIDEXT.x), vec4(2.0));\n    Blah._m0[101u] = 42u;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformShuffle\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %9 %13 %17 %20\nOpName %3 \"main\"\nOpName %7 \"BlahSSBO\"\nOpName %9 \"Blah\"\nOpName %11 \"BABSSBO\"\nOpName %13 \"BAB\"\nOpName %17 \"RWTex\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonReadable\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 2\nOpDecorate %17 NonReadable\nOpDecorate %20 BuiltIn LaunchIdKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFloat 32\n%15 = OpTypeImage %14 1D 0 0 0 2 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %5 3\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Input %5\n%23 = OpConstant %5 0\n%26 = OpConstant %5 9\n%28 = OpConstant %5 3\n%29 = OpTypePointer StorageBuffer %5\n%31 = OpConstant %5 64\n%34 = OpConstant %5 1\n%35 = OpConstant %5 100\n%38 = OpConstant %5 10\n%39 = OpConstant %14 2\n%40 = OpTypeVector %14 4\n%41 = OpConstantComposite %40 %39 %39 %39 %39\n%42 = OpConstant %5 42\n%43 = OpConstant %5 101\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %45\n%45 = OpLabel\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%27 = OpGroupNonUniformShuffle %5 %28 %24 %26\n%30 = OpAccessChain %29 %9 %23 %24\nOpStore %30 %27\n%32 = OpAccessChain %29 %13 %23 %31\n%33 = OpAtomicIAdd %5 %32 %34 %23 %26\n%36 = OpAccessChain %29 %9 %23 %35\nOpStore %36 %33\n%37 = OpLoad %15 %17\nOpImageWrite %37 %24 %41\n%44 = OpAccessChain %29 %9 %23 %43\nOpStore %44 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/nvapi/get-special-global-timer.nvapi.ssbo.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_realtime_clock : require\n\nlayout(set = 0, binding = 0, std430) writeonly buffer BufSSBO\n{\n    uint _m0[];\n} Buf;\n\nvoid main()\n{\n    uvec2 _12 = clockRealtime2x32EXT();\n    Buf._m0[0u] = _12.x;\n    uvec2 _18 = clockRealtime2x32EXT();\n    Buf._m0[1u] = _18.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability ShaderClockKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpExtension \"SPV_KHR_shader_clock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %9\nOpName %3 \"main\"\nOpName %7 \"BufSSBO\"\nOpName %9 \"Buf\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%11 = OpTypeVector %5 2\n%13 = OpConstant %5 1\n%15 = OpConstant %5 0\n%16 = OpTypePointer StorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %21\n%21 = OpLabel\n%12 = OpReadClockKHR %11 %13\n%14 = OpCompositeExtract %5 %12 0\n%17 = OpAccessChain %16 %9 %15 %15\nOpStore %17 %14\n%18 = OpReadClockKHR %11 %13\n%19 = OpCompositeExtract %5 %18 1\n%20 = OpAccessChain %16 %9 %15 %13\nOpStore %20 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/nvapi/hit-object.local-root-signature.noglsl.nvapi.ssbo.rgen",
    "content": "; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 202\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpCapability ShaderInvocationReorderNV\nOpCapability RayTracingClusterAccelerationStructureNV\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpExtension \"SPV_NV_cluster_acceleration_structure\"\nOpExtension \"SPV_NV_shader_invocation_reorder\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %13 %17 %21 %25 %30 %33 %34 %35 %38 %39 %40\nOpName %3 \"main\"\nOpName %11 \"SBTBlock\"\nOpName %13 \"SBT\"\nOpName %17 \"AS\"\nOpName %19 \"RWFloatSSBO\"\nOpName %21 \"RWFloat\"\nOpName %23 \"RWUintSSBO\"\nOpName %25 \"RWUint\"\nOpName %28 \"\"\nOpName %31 \"\"\nOpName %36 \"\"\nOpName %137 \"HitObjectSRB\"\nOpDecorate %7 ArrayStride 4\nOpDecorate %9 ArrayStride 4\nOpDecorate %11 Block\nOpMemberDecorate %11 0 Offset 0\nOpMemberDecorate %11 1 Offset 20\nOpMemberDecorate %11 2 Offset 48\nOpMemberDecorate %11 3 Offset 56\nOpMemberDecorate %11 4 Offset 64\nOpMemberDecorate %11 5 Offset 72\nOpMemberDecorate %11 6 Offset 80\nOpMemberDecorate %11 7 Offset 88\nOpMemberDecorate %11 8 Offset 96\nOpMemberDecorate %11 9 Offset 104\nOpMemberDecorate %11 10 Offset 112\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %18 ArrayStride 4\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 1\nOpDecorate %21 NonReadable\nOpDecorate %22 ArrayStride 4\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 2\nOpDecorate %25 NonReadable\nOpDecorate %137 Block\nOpDecorate %137 HitObjectShaderRecordBufferNV\nOpMemberDecorate %137 0 Offset 0\nOpMemberDecorate %137 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 5\n%7 = OpTypeArray %5 %6\n%8 = OpConstant %5 6\n%9 = OpTypeArray %5 %8\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %7 %9 %10 %10 %10 %10 %10 %10 %10 %10 %10\n%12 = OpTypePointer ShaderRecordBufferKHR %11\n%13 = OpVariable %12 ShaderRecordBufferKHR\n%14 = OpTypeInt 32 1\n%15 = OpTypeAccelerationStructureKHR\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeRuntimeArray %5\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %5\n%23 = OpTypeStruct %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeFloat 32\n%27 = OpTypeVector %26 2\n%28 = OpTypeStruct %27\n%29 = OpTypePointer HitObjectAttributeNV %28\n%30 = OpVariable %29 HitObjectAttributeNV\n%31 = OpTypeStruct %5\n%32 = OpTypePointer RayPayloadKHR %31\n%33 = OpVariable %32 RayPayloadKHR\n%34 = OpVariable %32 RayPayloadKHR\n%35 = OpVariable %32 RayPayloadKHR\n%36 = OpTypeStruct %28\n%37 = OpTypePointer HitObjectAttributeNV %36\n%38 = OpVariable %37 HitObjectAttributeNV\n%39 = OpVariable %32 RayPayloadKHR\n%40 = OpVariable %37 HitObjectAttributeNV\n%42 = OpTypeHitObjectNV\n%43 = OpTypePointer Function %42\n%45 = OpConstant %5 0\n%47 = OpConstant %5 1088421888\n%49 = OpConstant %5 1090519040\n%51 = OpConstant %5 1065353216\n%53 = OpConstant %5 1082130432\n%55 = OpConstant %5 1073741824\n%57 = OpConstant %5 1084227584\n%59 = OpConstant %5 1077936128\n%61 = OpConstant %5 1086324736\n%62 = OpTypeVector %26 3\n%67 = OpConstant %5 1\n%68 = OpConstant %5 2\n%69 = OpConstant %5 3\n%70 = OpConstant %5 4\n%71 = OpConstant %26 1\n%72 = OpConstant %26 4\n%73 = OpConstant %26 2\n%74 = OpConstant %26 5\n%75 = OpConstant %26 3\n%76 = OpConstant %26 6\n%77 = OpConstant %26 7\n%78 = OpConstant %26 8\n%87 = OpConstant %5 17\n%91 = OpTypePointer RayPayloadKHR %5\n%94 = OpTypePointer StorageBuffer %5\n%100 = OpTypeBool\n%121 = OpConstant %5 7\n%124 = OpConstant %5 8\n%127 = OpConstant %5 9\n%130 = OpConstant %5 10\n%133 = OpConstant %5 11\n%135 = OpConstant %5 32\n%136 = OpTypeInt 64 0\n%137 = OpTypeStruct %5\n%138 = OpTypePointer PhysicalStorageBuffer %137\n%139 = OpTypePointer PhysicalStorageBuffer %5\n%147 = OpConstant %5 12\n%191 = OpTypePointer HitObjectAttributeNV %27\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%44 = OpVariable %43 Function\n%65 = OpVariable %43 Function\n%81 = OpVariable %43 Function\n%85 = OpVariable %43 Function\n%90 = OpVariable %43 Function\nOpBranch %200\n%200 = OpLabel\nOpHitObjectRecordEmptyNV %44\n%46 = OpBitcast %26 %47\n%48 = OpBitcast %26 %49\n%50 = OpBitcast %26 %51\n%52 = OpBitcast %26 %53\n%54 = OpBitcast %26 %55\n%56 = OpBitcast %26 %57\n%58 = OpBitcast %26 %59\n%60 = OpBitcast %26 %61\n%63 = OpCompositeConstruct %62 %50 %54 %58\n%64 = OpCompositeConstruct %62 %52 %56 %60\nOpHitObjectRecordMissNV %65 %45 %63 %46 %64 %48\n%66 = OpLoad %15 %17\n%79 = OpCompositeConstruct %62 %71 %73 %75\n%80 = OpCompositeConstruct %62 %72 %74 %76\nOpHitObjectRecordHitNV %81 %66 %45 %68 %67 %69 %70 %6 %79 %77 %80 %78 %40\n%82 = OpLoad %15 %17\n%83 = OpCompositeConstruct %62 %71 %73 %75\n%84 = OpCompositeConstruct %62 %72 %74 %76\nOpHitObjectRecordHitWithIndexNV %85 %82 %45 %68 %67 %69 %70 %83 %77 %84 %78 %38\n%86 = OpLoad %15 %17\n%88 = OpCompositeConstruct %62 %71 %73 %75\n%89 = OpCompositeConstruct %62 %72 %74 %76\nOpHitObjectTraceRayNV %90 %86 %87 %45 %67 %68 %69 %88 %77 %89 %78 %33\n%92 = OpInBoundsAccessChain %91 %33 %45\n%93 = OpLoad %5 %92\n%95 = OpAccessChain %94 %25 %45 %45\nOpStore %95 %93\nOpReorderThreadWithHintNV %67 %68\nOpReorderThreadWithHitObjectNV %90 %45 %45\n%96 = OpLoad %15 %17\n%97 = OpInBoundsAccessChain %91 %34 %45\nOpStore %97 %93\nOpHitObjectExecuteShaderNV %90 %34\n%98 = OpLoad %5 %97\n%99 = OpAccessChain %94 %25 %45 %67\nOpStore %99 %98\n%101 = OpHitObjectIsEmptyNV %100 %90\n%102 = OpSelect %5 %101 %67 %45\n%103 = OpINotEqual %100 %102 %45\n%104 = OpSelect %5 %103 %67 %45\n%105 = OpAccessChain %94 %25 %45 %68\nOpStore %105 %104\n%106 = OpHitObjectIsMissNV %100 %90\n%107 = OpSelect %5 %106 %67 %45\n%108 = OpINotEqual %100 %107 %45\n%109 = OpSelect %5 %108 %67 %45\n%110 = OpAccessChain %94 %25 %45 %69\nOpStore %110 %109\n%111 = OpHitObjectIsHitNV %100 %90\n%112 = OpSelect %5 %111 %67 %45\n%113 = OpINotEqual %100 %112 %45\n%114 = OpSelect %5 %113 %67 %45\n%115 = OpAccessChain %94 %25 %45 %70\nOpStore %115 %114\n%116 = OpHitObjectGetClusterIdNV %5 %90\n%117 = OpAccessChain %94 %25 %45 %6\nOpStore %117 %116\n%118 = OpHitObjectGetInstanceIdNV %5 %90\n%119 = OpAccessChain %94 %25 %45 %8\nOpStore %119 %118\n%120 = OpHitObjectGetInstanceCustomIndexNV %5 %90\n%122 = OpAccessChain %94 %25 %45 %121\nOpStore %122 %120\n%123 = OpHitObjectGetPrimitiveIndexNV %5 %90\n%125 = OpAccessChain %94 %25 %45 %124\nOpStore %125 %123\n%126 = OpHitObjectGetGeometryIndexNV %5 %90\n%128 = OpAccessChain %94 %25 %45 %127\nOpStore %128 %126\n%129 = OpHitObjectGetHitKindNV %5 %90\n%131 = OpAccessChain %94 %25 %45 %130\nOpStore %131 %129\n%132 = OpHitObjectGetShaderBindingTableRecordIndexNV %5 %90\n%134 = OpAccessChain %94 %25 %45 %133\nOpStore %134 %132\n%140 = OpHitObjectGetShaderRecordBufferHandleNV %10 %90\n%141 = OpBitcast %136 %140\n%142 = OpUConvert %136 %135\n%143 = OpIAdd %136 %141 %142\n%144 = OpConvertUToPtr %138 %143\n%145 = OpAccessChain %139 %144 %45\n%146 = OpLoad %5 %145 Aligned 4\n%148 = OpAccessChain %94 %25 %45 %147\nOpStore %148 %146\n%149 = OpHitObjectGetRayTMinNV %26 %90\n%150 = OpBitcast %5 %149\n%151 = OpHitObjectGetRayTMaxNV %26 %90\n%152 = OpBitcast %5 %151\n%153 = OpHitObjectGetWorldRayOriginNV %62 %90\n%154 = OpCompositeExtract %26 %153 0\n%155 = OpBitcast %5 %154\n%156 = OpCompositeExtract %26 %153 1\n%157 = OpBitcast %5 %156\n%158 = OpCompositeExtract %26 %153 2\n%159 = OpBitcast %5 %158\n%160 = OpHitObjectGetWorldRayDirectionNV %62 %90\n%161 = OpCompositeExtract %26 %160 0\n%162 = OpBitcast %5 %161\n%163 = OpCompositeExtract %26 %160 1\n%164 = OpBitcast %5 %163\n%165 = OpCompositeExtract %26 %160 2\n%166 = OpBitcast %5 %165\n%167 = OpBitcast %26 %150\n%168 = OpBitcast %26 %152\n%169 = OpBitcast %26 %155\n%170 = OpBitcast %26 %157\n%171 = OpBitcast %26 %159\n%172 = OpBitcast %26 %162\n%173 = OpBitcast %26 %164\n%174 = OpBitcast %26 %166\n%175 = OpBitcast %5 %167\n%176 = OpAccessChain %94 %21 %45 %45\nOpStore %176 %175\n%177 = OpBitcast %5 %168\n%178 = OpAccessChain %94 %21 %45 %67\nOpStore %178 %177\n%179 = OpBitcast %5 %169\n%180 = OpAccessChain %94 %21 %45 %68\nOpStore %180 %179\n%181 = OpBitcast %5 %170\n%182 = OpAccessChain %94 %21 %45 %69\nOpStore %182 %181\n%183 = OpBitcast %5 %171\n%184 = OpAccessChain %94 %21 %45 %70\nOpStore %184 %183\n%185 = OpBitcast %5 %172\n%186 = OpAccessChain %94 %21 %45 %6\nOpStore %186 %185\n%187 = OpBitcast %5 %173\n%188 = OpAccessChain %94 %21 %45 %8\nOpStore %188 %187\n%189 = OpBitcast %5 %174\n%190 = OpAccessChain %94 %21 %45 %121\nOpStore %190 %189\nOpHitObjectGetAttributesNV %90 %30\n%192 = OpInBoundsAccessChain %191 %30 %45\n%193 = OpLoad %27 %192\n%194 = OpCompositeExtract %26 %193 0\n%195 = OpBitcast %5 %194\n%196 = OpAccessChain %94 %21 %45 %124\nOpStore %196 %195\n%197 = OpCompositeExtract %26 %193 1\n%198 = OpBitcast %5 %197\n%199 = OpAccessChain %94 %21 %45 %127\nOpStore %199 %198\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/nvapi/ray-query-cluster-id.nvapi.comp",
    "content": "#version 460\n#extension GL_EXT_ray_query : require\n#extension GL_EXT_ray_flags_primitive_culling : require\n#extension GL_NV_cluster_acceleration_structure : require\nlayout(primitive_culling);\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _12;\n\nrayQueryEXT _21;\n\nvoid main()\n{\n    rayQueryInitializeEXT(_21, _8, 132u, 170u, vec3(1.0, 2.0, 3.0), 4.0, vec3(5.0, 6.0, 7.0), 8.0);\n    bool _37 = rayQueryProceedEXT(_21);\n    if (_37)\n    {\n        for (;;)\n        {\n            uint _42 = rayQueryGetRayFlagsEXT(_21);\n            uint _43 = rayQueryGetIntersectionClusterIdNV(_21, bool(0u));\n            imageStore(_12, int(gl_LocalInvocationIndex * 2u), uvec4(_43));\n            rayQueryTerminateEXT(_21);\n            bool _49 = rayQueryProceedEXT(_21);\n            if (_49)\n            {\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    uint _38 = rayQueryGetIntersectionTypeEXT(_21, bool(1u));\n    if (!(_38 == 0u))\n    {\n        uint _50 = rayQueryGetRayFlagsEXT(_21);\n        uint _51 = rayQueryGetIntersectionClusterIdNV(_21, bool(1u));\n        imageStore(_12, int((gl_LocalInvocationIndex * 2u) + 1u), uvec4(_51));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 65\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RayQueryKHR\nOpCapability RayTraversalPrimitiveCullingKHR\nOpCapability RayTracingClusterAccelerationStructureNV\nOpExtension \"SPV_KHR_ray_query\"\nOpExtension \"SPV_NV_cluster_acceleration_structure\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %8 %12 %17 %21\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %12 NonReadable\nOpDecorate %17 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 0\n%10 = OpTypeImage %9 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%16 = OpTypePointer Input %9\n%17 = OpVariable %16 Input\n%19 = OpTypeRayQueryKHR\n%20 = OpTypePointer Private %19\n%21 = OpVariable %20 Private\n%22 = OpConstant %9 132\n%23 = OpConstant %9 170\n%24 = OpTypeFloat 32\n%25 = OpConstant %24 1\n%26 = OpConstant %24 5\n%27 = OpConstant %24 2\n%28 = OpConstant %24 6\n%29 = OpConstant %24 3\n%30 = OpConstant %24 7\n%31 = OpTypeVector %24 3\n%33 = OpConstant %24 4\n%35 = OpConstant %24 8\n%36 = OpTypeBool\n%39 = OpConstant %9 1\n%41 = OpConstant %9 0\n%46 = OpConstant %9 2\n%47 = OpTypeVector %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%13 = OpLoad %10 %12\n%15 = OpLoad %6 %8\n%18 = OpLoad %9 %17\n%32 = OpCompositeConstruct %31 %25 %27 %29\n%34 = OpCompositeConstruct %31 %26 %28 %30\nOpRayQueryInitializeKHR %21 %15 %22 %23 %32 %33 %34 %35\n%37 = OpRayQueryProceedKHR %36 %21\nOpSelectionMerge %61 None\nOpBranchConditional %37 %58 %61\n%58 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%42 = OpRayQueryGetRayFlagsKHR %9 %21\n%43 = OpRayQueryGetIntersectionClusterIdNV %9 %21 %41\n%44 = OpShiftLeftLogical %9 %18 %39\n%45 = OpIMul %9 %18 %46\n%48 = OpCompositeConstruct %47 %43 %43 %43 %43\nOpImageWrite %13 %45 %48\nOpRayQueryTerminateKHR %21\n%49 = OpRayQueryProceedKHR %36 %21\nOpLoopMerge %60 %59 None\nOpBranchConditional %49 %59 %60\n%60 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%38 = OpRayQueryGetIntersectionTypeKHR %9 %21 %39\n%40 = OpIEqual %36 %38 %41\nOpSelectionMerge %63 None\nOpBranchConditional %40 %63 %62\n%62 = OpLabel\n%50 = OpRayQueryGetRayFlagsKHR %9 %21\n%51 = OpRayQueryGetIntersectionClusterIdNV %9 %21 %39\n%52 = OpShiftLeftLogical %9 %18 %39\n%53 = OpBitwiseOr %9 %52 %39\n%54 = OpIMul %9 %18 %46\n%55 = OpIAdd %9 %54 %39\n%56 = OpCompositeConstruct %47 %51 %51 %51 %51\nOpImageWrite %13 %55 %56\nOpBranch %63\n%63 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/nvapi/rt-cluster-id.nvapi.rany",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_NV_cluster_acceleration_structure : require\n\nstruct _6\n{\n    uint _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _6 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = gl_ClusterIDNV;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability RayTracingClusterAccelerationStructureNV\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpExtension \"SPV_NV_cluster_acceleration_structure\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint AnyHitKHR %3 \"main\" %8 %13 %16\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\nOpDecorate %16 BuiltIn ClusterIDNV\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingRayPayloadKHR %6\n%8 = OpVariable %7 IncomingRayPayloadKHR\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%15 = OpTypePointer Input %5\n%16 = OpVariable %15 Input\n%18 = OpTypePointer IncomingRayPayloadKHR %5\n%20 = OpConstant %5 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %21\n%21 = OpLabel\n%17 = OpLoad %5 %16\n%19 = OpInBoundsAccessChain %18 %8 %20\nOpStore %19 %17\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/nvapi/shuffle.nvapi.ssbo.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_shuffle : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nlayout(set = 0, binding = 2) uniform writeonly image1D _17;\n\nvoid main()\n{\n    _9._m0[gl_GlobalInvocationID.x] = subgroupShuffle(gl_GlobalInvocationID.x, 9u);\n    uint _34 = atomicAdd(_13._m0[64u], 9u);\n    _9._m0[100u] = _34;\n    imageStore(_17, int(gl_GlobalInvocationID.x), vec4(2.0));\n    _9._m0[101u] = 42u;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformShuffle\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %22\nOpExecutionMode %3 LocalSize 32 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonReadable\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 2\nOpDecorate %17 NonReadable\nOpDecorate %22 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFloat 32\n%15 = OpTypeImage %14 1D 0 0 0 2 Unknown\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%20 = OpTypeVector %5 3\n%21 = OpTypePointer Input %20\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Input %5\n%25 = OpConstant %5 0\n%27 = OpConstant %5 9\n%29 = OpConstant %5 3\n%30 = OpTypePointer StorageBuffer %5\n%32 = OpConstant %5 64\n%35 = OpConstant %5 1\n%36 = OpConstant %5 100\n%38 = OpConstant %5 10\n%39 = OpConstant %14 2\n%40 = OpTypeVector %14 4\n%41 = OpConstantComposite %40 %39 %39 %39 %39\n%42 = OpConstant %5 42\n%43 = OpConstant %5 101\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %45\n%45 = OpLabel\n%18 = OpLoad %15 %17\n%24 = OpAccessChain %23 %22 %25\n%26 = OpLoad %5 %24\n%28 = OpGroupNonUniformShuffle %5 %29 %26 %27\n%31 = OpAccessChain %30 %9 %25 %26\nOpStore %31 %28\n%33 = OpAccessChain %30 %13 %25 %32\n%34 = OpAtomicIAdd %5 %33 %35 %25 %27\n%37 = OpAccessChain %30 %9 %25 %36\nOpStore %37 %34\nOpImageWrite %18 %26 %41\n%44 = OpAccessChain %30 %9 %25 %43\nOpStore %44 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/fp16-fp32-fp16-1.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    uint16_t _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _16_18\n{\n    uint _m0[];\n} _18;\n\nvoid main()\n{\n    uint _28 = _9._m0[gl_GlobalInvocationID.x];\n    float16_t _44 = uint16BitsToFloat16(unpackUint2x16(_28).x);\n    uint _45 = gl_GlobalInvocationID.x << 1u;\n    _14._m0[gl_GlobalInvocationID.x * 2u] = float16BitsToUint16(_44);\n    float16_t _54 = uint16BitsToFloat16(unpackUint2x16(_28).y);\n    _14._m0[(gl_GlobalInvocationID.x * 2u) + 1u] = float16BitsToUint16(_54);\n    _18._m0[gl_GlobalInvocationID.x * 2u] = uint(unpackUint2x16(_28).x);\n    _18._m0[(gl_GlobalInvocationID.x * 2u) + 1u] = uint(unpackUint2x16(_28).y);\n    _18._m0[(gl_GlobalInvocationID.x * 2u) + 1024u] = uint(float16BitsToUint16(_44));\n    _18._m0[(gl_GlobalInvocationID.x * 2u) + 1025u] = uint(float16BitsToUint16(_54));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 89\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\n%31 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %21\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %11 ArrayStride 2\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %15 ArrayStride 4\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 2\nOpDecorate %18 NonReadable\nOpDecorate %21 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeInt 16 0\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %5\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeVector %5 3\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Input %5\n%24 = OpConstant %5 0\n%26 = OpTypePointer StorageBuffer %5\n%30 = OpConstant %5 65535\n%32 = OpTypeFloat 32\n%33 = OpTypeVector %32 2\n%37 = OpConstant %5 16\n%40 = OpTypeVector %10 2\n%43 = OpTypeFloat 16\n%46 = OpConstant %5 1\n%48 = OpConstant %5 2\n%50 = OpTypePointer StorageBuffer %10\n%75 = OpConstant %5 1024\n%83 = OpConstant %5 1025\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %87\n%87 = OpLabel\n%23 = OpAccessChain %22 %21 %24\n%25 = OpLoad %5 %23\n%27 = OpAccessChain %26 %9 %24 %25\n%28 = OpLoad %5 %27\n%29 = OpBitwiseAnd %5 %28 %30\n%34 = OpExtInst %33 %31 UnpackHalf2x16 %29\n%35 = OpCompositeExtract %32 %34 0\n%36 = OpShiftRightLogical %5 %28 %37\n%38 = OpExtInst %33 %31 UnpackHalf2x16 %36\n%39 = OpCompositeExtract %32 %38 0\n%41 = OpBitcast %40 %28\n%42 = OpCompositeExtract %10 %41 0\n%44 = OpBitcast %43 %42\n%45 = OpShiftLeftLogical %5 %25 %46\n%47 = OpIMul %5 %25 %48\n%49 = OpBitcast %10 %44\n%51 = OpAccessChain %50 %14 %24 %47\nOpStore %51 %49\n%52 = OpBitcast %40 %28\n%53 = OpCompositeExtract %10 %52 1\n%54 = OpBitcast %43 %53\n%55 = OpBitwiseOr %5 %45 %46\n%56 = OpIMul %5 %25 %48\n%57 = OpIAdd %5 %56 %46\n%58 = OpBitcast %10 %54\n%59 = OpAccessChain %50 %14 %24 %57\nOpStore %59 %58\n%60 = OpBitcast %40 %28\n%61 = OpCompositeExtract %10 %60 0\n%62 = OpUConvert %5 %61\n%63 = OpIMul %5 %25 %48\n%64 = OpAccessChain %26 %18 %24 %63\nOpStore %64 %62\n%65 = OpBitcast %40 %28\n%66 = OpCompositeExtract %10 %65 1\n%67 = OpUConvert %5 %66\n%68 = OpIMul %5 %25 %48\n%69 = OpIAdd %5 %68 %46\n%70 = OpAccessChain %26 %18 %24 %69\nOpStore %70 %67\n%71 = OpQuantizeToF16 %32 %35\n%72 = OpBitcast %10 %44\n%73 = OpUConvert %5 %72\n%74 = OpIAdd %5 %45 %75\n%76 = OpIMul %5 %25 %48\n%77 = OpIAdd %5 %76 %75\n%78 = OpAccessChain %26 %18 %24 %77\nOpStore %78 %73\n%79 = OpQuantizeToF16 %32 %39\n%80 = OpBitcast %10 %54\n%81 = OpUConvert %5 %80\n%82 = OpIAdd %5 %45 %83\n%84 = OpIMul %5 %25 %48\n%85 = OpIAdd %5 %84 %83\n%86 = OpAccessChain %26 %18 %24 %85\nOpStore %86 %81\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/sabs.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec4 A;\nlayout(location = 0) out ivec4 SV_Target;\n\nvoid main()\n{\n    uint _16 = uint(A.x);\n    uint _20 = uint(A.y);\n    uint _24 = uint(A.z);\n    uint _28 = uint(A.w);\n    SV_Target.x = int(uint(abs(int(_16))));\n    SV_Target.y = int(uint(abs(int(_20))));\n    SV_Target.z = int(uint(abs(int(_24))));\n    SV_Target.w = int(uint(abs(int(_28))));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\nOpCapability Shader\n%33 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%22 = OpConstant %13 2\n%26 = OpConstant %13 3\n%38 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %47\n%47 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %13 %23\n%25 = OpAccessChain %11 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpBitcast %13 %27\n%29 = OpSNegate %13 %16\n%30 = OpSNegate %13 %20\n%31 = OpSNegate %13 %24\n%32 = OpSNegate %13 %28\n%34 = OpExtInst %13 %33 SAbs %16\n%35 = OpExtInst %13 %33 SAbs %20\n%36 = OpExtInst %13 %33 SAbs %24\n%37 = OpExtInst %13 %33 SAbs %28\n%39 = OpAccessChain %38 %10 %14\n%40 = OpBitcast %5 %34\nOpStore %39 %40\n%41 = OpAccessChain %38 %10 %18\n%42 = OpBitcast %5 %35\nOpStore %41 %42\n%43 = OpAccessChain %38 %10 %22\n%44 = OpBitcast %5 %36\nOpStore %43 %44\n%45 = OpAccessChain %38 %10 %26\n%46 = OpBitcast %5 %37\nOpStore %45 %46\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/sneg.frag",
    "content": "#version 460\n\nlayout(location = 0) flat in ivec4 A;\nlayout(location = 0) out ivec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = int(-uint(A.x));\n    SV_Target.y = int(-uint(A.y));\n    SV_Target.z = int(-uint(A.z));\n    SV_Target.w = int(-uint(A.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Flat\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%18 = OpConstant %13 1\n%22 = OpConstant %13 2\n%26 = OpConstant %13 3\n%33 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpBitcast %13 %15\n%17 = OpAccessChain %11 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpBitcast %13 %19\n%21 = OpAccessChain %11 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpBitcast %13 %23\n%25 = OpAccessChain %11 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpBitcast %13 %27\n%29 = OpSNegate %13 %16\n%30 = OpSNegate %13 %20\n%31 = OpSNegate %13 %24\n%32 = OpSNegate %13 %28\n%34 = OpAccessChain %33 %10 %14\n%35 = OpBitcast %5 %29\nOpStore %34 %35\n%36 = OpAccessChain %33 %10 %18\n%37 = OpBitcast %5 %30\nOpStore %36 %37\n%38 = OpAccessChain %33 %10 %22\n%39 = OpBitcast %5 %31\nOpStore %38 %39\n%40 = OpAccessChain %33 %10 %26\n%41 = OpBitcast %5 %32\nOpStore %40 %41\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first-heap.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _13[];\n\nlayout(set = 0, binding = 0, std140) uniform _29_31\n{\n    vec4 _m0[1024];\n} _31;\n\nlayout(set = 0, binding = 1, std140) uniform _33_36\n{\n    vec4 _m0[1024];\n} _36[2];\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _16;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _20[2];\nlayout(set = 0, binding = 3) uniform samplerBuffer _23;\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _26;\n\nvoid main()\n{\n    uint _63 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(floatBitsToUint(_13[0u]._m0[0u]).x));\n    uint _70 = imageAtomicAdd(_26, int(0u), floatBitsToUint(_31._m0[1u]).x);\n    uint _78 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x));\n    uint _86 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(floatBitsToUint(_36[0u]._m0[1u]).x));\n    uint _94 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(floatBitsToUint(_36[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _101 = imageAtomicAdd(_26, int(0u), subgroupBroadcastFirst(texelFetch(_16, int(1u)).x));\n    uint _108 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(texelFetch(_16, int(gl_GlobalInvocationID.x)).x));\n    uint _116 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(texelFetch(_20[0u], int(1u)).x));\n    uint _123 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(imageLoad(_26, int(2u)).x));\n    uint _131 = imageAtomicAdd(_26, int(1u), uint(subgroupBroadcastFirst(texelFetch(_23, int(0u)).x)));\n    uint _134 = imageAtomicAdd(_26, int(0u), gl_WorkGroupID.x);\n    uint _138 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _145 = imageAtomicAdd(_26, int(0u), floatBitsToUint(_31._m0[1u]).x);\n    uint _153 = imageAtomicAdd(_26, int(0u), subgroupAdd(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x));\n    uint _161 = imageAtomicAdd(_26, int(0u), subgroupOr(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x));\n    uint _171 = imageAtomicAdd(_26, int(0u), uint(subgroupAllEqual(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x)));\n    uint _181 = imageAtomicAdd(_26, int(0u), subgroupBallot(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _191 = imageAtomicAdd(_26, int(0u), uint(subgroupAny(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _201 = imageAtomicAdd(_26, int(0u), uint(subgroupAll(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _210 = imageAtomicAdd(_26, int(1u), subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_31._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 213\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %42 %46\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %10 \"BindlessCBV\"\nOpName %29 \"\"\nOpName %33 \"\"\nOpDecorate %9 ArrayStride 16\nOpDecorate %10 Block\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 3\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %28 ArrayStride 16\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 0\nOpDecorate %32 ArrayStride 16\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %36 DescriptorSet 0\nOpDecorate %36 Binding 1\nOpDecorate %42 BuiltIn GlobalInvocationId\nOpDecorate %46 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 4096\n%9 = OpTypeArray %6 %8\n%10 = OpTypeStruct %9\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer Uniform %11\n%13 = OpVariable %12 Uniform\n%14 = OpTypeImage %7 Buffer 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpConstant %7 2\n%18 = OpTypeArray %14 %17\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypeImage %7 Buffer 0 0 0 2 R32ui\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpConstant %7 1024\n%28 = OpTypeArray %6 %27\n%29 = OpTypeStruct %28\n%30 = OpTypePointer Uniform %29\n%31 = OpVariable %30 Uniform\n%32 = OpTypeArray %6 %27\n%33 = OpTypeStruct %32\n%34 = OpTypeArray %33 %17\n%35 = OpTypePointer Uniform %34\n%36 = OpVariable %35 Uniform\n%37 = OpTypePointer Uniform %33\n%39 = OpConstant %7 0\n%40 = OpTypeVector %7 3\n%41 = OpTypePointer Input %40\n%42 = OpVariable %41 Input\n%43 = OpTypePointer Input %7\n%46 = OpVariable %41 Input\n%49 = OpTypePointer Uniform %10\n%51 = OpTypePointer Uniform %6\n%54 = OpTypeVector %7 4\n%58 = OpConstant %7 3\n%60 = OpConstant %7 1\n%61 = OpTypePointer Image %7\n%166 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %211\n%211 = OpLabel\n%38 = OpAccessChain %37 %36 %39\n%44 = OpAccessChain %43 %42 %39\n%45 = OpLoad %7 %44\n%47 = OpAccessChain %43 %46 %39\n%48 = OpLoad %7 %47\n%50 = OpAccessChain %49 %13 %39\n%52 = OpAccessChain %51 %50 %39 %39\n%53 = OpLoad %6 %52\n%55 = OpBitcast %54 %53\n%56 = OpCompositeExtract %7 %55 0\n%57 = OpGroupNonUniformBroadcastFirst %7 %58 %56\n%59 = OpLoad %24 %26\n%62 = OpImageTexelPointer %61 %26 %60 %39\n%63 = OpAtomicIAdd %7 %62 %60 %39 %57\n%64 = OpAccessChain %51 %31 %39 %60\n%65 = OpLoad %6 %64\n%66 = OpBitcast %54 %65\n%67 = OpCompositeExtract %7 %66 0\n%68 = OpLoad %24 %26\n%69 = OpImageTexelPointer %61 %26 %39 %39\n%70 = OpAtomicIAdd %7 %69 %60 %39 %67\n%71 = OpAccessChain %51 %31 %39 %45\n%72 = OpLoad %6 %71\n%73 = OpBitcast %54 %72\n%74 = OpCompositeExtract %7 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %7 %58 %74\n%76 = OpLoad %24 %26\n%77 = OpImageTexelPointer %61 %26 %60 %39\n%78 = OpAtomicIAdd %7 %77 %60 %39 %75\n%79 = OpAccessChain %51 %38 %39 %60\n%80 = OpLoad %6 %79\n%81 = OpBitcast %54 %80\n%82 = OpCompositeExtract %7 %81 0\n%83 = OpGroupNonUniformBroadcastFirst %7 %58 %82\n%84 = OpLoad %24 %26\n%85 = OpImageTexelPointer %61 %26 %60 %39\n%86 = OpAtomicIAdd %7 %85 %60 %39 %83\n%87 = OpAccessChain %51 %38 %39 %45\n%88 = OpLoad %6 %87\n%89 = OpBitcast %54 %88\n%90 = OpCompositeExtract %7 %89 0\n%91 = OpGroupNonUniformBroadcastFirst %7 %58 %90\n%92 = OpLoad %24 %26\n%93 = OpImageTexelPointer %61 %26 %60 %39\n%94 = OpAtomicIAdd %7 %93 %60 %39 %91\n%95 = OpLoad %14 %16\n%96 = OpImageFetch %54 %95 %60\n%97 = OpCompositeExtract %7 %96 0\n%98 = OpGroupNonUniformBroadcastFirst %7 %58 %97\n%99 = OpLoad %24 %26\n%100 = OpImageTexelPointer %61 %26 %39 %39\n%101 = OpAtomicIAdd %7 %100 %60 %39 %98\n%102 = OpLoad %14 %16\n%103 = OpImageFetch %54 %102 %45\n%104 = OpCompositeExtract %7 %103 0\n%105 = OpGroupNonUniformBroadcastFirst %7 %58 %104\n%106 = OpLoad %24 %26\n%107 = OpImageTexelPointer %61 %26 %60 %39\n%108 = OpAtomicIAdd %7 %107 %60 %39 %105\n%109 = OpAccessChain %15 %20 %39\n%110 = OpLoad %14 %109\n%111 = OpImageFetch %54 %110 %60\n%112 = OpCompositeExtract %7 %111 0\n%113 = OpGroupNonUniformBroadcastFirst %7 %58 %112\n%114 = OpLoad %24 %26\n%115 = OpImageTexelPointer %61 %26 %60 %39\n%116 = OpAtomicIAdd %7 %115 %60 %39 %113\n%117 = OpLoad %24 %26\n%118 = OpImageRead %54 %117 %17\n%119 = OpCompositeExtract %7 %118 0\n%120 = OpGroupNonUniformBroadcastFirst %7 %58 %119\n%121 = OpLoad %24 %26\n%122 = OpImageTexelPointer %61 %26 %60 %39\n%123 = OpAtomicIAdd %7 %122 %60 %39 %120\n%124 = OpLoad %21 %23\n%125 = OpImageFetch %6 %124 %39\n%126 = OpCompositeExtract %5 %125 0\n%127 = OpGroupNonUniformBroadcastFirst %5 %58 %126\n%128 = OpConvertFToU %7 %127\n%129 = OpLoad %24 %26\n%130 = OpImageTexelPointer %61 %26 %60 %39\n%131 = OpAtomicIAdd %7 %130 %60 %39 %128\n%132 = OpLoad %24 %26\n%133 = OpImageTexelPointer %61 %26 %39 %39\n%134 = OpAtomicIAdd %7 %133 %60 %39 %48\n%135 = OpGroupNonUniformBroadcastFirst %7 %58 %45\n%136 = OpLoad %24 %26\n%137 = OpImageTexelPointer %61 %26 %60 %39\n%138 = OpAtomicIAdd %7 %137 %60 %39 %135\n%139 = OpAccessChain %51 %31 %39 %60\n%140 = OpLoad %6 %139\n%141 = OpBitcast %54 %140\n%142 = OpCompositeExtract %7 %141 0\n%143 = OpLoad %24 %26\n%144 = OpImageTexelPointer %61 %26 %39 %39\n%145 = OpAtomicIAdd %7 %144 %60 %39 %142\n%146 = OpAccessChain %51 %31 %39 %45\n%147 = OpLoad %6 %146\n%148 = OpBitcast %54 %147\n%149 = OpCompositeExtract %7 %148 0\n%150 = OpGroupNonUniformIAdd %7 %58 Reduce %149\n%151 = OpLoad %24 %26\n%152 = OpImageTexelPointer %61 %26 %39 %39\n%153 = OpAtomicIAdd %7 %152 %60 %39 %150\n%154 = OpAccessChain %51 %31 %39 %45\n%155 = OpLoad %6 %154\n%156 = OpBitcast %54 %155\n%157 = OpCompositeExtract %7 %156 0\n%158 = OpGroupNonUniformBitwiseOr %7 %58 Reduce %157\n%159 = OpLoad %24 %26\n%160 = OpImageTexelPointer %61 %26 %39 %39\n%161 = OpAtomicIAdd %7 %160 %60 %39 %158\n%162 = OpAccessChain %51 %31 %39 %45\n%163 = OpLoad %6 %162\n%164 = OpBitcast %54 %163\n%165 = OpCompositeExtract %7 %164 0\n%167 = OpGroupNonUniformAllEqual %166 %58 %165\n%168 = OpSelect %7 %167 %60 %39\n%169 = OpLoad %24 %26\n%170 = OpImageTexelPointer %61 %26 %39 %39\n%171 = OpAtomicIAdd %7 %170 %60 %39 %168\n%172 = OpAccessChain %51 %31 %39 %45\n%173 = OpLoad %6 %172\n%174 = OpBitcast %54 %173\n%175 = OpCompositeExtract %7 %174 0\n%176 = OpINotEqual %166 %175 %39\n%177 = OpGroupNonUniformBallot %54 %58 %176\n%178 = OpCompositeExtract %7 %177 0\n%179 = OpLoad %24 %26\n%180 = OpImageTexelPointer %61 %26 %39 %39\n%181 = OpAtomicIAdd %7 %180 %60 %39 %178\n%182 = OpAccessChain %51 %31 %39 %45\n%183 = OpLoad %6 %182\n%184 = OpBitcast %54 %183\n%185 = OpCompositeExtract %7 %184 0\n%186 = OpINotEqual %166 %185 %39\n%187 = OpGroupNonUniformAny %166 %58 %186\n%188 = OpSelect %7 %187 %60 %39\n%189 = OpLoad %24 %26\n%190 = OpImageTexelPointer %61 %26 %39 %39\n%191 = OpAtomicIAdd %7 %190 %60 %39 %188\n%192 = OpAccessChain %51 %31 %39 %45\n%193 = OpLoad %6 %192\n%194 = OpBitcast %54 %193\n%195 = OpCompositeExtract %7 %194 0\n%196 = OpINotEqual %166 %195 %39\n%197 = OpGroupNonUniformAll %166 %58 %196\n%198 = OpSelect %7 %197 %60 %39\n%199 = OpLoad %24 %26\n%200 = OpImageTexelPointer %61 %26 %39 %39\n%201 = OpAtomicIAdd %7 %200 %60 %39 %198\n%202 = OpAccessChain %51 %31 %39 %45\n%203 = OpLoad %6 %202\n%204 = OpBitcast %54 %203\n%205 = OpCompositeExtract %7 %204 0\n%206 = OpGroupNonUniformIAdd %7 %58 ExclusiveScan %205\n%207 = OpGroupNonUniformBroadcastFirst %7 %58 %206\n%208 = OpLoad %24 %26\n%209 = OpImageTexelPointer %61 %26 %60 %39\n%210 = OpAtomicIAdd %7 %209 %60 %39 %207\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.bindless.local-root-signature.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _25\n{\n    vec4 _m0;\n    uint _m1;\n};\n\nvec4 _89;\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _24[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) rayPayloadInEXT _25 payload;\n\nvoid main()\n{\n    uint _38 = (SBT._m9.x >> 6u) + 12u;\n    vec4 _53 = uintBitsToFloat(uvec4(SBT._m0[0u], SBT._m0[1u], SBT._m0[2u], SBT._m0[3u]));\n    vec4 _88;\n    _88.x = (payload._m0.x + subgroupBroadcastFirst(_53.x)) + subgroupBroadcastFirst(_24[nonuniformEXT(_38)]._m0[0u].x);\n    _88.y = subgroupBroadcastFirst(_24[nonuniformEXT(_38)]._m0[0u].y) + (payload._m0.y + subgroupBroadcastFirst(_53.y));\n    _88.z = subgroupBroadcastFirst(_24[nonuniformEXT(_38)]._m0[0u].z) + (payload._m0.z + subgroupBroadcastFirst(_53.z));\n    _88.w = subgroupBroadcastFirst(_24[nonuniformEXT(_38)]._m0[0u].w) + (payload._m0.w + subgroupBroadcastFirst(_53.w));\n    payload._m0 = _88;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint MissKHR %3 \"main\" %8 %16 %24 %27\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %14 \"SBTBlock\"\nOpName %16 \"SBT\"\nOpName %21 \"BindlessCBV\"\nOpName %25 \"\"\nOpName %27 \"payload\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 4\nOpDecorate %12 ArrayStride 4\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpMemberDecorate %14 1 Offset 20\nOpMemberDecorate %14 2 Offset 48\nOpMemberDecorate %14 3 Offset 56\nOpMemberDecorate %14 4 Offset 64\nOpMemberDecorate %14 5 Offset 72\nOpMemberDecorate %14 6 Offset 80\nOpMemberDecorate %14 7 Offset 88\nOpMemberDecorate %14 8 Offset 96\nOpMemberDecorate %14 9 Offset 104\nOpMemberDecorate %14 10 Offset 112\nOpDecorate %20 ArrayStride 16\nOpDecorate %21 Block\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %24 DescriptorSet 5\nOpDecorate %24 Binding 0\nOpDecorate %32 NonUniform\nOpDecorate %74 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpConstant %5 5\n%10 = OpTypeArray %5 %9\n%11 = OpConstant %5 6\n%12 = OpTypeArray %5 %11\n%13 = OpTypeVector %5 2\n%14 = OpTypeStruct %10 %12 %13 %13 %13 %13 %13 %13 %13 %13 %13\n%15 = OpTypePointer ShaderRecordBufferKHR %14\n%16 = OpVariable %15 ShaderRecordBufferKHR\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 4\n%19 = OpConstant %5 4096\n%20 = OpTypeArray %18 %19\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer Uniform %22\n%24 = OpVariable %23 Uniform\n%25 = OpTypeStruct %18 %5\n%26 = OpTypePointer IncomingRayPayloadKHR %25\n%27 = OpVariable %26 IncomingRayPayloadKHR\n%28 = OpTypePointer ShaderRecordBufferKHR %10\n%30 = OpConstant %5 0\n%31 = OpTypePointer Uniform %21\n%33 = OpTypePointer ShaderRecordBufferKHR %5\n%35 = OpConstant %5 9\n%39 = OpConstant %5 12\n%43 = OpConstant %5 1\n%46 = OpConstant %5 2\n%49 = OpConstant %5 3\n%51 = OpTypeVector %5 4\n%62 = OpTypePointer IncomingRayPayloadKHR %18\n%73 = OpTypePointer Uniform %18\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%89 = OpUndef %18\nOpBranch %93\n%93 = OpLabel\n%29 = OpAccessChain %28 %16 %30\n%34 = OpAccessChain %33 %16 %35 %30\n%36 = OpLoad %5 %34\n%37 = OpShiftRightLogical %5 %36 %11\n%38 = OpIAdd %5 %37 %39\n%32 = OpAccessChain %31 %24 %38\n%40 = OpAccessChain %33 %29 %30\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %33 %29 %43\n%44 = OpLoad %5 %42\n%45 = OpAccessChain %33 %29 %46\n%47 = OpLoad %5 %45\n%48 = OpAccessChain %33 %29 %49\n%50 = OpLoad %5 %48\n%52 = OpCompositeConstruct %51 %41 %44 %47 %50\n%53 = OpBitcast %18 %52\n%54 = OpCompositeExtract %17 %53 0\n%55 = OpCompositeExtract %17 %53 1\n%56 = OpCompositeExtract %17 %53 2\n%57 = OpCompositeExtract %17 %53 3\n%58 = OpGroupNonUniformBroadcastFirst %17 %49 %54\n%59 = OpGroupNonUniformBroadcastFirst %17 %49 %55\n%60 = OpGroupNonUniformBroadcastFirst %17 %49 %56\n%61 = OpGroupNonUniformBroadcastFirst %17 %49 %57\n%63 = OpInBoundsAccessChain %62 %27 %30\n%64 = OpLoad %18 %63\n%65 = OpCompositeExtract %17 %64 0\n%66 = OpFAdd %17 %65 %58\n%67 = OpCompositeExtract %17 %64 1\n%68 = OpFAdd %17 %67 %59\n%69 = OpCompositeExtract %17 %64 2\n%70 = OpFAdd %17 %69 %60\n%71 = OpCompositeExtract %17 %64 3\n%72 = OpFAdd %17 %71 %61\n%74 = OpAccessChain %73 %32 %30 %30\n%75 = OpLoad %18 %74\n%76 = OpCompositeExtract %17 %75 0\n%77 = OpCompositeExtract %17 %75 1\n%78 = OpCompositeExtract %17 %75 2\n%79 = OpCompositeExtract %17 %75 3\n%80 = OpGroupNonUniformBroadcastFirst %17 %49 %76\n%81 = OpGroupNonUniformBroadcastFirst %17 %49 %77\n%82 = OpGroupNonUniformBroadcastFirst %17 %49 %78\n%83 = OpGroupNonUniformBroadcastFirst %17 %49 %79\n%84 = OpFAdd %17 %66 %80\n%85 = OpFAdd %17 %81 %68\n%86 = OpFAdd %17 %82 %70\n%87 = OpFAdd %17 %83 %72\n%88 = OpCompositeInsert %18 %84 %89 0\n%90 = OpCompositeInsert %18 %85 %88 1\n%91 = OpCompositeInsert %18 %86 %90 2\n%92 = OpCompositeInsert %18 %87 %91 3\nOpStore %63 %92\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _23_25\n{\n    vec4 _m0[1024];\n} _25;\n\nlayout(set = 0, binding = 1, std140) uniform _27_30\n{\n    vec4 _m0[1024];\n} _30[2];\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _12[2];\nlayout(set = 0, binding = 3) uniform samplerBuffer _16;\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _19;\n\nvoid main()\n{\n    uint _55 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _63 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _70 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[1u]).x));\n    uint _77 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _82 = imageAtomicAdd(_19, int(0u), subgroupBroadcastFirst(texelFetch(_8, int(1u)).x));\n    uint _87 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_8, int(gl_GlobalInvocationID.x)).x));\n    uint _94 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_12[0u], int(1u)).x));\n    uint _99 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(imageLoad(_19, int(2u)).x));\n    uint _105 = imageAtomicAdd(_19, int(1u), uint(subgroupBroadcastFirst(texelFetch(_16, int(0u)).x)));\n    uint _107 = imageAtomicAdd(_19, int(0u), gl_WorkGroupID.x);\n    uint _110 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _116 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _123 = imageAtomicAdd(_19, int(0u), subgroupAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _130 = imageAtomicAdd(_19, int(0u), subgroupOr(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _139 = imageAtomicAdd(_19, int(0u), uint(subgroupAllEqual(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n    uint _148 = imageAtomicAdd(_19, int(0u), subgroupBallot(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _157 = imageAtomicAdd(_19, int(0u), uint(subgroupAny(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _166 = imageAtomicAdd(_19, int(0u), uint(subgroupAll(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _174 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 177\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %39 %43\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %23 \"\"\nOpName %27 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 3\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %22 ArrayStride 16\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 1\nOpDecorate %39 BuiltIn GlobalInvocationId\nOpDecorate %43 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 2\n%10 = OpTypeArray %6 %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpConstant %5 1024\n%21 = OpTypeVector %13 4\n%22 = OpTypeArray %21 %20\n%23 = OpTypeStruct %22\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypeArray %21 %20\n%27 = OpTypeStruct %26\n%28 = OpTypeArray %27 %9\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%34 = OpTypePointer Uniform %27\n%36 = OpConstant %5 0\n%37 = OpTypeVector %5 3\n%38 = OpTypePointer Input %37\n%39 = OpVariable %38 Input\n%40 = OpTypePointer Input %5\n%43 = OpVariable %38 Input\n%46 = OpConstant %5 1\n%47 = OpTypePointer Uniform %21\n%50 = OpTypeVector %5 4\n%53 = OpTypePointer Image %5\n%61 = OpConstant %5 3\n%135 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %175\n%175 = OpLabel\n%31 = OpLoad %17 %19\n%32 = OpLoad %14 %16\n%33 = OpLoad %6 %8\n%35 = OpAccessChain %34 %30 %36\n%41 = OpAccessChain %40 %39 %36\n%42 = OpLoad %5 %41\n%44 = OpAccessChain %40 %43 %36\n%45 = OpLoad %5 %44\n%48 = OpAccessChain %47 %25 %36 %46\n%49 = OpLoad %21 %48\n%51 = OpBitcast %50 %49\n%52 = OpCompositeExtract %5 %51 0\n%54 = OpImageTexelPointer %53 %19 %36 %36\n%55 = OpAtomicIAdd %5 %54 %46 %36 %52\n%56 = OpAccessChain %47 %25 %36 %42\n%57 = OpLoad %21 %56\n%58 = OpBitcast %50 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpGroupNonUniformBroadcastFirst %5 %61 %59\n%62 = OpImageTexelPointer %53 %19 %46 %36\n%63 = OpAtomicIAdd %5 %62 %46 %36 %60\n%64 = OpAccessChain %47 %35 %36 %46\n%65 = OpLoad %21 %64\n%66 = OpBitcast %50 %65\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpGroupNonUniformBroadcastFirst %5 %61 %67\n%69 = OpImageTexelPointer %53 %19 %46 %36\n%70 = OpAtomicIAdd %5 %69 %46 %36 %68\n%71 = OpAccessChain %47 %35 %36 %42\n%72 = OpLoad %21 %71\n%73 = OpBitcast %50 %72\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %5 %61 %74\n%76 = OpImageTexelPointer %53 %19 %46 %36\n%77 = OpAtomicIAdd %5 %76 %46 %36 %75\n%78 = OpImageFetch %50 %33 %46\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpGroupNonUniformBroadcastFirst %5 %61 %79\n%81 = OpImageTexelPointer %53 %19 %36 %36\n%82 = OpAtomicIAdd %5 %81 %46 %36 %80\n%83 = OpImageFetch %50 %33 %42\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpGroupNonUniformBroadcastFirst %5 %61 %84\n%86 = OpImageTexelPointer %53 %19 %46 %36\n%87 = OpAtomicIAdd %5 %86 %46 %36 %85\n%88 = OpAccessChain %7 %12 %36\n%89 = OpLoad %6 %88\n%90 = OpImageFetch %50 %89 %46\n%91 = OpCompositeExtract %5 %90 0\n%92 = OpGroupNonUniformBroadcastFirst %5 %61 %91\n%93 = OpImageTexelPointer %53 %19 %46 %36\n%94 = OpAtomicIAdd %5 %93 %46 %36 %92\n%95 = OpImageRead %50 %31 %9\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpGroupNonUniformBroadcastFirst %5 %61 %96\n%98 = OpImageTexelPointer %53 %19 %46 %36\n%99 = OpAtomicIAdd %5 %98 %46 %36 %97\n%100 = OpImageFetch %21 %32 %36\n%101 = OpCompositeExtract %13 %100 0\n%102 = OpGroupNonUniformBroadcastFirst %13 %61 %101\n%103 = OpConvertFToU %5 %102\n%104 = OpImageTexelPointer %53 %19 %46 %36\n%105 = OpAtomicIAdd %5 %104 %46 %36 %103\n%106 = OpImageTexelPointer %53 %19 %36 %36\n%107 = OpAtomicIAdd %5 %106 %46 %36 %45\n%108 = OpGroupNonUniformBroadcastFirst %5 %61 %42\n%109 = OpImageTexelPointer %53 %19 %46 %36\n%110 = OpAtomicIAdd %5 %109 %46 %36 %108\n%111 = OpAccessChain %47 %25 %36 %46\n%112 = OpLoad %21 %111\n%113 = OpBitcast %50 %112\n%114 = OpCompositeExtract %5 %113 0\n%115 = OpImageTexelPointer %53 %19 %36 %36\n%116 = OpAtomicIAdd %5 %115 %46 %36 %114\n%117 = OpAccessChain %47 %25 %36 %42\n%118 = OpLoad %21 %117\n%119 = OpBitcast %50 %118\n%120 = OpCompositeExtract %5 %119 0\n%121 = OpGroupNonUniformIAdd %5 %61 Reduce %120\n%122 = OpImageTexelPointer %53 %19 %36 %36\n%123 = OpAtomicIAdd %5 %122 %46 %36 %121\n%124 = OpAccessChain %47 %25 %36 %42\n%125 = OpLoad %21 %124\n%126 = OpBitcast %50 %125\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpGroupNonUniformBitwiseOr %5 %61 Reduce %127\n%129 = OpImageTexelPointer %53 %19 %36 %36\n%130 = OpAtomicIAdd %5 %129 %46 %36 %128\n%131 = OpAccessChain %47 %25 %36 %42\n%132 = OpLoad %21 %131\n%133 = OpBitcast %50 %132\n%134 = OpCompositeExtract %5 %133 0\n%136 = OpGroupNonUniformAllEqual %135 %61 %134\n%137 = OpSelect %5 %136 %46 %36\n%138 = OpImageTexelPointer %53 %19 %36 %36\n%139 = OpAtomicIAdd %5 %138 %46 %36 %137\n%140 = OpAccessChain %47 %25 %36 %42\n%141 = OpLoad %21 %140\n%142 = OpBitcast %50 %141\n%143 = OpCompositeExtract %5 %142 0\n%144 = OpINotEqual %135 %143 %36\n%145 = OpGroupNonUniformBallot %50 %61 %144\n%146 = OpCompositeExtract %5 %145 0\n%147 = OpImageTexelPointer %53 %19 %36 %36\n%148 = OpAtomicIAdd %5 %147 %46 %36 %146\n%149 = OpAccessChain %47 %25 %36 %42\n%150 = OpLoad %21 %149\n%151 = OpBitcast %50 %150\n%152 = OpCompositeExtract %5 %151 0\n%153 = OpINotEqual %135 %152 %36\n%154 = OpGroupNonUniformAny %135 %61 %153\n%155 = OpSelect %5 %154 %46 %36\n%156 = OpImageTexelPointer %53 %19 %36 %36\n%157 = OpAtomicIAdd %5 %156 %46 %36 %155\n%158 = OpAccessChain %47 %25 %36 %42\n%159 = OpLoad %21 %158\n%160 = OpBitcast %50 %159\n%161 = OpCompositeExtract %5 %160 0\n%162 = OpINotEqual %135 %161 %36\n%163 = OpGroupNonUniformAll %135 %61 %162\n%164 = OpSelect %5 %163 %46 %36\n%165 = OpImageTexelPointer %53 %19 %36 %36\n%166 = OpAtomicIAdd %5 %165 %46 %36 %164\n%167 = OpAccessChain %47 %25 %36 %42\n%168 = OpLoad %21 %167\n%169 = OpBitcast %50 %168\n%170 = OpCompositeExtract %5 %169 0\n%171 = OpGroupNonUniformIAdd %5 %61 ExclusiveScan %170\n%172 = OpGroupNonUniformBroadcastFirst %5 %61 %171\n%173 = OpImageTexelPointer %53 %19 %46 %36\n%174 = OpAtomicIAdd %5 %173 %46 %36 %172\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.no-legacy-cbuf-layout.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _23_25\n{\n    vec4 _m0[1024];\n} _25;\n\nlayout(set = 0, binding = 1, std140) uniform _27_30\n{\n    vec4 _m0[1024];\n} _30[2];\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _12[2];\nlayout(set = 0, binding = 3) uniform samplerBuffer _16;\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _19;\n\nvoid main()\n{\n    uint _55 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _63 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _70 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[1u]).x));\n    uint _77 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _82 = imageAtomicAdd(_19, int(0u), subgroupBroadcastFirst(texelFetch(_8, int(1u)).x));\n    uint _87 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_8, int(gl_GlobalInvocationID.x)).x));\n    uint _94 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_12[0u], int(1u)).x));\n    uint _99 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(imageLoad(_19, int(2u)).x));\n    uint _105 = imageAtomicAdd(_19, int(1u), uint(subgroupBroadcastFirst(texelFetch(_16, int(0u)).x)));\n    uint _107 = imageAtomicAdd(_19, int(0u), gl_WorkGroupID.x);\n    uint _110 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _116 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _123 = imageAtomicAdd(_19, int(0u), subgroupAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _130 = imageAtomicAdd(_19, int(0u), subgroupOr(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _139 = imageAtomicAdd(_19, int(0u), uint(subgroupAllEqual(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n    uint _148 = imageAtomicAdd(_19, int(0u), subgroupBallot(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _157 = imageAtomicAdd(_19, int(0u), uint(subgroupAny(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _166 = imageAtomicAdd(_19, int(0u), uint(subgroupAll(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _174 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 177\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %39 %43\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %23 \"\"\nOpName %27 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 3\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %22 ArrayStride 16\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 1\nOpDecorate %39 BuiltIn GlobalInvocationId\nOpDecorate %43 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 2\n%10 = OpTypeArray %6 %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpConstant %5 1024\n%21 = OpTypeVector %13 4\n%22 = OpTypeArray %21 %20\n%23 = OpTypeStruct %22\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypeArray %21 %20\n%27 = OpTypeStruct %26\n%28 = OpTypeArray %27 %9\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%34 = OpTypePointer Uniform %27\n%36 = OpConstant %5 0\n%37 = OpTypeVector %5 3\n%38 = OpTypePointer Input %37\n%39 = OpVariable %38 Input\n%40 = OpTypePointer Input %5\n%43 = OpVariable %38 Input\n%46 = OpConstant %5 1\n%47 = OpTypePointer Uniform %21\n%50 = OpTypeVector %5 4\n%53 = OpTypePointer Image %5\n%61 = OpConstant %5 3\n%135 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %175\n%175 = OpLabel\n%31 = OpLoad %17 %19\n%32 = OpLoad %14 %16\n%33 = OpLoad %6 %8\n%35 = OpAccessChain %34 %30 %36\n%41 = OpAccessChain %40 %39 %36\n%42 = OpLoad %5 %41\n%44 = OpAccessChain %40 %43 %36\n%45 = OpLoad %5 %44\n%48 = OpAccessChain %47 %25 %36 %46\n%49 = OpLoad %21 %48\n%51 = OpBitcast %50 %49\n%52 = OpCompositeExtract %5 %51 0\n%54 = OpImageTexelPointer %53 %19 %36 %36\n%55 = OpAtomicIAdd %5 %54 %46 %36 %52\n%56 = OpAccessChain %47 %25 %36 %42\n%57 = OpLoad %21 %56\n%58 = OpBitcast %50 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpGroupNonUniformBroadcastFirst %5 %61 %59\n%62 = OpImageTexelPointer %53 %19 %46 %36\n%63 = OpAtomicIAdd %5 %62 %46 %36 %60\n%64 = OpAccessChain %47 %35 %36 %46\n%65 = OpLoad %21 %64\n%66 = OpBitcast %50 %65\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpGroupNonUniformBroadcastFirst %5 %61 %67\n%69 = OpImageTexelPointer %53 %19 %46 %36\n%70 = OpAtomicIAdd %5 %69 %46 %36 %68\n%71 = OpAccessChain %47 %35 %36 %42\n%72 = OpLoad %21 %71\n%73 = OpBitcast %50 %72\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %5 %61 %74\n%76 = OpImageTexelPointer %53 %19 %46 %36\n%77 = OpAtomicIAdd %5 %76 %46 %36 %75\n%78 = OpImageFetch %50 %33 %46\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpGroupNonUniformBroadcastFirst %5 %61 %79\n%81 = OpImageTexelPointer %53 %19 %36 %36\n%82 = OpAtomicIAdd %5 %81 %46 %36 %80\n%83 = OpImageFetch %50 %33 %42\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpGroupNonUniformBroadcastFirst %5 %61 %84\n%86 = OpImageTexelPointer %53 %19 %46 %36\n%87 = OpAtomicIAdd %5 %86 %46 %36 %85\n%88 = OpAccessChain %7 %12 %36\n%89 = OpLoad %6 %88\n%90 = OpImageFetch %50 %89 %46\n%91 = OpCompositeExtract %5 %90 0\n%92 = OpGroupNonUniformBroadcastFirst %5 %61 %91\n%93 = OpImageTexelPointer %53 %19 %46 %36\n%94 = OpAtomicIAdd %5 %93 %46 %36 %92\n%95 = OpImageRead %50 %31 %9\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpGroupNonUniformBroadcastFirst %5 %61 %96\n%98 = OpImageTexelPointer %53 %19 %46 %36\n%99 = OpAtomicIAdd %5 %98 %46 %36 %97\n%100 = OpImageFetch %21 %32 %36\n%101 = OpCompositeExtract %13 %100 0\n%102 = OpGroupNonUniformBroadcastFirst %13 %61 %101\n%103 = OpConvertFToU %5 %102\n%104 = OpImageTexelPointer %53 %19 %46 %36\n%105 = OpAtomicIAdd %5 %104 %46 %36 %103\n%106 = OpImageTexelPointer %53 %19 %36 %36\n%107 = OpAtomicIAdd %5 %106 %46 %36 %45\n%108 = OpGroupNonUniformBroadcastFirst %5 %61 %42\n%109 = OpImageTexelPointer %53 %19 %46 %36\n%110 = OpAtomicIAdd %5 %109 %46 %36 %108\n%111 = OpAccessChain %47 %25 %36 %46\n%112 = OpLoad %21 %111\n%113 = OpBitcast %50 %112\n%114 = OpCompositeExtract %5 %113 0\n%115 = OpImageTexelPointer %53 %19 %36 %36\n%116 = OpAtomicIAdd %5 %115 %46 %36 %114\n%117 = OpAccessChain %47 %25 %36 %42\n%118 = OpLoad %21 %117\n%119 = OpBitcast %50 %118\n%120 = OpCompositeExtract %5 %119 0\n%121 = OpGroupNonUniformIAdd %5 %61 Reduce %120\n%122 = OpImageTexelPointer %53 %19 %36 %36\n%123 = OpAtomicIAdd %5 %122 %46 %36 %121\n%124 = OpAccessChain %47 %25 %36 %42\n%125 = OpLoad %21 %124\n%126 = OpBitcast %50 %125\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpGroupNonUniformBitwiseOr %5 %61 Reduce %127\n%129 = OpImageTexelPointer %53 %19 %36 %36\n%130 = OpAtomicIAdd %5 %129 %46 %36 %128\n%131 = OpAccessChain %47 %25 %36 %42\n%132 = OpLoad %21 %131\n%133 = OpBitcast %50 %132\n%134 = OpCompositeExtract %5 %133 0\n%136 = OpGroupNonUniformAllEqual %135 %61 %134\n%137 = OpSelect %5 %136 %46 %36\n%138 = OpImageTexelPointer %53 %19 %36 %36\n%139 = OpAtomicIAdd %5 %138 %46 %36 %137\n%140 = OpAccessChain %47 %25 %36 %42\n%141 = OpLoad %21 %140\n%142 = OpBitcast %50 %141\n%143 = OpCompositeExtract %5 %142 0\n%144 = OpINotEqual %135 %143 %36\n%145 = OpGroupNonUniformBallot %50 %61 %144\n%146 = OpCompositeExtract %5 %145 0\n%147 = OpImageTexelPointer %53 %19 %36 %36\n%148 = OpAtomicIAdd %5 %147 %46 %36 %146\n%149 = OpAccessChain %47 %25 %36 %42\n%150 = OpLoad %21 %149\n%151 = OpBitcast %50 %150\n%152 = OpCompositeExtract %5 %151 0\n%153 = OpINotEqual %135 %152 %36\n%154 = OpGroupNonUniformAny %135 %61 %153\n%155 = OpSelect %5 %154 %46 %36\n%156 = OpImageTexelPointer %53 %19 %36 %36\n%157 = OpAtomicIAdd %5 %156 %46 %36 %155\n%158 = OpAccessChain %47 %25 %36 %42\n%159 = OpLoad %21 %158\n%160 = OpBitcast %50 %159\n%161 = OpCompositeExtract %5 %160 0\n%162 = OpINotEqual %135 %161 %36\n%163 = OpGroupNonUniformAll %135 %61 %162\n%164 = OpSelect %5 %163 %46 %36\n%165 = OpImageTexelPointer %53 %19 %36 %36\n%166 = OpAtomicIAdd %5 %165 %46 %36 %164\n%167 = OpAccessChain %47 %25 %36 %42\n%168 = OpLoad %21 %167\n%169 = OpBitcast %50 %168\n%170 = OpCompositeExtract %5 %169 0\n%171 = OpGroupNonUniformIAdd %5 %61 ExclusiveScan %170\n%172 = OpGroupNonUniformBroadcastFirst %5 %61 %171\n%173 = OpImageTexelPointer %53 %19 %46 %36\n%174 = OpAtomicIAdd %5 %173 %46 %36 %172\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.no-legacy-cbuf-layout.sm60.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _23_25\n{\n    vec4 _m0[1024];\n} _25;\n\nlayout(set = 0, binding = 1, std140) uniform _27_30\n{\n    vec4 _m0[1024];\n} _30[2];\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _12[2];\nlayout(set = 0, binding = 3) uniform samplerBuffer _16;\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _19;\n\nvoid main()\n{\n    uint _55 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _63 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _70 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[1u]).x));\n    uint _77 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _82 = imageAtomicAdd(_19, int(0u), subgroupBroadcastFirst(texelFetch(_8, int(1u)).x));\n    uint _87 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_8, int(gl_GlobalInvocationID.x)).x));\n    uint _94 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_12[0u], int(1u)).x));\n    uint _99 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(imageLoad(_19, int(2u)).x));\n    uint _105 = imageAtomicAdd(_19, int(1u), uint(subgroupBroadcastFirst(texelFetch(_16, int(0u)).x)));\n    uint _107 = imageAtomicAdd(_19, int(0u), gl_WorkGroupID.x);\n    uint _110 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _116 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _123 = imageAtomicAdd(_19, int(0u), subgroupAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _130 = imageAtomicAdd(_19, int(0u), subgroupOr(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _139 = imageAtomicAdd(_19, int(0u), uint(subgroupAllEqual(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n    uint _148 = imageAtomicAdd(_19, int(0u), subgroupBallot(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _157 = imageAtomicAdd(_19, int(0u), uint(subgroupAny(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _166 = imageAtomicAdd(_19, int(0u), uint(subgroupAll(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _174 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 177\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %39 %43\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %23 \"\"\nOpName %27 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 3\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %22 ArrayStride 16\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 1\nOpDecorate %39 BuiltIn GlobalInvocationId\nOpDecorate %43 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 2\n%10 = OpTypeArray %6 %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpConstant %5 1024\n%21 = OpTypeVector %13 4\n%22 = OpTypeArray %21 %20\n%23 = OpTypeStruct %22\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypeArray %21 %20\n%27 = OpTypeStruct %26\n%28 = OpTypeArray %27 %9\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%34 = OpTypePointer Uniform %27\n%36 = OpConstant %5 0\n%37 = OpTypeVector %5 3\n%38 = OpTypePointer Input %37\n%39 = OpVariable %38 Input\n%40 = OpTypePointer Input %5\n%43 = OpVariable %38 Input\n%46 = OpConstant %5 1\n%47 = OpTypePointer Uniform %21\n%50 = OpTypeVector %5 4\n%53 = OpTypePointer Image %5\n%61 = OpConstant %5 3\n%135 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %175\n%175 = OpLabel\n%31 = OpLoad %17 %19\n%32 = OpLoad %14 %16\n%33 = OpLoad %6 %8\n%35 = OpAccessChain %34 %30 %36\n%41 = OpAccessChain %40 %39 %36\n%42 = OpLoad %5 %41\n%44 = OpAccessChain %40 %43 %36\n%45 = OpLoad %5 %44\n%48 = OpAccessChain %47 %25 %36 %46\n%49 = OpLoad %21 %48\n%51 = OpBitcast %50 %49\n%52 = OpCompositeExtract %5 %51 0\n%54 = OpImageTexelPointer %53 %19 %36 %36\n%55 = OpAtomicIAdd %5 %54 %46 %36 %52\n%56 = OpAccessChain %47 %25 %36 %42\n%57 = OpLoad %21 %56\n%58 = OpBitcast %50 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpGroupNonUniformBroadcastFirst %5 %61 %59\n%62 = OpImageTexelPointer %53 %19 %46 %36\n%63 = OpAtomicIAdd %5 %62 %46 %36 %60\n%64 = OpAccessChain %47 %35 %36 %46\n%65 = OpLoad %21 %64\n%66 = OpBitcast %50 %65\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpGroupNonUniformBroadcastFirst %5 %61 %67\n%69 = OpImageTexelPointer %53 %19 %46 %36\n%70 = OpAtomicIAdd %5 %69 %46 %36 %68\n%71 = OpAccessChain %47 %35 %36 %42\n%72 = OpLoad %21 %71\n%73 = OpBitcast %50 %72\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %5 %61 %74\n%76 = OpImageTexelPointer %53 %19 %46 %36\n%77 = OpAtomicIAdd %5 %76 %46 %36 %75\n%78 = OpImageFetch %50 %33 %46\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpGroupNonUniformBroadcastFirst %5 %61 %79\n%81 = OpImageTexelPointer %53 %19 %36 %36\n%82 = OpAtomicIAdd %5 %81 %46 %36 %80\n%83 = OpImageFetch %50 %33 %42\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpGroupNonUniformBroadcastFirst %5 %61 %84\n%86 = OpImageTexelPointer %53 %19 %46 %36\n%87 = OpAtomicIAdd %5 %86 %46 %36 %85\n%88 = OpAccessChain %7 %12 %36\n%89 = OpLoad %6 %88\n%90 = OpImageFetch %50 %89 %46\n%91 = OpCompositeExtract %5 %90 0\n%92 = OpGroupNonUniformBroadcastFirst %5 %61 %91\n%93 = OpImageTexelPointer %53 %19 %46 %36\n%94 = OpAtomicIAdd %5 %93 %46 %36 %92\n%95 = OpImageRead %50 %31 %9\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpGroupNonUniformBroadcastFirst %5 %61 %96\n%98 = OpImageTexelPointer %53 %19 %46 %36\n%99 = OpAtomicIAdd %5 %98 %46 %36 %97\n%100 = OpImageFetch %21 %32 %36\n%101 = OpCompositeExtract %13 %100 0\n%102 = OpGroupNonUniformBroadcastFirst %13 %61 %101\n%103 = OpConvertFToU %5 %102\n%104 = OpImageTexelPointer %53 %19 %46 %36\n%105 = OpAtomicIAdd %5 %104 %46 %36 %103\n%106 = OpImageTexelPointer %53 %19 %36 %36\n%107 = OpAtomicIAdd %5 %106 %46 %36 %45\n%108 = OpGroupNonUniformBroadcastFirst %5 %61 %42\n%109 = OpImageTexelPointer %53 %19 %46 %36\n%110 = OpAtomicIAdd %5 %109 %46 %36 %108\n%111 = OpAccessChain %47 %25 %36 %46\n%112 = OpLoad %21 %111\n%113 = OpBitcast %50 %112\n%114 = OpCompositeExtract %5 %113 0\n%115 = OpImageTexelPointer %53 %19 %36 %36\n%116 = OpAtomicIAdd %5 %115 %46 %36 %114\n%117 = OpAccessChain %47 %25 %36 %42\n%118 = OpLoad %21 %117\n%119 = OpBitcast %50 %118\n%120 = OpCompositeExtract %5 %119 0\n%121 = OpGroupNonUniformIAdd %5 %61 Reduce %120\n%122 = OpImageTexelPointer %53 %19 %36 %36\n%123 = OpAtomicIAdd %5 %122 %46 %36 %121\n%124 = OpAccessChain %47 %25 %36 %42\n%125 = OpLoad %21 %124\n%126 = OpBitcast %50 %125\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpGroupNonUniformBitwiseOr %5 %61 Reduce %127\n%129 = OpImageTexelPointer %53 %19 %36 %36\n%130 = OpAtomicIAdd %5 %129 %46 %36 %128\n%131 = OpAccessChain %47 %25 %36 %42\n%132 = OpLoad %21 %131\n%133 = OpBitcast %50 %132\n%134 = OpCompositeExtract %5 %133 0\n%136 = OpGroupNonUniformAllEqual %135 %61 %134\n%137 = OpSelect %5 %136 %46 %36\n%138 = OpImageTexelPointer %53 %19 %36 %36\n%139 = OpAtomicIAdd %5 %138 %46 %36 %137\n%140 = OpAccessChain %47 %25 %36 %42\n%141 = OpLoad %21 %140\n%142 = OpBitcast %50 %141\n%143 = OpCompositeExtract %5 %142 0\n%144 = OpINotEqual %135 %143 %36\n%145 = OpGroupNonUniformBallot %50 %61 %144\n%146 = OpCompositeExtract %5 %145 0\n%147 = OpImageTexelPointer %53 %19 %36 %36\n%148 = OpAtomicIAdd %5 %147 %46 %36 %146\n%149 = OpAccessChain %47 %25 %36 %42\n%150 = OpLoad %21 %149\n%151 = OpBitcast %50 %150\n%152 = OpCompositeExtract %5 %151 0\n%153 = OpINotEqual %135 %152 %36\n%154 = OpGroupNonUniformAny %135 %61 %153\n%155 = OpSelect %5 %154 %46 %36\n%156 = OpImageTexelPointer %53 %19 %36 %36\n%157 = OpAtomicIAdd %5 %156 %46 %36 %155\n%158 = OpAccessChain %47 %25 %36 %42\n%159 = OpLoad %21 %158\n%160 = OpBitcast %50 %159\n%161 = OpCompositeExtract %5 %160 0\n%162 = OpINotEqual %135 %161 %36\n%163 = OpGroupNonUniformAll %135 %61 %162\n%164 = OpSelect %5 %163 %46 %36\n%165 = OpImageTexelPointer %53 %19 %36 %36\n%166 = OpAtomicIAdd %5 %165 %46 %36 %164\n%167 = OpAccessChain %47 %25 %36 %42\n%168 = OpLoad %21 %167\n%169 = OpBitcast %50 %168\n%170 = OpCompositeExtract %5 %169 0\n%171 = OpGroupNonUniformIAdd %5 %61 ExclusiveScan %170\n%172 = OpGroupNonUniformBroadcastFirst %5 %61 %171\n%173 = OpImageTexelPointer %53 %19 %46 %36\n%174 = OpAtomicIAdd %5 %173 %46 %36 %172\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.sm60.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _23_25\n{\n    vec4 _m0[1024];\n} _25;\n\nlayout(set = 0, binding = 1, std140) uniform _27_30\n{\n    vec4 _m0[1024];\n} _30[2];\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _12[2];\nlayout(set = 0, binding = 3) uniform samplerBuffer _16;\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _19;\n\nvoid main()\n{\n    uint _55 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _63 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _70 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[1u]).x));\n    uint _77 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _82 = imageAtomicAdd(_19, int(0u), subgroupBroadcastFirst(texelFetch(_8, int(1u)).x));\n    uint _87 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_8, int(gl_GlobalInvocationID.x)).x));\n    uint _94 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_12[0u], int(1u)).x));\n    uint _99 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(imageLoad(_19, int(2u)).x));\n    uint _105 = imageAtomicAdd(_19, int(1u), uint(subgroupBroadcastFirst(texelFetch(_16, int(0u)).x)));\n    uint _107 = imageAtomicAdd(_19, int(0u), gl_WorkGroupID.x);\n    uint _110 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _116 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _123 = imageAtomicAdd(_19, int(0u), subgroupAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _130 = imageAtomicAdd(_19, int(0u), subgroupOr(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _139 = imageAtomicAdd(_19, int(0u), uint(subgroupAllEqual(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n    uint _148 = imageAtomicAdd(_19, int(0u), subgroupBallot(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _157 = imageAtomicAdd(_19, int(0u), uint(subgroupAny(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _166 = imageAtomicAdd(_19, int(0u), uint(subgroupAll(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _174 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 177\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %39 %43\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %23 \"\"\nOpName %27 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 3\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %22 ArrayStride 16\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 1\nOpDecorate %39 BuiltIn GlobalInvocationId\nOpDecorate %43 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 2\n%10 = OpTypeArray %6 %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpConstant %5 1024\n%21 = OpTypeVector %13 4\n%22 = OpTypeArray %21 %20\n%23 = OpTypeStruct %22\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypeArray %21 %20\n%27 = OpTypeStruct %26\n%28 = OpTypeArray %27 %9\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%34 = OpTypePointer Uniform %27\n%36 = OpConstant %5 0\n%37 = OpTypeVector %5 3\n%38 = OpTypePointer Input %37\n%39 = OpVariable %38 Input\n%40 = OpTypePointer Input %5\n%43 = OpVariable %38 Input\n%46 = OpConstant %5 1\n%47 = OpTypePointer Uniform %21\n%50 = OpTypeVector %5 4\n%53 = OpTypePointer Image %5\n%61 = OpConstant %5 3\n%135 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %175\n%175 = OpLabel\n%31 = OpLoad %17 %19\n%32 = OpLoad %14 %16\n%33 = OpLoad %6 %8\n%35 = OpAccessChain %34 %30 %36\n%41 = OpAccessChain %40 %39 %36\n%42 = OpLoad %5 %41\n%44 = OpAccessChain %40 %43 %36\n%45 = OpLoad %5 %44\n%48 = OpAccessChain %47 %25 %36 %46\n%49 = OpLoad %21 %48\n%51 = OpBitcast %50 %49\n%52 = OpCompositeExtract %5 %51 0\n%54 = OpImageTexelPointer %53 %19 %36 %36\n%55 = OpAtomicIAdd %5 %54 %46 %36 %52\n%56 = OpAccessChain %47 %25 %36 %42\n%57 = OpLoad %21 %56\n%58 = OpBitcast %50 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpGroupNonUniformBroadcastFirst %5 %61 %59\n%62 = OpImageTexelPointer %53 %19 %46 %36\n%63 = OpAtomicIAdd %5 %62 %46 %36 %60\n%64 = OpAccessChain %47 %35 %36 %46\n%65 = OpLoad %21 %64\n%66 = OpBitcast %50 %65\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpGroupNonUniformBroadcastFirst %5 %61 %67\n%69 = OpImageTexelPointer %53 %19 %46 %36\n%70 = OpAtomicIAdd %5 %69 %46 %36 %68\n%71 = OpAccessChain %47 %35 %36 %42\n%72 = OpLoad %21 %71\n%73 = OpBitcast %50 %72\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %5 %61 %74\n%76 = OpImageTexelPointer %53 %19 %46 %36\n%77 = OpAtomicIAdd %5 %76 %46 %36 %75\n%78 = OpImageFetch %50 %33 %46\n%79 = OpCompositeExtract %5 %78 0\n%80 = OpGroupNonUniformBroadcastFirst %5 %61 %79\n%81 = OpImageTexelPointer %53 %19 %36 %36\n%82 = OpAtomicIAdd %5 %81 %46 %36 %80\n%83 = OpImageFetch %50 %33 %42\n%84 = OpCompositeExtract %5 %83 0\n%85 = OpGroupNonUniformBroadcastFirst %5 %61 %84\n%86 = OpImageTexelPointer %53 %19 %46 %36\n%87 = OpAtomicIAdd %5 %86 %46 %36 %85\n%88 = OpAccessChain %7 %12 %36\n%89 = OpLoad %6 %88\n%90 = OpImageFetch %50 %89 %46\n%91 = OpCompositeExtract %5 %90 0\n%92 = OpGroupNonUniformBroadcastFirst %5 %61 %91\n%93 = OpImageTexelPointer %53 %19 %46 %36\n%94 = OpAtomicIAdd %5 %93 %46 %36 %92\n%95 = OpImageRead %50 %31 %9\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpGroupNonUniformBroadcastFirst %5 %61 %96\n%98 = OpImageTexelPointer %53 %19 %46 %36\n%99 = OpAtomicIAdd %5 %98 %46 %36 %97\n%100 = OpImageFetch %21 %32 %36\n%101 = OpCompositeExtract %13 %100 0\n%102 = OpGroupNonUniformBroadcastFirst %13 %61 %101\n%103 = OpConvertFToU %5 %102\n%104 = OpImageTexelPointer %53 %19 %46 %36\n%105 = OpAtomicIAdd %5 %104 %46 %36 %103\n%106 = OpImageTexelPointer %53 %19 %36 %36\n%107 = OpAtomicIAdd %5 %106 %46 %36 %45\n%108 = OpGroupNonUniformBroadcastFirst %5 %61 %42\n%109 = OpImageTexelPointer %53 %19 %46 %36\n%110 = OpAtomicIAdd %5 %109 %46 %36 %108\n%111 = OpAccessChain %47 %25 %36 %46\n%112 = OpLoad %21 %111\n%113 = OpBitcast %50 %112\n%114 = OpCompositeExtract %5 %113 0\n%115 = OpImageTexelPointer %53 %19 %36 %36\n%116 = OpAtomicIAdd %5 %115 %46 %36 %114\n%117 = OpAccessChain %47 %25 %36 %42\n%118 = OpLoad %21 %117\n%119 = OpBitcast %50 %118\n%120 = OpCompositeExtract %5 %119 0\n%121 = OpGroupNonUniformIAdd %5 %61 Reduce %120\n%122 = OpImageTexelPointer %53 %19 %36 %36\n%123 = OpAtomicIAdd %5 %122 %46 %36 %121\n%124 = OpAccessChain %47 %25 %36 %42\n%125 = OpLoad %21 %124\n%126 = OpBitcast %50 %125\n%127 = OpCompositeExtract %5 %126 0\n%128 = OpGroupNonUniformBitwiseOr %5 %61 Reduce %127\n%129 = OpImageTexelPointer %53 %19 %36 %36\n%130 = OpAtomicIAdd %5 %129 %46 %36 %128\n%131 = OpAccessChain %47 %25 %36 %42\n%132 = OpLoad %21 %131\n%133 = OpBitcast %50 %132\n%134 = OpCompositeExtract %5 %133 0\n%136 = OpGroupNonUniformAllEqual %135 %61 %134\n%137 = OpSelect %5 %136 %46 %36\n%138 = OpImageTexelPointer %53 %19 %36 %36\n%139 = OpAtomicIAdd %5 %138 %46 %36 %137\n%140 = OpAccessChain %47 %25 %36 %42\n%141 = OpLoad %21 %140\n%142 = OpBitcast %50 %141\n%143 = OpCompositeExtract %5 %142 0\n%144 = OpINotEqual %135 %143 %36\n%145 = OpGroupNonUniformBallot %50 %61 %144\n%146 = OpCompositeExtract %5 %145 0\n%147 = OpImageTexelPointer %53 %19 %36 %36\n%148 = OpAtomicIAdd %5 %147 %46 %36 %146\n%149 = OpAccessChain %47 %25 %36 %42\n%150 = OpLoad %21 %149\n%151 = OpBitcast %50 %150\n%152 = OpCompositeExtract %5 %151 0\n%153 = OpINotEqual %135 %152 %36\n%154 = OpGroupNonUniformAny %135 %61 %153\n%155 = OpSelect %5 %154 %46 %36\n%156 = OpImageTexelPointer %53 %19 %36 %36\n%157 = OpAtomicIAdd %5 %156 %46 %36 %155\n%158 = OpAccessChain %47 %25 %36 %42\n%159 = OpLoad %21 %158\n%160 = OpBitcast %50 %159\n%161 = OpCompositeExtract %5 %160 0\n%162 = OpINotEqual %135 %161 %36\n%163 = OpGroupNonUniformAll %135 %61 %162\n%164 = OpSelect %5 %163 %46 %36\n%165 = OpImageTexelPointer %53 %19 %36 %36\n%166 = OpAtomicIAdd %5 %165 %46 %36 %164\n%167 = OpAccessChain %47 %25 %36 %42\n%168 = OpLoad %21 %167\n%169 = OpBitcast %50 %168\n%170 = OpCompositeExtract %5 %169 0\n%171 = OpGroupNonUniformIAdd %5 %61 ExclusiveScan %170\n%172 = OpGroupNonUniformBroadcastFirst %5 %61 %171\n%173 = OpImageTexelPointer %53 %19 %46 %36\n%174 = OpAtomicIAdd %5 %173 %46 %36 %172\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.sm66.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std140) uniform _23_25\n{\n    vec4 _m0[1024];\n} _25;\n\nlayout(set = 0, binding = 1, std140) uniform _27_30\n{\n    vec4 _m0[1024];\n} _30[2];\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _12[2];\nlayout(set = 0, binding = 3) uniform samplerBuffer _16;\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _19;\n\nvoid main()\n{\n    uint _53 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _62 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _70 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[1u]).x));\n    uint _78 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(floatBitsToUint(_30[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _85 = imageAtomicAdd(_19, int(0u), subgroupBroadcastFirst(texelFetch(_8, int(1u)).x));\n    uint _92 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_8, int(gl_GlobalInvocationID.x)).x));\n    uint _100 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(texelFetch(_12[0u], int(1u)).x));\n    uint _107 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(imageLoad(_19, int(2u)).x));\n    uint _115 = imageAtomicAdd(_19, int(1u), uint(subgroupBroadcastFirst(texelFetch(_16, int(0u)).x)));\n    uint _118 = imageAtomicAdd(_19, int(0u), gl_WorkGroupID.x);\n    uint _122 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _129 = imageAtomicAdd(_19, int(0u), floatBitsToUint(_25._m0[1u]).x);\n    uint _137 = imageAtomicAdd(_19, int(0u), subgroupAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _145 = imageAtomicAdd(_19, int(0u), subgroupOr(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x));\n    uint _155 = imageAtomicAdd(_19, int(0u), uint(subgroupAllEqual(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n    uint _165 = imageAtomicAdd(_19, int(0u), subgroupBallot(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _175 = imageAtomicAdd(_19, int(0u), uint(subgroupAny(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _185 = imageAtomicAdd(_19, int(0u), uint(subgroupAll(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _194 = imageAtomicAdd(_19, int(1u), subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_25._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 197\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %36 %40\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %23 \"\"\nOpName %27 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 3\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %22 ArrayStride 16\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 1\nOpDecorate %36 BuiltIn GlobalInvocationId\nOpDecorate %40 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 2\n%10 = OpTypeArray %6 %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpConstant %5 1024\n%21 = OpTypeVector %13 4\n%22 = OpTypeArray %21 %20\n%23 = OpTypeStruct %22\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypeArray %21 %20\n%27 = OpTypeStruct %26\n%28 = OpTypeArray %27 %9\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%31 = OpTypePointer Uniform %27\n%33 = OpConstant %5 0\n%34 = OpTypeVector %5 3\n%35 = OpTypePointer Input %34\n%36 = OpVariable %35 Input\n%37 = OpTypePointer Input %5\n%40 = OpVariable %35 Input\n%43 = OpConstant %5 1\n%44 = OpTypePointer Uniform %21\n%47 = OpTypeVector %5 4\n%51 = OpTypePointer Image %5\n%59 = OpConstant %5 3\n%150 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %195\n%195 = OpLabel\n%32 = OpAccessChain %31 %30 %33\n%38 = OpAccessChain %37 %36 %33\n%39 = OpLoad %5 %38\n%41 = OpAccessChain %37 %40 %33\n%42 = OpLoad %5 %41\n%45 = OpAccessChain %44 %25 %33 %43\n%46 = OpLoad %21 %45\n%48 = OpBitcast %47 %46\n%49 = OpCompositeExtract %5 %48 0\n%50 = OpLoad %17 %19\n%52 = OpImageTexelPointer %51 %19 %33 %33\n%53 = OpAtomicIAdd %5 %52 %43 %33 %49\n%54 = OpAccessChain %44 %25 %33 %39\n%55 = OpLoad %21 %54\n%56 = OpBitcast %47 %55\n%57 = OpCompositeExtract %5 %56 0\n%58 = OpGroupNonUniformBroadcastFirst %5 %59 %57\n%60 = OpLoad %17 %19\n%61 = OpImageTexelPointer %51 %19 %43 %33\n%62 = OpAtomicIAdd %5 %61 %43 %33 %58\n%63 = OpAccessChain %44 %32 %33 %43\n%64 = OpLoad %21 %63\n%65 = OpBitcast %47 %64\n%66 = OpCompositeExtract %5 %65 0\n%67 = OpGroupNonUniformBroadcastFirst %5 %59 %66\n%68 = OpLoad %17 %19\n%69 = OpImageTexelPointer %51 %19 %43 %33\n%70 = OpAtomicIAdd %5 %69 %43 %33 %67\n%71 = OpAccessChain %44 %32 %33 %39\n%72 = OpLoad %21 %71\n%73 = OpBitcast %47 %72\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %5 %59 %74\n%76 = OpLoad %17 %19\n%77 = OpImageTexelPointer %51 %19 %43 %33\n%78 = OpAtomicIAdd %5 %77 %43 %33 %75\n%79 = OpLoad %6 %8\n%80 = OpImageFetch %47 %79 %43\n%81 = OpCompositeExtract %5 %80 0\n%82 = OpGroupNonUniformBroadcastFirst %5 %59 %81\n%83 = OpLoad %17 %19\n%84 = OpImageTexelPointer %51 %19 %33 %33\n%85 = OpAtomicIAdd %5 %84 %43 %33 %82\n%86 = OpLoad %6 %8\n%87 = OpImageFetch %47 %86 %39\n%88 = OpCompositeExtract %5 %87 0\n%89 = OpGroupNonUniformBroadcastFirst %5 %59 %88\n%90 = OpLoad %17 %19\n%91 = OpImageTexelPointer %51 %19 %43 %33\n%92 = OpAtomicIAdd %5 %91 %43 %33 %89\n%93 = OpAccessChain %7 %12 %33\n%94 = OpLoad %6 %93\n%95 = OpImageFetch %47 %94 %43\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpGroupNonUniformBroadcastFirst %5 %59 %96\n%98 = OpLoad %17 %19\n%99 = OpImageTexelPointer %51 %19 %43 %33\n%100 = OpAtomicIAdd %5 %99 %43 %33 %97\n%101 = OpLoad %17 %19\n%102 = OpImageRead %47 %101 %9\n%103 = OpCompositeExtract %5 %102 0\n%104 = OpGroupNonUniformBroadcastFirst %5 %59 %103\n%105 = OpLoad %17 %19\n%106 = OpImageTexelPointer %51 %19 %43 %33\n%107 = OpAtomicIAdd %5 %106 %43 %33 %104\n%108 = OpLoad %14 %16\n%109 = OpImageFetch %21 %108 %33\n%110 = OpCompositeExtract %13 %109 0\n%111 = OpGroupNonUniformBroadcastFirst %13 %59 %110\n%112 = OpConvertFToU %5 %111\n%113 = OpLoad %17 %19\n%114 = OpImageTexelPointer %51 %19 %43 %33\n%115 = OpAtomicIAdd %5 %114 %43 %33 %112\n%116 = OpLoad %17 %19\n%117 = OpImageTexelPointer %51 %19 %33 %33\n%118 = OpAtomicIAdd %5 %117 %43 %33 %42\n%119 = OpGroupNonUniformBroadcastFirst %5 %59 %39\n%120 = OpLoad %17 %19\n%121 = OpImageTexelPointer %51 %19 %43 %33\n%122 = OpAtomicIAdd %5 %121 %43 %33 %119\n%123 = OpAccessChain %44 %25 %33 %43\n%124 = OpLoad %21 %123\n%125 = OpBitcast %47 %124\n%126 = OpCompositeExtract %5 %125 0\n%127 = OpLoad %17 %19\n%128 = OpImageTexelPointer %51 %19 %33 %33\n%129 = OpAtomicIAdd %5 %128 %43 %33 %126\n%130 = OpAccessChain %44 %25 %33 %39\n%131 = OpLoad %21 %130\n%132 = OpBitcast %47 %131\n%133 = OpCompositeExtract %5 %132 0\n%134 = OpGroupNonUniformIAdd %5 %59 Reduce %133\n%135 = OpLoad %17 %19\n%136 = OpImageTexelPointer %51 %19 %33 %33\n%137 = OpAtomicIAdd %5 %136 %43 %33 %134\n%138 = OpAccessChain %44 %25 %33 %39\n%139 = OpLoad %21 %138\n%140 = OpBitcast %47 %139\n%141 = OpCompositeExtract %5 %140 0\n%142 = OpGroupNonUniformBitwiseOr %5 %59 Reduce %141\n%143 = OpLoad %17 %19\n%144 = OpImageTexelPointer %51 %19 %33 %33\n%145 = OpAtomicIAdd %5 %144 %43 %33 %142\n%146 = OpAccessChain %44 %25 %33 %39\n%147 = OpLoad %21 %146\n%148 = OpBitcast %47 %147\n%149 = OpCompositeExtract %5 %148 0\n%151 = OpGroupNonUniformAllEqual %150 %59 %149\n%152 = OpSelect %5 %151 %43 %33\n%153 = OpLoad %17 %19\n%154 = OpImageTexelPointer %51 %19 %33 %33\n%155 = OpAtomicIAdd %5 %154 %43 %33 %152\n%156 = OpAccessChain %44 %25 %33 %39\n%157 = OpLoad %21 %156\n%158 = OpBitcast %47 %157\n%159 = OpCompositeExtract %5 %158 0\n%160 = OpINotEqual %150 %159 %33\n%161 = OpGroupNonUniformBallot %47 %59 %160\n%162 = OpCompositeExtract %5 %161 0\n%163 = OpLoad %17 %19\n%164 = OpImageTexelPointer %51 %19 %33 %33\n%165 = OpAtomicIAdd %5 %164 %43 %33 %162\n%166 = OpAccessChain %44 %25 %33 %39\n%167 = OpLoad %21 %166\n%168 = OpBitcast %47 %167\n%169 = OpCompositeExtract %5 %168 0\n%170 = OpINotEqual %150 %169 %33\n%171 = OpGroupNonUniformAny %150 %59 %170\n%172 = OpSelect %5 %171 %43 %33\n%173 = OpLoad %17 %19\n%174 = OpImageTexelPointer %51 %19 %33 %33\n%175 = OpAtomicIAdd %5 %174 %43 %33 %172\n%176 = OpAccessChain %44 %25 %33 %39\n%177 = OpLoad %21 %176\n%178 = OpBitcast %47 %177\n%179 = OpCompositeExtract %5 %178 0\n%180 = OpINotEqual %150 %179 %33\n%181 = OpGroupNonUniformAll %150 %59 %180\n%182 = OpSelect %5 %181 %43 %33\n%183 = OpLoad %17 %19\n%184 = OpImageTexelPointer %51 %19 %33 %33\n%185 = OpAtomicIAdd %5 %184 %43 %33 %182\n%186 = OpAccessChain %44 %25 %33 %39\n%187 = OpLoad %21 %186\n%188 = OpBitcast %47 %187\n%189 = OpCompositeExtract %5 %188 0\n%190 = OpGroupNonUniformIAdd %5 %59 ExclusiveScan %189\n%191 = OpGroupNonUniformBroadcastFirst %5 %59 %190\n%192 = OpLoad %17 %19\n%193 = OpImageTexelPointer %51 %19 %43 %33\n%194 = OpAtomicIAdd %5 %193 %43 %33 %191\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.ssbo.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _12_14\n{\n    uvec2 _m0[];\n} _14;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _16_20\n{\n    uint _m0[];\n} _20[2];\n\nlayout(set = 0, binding = 4, std430) restrict readonly buffer _26_28\n{\n    uint _m0[];\n} _28;\n\nlayout(set = 0, binding = 0, std430) buffer _30_32\n{\n    uint _m0[];\n} _32;\n\nlayout(set = 0, binding = 0, std140) uniform _36_38\n{\n    vec4 _m0[1024];\n} _38;\n\nlayout(set = 0, binding = 1, std140) uniform _40_43\n{\n    vec4 _m0[1024];\n} _43[2];\n\nlayout(set = 0, binding = 3) uniform samplerBuffer _24;\n\nvoid main()\n{\n    uint _66 = atomicAdd(_32._m0[0u], floatBitsToUint(_38._m0[1u]).x);\n    uint _74 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x));\n    uint _81 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_43[0u]._m0[1u]).x));\n    uint _88 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_43[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _92 = atomicAdd(_32._m0[0u], _9._m0[2u]);\n    uint _96 = atomicAdd(_32._m0[0u], _28._m0[0u]);\n    uint _103 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(_14._m0[gl_GlobalInvocationID.x].y));\n    uint _107 = 1u * 2u;\n    uint _114 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(_9._m0[_107 + (((gl_GlobalInvocationID.x << 2u) & 4u) >> 2u)]));\n    uint _121 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(_20[0u]._m0[1u]));\n    uint _126 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(_28._m0[gl_GlobalInvocationID.x]));\n    uint _131 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(_32._m0[2u]));\n    uint _137 = atomicAdd(_32._m0[1u], uint(subgroupBroadcastFirst(texelFetch(_24, int(0u)).x)));\n    uint _139 = atomicAdd(_32._m0[0u], gl_WorkGroupID.x);\n    uint _142 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _148 = atomicAdd(_32._m0[0u], floatBitsToUint(_38._m0[1u]).x);\n    uint _155 = atomicAdd(_32._m0[0u], subgroupAdd(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x));\n    uint _162 = atomicAdd(_32._m0[0u], subgroupOr(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x));\n    uint _171 = atomicAdd(_32._m0[0u], uint(subgroupAllEqual(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x)));\n    uint _180 = atomicAdd(_32._m0[0u], subgroupBallot(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _189 = atomicAdd(_32._m0[0u], uint(subgroupAny(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _198 = atomicAdd(_32._m0[0u], uint(subgroupAll(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _206 = atomicAdd(_32._m0[1u], subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_38._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 209\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %50 %54\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %30 \"SSBO\"\nOpName %36 \"\"\nOpName %40 \"\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 4\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 3\nOpDecorate %25 ArrayStride 4\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 4\nOpDecorate %28 NonWritable\nOpDecorate %28 Restrict\nOpDecorate %29 ArrayStride 4\nOpMemberDecorate %30 0 Offset 0\nOpDecorate %30 Block\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 0\nOpDecorate %35 ArrayStride 16\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 0\nOpDecorate %39 ArrayStride 16\nOpMemberDecorate %40 0 Offset 0\nOpDecorate %40 Block\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 1\nOpDecorate %50 BuiltIn GlobalInvocationId\nOpDecorate %54 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %5\n%16 = OpTypeStruct %15\n%17 = OpConstant %5 2\n%18 = OpTypeArray %16 %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeFloat 32\n%22 = OpTypeImage %21 Buffer 0 0 0 1 Unknown\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeRuntimeArray %5\n%26 = OpTypeStruct %25\n%27 = OpTypePointer StorageBuffer %26\n%28 = OpVariable %27 StorageBuffer\n%29 = OpTypeRuntimeArray %5\n%30 = OpTypeStruct %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpConstant %5 1024\n%34 = OpTypeVector %21 4\n%35 = OpTypeArray %34 %33\n%36 = OpTypeStruct %35\n%37 = OpTypePointer Uniform %36\n%38 = OpVariable %37 Uniform\n%39 = OpTypeArray %34 %33\n%40 = OpTypeStruct %39\n%41 = OpTypeArray %40 %17\n%42 = OpTypePointer Uniform %41\n%43 = OpVariable %42 Uniform\n%45 = OpTypePointer Uniform %40\n%47 = OpConstant %5 0\n%48 = OpTypeVector %5 3\n%49 = OpTypePointer Input %48\n%50 = OpVariable %49 Input\n%51 = OpTypePointer Input %5\n%54 = OpVariable %49 Input\n%57 = OpConstant %5 1\n%58 = OpTypePointer Uniform %34\n%61 = OpTypeVector %5 4\n%64 = OpTypePointer StorageBuffer %5\n%72 = OpConstant %5 3\n%97 = OpTypePointer StorageBuffer %10\n%106 = OpConstant %5 4\n%115 = OpTypePointer StorageBuffer %16\n%167 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %207\n%207 = OpLabel\n%44 = OpLoad %22 %24\n%46 = OpAccessChain %45 %43 %47\n%52 = OpAccessChain %51 %50 %47\n%53 = OpLoad %5 %52\n%55 = OpAccessChain %51 %54 %47\n%56 = OpLoad %5 %55\n%59 = OpAccessChain %58 %38 %47 %57\n%60 = OpLoad %34 %59\n%62 = OpBitcast %61 %60\n%63 = OpCompositeExtract %5 %62 0\n%65 = OpAccessChain %64 %32 %47 %47\n%66 = OpAtomicIAdd %5 %65 %57 %47 %63\n%67 = OpAccessChain %58 %38 %47 %53\n%68 = OpLoad %34 %67\n%69 = OpBitcast %61 %68\n%70 = OpCompositeExtract %5 %69 0\n%71 = OpGroupNonUniformBroadcastFirst %5 %72 %70\n%73 = OpAccessChain %64 %32 %47 %57\n%74 = OpAtomicIAdd %5 %73 %57 %47 %71\n%75 = OpAccessChain %58 %46 %47 %57\n%76 = OpLoad %34 %75\n%77 = OpBitcast %61 %76\n%78 = OpCompositeExtract %5 %77 0\n%79 = OpGroupNonUniformBroadcastFirst %5 %72 %78\n%80 = OpAccessChain %64 %32 %47 %57\n%81 = OpAtomicIAdd %5 %80 %57 %47 %79\n%82 = OpAccessChain %58 %46 %47 %53\n%83 = OpLoad %34 %82\n%84 = OpBitcast %61 %83\n%85 = OpCompositeExtract %5 %84 0\n%86 = OpGroupNonUniformBroadcastFirst %5 %72 %85\n%87 = OpAccessChain %64 %32 %47 %57\n%88 = OpAtomicIAdd %5 %87 %57 %47 %86\n%89 = OpAccessChain %64 %9 %47 %17\n%90 = OpLoad %5 %89\n%91 = OpAccessChain %64 %32 %47 %47\n%92 = OpAtomicIAdd %5 %91 %57 %47 %90\n%93 = OpAccessChain %64 %28 %47 %47\n%94 = OpLoad %5 %93\n%95 = OpAccessChain %64 %32 %47 %47\n%96 = OpAtomicIAdd %5 %95 %57 %47 %94\n%98 = OpAccessChain %97 %14 %47 %53\n%99 = OpLoad %10 %98\n%100 = OpCompositeExtract %5 %99 1\n%101 = OpGroupNonUniformBroadcastFirst %5 %72 %100\n%102 = OpAccessChain %64 %32 %47 %57\n%103 = OpAtomicIAdd %5 %102 %57 %47 %101\n%104 = OpShiftLeftLogical %5 %53 %17\n%105 = OpBitwiseAnd %5 %104 %106\n%107 = OpIMul %5 %57 %17\n%108 = OpShiftRightLogical %5 %105 %17\n%109 = OpIAdd %5 %107 %108\n%110 = OpAccessChain %64 %9 %47 %109\n%111 = OpLoad %5 %110\n%112 = OpGroupNonUniformBroadcastFirst %5 %72 %111\n%113 = OpAccessChain %64 %32 %47 %57\n%114 = OpAtomicIAdd %5 %113 %57 %47 %112\n%116 = OpAccessChain %115 %20 %47\n%117 = OpAccessChain %64 %116 %47 %57\n%118 = OpLoad %5 %117\n%119 = OpGroupNonUniformBroadcastFirst %5 %72 %118\n%120 = OpAccessChain %64 %32 %47 %57\n%121 = OpAtomicIAdd %5 %120 %57 %47 %119\n%122 = OpAccessChain %64 %28 %47 %53\n%123 = OpLoad %5 %122\n%124 = OpGroupNonUniformBroadcastFirst %5 %72 %123\n%125 = OpAccessChain %64 %32 %47 %57\n%126 = OpAtomicIAdd %5 %125 %57 %47 %124\n%127 = OpAccessChain %64 %32 %47 %17\n%128 = OpLoad %5 %127\n%129 = OpGroupNonUniformBroadcastFirst %5 %72 %128\n%130 = OpAccessChain %64 %32 %47 %57\n%131 = OpAtomicIAdd %5 %130 %57 %47 %129\n%132 = OpImageFetch %34 %44 %47\n%133 = OpCompositeExtract %21 %132 0\n%134 = OpGroupNonUniformBroadcastFirst %21 %72 %133\n%135 = OpConvertFToU %5 %134\n%136 = OpAccessChain %64 %32 %47 %57\n%137 = OpAtomicIAdd %5 %136 %57 %47 %135\n%138 = OpAccessChain %64 %32 %47 %47\n%139 = OpAtomicIAdd %5 %138 %57 %47 %56\n%140 = OpGroupNonUniformBroadcastFirst %5 %72 %53\n%141 = OpAccessChain %64 %32 %47 %57\n%142 = OpAtomicIAdd %5 %141 %57 %47 %140\n%143 = OpAccessChain %58 %38 %47 %57\n%144 = OpLoad %34 %143\n%145 = OpBitcast %61 %144\n%146 = OpCompositeExtract %5 %145 0\n%147 = OpAccessChain %64 %32 %47 %47\n%148 = OpAtomicIAdd %5 %147 %57 %47 %146\n%149 = OpAccessChain %58 %38 %47 %53\n%150 = OpLoad %34 %149\n%151 = OpBitcast %61 %150\n%152 = OpCompositeExtract %5 %151 0\n%153 = OpGroupNonUniformIAdd %5 %72 Reduce %152\n%154 = OpAccessChain %64 %32 %47 %47\n%155 = OpAtomicIAdd %5 %154 %57 %47 %153\n%156 = OpAccessChain %58 %38 %47 %53\n%157 = OpLoad %34 %156\n%158 = OpBitcast %61 %157\n%159 = OpCompositeExtract %5 %158 0\n%160 = OpGroupNonUniformBitwiseOr %5 %72 Reduce %159\n%161 = OpAccessChain %64 %32 %47 %47\n%162 = OpAtomicIAdd %5 %161 %57 %47 %160\n%163 = OpAccessChain %58 %38 %47 %53\n%164 = OpLoad %34 %163\n%165 = OpBitcast %61 %164\n%166 = OpCompositeExtract %5 %165 0\n%168 = OpGroupNonUniformAllEqual %167 %72 %166\n%169 = OpSelect %5 %168 %57 %47\n%170 = OpAccessChain %64 %32 %47 %47\n%171 = OpAtomicIAdd %5 %170 %57 %47 %169\n%172 = OpAccessChain %58 %38 %47 %53\n%173 = OpLoad %34 %172\n%174 = OpBitcast %61 %173\n%175 = OpCompositeExtract %5 %174 0\n%176 = OpINotEqual %167 %175 %47\n%177 = OpGroupNonUniformBallot %61 %72 %176\n%178 = OpCompositeExtract %5 %177 0\n%179 = OpAccessChain %64 %32 %47 %47\n%180 = OpAtomicIAdd %5 %179 %57 %47 %178\n%181 = OpAccessChain %58 %38 %47 %53\n%182 = OpLoad %34 %181\n%183 = OpBitcast %61 %182\n%184 = OpCompositeExtract %5 %183 0\n%185 = OpINotEqual %167 %184 %47\n%186 = OpGroupNonUniformAny %167 %72 %185\n%187 = OpSelect %5 %186 %57 %47\n%188 = OpAccessChain %64 %32 %47 %47\n%189 = OpAtomicIAdd %5 %188 %57 %47 %187\n%190 = OpAccessChain %58 %38 %47 %53\n%191 = OpLoad %34 %190\n%192 = OpBitcast %61 %191\n%193 = OpCompositeExtract %5 %192 0\n%194 = OpINotEqual %167 %193 %47\n%195 = OpGroupNonUniformAll %167 %72 %194\n%196 = OpSelect %5 %195 %57 %47\n%197 = OpAccessChain %64 %32 %47 %47\n%198 = OpAtomicIAdd %5 %197 %57 %47 %196\n%199 = OpAccessChain %58 %38 %47 %53\n%200 = OpLoad %34 %199\n%201 = OpBitcast %61 %200\n%202 = OpCompositeExtract %5 %201 0\n%203 = OpGroupNonUniformIAdd %5 %72 ExclusiveScan %202\n%204 = OpGroupNonUniformBroadcastFirst %5 %72 %203\n%205 = OpAccessChain %64 %32 %47 %57\n%206 = OpAtomicIAdd %5 %205 %57 %47 %204\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.ssbo.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer TSSBO\n{\n    uint _m0[];\n} T;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer T_1\n{\n    uvec2 _m0[];\n} T_2;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer TsSSBO\n{\n    uint _m0[];\n} Ts[2];\n\nlayout(set = 0, binding = 4, std430) restrict readonly buffer TBSSBO\n{\n    uint _m0[];\n} TB;\n\nlayout(set = 0, binding = 0, std430) buffer USSBO\n{\n    uint _m0[];\n} U;\n\nlayout(set = 0, binding = 0, std140) uniform CUBO\n{\n    vec4 _m0[1024];\n} C;\n\nlayout(set = 0, binding = 1, std140) uniform CsUBO\n{\n    vec4 _m0[1024];\n} Cs[2];\n\nlayout(set = 0, binding = 3) uniform samplerBuffer B;\n\nvoid main()\n{\n    uint _62 = atomicAdd(U._m0[0u], floatBitsToUint(C._m0[1u]).x);\n    uint _70 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x));\n    uint _77 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(floatBitsToUint(Cs[0u]._m0[1u]).x));\n    uint _84 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(floatBitsToUint(Cs[0u]._m0[gl_LaunchIDEXT.x]).x));\n    uint _88 = atomicAdd(U._m0[0u], T._m0[2u]);\n    uint _92 = atomicAdd(U._m0[0u], TB._m0[0u]);\n    uint _99 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(T_2._m0[gl_LaunchIDEXT.x].y));\n    uint _103 = 1u * 2u;\n    uint _110 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(T._m0[_103 + (((gl_LaunchIDEXT.x << 2u) & 4u) >> 2u)]));\n    uint _117 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(Ts[0u]._m0[1u]));\n    uint _122 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(TB._m0[gl_LaunchIDEXT.x]));\n    uint _127 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(U._m0[2u]));\n    uint _134 = atomicAdd(U._m0[1u], uint(subgroupBroadcastFirst(texelFetch(B, int(0u)).x)));\n    uint _140 = atomicAdd(U._m0[0u], floatBitsToUint(C._m0[1u]).x);\n    uint _147 = atomicAdd(U._m0[0u], subgroupAdd(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x));\n    uint _154 = atomicAdd(U._m0[0u], subgroupOr(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x));\n    uint _163 = atomicAdd(U._m0[0u], uint(subgroupAllEqual(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x)));\n    uint _172 = atomicAdd(U._m0[0u], subgroupBallot(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x != 0u).x);\n    uint _181 = atomicAdd(U._m0[0u], uint(subgroupAny(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x != 0u)));\n    uint _190 = atomicAdd(U._m0[0u], uint(subgroupAll(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x != 0u)));\n    uint _198 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 201\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %9 %14 %20 %24 %28 %32 %38 %43 %49\nOpName %3 \"main\"\nOpName %7 \"TSSBO\"\nOpName %9 \"T\"\nOpName %12 \"TSSBO\"\nOpName %14 \"T\"\nOpName %16 \"TsSSBO\"\nOpName %20 \"Ts\"\nOpName %24 \"B\"\nOpName %26 \"TBSSBO\"\nOpName %28 \"TB\"\nOpName %30 \"USSBO\"\nOpName %32 \"U\"\nOpName %36 \"CUBO\"\nOpName %38 \"C\"\nOpName %40 \"CsUBO\"\nOpName %43 \"Cs\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 4\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 3\nOpDecorate %25 ArrayStride 4\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 4\nOpDecorate %28 NonWritable\nOpDecorate %28 Restrict\nOpDecorate %29 ArrayStride 4\nOpMemberDecorate %30 0 Offset 0\nOpDecorate %30 Block\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 0\nOpDecorate %35 ArrayStride 16\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 0\nOpDecorate %39 ArrayStride 16\nOpMemberDecorate %40 0 Offset 0\nOpDecorate %40 Block\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 1\nOpDecorate %49 BuiltIn LaunchIdKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %5\n%16 = OpTypeStruct %15\n%17 = OpConstant %5 2\n%18 = OpTypeArray %16 %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeFloat 32\n%22 = OpTypeImage %21 Buffer 0 0 0 1 Unknown\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeRuntimeArray %5\n%26 = OpTypeStruct %25\n%27 = OpTypePointer StorageBuffer %26\n%28 = OpVariable %27 StorageBuffer\n%29 = OpTypeRuntimeArray %5\n%30 = OpTypeStruct %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpConstant %5 1024\n%34 = OpTypeVector %21 4\n%35 = OpTypeArray %34 %33\n%36 = OpTypeStruct %35\n%37 = OpTypePointer Uniform %36\n%38 = OpVariable %37 Uniform\n%39 = OpTypeArray %34 %33\n%40 = OpTypeStruct %39\n%41 = OpTypeArray %40 %17\n%42 = OpTypePointer Uniform %41\n%43 = OpVariable %42 Uniform\n%44 = OpTypePointer Uniform %40\n%46 = OpConstant %5 0\n%47 = OpTypeVector %5 3\n%48 = OpTypePointer Input %47\n%49 = OpVariable %48 Input\n%50 = OpTypePointer Input %5\n%53 = OpConstant %5 1\n%54 = OpTypePointer Uniform %34\n%57 = OpTypeVector %5 4\n%60 = OpTypePointer StorageBuffer %5\n%68 = OpConstant %5 3\n%93 = OpTypePointer StorageBuffer %10\n%102 = OpConstant %5 4\n%111 = OpTypePointer StorageBuffer %16\n%159 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %199\n%199 = OpLabel\n%45 = OpAccessChain %44 %43 %46\n%51 = OpAccessChain %50 %49 %46\n%52 = OpLoad %5 %51\n%55 = OpAccessChain %54 %38 %46 %53\n%56 = OpLoad %34 %55\n%58 = OpBitcast %57 %56\n%59 = OpCompositeExtract %5 %58 0\n%61 = OpAccessChain %60 %32 %46 %46\n%62 = OpAtomicIAdd %5 %61 %53 %46 %59\n%63 = OpAccessChain %54 %38 %46 %52\n%64 = OpLoad %34 %63\n%65 = OpBitcast %57 %64\n%66 = OpCompositeExtract %5 %65 0\n%67 = OpGroupNonUniformBroadcastFirst %5 %68 %66\n%69 = OpAccessChain %60 %32 %46 %53\n%70 = OpAtomicIAdd %5 %69 %53 %46 %67\n%71 = OpAccessChain %54 %45 %46 %53\n%72 = OpLoad %34 %71\n%73 = OpBitcast %57 %72\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %5 %68 %74\n%76 = OpAccessChain %60 %32 %46 %53\n%77 = OpAtomicIAdd %5 %76 %53 %46 %75\n%78 = OpAccessChain %54 %45 %46 %52\n%79 = OpLoad %34 %78\n%80 = OpBitcast %57 %79\n%81 = OpCompositeExtract %5 %80 0\n%82 = OpGroupNonUniformBroadcastFirst %5 %68 %81\n%83 = OpAccessChain %60 %32 %46 %53\n%84 = OpAtomicIAdd %5 %83 %53 %46 %82\n%85 = OpAccessChain %60 %9 %46 %17\n%86 = OpLoad %5 %85\n%87 = OpAccessChain %60 %32 %46 %46\n%88 = OpAtomicIAdd %5 %87 %53 %46 %86\n%89 = OpAccessChain %60 %28 %46 %46\n%90 = OpLoad %5 %89\n%91 = OpAccessChain %60 %32 %46 %46\n%92 = OpAtomicIAdd %5 %91 %53 %46 %90\n%94 = OpAccessChain %93 %14 %46 %52\n%95 = OpLoad %10 %94\n%96 = OpCompositeExtract %5 %95 1\n%97 = OpGroupNonUniformBroadcastFirst %5 %68 %96\n%98 = OpAccessChain %60 %32 %46 %53\n%99 = OpAtomicIAdd %5 %98 %53 %46 %97\n%100 = OpShiftLeftLogical %5 %52 %17\n%101 = OpBitwiseAnd %5 %100 %102\n%103 = OpIMul %5 %53 %17\n%104 = OpShiftRightLogical %5 %101 %17\n%105 = OpIAdd %5 %103 %104\n%106 = OpAccessChain %60 %9 %46 %105\n%107 = OpLoad %5 %106\n%108 = OpGroupNonUniformBroadcastFirst %5 %68 %107\n%109 = OpAccessChain %60 %32 %46 %53\n%110 = OpAtomicIAdd %5 %109 %53 %46 %108\n%112 = OpAccessChain %111 %20 %46\n%113 = OpAccessChain %60 %112 %46 %53\n%114 = OpLoad %5 %113\n%115 = OpGroupNonUniformBroadcastFirst %5 %68 %114\n%116 = OpAccessChain %60 %32 %46 %53\n%117 = OpAtomicIAdd %5 %116 %53 %46 %115\n%118 = OpAccessChain %60 %28 %46 %52\n%119 = OpLoad %5 %118\n%120 = OpGroupNonUniformBroadcastFirst %5 %68 %119\n%121 = OpAccessChain %60 %32 %46 %53\n%122 = OpAtomicIAdd %5 %121 %53 %46 %120\n%123 = OpAccessChain %60 %32 %46 %17\n%124 = OpLoad %5 %123\n%125 = OpGroupNonUniformBroadcastFirst %5 %68 %124\n%126 = OpAccessChain %60 %32 %46 %53\n%127 = OpAtomicIAdd %5 %126 %53 %46 %125\n%128 = OpLoad %22 %24\n%129 = OpImageFetch %34 %128 %46\n%130 = OpCompositeExtract %21 %129 0\n%131 = OpGroupNonUniformBroadcastFirst %21 %68 %130\n%132 = OpConvertFToU %5 %131\n%133 = OpAccessChain %60 %32 %46 %53\n%134 = OpAtomicIAdd %5 %133 %53 %46 %132\n%135 = OpAccessChain %54 %38 %46 %53\n%136 = OpLoad %34 %135\n%137 = OpBitcast %57 %136\n%138 = OpCompositeExtract %5 %137 0\n%139 = OpAccessChain %60 %32 %46 %46\n%140 = OpAtomicIAdd %5 %139 %53 %46 %138\n%141 = OpAccessChain %54 %38 %46 %52\n%142 = OpLoad %34 %141\n%143 = OpBitcast %57 %142\n%144 = OpCompositeExtract %5 %143 0\n%145 = OpGroupNonUniformIAdd %5 %68 Reduce %144\n%146 = OpAccessChain %60 %32 %46 %46\n%147 = OpAtomicIAdd %5 %146 %53 %46 %145\n%148 = OpAccessChain %54 %38 %46 %52\n%149 = OpLoad %34 %148\n%150 = OpBitcast %57 %149\n%151 = OpCompositeExtract %5 %150 0\n%152 = OpGroupNonUniformBitwiseOr %5 %68 Reduce %151\n%153 = OpAccessChain %60 %32 %46 %46\n%154 = OpAtomicIAdd %5 %153 %53 %46 %152\n%155 = OpAccessChain %54 %38 %46 %52\n%156 = OpLoad %34 %155\n%157 = OpBitcast %57 %156\n%158 = OpCompositeExtract %5 %157 0\n%160 = OpGroupNonUniformAllEqual %159 %68 %158\n%161 = OpSelect %5 %160 %53 %46\n%162 = OpAccessChain %60 %32 %46 %46\n%163 = OpAtomicIAdd %5 %162 %53 %46 %161\n%164 = OpAccessChain %54 %38 %46 %52\n%165 = OpLoad %34 %164\n%166 = OpBitcast %57 %165\n%167 = OpCompositeExtract %5 %166 0\n%168 = OpINotEqual %159 %167 %46\n%169 = OpGroupNonUniformBallot %57 %68 %168\n%170 = OpCompositeExtract %5 %169 0\n%171 = OpAccessChain %60 %32 %46 %46\n%172 = OpAtomicIAdd %5 %171 %53 %46 %170\n%173 = OpAccessChain %54 %38 %46 %52\n%174 = OpLoad %34 %173\n%175 = OpBitcast %57 %174\n%176 = OpCompositeExtract %5 %175 0\n%177 = OpINotEqual %159 %176 %46\n%178 = OpGroupNonUniformAny %159 %68 %177\n%179 = OpSelect %5 %178 %53 %46\n%180 = OpAccessChain %60 %32 %46 %46\n%181 = OpAtomicIAdd %5 %180 %53 %46 %179\n%182 = OpAccessChain %54 %38 %46 %52\n%183 = OpLoad %34 %182\n%184 = OpBitcast %57 %183\n%185 = OpCompositeExtract %5 %184 0\n%186 = OpINotEqual %159 %185 %46\n%187 = OpGroupNonUniformAll %159 %68 %186\n%188 = OpSelect %5 %187 %53 %46\n%189 = OpAccessChain %60 %32 %46 %46\n%190 = OpAtomicIAdd %5 %189 %53 %46 %188\n%191 = OpAccessChain %54 %38 %46 %52\n%192 = OpLoad %34 %191\n%193 = OpBitcast %57 %192\n%194 = OpCompositeExtract %5 %193 0\n%195 = OpGroupNonUniformIAdd %5 %68 ExclusiveScan %194\n%196 = OpGroupNonUniformBroadcastFirst %5 %68 %195\n%197 = OpAccessChain %60 %32 %46 %53\n%198 = OpAtomicIAdd %5 %197 %53 %46 %196\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.ssbo.sm60.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _11_15\n{\n    uint _m0[];\n} _15[2];\n\nlayout(set = 0, binding = 0, std430) buffer _21_23\n{\n    uint _m0[];\n} _23;\n\nlayout(set = 0, binding = 0, std140) uniform _27_29\n{\n    vec4 _m0[1024];\n} _29;\n\nlayout(set = 0, binding = 1, std140) uniform _31_34\n{\n    vec4 _m0[1024];\n} _34[2];\n\nlayout(set = 0, binding = 3) uniform samplerBuffer _19;\n\nvoid main()\n{\n    uint _57 = atomicAdd(_23._m0[0u], floatBitsToUint(_29._m0[1u]).x);\n    uint _65 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x));\n    uint _72 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_34[0u]._m0[1u]).x));\n    uint _79 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_34[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _83 = atomicAdd(_23._m0[0u], _9._m0[1u]);\n    uint _88 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(_9._m0[gl_GlobalInvocationID.x]));\n    uint _95 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(_15[0u]._m0[1u]));\n    uint _100 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(_23._m0[2u]));\n    uint _106 = atomicAdd(_23._m0[1u], uint(subgroupBroadcastFirst(texelFetch(_19, int(0u)).x)));\n    uint _108 = atomicAdd(_23._m0[0u], gl_WorkGroupID.x);\n    uint _111 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _117 = atomicAdd(_23._m0[0u], floatBitsToUint(_29._m0[1u]).x);\n    uint _124 = atomicAdd(_23._m0[0u], subgroupAdd(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x));\n    uint _131 = atomicAdd(_23._m0[0u], subgroupOr(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x));\n    uint _140 = atomicAdd(_23._m0[0u], uint(subgroupAllEqual(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x)));\n    uint _149 = atomicAdd(_23._m0[0u], subgroupBallot(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _158 = atomicAdd(_23._m0[0u], uint(subgroupAny(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _167 = atomicAdd(_23._m0[0u], uint(subgroupAll(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _175 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 178\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %41 %45\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %27 \"\"\nOpName %31 \"\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 1\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 3\nOpDecorate %20 ArrayStride 4\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 1\nOpDecorate %41 BuiltIn GlobalInvocationId\nOpDecorate %45 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpConstant %5 2\n%13 = OpTypeArray %11 %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeFloat 32\n%17 = OpTypeImage %16 Buffer 0 0 0 1 Unknown\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeRuntimeArray %5\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpConstant %5 1024\n%25 = OpTypeVector %16 4\n%26 = OpTypeArray %25 %24\n%27 = OpTypeStruct %26\n%28 = OpTypePointer Uniform %27\n%29 = OpVariable %28 Uniform\n%30 = OpTypeArray %25 %24\n%31 = OpTypeStruct %30\n%32 = OpTypeArray %31 %12\n%33 = OpTypePointer Uniform %32\n%34 = OpVariable %33 Uniform\n%36 = OpTypePointer Uniform %31\n%38 = OpConstant %5 0\n%39 = OpTypeVector %5 3\n%40 = OpTypePointer Input %39\n%41 = OpVariable %40 Input\n%42 = OpTypePointer Input %5\n%45 = OpVariable %40 Input\n%48 = OpConstant %5 1\n%49 = OpTypePointer Uniform %25\n%52 = OpTypeVector %5 4\n%55 = OpTypePointer StorageBuffer %5\n%63 = OpConstant %5 3\n%89 = OpTypePointer StorageBuffer %11\n%136 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %176\n%176 = OpLabel\n%35 = OpLoad %17 %19\n%37 = OpAccessChain %36 %34 %38\n%43 = OpAccessChain %42 %41 %38\n%44 = OpLoad %5 %43\n%46 = OpAccessChain %42 %45 %38\n%47 = OpLoad %5 %46\n%50 = OpAccessChain %49 %29 %38 %48\n%51 = OpLoad %25 %50\n%53 = OpBitcast %52 %51\n%54 = OpCompositeExtract %5 %53 0\n%56 = OpAccessChain %55 %23 %38 %38\n%57 = OpAtomicIAdd %5 %56 %48 %38 %54\n%58 = OpAccessChain %49 %29 %38 %44\n%59 = OpLoad %25 %58\n%60 = OpBitcast %52 %59\n%61 = OpCompositeExtract %5 %60 0\n%62 = OpGroupNonUniformBroadcastFirst %5 %63 %61\n%64 = OpAccessChain %55 %23 %38 %48\n%65 = OpAtomicIAdd %5 %64 %48 %38 %62\n%66 = OpAccessChain %49 %37 %38 %48\n%67 = OpLoad %25 %66\n%68 = OpBitcast %52 %67\n%69 = OpCompositeExtract %5 %68 0\n%70 = OpGroupNonUniformBroadcastFirst %5 %63 %69\n%71 = OpAccessChain %55 %23 %38 %48\n%72 = OpAtomicIAdd %5 %71 %48 %38 %70\n%73 = OpAccessChain %49 %37 %38 %44\n%74 = OpLoad %25 %73\n%75 = OpBitcast %52 %74\n%76 = OpCompositeExtract %5 %75 0\n%77 = OpGroupNonUniformBroadcastFirst %5 %63 %76\n%78 = OpAccessChain %55 %23 %38 %48\n%79 = OpAtomicIAdd %5 %78 %48 %38 %77\n%80 = OpAccessChain %55 %9 %38 %48\n%81 = OpLoad %5 %80\n%82 = OpAccessChain %55 %23 %38 %38\n%83 = OpAtomicIAdd %5 %82 %48 %38 %81\n%84 = OpAccessChain %55 %9 %38 %44\n%85 = OpLoad %5 %84\n%86 = OpGroupNonUniformBroadcastFirst %5 %63 %85\n%87 = OpAccessChain %55 %23 %38 %48\n%88 = OpAtomicIAdd %5 %87 %48 %38 %86\n%90 = OpAccessChain %89 %15 %38\n%91 = OpAccessChain %55 %90 %38 %48\n%92 = OpLoad %5 %91\n%93 = OpGroupNonUniformBroadcastFirst %5 %63 %92\n%94 = OpAccessChain %55 %23 %38 %48\n%95 = OpAtomicIAdd %5 %94 %48 %38 %93\n%96 = OpAccessChain %55 %23 %38 %12\n%97 = OpLoad %5 %96\n%98 = OpGroupNonUniformBroadcastFirst %5 %63 %97\n%99 = OpAccessChain %55 %23 %38 %48\n%100 = OpAtomicIAdd %5 %99 %48 %38 %98\n%101 = OpImageFetch %25 %35 %38\n%102 = OpCompositeExtract %16 %101 0\n%103 = OpGroupNonUniformBroadcastFirst %16 %63 %102\n%104 = OpConvertFToU %5 %103\n%105 = OpAccessChain %55 %23 %38 %48\n%106 = OpAtomicIAdd %5 %105 %48 %38 %104\n%107 = OpAccessChain %55 %23 %38 %38\n%108 = OpAtomicIAdd %5 %107 %48 %38 %47\n%109 = OpGroupNonUniformBroadcastFirst %5 %63 %44\n%110 = OpAccessChain %55 %23 %38 %48\n%111 = OpAtomicIAdd %5 %110 %48 %38 %109\n%112 = OpAccessChain %49 %29 %38 %48\n%113 = OpLoad %25 %112\n%114 = OpBitcast %52 %113\n%115 = OpCompositeExtract %5 %114 0\n%116 = OpAccessChain %55 %23 %38 %38\n%117 = OpAtomicIAdd %5 %116 %48 %38 %115\n%118 = OpAccessChain %49 %29 %38 %44\n%119 = OpLoad %25 %118\n%120 = OpBitcast %52 %119\n%121 = OpCompositeExtract %5 %120 0\n%122 = OpGroupNonUniformIAdd %5 %63 Reduce %121\n%123 = OpAccessChain %55 %23 %38 %38\n%124 = OpAtomicIAdd %5 %123 %48 %38 %122\n%125 = OpAccessChain %49 %29 %38 %44\n%126 = OpLoad %25 %125\n%127 = OpBitcast %52 %126\n%128 = OpCompositeExtract %5 %127 0\n%129 = OpGroupNonUniformBitwiseOr %5 %63 Reduce %128\n%130 = OpAccessChain %55 %23 %38 %38\n%131 = OpAtomicIAdd %5 %130 %48 %38 %129\n%132 = OpAccessChain %49 %29 %38 %44\n%133 = OpLoad %25 %132\n%134 = OpBitcast %52 %133\n%135 = OpCompositeExtract %5 %134 0\n%137 = OpGroupNonUniformAllEqual %136 %63 %135\n%138 = OpSelect %5 %137 %48 %38\n%139 = OpAccessChain %55 %23 %38 %38\n%140 = OpAtomicIAdd %5 %139 %48 %38 %138\n%141 = OpAccessChain %49 %29 %38 %44\n%142 = OpLoad %25 %141\n%143 = OpBitcast %52 %142\n%144 = OpCompositeExtract %5 %143 0\n%145 = OpINotEqual %136 %144 %38\n%146 = OpGroupNonUniformBallot %52 %63 %145\n%147 = OpCompositeExtract %5 %146 0\n%148 = OpAccessChain %55 %23 %38 %38\n%149 = OpAtomicIAdd %5 %148 %48 %38 %147\n%150 = OpAccessChain %49 %29 %38 %44\n%151 = OpLoad %25 %150\n%152 = OpBitcast %52 %151\n%153 = OpCompositeExtract %5 %152 0\n%154 = OpINotEqual %136 %153 %38\n%155 = OpGroupNonUniformAny %136 %63 %154\n%156 = OpSelect %5 %155 %48 %38\n%157 = OpAccessChain %55 %23 %38 %38\n%158 = OpAtomicIAdd %5 %157 %48 %38 %156\n%159 = OpAccessChain %49 %29 %38 %44\n%160 = OpLoad %25 %159\n%161 = OpBitcast %52 %160\n%162 = OpCompositeExtract %5 %161 0\n%163 = OpINotEqual %136 %162 %38\n%164 = OpGroupNonUniformAll %136 %63 %163\n%165 = OpSelect %5 %164 %48 %38\n%166 = OpAccessChain %55 %23 %38 %38\n%167 = OpAtomicIAdd %5 %166 %48 %38 %165\n%168 = OpAccessChain %49 %29 %38 %44\n%169 = OpLoad %25 %168\n%170 = OpBitcast %52 %169\n%171 = OpCompositeExtract %5 %170 0\n%172 = OpGroupNonUniformIAdd %5 %63 ExclusiveScan %171\n%173 = OpGroupNonUniformBroadcastFirst %5 %63 %172\n%174 = OpAccessChain %55 %23 %38 %48\n%175 = OpAtomicIAdd %5 %174 %48 %38 %173\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.ssbo.sm66.comp",
    "content": "#version 460\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _11_15\n{\n    uint _m0[];\n} _15[2];\n\nlayout(set = 0, binding = 0, std430) buffer _21_23\n{\n    uint _m0[];\n} _23;\n\nlayout(set = 0, binding = 0, std140) uniform _27_29\n{\n    vec4 _m0[1024];\n} _29;\n\nlayout(set = 0, binding = 1, std140) uniform _31_34\n{\n    vec4 _m0[1024];\n} _34[2];\n\nlayout(set = 0, binding = 3) uniform samplerBuffer _19;\n\nvoid main()\n{\n    uint _56 = atomicAdd(_23._m0[0u], floatBitsToUint(_29._m0[1u]).x);\n    uint _64 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x));\n    uint _71 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_34[0u]._m0[1u]).x));\n    uint _78 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(floatBitsToUint(_34[0u]._m0[gl_GlobalInvocationID.x]).x));\n    uint _82 = atomicAdd(_23._m0[0u], _9._m0[1u]);\n    uint _87 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(_9._m0[gl_GlobalInvocationID.x]));\n    uint _94 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(_15[0u]._m0[1u]));\n    uint _99 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(_23._m0[2u]));\n    uint _106 = atomicAdd(_23._m0[1u], uint(subgroupBroadcastFirst(texelFetch(_19, int(0u)).x)));\n    uint _108 = atomicAdd(_23._m0[0u], gl_WorkGroupID.x);\n    uint _111 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(gl_GlobalInvocationID.x));\n    uint _117 = atomicAdd(_23._m0[0u], floatBitsToUint(_29._m0[1u]).x);\n    uint _124 = atomicAdd(_23._m0[0u], subgroupAdd(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x));\n    uint _131 = atomicAdd(_23._m0[0u], subgroupOr(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x));\n    uint _140 = atomicAdd(_23._m0[0u], uint(subgroupAllEqual(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x)));\n    uint _149 = atomicAdd(_23._m0[0u], subgroupBallot(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x != 0u).x);\n    uint _158 = atomicAdd(_23._m0[0u], uint(subgroupAny(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _167 = atomicAdd(_23._m0[0u], uint(subgroupAll(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x != 0u)));\n    uint _175 = atomicAdd(_23._m0[1u], subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(_29._m0[gl_GlobalInvocationID.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n// HeuristicWaveSize(32)\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 178\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %40 %44\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %27 \"\"\nOpName %31 \"\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 1\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 3\nOpDecorate %20 ArrayStride 4\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 1\nOpDecorate %40 BuiltIn GlobalInvocationId\nOpDecorate %44 BuiltIn WorkgroupId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpConstant %5 2\n%13 = OpTypeArray %11 %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeFloat 32\n%17 = OpTypeImage %16 Buffer 0 0 0 1 Unknown\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeRuntimeArray %5\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpConstant %5 1024\n%25 = OpTypeVector %16 4\n%26 = OpTypeArray %25 %24\n%27 = OpTypeStruct %26\n%28 = OpTypePointer Uniform %27\n%29 = OpVariable %28 Uniform\n%30 = OpTypeArray %25 %24\n%31 = OpTypeStruct %30\n%32 = OpTypeArray %31 %12\n%33 = OpTypePointer Uniform %32\n%34 = OpVariable %33 Uniform\n%35 = OpTypePointer Uniform %31\n%37 = OpConstant %5 0\n%38 = OpTypeVector %5 3\n%39 = OpTypePointer Input %38\n%40 = OpVariable %39 Input\n%41 = OpTypePointer Input %5\n%44 = OpVariable %39 Input\n%47 = OpConstant %5 1\n%48 = OpTypePointer Uniform %25\n%51 = OpTypeVector %5 4\n%54 = OpTypePointer StorageBuffer %5\n%62 = OpConstant %5 3\n%88 = OpTypePointer StorageBuffer %11\n%136 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %176\n%176 = OpLabel\n%36 = OpAccessChain %35 %34 %37\n%42 = OpAccessChain %41 %40 %37\n%43 = OpLoad %5 %42\n%45 = OpAccessChain %41 %44 %37\n%46 = OpLoad %5 %45\n%49 = OpAccessChain %48 %29 %37 %47\n%50 = OpLoad %25 %49\n%52 = OpBitcast %51 %50\n%53 = OpCompositeExtract %5 %52 0\n%55 = OpAccessChain %54 %23 %37 %37\n%56 = OpAtomicIAdd %5 %55 %47 %37 %53\n%57 = OpAccessChain %48 %29 %37 %43\n%58 = OpLoad %25 %57\n%59 = OpBitcast %51 %58\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpGroupNonUniformBroadcastFirst %5 %62 %60\n%63 = OpAccessChain %54 %23 %37 %47\n%64 = OpAtomicIAdd %5 %63 %47 %37 %61\n%65 = OpAccessChain %48 %36 %37 %47\n%66 = OpLoad %25 %65\n%67 = OpBitcast %51 %66\n%68 = OpCompositeExtract %5 %67 0\n%69 = OpGroupNonUniformBroadcastFirst %5 %62 %68\n%70 = OpAccessChain %54 %23 %37 %47\n%71 = OpAtomicIAdd %5 %70 %47 %37 %69\n%72 = OpAccessChain %48 %36 %37 %43\n%73 = OpLoad %25 %72\n%74 = OpBitcast %51 %73\n%75 = OpCompositeExtract %5 %74 0\n%76 = OpGroupNonUniformBroadcastFirst %5 %62 %75\n%77 = OpAccessChain %54 %23 %37 %47\n%78 = OpAtomicIAdd %5 %77 %47 %37 %76\n%79 = OpAccessChain %54 %9 %37 %47\n%80 = OpLoad %5 %79\n%81 = OpAccessChain %54 %23 %37 %37\n%82 = OpAtomicIAdd %5 %81 %47 %37 %80\n%83 = OpAccessChain %54 %9 %37 %43\n%84 = OpLoad %5 %83\n%85 = OpGroupNonUniformBroadcastFirst %5 %62 %84\n%86 = OpAccessChain %54 %23 %37 %47\n%87 = OpAtomicIAdd %5 %86 %47 %37 %85\n%89 = OpAccessChain %88 %15 %37\n%90 = OpAccessChain %54 %89 %37 %47\n%91 = OpLoad %5 %90\n%92 = OpGroupNonUniformBroadcastFirst %5 %62 %91\n%93 = OpAccessChain %54 %23 %37 %47\n%94 = OpAtomicIAdd %5 %93 %47 %37 %92\n%95 = OpAccessChain %54 %23 %37 %12\n%96 = OpLoad %5 %95\n%97 = OpGroupNonUniformBroadcastFirst %5 %62 %96\n%98 = OpAccessChain %54 %23 %37 %47\n%99 = OpAtomicIAdd %5 %98 %47 %37 %97\n%100 = OpLoad %17 %19\n%101 = OpImageFetch %25 %100 %37\n%102 = OpCompositeExtract %16 %101 0\n%103 = OpGroupNonUniformBroadcastFirst %16 %62 %102\n%104 = OpConvertFToU %5 %103\n%105 = OpAccessChain %54 %23 %37 %47\n%106 = OpAtomicIAdd %5 %105 %47 %37 %104\n%107 = OpAccessChain %54 %23 %37 %37\n%108 = OpAtomicIAdd %5 %107 %47 %37 %46\n%109 = OpGroupNonUniformBroadcastFirst %5 %62 %43\n%110 = OpAccessChain %54 %23 %37 %47\n%111 = OpAtomicIAdd %5 %110 %47 %37 %109\n%112 = OpAccessChain %48 %29 %37 %47\n%113 = OpLoad %25 %112\n%114 = OpBitcast %51 %113\n%115 = OpCompositeExtract %5 %114 0\n%116 = OpAccessChain %54 %23 %37 %37\n%117 = OpAtomicIAdd %5 %116 %47 %37 %115\n%118 = OpAccessChain %48 %29 %37 %43\n%119 = OpLoad %25 %118\n%120 = OpBitcast %51 %119\n%121 = OpCompositeExtract %5 %120 0\n%122 = OpGroupNonUniformIAdd %5 %62 Reduce %121\n%123 = OpAccessChain %54 %23 %37 %37\n%124 = OpAtomicIAdd %5 %123 %47 %37 %122\n%125 = OpAccessChain %48 %29 %37 %43\n%126 = OpLoad %25 %125\n%127 = OpBitcast %51 %126\n%128 = OpCompositeExtract %5 %127 0\n%129 = OpGroupNonUniformBitwiseOr %5 %62 Reduce %128\n%130 = OpAccessChain %54 %23 %37 %37\n%131 = OpAtomicIAdd %5 %130 %47 %37 %129\n%132 = OpAccessChain %48 %29 %37 %43\n%133 = OpLoad %25 %132\n%134 = OpBitcast %51 %133\n%135 = OpCompositeExtract %5 %134 0\n%137 = OpGroupNonUniformAllEqual %136 %62 %135\n%138 = OpSelect %5 %137 %47 %37\n%139 = OpAccessChain %54 %23 %37 %37\n%140 = OpAtomicIAdd %5 %139 %47 %37 %138\n%141 = OpAccessChain %48 %29 %37 %43\n%142 = OpLoad %25 %141\n%143 = OpBitcast %51 %142\n%144 = OpCompositeExtract %5 %143 0\n%145 = OpINotEqual %136 %144 %37\n%146 = OpGroupNonUniformBallot %51 %62 %145\n%147 = OpCompositeExtract %5 %146 0\n%148 = OpAccessChain %54 %23 %37 %37\n%149 = OpAtomicIAdd %5 %148 %47 %37 %147\n%150 = OpAccessChain %48 %29 %37 %43\n%151 = OpLoad %25 %150\n%152 = OpBitcast %51 %151\n%153 = OpCompositeExtract %5 %152 0\n%154 = OpINotEqual %136 %153 %37\n%155 = OpGroupNonUniformAny %136 %62 %154\n%156 = OpSelect %5 %155 %47 %37\n%157 = OpAccessChain %54 %23 %37 %37\n%158 = OpAtomicIAdd %5 %157 %47 %37 %156\n%159 = OpAccessChain %48 %29 %37 %43\n%160 = OpLoad %25 %159\n%161 = OpBitcast %51 %160\n%162 = OpCompositeExtract %5 %161 0\n%163 = OpINotEqual %136 %162 %37\n%164 = OpGroupNonUniformAll %136 %62 %163\n%165 = OpSelect %5 %164 %47 %37\n%166 = OpAccessChain %54 %23 %37 %37\n%167 = OpAtomicIAdd %5 %166 %47 %37 %165\n%168 = OpAccessChain %48 %29 %37 %43\n%169 = OpLoad %25 %168\n%170 = OpBitcast %51 %169\n%171 = OpCompositeExtract %5 %170 0\n%172 = OpGroupNonUniformIAdd %5 %62 ExclusiveScan %171\n%173 = OpGroupNonUniformBroadcastFirst %5 %62 %172\n%174 = OpAccessChain %54 %23 %37 %47\n%175 = OpAtomicIAdd %5 %174 %47 %37 %173\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/opts/wave-read-lane-first.ssbo.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_vote : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer TSSBO\n{\n    uint _m0[];\n} T;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer T_1\n{\n    uvec2 _m0[];\n} T_2;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer TsSSBO\n{\n    uint _m0[];\n} Ts[2];\n\nlayout(set = 0, binding = 4, std430) restrict readonly buffer TBSSBO\n{\n    uint _m0[];\n} TB;\n\nlayout(set = 0, binding = 0, std430) buffer USSBO\n{\n    uint _m0[];\n} U;\n\nlayout(set = 0, binding = 0, std140) uniform CUBO\n{\n    vec4 _m0[1024];\n} C;\n\nlayout(set = 0, binding = 1, std140) uniform CsUBO\n{\n    vec4 _m0[1024];\n} Cs[2];\n\nlayout(set = 0, binding = 3) uniform samplerBuffer B;\n\nvoid main()\n{\n    uint _62 = atomicAdd(U._m0[0u], floatBitsToUint(C._m0[1u]).x);\n    uint _70 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x));\n    uint _77 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(floatBitsToUint(Cs[0u]._m0[1u]).x));\n    uint _84 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(floatBitsToUint(Cs[0u]._m0[gl_LaunchIDEXT.x]).x));\n    uint _88 = atomicAdd(U._m0[0u], T._m0[2u]);\n    uint _92 = atomicAdd(U._m0[0u], TB._m0[0u]);\n    uint _99 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(T_2._m0[gl_LaunchIDEXT.x].y));\n    uint _103 = 1u * 2u;\n    uint _110 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(T._m0[_103 + (((gl_LaunchIDEXT.x << 2u) & 4u) >> 2u)]));\n    uint _117 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(Ts[0u]._m0[1u]));\n    uint _122 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(TB._m0[gl_LaunchIDEXT.x]));\n    uint _127 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(U._m0[2u]));\n    uint _134 = atomicAdd(U._m0[1u], uint(subgroupBroadcastFirst(texelFetch(B, int(0u)).x)));\n    uint _140 = atomicAdd(U._m0[0u], floatBitsToUint(C._m0[1u]).x);\n    uint _147 = atomicAdd(U._m0[0u], subgroupAdd(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x));\n    uint _154 = atomicAdd(U._m0[0u], subgroupOr(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x));\n    uint _163 = atomicAdd(U._m0[0u], uint(subgroupAllEqual(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x)));\n    uint _172 = atomicAdd(U._m0[0u], subgroupBallot(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x != 0u).x);\n    uint _181 = atomicAdd(U._m0[0u], uint(subgroupAny(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x != 0u)));\n    uint _190 = atomicAdd(U._m0[0u], uint(subgroupAll(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x != 0u)));\n    uint _198 = atomicAdd(U._m0[1u], subgroupBroadcastFirst(subgroupExclusiveAdd(floatBitsToUint(C._m0[gl_LaunchIDEXT.x]).x)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 201\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability GroupNonUniformVote\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %9 %14 %20 %24 %28 %32 %38 %43 %49\nOpName %3 \"main\"\nOpName %7 \"TSSBO\"\nOpName %9 \"T\"\nOpName %12 \"TSSBO\"\nOpName %14 \"T\"\nOpName %16 \"TsSSBO\"\nOpName %20 \"Ts\"\nOpName %24 \"B\"\nOpName %26 \"TBSSBO\"\nOpName %28 \"TB\"\nOpName %30 \"USSBO\"\nOpName %32 \"U\"\nOpName %36 \"CUBO\"\nOpName %38 \"C\"\nOpName %40 \"CsUBO\"\nOpName %43 \"Cs\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 4\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 3\nOpDecorate %25 ArrayStride 4\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 4\nOpDecorate %28 NonWritable\nOpDecorate %28 Restrict\nOpDecorate %29 ArrayStride 4\nOpMemberDecorate %30 0 Offset 0\nOpDecorate %30 Block\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 0\nOpDecorate %35 ArrayStride 16\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 0\nOpDecorate %39 ArrayStride 16\nOpMemberDecorate %40 0 Offset 0\nOpDecorate %40 Block\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 1\nOpDecorate %49 BuiltIn LaunchIdKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %5\n%16 = OpTypeStruct %15\n%17 = OpConstant %5 2\n%18 = OpTypeArray %16 %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeFloat 32\n%22 = OpTypeImage %21 Buffer 0 0 0 1 Unknown\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeRuntimeArray %5\n%26 = OpTypeStruct %25\n%27 = OpTypePointer StorageBuffer %26\n%28 = OpVariable %27 StorageBuffer\n%29 = OpTypeRuntimeArray %5\n%30 = OpTypeStruct %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpConstant %5 1024\n%34 = OpTypeVector %21 4\n%35 = OpTypeArray %34 %33\n%36 = OpTypeStruct %35\n%37 = OpTypePointer Uniform %36\n%38 = OpVariable %37 Uniform\n%39 = OpTypeArray %34 %33\n%40 = OpTypeStruct %39\n%41 = OpTypeArray %40 %17\n%42 = OpTypePointer Uniform %41\n%43 = OpVariable %42 Uniform\n%44 = OpTypePointer Uniform %40\n%46 = OpConstant %5 0\n%47 = OpTypeVector %5 3\n%48 = OpTypePointer Input %47\n%49 = OpVariable %48 Input\n%50 = OpTypePointer Input %5\n%53 = OpConstant %5 1\n%54 = OpTypePointer Uniform %34\n%57 = OpTypeVector %5 4\n%60 = OpTypePointer StorageBuffer %5\n%68 = OpConstant %5 3\n%93 = OpTypePointer StorageBuffer %10\n%102 = OpConstant %5 4\n%111 = OpTypePointer StorageBuffer %16\n%159 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %199\n%199 = OpLabel\n%45 = OpAccessChain %44 %43 %46\n%51 = OpAccessChain %50 %49 %46\n%52 = OpLoad %5 %51\n%55 = OpAccessChain %54 %38 %46 %53\n%56 = OpLoad %34 %55\n%58 = OpBitcast %57 %56\n%59 = OpCompositeExtract %5 %58 0\n%61 = OpAccessChain %60 %32 %46 %46\n%62 = OpAtomicIAdd %5 %61 %53 %46 %59\n%63 = OpAccessChain %54 %38 %46 %52\n%64 = OpLoad %34 %63\n%65 = OpBitcast %57 %64\n%66 = OpCompositeExtract %5 %65 0\n%67 = OpGroupNonUniformBroadcastFirst %5 %68 %66\n%69 = OpAccessChain %60 %32 %46 %53\n%70 = OpAtomicIAdd %5 %69 %53 %46 %67\n%71 = OpAccessChain %54 %45 %46 %53\n%72 = OpLoad %34 %71\n%73 = OpBitcast %57 %72\n%74 = OpCompositeExtract %5 %73 0\n%75 = OpGroupNonUniformBroadcastFirst %5 %68 %74\n%76 = OpAccessChain %60 %32 %46 %53\n%77 = OpAtomicIAdd %5 %76 %53 %46 %75\n%78 = OpAccessChain %54 %45 %46 %52\n%79 = OpLoad %34 %78\n%80 = OpBitcast %57 %79\n%81 = OpCompositeExtract %5 %80 0\n%82 = OpGroupNonUniformBroadcastFirst %5 %68 %81\n%83 = OpAccessChain %60 %32 %46 %53\n%84 = OpAtomicIAdd %5 %83 %53 %46 %82\n%85 = OpAccessChain %60 %9 %46 %17\n%86 = OpLoad %5 %85\n%87 = OpAccessChain %60 %32 %46 %46\n%88 = OpAtomicIAdd %5 %87 %53 %46 %86\n%89 = OpAccessChain %60 %28 %46 %46\n%90 = OpLoad %5 %89\n%91 = OpAccessChain %60 %32 %46 %46\n%92 = OpAtomicIAdd %5 %91 %53 %46 %90\n%94 = OpAccessChain %93 %14 %46 %52\n%95 = OpLoad %10 %94\n%96 = OpCompositeExtract %5 %95 1\n%97 = OpGroupNonUniformBroadcastFirst %5 %68 %96\n%98 = OpAccessChain %60 %32 %46 %53\n%99 = OpAtomicIAdd %5 %98 %53 %46 %97\n%100 = OpShiftLeftLogical %5 %52 %17\n%101 = OpBitwiseAnd %5 %100 %102\n%103 = OpIMul %5 %53 %17\n%104 = OpShiftRightLogical %5 %101 %17\n%105 = OpIAdd %5 %103 %104\n%106 = OpAccessChain %60 %9 %46 %105\n%107 = OpLoad %5 %106\n%108 = OpGroupNonUniformBroadcastFirst %5 %68 %107\n%109 = OpAccessChain %60 %32 %46 %53\n%110 = OpAtomicIAdd %5 %109 %53 %46 %108\n%112 = OpAccessChain %111 %20 %46\n%113 = OpAccessChain %60 %112 %46 %53\n%114 = OpLoad %5 %113\n%115 = OpGroupNonUniformBroadcastFirst %5 %68 %114\n%116 = OpAccessChain %60 %32 %46 %53\n%117 = OpAtomicIAdd %5 %116 %53 %46 %115\n%118 = OpAccessChain %60 %28 %46 %52\n%119 = OpLoad %5 %118\n%120 = OpGroupNonUniformBroadcastFirst %5 %68 %119\n%121 = OpAccessChain %60 %32 %46 %53\n%122 = OpAtomicIAdd %5 %121 %53 %46 %120\n%123 = OpAccessChain %60 %32 %46 %17\n%124 = OpLoad %5 %123\n%125 = OpGroupNonUniformBroadcastFirst %5 %68 %124\n%126 = OpAccessChain %60 %32 %46 %53\n%127 = OpAtomicIAdd %5 %126 %53 %46 %125\n%128 = OpLoad %22 %24\n%129 = OpImageFetch %34 %128 %46\n%130 = OpCompositeExtract %21 %129 0\n%131 = OpGroupNonUniformBroadcastFirst %21 %68 %130\n%132 = OpConvertFToU %5 %131\n%133 = OpAccessChain %60 %32 %46 %53\n%134 = OpAtomicIAdd %5 %133 %53 %46 %132\n%135 = OpAccessChain %54 %38 %46 %53\n%136 = OpLoad %34 %135\n%137 = OpBitcast %57 %136\n%138 = OpCompositeExtract %5 %137 0\n%139 = OpAccessChain %60 %32 %46 %46\n%140 = OpAtomicIAdd %5 %139 %53 %46 %138\n%141 = OpAccessChain %54 %38 %46 %52\n%142 = OpLoad %34 %141\n%143 = OpBitcast %57 %142\n%144 = OpCompositeExtract %5 %143 0\n%145 = OpGroupNonUniformIAdd %5 %68 Reduce %144\n%146 = OpAccessChain %60 %32 %46 %46\n%147 = OpAtomicIAdd %5 %146 %53 %46 %145\n%148 = OpAccessChain %54 %38 %46 %52\n%149 = OpLoad %34 %148\n%150 = OpBitcast %57 %149\n%151 = OpCompositeExtract %5 %150 0\n%152 = OpGroupNonUniformBitwiseOr %5 %68 Reduce %151\n%153 = OpAccessChain %60 %32 %46 %46\n%154 = OpAtomicIAdd %5 %153 %53 %46 %152\n%155 = OpAccessChain %54 %38 %46 %52\n%156 = OpLoad %34 %155\n%157 = OpBitcast %57 %156\n%158 = OpCompositeExtract %5 %157 0\n%160 = OpGroupNonUniformAllEqual %159 %68 %158\n%161 = OpSelect %5 %160 %53 %46\n%162 = OpAccessChain %60 %32 %46 %46\n%163 = OpAtomicIAdd %5 %162 %53 %46 %161\n%164 = OpAccessChain %54 %38 %46 %52\n%165 = OpLoad %34 %164\n%166 = OpBitcast %57 %165\n%167 = OpCompositeExtract %5 %166 0\n%168 = OpINotEqual %159 %167 %46\n%169 = OpGroupNonUniformBallot %57 %68 %168\n%170 = OpCompositeExtract %5 %169 0\n%171 = OpAccessChain %60 %32 %46 %46\n%172 = OpAtomicIAdd %5 %171 %53 %46 %170\n%173 = OpAccessChain %54 %38 %46 %52\n%174 = OpLoad %34 %173\n%175 = OpBitcast %57 %174\n%176 = OpCompositeExtract %5 %175 0\n%177 = OpINotEqual %159 %176 %46\n%178 = OpGroupNonUniformAny %159 %68 %177\n%179 = OpSelect %5 %178 %53 %46\n%180 = OpAccessChain %60 %32 %46 %46\n%181 = OpAtomicIAdd %5 %180 %53 %46 %179\n%182 = OpAccessChain %54 %38 %46 %52\n%183 = OpLoad %34 %182\n%184 = OpBitcast %57 %183\n%185 = OpCompositeExtract %5 %184 0\n%186 = OpINotEqual %159 %185 %46\n%187 = OpGroupNonUniformAll %159 %68 %186\n%188 = OpSelect %5 %187 %53 %46\n%189 = OpAccessChain %60 %32 %46 %46\n%190 = OpAtomicIAdd %5 %189 %53 %46 %188\n%191 = OpAccessChain %54 %38 %46 %52\n%192 = OpLoad %34 %191\n%193 = OpBitcast %57 %192\n%194 = OpCompositeExtract %5 %193 0\n%195 = OpGroupNonUniformIAdd %5 %68 ExclusiveScan %194\n%196 = OpGroupNonUniformBroadcastFirst %5 %68 %195\n%197 = OpAccessChain %60 %32 %46 %53\n%198 = OpAtomicIAdd %5 %197 %53 %46 %196\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-double1.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 3\n%19 = OpTypeFloat 64\n%20 = OpTypePointer StorageBuffer %19\n%24 = OpConstant %19 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpShiftLeftLogical %5 %16 %18\n%21 = OpRawAccessChainNV %20 %9 %15 %15 %17 RobustnessPerComponentNV\n%22 = OpLoad %19 %21 Aligned 8\n%23 = OpFAdd %19 %22 %24\n%25 = OpRawAccessChainNV %20 %9 %15 %15 %17 RobustnessPerComponentNV\nOpStore %25 %23 Aligned 8\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-double2.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 50\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability DenormPreserve\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 2\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 3\n%21 = OpTypePointer StorageBuffer %7\n%23 = OpTypeFloat 64\n%24 = OpTypeVector %23 2\n%25 = OpTypePointer StorageBuffer %24\n%31 = OpConstant %23 4\n%36 = OpConstant %5 4\n%38 = OpConstant %5 1\n%40 = OpConstant %5 16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %48\n%48 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpAccessChain %21 %11 %17\n%26 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%27 = OpLoad %24 %26 Aligned 8\n%28 = OpCompositeExtract %23 %27 0\n%29 = OpCompositeExtract %23 %27 1\n%30 = OpFAdd %23 %28 %31\n%32 = OpFAdd %23 %29 %31\n%33 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%34 = OpCompositeConstruct %24 %30 %32\nOpStore %33 %34 Aligned 8\n%35 = OpShiftLeftLogical %5 %18 %36\n%37 = OpAccessChain %21 %11 %38\n%39 = OpRawAccessChainNV %25 %37 %40 %18 %17 RobustnessPerElementNV\n%41 = OpLoad %24 %39 Aligned 16\n%42 = OpCompositeExtract %23 %41 0\n%43 = OpCompositeExtract %23 %41 1\n%44 = OpFAdd %23 %42 %31\n%45 = OpFAdd %23 %43 %31\n%46 = OpRawAccessChainNV %25 %37 %40 %18 %17 RobustnessPerElementNV\n%47 = OpCompositeConstruct %24 %44 %45\nOpStore %46 %47 Aligned 16\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-double3.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability DenormPreserve\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 4\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 3\n%21 = OpTypePointer StorageBuffer %7\n%23 = OpTypeFloat 64\n%24 = OpTypeVector %23 3\n%25 = OpTypePointer StorageBuffer %24\n%32 = OpConstant %23 4\n%39 = OpConstant %5 1\n%51 = OpConstant %5 24\n%53 = OpConstant %5 2\n%65 = OpConstant %5 5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %77\n%77 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpAccessChain %21 %11 %17\n%26 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%27 = OpLoad %24 %26 Aligned 8\n%28 = OpCompositeExtract %23 %27 0\n%29 = OpCompositeExtract %23 %27 1\n%30 = OpCompositeExtract %23 %27 2\n%31 = OpFAdd %23 %28 %32\n%33 = OpFAdd %23 %29 %32\n%34 = OpFAdd %23 %30 %32\n%35 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%36 = OpCompositeConstruct %24 %31 %33 %34\nOpStore %35 %36 Aligned 8\n%37 = OpShiftLeftLogical %5 %18 %8\n%38 = OpAccessChain %21 %11 %39\n%40 = OpRawAccessChainNV %25 %38 %17 %17 %37 RobustnessPerComponentNV\n%41 = OpLoad %24 %40 Aligned 16\n%42 = OpCompositeExtract %23 %41 0\n%43 = OpCompositeExtract %23 %41 1\n%44 = OpCompositeExtract %23 %41 2\n%45 = OpFAdd %23 %42 %32\n%46 = OpFAdd %23 %43 %32\n%47 = OpFAdd %23 %44 %32\n%48 = OpRawAccessChainNV %25 %38 %17 %17 %37 RobustnessPerComponentNV\n%49 = OpCompositeConstruct %24 %45 %46 %47\nOpStore %48 %49 Aligned 16\n%50 = OpIMul %5 %18 %51\n%52 = OpAccessChain %21 %11 %53\n%54 = OpRawAccessChainNV %25 %52 %17 %17 %50 RobustnessPerComponentNV\n%55 = OpLoad %24 %54 Aligned 8\n%56 = OpCompositeExtract %23 %55 0\n%57 = OpCompositeExtract %23 %55 1\n%58 = OpCompositeExtract %23 %55 2\n%59 = OpFAdd %23 %56 %32\n%60 = OpFAdd %23 %57 %32\n%61 = OpFAdd %23 %58 %32\n%62 = OpRawAccessChainNV %25 %52 %17 %17 %50 RobustnessPerComponentNV\n%63 = OpCompositeConstruct %24 %59 %60 %61\nOpStore %62 %63 Aligned 8\n%64 = OpShiftLeftLogical %5 %18 %65\n%66 = OpAccessChain %21 %11 %20\n%67 = OpRawAccessChainNV %25 %66 %17 %17 %64 RobustnessPerComponentNV\n%68 = OpLoad %24 %67 Aligned 32\n%69 = OpCompositeExtract %23 %68 0\n%70 = OpCompositeExtract %23 %68 1\n%71 = OpCompositeExtract %23 %68 2\n%72 = OpFAdd %23 %69 %32\n%73 = OpFAdd %23 %70 %32\n%74 = OpFAdd %23 %71 %32\n%75 = OpRawAccessChainNV %25 %66 %17 %17 %64 RobustnessPerComponentNV\n%76 = OpCompositeConstruct %24 %72 %73 %74\nOpStore %75 %76 Aligned 32\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-double4.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability DenormPreserve\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 5\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 3\n%21 = OpTypePointer StorageBuffer %7\n%23 = OpTypeFloat 64\n%24 = OpTypeVector %23 4\n%25 = OpTypePointer StorageBuffer %24\n%33 = OpConstant %23 4\n%40 = OpConstant %5 4\n%42 = OpConstant %5 1\n%56 = OpConstant %5 24\n%58 = OpConstant %5 2\n%86 = OpConstant %5 40\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %100\n%100 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpAccessChain %21 %11 %17\n%26 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%27 = OpLoad %24 %26 Aligned 8\n%28 = OpCompositeExtract %23 %27 0\n%29 = OpCompositeExtract %23 %27 1\n%30 = OpCompositeExtract %23 %27 2\n%31 = OpCompositeExtract %23 %27 3\n%32 = OpFAdd %23 %28 %33\n%34 = OpFAdd %23 %29 %33\n%35 = OpFAdd %23 %30 %33\n%36 = OpFAdd %23 %31 %33\n%37 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%38 = OpCompositeConstruct %24 %32 %34 %35 %36\nOpStore %37 %38 Aligned 8\n%39 = OpShiftLeftLogical %5 %18 %40\n%41 = OpAccessChain %21 %11 %42\n%43 = OpRawAccessChainNV %25 %41 %17 %17 %39 RobustnessPerComponentNV\n%44 = OpLoad %24 %43 Aligned 16\n%45 = OpCompositeExtract %23 %44 0\n%46 = OpCompositeExtract %23 %44 1\n%47 = OpCompositeExtract %23 %44 2\n%48 = OpCompositeExtract %23 %44 3\n%49 = OpFAdd %23 %45 %33\n%50 = OpFAdd %23 %46 %33\n%51 = OpFAdd %23 %47 %33\n%52 = OpFAdd %23 %48 %33\n%53 = OpRawAccessChainNV %25 %41 %17 %17 %39 RobustnessPerComponentNV\n%54 = OpCompositeConstruct %24 %49 %50 %51 %52\nOpStore %53 %54 Aligned 16\n%55 = OpIMul %5 %18 %56\n%57 = OpAccessChain %21 %11 %58\n%59 = OpRawAccessChainNV %25 %57 %17 %17 %55 RobustnessPerComponentNV\n%60 = OpLoad %24 %59 Aligned 8\n%61 = OpCompositeExtract %23 %60 0\n%62 = OpCompositeExtract %23 %60 1\n%63 = OpCompositeExtract %23 %60 2\n%64 = OpCompositeExtract %23 %60 3\n%65 = OpFAdd %23 %61 %33\n%66 = OpFAdd %23 %62 %33\n%67 = OpFAdd %23 %63 %33\n%68 = OpFAdd %23 %64 %33\n%69 = OpRawAccessChainNV %25 %57 %17 %17 %55 RobustnessPerComponentNV\n%70 = OpCompositeConstruct %24 %65 %66 %67 %68\nOpStore %69 %70 Aligned 8\n%71 = OpShiftLeftLogical %5 %18 %8\n%72 = OpAccessChain %21 %11 %20\n%73 = OpRawAccessChainNV %25 %72 %17 %17 %71 RobustnessPerComponentNV\n%74 = OpLoad %24 %73 Aligned 32\n%75 = OpCompositeExtract %23 %74 0\n%76 = OpCompositeExtract %23 %74 1\n%77 = OpCompositeExtract %23 %74 2\n%78 = OpCompositeExtract %23 %74 3\n%79 = OpFAdd %23 %75 %33\n%80 = OpFAdd %23 %76 %33\n%81 = OpFAdd %23 %77 %33\n%82 = OpFAdd %23 %78 %33\n%83 = OpRawAccessChainNV %25 %72 %17 %17 %71 RobustnessPerComponentNV\n%84 = OpCompositeConstruct %24 %79 %80 %81 %82\nOpStore %83 %84 Aligned 32\n%85 = OpIMul %5 %18 %86\n%87 = OpAccessChain %21 %11 %40\n%88 = OpRawAccessChainNV %25 %87 %17 %17 %85 RobustnessPerComponentNV\n%89 = OpLoad %24 %88 Aligned 8\n%90 = OpCompositeExtract %23 %89 0\n%91 = OpCompositeExtract %23 %89 1\n%92 = OpCompositeExtract %23 %89 2\n%93 = OpCompositeExtract %23 %89 3\n%94 = OpFAdd %23 %90 %33\n%95 = OpFAdd %23 %91 %33\n%96 = OpFAdd %23 %92 %33\n%97 = OpFAdd %23 %93 %33\n%98 = OpRawAccessChainNV %25 %87 %17 %17 %85 RobustnessPerComponentNV\n%99 = OpCompositeConstruct %24 %94 %95 %96 %97\nOpStore %98 %99 Aligned 8\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-float1.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 2\n%19 = OpTypeFloat 32\n%20 = OpTypePointer StorageBuffer %19\n%24 = OpConstant %19 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpShiftLeftLogical %5 %16 %18\n%21 = OpRawAccessChainNV %20 %9 %15 %15 %17 RobustnessPerComponentNV\n%22 = OpLoad %19 %21 Aligned 4\n%23 = OpFAdd %19 %22 %24\n%25 = OpRawAccessChainNV %20 %9 %15 %15 %17 RobustnessPerComponentNV\nOpStore %25 %23 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-float2.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 2\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpTypePointer StorageBuffer %7\n%22 = OpTypeFloat 32\n%23 = OpTypeVector %22 2\n%24 = OpTypePointer StorageBuffer %23\n%30 = OpConstant %22 4\n%35 = OpConstant %5 3\n%37 = OpConstant %5 1\n%39 = OpConstant %5 8\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %47\n%47 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %8\n%21 = OpAccessChain %20 %11 %17\n%25 = OpRawAccessChainNV %24 %21 %17 %17 %19 RobustnessPerComponentNV\n%26 = OpLoad %23 %25 Aligned 4\n%27 = OpCompositeExtract %22 %26 0\n%28 = OpCompositeExtract %22 %26 1\n%29 = OpFAdd %22 %27 %30\n%31 = OpFAdd %22 %28 %30\n%32 = OpRawAccessChainNV %24 %21 %17 %17 %19 RobustnessPerComponentNV\n%33 = OpCompositeConstruct %23 %29 %31\nOpStore %32 %33 Aligned 4\n%34 = OpShiftLeftLogical %5 %18 %35\n%36 = OpAccessChain %20 %11 %37\n%38 = OpRawAccessChainNV %24 %36 %39 %18 %17 RobustnessPerElementNV\n%40 = OpLoad %23 %38 Aligned 8\n%41 = OpCompositeExtract %22 %40 0\n%42 = OpCompositeExtract %22 %40 1\n%43 = OpFAdd %22 %41 %30\n%44 = OpFAdd %22 %42 %30\n%45 = OpRawAccessChainNV %24 %36 %39 %18 %17 RobustnessPerElementNV\n%46 = OpCompositeConstruct %23 %43 %44\nOpStore %45 %46 Aligned 8\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-float3.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 4\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 2\n%21 = OpTypePointer StorageBuffer %7\n%23 = OpTypeFloat 32\n%24 = OpTypeVector %23 3\n%25 = OpTypePointer StorageBuffer %24\n%32 = OpConstant %23 4\n%38 = OpConstant %5 3\n%40 = OpConstant %5 1\n%52 = OpConstant %5 12\n%67 = OpConstant %5 16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %77\n%77 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpAccessChain %21 %11 %17\n%26 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%27 = OpLoad %24 %26 Aligned 4\n%28 = OpCompositeExtract %23 %27 0\n%29 = OpCompositeExtract %23 %27 1\n%30 = OpCompositeExtract %23 %27 2\n%31 = OpFAdd %23 %28 %32\n%33 = OpFAdd %23 %29 %32\n%34 = OpFAdd %23 %30 %32\n%35 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%36 = OpCompositeConstruct %24 %31 %33 %34\nOpStore %35 %36 Aligned 4\n%37 = OpShiftLeftLogical %5 %18 %38\n%39 = OpAccessChain %21 %11 %40\n%41 = OpRawAccessChainNV %25 %39 %17 %17 %37 RobustnessPerComponentNV\n%42 = OpLoad %24 %41 Aligned 8\n%43 = OpCompositeExtract %23 %42 0\n%44 = OpCompositeExtract %23 %42 1\n%45 = OpCompositeExtract %23 %42 2\n%46 = OpFAdd %23 %43 %32\n%47 = OpFAdd %23 %44 %32\n%48 = OpFAdd %23 %45 %32\n%49 = OpRawAccessChainNV %25 %39 %17 %17 %37 RobustnessPerComponentNV\n%50 = OpCompositeConstruct %24 %46 %47 %48\nOpStore %49 %50 Aligned 8\n%51 = OpIMul %5 %18 %52\n%53 = OpAccessChain %21 %11 %20\n%54 = OpRawAccessChainNV %25 %53 %17 %17 %51 RobustnessPerComponentNV\n%55 = OpLoad %24 %54 Aligned 4\n%56 = OpCompositeExtract %23 %55 0\n%57 = OpCompositeExtract %23 %55 1\n%58 = OpCompositeExtract %23 %55 2\n%59 = OpFAdd %23 %56 %32\n%60 = OpFAdd %23 %57 %32\n%61 = OpFAdd %23 %58 %32\n%62 = OpRawAccessChainNV %25 %53 %17 %17 %51 RobustnessPerComponentNV\n%63 = OpCompositeConstruct %24 %59 %60 %61\nOpStore %62 %63 Aligned 4\n%64 = OpShiftLeftLogical %5 %18 %8\n%65 = OpAccessChain %21 %11 %38\n%66 = OpRawAccessChainNV %25 %65 %67 %18 %17 RobustnessPerElementNV\n%68 = OpLoad %24 %66 Aligned 16\n%69 = OpCompositeExtract %23 %68 0\n%70 = OpCompositeExtract %23 %68 1\n%71 = OpCompositeExtract %23 %68 2\n%72 = OpFAdd %23 %69 %32\n%73 = OpFAdd %23 %70 %32\n%74 = OpFAdd %23 %71 %32\n%75 = OpRawAccessChainNV %25 %65 %67 %18 %17 RobustnessPerElementNV\n%76 = OpCompositeConstruct %24 %72 %73 %74\nOpStore %75 %76 Aligned 16\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-float4.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 103\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 5\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 2\n%21 = OpTypePointer StorageBuffer %7\n%23 = OpTypeFloat 32\n%24 = OpTypeVector %23 4\n%25 = OpTypePointer StorageBuffer %24\n%33 = OpConstant %23 4\n%40 = OpConstant %5 3\n%42 = OpConstant %5 1\n%56 = OpConstant %5 12\n%71 = OpConstant %5 4\n%74 = OpConstant %5 16\n%87 = OpConstant %5 20\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %101\n%101 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpAccessChain %21 %11 %17\n%26 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%27 = OpLoad %24 %26 Aligned 4\n%28 = OpCompositeExtract %23 %27 0\n%29 = OpCompositeExtract %23 %27 1\n%30 = OpCompositeExtract %23 %27 2\n%31 = OpCompositeExtract %23 %27 3\n%32 = OpFAdd %23 %28 %33\n%34 = OpFAdd %23 %29 %33\n%35 = OpFAdd %23 %30 %33\n%36 = OpFAdd %23 %31 %33\n%37 = OpRawAccessChainNV %25 %22 %17 %17 %19 RobustnessPerComponentNV\n%38 = OpCompositeConstruct %24 %32 %34 %35 %36\nOpStore %37 %38 Aligned 4\n%39 = OpShiftLeftLogical %5 %18 %40\n%41 = OpAccessChain %21 %11 %42\n%43 = OpRawAccessChainNV %25 %41 %17 %17 %39 RobustnessPerComponentNV\n%44 = OpLoad %24 %43 Aligned 8\n%45 = OpCompositeExtract %23 %44 0\n%46 = OpCompositeExtract %23 %44 1\n%47 = OpCompositeExtract %23 %44 2\n%48 = OpCompositeExtract %23 %44 3\n%49 = OpFAdd %23 %45 %33\n%50 = OpFAdd %23 %46 %33\n%51 = OpFAdd %23 %47 %33\n%52 = OpFAdd %23 %48 %33\n%53 = OpRawAccessChainNV %25 %41 %17 %17 %39 RobustnessPerComponentNV\n%54 = OpCompositeConstruct %24 %49 %50 %51 %52\nOpStore %53 %54 Aligned 8\n%55 = OpIMul %5 %18 %56\n%57 = OpAccessChain %21 %11 %20\n%58 = OpRawAccessChainNV %25 %57 %17 %17 %55 RobustnessPerComponentNV\n%59 = OpLoad %24 %58 Aligned 4\n%60 = OpCompositeExtract %23 %59 0\n%61 = OpCompositeExtract %23 %59 1\n%62 = OpCompositeExtract %23 %59 2\n%63 = OpCompositeExtract %23 %59 3\n%64 = OpFAdd %23 %60 %33\n%65 = OpFAdd %23 %61 %33\n%66 = OpFAdd %23 %62 %33\n%67 = OpFAdd %23 %63 %33\n%68 = OpRawAccessChainNV %25 %57 %17 %17 %55 RobustnessPerComponentNV\n%69 = OpCompositeConstruct %24 %64 %65 %66 %67\nOpStore %68 %69 Aligned 4\n%70 = OpShiftLeftLogical %5 %18 %71\n%72 = OpAccessChain %21 %11 %40\n%73 = OpRawAccessChainNV %25 %72 %74 %18 %17 RobustnessPerElementNV\n%75 = OpLoad %24 %73 Aligned 16\n%76 = OpCompositeExtract %23 %75 0\n%77 = OpCompositeExtract %23 %75 1\n%78 = OpCompositeExtract %23 %75 2\n%79 = OpCompositeExtract %23 %75 3\n%80 = OpFAdd %23 %76 %33\n%81 = OpFAdd %23 %77 %33\n%82 = OpFAdd %23 %78 %33\n%83 = OpFAdd %23 %79 %33\n%84 = OpRawAccessChainNV %25 %72 %74 %18 %17 RobustnessPerElementNV\n%85 = OpCompositeConstruct %24 %80 %81 %82 %83\nOpStore %84 %85 Aligned 16\n%86 = OpIMul %5 %18 %87\n%88 = OpAccessChain %21 %11 %71\n%89 = OpRawAccessChainNV %25 %88 %17 %17 %86 RobustnessPerComponentNV\n%90 = OpLoad %24 %89 Aligned 4\n%91 = OpCompositeExtract %23 %90 0\n%92 = OpCompositeExtract %23 %90 1\n%93 = OpCompositeExtract %23 %90 2\n%94 = OpCompositeExtract %23 %90 3\n%95 = OpFAdd %23 %91 %33\n%96 = OpFAdd %23 %92 %33\n%97 = OpFAdd %23 %93 %33\n%98 = OpFAdd %23 %94 %33\n%99 = OpRawAccessChainNV %25 %88 %17 %17 %86 RobustnessPerComponentNV\n%100 = OpCompositeConstruct %24 %95 %96 %97 %98\nOpStore %99 %100 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/bab-float4x4.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 168\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %14\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 2\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %5\n%17 = OpConstant %5 0\n%20 = OpConstant %5 6\n%21 = OpTypePointer StorageBuffer %7\n%23 = OpTypeFloat 32\n%24 = OpTypeVector %23 4\n%25 = OpTypePointer StorageBuffer %24\n%28 = OpConstant %5 4\n%29 = OpConstant %5 16\n%39 = OpConstant %5 1\n%53 = OpConstant %5 48\n%57 = OpConstant %5 3\n%64 = OpConstant %23 4\n%88 = OpConstant %5 32\n%98 = OpConstant %5 80\n%102 = OpConstant %5 5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %166\n%166 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %5 %16\n%19 = OpShiftLeftLogical %5 %18 %20\n%22 = OpAccessChain %21 %11 %17\n%27 = OpIMul %5 %18 %28\n%26 = OpRawAccessChainNV %25 %22 %29 %27 %17 RobustnessPerElementNV\n%30 = OpLoad %24 %26 Aligned 16\n%31 = OpCompositeExtract %23 %30 0\n%32 = OpCompositeExtract %23 %30 1\n%33 = OpCompositeExtract %23 %30 2\n%34 = OpCompositeExtract %23 %30 3\n%35 = OpBitwiseOr %5 %19 %29\n%37 = OpIMul %5 %18 %28\n%38 = OpIAdd %5 %37 %39\n%36 = OpRawAccessChainNV %25 %22 %29 %38 %17 RobustnessPerElementNV\n%40 = OpLoad %24 %36 Aligned 16\n%41 = OpCompositeExtract %23 %40 0\n%42 = OpCompositeExtract %23 %40 1\n%43 = OpCompositeExtract %23 %40 2\n%44 = OpCompositeExtract %23 %40 3\n%45 = OpIAdd %5 %35 %29\n%46 = OpRawAccessChainNV %25 %22 %17 %17 %45 RobustnessPerComponentNV\n%47 = OpLoad %24 %46 Aligned 4\n%48 = OpCompositeExtract %23 %47 0\n%49 = OpCompositeExtract %23 %47 1\n%50 = OpCompositeExtract %23 %47 2\n%51 = OpCompositeExtract %23 %47 3\n%52 = OpBitwiseOr %5 %19 %53\n%55 = OpIMul %5 %18 %28\n%56 = OpIAdd %5 %55 %57\n%54 = OpRawAccessChainNV %25 %22 %29 %56 %17 RobustnessPerElementNV\n%58 = OpLoad %24 %54 Aligned 16\n%59 = OpCompositeExtract %23 %58 0\n%60 = OpCompositeExtract %23 %58 1\n%61 = OpCompositeExtract %23 %58 2\n%62 = OpCompositeExtract %23 %58 3\n%63 = OpFAdd %23 %31 %64\n%65 = OpFAdd %23 %32 %64\n%66 = OpFAdd %23 %33 %64\n%67 = OpFAdd %23 %34 %64\n%68 = OpFAdd %23 %41 %64\n%69 = OpFAdd %23 %42 %64\n%70 = OpFAdd %23 %43 %64\n%71 = OpFAdd %23 %44 %64\n%72 = OpFAdd %23 %48 %64\n%73 = OpFAdd %23 %49 %64\n%74 = OpFAdd %23 %50 %64\n%75 = OpFAdd %23 %51 %64\n%76 = OpFAdd %23 %59 %64\n%77 = OpFAdd %23 %60 %64\n%78 = OpFAdd %23 %61 %64\n%79 = OpFAdd %23 %62 %64\n%81 = OpIMul %5 %18 %28\n%80 = OpRawAccessChainNV %25 %22 %29 %81 %17 RobustnessPerElementNV\n%82 = OpCompositeConstruct %24 %63 %68 %72 %76\nOpStore %80 %82 Aligned 16\n%84 = OpIMul %5 %18 %28\n%85 = OpIAdd %5 %84 %39\n%83 = OpRawAccessChainNV %25 %22 %29 %85 %17 RobustnessPerElementNV\n%86 = OpCompositeConstruct %24 %65 %69 %73 %77\nOpStore %83 %86 Aligned 16\n%87 = OpBitwiseOr %5 %19 %88\n%90 = OpIMul %5 %18 %28\n%91 = OpIAdd %5 %90 %8\n%89 = OpRawAccessChainNV %25 %22 %29 %91 %17 RobustnessPerElementNV\n%92 = OpCompositeConstruct %24 %66 %70 %74 %78\nOpStore %89 %92 Aligned 16\n%94 = OpIMul %5 %18 %28\n%95 = OpIAdd %5 %94 %57\n%93 = OpRawAccessChainNV %25 %22 %29 %95 %17 RobustnessPerElementNV\n%96 = OpCompositeConstruct %24 %67 %71 %75 %79\nOpStore %93 %96 Aligned 16\n%97 = OpIMul %5 %18 %98\n%99 = OpAccessChain %21 %11 %39\n%101 = OpIMul %5 %18 %102\n%100 = OpRawAccessChainNV %25 %99 %29 %101 %17 RobustnessPerElementNV\n%103 = OpLoad %24 %100 Aligned 16\n%104 = OpCompositeExtract %23 %103 0\n%105 = OpCompositeExtract %23 %103 1\n%106 = OpCompositeExtract %23 %103 2\n%107 = OpCompositeExtract %23 %103 3\n%108 = OpIAdd %5 %97 %29\n%110 = OpIMul %5 %18 %102\n%111 = OpIAdd %5 %110 %39\n%109 = OpRawAccessChainNV %25 %99 %29 %111 %17 RobustnessPerElementNV\n%112 = OpLoad %24 %109 Aligned 16\n%113 = OpCompositeExtract %23 %112 0\n%114 = OpCompositeExtract %23 %112 1\n%115 = OpCompositeExtract %23 %112 2\n%116 = OpCompositeExtract %23 %112 3\n%117 = OpIAdd %5 %97 %88\n%119 = OpIMul %5 %18 %102\n%120 = OpIAdd %5 %119 %8\n%118 = OpRawAccessChainNV %25 %99 %29 %120 %17 RobustnessPerElementNV\n%121 = OpLoad %24 %118 Aligned 16\n%122 = OpCompositeExtract %23 %121 0\n%123 = OpCompositeExtract %23 %121 1\n%124 = OpCompositeExtract %23 %121 2\n%125 = OpCompositeExtract %23 %121 3\n%126 = OpIAdd %5 %97 %53\n%128 = OpIMul %5 %18 %102\n%129 = OpIAdd %5 %128 %57\n%127 = OpRawAccessChainNV %25 %99 %29 %129 %17 RobustnessPerElementNV\n%130 = OpLoad %24 %127 Aligned 16\n%131 = OpCompositeExtract %23 %130 0\n%132 = OpCompositeExtract %23 %130 1\n%133 = OpCompositeExtract %23 %130 2\n%134 = OpCompositeExtract %23 %130 3\n%135 = OpFAdd %23 %104 %64\n%136 = OpFAdd %23 %105 %64\n%137 = OpFAdd %23 %106 %64\n%138 = OpFAdd %23 %107 %64\n%139 = OpFAdd %23 %113 %64\n%140 = OpFAdd %23 %114 %64\n%141 = OpFAdd %23 %115 %64\n%142 = OpFAdd %23 %116 %64\n%143 = OpFAdd %23 %122 %64\n%144 = OpFAdd %23 %123 %64\n%145 = OpFAdd %23 %124 %64\n%146 = OpFAdd %23 %125 %64\n%147 = OpFAdd %23 %131 %64\n%148 = OpFAdd %23 %132 %64\n%149 = OpFAdd %23 %133 %64\n%150 = OpFAdd %23 %134 %64\n%152 = OpIMul %5 %18 %102\n%151 = OpRawAccessChainNV %25 %99 %29 %152 %17 RobustnessPerElementNV\n%153 = OpCompositeConstruct %24 %135 %139 %143 %147\nOpStore %151 %153 Aligned 16\n%155 = OpIMul %5 %18 %102\n%156 = OpIAdd %5 %155 %39\n%154 = OpRawAccessChainNV %25 %99 %29 %156 %17 RobustnessPerElementNV\n%157 = OpCompositeConstruct %24 %136 %140 %144 %148\nOpStore %154 %157 Aligned 16\n%159 = OpIMul %5 %18 %102\n%160 = OpIAdd %5 %159 %8\n%158 = OpRawAccessChainNV %25 %99 %29 %160 %17 RobustnessPerElementNV\n%161 = OpCompositeConstruct %24 %137 %141 %145 %149\nOpStore %158 %161 Aligned 16\n%163 = OpIMul %5 %18 %102\n%164 = OpIAdd %5 %163 %57\n%162 = OpRawAccessChainNV %25 %99 %29 %164 %17 RobustnessPerElementNV\n%165 = OpCompositeConstruct %24 %138 %142 %146 %150\nOpStore %162 %165 Aligned 16\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-float1.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpTypePointer StorageBuffer %17\n%20 = OpConstant %5 4\n%23 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%19 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%21 = OpLoad %17 %19 Aligned 4\n%22 = OpFAdd %17 %21 %23\n%24 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\nOpStore %24 %22 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-float2.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 2\n%19 = OpTypePointer StorageBuffer %18\n%21 = OpConstant %5 8\n%26 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%20 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%22 = OpLoad %18 %20 Aligned 8\n%23 = OpCompositeExtract %17 %22 0\n%24 = OpCompositeExtract %17 %22 1\n%25 = OpFAdd %17 %23 %26\n%27 = OpFAdd %17 %24 %26\n%28 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%29 = OpCompositeConstruct %18 %25 %27\nOpStore %28 %29 Aligned 8\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-float3.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 3\n%19 = OpTypePointer StorageBuffer %18\n%21 = OpConstant %5 12\n%27 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%20 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%22 = OpLoad %18 %20 Aligned 4\n%23 = OpCompositeExtract %17 %22 0\n%24 = OpCompositeExtract %17 %22 1\n%25 = OpCompositeExtract %17 %22 2\n%26 = OpFAdd %17 %23 %27\n%28 = OpFAdd %17 %24 %27\n%29 = OpFAdd %17 %25 %27\n%30 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%31 = OpCompositeConstruct %18 %26 %28 %29\nOpStore %30 %31 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-float4.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 4\n%19 = OpTypePointer StorageBuffer %18\n%21 = OpConstant %5 16\n%28 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%20 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%22 = OpLoad %18 %20 Aligned 16\n%23 = OpCompositeExtract %17 %22 0\n%24 = OpCompositeExtract %17 %22 1\n%25 = OpCompositeExtract %17 %22 2\n%26 = OpCompositeExtract %17 %22 3\n%27 = OpFAdd %17 %23 %28\n%29 = OpFAdd %17 %24 %28\n%30 = OpFAdd %17 %25 %28\n%31 = OpFAdd %17 %26 %28\n%32 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%33 = OpCompositeConstruct %18 %27 %29 %30 %31\nOpStore %32 %33 Aligned 16\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-float4x4.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 75\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 4\n%19 = OpTypePointer StorageBuffer %18\n%21 = OpConstant %5 64\n%28 = OpConstant %5 16\n%35 = OpConstant %5 32\n%42 = OpConstant %5 48\n%49 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%20 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%22 = OpLoad %18 %20 Aligned 16\n%23 = OpCompositeExtract %17 %22 0\n%24 = OpCompositeExtract %17 %22 1\n%25 = OpCompositeExtract %17 %22 2\n%26 = OpCompositeExtract %17 %22 3\n%27 = OpRawAccessChainNV %19 %9 %21 %16 %28 RobustnessPerElementNV\n%29 = OpLoad %18 %27 Aligned 16\n%30 = OpCompositeExtract %17 %29 0\n%31 = OpCompositeExtract %17 %29 1\n%32 = OpCompositeExtract %17 %29 2\n%33 = OpCompositeExtract %17 %29 3\n%34 = OpRawAccessChainNV %19 %9 %21 %16 %35 RobustnessPerElementNV\n%36 = OpLoad %18 %34 Aligned 16\n%37 = OpCompositeExtract %17 %36 0\n%38 = OpCompositeExtract %17 %36 1\n%39 = OpCompositeExtract %17 %36 2\n%40 = OpCompositeExtract %17 %36 3\n%41 = OpRawAccessChainNV %19 %9 %21 %16 %42 RobustnessPerElementNV\n%43 = OpLoad %18 %41 Aligned 16\n%44 = OpCompositeExtract %17 %43 0\n%45 = OpCompositeExtract %17 %43 1\n%46 = OpCompositeExtract %17 %43 2\n%47 = OpCompositeExtract %17 %43 3\n%48 = OpFAdd %17 %23 %49\n%50 = OpFAdd %17 %30 %49\n%51 = OpFAdd %17 %37 %49\n%52 = OpFAdd %17 %44 %49\n%53 = OpFAdd %17 %24 %49\n%54 = OpFAdd %17 %31 %49\n%55 = OpFAdd %17 %38 %49\n%56 = OpFAdd %17 %45 %49\n%57 = OpFAdd %17 %25 %49\n%58 = OpFAdd %17 %32 %49\n%59 = OpFAdd %17 %39 %49\n%60 = OpFAdd %17 %46 %49\n%61 = OpFAdd %17 %26 %49\n%62 = OpFAdd %17 %33 %49\n%63 = OpFAdd %17 %40 %49\n%64 = OpFAdd %17 %47 %49\n%65 = OpRawAccessChainNV %19 %9 %21 %16 %15 RobustnessPerElementNV\n%66 = OpCompositeConstruct %18 %48 %53 %57 %61\nOpStore %65 %66 Aligned 16\n%67 = OpRawAccessChainNV %19 %9 %21 %16 %28 RobustnessPerElementNV\n%68 = OpCompositeConstruct %18 %50 %54 %58 %62\nOpStore %67 %68 Aligned 16\n%69 = OpRawAccessChainNV %19 %9 %21 %16 %35 RobustnessPerElementNV\n%70 = OpCompositeConstruct %18 %51 %55 %59 %63\nOpStore %69 %70 Aligned 16\n%71 = OpRawAccessChainNV %19 %9 %21 %16 %42 RobustnessPerElementNV\n%72 = OpCompositeConstruct %18 %52 %56 %60 %64\nOpStore %71 %72 Aligned 16\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-half1.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DenormPreserve\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 16\n%18 = OpTypePointer StorageBuffer %17\n%20 = OpConstant %5 2\n%23 = OpConstant %17 0x1p+2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%19 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%21 = OpLoad %17 %19 Aligned 2\n%22 = OpFAdd %17 %21 %23\n%24 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\nOpStore %24 %22 Aligned 2\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-min16float1.raw-access-chains.noglsl.ssbo.sm60.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\nOpDecorate %22 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpTypePointer StorageBuffer %17\n%20 = OpConstant %5 4\n%23 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%19 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%21 = OpLoad %17 %19 Aligned 4\n%22 = OpFAdd %17 %21 %23\n%24 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\nOpStore %24 %22 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-min16float1.raw-access-chains.noglsl.ssbo.sm60.native-fp16.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DenormPreserve\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeFloat 32\n%18 = OpTypePointer StorageBuffer %17\n%20 = OpConstant %5 4\n%22 = OpTypeFloat 16\n%25 = OpConstant %22 0x1p+2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%19 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%21 = OpLoad %17 %19 Aligned 4\n%23 = OpFConvert %22 %21\n%24 = OpFAdd %22 %23 %25\n%26 = OpFConvert %17 %24\n%27 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\nOpStore %27 %26 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-min16uint1.raw-access-chains.noglsl.ssbo.sm60.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeInt 16 0\n%18 = OpTypePointer StorageBuffer %17\n%20 = OpConstant %5 4\n%23 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%19 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%21 = OpLoad %17 %19 Aligned 2\n%22 = OpIAdd %17 %21 %23\n%24 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\nOpStore %24 %22 Aligned 2\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-min16uint1.raw-access-chains.noglsl.ssbo.sm60.native-fp16.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypePointer StorageBuffer %5\n%19 = OpConstant %5 4\n%21 = OpTypeInt 16 0\n%24 = OpConstant %21 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpRawAccessChainNV %17 %9 %19 %16 %15 RobustnessPerElementNV\n%20 = OpLoad %5 %18 Aligned 4\n%22 = OpUConvert %21 %20\n%23 = OpIAdd %21 %22 %24\n%25 = OpUConvert %5 %23\n%26 = OpRawAccessChainNV %17 %9 %19 %16 %15 RobustnessPerElementNV\nOpStore %26 %25 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-uint1.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 25\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypePointer StorageBuffer %5\n%19 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %23\n%23 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpRawAccessChainNV %17 %9 %19 %16 %15 RobustnessPerElementNV\n%20 = OpLoad %5 %18 Aligned 4\n%21 = OpIAdd %5 %20 %19\n%22 = OpRawAccessChainNV %17 %9 %19 %16 %15 RobustnessPerElementNV\nOpStore %22 %21 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-uint2.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 31\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeVector %5 2\n%18 = OpTypePointer StorageBuffer %17\n%20 = OpConstant %5 8\n%25 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %29\n%29 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%19 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%21 = OpLoad %17 %19 Aligned 8\n%22 = OpCompositeExtract %5 %21 0\n%23 = OpCompositeExtract %5 %21 1\n%24 = OpIAdd %5 %22 %25\n%26 = OpIAdd %5 %23 %25\n%27 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%28 = OpCompositeConstruct %17 %24 %26\nOpStore %27 %28 Aligned 8\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-uint3.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypePointer StorageBuffer %10\n%19 = OpConstant %5 12\n%25 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpRawAccessChainNV %17 %9 %19 %16 %15 RobustnessPerElementNV\n%20 = OpLoad %10 %18 Aligned 4\n%21 = OpCompositeExtract %5 %20 0\n%22 = OpCompositeExtract %5 %20 1\n%23 = OpCompositeExtract %5 %20 2\n%24 = OpIAdd %5 %21 %25\n%26 = OpIAdd %5 %22 %25\n%27 = OpIAdd %5 %23 %25\n%28 = OpRawAccessChainNV %17 %9 %19 %16 %15 RobustnessPerElementNV\n%29 = OpCompositeConstruct %10 %24 %26 %27\nOpStore %28 %29 Aligned 4\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/raw-access/structured-uint4.raw-access-chains.noglsl.ssbo.comp",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability RawAccessChainsNV\nOpExtension \"SPV_NV_raw_access_chains\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeVector %5 4\n%18 = OpTypePointer StorageBuffer %17\n%20 = OpConstant %5 16\n%27 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%19 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%21 = OpLoad %17 %19 Aligned 16\n%22 = OpCompositeExtract %5 %21 0\n%23 = OpCompositeExtract %5 %21 1\n%24 = OpCompositeExtract %5 %21 2\n%25 = OpCompositeExtract %5 %21 3\n%26 = OpIAdd %5 %22 %27\n%28 = OpIAdd %5 %23 %27\n%29 = OpIAdd %5 %24 %27\n%30 = OpIAdd %5 %25 %27\n%31 = OpRawAccessChainNV %18 %9 %20 %16 %15 RobustnessPerElementNV\n%32 = OpCompositeConstruct %17 %26 %28 %29 %30\nOpStore %31 %32 Aligned 16\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/resources/acceleration-structure.bindless.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _15\n{\n    vec4 _m0;\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _12[];\nlayout(location = 0) rayPayloadEXT _15 _17;\nlayout(location = 1) rayPayloadEXT _15 _18;\nlayout(location = 2) rayPayloadEXT _15 _19;\n\nvoid main()\n{\n    _19._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n    traceRayEXT(_12[registers._m0 + 110u], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 2);\n    _18._m0 = _19._m0;\n    traceRayEXT(_12[registers._m0 + 3u], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    _17._m0 = _18._m0;\n    traceRayEXT(_12[nonuniformEXT((registers._m0 + 100u) + uint(int(_18._m0.w)))], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 65\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %17 %18 %19\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %58 NonUniform\nOpDecorate %59 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeAccelerationStructureKHR\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeStruct %14\n%16 = OpTypePointer RayPayloadKHR %15\n%17 = OpVariable %16 RayPayloadKHR\n%18 = OpVariable %16 RayPayloadKHR\n%19 = OpVariable %16 RayPayloadKHR\n%20 = OpTypePointer UniformConstant %9\n%22 = OpTypePointer PushConstant %5\n%24 = OpConstant %5 0\n%27 = OpConstant %5 110\n%29 = OpTypePointer RayPayloadKHR %14\n%31 = OpConstant %13 1\n%32 = OpConstant %13 2\n%33 = OpConstant %13 3\n%34 = OpConstant %13 4\n%35 = OpConstantComposite %14 %31 %32 %33 %34\n%36 = OpConstant %13 0\n%37 = OpTypeVector %13 3\n%45 = OpConstant %5 3\n%57 = OpConstant %5 100\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %63\n%63 = OpLabel\n%23 = OpAccessChain %22 %8 %24\n%25 = OpLoad %5 %23\n%26 = OpIAdd %5 %25 %27\n%21 = OpAccessChain %20 %12 %26\n%28 = OpLoad %9 %21\n%30 = OpInBoundsAccessChain %29 %19 %24\nOpStore %30 %35\n%38 = OpCompositeConstruct %37 %31 %32 %33\n%39 = OpCompositeConstruct %37 %36 %36 %31\nOpTraceRayKHR %28 %24 %24 %24 %24 %24 %38 %31 %39 %34 %19\n%40 = OpLoad %14 %30\n%42 = OpAccessChain %22 %8 %24\n%43 = OpLoad %5 %42\n%44 = OpIAdd %5 %43 %45\n%41 = OpAccessChain %20 %12 %44\n%46 = OpLoad %9 %41\n%47 = OpInBoundsAccessChain %29 %18 %24\nOpStore %47 %40\n%48 = OpCompositeConstruct %37 %31 %32 %33\n%49 = OpCompositeConstruct %37 %36 %36 %31\nOpTraceRayKHR %46 %24 %24 %24 %24 %24 %48 %31 %49 %34 %18\n%50 = OpLoad %14 %47\n%51 = OpCompositeExtract %13 %50 3\n%52 = OpConvertFToS %5 %51\n%54 = OpAccessChain %22 %8 %24\n%55 = OpLoad %5 %54\n%56 = OpIAdd %5 %55 %57\n%58 = OpIAdd %5 %56 %52\n%53 = OpAccessChain %20 %12 %58\n%59 = OpLoad %9 %53\n%60 = OpInBoundsAccessChain %29 %17 %24\nOpStore %60 %50\n%61 = OpCompositeConstruct %37 %31 %32 %33\n%62 = OpCompositeConstruct %37 %36 %36 %31\nOpTraceRayKHR %59 %24 %24 %24 %24 %24 %61 %31 %62 %34 %17\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/acceleration-structure.bindless.ssbo-rtas.local-root-signature.raw-va-stride-offset.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _23\n{\n    vec4 _m0;\n};\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer RTASHeap\n{\n    uvec2 _m0[];\n} _20;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) rayPayloadEXT _23 _25;\nlayout(location = 1) rayPayloadEXT _23 _26;\nlayout(location = 2) rayPayloadEXT _23 _27;\nlayout(location = 3) rayPayloadEXT _23 _28;\n\nvoid main()\n{\n    _28._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n    traceRayEXT(accelerationStructureEXT(_20._m0[(4u * subgroupBroadcastFirst(registers._m0 + 110u)) + 3u]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 3);\n    _27._m0 = _28._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[(4u * subgroupBroadcastFirst(registers._m0 + 3u)) + 3u]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 2);\n    _26._m0 = _27._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[(4u * ((registers._m0 + 100u) + uint(int(_27._m0.w)))) + 3u]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    _25._m0 = _26._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[(4u * subgroupBroadcastFirst((SBT._m7.x >> 6u) + 210u)) + 3u]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 104\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %16 %20 %25 %26 %27 %28\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %14 \"SBTBlock\"\nOpName %16 \"SBT\"\nOpName %18 \"RTASHeap\"\nOpName %23 \"\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 4\nOpDecorate %12 ArrayStride 4\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpMemberDecorate %14 1 Offset 20\nOpMemberDecorate %14 2 Offset 48\nOpMemberDecorate %14 3 Offset 56\nOpMemberDecorate %14 4 Offset 64\nOpMemberDecorate %14 5 Offset 72\nOpMemberDecorate %14 6 Offset 80\nOpMemberDecorate %14 7 Offset 88\nOpMemberDecorate %14 8 Offset 96\nOpMemberDecorate %14 9 Offset 104\nOpMemberDecorate %14 10 Offset 112\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpConstant %5 5\n%10 = OpTypeArray %5 %9\n%11 = OpConstant %5 6\n%12 = OpTypeArray %5 %11\n%13 = OpTypeVector %5 2\n%14 = OpTypeStruct %10 %12 %13 %13 %13 %13 %13 %13 %13 %13 %13\n%15 = OpTypePointer ShaderRecordBufferKHR %14\n%16 = OpVariable %15 ShaderRecordBufferKHR\n%17 = OpTypeRuntimeArray %13\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypeStruct %22\n%24 = OpTypePointer RayPayloadKHR %23\n%25 = OpVariable %24 RayPayloadKHR\n%26 = OpVariable %24 RayPayloadKHR\n%27 = OpVariable %24 RayPayloadKHR\n%28 = OpVariable %24 RayPayloadKHR\n%29 = OpTypePointer PushConstant %5\n%31 = OpConstant %5 0\n%34 = OpConstant %5 110\n%36 = OpConstant %5 3\n%38 = OpConstant %5 4\n%40 = OpTypePointer StorageBuffer %13\n%43 = OpTypeAccelerationStructureKHR\n%45 = OpTypePointer RayPayloadKHR %22\n%47 = OpConstant %21 1\n%48 = OpConstant %21 2\n%49 = OpConstant %21 3\n%50 = OpConstant %21 4\n%51 = OpConstantComposite %22 %47 %48 %49 %50\n%52 = OpConstant %21 0\n%53 = OpTypeVector %21 3\n%75 = OpConstant %5 100\n%86 = OpTypePointer ShaderRecordBufferKHR %5\n%88 = OpConstant %5 7\n%92 = OpConstant %5 210\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %102\n%102 = OpLabel\n%30 = OpAccessChain %29 %8 %31\n%32 = OpLoad %5 %30\n%33 = OpIAdd %5 %32 %34\n%35 = OpGroupNonUniformBroadcastFirst %5 %36 %33\n%37 = OpIMul %5 %38 %35\n%39 = OpIAdd %5 %37 %36\n%41 = OpAccessChain %40 %20 %31 %39\n%42 = OpLoad %13 %41\n%44 = OpConvertUToAccelerationStructureKHR %43 %42\n%46 = OpInBoundsAccessChain %45 %28 %31\nOpStore %46 %51\n%54 = OpCompositeConstruct %53 %47 %48 %49\n%55 = OpCompositeConstruct %53 %52 %52 %47\nOpTraceRayKHR %44 %31 %31 %31 %31 %31 %54 %47 %55 %50 %28\n%56 = OpLoad %22 %46\n%57 = OpAccessChain %29 %8 %31\n%58 = OpLoad %5 %57\n%59 = OpIAdd %5 %58 %36\n%60 = OpGroupNonUniformBroadcastFirst %5 %36 %59\n%61 = OpIMul %5 %38 %60\n%62 = OpIAdd %5 %61 %36\n%63 = OpAccessChain %40 %20 %31 %62\n%64 = OpLoad %13 %63\n%65 = OpConvertUToAccelerationStructureKHR %43 %64\n%66 = OpInBoundsAccessChain %45 %27 %31\nOpStore %66 %56\n%67 = OpCompositeConstruct %53 %47 %48 %49\n%68 = OpCompositeConstruct %53 %52 %52 %47\nOpTraceRayKHR %65 %31 %31 %31 %31 %31 %67 %47 %68 %50 %27\n%69 = OpLoad %22 %66\n%70 = OpCompositeExtract %21 %69 3\n%71 = OpConvertFToS %5 %70\n%72 = OpAccessChain %29 %8 %31\n%73 = OpLoad %5 %72\n%74 = OpIAdd %5 %73 %75\n%76 = OpIAdd %5 %74 %71\n%77 = OpIMul %5 %38 %76\n%78 = OpIAdd %5 %77 %36\n%79 = OpAccessChain %40 %20 %31 %78\n%80 = OpLoad %13 %79\n%81 = OpConvertUToAccelerationStructureKHR %43 %80\n%82 = OpInBoundsAccessChain %45 %26 %31\nOpStore %82 %69\n%83 = OpCompositeConstruct %53 %47 %48 %49\n%84 = OpCompositeConstruct %53 %52 %52 %47\nOpTraceRayKHR %81 %31 %31 %31 %31 %31 %83 %47 %84 %50 %26\n%85 = OpLoad %22 %82\n%87 = OpAccessChain %86 %16 %88 %31\n%89 = OpLoad %5 %87\n%90 = OpShiftRightLogical %5 %89 %11\n%91 = OpIAdd %5 %90 %92\n%93 = OpGroupNonUniformBroadcastFirst %5 %36 %91\n%94 = OpIMul %5 %38 %93\n%95 = OpIAdd %5 %94 %36\n%96 = OpAccessChain %40 %20 %31 %95\n%97 = OpLoad %13 %96\n%98 = OpConvertUToAccelerationStructureKHR %43 %97\n%99 = OpInBoundsAccessChain %45 %25 %31\nOpStore %99 %85\n%100 = OpCompositeConstruct %53 %47 %48 %49\n%101 = OpCompositeConstruct %53 %52 %52 %47\nOpTraceRayKHR %98 %31 %31 %31 %31 %31 %100 %47 %101 %50 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/acceleration-structure.bindless.ssbo-rtas.local-root-signature.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _23\n{\n    vec4 _m0;\n};\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer RTASHeap\n{\n    uvec2 _m0[];\n} _20;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) rayPayloadEXT _23 _25;\nlayout(location = 1) rayPayloadEXT _23 _26;\nlayout(location = 2) rayPayloadEXT _23 _27;\nlayout(location = 3) rayPayloadEXT _23 _28;\n\nvoid main()\n{\n    _28._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n    traceRayEXT(accelerationStructureEXT(_20._m0[subgroupBroadcastFirst(registers._m0 + 110u)]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 3);\n    _27._m0 = _28._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[subgroupBroadcastFirst(registers._m0 + 3u)]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 2);\n    _26._m0 = _27._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[(registers._m0 + 100u) + uint(int(_27._m0.w))]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    _25._m0 = _26._m0;\n    traceRayEXT(accelerationStructureEXT(_20._m0[subgroupBroadcastFirst((SBT._m7.x >> 6u) + 210u)]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %16 %20 %25 %26 %27 %28\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %14 \"SBTBlock\"\nOpName %16 \"SBT\"\nOpName %18 \"RTASHeap\"\nOpName %23 \"\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 4\nOpDecorate %12 ArrayStride 4\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpMemberDecorate %14 1 Offset 20\nOpMemberDecorate %14 2 Offset 48\nOpMemberDecorate %14 3 Offset 56\nOpMemberDecorate %14 4 Offset 64\nOpMemberDecorate %14 5 Offset 72\nOpMemberDecorate %14 6 Offset 80\nOpMemberDecorate %14 7 Offset 88\nOpMemberDecorate %14 8 Offset 96\nOpMemberDecorate %14 9 Offset 104\nOpMemberDecorate %14 10 Offset 112\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpConstant %5 5\n%10 = OpTypeArray %5 %9\n%11 = OpConstant %5 6\n%12 = OpTypeArray %5 %11\n%13 = OpTypeVector %5 2\n%14 = OpTypeStruct %10 %12 %13 %13 %13 %13 %13 %13 %13 %13 %13\n%15 = OpTypePointer ShaderRecordBufferKHR %14\n%16 = OpVariable %15 ShaderRecordBufferKHR\n%17 = OpTypeRuntimeArray %13\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypeStruct %22\n%24 = OpTypePointer RayPayloadKHR %23\n%25 = OpVariable %24 RayPayloadKHR\n%26 = OpVariable %24 RayPayloadKHR\n%27 = OpVariable %24 RayPayloadKHR\n%28 = OpVariable %24 RayPayloadKHR\n%29 = OpTypePointer PushConstant %5\n%31 = OpConstant %5 0\n%34 = OpConstant %5 110\n%36 = OpConstant %5 3\n%37 = OpTypePointer StorageBuffer %13\n%40 = OpTypeAccelerationStructureKHR\n%42 = OpTypePointer RayPayloadKHR %22\n%44 = OpConstant %21 1\n%45 = OpConstant %21 2\n%46 = OpConstant %21 3\n%47 = OpConstant %21 4\n%48 = OpConstantComposite %22 %44 %45 %46 %47\n%49 = OpConstant %21 0\n%50 = OpTypeVector %21 3\n%70 = OpConstant %5 100\n%79 = OpTypePointer ShaderRecordBufferKHR %5\n%81 = OpConstant %5 7\n%85 = OpConstant %5 210\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%30 = OpAccessChain %29 %8 %31\n%32 = OpLoad %5 %30\n%33 = OpIAdd %5 %32 %34\n%35 = OpGroupNonUniformBroadcastFirst %5 %36 %33\n%38 = OpAccessChain %37 %20 %31 %35\n%39 = OpLoad %13 %38\n%41 = OpConvertUToAccelerationStructureKHR %40 %39\n%43 = OpInBoundsAccessChain %42 %28 %31\nOpStore %43 %48\n%51 = OpCompositeConstruct %50 %44 %45 %46\n%52 = OpCompositeConstruct %50 %49 %49 %44\nOpTraceRayKHR %41 %31 %31 %31 %31 %31 %51 %44 %52 %47 %28\n%53 = OpLoad %22 %43\n%54 = OpAccessChain %29 %8 %31\n%55 = OpLoad %5 %54\n%56 = OpIAdd %5 %55 %36\n%57 = OpGroupNonUniformBroadcastFirst %5 %36 %56\n%58 = OpAccessChain %37 %20 %31 %57\n%59 = OpLoad %13 %58\n%60 = OpConvertUToAccelerationStructureKHR %40 %59\n%61 = OpInBoundsAccessChain %42 %27 %31\nOpStore %61 %53\n%62 = OpCompositeConstruct %50 %44 %45 %46\n%63 = OpCompositeConstruct %50 %49 %49 %44\nOpTraceRayKHR %60 %31 %31 %31 %31 %31 %62 %44 %63 %47 %27\n%64 = OpLoad %22 %61\n%65 = OpCompositeExtract %21 %64 3\n%66 = OpConvertFToS %5 %65\n%67 = OpAccessChain %29 %8 %31\n%68 = OpLoad %5 %67\n%69 = OpIAdd %5 %68 %70\n%71 = OpIAdd %5 %69 %66\n%72 = OpAccessChain %37 %20 %31 %71\n%73 = OpLoad %13 %72\n%74 = OpConvertUToAccelerationStructureKHR %40 %73\n%75 = OpInBoundsAccessChain %42 %26 %31\nOpStore %75 %64\n%76 = OpCompositeConstruct %50 %44 %45 %46\n%77 = OpCompositeConstruct %50 %49 %49 %44\nOpTraceRayKHR %74 %31 %31 %31 %31 %31 %76 %44 %77 %47 %26\n%78 = OpLoad %22 %75\n%80 = OpAccessChain %79 %16 %81 %31\n%82 = OpLoad %5 %80\n%83 = OpShiftRightLogical %5 %82 %11\n%84 = OpIAdd %5 %83 %85\n%86 = OpGroupNonUniformBroadcastFirst %5 %36 %84\n%87 = OpAccessChain %37 %20 %31 %86\n%88 = OpLoad %13 %87\n%89 = OpConvertUToAccelerationStructureKHR %40 %88\n%90 = OpInBoundsAccessChain %42 %25 %31\nOpStore %90 %78\n%91 = OpCompositeConstruct %50 %44 %45 %46\n%92 = OpCompositeConstruct %50 %49 %49 %44\nOpTraceRayKHR %89 %31 %31 %31 %31 %31 %91 %44 %92 %47 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/acceleration-structure.local-root-signature.root-descriptor.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _23\n{\n    vec4 _m0;\n};\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(set = 0, binding = 1) uniform accelerationStructureEXT AS_Plain;\nlayout(location = 0) rayPayloadEXT _23 _25;\nlayout(location = 1) rayPayloadEXT _23 _26;\nlayout(location = 2) rayPayloadEXT _23 _27;\n\nvoid main()\n{\n    _27._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n    traceRayEXT(accelerationStructureEXT(SBT._m2), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 2);\n    _26._m0 = _27._m0;\n    traceRayEXT(accelerationStructureEXT(registers._m1), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    _25._m0 = _26._m0;\n    traceRayEXT(AS_Plain, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %9 %16 %20 %25 %26 %27\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %14 \"SBTBlock\"\nOpName %16 \"SBT\"\nOpName %20 \"AS_Plain\"\nOpName %23 \"\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 4\nOpDecorate %13 ArrayStride 4\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpMemberDecorate %14 1 Offset 20\nOpMemberDecorate %14 2 Offset 48\nOpMemberDecorate %14 3 Offset 56\nOpMemberDecorate %14 4 Offset 64\nOpMemberDecorate %14 5 Offset 72\nOpMemberDecorate %14 6 Offset 80\nOpMemberDecorate %14 7 Offset 88\nOpMemberDecorate %14 8 Offset 96\nOpMemberDecorate %14 9 Offset 104\nOpMemberDecorate %14 10 Offset 112\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpConstant %5 5\n%11 = OpTypeArray %5 %10\n%12 = OpConstant %5 6\n%13 = OpTypeArray %5 %12\n%14 = OpTypeStruct %11 %13 %6 %6 %6 %6 %6 %6 %6 %6 %6\n%15 = OpTypePointer ShaderRecordBufferKHR %14\n%16 = OpVariable %15 ShaderRecordBufferKHR\n%17 = OpTypeInt 32 1\n%18 = OpTypeAccelerationStructureKHR\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypeStruct %22\n%24 = OpTypePointer RayPayloadKHR %23\n%25 = OpVariable %24 RayPayloadKHR\n%26 = OpVariable %24 RayPayloadKHR\n%27 = OpVariable %24 RayPayloadKHR\n%28 = OpTypePointer ShaderRecordBufferKHR %6\n%30 = OpConstant %5 2\n%33 = OpTypePointer RayPayloadKHR %22\n%35 = OpConstant %5 0\n%36 = OpConstant %21 1\n%37 = OpConstant %21 2\n%38 = OpConstant %21 3\n%39 = OpConstant %21 4\n%40 = OpConstantComposite %22 %36 %37 %38 %39\n%41 = OpConstant %21 0\n%42 = OpTypeVector %21 3\n%46 = OpTypePointer PushConstant %6\n%48 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%29 = OpAccessChain %28 %16 %30\n%31 = OpLoad %6 %29\n%32 = OpConvertUToAccelerationStructureKHR %18 %31\n%34 = OpInBoundsAccessChain %33 %27 %35\nOpStore %34 %40\n%43 = OpCompositeConstruct %42 %36 %37 %38\n%44 = OpCompositeConstruct %42 %41 %41 %36\nOpTraceRayKHR %32 %35 %35 %35 %35 %35 %43 %36 %44 %39 %27\n%45 = OpLoad %22 %34\n%47 = OpAccessChain %46 %9 %48\n%49 = OpLoad %6 %47\n%50 = OpConvertUToAccelerationStructureKHR %18 %49\n%51 = OpInBoundsAccessChain %33 %26 %35\nOpStore %51 %45\n%52 = OpCompositeConstruct %42 %36 %37 %38\n%53 = OpCompositeConstruct %42 %41 %41 %36\nOpTraceRayKHR %50 %35 %35 %35 %35 %35 %52 %36 %53 %39 %26\n%54 = OpLoad %22 %51\n%55 = OpLoad %18 %20\n%56 = OpInBoundsAccessChain %33 %25 %35\nOpStore %56 %54\n%57 = OpCompositeConstruct %42 %36 %37 %38\n%58 = OpCompositeConstruct %42 %41 %41 %36\nOpTraceRayKHR %55 %35 %35 %35 %35 %35 %57 %36 %58 %39 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/basic.input-attachment.frag",
    "content": "#version 460\n\nlayout(input_attachment_index = 0, set = 1000, binding = 0) uniform subpassInput _8;\nlayout(input_attachment_index = 1, set = 1000, binding = 1) uniform isubpassInput _12;\nlayout(input_attachment_index = 2, set = 1000, binding = 2) uniform usubpassInput _16;\nlayout(set = 1001, binding = 3) uniform subpassInput _17;\nlayout(set = 1001, binding = 4) uniform usubpassInput _18;\nlayout(input_attachment_index = 5, set = 1000, binding = 5) uniform subpassInputMS _21;\nlayout(set = 1001, binding = 6) uniform subpassInputMS _22;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _47 = subpassLoad(_8);\n    uvec4 _57 = uvec4(subpassLoad(_12));\n    uvec4 _66 = subpassLoad(_16);\n    vec4 _80 = subpassLoad(_21, uint(gl_SampleID));\n    float _88 = subpassLoad(_22, uint(gl_SampleID)).x + (float(subpassLoad(_18).x) + subpassLoad(_17).x);\n    SV_Target.x = (((_88 + _47.x) + float(int(_57.x))) + float(_66.x)) + _80.x;\n    SV_Target.y = (((_88 + _47.y) + float(int(_57.y))) + float(_66.y)) + _80.y;\n    SV_Target.z = (((_88 + _47.z) + float(int(_57.z))) + float(_66.z)) + _80.z;\n    SV_Target.w = (((_88 + _47.w) + float(int(_57.w))) + float(_66.w)) + _80.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 114\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageMultisample\nOpCapability SampleRateShading\nOpCapability InputAttachment\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %25 %27 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %25 \"SV_Position\"\nOpName %27 \"SV_SampleIndex\"\nOpName %29 \"SV_Target\"\nOpDecorate %8 DescriptorSet 1000\nOpDecorate %8 Binding 0\nOpDecorate %8 InputAttachmentIndex 0\nOpDecorate %12 DescriptorSet 1000\nOpDecorate %12 Binding 1\nOpDecorate %12 InputAttachmentIndex 1\nOpDecorate %16 DescriptorSet 1000\nOpDecorate %16 Binding 2\nOpDecorate %16 InputAttachmentIndex 2\nOpDecorate %17 DescriptorSet 1001\nOpDecorate %17 Binding 3\nOpDecorate %18 DescriptorSet 1001\nOpDecorate %18 Binding 4\nOpDecorate %21 DescriptorSet 1000\nOpDecorate %21 Binding 5\nOpDecorate %21 InputAttachmentIndex 5\nOpDecorate %22 DescriptorSet 1001\nOpDecorate %22 Binding 6\nOpDecorate %25 BuiltIn FragCoord\nOpDecorate %27 BuiltIn SampleId\nOpDecorate %27 Flat\nOpDecorate %29 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 SubpassData 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 1\n%10 = OpTypeImage %9 SubpassData 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeInt 32 0\n%14 = OpTypeImage %13 SubpassData 0 0 0 2 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpVariable %7 UniformConstant\n%18 = OpVariable %15 UniformConstant\n%19 = OpTypeImage %5 SubpassData 0 0 1 2 Unknown\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpVariable %20 UniformConstant\n%23 = OpTypeVector %5 4\n%24 = OpTypePointer Input %23\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Input %13\n%27 = OpVariable %26 Input\n%28 = OpTypePointer Output %23\n%29 = OpVariable %28 Output\n%37 = OpTypePointer Input %5\n%39 = OpConstant %13 0\n%42 = OpConstant %13 1\n%48 = OpTypeVector %13 2\n%49 = OpConstantComposite %48 %39 %39\n%54 = OpTypeVector %9 4\n%56 = OpTypeVector %13 4\n%105 = OpTypePointer Output %5\n%109 = OpConstant %13 2\n%111 = OpConstant %13 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %112\n%112 = OpLabel\n%30 = OpLoad %19 %22\n%31 = OpLoad %19 %21\n%32 = OpLoad %14 %18\n%33 = OpLoad %6 %17\n%34 = OpLoad %14 %16\n%35 = OpLoad %10 %12\n%36 = OpLoad %6 %8\n%38 = OpAccessChain %37 %25 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %37 %25 %42\n%43 = OpLoad %5 %41\n%44 = OpLoad %13 %27\n%45 = OpConvertFToS %13 %40\n%46 = OpConvertFToS %13 %43\n%47 = OpImageRead %23 %36 %49 None\n%50 = OpCompositeExtract %5 %47 0\n%51 = OpCompositeExtract %5 %47 1\n%52 = OpCompositeExtract %5 %47 2\n%53 = OpCompositeExtract %5 %47 3\n%55 = OpImageRead %54 %35 %49 None\n%57 = OpBitcast %56 %55\n%58 = OpCompositeExtract %13 %57 0\n%59 = OpCompositeExtract %13 %57 1\n%60 = OpCompositeExtract %13 %57 2\n%61 = OpCompositeExtract %13 %57 3\n%62 = OpConvertSToF %5 %58\n%63 = OpConvertSToF %5 %59\n%64 = OpConvertSToF %5 %60\n%65 = OpConvertSToF %5 %61\n%66 = OpImageRead %56 %34 %49 None\n%67 = OpCompositeExtract %13 %66 0\n%68 = OpCompositeExtract %13 %66 1\n%69 = OpCompositeExtract %13 %66 2\n%70 = OpCompositeExtract %13 %66 3\n%71 = OpConvertUToF %5 %67\n%72 = OpConvertUToF %5 %68\n%73 = OpConvertUToF %5 %69\n%74 = OpConvertUToF %5 %70\n%75 = OpImageRead %23 %33 %49 None\n%76 = OpCompositeExtract %5 %75 0\n%77 = OpImageRead %56 %32 %49 None\n%78 = OpCompositeExtract %13 %77 0\n%79 = OpConvertUToF %5 %78\n%80 = OpImageRead %23 %31 %49 Sample %44\n%81 = OpCompositeExtract %5 %80 0\n%82 = OpCompositeExtract %5 %80 1\n%83 = OpCompositeExtract %5 %80 2\n%84 = OpCompositeExtract %5 %80 3\n%85 = OpImageRead %23 %30 %49 Sample %44\n%86 = OpCompositeExtract %5 %85 0\n%87 = OpFAdd %5 %79 %76\n%88 = OpFAdd %5 %86 %87\n%89 = OpFAdd %5 %88 %50\n%90 = OpFAdd %5 %89 %62\n%91 = OpFAdd %5 %90 %71\n%92 = OpFAdd %5 %91 %81\n%93 = OpFAdd %5 %88 %51\n%94 = OpFAdd %5 %93 %63\n%95 = OpFAdd %5 %94 %72\n%96 = OpFAdd %5 %95 %82\n%97 = OpFAdd %5 %88 %52\n%98 = OpFAdd %5 %97 %64\n%99 = OpFAdd %5 %98 %73\n%100 = OpFAdd %5 %99 %83\n%101 = OpFAdd %5 %88 %53\n%102 = OpFAdd %5 %101 %65\n%103 = OpFAdd %5 %102 %74\n%104 = OpFAdd %5 %103 %84\n%106 = OpAccessChain %105 %29 %39\nOpStore %106 %92\n%107 = OpAccessChain %105 %29 %42\nOpStore %107 %96\n%108 = OpAccessChain %105 %29 %109\nOpStore %108 %100\n%110 = OpAccessChain %105 %29 %111\nOpStore %110 %104\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-16bit.ssbo.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 4, binding = 0, std430) buffer SSBO\n{\n    uint16_t _m0[];\n} _14[];\n\nlayout(set = 4, binding = 0, std430) buffer _17_20\n{\n    u16vec2 _m0[];\n} _20[];\n\nlayout(set = 4, binding = 0, scalar) buffer _23_26\n{\n    u16vec3 _m0[];\n} _26[];\n\nlayout(set = 4, binding = 0, std430) buffer _29_32\n{\n    u16vec4 _m0[];\n} _32[];\n\nlayout(set = 4, binding = 0, std430) buffer _34_37\n{\n    uint16_t _m0[];\n} _37[];\n\nlayout(set = 4, binding = 0, std430) buffer _39_42\n{\n    u16vec2 _m0[];\n} _42[];\n\nlayout(set = 4, binding = 0, scalar) buffer _44_47\n{\n    u16vec3 _m0[];\n} _47[];\n\nlayout(set = 4, binding = 0, std430) buffer _49_52\n{\n    u16vec4 _m0[];\n} _52[];\n\nlayout(set = 4, binding = 0, std430) buffer _54_57\n{\n    uint _m0[];\n} _57[];\n\nlayout(set = 4, binding = 0, std430) buffer _60_63\n{\n    uvec4 _m0[];\n} _63[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _65_68\n{\n    uint16_t _m0[];\n} _68[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _70_73\n{\n    u16vec2 _m0[];\n} _73[];\n\nlayout(set = 4, binding = 0, scalar) writeonly buffer _75_78\n{\n    u16vec3 _m0[];\n} _78[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _80_83\n{\n    u16vec4 _m0[];\n} _83[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _123 = registers._m4 + 5u;\n    uint _128 = registers._m4 + 4u;\n    uint _133 = registers._m4 + 4u;\n    uint _138 = registers._m4 + 4u;\n    uint _143 = registers._m4 + 4u;\n    uint _158 = registers._m4 + 3u;\n    uint _164 = registers._m4 + 2u;\n    uint _170 = registers._m4 + 1u;\n    _14[registers._m4]._m0[gl_GlobalInvocationID.x] = float16BitsToUint16(uint16BitsToFloat16(_14[registers._m4]._m0[gl_GlobalInvocationID.x]) + float16_t(1.0));\n    _20[_170]._m0[gl_GlobalInvocationID.x] = u16vec2(_20[_170]._m0[gl_GlobalInvocationID.x].x + 2us, _20[_170]._m0[gl_GlobalInvocationID.x].y + 2us);\n    f16vec3 _206 = uint16BitsToFloat16(_26[_164]._m0[gl_GlobalInvocationID.x]);\n    _26[_164]._m0[gl_GlobalInvocationID.x] = u16vec3(float16BitsToUint16(_206.x + float16_t(3.0)), float16BitsToUint16(_206.y + float16_t(3.0)), float16BitsToUint16(_206.z + float16_t(3.0)));\n    _32[_158]._m0[gl_GlobalInvocationID.x] = u16vec4(_32[_158]._m0[gl_GlobalInvocationID.x].x + 4us, _32[_158]._m0[gl_GlobalInvocationID.x].y + 4us, _32[_158]._m0[gl_GlobalInvocationID.x].z + 4us, _32[_158]._m0[gl_GlobalInvocationID.x].w + 4us);\n    uint16_t _235 = _37[_128]._m0[gl_GlobalInvocationID.x];\n    float _238 = float(uint16BitsToFloat16(_235));\n    u16vec2 _241 = _42[_133]._m0[gl_GlobalInvocationID.x];\n    f16vec2 _243 = uint16BitsToFloat16(_241);\n    float _247 = float(_243.y);\n    u16vec3 _251 = _47[_138]._m0[gl_GlobalInvocationID.x];\n    f16vec3 _252 = uint16BitsToFloat16(_251);\n    float _256 = float(_252.x);\n    u16vec4 _262 = _52[_143]._m0[gl_GlobalInvocationID.x];\n    f16vec4 _264 = uint16BitsToFloat16(_262);\n    uint16_t _275 = _37[_128]._m0[gl_GlobalInvocationID.x];\n    float _276 = float(_275);\n    u16vec2 _279 = _42[_133]._m0[gl_GlobalInvocationID.x];\n    float _283 = float(_279.y);\n    u16vec3 _286 = _47[_138]._m0[gl_GlobalInvocationID.x];\n    float _290 = float(_286.x);\n    u16vec4 _295 = _52[_143]._m0[gl_GlobalInvocationID.x];\n    _68[registers._m4 + 5u]._m0[gl_GlobalInvocationID.x] = float16BitsToUint16(float16_t(1.0));\n    _73[registers._m4 + 5u]._m0[gl_GlobalInvocationID.x] = u16vec2(float16BitsToUint16(float16_t(2.0)), float16BitsToUint16(float16_t(4.0)));\n    _78[registers._m4 + 5u]._m0[gl_GlobalInvocationID.x] = u16vec3(float16BitsToUint16(float16_t(4.0)), float16BitsToUint16(float16_t(5.0)), float16BitsToUint16(float16_t(6.0)));\n    _83[_123]._m0[gl_GlobalInvocationID.x] = u16vec4(float16BitsToUint16(float16_t(7.0)), float16BitsToUint16(float16_t(8.0)), float16BitsToUint16(float16_t(9.0)), float16BitsToUint16(float16_t(10.0)));\n    _68[registers._m4 + 6u]._m0[gl_GlobalInvocationID.x] = 1us;\n    _73[registers._m4 + 6u]._m0[gl_GlobalInvocationID.x] = u16vec2(2us, 4us);\n    _78[registers._m4 + 6u]._m0[gl_GlobalInvocationID.x] = u16vec3(4us, 5us, 6us);\n    _83[registers._m4 + 6u]._m0[gl_GlobalInvocationID.x] = u16vec4(7us, 8us, 9us, 10us);\n    uint _346 = _57[registers._m4 + 4u]._m0[gl_GlobalInvocationID.x];\n    float _347 = uintBitsToFloat(_346);\n    uint _349 = gl_GlobalInvocationID.x + 0u;\n    uint16_t _360 = _37[nonuniformEXT(registers._m4 + _349)]._m0[gl_GlobalInvocationID.x * 2u];\n    float _362 = float(uint16BitsToFloat16(_360));\n    float _365 = ((float(_243.x) + _238) + _276) + float(_279.x);\n    float _371 = (((((_365 + _256) + float(_264.x)) + _290) + float(_295.x)) + _347) + _362;\n    float _377 = (((((_365 + float(_252.y)) + float(_264.y)) + float(_286.y)) + float(_295.y)) + _347) + _362;\n    _42[nonuniformEXT(registers._m4 + _349)]._m0[gl_GlobalInvocationID.x * 2u] = u16vec2(float16BitsToUint16(float16_t(_371)), float16BitsToUint16(float16_t(_377)));\n    _63[registers._m4 + 4u]._m0[gl_GlobalInvocationID.x] = uvec4(uint((float(uint(_14[registers._m4]._m0.length()) / 1u) + _371) + float(uint(_83[_123]._m0.length()) * 8u)), uint(_377 + 2.0), uint((((((((((_247 + _238) + float(_252.z)) + float(_264.z)) + _276) + _283) + float(_286.z)) + float(_295.z)) + _347) + _362) + float(uint(_32[_158]._m0.length()) / 1u)), uint((((((((((_238 + 8.0) + _247) + _256) + float(_264.w)) + _276) + _283) + _290) + float(_295.w)) + _347) + _362));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 422\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageQuery\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %178\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %29 \"SSBO\"\nOpName %34 \"SSBO\"\nOpName %39 \"SSBO\"\nOpName %44 \"SSBO\"\nOpName %49 \"SSBO\"\nOpName %54 \"SSBO\"\nOpName %60 \"SSBO\"\nOpName %65 \"SSBO\"\nOpName %70 \"SSBO\"\nOpName %75 \"SSBO\"\nOpName %80 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 2\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %14 DescriptorSet 4\nOpDecorate %14 Binding 0\nOpDecorate %16 ArrayStride 4\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %20 DescriptorSet 4\nOpDecorate %20 Binding 0\nOpDecorate %22 ArrayStride 6\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %26 DescriptorSet 4\nOpDecorate %26 Binding 0\nOpDecorate %28 ArrayStride 8\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %32 DescriptorSet 4\nOpDecorate %32 Binding 0\nOpDecorate %33 ArrayStride 2\nOpMemberDecorate %34 0 Offset 0\nOpDecorate %34 Block\nOpDecorate %37 DescriptorSet 4\nOpDecorate %37 Binding 0\nOpDecorate %37 Aliased\nOpDecorate %38 ArrayStride 4\nOpMemberDecorate %39 0 Offset 0\nOpDecorate %39 Block\nOpDecorate %42 DescriptorSet 4\nOpDecorate %42 Binding 0\nOpDecorate %42 Aliased\nOpDecorate %43 ArrayStride 6\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %44 Block\nOpDecorate %47 DescriptorSet 4\nOpDecorate %47 Binding 0\nOpDecorate %47 Aliased\nOpDecorate %48 ArrayStride 8\nOpMemberDecorate %49 0 Offset 0\nOpDecorate %49 Block\nOpDecorate %52 DescriptorSet 4\nOpDecorate %52 Binding 0\nOpDecorate %52 Aliased\nOpDecorate %53 ArrayStride 4\nOpMemberDecorate %54 0 Offset 0\nOpDecorate %54 Block\nOpDecorate %57 DescriptorSet 4\nOpDecorate %57 Binding 0\nOpDecorate %57 Aliased\nOpDecorate %59 ArrayStride 16\nOpMemberDecorate %60 0 Offset 0\nOpDecorate %60 Block\nOpDecorate %63 DescriptorSet 4\nOpDecorate %63 Binding 0\nOpDecorate %63 Aliased\nOpDecorate %64 ArrayStride 2\nOpMemberDecorate %65 0 Offset 0\nOpDecorate %65 Block\nOpDecorate %68 DescriptorSet 4\nOpDecorate %68 Binding 0\nOpDecorate %68 NonReadable\nOpDecorate %68 Aliased\nOpDecorate %69 ArrayStride 4\nOpMemberDecorate %70 0 Offset 0\nOpDecorate %70 Block\nOpDecorate %73 DescriptorSet 4\nOpDecorate %73 Binding 0\nOpDecorate %73 NonReadable\nOpDecorate %73 Aliased\nOpDecorate %74 ArrayStride 6\nOpMemberDecorate %75 0 Offset 0\nOpDecorate %75 Block\nOpDecorate %78 DescriptorSet 4\nOpDecorate %78 Binding 0\nOpDecorate %78 NonReadable\nOpDecorate %78 Aliased\nOpDecorate %79 ArrayStride 8\nOpMemberDecorate %80 0 Offset 0\nOpDecorate %80 Block\nOpDecorate %83 DescriptorSet 4\nOpDecorate %83 Binding 0\nOpDecorate %83 NonReadable\nOpDecorate %83 Aliased\nOpDecorate %178 BuiltIn GlobalInvocationId\nOpDecorate %353 NonUniform\nOpDecorate %350 NonUniform\nOpDecorate %357 NonUniform\nOpDecorate %354 NonUniform\nOpDecorate %359 NonUniform\nOpDecorate %385 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeInt 16 0\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %9 2\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeVector %9 3\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypeStruct %22\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeVector %9 4\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpTypeRuntimeArray %9\n%34 = OpTypeStruct %33\n%35 = OpTypeRuntimeArray %34\n%36 = OpTypePointer StorageBuffer %35\n%37 = OpVariable %36 StorageBuffer\n%38 = OpTypeRuntimeArray %15\n%39 = OpTypeStruct %38\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer StorageBuffer %40\n%42 = OpVariable %41 StorageBuffer\n%43 = OpTypeRuntimeArray %21\n%44 = OpTypeStruct %43\n%45 = OpTypeRuntimeArray %44\n%46 = OpTypePointer StorageBuffer %45\n%47 = OpVariable %46 StorageBuffer\n%48 = OpTypeRuntimeArray %27\n%49 = OpTypeStruct %48\n%50 = OpTypeRuntimeArray %49\n%51 = OpTypePointer StorageBuffer %50\n%52 = OpVariable %51 StorageBuffer\n%53 = OpTypeRuntimeArray %5\n%54 = OpTypeStruct %53\n%55 = OpTypeRuntimeArray %54\n%56 = OpTypePointer StorageBuffer %55\n%57 = OpVariable %56 StorageBuffer\n%58 = OpTypeVector %5 4\n%59 = OpTypeRuntimeArray %58\n%60 = OpTypeStruct %59\n%61 = OpTypeRuntimeArray %60\n%62 = OpTypePointer StorageBuffer %61\n%63 = OpVariable %62 StorageBuffer\n%64 = OpTypeRuntimeArray %9\n%65 = OpTypeStruct %64\n%66 = OpTypeRuntimeArray %65\n%67 = OpTypePointer StorageBuffer %66\n%68 = OpVariable %67 StorageBuffer\n%69 = OpTypeRuntimeArray %15\n%70 = OpTypeStruct %69\n%71 = OpTypeRuntimeArray %70\n%72 = OpTypePointer StorageBuffer %71\n%73 = OpVariable %72 StorageBuffer\n%74 = OpTypeRuntimeArray %21\n%75 = OpTypeStruct %74\n%76 = OpTypeRuntimeArray %75\n%77 = OpTypePointer StorageBuffer %76\n%78 = OpVariable %77 StorageBuffer\n%79 = OpTypeRuntimeArray %27\n%80 = OpTypeStruct %79\n%81 = OpTypeRuntimeArray %80\n%82 = OpTypePointer StorageBuffer %81\n%83 = OpVariable %82 StorageBuffer\n%84 = OpTypePointer StorageBuffer %65\n%86 = OpTypePointer PushConstant %5\n%88 = OpConstant %5 4\n%91 = OpConstant %5 6\n%92 = OpTypePointer StorageBuffer %70\n%97 = OpTypePointer StorageBuffer %75\n%102 = OpTypePointer StorageBuffer %80\n%111 = OpConstant %5 5\n%124 = OpTypePointer StorageBuffer %34\n%129 = OpTypePointer StorageBuffer %39\n%134 = OpTypePointer StorageBuffer %44\n%139 = OpTypePointer StorageBuffer %49\n%144 = OpTypePointer StorageBuffer %54\n%149 = OpTypePointer StorageBuffer %60\n%154 = OpTypePointer StorageBuffer %29\n%159 = OpConstant %5 3\n%160 = OpTypePointer StorageBuffer %23\n%165 = OpConstant %5 2\n%166 = OpTypePointer StorageBuffer %17\n%171 = OpConstant %5 1\n%172 = OpTypePointer StorageBuffer %11\n%176 = OpTypeVector %5 3\n%177 = OpTypePointer Input %176\n%178 = OpVariable %177 Input\n%179 = OpTypePointer Input %5\n%181 = OpConstant %5 0\n%183 = OpTypePointer StorageBuffer %9\n%186 = OpTypeFloat 16\n%189 = OpConstant %186 0x1p+0\n%192 = OpTypePointer StorageBuffer %15\n%198 = OpConstant %9 2\n%202 = OpTypePointer StorageBuffer %21\n%205 = OpTypeVector %186 3\n%211 = OpConstant %186 0x1.8p+1\n%219 = OpTypePointer StorageBuffer %27\n%227 = OpConstant %9 4\n%237 = OpTypeFloat 32\n%242 = OpTypeVector %186 2\n%263 = OpTypeVector %186 4\n%307 = OpConstant %186 0x1p+1\n%309 = OpConstant %186 0x1p+2\n%314 = OpConstant %186 0x1.4p+2\n%316 = OpConstant %186 0x1.8p+2\n%320 = OpConstant %186 0x1.cp+2\n%322 = OpConstant %186 0x1p+3\n%324 = OpConstant %186 0x1.2p+3\n%326 = OpConstant %186 0x1.4p+3\n%330 = OpConstant %9 1\n%334 = OpConstant %9 5\n%335 = OpConstant %9 6\n%338 = OpConstant %9 7\n%339 = OpConstant %9 8\n%340 = OpConstant %9 9\n%341 = OpConstant %9 10\n%344 = OpTypePointer StorageBuffer %5\n%391 = OpConstant %237 2\n%397 = OpConstant %237 8\n%409 = OpConstant %5 8\n%418 = OpTypePointer StorageBuffer %58\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %420\n%420 = OpLabel\n%87 = OpAccessChain %86 %8 %88\n%89 = OpLoad %5 %87\n%90 = OpIAdd %5 %89 %91\n%85 = OpAccessChain %84 %68 %90\n%94 = OpAccessChain %86 %8 %88\n%95 = OpLoad %5 %94\n%96 = OpIAdd %5 %95 %91\n%93 = OpAccessChain %92 %73 %96\n%99 = OpAccessChain %86 %8 %88\n%100 = OpLoad %5 %99\n%101 = OpIAdd %5 %100 %91\n%98 = OpAccessChain %97 %78 %101\n%104 = OpAccessChain %86 %8 %88\n%105 = OpLoad %5 %104\n%106 = OpIAdd %5 %105 %91\n%103 = OpAccessChain %102 %83 %106\n%108 = OpAccessChain %86 %8 %88\n%109 = OpLoad %5 %108\n%110 = OpIAdd %5 %109 %111\n%107 = OpAccessChain %84 %68 %110\n%113 = OpAccessChain %86 %8 %88\n%114 = OpLoad %5 %113\n%115 = OpIAdd %5 %114 %111\n%112 = OpAccessChain %92 %73 %115\n%117 = OpAccessChain %86 %8 %88\n%118 = OpLoad %5 %117\n%119 = OpIAdd %5 %118 %111\n%116 = OpAccessChain %97 %78 %119\n%121 = OpAccessChain %86 %8 %88\n%122 = OpLoad %5 %121\n%123 = OpIAdd %5 %122 %111\n%120 = OpAccessChain %102 %83 %123\n%126 = OpAccessChain %86 %8 %88\n%127 = OpLoad %5 %126\n%128 = OpIAdd %5 %127 %88\n%125 = OpAccessChain %124 %37 %128\n%131 = OpAccessChain %86 %8 %88\n%132 = OpLoad %5 %131\n%133 = OpIAdd %5 %132 %88\n%130 = OpAccessChain %129 %42 %133\n%136 = OpAccessChain %86 %8 %88\n%137 = OpLoad %5 %136\n%138 = OpIAdd %5 %137 %88\n%135 = OpAccessChain %134 %47 %138\n%141 = OpAccessChain %86 %8 %88\n%142 = OpLoad %5 %141\n%143 = OpIAdd %5 %142 %88\n%140 = OpAccessChain %139 %52 %143\n%146 = OpAccessChain %86 %8 %88\n%147 = OpLoad %5 %146\n%148 = OpIAdd %5 %147 %88\n%145 = OpAccessChain %144 %57 %148\n%151 = OpAccessChain %86 %8 %88\n%152 = OpLoad %5 %151\n%153 = OpIAdd %5 %152 %88\n%150 = OpAccessChain %149 %63 %153\n%156 = OpAccessChain %86 %8 %88\n%157 = OpLoad %5 %156\n%158 = OpIAdd %5 %157 %159\n%155 = OpAccessChain %154 %32 %158\n%162 = OpAccessChain %86 %8 %88\n%163 = OpLoad %5 %162\n%164 = OpIAdd %5 %163 %165\n%161 = OpAccessChain %160 %26 %164\n%168 = OpAccessChain %86 %8 %88\n%169 = OpLoad %5 %168\n%170 = OpIAdd %5 %169 %171\n%167 = OpAccessChain %166 %20 %170\n%174 = OpAccessChain %86 %8 %88\n%175 = OpLoad %5 %174\n%173 = OpAccessChain %172 %14 %175\n%180 = OpAccessChain %179 %178 %181\n%182 = OpLoad %5 %180\n%184 = OpAccessChain %183 %173 %181 %182\n%185 = OpLoad %9 %184\n%187 = OpBitcast %186 %185\n%188 = OpFAdd %186 %187 %189\n%190 = OpBitcast %9 %188\n%191 = OpAccessChain %183 %173 %181 %182\nOpStore %191 %190\n%193 = OpAccessChain %192 %167 %181 %182\n%194 = OpLoad %15 %193\n%195 = OpCompositeExtract %9 %194 0\n%196 = OpCompositeExtract %9 %194 1\n%197 = OpIAdd %9 %195 %198\n%199 = OpIAdd %9 %196 %198\n%200 = OpCompositeConstruct %15 %197 %199\n%201 = OpAccessChain %192 %167 %181 %182\nOpStore %201 %200\n%203 = OpAccessChain %202 %161 %181 %182\n%204 = OpLoad %21 %203\n%206 = OpBitcast %205 %204\n%207 = OpCompositeExtract %186 %206 0\n%208 = OpCompositeExtract %186 %206 1\n%209 = OpCompositeExtract %186 %206 2\n%210 = OpFAdd %186 %207 %211\n%212 = OpFAdd %186 %208 %211\n%213 = OpFAdd %186 %209 %211\n%214 = OpBitcast %9 %210\n%215 = OpBitcast %9 %212\n%216 = OpBitcast %9 %213\n%217 = OpCompositeConstruct %21 %214 %215 %216\n%218 = OpAccessChain %202 %161 %181 %182\nOpStore %218 %217\n%220 = OpAccessChain %219 %155 %181 %182\n%221 = OpLoad %27 %220\n%222 = OpCompositeExtract %9 %221 0\n%223 = OpCompositeExtract %9 %221 1\n%224 = OpCompositeExtract %9 %221 2\n%225 = OpCompositeExtract %9 %221 3\n%226 = OpIAdd %9 %222 %227\n%228 = OpIAdd %9 %223 %227\n%229 = OpIAdd %9 %224 %227\n%230 = OpIAdd %9 %225 %227\n%231 = OpCompositeConstruct %27 %226 %228 %229 %230\n%232 = OpAccessChain %219 %155 %181 %182\nOpStore %232 %231\n%233 = OpShiftLeftLogical %5 %182 %171\n%234 = OpAccessChain %183 %125 %181 %182\n%235 = OpLoad %9 %234\n%236 = OpBitcast %186 %235\n%238 = OpFConvert %237 %236\n%239 = OpShiftLeftLogical %5 %182 %165\n%240 = OpAccessChain %192 %130 %181 %182\n%241 = OpLoad %15 %240\n%243 = OpBitcast %242 %241\n%244 = OpCompositeExtract %186 %243 0\n%245 = OpCompositeExtract %186 %243 1\n%246 = OpFConvert %237 %244\n%247 = OpFConvert %237 %245\n%248 = OpFAdd %237 %247 %238\n%249 = OpIMul %5 %182 %91\n%250 = OpAccessChain %202 %135 %181 %182\n%251 = OpLoad %21 %250\n%252 = OpBitcast %205 %251\n%253 = OpCompositeExtract %186 %252 0\n%254 = OpCompositeExtract %186 %252 1\n%255 = OpCompositeExtract %186 %252 2\n%256 = OpFConvert %237 %253\n%257 = OpFConvert %237 %254\n%258 = OpFConvert %237 %255\n%259 = OpFAdd %237 %248 %258\n%260 = OpShiftLeftLogical %5 %182 %159\n%261 = OpAccessChain %219 %140 %181 %182\n%262 = OpLoad %27 %261\n%264 = OpBitcast %263 %262\n%265 = OpCompositeExtract %186 %264 0\n%266 = OpCompositeExtract %186 %264 1\n%267 = OpCompositeExtract %186 %264 2\n%268 = OpCompositeExtract %186 %264 3\n%269 = OpFConvert %237 %265\n%270 = OpFConvert %237 %266\n%271 = OpFConvert %237 %267\n%272 = OpFConvert %237 %268\n%273 = OpFAdd %237 %259 %271\n%274 = OpAccessChain %183 %125 %181 %182\n%275 = OpLoad %9 %274\n%276 = OpConvertUToF %237 %275\n%277 = OpFAdd %237 %273 %276\n%278 = OpAccessChain %192 %130 %181 %182\n%279 = OpLoad %15 %278\n%280 = OpCompositeExtract %9 %279 0\n%281 = OpCompositeExtract %9 %279 1\n%282 = OpConvertUToF %237 %280\n%283 = OpConvertUToF %237 %281\n%284 = OpFAdd %237 %277 %283\n%285 = OpAccessChain %202 %135 %181 %182\n%286 = OpLoad %21 %285\n%287 = OpCompositeExtract %9 %286 0\n%288 = OpCompositeExtract %9 %286 1\n%289 = OpCompositeExtract %9 %286 2\n%290 = OpConvertUToF %237 %287\n%291 = OpConvertUToF %237 %288\n%292 = OpConvertUToF %237 %289\n%293 = OpFAdd %237 %284 %292\n%294 = OpAccessChain %219 %140 %181 %182\n%295 = OpLoad %27 %294\n%296 = OpCompositeExtract %9 %295 0\n%297 = OpCompositeExtract %9 %295 1\n%298 = OpCompositeExtract %9 %295 2\n%299 = OpCompositeExtract %9 %295 3\n%300 = OpConvertUToF %237 %296\n%301 = OpConvertUToF %237 %297\n%302 = OpConvertUToF %237 %298\n%303 = OpConvertUToF %237 %299\n%304 = OpFAdd %237 %293 %302\n%305 = OpBitcast %9 %189\n%306 = OpAccessChain %183 %107 %181 %182\nOpStore %306 %305\n%308 = OpBitcast %9 %307\n%310 = OpBitcast %9 %309\n%311 = OpCompositeConstruct %15 %308 %310\n%312 = OpAccessChain %192 %112 %181 %182\nOpStore %312 %311\n%313 = OpBitcast %9 %309\n%315 = OpBitcast %9 %314\n%317 = OpBitcast %9 %316\n%318 = OpCompositeConstruct %21 %313 %315 %317\n%319 = OpAccessChain %202 %116 %181 %182\nOpStore %319 %318\n%321 = OpBitcast %9 %320\n%323 = OpBitcast %9 %322\n%325 = OpBitcast %9 %324\n%327 = OpBitcast %9 %326\n%328 = OpCompositeConstruct %27 %321 %323 %325 %327\n%329 = OpAccessChain %219 %120 %181 %182\nOpStore %329 %328\n%331 = OpAccessChain %183 %85 %181 %182\nOpStore %331 %330\n%332 = OpCompositeConstruct %15 %198 %227\n%333 = OpAccessChain %192 %93 %181 %182\nOpStore %333 %332\n%336 = OpCompositeConstruct %21 %227 %334 %335\n%337 = OpAccessChain %202 %98 %181 %182\nOpStore %337 %336\n%342 = OpCompositeConstruct %27 %338 %339 %340 %341\n%343 = OpAccessChain %219 %103 %181 %182\nOpStore %343 %342\n%345 = OpAccessChain %344 %145 %181 %182\n%346 = OpLoad %5 %345\n%347 = OpBitcast %237 %346\n%348 = OpFAdd %237 %304 %347\n%349 = OpIAdd %5 %182 %181\n%351 = OpAccessChain %86 %8 %88\n%352 = OpLoad %5 %351\n%353 = OpIAdd %5 %352 %349\n%350 = OpAccessChain %124 %37 %353\n%355 = OpAccessChain %86 %8 %88\n%356 = OpLoad %5 %355\n%357 = OpIAdd %5 %356 %349\n%354 = OpAccessChain %129 %42 %357\n%358 = OpIMul %5 %182 %165\n%359 = OpAccessChain %183 %350 %181 %358\n%360 = OpLoad %9 %359\n%361 = OpBitcast %186 %360\n%362 = OpFConvert %237 %361\n%363 = OpFAdd %237 %246 %238\n%364 = OpFAdd %237 %363 %276\n%365 = OpFAdd %237 %364 %282\n%366 = OpFAdd %237 %365 %256\n%367 = OpFAdd %237 %366 %269\n%368 = OpFAdd %237 %367 %290\n%369 = OpFAdd %237 %368 %300\n%370 = OpFAdd %237 %369 %347\n%371 = OpFAdd %237 %370 %362\n%372 = OpFAdd %237 %365 %257\n%373 = OpFAdd %237 %372 %270\n%374 = OpFAdd %237 %373 %291\n%375 = OpFAdd %237 %374 %301\n%376 = OpFAdd %237 %375 %347\n%377 = OpFAdd %237 %376 %362\n%378 = OpFAdd %237 %348 %362\n%379 = OpFConvert %186 %371\n%380 = OpFConvert %186 %377\n%381 = OpIMul %5 %182 %165\n%382 = OpBitcast %9 %379\n%383 = OpBitcast %9 %380\n%384 = OpCompositeConstruct %15 %382 %383\n%385 = OpAccessChain %192 %354 %181 %381\nOpStore %385 %384\n%386 = OpArrayLength %5 %173 0\n%387 = OpUDiv %5 %386 %171\n%388 = OpConvertUToF %237 %387\n%389 = OpFAdd %237 %388 %371\n%390 = OpFAdd %237 %377 %391\n%392 = OpArrayLength %5 %155 0\n%393 = OpUDiv %5 %392 %171\n%394 = OpConvertUToF %237 %393\n%395 = OpFAdd %237 %378 %394\n%396 = OpFAdd %237 %238 %397\n%398 = OpFAdd %237 %396 %247\n%399 = OpFAdd %237 %398 %256\n%400 = OpFAdd %237 %399 %272\n%401 = OpFAdd %237 %400 %276\n%402 = OpFAdd %237 %401 %283\n%403 = OpFAdd %237 %402 %290\n%404 = OpFAdd %237 %403 %303\n%405 = OpFAdd %237 %404 %347\n%406 = OpFAdd %237 %405 %362\n%407 = OpArrayLength %5 %120 0\n%408 = OpIMul %5 %407 %409\n%410 = OpConvertUToF %237 %408\n%411 = OpFAdd %237 %389 %410\n%412 = OpConvertFToU %5 %411\n%413 = OpConvertFToU %5 %390\n%414 = OpConvertFToU %5 %395\n%415 = OpConvertFToU %5 %406\n%416 = OpShiftLeftLogical %5 %182 %88\n%417 = OpCompositeConstruct %58 %412 %413 %414 %415\n%419 = OpAccessChain %418 %150 %181 %182\nOpStore %419 %417\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-16bit.ssbo.bindless.ssbo-align.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) buffer SSBO\n{\n    uint16_t _m0[];\n} _19[];\n\nlayout(set = 4, binding = 0, std430) buffer _22_25\n{\n    u16vec2 _m0[];\n} _25[];\n\nlayout(set = 4, binding = 0, std430) buffer _28_31\n{\n    u16vec4 _m0[];\n} _31[];\n\nlayout(set = 4, binding = 0, std430) buffer _33_36\n{\n    uint16_t _m0[];\n} _36[];\n\nlayout(set = 4, binding = 0, std430) buffer _38_41\n{\n    u16vec2 _m0[];\n} _41[];\n\nlayout(set = 4, binding = 0, std430) buffer _43_46\n{\n    u16vec4 _m0[];\n} _46[];\n\nlayout(set = 4, binding = 0, std430) buffer _48_51\n{\n    uint _m0[];\n} _51[];\n\nlayout(set = 4, binding = 0, std430) buffer _54_57\n{\n    uvec4 _m0[];\n} _57[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _59_62\n{\n    uint16_t _m0[];\n} _62[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _64_67\n{\n    u16vec2 _m0[];\n} _67[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _69_72\n{\n    u16vec4 _m0[];\n} _72[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _79 = registers._m4 + 6u;\n    uint _90 = registers._m4 + 6u;\n    uint _91 = subgroupBroadcastFirst(_90);\n    uint _100 = registers._m4 + 5u;\n    uint _109 = registers._m4 + 5u;\n    uint _110 = subgroupBroadcastFirst(_109);\n    uint _117 = registers._m4 + 4u;\n    uint _122 = registers._m4 + 4u;\n    uint _127 = registers._m4 + 4u;\n    uint _137 = registers._m4 + 4u;\n    uint _138 = subgroupBroadcastFirst(_137);\n    uint _145 = registers._m4 + 3u;\n    uvec2 _149 = _13._m0[subgroupBroadcastFirst(_145)] >> uvec2(3u);\n    uint _155 = registers._m4 + 2u;\n    uvec2 _160 = _13._m0[subgroupBroadcastFirst(_155)] >> uvec2(1u);\n    uint _167 = registers._m4 + 1u;\n    uvec2 _171 = _13._m0[subgroupBroadcastFirst(_167)] >> uvec2(2u);\n    uvec2 _179 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(1u);\n    _19[registers._m4]._m0[(gl_GlobalInvocationID.x < _179.y) ? (gl_GlobalInvocationID.x + _179.x) : 2147483644u] = float16BitsToUint16(uint16BitsToFloat16(_19[registers._m4]._m0[(gl_GlobalInvocationID.x < _179.y) ? (gl_GlobalInvocationID.x + _179.x) : 2147483644u]) + float16_t(1.0));\n    uint _211 = (gl_GlobalInvocationID.x < _171.y) ? (gl_GlobalInvocationID.x + _171.x) : 1073741823u;\n    _25[_167]._m0[(gl_GlobalInvocationID.x < _171.y) ? (gl_GlobalInvocationID.x + _171.x) : 1073741823u] = u16vec2(_25[_167]._m0[_211].x + 2us, _25[_167]._m0[_211].y + 2us);\n    uint _228 = gl_GlobalInvocationID.x * 3u;\n    uint _233 = (_228 < _160.y) ? (_228 + _160.x) : 2147483644u;\n    uint16_t _235 = _19[_155]._m0[_233];\n    uint16_t _238 = _19[_155]._m0[_233 + 1u];\n    uint16_t _241 = _19[_155]._m0[_233 + 2u];\n    f16vec3 _245 = uint16BitsToFloat16(u16vec3(_235, _238, _241));\n    uint _253 = gl_GlobalInvocationID.x * 3u;\n    uint _258 = (_253 < _160.y) ? (_253 + _160.x) : 2147483644u;\n    _19[_155]._m0[_258] = float16BitsToUint16(_245.x + float16_t(3.0));\n    _19[_155]._m0[_258 + 1u] = float16BitsToUint16(_245.y + float16_t(3.0));\n    _19[_155]._m0[_258 + 2u] = float16BitsToUint16(_245.z + float16_t(3.0));\n    uint _271 = (gl_GlobalInvocationID.x < _149.y) ? (gl_GlobalInvocationID.x + _149.x) : 536870911u;\n    _31[_145]._m0[(gl_GlobalInvocationID.x < _149.y) ? (gl_GlobalInvocationID.x + _149.x) : 536870911u] = u16vec4(_31[_145]._m0[_271].x + 4us, _31[_145]._m0[_271].y + 4us, _31[_145]._m0[_271].z + 4us, _31[_145]._m0[_271].w + 4us);\n    uvec2 _293 = _13._m0[_138] >> uvec2(1u);\n    uint16_t _300 = _36[_117]._m0[(gl_GlobalInvocationID.x < _293.y) ? (gl_GlobalInvocationID.x + _293.x) : 2147483644u];\n    float _303 = float(uint16BitsToFloat16(_300));\n    uvec2 _305 = _13._m0[_138] >> uvec2(2u);\n    u16vec2 _312 = _41[_122]._m0[(gl_GlobalInvocationID.x < _305.y) ? (gl_GlobalInvocationID.x + _305.x) : 1073741823u];\n    f16vec2 _314 = uint16BitsToFloat16(_312);\n    float _318 = float(_314.y);\n    uint _321 = gl_GlobalInvocationID.x * 3u;\n    uvec2 _322 = _13._m0[_138] >> uvec2(1u);\n    uint _327 = (_321 < _322.y) ? (_321 + _322.x) : 2147483644u;\n    uint16_t _329 = _36[_117]._m0[_327];\n    uint16_t _332 = _36[_117]._m0[_327 + 1u];\n    uint16_t _335 = _36[_117]._m0[_327 + 2u];\n    f16vec3 _337 = uint16BitsToFloat16(u16vec3(_329, _332, _335));\n    float _341 = float(_337.x);\n    uvec2 _346 = _13._m0[_138] >> uvec2(3u);\n    u16vec4 _353 = _46[_127]._m0[(gl_GlobalInvocationID.x < _346.y) ? (gl_GlobalInvocationID.x + _346.x) : 536870911u];\n    f16vec4 _355 = uint16BitsToFloat16(_353);\n    uvec2 _365 = _13._m0[_138] >> uvec2(1u);\n    uint16_t _372 = _36[_117]._m0[(gl_GlobalInvocationID.x < _365.y) ? (gl_GlobalInvocationID.x + _365.x) : 2147483644u];\n    float _373 = float(_372);\n    uvec2 _375 = _13._m0[_138] >> uvec2(2u);\n    uint _380 = (gl_GlobalInvocationID.x < _375.y) ? (gl_GlobalInvocationID.x + _375.x) : 1073741823u;\n    u16vec2 _382 = _41[_122]._m0[_380];\n    float _386 = float(_382.y);\n    uint _388 = gl_GlobalInvocationID.x * 3u;\n    uvec2 _389 = _13._m0[_138] >> uvec2(1u);\n    uint _394 = (_388 < _389.y) ? (_388 + _389.x) : 2147483644u;\n    uint16_t _396 = _36[_117]._m0[_394];\n    uint16_t _399 = _36[_117]._m0[_394 + 1u];\n    uint16_t _402 = _36[_117]._m0[_394 + 2u];\n    u16vec3 _403 = u16vec3(_396, _399, _402);\n    float _407 = float(_403.x);\n    uvec2 _411 = _13._m0[_138] >> uvec2(3u);\n    uint _416 = (gl_GlobalInvocationID.x < _411.y) ? (gl_GlobalInvocationID.x + _411.x) : 536870911u;\n    u16vec4 _418 = _46[_127]._m0[_416];\n    uvec2 _428 = _13._m0[_110] >> uvec2(1u);\n    _62[_100]._m0[(gl_GlobalInvocationID.x < _428.y) ? (gl_GlobalInvocationID.x + _428.x) : 2147483644u] = float16BitsToUint16(float16_t(1.0));\n    uvec2 _436 = _13._m0[_110] >> uvec2(2u);\n    _67[registers._m4 + 5u]._m0[(gl_GlobalInvocationID.x < _436.y) ? (gl_GlobalInvocationID.x + _436.x) : 1073741823u] = u16vec2(float16BitsToUint16(float16_t(2.0)), float16BitsToUint16(float16_t(4.0)));\n    uint _448 = gl_GlobalInvocationID.x * 3u;\n    uvec2 _449 = _13._m0[_110] >> uvec2(1u);\n    uint _454 = (_448 < _449.y) ? (_448 + _449.x) : 2147483644u;\n    _62[_100]._m0[_454] = float16BitsToUint16(float16_t(4.0));\n    _62[_100]._m0[_454 + 1u] = float16BitsToUint16(float16_t(5.0));\n    _62[_100]._m0[_454 + 2u] = float16BitsToUint16(float16_t(6.0));\n    uvec2 _465 = _13._m0[_110] >> uvec2(3u);\n    _72[_109]._m0[(gl_GlobalInvocationID.x < _465.y) ? (gl_GlobalInvocationID.x + _465.x) : 536870911u] = u16vec4(float16BitsToUint16(float16_t(7.0)), float16BitsToUint16(float16_t(8.0)), float16BitsToUint16(float16_t(9.0)), float16BitsToUint16(float16_t(10.0)));\n    uvec2 _481 = _13._m0[_91] >> uvec2(1u);\n    _62[_79]._m0[(gl_GlobalInvocationID.x < _481.y) ? (gl_GlobalInvocationID.x + _481.x) : 2147483644u] = 1us;\n    uvec2 _489 = _13._m0[_91] >> uvec2(2u);\n    _67[registers._m4 + 6u]._m0[(gl_GlobalInvocationID.x < _489.y) ? (gl_GlobalInvocationID.x + _489.x) : 1073741823u] = u16vec2(2us, 4us);\n    uint _497 = gl_GlobalInvocationID.x * 3u;\n    uvec2 _498 = _13._m0[_91] >> uvec2(1u);\n    uint _503 = (_497 < _498.y) ? (_497 + _498.x) : 2147483644u;\n    _62[_79]._m0[_503] = 4us;\n    _62[_79]._m0[_503 + 1u] = 5us;\n    _62[_79]._m0[_503 + 2u] = 6us;\n    uvec2 _511 = _13._m0[_91] >> uvec2(3u);\n    _72[_90]._m0[(gl_GlobalInvocationID.x < _511.y) ? (gl_GlobalInvocationID.x + _511.x) : 536870911u] = u16vec4(7us, 8us, 9us, 10us);\n    uvec2 _523 = _13._m0[_138] >> uvec2(2u);\n    uint _532 = _51[registers._m4 + 4u]._m0[(gl_GlobalInvocationID.x < _523.y) ? (gl_GlobalInvocationID.x + _523.x) : 1073741820u];\n    float _533 = uintBitsToFloat(_532);\n    uint _535 = gl_GlobalInvocationID.x + 0u;\n    uint _543 = registers._m4 + _535;\n    uint _546 = gl_GlobalInvocationID.x * 2u;\n    uvec2 _547 = _13._m0[_543] >> uvec2(1u);\n    uint16_t _554 = _36[nonuniformEXT(registers._m4 + _535)]._m0[(_546 < _547.y) ? (_546 + _547.x) : 2147483644u];\n    float _556 = float(uint16BitsToFloat16(_554));\n    float _559 = ((float(_314.x) + _303) + _373) + float(_382.x);\n    float _565 = (((((_559 + _341) + float(_355.x)) + _407) + float(_418.x)) + _533) + _556;\n    float _571 = (((((_559 + float(_337.y)) + float(_355.y)) + float(_403.y)) + float(_418.y)) + _533) + _556;\n    uint _575 = gl_GlobalInvocationID.x * 2u;\n    uvec2 _576 = _13._m0[_543] >> uvec2(2u);\n    _41[nonuniformEXT(_543)]._m0[(_575 < _576.y) ? (_575 + _576.x) : 1073741823u] = u16vec2(float16BitsToUint16(float16_t(_565)), float16BitsToUint16(float16_t(_571)));\n    uvec2 _617 = _13._m0[_138] >> uvec2(4u);\n    _57[_137]._m0[(gl_GlobalInvocationID.x < _617.y) ? (gl_GlobalInvocationID.x + _617.x) : 268435455u] = uvec4(uint((float(_179.y / 1u) + _565) + float(_13._m0[_110].y * 8u)), uint(_571 + 2.0), uint((((((((((_318 + _303) + float(_337.z)) + float(_355.z)) + _373) + _386) + float(_403.z)) + float(_418.z)) + _533) + _556) + float(_149.y / 1u)), uint((((((((((_303 + 8.0) + _318) + _341) + float(_355.w)) + _373) + _386) + _407) + float(_418.w)) + _533) + _556));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 630\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageQuery\nOpCapability GroupNonUniformBallot\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %182\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %16 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %28 \"SSBO\"\nOpName %33 \"SSBO\"\nOpName %38 \"SSBO\"\nOpName %43 \"SSBO\"\nOpName %48 \"SSBO\"\nOpName %54 \"SSBO\"\nOpName %59 \"SSBO\"\nOpName %64 \"SSBO\"\nOpName %69 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %15 ArrayStride 2\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 4\nOpDecorate %19 Binding 0\nOpDecorate %21 ArrayStride 4\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %25 DescriptorSet 4\nOpDecorate %25 Binding 0\nOpDecorate %27 ArrayStride 8\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %31 DescriptorSet 4\nOpDecorate %31 Binding 0\nOpDecorate %32 ArrayStride 2\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %36 DescriptorSet 4\nOpDecorate %36 Binding 0\nOpDecorate %36 Aliased\nOpDecorate %37 ArrayStride 4\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpDecorate %41 DescriptorSet 4\nOpDecorate %41 Binding 0\nOpDecorate %41 Aliased\nOpDecorate %42 ArrayStride 8\nOpMemberDecorate %43 0 Offset 0\nOpDecorate %43 Block\nOpDecorate %46 DescriptorSet 4\nOpDecorate %46 Binding 0\nOpDecorate %46 Aliased\nOpDecorate %47 ArrayStride 4\nOpMemberDecorate %48 0 Offset 0\nOpDecorate %48 Block\nOpDecorate %51 DescriptorSet 4\nOpDecorate %51 Binding 0\nOpDecorate %51 Aliased\nOpDecorate %53 ArrayStride 16\nOpMemberDecorate %54 0 Offset 0\nOpDecorate %54 Block\nOpDecorate %57 DescriptorSet 4\nOpDecorate %57 Binding 0\nOpDecorate %57 Aliased\nOpDecorate %58 ArrayStride 2\nOpMemberDecorate %59 0 Offset 0\nOpDecorate %59 Block\nOpDecorate %62 DescriptorSet 4\nOpDecorate %62 Binding 0\nOpDecorate %62 NonReadable\nOpDecorate %62 Aliased\nOpDecorate %63 ArrayStride 4\nOpMemberDecorate %64 0 Offset 0\nOpDecorate %64 Block\nOpDecorate %67 DescriptorSet 4\nOpDecorate %67 Binding 0\nOpDecorate %67 NonReadable\nOpDecorate %67 Aliased\nOpDecorate %68 ArrayStride 8\nOpMemberDecorate %69 0 Offset 0\nOpDecorate %69 Block\nOpDecorate %72 DescriptorSet 4\nOpDecorate %72 Binding 0\nOpDecorate %72 NonReadable\nOpDecorate %72 Aliased\nOpDecorate %182 BuiltIn GlobalInvocationId\nOpDecorate %539 NonUniform\nOpDecorate %536 NonUniform\nOpDecorate %543 NonUniform\nOpDecorate %540 NonUniform\nOpDecorate %553 NonUniform\nOpDecorate %585 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeVector %14 2\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypeStruct %21\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeVector %14 4\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypeStruct %27\n%29 = OpTypeRuntimeArray %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeRuntimeArray %14\n%33 = OpTypeStruct %32\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypePointer StorageBuffer %34\n%36 = OpVariable %35 StorageBuffer\n%37 = OpTypeRuntimeArray %20\n%38 = OpTypeStruct %37\n%39 = OpTypeRuntimeArray %38\n%40 = OpTypePointer StorageBuffer %39\n%41 = OpVariable %40 StorageBuffer\n%42 = OpTypeRuntimeArray %26\n%43 = OpTypeStruct %42\n%44 = OpTypeRuntimeArray %43\n%45 = OpTypePointer StorageBuffer %44\n%46 = OpVariable %45 StorageBuffer\n%47 = OpTypeRuntimeArray %5\n%48 = OpTypeStruct %47\n%49 = OpTypeRuntimeArray %48\n%50 = OpTypePointer StorageBuffer %49\n%51 = OpVariable %50 StorageBuffer\n%52 = OpTypeVector %5 4\n%53 = OpTypeRuntimeArray %52\n%54 = OpTypeStruct %53\n%55 = OpTypeRuntimeArray %54\n%56 = OpTypePointer StorageBuffer %55\n%57 = OpVariable %56 StorageBuffer\n%58 = OpTypeRuntimeArray %14\n%59 = OpTypeStruct %58\n%60 = OpTypeRuntimeArray %59\n%61 = OpTypePointer StorageBuffer %60\n%62 = OpVariable %61 StorageBuffer\n%63 = OpTypeRuntimeArray %20\n%64 = OpTypeStruct %63\n%65 = OpTypeRuntimeArray %64\n%66 = OpTypePointer StorageBuffer %65\n%67 = OpVariable %66 StorageBuffer\n%68 = OpTypeRuntimeArray %26\n%69 = OpTypeStruct %68\n%70 = OpTypeRuntimeArray %69\n%71 = OpTypePointer StorageBuffer %70\n%72 = OpVariable %71 StorageBuffer\n%73 = OpTypePointer StorageBuffer %59\n%75 = OpTypePointer PushConstant %5\n%77 = OpConstant %5 4\n%80 = OpConstant %5 6\n%81 = OpTypePointer StorageBuffer %64\n%86 = OpTypePointer StorageBuffer %69\n%92 = OpConstant %5 3\n%93 = OpTypePointer StorageBuffer %9\n%95 = OpConstant %5 0\n%101 = OpConstant %5 5\n%113 = OpTypePointer StorageBuffer %33\n%118 = OpTypePointer StorageBuffer %38\n%123 = OpTypePointer StorageBuffer %43\n%128 = OpTypePointer StorageBuffer %48\n%133 = OpTypePointer StorageBuffer %54\n%141 = OpTypePointer StorageBuffer %28\n%150 = OpConstantComposite %9 %92 %92\n%151 = OpTypePointer StorageBuffer %16\n%156 = OpConstant %5 2\n%161 = OpConstant %5 1\n%162 = OpConstantComposite %9 %161 %161\n%163 = OpTypePointer StorageBuffer %22\n%172 = OpConstantComposite %9 %156 %156\n%180 = OpTypeVector %5 3\n%181 = OpTypePointer Input %180\n%182 = OpVariable %181 Input\n%183 = OpTypePointer Input %5\n%189 = OpTypeBool\n%192 = OpConstant %5 2147483644\n%193 = OpTypePointer StorageBuffer %14\n%196 = OpTypeFloat 16\n%199 = OpConstant %196 0x1p+0\n%212 = OpConstant %5 1073741823\n%213 = OpTypePointer StorageBuffer %20\n%219 = OpConstant %14 2\n%242 = OpTypeVector %14 3\n%244 = OpTypeVector %196 3\n%250 = OpConstant %196 0x1.8p+1\n%272 = OpConstant %5 536870911\n%273 = OpTypePointer StorageBuffer %26\n%281 = OpConstant %14 4\n%302 = OpTypeFloat 32\n%313 = OpTypeVector %196 2\n%354 = OpTypeVector %196 4\n%442 = OpConstant %196 0x1p+1\n%444 = OpConstant %196 0x1p+2\n%456 = OpConstant %196 0x1.4p+2\n%458 = OpConstant %196 0x1.8p+2\n%471 = OpConstant %196 0x1.cp+2\n%473 = OpConstant %196 0x1p+3\n%475 = OpConstant %196 0x1.2p+3\n%477 = OpConstant %196 0x1.4p+3\n%487 = OpConstant %14 1\n%504 = OpConstant %14 5\n%505 = OpConstant %14 6\n%517 = OpConstant %14 7\n%518 = OpConstant %14 8\n%519 = OpConstant %14 9\n%520 = OpConstant %14 10\n%529 = OpConstant %5 1073741820\n%530 = OpTypePointer StorageBuffer %5\n%591 = OpConstant %302 2\n%597 = OpConstant %302 8\n%609 = OpConstant %5 8\n%618 = OpConstantComposite %9 %77 %77\n%624 = OpConstant %5 268435455\n%626 = OpTypePointer StorageBuffer %52\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %628\n%628 = OpLabel\n%76 = OpAccessChain %75 %8 %77\n%78 = OpLoad %5 %76\n%79 = OpIAdd %5 %78 %80\n%74 = OpAccessChain %73 %62 %79\n%83 = OpAccessChain %75 %8 %77\n%84 = OpLoad %5 %83\n%85 = OpIAdd %5 %84 %80\n%82 = OpAccessChain %81 %67 %85\n%88 = OpAccessChain %75 %8 %77\n%89 = OpLoad %5 %88\n%90 = OpIAdd %5 %89 %80\n%87 = OpAccessChain %86 %72 %90\n%91 = OpGroupNonUniformBroadcastFirst %5 %92 %90\n%94 = OpAccessChain %93 %13 %95 %91\n%96 = OpLoad %9 %94\n%98 = OpAccessChain %75 %8 %77\n%99 = OpLoad %5 %98\n%100 = OpIAdd %5 %99 %101\n%97 = OpAccessChain %73 %62 %100\n%103 = OpAccessChain %75 %8 %77\n%104 = OpLoad %5 %103\n%105 = OpIAdd %5 %104 %101\n%102 = OpAccessChain %81 %67 %105\n%107 = OpAccessChain %75 %8 %77\n%108 = OpLoad %5 %107\n%109 = OpIAdd %5 %108 %101\n%106 = OpAccessChain %86 %72 %109\n%110 = OpGroupNonUniformBroadcastFirst %5 %92 %109\n%111 = OpAccessChain %93 %13 %95 %110\n%112 = OpLoad %9 %111\n%115 = OpAccessChain %75 %8 %77\n%116 = OpLoad %5 %115\n%117 = OpIAdd %5 %116 %77\n%114 = OpAccessChain %113 %36 %117\n%120 = OpAccessChain %75 %8 %77\n%121 = OpLoad %5 %120\n%122 = OpIAdd %5 %121 %77\n%119 = OpAccessChain %118 %41 %122\n%125 = OpAccessChain %75 %8 %77\n%126 = OpLoad %5 %125\n%127 = OpIAdd %5 %126 %77\n%124 = OpAccessChain %123 %46 %127\n%130 = OpAccessChain %75 %8 %77\n%131 = OpLoad %5 %130\n%132 = OpIAdd %5 %131 %77\n%129 = OpAccessChain %128 %51 %132\n%135 = OpAccessChain %75 %8 %77\n%136 = OpLoad %5 %135\n%137 = OpIAdd %5 %136 %77\n%134 = OpAccessChain %133 %57 %137\n%138 = OpGroupNonUniformBroadcastFirst %5 %92 %137\n%139 = OpAccessChain %93 %13 %95 %138\n%140 = OpLoad %9 %139\n%143 = OpAccessChain %75 %8 %77\n%144 = OpLoad %5 %143\n%145 = OpIAdd %5 %144 %92\n%142 = OpAccessChain %141 %31 %145\n%146 = OpGroupNonUniformBroadcastFirst %5 %92 %145\n%147 = OpAccessChain %93 %13 %95 %146\n%148 = OpLoad %9 %147\n%149 = OpShiftRightLogical %9 %148 %150\n%153 = OpAccessChain %75 %8 %77\n%154 = OpLoad %5 %153\n%155 = OpIAdd %5 %154 %156\n%152 = OpAccessChain %151 %19 %155\n%157 = OpGroupNonUniformBroadcastFirst %5 %92 %155\n%158 = OpAccessChain %93 %13 %95 %157\n%159 = OpLoad %9 %158\n%160 = OpShiftRightLogical %9 %159 %162\n%165 = OpAccessChain %75 %8 %77\n%166 = OpLoad %5 %165\n%167 = OpIAdd %5 %166 %161\n%164 = OpAccessChain %163 %25 %167\n%168 = OpGroupNonUniformBroadcastFirst %5 %92 %167\n%169 = OpAccessChain %93 %13 %95 %168\n%170 = OpLoad %9 %169\n%171 = OpShiftRightLogical %9 %170 %172\n%174 = OpAccessChain %75 %8 %77\n%175 = OpLoad %5 %174\n%173 = OpAccessChain %151 %19 %175\n%176 = OpGroupNonUniformBroadcastFirst %5 %92 %175\n%177 = OpAccessChain %93 %13 %95 %176\n%178 = OpLoad %9 %177\n%179 = OpShiftRightLogical %9 %178 %162\n%184 = OpAccessChain %183 %182 %95\n%185 = OpLoad %5 %184\n%186 = OpCompositeExtract %5 %179 0\n%187 = OpCompositeExtract %5 %179 1\n%188 = OpIAdd %5 %185 %186\n%190 = OpULessThan %189 %185 %187\n%191 = OpSelect %5 %190 %188 %192\n%194 = OpAccessChain %193 %173 %95 %191\n%195 = OpLoad %14 %194\n%197 = OpBitcast %196 %195\n%198 = OpFAdd %196 %197 %199\n%200 = OpCompositeExtract %5 %179 0\n%201 = OpCompositeExtract %5 %179 1\n%202 = OpIAdd %5 %185 %200\n%203 = OpULessThan %189 %185 %201\n%204 = OpSelect %5 %203 %202 %192\n%205 = OpBitcast %14 %198\n%206 = OpAccessChain %193 %173 %95 %204\nOpStore %206 %205\n%207 = OpCompositeExtract %5 %171 0\n%208 = OpCompositeExtract %5 %171 1\n%209 = OpIAdd %5 %185 %207\n%210 = OpULessThan %189 %185 %208\n%211 = OpSelect %5 %210 %209 %212\n%214 = OpAccessChain %213 %164 %95 %211\n%215 = OpLoad %20 %214\n%216 = OpCompositeExtract %14 %215 0\n%217 = OpCompositeExtract %14 %215 1\n%218 = OpIAdd %14 %216 %219\n%220 = OpIAdd %14 %217 %219\n%221 = OpCompositeExtract %5 %171 0\n%222 = OpCompositeExtract %5 %171 1\n%223 = OpIAdd %5 %185 %221\n%224 = OpULessThan %189 %185 %222\n%225 = OpSelect %5 %224 %223 %212\n%226 = OpCompositeConstruct %20 %218 %220\n%227 = OpAccessChain %213 %164 %95 %225\nOpStore %227 %226\n%228 = OpIMul %5 %185 %92\n%229 = OpCompositeExtract %5 %160 0\n%230 = OpCompositeExtract %5 %160 1\n%231 = OpIAdd %5 %228 %229\n%232 = OpULessThan %189 %228 %230\n%233 = OpSelect %5 %232 %231 %192\n%234 = OpAccessChain %193 %152 %95 %233\n%235 = OpLoad %14 %234\n%237 = OpIAdd %5 %233 %161\n%236 = OpAccessChain %193 %152 %95 %237\n%238 = OpLoad %14 %236\n%240 = OpIAdd %5 %233 %156\n%239 = OpAccessChain %193 %152 %95 %240\n%241 = OpLoad %14 %239\n%243 = OpCompositeConstruct %242 %235 %238 %241\n%245 = OpBitcast %244 %243\n%246 = OpCompositeExtract %196 %245 0\n%247 = OpCompositeExtract %196 %245 1\n%248 = OpCompositeExtract %196 %245 2\n%249 = OpFAdd %196 %246 %250\n%251 = OpFAdd %196 %247 %250\n%252 = OpFAdd %196 %248 %250\n%253 = OpIMul %5 %185 %92\n%254 = OpCompositeExtract %5 %160 0\n%255 = OpCompositeExtract %5 %160 1\n%256 = OpIAdd %5 %253 %254\n%257 = OpULessThan %189 %253 %255\n%258 = OpSelect %5 %257 %256 %192\n%259 = OpBitcast %14 %249\n%260 = OpBitcast %14 %251\n%261 = OpBitcast %14 %252\n%262 = OpAccessChain %193 %152 %95 %258\nOpStore %262 %259\n%264 = OpIAdd %5 %258 %161\n%263 = OpAccessChain %193 %152 %95 %264\nOpStore %263 %260\n%266 = OpIAdd %5 %258 %156\n%265 = OpAccessChain %193 %152 %95 %266\nOpStore %265 %261\n%267 = OpCompositeExtract %5 %149 0\n%268 = OpCompositeExtract %5 %149 1\n%269 = OpIAdd %5 %185 %267\n%270 = OpULessThan %189 %185 %268\n%271 = OpSelect %5 %270 %269 %272\n%274 = OpAccessChain %273 %142 %95 %271\n%275 = OpLoad %26 %274\n%276 = OpCompositeExtract %14 %275 0\n%277 = OpCompositeExtract %14 %275 1\n%278 = OpCompositeExtract %14 %275 2\n%279 = OpCompositeExtract %14 %275 3\n%280 = OpIAdd %14 %276 %281\n%282 = OpIAdd %14 %277 %281\n%283 = OpIAdd %14 %278 %281\n%284 = OpIAdd %14 %279 %281\n%285 = OpCompositeExtract %5 %149 0\n%286 = OpCompositeExtract %5 %149 1\n%287 = OpIAdd %5 %185 %285\n%288 = OpULessThan %189 %185 %286\n%289 = OpSelect %5 %288 %287 %272\n%290 = OpCompositeConstruct %26 %280 %282 %283 %284\n%291 = OpAccessChain %273 %142 %95 %289\nOpStore %291 %290\n%292 = OpShiftLeftLogical %5 %185 %161\n%293 = OpShiftRightLogical %9 %140 %162\n%294 = OpCompositeExtract %5 %293 0\n%295 = OpCompositeExtract %5 %293 1\n%296 = OpIAdd %5 %185 %294\n%297 = OpULessThan %189 %185 %295\n%298 = OpSelect %5 %297 %296 %192\n%299 = OpAccessChain %193 %114 %95 %298\n%300 = OpLoad %14 %299\n%301 = OpBitcast %196 %300\n%303 = OpFConvert %302 %301\n%304 = OpShiftLeftLogical %5 %185 %156\n%305 = OpShiftRightLogical %9 %140 %172\n%306 = OpCompositeExtract %5 %305 0\n%307 = OpCompositeExtract %5 %305 1\n%308 = OpIAdd %5 %185 %306\n%309 = OpULessThan %189 %185 %307\n%310 = OpSelect %5 %309 %308 %212\n%311 = OpAccessChain %213 %119 %95 %310\n%312 = OpLoad %20 %311\n%314 = OpBitcast %313 %312\n%315 = OpCompositeExtract %196 %314 0\n%316 = OpCompositeExtract %196 %314 1\n%317 = OpFConvert %302 %315\n%318 = OpFConvert %302 %316\n%319 = OpFAdd %302 %318 %303\n%320 = OpIMul %5 %185 %80\n%321 = OpIMul %5 %185 %92\n%322 = OpShiftRightLogical %9 %140 %162\n%323 = OpCompositeExtract %5 %322 0\n%324 = OpCompositeExtract %5 %322 1\n%325 = OpIAdd %5 %321 %323\n%326 = OpULessThan %189 %321 %324\n%327 = OpSelect %5 %326 %325 %192\n%328 = OpAccessChain %193 %114 %95 %327\n%329 = OpLoad %14 %328\n%331 = OpIAdd %5 %327 %161\n%330 = OpAccessChain %193 %114 %95 %331\n%332 = OpLoad %14 %330\n%334 = OpIAdd %5 %327 %156\n%333 = OpAccessChain %193 %114 %95 %334\n%335 = OpLoad %14 %333\n%336 = OpCompositeConstruct %242 %329 %332 %335\n%337 = OpBitcast %244 %336\n%338 = OpCompositeExtract %196 %337 0\n%339 = OpCompositeExtract %196 %337 1\n%340 = OpCompositeExtract %196 %337 2\n%341 = OpFConvert %302 %338\n%342 = OpFConvert %302 %339\n%343 = OpFConvert %302 %340\n%344 = OpFAdd %302 %319 %343\n%345 = OpShiftLeftLogical %5 %185 %92\n%346 = OpShiftRightLogical %9 %140 %150\n%347 = OpCompositeExtract %5 %346 0\n%348 = OpCompositeExtract %5 %346 1\n%349 = OpIAdd %5 %185 %347\n%350 = OpULessThan %189 %185 %348\n%351 = OpSelect %5 %350 %349 %272\n%352 = OpAccessChain %273 %124 %95 %351\n%353 = OpLoad %26 %352\n%355 = OpBitcast %354 %353\n%356 = OpCompositeExtract %196 %355 0\n%357 = OpCompositeExtract %196 %355 1\n%358 = OpCompositeExtract %196 %355 2\n%359 = OpCompositeExtract %196 %355 3\n%360 = OpFConvert %302 %356\n%361 = OpFConvert %302 %357\n%362 = OpFConvert %302 %358\n%363 = OpFConvert %302 %359\n%364 = OpFAdd %302 %344 %362\n%365 = OpShiftRightLogical %9 %140 %162\n%366 = OpCompositeExtract %5 %365 0\n%367 = OpCompositeExtract %5 %365 1\n%368 = OpIAdd %5 %185 %366\n%369 = OpULessThan %189 %185 %367\n%370 = OpSelect %5 %369 %368 %192\n%371 = OpAccessChain %193 %114 %95 %370\n%372 = OpLoad %14 %371\n%373 = OpConvertUToF %302 %372\n%374 = OpFAdd %302 %364 %373\n%375 = OpShiftRightLogical %9 %140 %172\n%376 = OpCompositeExtract %5 %375 0\n%377 = OpCompositeExtract %5 %375 1\n%378 = OpIAdd %5 %185 %376\n%379 = OpULessThan %189 %185 %377\n%380 = OpSelect %5 %379 %378 %212\n%381 = OpAccessChain %213 %119 %95 %380\n%382 = OpLoad %20 %381\n%383 = OpCompositeExtract %14 %382 0\n%384 = OpCompositeExtract %14 %382 1\n%385 = OpConvertUToF %302 %383\n%386 = OpConvertUToF %302 %384\n%387 = OpFAdd %302 %374 %386\n%388 = OpIMul %5 %185 %92\n%389 = OpShiftRightLogical %9 %140 %162\n%390 = OpCompositeExtract %5 %389 0\n%391 = OpCompositeExtract %5 %389 1\n%392 = OpIAdd %5 %388 %390\n%393 = OpULessThan %189 %388 %391\n%394 = OpSelect %5 %393 %392 %192\n%395 = OpAccessChain %193 %114 %95 %394\n%396 = OpLoad %14 %395\n%398 = OpIAdd %5 %394 %161\n%397 = OpAccessChain %193 %114 %95 %398\n%399 = OpLoad %14 %397\n%401 = OpIAdd %5 %394 %156\n%400 = OpAccessChain %193 %114 %95 %401\n%402 = OpLoad %14 %400\n%403 = OpCompositeConstruct %242 %396 %399 %402\n%404 = OpCompositeExtract %14 %403 0\n%405 = OpCompositeExtract %14 %403 1\n%406 = OpCompositeExtract %14 %403 2\n%407 = OpConvertUToF %302 %404\n%408 = OpConvertUToF %302 %405\n%409 = OpConvertUToF %302 %406\n%410 = OpFAdd %302 %387 %409\n%411 = OpShiftRightLogical %9 %140 %150\n%412 = OpCompositeExtract %5 %411 0\n%413 = OpCompositeExtract %5 %411 1\n%414 = OpIAdd %5 %185 %412\n%415 = OpULessThan %189 %185 %413\n%416 = OpSelect %5 %415 %414 %272\n%417 = OpAccessChain %273 %124 %95 %416\n%418 = OpLoad %26 %417\n%419 = OpCompositeExtract %14 %418 0\n%420 = OpCompositeExtract %14 %418 1\n%421 = OpCompositeExtract %14 %418 2\n%422 = OpCompositeExtract %14 %418 3\n%423 = OpConvertUToF %302 %419\n%424 = OpConvertUToF %302 %420\n%425 = OpConvertUToF %302 %421\n%426 = OpConvertUToF %302 %422\n%427 = OpFAdd %302 %410 %425\n%428 = OpShiftRightLogical %9 %112 %162\n%429 = OpCompositeExtract %5 %428 0\n%430 = OpCompositeExtract %5 %428 1\n%431 = OpIAdd %5 %185 %429\n%432 = OpULessThan %189 %185 %430\n%433 = OpSelect %5 %432 %431 %192\n%434 = OpBitcast %14 %199\n%435 = OpAccessChain %193 %97 %95 %433\nOpStore %435 %434\n%436 = OpShiftRightLogical %9 %112 %172\n%437 = OpCompositeExtract %5 %436 0\n%438 = OpCompositeExtract %5 %436 1\n%439 = OpIAdd %5 %185 %437\n%440 = OpULessThan %189 %185 %438\n%441 = OpSelect %5 %440 %439 %212\n%443 = OpBitcast %14 %442\n%445 = OpBitcast %14 %444\n%446 = OpCompositeConstruct %20 %443 %445\n%447 = OpAccessChain %213 %102 %95 %441\nOpStore %447 %446\n%448 = OpIMul %5 %185 %92\n%449 = OpShiftRightLogical %9 %112 %162\n%450 = OpCompositeExtract %5 %449 0\n%451 = OpCompositeExtract %5 %449 1\n%452 = OpIAdd %5 %448 %450\n%453 = OpULessThan %189 %448 %451\n%454 = OpSelect %5 %453 %452 %192\n%455 = OpBitcast %14 %444\n%457 = OpBitcast %14 %456\n%459 = OpBitcast %14 %458\n%460 = OpAccessChain %193 %97 %95 %454\nOpStore %460 %455\n%462 = OpIAdd %5 %454 %161\n%461 = OpAccessChain %193 %97 %95 %462\nOpStore %461 %457\n%464 = OpIAdd %5 %454 %156\n%463 = OpAccessChain %193 %97 %95 %464\nOpStore %463 %459\n%465 = OpShiftRightLogical %9 %112 %150\n%466 = OpCompositeExtract %5 %465 0\n%467 = OpCompositeExtract %5 %465 1\n%468 = OpIAdd %5 %185 %466\n%469 = OpULessThan %189 %185 %467\n%470 = OpSelect %5 %469 %468 %272\n%472 = OpBitcast %14 %471\n%474 = OpBitcast %14 %473\n%476 = OpBitcast %14 %475\n%478 = OpBitcast %14 %477\n%479 = OpCompositeConstruct %26 %472 %474 %476 %478\n%480 = OpAccessChain %273 %106 %95 %470\nOpStore %480 %479\n%481 = OpShiftRightLogical %9 %96 %162\n%482 = OpCompositeExtract %5 %481 0\n%483 = OpCompositeExtract %5 %481 1\n%484 = OpIAdd %5 %185 %482\n%485 = OpULessThan %189 %185 %483\n%486 = OpSelect %5 %485 %484 %192\n%488 = OpAccessChain %193 %74 %95 %486\nOpStore %488 %487\n%489 = OpShiftRightLogical %9 %96 %172\n%490 = OpCompositeExtract %5 %489 0\n%491 = OpCompositeExtract %5 %489 1\n%492 = OpIAdd %5 %185 %490\n%493 = OpULessThan %189 %185 %491\n%494 = OpSelect %5 %493 %492 %212\n%495 = OpCompositeConstruct %20 %219 %281\n%496 = OpAccessChain %213 %82 %95 %494\nOpStore %496 %495\n%497 = OpIMul %5 %185 %92\n%498 = OpShiftRightLogical %9 %96 %162\n%499 = OpCompositeExtract %5 %498 0\n%500 = OpCompositeExtract %5 %498 1\n%501 = OpIAdd %5 %497 %499\n%502 = OpULessThan %189 %497 %500\n%503 = OpSelect %5 %502 %501 %192\n%506 = OpAccessChain %193 %74 %95 %503\nOpStore %506 %281\n%508 = OpIAdd %5 %503 %161\n%507 = OpAccessChain %193 %74 %95 %508\nOpStore %507 %504\n%510 = OpIAdd %5 %503 %156\n%509 = OpAccessChain %193 %74 %95 %510\nOpStore %509 %505\n%511 = OpShiftRightLogical %9 %96 %150\n%512 = OpCompositeExtract %5 %511 0\n%513 = OpCompositeExtract %5 %511 1\n%514 = OpIAdd %5 %185 %512\n%515 = OpULessThan %189 %185 %513\n%516 = OpSelect %5 %515 %514 %272\n%521 = OpCompositeConstruct %26 %517 %518 %519 %520\n%522 = OpAccessChain %273 %87 %95 %516\nOpStore %522 %521\n%523 = OpShiftRightLogical %9 %140 %172\n%524 = OpCompositeExtract %5 %523 0\n%525 = OpCompositeExtract %5 %523 1\n%526 = OpIAdd %5 %185 %524\n%527 = OpULessThan %189 %185 %525\n%528 = OpSelect %5 %527 %526 %529\n%531 = OpAccessChain %530 %129 %95 %528\n%532 = OpLoad %5 %531\n%533 = OpBitcast %302 %532\n%534 = OpFAdd %302 %427 %533\n%535 = OpIAdd %5 %185 %95\n%537 = OpAccessChain %75 %8 %77\n%538 = OpLoad %5 %537\n%539 = OpIAdd %5 %538 %535\n%536 = OpAccessChain %113 %36 %539\n%541 = OpAccessChain %75 %8 %77\n%542 = OpLoad %5 %541\n%543 = OpIAdd %5 %542 %535\n%540 = OpAccessChain %118 %41 %543\n%544 = OpAccessChain %93 %13 %95 %543\n%545 = OpLoad %9 %544\n%546 = OpIMul %5 %185 %156\n%547 = OpShiftRightLogical %9 %545 %162\n%548 = OpCompositeExtract %5 %547 0\n%549 = OpCompositeExtract %5 %547 1\n%550 = OpIAdd %5 %546 %548\n%551 = OpULessThan %189 %546 %549\n%552 = OpSelect %5 %551 %550 %192\n%553 = OpAccessChain %193 %536 %95 %552\n%554 = OpLoad %14 %553\n%555 = OpBitcast %196 %554\n%556 = OpFConvert %302 %555\n%557 = OpFAdd %302 %317 %303\n%558 = OpFAdd %302 %557 %373\n%559 = OpFAdd %302 %558 %385\n%560 = OpFAdd %302 %559 %341\n%561 = OpFAdd %302 %560 %360\n%562 = OpFAdd %302 %561 %407\n%563 = OpFAdd %302 %562 %423\n%564 = OpFAdd %302 %563 %533\n%565 = OpFAdd %302 %564 %556\n%566 = OpFAdd %302 %559 %342\n%567 = OpFAdd %302 %566 %361\n%568 = OpFAdd %302 %567 %408\n%569 = OpFAdd %302 %568 %424\n%570 = OpFAdd %302 %569 %533\n%571 = OpFAdd %302 %570 %556\n%572 = OpFAdd %302 %534 %556\n%573 = OpFConvert %196 %565\n%574 = OpFConvert %196 %571\n%575 = OpIMul %5 %185 %156\n%576 = OpShiftRightLogical %9 %545 %172\n%577 = OpCompositeExtract %5 %576 0\n%578 = OpCompositeExtract %5 %576 1\n%579 = OpIAdd %5 %575 %577\n%580 = OpULessThan %189 %575 %578\n%581 = OpSelect %5 %580 %579 %212\n%582 = OpBitcast %14 %573\n%583 = OpBitcast %14 %574\n%584 = OpCompositeConstruct %20 %582 %583\n%585 = OpAccessChain %213 %540 %95 %581\nOpStore %585 %584\n%586 = OpCompositeExtract %5 %179 1\n%587 = OpUDiv %5 %586 %161\n%588 = OpConvertUToF %302 %587\n%589 = OpFAdd %302 %588 %565\n%590 = OpFAdd %302 %571 %591\n%592 = OpCompositeExtract %5 %149 1\n%593 = OpUDiv %5 %592 %161\n%594 = OpConvertUToF %302 %593\n%595 = OpFAdd %302 %572 %594\n%596 = OpFAdd %302 %303 %597\n%598 = OpFAdd %302 %596 %318\n%599 = OpFAdd %302 %598 %341\n%600 = OpFAdd %302 %599 %363\n%601 = OpFAdd %302 %600 %373\n%602 = OpFAdd %302 %601 %386\n%603 = OpFAdd %302 %602 %407\n%604 = OpFAdd %302 %603 %426\n%605 = OpFAdd %302 %604 %533\n%606 = OpFAdd %302 %605 %556\n%607 = OpCompositeExtract %5 %112 1\n%608 = OpIMul %5 %607 %609\n%610 = OpConvertUToF %302 %608\n%611 = OpFAdd %302 %589 %610\n%612 = OpConvertFToU %5 %611\n%613 = OpConvertFToU %5 %590\n%614 = OpConvertFToU %5 %595\n%615 = OpConvertFToU %5 %606\n%616 = OpShiftLeftLogical %5 %185 %77\n%617 = OpShiftRightLogical %9 %140 %618\n%619 = OpCompositeExtract %5 %617 0\n%620 = OpCompositeExtract %5 %617 1\n%621 = OpIAdd %5 %185 %619\n%622 = OpULessThan %189 %185 %620\n%623 = OpSelect %5 %622 %621 %624\n%625 = OpCompositeConstruct %52 %612 %613 %614 %615\n%627 = OpAccessChain %626 %134 %95 %623\nOpStore %627 %625\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-16bit.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint16_t _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) buffer _12_14\n{\n    u16vec2 _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, scalar) buffer _17_19\n{\n    u16vec3 _m0[];\n} _19;\n\nlayout(set = 0, binding = 3, std430) buffer _22_24\n{\n    u16vec4 _m0[];\n} _24;\n\nlayout(set = 0, binding = 4, std430) buffer _26_28\n{\n    uint16_t _m0[];\n} _28;\n\nlayout(set = 0, binding = 4, std430) buffer _30_32\n{\n    u16vec2 _m0[];\n} _32;\n\nlayout(set = 0, binding = 4, scalar) buffer _34_36\n{\n    u16vec3 _m0[];\n} _36;\n\nlayout(set = 0, binding = 4, std430) buffer _38_40\n{\n    u16vec4 _m0[];\n} _40;\n\nlayout(set = 0, binding = 4, std430) buffer _43_45\n{\n    uint _m0[];\n} _45;\n\nlayout(set = 0, binding = 4, std430) buffer _48_50\n{\n    uvec4 _m0[];\n} _50;\n\nlayout(set = 0, binding = 5, std430) writeonly buffer _52_54\n{\n    uint16_t _m0[];\n} _54;\n\nlayout(set = 0, binding = 5, std430) writeonly buffer _56_58\n{\n    u16vec2 _m0[];\n} _58;\n\nlayout(set = 0, binding = 5, scalar) writeonly buffer _60_62\n{\n    u16vec3 _m0[];\n} _62;\n\nlayout(set = 0, binding = 5, std430) writeonly buffer _64_66\n{\n    u16vec4 _m0[];\n} _66;\n\nlayout(set = 0, binding = 6, std430) writeonly buffer _68_70\n{\n    uint16_t _m0[];\n} _70;\n\nlayout(set = 0, binding = 6, std430) writeonly buffer _72_74\n{\n    u16vec2 _m0[];\n} _74;\n\nlayout(set = 0, binding = 6, scalar) writeonly buffer _76_78\n{\n    u16vec3 _m0[];\n} _78;\n\nlayout(set = 0, binding = 6, std430) writeonly buffer _80_82\n{\n    u16vec4 _m0[];\n} _82;\n\nlayout(set = 1, binding = 0, std430) buffer _84_87\n{\n    uint16_t _m0[];\n} _87[];\n\nlayout(set = 1, binding = 0, std430) buffer _89_92\n{\n    u16vec2 _m0[];\n} _92[];\n\nvoid main()\n{\n    _9._m0[gl_GlobalInvocationID.x] = float16BitsToUint16(uint16BitsToFloat16(_9._m0[gl_GlobalInvocationID.x]) + float16_t(1.0));\n    _14._m0[gl_GlobalInvocationID.x] = u16vec2(_14._m0[gl_GlobalInvocationID.x].x + 2us, _14._m0[gl_GlobalInvocationID.x].y + 2us);\n    f16vec3 _123 = uint16BitsToFloat16(_19._m0[gl_GlobalInvocationID.x]);\n    _19._m0[gl_GlobalInvocationID.x] = u16vec3(float16BitsToUint16(_123.x + float16_t(3.0)), float16BitsToUint16(_123.y + float16_t(3.0)), float16BitsToUint16(_123.z + float16_t(3.0)));\n    _24._m0[gl_GlobalInvocationID.x] = u16vec4(_24._m0[gl_GlobalInvocationID.x].x + 4us, _24._m0[gl_GlobalInvocationID.x].y + 4us, _24._m0[gl_GlobalInvocationID.x].z + 4us, _24._m0[gl_GlobalInvocationID.x].w + 4us);\n    uint16_t _153 = _28._m0[gl_GlobalInvocationID.x];\n    float _156 = float(uint16BitsToFloat16(_153));\n    u16vec2 _160 = _32._m0[gl_GlobalInvocationID.x];\n    f16vec2 _162 = uint16BitsToFloat16(_160);\n    float _166 = float(_162.y);\n    u16vec3 _171 = _36._m0[gl_GlobalInvocationID.x];\n    f16vec3 _172 = uint16BitsToFloat16(_171);\n    float _176 = float(_172.x);\n    u16vec4 _183 = _40._m0[gl_GlobalInvocationID.x];\n    f16vec4 _185 = uint16BitsToFloat16(_183);\n    uint16_t _196 = _28._m0[gl_GlobalInvocationID.x];\n    float _197 = float(_196);\n    u16vec2 _200 = _32._m0[gl_GlobalInvocationID.x];\n    float _204 = float(_200.y);\n    u16vec3 _207 = _36._m0[gl_GlobalInvocationID.x];\n    float _211 = float(_207.x);\n    u16vec4 _216 = _40._m0[gl_GlobalInvocationID.x];\n    _54._m0[gl_GlobalInvocationID.x] = float16BitsToUint16(float16_t(1.0));\n    _58._m0[gl_GlobalInvocationID.x] = u16vec2(float16BitsToUint16(float16_t(2.0)), float16BitsToUint16(float16_t(4.0)));\n    _62._m0[gl_GlobalInvocationID.x] = u16vec3(float16BitsToUint16(float16_t(4.0)), float16BitsToUint16(float16_t(5.0)), float16BitsToUint16(float16_t(6.0)));\n    _66._m0[gl_GlobalInvocationID.x] = u16vec4(float16BitsToUint16(float16_t(7.0)), float16BitsToUint16(float16_t(8.0)), float16BitsToUint16(float16_t(9.0)), float16BitsToUint16(float16_t(10.0)));\n    _70._m0[gl_GlobalInvocationID.x] = 1us;\n    _74._m0[gl_GlobalInvocationID.x] = u16vec2(2us, 4us);\n    _78._m0[gl_GlobalInvocationID.x] = u16vec3(4us, 5us, 6us);\n    _82._m0[gl_GlobalInvocationID.x] = u16vec4(7us, 8us, 9us, 10us);\n    uint _267 = _45._m0[gl_GlobalInvocationID.x];\n    float _268 = uintBitsToFloat(_267);\n    uint _270 = gl_GlobalInvocationID.x + 0u;\n    uint16_t _277 = _87[nonuniformEXT(_270)]._m0[gl_GlobalInvocationID.x * 2u];\n    float _279 = float(uint16BitsToFloat16(_277));\n    float _282 = ((float(_162.x) + _156) + _197) + float(_200.x);\n    float _288 = (((((_282 + _176) + float(_185.x)) + _211) + float(_216.x)) + _268) + _279;\n    float _294 = (((((_282 + float(_172.y)) + float(_185.y)) + float(_207.y)) + float(_216.y)) + _268) + _279;\n    _92[nonuniformEXT(_270)]._m0[gl_GlobalInvocationID.x * 2u] = u16vec2(float16BitsToUint16(float16_t(_288)), float16BitsToUint16(float16_t(_294)));\n    _50._m0[gl_GlobalInvocationID.x] = uvec4(uint((float(uint(_9._m0.length()) / 1u) + _288) + float(uint(_66._m0.length()) * 8u)), uint(_294 + 2.0), uint((((((((((_166 + _156) + float(_172.z)) + float(_185.z)) + _197) + _204) + float(_207.z)) + float(_216.z)) + _268) + _279) + float(uint(_24._m0.length()) / 1u)), uint((((((((((_156 + 8.0) + _166) + _176) + float(_185.w)) + _197) + _204) + _211) + float(_216.w)) + _268) + _279));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 340\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageQuery\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %95\nOpExecutionMode %3 LocalSize 64 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %30 \"SSBO\"\nOpName %34 \"SSBO\"\nOpName %38 \"SSBO\"\nOpName %43 \"SSBO\"\nOpName %48 \"SSBO\"\nOpName %52 \"SSBO\"\nOpName %56 \"SSBO\"\nOpName %60 \"SSBO\"\nOpName %64 \"SSBO\"\nOpName %68 \"SSBO\"\nOpName %72 \"SSBO\"\nOpName %76 \"SSBO\"\nOpName %80 \"SSBO\"\nOpName %84 \"SSBO\"\nOpName %89 \"SSBO\"\nOpDecorate %6 ArrayStride 2\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %16 ArrayStride 6\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 2\nOpDecorate %21 ArrayStride 8\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 3\nOpDecorate %25 ArrayStride 2\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 ArrayStride 4\nOpMemberDecorate %30 0 Offset 0\nOpDecorate %30 Block\nOpDecorate %33 ArrayStride 6\nOpMemberDecorate %34 0 Offset 0\nOpDecorate %34 Block\nOpDecorate %37 ArrayStride 8\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpDecorate %42 ArrayStride 4\nOpMemberDecorate %43 0 Offset 0\nOpDecorate %43 Block\nOpDecorate %47 ArrayStride 16\nOpMemberDecorate %48 0 Offset 0\nOpDecorate %48 Block\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 4\nOpDecorate %28 Aliased\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 4\nOpDecorate %32 Aliased\nOpDecorate %36 DescriptorSet 0\nOpDecorate %36 Binding 4\nOpDecorate %36 Aliased\nOpDecorate %40 DescriptorSet 0\nOpDecorate %40 Binding 4\nOpDecorate %40 Aliased\nOpDecorate %45 DescriptorSet 0\nOpDecorate %45 Binding 4\nOpDecorate %45 Aliased\nOpDecorate %50 DescriptorSet 0\nOpDecorate %50 Binding 4\nOpDecorate %50 Aliased\nOpDecorate %51 ArrayStride 2\nOpMemberDecorate %52 0 Offset 0\nOpDecorate %52 Block\nOpDecorate %55 ArrayStride 4\nOpMemberDecorate %56 0 Offset 0\nOpDecorate %56 Block\nOpDecorate %59 ArrayStride 6\nOpMemberDecorate %60 0 Offset 0\nOpDecorate %60 Block\nOpDecorate %63 ArrayStride 8\nOpMemberDecorate %64 0 Offset 0\nOpDecorate %64 Block\nOpDecorate %54 DescriptorSet 0\nOpDecorate %54 Binding 5\nOpDecorate %54 NonReadable\nOpDecorate %54 Aliased\nOpDecorate %58 DescriptorSet 0\nOpDecorate %58 Binding 5\nOpDecorate %58 NonReadable\nOpDecorate %58 Aliased\nOpDecorate %62 DescriptorSet 0\nOpDecorate %62 Binding 5\nOpDecorate %62 NonReadable\nOpDecorate %62 Aliased\nOpDecorate %66 DescriptorSet 0\nOpDecorate %66 Binding 5\nOpDecorate %66 NonReadable\nOpDecorate %66 Aliased\nOpDecorate %67 ArrayStride 2\nOpMemberDecorate %68 0 Offset 0\nOpDecorate %68 Block\nOpDecorate %71 ArrayStride 4\nOpMemberDecorate %72 0 Offset 0\nOpDecorate %72 Block\nOpDecorate %75 ArrayStride 6\nOpMemberDecorate %76 0 Offset 0\nOpDecorate %76 Block\nOpDecorate %79 ArrayStride 8\nOpMemberDecorate %80 0 Offset 0\nOpDecorate %80 Block\nOpDecorate %70 DescriptorSet 0\nOpDecorate %70 Binding 6\nOpDecorate %70 NonReadable\nOpDecorate %70 Aliased\nOpDecorate %74 DescriptorSet 0\nOpDecorate %74 Binding 6\nOpDecorate %74 NonReadable\nOpDecorate %74 Aliased\nOpDecorate %78 DescriptorSet 0\nOpDecorate %78 Binding 6\nOpDecorate %78 NonReadable\nOpDecorate %78 Aliased\nOpDecorate %82 DescriptorSet 0\nOpDecorate %82 Binding 6\nOpDecorate %82 NonReadable\nOpDecorate %82 Aliased\nOpDecorate %83 ArrayStride 2\nOpMemberDecorate %84 0 Offset 0\nOpDecorate %84 Block\nOpDecorate %88 ArrayStride 4\nOpMemberDecorate %89 0 Offset 0\nOpDecorate %89 Block\nOpDecorate %87 DescriptorSet 1\nOpDecorate %87 Binding 0\nOpDecorate %87 Aliased\nOpDecorate %92 DescriptorSet 1\nOpDecorate %92 Binding 0\nOpDecorate %92 Aliased\nOpDecorate %95 BuiltIn GlobalInvocationId\nOpDecorate %270 NonUniform\nOpDecorate %272 NonUniform\nOpDecorate %274 NonUniform\nOpDecorate %276 NonUniform\nOpDecorate %302 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 16 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 3\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeVector %5 4\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %5\n%26 = OpTypeStruct %25\n%27 = OpTypePointer StorageBuffer %26\n%28 = OpVariable %27 StorageBuffer\n%29 = OpTypeRuntimeArray %10\n%30 = OpTypeStruct %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpTypeRuntimeArray %15\n%34 = OpTypeStruct %33\n%35 = OpTypePointer StorageBuffer %34\n%36 = OpVariable %35 StorageBuffer\n%37 = OpTypeRuntimeArray %20\n%38 = OpTypeStruct %37\n%39 = OpTypePointer StorageBuffer %38\n%40 = OpVariable %39 StorageBuffer\n%41 = OpTypeInt 32 0\n%42 = OpTypeRuntimeArray %41\n%43 = OpTypeStruct %42\n%44 = OpTypePointer StorageBuffer %43\n%45 = OpVariable %44 StorageBuffer\n%46 = OpTypeVector %41 4\n%47 = OpTypeRuntimeArray %46\n%48 = OpTypeStruct %47\n%49 = OpTypePointer StorageBuffer %48\n%50 = OpVariable %49 StorageBuffer\n%51 = OpTypeRuntimeArray %5\n%52 = OpTypeStruct %51\n%53 = OpTypePointer StorageBuffer %52\n%54 = OpVariable %53 StorageBuffer\n%55 = OpTypeRuntimeArray %10\n%56 = OpTypeStruct %55\n%57 = OpTypePointer StorageBuffer %56\n%58 = OpVariable %57 StorageBuffer\n%59 = OpTypeRuntimeArray %15\n%60 = OpTypeStruct %59\n%61 = OpTypePointer StorageBuffer %60\n%62 = OpVariable %61 StorageBuffer\n%63 = OpTypeRuntimeArray %20\n%64 = OpTypeStruct %63\n%65 = OpTypePointer StorageBuffer %64\n%66 = OpVariable %65 StorageBuffer\n%67 = OpTypeRuntimeArray %5\n%68 = OpTypeStruct %67\n%69 = OpTypePointer StorageBuffer %68\n%70 = OpVariable %69 StorageBuffer\n%71 = OpTypeRuntimeArray %10\n%72 = OpTypeStruct %71\n%73 = OpTypePointer StorageBuffer %72\n%74 = OpVariable %73 StorageBuffer\n%75 = OpTypeRuntimeArray %15\n%76 = OpTypeStruct %75\n%77 = OpTypePointer StorageBuffer %76\n%78 = OpVariable %77 StorageBuffer\n%79 = OpTypeRuntimeArray %20\n%80 = OpTypeStruct %79\n%81 = OpTypePointer StorageBuffer %80\n%82 = OpVariable %81 StorageBuffer\n%83 = OpTypeRuntimeArray %5\n%84 = OpTypeStruct %83\n%85 = OpTypeRuntimeArray %84\n%86 = OpTypePointer StorageBuffer %85\n%87 = OpVariable %86 StorageBuffer\n%88 = OpTypeRuntimeArray %10\n%89 = OpTypeStruct %88\n%90 = OpTypeRuntimeArray %89\n%91 = OpTypePointer StorageBuffer %90\n%92 = OpVariable %91 StorageBuffer\n%93 = OpTypeVector %41 3\n%94 = OpTypePointer Input %93\n%95 = OpVariable %94 Input\n%96 = OpTypePointer Input %41\n%98 = OpConstant %41 0\n%100 = OpTypePointer StorageBuffer %5\n%103 = OpTypeFloat 16\n%106 = OpConstant %103 0x1p+0\n%109 = OpTypePointer StorageBuffer %10\n%115 = OpConstant %5 2\n%119 = OpTypePointer StorageBuffer %15\n%122 = OpTypeVector %103 3\n%128 = OpConstant %103 0x1.8p+1\n%136 = OpTypePointer StorageBuffer %20\n%144 = OpConstant %5 4\n%151 = OpConstant %41 1\n%155 = OpTypeFloat 32\n%158 = OpConstant %41 2\n%161 = OpTypeVector %103 2\n%169 = OpConstant %41 6\n%181 = OpConstant %41 3\n%184 = OpTypeVector %103 4\n%228 = OpConstant %103 0x1p+1\n%230 = OpConstant %103 0x1p+2\n%235 = OpConstant %103 0x1.4p+2\n%237 = OpConstant %103 0x1.8p+2\n%241 = OpConstant %103 0x1.cp+2\n%243 = OpConstant %103 0x1p+3\n%245 = OpConstant %103 0x1.2p+3\n%247 = OpConstant %103 0x1.4p+3\n%251 = OpConstant %5 1\n%255 = OpConstant %5 5\n%256 = OpConstant %5 6\n%259 = OpConstant %5 7\n%260 = OpConstant %5 8\n%261 = OpConstant %5 9\n%262 = OpConstant %5 10\n%265 = OpTypePointer StorageBuffer %41\n%271 = OpTypePointer StorageBuffer %84\n%273 = OpTypePointer StorageBuffer %89\n%308 = OpConstant %155 2\n%314 = OpConstant %155 8\n%326 = OpConstant %41 8\n%334 = OpConstant %41 4\n%336 = OpTypePointer StorageBuffer %46\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %338\n%338 = OpLabel\n%97 = OpAccessChain %96 %95 %98\n%99 = OpLoad %41 %97\n%101 = OpAccessChain %100 %9 %98 %99\n%102 = OpLoad %5 %101\n%104 = OpBitcast %103 %102\n%105 = OpFAdd %103 %104 %106\n%107 = OpBitcast %5 %105\n%108 = OpAccessChain %100 %9 %98 %99\nOpStore %108 %107\n%110 = OpAccessChain %109 %14 %98 %99\n%111 = OpLoad %10 %110\n%112 = OpCompositeExtract %5 %111 0\n%113 = OpCompositeExtract %5 %111 1\n%114 = OpIAdd %5 %112 %115\n%116 = OpIAdd %5 %113 %115\n%117 = OpCompositeConstruct %10 %114 %116\n%118 = OpAccessChain %109 %14 %98 %99\nOpStore %118 %117\n%120 = OpAccessChain %119 %19 %98 %99\n%121 = OpLoad %15 %120\n%123 = OpBitcast %122 %121\n%124 = OpCompositeExtract %103 %123 0\n%125 = OpCompositeExtract %103 %123 1\n%126 = OpCompositeExtract %103 %123 2\n%127 = OpFAdd %103 %124 %128\n%129 = OpFAdd %103 %125 %128\n%130 = OpFAdd %103 %126 %128\n%131 = OpBitcast %5 %127\n%132 = OpBitcast %5 %129\n%133 = OpBitcast %5 %130\n%134 = OpCompositeConstruct %15 %131 %132 %133\n%135 = OpAccessChain %119 %19 %98 %99\nOpStore %135 %134\n%137 = OpAccessChain %136 %24 %98 %99\n%138 = OpLoad %20 %137\n%139 = OpCompositeExtract %5 %138 0\n%140 = OpCompositeExtract %5 %138 1\n%141 = OpCompositeExtract %5 %138 2\n%142 = OpCompositeExtract %5 %138 3\n%143 = OpIAdd %5 %139 %144\n%145 = OpIAdd %5 %140 %144\n%146 = OpIAdd %5 %141 %144\n%147 = OpIAdd %5 %142 %144\n%148 = OpCompositeConstruct %20 %143 %145 %146 %147\n%149 = OpAccessChain %136 %24 %98 %99\nOpStore %149 %148\n%150 = OpShiftLeftLogical %41 %99 %151\n%152 = OpAccessChain %100 %28 %98 %99\n%153 = OpLoad %5 %152\n%154 = OpBitcast %103 %153\n%156 = OpFConvert %155 %154\n%157 = OpShiftLeftLogical %41 %99 %158\n%159 = OpAccessChain %109 %32 %98 %99\n%160 = OpLoad %10 %159\n%162 = OpBitcast %161 %160\n%163 = OpCompositeExtract %103 %162 0\n%164 = OpCompositeExtract %103 %162 1\n%165 = OpFConvert %155 %163\n%166 = OpFConvert %155 %164\n%167 = OpFAdd %155 %166 %156\n%168 = OpIMul %41 %99 %169\n%170 = OpAccessChain %119 %36 %98 %99\n%171 = OpLoad %15 %170\n%172 = OpBitcast %122 %171\n%173 = OpCompositeExtract %103 %172 0\n%174 = OpCompositeExtract %103 %172 1\n%175 = OpCompositeExtract %103 %172 2\n%176 = OpFConvert %155 %173\n%177 = OpFConvert %155 %174\n%178 = OpFConvert %155 %175\n%179 = OpFAdd %155 %167 %178\n%180 = OpShiftLeftLogical %41 %99 %181\n%182 = OpAccessChain %136 %40 %98 %99\n%183 = OpLoad %20 %182\n%185 = OpBitcast %184 %183\n%186 = OpCompositeExtract %103 %185 0\n%187 = OpCompositeExtract %103 %185 1\n%188 = OpCompositeExtract %103 %185 2\n%189 = OpCompositeExtract %103 %185 3\n%190 = OpFConvert %155 %186\n%191 = OpFConvert %155 %187\n%192 = OpFConvert %155 %188\n%193 = OpFConvert %155 %189\n%194 = OpFAdd %155 %179 %192\n%195 = OpAccessChain %100 %28 %98 %99\n%196 = OpLoad %5 %195\n%197 = OpConvertUToF %155 %196\n%198 = OpFAdd %155 %194 %197\n%199 = OpAccessChain %109 %32 %98 %99\n%200 = OpLoad %10 %199\n%201 = OpCompositeExtract %5 %200 0\n%202 = OpCompositeExtract %5 %200 1\n%203 = OpConvertUToF %155 %201\n%204 = OpConvertUToF %155 %202\n%205 = OpFAdd %155 %198 %204\n%206 = OpAccessChain %119 %36 %98 %99\n%207 = OpLoad %15 %206\n%208 = OpCompositeExtract %5 %207 0\n%209 = OpCompositeExtract %5 %207 1\n%210 = OpCompositeExtract %5 %207 2\n%211 = OpConvertUToF %155 %208\n%212 = OpConvertUToF %155 %209\n%213 = OpConvertUToF %155 %210\n%214 = OpFAdd %155 %205 %213\n%215 = OpAccessChain %136 %40 %98 %99\n%216 = OpLoad %20 %215\n%217 = OpCompositeExtract %5 %216 0\n%218 = OpCompositeExtract %5 %216 1\n%219 = OpCompositeExtract %5 %216 2\n%220 = OpCompositeExtract %5 %216 3\n%221 = OpConvertUToF %155 %217\n%222 = OpConvertUToF %155 %218\n%223 = OpConvertUToF %155 %219\n%224 = OpConvertUToF %155 %220\n%225 = OpFAdd %155 %214 %223\n%226 = OpBitcast %5 %106\n%227 = OpAccessChain %100 %54 %98 %99\nOpStore %227 %226\n%229 = OpBitcast %5 %228\n%231 = OpBitcast %5 %230\n%232 = OpCompositeConstruct %10 %229 %231\n%233 = OpAccessChain %109 %58 %98 %99\nOpStore %233 %232\n%234 = OpBitcast %5 %230\n%236 = OpBitcast %5 %235\n%238 = OpBitcast %5 %237\n%239 = OpCompositeConstruct %15 %234 %236 %238\n%240 = OpAccessChain %119 %62 %98 %99\nOpStore %240 %239\n%242 = OpBitcast %5 %241\n%244 = OpBitcast %5 %243\n%246 = OpBitcast %5 %245\n%248 = OpBitcast %5 %247\n%249 = OpCompositeConstruct %20 %242 %244 %246 %248\n%250 = OpAccessChain %136 %66 %98 %99\nOpStore %250 %249\n%252 = OpAccessChain %100 %70 %98 %99\nOpStore %252 %251\n%253 = OpCompositeConstruct %10 %115 %144\n%254 = OpAccessChain %109 %74 %98 %99\nOpStore %254 %253\n%257 = OpCompositeConstruct %15 %144 %255 %256\n%258 = OpAccessChain %119 %78 %98 %99\nOpStore %258 %257\n%263 = OpCompositeConstruct %20 %259 %260 %261 %262\n%264 = OpAccessChain %136 %82 %98 %99\nOpStore %264 %263\n%266 = OpAccessChain %265 %45 %98 %99\n%267 = OpLoad %41 %266\n%268 = OpBitcast %155 %267\n%269 = OpFAdd %155 %225 %268\n%270 = OpIAdd %41 %99 %98\n%272 = OpAccessChain %271 %87 %270\n%274 = OpAccessChain %273 %92 %270\n%275 = OpIMul %41 %99 %158\n%276 = OpAccessChain %100 %272 %98 %275\n%277 = OpLoad %5 %276\n%278 = OpBitcast %103 %277\n%279 = OpFConvert %155 %278\n%280 = OpFAdd %155 %165 %156\n%281 = OpFAdd %155 %280 %197\n%282 = OpFAdd %155 %281 %203\n%283 = OpFAdd %155 %282 %176\n%284 = OpFAdd %155 %283 %190\n%285 = OpFAdd %155 %284 %211\n%286 = OpFAdd %155 %285 %221\n%287 = OpFAdd %155 %286 %268\n%288 = OpFAdd %155 %287 %279\n%289 = OpFAdd %155 %282 %177\n%290 = OpFAdd %155 %289 %191\n%291 = OpFAdd %155 %290 %212\n%292 = OpFAdd %155 %291 %222\n%293 = OpFAdd %155 %292 %268\n%294 = OpFAdd %155 %293 %279\n%295 = OpFAdd %155 %269 %279\n%296 = OpFConvert %103 %288\n%297 = OpFConvert %103 %294\n%298 = OpIMul %41 %99 %158\n%299 = OpBitcast %5 %296\n%300 = OpBitcast %5 %297\n%301 = OpCompositeConstruct %10 %299 %300\n%302 = OpAccessChain %109 %274 %98 %298\nOpStore %302 %301\n%303 = OpArrayLength %41 %9 0\n%304 = OpUDiv %41 %303 %151\n%305 = OpConvertUToF %155 %304\n%306 = OpFAdd %155 %305 %288\n%307 = OpFAdd %155 %294 %308\n%309 = OpArrayLength %41 %24 0\n%310 = OpUDiv %41 %309 %151\n%311 = OpConvertUToF %155 %310\n%312 = OpFAdd %155 %295 %311\n%313 = OpFAdd %155 %156 %314\n%315 = OpFAdd %155 %313 %166\n%316 = OpFAdd %155 %315 %176\n%317 = OpFAdd %155 %316 %193\n%318 = OpFAdd %155 %317 %197\n%319 = OpFAdd %155 %318 %204\n%320 = OpFAdd %155 %319 %211\n%321 = OpFAdd %155 %320 %224\n%322 = OpFAdd %155 %321 %268\n%323 = OpFAdd %155 %322 %279\n%324 = OpArrayLength %41 %66 0\n%325 = OpIMul %41 %324 %326\n%327 = OpConvertUToF %155 %325\n%328 = OpFAdd %155 %306 %327\n%329 = OpConvertFToU %41 %328\n%330 = OpConvertFToU %41 %307\n%331 = OpConvertFToU %41 %312\n%332 = OpConvertFToU %41 %323\n%333 = OpShiftLeftLogical %41 %99 %334\n%335 = OpCompositeConstruct %46 %329 %330 %331 %332\n%337 = OpAccessChain %336 %50 %98 %99\nOpStore %337 %335\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-64bit.ssbo.bindless.ssbo-align.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint64_t _m0[];\n} _19[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _21_24\n{\n    uint64_t _m0[];\n} _24[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _26_29\n{\n    uint64_t _m0[];\n} _29[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _31_34\n{\n    uint64_t _m0[];\n} _34[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _41 = registers._m4 + 1u;\n    uvec2 _49 = _13._m0[subgroupBroadcastFirst(_41)] >> uvec2(3u);\n    uvec2 _58 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(3u);\n    uint _63 = registers._m1 + 1u;\n    uvec2 _67 = _13._m0[subgroupBroadcastFirst(_63)] >> uvec2(3u);\n    uvec2 _75 = _13._m0[subgroupBroadcastFirst(registers._m1)] >> uvec2(3u);\n    uint _83 = gl_GlobalInvocationID.x * 6u;\n    uint _90 = (_83 < _75.y) ? (_83 + _75.x) : 536870908u;\n    u64vec3 _103 = u64vec3(_19[registers._m1]._m0[_90], _19[registers._m1]._m0[_90 + 1u], _19[registers._m1]._m0[_90 + 2u]);\n    uint64_t _104 = _103.x;\n    uint64_t _105 = _103.y;\n    uint64_t _106 = _103.z;\n    uint _109 = (gl_GlobalInvocationID.x * 6u) + 3u;\n    uint _114 = (_109 < _75.y) ? (_109 + _75.x) : 536870908u;\n    u64vec3 _123 = u64vec3(_19[registers._m1]._m0[_114], _19[registers._m1]._m0[_114 + 1u], _19[registers._m1]._m0[_114 + 2u]);\n    uint64_t _124 = _123.x;\n    uint64_t _125 = _123.y;\n    uint64_t _126 = _123.z;\n    uint _130 = gl_GlobalInvocationID.x << 3u;\n    uint _131 = gl_GlobalInvocationID.x * 24u;\n    uint _137 = (_131 < _58.y) ? (_131 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_137] = _124 + _104;\n    _29[registers._m4]._m0[_137 + 1u] = _125 + _105;\n    _29[registers._m4]._m0[_137 + 2u] = _126 + _106;\n    uint _148 = (gl_GlobalInvocationID.x * 24u) + 3u;\n    uint _153 = (_148 < _58.y) ? (_148 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_153] = _104 - _124;\n    _29[registers._m4]._m0[_153 + 1u] = _105 - _125;\n    _29[registers._m4]._m0[_153 + 2u] = _106 - _126;\n    uint _164 = (gl_GlobalInvocationID.x * 24u) + 6u;\n    uint _169 = (_164 < _58.y) ? (_164 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_169] = _124 * _104;\n    _29[registers._m4]._m0[_169 + 1u] = _125 * _105;\n    _29[registers._m4]._m0[_169 + 2u] = _126 * _106;\n    uint _181 = (gl_GlobalInvocationID.x * 24u) + 9u;\n    uint _186 = (_181 < _58.y) ? (_181 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_186] = _104 / _124;\n    _29[registers._m4]._m0[_186 + 1u] = _105 / _125;\n    _29[registers._m4]._m0[_186 + 2u] = _106 / _126;\n    uint64_t _192 = _124 & 63ul;\n    uint64_t _194 = _125 & 63ul;\n    uint64_t _195 = _126 & 63ul;\n    uint _202 = (gl_GlobalInvocationID.x * 24u) + 12u;\n    uint _207 = (_202 < _58.y) ? (_202 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_207] = _104 << _192;\n    _29[registers._m4]._m0[_207 + 1u] = _105 << _194;\n    _29[registers._m4]._m0[_207 + 2u] = _106 << _195;\n    uint _220 = (gl_GlobalInvocationID.x * 24u) + 15u;\n    uint _225 = (_220 < _58.y) ? (_220 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_225] = _104 >> _192;\n    _29[registers._m4]._m0[_225 + 1u] = _105 >> _194;\n    _29[registers._m4]._m0[_225 + 2u] = _106 >> _195;\n    uint _237 = (gl_GlobalInvocationID.x * 24u) + 18u;\n    uint _242 = (_237 < _58.y) ? (_237 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_242] = uint64_t(int64_t(_104) >> int64_t(_192));\n    _29[registers._m4]._m0[_242 + 1u] = uint64_t(int64_t(_105) >> int64_t(_194));\n    _29[registers._m4]._m0[_242 + 2u] = uint64_t(int64_t(_106) >> int64_t(_195));\n    uint _255 = (gl_GlobalInvocationID.x * 24u) + 21u;\n    uint _260 = (_255 < _58.y) ? (_255 + _58.x) : 536870908u;\n    _29[registers._m4]._m0[_260] = _124 & _104;\n    _29[registers._m4]._m0[_260 + 1u] = _125 & _105;\n    _29[registers._m4]._m0[_260 + 2u] = _126 & _106;\n    uint _267 = gl_GlobalInvocationID.x * 3u;\n    uint _272 = (_267 < _67.y) ? (_267 + _67.x) : 536870908u;\n    u64vec2 _279 = u64vec2(_24[_63]._m0[_272], _24[_63]._m0[_272 + 1u]);\n    uint _286 = (gl_GlobalInvocationID.x < _49.y) ? (gl_GlobalInvocationID.x + _49.x) : 536870908u;\n    _34[_41]._m0[_286] = _279.x;\n    _34[_41]._m0[_286 + 1u] = _279.y;\n    _34[_41]._m0[_286 + 2u] = _106;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 294\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %78\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %31 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %15 ArrayStride 8\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 8\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %25 ArrayStride 8\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 DescriptorSet 4\nOpDecorate %29 Binding 0\nOpDecorate %29 NonReadable\nOpDecorate %30 ArrayStride 8\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %34 DescriptorSet 4\nOpDecorate %34 Binding 0\nOpDecorate %34 NonReadable\nOpDecorate %78 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 64 0\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %14\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %14\n%26 = OpTypeStruct %25\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeRuntimeArray %14\n%31 = OpTypeStruct %30\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypePointer StorageBuffer %31\n%37 = OpTypePointer PushConstant %5\n%39 = OpConstant %5 4\n%42 = OpConstant %5 1\n%44 = OpConstant %5 3\n%45 = OpTypePointer StorageBuffer %9\n%47 = OpConstant %5 0\n%50 = OpConstantComposite %9 %44 %44\n%51 = OpTypePointer StorageBuffer %26\n%59 = OpTypePointer StorageBuffer %21\n%68 = OpTypePointer StorageBuffer %16\n%76 = OpTypeVector %5 3\n%77 = OpTypePointer Input %76\n%78 = OpVariable %77 Input\n%79 = OpTypePointer Input %5\n%84 = OpConstant %5 6\n%88 = OpTypeBool\n%91 = OpConstant %5 536870908\n%92 = OpTypePointer StorageBuffer %14\n%100 = OpConstant %5 2\n%102 = OpTypeVector %14 3\n%132 = OpConstant %5 24\n%180 = OpConstant %5 9\n%193 = OpConstant %14 63\n%201 = OpConstant %5 12\n%217 = OpConstant %5 5\n%219 = OpConstant %5 15\n%236 = OpConstant %5 18\n%252 = OpConstant %5 7\n%254 = OpConstant %5 21\n%278 = OpTypeVector %14 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %292\n%292 = OpLabel\n%38 = OpAccessChain %37 %8 %39\n%40 = OpLoad %5 %38\n%41 = OpIAdd %5 %40 %42\n%36 = OpAccessChain %35 %34 %41\n%43 = OpGroupNonUniformBroadcastFirst %5 %44 %41\n%46 = OpAccessChain %45 %13 %47 %43\n%48 = OpLoad %9 %46\n%49 = OpShiftRightLogical %9 %48 %50\n%53 = OpAccessChain %37 %8 %39\n%54 = OpLoad %5 %53\n%52 = OpAccessChain %51 %29 %54\n%55 = OpGroupNonUniformBroadcastFirst %5 %44 %54\n%56 = OpAccessChain %45 %13 %47 %55\n%57 = OpLoad %9 %56\n%58 = OpShiftRightLogical %9 %57 %50\n%61 = OpAccessChain %37 %8 %42\n%62 = OpLoad %5 %61\n%63 = OpIAdd %5 %62 %42\n%60 = OpAccessChain %59 %24 %63\n%64 = OpGroupNonUniformBroadcastFirst %5 %44 %63\n%65 = OpAccessChain %45 %13 %47 %64\n%66 = OpLoad %9 %65\n%67 = OpShiftRightLogical %9 %66 %50\n%70 = OpAccessChain %37 %8 %42\n%71 = OpLoad %5 %70\n%69 = OpAccessChain %68 %19 %71\n%72 = OpGroupNonUniformBroadcastFirst %5 %44 %71\n%73 = OpAccessChain %45 %13 %47 %72\n%74 = OpLoad %9 %73\n%75 = OpShiftRightLogical %9 %74 %50\n%80 = OpAccessChain %79 %78 %47\n%81 = OpLoad %5 %80\n%82 = OpShiftLeftLogical %5 %81 %42\n%83 = OpIMul %5 %81 %84\n%85 = OpCompositeExtract %5 %75 0\n%86 = OpCompositeExtract %5 %75 1\n%87 = OpIAdd %5 %83 %85\n%89 = OpULessThan %88 %83 %86\n%90 = OpSelect %5 %89 %87 %91\n%93 = OpAccessChain %92 %69 %47 %90\n%94 = OpLoad %14 %93\n%96 = OpIAdd %5 %90 %42\n%95 = OpAccessChain %92 %69 %47 %96\n%97 = OpLoad %14 %95\n%99 = OpIAdd %5 %90 %100\n%98 = OpAccessChain %92 %69 %47 %99\n%101 = OpLoad %14 %98\n%103 = OpCompositeConstruct %102 %94 %97 %101\n%104 = OpCompositeExtract %14 %103 0\n%105 = OpCompositeExtract %14 %103 1\n%106 = OpCompositeExtract %14 %103 2\n%107 = OpBitwiseOr %5 %82 %42\n%108 = OpIMul %5 %81 %84\n%109 = OpIAdd %5 %108 %44\n%110 = OpCompositeExtract %5 %75 0\n%111 = OpCompositeExtract %5 %75 1\n%112 = OpIAdd %5 %109 %110\n%113 = OpULessThan %88 %109 %111\n%114 = OpSelect %5 %113 %112 %91\n%115 = OpAccessChain %92 %69 %47 %114\n%116 = OpLoad %14 %115\n%118 = OpIAdd %5 %114 %42\n%117 = OpAccessChain %92 %69 %47 %118\n%119 = OpLoad %14 %117\n%121 = OpIAdd %5 %114 %100\n%120 = OpAccessChain %92 %69 %47 %121\n%122 = OpLoad %14 %120\n%123 = OpCompositeConstruct %102 %116 %119 %122\n%124 = OpCompositeExtract %14 %123 0\n%125 = OpCompositeExtract %14 %123 1\n%126 = OpCompositeExtract %14 %123 2\n%127 = OpIAdd %14 %124 %104\n%128 = OpIAdd %14 %125 %105\n%129 = OpIAdd %14 %126 %106\n%130 = OpShiftLeftLogical %5 %81 %44\n%131 = OpIMul %5 %81 %132\n%133 = OpCompositeExtract %5 %58 0\n%134 = OpCompositeExtract %5 %58 1\n%135 = OpIAdd %5 %131 %133\n%136 = OpULessThan %88 %131 %134\n%137 = OpSelect %5 %136 %135 %91\n%138 = OpAccessChain %92 %52 %47 %137\nOpStore %138 %127\n%140 = OpIAdd %5 %137 %42\n%139 = OpAccessChain %92 %52 %47 %140\nOpStore %139 %128\n%142 = OpIAdd %5 %137 %100\n%141 = OpAccessChain %92 %52 %47 %142\nOpStore %141 %129\n%143 = OpISub %14 %104 %124\n%144 = OpISub %14 %105 %125\n%145 = OpISub %14 %106 %126\n%146 = OpBitwiseOr %5 %130 %42\n%147 = OpIMul %5 %81 %132\n%148 = OpIAdd %5 %147 %44\n%149 = OpCompositeExtract %5 %58 0\n%150 = OpCompositeExtract %5 %58 1\n%151 = OpIAdd %5 %148 %149\n%152 = OpULessThan %88 %148 %150\n%153 = OpSelect %5 %152 %151 %91\n%154 = OpAccessChain %92 %52 %47 %153\nOpStore %154 %143\n%156 = OpIAdd %5 %153 %42\n%155 = OpAccessChain %92 %52 %47 %156\nOpStore %155 %144\n%158 = OpIAdd %5 %153 %100\n%157 = OpAccessChain %92 %52 %47 %158\nOpStore %157 %145\n%159 = OpIMul %14 %124 %104\n%160 = OpIMul %14 %125 %105\n%161 = OpIMul %14 %126 %106\n%162 = OpBitwiseOr %5 %130 %100\n%163 = OpIMul %5 %81 %132\n%164 = OpIAdd %5 %163 %84\n%165 = OpCompositeExtract %5 %58 0\n%166 = OpCompositeExtract %5 %58 1\n%167 = OpIAdd %5 %164 %165\n%168 = OpULessThan %88 %164 %166\n%169 = OpSelect %5 %168 %167 %91\n%170 = OpAccessChain %92 %52 %47 %169\nOpStore %170 %159\n%172 = OpIAdd %5 %169 %42\n%171 = OpAccessChain %92 %52 %47 %172\nOpStore %171 %160\n%174 = OpIAdd %5 %169 %100\n%173 = OpAccessChain %92 %52 %47 %174\nOpStore %173 %161\n%175 = OpUDiv %14 %104 %124\n%176 = OpUDiv %14 %105 %125\n%177 = OpUDiv %14 %106 %126\n%178 = OpBitwiseOr %5 %130 %44\n%179 = OpIMul %5 %81 %132\n%181 = OpIAdd %5 %179 %180\n%182 = OpCompositeExtract %5 %58 0\n%183 = OpCompositeExtract %5 %58 1\n%184 = OpIAdd %5 %181 %182\n%185 = OpULessThan %88 %181 %183\n%186 = OpSelect %5 %185 %184 %91\n%187 = OpAccessChain %92 %52 %47 %186\nOpStore %187 %175\n%189 = OpIAdd %5 %186 %42\n%188 = OpAccessChain %92 %52 %47 %189\nOpStore %188 %176\n%191 = OpIAdd %5 %186 %100\n%190 = OpAccessChain %92 %52 %47 %191\nOpStore %190 %177\n%192 = OpBitwiseAnd %14 %124 %193\n%194 = OpBitwiseAnd %14 %125 %193\n%195 = OpBitwiseAnd %14 %126 %193\n%196 = OpShiftLeftLogical %14 %104 %192\n%197 = OpShiftLeftLogical %14 %105 %194\n%198 = OpShiftLeftLogical %14 %106 %195\n%199 = OpBitwiseOr %5 %130 %39\n%200 = OpIMul %5 %81 %132\n%202 = OpIAdd %5 %200 %201\n%203 = OpCompositeExtract %5 %58 0\n%204 = OpCompositeExtract %5 %58 1\n%205 = OpIAdd %5 %202 %203\n%206 = OpULessThan %88 %202 %204\n%207 = OpSelect %5 %206 %205 %91\n%208 = OpAccessChain %92 %52 %47 %207\nOpStore %208 %196\n%210 = OpIAdd %5 %207 %42\n%209 = OpAccessChain %92 %52 %47 %210\nOpStore %209 %197\n%212 = OpIAdd %5 %207 %100\n%211 = OpAccessChain %92 %52 %47 %212\nOpStore %211 %198\n%213 = OpShiftRightLogical %14 %104 %192\n%214 = OpShiftRightLogical %14 %105 %194\n%215 = OpShiftRightLogical %14 %106 %195\n%216 = OpBitwiseOr %5 %130 %217\n%218 = OpIMul %5 %81 %132\n%220 = OpIAdd %5 %218 %219\n%221 = OpCompositeExtract %5 %58 0\n%222 = OpCompositeExtract %5 %58 1\n%223 = OpIAdd %5 %220 %221\n%224 = OpULessThan %88 %220 %222\n%225 = OpSelect %5 %224 %223 %91\n%226 = OpAccessChain %92 %52 %47 %225\nOpStore %226 %213\n%228 = OpIAdd %5 %225 %42\n%227 = OpAccessChain %92 %52 %47 %228\nOpStore %227 %214\n%230 = OpIAdd %5 %225 %100\n%229 = OpAccessChain %92 %52 %47 %230\nOpStore %229 %215\n%231 = OpShiftRightArithmetic %14 %104 %192\n%232 = OpShiftRightArithmetic %14 %105 %194\n%233 = OpShiftRightArithmetic %14 %106 %195\n%234 = OpBitwiseOr %5 %130 %84\n%235 = OpIMul %5 %81 %132\n%237 = OpIAdd %5 %235 %236\n%238 = OpCompositeExtract %5 %58 0\n%239 = OpCompositeExtract %5 %58 1\n%240 = OpIAdd %5 %237 %238\n%241 = OpULessThan %88 %237 %239\n%242 = OpSelect %5 %241 %240 %91\n%243 = OpAccessChain %92 %52 %47 %242\nOpStore %243 %231\n%245 = OpIAdd %5 %242 %42\n%244 = OpAccessChain %92 %52 %47 %245\nOpStore %244 %232\n%247 = OpIAdd %5 %242 %100\n%246 = OpAccessChain %92 %52 %47 %247\nOpStore %246 %233\n%248 = OpBitwiseAnd %14 %124 %104\n%249 = OpBitwiseAnd %14 %125 %105\n%250 = OpBitwiseAnd %14 %126 %106\n%251 = OpBitwiseOr %5 %130 %252\n%253 = OpIMul %5 %81 %132\n%255 = OpIAdd %5 %253 %254\n%256 = OpCompositeExtract %5 %58 0\n%257 = OpCompositeExtract %5 %58 1\n%258 = OpIAdd %5 %255 %256\n%259 = OpULessThan %88 %255 %257\n%260 = OpSelect %5 %259 %258 %91\n%261 = OpAccessChain %92 %52 %47 %260\nOpStore %261 %248\n%263 = OpIAdd %5 %260 %42\n%262 = OpAccessChain %92 %52 %47 %263\nOpStore %262 %249\n%265 = OpIAdd %5 %260 %100\n%264 = OpAccessChain %92 %52 %47 %265\nOpStore %264 %250\n%266 = OpIMul %5 %81 %132\n%267 = OpIMul %5 %81 %44\n%268 = OpCompositeExtract %5 %67 0\n%269 = OpCompositeExtract %5 %67 1\n%270 = OpIAdd %5 %267 %268\n%271 = OpULessThan %88 %267 %269\n%272 = OpSelect %5 %271 %270 %91\n%273 = OpAccessChain %92 %60 %47 %272\n%274 = OpLoad %14 %273\n%276 = OpIAdd %5 %272 %42\n%275 = OpAccessChain %92 %60 %47 %276\n%277 = OpLoad %14 %275\n%279 = OpCompositeConstruct %278 %274 %277\n%280 = OpCompositeExtract %14 %279 0\n%281 = OpCompositeExtract %14 %279 1\n%282 = OpCompositeExtract %5 %49 0\n%283 = OpCompositeExtract %5 %49 1\n%284 = OpIAdd %5 %81 %282\n%285 = OpULessThan %88 %81 %283\n%286 = OpSelect %5 %285 %284 %91\n%287 = OpAccessChain %92 %36 %47 %286\nOpStore %287 %280\n%289 = OpIAdd %5 %286 %42\n%288 = OpAccessChain %92 %36 %47 %289\nOpStore %288 %281\n%291 = OpIAdd %5 %286 %100\n%290 = OpAccessChain %92 %36 %47 %291\nOpStore %290 %106\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-64bit.ssbo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, scalar) restrict readonly buffer SSBO\n{\n    u64vec3 _m0[];\n} _11;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _13_15\n{\n    uint64_t _m0[];\n} _15;\n\nlayout(set = 0, binding = 0, scalar) writeonly buffer _17_19\n{\n    u64vec3 _m0[];\n} _19;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _21_23\n{\n    uint64_t _m0[];\n} _23;\n\nvoid main()\n{\n    uint _33 = gl_GlobalInvocationID.x * 2u;\n    uint _43 = (gl_GlobalInvocationID.x * 2u) + 1u;\n    uint _52 = gl_GlobalInvocationID.x << 3u;\n    _19._m0[gl_GlobalInvocationID.x * 8u] = u64vec3(_11._m0[_43].x + _11._m0[_33].x, _11._m0[_43].y + _11._m0[_33].y, _11._m0[_43].z + _11._m0[_33].z);\n    _19._m0[(gl_GlobalInvocationID.x * 8u) + 1u] = u64vec3(_11._m0[_33].x - _11._m0[_43].x, _11._m0[_33].y - _11._m0[_43].y, _11._m0[_33].z - _11._m0[_43].z);\n    _19._m0[(gl_GlobalInvocationID.x * 8u) + 2u] = u64vec3(_11._m0[_43].x * _11._m0[_33].x, _11._m0[_43].y * _11._m0[_33].y, _11._m0[_43].z * _11._m0[_33].z);\n    _19._m0[(gl_GlobalInvocationID.x * 8u) + 3u] = u64vec3(_11._m0[_33].x / _11._m0[_43].x, _11._m0[_33].y / _11._m0[_43].y, _11._m0[_33].z / _11._m0[_43].z);\n    uint64_t _82 = _11._m0[_43].x & 63ul;\n    uint64_t _84 = _11._m0[_43].y & 63ul;\n    uint64_t _85 = _11._m0[_43].z & 63ul;\n    _19._m0[(gl_GlobalInvocationID.x * 8u) + 4u] = u64vec3(_11._m0[_33].x << _82, _11._m0[_33].y << _84, _11._m0[_33].z << _85);\n    _19._m0[(gl_GlobalInvocationID.x * 8u) + 5u] = u64vec3(_11._m0[_33].x >> _82, _11._m0[_33].y >> _84, _11._m0[_33].z >> _85);\n    _19._m0[(gl_GlobalInvocationID.x * 8u) + 6u] = u64vec3(uint64_t(int64_t(_11._m0[_33].x) >> int64_t(_82)), uint64_t(int64_t(_11._m0[_33].y) >> int64_t(_84)), uint64_t(int64_t(_11._m0[_33].z) >> int64_t(_85)));\n    _19._m0[(gl_GlobalInvocationID.x * 8u) + 7u] = u64vec3(_11._m0[_43].x & _11._m0[_33].x, _11._m0[_43].y & _11._m0[_33].y, _11._m0[_43].z & _11._m0[_33].z);\n    uint _124 = gl_GlobalInvocationID.x * 3u;\n    u64vec2 _132 = u64vec2(_15._m0[_124], _15._m0[_124 + 1u]);\n    _23._m0[gl_GlobalInvocationID.x] = _132.x;\n    _23._m0[gl_GlobalInvocationID.x + 1u] = _132.y;\n    _23._m0[gl_GlobalInvocationID.x + 2u] = _11._m0[_33].z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 142\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %26\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %9 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %21 \"SSBO\"\nOpDecorate %8 ArrayStride 24\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %9 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonWritable\nOpDecorate %11 Restrict\nOpDecorate %12 ArrayStride 8\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 1\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %16 ArrayStride 24\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %19 NonReadable\nOpDecorate %20 ArrayStride 8\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 1\nOpDecorate %23 NonReadable\nOpDecorate %26 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeInt 64 0\n%7 = OpTypeVector %6 3\n%8 = OpTypeRuntimeArray %7\n%9 = OpTypeStruct %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeRuntimeArray %6\n%13 = OpTypeStruct %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeRuntimeArray %7\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %6\n%21 = OpTypeStruct %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypeVector %5 3\n%25 = OpTypePointer Input %24\n%26 = OpVariable %25 Input\n%27 = OpTypePointer Input %5\n%29 = OpConstant %5 0\n%32 = OpConstant %5 1\n%34 = OpConstant %5 2\n%35 = OpTypePointer StorageBuffer %7\n%53 = OpConstant %5 3\n%55 = OpConstant %5 8\n%83 = OpConstant %6 63\n%90 = OpConstant %5 4\n%99 = OpConstant %5 5\n%108 = OpConstant %5 6\n%117 = OpConstant %5 7\n%123 = OpConstant %5 24\n%125 = OpTypePointer StorageBuffer %6\n%131 = OpTypeVector %6 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %140\n%140 = OpLabel\n%28 = OpAccessChain %27 %26 %29\n%30 = OpLoad %5 %28\n%31 = OpShiftLeftLogical %5 %30 %32\n%33 = OpIMul %5 %30 %34\n%36 = OpAccessChain %35 %11 %29 %33\n%37 = OpLoad %7 %36\n%38 = OpCompositeExtract %6 %37 0\n%39 = OpCompositeExtract %6 %37 1\n%40 = OpCompositeExtract %6 %37 2\n%41 = OpBitwiseOr %5 %31 %32\n%42 = OpIMul %5 %30 %34\n%43 = OpIAdd %5 %42 %32\n%44 = OpAccessChain %35 %11 %29 %43\n%45 = OpLoad %7 %44\n%46 = OpCompositeExtract %6 %45 0\n%47 = OpCompositeExtract %6 %45 1\n%48 = OpCompositeExtract %6 %45 2\n%49 = OpIAdd %6 %46 %38\n%50 = OpIAdd %6 %47 %39\n%51 = OpIAdd %6 %48 %40\n%52 = OpShiftLeftLogical %5 %30 %53\n%54 = OpIMul %5 %30 %55\n%56 = OpCompositeConstruct %7 %49 %50 %51\n%57 = OpAccessChain %35 %19 %29 %54\nOpStore %57 %56\n%58 = OpISub %6 %38 %46\n%59 = OpISub %6 %39 %47\n%60 = OpISub %6 %40 %48\n%61 = OpBitwiseOr %5 %52 %32\n%62 = OpIMul %5 %30 %55\n%63 = OpIAdd %5 %62 %32\n%64 = OpCompositeConstruct %7 %58 %59 %60\n%65 = OpAccessChain %35 %19 %29 %63\nOpStore %65 %64\n%66 = OpIMul %6 %46 %38\n%67 = OpIMul %6 %47 %39\n%68 = OpIMul %6 %48 %40\n%69 = OpBitwiseOr %5 %52 %34\n%70 = OpIMul %5 %30 %55\n%71 = OpIAdd %5 %70 %34\n%72 = OpCompositeConstruct %7 %66 %67 %68\n%73 = OpAccessChain %35 %19 %29 %71\nOpStore %73 %72\n%74 = OpUDiv %6 %38 %46\n%75 = OpUDiv %6 %39 %47\n%76 = OpUDiv %6 %40 %48\n%77 = OpBitwiseOr %5 %52 %53\n%78 = OpIMul %5 %30 %55\n%79 = OpIAdd %5 %78 %53\n%80 = OpCompositeConstruct %7 %74 %75 %76\n%81 = OpAccessChain %35 %19 %29 %79\nOpStore %81 %80\n%82 = OpBitwiseAnd %6 %46 %83\n%84 = OpBitwiseAnd %6 %47 %83\n%85 = OpBitwiseAnd %6 %48 %83\n%86 = OpShiftLeftLogical %6 %38 %82\n%87 = OpShiftLeftLogical %6 %39 %84\n%88 = OpShiftLeftLogical %6 %40 %85\n%89 = OpBitwiseOr %5 %52 %90\n%91 = OpIMul %5 %30 %55\n%92 = OpIAdd %5 %91 %90\n%93 = OpCompositeConstruct %7 %86 %87 %88\n%94 = OpAccessChain %35 %19 %29 %92\nOpStore %94 %93\n%95 = OpShiftRightLogical %6 %38 %82\n%96 = OpShiftRightLogical %6 %39 %84\n%97 = OpShiftRightLogical %6 %40 %85\n%98 = OpBitwiseOr %5 %52 %99\n%100 = OpIMul %5 %30 %55\n%101 = OpIAdd %5 %100 %99\n%102 = OpCompositeConstruct %7 %95 %96 %97\n%103 = OpAccessChain %35 %19 %29 %101\nOpStore %103 %102\n%104 = OpShiftRightArithmetic %6 %38 %82\n%105 = OpShiftRightArithmetic %6 %39 %84\n%106 = OpShiftRightArithmetic %6 %40 %85\n%107 = OpBitwiseOr %5 %52 %108\n%109 = OpIMul %5 %30 %55\n%110 = OpIAdd %5 %109 %108\n%111 = OpCompositeConstruct %7 %104 %105 %106\n%112 = OpAccessChain %35 %19 %29 %110\nOpStore %112 %111\n%113 = OpBitwiseAnd %6 %46 %38\n%114 = OpBitwiseAnd %6 %47 %39\n%115 = OpBitwiseAnd %6 %48 %40\n%116 = OpBitwiseOr %5 %52 %117\n%118 = OpIMul %5 %30 %55\n%119 = OpIAdd %5 %118 %117\n%120 = OpCompositeConstruct %7 %113 %114 %115\n%121 = OpAccessChain %35 %19 %29 %119\nOpStore %121 %120\n%122 = OpIMul %5 %30 %123\n%124 = OpIMul %5 %30 %53\n%126 = OpAccessChain %125 %15 %29 %124\n%127 = OpLoad %6 %126\n%129 = OpIAdd %5 %124 %32\n%128 = OpAccessChain %125 %15 %29 %129\n%130 = OpLoad %6 %128\n%132 = OpCompositeConstruct %131 %127 %130\n%133 = OpCompositeExtract %6 %132 0\n%134 = OpCompositeExtract %6 %132 1\n%135 = OpAccessChain %125 %23 %29 %30\nOpStore %135 %133\n%137 = OpIAdd %5 %30 %32\n%136 = OpAccessChain %125 %23 %29 %137\nOpStore %136 %134\n%139 = OpIAdd %5 %30 %34\n%138 = OpAccessChain %125 %23 %29 %139\nOpStore %138 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-alignment-fixup.bindless.root-constant.offset-layout.typed-buffer-offset.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 1, binding = 0) uniform usamplerBuffer _17[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _20[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _24[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _27[];\nlayout(set = 4, binding = 0, r32ui) uniform uimageBuffer _30[];\nlayout(set = 4, binding = 0) uniform writeonly uimageBuffer _34[];\n\nvoid main()\n{\n    uint _46 = (subgroupBroadcastFirst(registers._m4) * 2u) + 1u;\n    uint _59 = (subgroupBroadcastFirst(registers._m4) * 2u) + 1u;\n    uint _65 = registers._m4 + 1u;\n    uint _69 = (subgroupBroadcastFirst(_65) * 2u) + 1u;\n    uint _78 = (subgroupBroadcastFirst(registers._m4) * 2u) + 1u;\n    uint _85 = registers._m1 + 1u;\n    uint _89 = (subgroupBroadcastFirst(_85) * 2u) + 1u;\n    uint _98 = (subgroupBroadcastFirst(registers._m1) * 2u) + 1u;\n    uint _110 = gl_GlobalInvocationID.x * 2u;\n    uint _116 = (_110 < _13._m0[_98].y) ? (_110 + _13._m0[_98].x) : 1073741820u;\n    vec2 _127 = uintBitsToFloat(uvec2(texelFetch(_17[registers._m1], int(_116)).x, texelFetch(_17[registers._m1], int(_116 + 1u)).x));\n    uint _130 = gl_GlobalInvocationID.x * 2u;\n    uint _135 = (_130 < _13._m0[_78].y) ? (_130 + _13._m0[_78].x) : 1073741820u;\n    imageStore(_24[registers._m4], int(_135), uvec4(floatBitsToUint(_127.x)));\n    imageStore(_24[registers._m4], int(_135 + 1u), uvec4(floatBitsToUint(_127.y)));\n    uint _142 = gl_GlobalInvocationID.x * 4u;\n    uint _147 = (_142 < _13._m0[_89].y) ? (_142 + _13._m0[_89].x) : 1073741820u;\n    uvec4 _159 = uvec4(texelFetch(_20[_85], int(_147)).x, texelFetch(_20[_85], int(_147 + 1u)).x, texelFetch(_20[_85], int(_147 + 2u)).x, texelFetch(_20[_85], int(_147 + 3u)).x);\n    uint _164 = gl_GlobalInvocationID.x * 4u;\n    uint _169 = (_164 < _13._m0[_69].y) ? (_164 + _13._m0[_69].x) : 1073741820u;\n    imageStore(_27[_65], int(_169), uvec4(_159.x));\n    imageStore(_27[_65], int(_169 + 1u), uvec4(_159.y));\n    imageStore(_27[_65], int(_169 + 2u), uvec4(_159.z));\n    imageStore(_27[_65], int(_169 + 3u), uvec4(_159.w));\n    uint _177 = gl_GlobalInvocationID.x * 2u;\n    uint _182 = (_177 < _13._m0[_98].y) ? (_177 + _13._m0[_98].x) : 1073741820u;\n    vec2 _189 = uintBitsToFloat(uvec2(texelFetch(_17[registers._m1], int(_182)).x, texelFetch(_17[registers._m1], int(_182 + 1u)).x));\n    uint _192 = gl_GlobalInvocationID.x * 2u;\n    uint _197 = (_192 < _13._m0[_78].y) ? (_192 + _13._m0[_78].x) : 1073741820u;\n    imageStore(_24[registers._m4], int(_197), uvec4(floatBitsToUint(_189.x)));\n    imageStore(_24[registers._m4], int(_197 + 1u), uvec4(floatBitsToUint(_189.y)));\n    uint _203 = gl_GlobalInvocationID.x * 4u;\n    uint _208 = (_203 < _13._m0[_89].y) ? (_203 + _13._m0[_89].x) : 1073741820u;\n    uvec4 _220 = uvec4(texelFetch(_20[_85], int(_208)).x, texelFetch(_20[_85], int(_208 + 1u)).x, texelFetch(_20[_85], int(_208 + 2u)).x, texelFetch(_20[_85], int(_208 + 3u)).x);\n    uint _225 = gl_GlobalInvocationID.x * 4u;\n    uint _230 = (_225 < _13._m0[_69].y) ? (_225 + _13._m0[_69].x) : 1073741820u;\n    imageStore(_27[_65], int(_230), uvec4(_220.x));\n    imageStore(_27[_65], int(_230 + 1u), uvec4(_220.y));\n    imageStore(_27[_65], int(_230 + 2u), uvec4(_220.z));\n    imageStore(_27[_65], int(_230 + 3u), uvec4(_220.w));\n    uint _242 = registers._m1 + (gl_WorkGroupID.x + 2u);\n    uint _246 = (subgroupBroadcastFirst(_242) * 2u) + 1u;\n    uint _249 = gl_GlobalInvocationID.x * 2u;\n    uint _254 = (_249 < _13._m0[_246].y) ? (_249 + _13._m0[_246].x) : 1073741820u;\n    vec2 _261 = uintBitsToFloat(uvec2(texelFetch(_17[_242], int(_254)).x, texelFetch(_17[_242], int(_254 + 1u)).x));\n    uint _268 = registers._m4 + (gl_WorkGroupID.x + 0u);\n    uint _272 = (subgroupBroadcastFirst(_268) * 2u) + 1u;\n    uint _275 = gl_GlobalInvocationID.x * 2u;\n    uint _280 = (_275 < _13._m0[_272].y) ? (_275 + _13._m0[_272].x) : 1073741820u;\n    imageStore(_24[_268], int(_280), uvec4(floatBitsToUint(_261.x)));\n    imageStore(_24[_268], int(_280 + 1u), uvec4(floatBitsToUint(_261.y)));\n    uint _290 = registers._m1 + (gl_GlobalInvocationID.x + 2u);\n    uint _293 = (_290 * 2u) + 1u;\n    uint _296 = gl_GlobalInvocationID.x * 2u;\n    uint _301 = (_296 < _13._m0[_293].y) ? (_296 + _13._m0[_293].x) : 1073741820u;\n    vec2 _308 = uintBitsToFloat(uvec2(texelFetch(_17[nonuniformEXT(_290)], int(_301)).x, texelFetch(_17[nonuniformEXT(_290)], int(_301 + 1u)).x));\n    uint _315 = registers._m4 + (gl_GlobalInvocationID.x + 0u);\n    uint _318 = (_315 * 2u) + 1u;\n    uint _321 = gl_GlobalInvocationID.x * 2u;\n    uint _326 = (_321 < _13._m0[_318].y) ? (_321 + _13._m0[_318].x) : 1073741820u;\n    imageStore(_24[nonuniformEXT(_315)], int(_326), uvec4(floatBitsToUint(_308.x)));\n    imageStore(_24[nonuniformEXT(_315)], int(_326 + 1u), uvec4(floatBitsToUint(_308.y)));\n    uint _336 = registers._m1 + (gl_WorkGroupID.x + 3u);\n    uint _340 = (subgroupBroadcastFirst(_336) * 2u) + 1u;\n    uint _343 = gl_GlobalInvocationID.x * 4u;\n    uint _348 = (_343 < _13._m0[_340].y) ? (_343 + _13._m0[_340].x) : 1073741820u;\n    uvec4 _360 = uvec4(texelFetch(_20[_336], int(_348)).x, texelFetch(_20[_336], int(_348 + 1u)).x, texelFetch(_20[_336], int(_348 + 2u)).x, texelFetch(_20[_336], int(_348 + 3u)).x);\n    uint _369 = registers._m4 + (gl_WorkGroupID.x + 1u);\n    uint _373 = (subgroupBroadcastFirst(_369) * 2u) + 1u;\n    uint _376 = gl_GlobalInvocationID.x * 4u;\n    uint _381 = (_376 < _13._m0[_373].y) ? (_376 + _13._m0[_373].x) : 1073741820u;\n    imageStore(_27[_369], int(_381), uvec4(_360.x));\n    imageStore(_27[_369], int(_381 + 1u), uvec4(_360.y));\n    imageStore(_27[_369], int(_381 + 2u), uvec4(_360.z));\n    imageStore(_27[_369], int(_381 + 3u), uvec4(_360.w));\n    uint _393 = registers._m1 + (gl_GlobalInvocationID.x + 3u);\n    uint _396 = (_393 * 2u) + 1u;\n    uint _399 = gl_GlobalInvocationID.x * 4u;\n    uint _404 = (_399 < _13._m0[_396].y) ? (_399 + _13._m0[_396].x) : 1073741820u;\n    uvec4 _416 = uvec4(texelFetch(_20[nonuniformEXT(_393)], int(_404)).x, texelFetch(_20[nonuniformEXT(_393)], int(_404 + 1u)).x, texelFetch(_20[nonuniformEXT(_393)], int(_404 + 2u)).x, texelFetch(_20[nonuniformEXT(_393)], int(_404 + 3u)).x);\n    uint _425 = registers._m4 + (gl_GlobalInvocationID.x + 1u);\n    uint _428 = (_425 * 2u) + 1u;\n    uint _431 = gl_GlobalInvocationID.x * 4u;\n    uint _436 = (_431 < _13._m0[_428].y) ? (_431 + _13._m0[_428].x) : 1073741820u;\n    imageStore(_27[nonuniformEXT(_425)], int(_436), uvec4(_416.x));\n    imageStore(_27[nonuniformEXT(_425)], int(_436 + 1u), uvec4(_416.y));\n    imageStore(_27[nonuniformEXT(_425)], int(_436 + 2u), uvec4(_416.z));\n    imageStore(_27[nonuniformEXT(_425)], int(_436 + 3u), uvec4(_416.w));\n    uint _445 = (gl_GlobalInvocationID.x * 2u) + 1u;\n    uint _453 = imageAtomicAdd(_30[registers._m4], int((_445 < _13._m0[_59].y) ? (_445 + _13._m0[_59].x) : 1073741820u), 1u);\n    uint _456 = gl_GlobalInvocationID.x * 2u;\n    uint _463 = imageAtomicAdd(_30[registers._m4], int((_456 < _13._m0[_59].y) ? (_456 + _13._m0[_59].x) : 1073741820u), _13._m0[_78].y / 2u);\n    uint _464 = gl_GlobalInvocationID.x << 2u;\n    imageStore(_34[registers._m4], int((gl_GlobalInvocationID.x < _13._m0[_46].y) ? (gl_GlobalInvocationID.x + _13._m0[_46].x) : 4294967295u), uvec4(_464, _464 | 1u, _464 | 2u, _464 | 3u));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 477\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %103 %107\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 0\nOpDecorate %24 DescriptorSet 4\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\nOpDecorate %27 DescriptorSet 4\nOpDecorate %27 Binding 0\nOpDecorate %27 NonReadable\nOpDecorate %30 DescriptorSet 4\nOpDecorate %30 Binding 0\nOpDecorate %34 DescriptorSet 4\nOpDecorate %34 Binding 0\nOpDecorate %34 NonReadable\nOpDecorate %103 BuiltIn GlobalInvocationId\nOpDecorate %107 BuiltIn WorkgroupId\nOpDecorate %290 NonUniform\nOpDecorate %291 NonUniform\nOpDecorate %315 NonUniform\nOpDecorate %316 NonUniform\nOpDecorate %393 NonUniform\nOpDecorate %394 NonUniform\nOpDecorate %425 NonUniform\nOpDecorate %426 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeRuntimeArray %14\n%19 = OpTypePointer UniformConstant %18\n%20 = OpVariable %19 UniformConstant\n%21 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeRuntimeArray %21\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeRuntimeArray %21\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer UniformConstant %32\n%34 = OpVariable %33 UniformConstant\n%35 = OpTypePointer UniformConstant %31\n%37 = OpTypePointer PushConstant %5\n%39 = OpConstant %5 4\n%43 = OpConstant %5 3\n%45 = OpConstant %5 2\n%47 = OpConstant %5 1\n%48 = OpTypePointer StorageBuffer %9\n%50 = OpConstant %5 0\n%52 = OpTypePointer UniformConstant %21\n%81 = OpTypePointer UniformConstant %14\n%101 = OpTypeVector %5 3\n%102 = OpTypePointer Input %101\n%103 = OpVariable %102 Input\n%104 = OpTypePointer Input %5\n%107 = OpVariable %102 Input\n%114 = OpTypeBool\n%117 = OpConstant %5 1073741820\n%118 = OpTypeVector %5 4\n%125 = OpTypeFloat 32\n%126 = OpTypeVector %125 2\n%451 = OpTypePointer Image %5\n%473 = OpConstant %5 4294967295\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %475\n%475 = OpLabel\n%38 = OpAccessChain %37 %8 %39\n%40 = OpLoad %5 %38\n%36 = OpAccessChain %35 %34 %40\n%41 = OpLoad %31 %36\n%42 = OpGroupNonUniformBroadcastFirst %5 %43 %40\n%44 = OpIMul %5 %42 %45\n%46 = OpIAdd %5 %44 %47\n%49 = OpAccessChain %48 %13 %50 %46\n%51 = OpLoad %9 %49\n%54 = OpAccessChain %37 %8 %39\n%55 = OpLoad %5 %54\n%53 = OpAccessChain %52 %30 %55\n%56 = OpLoad %21 %53\n%57 = OpGroupNonUniformBroadcastFirst %5 %43 %55\n%58 = OpIMul %5 %57 %45\n%59 = OpIAdd %5 %58 %47\n%60 = OpAccessChain %48 %13 %50 %59\n%61 = OpLoad %9 %60\n%63 = OpAccessChain %37 %8 %39\n%64 = OpLoad %5 %63\n%65 = OpIAdd %5 %64 %47\n%62 = OpAccessChain %52 %27 %65\n%66 = OpLoad %21 %62\n%67 = OpGroupNonUniformBroadcastFirst %5 %43 %65\n%68 = OpIMul %5 %67 %45\n%69 = OpIAdd %5 %68 %47\n%70 = OpAccessChain %48 %13 %50 %69\n%71 = OpLoad %9 %70\n%73 = OpAccessChain %37 %8 %39\n%74 = OpLoad %5 %73\n%72 = OpAccessChain %52 %24 %74\n%75 = OpLoad %21 %72\n%76 = OpGroupNonUniformBroadcastFirst %5 %43 %74\n%77 = OpIMul %5 %76 %45\n%78 = OpIAdd %5 %77 %47\n%79 = OpAccessChain %48 %13 %50 %78\n%80 = OpLoad %9 %79\n%83 = OpAccessChain %37 %8 %47\n%84 = OpLoad %5 %83\n%85 = OpIAdd %5 %84 %47\n%82 = OpAccessChain %81 %20 %85\n%86 = OpLoad %14 %82\n%87 = OpGroupNonUniformBroadcastFirst %5 %43 %85\n%88 = OpIMul %5 %87 %45\n%89 = OpIAdd %5 %88 %47\n%90 = OpAccessChain %48 %13 %50 %89\n%91 = OpLoad %9 %90\n%93 = OpAccessChain %37 %8 %47\n%94 = OpLoad %5 %93\n%92 = OpAccessChain %81 %17 %94\n%95 = OpLoad %14 %92\n%96 = OpGroupNonUniformBroadcastFirst %5 %43 %94\n%97 = OpIMul %5 %96 %45\n%98 = OpIAdd %5 %97 %47\n%99 = OpAccessChain %48 %13 %50 %98\n%100 = OpLoad %9 %99\n%105 = OpAccessChain %104 %103 %50\n%106 = OpLoad %5 %105\n%108 = OpAccessChain %104 %107 %50\n%109 = OpLoad %5 %108\n%110 = OpIMul %5 %106 %45\n%111 = OpCompositeExtract %5 %100 0\n%112 = OpCompositeExtract %5 %100 1\n%113 = OpIAdd %5 %110 %111\n%115 = OpULessThan %114 %110 %112\n%116 = OpSelect %5 %115 %113 %117\n%119 = OpImageFetch %118 %95 %116\n%120 = OpCompositeExtract %5 %119 0\n%122 = OpIAdd %5 %116 %47\n%121 = OpImageFetch %118 %95 %122\n%123 = OpCompositeExtract %5 %121 0\n%124 = OpCompositeConstruct %9 %120 %123\n%127 = OpBitcast %126 %124\n%128 = OpCompositeExtract %125 %127 0\n%129 = OpCompositeExtract %125 %127 1\n%130 = OpIMul %5 %106 %45\n%131 = OpCompositeExtract %5 %80 0\n%132 = OpCompositeExtract %5 %80 1\n%133 = OpIAdd %5 %130 %131\n%134 = OpULessThan %114 %130 %132\n%135 = OpSelect %5 %134 %133 %117\n%136 = OpBitcast %5 %128\n%137 = OpBitcast %5 %129\n%138 = OpCompositeConstruct %118 %136 %136 %136 %136\nOpImageWrite %75 %135 %138\n%139 = OpCompositeConstruct %118 %137 %137 %137 %137\n%140 = OpIAdd %5 %135 %47\nOpImageWrite %75 %140 %139\n%141 = OpShiftLeftLogical %5 %106 %39\n%142 = OpIMul %5 %106 %39\n%143 = OpCompositeExtract %5 %91 0\n%144 = OpCompositeExtract %5 %91 1\n%145 = OpIAdd %5 %142 %143\n%146 = OpULessThan %114 %142 %144\n%147 = OpSelect %5 %146 %145 %117\n%148 = OpImageFetch %118 %86 %147\n%149 = OpCompositeExtract %5 %148 0\n%151 = OpIAdd %5 %147 %47\n%150 = OpImageFetch %118 %86 %151\n%152 = OpCompositeExtract %5 %150 0\n%154 = OpIAdd %5 %147 %45\n%153 = OpImageFetch %118 %86 %154\n%155 = OpCompositeExtract %5 %153 0\n%157 = OpIAdd %5 %147 %43\n%156 = OpImageFetch %118 %86 %157\n%158 = OpCompositeExtract %5 %156 0\n%159 = OpCompositeConstruct %118 %149 %152 %155 %158\n%160 = OpCompositeExtract %5 %159 0\n%161 = OpCompositeExtract %5 %159 1\n%162 = OpCompositeExtract %5 %159 2\n%163 = OpCompositeExtract %5 %159 3\n%164 = OpIMul %5 %106 %39\n%165 = OpCompositeExtract %5 %71 0\n%166 = OpCompositeExtract %5 %71 1\n%167 = OpIAdd %5 %164 %165\n%168 = OpULessThan %114 %164 %166\n%169 = OpSelect %5 %168 %167 %117\n%170 = OpCompositeConstruct %118 %160 %160 %160 %160\nOpImageWrite %66 %169 %170\n%171 = OpCompositeConstruct %118 %161 %161 %161 %161\n%172 = OpIAdd %5 %169 %47\nOpImageWrite %66 %172 %171\n%173 = OpCompositeConstruct %118 %162 %162 %162 %162\n%174 = OpIAdd %5 %169 %45\nOpImageWrite %66 %174 %173\n%175 = OpCompositeConstruct %118 %163 %163 %163 %163\n%176 = OpIAdd %5 %169 %43\nOpImageWrite %66 %176 %175\n%177 = OpIMul %5 %106 %45\n%178 = OpCompositeExtract %5 %100 0\n%179 = OpCompositeExtract %5 %100 1\n%180 = OpIAdd %5 %177 %178\n%181 = OpULessThan %114 %177 %179\n%182 = OpSelect %5 %181 %180 %117\n%183 = OpImageFetch %118 %95 %182\n%184 = OpCompositeExtract %5 %183 0\n%186 = OpIAdd %5 %182 %47\n%185 = OpImageFetch %118 %95 %186\n%187 = OpCompositeExtract %5 %185 0\n%188 = OpCompositeConstruct %9 %184 %187\n%189 = OpBitcast %126 %188\n%190 = OpCompositeExtract %125 %189 0\n%191 = OpCompositeExtract %125 %189 1\n%192 = OpIMul %5 %106 %45\n%193 = OpCompositeExtract %5 %80 0\n%194 = OpCompositeExtract %5 %80 1\n%195 = OpIAdd %5 %192 %193\n%196 = OpULessThan %114 %192 %194\n%197 = OpSelect %5 %196 %195 %117\n%198 = OpBitcast %5 %190\n%199 = OpBitcast %5 %191\n%200 = OpCompositeConstruct %118 %198 %198 %198 %198\nOpImageWrite %75 %197 %200\n%201 = OpCompositeConstruct %118 %199 %199 %199 %199\n%202 = OpIAdd %5 %197 %47\nOpImageWrite %75 %202 %201\n%203 = OpIMul %5 %106 %39\n%204 = OpCompositeExtract %5 %91 0\n%205 = OpCompositeExtract %5 %91 1\n%206 = OpIAdd %5 %203 %204\n%207 = OpULessThan %114 %203 %205\n%208 = OpSelect %5 %207 %206 %117\n%209 = OpImageFetch %118 %86 %208\n%210 = OpCompositeExtract %5 %209 0\n%212 = OpIAdd %5 %208 %47\n%211 = OpImageFetch %118 %86 %212\n%213 = OpCompositeExtract %5 %211 0\n%215 = OpIAdd %5 %208 %45\n%214 = OpImageFetch %118 %86 %215\n%216 = OpCompositeExtract %5 %214 0\n%218 = OpIAdd %5 %208 %43\n%217 = OpImageFetch %118 %86 %218\n%219 = OpCompositeExtract %5 %217 0\n%220 = OpCompositeConstruct %118 %210 %213 %216 %219\n%221 = OpCompositeExtract %5 %220 0\n%222 = OpCompositeExtract %5 %220 1\n%223 = OpCompositeExtract %5 %220 2\n%224 = OpCompositeExtract %5 %220 3\n%225 = OpIMul %5 %106 %39\n%226 = OpCompositeExtract %5 %71 0\n%227 = OpCompositeExtract %5 %71 1\n%228 = OpIAdd %5 %225 %226\n%229 = OpULessThan %114 %225 %227\n%230 = OpSelect %5 %229 %228 %117\n%231 = OpCompositeConstruct %118 %221 %221 %221 %221\nOpImageWrite %66 %230 %231\n%232 = OpCompositeConstruct %118 %222 %222 %222 %222\n%233 = OpIAdd %5 %230 %47\nOpImageWrite %66 %233 %232\n%234 = OpCompositeConstruct %118 %223 %223 %223 %223\n%235 = OpIAdd %5 %230 %45\nOpImageWrite %66 %235 %234\n%236 = OpCompositeConstruct %118 %224 %224 %224 %224\n%237 = OpIAdd %5 %230 %43\nOpImageWrite %66 %237 %236\n%238 = OpIAdd %5 %109 %45\n%240 = OpAccessChain %37 %8 %47\n%241 = OpLoad %5 %240\n%242 = OpIAdd %5 %241 %238\n%239 = OpAccessChain %81 %17 %242\n%243 = OpLoad %14 %239\n%244 = OpGroupNonUniformBroadcastFirst %5 %43 %242\n%245 = OpIMul %5 %244 %45\n%246 = OpIAdd %5 %245 %47\n%247 = OpAccessChain %48 %13 %50 %246\n%248 = OpLoad %9 %247\n%249 = OpIMul %5 %106 %45\n%250 = OpCompositeExtract %5 %248 0\n%251 = OpCompositeExtract %5 %248 1\n%252 = OpIAdd %5 %249 %250\n%253 = OpULessThan %114 %249 %251\n%254 = OpSelect %5 %253 %252 %117\n%255 = OpImageFetch %118 %243 %254\n%256 = OpCompositeExtract %5 %255 0\n%258 = OpIAdd %5 %254 %47\n%257 = OpImageFetch %118 %243 %258\n%259 = OpCompositeExtract %5 %257 0\n%260 = OpCompositeConstruct %9 %256 %259\n%261 = OpBitcast %126 %260\n%262 = OpCompositeExtract %125 %261 0\n%263 = OpCompositeExtract %125 %261 1\n%264 = OpIAdd %5 %109 %50\n%266 = OpAccessChain %37 %8 %39\n%267 = OpLoad %5 %266\n%268 = OpIAdd %5 %267 %264\n%265 = OpAccessChain %52 %24 %268\n%269 = OpLoad %21 %265\n%270 = OpGroupNonUniformBroadcastFirst %5 %43 %268\n%271 = OpIMul %5 %270 %45\n%272 = OpIAdd %5 %271 %47\n%273 = OpAccessChain %48 %13 %50 %272\n%274 = OpLoad %9 %273\n%275 = OpIMul %5 %106 %45\n%276 = OpCompositeExtract %5 %274 0\n%277 = OpCompositeExtract %5 %274 1\n%278 = OpIAdd %5 %275 %276\n%279 = OpULessThan %114 %275 %277\n%280 = OpSelect %5 %279 %278 %117\n%281 = OpBitcast %5 %262\n%282 = OpBitcast %5 %263\n%283 = OpCompositeConstruct %118 %281 %281 %281 %281\nOpImageWrite %269 %280 %283\n%284 = OpCompositeConstruct %118 %282 %282 %282 %282\n%285 = OpIAdd %5 %280 %47\nOpImageWrite %269 %285 %284\n%286 = OpIAdd %5 %106 %45\n%288 = OpAccessChain %37 %8 %47\n%289 = OpLoad %5 %288\n%290 = OpIAdd %5 %289 %286\n%287 = OpAccessChain %81 %17 %290\n%291 = OpLoad %14 %287\n%292 = OpIMul %5 %290 %45\n%293 = OpIAdd %5 %292 %47\n%294 = OpAccessChain %48 %13 %50 %293\n%295 = OpLoad %9 %294\n%296 = OpIMul %5 %106 %45\n%297 = OpCompositeExtract %5 %295 0\n%298 = OpCompositeExtract %5 %295 1\n%299 = OpIAdd %5 %296 %297\n%300 = OpULessThan %114 %296 %298\n%301 = OpSelect %5 %300 %299 %117\n%302 = OpImageFetch %118 %291 %301\n%303 = OpCompositeExtract %5 %302 0\n%305 = OpIAdd %5 %301 %47\n%304 = OpImageFetch %118 %291 %305\n%306 = OpCompositeExtract %5 %304 0\n%307 = OpCompositeConstruct %9 %303 %306\n%308 = OpBitcast %126 %307\n%309 = OpCompositeExtract %125 %308 0\n%310 = OpCompositeExtract %125 %308 1\n%311 = OpIAdd %5 %106 %50\n%313 = OpAccessChain %37 %8 %39\n%314 = OpLoad %5 %313\n%315 = OpIAdd %5 %314 %311\n%312 = OpAccessChain %52 %24 %315\n%316 = OpLoad %21 %312\n%317 = OpIMul %5 %315 %45\n%318 = OpIAdd %5 %317 %47\n%319 = OpAccessChain %48 %13 %50 %318\n%320 = OpLoad %9 %319\n%321 = OpIMul %5 %106 %45\n%322 = OpCompositeExtract %5 %320 0\n%323 = OpCompositeExtract %5 %320 1\n%324 = OpIAdd %5 %321 %322\n%325 = OpULessThan %114 %321 %323\n%326 = OpSelect %5 %325 %324 %117\n%327 = OpBitcast %5 %309\n%328 = OpBitcast %5 %310\n%329 = OpCompositeConstruct %118 %327 %327 %327 %327\nOpImageWrite %316 %326 %329\n%330 = OpCompositeConstruct %118 %328 %328 %328 %328\n%331 = OpIAdd %5 %326 %47\nOpImageWrite %316 %331 %330\n%332 = OpIAdd %5 %109 %43\n%334 = OpAccessChain %37 %8 %47\n%335 = OpLoad %5 %334\n%336 = OpIAdd %5 %335 %332\n%333 = OpAccessChain %81 %20 %336\n%337 = OpLoad %14 %333\n%338 = OpGroupNonUniformBroadcastFirst %5 %43 %336\n%339 = OpIMul %5 %338 %45\n%340 = OpIAdd %5 %339 %47\n%341 = OpAccessChain %48 %13 %50 %340\n%342 = OpLoad %9 %341\n%343 = OpIMul %5 %106 %39\n%344 = OpCompositeExtract %5 %342 0\n%345 = OpCompositeExtract %5 %342 1\n%346 = OpIAdd %5 %343 %344\n%347 = OpULessThan %114 %343 %345\n%348 = OpSelect %5 %347 %346 %117\n%349 = OpImageFetch %118 %337 %348\n%350 = OpCompositeExtract %5 %349 0\n%352 = OpIAdd %5 %348 %47\n%351 = OpImageFetch %118 %337 %352\n%353 = OpCompositeExtract %5 %351 0\n%355 = OpIAdd %5 %348 %45\n%354 = OpImageFetch %118 %337 %355\n%356 = OpCompositeExtract %5 %354 0\n%358 = OpIAdd %5 %348 %43\n%357 = OpImageFetch %118 %337 %358\n%359 = OpCompositeExtract %5 %357 0\n%360 = OpCompositeConstruct %118 %350 %353 %356 %359\n%361 = OpCompositeExtract %5 %360 0\n%362 = OpCompositeExtract %5 %360 1\n%363 = OpCompositeExtract %5 %360 2\n%364 = OpCompositeExtract %5 %360 3\n%365 = OpIAdd %5 %109 %47\n%367 = OpAccessChain %37 %8 %39\n%368 = OpLoad %5 %367\n%369 = OpIAdd %5 %368 %365\n%366 = OpAccessChain %52 %27 %369\n%370 = OpLoad %21 %366\n%371 = OpGroupNonUniformBroadcastFirst %5 %43 %369\n%372 = OpIMul %5 %371 %45\n%373 = OpIAdd %5 %372 %47\n%374 = OpAccessChain %48 %13 %50 %373\n%375 = OpLoad %9 %374\n%376 = OpIMul %5 %106 %39\n%377 = OpCompositeExtract %5 %375 0\n%378 = OpCompositeExtract %5 %375 1\n%379 = OpIAdd %5 %376 %377\n%380 = OpULessThan %114 %376 %378\n%381 = OpSelect %5 %380 %379 %117\n%382 = OpCompositeConstruct %118 %361 %361 %361 %361\nOpImageWrite %370 %381 %382\n%383 = OpCompositeConstruct %118 %362 %362 %362 %362\n%384 = OpIAdd %5 %381 %47\nOpImageWrite %370 %384 %383\n%385 = OpCompositeConstruct %118 %363 %363 %363 %363\n%386 = OpIAdd %5 %381 %45\nOpImageWrite %370 %386 %385\n%387 = OpCompositeConstruct %118 %364 %364 %364 %364\n%388 = OpIAdd %5 %381 %43\nOpImageWrite %370 %388 %387\n%389 = OpIAdd %5 %106 %43\n%391 = OpAccessChain %37 %8 %47\n%392 = OpLoad %5 %391\n%393 = OpIAdd %5 %392 %389\n%390 = OpAccessChain %81 %20 %393\n%394 = OpLoad %14 %390\n%395 = OpIMul %5 %393 %45\n%396 = OpIAdd %5 %395 %47\n%397 = OpAccessChain %48 %13 %50 %396\n%398 = OpLoad %9 %397\n%399 = OpIMul %5 %106 %39\n%400 = OpCompositeExtract %5 %398 0\n%401 = OpCompositeExtract %5 %398 1\n%402 = OpIAdd %5 %399 %400\n%403 = OpULessThan %114 %399 %401\n%404 = OpSelect %5 %403 %402 %117\n%405 = OpImageFetch %118 %394 %404\n%406 = OpCompositeExtract %5 %405 0\n%408 = OpIAdd %5 %404 %47\n%407 = OpImageFetch %118 %394 %408\n%409 = OpCompositeExtract %5 %407 0\n%411 = OpIAdd %5 %404 %45\n%410 = OpImageFetch %118 %394 %411\n%412 = OpCompositeExtract %5 %410 0\n%414 = OpIAdd %5 %404 %43\n%413 = OpImageFetch %118 %394 %414\n%415 = OpCompositeExtract %5 %413 0\n%416 = OpCompositeConstruct %118 %406 %409 %412 %415\n%417 = OpCompositeExtract %5 %416 0\n%418 = OpCompositeExtract %5 %416 1\n%419 = OpCompositeExtract %5 %416 2\n%420 = OpCompositeExtract %5 %416 3\n%421 = OpIAdd %5 %106 %47\n%423 = OpAccessChain %37 %8 %39\n%424 = OpLoad %5 %423\n%425 = OpIAdd %5 %424 %421\n%422 = OpAccessChain %52 %27 %425\n%426 = OpLoad %21 %422\n%427 = OpIMul %5 %425 %45\n%428 = OpIAdd %5 %427 %47\n%429 = OpAccessChain %48 %13 %50 %428\n%430 = OpLoad %9 %429\n%431 = OpIMul %5 %106 %39\n%432 = OpCompositeExtract %5 %430 0\n%433 = OpCompositeExtract %5 %430 1\n%434 = OpIAdd %5 %431 %432\n%435 = OpULessThan %114 %431 %433\n%436 = OpSelect %5 %435 %434 %117\n%437 = OpCompositeConstruct %118 %417 %417 %417 %417\nOpImageWrite %426 %436 %437\n%438 = OpCompositeConstruct %118 %418 %418 %418 %418\n%439 = OpIAdd %5 %436 %47\nOpImageWrite %426 %439 %438\n%440 = OpCompositeConstruct %118 %419 %419 %419 %419\n%441 = OpIAdd %5 %436 %45\nOpImageWrite %426 %441 %440\n%442 = OpCompositeConstruct %118 %420 %420 %420 %420\n%443 = OpIAdd %5 %436 %43\nOpImageWrite %426 %443 %442\n%444 = OpIMul %5 %106 %45\n%445 = OpIAdd %5 %444 %47\n%446 = OpCompositeExtract %5 %61 0\n%447 = OpCompositeExtract %5 %61 1\n%448 = OpIAdd %5 %445 %446\n%449 = OpULessThan %114 %445 %447\n%450 = OpSelect %5 %449 %448 %117\n%452 = OpImageTexelPointer %451 %53 %450 %50\n%453 = OpAtomicIAdd %5 %452 %47 %50 %47\n%454 = OpCompositeExtract %5 %80 1\n%455 = OpUDiv %5 %454 %45\n%456 = OpIMul %5 %106 %45\n%457 = OpCompositeExtract %5 %61 0\n%458 = OpCompositeExtract %5 %61 1\n%459 = OpIAdd %5 %456 %457\n%460 = OpULessThan %114 %456 %458\n%461 = OpSelect %5 %460 %459 %117\n%462 = OpImageTexelPointer %451 %53 %461 %50\n%463 = OpAtomicIAdd %5 %462 %47 %50 %455\n%464 = OpShiftLeftLogical %5 %106 %45\n%465 = OpBitwiseOr %5 %464 %47\n%466 = OpBitwiseOr %5 %464 %45\n%467 = OpBitwiseOr %5 %464 %43\n%468 = OpCompositeExtract %5 %51 0\n%469 = OpCompositeExtract %5 %51 1\n%470 = OpIAdd %5 %106 %468\n%471 = OpULessThan %114 %106 %469\n%472 = OpSelect %5 %471 %470 %473\n%474 = OpCompositeConstruct %118 %464 %465 %466 %467\nOpImageWrite %41 %472 %474\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-alignment-fixup.ssbo.ssbo-align.bindless.root-constant.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _18[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _21_24\n{\n    uvec4 _m0[];\n} _24[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _26_29\n{\n    uvec2 _m0[];\n} _29[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _31_34\n{\n    uvec4 _m0[];\n} _34[];\n\nlayout(set = 4, binding = 0, std430) buffer _36_39\n{\n    uint _m0[];\n} _39[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nvoid main()\n{\n    uvec2 _52 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(2u);\n    uint _59 = registers._m4 + 1u;\n    uvec2 _64 = _13._m0[subgroupBroadcastFirst(_59)] >> uvec2(4u);\n    uvec2 _73 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(3u);\n    uint _79 = registers._m1 + 1u;\n    uvec2 _83 = _13._m0[subgroupBroadcastFirst(_79)] >> uvec2(4u);\n    uvec2 _91 = _13._m0[subgroupBroadcastFirst(registers._m1)] >> uvec2(3u);\n    vec2 _112 = uintBitsToFloat(_18[registers._m1]._m0[(gl_GlobalInvocationID.x < _91.y) ? (gl_GlobalInvocationID.x + _91.x) : 536870911u]);\n    _29[registers._m4]._m0[(gl_GlobalInvocationID.x < _73.y) ? (gl_GlobalInvocationID.x + _73.x) : 536870911u] = uvec2(floatBitsToUint(_112.x), floatBitsToUint(_112.y));\n    _34[_59]._m0[(gl_GlobalInvocationID.x < _64.y) ? (gl_GlobalInvocationID.x + _64.x) : 268435455u] = uvec4(_24[_79]._m0[(gl_GlobalInvocationID.x < _83.y) ? (gl_GlobalInvocationID.x + _83.x) : 268435455u]);\n    vec2 _152 = uintBitsToFloat(_18[registers._m1]._m0[(gl_GlobalInvocationID.x < _91.y) ? (gl_GlobalInvocationID.x + _91.x) : 536870911u]);\n    _29[registers._m4]._m0[(gl_GlobalInvocationID.x < _73.y) ? (gl_GlobalInvocationID.x + _73.x) : 536870911u] = uvec2(floatBitsToUint(_152.x), floatBitsToUint(_152.y));\n    _34[_59]._m0[(gl_GlobalInvocationID.x < _64.y) ? (gl_GlobalInvocationID.x + _64.x) : 268435455u] = uvec4(_24[_79]._m0[(gl_GlobalInvocationID.x < _83.y) ? (gl_GlobalInvocationID.x + _83.x) : 268435455u]);\n    uint _186 = registers._m1 + (gl_WorkGroupID.x + 2u);\n    uvec2 _190 = _13._m0[subgroupBroadcastFirst(_186)] >> uvec2(3u);\n    vec2 _198 = uintBitsToFloat(_18[_186]._m0[(gl_GlobalInvocationID.x < _190.y) ? (gl_GlobalInvocationID.x + _190.x) : 536870911u]);\n    uint _205 = registers._m4 + (gl_WorkGroupID.x + 0u);\n    uvec2 _209 = _13._m0[subgroupBroadcastFirst(_205)] >> uvec2(3u);\n    _29[_205]._m0[(gl_GlobalInvocationID.x < _209.y) ? (gl_GlobalInvocationID.x + _209.x) : 536870911u] = uvec2(floatBitsToUint(_198.x), floatBitsToUint(_198.y));\n    uint _223 = registers._m1 + (gl_GlobalInvocationID.x + 2u);\n    uvec2 _226 = _13._m0[_223] >> uvec2(3u);\n    vec2 _234 = uintBitsToFloat(_18[nonuniformEXT(_223)]._m0[(gl_GlobalInvocationID.x < _226.y) ? (gl_GlobalInvocationID.x + _226.x) : 536870911u]);\n    uint _241 = registers._m4 + (gl_GlobalInvocationID.x + 0u);\n    uvec2 _244 = _13._m0[_241] >> uvec2(3u);\n    _29[nonuniformEXT(_241)]._m0[(gl_GlobalInvocationID.x < _244.y) ? (gl_GlobalInvocationID.x + _244.x) : 536870911u] = uvec2(floatBitsToUint(_234.x), floatBitsToUint(_234.y));\n    uint _258 = registers._m1 + (gl_WorkGroupID.x + 3u);\n    uvec2 _262 = _13._m0[subgroupBroadcastFirst(_258)] >> uvec2(4u);\n    uint _278 = registers._m4 + (gl_WorkGroupID.x + 1u);\n    uvec2 _282 = _13._m0[subgroupBroadcastFirst(_278)] >> uvec2(4u);\n    _34[_278]._m0[(gl_GlobalInvocationID.x < _282.y) ? (gl_GlobalInvocationID.x + _282.x) : 268435455u] = uvec4(_24[_258]._m0[(gl_GlobalInvocationID.x < _262.y) ? (gl_GlobalInvocationID.x + _262.x) : 268435455u]);\n    uint _294 = registers._m1 + (gl_GlobalInvocationID.x + 3u);\n    uvec2 _297 = _13._m0[_294] >> uvec2(4u);\n    uint _313 = registers._m4 + (gl_GlobalInvocationID.x + 1u);\n    uvec2 _316 = _13._m0[_313] >> uvec2(4u);\n    _34[nonuniformEXT(_313)]._m0[(gl_GlobalInvocationID.x < _316.y) ? (gl_GlobalInvocationID.x + _316.x) : 268435455u] = uvec4(_24[nonuniformEXT(_294)]._m0[(gl_GlobalInvocationID.x < _297.y) ? (gl_GlobalInvocationID.x + _297.x) : 268435455u]);\n    uint _325 = (gl_GlobalInvocationID.x * 2u) + 1u;\n    uint _334 = atomicAdd(_39[registers._m4]._m0[(_325 < _52.y) ? (_325 + _52.x) : 1073741820u], 1u);\n    uint _337 = gl_GlobalInvocationID.x * 2u;\n    uint _344 = atomicAdd(_39[registers._m4]._m0[(_337 < _52.y) ? (_337 + _52.x) : 1073741820u], _73.y / 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 347\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageQuery\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %94 %98\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %15 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %31 \"SSBO\"\nOpName %36 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %14 ArrayStride 8\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 1\nOpDecorate %18 Binding 0\nOpDecorate %18 NonWritable\nOpDecorate %18 Restrict\nOpDecorate %20 ArrayStride 16\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %25 ArrayStride 8\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 DescriptorSet 4\nOpDecorate %29 Binding 0\nOpDecorate %29 NonReadable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %34 DescriptorSet 4\nOpDecorate %34 Binding 0\nOpDecorate %34 NonReadable\nOpDecorate %35 ArrayStride 4\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %39 DescriptorSet 4\nOpDecorate %39 Binding 0\nOpDecorate %94 BuiltIn GlobalInvocationId\nOpDecorate %98 BuiltIn WorkgroupId\nOpDecorate %223 NonUniform\nOpDecorate %220 NonUniform\nOpDecorate %232 NonUniform\nOpDecorate %241 NonUniform\nOpDecorate %238 NonUniform\nOpDecorate %253 NonUniform\nOpDecorate %294 NonUniform\nOpDecorate %291 NonUniform\nOpDecorate %303 NonUniform\nOpDecorate %313 NonUniform\nOpDecorate %310 NonUniform\nOpDecorate %323 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeRuntimeArray %9\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeVector %5 4\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %9\n%26 = OpTypeStruct %25\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeRuntimeArray %19\n%31 = OpTypeStruct %30\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeRuntimeArray %5\n%36 = OpTypeStruct %35\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypePointer StorageBuffer %37\n%39 = OpVariable %38 StorageBuffer\n%40 = OpTypePointer StorageBuffer %36\n%42 = OpTypePointer PushConstant %5\n%44 = OpConstant %5 4\n%47 = OpConstant %5 3\n%48 = OpTypePointer StorageBuffer %9\n%50 = OpConstant %5 0\n%53 = OpConstant %5 2\n%54 = OpConstantComposite %9 %53 %53\n%55 = OpTypePointer StorageBuffer %31\n%60 = OpConstant %5 1\n%65 = OpConstantComposite %9 %44 %44\n%66 = OpTypePointer StorageBuffer %26\n%74 = OpConstantComposite %9 %47 %47\n%75 = OpTypePointer StorageBuffer %21\n%84 = OpTypePointer StorageBuffer %15\n%92 = OpTypeVector %5 3\n%93 = OpTypePointer Input %92\n%94 = OpVariable %93 Input\n%95 = OpTypePointer Input %5\n%98 = OpVariable %93 Input\n%104 = OpTypeBool\n%107 = OpConstant %5 536870911\n%110 = OpTypeFloat 32\n%111 = OpTypeVector %110 2\n%130 = OpConstant %5 268435455\n%131 = OpTypePointer StorageBuffer %19\n%331 = OpConstant %5 1073741820\n%332 = OpTypePointer StorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %345\n%345 = OpLabel\n%43 = OpAccessChain %42 %8 %44\n%45 = OpLoad %5 %43\n%41 = OpAccessChain %40 %39 %45\n%46 = OpGroupNonUniformBroadcastFirst %5 %47 %45\n%49 = OpAccessChain %48 %13 %50 %46\n%51 = OpLoad %9 %49\n%52 = OpShiftRightLogical %9 %51 %54\n%57 = OpAccessChain %42 %8 %44\n%58 = OpLoad %5 %57\n%59 = OpIAdd %5 %58 %60\n%56 = OpAccessChain %55 %34 %59\n%61 = OpGroupNonUniformBroadcastFirst %5 %47 %59\n%62 = OpAccessChain %48 %13 %50 %61\n%63 = OpLoad %9 %62\n%64 = OpShiftRightLogical %9 %63 %65\n%68 = OpAccessChain %42 %8 %44\n%69 = OpLoad %5 %68\n%67 = OpAccessChain %66 %29 %69\n%70 = OpGroupNonUniformBroadcastFirst %5 %47 %69\n%71 = OpAccessChain %48 %13 %50 %70\n%72 = OpLoad %9 %71\n%73 = OpShiftRightLogical %9 %72 %74\n%77 = OpAccessChain %42 %8 %60\n%78 = OpLoad %5 %77\n%79 = OpIAdd %5 %78 %60\n%76 = OpAccessChain %75 %24 %79\n%80 = OpGroupNonUniformBroadcastFirst %5 %47 %79\n%81 = OpAccessChain %48 %13 %50 %80\n%82 = OpLoad %9 %81\n%83 = OpShiftRightLogical %9 %82 %65\n%86 = OpAccessChain %42 %8 %60\n%87 = OpLoad %5 %86\n%85 = OpAccessChain %84 %18 %87\n%88 = OpGroupNonUniformBroadcastFirst %5 %47 %87\n%89 = OpAccessChain %48 %13 %50 %88\n%90 = OpLoad %9 %89\n%91 = OpShiftRightLogical %9 %90 %74\n%96 = OpAccessChain %95 %94 %50\n%97 = OpLoad %5 %96\n%99 = OpAccessChain %95 %98 %50\n%100 = OpLoad %5 %99\n%101 = OpCompositeExtract %5 %91 0\n%102 = OpCompositeExtract %5 %91 1\n%103 = OpIAdd %5 %97 %101\n%105 = OpULessThan %104 %97 %102\n%106 = OpSelect %5 %105 %103 %107\n%108 = OpAccessChain %48 %85 %50 %106\n%109 = OpLoad %9 %108\n%112 = OpBitcast %111 %109\n%113 = OpCompositeExtract %110 %112 0\n%114 = OpCompositeExtract %110 %112 1\n%115 = OpCompositeExtract %5 %73 0\n%116 = OpCompositeExtract %5 %73 1\n%117 = OpIAdd %5 %97 %115\n%118 = OpULessThan %104 %97 %116\n%119 = OpSelect %5 %118 %117 %107\n%120 = OpBitcast %5 %113\n%121 = OpBitcast %5 %114\n%122 = OpCompositeConstruct %9 %120 %121\n%123 = OpAccessChain %48 %67 %50 %119\nOpStore %123 %122\n%124 = OpShiftLeftLogical %5 %97 %44\n%125 = OpCompositeExtract %5 %83 0\n%126 = OpCompositeExtract %5 %83 1\n%127 = OpIAdd %5 %97 %125\n%128 = OpULessThan %104 %97 %126\n%129 = OpSelect %5 %128 %127 %130\n%132 = OpAccessChain %131 %76 %50 %129\n%133 = OpLoad %19 %132\n%134 = OpCompositeExtract %5 %133 0\n%135 = OpCompositeExtract %5 %133 1\n%136 = OpCompositeExtract %5 %133 2\n%137 = OpCompositeExtract %5 %133 3\n%138 = OpCompositeExtract %5 %64 0\n%139 = OpCompositeExtract %5 %64 1\n%140 = OpIAdd %5 %97 %138\n%141 = OpULessThan %104 %97 %139\n%142 = OpSelect %5 %141 %140 %130\n%143 = OpCompositeConstruct %19 %134 %135 %136 %137\n%144 = OpAccessChain %131 %56 %50 %142\nOpStore %144 %143\n%145 = OpCompositeExtract %5 %91 0\n%146 = OpCompositeExtract %5 %91 1\n%147 = OpIAdd %5 %97 %145\n%148 = OpULessThan %104 %97 %146\n%149 = OpSelect %5 %148 %147 %107\n%150 = OpAccessChain %48 %85 %50 %149\n%151 = OpLoad %9 %150\n%152 = OpBitcast %111 %151\n%153 = OpCompositeExtract %110 %152 0\n%154 = OpCompositeExtract %110 %152 1\n%155 = OpCompositeExtract %5 %73 0\n%156 = OpCompositeExtract %5 %73 1\n%157 = OpIAdd %5 %97 %155\n%158 = OpULessThan %104 %97 %156\n%159 = OpSelect %5 %158 %157 %107\n%160 = OpBitcast %5 %153\n%161 = OpBitcast %5 %154\n%162 = OpCompositeConstruct %9 %160 %161\n%163 = OpAccessChain %48 %67 %50 %159\nOpStore %163 %162\n%164 = OpCompositeExtract %5 %83 0\n%165 = OpCompositeExtract %5 %83 1\n%166 = OpIAdd %5 %97 %164\n%167 = OpULessThan %104 %97 %165\n%168 = OpSelect %5 %167 %166 %130\n%169 = OpAccessChain %131 %76 %50 %168\n%170 = OpLoad %19 %169\n%171 = OpCompositeExtract %5 %170 0\n%172 = OpCompositeExtract %5 %170 1\n%173 = OpCompositeExtract %5 %170 2\n%174 = OpCompositeExtract %5 %170 3\n%175 = OpCompositeExtract %5 %64 0\n%176 = OpCompositeExtract %5 %64 1\n%177 = OpIAdd %5 %97 %175\n%178 = OpULessThan %104 %97 %176\n%179 = OpSelect %5 %178 %177 %130\n%180 = OpCompositeConstruct %19 %171 %172 %173 %174\n%181 = OpAccessChain %131 %56 %50 %179\nOpStore %181 %180\n%182 = OpIAdd %5 %100 %53\n%184 = OpAccessChain %42 %8 %60\n%185 = OpLoad %5 %184\n%186 = OpIAdd %5 %185 %182\n%183 = OpAccessChain %84 %18 %186\n%187 = OpGroupNonUniformBroadcastFirst %5 %47 %186\n%188 = OpAccessChain %48 %13 %50 %187\n%189 = OpLoad %9 %188\n%190 = OpShiftRightLogical %9 %189 %74\n%191 = OpCompositeExtract %5 %190 0\n%192 = OpCompositeExtract %5 %190 1\n%193 = OpIAdd %5 %97 %191\n%194 = OpULessThan %104 %97 %192\n%195 = OpSelect %5 %194 %193 %107\n%196 = OpAccessChain %48 %183 %50 %195\n%197 = OpLoad %9 %196\n%198 = OpBitcast %111 %197\n%199 = OpCompositeExtract %110 %198 0\n%200 = OpCompositeExtract %110 %198 1\n%201 = OpIAdd %5 %100 %50\n%203 = OpAccessChain %42 %8 %44\n%204 = OpLoad %5 %203\n%205 = OpIAdd %5 %204 %201\n%202 = OpAccessChain %66 %29 %205\n%206 = OpGroupNonUniformBroadcastFirst %5 %47 %205\n%207 = OpAccessChain %48 %13 %50 %206\n%208 = OpLoad %9 %207\n%209 = OpShiftRightLogical %9 %208 %74\n%210 = OpCompositeExtract %5 %209 0\n%211 = OpCompositeExtract %5 %209 1\n%212 = OpIAdd %5 %97 %210\n%213 = OpULessThan %104 %97 %211\n%214 = OpSelect %5 %213 %212 %107\n%215 = OpBitcast %5 %199\n%216 = OpBitcast %5 %200\n%217 = OpCompositeConstruct %9 %215 %216\n%218 = OpAccessChain %48 %202 %50 %214\nOpStore %218 %217\n%219 = OpIAdd %5 %97 %53\n%221 = OpAccessChain %42 %8 %60\n%222 = OpLoad %5 %221\n%223 = OpIAdd %5 %222 %219\n%220 = OpAccessChain %84 %18 %223\n%224 = OpAccessChain %48 %13 %50 %223\n%225 = OpLoad %9 %224\n%226 = OpShiftRightLogical %9 %225 %74\n%227 = OpCompositeExtract %5 %226 0\n%228 = OpCompositeExtract %5 %226 1\n%229 = OpIAdd %5 %97 %227\n%230 = OpULessThan %104 %97 %228\n%231 = OpSelect %5 %230 %229 %107\n%232 = OpAccessChain %48 %220 %50 %231\n%233 = OpLoad %9 %232\n%234 = OpBitcast %111 %233\n%235 = OpCompositeExtract %110 %234 0\n%236 = OpCompositeExtract %110 %234 1\n%237 = OpIAdd %5 %97 %50\n%239 = OpAccessChain %42 %8 %44\n%240 = OpLoad %5 %239\n%241 = OpIAdd %5 %240 %237\n%238 = OpAccessChain %66 %29 %241\n%242 = OpAccessChain %48 %13 %50 %241\n%243 = OpLoad %9 %242\n%244 = OpShiftRightLogical %9 %243 %74\n%245 = OpCompositeExtract %5 %244 0\n%246 = OpCompositeExtract %5 %244 1\n%247 = OpIAdd %5 %97 %245\n%248 = OpULessThan %104 %97 %246\n%249 = OpSelect %5 %248 %247 %107\n%250 = OpBitcast %5 %235\n%251 = OpBitcast %5 %236\n%252 = OpCompositeConstruct %9 %250 %251\n%253 = OpAccessChain %48 %238 %50 %249\nOpStore %253 %252\n%254 = OpIAdd %5 %100 %47\n%256 = OpAccessChain %42 %8 %60\n%257 = OpLoad %5 %256\n%258 = OpIAdd %5 %257 %254\n%255 = OpAccessChain %75 %24 %258\n%259 = OpGroupNonUniformBroadcastFirst %5 %47 %258\n%260 = OpAccessChain %48 %13 %50 %259\n%261 = OpLoad %9 %260\n%262 = OpShiftRightLogical %9 %261 %65\n%263 = OpCompositeExtract %5 %262 0\n%264 = OpCompositeExtract %5 %262 1\n%265 = OpIAdd %5 %97 %263\n%266 = OpULessThan %104 %97 %264\n%267 = OpSelect %5 %266 %265 %130\n%268 = OpAccessChain %131 %255 %50 %267\n%269 = OpLoad %19 %268\n%270 = OpCompositeExtract %5 %269 0\n%271 = OpCompositeExtract %5 %269 1\n%272 = OpCompositeExtract %5 %269 2\n%273 = OpCompositeExtract %5 %269 3\n%274 = OpIAdd %5 %100 %60\n%276 = OpAccessChain %42 %8 %44\n%277 = OpLoad %5 %276\n%278 = OpIAdd %5 %277 %274\n%275 = OpAccessChain %55 %34 %278\n%279 = OpGroupNonUniformBroadcastFirst %5 %47 %278\n%280 = OpAccessChain %48 %13 %50 %279\n%281 = OpLoad %9 %280\n%282 = OpShiftRightLogical %9 %281 %65\n%283 = OpCompositeExtract %5 %282 0\n%284 = OpCompositeExtract %5 %282 1\n%285 = OpIAdd %5 %97 %283\n%286 = OpULessThan %104 %97 %284\n%287 = OpSelect %5 %286 %285 %130\n%288 = OpCompositeConstruct %19 %270 %271 %272 %273\n%289 = OpAccessChain %131 %275 %50 %287\nOpStore %289 %288\n%290 = OpIAdd %5 %97 %47\n%292 = OpAccessChain %42 %8 %60\n%293 = OpLoad %5 %292\n%294 = OpIAdd %5 %293 %290\n%291 = OpAccessChain %75 %24 %294\n%295 = OpAccessChain %48 %13 %50 %294\n%296 = OpLoad %9 %295\n%297 = OpShiftRightLogical %9 %296 %65\n%298 = OpCompositeExtract %5 %297 0\n%299 = OpCompositeExtract %5 %297 1\n%300 = OpIAdd %5 %97 %298\n%301 = OpULessThan %104 %97 %299\n%302 = OpSelect %5 %301 %300 %130\n%303 = OpAccessChain %131 %291 %50 %302\n%304 = OpLoad %19 %303\n%305 = OpCompositeExtract %5 %304 0\n%306 = OpCompositeExtract %5 %304 1\n%307 = OpCompositeExtract %5 %304 2\n%308 = OpCompositeExtract %5 %304 3\n%309 = OpIAdd %5 %97 %60\n%311 = OpAccessChain %42 %8 %44\n%312 = OpLoad %5 %311\n%313 = OpIAdd %5 %312 %309\n%310 = OpAccessChain %55 %34 %313\n%314 = OpAccessChain %48 %13 %50 %313\n%315 = OpLoad %9 %314\n%316 = OpShiftRightLogical %9 %315 %65\n%317 = OpCompositeExtract %5 %316 0\n%318 = OpCompositeExtract %5 %316 1\n%319 = OpIAdd %5 %97 %317\n%320 = OpULessThan %104 %97 %318\n%321 = OpSelect %5 %320 %319 %130\n%322 = OpCompositeConstruct %19 %305 %306 %307 %308\n%323 = OpAccessChain %131 %310 %50 %321\nOpStore %323 %322\n%324 = OpIMul %5 %97 %53\n%325 = OpIAdd %5 %324 %60\n%326 = OpCompositeExtract %5 %52 0\n%327 = OpCompositeExtract %5 %52 1\n%328 = OpIAdd %5 %325 %326\n%329 = OpULessThan %104 %325 %327\n%330 = OpSelect %5 %329 %328 %331\n%333 = OpAccessChain %332 %41 %50 %330\n%334 = OpAtomicIAdd %5 %333 %60 %50 %60\n%335 = OpCompositeExtract %5 %73 1\n%336 = OpUDiv %5 %335 %60\n%337 = OpIMul %5 %97 %53\n%338 = OpCompositeExtract %5 %52 0\n%339 = OpCompositeExtract %5 %52 1\n%340 = OpIAdd %5 %337 %338\n%341 = OpULessThan %104 %337 %339\n%342 = OpSelect %5 %341 %340 %331\n%343 = OpAccessChain %332 %41 %50 %342\n%344 = OpAtomicIAdd %5 %343 %60 %50 %336\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/buffer-alignment-fixup.ssbo.ssbo-align.bindless.root-constant.offset-layout.typed-buffer-offset.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _18[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _21_24\n{\n    uvec4 _m0[];\n} _24[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _26_29\n{\n    uvec2 _m0[];\n} _29[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _31_34\n{\n    uvec4 _m0[];\n} _34[];\n\nlayout(set = 4, binding = 0, std430) buffer _36_39\n{\n    uint _m0[];\n} _39[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0) uniform writeonly uimageBuffer _43[];\n\nvoid main()\n{\n    uint _55 = (subgroupBroadcastFirst(registers._m4) * 2u) + 1u;\n    uvec2 _69 = _13._m0[subgroupBroadcastFirst(registers._m4) * 2u] >> uvec2(2u);\n    uint _75 = registers._m4 + 1u;\n    uvec2 _80 = _13._m0[subgroupBroadcastFirst(_75) * 2u] >> uvec2(4u);\n    uvec2 _90 = _13._m0[subgroupBroadcastFirst(registers._m4) * 2u] >> uvec2(3u);\n    uint _96 = registers._m1 + 1u;\n    uvec2 _101 = _13._m0[subgroupBroadcastFirst(_96) * 2u] >> uvec2(4u);\n    uvec2 _110 = _13._m0[subgroupBroadcastFirst(registers._m1) * 2u] >> uvec2(3u);\n    vec2 _131 = uintBitsToFloat(_18[registers._m1]._m0[(gl_GlobalInvocationID.x < _110.y) ? (gl_GlobalInvocationID.x + _110.x) : 536870911u]);\n    _29[registers._m4]._m0[(gl_GlobalInvocationID.x < _90.y) ? (gl_GlobalInvocationID.x + _90.x) : 536870911u] = uvec2(floatBitsToUint(_131.x), floatBitsToUint(_131.y));\n    _34[_75]._m0[(gl_GlobalInvocationID.x < _80.y) ? (gl_GlobalInvocationID.x + _80.x) : 268435455u] = uvec4(_24[_96]._m0[(gl_GlobalInvocationID.x < _101.y) ? (gl_GlobalInvocationID.x + _101.x) : 268435455u]);\n    vec2 _171 = uintBitsToFloat(_18[registers._m1]._m0[(gl_GlobalInvocationID.x < _110.y) ? (gl_GlobalInvocationID.x + _110.x) : 536870911u]);\n    _29[registers._m4]._m0[(gl_GlobalInvocationID.x < _90.y) ? (gl_GlobalInvocationID.x + _90.x) : 536870911u] = uvec2(floatBitsToUint(_171.x), floatBitsToUint(_171.y));\n    _34[_75]._m0[(gl_GlobalInvocationID.x < _80.y) ? (gl_GlobalInvocationID.x + _80.x) : 268435455u] = uvec4(_24[_96]._m0[(gl_GlobalInvocationID.x < _101.y) ? (gl_GlobalInvocationID.x + _101.x) : 268435455u]);\n    uint _205 = registers._m1 + (gl_WorkGroupID.x + 2u);\n    uvec2 _210 = _13._m0[subgroupBroadcastFirst(_205) * 2u] >> uvec2(3u);\n    vec2 _218 = uintBitsToFloat(_18[_205]._m0[(gl_GlobalInvocationID.x < _210.y) ? (gl_GlobalInvocationID.x + _210.x) : 536870911u]);\n    uint _225 = registers._m4 + (gl_WorkGroupID.x + 0u);\n    uvec2 _230 = _13._m0[subgroupBroadcastFirst(_225) * 2u] >> uvec2(3u);\n    _29[_225]._m0[(gl_GlobalInvocationID.x < _230.y) ? (gl_GlobalInvocationID.x + _230.x) : 536870911u] = uvec2(floatBitsToUint(_218.x), floatBitsToUint(_218.y));\n    uint _244 = registers._m1 + (gl_GlobalInvocationID.x + 2u);\n    uvec2 _248 = _13._m0[_244 * 2u] >> uvec2(3u);\n    vec2 _256 = uintBitsToFloat(_18[nonuniformEXT(_244)]._m0[(gl_GlobalInvocationID.x < _248.y) ? (gl_GlobalInvocationID.x + _248.x) : 536870911u]);\n    uint _263 = registers._m4 + (gl_GlobalInvocationID.x + 0u);\n    uvec2 _267 = _13._m0[_263 * 2u] >> uvec2(3u);\n    _29[nonuniformEXT(_263)]._m0[(gl_GlobalInvocationID.x < _267.y) ? (gl_GlobalInvocationID.x + _267.x) : 536870911u] = uvec2(floatBitsToUint(_256.x), floatBitsToUint(_256.y));\n    uint _281 = registers._m1 + (gl_WorkGroupID.x + 3u);\n    uvec2 _286 = _13._m0[subgroupBroadcastFirst(_281) * 2u] >> uvec2(4u);\n    uint _302 = registers._m4 + (gl_WorkGroupID.x + 1u);\n    uvec2 _307 = _13._m0[subgroupBroadcastFirst(_302) * 2u] >> uvec2(4u);\n    _34[_302]._m0[(gl_GlobalInvocationID.x < _307.y) ? (gl_GlobalInvocationID.x + _307.x) : 268435455u] = uvec4(_24[_281]._m0[(gl_GlobalInvocationID.x < _286.y) ? (gl_GlobalInvocationID.x + _286.x) : 268435455u]);\n    uint _319 = registers._m1 + (gl_GlobalInvocationID.x + 3u);\n    uvec2 _323 = _13._m0[_319 * 2u] >> uvec2(4u);\n    uint _339 = registers._m4 + (gl_GlobalInvocationID.x + 1u);\n    uvec2 _343 = _13._m0[_339 * 2u] >> uvec2(4u);\n    _34[nonuniformEXT(_339)]._m0[(gl_GlobalInvocationID.x < _343.y) ? (gl_GlobalInvocationID.x + _343.x) : 268435455u] = uvec4(_24[nonuniformEXT(_319)]._m0[(gl_GlobalInvocationID.x < _323.y) ? (gl_GlobalInvocationID.x + _323.x) : 268435455u]);\n    uint _352 = (gl_GlobalInvocationID.x * 2u) + 1u;\n    uint _361 = atomicAdd(_39[registers._m4]._m0[(_352 < _69.y) ? (_352 + _69.x) : 1073741820u], 1u);\n    uint _364 = gl_GlobalInvocationID.x * 2u;\n    uint _371 = atomicAdd(_39[registers._m4]._m0[(_364 < _69.y) ? (_364 + _69.x) : 1073741820u], _90.y / 1u);\n    uint _372 = gl_GlobalInvocationID.x << 2u;\n    imageStore(_43[registers._m4], int((gl_GlobalInvocationID.x < _13._m0[_55].y) ? (gl_GlobalInvocationID.x + _13._m0[_55].x) : 4294967295u), uvec4(_372, _372 | 1u, _372 | 2u, _372 | 3u));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 385\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %113 %117\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %15 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %31 \"SSBO\"\nOpName %36 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %14 ArrayStride 8\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 1\nOpDecorate %18 Binding 0\nOpDecorate %18 NonWritable\nOpDecorate %18 Restrict\nOpDecorate %20 ArrayStride 16\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %25 ArrayStride 8\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 DescriptorSet 4\nOpDecorate %29 Binding 0\nOpDecorate %29 NonReadable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %34 DescriptorSet 4\nOpDecorate %34 Binding 0\nOpDecorate %34 NonReadable\nOpDecorate %35 ArrayStride 4\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %39 DescriptorSet 4\nOpDecorate %39 Binding 0\nOpDecorate %43 DescriptorSet 4\nOpDecorate %43 Binding 0\nOpDecorate %43 NonReadable\nOpDecorate %113 BuiltIn GlobalInvocationId\nOpDecorate %117 BuiltIn WorkgroupId\nOpDecorate %244 NonUniform\nOpDecorate %241 NonUniform\nOpDecorate %254 NonUniform\nOpDecorate %263 NonUniform\nOpDecorate %260 NonUniform\nOpDecorate %276 NonUniform\nOpDecorate %319 NonUniform\nOpDecorate %316 NonUniform\nOpDecorate %329 NonUniform\nOpDecorate %339 NonUniform\nOpDecorate %336 NonUniform\nOpDecorate %350 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeRuntimeArray %9\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeVector %5 4\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %9\n%26 = OpTypeStruct %25\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeRuntimeArray %19\n%31 = OpTypeStruct %30\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeRuntimeArray %5\n%36 = OpTypeStruct %35\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypePointer StorageBuffer %37\n%39 = OpVariable %38 StorageBuffer\n%40 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%41 = OpTypeRuntimeArray %40\n%42 = OpTypePointer UniformConstant %41\n%43 = OpVariable %42 UniformConstant\n%44 = OpTypePointer UniformConstant %40\n%46 = OpTypePointer PushConstant %5\n%48 = OpConstant %5 4\n%52 = OpConstant %5 3\n%54 = OpConstant %5 2\n%56 = OpConstant %5 1\n%57 = OpTypePointer StorageBuffer %9\n%59 = OpConstant %5 0\n%61 = OpTypePointer StorageBuffer %36\n%70 = OpConstantComposite %9 %54 %54\n%71 = OpTypePointer StorageBuffer %31\n%81 = OpConstantComposite %9 %48 %48\n%82 = OpTypePointer StorageBuffer %26\n%91 = OpConstantComposite %9 %52 %52\n%92 = OpTypePointer StorageBuffer %21\n%102 = OpTypePointer StorageBuffer %15\n%111 = OpTypeVector %5 3\n%112 = OpTypePointer Input %111\n%113 = OpVariable %112 Input\n%114 = OpTypePointer Input %5\n%117 = OpVariable %112 Input\n%123 = OpTypeBool\n%126 = OpConstant %5 536870911\n%129 = OpTypeFloat 32\n%130 = OpTypeVector %129 2\n%149 = OpConstant %5 268435455\n%150 = OpTypePointer StorageBuffer %19\n%358 = OpConstant %5 1073741820\n%359 = OpTypePointer StorageBuffer %5\n%381 = OpConstant %5 4294967295\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %383\n%383 = OpLabel\n%47 = OpAccessChain %46 %8 %48\n%49 = OpLoad %5 %47\n%45 = OpAccessChain %44 %43 %49\n%50 = OpLoad %40 %45\n%51 = OpGroupNonUniformBroadcastFirst %5 %52 %49\n%53 = OpIMul %5 %51 %54\n%55 = OpIAdd %5 %53 %56\n%58 = OpAccessChain %57 %13 %59 %55\n%60 = OpLoad %9 %58\n%63 = OpAccessChain %46 %8 %48\n%64 = OpLoad %5 %63\n%62 = OpAccessChain %61 %39 %64\n%65 = OpGroupNonUniformBroadcastFirst %5 %52 %64\n%66 = OpIMul %5 %65 %54\n%67 = OpAccessChain %57 %13 %59 %66\n%68 = OpLoad %9 %67\n%69 = OpShiftRightLogical %9 %68 %70\n%73 = OpAccessChain %46 %8 %48\n%74 = OpLoad %5 %73\n%75 = OpIAdd %5 %74 %56\n%72 = OpAccessChain %71 %34 %75\n%76 = OpGroupNonUniformBroadcastFirst %5 %52 %75\n%77 = OpIMul %5 %76 %54\n%78 = OpAccessChain %57 %13 %59 %77\n%79 = OpLoad %9 %78\n%80 = OpShiftRightLogical %9 %79 %81\n%84 = OpAccessChain %46 %8 %48\n%85 = OpLoad %5 %84\n%83 = OpAccessChain %82 %29 %85\n%86 = OpGroupNonUniformBroadcastFirst %5 %52 %85\n%87 = OpIMul %5 %86 %54\n%88 = OpAccessChain %57 %13 %59 %87\n%89 = OpLoad %9 %88\n%90 = OpShiftRightLogical %9 %89 %91\n%94 = OpAccessChain %46 %8 %56\n%95 = OpLoad %5 %94\n%96 = OpIAdd %5 %95 %56\n%93 = OpAccessChain %92 %24 %96\n%97 = OpGroupNonUniformBroadcastFirst %5 %52 %96\n%98 = OpIMul %5 %97 %54\n%99 = OpAccessChain %57 %13 %59 %98\n%100 = OpLoad %9 %99\n%101 = OpShiftRightLogical %9 %100 %81\n%104 = OpAccessChain %46 %8 %56\n%105 = OpLoad %5 %104\n%103 = OpAccessChain %102 %18 %105\n%106 = OpGroupNonUniformBroadcastFirst %5 %52 %105\n%107 = OpIMul %5 %106 %54\n%108 = OpAccessChain %57 %13 %59 %107\n%109 = OpLoad %9 %108\n%110 = OpShiftRightLogical %9 %109 %91\n%115 = OpAccessChain %114 %113 %59\n%116 = OpLoad %5 %115\n%118 = OpAccessChain %114 %117 %59\n%119 = OpLoad %5 %118\n%120 = OpCompositeExtract %5 %110 0\n%121 = OpCompositeExtract %5 %110 1\n%122 = OpIAdd %5 %116 %120\n%124 = OpULessThan %123 %116 %121\n%125 = OpSelect %5 %124 %122 %126\n%127 = OpAccessChain %57 %103 %59 %125\n%128 = OpLoad %9 %127\n%131 = OpBitcast %130 %128\n%132 = OpCompositeExtract %129 %131 0\n%133 = OpCompositeExtract %129 %131 1\n%134 = OpCompositeExtract %5 %90 0\n%135 = OpCompositeExtract %5 %90 1\n%136 = OpIAdd %5 %116 %134\n%137 = OpULessThan %123 %116 %135\n%138 = OpSelect %5 %137 %136 %126\n%139 = OpBitcast %5 %132\n%140 = OpBitcast %5 %133\n%141 = OpCompositeConstruct %9 %139 %140\n%142 = OpAccessChain %57 %83 %59 %138\nOpStore %142 %141\n%143 = OpShiftLeftLogical %5 %116 %48\n%144 = OpCompositeExtract %5 %101 0\n%145 = OpCompositeExtract %5 %101 1\n%146 = OpIAdd %5 %116 %144\n%147 = OpULessThan %123 %116 %145\n%148 = OpSelect %5 %147 %146 %149\n%151 = OpAccessChain %150 %93 %59 %148\n%152 = OpLoad %19 %151\n%153 = OpCompositeExtract %5 %152 0\n%154 = OpCompositeExtract %5 %152 1\n%155 = OpCompositeExtract %5 %152 2\n%156 = OpCompositeExtract %5 %152 3\n%157 = OpCompositeExtract %5 %80 0\n%158 = OpCompositeExtract %5 %80 1\n%159 = OpIAdd %5 %116 %157\n%160 = OpULessThan %123 %116 %158\n%161 = OpSelect %5 %160 %159 %149\n%162 = OpCompositeConstruct %19 %153 %154 %155 %156\n%163 = OpAccessChain %150 %72 %59 %161\nOpStore %163 %162\n%164 = OpCompositeExtract %5 %110 0\n%165 = OpCompositeExtract %5 %110 1\n%166 = OpIAdd %5 %116 %164\n%167 = OpULessThan %123 %116 %165\n%168 = OpSelect %5 %167 %166 %126\n%169 = OpAccessChain %57 %103 %59 %168\n%170 = OpLoad %9 %169\n%171 = OpBitcast %130 %170\n%172 = OpCompositeExtract %129 %171 0\n%173 = OpCompositeExtract %129 %171 1\n%174 = OpCompositeExtract %5 %90 0\n%175 = OpCompositeExtract %5 %90 1\n%176 = OpIAdd %5 %116 %174\n%177 = OpULessThan %123 %116 %175\n%178 = OpSelect %5 %177 %176 %126\n%179 = OpBitcast %5 %172\n%180 = OpBitcast %5 %173\n%181 = OpCompositeConstruct %9 %179 %180\n%182 = OpAccessChain %57 %83 %59 %178\nOpStore %182 %181\n%183 = OpCompositeExtract %5 %101 0\n%184 = OpCompositeExtract %5 %101 1\n%185 = OpIAdd %5 %116 %183\n%186 = OpULessThan %123 %116 %184\n%187 = OpSelect %5 %186 %185 %149\n%188 = OpAccessChain %150 %93 %59 %187\n%189 = OpLoad %19 %188\n%190 = OpCompositeExtract %5 %189 0\n%191 = OpCompositeExtract %5 %189 1\n%192 = OpCompositeExtract %5 %189 2\n%193 = OpCompositeExtract %5 %189 3\n%194 = OpCompositeExtract %5 %80 0\n%195 = OpCompositeExtract %5 %80 1\n%196 = OpIAdd %5 %116 %194\n%197 = OpULessThan %123 %116 %195\n%198 = OpSelect %5 %197 %196 %149\n%199 = OpCompositeConstruct %19 %190 %191 %192 %193\n%200 = OpAccessChain %150 %72 %59 %198\nOpStore %200 %199\n%201 = OpIAdd %5 %119 %54\n%203 = OpAccessChain %46 %8 %56\n%204 = OpLoad %5 %203\n%205 = OpIAdd %5 %204 %201\n%202 = OpAccessChain %102 %18 %205\n%206 = OpGroupNonUniformBroadcastFirst %5 %52 %205\n%207 = OpIMul %5 %206 %54\n%208 = OpAccessChain %57 %13 %59 %207\n%209 = OpLoad %9 %208\n%210 = OpShiftRightLogical %9 %209 %91\n%211 = OpCompositeExtract %5 %210 0\n%212 = OpCompositeExtract %5 %210 1\n%213 = OpIAdd %5 %116 %211\n%214 = OpULessThan %123 %116 %212\n%215 = OpSelect %5 %214 %213 %126\n%216 = OpAccessChain %57 %202 %59 %215\n%217 = OpLoad %9 %216\n%218 = OpBitcast %130 %217\n%219 = OpCompositeExtract %129 %218 0\n%220 = OpCompositeExtract %129 %218 1\n%221 = OpIAdd %5 %119 %59\n%223 = OpAccessChain %46 %8 %48\n%224 = OpLoad %5 %223\n%225 = OpIAdd %5 %224 %221\n%222 = OpAccessChain %82 %29 %225\n%226 = OpGroupNonUniformBroadcastFirst %5 %52 %225\n%227 = OpIMul %5 %226 %54\n%228 = OpAccessChain %57 %13 %59 %227\n%229 = OpLoad %9 %228\n%230 = OpShiftRightLogical %9 %229 %91\n%231 = OpCompositeExtract %5 %230 0\n%232 = OpCompositeExtract %5 %230 1\n%233 = OpIAdd %5 %116 %231\n%234 = OpULessThan %123 %116 %232\n%235 = OpSelect %5 %234 %233 %126\n%236 = OpBitcast %5 %219\n%237 = OpBitcast %5 %220\n%238 = OpCompositeConstruct %9 %236 %237\n%239 = OpAccessChain %57 %222 %59 %235\nOpStore %239 %238\n%240 = OpIAdd %5 %116 %54\n%242 = OpAccessChain %46 %8 %56\n%243 = OpLoad %5 %242\n%244 = OpIAdd %5 %243 %240\n%241 = OpAccessChain %102 %18 %244\n%245 = OpIMul %5 %244 %54\n%246 = OpAccessChain %57 %13 %59 %245\n%247 = OpLoad %9 %246\n%248 = OpShiftRightLogical %9 %247 %91\n%249 = OpCompositeExtract %5 %248 0\n%250 = OpCompositeExtract %5 %248 1\n%251 = OpIAdd %5 %116 %249\n%252 = OpULessThan %123 %116 %250\n%253 = OpSelect %5 %252 %251 %126\n%254 = OpAccessChain %57 %241 %59 %253\n%255 = OpLoad %9 %254\n%256 = OpBitcast %130 %255\n%257 = OpCompositeExtract %129 %256 0\n%258 = OpCompositeExtract %129 %256 1\n%259 = OpIAdd %5 %116 %59\n%261 = OpAccessChain %46 %8 %48\n%262 = OpLoad %5 %261\n%263 = OpIAdd %5 %262 %259\n%260 = OpAccessChain %82 %29 %263\n%264 = OpIMul %5 %263 %54\n%265 = OpAccessChain %57 %13 %59 %264\n%266 = OpLoad %9 %265\n%267 = OpShiftRightLogical %9 %266 %91\n%268 = OpCompositeExtract %5 %267 0\n%269 = OpCompositeExtract %5 %267 1\n%270 = OpIAdd %5 %116 %268\n%271 = OpULessThan %123 %116 %269\n%272 = OpSelect %5 %271 %270 %126\n%273 = OpBitcast %5 %257\n%274 = OpBitcast %5 %258\n%275 = OpCompositeConstruct %9 %273 %274\n%276 = OpAccessChain %57 %260 %59 %272\nOpStore %276 %275\n%277 = OpIAdd %5 %119 %52\n%279 = OpAccessChain %46 %8 %56\n%280 = OpLoad %5 %279\n%281 = OpIAdd %5 %280 %277\n%278 = OpAccessChain %92 %24 %281\n%282 = OpGroupNonUniformBroadcastFirst %5 %52 %281\n%283 = OpIMul %5 %282 %54\n%284 = OpAccessChain %57 %13 %59 %283\n%285 = OpLoad %9 %284\n%286 = OpShiftRightLogical %9 %285 %81\n%287 = OpCompositeExtract %5 %286 0\n%288 = OpCompositeExtract %5 %286 1\n%289 = OpIAdd %5 %116 %287\n%290 = OpULessThan %123 %116 %288\n%291 = OpSelect %5 %290 %289 %149\n%292 = OpAccessChain %150 %278 %59 %291\n%293 = OpLoad %19 %292\n%294 = OpCompositeExtract %5 %293 0\n%295 = OpCompositeExtract %5 %293 1\n%296 = OpCompositeExtract %5 %293 2\n%297 = OpCompositeExtract %5 %293 3\n%298 = OpIAdd %5 %119 %56\n%300 = OpAccessChain %46 %8 %48\n%301 = OpLoad %5 %300\n%302 = OpIAdd %5 %301 %298\n%299 = OpAccessChain %71 %34 %302\n%303 = OpGroupNonUniformBroadcastFirst %5 %52 %302\n%304 = OpIMul %5 %303 %54\n%305 = OpAccessChain %57 %13 %59 %304\n%306 = OpLoad %9 %305\n%307 = OpShiftRightLogical %9 %306 %81\n%308 = OpCompositeExtract %5 %307 0\n%309 = OpCompositeExtract %5 %307 1\n%310 = OpIAdd %5 %116 %308\n%311 = OpULessThan %123 %116 %309\n%312 = OpSelect %5 %311 %310 %149\n%313 = OpCompositeConstruct %19 %294 %295 %296 %297\n%314 = OpAccessChain %150 %299 %59 %312\nOpStore %314 %313\n%315 = OpIAdd %5 %116 %52\n%317 = OpAccessChain %46 %8 %56\n%318 = OpLoad %5 %317\n%319 = OpIAdd %5 %318 %315\n%316 = OpAccessChain %92 %24 %319\n%320 = OpIMul %5 %319 %54\n%321 = OpAccessChain %57 %13 %59 %320\n%322 = OpLoad %9 %321\n%323 = OpShiftRightLogical %9 %322 %81\n%324 = OpCompositeExtract %5 %323 0\n%325 = OpCompositeExtract %5 %323 1\n%326 = OpIAdd %5 %116 %324\n%327 = OpULessThan %123 %116 %325\n%328 = OpSelect %5 %327 %326 %149\n%329 = OpAccessChain %150 %316 %59 %328\n%330 = OpLoad %19 %329\n%331 = OpCompositeExtract %5 %330 0\n%332 = OpCompositeExtract %5 %330 1\n%333 = OpCompositeExtract %5 %330 2\n%334 = OpCompositeExtract %5 %330 3\n%335 = OpIAdd %5 %116 %56\n%337 = OpAccessChain %46 %8 %48\n%338 = OpLoad %5 %337\n%339 = OpIAdd %5 %338 %335\n%336 = OpAccessChain %71 %34 %339\n%340 = OpIMul %5 %339 %54\n%341 = OpAccessChain %57 %13 %59 %340\n%342 = OpLoad %9 %341\n%343 = OpShiftRightLogical %9 %342 %81\n%344 = OpCompositeExtract %5 %343 0\n%345 = OpCompositeExtract %5 %343 1\n%346 = OpIAdd %5 %116 %344\n%347 = OpULessThan %123 %116 %345\n%348 = OpSelect %5 %347 %346 %149\n%349 = OpCompositeConstruct %19 %331 %332 %333 %334\n%350 = OpAccessChain %150 %336 %59 %348\nOpStore %350 %349\n%351 = OpIMul %5 %116 %54\n%352 = OpIAdd %5 %351 %56\n%353 = OpCompositeExtract %5 %69 0\n%354 = OpCompositeExtract %5 %69 1\n%355 = OpIAdd %5 %352 %353\n%356 = OpULessThan %123 %352 %354\n%357 = OpSelect %5 %356 %355 %358\n%360 = OpAccessChain %359 %62 %59 %357\n%361 = OpAtomicIAdd %5 %360 %56 %59 %56\n%362 = OpCompositeExtract %5 %90 1\n%363 = OpUDiv %5 %362 %56\n%364 = OpIMul %5 %116 %54\n%365 = OpCompositeExtract %5 %69 0\n%366 = OpCompositeExtract %5 %69 1\n%367 = OpIAdd %5 %364 %365\n%368 = OpULessThan %123 %364 %366\n%369 = OpSelect %5 %368 %367 %358\n%370 = OpAccessChain %359 %62 %59 %369\n%371 = OpAtomicIAdd %5 %370 %56 %59 %363\n%372 = OpShiftLeftLogical %5 %116 %54\n%373 = OpBitwiseOr %5 %372 %56\n%374 = OpBitwiseOr %5 %372 %54\n%375 = OpBitwiseOr %5 %372 %52\n%376 = OpCompositeExtract %5 %60 0\n%377 = OpCompositeExtract %5 %60 1\n%378 = OpIAdd %5 %116 %376\n%379 = OpULessThan %123 %116 %377\n%380 = OpSelect %5 %379 %378 %381\n%382 = OpCompositeConstruct %19 %372 %373 %374 %375\nOpImageWrite %50 %380 %382\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbuf.root-constant.min16float.sm60.frag",
    "content": "#version 460\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) in mediump vec4 C;\nlayout(location = 0) out mediump vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _43 = uintBitsToFloat(uvec4(registers._m4, registers._m5, registers._m6, registers._m7));\n    vec4 _61 = uintBitsToFloat(uvec4(registers._m8, registers._m9, registers._m10, registers._m11));\n    SV_Target.x = (_43.x + C.x) + _61.x;\n    SV_Target.y = (_43.y + C.y) + _61.y;\n    SV_Target.z = (_43.z + C.z) + _61.z;\n    SV_Target.w = (_43.w + C.w) + _61.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 81\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %14\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"C\"\nOpName %14 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 Location 0\nOpDecorate %14 RelaxedPrecision\nOpDecorate %14 Location 0\nOpDecorate %44 RelaxedPrecision\nOpDecorate %45 RelaxedPrecision\nOpDecorate %46 RelaxedPrecision\nOpDecorate %47 RelaxedPrecision\nOpDecorate %62 RelaxedPrecision\nOpDecorate %63 RelaxedPrecision\nOpDecorate %64 RelaxedPrecision\nOpDecorate %65 RelaxedPrecision\nOpDecorate %66 RelaxedPrecision\nOpDecorate %67 RelaxedPrecision\nOpDecorate %68 RelaxedPrecision\nOpDecorate %69 RelaxedPrecision\nOpDecorate %70 RelaxedPrecision\nOpDecorate %71 RelaxedPrecision\nOpDecorate %72 RelaxedPrecision\nOpDecorate %73 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Output %10\n%14 = OpVariable %13 Output\n%15 = OpTypePointer Input %9\n%17 = OpConstant %5 0\n%20 = OpConstant %5 1\n%23 = OpConstant %5 2\n%26 = OpConstant %5 3\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 4\n%33 = OpConstant %5 5\n%36 = OpConstant %5 6\n%39 = OpConstant %5 7\n%41 = OpTypeVector %5 4\n%49 = OpConstant %5 8\n%52 = OpConstant %5 9\n%55 = OpConstant %5 10\n%58 = OpConstant %5 11\n%74 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %79\n%79 = OpLabel\n%16 = OpAccessChain %15 %12 %17\n%18 = OpLoad %9 %16\n%19 = OpAccessChain %15 %12 %20\n%21 = OpLoad %9 %19\n%22 = OpAccessChain %15 %12 %23\n%24 = OpLoad %9 %22\n%25 = OpAccessChain %15 %12 %26\n%27 = OpLoad %9 %25\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%32 = OpAccessChain %28 %8 %33\n%34 = OpLoad %5 %32\n%35 = OpAccessChain %28 %8 %36\n%37 = OpLoad %5 %35\n%38 = OpAccessChain %28 %8 %39\n%40 = OpLoad %5 %38\n%42 = OpCompositeConstruct %41 %31 %34 %37 %40\n%43 = OpBitcast %10 %42\n%44 = OpCompositeExtract %9 %43 0\n%45 = OpCompositeExtract %9 %43 1\n%46 = OpCompositeExtract %9 %43 2\n%47 = OpCompositeExtract %9 %43 3\n%48 = OpAccessChain %28 %8 %49\n%50 = OpLoad %5 %48\n%51 = OpAccessChain %28 %8 %52\n%53 = OpLoad %5 %51\n%54 = OpAccessChain %28 %8 %55\n%56 = OpLoad %5 %54\n%57 = OpAccessChain %28 %8 %58\n%59 = OpLoad %5 %57\n%60 = OpCompositeConstruct %41 %50 %53 %56 %59\n%61 = OpBitcast %10 %60\n%62 = OpCompositeExtract %9 %61 0\n%63 = OpCompositeExtract %9 %61 1\n%64 = OpCompositeExtract %9 %61 2\n%65 = OpCompositeExtract %9 %61 3\n%66 = OpFAdd %9 %44 %18\n%67 = OpFAdd %9 %66 %62\n%68 = OpFAdd %9 %45 %21\n%69 = OpFAdd %9 %68 %63\n%70 = OpFAdd %9 %46 %24\n%71 = OpFAdd %9 %70 %64\n%72 = OpFAdd %9 %47 %27\n%73 = OpFAdd %9 %72 %65\n%75 = OpAccessChain %74 %14 %17\nOpStore %75 %67\n%76 = OpAccessChain %74 %14 %20\nOpStore %76 %69\n%77 = OpAccessChain %74 %14 %23\nOpStore %77 %71\n%78 = OpAccessChain %74 %14 %26\nOpStore %78 %73\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbuf.root-constant.min16float.sm60.native-fp16.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) in mediump vec4 C;\nlayout(location = 0) out mediump vec4 SV_Target;\n\nvoid main()\n{\n    f16vec4 _50 = f16vec4(uintBitsToFloat(uvec4(registers._m4, registers._m5, registers._m6, registers._m7)));\n    f16vec4 _69 = f16vec4(uintBitsToFloat(uvec4(registers._m8, registers._m9, registers._m10, registers._m11)));\n    SV_Target.x = float((_50.x + float16_t(C.x)) + _69.x);\n    SV_Target.y = float((_50.y + float16_t(C.y)) + _69.y);\n    SV_Target.z = float((_50.z + float16_t(C.z)) + _69.z);\n    SV_Target.w = float((_50.w + float16_t(C.w)) + _69.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 93\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %14\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"C\"\nOpName %14 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 Location 0\nOpDecorate %14 RelaxedPrecision\nOpDecorate %14 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Output %10\n%14 = OpVariable %13 Output\n%15 = OpTypePointer Input %9\n%17 = OpConstant %5 0\n%19 = OpTypeFloat 16\n%22 = OpConstant %5 1\n%26 = OpConstant %5 2\n%30 = OpConstant %5 3\n%33 = OpTypePointer PushConstant %5\n%35 = OpConstant %5 4\n%38 = OpConstant %5 5\n%41 = OpConstant %5 6\n%44 = OpConstant %5 7\n%46 = OpTypeVector %5 4\n%49 = OpTypeVector %19 4\n%56 = OpConstant %5 8\n%59 = OpConstant %5 9\n%62 = OpConstant %5 10\n%65 = OpConstant %5 11\n%82 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %91\n%91 = OpLabel\n%16 = OpAccessChain %15 %12 %17\n%18 = OpLoad %9 %16\n%20 = OpFConvert %19 %18\n%21 = OpAccessChain %15 %12 %22\n%23 = OpLoad %9 %21\n%24 = OpFConvert %19 %23\n%25 = OpAccessChain %15 %12 %26\n%27 = OpLoad %9 %25\n%28 = OpFConvert %19 %27\n%29 = OpAccessChain %15 %12 %30\n%31 = OpLoad %9 %29\n%32 = OpFConvert %19 %31\n%34 = OpAccessChain %33 %8 %35\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %33 %8 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %33 %8 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %33 %8 %44\n%45 = OpLoad %5 %43\n%47 = OpCompositeConstruct %46 %36 %39 %42 %45\n%48 = OpBitcast %10 %47\n%50 = OpFConvert %49 %48\n%51 = OpCompositeExtract %19 %50 0\n%52 = OpCompositeExtract %19 %50 1\n%53 = OpCompositeExtract %19 %50 2\n%54 = OpCompositeExtract %19 %50 3\n%55 = OpAccessChain %33 %8 %56\n%57 = OpLoad %5 %55\n%58 = OpAccessChain %33 %8 %59\n%60 = OpLoad %5 %58\n%61 = OpAccessChain %33 %8 %62\n%63 = OpLoad %5 %61\n%64 = OpAccessChain %33 %8 %65\n%66 = OpLoad %5 %64\n%67 = OpCompositeConstruct %46 %57 %60 %63 %66\n%68 = OpBitcast %10 %67\n%69 = OpFConvert %49 %68\n%70 = OpCompositeExtract %19 %69 0\n%71 = OpCompositeExtract %19 %69 1\n%72 = OpCompositeExtract %19 %69 2\n%73 = OpCompositeExtract %19 %69 3\n%74 = OpFAdd %19 %51 %20\n%75 = OpFAdd %19 %74 %70\n%76 = OpFAdd %19 %52 %24\n%77 = OpFAdd %19 %76 %71\n%78 = OpFAdd %19 %53 %28\n%79 = OpFAdd %19 %78 %72\n%80 = OpFAdd %19 %54 %32\n%81 = OpFAdd %19 %80 %73\n%83 = OpAccessChain %82 %14 %17\n%84 = OpFConvert %9 %75\nOpStore %83 %84\n%85 = OpAccessChain %82 %14 %22\n%86 = OpFConvert %9 %77\nOpStore %85 %86\n%87 = OpAccessChain %82 %14 %26\n%88 = OpFConvert %9 %79\nOpStore %87 %88\n%89 = OpAccessChain %82 %14 %30\n%90 = OpFConvert %9 %81\nOpStore %89 %90\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbuf.root-constant.min16int.sm60.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) in mediump vec4 C;\nlayout(location = 0) out mediump ivec4 SV_Target;\n\nvoid main()\n{\n    u16vec4 _47 = u16vec4(uvec4(registers._m4, registers._m5, registers._m6, registers._m7));\n    u16vec4 _65 = u16vec4(uvec4(registers._m8, registers._m9, registers._m10, registers._m11));\n    SV_Target.x = int(int16_t((_47.x + uint16_t(int16_t(C.x))) + _65.x));\n    SV_Target.y = int(int16_t((_47.y + uint16_t(int16_t(C.y))) + _65.y));\n    SV_Target.z = int(int16_t((_47.z + uint16_t(int16_t(C.z))) + _65.z));\n    SV_Target.w = int(int16_t((_47.w + uint16_t(int16_t(C.w))) + _65.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 93\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %16\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"C\"\nOpName %16 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 Location 0\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeInt 32 1\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Input %9\n%19 = OpConstant %5 0\n%22 = OpConstant %5 1\n%25 = OpConstant %5 2\n%28 = OpConstant %5 3\n%30 = OpTypePointer PushConstant %5\n%32 = OpConstant %5 4\n%35 = OpConstant %5 5\n%38 = OpConstant %5 6\n%41 = OpConstant %5 7\n%43 = OpTypeVector %5 4\n%45 = OpTypeInt 16 0\n%46 = OpTypeVector %45 4\n%53 = OpConstant %5 8\n%56 = OpConstant %5 9\n%59 = OpConstant %5 10\n%62 = OpConstant %5 11\n%82 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %91\n%91 = OpLabel\n%18 = OpAccessChain %17 %12 %19\n%20 = OpLoad %9 %18\n%21 = OpAccessChain %17 %12 %22\n%23 = OpLoad %9 %21\n%24 = OpAccessChain %17 %12 %25\n%26 = OpLoad %9 %24\n%27 = OpAccessChain %17 %12 %28\n%29 = OpLoad %9 %27\n%31 = OpAccessChain %30 %8 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %30 %8 %35\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %30 %8 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %30 %8 %41\n%42 = OpLoad %5 %40\n%44 = OpCompositeConstruct %43 %33 %36 %39 %42\n%47 = OpUConvert %46 %44\n%48 = OpCompositeExtract %45 %47 0\n%49 = OpCompositeExtract %45 %47 1\n%50 = OpCompositeExtract %45 %47 2\n%51 = OpCompositeExtract %45 %47 3\n%52 = OpAccessChain %30 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %30 %8 %56\n%57 = OpLoad %5 %55\n%58 = OpAccessChain %30 %8 %59\n%60 = OpLoad %5 %58\n%61 = OpAccessChain %30 %8 %62\n%63 = OpLoad %5 %61\n%64 = OpCompositeConstruct %43 %54 %57 %60 %63\n%65 = OpUConvert %46 %64\n%66 = OpCompositeExtract %45 %65 0\n%67 = OpCompositeExtract %45 %65 1\n%68 = OpCompositeExtract %45 %65 2\n%69 = OpCompositeExtract %45 %65 3\n%70 = OpConvertFToS %45 %20\n%71 = OpConvertFToS %45 %23\n%72 = OpConvertFToS %45 %26\n%73 = OpConvertFToS %45 %29\n%74 = OpIAdd %45 %48 %70\n%75 = OpIAdd %45 %74 %66\n%76 = OpIAdd %45 %49 %71\n%77 = OpIAdd %45 %76 %67\n%78 = OpIAdd %45 %50 %72\n%79 = OpIAdd %45 %78 %68\n%80 = OpIAdd %45 %51 %73\n%81 = OpIAdd %45 %80 %69\n%83 = OpAccessChain %82 %16 %19\n%84 = OpSConvert %13 %75\nOpStore %83 %84\n%85 = OpAccessChain %82 %16 %22\n%86 = OpSConvert %13 %77\nOpStore %85 %86\n%87 = OpAccessChain %82 %16 %25\n%88 = OpSConvert %13 %79\nOpStore %87 %88\n%89 = OpAccessChain %82 %16 %28\n%90 = OpSConvert %13 %81\nOpStore %89 %90\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbuf.root-constant.min16int.sm60.native-fp16.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) in mediump vec4 C;\nlayout(location = 0) out mediump ivec4 SV_Target;\n\nvoid main()\n{\n    u16vec4 _52 = u16vec4(uvec4(registers._m4, registers._m5, registers._m6, registers._m7));\n    u16vec4 _70 = u16vec4(uvec4(registers._m8, registers._m9, registers._m10, registers._m11));\n    SV_Target.x = int(int16_t((_52.x + uint16_t(int16_t(float16_t(C.x)))) + _70.x));\n    SV_Target.y = int(int16_t((_52.y + uint16_t(int16_t(float16_t(C.y)))) + _70.y));\n    SV_Target.z = int(int16_t((_52.z + uint16_t(int16_t(float16_t(C.z)))) + _70.z));\n    SV_Target.w = int(int16_t((_52.w + uint16_t(int16_t(float16_t(C.w)))) + _70.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 98\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"C\"\nOpName %16 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 Location 0\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeInt 32 1\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Input %9\n%19 = OpConstant %5 0\n%21 = OpTypeFloat 16\n%24 = OpConstant %5 1\n%28 = OpConstant %5 2\n%32 = OpConstant %5 3\n%35 = OpTypePointer PushConstant %5\n%37 = OpConstant %5 4\n%40 = OpConstant %5 5\n%43 = OpConstant %5 6\n%46 = OpConstant %5 7\n%48 = OpTypeVector %5 4\n%50 = OpTypeInt 16 0\n%51 = OpTypeVector %50 4\n%58 = OpConstant %5 8\n%61 = OpConstant %5 9\n%64 = OpConstant %5 10\n%67 = OpConstant %5 11\n%87 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %96\n%96 = OpLabel\n%18 = OpAccessChain %17 %12 %19\n%20 = OpLoad %9 %18\n%22 = OpFConvert %21 %20\n%23 = OpAccessChain %17 %12 %24\n%25 = OpLoad %9 %23\n%26 = OpFConvert %21 %25\n%27 = OpAccessChain %17 %12 %28\n%29 = OpLoad %9 %27\n%30 = OpFConvert %21 %29\n%31 = OpAccessChain %17 %12 %32\n%33 = OpLoad %9 %31\n%34 = OpFConvert %21 %33\n%36 = OpAccessChain %35 %8 %37\n%38 = OpLoad %5 %36\n%39 = OpAccessChain %35 %8 %40\n%41 = OpLoad %5 %39\n%42 = OpAccessChain %35 %8 %43\n%44 = OpLoad %5 %42\n%45 = OpAccessChain %35 %8 %46\n%47 = OpLoad %5 %45\n%49 = OpCompositeConstruct %48 %38 %41 %44 %47\n%52 = OpUConvert %51 %49\n%53 = OpCompositeExtract %50 %52 0\n%54 = OpCompositeExtract %50 %52 1\n%55 = OpCompositeExtract %50 %52 2\n%56 = OpCompositeExtract %50 %52 3\n%57 = OpAccessChain %35 %8 %58\n%59 = OpLoad %5 %57\n%60 = OpAccessChain %35 %8 %61\n%62 = OpLoad %5 %60\n%63 = OpAccessChain %35 %8 %64\n%65 = OpLoad %5 %63\n%66 = OpAccessChain %35 %8 %67\n%68 = OpLoad %5 %66\n%69 = OpCompositeConstruct %48 %59 %62 %65 %68\n%70 = OpUConvert %51 %69\n%71 = OpCompositeExtract %50 %70 0\n%72 = OpCompositeExtract %50 %70 1\n%73 = OpCompositeExtract %50 %70 2\n%74 = OpCompositeExtract %50 %70 3\n%75 = OpConvertFToS %50 %22\n%76 = OpConvertFToS %50 %26\n%77 = OpConvertFToS %50 %30\n%78 = OpConvertFToS %50 %34\n%79 = OpIAdd %50 %53 %75\n%80 = OpIAdd %50 %79 %71\n%81 = OpIAdd %50 %54 %76\n%82 = OpIAdd %50 %81 %72\n%83 = OpIAdd %50 %55 %77\n%84 = OpIAdd %50 %83 %73\n%85 = OpIAdd %50 %56 %78\n%86 = OpIAdd %50 %85 %74\n%88 = OpAccessChain %87 %16 %19\n%89 = OpSConvert %13 %80\nOpStore %88 %89\n%90 = OpAccessChain %87 %16 %24\n%91 = OpSConvert %13 %82\nOpStore %90 %91\n%92 = OpAccessChain %87 %16 %28\n%93 = OpSConvert %13 %84\nOpStore %92 %93\n%94 = OpAccessChain %87 %16 %32\n%95 = OpSConvert %13 %86\nOpStore %94 %95\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-array-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std140) uniform _10_13\n{\n    vec4 _m0[4];\n} _13[];\n\nlayout(set = 1, binding = 0, std140) uniform _15_19\n{\n    vec4 _m0[4];\n} _19[100];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _25 = INDEX & 3u;\n    uint _27 = INDEX + 0u;\n    uint _38 = INDEX & 1u;\n    uint _41 = (INDEX ^ 1u) + 0u;\n    SV_Target.x = _19[nonuniformEXT(_41)]._m0[_38].x + _13[nonuniformEXT(_27)]._m0[_25].x;\n    SV_Target.y = _19[nonuniformEXT(_41)]._m0[_38].y + _13[nonuniformEXT(_27)]._m0[_25].y;\n    SV_Target.z = _19[nonuniformEXT(_41)]._m0[_38].z + _13[nonuniformEXT(_27)]._m0[_25].z;\n    SV_Target.w = _19[nonuniformEXT(_41)]._m0[_38].w + _13[nonuniformEXT(_27)]._m0[_25].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %21 %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %15 \"\"\nOpName %21 \"INDEX\"\nOpName %23 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %21 Flat\nOpDecorate %21 Location 0\nOpDecorate %23 Location 0\nOpDecorate %27 NonUniform\nOpDecorate %30 NonUniform\nOpDecorate %32 NonUniform\nOpDecorate %41 NonUniform\nOpDecorate %43 NonUniform\nOpDecorate %44 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 4\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer Uniform %11\n%13 = OpVariable %12 Uniform\n%14 = OpTypeArray %8 %6\n%15 = OpTypeStruct %14\n%16 = OpConstant %5 100\n%17 = OpTypeArray %15 %16\n%18 = OpTypePointer Uniform %17\n%19 = OpVariable %18 Uniform\n%20 = OpTypePointer Input %5\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Output %8\n%23 = OpVariable %22 Output\n%26 = OpConstant %5 3\n%28 = OpConstant %5 0\n%29 = OpTypePointer Uniform %10\n%31 = OpTypePointer Uniform %8\n%39 = OpConstant %5 1\n%42 = OpTypePointer Uniform %15\n%54 = OpTypePointer Output %7\n%58 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%24 = OpLoad %5 %21\n%25 = OpBitwiseAnd %5 %24 %26\n%27 = OpIAdd %5 %24 %28\n%30 = OpAccessChain %29 %13 %27\n%32 = OpAccessChain %31 %30 %28 %25\n%33 = OpLoad %8 %32\n%34 = OpCompositeExtract %7 %33 0\n%35 = OpCompositeExtract %7 %33 1\n%36 = OpCompositeExtract %7 %33 2\n%37 = OpCompositeExtract %7 %33 3\n%38 = OpBitwiseAnd %5 %24 %39\n%40 = OpBitwiseXor %5 %24 %39\n%41 = OpIAdd %5 %40 %28\n%43 = OpAccessChain %42 %19 %41\n%44 = OpAccessChain %31 %43 %28 %38\n%45 = OpLoad %8 %44\n%46 = OpCompositeExtract %7 %45 0\n%47 = OpCompositeExtract %7 %45 1\n%48 = OpCompositeExtract %7 %45 2\n%49 = OpCompositeExtract %7 %45 3\n%50 = OpFAdd %7 %46 %34\n%51 = OpFAdd %7 %47 %35\n%52 = OpFAdd %7 %48 %36\n%53 = OpFAdd %7 %49 %37\n%55 = OpAccessChain %54 %23 %28\nOpStore %55 %50\n%56 = OpAccessChain %54 %23 %39\nOpStore %56 %51\n%57 = OpAccessChain %54 %23 %58\nOpStore %57 %52\n%59 = OpAccessChain %54 %23 %26\nOpStore %59 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-array.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std140) uniform _10_13\n{\n    vec4 _m0[4];\n} _13[];\n\nlayout(set = 1, binding = 0, std140) uniform _15_19\n{\n    vec4 _m0[4];\n} _19[100];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _25 = INDEX & 3u;\n    uint _27 = INDEX + 0u;\n    uint _38 = INDEX & 1u;\n    uint _41 = (INDEX ^ 1u) + 0u;\n    SV_Target.x = _19[nonuniformEXT(_41)]._m0[_38].x + _13[nonuniformEXT(_27)]._m0[_25].x;\n    SV_Target.y = _19[nonuniformEXT(_41)]._m0[_38].y + _13[nonuniformEXT(_27)]._m0[_25].y;\n    SV_Target.z = _19[nonuniformEXT(_41)]._m0[_38].z + _13[nonuniformEXT(_27)]._m0[_25].z;\n    SV_Target.w = _19[nonuniformEXT(_41)]._m0[_38].w + _13[nonuniformEXT(_27)]._m0[_25].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %21 %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %15 \"\"\nOpName %21 \"INDEX\"\nOpName %23 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %21 Flat\nOpDecorate %21 Location 0\nOpDecorate %23 Location 0\nOpDecorate %30 NonUniform\nOpDecorate %32 NonUniform\nOpDecorate %43 NonUniform\nOpDecorate %44 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 4\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer Uniform %11\n%13 = OpVariable %12 Uniform\n%14 = OpTypeArray %8 %6\n%15 = OpTypeStruct %14\n%16 = OpConstant %5 100\n%17 = OpTypeArray %15 %16\n%18 = OpTypePointer Uniform %17\n%19 = OpVariable %18 Uniform\n%20 = OpTypePointer Input %5\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Output %8\n%23 = OpVariable %22 Output\n%26 = OpConstant %5 3\n%28 = OpConstant %5 0\n%29 = OpTypePointer Uniform %10\n%31 = OpTypePointer Uniform %8\n%39 = OpConstant %5 1\n%42 = OpTypePointer Uniform %15\n%54 = OpTypePointer Output %7\n%58 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%24 = OpLoad %5 %21\n%25 = OpBitwiseAnd %5 %24 %26\n%27 = OpIAdd %5 %24 %28\n%30 = OpAccessChain %29 %13 %27\n%32 = OpAccessChain %31 %30 %28 %25\n%33 = OpLoad %8 %32\n%34 = OpCompositeExtract %7 %33 0\n%35 = OpCompositeExtract %7 %33 1\n%36 = OpCompositeExtract %7 %33 2\n%37 = OpCompositeExtract %7 %33 3\n%38 = OpBitwiseAnd %5 %24 %39\n%40 = OpBitwiseXor %5 %24 %39\n%41 = OpIAdd %5 %40 %28\n%43 = OpAccessChain %42 %19 %41\n%44 = OpAccessChain %31 %43 %28 %38\n%45 = OpLoad %8 %44\n%46 = OpCompositeExtract %7 %45 0\n%47 = OpCompositeExtract %7 %45 1\n%48 = OpCompositeExtract %7 %45 2\n%49 = OpCompositeExtract %7 %45 3\n%50 = OpFAdd %7 %46 %34\n%51 = OpFAdd %7 %47 %35\n%52 = OpFAdd %7 %48 %36\n%53 = OpFAdd %7 %49 %37\n%55 = OpAccessChain %54 %23 %28\nOpStore %55 %50\n%56 = OpAccessChain %54 %23 %39\nOpStore %56 %51\n%57 = OpAccessChain %54 %23 %58\nOpStore %57 %52\n%59 = OpAccessChain %54 %23 %26\nOpStore %59 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-dynamic.no-legacy-cbuf-layout.local-root-signature.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _17\n{\n    vec4 _m0;\n    uvec4 _m1;\n};\n\nvec4 _63;\nuvec4 _101;\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(location = 0) rayPayloadInEXT _17 payload;\n\nvoid main()\n{\n    uvec4 _28 = payload._m1;\n    uint _30 = 4u * _28.x;\n    uvec4 _57 = uvec4(SBT._m0[4u], 0u, 0u, 0u);\n    uint _60 = _57.z;\n    vec4 _62;\n    _62.x = uintBitsToFloat(uvec4(SBT._m0[min((_30 + 0u), 4u)], SBT._m0[min((_30 + 1u), 4u)], SBT._m0[min((_30 + 2u), 4u)], SBT._m0[min((_30 + 3u), 4u)])).x;\n    _62.y = float(_57.y);\n    _62.z = float(int(_60));\n    _62.w = 1.0;\n    payload._m0 = _62;\n    uint _71 = 4u * _28.y;\n    vec4 _89 = uintBitsToFloat(uvec4(SBT._m1[min((_71 + 0u), 5u)], SBT._m1[min((_71 + 1u), 5u)], SBT._m1[min((_71 + 2u), 5u)], SBT._m1[min((_71 + 3u), 5u)]));\n    uvec4 _100;\n    _100.x = uint(int(_89.x));\n    _100.y = uint(int(_89.y));\n    _100.z = uvec4(SBT._m1[4u], SBT._m1[5u], 0u, 0u).z;\n    _100.w = _60;\n    payload._m1 = _100;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\n%35 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint MissKHR %3 \"main\" %13 %19\nOpName %3 \"main\"\nOpName %11 \"SBTBlock\"\nOpName %13 \"SBT\"\nOpName %17 \"\"\nOpName %19 \"payload\"\nOpDecorate %7 ArrayStride 4\nOpDecorate %9 ArrayStride 4\nOpDecorate %11 Block\nOpMemberDecorate %11 0 Offset 0\nOpMemberDecorate %11 1 Offset 20\nOpMemberDecorate %11 2 Offset 48\nOpMemberDecorate %11 3 Offset 56\nOpMemberDecorate %11 4 Offset 64\nOpMemberDecorate %11 5 Offset 72\nOpMemberDecorate %11 6 Offset 80\nOpMemberDecorate %11 7 Offset 88\nOpMemberDecorate %11 8 Offset 96\nOpMemberDecorate %11 9 Offset 104\nOpMemberDecorate %11 10 Offset 112\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 5\n%7 = OpTypeArray %5 %6\n%8 = OpConstant %5 6\n%9 = OpTypeArray %5 %8\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %7 %9 %10 %10 %10 %10 %10 %10 %10 %10 %10\n%12 = OpTypePointer ShaderRecordBufferKHR %11\n%13 = OpVariable %12 ShaderRecordBufferKHR\n%14 = OpTypeFloat 32\n%15 = OpTypeVector %14 4\n%16 = OpTypeVector %5 4\n%17 = OpTypeStruct %15 %16\n%18 = OpTypePointer IncomingRayPayloadKHR %17\n%19 = OpVariable %18 IncomingRayPayloadKHR\n%20 = OpTypePointer ShaderRecordBufferKHR %9\n%22 = OpConstant %5 1\n%23 = OpTypePointer ShaderRecordBufferKHR %7\n%25 = OpConstant %5 0\n%26 = OpTypePointer IncomingRayPayloadKHR %16\n%31 = OpConstant %5 4\n%32 = OpTypePointer ShaderRecordBufferKHR %5\n%44 = OpConstant %5 2\n%49 = OpConstant %5 3\n%67 = OpConstant %14 1\n%68 = OpTypePointer IncomingRayPayloadKHR %15\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%63 = OpUndef %15\n%101 = OpUndef %16\nOpBranch %105\n%105 = OpLabel\n%21 = OpAccessChain %20 %13 %22\n%24 = OpAccessChain %23 %13 %25\n%27 = OpInBoundsAccessChain %26 %19 %22\n%28 = OpLoad %16 %27\n%29 = OpCompositeExtract %5 %28 0\n%30 = OpIMul %5 %31 %29\n%34 = OpIAdd %5 %30 %25\n%36 = OpExtInst %5 %35 UMin %34 %31\n%33 = OpAccessChain %32 %24 %36\n%37 = OpLoad %5 %33\n%39 = OpIAdd %5 %30 %22\n%40 = OpExtInst %5 %35 UMin %39 %31\n%38 = OpAccessChain %32 %24 %40\n%41 = OpLoad %5 %38\n%43 = OpIAdd %5 %30 %44\n%45 = OpExtInst %5 %35 UMin %43 %31\n%42 = OpAccessChain %32 %24 %45\n%46 = OpLoad %5 %42\n%48 = OpIAdd %5 %30 %49\n%50 = OpExtInst %5 %35 UMin %48 %31\n%47 = OpAccessChain %32 %24 %50\n%51 = OpLoad %5 %47\n%52 = OpCompositeConstruct %16 %37 %41 %46 %51\n%53 = OpBitcast %15 %52\n%54 = OpCompositeExtract %14 %53 0\n%55 = OpAccessChain %32 %24 %31\n%56 = OpLoad %5 %55\n%57 = OpCompositeConstruct %16 %56 %25 %25 %25\n%58 = OpCompositeExtract %5 %57 1\n%59 = OpConvertUToF %14 %58\n%60 = OpCompositeExtract %5 %57 2\n%61 = OpConvertSToF %14 %60\n%62 = OpCompositeInsert %15 %54 %63 0\n%64 = OpCompositeInsert %15 %59 %62 1\n%65 = OpCompositeInsert %15 %61 %64 2\n%66 = OpCompositeInsert %15 %67 %65 3\n%69 = OpInBoundsAccessChain %68 %19 %25\nOpStore %69 %66\n%70 = OpCompositeExtract %5 %28 1\n%71 = OpIMul %5 %31 %70\n%73 = OpIAdd %5 %71 %25\n%74 = OpExtInst %5 %35 UMin %73 %6\n%72 = OpAccessChain %32 %21 %74\n%75 = OpLoad %5 %72\n%77 = OpIAdd %5 %71 %22\n%78 = OpExtInst %5 %35 UMin %77 %6\n%76 = OpAccessChain %32 %21 %78\n%79 = OpLoad %5 %76\n%81 = OpIAdd %5 %71 %44\n%82 = OpExtInst %5 %35 UMin %81 %6\n%80 = OpAccessChain %32 %21 %82\n%83 = OpLoad %5 %80\n%85 = OpIAdd %5 %71 %49\n%86 = OpExtInst %5 %35 UMin %85 %6\n%84 = OpAccessChain %32 %21 %86\n%87 = OpLoad %5 %84\n%88 = OpCompositeConstruct %16 %75 %79 %83 %87\n%89 = OpBitcast %15 %88\n%90 = OpCompositeExtract %14 %89 0\n%91 = OpCompositeExtract %14 %89 1\n%92 = OpAccessChain %32 %21 %31\n%93 = OpLoad %5 %92\n%94 = OpAccessChain %32 %21 %6\n%95 = OpLoad %5 %94\n%96 = OpCompositeConstruct %16 %93 %95 %25 %25\n%97 = OpCompositeExtract %5 %96 2\n%98 = OpConvertFToS %5 %90\n%99 = OpConvertFToS %5 %91\n%100 = OpCompositeInsert %16 %98 %101 0\n%102 = OpCompositeInsert %16 %99 %100 1\n%103 = OpCompositeInsert %16 %97 %102 2\n%104 = OpCompositeInsert %16 %60 %103 3\nOpStore %27 %104\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-indexing.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 5, std140) uniform _10_14\n{\n    vec4 _m0[1];\n} _14[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = (_14[2u]._m0[0u].x + _14[0u]._m0[0u].x) + _14[nonuniformEXT(V)]._m0[0u].x;\n    SV_Target.y = (_14[2u]._m0[0u].y + _14[0u]._m0[0u].y) + _14[nonuniformEXT(V)]._m0[0u].y;\n    SV_Target.z = (_14[2u]._m0[0u].z + _14[0u]._m0[0u].z) + _14[nonuniformEXT(V)]._m0[0u].z;\n    SV_Target.w = (_14[2u]._m0[0u].w + _14[0u]._m0[0u].w) + _14[nonuniformEXT(V)]._m0[0u].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability UniformBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"V\"\nOpName %18 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 5\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %18 Location 0\nOpDecorate %44 NonUniform\nOpDecorate %45 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpConstant %5 3\n%12 = OpTypeArray %10 %11\n%13 = OpTypePointer Uniform %12\n%14 = OpVariable %13 Uniform\n%15 = OpTypePointer Input %5\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %8\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Uniform %10\n%21 = OpConstant %5 2\n%23 = OpConstant %5 0\n%25 = OpTypePointer Uniform %8\n%43 = OpConstant %5 5\n%55 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%20 = OpAccessChain %19 %14 %21\n%22 = OpAccessChain %19 %14 %23\n%24 = OpLoad %5 %16\n%26 = OpAccessChain %25 %22 %23 %23\n%27 = OpLoad %8 %26\n%28 = OpCompositeExtract %7 %27 0\n%29 = OpCompositeExtract %7 %27 1\n%30 = OpCompositeExtract %7 %27 2\n%31 = OpCompositeExtract %7 %27 3\n%32 = OpAccessChain %25 %20 %23 %23\n%33 = OpLoad %8 %32\n%34 = OpCompositeExtract %7 %33 0\n%35 = OpCompositeExtract %7 %33 1\n%36 = OpCompositeExtract %7 %33 2\n%37 = OpCompositeExtract %7 %33 3\n%38 = OpFAdd %7 %34 %28\n%39 = OpFAdd %7 %35 %29\n%40 = OpFAdd %7 %36 %30\n%41 = OpFAdd %7 %37 %31\n%42 = OpIAdd %5 %24 %43\n%44 = OpAccessChain %19 %14 %24\n%45 = OpAccessChain %25 %44 %23 %23\n%46 = OpLoad %8 %45\n%47 = OpCompositeExtract %7 %46 0\n%48 = OpCompositeExtract %7 %46 1\n%49 = OpCompositeExtract %7 %46 2\n%50 = OpCompositeExtract %7 %46 3\n%51 = OpFAdd %7 %38 %47\n%52 = OpFAdd %7 %39 %48\n%53 = OpFAdd %7 %40 %49\n%54 = OpFAdd %7 %41 %50\n%56 = OpAccessChain %55 %18 %23\nOpStore %56 %51\n%57 = OpAccessChain %55 %18 %6\nOpStore %57 %52\n%58 = OpAccessChain %55 %18 %21\nOpStore %58 %53\n%59 = OpAccessChain %55 %18 %11\nOpStore %59 %54\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-indexing.sm66.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 5, std140) uniform _10_14\n{\n    vec4 _m0[1];\n} _14[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = (_14[2u]._m0[0u].x + _14[0u]._m0[0u].x) + _14[nonuniformEXT(V)]._m0[0u].x;\n    SV_Target.y = (_14[2u]._m0[0u].y + _14[0u]._m0[0u].y) + _14[nonuniformEXT(V)]._m0[0u].y;\n    SV_Target.z = (_14[2u]._m0[0u].z + _14[0u]._m0[0u].z) + _14[nonuniformEXT(V)]._m0[0u].z;\n    SV_Target.w = (_14[2u]._m0[0u].w + _14[0u]._m0[0u].w) + _14[nonuniformEXT(V)]._m0[0u].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability UniformBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"V\"\nOpName %18 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 5\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %18 Location 0\nOpDecorate %44 NonUniform\nOpDecorate %45 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpConstant %5 3\n%12 = OpTypeArray %10 %11\n%13 = OpTypePointer Uniform %12\n%14 = OpVariable %13 Uniform\n%15 = OpTypePointer Input %5\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %8\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Uniform %10\n%21 = OpConstant %5 2\n%23 = OpConstant %5 0\n%25 = OpTypePointer Uniform %8\n%43 = OpConstant %5 5\n%55 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%20 = OpAccessChain %19 %14 %21\n%22 = OpAccessChain %19 %14 %23\n%24 = OpLoad %5 %16\n%26 = OpAccessChain %25 %22 %23 %23\n%27 = OpLoad %8 %26\n%28 = OpCompositeExtract %7 %27 0\n%29 = OpCompositeExtract %7 %27 1\n%30 = OpCompositeExtract %7 %27 2\n%31 = OpCompositeExtract %7 %27 3\n%32 = OpAccessChain %25 %20 %23 %23\n%33 = OpLoad %8 %32\n%34 = OpCompositeExtract %7 %33 0\n%35 = OpCompositeExtract %7 %33 1\n%36 = OpCompositeExtract %7 %33 2\n%37 = OpCompositeExtract %7 %33 3\n%38 = OpFAdd %7 %34 %28\n%39 = OpFAdd %7 %35 %29\n%40 = OpFAdd %7 %36 %30\n%41 = OpFAdd %7 %37 %31\n%42 = OpIAdd %5 %24 %43\n%44 = OpAccessChain %19 %14 %24\n%45 = OpAccessChain %25 %44 %23 %23\n%46 = OpLoad %8 %45\n%47 = OpCompositeExtract %7 %46 0\n%48 = OpCompositeExtract %7 %46 1\n%49 = OpCompositeExtract %7 %46 2\n%50 = OpCompositeExtract %7 %46 3\n%51 = OpFAdd %7 %38 %47\n%52 = OpFAdd %7 %39 %48\n%53 = OpFAdd %7 %40 %49\n%54 = OpFAdd %7 %41 %50\n%56 = OpAccessChain %55 %18 %23\nOpStore %56 %51\n%57 = OpAccessChain %55 %18 %6\nOpStore %57 %52\n%58 = OpAccessChain %55 %18 %21\nOpStore %58 %53\n%59 = OpAccessChain %55 %18 %11\nOpStore %59 %54\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-legacy-fp16-fp64.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nstruct CBVComposite16x8\n{\n    float16_t _m0;\n    float16_t _m1;\n    float16_t _m2;\n    float16_t _m3;\n    float16_t _m4;\n    float16_t _m5;\n    float16_t _m6;\n    float16_t _m7;\n};\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    u64vec2 _m0[4];\n} _12;\n\nlayout(set = 0, binding = 0, std140) uniform _16_18\n{\n    vec4 _m0[4];\n} _18;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    f16vec2 _38 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].x));\n    f16vec2 _41 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].y));\n    f16vec2 _44 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].z));\n    f16vec2 _47 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].w));\n    CBVComposite16x8 _51 = CBVComposite16x8(_38.x, _38.y, _41.x, _41.y, _44.x, _44.y, _47.x, _47.y);\n    SV_Target.x = ((float(_51._m0) + _18._m0[0u].x) + float(_51._m4)) + float(int64_t(_12._m0[2u].x));\n    SV_Target.y = ((float(_51._m1) + _18._m0[0u].y) + float(_51._m5)) + float(int64_t(_12._m0[2u].y));\n    SV_Target.z = ((float(_51._m2) + _18._m0[0u].z) + float(_51._m6)) + float(int64_t(_12._m0[3u].x));\n    SV_Target.w = ((float(_51._m3) + _18._m0[0u].w) + float(_51._m7)) + float(int64_t(_12._m0[3u].y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %20\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"\"\nOpName %20 \"SV_Target\"\nOpName %50 \"CBVComposite16x8\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %20 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 4\n%7 = OpTypeInt 64 0\n%8 = OpTypeVector %7 2\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeArray %14 %6\n%16 = OpTypeStruct %15\n%17 = OpTypePointer Uniform %16\n%18 = OpVariable %17 Uniform\n%19 = OpTypePointer Output %14\n%20 = OpVariable %19 Output\n%21 = OpConstant %5 0\n%22 = OpTypePointer Uniform %14\n%29 = OpTypeFloat 16\n%30 = OpConstant %5 1\n%33 = OpTypeVector %29 2\n%50 = OpTypeStruct %29 %29 %29 %29 %29 %29 %29 %29\n%76 = OpConstant %5 2\n%77 = OpTypePointer Uniform %8\n%82 = OpConstant %5 3\n%95 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %100\n%100 = OpLabel\n%23 = OpAccessChain %22 %18 %21 %21\n%24 = OpLoad %14 %23\n%25 = OpCompositeExtract %13 %24 0\n%26 = OpCompositeExtract %13 %24 1\n%27 = OpCompositeExtract %13 %24 2\n%28 = OpCompositeExtract %13 %24 3\n%31 = OpAccessChain %22 %18 %21 %30\n%32 = OpLoad %14 %31\n%34 = OpCompositeExtract %13 %32 0\n%35 = OpCompositeExtract %13 %32 1\n%36 = OpCompositeExtract %13 %32 2\n%37 = OpCompositeExtract %13 %32 3\n%38 = OpBitcast %33 %34\n%39 = OpCompositeExtract %29 %38 0\n%40 = OpCompositeExtract %29 %38 1\n%41 = OpBitcast %33 %35\n%42 = OpCompositeExtract %29 %41 0\n%43 = OpCompositeExtract %29 %41 1\n%44 = OpBitcast %33 %36\n%45 = OpCompositeExtract %29 %44 0\n%46 = OpCompositeExtract %29 %44 1\n%47 = OpBitcast %33 %37\n%48 = OpCompositeExtract %29 %47 0\n%49 = OpCompositeExtract %29 %47 1\n%51 = OpCompositeConstruct %50 %39 %40 %42 %43 %45 %46 %48 %49\n%52 = OpCompositeExtract %29 %51 0\n%53 = OpCompositeExtract %29 %51 1\n%54 = OpCompositeExtract %29 %51 2\n%55 = OpCompositeExtract %29 %51 3\n%56 = OpFConvert %13 %52\n%57 = OpFConvert %13 %53\n%58 = OpFConvert %13 %54\n%59 = OpFConvert %13 %55\n%60 = OpFAdd %13 %56 %25\n%61 = OpFAdd %13 %57 %26\n%62 = OpFAdd %13 %58 %27\n%63 = OpFAdd %13 %59 %28\n%64 = OpCompositeExtract %29 %51 4\n%65 = OpCompositeExtract %29 %51 5\n%66 = OpCompositeExtract %29 %51 6\n%67 = OpCompositeExtract %29 %51 7\n%68 = OpFConvert %13 %64\n%69 = OpFConvert %13 %65\n%70 = OpFConvert %13 %66\n%71 = OpFConvert %13 %67\n%72 = OpFAdd %13 %60 %68\n%73 = OpFAdd %13 %61 %69\n%74 = OpFAdd %13 %62 %70\n%75 = OpFAdd %13 %63 %71\n%78 = OpAccessChain %77 %12 %21 %76\n%79 = OpLoad %8 %78\n%80 = OpCompositeExtract %7 %79 0\n%81 = OpCompositeExtract %7 %79 1\n%83 = OpAccessChain %77 %12 %21 %82\n%84 = OpLoad %8 %83\n%85 = OpCompositeExtract %7 %84 0\n%86 = OpCompositeExtract %7 %84 1\n%87 = OpConvertSToF %13 %80\n%88 = OpConvertSToF %13 %81\n%89 = OpConvertSToF %13 %85\n%90 = OpConvertSToF %13 %86\n%91 = OpFAdd %13 %72 %87\n%92 = OpFAdd %13 %73 %88\n%93 = OpFAdd %13 %74 %89\n%94 = OpFAdd %13 %75 %90\n%96 = OpAccessChain %95 %20 %21\nOpStore %96 %91\n%97 = OpAccessChain %95 %20 %30\nOpStore %97 %92\n%98 = OpAccessChain %95 %20 %76\nOpStore %98 %93\n%99 = OpAccessChain %95 %20 %82\nOpStore %99 %94\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-legacy-fp16-fp64.root-descriptor.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerUint642NonWriteCBVArray;\n\nstruct CBVComposite16x8\n{\n    float16_t _m0;\n    float16_t _m1;\n    float16_t _m2;\n    float16_t _m3;\n    float16_t _m4;\n    float16_t _m5;\n    float16_t _m6;\n    float16_t _m7;\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint642NonWriteCBVArray\n{\n    u64vec2 value[4096];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    PhysicalPointerFloat4NonWriteCBVArray _22 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    PhysicalPointerFloat4NonWriteCBVArray _32 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    f16vec2 _40 = unpackFloat2x16(floatBitsToUint(_32.value[1u].x));\n    f16vec2 _43 = unpackFloat2x16(floatBitsToUint(_32.value[1u].y));\n    f16vec2 _46 = unpackFloat2x16(floatBitsToUint(_32.value[1u].z));\n    f16vec2 _49 = unpackFloat2x16(floatBitsToUint(_32.value[1u].w));\n    CBVComposite16x8 _53 = CBVComposite16x8(_40.x, _40.y, _43.x, _43.y, _46.x, _46.y, _49.x, _49.y);\n    PhysicalPointerUint642NonWriteCBVArray _84 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    PhysicalPointerUint642NonWriteCBVArray _91 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    SV_Target.x = ((float(_53._m0) + _22.value[0u].x) + float(_53._m4)) + float(int64_t(_84.value[2u].x));\n    SV_Target.y = ((float(_53._m1) + _22.value[0u].y) + float(_53._m5)) + float(int64_t(_84.value[2u].y));\n    SV_Target.z = ((float(_53._m2) + _22.value[0u].z) + float(_53._m6)) + float(int64_t(_91.value[3u].x));\n    SV_Target.w = ((float(_53._m3) + _22.value[0u].w) + float(_53._m7)) + float(int64_t(_91.value[3u].y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 111\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int64\nOpCapability DenormPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %13 \"SV_Target\"\nOpName %20 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %20 0 \"value\"\nOpName %52 \"CBVComposite16x8\"\nOpName %82 \"PhysicalPointerUint642NonWriteCBVArray\"\nOpMemberName %82 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %13 Location 0\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpMemberDecorate %20 0 NonWritable\nOpDecorate %81 ArrayStride 16\nOpMemberDecorate %82 0 Offset 0\nOpDecorate %82 Block\nOpMemberDecorate %82 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeVector %10 4\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%14 = OpTypePointer PushConstant %6\n%16 = OpConstant %5 0\n%18 = OpConstant %5 4096\n%19 = OpTypeArray %11 %18\n%20 = OpTypeStruct %19\n%21 = OpTypePointer PhysicalStorageBuffer %20\n%23 = OpTypePointer PhysicalStorageBuffer %11\n%30 = OpTypeFloat 16\n%31 = OpConstant %5 1\n%35 = OpTypeVector %30 2\n%52 = OpTypeStruct %30 %30 %30 %30 %30 %30 %30 %30\n%78 = OpTypeInt 64 0\n%79 = OpConstant %5 2\n%80 = OpTypeVector %78 2\n%81 = OpTypeArray %80 %18\n%82 = OpTypeStruct %81\n%83 = OpTypePointer PhysicalStorageBuffer %82\n%85 = OpTypePointer PhysicalStorageBuffer %80\n%90 = OpConstant %5 3\n%104 = OpTypePointer Output %10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %109\n%109 = OpLabel\n%15 = OpAccessChain %14 %9 %16\n%17 = OpLoad %6 %15\n%22 = OpBitcast %21 %17\n%24 = OpInBoundsAccessChain %23 %22 %16 %16\n%25 = OpLoad %11 %24 Aligned 16\n%26 = OpCompositeExtract %10 %25 0\n%27 = OpCompositeExtract %10 %25 1\n%28 = OpCompositeExtract %10 %25 2\n%29 = OpCompositeExtract %10 %25 3\n%32 = OpBitcast %21 %17\n%33 = OpInBoundsAccessChain %23 %32 %16 %31\n%34 = OpLoad %11 %33 Aligned 16\n%36 = OpCompositeExtract %10 %34 0\n%37 = OpCompositeExtract %10 %34 1\n%38 = OpCompositeExtract %10 %34 2\n%39 = OpCompositeExtract %10 %34 3\n%40 = OpBitcast %35 %36\n%41 = OpCompositeExtract %30 %40 0\n%42 = OpCompositeExtract %30 %40 1\n%43 = OpBitcast %35 %37\n%44 = OpCompositeExtract %30 %43 0\n%45 = OpCompositeExtract %30 %43 1\n%46 = OpBitcast %35 %38\n%47 = OpCompositeExtract %30 %46 0\n%48 = OpCompositeExtract %30 %46 1\n%49 = OpBitcast %35 %39\n%50 = OpCompositeExtract %30 %49 0\n%51 = OpCompositeExtract %30 %49 1\n%53 = OpCompositeConstruct %52 %41 %42 %44 %45 %47 %48 %50 %51\n%54 = OpCompositeExtract %30 %53 0\n%55 = OpCompositeExtract %30 %53 1\n%56 = OpCompositeExtract %30 %53 2\n%57 = OpCompositeExtract %30 %53 3\n%58 = OpFConvert %10 %54\n%59 = OpFConvert %10 %55\n%60 = OpFConvert %10 %56\n%61 = OpFConvert %10 %57\n%62 = OpFAdd %10 %58 %26\n%63 = OpFAdd %10 %59 %27\n%64 = OpFAdd %10 %60 %28\n%65 = OpFAdd %10 %61 %29\n%66 = OpCompositeExtract %30 %53 4\n%67 = OpCompositeExtract %30 %53 5\n%68 = OpCompositeExtract %30 %53 6\n%69 = OpCompositeExtract %30 %53 7\n%70 = OpFConvert %10 %66\n%71 = OpFConvert %10 %67\n%72 = OpFConvert %10 %68\n%73 = OpFConvert %10 %69\n%74 = OpFAdd %10 %62 %70\n%75 = OpFAdd %10 %63 %71\n%76 = OpFAdd %10 %64 %72\n%77 = OpFAdd %10 %65 %73\n%84 = OpBitcast %83 %17\n%86 = OpInBoundsAccessChain %85 %84 %16 %79\n%87 = OpLoad %80 %86 Aligned 16\n%88 = OpCompositeExtract %78 %87 0\n%89 = OpCompositeExtract %78 %87 1\n%91 = OpBitcast %83 %17\n%92 = OpInBoundsAccessChain %85 %91 %16 %90\n%93 = OpLoad %80 %92 Aligned 16\n%94 = OpCompositeExtract %78 %93 0\n%95 = OpCompositeExtract %78 %93 1\n%96 = OpConvertSToF %10 %88\n%97 = OpConvertSToF %10 %89\n%98 = OpConvertSToF %10 %94\n%99 = OpConvertSToF %10 %95\n%100 = OpFAdd %10 %74 %96\n%101 = OpFAdd %10 %75 %97\n%102 = OpFAdd %10 %76 %98\n%103 = OpFAdd %10 %77 %99\n%105 = OpAccessChain %104 %13 %16\nOpStore %105 %100\n%106 = OpAccessChain %104 %13 %31\nOpStore %106 %101\n%107 = OpAccessChain %104 %13 %79\nOpStore %107 %102\n%108 = OpAccessChain %104 %13 %90\nOpStore %108 %103\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-legacy-fp16-fp64.root-descriptor.sm60.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerUint642NonWriteCBVArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint642NonWriteCBVArray\n{\n    u64vec2 value[4096];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    PhysicalPointerFloat4NonWriteCBVArray _22 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    PhysicalPointerFloat4NonWriteCBVArray _31 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    PhysicalPointerFloat4NonWriteCBVArray _43 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    PhysicalPointerUint642NonWriteCBVArray _60 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    PhysicalPointerUint642NonWriteCBVArray _67 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    SV_Target.x = ((_31.value[1u].x + _22.value[0u].x) + _43.value[2u].x) + float(int64_t(_60.value[3u].x));\n    SV_Target.y = ((_31.value[1u].y + _22.value[0u].y) + _43.value[2u].y) + float(int64_t(_60.value[3u].y));\n    SV_Target.z = ((_31.value[1u].z + _22.value[0u].z) + _43.value[2u].z) + float(int64_t(_67.value[4u].x));\n    SV_Target.w = ((_31.value[1u].w + _22.value[0u].w) + _43.value[2u].w) + float(int64_t(_67.value[4u].y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %13 \"SV_Target\"\nOpName %20 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %20 0 \"value\"\nOpName %58 \"PhysicalPointerUint642NonWriteCBVArray\"\nOpMemberName %58 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %13 Location 0\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpMemberDecorate %20 0 NonWritable\nOpDecorate %34 RelaxedPrecision\nOpDecorate %35 RelaxedPrecision\nOpDecorate %36 RelaxedPrecision\nOpDecorate %37 RelaxedPrecision\nOpDecorate %46 RelaxedPrecision\nOpDecorate %47 RelaxedPrecision\nOpDecorate %48 RelaxedPrecision\nOpDecorate %49 RelaxedPrecision\nOpDecorate %57 ArrayStride 16\nOpMemberDecorate %58 0 Offset 0\nOpDecorate %58 Block\nOpMemberDecorate %58 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeVector %10 4\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%14 = OpTypePointer PushConstant %6\n%16 = OpConstant %5 0\n%18 = OpConstant %5 4096\n%19 = OpTypeArray %11 %18\n%20 = OpTypeStruct %19\n%21 = OpTypePointer PhysicalStorageBuffer %20\n%23 = OpTypePointer PhysicalStorageBuffer %11\n%30 = OpConstant %5 1\n%42 = OpConstant %5 2\n%54 = OpTypeInt 64 0\n%55 = OpConstant %5 3\n%56 = OpTypeVector %54 2\n%57 = OpTypeArray %56 %18\n%58 = OpTypeStruct %57\n%59 = OpTypePointer PhysicalStorageBuffer %58\n%61 = OpTypePointer PhysicalStorageBuffer %56\n%66 = OpConstant %5 4\n%80 = OpTypePointer Output %10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %85\n%85 = OpLabel\n%15 = OpAccessChain %14 %9 %16\n%17 = OpLoad %6 %15\n%22 = OpBitcast %21 %17\n%24 = OpInBoundsAccessChain %23 %22 %16 %16\n%25 = OpLoad %11 %24 Aligned 16\n%26 = OpCompositeExtract %10 %25 0\n%27 = OpCompositeExtract %10 %25 1\n%28 = OpCompositeExtract %10 %25 2\n%29 = OpCompositeExtract %10 %25 3\n%31 = OpBitcast %21 %17\n%32 = OpInBoundsAccessChain %23 %31 %16 %30\n%33 = OpLoad %11 %32 Aligned 16\n%34 = OpCompositeExtract %10 %33 0\n%35 = OpCompositeExtract %10 %33 1\n%36 = OpCompositeExtract %10 %33 2\n%37 = OpCompositeExtract %10 %33 3\n%38 = OpFAdd %10 %34 %26\n%39 = OpFAdd %10 %35 %27\n%40 = OpFAdd %10 %36 %28\n%41 = OpFAdd %10 %37 %29\n%43 = OpBitcast %21 %17\n%44 = OpInBoundsAccessChain %23 %43 %16 %42\n%45 = OpLoad %11 %44 Aligned 16\n%46 = OpCompositeExtract %10 %45 0\n%47 = OpCompositeExtract %10 %45 1\n%48 = OpCompositeExtract %10 %45 2\n%49 = OpCompositeExtract %10 %45 3\n%50 = OpFAdd %10 %38 %46\n%51 = OpFAdd %10 %39 %47\n%52 = OpFAdd %10 %40 %48\n%53 = OpFAdd %10 %41 %49\n%60 = OpBitcast %59 %17\n%62 = OpInBoundsAccessChain %61 %60 %16 %55\n%63 = OpLoad %56 %62 Aligned 16\n%64 = OpCompositeExtract %54 %63 0\n%65 = OpCompositeExtract %54 %63 1\n%67 = OpBitcast %59 %17\n%68 = OpInBoundsAccessChain %61 %67 %16 %66\n%69 = OpLoad %56 %68 Aligned 16\n%70 = OpCompositeExtract %54 %69 0\n%71 = OpCompositeExtract %54 %69 1\n%72 = OpConvertSToF %10 %64\n%73 = OpConvertSToF %10 %65\n%74 = OpConvertSToF %10 %70\n%75 = OpConvertSToF %10 %71\n%76 = OpFAdd %10 %50 %72\n%77 = OpFAdd %10 %51 %73\n%78 = OpFAdd %10 %52 %74\n%79 = OpFAdd %10 %53 %75\n%81 = OpAccessChain %80 %13 %16\nOpStore %81 %76\n%82 = OpAccessChain %80 %13 %30\nOpStore %82 %77\n%83 = OpAccessChain %80 %13 %42\nOpStore %83 %78\n%84 = OpAccessChain %80 %13 %55\nOpStore %84 %79\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-legacy-fp16-fp64.root-descriptor.sm60.native-fp16.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerUint642NonWriteCBVArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint642NonWriteCBVArray\n{\n    u64vec2 value[4096];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    PhysicalPointerFloat4NonWriteCBVArray _22 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    f16vec4 _36 = f16vec4(PhysicalPointerFloat4NonWriteCBVArray(registers._m0).value[1u]);\n    f16vec4 _53 = f16vec4(PhysicalPointerFloat4NonWriteCBVArray(registers._m0).value[2u]);\n    PhysicalPointerUint642NonWriteCBVArray _72 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    PhysicalPointerUint642NonWriteCBVArray _79 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    SV_Target.x = ((float(_36.x) + _22.value[0u].x) + float(_53.x)) + float(int64_t(_72.value[3u].x));\n    SV_Target.y = ((float(_36.y) + _22.value[0u].y) + float(_53.y)) + float(int64_t(_72.value[3u].y));\n    SV_Target.z = ((float(_36.z) + _22.value[0u].z) + float(_53.z)) + float(int64_t(_79.value[4u].x));\n    SV_Target.w = ((float(_36.w) + _22.value[0u].w) + float(_53.w)) + float(int64_t(_79.value[4u].y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int64\nOpCapability DenormPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %13 \"SV_Target\"\nOpName %20 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %20 0 \"value\"\nOpName %70 \"PhysicalPointerUint642NonWriteCBVArray\"\nOpMemberName %70 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %13 Location 0\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpMemberDecorate %20 0 NonWritable\nOpDecorate %69 ArrayStride 16\nOpMemberDecorate %70 0 Offset 0\nOpDecorate %70 Block\nOpMemberDecorate %70 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeVector %10 4\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%14 = OpTypePointer PushConstant %6\n%16 = OpConstant %5 0\n%18 = OpConstant %5 4096\n%19 = OpTypeArray %11 %18\n%20 = OpTypeStruct %19\n%21 = OpTypePointer PhysicalStorageBuffer %20\n%23 = OpTypePointer PhysicalStorageBuffer %11\n%30 = OpConstant %5 1\n%34 = OpTypeFloat 16\n%35 = OpTypeVector %34 4\n%49 = OpConstant %5 2\n%66 = OpTypeInt 64 0\n%67 = OpConstant %5 3\n%68 = OpTypeVector %66 2\n%69 = OpTypeArray %68 %18\n%70 = OpTypeStruct %69\n%71 = OpTypePointer PhysicalStorageBuffer %70\n%73 = OpTypePointer PhysicalStorageBuffer %68\n%78 = OpConstant %5 4\n%92 = OpTypePointer Output %10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %97\n%97 = OpLabel\n%15 = OpAccessChain %14 %9 %16\n%17 = OpLoad %6 %15\n%22 = OpBitcast %21 %17\n%24 = OpInBoundsAccessChain %23 %22 %16 %16\n%25 = OpLoad %11 %24 Aligned 16\n%26 = OpCompositeExtract %10 %25 0\n%27 = OpCompositeExtract %10 %25 1\n%28 = OpCompositeExtract %10 %25 2\n%29 = OpCompositeExtract %10 %25 3\n%31 = OpBitcast %21 %17\n%32 = OpInBoundsAccessChain %23 %31 %16 %30\n%33 = OpLoad %11 %32 Aligned 16\n%36 = OpFConvert %35 %33\n%37 = OpCompositeExtract %34 %36 0\n%38 = OpCompositeExtract %34 %36 1\n%39 = OpCompositeExtract %34 %36 2\n%40 = OpCompositeExtract %34 %36 3\n%41 = OpFConvert %10 %37\n%42 = OpFConvert %10 %38\n%43 = OpFConvert %10 %39\n%44 = OpFConvert %10 %40\n%45 = OpFAdd %10 %41 %26\n%46 = OpFAdd %10 %42 %27\n%47 = OpFAdd %10 %43 %28\n%48 = OpFAdd %10 %44 %29\n%50 = OpBitcast %21 %17\n%51 = OpInBoundsAccessChain %23 %50 %16 %49\n%52 = OpLoad %11 %51 Aligned 16\n%53 = OpFConvert %35 %52\n%54 = OpCompositeExtract %34 %53 0\n%55 = OpCompositeExtract %34 %53 1\n%56 = OpCompositeExtract %34 %53 2\n%57 = OpCompositeExtract %34 %53 3\n%58 = OpFConvert %10 %54\n%59 = OpFConvert %10 %55\n%60 = OpFConvert %10 %56\n%61 = OpFConvert %10 %57\n%62 = OpFAdd %10 %45 %58\n%63 = OpFAdd %10 %46 %59\n%64 = OpFAdd %10 %47 %60\n%65 = OpFAdd %10 %48 %61\n%72 = OpBitcast %71 %17\n%74 = OpInBoundsAccessChain %73 %72 %16 %67\n%75 = OpLoad %68 %74 Aligned 16\n%76 = OpCompositeExtract %66 %75 0\n%77 = OpCompositeExtract %66 %75 1\n%79 = OpBitcast %71 %17\n%80 = OpInBoundsAccessChain %73 %79 %16 %78\n%81 = OpLoad %68 %80 Aligned 16\n%82 = OpCompositeExtract %66 %81 0\n%83 = OpCompositeExtract %66 %81 1\n%84 = OpConvertSToF %10 %76\n%85 = OpConvertSToF %10 %77\n%86 = OpConvertSToF %10 %82\n%87 = OpConvertSToF %10 %83\n%88 = OpFAdd %10 %62 %84\n%89 = OpFAdd %10 %63 %85\n%90 = OpFAdd %10 %64 %86\n%91 = OpFAdd %10 %65 %87\n%93 = OpAccessChain %92 %13 %16\nOpStore %93 %88\n%94 = OpAccessChain %92 %13 %30\nOpStore %94 %89\n%95 = OpAccessChain %92 %13 %49\nOpStore %95 %90\n%96 = OpAccessChain %92 %13 %67\nOpStore %96 %91\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-legacy-fp16-fp64.sm60.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    u64vec2 _m0[5];\n} _12;\n\nlayout(set = 0, binding = 0, std140) uniform _16_18\n{\n    vec4 _m0[5];\n} _18;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = ((_18._m0[1u].x + _18._m0[0u].x) + _18._m0[2u].x) + float(int64_t(_12._m0[3u].x));\n    SV_Target.y = ((_18._m0[1u].y + _18._m0[0u].y) + _18._m0[2u].y) + float(int64_t(_12._m0[3u].y));\n    SV_Target.z = ((_18._m0[1u].z + _18._m0[0u].z) + _18._m0[2u].z) + float(int64_t(_12._m0[4u].x));\n    SV_Target.w = ((_18._m0[1u].w + _18._m0[0u].w) + _18._m0[2u].w) + float(int64_t(_12._m0[4u].y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 77\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %20\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"\"\nOpName %20 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %20 Location 0\nOpDecorate %32 RelaxedPrecision\nOpDecorate %33 RelaxedPrecision\nOpDecorate %34 RelaxedPrecision\nOpDecorate %35 RelaxedPrecision\nOpDecorate %43 RelaxedPrecision\nOpDecorate %44 RelaxedPrecision\nOpDecorate %45 RelaxedPrecision\nOpDecorate %46 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 5\n%7 = OpTypeInt 64 0\n%8 = OpTypeVector %7 2\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeArray %14 %6\n%16 = OpTypeStruct %15\n%17 = OpTypePointer Uniform %16\n%18 = OpVariable %17 Uniform\n%19 = OpTypePointer Output %14\n%20 = OpVariable %19 Output\n%21 = OpConstant %5 0\n%22 = OpTypePointer Uniform %14\n%29 = OpConstant %5 1\n%40 = OpConstant %5 2\n%51 = OpConstant %5 3\n%52 = OpTypePointer Uniform %8\n%57 = OpConstant %5 4\n%70 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%23 = OpAccessChain %22 %18 %21 %21\n%24 = OpLoad %14 %23\n%25 = OpCompositeExtract %13 %24 0\n%26 = OpCompositeExtract %13 %24 1\n%27 = OpCompositeExtract %13 %24 2\n%28 = OpCompositeExtract %13 %24 3\n%30 = OpAccessChain %22 %18 %21 %29\n%31 = OpLoad %14 %30\n%32 = OpCompositeExtract %13 %31 0\n%33 = OpCompositeExtract %13 %31 1\n%34 = OpCompositeExtract %13 %31 2\n%35 = OpCompositeExtract %13 %31 3\n%36 = OpFAdd %13 %32 %25\n%37 = OpFAdd %13 %33 %26\n%38 = OpFAdd %13 %34 %27\n%39 = OpFAdd %13 %35 %28\n%41 = OpAccessChain %22 %18 %21 %40\n%42 = OpLoad %14 %41\n%43 = OpCompositeExtract %13 %42 0\n%44 = OpCompositeExtract %13 %42 1\n%45 = OpCompositeExtract %13 %42 2\n%46 = OpCompositeExtract %13 %42 3\n%47 = OpFAdd %13 %36 %43\n%48 = OpFAdd %13 %37 %44\n%49 = OpFAdd %13 %38 %45\n%50 = OpFAdd %13 %39 %46\n%53 = OpAccessChain %52 %12 %21 %51\n%54 = OpLoad %8 %53\n%55 = OpCompositeExtract %7 %54 0\n%56 = OpCompositeExtract %7 %54 1\n%58 = OpAccessChain %52 %12 %21 %57\n%59 = OpLoad %8 %58\n%60 = OpCompositeExtract %7 %59 0\n%61 = OpCompositeExtract %7 %59 1\n%62 = OpConvertSToF %13 %55\n%63 = OpConvertSToF %13 %56\n%64 = OpConvertSToF %13 %60\n%65 = OpConvertSToF %13 %61\n%66 = OpFAdd %13 %47 %62\n%67 = OpFAdd %13 %48 %63\n%68 = OpFAdd %13 %49 %64\n%69 = OpFAdd %13 %50 %65\n%71 = OpAccessChain %70 %20 %21\nOpStore %71 %66\n%72 = OpAccessChain %70 %20 %29\nOpStore %72 %67\n%73 = OpAccessChain %70 %20 %40\nOpStore %73 %68\n%74 = OpAccessChain %70 %20 %51\nOpStore %74 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv-legacy-fp16-fp64.sm60.native-fp16.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    u64vec2 _m0[5];\n} _12;\n\nlayout(set = 0, binding = 0, std140) uniform _16_18\n{\n    vec4 _m0[5];\n} _18;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    f16vec4 _34 = f16vec4(_18._m0[1u]);\n    f16vec4 _50 = f16vec4(_18._m0[2u]);\n    SV_Target.x = ((float(_34.x) + _18._m0[0u].x) + float(_50.x)) + float(int64_t(_12._m0[3u].x));\n    SV_Target.y = ((float(_34.y) + _18._m0[0u].y) + float(_50.y)) + float(int64_t(_12._m0[3u].y));\n    SV_Target.z = ((float(_34.z) + _18._m0[0u].z) + float(_50.z)) + float(int64_t(_12._m0[4u].x));\n    SV_Target.w = ((float(_34.w) + _18._m0[0u].w) + float(_50.w)) + float(int64_t(_12._m0[4u].y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 89\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %20\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"\"\nOpName %20 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %20 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 5\n%7 = OpTypeInt 64 0\n%8 = OpTypeVector %7 2\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeArray %14 %6\n%16 = OpTypeStruct %15\n%17 = OpTypePointer Uniform %16\n%18 = OpVariable %17 Uniform\n%19 = OpTypePointer Output %14\n%20 = OpVariable %19 Output\n%21 = OpConstant %5 0\n%22 = OpTypePointer Uniform %14\n%29 = OpConstant %5 1\n%32 = OpTypeFloat 16\n%33 = OpTypeVector %32 4\n%47 = OpConstant %5 2\n%63 = OpConstant %5 3\n%64 = OpTypePointer Uniform %8\n%69 = OpConstant %5 4\n%82 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %87\n%87 = OpLabel\n%23 = OpAccessChain %22 %18 %21 %21\n%24 = OpLoad %14 %23\n%25 = OpCompositeExtract %13 %24 0\n%26 = OpCompositeExtract %13 %24 1\n%27 = OpCompositeExtract %13 %24 2\n%28 = OpCompositeExtract %13 %24 3\n%30 = OpAccessChain %22 %18 %21 %29\n%31 = OpLoad %14 %30\n%34 = OpFConvert %33 %31\n%35 = OpCompositeExtract %32 %34 0\n%36 = OpCompositeExtract %32 %34 1\n%37 = OpCompositeExtract %32 %34 2\n%38 = OpCompositeExtract %32 %34 3\n%39 = OpFConvert %13 %35\n%40 = OpFConvert %13 %36\n%41 = OpFConvert %13 %37\n%42 = OpFConvert %13 %38\n%43 = OpFAdd %13 %39 %25\n%44 = OpFAdd %13 %40 %26\n%45 = OpFAdd %13 %41 %27\n%46 = OpFAdd %13 %42 %28\n%48 = OpAccessChain %22 %18 %21 %47\n%49 = OpLoad %14 %48\n%50 = OpFConvert %33 %49\n%51 = OpCompositeExtract %32 %50 0\n%52 = OpCompositeExtract %32 %50 1\n%53 = OpCompositeExtract %32 %50 2\n%54 = OpCompositeExtract %32 %50 3\n%55 = OpFConvert %13 %51\n%56 = OpFConvert %13 %52\n%57 = OpFConvert %13 %53\n%58 = OpFConvert %13 %54\n%59 = OpFAdd %13 %43 %55\n%60 = OpFAdd %13 %44 %56\n%61 = OpFAdd %13 %45 %57\n%62 = OpFAdd %13 %46 %58\n%65 = OpAccessChain %64 %12 %21 %63\n%66 = OpLoad %8 %65\n%67 = OpCompositeExtract %7 %66 0\n%68 = OpCompositeExtract %7 %66 1\n%70 = OpAccessChain %64 %12 %21 %69\n%71 = OpLoad %8 %70\n%72 = OpCompositeExtract %7 %71 0\n%73 = OpCompositeExtract %7 %71 1\n%74 = OpConvertSToF %13 %67\n%75 = OpConvertSToF %13 %68\n%76 = OpConvertSToF %13 %72\n%77 = OpConvertSToF %13 %73\n%78 = OpFAdd %13 %59 %74\n%79 = OpFAdd %13 %60 %75\n%80 = OpFAdd %13 %61 %76\n%81 = OpFAdd %13 %62 %77\n%83 = OpAccessChain %82 %20 %21\nOpStore %83 %78\n%84 = OpAccessChain %82 %20 %29\nOpStore %84 %79\n%85 = OpAccessChain %82 %20 %47\nOpStore %85 %80\n%86 = OpAccessChain %82 %20 %63\nOpStore %86 %81\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.bindless.root-constant.cbv-as-ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 5, binding = 0, std430) readonly buffer BindlessCBV\n{\n    vec4 _m0[4096];\n} _16[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _27 = registers._m5 + 3u;\n    uint _32 = registers._m5 + 5u;\n    uint _70 = registers._m5 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u);\n    uint _86 = registers._m5 + (INDEX + 100u);\n    SV_Target.x = ((_16[_32]._m0[0u].x + _16[_27]._m0[0u].x) + _16[_70]._m0[0u].x) + _16[nonuniformEXT(_86)]._m0[0u].x;\n    SV_Target.y = ((_16[_32]._m0[0u].y + _16[_27]._m0[0u].y) + _16[_70]._m0[0u].y) + _16[nonuniformEXT(_86)]._m0[0u].y;\n    SV_Target.z = ((_16[_32]._m0[0u].z + _16[_27]._m0[0u].z) + _16[_70]._m0[0u].z) + _16[nonuniformEXT(_86)]._m0[0u].z;\n    SV_Target.w = ((_16[_32]._m0[0u].w + _16[_27]._m0[0u].w) + _16[_70]._m0[0u].w) + _16[nonuniformEXT(_86)]._m0[0u].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 106\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %18 %20\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %13 \"BindlessCBV\"\nOpName %18 \"INDEX\"\nOpName %20 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 ArrayStride 16\nOpDecorate %13 Block\nOpMemberDecorate %13 0 NonWritable\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %16 DescriptorSet 5\nOpDecorate %16 Binding 0\nOpDecorate %18 Flat\nOpDecorate %18 Location 0\nOpDecorate %20 Location 0\nOpDecorate %86 NonUniform\nOpDecorate %83 NonUniform\nOpDecorate %87 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpConstant %5 4096\n%12 = OpTypeArray %10 %11\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Output %10\n%20 = OpVariable %19 Output\n%21 = OpTypePointer StorageBuffer %13\n%23 = OpTypePointer PushConstant %5\n%25 = OpConstant %5 5\n%28 = OpConstant %5 3\n%34 = OpConstant %5 0\n%35 = OpTypePointer StorageBuffer %10\n%53 = OpConstant %5 4\n%58 = OpConstant %5 6\n%61 = OpConstant %5 7\n%63 = OpTypeVector %5 4\n%82 = OpConstant %5 100\n%97 = OpTypePointer Output %9\n%100 = OpConstant %5 1\n%102 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %104\n%104 = OpLabel\n%24 = OpAccessChain %23 %8 %25\n%26 = OpLoad %5 %24\n%27 = OpIAdd %5 %26 %28\n%22 = OpAccessChain %21 %16 %27\n%30 = OpAccessChain %23 %8 %25\n%31 = OpLoad %5 %30\n%32 = OpIAdd %5 %31 %25\n%29 = OpAccessChain %21 %16 %32\n%33 = OpLoad %5 %18\n%36 = OpAccessChain %35 %22 %34 %34\n%37 = OpLoad %10 %36\n%38 = OpCompositeExtract %9 %37 0\n%39 = OpCompositeExtract %9 %37 1\n%40 = OpCompositeExtract %9 %37 2\n%41 = OpCompositeExtract %9 %37 3\n%42 = OpAccessChain %35 %29 %34 %34\n%43 = OpLoad %10 %42\n%44 = OpCompositeExtract %9 %43 0\n%45 = OpCompositeExtract %9 %43 1\n%46 = OpCompositeExtract %9 %43 2\n%47 = OpCompositeExtract %9 %43 3\n%48 = OpFAdd %9 %44 %38\n%49 = OpFAdd %9 %45 %39\n%50 = OpFAdd %9 %46 %40\n%51 = OpFAdd %9 %47 %41\n%52 = OpAccessChain %23 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %23 %8 %25\n%56 = OpLoad %5 %55\n%57 = OpAccessChain %23 %8 %58\n%59 = OpLoad %5 %57\n%60 = OpAccessChain %23 %8 %61\n%62 = OpLoad %5 %60\n%64 = OpCompositeConstruct %63 %54 %56 %59 %62\n%65 = OpCompositeExtract %5 %64 0\n%66 = OpIAdd %5 %65 %53\n%68 = OpAccessChain %23 %8 %25\n%69 = OpLoad %5 %68\n%70 = OpIAdd %5 %69 %66\n%67 = OpAccessChain %21 %16 %70\n%71 = OpAccessChain %35 %67 %34 %34\n%72 = OpLoad %10 %71\n%73 = OpCompositeExtract %9 %72 0\n%74 = OpCompositeExtract %9 %72 1\n%75 = OpCompositeExtract %9 %72 2\n%76 = OpCompositeExtract %9 %72 3\n%77 = OpFAdd %9 %48 %73\n%78 = OpFAdd %9 %49 %74\n%79 = OpFAdd %9 %50 %75\n%80 = OpFAdd %9 %51 %76\n%81 = OpIAdd %5 %33 %82\n%84 = OpAccessChain %23 %8 %25\n%85 = OpLoad %5 %84\n%86 = OpIAdd %5 %85 %81\n%83 = OpAccessChain %21 %16 %86\n%87 = OpAccessChain %35 %83 %34 %34\n%88 = OpLoad %10 %87\n%89 = OpCompositeExtract %9 %88 0\n%90 = OpCompositeExtract %9 %88 1\n%91 = OpCompositeExtract %9 %88 2\n%92 = OpCompositeExtract %9 %88 3\n%93 = OpFAdd %9 %77 %89\n%94 = OpFAdd %9 %78 %90\n%95 = OpFAdd %9 %79 %91\n%96 = OpFAdd %9 %80 %92\n%98 = OpAccessChain %97 %20 %34\nOpStore %98 %93\n%99 = OpAccessChain %97 %20 %100\nOpStore %99 %94\n%101 = OpAccessChain %97 %20 %102\nOpStore %101 %95\n%103 = OpAccessChain %97 %20 %28\nOpStore %103 %96\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _16[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _27 = registers._m5 + 3u;\n    uint _32 = registers._m5 + 5u;\n    uint _70 = registers._m5 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u);\n    uint _86 = registers._m5 + (INDEX + 100u);\n    SV_Target.x = ((_16[_32]._m0[0u].x + _16[_27]._m0[0u].x) + _16[_70]._m0[0u].x) + _16[nonuniformEXT(_86)]._m0[0u].x;\n    SV_Target.y = ((_16[_32]._m0[0u].y + _16[_27]._m0[0u].y) + _16[_70]._m0[0u].y) + _16[nonuniformEXT(_86)]._m0[0u].y;\n    SV_Target.z = ((_16[_32]._m0[0u].z + _16[_27]._m0[0u].z) + _16[_70]._m0[0u].z) + _16[nonuniformEXT(_86)]._m0[0u].z;\n    SV_Target.w = ((_16[_32]._m0[0u].w + _16[_27]._m0[0u].w) + _16[_70]._m0[0u].w) + _16[nonuniformEXT(_86)]._m0[0u].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 106\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %18 %20\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %13 \"BindlessCBV\"\nOpName %18 \"INDEX\"\nOpName %20 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 ArrayStride 16\nOpDecorate %13 Block\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %16 DescriptorSet 5\nOpDecorate %16 Binding 0\nOpDecorate %18 Flat\nOpDecorate %18 Location 0\nOpDecorate %20 Location 0\nOpDecorate %86 NonUniform\nOpDecorate %83 NonUniform\nOpDecorate %87 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpConstant %5 4096\n%12 = OpTypeArray %10 %11\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Output %10\n%20 = OpVariable %19 Output\n%21 = OpTypePointer Uniform %13\n%23 = OpTypePointer PushConstant %5\n%25 = OpConstant %5 5\n%28 = OpConstant %5 3\n%34 = OpConstant %5 0\n%35 = OpTypePointer Uniform %10\n%53 = OpConstant %5 4\n%58 = OpConstant %5 6\n%61 = OpConstant %5 7\n%63 = OpTypeVector %5 4\n%82 = OpConstant %5 100\n%97 = OpTypePointer Output %9\n%100 = OpConstant %5 1\n%102 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %104\n%104 = OpLabel\n%24 = OpAccessChain %23 %8 %25\n%26 = OpLoad %5 %24\n%27 = OpIAdd %5 %26 %28\n%22 = OpAccessChain %21 %16 %27\n%30 = OpAccessChain %23 %8 %25\n%31 = OpLoad %5 %30\n%32 = OpIAdd %5 %31 %25\n%29 = OpAccessChain %21 %16 %32\n%33 = OpLoad %5 %18\n%36 = OpAccessChain %35 %22 %34 %34\n%37 = OpLoad %10 %36\n%38 = OpCompositeExtract %9 %37 0\n%39 = OpCompositeExtract %9 %37 1\n%40 = OpCompositeExtract %9 %37 2\n%41 = OpCompositeExtract %9 %37 3\n%42 = OpAccessChain %35 %29 %34 %34\n%43 = OpLoad %10 %42\n%44 = OpCompositeExtract %9 %43 0\n%45 = OpCompositeExtract %9 %43 1\n%46 = OpCompositeExtract %9 %43 2\n%47 = OpCompositeExtract %9 %43 3\n%48 = OpFAdd %9 %44 %38\n%49 = OpFAdd %9 %45 %39\n%50 = OpFAdd %9 %46 %40\n%51 = OpFAdd %9 %47 %41\n%52 = OpAccessChain %23 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %23 %8 %25\n%56 = OpLoad %5 %55\n%57 = OpAccessChain %23 %8 %58\n%59 = OpLoad %5 %57\n%60 = OpAccessChain %23 %8 %61\n%62 = OpLoad %5 %60\n%64 = OpCompositeConstruct %63 %54 %56 %59 %62\n%65 = OpCompositeExtract %5 %64 0\n%66 = OpIAdd %5 %65 %53\n%68 = OpAccessChain %23 %8 %25\n%69 = OpLoad %5 %68\n%70 = OpIAdd %5 %69 %66\n%67 = OpAccessChain %21 %16 %70\n%71 = OpAccessChain %35 %67 %34 %34\n%72 = OpLoad %10 %71\n%73 = OpCompositeExtract %9 %72 0\n%74 = OpCompositeExtract %9 %72 1\n%75 = OpCompositeExtract %9 %72 2\n%76 = OpCompositeExtract %9 %72 3\n%77 = OpFAdd %9 %48 %73\n%78 = OpFAdd %9 %49 %74\n%79 = OpFAdd %9 %50 %75\n%80 = OpFAdd %9 %51 %76\n%81 = OpIAdd %5 %33 %82\n%84 = OpAccessChain %23 %8 %25\n%85 = OpLoad %5 %84\n%86 = OpIAdd %5 %85 %81\n%83 = OpAccessChain %21 %16 %86\n%87 = OpAccessChain %35 %83 %34 %34\n%88 = OpLoad %10 %87\n%89 = OpCompositeExtract %9 %88 0\n%90 = OpCompositeExtract %9 %88 1\n%91 = OpCompositeExtract %9 %88 2\n%92 = OpCompositeExtract %9 %88 3\n%93 = OpFAdd %9 %77 %89\n%94 = OpFAdd %9 %78 %90\n%95 = OpFAdd %9 %79 %91\n%96 = OpFAdd %9 %80 %92\n%98 = OpAccessChain %97 %20 %34\nOpStore %98 %93\n%99 = OpAccessChain %97 %20 %100\nOpStore %99 %94\n%101 = OpAccessChain %97 %20 %102\nOpStore %101 %95\n%103 = OpAccessChain %97 %20 %28\nOpStore %103 %96\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.frag",
    "content": "#version 460\n\nlayout(set = 2, binding = 1, std140) uniform _10_12\n{\n    vec4 _m0[1];\n} _12;\n\nlayout(set = 2, binding = 2, std140) uniform _14_16\n{\n    vec4 _m0[1];\n} _16;\n\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    uvec4 _31 = floatBitsToUint(_12._m0[0u]);\n    uvec4 _35 = floatBitsToUint(_16._m0[0u]);\n    SV_Target = ((_16._m0[0u].x + _12._m0[0u].x) + float(_35.y + _31.y)) + float(int(_35.z + _31.z));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"\"\nOpName %18 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 2\nOpDecorate %12 Binding 1\nOpDecorate %13 ArrayStride 16\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 2\nOpDecorate %16 Binding 2\nOpDecorate %18 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeArray %8 %6\n%14 = OpTypeStruct %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypePointer Output %7\n%18 = OpVariable %17 Output\n%19 = OpConstant %5 0\n%20 = OpTypePointer Uniform %8\n%30 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %45\n%45 = OpLabel\n%21 = OpAccessChain %20 %12 %19 %19\n%22 = OpLoad %8 %21\n%23 = OpCompositeExtract %7 %22 0\n%24 = OpAccessChain %20 %16 %19 %19\n%25 = OpLoad %8 %24\n%26 = OpCompositeExtract %7 %25 0\n%27 = OpFAdd %7 %26 %23\n%28 = OpAccessChain %20 %12 %19 %19\n%29 = OpLoad %8 %28\n%31 = OpBitcast %30 %29\n%32 = OpCompositeExtract %5 %31 1\n%33 = OpAccessChain %20 %16 %19 %19\n%34 = OpLoad %8 %33\n%35 = OpBitcast %30 %34\n%36 = OpCompositeExtract %5 %35 1\n%37 = OpIAdd %5 %36 %32\n%38 = OpConvertUToF %7 %37\n%39 = OpFAdd %7 %27 %38\n%40 = OpCompositeExtract %5 %31 2\n%41 = OpCompositeExtract %5 %35 2\n%42 = OpIAdd %5 %41 %40\n%43 = OpConvertSToF %7 %42\n%44 = OpFAdd %7 %39 %43\nOpStore %18 %44\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.no-legacy-cbuf-layout.bindless.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct CBVComposite16x8\n{\n    float16_t _m0;\n    float16_t _m1;\n    float16_t _m2;\n    float16_t _m3;\n    float16_t _m4;\n    float16_t _m5;\n    float16_t _m6;\n    float16_t _m7;\n};\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    u64vec2 _m0[4096];\n} _16[];\n\nlayout(set = 5, binding = 0, std140) uniform _20_23\n{\n    vec4 _m0[4096];\n} _23[];\n\nlayout(set = 5, binding = 0, std140) uniform _27_30\n{\n    dvec2 _m0[4096];\n} _30[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _39 = registers._m5 + 2u;\n    uint _45 = registers._m5 + 1u;\n    f16vec2 _70 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].x));\n    f16vec2 _73 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].y));\n    f16vec2 _76 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].z));\n    f16vec2 _79 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].w));\n    CBVComposite16x8 _83 = CBVComposite16x8(_70.x, _70.y, _73.x, _73.y, _76.x, _76.y, _79.x, _79.y);\n    SV_Target.x = (((float(_83._m0) + _23[registers._m5]._m0[0u].x) + float(int64_t(_16[registers._m5]._m0[2u].x))) + _23[_45]._m0[0u].x) + float(_30[_39]._m0[0u].x);\n    SV_Target.y = (((float(_83._m1) + _23[registers._m5]._m0[0u].y) + float(int64_t(_16[registers._m5]._m0[2u].y))) + _23[_45]._m0[0u].y) + float(_30[_39]._m0[0u].y);\n    SV_Target.z = (((float(_83._m2) + _23[registers._m5]._m0[0u].z) + float(int64_t(_16[registers._m5]._m0[3u].x))) + _23[_45]._m0[0u].z) + float(_30[_39]._m0[1u].x);\n    SV_Target.w = (((float(_83._m3) + _23[registers._m5]._m0[0u].w) + float(int64_t(_16[registers._m5]._m0[3u].y))) + _23[_45]._m0[0u].w) + float(_30[_39]._m0[1u].y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 148\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Float64\nOpCapability Int64\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %32\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %13 \"BindlessCBV\"\nOpName %20 \"BindlessCBV\"\nOpName %27 \"BindlessCBV\"\nOpName %32 \"SV_Target\"\nOpName %82 \"CBVComposite16x8\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 ArrayStride 16\nOpDecorate %13 Block\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %16 DescriptorSet 5\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 16\nOpDecorate %20 Block\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %23 DescriptorSet 5\nOpDecorate %23 Binding 0\nOpDecorate %26 ArrayStride 16\nOpDecorate %27 Block\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %30 DescriptorSet 5\nOpDecorate %30 Binding 0\nOpDecorate %32 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeInt 64 0\n%10 = OpTypeVector %9 2\n%11 = OpConstant %5 4096\n%12 = OpTypeArray %10 %11\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 4\n%19 = OpTypeArray %18 %11\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer Uniform %21\n%23 = OpVariable %22 Uniform\n%24 = OpTypeFloat 64\n%25 = OpTypeVector %24 2\n%26 = OpTypeArray %25 %11\n%27 = OpTypeStruct %26\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%31 = OpTypePointer Output %18\n%32 = OpVariable %31 Output\n%33 = OpTypePointer Uniform %27\n%35 = OpTypePointer PushConstant %5\n%37 = OpConstant %5 5\n%40 = OpConstant %5 2\n%41 = OpTypePointer Uniform %20\n%46 = OpConstant %5 1\n%47 = OpTypePointer Uniform %13\n%54 = OpConstant %5 0\n%55 = OpTypePointer Uniform %18\n%62 = OpTypeFloat 16\n%65 = OpTypeVector %62 2\n%82 = OpTypeStruct %62 %62 %62 %62 %62 %62 %62 %62\n%96 = OpTypePointer Uniform %10\n%101 = OpConstant %5 3\n%124 = OpTypePointer Uniform %25\n%141 = OpTypePointer Output %17\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %146\n%146 = OpLabel\n%36 = OpAccessChain %35 %8 %37\n%38 = OpLoad %5 %36\n%39 = OpIAdd %5 %38 %40\n%34 = OpAccessChain %33 %30 %39\n%43 = OpAccessChain %35 %8 %37\n%44 = OpLoad %5 %43\n%45 = OpIAdd %5 %44 %46\n%42 = OpAccessChain %41 %23 %45\n%49 = OpAccessChain %35 %8 %37\n%50 = OpLoad %5 %49\n%48 = OpAccessChain %47 %16 %50\n%52 = OpAccessChain %35 %8 %37\n%53 = OpLoad %5 %52\n%51 = OpAccessChain %41 %23 %53\n%56 = OpAccessChain %55 %51 %54 %54\n%57 = OpLoad %18 %56\n%58 = OpCompositeExtract %17 %57 0\n%59 = OpCompositeExtract %17 %57 1\n%60 = OpCompositeExtract %17 %57 2\n%61 = OpCompositeExtract %17 %57 3\n%63 = OpAccessChain %55 %51 %54 %46\n%64 = OpLoad %18 %63\n%66 = OpCompositeExtract %17 %64 0\n%67 = OpCompositeExtract %17 %64 1\n%68 = OpCompositeExtract %17 %64 2\n%69 = OpCompositeExtract %17 %64 3\n%70 = OpBitcast %65 %66\n%71 = OpCompositeExtract %62 %70 0\n%72 = OpCompositeExtract %62 %70 1\n%73 = OpBitcast %65 %67\n%74 = OpCompositeExtract %62 %73 0\n%75 = OpCompositeExtract %62 %73 1\n%76 = OpBitcast %65 %68\n%77 = OpCompositeExtract %62 %76 0\n%78 = OpCompositeExtract %62 %76 1\n%79 = OpBitcast %65 %69\n%80 = OpCompositeExtract %62 %79 0\n%81 = OpCompositeExtract %62 %79 1\n%83 = OpCompositeConstruct %82 %71 %72 %74 %75 %77 %78 %80 %81\n%84 = OpCompositeExtract %62 %83 0\n%85 = OpCompositeExtract %62 %83 1\n%86 = OpCompositeExtract %62 %83 2\n%87 = OpCompositeExtract %62 %83 3\n%88 = OpFConvert %17 %84\n%89 = OpFConvert %17 %85\n%90 = OpFConvert %17 %86\n%91 = OpFConvert %17 %87\n%92 = OpFAdd %17 %88 %58\n%93 = OpFAdd %17 %89 %59\n%94 = OpFAdd %17 %90 %60\n%95 = OpFAdd %17 %91 %61\n%97 = OpAccessChain %96 %48 %54 %40\n%98 = OpLoad %10 %97\n%99 = OpCompositeExtract %9 %98 0\n%100 = OpCompositeExtract %9 %98 1\n%102 = OpAccessChain %96 %48 %54 %101\n%103 = OpLoad %10 %102\n%104 = OpCompositeExtract %9 %103 0\n%105 = OpCompositeExtract %9 %103 1\n%106 = OpConvertSToF %17 %99\n%107 = OpConvertSToF %17 %100\n%108 = OpConvertSToF %17 %104\n%109 = OpConvertSToF %17 %105\n%110 = OpFAdd %17 %92 %106\n%111 = OpFAdd %17 %93 %107\n%112 = OpFAdd %17 %94 %108\n%113 = OpFAdd %17 %95 %109\n%114 = OpAccessChain %55 %42 %54 %54\n%115 = OpLoad %18 %114\n%116 = OpCompositeExtract %17 %115 0\n%117 = OpCompositeExtract %17 %115 1\n%118 = OpCompositeExtract %17 %115 2\n%119 = OpCompositeExtract %17 %115 3\n%120 = OpFAdd %17 %110 %116\n%121 = OpFAdd %17 %111 %117\n%122 = OpFAdd %17 %112 %118\n%123 = OpFAdd %17 %113 %119\n%125 = OpAccessChain %124 %34 %54 %54\n%126 = OpLoad %25 %125\n%127 = OpCompositeExtract %24 %126 0\n%128 = OpCompositeExtract %24 %126 1\n%129 = OpAccessChain %124 %34 %54 %46\n%130 = OpLoad %25 %129\n%131 = OpCompositeExtract %24 %130 0\n%132 = OpCompositeExtract %24 %130 1\n%133 = OpFConvert %17 %127\n%134 = OpFConvert %17 %128\n%135 = OpFConvert %17 %131\n%136 = OpFConvert %17 %132\n%137 = OpFAdd %17 %120 %133\n%138 = OpFAdd %17 %121 %134\n%139 = OpFAdd %17 %122 %135\n%140 = OpFAdd %17 %123 %136\n%142 = OpAccessChain %141 %32 %54\nOpStore %142 %137\n%143 = OpAccessChain %141 %32 %46\nOpStore %143 %138\n%144 = OpAccessChain %141 %32 %40\nOpStore %144 %139\n%145 = OpAccessChain %141 %32 %101\nOpStore %145 %140\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.no-legacy-cbuf-layout.index-divider.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[256];\n} _12;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _23 = INDEX + 64u;\n    float _29 = _12._m0[_23].x + _12._m0[INDEX].x;\n    float _30 = _12._m0[_23].y + _12._m0[INDEX].x;\n    uint _31 = INDEX + 128u;\n    uint _42 = INDEX + 192u;\n    SV_Target.x = (_29 + _12._m0[_31].x) + _12._m0[_42].x;\n    SV_Target.y = (_30 + _12._m0[_31].y) + _12._m0[_42].y;\n    SV_Target.z = (_29 + _12._m0[_31].z) + _12._m0[_42].z;\n    SV_Target.w = (_30 + _12._m0[_31].x) + _12._m0[_42].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %16\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"INDEX\"\nOpName %16 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Flat\nOpDecorate %14 Location 0\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 256\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Output %8\n%16 = OpVariable %15 Output\n%18 = OpTypePointer Uniform %8\n%20 = OpConstant %5 0\n%24 = OpConstant %5 64\n%32 = OpConstant %5 128\n%43 = OpConstant %5 192\n%54 = OpTypePointer Output %7\n%57 = OpConstant %5 1\n%59 = OpConstant %5 2\n%61 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%17 = OpLoad %5 %14\n%19 = OpAccessChain %18 %12 %20 %17\n%21 = OpLoad %8 %19\n%22 = OpCompositeExtract %7 %21 0\n%23 = OpIAdd %5 %17 %24\n%25 = OpAccessChain %18 %12 %20 %23\n%26 = OpLoad %8 %25\n%27 = OpCompositeExtract %7 %26 0\n%28 = OpCompositeExtract %7 %26 1\n%29 = OpFAdd %7 %27 %22\n%30 = OpFAdd %7 %28 %22\n%31 = OpIAdd %5 %17 %32\n%33 = OpAccessChain %18 %12 %20 %31\n%34 = OpLoad %8 %33\n%35 = OpCompositeExtract %7 %34 0\n%36 = OpCompositeExtract %7 %34 1\n%37 = OpCompositeExtract %7 %34 2\n%38 = OpFAdd %7 %29 %35\n%39 = OpFAdd %7 %30 %36\n%40 = OpFAdd %7 %29 %37\n%41 = OpFAdd %7 %30 %35\n%42 = OpIAdd %5 %17 %43\n%44 = OpAccessChain %18 %12 %20 %42\n%45 = OpLoad %8 %44\n%46 = OpCompositeExtract %7 %45 0\n%47 = OpCompositeExtract %7 %45 1\n%48 = OpCompositeExtract %7 %45 2\n%49 = OpCompositeExtract %7 %45 3\n%50 = OpFAdd %7 %38 %46\n%51 = OpFAdd %7 %39 %47\n%52 = OpFAdd %7 %40 %48\n%53 = OpFAdd %7 %41 %49\n%55 = OpAccessChain %54 %16 %20\nOpStore %55 %50\n%56 = OpAccessChain %54 %16 %57\nOpStore %56 %51\n%58 = OpAccessChain %54 %16 %59\nOpStore %58 %52\n%60 = OpAccessChain %54 %16 %61\nOpStore %60 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.no-legacy-cbuf-layout.local-root-signature.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _17\n{\n    vec4 _m0;\n    uvec4 _m1;\n};\n\nvec4 _54;\nuvec4 _84;\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(location = 0) rayPayloadInEXT _17 payload;\n\nvoid main()\n{\n    uvec4 _48 = uvec4(SBT._m0[0u], SBT._m0[1u], SBT._m0[2u], SBT._m0[3u]);\n    uint _51 = _48.z;\n    vec4 _53;\n    _53.x = uintBitsToFloat(uvec4(SBT._m0[0u], SBT._m0[1u], SBT._m0[2u], SBT._m0[3u])).x;\n    _53.y = float(_48.y);\n    _53.z = float(int(_51));\n    _53.w = 1.0;\n    vec4 _68 = uintBitsToFloat(uvec4(SBT._m1[0u], SBT._m1[1u], SBT._m1[2u], SBT._m1[3u]));\n    uvec4 _83;\n    _83.x = uint(int(_68.x));\n    _83.y = uint(int(_68.y));\n    _83.z = uvec4(SBT._m1[0u], SBT._m1[1u], SBT._m1[2u], SBT._m1[3u]).z;\n    _83.w = _51;\n    payload._m0 = _53;\n    payload._m1 = _83;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 94\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint MissKHR %3 \"main\" %13 %19\nOpName %3 \"main\"\nOpName %11 \"SBTBlock\"\nOpName %13 \"SBT\"\nOpName %17 \"\"\nOpName %19 \"payload\"\nOpDecorate %7 ArrayStride 4\nOpDecorate %9 ArrayStride 4\nOpDecorate %11 Block\nOpMemberDecorate %11 0 Offset 0\nOpMemberDecorate %11 1 Offset 20\nOpMemberDecorate %11 2 Offset 48\nOpMemberDecorate %11 3 Offset 56\nOpMemberDecorate %11 4 Offset 64\nOpMemberDecorate %11 5 Offset 72\nOpMemberDecorate %11 6 Offset 80\nOpMemberDecorate %11 7 Offset 88\nOpMemberDecorate %11 8 Offset 96\nOpMemberDecorate %11 9 Offset 104\nOpMemberDecorate %11 10 Offset 112\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 5\n%7 = OpTypeArray %5 %6\n%8 = OpConstant %5 6\n%9 = OpTypeArray %5 %8\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %7 %9 %10 %10 %10 %10 %10 %10 %10 %10 %10\n%12 = OpTypePointer ShaderRecordBufferKHR %11\n%13 = OpVariable %12 ShaderRecordBufferKHR\n%14 = OpTypeFloat 32\n%15 = OpTypeVector %14 4\n%16 = OpTypeVector %5 4\n%17 = OpTypeStruct %15 %16\n%18 = OpTypePointer IncomingRayPayloadKHR %17\n%19 = OpVariable %18 IncomingRayPayloadKHR\n%20 = OpTypePointer ShaderRecordBufferKHR %9\n%22 = OpConstant %5 1\n%23 = OpTypePointer ShaderRecordBufferKHR %7\n%25 = OpConstant %5 0\n%26 = OpTypePointer ShaderRecordBufferKHR %5\n%32 = OpConstant %5 2\n%35 = OpConstant %5 3\n%58 = OpConstant %14 1\n%88 = OpTypePointer IncomingRayPayloadKHR %15\n%90 = OpTypePointer IncomingRayPayloadKHR %16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%54 = OpUndef %15\n%84 = OpUndef %16\nOpBranch %92\n%92 = OpLabel\n%21 = OpAccessChain %20 %13 %22\n%24 = OpAccessChain %23 %13 %25\n%27 = OpAccessChain %26 %24 %25\n%28 = OpLoad %5 %27\n%29 = OpAccessChain %26 %24 %22\n%30 = OpLoad %5 %29\n%31 = OpAccessChain %26 %24 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %26 %24 %35\n%36 = OpLoad %5 %34\n%37 = OpCompositeConstruct %16 %28 %30 %33 %36\n%38 = OpBitcast %15 %37\n%39 = OpCompositeExtract %14 %38 0\n%40 = OpAccessChain %26 %24 %25\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %26 %24 %22\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %26 %24 %32\n%45 = OpLoad %5 %44\n%46 = OpAccessChain %26 %24 %35\n%47 = OpLoad %5 %46\n%48 = OpCompositeConstruct %16 %41 %43 %45 %47\n%49 = OpCompositeExtract %5 %48 1\n%50 = OpConvertUToF %14 %49\n%51 = OpCompositeExtract %5 %48 2\n%52 = OpConvertSToF %14 %51\n%53 = OpCompositeInsert %15 %39 %54 0\n%55 = OpCompositeInsert %15 %50 %53 1\n%56 = OpCompositeInsert %15 %52 %55 2\n%57 = OpCompositeInsert %15 %58 %56 3\n%59 = OpAccessChain %26 %21 %25\n%60 = OpLoad %5 %59\n%61 = OpAccessChain %26 %21 %22\n%62 = OpLoad %5 %61\n%63 = OpAccessChain %26 %21 %32\n%64 = OpLoad %5 %63\n%65 = OpAccessChain %26 %21 %35\n%66 = OpLoad %5 %65\n%67 = OpCompositeConstruct %16 %60 %62 %64 %66\n%68 = OpBitcast %15 %67\n%69 = OpCompositeExtract %14 %68 0\n%70 = OpCompositeExtract %14 %68 1\n%71 = OpAccessChain %26 %21 %25\n%72 = OpLoad %5 %71\n%73 = OpAccessChain %26 %21 %22\n%74 = OpLoad %5 %73\n%75 = OpAccessChain %26 %21 %32\n%76 = OpLoad %5 %75\n%77 = OpAccessChain %26 %21 %35\n%78 = OpLoad %5 %77\n%79 = OpCompositeConstruct %16 %72 %74 %76 %78\n%80 = OpCompositeExtract %5 %79 2\n%81 = OpConvertFToS %5 %69\n%82 = OpConvertFToS %5 %70\n%83 = OpCompositeInsert %16 %81 %84 0\n%85 = OpCompositeInsert %16 %82 %83 1\n%86 = OpCompositeInsert %16 %80 %85 2\n%87 = OpCompositeInsert %16 %51 %86 3\n%89 = OpInBoundsAccessChain %88 %19 %25\nOpStore %89 %57\n%91 = OpInBoundsAccessChain %90 %19 %22\nOpStore %91 %87\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.no-legacy-cbuf-layout.native-fp16.sm60.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    u64vec2 _m0[5];\n} _12;\n\nlayout(set = 0, binding = 0, std140) uniform _16_18\n{\n    vec4 _m0[5];\n} _18;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    f16vec4 _34 = f16vec4(_18._m0[1u]);\n    f16vec4 _50 = f16vec4(_18._m0[2u]);\n    SV_Target.x = ((float(_34.x) + _18._m0[0u].x) + float(_50.x)) + float(int64_t(_12._m0[3u].x));\n    SV_Target.y = ((float(_34.y) + _18._m0[0u].y) + float(_50.y)) + float(int64_t(_12._m0[3u].y));\n    SV_Target.z = ((float(_34.z) + _18._m0[0u].z) + float(_50.z)) + float(int64_t(_12._m0[4u].x));\n    SV_Target.w = ((float(_34.w) + _18._m0[0u].w) + float(_50.w)) + float(int64_t(_12._m0[4u].y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 89\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %20\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"\"\nOpName %20 \"SV_Target\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %20 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 5\n%7 = OpTypeInt 64 0\n%8 = OpTypeVector %7 2\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeArray %14 %6\n%16 = OpTypeStruct %15\n%17 = OpTypePointer Uniform %16\n%18 = OpVariable %17 Uniform\n%19 = OpTypePointer Output %14\n%20 = OpVariable %19 Output\n%21 = OpConstant %5 0\n%22 = OpTypePointer Uniform %14\n%29 = OpConstant %5 1\n%32 = OpTypeFloat 16\n%33 = OpTypeVector %32 4\n%47 = OpConstant %5 2\n%63 = OpConstant %5 3\n%64 = OpTypePointer Uniform %8\n%69 = OpConstant %5 4\n%82 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %87\n%87 = OpLabel\n%23 = OpAccessChain %22 %18 %21 %21\n%24 = OpLoad %14 %23\n%25 = OpCompositeExtract %13 %24 0\n%26 = OpCompositeExtract %13 %24 1\n%27 = OpCompositeExtract %13 %24 2\n%28 = OpCompositeExtract %13 %24 3\n%30 = OpAccessChain %22 %18 %21 %29\n%31 = OpLoad %14 %30\n%34 = OpFConvert %33 %31\n%35 = OpCompositeExtract %32 %34 0\n%36 = OpCompositeExtract %32 %34 1\n%37 = OpCompositeExtract %32 %34 2\n%38 = OpCompositeExtract %32 %34 3\n%39 = OpFConvert %13 %35\n%40 = OpFConvert %13 %36\n%41 = OpFConvert %13 %37\n%42 = OpFConvert %13 %38\n%43 = OpFAdd %13 %39 %25\n%44 = OpFAdd %13 %40 %26\n%45 = OpFAdd %13 %41 %27\n%46 = OpFAdd %13 %42 %28\n%48 = OpAccessChain %22 %18 %21 %47\n%49 = OpLoad %14 %48\n%50 = OpFConvert %33 %49\n%51 = OpCompositeExtract %32 %50 0\n%52 = OpCompositeExtract %32 %50 1\n%53 = OpCompositeExtract %32 %50 2\n%54 = OpCompositeExtract %32 %50 3\n%55 = OpFConvert %13 %51\n%56 = OpFConvert %13 %52\n%57 = OpFConvert %13 %53\n%58 = OpFConvert %13 %54\n%59 = OpFAdd %13 %43 %55\n%60 = OpFAdd %13 %44 %56\n%61 = OpFAdd %13 %45 %57\n%62 = OpFAdd %13 %46 %58\n%65 = OpAccessChain %64 %12 %21 %63\n%66 = OpLoad %8 %65\n%67 = OpCompositeExtract %7 %66 0\n%68 = OpCompositeExtract %7 %66 1\n%70 = OpAccessChain %64 %12 %21 %69\n%71 = OpLoad %8 %70\n%72 = OpCompositeExtract %7 %71 0\n%73 = OpCompositeExtract %7 %71 1\n%74 = OpConvertSToF %13 %67\n%75 = OpConvertSToF %13 %68\n%76 = OpConvertSToF %13 %72\n%77 = OpConvertSToF %13 %73\n%78 = OpFAdd %13 %59 %74\n%79 = OpFAdd %13 %60 %75\n%80 = OpFAdd %13 %61 %76\n%81 = OpFAdd %13 %62 %77\n%83 = OpAccessChain %82 %20 %21\nOpStore %83 %78\n%84 = OpAccessChain %82 %20 %29\nOpStore %84 %79\n%85 = OpAccessChain %82 %20 %47\nOpStore %85 %80\n%86 = OpAccessChain %82 %20 %63\nOpStore %86 %81\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.no-legacy-cbuf-layout.root-constant.frag",
    "content": "#version 460\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) out vec2 SV_Target;\n\nvoid main()\n{\n    vec4 _44 = uintBitsToFloat(uvec4(registers._m0, registers._m1, registers._m2, registers._m3));\n    uvec4 _55 = uvec4(registers._m4, registers._m5, registers._m6, registers._m7);\n    uvec4 _65 = uvec4(registers._m0, registers._m1, registers._m2, registers._m3);\n    float _74 = (float(_65.z + _55.y) + uintBitsToFloat(uvec4(registers._m4, registers._m5, registers._m6, registers._m7)).x) + float(int(_65.w + _55.z));\n    SV_Target.x = _74 + _44.x;\n    SV_Target.y = _74 + _44.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 82\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %12 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 2\n%11 = OpTypePointer Output %10\n%12 = OpVariable %11 Output\n%13 = OpTypePointer PushConstant %5\n%15 = OpConstant %5 4\n%18 = OpConstant %5 5\n%21 = OpConstant %5 6\n%24 = OpConstant %5 7\n%26 = OpTypeVector %5 4\n%28 = OpTypeVector %9 4\n%32 = OpConstant %5 0\n%35 = OpConstant %5 1\n%38 = OpConstant %5 2\n%41 = OpConstant %5 3\n%77 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %80\n%80 = OpLabel\n%14 = OpAccessChain %13 %8 %15\n%16 = OpLoad %5 %14\n%17 = OpAccessChain %13 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %13 %8 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %13 %8 %24\n%25 = OpLoad %5 %23\n%27 = OpCompositeConstruct %26 %16 %19 %22 %25\n%29 = OpBitcast %28 %27\n%30 = OpCompositeExtract %9 %29 0\n%31 = OpAccessChain %13 %8 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %13 %8 %35\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %13 %8 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %13 %8 %41\n%42 = OpLoad %5 %40\n%43 = OpCompositeConstruct %26 %33 %36 %39 %42\n%44 = OpBitcast %28 %43\n%45 = OpCompositeExtract %9 %44 0\n%46 = OpCompositeExtract %9 %44 1\n%47 = OpAccessChain %13 %8 %15\n%48 = OpLoad %5 %47\n%49 = OpAccessChain %13 %8 %18\n%50 = OpLoad %5 %49\n%51 = OpAccessChain %13 %8 %21\n%52 = OpLoad %5 %51\n%53 = OpAccessChain %13 %8 %24\n%54 = OpLoad %5 %53\n%55 = OpCompositeConstruct %26 %48 %50 %52 %54\n%56 = OpCompositeExtract %5 %55 1\n%57 = OpAccessChain %13 %8 %32\n%58 = OpLoad %5 %57\n%59 = OpAccessChain %13 %8 %35\n%60 = OpLoad %5 %59\n%61 = OpAccessChain %13 %8 %38\n%62 = OpLoad %5 %61\n%63 = OpAccessChain %13 %8 %41\n%64 = OpLoad %5 %63\n%65 = OpCompositeConstruct %26 %58 %60 %62 %64\n%66 = OpCompositeExtract %5 %65 2\n%67 = OpIAdd %5 %66 %56\n%68 = OpConvertUToF %9 %67\n%69 = OpCompositeExtract %5 %55 2\n%70 = OpCompositeExtract %5 %65 3\n%71 = OpIAdd %5 %70 %69\n%72 = OpConvertSToF %9 %71\n%73 = OpFAdd %9 %68 %30\n%74 = OpFAdd %9 %73 %72\n%75 = OpFAdd %9 %74 %45\n%76 = OpFAdd %9 %74 %46\n%78 = OpAccessChain %77 %12 %32\nOpStore %78 %75\n%79 = OpAccessChain %77 %12 %35\nOpStore %79 %76\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.root-constant.frag",
    "content": "#version 460\n\nlayout(set = 2, binding = 2, std140) uniform _13_15\n{\n    vec4 _m0[1];\n} _15;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    uvec4 _49 = uvec4(registers._m4, registers._m5, registers._m6, registers._m7);\n    uvec4 _53 = floatBitsToUint(_15._m0[0u]);\n    SV_Target = ((_15._m0[0u].x + uintBitsToFloat(uvec4(registers._m4, registers._m5, registers._m6, registers._m7)).x) + float(_53.y + _49.y)) + float(int(_53.z + _49.z));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 65\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %13 \"\"\nOpName %17 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 ArrayStride 16\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 2\nOpDecorate %15 Binding 2\nOpDecorate %17 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpConstant %5 1\n%10 = OpTypeFloat 32\n%11 = OpTypeVector %10 4\n%12 = OpTypeArray %11 %9\n%13 = OpTypeStruct %12\n%14 = OpTypePointer Uniform %13\n%15 = OpVariable %14 Uniform\n%16 = OpTypePointer Output %10\n%17 = OpVariable %16 Output\n%18 = OpTypePointer PushConstant %5\n%20 = OpConstant %5 4\n%23 = OpConstant %5 5\n%26 = OpConstant %5 6\n%29 = OpConstant %5 7\n%31 = OpTypeVector %5 4\n%35 = OpConstant %5 0\n%36 = OpTypePointer Uniform %11\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %63\n%63 = OpLabel\n%19 = OpAccessChain %18 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %18 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %18 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %18 %8 %29\n%30 = OpLoad %5 %28\n%32 = OpCompositeConstruct %31 %21 %24 %27 %30\n%33 = OpBitcast %11 %32\n%34 = OpCompositeExtract %10 %33 0\n%37 = OpAccessChain %36 %15 %35 %35\n%38 = OpLoad %11 %37\n%39 = OpCompositeExtract %10 %38 0\n%40 = OpFAdd %10 %39 %34\n%41 = OpAccessChain %18 %8 %20\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %18 %8 %23\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %18 %8 %26\n%46 = OpLoad %5 %45\n%47 = OpAccessChain %18 %8 %29\n%48 = OpLoad %5 %47\n%49 = OpCompositeConstruct %31 %42 %44 %46 %48\n%50 = OpCompositeExtract %5 %49 1\n%51 = OpAccessChain %36 %15 %35 %35\n%52 = OpLoad %11 %51\n%53 = OpBitcast %31 %52\n%54 = OpCompositeExtract %5 %53 1\n%55 = OpIAdd %5 %54 %50\n%56 = OpConvertUToF %10 %55\n%57 = OpFAdd %10 %40 %56\n%58 = OpCompositeExtract %5 %49 2\n%59 = OpCompositeExtract %5 %53 2\n%60 = OpIAdd %5 %59 %58\n%61 = OpConvertSToF %10 %60\n%62 = OpFAdd %10 %57 %61\nOpStore %17 %62\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/cbv.root-descriptor.no-legacy-cbuf-layout.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerUint642NonWriteCBVArray;\n\nstruct CBVComposite16x8\n{\n    float16_t _m0;\n    float16_t _m1;\n    float16_t _m2;\n    float16_t _m3;\n    float16_t _m4;\n    float16_t _m5;\n    float16_t _m6;\n    float16_t _m7;\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint642NonWriteCBVArray\n{\n    u64vec2 value[4096];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    PhysicalPointerFloat4NonWriteCBVArray _22 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    PhysicalPointerUint642NonWriteCBVArray _36 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    PhysicalPointerUint642NonWriteCBVArray _43 = PhysicalPointerUint642NonWriteCBVArray(registers._m0);\n    PhysicalPointerFloat4NonWriteCBVArray _58 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    f16vec2 _66 = unpackFloat2x16(floatBitsToUint(_58.value[1u].x));\n    f16vec2 _69 = unpackFloat2x16(floatBitsToUint(_58.value[1u].y));\n    f16vec2 _72 = unpackFloat2x16(floatBitsToUint(_58.value[1u].z));\n    f16vec2 _75 = unpackFloat2x16(floatBitsToUint(_58.value[1u].w));\n    CBVComposite16x8 _79 = CBVComposite16x8(_66.x, _66.y, _69.x, _69.y, _72.x, _72.y, _75.x, _75.y);\n    SV_Target.x = (float(int64_t(_36.value[2u].x)) + _22.value[0u].x) + float(_79._m0);\n    SV_Target.y = (float(int64_t(_36.value[2u].y)) + _22.value[0u].y) + float(_79._m1);\n    SV_Target.z = (float(int64_t(_43.value[3u].x)) + _22.value[0u].z) + float(_79._m2);\n    SV_Target.w = (float(int64_t(_43.value[3u].y)) + _22.value[0u].w) + float(_79._m3);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int64\nOpCapability DenormPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %13 \"SV_Target\"\nOpName %20 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %20 0 \"value\"\nOpName %34 \"PhysicalPointerUint642NonWriteCBVArray\"\nOpMemberName %34 0 \"value\"\nOpName %78 \"CBVComposite16x8\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %13 Location 0\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpMemberDecorate %20 0 NonWritable\nOpDecorate %33 ArrayStride 16\nOpMemberDecorate %34 0 Offset 0\nOpDecorate %34 Block\nOpMemberDecorate %34 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeVector %10 4\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%14 = OpTypePointer PushConstant %6\n%16 = OpConstant %5 0\n%18 = OpConstant %5 4096\n%19 = OpTypeArray %11 %18\n%20 = OpTypeStruct %19\n%21 = OpTypePointer PhysicalStorageBuffer %20\n%23 = OpTypePointer PhysicalStorageBuffer %11\n%30 = OpTypeInt 64 0\n%31 = OpConstant %5 2\n%32 = OpTypeVector %30 2\n%33 = OpTypeArray %32 %18\n%34 = OpTypeStruct %33\n%35 = OpTypePointer PhysicalStorageBuffer %34\n%37 = OpTypePointer PhysicalStorageBuffer %32\n%42 = OpConstant %5 3\n%56 = OpTypeFloat 16\n%57 = OpConstant %5 1\n%61 = OpTypeVector %56 2\n%78 = OpTypeStruct %56 %56 %56 %56 %56 %56 %56 %56\n%92 = OpTypePointer Output %10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %97\n%97 = OpLabel\n%15 = OpAccessChain %14 %9 %16\n%17 = OpLoad %6 %15\n%22 = OpBitcast %21 %17\n%24 = OpInBoundsAccessChain %23 %22 %16 %16\n%25 = OpLoad %11 %24 Aligned 16\n%26 = OpCompositeExtract %10 %25 0\n%27 = OpCompositeExtract %10 %25 1\n%28 = OpCompositeExtract %10 %25 2\n%29 = OpCompositeExtract %10 %25 3\n%36 = OpBitcast %35 %17\n%38 = OpInBoundsAccessChain %37 %36 %16 %31\n%39 = OpLoad %32 %38 Aligned 16\n%40 = OpCompositeExtract %30 %39 0\n%41 = OpCompositeExtract %30 %39 1\n%43 = OpBitcast %35 %17\n%44 = OpInBoundsAccessChain %37 %43 %16 %42\n%45 = OpLoad %32 %44 Aligned 16\n%46 = OpCompositeExtract %30 %45 0\n%47 = OpCompositeExtract %30 %45 1\n%48 = OpConvertSToF %10 %40\n%49 = OpConvertSToF %10 %41\n%50 = OpConvertSToF %10 %46\n%51 = OpConvertSToF %10 %47\n%52 = OpFAdd %10 %48 %26\n%53 = OpFAdd %10 %49 %27\n%54 = OpFAdd %10 %50 %28\n%55 = OpFAdd %10 %51 %29\n%58 = OpBitcast %21 %17\n%59 = OpInBoundsAccessChain %23 %58 %16 %57\n%60 = OpLoad %11 %59 Aligned 16\n%62 = OpCompositeExtract %10 %60 0\n%63 = OpCompositeExtract %10 %60 1\n%64 = OpCompositeExtract %10 %60 2\n%65 = OpCompositeExtract %10 %60 3\n%66 = OpBitcast %61 %62\n%67 = OpCompositeExtract %56 %66 0\n%68 = OpCompositeExtract %56 %66 1\n%69 = OpBitcast %61 %63\n%70 = OpCompositeExtract %56 %69 0\n%71 = OpCompositeExtract %56 %69 1\n%72 = OpBitcast %61 %64\n%73 = OpCompositeExtract %56 %72 0\n%74 = OpCompositeExtract %56 %72 1\n%75 = OpBitcast %61 %65\n%76 = OpCompositeExtract %56 %75 0\n%77 = OpCompositeExtract %56 %75 1\n%79 = OpCompositeConstruct %78 %67 %68 %70 %71 %73 %74 %76 %77\n%80 = OpCompositeExtract %56 %79 0\n%81 = OpCompositeExtract %56 %79 1\n%82 = OpCompositeExtract %56 %79 2\n%83 = OpCompositeExtract %56 %79 3\n%84 = OpFConvert %10 %80\n%85 = OpFConvert %10 %81\n%86 = OpFConvert %10 %82\n%87 = OpFConvert %10 %83\n%88 = OpFAdd %10 %52 %84\n%89 = OpFAdd %10 %53 %85\n%90 = OpFAdd %10 %54 %86\n%91 = OpFAdd %10 %55 %87\n%93 = OpAccessChain %92 %13 %16\nOpStore %93 %88\n%94 = OpAccessChain %92 %13 %57\nOpStore %94 %89\n%95 = OpAccessChain %92 %13 %31\nOpStore %95 %90\n%96 = OpAccessChain %92 %13 %42\nOpStore %96 %91\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/combined-image-sampler-reuse.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 1, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _31 = texture(sampler2D(_8, _11), vec2(UV.x, UV.y));\n    vec4 _40 = texture(sampler2D(_8, _11), vec2(UV.x + 0.100000001490116119384765625, UV.y + 0.100000001490116119384765625));\n    SV_Target.x = _40.x + _31.x;\n    SV_Target.y = _40.y + _31.y;\n    SV_Target.z = _40.z + _31.z;\n    SV_Target.w = _40.w + _31.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"UV\"\nOpName %17 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 1\nOpDecorate %11 Binding 0\nOpDecorate %14 Location 0\nOpDecorate %17 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeSampler\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeVector %5 2\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypeVector %5 4\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%20 = OpTypePointer Input %5\n%22 = OpTypeInt 32 0\n%23 = OpConstant %22 0\n%26 = OpConstant %22 1\n%28 = OpTypeSampledImage %6\n%30 = OpConstant %5 0\n%38 = OpConstant %5 0.100000001\n%50 = OpTypePointer Output %5\n%54 = OpConstant %22 2\n%56 = OpConstant %22 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%18 = OpLoad %6 %8\n%19 = OpLoad %9 %11\n%21 = OpAccessChain %20 %14 %23\n%24 = OpLoad %5 %21\n%25 = OpAccessChain %20 %14 %26\n%27 = OpLoad %5 %25\n%29 = OpSampledImage %28 %18 %19\n%32 = OpCompositeConstruct %12 %24 %27\n%31 = OpImageSampleImplicitLod %15 %29 %32 None\n%33 = OpCompositeExtract %5 %31 0\n%34 = OpCompositeExtract %5 %31 1\n%35 = OpCompositeExtract %5 %31 2\n%36 = OpCompositeExtract %5 %31 3\n%37 = OpFAdd %5 %24 %38\n%39 = OpFAdd %5 %27 %38\n%41 = OpCompositeConstruct %12 %37 %39\n%40 = OpImageSampleImplicitLod %15 %29 %41 None\n%42 = OpCompositeExtract %5 %40 0\n%43 = OpCompositeExtract %5 %40 1\n%44 = OpCompositeExtract %5 %40 2\n%45 = OpCompositeExtract %5 %40 3\n%46 = OpFAdd %5 %42 %33\n%47 = OpFAdd %5 %43 %34\n%48 = OpFAdd %5 %44 %35\n%49 = OpFAdd %5 %45 %36\n%51 = OpAccessChain %50 %17 %23\nOpStore %51 %46\n%52 = OpAccessChain %50 %17 %26\nOpStore %52 %47\n%53 = OpAccessChain %50 %17 %54\nOpStore %53 %48\n%55 = OpAccessChain %50 %17 %56\nOpStore %55 %49\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/dynamic-root-constant.root-constant.bindless.root-descriptor.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4Array;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) buffer PhysicalPointerFloat4Array\n{\n    vec4 value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n    uint root_constants_and_tables[16];\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _15[];\n\nvoid main()\n{\n    uint _22 = registers.root_constants_and_tables[4u] + 2u;\n    uint _41 = 4u * ((gl_WorkGroupID.x << 1u) | 1u);\n    PhysicalPointerFloat4Array(registers._m2).value[gl_GlobalInvocationID.x] = vec4(uintBitsToFloat(uvec4(registers.root_constants_and_tables[min((_41 + 0u), 15u)], registers.root_constants_and_tables[min((_41 + 1u), 15u)], registers.root_constants_and_tables[min((_41 + 2u), 15u)], registers.root_constants_and_tables[min((_41 + 3u), 15u)])));\n    vec4 _89 = uintBitsToFloat(uvec4(registers.root_constants_and_tables[12u], registers.root_constants_and_tables[13u], registers.root_constants_and_tables[14u], registers.root_constants_and_tables[15u]));\n    uint _94 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_15[_22], int(_94), uvec4(floatBitsToUint(_89.x)));\n    imageStore(_15[_22], int(_94 + 1u), uvec4(floatBitsToUint(_89.y)));\n    imageStore(_15[_22], int(_94 + 2u), uvec4(floatBitsToUint(_89.z)));\n    imageStore(_15[_22], int(_94 + 3u), uvec4(floatBitsToUint(_89.w)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 108\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%44 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %30 %35\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %9 \"RootConstants\"\nOpMemberName %9 4 \"root_constants_and_tables\"\nOpName %11 \"registers\"\nOpName %71 \"PhysicalPointerFloat4Array\"\nOpMemberName %71 0 \"value\"\nOpDecorate %8 ArrayStride 4\nOpDecorate %9 Block\nOpMemberDecorate %9 0 Offset 0\nOpMemberDecorate %9 1 Offset 8\nOpMemberDecorate %9 2 Offset 16\nOpMemberDecorate %9 3 Offset 24\nOpMemberDecorate %9 4 Offset 32\nOpDecorate %15 DescriptorSet 4\nOpDecorate %15 Binding 0\nOpDecorate %15 NonReadable\nOpDecorate %30 BuiltIn GlobalInvocationId\nOpDecorate %35 BuiltIn WorkgroupId\nOpDecorate %70 ArrayStride 16\nOpMemberDecorate %71 0 Offset 0\nOpDecorate %71 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpConstant %5 16\n%8 = OpTypeArray %5 %7\n%9 = OpTypeStruct %6 %6 %6 %6 %8\n%10 = OpTypePointer PushConstant %9\n%11 = OpVariable %10 PushConstant\n%12 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypePointer UniformConstant %12\n%18 = OpTypePointer PushConstant %5\n%20 = OpConstant %5 4\n%23 = OpConstant %5 2\n%25 = OpTypePointer PushConstant %6\n%28 = OpTypeVector %5 3\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%31 = OpTypePointer Input %5\n%33 = OpConstant %5 0\n%35 = OpVariable %29 Input\n%39 = OpConstant %5 1\n%46 = OpConstant %5 15\n%58 = OpConstant %5 3\n%61 = OpTypeVector %5 4\n%63 = OpTypeFloat 32\n%64 = OpTypeVector %63 4\n%70 = OpTypeRuntimeArray %64\n%71 = OpTypeStruct %70\n%72 = OpTypePointer PhysicalStorageBuffer %71\n%74 = OpTypePointer PhysicalStorageBuffer %64\n%78 = OpConstant %5 12\n%81 = OpConstant %5 13\n%84 = OpConstant %5 14\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %106\n%106 = OpLabel\n%19 = OpAccessChain %18 %11 %20 %20\n%21 = OpLoad %5 %19\n%22 = OpIAdd %5 %21 %23\n%17 = OpAccessChain %16 %15 %22\n%24 = OpLoad %12 %17\n%26 = OpAccessChain %25 %11 %23\n%27 = OpLoad %6 %26\n%32 = OpAccessChain %31 %30 %33\n%34 = OpLoad %5 %32\n%36 = OpAccessChain %31 %35 %33\n%37 = OpLoad %5 %36\n%38 = OpShiftLeftLogical %5 %37 %39\n%40 = OpBitwiseOr %5 %38 %39\n%41 = OpIMul %5 %20 %40\n%43 = OpIAdd %5 %41 %33\n%45 = OpExtInst %5 %44 UMin %43 %46\n%42 = OpAccessChain %18 %11 %20 %45\n%47 = OpLoad %5 %42\n%49 = OpIAdd %5 %41 %39\n%50 = OpExtInst %5 %44 UMin %49 %46\n%48 = OpAccessChain %18 %11 %20 %50\n%51 = OpLoad %5 %48\n%53 = OpIAdd %5 %41 %23\n%54 = OpExtInst %5 %44 UMin %53 %46\n%52 = OpAccessChain %18 %11 %20 %54\n%55 = OpLoad %5 %52\n%57 = OpIAdd %5 %41 %58\n%59 = OpExtInst %5 %44 UMin %57 %46\n%56 = OpAccessChain %18 %11 %20 %59\n%60 = OpLoad %5 %56\n%62 = OpCompositeConstruct %61 %47 %51 %55 %60\n%65 = OpBitcast %64 %62\n%66 = OpCompositeExtract %63 %65 0\n%67 = OpCompositeExtract %63 %65 1\n%68 = OpCompositeExtract %63 %65 2\n%69 = OpCompositeExtract %63 %65 3\n%73 = OpBitcast %72 %27\n%75 = OpInBoundsAccessChain %74 %73 %33 %34\n%76 = OpCompositeConstruct %64 %66 %67 %68 %69\nOpStore %75 %76 Aligned 16\n%77 = OpAccessChain %18 %11 %20 %78\n%79 = OpLoad %5 %77\n%80 = OpAccessChain %18 %11 %20 %81\n%82 = OpLoad %5 %80\n%83 = OpAccessChain %18 %11 %20 %84\n%85 = OpLoad %5 %83\n%86 = OpAccessChain %18 %11 %20 %46\n%87 = OpLoad %5 %86\n%88 = OpCompositeConstruct %61 %79 %82 %85 %87\n%89 = OpBitcast %64 %88\n%90 = OpCompositeExtract %63 %89 0\n%91 = OpCompositeExtract %63 %89 1\n%92 = OpCompositeExtract %63 %89 2\n%93 = OpCompositeExtract %63 %89 3\n%94 = OpIMul %5 %34 %20\n%95 = OpBitcast %5 %90\n%96 = OpBitcast %5 %91\n%97 = OpBitcast %5 %92\n%98 = OpBitcast %5 %93\n%99 = OpCompositeConstruct %61 %95 %95 %95 %95\nOpImageWrite %24 %94 %99\n%100 = OpCompositeConstruct %61 %96 %96 %96 %96\n%101 = OpIAdd %5 %94 %39\nOpImageWrite %24 %101 %100\n%102 = OpCompositeConstruct %61 %97 %97 %97 %97\n%103 = OpIAdd %5 %94 %23\nOpImageWrite %24 %103 %102\n%104 = OpCompositeConstruct %61 %98 %98 %98 %98\n%105 = OpIAdd %5 %94 %58\nOpImageWrite %24 %105 %104\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/min16-alloca-groupshared.sm60.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared mediump float _13[64];\nshared mediump float _17[256];\n\nvoid main()\n{\n    mediump float _31[4];\n    _31[0u] = 0.0;\n    _31[1u] = 0.0;\n    _31[2u] = 0.0;\n    _31[3u] = 0.0;\n    float _41 = float(gl_LocalInvocationIndex);\n    mediump float mp_copy_41 = _41;\n    _13[gl_LocalInvocationIndex] = _41;\n    _17[0u + (gl_LocalInvocationIndex * 4u)] = mp_copy_41 + 1.0;\n    _17[1u + (gl_LocalInvocationIndex * 4u)] = mp_copy_41 + 2.0;\n    _17[2u + (gl_LocalInvocationIndex * 4u)] = mp_copy_41 + 3.0;\n    _17[3u + (gl_LocalInvocationIndex * 4u)] = mp_copy_41 + 4.0;\n    barrier();\n    _31[gl_LocalInvocationIndex & 3u] = _13[gl_LocalInvocationIndex ^ 5u];\n    _31[(gl_LocalInvocationIndex + 1u) & 3u] = _13[gl_LocalInvocationIndex ^ 4u];\n    uint _77 = gl_LocalInvocationIndex ^ 1u;\n    uint _80 = gl_LocalInvocationIndex ^ 3u;\n    uint _109 = gl_GlobalInvocationID.x * 4u;\n    imageStore(_8, int(_109), uvec4(floatBitsToUint((_17[0u + (_80 * 4u)] + _13[_77]) + _31[0u])));\n    imageStore(_8, int(_109 + 1u), uvec4(floatBitsToUint((_17[1u + (_80 * 4u)] + _13[_77]) + _31[1u])));\n    imageStore(_8, int(_109 + 2u), uvec4(floatBitsToUint((_17[2u + (_80 * 4u)] + _13[_77]) + _31[2u])));\n    imageStore(_8, int(_109 + 3u), uvec4(floatBitsToUint((_17[3u + (_80 * 4u)] + _13[_77]) + _31[3u])));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 124\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %21 %26\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %13 RelaxedPrecision\nOpDecorate %17 RelaxedPrecision\nOpDecorate %21 BuiltIn GlobalInvocationId\nOpDecorate %26 BuiltIn LocalInvocationIndex\nOpDecorate %31 RelaxedPrecision\nOpDecorate %44 RelaxedPrecision\nOpDecorate %46 RelaxedPrecision\nOpDecorate %48 RelaxedPrecision\nOpDecorate %50 RelaxedPrecision\nOpDecorate %97 RelaxedPrecision\nOpDecorate %98 RelaxedPrecision\nOpDecorate %99 RelaxedPrecision\nOpDecorate %100 RelaxedPrecision\nOpDecorate %105 RelaxedPrecision\nOpDecorate %106 RelaxedPrecision\nOpDecorate %107 RelaxedPrecision\nOpDecorate %108 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 64\n%10 = OpTypeFloat 32\n%11 = OpTypeArray %10 %9\n%12 = OpTypePointer Workgroup %11\n%13 = OpVariable %12 Workgroup\n%14 = OpConstant %5 256\n%15 = OpTypeArray %10 %14\n%16 = OpTypePointer Workgroup %15\n%17 = OpVariable %16 Workgroup\n%19 = OpTypeVector %5 3\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Input %5\n%24 = OpConstant %5 0\n%26 = OpVariable %22 Input\n%28 = OpConstant %5 4\n%29 = OpTypeArray %10 %28\n%30 = OpTypePointer Function %29\n%32 = OpTypePointer Function %10\n%35 = OpConstant %5 1\n%37 = OpConstant %5 2\n%39 = OpConstant %5 3\n%40 = OpConstant %10 0\n%42 = OpTypePointer Workgroup %10\n%45 = OpConstant %10 1\n%47 = OpConstant %10 2\n%49 = OpConstant %10 3\n%51 = OpConstant %10 4\n%64 = OpConstant %5 264\n%66 = OpConstant %5 5\n%114 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%31 = OpVariable %30 Function\nOpBranch %122\n%122 = OpLabel\n%18 = OpLoad %6 %8\n%23 = OpAccessChain %22 %21 %24\n%25 = OpLoad %5 %23\n%27 = OpLoad %5 %26\n%33 = OpInBoundsAccessChain %32 %31 %24\n%34 = OpInBoundsAccessChain %32 %31 %35\n%36 = OpInBoundsAccessChain %32 %31 %37\n%38 = OpInBoundsAccessChain %32 %31 %39\nOpStore %33 %40\nOpStore %34 %40\nOpStore %36 %40\nOpStore %38 %40\n%41 = OpConvertUToF %10 %27\n%43 = OpAccessChain %42 %13 %27\nOpStore %43 %41\n%44 = OpFAdd %10 %41 %45\n%46 = OpFAdd %10 %41 %47\n%48 = OpFAdd %10 %41 %49\n%50 = OpFAdd %10 %41 %51\n%52 = OpIMul %5 %27 %28\n%53 = OpIAdd %5 %24 %52\n%54 = OpAccessChain %42 %17 %53\nOpStore %54 %44\n%55 = OpIMul %5 %27 %28\n%56 = OpIAdd %5 %35 %55\n%57 = OpAccessChain %42 %17 %56\nOpStore %57 %46\n%58 = OpIMul %5 %27 %28\n%59 = OpIAdd %5 %37 %58\n%60 = OpAccessChain %42 %17 %59\nOpStore %60 %48\n%61 = OpIMul %5 %27 %28\n%62 = OpIAdd %5 %39 %61\n%63 = OpAccessChain %42 %17 %62\nOpStore %63 %50\nOpControlBarrier %37 %37 %64\n%65 = OpBitwiseXor %5 %27 %66\n%67 = OpAccessChain %42 %13 %65\n%68 = OpLoad %10 %67\n%69 = OpBitwiseAnd %5 %27 %39\n%70 = OpAccessChain %32 %31 %69\nOpStore %70 %68\n%71 = OpBitwiseXor %5 %27 %28\n%72 = OpAccessChain %42 %13 %71\n%73 = OpLoad %10 %72\n%74 = OpIAdd %5 %27 %35\n%75 = OpBitwiseAnd %5 %74 %39\n%76 = OpAccessChain %32 %31 %75\nOpStore %76 %73\n%77 = OpBitwiseXor %5 %27 %35\n%78 = OpAccessChain %42 %13 %77\n%79 = OpLoad %10 %78\n%80 = OpBitwiseXor %5 %27 %39\n%81 = OpIMul %5 %80 %28\n%82 = OpIAdd %5 %24 %81\n%83 = OpAccessChain %42 %17 %82\n%84 = OpLoad %10 %83\n%85 = OpIMul %5 %80 %28\n%86 = OpIAdd %5 %35 %85\n%87 = OpAccessChain %42 %17 %86\n%88 = OpLoad %10 %87\n%89 = OpIMul %5 %80 %28\n%90 = OpIAdd %5 %37 %89\n%91 = OpAccessChain %42 %17 %90\n%92 = OpLoad %10 %91\n%93 = OpIMul %5 %80 %28\n%94 = OpIAdd %5 %39 %93\n%95 = OpAccessChain %42 %17 %94\n%96 = OpLoad %10 %95\n%97 = OpFAdd %10 %84 %79\n%98 = OpFAdd %10 %88 %79\n%99 = OpFAdd %10 %92 %79\n%100 = OpFAdd %10 %96 %79\n%101 = OpLoad %10 %33\n%102 = OpLoad %10 %34\n%103 = OpLoad %10 %36\n%104 = OpLoad %10 %38\n%105 = OpFAdd %10 %97 %101\n%106 = OpFAdd %10 %98 %102\n%107 = OpFAdd %10 %99 %103\n%108 = OpFAdd %10 %100 %104\n%109 = OpIMul %5 %25 %28\n%110 = OpBitcast %5 %105\n%111 = OpBitcast %5 %106\n%112 = OpBitcast %5 %107\n%113 = OpBitcast %5 %108\n%115 = OpCompositeConstruct %114 %110 %110 %110 %110\nOpImageWrite %18 %109 %115\n%116 = OpCompositeConstruct %114 %111 %111 %111 %111\n%117 = OpIAdd %5 %109 %35\nOpImageWrite %18 %117 %116\n%118 = OpCompositeConstruct %114 %112 %112 %112 %112\n%119 = OpIAdd %5 %109 %37\nOpImageWrite %18 %119 %118\n%120 = OpCompositeConstruct %114 %113 %113 %113 %113\n%121 = OpIAdd %5 %109 %39\nOpImageWrite %18 %121 %120\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/min16float-ssbo-dxr.ssbo.rgen",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) writeonly buffer BUFSSBO\n{\n    uint16_t _m0[];\n} BUF;\n\nvoid main()\n{\n    BUF._m0[gl_LaunchIDEXT.x] = float16BitsToUint16(float16_t(20.0));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 25\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %9 %13\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"BUFSSBO\"\nOpName %9 \"BUF\"\nOpDecorate %6 ArrayStride 2\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\nOpDecorate %13 BuiltIn LaunchIdKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 16 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeInt 32 0\n%11 = OpTypeVector %10 3\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%14 = OpTypePointer Input %10\n%16 = OpConstant %10 0\n%18 = OpTypeFloat 16\n%19 = OpConstant %18 0x1.4p+4\n%21 = OpTypePointer StorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %23\n%23 = OpLabel\n%15 = OpAccessChain %14 %13 %16\n%17 = OpLoad %10 %15\n%20 = OpBitcast %5 %19\n%22 = OpAccessChain %21 %9 %16 %17\nOpStore %22 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/raw-buffer-addressing.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nvoid main()\n{\n    imageStore(_8, int(gl_GlobalInvocationID.x >> 2u), uvec4(floatBitsToUint(1.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x << 1u) >> 2u), uvec4(floatBitsToUint(2.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 3u) >> 2u), uvec4(floatBitsToUint(3.0)));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(4.0)));\n    imageStore(_8, int(gl_GlobalInvocationID.x * 2u), uvec4(floatBitsToUint(5.0)));\n    uint _45 = gl_GlobalInvocationID.x * 12u;\n    imageStore(_8, int(gl_GlobalInvocationID.x * 3u), uvec4(floatBitsToUint(6.0)));\n    imageStore(_8, int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(7.0)));\n    imageStore(_8, int(gl_GlobalInvocationID.x * 2u), uvec4(floatBitsToUint(8.0)));\n    imageStore(_8, int(gl_GlobalInvocationID.x * 4u), uvec4(floatBitsToUint(9.0)));\n    imageStore(_8, int((_45 | 1u) >> 2u), uvec4(floatBitsToUint(10.0)));\n    imageStore(_8, int((_45 | 2u) >> 2u), uvec4(floatBitsToUint(11.0)));\n    imageStore(_8, int((_45 | 3u) >> 2u), uvec4(floatBitsToUint(12.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 3u) + 1u), uvec4(floatBitsToUint(13.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 3u) + 2u), uvec4(floatBitsToUint(14.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 3u) - 1u), uvec4(floatBitsToUint(15.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x * 3u) - 2u), uvec4(floatBitsToUint(16.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 4u) >> 2u), uvec4(floatBitsToUint(17.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 8u) >> 2u), uvec4(floatBitsToUint(18.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 4294967292u) >> 2u), uvec4(floatBitsToUint(19.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 4294967288u) >> 2u), uvec4(floatBitsToUint(20.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 5u) >> 2u), uvec4(floatBitsToUint(17.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 9u) >> 2u), uvec4(floatBitsToUint(18.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 4294967291u) >> 2u), uvec4(floatBitsToUint(19.0)));\n    imageStore(_8, int((gl_GlobalInvocationID.x + 4294967287u) >> 2u), uvec4(floatBitsToUint(20.0)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 148\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 2\n%19 = OpTypeFloat 32\n%20 = OpConstant %19 1\n%22 = OpTypeVector %5 4\n%25 = OpConstant %5 1\n%27 = OpConstant %19 2\n%31 = OpConstant %5 3\n%33 = OpConstant %19 3\n%37 = OpConstant %19 4\n%42 = OpConstant %19 5\n%46 = OpConstant %5 12\n%48 = OpConstant %19 6\n%51 = OpConstant %19 7\n%55 = OpConstant %19 8\n%59 = OpConstant %5 4\n%61 = OpConstant %19 9\n%66 = OpConstant %19 10\n%71 = OpConstant %19 11\n%76 = OpConstant %19 12\n%82 = OpConstant %19 13\n%86 = OpConstant %5 8\n%89 = OpConstant %19 14\n%93 = OpConstant %5 4294967292\n%96 = OpConstant %19 15\n%100 = OpConstant %5 4294967288\n%103 = OpConstant %19 16\n%108 = OpConstant %19 17\n%113 = OpConstant %19 18\n%118 = OpConstant %19 19\n%123 = OpConstant %19 20\n%127 = OpConstant %5 5\n%132 = OpConstant %5 9\n%137 = OpConstant %5 4294967291\n%142 = OpConstant %5 4294967287\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %146\n%146 = OpLabel\n%9 = OpLoad %6 %8\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpShiftRightLogical %5 %16 %18\n%21 = OpBitcast %5 %20\n%23 = OpCompositeConstruct %22 %21 %21 %21 %21\nOpImageWrite %9 %17 %23\n%24 = OpShiftLeftLogical %5 %16 %25\n%26 = OpShiftRightLogical %5 %24 %18\n%28 = OpBitcast %5 %27\n%29 = OpCompositeConstruct %22 %28 %28 %28 %28\nOpImageWrite %9 %26 %29\n%30 = OpIMul %5 %16 %31\n%32 = OpShiftRightLogical %5 %30 %18\n%34 = OpBitcast %5 %33\n%35 = OpCompositeConstruct %22 %34 %34 %34 %34\nOpImageWrite %9 %32 %35\n%36 = OpShiftLeftLogical %5 %16 %18\n%38 = OpBitcast %5 %37\n%39 = OpCompositeConstruct %22 %38 %38 %38 %38\nOpImageWrite %9 %16 %39\n%40 = OpShiftLeftLogical %5 %16 %31\n%41 = OpIMul %5 %16 %18\n%43 = OpBitcast %5 %42\n%44 = OpCompositeConstruct %22 %43 %43 %43 %43\nOpImageWrite %9 %41 %44\n%45 = OpIMul %5 %16 %46\n%47 = OpIMul %5 %16 %31\n%49 = OpBitcast %5 %48\n%50 = OpCompositeConstruct %22 %49 %49 %49 %49\nOpImageWrite %9 %47 %50\n%52 = OpBitcast %5 %51\n%53 = OpCompositeConstruct %22 %52 %52 %52 %52\nOpImageWrite %9 %16 %53\n%54 = OpIMul %5 %16 %18\n%56 = OpBitcast %5 %55\n%57 = OpCompositeConstruct %22 %56 %56 %56 %56\nOpImageWrite %9 %54 %57\n%58 = OpShiftLeftLogical %5 %16 %59\n%60 = OpIMul %5 %16 %59\n%62 = OpBitcast %5 %61\n%63 = OpCompositeConstruct %22 %62 %62 %62 %62\nOpImageWrite %9 %60 %63\n%64 = OpBitwiseOr %5 %45 %25\n%65 = OpShiftRightLogical %5 %64 %18\n%67 = OpBitcast %5 %66\n%68 = OpCompositeConstruct %22 %67 %67 %67 %67\nOpImageWrite %9 %65 %68\n%69 = OpBitwiseOr %5 %45 %18\n%70 = OpShiftRightLogical %5 %69 %18\n%72 = OpBitcast %5 %71\n%73 = OpCompositeConstruct %22 %72 %72 %72 %72\nOpImageWrite %9 %70 %73\n%74 = OpBitwiseOr %5 %45 %31\n%75 = OpShiftRightLogical %5 %74 %18\n%77 = OpBitcast %5 %76\n%78 = OpCompositeConstruct %22 %77 %77 %77 %77\nOpImageWrite %9 %75 %78\n%79 = OpIAdd %5 %45 %59\n%80 = OpIMul %5 %16 %31\n%81 = OpIAdd %5 %80 %25\n%83 = OpBitcast %5 %82\n%84 = OpCompositeConstruct %22 %83 %83 %83 %83\nOpImageWrite %9 %81 %84\n%85 = OpIAdd %5 %45 %86\n%87 = OpIMul %5 %16 %31\n%88 = OpIAdd %5 %87 %18\n%90 = OpBitcast %5 %89\n%91 = OpCompositeConstruct %22 %90 %90 %90 %90\nOpImageWrite %9 %88 %91\n%92 = OpIAdd %5 %45 %93\n%94 = OpIMul %5 %16 %31\n%95 = OpISub %5 %94 %25\n%97 = OpBitcast %5 %96\n%98 = OpCompositeConstruct %22 %97 %97 %97 %97\nOpImageWrite %9 %95 %98\n%99 = OpIAdd %5 %45 %100\n%101 = OpIMul %5 %16 %31\n%102 = OpISub %5 %101 %18\n%104 = OpBitcast %5 %103\n%105 = OpCompositeConstruct %22 %104 %104 %104 %104\nOpImageWrite %9 %102 %105\n%106 = OpIAdd %5 %16 %59\n%107 = OpShiftRightLogical %5 %106 %18\n%109 = OpBitcast %5 %108\n%110 = OpCompositeConstruct %22 %109 %109 %109 %109\nOpImageWrite %9 %107 %110\n%111 = OpIAdd %5 %16 %86\n%112 = OpShiftRightLogical %5 %111 %18\n%114 = OpBitcast %5 %113\n%115 = OpCompositeConstruct %22 %114 %114 %114 %114\nOpImageWrite %9 %112 %115\n%116 = OpIAdd %5 %16 %93\n%117 = OpShiftRightLogical %5 %116 %18\n%119 = OpBitcast %5 %118\n%120 = OpCompositeConstruct %22 %119 %119 %119 %119\nOpImageWrite %9 %117 %120\n%121 = OpIAdd %5 %16 %100\n%122 = OpShiftRightLogical %5 %121 %18\n%124 = OpBitcast %5 %123\n%125 = OpCompositeConstruct %22 %124 %124 %124 %124\nOpImageWrite %9 %122 %125\n%126 = OpIAdd %5 %16 %127\n%128 = OpShiftRightLogical %5 %126 %18\n%129 = OpBitcast %5 %108\n%130 = OpCompositeConstruct %22 %129 %129 %129 %129\nOpImageWrite %9 %128 %130\n%131 = OpIAdd %5 %16 %132\n%133 = OpShiftRightLogical %5 %131 %18\n%134 = OpBitcast %5 %113\n%135 = OpCompositeConstruct %22 %134 %134 %134 %134\nOpImageWrite %9 %133 %135\n%136 = OpIAdd %5 %16 %137\n%138 = OpShiftRightLogical %5 %136 %18\n%139 = OpBitcast %5 %118\n%140 = OpCompositeConstruct %22 %139 %139 %139 %139\nOpImageWrite %9 %138 %140\n%141 = OpIAdd %5 %16 %142\n%143 = OpShiftRightLogical %5 %141 %18\n%144 = OpBitcast %5 %123\n%145 = OpCompositeConstruct %22 %144 %144 %144 %144\nOpImageWrite %9 %143 %145\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/raw-buffer-addressing.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nvoid main()\n{\n    _9._m0[gl_GlobalInvocationID.x >> 2u] = floatBitsToUint(1.0);\n    _9._m0[(gl_GlobalInvocationID.x << 1u) >> 2u] = floatBitsToUint(2.0);\n    _9._m0[(gl_GlobalInvocationID.x * 3u) >> 2u] = floatBitsToUint(3.0);\n    _9._m0[gl_GlobalInvocationID.x] = floatBitsToUint(4.0);\n    _9._m0[gl_GlobalInvocationID.x * 2u] = floatBitsToUint(5.0);\n    uint _45 = gl_GlobalInvocationID.x * 12u;\n    _9._m0[gl_GlobalInvocationID.x * 3u] = floatBitsToUint(6.0);\n    _9._m0[gl_GlobalInvocationID.x] = floatBitsToUint(7.0);\n    _9._m0[gl_GlobalInvocationID.x * 2u] = floatBitsToUint(8.0);\n    _9._m0[gl_GlobalInvocationID.x * 4u] = floatBitsToUint(9.0);\n    _9._m0[(_45 | 1u) >> 2u] = floatBitsToUint(10.0);\n    _9._m0[(_45 | 2u) >> 2u] = floatBitsToUint(11.0);\n    _9._m0[(_45 | 3u) >> 2u] = floatBitsToUint(12.0);\n    _9._m0[(gl_GlobalInvocationID.x * 3u) + 1u] = floatBitsToUint(13.0);\n    _9._m0[(gl_GlobalInvocationID.x * 3u) + 2u] = floatBitsToUint(14.0);\n    _9._m0[(gl_GlobalInvocationID.x * 3u) - 1u] = floatBitsToUint(15.0);\n    _9._m0[(gl_GlobalInvocationID.x * 3u) - 2u] = floatBitsToUint(16.0);\n    _9._m0[(gl_GlobalInvocationID.x + 4u) >> 2u] = floatBitsToUint(17.0);\n    _9._m0[(gl_GlobalInvocationID.x + 8u) >> 2u] = floatBitsToUint(18.0);\n    _9._m0[(gl_GlobalInvocationID.x + 4294967292u) >> 2u] = floatBitsToUint(19.0);\n    _9._m0[(gl_GlobalInvocationID.x + 4294967288u) >> 2u] = floatBitsToUint(20.0);\n    _9._m0[(gl_GlobalInvocationID.x + 5u) >> 2u] = floatBitsToUint(17.0);\n    _9._m0[(gl_GlobalInvocationID.x + 9u) >> 2u] = floatBitsToUint(18.0);\n    _9._m0[(gl_GlobalInvocationID.x + 4294967291u) >> 2u] = floatBitsToUint(19.0);\n    _9._m0[(gl_GlobalInvocationID.x + 4294967287u) >> 2u] = floatBitsToUint(20.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 148\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\nOpDecorate %12 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%18 = OpConstant %5 2\n%19 = OpTypeFloat 32\n%20 = OpConstant %19 1\n%22 = OpTypePointer StorageBuffer %5\n%25 = OpConstant %5 1\n%27 = OpConstant %19 2\n%31 = OpConstant %5 3\n%33 = OpConstant %19 3\n%37 = OpConstant %19 4\n%42 = OpConstant %19 5\n%46 = OpConstant %5 12\n%48 = OpConstant %19 6\n%51 = OpConstant %19 7\n%55 = OpConstant %19 8\n%59 = OpConstant %5 4\n%61 = OpConstant %19 9\n%66 = OpConstant %19 10\n%71 = OpConstant %19 11\n%76 = OpConstant %19 12\n%82 = OpConstant %19 13\n%86 = OpConstant %5 8\n%89 = OpConstant %19 14\n%93 = OpConstant %5 4294967292\n%96 = OpConstant %19 15\n%100 = OpConstant %5 4294967288\n%103 = OpConstant %19 16\n%108 = OpConstant %19 17\n%113 = OpConstant %19 18\n%118 = OpConstant %19 19\n%123 = OpConstant %19 20\n%127 = OpConstant %5 5\n%132 = OpConstant %5 9\n%137 = OpConstant %5 4294967291\n%142 = OpConstant %5 4294967287\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %146\n%146 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%17 = OpShiftRightLogical %5 %16 %18\n%21 = OpBitcast %5 %20\n%23 = OpAccessChain %22 %9 %15 %17\nOpStore %23 %21\n%24 = OpShiftLeftLogical %5 %16 %25\n%26 = OpShiftRightLogical %5 %24 %18\n%28 = OpBitcast %5 %27\n%29 = OpAccessChain %22 %9 %15 %26\nOpStore %29 %28\n%30 = OpIMul %5 %16 %31\n%32 = OpShiftRightLogical %5 %30 %18\n%34 = OpBitcast %5 %33\n%35 = OpAccessChain %22 %9 %15 %32\nOpStore %35 %34\n%36 = OpShiftLeftLogical %5 %16 %18\n%38 = OpBitcast %5 %37\n%39 = OpAccessChain %22 %9 %15 %16\nOpStore %39 %38\n%40 = OpShiftLeftLogical %5 %16 %31\n%41 = OpIMul %5 %16 %18\n%43 = OpBitcast %5 %42\n%44 = OpAccessChain %22 %9 %15 %41\nOpStore %44 %43\n%45 = OpIMul %5 %16 %46\n%47 = OpIMul %5 %16 %31\n%49 = OpBitcast %5 %48\n%50 = OpAccessChain %22 %9 %15 %47\nOpStore %50 %49\n%52 = OpBitcast %5 %51\n%53 = OpAccessChain %22 %9 %15 %16\nOpStore %53 %52\n%54 = OpIMul %5 %16 %18\n%56 = OpBitcast %5 %55\n%57 = OpAccessChain %22 %9 %15 %54\nOpStore %57 %56\n%58 = OpShiftLeftLogical %5 %16 %59\n%60 = OpIMul %5 %16 %59\n%62 = OpBitcast %5 %61\n%63 = OpAccessChain %22 %9 %15 %60\nOpStore %63 %62\n%64 = OpBitwiseOr %5 %45 %25\n%65 = OpShiftRightLogical %5 %64 %18\n%67 = OpBitcast %5 %66\n%68 = OpAccessChain %22 %9 %15 %65\nOpStore %68 %67\n%69 = OpBitwiseOr %5 %45 %18\n%70 = OpShiftRightLogical %5 %69 %18\n%72 = OpBitcast %5 %71\n%73 = OpAccessChain %22 %9 %15 %70\nOpStore %73 %72\n%74 = OpBitwiseOr %5 %45 %31\n%75 = OpShiftRightLogical %5 %74 %18\n%77 = OpBitcast %5 %76\n%78 = OpAccessChain %22 %9 %15 %75\nOpStore %78 %77\n%79 = OpIAdd %5 %45 %59\n%80 = OpIMul %5 %16 %31\n%81 = OpIAdd %5 %80 %25\n%83 = OpBitcast %5 %82\n%84 = OpAccessChain %22 %9 %15 %81\nOpStore %84 %83\n%85 = OpIAdd %5 %45 %86\n%87 = OpIMul %5 %16 %31\n%88 = OpIAdd %5 %87 %18\n%90 = OpBitcast %5 %89\n%91 = OpAccessChain %22 %9 %15 %88\nOpStore %91 %90\n%92 = OpIAdd %5 %45 %93\n%94 = OpIMul %5 %16 %31\n%95 = OpISub %5 %94 %25\n%97 = OpBitcast %5 %96\n%98 = OpAccessChain %22 %9 %15 %95\nOpStore %98 %97\n%99 = OpIAdd %5 %45 %100\n%101 = OpIMul %5 %16 %31\n%102 = OpISub %5 %101 %18\n%104 = OpBitcast %5 %103\n%105 = OpAccessChain %22 %9 %15 %102\nOpStore %105 %104\n%106 = OpIAdd %5 %16 %59\n%107 = OpShiftRightLogical %5 %106 %18\n%109 = OpBitcast %5 %108\n%110 = OpAccessChain %22 %9 %15 %107\nOpStore %110 %109\n%111 = OpIAdd %5 %16 %86\n%112 = OpShiftRightLogical %5 %111 %18\n%114 = OpBitcast %5 %113\n%115 = OpAccessChain %22 %9 %15 %112\nOpStore %115 %114\n%116 = OpIAdd %5 %16 %93\n%117 = OpShiftRightLogical %5 %116 %18\n%119 = OpBitcast %5 %118\n%120 = OpAccessChain %22 %9 %15 %117\nOpStore %120 %119\n%121 = OpIAdd %5 %16 %100\n%122 = OpShiftRightLogical %5 %121 %18\n%124 = OpBitcast %5 %123\n%125 = OpAccessChain %22 %9 %15 %122\nOpStore %125 %124\n%126 = OpIAdd %5 %16 %127\n%128 = OpShiftRightLogical %5 %126 %18\n%129 = OpBitcast %5 %108\n%130 = OpAccessChain %22 %9 %15 %128\nOpStore %130 %129\n%131 = OpIAdd %5 %16 %132\n%133 = OpShiftRightLogical %5 %131 %18\n%134 = OpBitcast %5 %113\n%135 = OpAccessChain %22 %9 %15 %133\nOpStore %135 %134\n%136 = OpIAdd %5 %16 %137\n%138 = OpShiftRightLogical %5 %136 %18\n%139 = OpBitcast %5 %118\n%140 = OpAccessChain %22 %9 %15 %138\nOpStore %140 %139\n%141 = OpIAdd %5 %16 %142\n%143 = OpShiftRightLogical %5 %141 %18\n%144 = OpBitcast %5 %123\n%145 = OpAccessChain %22 %9 %15 %143\nOpStore %145 %144\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/root-bda.root-descriptor.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4CoherentArray;\nlayout(buffer_reference) buffer PhysicalPointerHalfArray;\nlayout(buffer_reference) buffer PhysicalPointerHalf2Array;\nlayout(buffer_reference) buffer PhysicalPointerHalf3Array;\nlayout(buffer_reference) buffer PhysicalPointerHalf4Array;\nlayout(buffer_reference) buffer PhysicalPointerUint2Array;\n\nfloat16_t _72;\nuint _112;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) coherent buffer PhysicalPointerFloat4CoherentArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 2, std430) buffer PhysicalPointerHalfArray\n{\n    float16_t value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerHalf2Array\n{\n    f16vec2 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 2, scalar) buffer PhysicalPointerHalf3Array\n{\n    f16vec3 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) buffer PhysicalPointerHalf4Array\n{\n    f16vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) buffer PhysicalPointerUint2Array\n{\n    uvec2 value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    PhysicalPointerFloat4NonWriteArray _34 = PhysicalPointerFloat4NonWriteArray(registers._m1);\n    PhysicalPointerFloat4NonWriteCBVArray _46 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    PhysicalPointerFloat4CoherentArray(registers._m2).value[gl_GlobalInvocationID.x] = vec4(_46.value[gl_GlobalInvocationID.x].x + _34.value[gl_GlobalInvocationID.x].x, _46.value[gl_GlobalInvocationID.x].y + _34.value[gl_GlobalInvocationID.x].y, _46.value[gl_GlobalInvocationID.x].z + _34.value[gl_GlobalInvocationID.x].z, _46.value[gl_GlobalInvocationID.x].w + _34.value[gl_GlobalInvocationID.x].w);\n    PhysicalPointerHalfArray(registers._m3).value[gl_GlobalInvocationID.x] = float16_t(1.0);\n    PhysicalPointerHalf2Array(registers._m3).value[gl_GlobalInvocationID.x] = f16vec2(float16_t(1.0), float16_t(2.0));\n    PhysicalPointerHalf3Array(registers._m3).value[gl_GlobalInvocationID.x] = f16vec3(float16_t(1.0), float16_t(2.0), float16_t(3.0));\n    PhysicalPointerHalf4Array(registers._m3).value[gl_GlobalInvocationID.x] = f16vec4(float16_t(1.0), float16_t(2.0), float16_t(3.0), float16_t(4.0));\n    PhysicalPointerUint2Array(registers._m3).value[gl_GlobalInvocationID.x] = uvec2(4u, 5u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 116\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability DenormPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %25\nOpExecutionMode %3 LocalSize 1 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %32 \"PhysicalPointerFloat4NonWriteArray\"\nOpMemberName %32 0 \"value\"\nOpName %44 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %44 0 \"value\"\nOpName %58 \"PhysicalPointerFloat4CoherentArray\"\nOpMemberName %58 0 \"value\"\nOpName %66 \"PhysicalPointerHalfArray\"\nOpMemberName %66 0 \"value\"\nOpName %76 \"PhysicalPointerHalf2Array\"\nOpMemberName %76 0 \"value\"\nOpName %87 \"PhysicalPointerHalf3Array\"\nOpMemberName %87 0 \"value\"\nOpName %97 \"PhysicalPointerHalf4Array\"\nOpMemberName %97 0 \"value\"\nOpName %105 \"PhysicalPointerUint2Array\"\nOpMemberName %105 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %25 BuiltIn GlobalInvocationId\nOpDecorate %31 ArrayStride 16\nOpMemberDecorate %32 0 Offset 0\nOpDecorate %32 Block\nOpMemberDecorate %32 0 NonWritable\nOpDecorate %43 ArrayStride 16\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %44 Block\nOpMemberDecorate %44 0 NonWritable\nOpDecorate %57 ArrayStride 16\nOpMemberDecorate %58 0 Offset 0\nOpDecorate %58 Block\nOpMemberDecorate %58 0 Coherent\nOpDecorate %65 ArrayStride 2\nOpMemberDecorate %66 0 Offset 0\nOpDecorate %66 Block\nOpDecorate %75 ArrayStride 4\nOpMemberDecorate %76 0 Offset 0\nOpDecorate %76 Block\nOpDecorate %86 ArrayStride 6\nOpMemberDecorate %87 0 Offset 0\nOpDecorate %87 Block\nOpDecorate %96 ArrayStride 8\nOpMemberDecorate %97 0 Offset 0\nOpDecorate %97 Block\nOpDecorate %104 ArrayStride 8\nOpMemberDecorate %105 0 Offset 0\nOpDecorate %105 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypePointer PushConstant %6\n%12 = OpConstant %5 3\n%15 = OpConstant %5 2\n%18 = OpConstant %5 1\n%21 = OpConstant %5 0\n%23 = OpTypeVector %5 3\n%24 = OpTypePointer Input %23\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Input %5\n%29 = OpTypeFloat 32\n%30 = OpTypeVector %29 4\n%31 = OpTypeRuntimeArray %30\n%32 = OpTypeStruct %31\n%33 = OpTypePointer PhysicalStorageBuffer %32\n%35 = OpTypePointer PhysicalStorageBuffer %30\n%42 = OpConstant %5 4096\n%43 = OpTypeArray %30 %42\n%44 = OpTypeStruct %43\n%45 = OpTypePointer PhysicalStorageBuffer %44\n%57 = OpTypeRuntimeArray %30\n%58 = OpTypeStruct %57\n%59 = OpTypePointer PhysicalStorageBuffer %58\n%64 = OpTypeFloat 16\n%65 = OpTypeRuntimeArray %64\n%66 = OpTypeStruct %65\n%67 = OpTypePointer PhysicalStorageBuffer %66\n%69 = OpTypePointer PhysicalStorageBuffer %64\n%71 = OpConstant %64 0x1p+0\n%74 = OpTypeVector %64 2\n%75 = OpTypeRuntimeArray %74\n%76 = OpTypeStruct %75\n%77 = OpTypePointer PhysicalStorageBuffer %76\n%79 = OpTypePointer PhysicalStorageBuffer %74\n%81 = OpConstant %64 0x1p+1\n%84 = OpConstant %5 6\n%85 = OpTypeVector %64 3\n%86 = OpTypeRuntimeArray %85\n%87 = OpTypeStruct %86\n%88 = OpTypePointer PhysicalStorageBuffer %87\n%90 = OpTypePointer PhysicalStorageBuffer %85\n%92 = OpConstant %64 0x1.8p+1\n%95 = OpTypeVector %64 4\n%96 = OpTypeRuntimeArray %95\n%97 = OpTypeStruct %96\n%98 = OpTypePointer PhysicalStorageBuffer %97\n%100 = OpTypePointer PhysicalStorageBuffer %95\n%102 = OpConstant %64 0x1p+2\n%104 = OpTypeRuntimeArray %6\n%105 = OpTypeStruct %104\n%106 = OpTypePointer PhysicalStorageBuffer %105\n%108 = OpTypePointer PhysicalStorageBuffer %6\n%110 = OpConstant %5 4\n%111 = OpConstant %5 5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%72 = OpUndef %64\n%112 = OpUndef %5\nOpBranch %114\n%114 = OpLabel\n%11 = OpAccessChain %10 %9 %12\n%13 = OpLoad %6 %11\n%14 = OpAccessChain %10 %9 %15\n%16 = OpLoad %6 %14\n%17 = OpAccessChain %10 %9 %18\n%19 = OpLoad %6 %17\n%20 = OpAccessChain %10 %9 %21\n%22 = OpLoad %6 %20\n%27 = OpAccessChain %26 %25 %21\n%28 = OpLoad %5 %27\n%34 = OpBitcast %33 %19\n%36 = OpInBoundsAccessChain %35 %34 %21 %28\n%37 = OpLoad %30 %36 Aligned 16\n%38 = OpCompositeExtract %29 %37 0\n%39 = OpCompositeExtract %29 %37 1\n%40 = OpCompositeExtract %29 %37 2\n%41 = OpCompositeExtract %29 %37 3\n%46 = OpBitcast %45 %22\n%47 = OpInBoundsAccessChain %35 %46 %21 %28\n%48 = OpLoad %30 %47 Aligned 16\n%49 = OpCompositeExtract %29 %48 0\n%50 = OpCompositeExtract %29 %48 1\n%51 = OpCompositeExtract %29 %48 2\n%52 = OpCompositeExtract %29 %48 3\n%53 = OpFAdd %29 %49 %38\n%54 = OpFAdd %29 %50 %39\n%55 = OpFAdd %29 %51 %40\n%56 = OpFAdd %29 %52 %41\n%60 = OpBitcast %59 %16\n%61 = OpInBoundsAccessChain %35 %60 %21 %28\n%62 = OpCompositeConstruct %30 %53 %54 %55 %56\nOpStore %61 %62 Aligned 16\n%63 = OpShiftLeftLogical %5 %28 %18\n%68 = OpBitcast %67 %13\n%70 = OpInBoundsAccessChain %69 %68 %21 %28\nOpStore %70 %71 Aligned 2\n%73 = OpShiftLeftLogical %5 %28 %15\n%78 = OpBitcast %77 %13\n%80 = OpInBoundsAccessChain %79 %78 %21 %28\n%82 = OpCompositeConstruct %74 %71 %81\nOpStore %80 %82 Aligned 4\n%83 = OpIMul %5 %28 %84\n%89 = OpBitcast %88 %13\n%91 = OpInBoundsAccessChain %90 %89 %21 %28\n%93 = OpCompositeConstruct %85 %71 %81 %92\nOpStore %91 %93 Aligned 2\n%94 = OpShiftLeftLogical %5 %28 %12\n%99 = OpBitcast %98 %13\n%101 = OpInBoundsAccessChain %100 %99 %21 %28\n%103 = OpCompositeConstruct %95 %71 %81 %92 %102\nOpStore %101 %103 Aligned 8\n%107 = OpBitcast %106 %13\n%109 = OpInBoundsAccessChain %108 %107 %21 %28\n%113 = OpCompositeConstruct %6 %110 %111\nOpStore %109 %113 Aligned 8\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/root-bda.root-descriptor.sm60.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4CoherentArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) coherent buffer PhysicalPointerFloat4CoherentArray\n{\n    vec4 value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    PhysicalPointerFloat4NonWriteArray _31 = PhysicalPointerFloat4NonWriteArray(registers._m1);\n    PhysicalPointerFloat4NonWriteCBVArray _43 = PhysicalPointerFloat4NonWriteCBVArray(registers._m0);\n    PhysicalPointerFloat4CoherentArray(registers._m2).value[gl_GlobalInvocationID.x] = vec4(_43.value[gl_GlobalInvocationID.x].x + _31.value[gl_GlobalInvocationID.x].x, _43.value[gl_GlobalInvocationID.x].y + _31.value[gl_GlobalInvocationID.x].y, _43.value[gl_GlobalInvocationID.x].z + _31.value[gl_GlobalInvocationID.x].z, _43.value[gl_GlobalInvocationID.x].w + _31.value[gl_GlobalInvocationID.x].w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %22\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %29 \"PhysicalPointerFloat4NonWriteArray\"\nOpMemberName %29 0 \"value\"\nOpName %41 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %41 0 \"value\"\nOpName %55 \"PhysicalPointerFloat4CoherentArray\"\nOpMemberName %55 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %22 BuiltIn GlobalInvocationId\nOpDecorate %28 ArrayStride 16\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpMemberDecorate %29 0 NonWritable\nOpDecorate %40 ArrayStride 16\nOpMemberDecorate %41 0 Offset 0\nOpDecorate %41 Block\nOpMemberDecorate %41 0 NonWritable\nOpDecorate %54 ArrayStride 16\nOpMemberDecorate %55 0 Offset 0\nOpDecorate %55 Block\nOpMemberDecorate %55 0 Coherent\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypePointer PushConstant %6\n%12 = OpConstant %5 2\n%15 = OpConstant %5 1\n%18 = OpConstant %5 0\n%20 = OpTypeVector %5 3\n%21 = OpTypePointer Input %20\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Input %5\n%26 = OpTypeFloat 32\n%27 = OpTypeVector %26 4\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypeStruct %28\n%30 = OpTypePointer PhysicalStorageBuffer %29\n%32 = OpTypePointer PhysicalStorageBuffer %27\n%39 = OpConstant %5 4096\n%40 = OpTypeArray %27 %39\n%41 = OpTypeStruct %40\n%42 = OpTypePointer PhysicalStorageBuffer %41\n%54 = OpTypeRuntimeArray %27\n%55 = OpTypeStruct %54\n%56 = OpTypePointer PhysicalStorageBuffer %55\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%11 = OpAccessChain %10 %9 %12\n%13 = OpLoad %6 %11\n%14 = OpAccessChain %10 %9 %15\n%16 = OpLoad %6 %14\n%17 = OpAccessChain %10 %9 %18\n%19 = OpLoad %6 %17\n%24 = OpAccessChain %23 %22 %18\n%25 = OpLoad %5 %24\n%31 = OpBitcast %30 %16\n%33 = OpInBoundsAccessChain %32 %31 %18 %25\n%34 = OpLoad %27 %33 Aligned 16\n%35 = OpCompositeExtract %26 %34 0\n%36 = OpCompositeExtract %26 %34 1\n%37 = OpCompositeExtract %26 %34 2\n%38 = OpCompositeExtract %26 %34 3\n%43 = OpBitcast %42 %19\n%44 = OpInBoundsAccessChain %32 %43 %18 %25\n%45 = OpLoad %27 %44 Aligned 16\n%46 = OpCompositeExtract %26 %45 0\n%47 = OpCompositeExtract %26 %45 1\n%48 = OpCompositeExtract %26 %45 2\n%49 = OpCompositeExtract %26 %45 3\n%50 = OpFAdd %26 %46 %35\n%51 = OpFAdd %26 %47 %36\n%52 = OpFAdd %26 %48 %37\n%53 = OpFAdd %26 %49 %38\n%57 = OpBitcast %56 %13\n%58 = OpInBoundsAccessChain %32 %57 %18 %25\n%59 = OpCompositeConstruct %27 %50 %51 %52 %53\nOpStore %58 %59 Aligned 16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/root-constant-with-bda.root-descriptor.root-constant.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4CoherentArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) coherent buffer PhysicalPointerFloat4CoherentArray\n{\n    vec4 value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n    uint _m16;\n    uint _m17;\n    uint _m18;\n    uint _m19;\n} registers;\n\nvoid main()\n{\n    PhysicalPointerFloat4NonWriteArray _29 = PhysicalPointerFloat4NonWriteArray(registers._m1);\n    float _85 = uintBitsToFloat(uvec4(registers._m12, registers._m13, registers._m14, registers._m15)).z + (uintBitsToFloat(uvec4(registers._m8, registers._m9, registers._m10, registers._m11)).y + uintBitsToFloat(uvec4(registers._m4, registers._m5, registers._m6, registers._m7)).x);\n    PhysicalPointerFloat4CoherentArray(registers._m2).value[gl_GlobalInvocationID.x] = vec4(_85 + _29.value[gl_GlobalInvocationID.x].x, _85 + _29.value[gl_GlobalInvocationID.x].y, _85 + _29.value[gl_GlobalInvocationID.x].z, _85 + _29.value[gl_GlobalInvocationID.x].w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 98\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %19\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %27 \"PhysicalPointerFloat4NonWriteArray\"\nOpMemberName %27 0 \"value\"\nOpName %91 \"PhysicalPointerFloat4CoherentArray\"\nOpMemberName %91 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpMemberDecorate %7 4 Offset 32\nOpMemberDecorate %7 5 Offset 36\nOpMemberDecorate %7 6 Offset 40\nOpMemberDecorate %7 7 Offset 44\nOpMemberDecorate %7 8 Offset 48\nOpMemberDecorate %7 9 Offset 52\nOpMemberDecorate %7 10 Offset 56\nOpMemberDecorate %7 11 Offset 60\nOpMemberDecorate %7 12 Offset 64\nOpMemberDecorate %7 13 Offset 68\nOpMemberDecorate %7 14 Offset 72\nOpMemberDecorate %7 15 Offset 76\nOpMemberDecorate %7 16 Offset 80\nOpMemberDecorate %7 17 Offset 84\nOpMemberDecorate %7 18 Offset 88\nOpMemberDecorate %7 19 Offset 92\nOpDecorate %19 BuiltIn GlobalInvocationId\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpMemberDecorate %27 0 NonWritable\nOpDecorate %90 ArrayStride 16\nOpMemberDecorate %91 0 Offset 0\nOpDecorate %91 Block\nOpMemberDecorate %91 0 Coherent\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypePointer PushConstant %6\n%12 = OpConstant %5 2\n%15 = OpConstant %5 1\n%17 = OpTypeVector %5 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %5\n%22 = OpConstant %5 0\n%24 = OpTypeFloat 32\n%25 = OpTypeVector %24 4\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypeStruct %26\n%28 = OpTypePointer PhysicalStorageBuffer %27\n%30 = OpTypePointer PhysicalStorageBuffer %25\n%37 = OpTypePointer PushConstant %5\n%39 = OpConstant %5 4\n%42 = OpConstant %5 5\n%45 = OpConstant %5 6\n%48 = OpConstant %5 7\n%50 = OpTypeVector %5 4\n%55 = OpConstant %5 8\n%58 = OpConstant %5 9\n%61 = OpConstant %5 10\n%64 = OpConstant %5 11\n%70 = OpConstant %5 12\n%73 = OpConstant %5 13\n%76 = OpConstant %5 14\n%79 = OpConstant %5 15\n%90 = OpTypeRuntimeArray %25\n%91 = OpTypeStruct %90\n%92 = OpTypePointer PhysicalStorageBuffer %91\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %96\n%96 = OpLabel\n%11 = OpAccessChain %10 %9 %12\n%13 = OpLoad %6 %11\n%14 = OpAccessChain %10 %9 %15\n%16 = OpLoad %6 %14\n%21 = OpAccessChain %20 %19 %22\n%23 = OpLoad %5 %21\n%29 = OpBitcast %28 %16\n%31 = OpInBoundsAccessChain %30 %29 %22 %23\n%32 = OpLoad %25 %31 Aligned 16\n%33 = OpCompositeExtract %24 %32 0\n%34 = OpCompositeExtract %24 %32 1\n%35 = OpCompositeExtract %24 %32 2\n%36 = OpCompositeExtract %24 %32 3\n%38 = OpAccessChain %37 %9 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %37 %9 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %37 %9 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %37 %9 %48\n%49 = OpLoad %5 %47\n%51 = OpCompositeConstruct %50 %40 %43 %46 %49\n%52 = OpBitcast %25 %51\n%53 = OpCompositeExtract %24 %52 0\n%54 = OpAccessChain %37 %9 %55\n%56 = OpLoad %5 %54\n%57 = OpAccessChain %37 %9 %58\n%59 = OpLoad %5 %57\n%60 = OpAccessChain %37 %9 %61\n%62 = OpLoad %5 %60\n%63 = OpAccessChain %37 %9 %64\n%65 = OpLoad %5 %63\n%66 = OpCompositeConstruct %50 %56 %59 %62 %65\n%67 = OpBitcast %25 %66\n%68 = OpCompositeExtract %24 %67 1\n%69 = OpAccessChain %37 %9 %70\n%71 = OpLoad %5 %69\n%72 = OpAccessChain %37 %9 %73\n%74 = OpLoad %5 %72\n%75 = OpAccessChain %37 %9 %76\n%77 = OpLoad %5 %75\n%78 = OpAccessChain %37 %9 %79\n%80 = OpLoad %5 %78\n%81 = OpCompositeConstruct %50 %71 %74 %77 %80\n%82 = OpBitcast %25 %81\n%83 = OpCompositeExtract %24 %82 2\n%84 = OpFAdd %24 %68 %53\n%85 = OpFAdd %24 %83 %84\n%86 = OpFAdd %24 %85 %33\n%87 = OpFAdd %24 %85 %34\n%88 = OpFAdd %24 %85 %35\n%89 = OpFAdd %24 %85 %36\n%93 = OpBitcast %92 %13\n%94 = OpInBoundsAccessChain %30 %93 %22 %23\n%95 = OpCompositeConstruct %25 %86 %87 %88 %89\nOpStore %94 %95 Aligned 16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/rt-resources.bindless.local-root-signature.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerUintNonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerUint2NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerUint3NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerUint4NonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatArray;\nlayout(buffer_reference) buffer PhysicalPointerUintArray;\n\nstruct _37\n{\n    vec4 _m0;\n    uint _m1;\n};\n\nvec4 _372;\nfloat _378;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteCBVArray\n{\n    vec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerFloat4NonWriteArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerUintNonWriteArray\n{\n    uint value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) readonly buffer PhysicalPointerUint2NonWriteArray\n{\n    uvec2 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, scalar) readonly buffer PhysicalPointerUint3NonWriteArray\n{\n    uvec3 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint4NonWriteArray\n{\n    uvec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerFloatArray\n{\n    float value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerUintArray\n{\n    uint value[];\n};\n\nlayout(shaderRecordEXT, std430) buffer SBTBlock\n{\n    uint _m0[5];\n    uint _m1[6];\n    uvec2 _m2;\n    uvec2 _m3;\n    uvec2 _m4;\n    uvec2 _m5;\n    uvec2 _m6;\n    uvec2 _m7;\n    uvec2 _m8;\n    uvec2 _m9;\n    uvec2 _m10;\n} SBT;\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _32[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _21[];\nlayout(set = 3, binding = 0, r32f) uniform readonly image2D _25[];\nlayout(set = 2, binding = 0) uniform sampler _36[];\nlayout(location = 0) rayPayloadInEXT _37 payload;\n\nvoid main()\n{\n    uint _53 = (SBT._m9.x >> 6u) + 12u;\n    uint _58 = payload._m1;\n    uint _59 = _58 & 1u;\n    vec4 _67 = texelFetch(_21[registers._m0 + _59], ivec2(uvec2(0u)), int(0u));\n    vec4 _80 = texelFetch(_21[registers._m0 + _58], ivec2(uvec2(0u)), int(0u));\n    vec4 _99 = texelFetch(_21[nonuniformEXT(((SBT._m7.x >> 6u) + 17u) + _58)], ivec2(uvec2(0u)), int(0u));\n    vec4 _119 = imageLoad(_25[nonuniformEXT(((SBT._m8.x >> 6u) + 18u) + _58)], ivec2(uvec2(0u)));\n    uint _146 = ((SBT._m9.x >> 6u) + 13u) + _58;\n    vec4 _169 = uintBitsToFloat(uvec4(SBT._m0[0u], SBT._m0[1u], SBT._m0[2u], SBT._m0[3u]));\n    vec4 _182 = uintBitsToFloat(uvec4(SBT._m0[4u], 0u, 0u, 0u));\n    PhysicalPointerFloat4NonWriteCBVArray _194 = PhysicalPointerFloat4NonWriteCBVArray(SBT._m6);\n    vec4 _223 = textureLod(nonuniformEXT(sampler2D(_21[registers._m0 + _59], _36[(SBT._m10.x >> 5u) + 13u])), vec2(0.5), 0.0);\n    vec4 _249 = textureLod(nonuniformEXT(sampler2D(_21[registers._m0 + _58], _36[((SBT._m10.x >> 5u) + 14u) + (_58 ^ 1u)])), vec2(0.5), 0.0);\n    PhysicalPointerFloat4NonWriteArray _264 = PhysicalPointerFloat4NonWriteArray(SBT._m2);\n    float _285 = uintBitsToFloat(PhysicalPointerUintNonWriteArray(SBT._m4).value[_58]);\n    PhysicalPointerUint2NonWriteArray _294 = PhysicalPointerUint2NonWriteArray(SBT._m4);\n    float _300 = uintBitsToFloat(_294.value[_58].x);\n    float _301 = uintBitsToFloat(_294.value[_58].y);\n    PhysicalPointerUint3NonWriteArray _311 = PhysicalPointerUint3NonWriteArray(SBT._m4);\n    float _320 = uintBitsToFloat(_311.value[_58].z);\n    PhysicalPointerUint4NonWriteArray _329 = PhysicalPointerUint4NonWriteArray(SBT._m4);\n    PhysicalPointerFloatArray _350 = PhysicalPointerFloatArray(SBT._m3);\n    float _366 = uintBitsToFloat(PhysicalPointerUintArray(SBT._m5).value[_58]);\n    float _367 = _366 + (_350.value[_58] + ((((_285 + (_264.value[_58].x + (_249.x + (_223.x + ((((_32[nonuniformEXT(_146)]._m0[0u].x + ((_119.x + (_99.x + (_80.x + _67.x))) + _32[nonuniformEXT(_53)]._m0[0u].x)) + _169.x) + _182.x) + _194.value[1u].x))))) + _300) + uintBitsToFloat(_311.value[_58].x)) + uintBitsToFloat(_329.value[_58].x)));\n    float _368 = _366 + (_350.value[_58] + ((((_285 + (_264.value[_58].y + (_249.y + (_223.y + ((((_32[nonuniformEXT(_146)]._m0[0u].y + ((_119.y + (_99.y + (_80.y + _67.y))) + _32[nonuniformEXT(_53)]._m0[0u].y)) + _169.y) + _182.y) + _194.value[1u].y))))) + _301) + uintBitsToFloat(_311.value[_58].y)) + uintBitsToFloat(_329.value[_58].y)));\n    vec4 _371;\n    _371.x = _367;\n    _371.y = _368;\n    _371.z = _366 + (_350.value[_58] + ((((_285 + (_264.value[_58].z + (_249.z + (_223.z + ((((_32[nonuniformEXT(_146)]._m0[0u].z + ((_119.z + (_99.z + (_80.z + _67.z))) + _32[nonuniformEXT(_53)]._m0[0u].z)) + _169.z) + _182.z) + _194.value[1u].z))))) + _300) + _320) + uintBitsToFloat(_329.value[_58].z)));\n    _371.w = _366 + (_350.value[_58] + ((((_285 + (_264.value[_58].w + (_249.w + (_223.w + ((((_32[nonuniformEXT(_146)]._m0[0u].w + ((_119.w + (_99.w + (_80.w + _67.w))) + _32[nonuniformEXT(_53)]._m0[0u].w)) + _169.w) + _182.w) + _194.value[1u].w))))) + _301) + _320) + uintBitsToFloat(_329.value[_58].w)));\n    payload._m0 = _371;\n    PhysicalPointerFloatArray(SBT._m3).value[_58] = _367;\n    PhysicalPointerFloatArray(SBT._m5).value[_58] = _368;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 385\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint MissKHR %3 \"main\" %8 %16 %21 %25 %32 %36 %39\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %14 \"SBTBlock\"\nOpName %16 \"SBT\"\nOpName %29 \"BindlessCBV\"\nOpName %37 \"\"\nOpName %39 \"payload\"\nOpName %192 \"PhysicalPointerFloat4NonWriteCBVArray\"\nOpMemberName %192 0 \"value\"\nOpName %262 \"PhysicalPointerFloat4NonWriteArray\"\nOpMemberName %262 0 \"value\"\nOpName %279 \"PhysicalPointerUintNonWriteArray\"\nOpMemberName %279 0 \"value\"\nOpName %292 \"PhysicalPointerUint2NonWriteArray\"\nOpMemberName %292 0 \"value\"\nOpName %309 \"PhysicalPointerUint3NonWriteArray\"\nOpMemberName %309 0 \"value\"\nOpName %327 \"PhysicalPointerUint4NonWriteArray\"\nOpMemberName %327 0 \"value\"\nOpName %348 \"PhysicalPointerFloatArray\"\nOpMemberName %348 0 \"value\"\nOpName %361 \"PhysicalPointerUintArray\"\nOpMemberName %361 0 \"value\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 4\nOpDecorate %12 ArrayStride 4\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpMemberDecorate %14 1 Offset 20\nOpMemberDecorate %14 2 Offset 48\nOpMemberDecorate %14 3 Offset 56\nOpMemberDecorate %14 4 Offset 64\nOpMemberDecorate %14 5 Offset 72\nOpMemberDecorate %14 6 Offset 80\nOpMemberDecorate %14 7 Offset 88\nOpMemberDecorate %14 8 Offset 96\nOpMemberDecorate %14 9 Offset 104\nOpMemberDecorate %14 10 Offset 112\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %25 DescriptorSet 3\nOpDecorate %25 Binding 0\nOpDecorate %25 NonWritable\nOpDecorate %28 ArrayStride 16\nOpDecorate %29 Block\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %32 DescriptorSet 5\nOpDecorate %32 Binding 0\nOpDecorate %36 DescriptorSet 2\nOpDecorate %36 Binding 0\nOpDecorate %47 NonUniform\nOpDecorate %97 NonUniform\nOpDecorate %98 NonUniform\nOpDecorate %117 NonUniform\nOpDecorate %118 NonUniform\nOpDecorate %130 NonUniform\nOpDecorate %146 NonUniform\nOpDecorate %140 NonUniform\nOpDecorate %147 NonUniform\nOpDecorate %191 ArrayStride 16\nOpMemberDecorate %192 0 Offset 0\nOpDecorate %192 Block\nOpMemberDecorate %192 0 NonWritable\nOpDecorate %218 NonUniform\nOpDecorate %220 NonUniform\nOpDecorate %246 NonUniform\nOpDecorate %247 NonUniform\nOpDecorate %248 NonUniform\nOpDecorate %261 ArrayStride 16\nOpMemberDecorate %262 0 Offset 0\nOpDecorate %262 Block\nOpMemberDecorate %262 0 NonWritable\nOpDecorate %278 ArrayStride 4\nOpMemberDecorate %279 0 Offset 0\nOpDecorate %279 Block\nOpMemberDecorate %279 0 NonWritable\nOpDecorate %291 ArrayStride 8\nOpMemberDecorate %292 0 Offset 0\nOpDecorate %292 Block\nOpMemberDecorate %292 0 NonWritable\nOpDecorate %308 ArrayStride 12\nOpMemberDecorate %309 0 Offset 0\nOpDecorate %309 Block\nOpMemberDecorate %309 0 NonWritable\nOpDecorate %326 ArrayStride 16\nOpMemberDecorate %327 0 Offset 0\nOpDecorate %327 Block\nOpMemberDecorate %327 0 NonWritable\nOpDecorate %347 ArrayStride 4\nOpMemberDecorate %348 0 Offset 0\nOpDecorate %348 Block\nOpDecorate %360 ArrayStride 4\nOpMemberDecorate %361 0 Offset 0\nOpDecorate %361 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpConstant %5 5\n%10 = OpTypeArray %5 %9\n%11 = OpConstant %5 6\n%12 = OpTypeArray %5 %11\n%13 = OpTypeVector %5 2\n%14 = OpTypeStruct %10 %12 %13 %13 %13 %13 %13 %13 %13 %13 %13\n%15 = OpTypePointer ShaderRecordBufferKHR %14\n%16 = OpVariable %15 ShaderRecordBufferKHR\n%17 = OpTypeFloat 32\n%18 = OpTypeImage %17 2D 0 0 0 1 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %17 2D 0 0 0 2 R32f\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %17 4\n%27 = OpConstant %5 4096\n%28 = OpTypeArray %26 %27\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer Uniform %30\n%32 = OpVariable %31 Uniform\n%33 = OpTypeSampler\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeStruct %26 %5\n%38 = OpTypePointer IncomingRayPayloadKHR %37\n%39 = OpVariable %38 IncomingRayPayloadKHR\n%40 = OpTypePointer ShaderRecordBufferKHR %13\n%43 = OpTypePointer ShaderRecordBufferKHR %10\n%45 = OpConstant %5 0\n%46 = OpTypePointer Uniform %29\n%48 = OpTypePointer ShaderRecordBufferKHR %5\n%50 = OpConstant %5 9\n%54 = OpConstant %5 12\n%55 = OpTypePointer IncomingRayPayloadKHR %5\n%57 = OpConstant %5 1\n%60 = OpTypePointer UniformConstant %18\n%62 = OpTypePointer PushConstant %5\n%73 = OpTypePointer IncomingRayPayloadKHR %26\n%92 = OpConstant %5 7\n%96 = OpConstant %5 17\n%109 = OpTypePointer UniformConstant %22\n%112 = OpConstant %5 8\n%116 = OpConstant %5 18\n%129 = OpTypePointer Uniform %26\n%145 = OpConstant %5 13\n%162 = OpConstant %5 2\n%165 = OpConstant %5 3\n%167 = OpTypeVector %5 4\n%179 = OpConstant %5 4\n%191 = OpTypeArray %26 %27\n%192 = OpTypeStruct %191\n%193 = OpTypePointer PhysicalStorageBuffer %192\n%195 = OpTypePointer PhysicalStorageBuffer %26\n%211 = OpTypePointer UniformConstant %33\n%214 = OpConstant %5 10\n%219 = OpTypeSampledImage %18\n%221 = OpConstant %17 0.5\n%222 = OpConstant %17 0\n%224 = OpTypeVector %17 2\n%245 = OpConstant %5 14\n%261 = OpTypeRuntimeArray %26\n%262 = OpTypeStruct %261\n%263 = OpTypePointer PhysicalStorageBuffer %262\n%278 = OpTypeRuntimeArray %5\n%279 = OpTypeStruct %278\n%280 = OpTypePointer PhysicalStorageBuffer %279\n%282 = OpTypePointer PhysicalStorageBuffer %5\n%291 = OpTypeRuntimeArray %13\n%292 = OpTypeStruct %291\n%293 = OpTypePointer PhysicalStorageBuffer %292\n%295 = OpTypePointer PhysicalStorageBuffer %13\n%307 = OpTypeVector %5 3\n%308 = OpTypeRuntimeArray %307\n%309 = OpTypeStruct %308\n%310 = OpTypePointer PhysicalStorageBuffer %309\n%312 = OpTypePointer PhysicalStorageBuffer %307\n%326 = OpTypeRuntimeArray %167\n%327 = OpTypeStruct %326\n%328 = OpTypePointer PhysicalStorageBuffer %327\n%330 = OpTypePointer PhysicalStorageBuffer %167\n%347 = OpTypeRuntimeArray %17\n%348 = OpTypeStruct %347\n%349 = OpTypePointer PhysicalStorageBuffer %348\n%351 = OpTypePointer PhysicalStorageBuffer %17\n%360 = OpTypeRuntimeArray %5\n%361 = OpTypeStruct %360\n%362 = OpTypePointer PhysicalStorageBuffer %361\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%372 = OpUndef %26\n%378 = OpUndef %17\nOpBranch %383\n%383 = OpLabel\n%41 = OpAccessChain %40 %16 %11\n%42 = OpLoad %13 %41\n%44 = OpAccessChain %43 %16 %45\n%49 = OpAccessChain %48 %16 %50 %45\n%51 = OpLoad %5 %49\n%52 = OpShiftRightLogical %5 %51 %11\n%53 = OpIAdd %5 %52 %54\n%47 = OpAccessChain %46 %32 %53\n%56 = OpInBoundsAccessChain %55 %39 %57\n%58 = OpLoad %5 %56\n%59 = OpBitwiseAnd %5 %58 %57\n%63 = OpAccessChain %62 %8 %45\n%64 = OpLoad %5 %63\n%65 = OpIAdd %5 %64 %59\n%61 = OpAccessChain %60 %21 %65\n%66 = OpLoad %18 %61\n%68 = OpCompositeConstruct %13 %45 %45\n%67 = OpImageFetch %26 %66 %68 Lod %45\n%69 = OpCompositeExtract %17 %67 0\n%70 = OpCompositeExtract %17 %67 1\n%71 = OpCompositeExtract %17 %67 2\n%72 = OpCompositeExtract %17 %67 3\n%74 = OpInBoundsAccessChain %73 %39 %45\n%76 = OpAccessChain %62 %8 %45\n%77 = OpLoad %5 %76\n%78 = OpIAdd %5 %77 %58\n%75 = OpAccessChain %60 %21 %78\n%79 = OpLoad %18 %75\n%81 = OpCompositeConstruct %13 %45 %45\n%80 = OpImageFetch %26 %79 %81 Lod %45\n%82 = OpCompositeExtract %17 %80 0\n%83 = OpCompositeExtract %17 %80 1\n%84 = OpCompositeExtract %17 %80 2\n%85 = OpCompositeExtract %17 %80 3\n%86 = OpFAdd %17 %82 %69\n%87 = OpFAdd %17 %83 %70\n%88 = OpFAdd %17 %84 %71\n%89 = OpFAdd %17 %85 %72\n%91 = OpAccessChain %48 %16 %92 %45\n%93 = OpLoad %5 %91\n%94 = OpShiftRightLogical %5 %93 %11\n%95 = OpIAdd %5 %94 %96\n%97 = OpIAdd %5 %95 %58\n%90 = OpAccessChain %60 %21 %97\n%98 = OpLoad %18 %90\n%100 = OpCompositeConstruct %13 %45 %45\n%99 = OpImageFetch %26 %98 %100 Lod %45\n%101 = OpCompositeExtract %17 %99 0\n%102 = OpCompositeExtract %17 %99 1\n%103 = OpCompositeExtract %17 %99 2\n%104 = OpCompositeExtract %17 %99 3\n%105 = OpFAdd %17 %101 %86\n%106 = OpFAdd %17 %102 %87\n%107 = OpFAdd %17 %103 %88\n%108 = OpFAdd %17 %104 %89\n%111 = OpAccessChain %48 %16 %112 %45\n%113 = OpLoad %5 %111\n%114 = OpShiftRightLogical %5 %113 %11\n%115 = OpIAdd %5 %114 %116\n%117 = OpIAdd %5 %115 %58\n%110 = OpAccessChain %109 %25 %117\n%118 = OpLoad %22 %110\n%120 = OpCompositeConstruct %13 %45 %45\n%119 = OpImageRead %26 %118 %120 None\n%121 = OpCompositeExtract %17 %119 0\n%122 = OpCompositeExtract %17 %119 1\n%123 = OpCompositeExtract %17 %119 2\n%124 = OpCompositeExtract %17 %119 3\n%125 = OpFAdd %17 %121 %105\n%126 = OpFAdd %17 %122 %106\n%127 = OpFAdd %17 %123 %107\n%128 = OpFAdd %17 %124 %108\n%130 = OpAccessChain %129 %47 %45 %45\n%131 = OpLoad %26 %130\n%132 = OpCompositeExtract %17 %131 0\n%133 = OpCompositeExtract %17 %131 1\n%134 = OpCompositeExtract %17 %131 2\n%135 = OpCompositeExtract %17 %131 3\n%136 = OpFAdd %17 %125 %132\n%137 = OpFAdd %17 %126 %133\n%138 = OpFAdd %17 %127 %134\n%139 = OpFAdd %17 %128 %135\n%141 = OpAccessChain %48 %16 %50 %45\n%142 = OpLoad %5 %141\n%143 = OpShiftRightLogical %5 %142 %11\n%144 = OpIAdd %5 %143 %145\n%146 = OpIAdd %5 %144 %58\n%140 = OpAccessChain %46 %32 %146\n%147 = OpAccessChain %129 %140 %45 %45\n%148 = OpLoad %26 %147\n%149 = OpCompositeExtract %17 %148 0\n%150 = OpCompositeExtract %17 %148 1\n%151 = OpCompositeExtract %17 %148 2\n%152 = OpCompositeExtract %17 %148 3\n%153 = OpFAdd %17 %149 %136\n%154 = OpFAdd %17 %150 %137\n%155 = OpFAdd %17 %151 %138\n%156 = OpFAdd %17 %152 %139\n%157 = OpAccessChain %48 %44 %45\n%158 = OpLoad %5 %157\n%159 = OpAccessChain %48 %44 %57\n%160 = OpLoad %5 %159\n%161 = OpAccessChain %48 %44 %162\n%163 = OpLoad %5 %161\n%164 = OpAccessChain %48 %44 %165\n%166 = OpLoad %5 %164\n%168 = OpCompositeConstruct %167 %158 %160 %163 %166\n%169 = OpBitcast %26 %168\n%170 = OpCompositeExtract %17 %169 0\n%171 = OpCompositeExtract %17 %169 1\n%172 = OpCompositeExtract %17 %169 2\n%173 = OpCompositeExtract %17 %169 3\n%174 = OpFAdd %17 %153 %170\n%175 = OpFAdd %17 %154 %171\n%176 = OpFAdd %17 %155 %172\n%177 = OpFAdd %17 %156 %173\n%178 = OpAccessChain %48 %44 %179\n%180 = OpLoad %5 %178\n%181 = OpCompositeConstruct %167 %180 %45 %45 %45\n%182 = OpBitcast %26 %181\n%183 = OpCompositeExtract %17 %182 0\n%184 = OpCompositeExtract %17 %182 1\n%185 = OpCompositeExtract %17 %182 2\n%186 = OpCompositeExtract %17 %182 3\n%187 = OpFAdd %17 %174 %183\n%188 = OpFAdd %17 %175 %184\n%189 = OpFAdd %17 %176 %185\n%190 = OpFAdd %17 %177 %186\n%194 = OpBitcast %193 %42\n%196 = OpInBoundsAccessChain %195 %194 %45 %57\n%197 = OpLoad %26 %196 Aligned 16\n%198 = OpCompositeExtract %17 %197 0\n%199 = OpCompositeExtract %17 %197 1\n%200 = OpCompositeExtract %17 %197 2\n%201 = OpCompositeExtract %17 %197 3\n%202 = OpFAdd %17 %187 %198\n%203 = OpFAdd %17 %188 %199\n%204 = OpFAdd %17 %189 %200\n%205 = OpFAdd %17 %190 %201\n%207 = OpAccessChain %62 %8 %45\n%208 = OpLoad %5 %207\n%209 = OpIAdd %5 %208 %59\n%206 = OpAccessChain %60 %21 %209\n%210 = OpLoad %18 %206\n%213 = OpAccessChain %48 %16 %214 %45\n%215 = OpLoad %5 %213\n%216 = OpShiftRightLogical %5 %215 %9\n%217 = OpIAdd %5 %216 %145\n%212 = OpAccessChain %211 %36 %217\n%218 = OpLoad %33 %212\n%220 = OpSampledImage %219 %210 %218\n%225 = OpCompositeConstruct %224 %221 %221\n%223 = OpImageSampleExplicitLod %26 %220 %225 Lod %222\n%226 = OpCompositeExtract %17 %223 0\n%227 = OpCompositeExtract %17 %223 1\n%228 = OpCompositeExtract %17 %223 2\n%229 = OpCompositeExtract %17 %223 3\n%230 = OpFAdd %17 %226 %202\n%231 = OpFAdd %17 %227 %203\n%232 = OpFAdd %17 %228 %204\n%233 = OpFAdd %17 %229 %205\n%234 = OpBitwiseXor %5 %58 %57\n%236 = OpAccessChain %62 %8 %45\n%237 = OpLoad %5 %236\n%238 = OpIAdd %5 %237 %58\n%235 = OpAccessChain %60 %21 %238\n%239 = OpLoad %18 %235\n%241 = OpAccessChain %48 %16 %214 %45\n%242 = OpLoad %5 %241\n%243 = OpShiftRightLogical %5 %242 %9\n%244 = OpIAdd %5 %243 %245\n%246 = OpIAdd %5 %244 %234\n%240 = OpAccessChain %211 %36 %246\n%247 = OpLoad %33 %240\n%248 = OpSampledImage %219 %239 %247\n%250 = OpCompositeConstruct %224 %221 %221\n%249 = OpImageSampleExplicitLod %26 %248 %250 Lod %222\n%251 = OpCompositeExtract %17 %249 0\n%252 = OpCompositeExtract %17 %249 1\n%253 = OpCompositeExtract %17 %249 2\n%254 = OpCompositeExtract %17 %249 3\n%255 = OpFAdd %17 %251 %230\n%256 = OpFAdd %17 %252 %231\n%257 = OpFAdd %17 %253 %232\n%258 = OpFAdd %17 %254 %233\n%259 = OpAccessChain %40 %16 %162\n%260 = OpLoad %13 %259\n%264 = OpBitcast %263 %260\n%265 = OpInBoundsAccessChain %195 %264 %45 %58\n%266 = OpLoad %26 %265 Aligned 16\n%267 = OpCompositeExtract %17 %266 0\n%268 = OpCompositeExtract %17 %266 1\n%269 = OpCompositeExtract %17 %266 2\n%270 = OpCompositeExtract %17 %266 3\n%271 = OpFAdd %17 %267 %255\n%272 = OpFAdd %17 %268 %256\n%273 = OpFAdd %17 %269 %257\n%274 = OpFAdd %17 %270 %258\n%275 = OpShiftLeftLogical %5 %58 %162\n%276 = OpAccessChain %40 %16 %179\n%277 = OpLoad %13 %276\n%281 = OpBitcast %280 %277\n%283 = OpInBoundsAccessChain %282 %281 %45 %58\n%284 = OpLoad %5 %283 Aligned 4\n%285 = OpBitcast %17 %284\n%286 = OpFAdd %17 %285 %271\n%287 = OpFAdd %17 %285 %272\n%288 = OpFAdd %17 %285 %273\n%289 = OpFAdd %17 %285 %274\n%290 = OpShiftLeftLogical %5 %58 %165\n%294 = OpBitcast %293 %277\n%296 = OpInBoundsAccessChain %295 %294 %45 %58\n%297 = OpLoad %13 %296 Aligned 8\n%298 = OpCompositeExtract %5 %297 0\n%299 = OpCompositeExtract %5 %297 1\n%300 = OpBitcast %17 %298\n%301 = OpBitcast %17 %299\n%302 = OpFAdd %17 %286 %300\n%303 = OpFAdd %17 %287 %301\n%304 = OpFAdd %17 %288 %300\n%305 = OpFAdd %17 %289 %301\n%306 = OpIMul %5 %58 %54\n%311 = OpBitcast %310 %277\n%313 = OpInBoundsAccessChain %312 %311 %45 %58\n%314 = OpLoad %307 %313 Aligned 4\n%315 = OpCompositeExtract %5 %314 0\n%316 = OpCompositeExtract %5 %314 1\n%317 = OpCompositeExtract %5 %314 2\n%318 = OpBitcast %17 %315\n%319 = OpBitcast %17 %316\n%320 = OpBitcast %17 %317\n%321 = OpFAdd %17 %302 %318\n%322 = OpFAdd %17 %303 %319\n%323 = OpFAdd %17 %304 %320\n%324 = OpFAdd %17 %305 %320\n%325 = OpShiftLeftLogical %5 %58 %179\n%329 = OpBitcast %328 %277\n%331 = OpInBoundsAccessChain %330 %329 %45 %58\n%332 = OpLoad %167 %331 Aligned 16\n%333 = OpCompositeExtract %5 %332 0\n%334 = OpCompositeExtract %5 %332 1\n%335 = OpCompositeExtract %5 %332 2\n%336 = OpCompositeExtract %5 %332 3\n%337 = OpBitcast %17 %333\n%338 = OpBitcast %17 %334\n%339 = OpBitcast %17 %335\n%340 = OpBitcast %17 %336\n%341 = OpFAdd %17 %321 %337\n%342 = OpFAdd %17 %322 %338\n%343 = OpFAdd %17 %323 %339\n%344 = OpFAdd %17 %324 %340\n%345 = OpAccessChain %40 %16 %165\n%346 = OpLoad %13 %345\n%350 = OpBitcast %349 %346\n%352 = OpInBoundsAccessChain %351 %350 %45 %58\n%353 = OpLoad %17 %352 Aligned 4\n%354 = OpFAdd %17 %353 %341\n%355 = OpFAdd %17 %353 %342\n%356 = OpFAdd %17 %353 %343\n%357 = OpFAdd %17 %353 %344\n%358 = OpAccessChain %40 %16 %9\n%359 = OpLoad %13 %358\n%363 = OpBitcast %362 %359\n%364 = OpInBoundsAccessChain %282 %363 %45 %58\n%365 = OpLoad %5 %364 Aligned 4\n%366 = OpBitcast %17 %365\n%367 = OpFAdd %17 %366 %354\n%368 = OpFAdd %17 %366 %355\n%369 = OpFAdd %17 %366 %356\n%370 = OpFAdd %17 %366 %357\n%371 = OpCompositeInsert %26 %367 %372 0\n%373 = OpCompositeInsert %26 %368 %371 1\n%374 = OpCompositeInsert %26 %369 %373 2\n%375 = OpCompositeInsert %26 %370 %374 3\nOpStore %74 %375\n%376 = OpBitcast %349 %346\n%377 = OpInBoundsAccessChain %351 %376 %45 %58\nOpStore %377 %367 Aligned 4\n%379 = OpAccessChain %40 %16 %9\n%380 = OpLoad %13 %379\n%381 = OpBitcast %349 %380\n%382 = OpInBoundsAccessChain %351 %381 %45 %58\nOpStore %382 %368 Aligned 4\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/rt-resources.bindless.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _15\n{\n    vec4 _m0;\n    uint _m1;\n};\n\nvec4 _73;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(location = 0) rayPayloadInEXT _15 payload;\n\nvoid main()\n{\n    vec4 _31 = texelFetch(_13[registers._m0 + (payload._m1 & 1u)], ivec2(uvec2(0u)), int(0u));\n    vec4 _45 = texelFetch(_13[registers._m0 + payload._m1], ivec2(uvec2(0u)), int(0u));\n    vec4 _62 = texelFetch(_13[(registers._m0 + 10u) + payload._m1], ivec2(uvec2(0u)), int(0u));\n    vec4 _72;\n    _72.x = _62.x + (_45.x + _31.x);\n    _72.y = _62.y + (_45.y + _31.y);\n    _72.z = _62.z + (_45.z + _31.z);\n    _72.w = _62.w + (_45.w + _31.w);\n    payload._m0 = _72;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint MissKHR %3 \"main\" %8 %13 %17\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"\"\nOpName %17 \"payload\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypeStruct %14 %5\n%16 = OpTypePointer IncomingRayPayloadKHR %15\n%17 = OpVariable %16 IncomingRayPayloadKHR\n%18 = OpTypePointer IncomingRayPayloadKHR %5\n%20 = OpConstant %5 1\n%23 = OpTypePointer UniformConstant %10\n%25 = OpTypePointer PushConstant %5\n%27 = OpConstant %5 0\n%32 = OpTypeVector %5 2\n%38 = OpTypePointer IncomingRayPayloadKHR %14\n%59 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%73 = OpUndef %14\nOpBranch %77\n%77 = OpLabel\n%19 = OpInBoundsAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpBitwiseAnd %5 %21 %20\n%26 = OpAccessChain %25 %8 %27\n%28 = OpLoad %5 %26\n%29 = OpIAdd %5 %28 %22\n%24 = OpAccessChain %23 %13 %29\n%30 = OpLoad %10 %24\n%33 = OpCompositeConstruct %32 %27 %27\n%31 = OpImageFetch %14 %30 %33 Lod %27\n%34 = OpCompositeExtract %9 %31 0\n%35 = OpCompositeExtract %9 %31 1\n%36 = OpCompositeExtract %9 %31 2\n%37 = OpCompositeExtract %9 %31 3\n%39 = OpInBoundsAccessChain %38 %17 %27\n%41 = OpAccessChain %25 %8 %27\n%42 = OpLoad %5 %41\n%43 = OpIAdd %5 %42 %21\n%40 = OpAccessChain %23 %13 %43\n%44 = OpLoad %10 %40\n%46 = OpCompositeConstruct %32 %27 %27\n%45 = OpImageFetch %14 %44 %46 Lod %27\n%47 = OpCompositeExtract %9 %45 0\n%48 = OpCompositeExtract %9 %45 1\n%49 = OpCompositeExtract %9 %45 2\n%50 = OpCompositeExtract %9 %45 3\n%51 = OpFAdd %9 %47 %34\n%52 = OpFAdd %9 %48 %35\n%53 = OpFAdd %9 %49 %36\n%54 = OpFAdd %9 %50 %37\n%56 = OpAccessChain %25 %8 %27\n%57 = OpLoad %5 %56\n%58 = OpIAdd %5 %57 %59\n%60 = OpIAdd %5 %58 %21\n%55 = OpAccessChain %23 %13 %60\n%61 = OpLoad %10 %55\n%63 = OpCompositeConstruct %32 %27 %27\n%62 = OpImageFetch %14 %61 %63 Lod %27\n%64 = OpCompositeExtract %9 %62 0\n%65 = OpCompositeExtract %9 %62 1\n%66 = OpCompositeExtract %9 %62 2\n%67 = OpCompositeExtract %9 %62 3\n%68 = OpFAdd %9 %64 %51\n%69 = OpFAdd %9 %65 %52\n%70 = OpFAdd %9 %66 %53\n%71 = OpFAdd %9 %67 %54\n%72 = OpCompositeInsert %14 %68 %73 0\n%74 = OpCompositeInsert %14 %69 %72 1\n%75 = OpCompositeInsert %14 %70 %74 2\n%76 = OpCompositeInsert %14 %71 %75 3\nOpStore %39 %76\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/rt-resources.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _16\n{\n    vec4 _m0;\n    uint _m1;\n};\n\nvec4 _50;\n\nlayout(set = 0, binding = 0) uniform texture2D Tex[2];\nlayout(set = 1, binding = 0) uniform texture2D TexUnsized[];\nlayout(location = 0) rayPayloadInEXT _16 payload;\n\nvoid main()\n{\n    vec4 _28 = texelFetch(Tex[payload._m1 & 1u], ivec2(uvec2(0u)), int(0u));\n    vec4 _39 = texelFetch(TexUnsized[payload._m1], ivec2(uvec2(0u)), int(0u));\n    vec4 _49;\n    _49.x = _39.x + _28.x;\n    _49.y = _39.y + _28.y;\n    _49.z = _39.z + _28.z;\n    _49.w = _39.w + _28.w;\n    payload._m0 = _49;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MissKHR %3 \"main\" %11 %14 %18\nOpName %3 \"main\"\nOpName %11 \"Tex\"\nOpName %14 \"TexUnsized\"\nOpName %16 \"\"\nOpName %18 \"payload\"\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 2\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeRuntimeArray %6\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeVector %5 4\n%16 = OpTypeStruct %15 %7\n%17 = OpTypePointer IncomingRayPayloadKHR %16\n%18 = OpVariable %17 IncomingRayPayloadKHR\n%19 = OpTypePointer IncomingRayPayloadKHR %7\n%21 = OpConstant %7 1\n%24 = OpTypePointer UniformConstant %6\n%27 = OpConstant %7 0\n%29 = OpTypeVector %7 2\n%35 = OpTypePointer IncomingRayPayloadKHR %15\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%50 = OpUndef %15\nOpBranch %54\n%54 = OpLabel\n%20 = OpInBoundsAccessChain %19 %18 %21\n%22 = OpLoad %7 %20\n%23 = OpBitwiseAnd %7 %22 %21\n%25 = OpAccessChain %24 %11 %23\n%26 = OpLoad %6 %25\n%30 = OpCompositeConstruct %29 %27 %27\n%28 = OpImageFetch %15 %26 %30 Lod %27\n%31 = OpCompositeExtract %5 %28 0\n%32 = OpCompositeExtract %5 %28 1\n%33 = OpCompositeExtract %5 %28 2\n%34 = OpCompositeExtract %5 %28 3\n%36 = OpInBoundsAccessChain %35 %18 %27\n%37 = OpAccessChain %24 %14 %22\n%38 = OpLoad %6 %37\n%40 = OpCompositeConstruct %29 %27 %27\n%39 = OpImageFetch %15 %38 %40 Lod %27\n%41 = OpCompositeExtract %5 %39 0\n%42 = OpCompositeExtract %5 %39 1\n%43 = OpCompositeExtract %5 %39 2\n%44 = OpCompositeExtract %5 %39 3\n%45 = OpFAdd %5 %41 %31\n%46 = OpFAdd %5 %42 %32\n%47 = OpFAdd %5 %43 %33\n%48 = OpFAdd %5 %44 %34\n%49 = OpCompositeInsert %15 %45 %50 0\n%51 = OpCompositeInsert %15 %46 %49 1\n%52 = OpCompositeInsert %15 %47 %51 2\n%53 = OpCompositeInsert %15 %48 %52 3\nOpStore %36 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sampler-array.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform sampler _12[];\nlayout(set = 1, binding = 0) uniform sampler _17[100];\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _30 = texture(sampler2D(_8, _12[2u]), vec2(0.5));\n    vec4 _41 = texture(sampler2D(_8, _17[3u]), vec2(0.5));\n    SV_Target.x = _41.x + _30.x;\n    SV_Target.y = _41.y + _30.y;\n    SV_Target.z = _41.z + _30.z;\n    SV_Target.w = _41.w + _30.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %20\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %20 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %20 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeSampler\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 100\n%15 = OpTypeArray %9 %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %5 4\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%22 = OpTypePointer UniformConstant %9\n%24 = OpConstant %13 2\n%26 = OpTypeSampledImage %6\n%28 = OpConstant %5 0.5\n%29 = OpConstant %5 0\n%31 = OpTypeVector %5 2\n%38 = OpConstant %13 3\n%51 = OpTypePointer Output %5\n%53 = OpConstant %13 0\n%55 = OpConstant %13 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %58\n%58 = OpLabel\n%21 = OpLoad %6 %8\n%23 = OpAccessChain %22 %12 %24\n%25 = OpLoad %9 %23\n%27 = OpSampledImage %26 %21 %25\n%32 = OpCompositeConstruct %31 %28 %28\n%30 = OpImageSampleImplicitLod %18 %27 %32 None\n%33 = OpCompositeExtract %5 %30 0\n%34 = OpCompositeExtract %5 %30 1\n%35 = OpCompositeExtract %5 %30 2\n%36 = OpCompositeExtract %5 %30 3\n%37 = OpAccessChain %22 %17 %38\n%39 = OpLoad %9 %37\n%40 = OpSampledImage %26 %21 %39\n%42 = OpCompositeConstruct %31 %28 %28\n%41 = OpImageSampleImplicitLod %18 %40 %42 None\n%43 = OpCompositeExtract %5 %41 0\n%44 = OpCompositeExtract %5 %41 1\n%45 = OpCompositeExtract %5 %41 2\n%46 = OpCompositeExtract %5 %41 3\n%47 = OpFAdd %5 %43 %33\n%48 = OpFAdd %5 %44 %34\n%49 = OpFAdd %5 %45 %35\n%50 = OpFAdd %5 %46 %36\n%52 = OpAccessChain %51 %20 %53\nOpStore %52 %47\n%54 = OpAccessChain %51 %20 %55\nOpStore %54 %48\n%56 = OpAccessChain %51 %20 %24\nOpStore %56 %49\n%57 = OpAccessChain %51 %20 %38\nOpStore %57 %50\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sampler-indexing.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 5) uniform sampler _14[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _30 = texture(sampler2D(_8, _14[0u]), vec2(0.5));\n    vec4 _41 = texture(sampler2D(_8, _14[2u]), vec2(0.5));\n    vec4 _56 = texture(sampler2D(_8, _14[V]), vec2(0.5));\n    SV_Target.x = (_41.x + _30.x) + _56.x;\n    SV_Target.y = (_41.y + _30.y) + _56.y;\n    SV_Target.z = (_41.z + _30.z) + _56.z;\n    SV_Target.w = (_41.w + _30.w) + _56.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 74\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"V\"\nOpName %19 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 5\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeSampler\n%10 = OpTypeInt 32 0\n%11 = OpConstant %10 3\n%12 = OpTypeArray %9 %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypePointer Input %10\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 4\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%22 = OpTypePointer UniformConstant %9\n%24 = OpConstant %10 0\n%26 = OpTypeSampledImage %6\n%28 = OpConstant %5 0.5\n%29 = OpConstant %5 0\n%31 = OpTypeVector %5 2\n%38 = OpConstant %10 2\n%52 = OpConstant %10 5\n%66 = OpTypePointer Output %5\n%69 = OpConstant %10 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %72\n%72 = OpLabel\n%20 = OpLoad %6 %8\n%21 = OpLoad %10 %16\n%23 = OpAccessChain %22 %14 %24\n%25 = OpLoad %9 %23\n%27 = OpSampledImage %26 %20 %25\n%32 = OpCompositeConstruct %31 %28 %28\n%30 = OpImageSampleImplicitLod %17 %27 %32 None\n%33 = OpCompositeExtract %5 %30 0\n%34 = OpCompositeExtract %5 %30 1\n%35 = OpCompositeExtract %5 %30 2\n%36 = OpCompositeExtract %5 %30 3\n%37 = OpAccessChain %22 %14 %38\n%39 = OpLoad %9 %37\n%40 = OpSampledImage %26 %20 %39\n%42 = OpCompositeConstruct %31 %28 %28\n%41 = OpImageSampleImplicitLod %17 %40 %42 None\n%43 = OpCompositeExtract %5 %41 0\n%44 = OpCompositeExtract %5 %41 1\n%45 = OpCompositeExtract %5 %41 2\n%46 = OpCompositeExtract %5 %41 3\n%47 = OpFAdd %5 %43 %33\n%48 = OpFAdd %5 %44 %34\n%49 = OpFAdd %5 %45 %35\n%50 = OpFAdd %5 %46 %36\n%51 = OpIAdd %10 %21 %52\n%53 = OpAccessChain %22 %14 %21\n%54 = OpLoad %9 %53\n%55 = OpSampledImage %26 %20 %54\n%57 = OpCompositeConstruct %31 %28 %28\n%56 = OpImageSampleImplicitLod %17 %55 %57 None\n%58 = OpCompositeExtract %5 %56 0\n%59 = OpCompositeExtract %5 %56 1\n%60 = OpCompositeExtract %5 %56 2\n%61 = OpCompositeExtract %5 %56 3\n%62 = OpFAdd %5 %47 %58\n%63 = OpFAdd %5 %48 %59\n%64 = OpFAdd %5 %49 %60\n%65 = OpFAdd %5 %50 %61\n%67 = OpAccessChain %66 %19 %24\nOpStore %67 %62\n%68 = OpAccessChain %66 %19 %69\nOpStore %68 %63\n%70 = OpAccessChain %66 %19 %38\nOpStore %70 %64\n%71 = OpAccessChain %66 %19 %11\nOpStore %71 %65\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sampler-indexing.sm66.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 5) uniform sampler _14[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _30 = texture(sampler2D(_8, _14[0u]), vec2(0.5));\n    vec4 _42 = texture(sampler2D(_8, _14[2u]), vec2(0.5));\n    vec4 _58 = texture(sampler2D(_8, _14[V]), vec2(0.5));\n    SV_Target.x = (_42.x + _30.x) + _58.x;\n    SV_Target.y = (_42.y + _30.y) + _58.y;\n    SV_Target.z = (_42.z + _30.z) + _58.z;\n    SV_Target.w = (_42.w + _30.w) + _58.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 76\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"V\"\nOpName %19 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 5\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeSampler\n%10 = OpTypeInt 32 0\n%11 = OpConstant %10 3\n%12 = OpTypeArray %9 %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypePointer Input %10\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 4\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%22 = OpTypePointer UniformConstant %9\n%24 = OpConstant %10 0\n%26 = OpTypeSampledImage %6\n%28 = OpConstant %5 0.5\n%29 = OpConstant %5 0\n%31 = OpTypeVector %5 2\n%39 = OpConstant %10 2\n%54 = OpConstant %10 5\n%68 = OpTypePointer Output %5\n%71 = OpConstant %10 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %74\n%74 = OpLabel\n%20 = OpLoad %10 %16\n%21 = OpLoad %6 %8\n%23 = OpAccessChain %22 %14 %24\n%25 = OpLoad %9 %23\n%27 = OpSampledImage %26 %21 %25\n%32 = OpCompositeConstruct %31 %28 %28\n%30 = OpImageSampleImplicitLod %17 %27 %32 None\n%33 = OpCompositeExtract %5 %30 0\n%34 = OpCompositeExtract %5 %30 1\n%35 = OpCompositeExtract %5 %30 2\n%36 = OpCompositeExtract %5 %30 3\n%37 = OpLoad %6 %8\n%38 = OpAccessChain %22 %14 %39\n%40 = OpLoad %9 %38\n%41 = OpSampledImage %26 %37 %40\n%43 = OpCompositeConstruct %31 %28 %28\n%42 = OpImageSampleImplicitLod %17 %41 %43 None\n%44 = OpCompositeExtract %5 %42 0\n%45 = OpCompositeExtract %5 %42 1\n%46 = OpCompositeExtract %5 %42 2\n%47 = OpCompositeExtract %5 %42 3\n%48 = OpFAdd %5 %44 %33\n%49 = OpFAdd %5 %45 %34\n%50 = OpFAdd %5 %46 %35\n%51 = OpFAdd %5 %47 %36\n%52 = OpLoad %6 %8\n%53 = OpIAdd %10 %20 %54\n%55 = OpAccessChain %22 %14 %20\n%56 = OpLoad %9 %55\n%57 = OpSampledImage %26 %52 %56\n%59 = OpCompositeConstruct %31 %28 %28\n%58 = OpImageSampleImplicitLod %17 %57 %59 None\n%60 = OpCompositeExtract %5 %58 0\n%61 = OpCompositeExtract %5 %58 1\n%62 = OpCompositeExtract %5 %58 2\n%63 = OpCompositeExtract %5 %58 3\n%64 = OpFAdd %5 %48 %60\n%65 = OpFAdd %5 %49 %61\n%66 = OpFAdd %5 %50 %62\n%67 = OpFAdd %5 %51 %63\n%69 = OpAccessChain %68 %19 %24\nOpStore %69 %64\n%70 = OpAccessChain %68 %19 %71\nOpStore %70 %65\n%72 = OpAccessChain %68 %19 %39\nOpStore %72 %66\n%73 = OpAccessChain %68 %19 %11\nOpStore %73 %67\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sampler.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 2, binding = 0) uniform sampler _17[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _51 = texture(sampler2D(_13[registers._m0], _17[registers._m2 + 3u]), vec2(UV.x, UV.y));\n    vec4 _64 = texture(sampler2D(_13[registers._m0], _17[registers._m2 + 5u]), vec2(UV.x, UV.y));\n    vec4 _95 = texture(sampler2D(_13[registers._m0], _17[registers._m2 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u)]), vec2(UV.x, UV.y));\n    vec4 _113 = texture(nonuniformEXT(sampler2D(_13[registers._m0], _17[registers._m2 + (INDEX + 100u)])), vec2(UV.x, UV.y));\n    SV_Target.x = ((_64.x + _51.x) + _95.x) + _113.x;\n    SV_Target.y = ((_64.y + _51.y) + _95.y) + _113.y;\n    SV_Target.z = ((_64.z + _51.z) + _95.z) + _113.z;\n    SV_Target.w = ((_64.w + _51.w) + _95.w) + _113.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 130\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %22 %25\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %20 \"UV\"\nOpName %22 \"INDEX\"\nOpName %25 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 2\nOpDecorate %17 Binding 0\nOpDecorate %20 Location 0\nOpDecorate %22 Flat\nOpDecorate %22 Location 1\nOpDecorate %25 Location 0\nOpDecorate %110 NonUniform\nOpDecorate %111 NonUniform\nOpDecorate %112 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeSampler\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %9 2\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Input %5\n%22 = OpVariable %21 Input\n%23 = OpTypeVector %9 4\n%24 = OpTypePointer Output %23\n%25 = OpVariable %24 Output\n%26 = OpTypePointer UniformConstant %10\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 0\n%33 = OpTypePointer UniformConstant %14\n%36 = OpConstant %5 2\n%39 = OpConstant %5 3\n%42 = OpTypePointer Input %9\n%46 = OpConstant %5 1\n%48 = OpTypeSampledImage %10\n%50 = OpConstant %9 0\n%61 = OpConstant %5 5\n%75 = OpConstant %5 4\n%80 = OpConstant %5 6\n%83 = OpConstant %5 7\n%85 = OpTypeVector %5 4\n%106 = OpConstant %5 100\n%123 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %128\n%128 = OpLabel\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%27 = OpAccessChain %26 %13 %31\n%32 = OpLoad %10 %27\n%35 = OpAccessChain %28 %8 %36\n%37 = OpLoad %5 %35\n%38 = OpIAdd %5 %37 %39\n%34 = OpAccessChain %33 %17 %38\n%40 = OpLoad %14 %34\n%41 = OpLoad %5 %22\n%43 = OpAccessChain %42 %20 %30\n%44 = OpLoad %9 %43\n%45 = OpAccessChain %42 %20 %46\n%47 = OpLoad %9 %45\n%49 = OpSampledImage %48 %32 %40\n%52 = OpCompositeConstruct %18 %44 %47\n%51 = OpImageSampleImplicitLod %23 %49 %52 None\n%53 = OpCompositeExtract %9 %51 0\n%54 = OpCompositeExtract %9 %51 1\n%55 = OpCompositeExtract %9 %51 2\n%56 = OpCompositeExtract %9 %51 3\n%58 = OpAccessChain %28 %8 %36\n%59 = OpLoad %5 %58\n%60 = OpIAdd %5 %59 %61\n%57 = OpAccessChain %33 %17 %60\n%62 = OpLoad %14 %57\n%63 = OpSampledImage %48 %32 %62\n%65 = OpCompositeConstruct %18 %44 %47\n%64 = OpImageSampleImplicitLod %23 %63 %65 None\n%66 = OpCompositeExtract %9 %64 0\n%67 = OpCompositeExtract %9 %64 1\n%68 = OpCompositeExtract %9 %64 2\n%69 = OpCompositeExtract %9 %64 3\n%70 = OpFAdd %9 %66 %53\n%71 = OpFAdd %9 %67 %54\n%72 = OpFAdd %9 %68 %55\n%73 = OpFAdd %9 %69 %56\n%74 = OpAccessChain %28 %8 %75\n%76 = OpLoad %5 %74\n%77 = OpAccessChain %28 %8 %61\n%78 = OpLoad %5 %77\n%79 = OpAccessChain %28 %8 %80\n%81 = OpLoad %5 %79\n%82 = OpAccessChain %28 %8 %83\n%84 = OpLoad %5 %82\n%86 = OpCompositeConstruct %85 %76 %78 %81 %84\n%87 = OpCompositeExtract %5 %86 0\n%88 = OpIAdd %5 %87 %75\n%90 = OpAccessChain %28 %8 %36\n%91 = OpLoad %5 %90\n%92 = OpIAdd %5 %91 %88\n%89 = OpAccessChain %33 %17 %92\n%93 = OpLoad %14 %89\n%94 = OpSampledImage %48 %32 %93\n%96 = OpCompositeConstruct %18 %44 %47\n%95 = OpImageSampleImplicitLod %23 %94 %96 None\n%97 = OpCompositeExtract %9 %95 0\n%98 = OpCompositeExtract %9 %95 1\n%99 = OpCompositeExtract %9 %95 2\n%100 = OpCompositeExtract %9 %95 3\n%101 = OpFAdd %9 %70 %97\n%102 = OpFAdd %9 %71 %98\n%103 = OpFAdd %9 %72 %99\n%104 = OpFAdd %9 %73 %100\n%105 = OpIAdd %5 %41 %106\n%108 = OpAccessChain %28 %8 %36\n%109 = OpLoad %5 %108\n%110 = OpIAdd %5 %109 %105\n%107 = OpAccessChain %33 %17 %110\n%111 = OpLoad %14 %107\n%112 = OpSampledImage %48 %32 %111\n%114 = OpCompositeConstruct %18 %44 %47\n%113 = OpImageSampleImplicitLod %23 %112 %114 None\n%115 = OpCompositeExtract %9 %113 0\n%116 = OpCompositeExtract %9 %113 1\n%117 = OpCompositeExtract %9 %113 2\n%118 = OpCompositeExtract %9 %113 3\n%119 = OpFAdd %9 %101 %115\n%120 = OpFAdd %9 %102 %116\n%121 = OpFAdd %9 %103 %117\n%122 = OpFAdd %9 %104 %118\n%124 = OpAccessChain %123 %25 %30\nOpStore %124 %119\n%125 = OpAccessChain %123 %25 %46\nOpStore %125 %120\n%126 = OpAccessChain %123 %25 %36\nOpStore %126 %121\n%127 = OpAccessChain %123 %25 %39\nOpStore %127 %122\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/atomics-64bit-groupshared.ssbo.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nstruct CmpXchgResult\n{\n    uint64_t _m0;\n    bool _m1;\n};\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint64_t _m0[];\n} _9;\n\nshared uint64_t _14[4];\n\nvoid main()\n{\n    bool _23 = gl_GlobalInvocationID.x < 4u;\n    if (_23)\n    {\n        _14[gl_GlobalInvocationID.x] = 0ul;\n    }\n    barrier();\n    uint _29 = gl_GlobalInvocationID.x & 3u;\n    uint64_t _31 = uint64_t(gl_GlobalInvocationID.x);\n    uint64_t _33 = atomicAdd(_14[_29], _31);\n    uint64_t _34 = atomicAnd(_14[_29], _31);\n    uint64_t _35 = atomicOr(_14[_29], _31);\n    uint64_t _36 = atomicXor(_14[_29], _31);\n    uint64_t _37 = atomicMin(_14[_29], _31);\n    uint64_t _38 = atomicMax(_14[_29], _31);\n    uint64_t _39 = atomicMin(_14[_29], _31);\n    uint64_t _40 = atomicMax(_14[_29], _31);\n    uint64_t _41 = atomicExchange(_14[_29], _31);\n    uint64_t _42 = atomicCompSwap(_14[_29], 10ul, _41);\n    uint64_t _47 = atomicCompSwap(_14[_29], 20ul, _31);\n    uint64_t _51 = atomicAdd(_14[_29], _31);\n    uint64_t _52 = atomicAdd(_14[_29], _31);\n    barrier();\n    if (_23)\n    {\n        _9._m0[gl_GlobalInvocationID.x] = _14[gl_GlobalInvocationID.x];\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %45 \"CmpXchgResult\"\nOpDecorate %6 ArrayStride 8\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonReadable\nOpDecorate %17 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 64 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeInt 32 0\n%11 = OpConstant %10 4\n%12 = OpTypeArray %5 %11\n%13 = OpTypePointer Workgroup %12\n%14 = OpVariable %13 Workgroup\n%15 = OpTypeVector %10 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %10\n%20 = OpConstant %10 0\n%22 = OpTypeBool\n%24 = OpTypePointer Workgroup %5\n%26 = OpConstant %5 0\n%27 = OpConstant %10 2\n%28 = OpConstant %10 264\n%30 = OpConstant %10 3\n%43 = OpConstant %5 10\n%45 = OpTypeStruct %5 %22\n%48 = OpConstant %5 20\n%56 = OpTypePointer StorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %58\n%58 = OpLabel\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %10 %19\n%23 = OpULessThan %22 %21 %11\nOpSelectionMerge %60 None\nOpBranchConditional %23 %59 %60\n%59 = OpLabel\n%25 = OpAccessChain %24 %14 %21\nOpStore %25 %26\nOpBranch %60\n%60 = OpLabel\nOpControlBarrier %27 %27 %28\n%29 = OpBitwiseAnd %10 %21 %30\n%31 = OpUConvert %5 %21\n%32 = OpAccessChain %24 %14 %29\n%33 = OpAtomicIAdd %5 %32 %27 %20 %31\n%34 = OpAtomicAnd %5 %32 %27 %20 %31\n%35 = OpAtomicOr %5 %32 %27 %20 %31\n%36 = OpAtomicXor %5 %32 %27 %20 %31\n%37 = OpAtomicSMin %5 %32 %27 %20 %31\n%38 = OpAtomicSMax %5 %32 %27 %20 %31\n%39 = OpAtomicSMin %5 %32 %27 %20 %31\n%40 = OpAtomicSMax %5 %32 %27 %20 %31\n%41 = OpAtomicExchange %5 %32 %27 %20 %31\n%42 = OpAtomicCompareExchange %5 %32 %27 %20 %20 %41 %43\n%44 = OpIEqual %22 %42 %43\n%46 = OpCompositeConstruct %45 %42 %44\n%47 = OpAtomicCompareExchange %5 %32 %27 %20 %20 %31 %48\n%49 = OpIEqual %22 %47 %48\n%50 = OpCompositeConstruct %45 %47 %49\n%51 = OpAtomicIAdd %5 %32 %27 %20 %31\n%52 = OpAtomicIAdd %5 %32 %27 %20 %31\nOpControlBarrier %27 %27 %28\nOpSelectionMerge %62 None\nOpBranchConditional %23 %61 %62\n%61 = OpLabel\n%53 = OpAccessChain %24 %14 %21\n%54 = OpLoad %5 %53\n%55 = OpShiftLeftLogical %10 %21 %30\n%57 = OpAccessChain %56 %9 %20 %21\nOpStore %57 %54\nOpBranch %62\n%62 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/atomics-64bit.root-descriptor.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerUint64Array;\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) buffer PhysicalPointerUint64Array\n{\n    uint64_t value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    uint64_t _18 = uint64_t(gl_GlobalInvocationID.x);\n    uint64_t _29 = atomicAdd(PhysicalPointerUint64Array(registers._m2).value[0u], _18);\n    uint64_t _35 = atomicAnd(PhysicalPointerUint64Array(registers._m2).value[1u], _18);\n    uint64_t _40 = atomicOr(PhysicalPointerUint64Array(registers._m2).value[2u], _18);\n    uint64_t _46 = atomicXor(PhysicalPointerUint64Array(registers._m2).value[3u], _18);\n    uint64_t _52 = atomicMin(PhysicalPointerUint64Array(registers._m2).value[4u], _18);\n    uint64_t _58 = atomicMax(PhysicalPointerUint64Array(registers._m2).value[5u], _18);\n    uint64_t _64 = atomicExchange(PhysicalPointerUint64Array(registers._m2).value[6u], _18);\n    uint64_t _70 = atomicCompSwap(PhysicalPointerUint64Array(registers._m2).value[7u], 10ul, _64);\n    uint64_t _77 = atomicCompSwap(PhysicalPointerUint64Array(registers._m2).value[8u], 20ul, _18);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 81\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %12\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %24 \"PhysicalPointerUint64Array\"\nOpMemberName %24 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %12 BuiltIn GlobalInvocationId\nOpDecorate %23 ArrayStride 8\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeVector %5 3\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Input %5\n%15 = OpConstant %5 0\n%17 = OpTypeInt 64 0\n%19 = OpTypePointer PushConstant %6\n%21 = OpConstant %5 2\n%23 = OpTypeRuntimeArray %17\n%24 = OpTypeStruct %23\n%25 = OpTypePointer PhysicalStorageBuffer %24\n%27 = OpTypePointer PhysicalStorageBuffer %17\n%30 = OpConstant %5 1\n%43 = OpConstant %5 3\n%49 = OpConstant %5 4\n%55 = OpConstant %5 5\n%61 = OpConstant %5 6\n%67 = OpConstant %5 7\n%71 = OpConstant %17 10\n%74 = OpConstant %5 8\n%78 = OpConstant %17 20\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %79\n%79 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %5 %14\n%18 = OpUConvert %17 %16\n%20 = OpAccessChain %19 %9 %21\n%22 = OpLoad %6 %20\n%26 = OpBitcast %25 %22\n%28 = OpAccessChain %27 %26 %15 %15\n%29 = OpAtomicIAdd %17 %28 %30 %15 %18\n%31 = OpAccessChain %19 %9 %21\n%32 = OpLoad %6 %31\n%33 = OpBitcast %25 %32\n%34 = OpAccessChain %27 %33 %15 %30\n%35 = OpAtomicAnd %17 %34 %30 %15 %18\n%36 = OpAccessChain %19 %9 %21\n%37 = OpLoad %6 %36\n%38 = OpBitcast %25 %37\n%39 = OpAccessChain %27 %38 %15 %21\n%40 = OpAtomicOr %17 %39 %30 %15 %18\n%41 = OpAccessChain %19 %9 %21\n%42 = OpLoad %6 %41\n%44 = OpBitcast %25 %42\n%45 = OpAccessChain %27 %44 %15 %43\n%46 = OpAtomicXor %17 %45 %30 %15 %18\n%47 = OpAccessChain %19 %9 %21\n%48 = OpLoad %6 %47\n%50 = OpBitcast %25 %48\n%51 = OpAccessChain %27 %50 %15 %49\n%52 = OpAtomicUMin %17 %51 %30 %15 %18\n%53 = OpAccessChain %19 %9 %21\n%54 = OpLoad %6 %53\n%56 = OpBitcast %25 %54\n%57 = OpAccessChain %27 %56 %15 %55\n%58 = OpAtomicUMax %17 %57 %30 %15 %18\n%59 = OpAccessChain %19 %9 %21\n%60 = OpLoad %6 %59\n%62 = OpBitcast %25 %60\n%63 = OpAccessChain %27 %62 %15 %61\n%64 = OpAtomicExchange %17 %63 %30 %15 %18\n%65 = OpAccessChain %19 %9 %21\n%66 = OpLoad %6 %65\n%68 = OpBitcast %25 %66\n%69 = OpAccessChain %27 %68 %15 %67\n%70 = OpAtomicCompareExchange %17 %69 %30 %15 %15 %64 %71\n%72 = OpAccessChain %19 %9 %21\n%73 = OpLoad %6 %72\n%75 = OpBitcast %25 %73\n%76 = OpAccessChain %27 %75 %15 %74\n%77 = OpAtomicCompareExchange %17 %76 %30 %15 %15 %18 %78\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/atomics-64bit.ssbo.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint64_t _m0[];\n} _10[];\n\nlayout(set = 0, binding = 0, std430) buffer _12_15\n{\n    uint64_t _m0[];\n} _15[];\n\nvoid main()\n{\n    uint64_t _31 = uint64_t(gl_GlobalInvocationID.x);\n    uint64_t _34 = atomicAdd(_10[0u]._m0[0u], _31);\n    uint64_t _36 = atomicAnd(_10[0u]._m0[1u], _31);\n    uint64_t _38 = atomicOr(_10[0u]._m0[2u], _31);\n    uint64_t _41 = atomicXor(_10[0u]._m0[3u], _31);\n    uint64_t _44 = atomicMin(_10[0u]._m0[4u], _31);\n    uint64_t _47 = atomicMax(_10[0u]._m0[5u], _31);\n    uint64_t _50 = atomicMin(_10[1u]._m0[6u], _31);\n    uint64_t _53 = atomicMax(_10[1u]._m0[7u], _31);\n    uint64_t _56 = atomicExchange(_10[0u]._m0[8u], _31);\n    uint64_t _59 = atomicCompSwap(_10[0u]._m0[9u], 10ul, _56);\n    uint64_t _63 = atomicCompSwap(_10[0u]._m0[10u], 20ul, _31);\n    uint64_t _66 = atomicAdd(_15[2u]._m0[0u], _31);\n    uint64_t _68 = atomicAnd(_15[2u]._m0[1u], _31);\n    uint64_t _70 = atomicOr(_15[2u]._m0[2u], _31);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 73\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %19\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %6 ArrayStride 8\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %19 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 64 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypeRuntimeArray %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %5\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeInt 32 0\n%17 = OpTypeVector %16 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %16\n%22 = OpConstant %16 0\n%24 = OpTypePointer StorageBuffer %7\n%27 = OpConstant %16 1\n%28 = OpTypePointer StorageBuffer %12\n%30 = OpConstant %16 2\n%32 = OpTypePointer StorageBuffer %5\n%39 = OpConstant %16 3\n%42 = OpConstant %16 4\n%45 = OpConstant %16 5\n%48 = OpConstant %16 6\n%51 = OpConstant %16 7\n%54 = OpConstant %16 8\n%57 = OpConstant %16 9\n%60 = OpConstant %5 10\n%61 = OpConstant %16 10\n%64 = OpConstant %5 20\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %71\n%71 = OpLabel\n%21 = OpAccessChain %20 %19 %22\n%23 = OpLoad %16 %21\n%25 = OpAccessChain %24 %10 %22\n%26 = OpAccessChain %24 %10 %27\n%29 = OpAccessChain %28 %15 %30\n%31 = OpUConvert %5 %23\n%33 = OpAccessChain %32 %25 %22 %22\n%34 = OpAtomicIAdd %5 %33 %27 %22 %31\n%35 = OpAccessChain %32 %25 %22 %27\n%36 = OpAtomicAnd %5 %35 %27 %22 %31\n%37 = OpAccessChain %32 %25 %22 %30\n%38 = OpAtomicOr %5 %37 %27 %22 %31\n%40 = OpAccessChain %32 %25 %22 %39\n%41 = OpAtomicXor %5 %40 %27 %22 %31\n%43 = OpAccessChain %32 %25 %22 %42\n%44 = OpAtomicUMin %5 %43 %27 %22 %31\n%46 = OpAccessChain %32 %25 %22 %45\n%47 = OpAtomicUMax %5 %46 %27 %22 %31\n%49 = OpAccessChain %32 %26 %22 %48\n%50 = OpAtomicSMin %5 %49 %27 %22 %31\n%52 = OpAccessChain %32 %26 %22 %51\n%53 = OpAtomicSMax %5 %52 %27 %22 %31\n%55 = OpAccessChain %32 %25 %22 %54\n%56 = OpAtomicExchange %5 %55 %27 %22 %31\n%58 = OpAccessChain %32 %25 %22 %57\n%59 = OpAtomicCompareExchange %5 %58 %27 %22 %22 %56 %60\n%62 = OpAccessChain %32 %25 %22 %61\n%63 = OpAtomicCompareExchange %5 %62 %27 %22 %22 %31 %64\n%65 = OpAccessChain %32 %29 %22 %22\n%66 = OpAtomicIAdd %5 %65 %27 %22 %31\n%67 = OpAccessChain %32 %29 %22 %27\n%68 = OpAtomicAnd %5 %67 %27 %22 %31\n%69 = OpAccessChain %32 %29 %22 %30\n%70 = OpAtomicOr %5 %69 %27 %22 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/atomics-component-alias.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_image_int64 : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform utexture2D _11;\nlayout(set = 0, binding = 0, r64ui) uniform u64imageBuffer _15;\nlayout(set = 0, binding = 1, r64ui) uniform u64image2D _18;\n\nvoid main()\n{\n    uvec4 _32 = uvec4(texelFetch(_8, int(gl_GlobalInvocationID.x)).xyxy);\n    imageStore(_15, int(gl_GlobalInvocationID.x), u64vec4(packUint2x32(_32.xy), packUint2x32(_32.zw), 0ul, 0ul));\n    uvec4 _47 = uvec4(unpackUint2x32(imageLoad(_15, int(gl_GlobalInvocationID.x + 10u)).x), 0u, 0u);\n    uint _55 = gl_GlobalInvocationID.x + 1u;\n    uint64_t _59 = imageAtomicAdd(_15, int(_55), (uint64_t(_47.y) << 32ul) | uint64_t(_47.x));\n    uvec4 _67 = uvec4(texelFetch(_11, ivec2(uvec2(gl_GlobalInvocationID.x)), int(0u)).xyxy);\n    imageStore(_18, ivec2(uvec2(gl_GlobalInvocationID.x)), u64vec4(packUint2x32(_67.xy), packUint2x32(_67.zw), 0ul, 0ul));\n    uvec4 _82 = uvec4(unpackUint2x32(imageLoad(_18, ivec2(uvec2(gl_GlobalInvocationID.x + 3u, gl_GlobalInvocationID.x + 4u))).x), 0u, 0u);\n    uint64_t _93 = imageAtomicAdd(_18, ivec2(uvec2(_55, gl_GlobalInvocationID.x + 2u)), (uint64_t(_82.y) << 32ul) | uint64_t(_82.x));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 96\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability Int64ImageEXT\nOpExtension \"SPV_EXT_shader_image_int64\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %21\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 1\nOpDecorate %21 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeInt 64 0\n%13 = OpTypeImage %12 Buffer 0 0 0 2 R64ui\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypeImage %12 2D 0 0 0 2 R64ui\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypeVector %5 3\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Input %5\n%24 = OpConstant %5 0\n%27 = OpTypeVector %5 4\n%33 = OpTypeVector %5 2\n%38 = OpConstant %12 0\n%39 = OpTypeVector %12 4\n%42 = OpConstant %5 10\n%53 = OpConstant %12 32\n%56 = OpConstant %5 1\n%57 = OpTypePointer Image %12\n%74 = OpConstant %5 3\n%76 = OpConstant %5 4\n%90 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %94\n%94 = OpLabel\n%23 = OpAccessChain %22 %21 %24\n%25 = OpLoad %5 %23\n%26 = OpLoad %6 %8\n%28 = OpImageFetch %27 %26 %25\n%29 = OpCompositeExtract %5 %28 0\n%30 = OpCompositeExtract %5 %28 1\n%31 = OpLoad %13 %15\n%32 = OpCompositeConstruct %27 %29 %30 %29 %30\n%34 = OpVectorShuffle %33 %32 %32 0 1\n%35 = OpBitcast %12 %34\n%36 = OpVectorShuffle %33 %32 %32 2 3\n%37 = OpBitcast %12 %36\n%40 = OpCompositeConstruct %39 %35 %37 %38 %38\nOpImageWrite %31 %25 %40\n%41 = OpIAdd %5 %25 %42\n%43 = OpLoad %13 %15\n%44 = OpImageRead %39 %43 %41\n%45 = OpCompositeExtract %12 %44 0\n%46 = OpBitcast %33 %45\n%47 = OpCompositeConstruct %27 %46 %24 %24\n%48 = OpCompositeExtract %5 %47 0\n%49 = OpCompositeExtract %5 %47 1\n%50 = OpUConvert %12 %48\n%51 = OpUConvert %12 %49\n%52 = OpShiftLeftLogical %12 %51 %53\n%54 = OpBitwiseOr %12 %52 %50\n%55 = OpIAdd %5 %25 %56\n%58 = OpImageTexelPointer %57 %15 %55 %24\n%59 = OpAtomicIAdd %12 %58 %56 %24 %54\n%60 = OpLoad %9 %11\n%62 = OpCompositeConstruct %33 %25 %25\n%61 = OpImageFetch %27 %60 %62 Lod %24\n%63 = OpCompositeExtract %5 %61 0\n%64 = OpCompositeExtract %5 %61 1\n%65 = OpLoad %16 %18\n%66 = OpCompositeConstruct %33 %25 %25\n%67 = OpCompositeConstruct %27 %63 %64 %63 %64\n%68 = OpVectorShuffle %33 %67 %67 0 1\n%69 = OpBitcast %12 %68\n%70 = OpVectorShuffle %33 %67 %67 2 3\n%71 = OpBitcast %12 %70\n%72 = OpCompositeConstruct %39 %69 %71 %38 %38\nOpImageWrite %65 %66 %72\n%73 = OpIAdd %5 %25 %74\n%75 = OpIAdd %5 %25 %76\n%77 = OpLoad %16 %18\n%79 = OpCompositeConstruct %33 %73 %75\n%78 = OpImageRead %39 %77 %79 None\n%80 = OpCompositeExtract %12 %78 0\n%81 = OpBitcast %33 %80\n%82 = OpCompositeConstruct %27 %81 %24 %24\n%83 = OpCompositeExtract %5 %82 0\n%84 = OpCompositeExtract %5 %82 1\n%85 = OpUConvert %12 %83\n%86 = OpUConvert %12 %84\n%87 = OpShiftLeftLogical %12 %86 %53\n%88 = OpBitwiseOr %12 %87 %85\n%89 = OpIAdd %5 %25 %90\n%91 = OpCompositeConstruct %33 %55 %89\n%92 = OpImageTexelPointer %57 %18 %91 %24\n%93 = OpAtomicIAdd %12 %92 %56 %24 %88\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/atomics-typed-64bit-heap.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_image_int64 : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r64ui) uniform u64imageBuffer _9[];\nlayout(set = 0, binding = 0, r64ui) uniform u64image2D _13[];\n\nvoid main()\n{\n    uint64_t _35 = uint64_t(gl_GlobalInvocationID.x);\n    uint64_t _38 = imageAtomicAdd(_9[0u], int(0u), _35);\n    uint64_t _40 = imageAtomicAnd(_9[1u], int(1u), _35);\n    uint64_t _42 = imageAtomicOr(_9[0u], int(2u), _35);\n    uint64_t _44 = imageAtomicXor(_9[1u], int(3u), _35);\n    uint64_t _47 = imageAtomicMin(_9[0u], int(4u), _35);\n    uint64_t _50 = imageAtomicMax(_9[0u], int(5u), _35);\n    uint64_t _53 = imageAtomicMin(_9[1u], int(6u), _35);\n    uint64_t _56 = imageAtomicMax(_9[1u], int(7u), _35);\n    uint64_t _59 = imageAtomicExchange(_9[1u], int(8u), _35);\n    uint64_t _62 = imageAtomicCompSwap(_9[0u], int(9u), 10ul, _59);\n    uint64_t _66 = imageAtomicCompSwap(_9[1u], int(10u), 20ul, _35);\n    uint64_t _71 = imageAtomicAdd(_13[2u], ivec2(uvec2(1u, 2u)), _35);\n    uint64_t _74 = imageAtomicAdd(_13[3u], ivec2(uvec2(3u, 4u)), _35);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 77\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability ImageBuffer\nOpCapability Int64ImageEXT\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_shader_image_int64\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 64 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R64ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeImage %5 2D 0 0 0 2 R64ui\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeInt 32 0\n%15 = OpTypeVector %14 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %14\n%20 = OpConstant %14 0\n%22 = OpTypePointer UniformConstant %6\n%26 = OpConstant %14 1\n%28 = OpTypePointer UniformConstant %10\n%30 = OpConstant %14 2\n%33 = OpConstant %14 3\n%36 = OpTypePointer Image %5\n%45 = OpConstant %14 4\n%48 = OpConstant %14 5\n%51 = OpConstant %14 6\n%54 = OpConstant %14 7\n%57 = OpConstant %14 8\n%60 = OpConstant %14 9\n%63 = OpConstant %5 10\n%64 = OpConstant %14 10\n%67 = OpConstant %5 20\n%68 = OpTypeVector %14 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %14 %19\n%23 = OpAccessChain %22 %9 %20\n%24 = OpLoad %6 %23\n%25 = OpAccessChain %22 %9 %26\n%27 = OpLoad %6 %25\n%29 = OpAccessChain %28 %13 %30\n%31 = OpLoad %10 %29\n%32 = OpAccessChain %28 %13 %33\n%34 = OpLoad %10 %32\n%35 = OpUConvert %5 %21\n%37 = OpImageTexelPointer %36 %23 %20 %20\n%38 = OpAtomicIAdd %5 %37 %26 %20 %35\n%39 = OpImageTexelPointer %36 %25 %26 %20\n%40 = OpAtomicAnd %5 %39 %26 %20 %35\n%41 = OpImageTexelPointer %36 %23 %30 %20\n%42 = OpAtomicOr %5 %41 %26 %20 %35\n%43 = OpImageTexelPointer %36 %25 %33 %20\n%44 = OpAtomicXor %5 %43 %26 %20 %35\n%46 = OpImageTexelPointer %36 %23 %45 %20\n%47 = OpAtomicUMin %5 %46 %26 %20 %35\n%49 = OpImageTexelPointer %36 %23 %48 %20\n%50 = OpAtomicUMax %5 %49 %26 %20 %35\n%52 = OpImageTexelPointer %36 %25 %51 %20\n%53 = OpAtomicSMin %5 %52 %26 %20 %35\n%55 = OpImageTexelPointer %36 %25 %54 %20\n%56 = OpAtomicSMax %5 %55 %26 %20 %35\n%58 = OpImageTexelPointer %36 %25 %57 %20\n%59 = OpAtomicExchange %5 %58 %26 %20 %35\n%61 = OpImageTexelPointer %36 %23 %60 %20\n%62 = OpAtomicCompareExchange %5 %61 %26 %20 %20 %59 %63\n%65 = OpImageTexelPointer %36 %25 %64 %20\n%66 = OpAtomicCompareExchange %5 %65 %26 %20 %20 %35 %67\n%69 = OpCompositeConstruct %68 %26 %30\n%70 = OpImageTexelPointer %36 %29 %69 %20\n%71 = OpAtomicIAdd %5 %70 %26 %20 %35\n%72 = OpCompositeConstruct %68 %33 %45\n%73 = OpImageTexelPointer %36 %32 %72 %20\n%74 = OpAtomicIAdd %5 %73 %26 %20 %35\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/atomics-typed-64bit.bindless.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_image_int64 : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 4, binding = 0, r64ui) uniform u64imageBuffer _13[];\nlayout(set = 3, binding = 0, r64ui) uniform u64image2D _17[];\n\nvoid main()\n{\n    uint64_t _25 = uint64_t(gl_GlobalInvocationID.x);\n    uint64_t _35 = imageAtomicAdd(_13[registers._m4], int(0u), _25);\n    uint64_t _43 = imageAtomicAnd(_13[registers._m4 + 1u], int(1u), _25);\n    uint64_t _50 = imageAtomicOr(_13[registers._m4], int(2u), _25);\n    uint64_t _58 = imageAtomicXor(_13[registers._m4 + 1u], int(3u), _25);\n    uint64_t _64 = imageAtomicMin(_13[registers._m4], int(4u), _25);\n    uint64_t _71 = imageAtomicMax(_13[registers._m4], int(5u), _25);\n    uint64_t _79 = imageAtomicMin(_13[registers._m4 + 1u], int(6u), _25);\n    uint64_t _87 = imageAtomicMax(_13[registers._m4 + 1u], int(7u), _25);\n    uint64_t _95 = imageAtomicExchange(_13[registers._m4 + 1u], int(8u), _25);\n    uint64_t _102 = imageAtomicCompSwap(_13[registers._m4], int(9u), 10ul, _95);\n    uint64_t _111 = imageAtomicCompSwap(_13[registers._m4 + 1u], int(10u), 20ul, _25);\n    uint64_t _122 = imageAtomicAdd(_17[registers._m3 + 2u], ivec2(uvec2(1u, 2u)), _25);\n    uint64_t _130 = imageAtomicAdd(_17[registers._m3 + 3u], ivec2(uvec2(3u, 4u)), _25);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 133\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability ImageBuffer\nOpCapability Int64ImageEXT\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_shader_image_int64\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %20\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 4\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 3\nOpDecorate %17 Binding 0\nOpDecorate %20 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeInt 64 0\n%10 = OpTypeImage %9 Buffer 0 0 0 2 R64ui\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 2D 0 0 0 2 R64ui\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %5 3\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Input %5\n%23 = OpConstant %5 0\n%26 = OpTypePointer UniformConstant %10\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 4\n%33 = OpTypePointer Image %9\n%36 = OpConstant %5 1\n%48 = OpConstant %5 2\n%56 = OpConstant %5 3\n%69 = OpConstant %5 5\n%77 = OpConstant %5 6\n%85 = OpConstant %5 7\n%93 = OpConstant %5 8\n%100 = OpConstant %5 9\n%103 = OpConstant %9 10\n%109 = OpConstant %5 10\n%112 = OpConstant %9 20\n%113 = OpTypePointer UniformConstant %14\n%119 = OpTypeVector %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %131\n%131 = OpLabel\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpUConvert %9 %24\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%27 = OpAccessChain %26 %13 %31\n%32 = OpLoad %10 %27\n%34 = OpImageTexelPointer %33 %27 %23 %23\n%35 = OpAtomicIAdd %9 %34 %36 %23 %25\n%38 = OpAccessChain %28 %8 %30\n%39 = OpLoad %5 %38\n%40 = OpIAdd %5 %39 %36\n%37 = OpAccessChain %26 %13 %40\n%41 = OpLoad %10 %37\n%42 = OpImageTexelPointer %33 %37 %36 %23\n%43 = OpAtomicAnd %9 %42 %36 %23 %25\n%45 = OpAccessChain %28 %8 %30\n%46 = OpLoad %5 %45\n%44 = OpAccessChain %26 %13 %46\n%47 = OpLoad %10 %44\n%49 = OpImageTexelPointer %33 %44 %48 %23\n%50 = OpAtomicOr %9 %49 %36 %23 %25\n%52 = OpAccessChain %28 %8 %30\n%53 = OpLoad %5 %52\n%54 = OpIAdd %5 %53 %36\n%51 = OpAccessChain %26 %13 %54\n%55 = OpLoad %10 %51\n%57 = OpImageTexelPointer %33 %51 %56 %23\n%58 = OpAtomicXor %9 %57 %36 %23 %25\n%60 = OpAccessChain %28 %8 %30\n%61 = OpLoad %5 %60\n%59 = OpAccessChain %26 %13 %61\n%62 = OpLoad %10 %59\n%63 = OpImageTexelPointer %33 %59 %30 %23\n%64 = OpAtomicUMin %9 %63 %36 %23 %25\n%66 = OpAccessChain %28 %8 %30\n%67 = OpLoad %5 %66\n%65 = OpAccessChain %26 %13 %67\n%68 = OpLoad %10 %65\n%70 = OpImageTexelPointer %33 %65 %69 %23\n%71 = OpAtomicUMax %9 %70 %36 %23 %25\n%73 = OpAccessChain %28 %8 %30\n%74 = OpLoad %5 %73\n%75 = OpIAdd %5 %74 %36\n%72 = OpAccessChain %26 %13 %75\n%76 = OpLoad %10 %72\n%78 = OpImageTexelPointer %33 %72 %77 %23\n%79 = OpAtomicSMin %9 %78 %36 %23 %25\n%81 = OpAccessChain %28 %8 %30\n%82 = OpLoad %5 %81\n%83 = OpIAdd %5 %82 %36\n%80 = OpAccessChain %26 %13 %83\n%84 = OpLoad %10 %80\n%86 = OpImageTexelPointer %33 %80 %85 %23\n%87 = OpAtomicSMax %9 %86 %36 %23 %25\n%89 = OpAccessChain %28 %8 %30\n%90 = OpLoad %5 %89\n%91 = OpIAdd %5 %90 %36\n%88 = OpAccessChain %26 %13 %91\n%92 = OpLoad %10 %88\n%94 = OpImageTexelPointer %33 %88 %93 %23\n%95 = OpAtomicExchange %9 %94 %36 %23 %25\n%97 = OpAccessChain %28 %8 %30\n%98 = OpLoad %5 %97\n%96 = OpAccessChain %26 %13 %98\n%99 = OpLoad %10 %96\n%101 = OpImageTexelPointer %33 %96 %100 %23\n%102 = OpAtomicCompareExchange %9 %101 %36 %23 %23 %95 %103\n%105 = OpAccessChain %28 %8 %30\n%106 = OpLoad %5 %105\n%107 = OpIAdd %5 %106 %36\n%104 = OpAccessChain %26 %13 %107\n%108 = OpLoad %10 %104\n%110 = OpImageTexelPointer %33 %104 %109 %23\n%111 = OpAtomicCompareExchange %9 %110 %36 %23 %23 %25 %112\n%115 = OpAccessChain %28 %8 %56\n%116 = OpLoad %5 %115\n%117 = OpIAdd %5 %116 %48\n%114 = OpAccessChain %113 %17 %117\n%118 = OpLoad %14 %114\n%120 = OpCompositeConstruct %119 %36 %48\n%121 = OpImageTexelPointer %33 %114 %120 %23\n%122 = OpAtomicIAdd %9 %121 %36 %23 %25\n%124 = OpAccessChain %28 %8 %56\n%125 = OpLoad %5 %124\n%126 = OpIAdd %5 %125 %56\n%123 = OpAccessChain %113 %17 %126\n%127 = OpLoad %14 %123\n%128 = OpCompositeConstruct %119 %56 %30\n%129 = OpImageTexelPointer %33 %123 %128 %23\n%130 = OpAtomicIAdd %9 %129 %36 %23 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/atomics-typed-64bit.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_shader_image_int64 : require\n#extension GL_EXT_shader_atomic_int64 : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r64ui) uniform u64imageBuffer _8;\nlayout(set = 0, binding = 1, r64ui) uniform u64imageBuffer _9;\nlayout(set = 0, binding = 2, r64ui) uniform u64image2D _12;\nlayout(set = 0, binding = 3, r64ui) uniform u64image2D _13;\n\nvoid main()\n{\n    uint64_t _22 = uint64_t(gl_GlobalInvocationID.x);\n    uint64_t _26 = imageAtomicAdd(_8, int(0u), _22);\n    uint64_t _30 = imageAtomicAnd(_9, int(1u), _22);\n    uint64_t _34 = imageAtomicOr(_8, int(2u), _22);\n    uint64_t _38 = imageAtomicXor(_9, int(3u), _22);\n    uint64_t _42 = imageAtomicMin(_8, int(4u), _22);\n    uint64_t _46 = imageAtomicMax(_8, int(5u), _22);\n    uint64_t _50 = imageAtomicMin(_9, int(6u), _22);\n    uint64_t _54 = imageAtomicMax(_9, int(7u), _22);\n    uint64_t _58 = imageAtomicExchange(_9, int(8u), _22);\n    uint64_t _62 = imageAtomicCompSwap(_8, int(9u), 10ul, _58);\n    uint64_t _67 = imageAtomicCompSwap(_9, int(10u), 20ul, _22);\n    uint64_t _73 = imageAtomicAdd(_12, ivec2(uvec2(1u, 2u)), _22);\n    uint64_t _77 = imageAtomicAdd(_13, ivec2(uvec2(3u, 4u)), _22);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 80\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability ImageBuffer\nOpCapability Int64ImageEXT\nOpExtension \"SPV_EXT_shader_image_int64\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 2\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 3\nOpDecorate %17 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 64 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R64ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 2D 0 0 0 2 R64ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpVariable %11 UniformConstant\n%14 = OpTypeInt 32 0\n%15 = OpTypeVector %14 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %14\n%20 = OpConstant %14 0\n%24 = OpTypePointer Image %5\n%27 = OpConstant %14 1\n%32 = OpConstant %14 2\n%36 = OpConstant %14 3\n%40 = OpConstant %14 4\n%44 = OpConstant %14 5\n%48 = OpConstant %14 6\n%52 = OpConstant %14 7\n%56 = OpConstant %14 8\n%60 = OpConstant %14 9\n%63 = OpConstant %5 10\n%65 = OpConstant %14 10\n%68 = OpConstant %5 20\n%70 = OpTypeVector %14 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %78\n%78 = OpLabel\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %14 %19\n%22 = OpUConvert %5 %21\n%23 = OpLoad %6 %8\n%25 = OpImageTexelPointer %24 %8 %20 %20\n%26 = OpAtomicIAdd %5 %25 %27 %20 %22\n%28 = OpLoad %6 %9\n%29 = OpImageTexelPointer %24 %9 %27 %20\n%30 = OpAtomicAnd %5 %29 %27 %20 %22\n%31 = OpLoad %6 %8\n%33 = OpImageTexelPointer %24 %8 %32 %20\n%34 = OpAtomicOr %5 %33 %27 %20 %22\n%35 = OpLoad %6 %9\n%37 = OpImageTexelPointer %24 %9 %36 %20\n%38 = OpAtomicXor %5 %37 %27 %20 %22\n%39 = OpLoad %6 %8\n%41 = OpImageTexelPointer %24 %8 %40 %20\n%42 = OpAtomicUMin %5 %41 %27 %20 %22\n%43 = OpLoad %6 %8\n%45 = OpImageTexelPointer %24 %8 %44 %20\n%46 = OpAtomicUMax %5 %45 %27 %20 %22\n%47 = OpLoad %6 %9\n%49 = OpImageTexelPointer %24 %9 %48 %20\n%50 = OpAtomicSMin %5 %49 %27 %20 %22\n%51 = OpLoad %6 %9\n%53 = OpImageTexelPointer %24 %9 %52 %20\n%54 = OpAtomicSMax %5 %53 %27 %20 %22\n%55 = OpLoad %6 %9\n%57 = OpImageTexelPointer %24 %9 %56 %20\n%58 = OpAtomicExchange %5 %57 %27 %20 %22\n%59 = OpLoad %6 %8\n%61 = OpImageTexelPointer %24 %8 %60 %20\n%62 = OpAtomicCompareExchange %5 %61 %27 %20 %20 %58 %63\n%64 = OpLoad %6 %9\n%66 = OpImageTexelPointer %24 %9 %65 %20\n%67 = OpAtomicCompareExchange %5 %66 %27 %20 %20 %22 %68\n%69 = OpLoad %10 %12\n%71 = OpCompositeConstruct %70 %27 %32\n%72 = OpImageTexelPointer %24 %12 %71 %20\n%73 = OpAtomicIAdd %5 %72 %27 %20 %22\n%74 = OpLoad %10 %13\n%75 = OpCompositeConstruct %70 %36 %40\n%76 = OpImageTexelPointer %24 %13 %75 %20\n%77 = OpAtomicIAdd %5 %76 %27 %20 %22\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/binding-range-selection.bindless.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _17;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _12[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _22[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _60, uint _61, uint _62)\n{\n    uint _76;\n    if (any(notEqual(_60, uvec2(0u))))\n    {\n        uint _73 = atomicAdd(uintPointer(_60).value, _61);\n        _76 = _73 + _62;\n    }\n    else\n    {\n        _76 = 0u;\n    }\n    return _76;\n}\n\nvoid main()\n{\n    if (gl_GlobalInvocationID.x > 80u)\n    {\n        imageStore(_22[registers._m3 + 6u], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(0.0));\n        if (gl_GlobalInvocationID.x > 90u)\n        {\n            imageStore(_22[registers._m3 + ((gl_GlobalInvocationID.x & 1u) + 7u)], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), vec4(0.0));\n        }\n    }\n    uvec2 _58 = _17.counters[registers._m4];\n    uint _78 = RobustPhysicalAtomicCounter(_58, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %25\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"AtomicCounters\"\nOpMemberName %15 0 \"counters\"\nOpName %63 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %12 NonWritable\nOpDecorate %14 ArrayStride 8\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpMemberDecorate %15 0 NonWritable\nOpDecorate %17 DescriptorSet 7\nOpDecorate %17 Binding 0\nOpDecorate %17 AliasedPointer\nOpDecorate %22 DescriptorSet 3\nOpDecorate %22 Binding 0\nOpDecorate %22 NonReadable\nOpDecorate %25 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %5 2\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypeStruct %14\n%16 = OpTypePointer StorageBuffer %15\n%17 = OpVariable %16 StorageBuffer\n%18 = OpTypeFloat 32\n%19 = OpTypeImage %18 2D 0 0 0 2 Unknown\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeVector %5 3\n%24 = OpTypePointer Input %23\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Input %5\n%28 = OpConstant %5 0\n%30 = OpTypeBool\n%32 = OpConstant %5 80\n%33 = OpTypePointer UniformConstant %19\n%35 = OpTypePointer PushConstant %5\n%37 = OpConstant %5 3\n%40 = OpConstant %5 6\n%42 = OpConstant %18 0\n%44 = OpTypeVector %18 4\n%47 = OpConstant %5 90\n%48 = OpTypePointer UniformConstant %9\n%51 = OpConstant %5 4\n%54 = OpTypePointer StorageBuffer %13\n%59 = OpTypeFunction %5 %13 %5 %5\n%67 = OpTypeVector %30 2\n%68 = OpConstantNull %13\n%71 = OpTypePointer PhysicalStorageBuffer %5\n%74 = OpConstant %5 1\n%81 = OpConstant %5 7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %89\n%89 = OpLabel\n%27 = OpAccessChain %26 %25 %28\n%29 = OpLoad %5 %27\n%31 = OpUGreaterThan %30 %29 %32\nOpSelectionMerge %93 None\nOpBranchConditional %31 %90 %93\n%90 = OpLabel\n%36 = OpAccessChain %35 %8 %37\n%38 = OpLoad %5 %36\n%39 = OpIAdd %5 %38 %40\n%34 = OpAccessChain %33 %22 %39\n%41 = OpLoad %19 %34\n%43 = OpCompositeConstruct %13 %29 %28\n%45 = OpCompositeConstruct %44 %42 %42 %42 %42\nOpImageWrite %41 %43 %45\n%46 = OpUGreaterThan %30 %29 %47\nOpSelectionMerge %92 None\nOpBranchConditional %46 %91 %92\n%91 = OpLabel\n%79 = OpBitwiseAnd %5 %29 %74\n%80 = OpIAdd %5 %79 %81\n%83 = OpAccessChain %35 %8 %37\n%84 = OpLoad %5 %83\n%85 = OpIAdd %5 %84 %80\n%82 = OpAccessChain %33 %22 %85\n%86 = OpLoad %19 %82\n%87 = OpCompositeConstruct %13 %28 %29\n%88 = OpCompositeConstruct %44 %42 %42 %42 %42\nOpImageWrite %86 %87 %88\nOpBranch %92\n%92 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%50 = OpAccessChain %35 %8 %51\n%52 = OpLoad %5 %50\n%49 = OpAccessChain %48 %12 %52\n%53 = OpLoad %9 %49\n%56 = OpAccessChain %35 %8 %51\n%57 = OpLoad %5 %56\n%55 = OpAccessChain %54 %17 %28 %57\n%58 = OpLoad %13 %55\n%78 = OpFunctionCall %5 %63 %58 %74 %28\nOpReturn\nOpFunctionEnd\n%63 = OpFunction %5 None %59\n%60 = OpFunctionParameter %13\n%61 = OpFunctionParameter %5\n%62 = OpFunctionParameter %5\n%64 = OpLabel\n%69 = OpINotEqual %67 %60 %68\n%70 = OpAny %30 %69\nOpSelectionMerge %66 None\nOpBranchConditional %70 %65 %66\n%65 = OpLabel\n%72 = OpBitcast %71 %60\n%73 = OpAtomicIAdd %5 %72 %74 %28 %61\n%75 = OpIAdd %5 %73 %62\nOpBranch %66\n%66 = OpLabel\n%76 = OpPhi %5 %28 %64 %75 %65\nOpReturnValue %76\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/binding-range-selection.sm66.comp",
    "content": "#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _8;\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _9;\nlayout(set = 0, binding = 6) uniform writeonly image2D _13;\nlayout(set = 0, binding = 7) uniform writeonly image2D _17[2];\n\nvoid main()\n{\n    if (gl_GlobalInvocationID.x > 80u)\n    {\n        imageStore(_13, ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(0.0));\n        if (gl_GlobalInvocationID.x > 90u)\n        {\n            uint _41 = gl_GlobalInvocationID.x & 1u;\n            imageStore(_17[_41], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), vec4(0.0));\n        }\n    }\n    uint _39 = imageAtomicAdd(_9, int(0u), 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %20\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %8 NonWritable\nOpDecorate %9 DescriptorSet 7\nOpDecorate %9 Binding 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 6\nOpDecorate %13 NonReadable\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 7\nOpDecorate %17 NonReadable\nOpDecorate %20 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeImage %10 2D 0 0 0 2 Unknown\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpConstant %5 2\n%15 = OpTypeArray %11 %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeVector %5 3\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Input %5\n%23 = OpConstant %5 0\n%25 = OpTypeBool\n%27 = OpConstant %5 80\n%29 = OpConstant %10 0\n%30 = OpTypeVector %5 2\n%32 = OpTypeVector %10 4\n%35 = OpConstant %5 90\n%37 = OpTypePointer Image %5\n%40 = OpConstant %5 1\n%43 = OpConstant %5 7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %48\n%48 = OpLabel\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%26 = OpUGreaterThan %25 %24 %27\nOpSelectionMerge %52 None\nOpBranchConditional %26 %49 %52\n%49 = OpLabel\n%28 = OpLoad %11 %13\n%31 = OpCompositeConstruct %30 %24 %23\n%33 = OpCompositeConstruct %32 %29 %29 %29 %29\nOpImageWrite %28 %31 %33\n%34 = OpUGreaterThan %25 %24 %35\nOpSelectionMerge %51 None\nOpBranchConditional %34 %50 %51\n%50 = OpLabel\n%41 = OpBitwiseAnd %5 %24 %40\n%42 = OpIAdd %5 %41 %43\n%44 = OpAccessChain %12 %17 %41\n%45 = OpLoad %11 %44\n%46 = OpCompositeConstruct %30 %23 %24\n%47 = OpCompositeConstruct %32 %29 %29 %29 %29\nOpImageWrite %45 %46 %47\nOpBranch %51\n%51 = OpLabel\nOpBranch %52\n%52 = OpLabel\n%36 = OpLoad %6 %8\n%38 = OpImageTexelPointer %37 %9 %23 %23\n%39 = OpAtomicIAdd %5 %38 %40 %23 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/buffer-64bit-double.ssbo.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, scalar) buffer SSBO\n{\n    dvec3 _m0[];\n} _11[];\n\nlayout(set = 0, binding = 0, scalar) restrict readonly buffer _13_16\n{\n    dvec3 _m0[];\n} _16[];\n\nlayout(set = 0, binding = 0, std430) buffer _18_21\n{\n    double _m0[];\n} _21[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _23_26\n{\n    double _m0[];\n} _26[];\n\nvoid main()\n{\n    uint _47 = gl_GlobalInvocationID.x * 2u;\n    uint _56 = (gl_GlobalInvocationID.x * 2u) + 1u;\n    uint _65 = gl_GlobalInvocationID.x << 2u;\n    _11[0u]._m0[gl_GlobalInvocationID.x * 4u] = dvec3(_16[1u]._m0[_56].x + _16[1u]._m0[_47].x, _16[1u]._m0[_56].y + _16[1u]._m0[_47].y, _16[1u]._m0[_56].z + _16[1u]._m0[_47].z);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 4u) + 1u] = dvec3(_16[1u]._m0[_47].x - _16[1u]._m0[_56].x, _16[1u]._m0[_47].y - _16[1u]._m0[_56].y, _16[1u]._m0[_47].z - _16[1u]._m0[_56].z);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 4u) + 2u] = dvec3(_16[1u]._m0[_56].x * _16[1u]._m0[_47].x, _16[1u]._m0[_56].y * _16[1u]._m0[_47].y, _16[1u]._m0[_56].z * _16[1u]._m0[_47].z);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 4u) + 3u] = dvec3(_16[1u]._m0[_47].x / _16[1u]._m0[_56].x, _16[1u]._m0[_47].y / _16[1u]._m0[_56].y, _16[1u]._m0[_47].z / _16[1u]._m0[_56].z);\n    uint _96 = gl_GlobalInvocationID.x * 3u;\n    dvec2 _104 = dvec2(_26[3u]._m0[_96], _26[3u]._m0[_96 + 1u]);\n    _21[2u]._m0[gl_GlobalInvocationID.x] = _104.x;\n    _21[2u]._m0[gl_GlobalInvocationID.x + 1u] = _104.y;\n    _21[2u]._m0[gl_GlobalInvocationID.x + 2u] = _16[1u]._m0[_47].z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 115\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %30\nOpExecutionMode %3 LocalSize 128 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %18 \"SSBO\"\nOpName %23 \"SSBO\"\nOpDecorate %7 ArrayStride 24\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %12 ArrayStride 24\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %16 NonWritable\nOpDecorate %16 Restrict\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %22 ArrayStride 8\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %26 NonWritable\nOpDecorate %26 Restrict\nOpDecorate %30 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 64\n%6 = OpTypeVector %5 3\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeRuntimeArray %6\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeRuntimeArray %5\n%18 = OpTypeStruct %17\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %5\n%23 = OpTypeStruct %22\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeInt 32 0\n%28 = OpTypeVector %27 3\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%31 = OpTypePointer Input %27\n%33 = OpConstant %27 0\n%35 = OpTypePointer StorageBuffer %8\n%37 = OpTypePointer StorageBuffer %13\n%39 = OpConstant %27 1\n%40 = OpTypePointer StorageBuffer %18\n%42 = OpConstant %27 2\n%43 = OpTypePointer StorageBuffer %23\n%45 = OpConstant %27 3\n%48 = OpTypePointer StorageBuffer %6\n%67 = OpConstant %27 4\n%95 = OpConstant %27 24\n%97 = OpTypePointer StorageBuffer %5\n%103 = OpTypeVector %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %113\n%113 = OpLabel\n%32 = OpAccessChain %31 %30 %33\n%34 = OpLoad %27 %32\n%36 = OpAccessChain %35 %11 %33\n%38 = OpAccessChain %37 %16 %39\n%41 = OpAccessChain %40 %21 %42\n%44 = OpAccessChain %43 %26 %45\n%46 = OpShiftLeftLogical %27 %34 %39\n%47 = OpIMul %27 %34 %42\n%49 = OpAccessChain %48 %38 %33 %47\n%50 = OpLoad %6 %49\n%51 = OpCompositeExtract %5 %50 0\n%52 = OpCompositeExtract %5 %50 1\n%53 = OpCompositeExtract %5 %50 2\n%54 = OpBitwiseOr %27 %46 %39\n%55 = OpIMul %27 %34 %42\n%56 = OpIAdd %27 %55 %39\n%57 = OpAccessChain %48 %38 %33 %56\n%58 = OpLoad %6 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpCompositeExtract %5 %58 1\n%61 = OpCompositeExtract %5 %58 2\n%62 = OpFAdd %5 %59 %51\n%63 = OpFAdd %5 %60 %52\n%64 = OpFAdd %5 %61 %53\n%65 = OpShiftLeftLogical %27 %34 %42\n%66 = OpIMul %27 %34 %67\n%68 = OpCompositeConstruct %6 %62 %63 %64\n%69 = OpAccessChain %48 %36 %33 %66\nOpStore %69 %68\n%70 = OpFSub %5 %51 %59\n%71 = OpFSub %5 %52 %60\n%72 = OpFSub %5 %53 %61\n%73 = OpBitwiseOr %27 %65 %39\n%74 = OpIMul %27 %34 %67\n%75 = OpIAdd %27 %74 %39\n%76 = OpCompositeConstruct %6 %70 %71 %72\n%77 = OpAccessChain %48 %36 %33 %75\nOpStore %77 %76\n%78 = OpFMul %5 %59 %51\n%79 = OpFMul %5 %60 %52\n%80 = OpFMul %5 %61 %53\n%81 = OpBitwiseOr %27 %65 %42\n%82 = OpIMul %27 %34 %67\n%83 = OpIAdd %27 %82 %42\n%84 = OpCompositeConstruct %6 %78 %79 %80\n%85 = OpAccessChain %48 %36 %33 %83\nOpStore %85 %84\n%86 = OpFDiv %5 %51 %59\n%87 = OpFDiv %5 %52 %60\n%88 = OpFDiv %5 %53 %61\n%89 = OpBitwiseOr %27 %65 %45\n%90 = OpIMul %27 %34 %67\n%91 = OpIAdd %27 %90 %45\n%92 = OpCompositeConstruct %6 %86 %87 %88\n%93 = OpAccessChain %48 %36 %33 %91\nOpStore %93 %92\n%94 = OpIMul %27 %34 %95\n%96 = OpIMul %27 %34 %45\n%98 = OpAccessChain %97 %44 %33 %96\n%99 = OpLoad %5 %98\n%101 = OpIAdd %27 %96 %39\n%100 = OpAccessChain %97 %44 %33 %101\n%102 = OpLoad %5 %100\n%104 = OpCompositeConstruct %103 %99 %102\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpCompositeExtract %5 %104 1\n%107 = OpShiftLeftLogical %27 %34 %45\n%108 = OpAccessChain %97 %41 %33 %34\nOpStore %108 %105\n%110 = OpIAdd %27 %34 %39\n%109 = OpAccessChain %97 %41 %33 %110\nOpStore %109 %106\n%112 = OpIAdd %27 %34 %42\n%111 = OpAccessChain %97 %41 %33 %112\nOpStore %111 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/buffer-64bit.ssbo.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, scalar) buffer SSBO\n{\n    u64vec3 _m0[];\n} _11[];\n\nlayout(set = 0, binding = 0, scalar) restrict readonly buffer _13_16\n{\n    u64vec3 _m0[];\n} _16[];\n\nlayout(set = 0, binding = 0, std430) buffer _18_21\n{\n    uint64_t _m0[];\n} _21[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _23_26\n{\n    uint64_t _m0[];\n} _26[];\n\nvoid main()\n{\n    uint _47 = gl_GlobalInvocationID.x * 2u;\n    uint _56 = (gl_GlobalInvocationID.x * 2u) + 1u;\n    uint _65 = gl_GlobalInvocationID.x << 3u;\n    _11[0u]._m0[gl_GlobalInvocationID.x * 8u] = u64vec3(_16[1u]._m0[_56].x + _16[1u]._m0[_47].x, _16[1u]._m0[_56].y + _16[1u]._m0[_47].y, _16[1u]._m0[_56].z + _16[1u]._m0[_47].z);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 8u) + 1u] = u64vec3(_16[1u]._m0[_47].x - _16[1u]._m0[_56].x, _16[1u]._m0[_47].y - _16[1u]._m0[_56].y, _16[1u]._m0[_47].z - _16[1u]._m0[_56].z);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 8u) + 2u] = u64vec3(_16[1u]._m0[_56].x * _16[1u]._m0[_47].x, _16[1u]._m0[_56].y * _16[1u]._m0[_47].y, _16[1u]._m0[_56].z * _16[1u]._m0[_47].z);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 8u) + 3u] = u64vec3(_16[1u]._m0[_47].x / _16[1u]._m0[_56].x, _16[1u]._m0[_47].y / _16[1u]._m0[_56].y, _16[1u]._m0[_47].z / _16[1u]._m0[_56].z);\n    uint64_t _94 = _16[1u]._m0[_56].x & 63ul;\n    uint64_t _96 = _16[1u]._m0[_56].y & 63ul;\n    uint64_t _97 = _16[1u]._m0[_56].z & 63ul;\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 8u) + 4u] = u64vec3(_16[1u]._m0[_47].x << _94, _16[1u]._m0[_47].y << _96, _16[1u]._m0[_47].z << _97);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 8u) + 5u] = u64vec3(_16[1u]._m0[_47].x >> _94, _16[1u]._m0[_47].y >> _96, _16[1u]._m0[_47].z >> _97);\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 8u) + 6u] = u64vec3(uint64_t(int64_t(_16[1u]._m0[_47].x) >> int64_t(_94)), uint64_t(int64_t(_16[1u]._m0[_47].y) >> int64_t(_96)), uint64_t(int64_t(_16[1u]._m0[_47].z) >> int64_t(_97)));\n    _11[0u]._m0[(gl_GlobalInvocationID.x * 8u) + 7u] = u64vec3(_16[1u]._m0[_56].x & _16[1u]._m0[_47].x, _16[1u]._m0[_56].y & _16[1u]._m0[_47].y, _16[1u]._m0[_56].z & _16[1u]._m0[_47].z);\n    uint _136 = gl_GlobalInvocationID.x * 3u;\n    u64vec2 _144 = u64vec2(_26[3u]._m0[_136], _26[3u]._m0[_136 + 1u]);\n    _21[2u]._m0[gl_GlobalInvocationID.x] = _144.x;\n    _21[2u]._m0[gl_GlobalInvocationID.x + 1u] = _144.y;\n    _21[2u]._m0[gl_GlobalInvocationID.x + 2u] = _16[1u]._m0[_47].z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 154\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %30\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %18 \"SSBO\"\nOpName %23 \"SSBO\"\nOpDecorate %7 ArrayStride 24\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %12 ArrayStride 24\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %16 NonWritable\nOpDecorate %16 Restrict\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %22 ArrayStride 8\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %26 NonWritable\nOpDecorate %26 Restrict\nOpDecorate %30 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 64 0\n%6 = OpTypeVector %5 3\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeRuntimeArray %6\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeRuntimeArray %5\n%18 = OpTypeStruct %17\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %5\n%23 = OpTypeStruct %22\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeInt 32 0\n%28 = OpTypeVector %27 3\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%31 = OpTypePointer Input %27\n%33 = OpConstant %27 0\n%35 = OpTypePointer StorageBuffer %8\n%37 = OpTypePointer StorageBuffer %13\n%39 = OpConstant %27 1\n%40 = OpTypePointer StorageBuffer %18\n%42 = OpConstant %27 2\n%43 = OpTypePointer StorageBuffer %23\n%45 = OpConstant %27 3\n%48 = OpTypePointer StorageBuffer %6\n%67 = OpConstant %27 8\n%95 = OpConstant %5 63\n%102 = OpConstant %27 4\n%111 = OpConstant %27 5\n%120 = OpConstant %27 6\n%129 = OpConstant %27 7\n%135 = OpConstant %27 24\n%137 = OpTypePointer StorageBuffer %5\n%143 = OpTypeVector %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %152\n%152 = OpLabel\n%32 = OpAccessChain %31 %30 %33\n%34 = OpLoad %27 %32\n%36 = OpAccessChain %35 %11 %33\n%38 = OpAccessChain %37 %16 %39\n%41 = OpAccessChain %40 %21 %42\n%44 = OpAccessChain %43 %26 %45\n%46 = OpShiftLeftLogical %27 %34 %39\n%47 = OpIMul %27 %34 %42\n%49 = OpAccessChain %48 %38 %33 %47\n%50 = OpLoad %6 %49\n%51 = OpCompositeExtract %5 %50 0\n%52 = OpCompositeExtract %5 %50 1\n%53 = OpCompositeExtract %5 %50 2\n%54 = OpBitwiseOr %27 %46 %39\n%55 = OpIMul %27 %34 %42\n%56 = OpIAdd %27 %55 %39\n%57 = OpAccessChain %48 %38 %33 %56\n%58 = OpLoad %6 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpCompositeExtract %5 %58 1\n%61 = OpCompositeExtract %5 %58 2\n%62 = OpIAdd %5 %59 %51\n%63 = OpIAdd %5 %60 %52\n%64 = OpIAdd %5 %61 %53\n%65 = OpShiftLeftLogical %27 %34 %45\n%66 = OpIMul %27 %34 %67\n%68 = OpCompositeConstruct %6 %62 %63 %64\n%69 = OpAccessChain %48 %36 %33 %66\nOpStore %69 %68\n%70 = OpISub %5 %51 %59\n%71 = OpISub %5 %52 %60\n%72 = OpISub %5 %53 %61\n%73 = OpBitwiseOr %27 %65 %39\n%74 = OpIMul %27 %34 %67\n%75 = OpIAdd %27 %74 %39\n%76 = OpCompositeConstruct %6 %70 %71 %72\n%77 = OpAccessChain %48 %36 %33 %75\nOpStore %77 %76\n%78 = OpIMul %5 %59 %51\n%79 = OpIMul %5 %60 %52\n%80 = OpIMul %5 %61 %53\n%81 = OpBitwiseOr %27 %65 %42\n%82 = OpIMul %27 %34 %67\n%83 = OpIAdd %27 %82 %42\n%84 = OpCompositeConstruct %6 %78 %79 %80\n%85 = OpAccessChain %48 %36 %33 %83\nOpStore %85 %84\n%86 = OpUDiv %5 %51 %59\n%87 = OpUDiv %5 %52 %60\n%88 = OpUDiv %5 %53 %61\n%89 = OpBitwiseOr %27 %65 %45\n%90 = OpIMul %27 %34 %67\n%91 = OpIAdd %27 %90 %45\n%92 = OpCompositeConstruct %6 %86 %87 %88\n%93 = OpAccessChain %48 %36 %33 %91\nOpStore %93 %92\n%94 = OpBitwiseAnd %5 %59 %95\n%96 = OpBitwiseAnd %5 %60 %95\n%97 = OpBitwiseAnd %5 %61 %95\n%98 = OpShiftLeftLogical %5 %51 %94\n%99 = OpShiftLeftLogical %5 %52 %96\n%100 = OpShiftLeftLogical %5 %53 %97\n%101 = OpBitwiseOr %27 %65 %102\n%103 = OpIMul %27 %34 %67\n%104 = OpIAdd %27 %103 %102\n%105 = OpCompositeConstruct %6 %98 %99 %100\n%106 = OpAccessChain %48 %36 %33 %104\nOpStore %106 %105\n%107 = OpShiftRightLogical %5 %51 %94\n%108 = OpShiftRightLogical %5 %52 %96\n%109 = OpShiftRightLogical %5 %53 %97\n%110 = OpBitwiseOr %27 %65 %111\n%112 = OpIMul %27 %34 %67\n%113 = OpIAdd %27 %112 %111\n%114 = OpCompositeConstruct %6 %107 %108 %109\n%115 = OpAccessChain %48 %36 %33 %113\nOpStore %115 %114\n%116 = OpShiftRightArithmetic %5 %51 %94\n%117 = OpShiftRightArithmetic %5 %52 %96\n%118 = OpShiftRightArithmetic %5 %53 %97\n%119 = OpBitwiseOr %27 %65 %120\n%121 = OpIMul %27 %34 %67\n%122 = OpIAdd %27 %121 %120\n%123 = OpCompositeConstruct %6 %116 %117 %118\n%124 = OpAccessChain %48 %36 %33 %122\nOpStore %124 %123\n%125 = OpBitwiseAnd %5 %59 %51\n%126 = OpBitwiseAnd %5 %60 %52\n%127 = OpBitwiseAnd %5 %61 %53\n%128 = OpBitwiseOr %27 %65 %129\n%130 = OpIMul %27 %34 %67\n%131 = OpIAdd %27 %130 %129\n%132 = OpCompositeConstruct %6 %125 %126 %127\n%133 = OpAccessChain %48 %36 %33 %131\nOpStore %133 %132\n%134 = OpIMul %27 %34 %135\n%136 = OpIMul %27 %34 %45\n%138 = OpAccessChain %137 %44 %33 %136\n%139 = OpLoad %5 %138\n%141 = OpIAdd %27 %136 %39\n%140 = OpAccessChain %137 %44 %33 %141\n%142 = OpLoad %5 %140\n%144 = OpCompositeConstruct %143 %139 %142\n%145 = OpCompositeExtract %5 %144 0\n%146 = OpCompositeExtract %5 %144 1\n%147 = OpAccessChain %137 %41 %33 %34\nOpStore %147 %145\n%149 = OpIAdd %27 %34 %39\n%148 = OpAccessChain %137 %41 %33 %149\nOpStore %148 %146\n%151 = OpIAdd %27 %34 %42\n%150 = OpAccessChain %137 %41 %33 %151\nOpStore %150 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/buffer-64bit.ssbo.ssbo-align.sm66.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint64_t _m0[];\n} _16[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _18_21\n{\n    uint64_t _m0[];\n} _21[];\n\nlayout(set = 0, binding = 0, std430) buffer _23_26\n{\n    uint64_t _m0[];\n} _26[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _28_31\n{\n    uint64_t _m0[];\n} _31[];\n\nvoid main()\n{\n    uvec2 _46 = _10._m0[subgroupBroadcastFirst(0u)] >> uvec2(3u);\n    uvec2 _54 = _10._m0[subgroupBroadcastFirst(1u)] >> uvec2(3u);\n    uvec2 _61 = _10._m0[subgroupBroadcastFirst(2u)] >> uvec2(3u);\n    uvec2 _67 = _10._m0[subgroupBroadcastFirst(3u)] >> uvec2(3u);\n    uint _69 = gl_GlobalInvocationID.x * 6u;\n    uint _76 = (_69 < _54.y) ? (_69 + _54.x) : 536870908u;\n    u64vec3 _88 = u64vec3(_21[1u]._m0[_76], _21[1u]._m0[_76 + 1u], _21[1u]._m0[_76 + 2u]);\n    uint64_t _89 = _88.x;\n    uint64_t _90 = _88.y;\n    uint64_t _91 = _88.z;\n    uint _94 = (gl_GlobalInvocationID.x * 6u) + 3u;\n    uint _99 = (_94 < _54.y) ? (_94 + _54.x) : 536870908u;\n    u64vec3 _108 = u64vec3(_21[1u]._m0[_99], _21[1u]._m0[_99 + 1u], _21[1u]._m0[_99 + 2u]);\n    uint64_t _109 = _108.x;\n    uint64_t _110 = _108.y;\n    uint64_t _111 = _108.z;\n    uint _115 = gl_GlobalInvocationID.x << 3u;\n    uint _116 = gl_GlobalInvocationID.x * 24u;\n    uint _122 = (_116 < _46.y) ? (_116 + _46.x) : 536870908u;\n    _16[0u]._m0[_122] = _109 + _89;\n    _16[0u]._m0[_122 + 1u] = _110 + _90;\n    _16[0u]._m0[_122 + 2u] = _111 + _91;\n    uint _133 = (gl_GlobalInvocationID.x * 24u) + 3u;\n    uint _138 = (_133 < _46.y) ? (_133 + _46.x) : 536870908u;\n    _16[0u]._m0[_138] = _89 - _109;\n    _16[0u]._m0[_138 + 1u] = _90 - _110;\n    _16[0u]._m0[_138 + 2u] = _91 - _111;\n    uint _149 = (gl_GlobalInvocationID.x * 24u) + 6u;\n    uint _154 = (_149 < _46.y) ? (_149 + _46.x) : 536870908u;\n    _16[0u]._m0[_154] = _109 * _89;\n    _16[0u]._m0[_154 + 1u] = _110 * _90;\n    _16[0u]._m0[_154 + 2u] = _111 * _91;\n    uint _166 = (gl_GlobalInvocationID.x * 24u) + 9u;\n    uint _171 = (_166 < _46.y) ? (_166 + _46.x) : 536870908u;\n    _16[0u]._m0[_171] = _89 / _109;\n    _16[0u]._m0[_171 + 1u] = _90 / _110;\n    _16[0u]._m0[_171 + 2u] = _91 / _111;\n    uint64_t _177 = _109 & 63ul;\n    uint64_t _179 = _110 & 63ul;\n    uint64_t _180 = _111 & 63ul;\n    uint _188 = (gl_GlobalInvocationID.x * 24u) + 12u;\n    uint _193 = (_188 < _46.y) ? (_188 + _46.x) : 536870908u;\n    _16[0u]._m0[_193] = _89 << _177;\n    _16[0u]._m0[_193 + 1u] = _90 << _179;\n    _16[0u]._m0[_193 + 2u] = _91 << _180;\n    uint _206 = (gl_GlobalInvocationID.x * 24u) + 15u;\n    uint _211 = (_206 < _46.y) ? (_206 + _46.x) : 536870908u;\n    _16[0u]._m0[_211] = _89 >> _177;\n    _16[0u]._m0[_211 + 1u] = _90 >> _179;\n    _16[0u]._m0[_211 + 2u] = _91 >> _180;\n    uint _223 = (gl_GlobalInvocationID.x * 24u) + 18u;\n    uint _228 = (_223 < _46.y) ? (_223 + _46.x) : 536870908u;\n    _16[0u]._m0[_228] = uint64_t(int64_t(_89) >> int64_t(_177));\n    _16[0u]._m0[_228 + 1u] = uint64_t(int64_t(_90) >> int64_t(_179));\n    _16[0u]._m0[_228 + 2u] = uint64_t(int64_t(_91) >> int64_t(_180));\n    uint _241 = (gl_GlobalInvocationID.x * 24u) + 21u;\n    uint _246 = (_241 < _46.y) ? (_241 + _46.x) : 536870908u;\n    _16[0u]._m0[_246] = _109 & _89;\n    _16[0u]._m0[_246 + 1u] = _110 & _90;\n    _16[0u]._m0[_246 + 2u] = _111 & _91;\n    uint _253 = gl_GlobalInvocationID.x * 3u;\n    uint _258 = (_253 < _67.y) ? (_253 + _67.x) : 536870908u;\n    u64vec2 _265 = u64vec2(_31[3u]._m0[_258], _31[3u]._m0[_258 + 1u]);\n    uint _272 = (gl_GlobalInvocationID.x < _61.y) ? (gl_GlobalInvocationID.x + _61.x) : 536870908u;\n    _26[2u]._m0[_272] = _265.x;\n    _26[2u]._m0[_272 + 1u] = _265.y;\n    _26[2u]._m0[_272 + 2u] = _91;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 280\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %34\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO_Offsets\"\nOpName %13 \"SSBO\"\nOpName %18 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %28 \"SSBO\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 15\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %12 ArrayStride 8\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %22 ArrayStride 8\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %27 ArrayStride 8\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 0\nOpDecorate %31 NonWritable\nOpDecorate %31 Restrict\nOpDecorate %34 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeInt 64 0\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeRuntimeArray %11\n%18 = OpTypeStruct %17\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeRuntimeArray %11\n%23 = OpTypeStruct %22\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeRuntimeArray %11\n%28 = OpTypeStruct %27\n%29 = OpTypeRuntimeArray %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeVector %5 3\n%33 = OpTypePointer Input %32\n%34 = OpVariable %33 Input\n%35 = OpTypePointer Input %5\n%37 = OpConstant %5 0\n%39 = OpTypePointer StorageBuffer %13\n%42 = OpConstant %5 3\n%43 = OpTypePointer StorageBuffer %6\n%47 = OpConstantComposite %6 %42 %42\n%48 = OpTypePointer StorageBuffer %18\n%50 = OpConstant %5 1\n%55 = OpTypePointer StorageBuffer %23\n%57 = OpConstant %5 2\n%62 = OpTypePointer StorageBuffer %28\n%70 = OpConstant %5 6\n%74 = OpTypeBool\n%77 = OpConstant %5 536870908\n%78 = OpTypePointer StorageBuffer %11\n%87 = OpTypeVector %11 3\n%117 = OpConstant %5 24\n%165 = OpConstant %5 9\n%178 = OpConstant %11 63\n%185 = OpConstant %5 4\n%187 = OpConstant %5 12\n%203 = OpConstant %5 5\n%205 = OpConstant %5 15\n%222 = OpConstant %5 18\n%238 = OpConstant %5 7\n%240 = OpConstant %5 21\n%264 = OpTypeVector %11 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %278\n%278 = OpLabel\n%36 = OpAccessChain %35 %34 %37\n%38 = OpLoad %5 %36\n%40 = OpAccessChain %39 %16 %37\n%41 = OpGroupNonUniformBroadcastFirst %5 %42 %37\n%44 = OpAccessChain %43 %10 %37 %41\n%45 = OpLoad %6 %44\n%46 = OpShiftRightLogical %6 %45 %47\n%49 = OpAccessChain %48 %21 %50\n%51 = OpGroupNonUniformBroadcastFirst %5 %42 %50\n%52 = OpAccessChain %43 %10 %37 %51\n%53 = OpLoad %6 %52\n%54 = OpShiftRightLogical %6 %53 %47\n%56 = OpAccessChain %55 %26 %57\n%58 = OpGroupNonUniformBroadcastFirst %5 %42 %57\n%59 = OpAccessChain %43 %10 %37 %58\n%60 = OpLoad %6 %59\n%61 = OpShiftRightLogical %6 %60 %47\n%63 = OpAccessChain %62 %31 %42\n%64 = OpGroupNonUniformBroadcastFirst %5 %42 %42\n%65 = OpAccessChain %43 %10 %37 %64\n%66 = OpLoad %6 %65\n%67 = OpShiftRightLogical %6 %66 %47\n%68 = OpShiftLeftLogical %5 %38 %50\n%69 = OpIMul %5 %38 %70\n%71 = OpCompositeExtract %5 %54 0\n%72 = OpCompositeExtract %5 %54 1\n%73 = OpIAdd %5 %69 %71\n%75 = OpULessThan %74 %69 %72\n%76 = OpSelect %5 %75 %73 %77\n%79 = OpAccessChain %78 %49 %37 %76\n%80 = OpLoad %11 %79\n%82 = OpIAdd %5 %76 %50\n%81 = OpAccessChain %78 %49 %37 %82\n%83 = OpLoad %11 %81\n%85 = OpIAdd %5 %76 %57\n%84 = OpAccessChain %78 %49 %37 %85\n%86 = OpLoad %11 %84\n%88 = OpCompositeConstruct %87 %80 %83 %86\n%89 = OpCompositeExtract %11 %88 0\n%90 = OpCompositeExtract %11 %88 1\n%91 = OpCompositeExtract %11 %88 2\n%92 = OpBitwiseOr %5 %68 %50\n%93 = OpIMul %5 %38 %70\n%94 = OpIAdd %5 %93 %42\n%95 = OpCompositeExtract %5 %54 0\n%96 = OpCompositeExtract %5 %54 1\n%97 = OpIAdd %5 %94 %95\n%98 = OpULessThan %74 %94 %96\n%99 = OpSelect %5 %98 %97 %77\n%100 = OpAccessChain %78 %49 %37 %99\n%101 = OpLoad %11 %100\n%103 = OpIAdd %5 %99 %50\n%102 = OpAccessChain %78 %49 %37 %103\n%104 = OpLoad %11 %102\n%106 = OpIAdd %5 %99 %57\n%105 = OpAccessChain %78 %49 %37 %106\n%107 = OpLoad %11 %105\n%108 = OpCompositeConstruct %87 %101 %104 %107\n%109 = OpCompositeExtract %11 %108 0\n%110 = OpCompositeExtract %11 %108 1\n%111 = OpCompositeExtract %11 %108 2\n%112 = OpIAdd %11 %109 %89\n%113 = OpIAdd %11 %110 %90\n%114 = OpIAdd %11 %111 %91\n%115 = OpShiftLeftLogical %5 %38 %42\n%116 = OpIMul %5 %38 %117\n%118 = OpCompositeExtract %5 %46 0\n%119 = OpCompositeExtract %5 %46 1\n%120 = OpIAdd %5 %116 %118\n%121 = OpULessThan %74 %116 %119\n%122 = OpSelect %5 %121 %120 %77\n%123 = OpAccessChain %78 %40 %37 %122\nOpStore %123 %112\n%125 = OpIAdd %5 %122 %50\n%124 = OpAccessChain %78 %40 %37 %125\nOpStore %124 %113\n%127 = OpIAdd %5 %122 %57\n%126 = OpAccessChain %78 %40 %37 %127\nOpStore %126 %114\n%128 = OpISub %11 %89 %109\n%129 = OpISub %11 %90 %110\n%130 = OpISub %11 %91 %111\n%131 = OpBitwiseOr %5 %115 %50\n%132 = OpIMul %5 %38 %117\n%133 = OpIAdd %5 %132 %42\n%134 = OpCompositeExtract %5 %46 0\n%135 = OpCompositeExtract %5 %46 1\n%136 = OpIAdd %5 %133 %134\n%137 = OpULessThan %74 %133 %135\n%138 = OpSelect %5 %137 %136 %77\n%139 = OpAccessChain %78 %40 %37 %138\nOpStore %139 %128\n%141 = OpIAdd %5 %138 %50\n%140 = OpAccessChain %78 %40 %37 %141\nOpStore %140 %129\n%143 = OpIAdd %5 %138 %57\n%142 = OpAccessChain %78 %40 %37 %143\nOpStore %142 %130\n%144 = OpIMul %11 %109 %89\n%145 = OpIMul %11 %110 %90\n%146 = OpIMul %11 %111 %91\n%147 = OpBitwiseOr %5 %115 %57\n%148 = OpIMul %5 %38 %117\n%149 = OpIAdd %5 %148 %70\n%150 = OpCompositeExtract %5 %46 0\n%151 = OpCompositeExtract %5 %46 1\n%152 = OpIAdd %5 %149 %150\n%153 = OpULessThan %74 %149 %151\n%154 = OpSelect %5 %153 %152 %77\n%155 = OpAccessChain %78 %40 %37 %154\nOpStore %155 %144\n%157 = OpIAdd %5 %154 %50\n%156 = OpAccessChain %78 %40 %37 %157\nOpStore %156 %145\n%159 = OpIAdd %5 %154 %57\n%158 = OpAccessChain %78 %40 %37 %159\nOpStore %158 %146\n%160 = OpUDiv %11 %89 %109\n%161 = OpUDiv %11 %90 %110\n%162 = OpUDiv %11 %91 %111\n%163 = OpBitwiseOr %5 %115 %42\n%164 = OpIMul %5 %38 %117\n%166 = OpIAdd %5 %164 %165\n%167 = OpCompositeExtract %5 %46 0\n%168 = OpCompositeExtract %5 %46 1\n%169 = OpIAdd %5 %166 %167\n%170 = OpULessThan %74 %166 %168\n%171 = OpSelect %5 %170 %169 %77\n%172 = OpAccessChain %78 %40 %37 %171\nOpStore %172 %160\n%174 = OpIAdd %5 %171 %50\n%173 = OpAccessChain %78 %40 %37 %174\nOpStore %173 %161\n%176 = OpIAdd %5 %171 %57\n%175 = OpAccessChain %78 %40 %37 %176\nOpStore %175 %162\n%177 = OpBitwiseAnd %11 %109 %178\n%179 = OpBitwiseAnd %11 %110 %178\n%180 = OpBitwiseAnd %11 %111 %178\n%181 = OpShiftLeftLogical %11 %89 %177\n%182 = OpShiftLeftLogical %11 %90 %179\n%183 = OpShiftLeftLogical %11 %91 %180\n%184 = OpBitwiseOr %5 %115 %185\n%186 = OpIMul %5 %38 %117\n%188 = OpIAdd %5 %186 %187\n%189 = OpCompositeExtract %5 %46 0\n%190 = OpCompositeExtract %5 %46 1\n%191 = OpIAdd %5 %188 %189\n%192 = OpULessThan %74 %188 %190\n%193 = OpSelect %5 %192 %191 %77\n%194 = OpAccessChain %78 %40 %37 %193\nOpStore %194 %181\n%196 = OpIAdd %5 %193 %50\n%195 = OpAccessChain %78 %40 %37 %196\nOpStore %195 %182\n%198 = OpIAdd %5 %193 %57\n%197 = OpAccessChain %78 %40 %37 %198\nOpStore %197 %183\n%199 = OpShiftRightLogical %11 %89 %177\n%200 = OpShiftRightLogical %11 %90 %179\n%201 = OpShiftRightLogical %11 %91 %180\n%202 = OpBitwiseOr %5 %115 %203\n%204 = OpIMul %5 %38 %117\n%206 = OpIAdd %5 %204 %205\n%207 = OpCompositeExtract %5 %46 0\n%208 = OpCompositeExtract %5 %46 1\n%209 = OpIAdd %5 %206 %207\n%210 = OpULessThan %74 %206 %208\n%211 = OpSelect %5 %210 %209 %77\n%212 = OpAccessChain %78 %40 %37 %211\nOpStore %212 %199\n%214 = OpIAdd %5 %211 %50\n%213 = OpAccessChain %78 %40 %37 %214\nOpStore %213 %200\n%216 = OpIAdd %5 %211 %57\n%215 = OpAccessChain %78 %40 %37 %216\nOpStore %215 %201\n%217 = OpShiftRightArithmetic %11 %89 %177\n%218 = OpShiftRightArithmetic %11 %90 %179\n%219 = OpShiftRightArithmetic %11 %91 %180\n%220 = OpBitwiseOr %5 %115 %70\n%221 = OpIMul %5 %38 %117\n%223 = OpIAdd %5 %221 %222\n%224 = OpCompositeExtract %5 %46 0\n%225 = OpCompositeExtract %5 %46 1\n%226 = OpIAdd %5 %223 %224\n%227 = OpULessThan %74 %223 %225\n%228 = OpSelect %5 %227 %226 %77\n%229 = OpAccessChain %78 %40 %37 %228\nOpStore %229 %217\n%231 = OpIAdd %5 %228 %50\n%230 = OpAccessChain %78 %40 %37 %231\nOpStore %230 %218\n%233 = OpIAdd %5 %228 %57\n%232 = OpAccessChain %78 %40 %37 %233\nOpStore %232 %219\n%234 = OpBitwiseAnd %11 %109 %89\n%235 = OpBitwiseAnd %11 %110 %90\n%236 = OpBitwiseAnd %11 %111 %91\n%237 = OpBitwiseOr %5 %115 %238\n%239 = OpIMul %5 %38 %117\n%241 = OpIAdd %5 %239 %240\n%242 = OpCompositeExtract %5 %46 0\n%243 = OpCompositeExtract %5 %46 1\n%244 = OpIAdd %5 %241 %242\n%245 = OpULessThan %74 %241 %243\n%246 = OpSelect %5 %245 %244 %77\n%247 = OpAccessChain %78 %40 %37 %246\nOpStore %247 %234\n%249 = OpIAdd %5 %246 %50\n%248 = OpAccessChain %78 %40 %37 %249\nOpStore %248 %235\n%251 = OpIAdd %5 %246 %57\n%250 = OpAccessChain %78 %40 %37 %251\nOpStore %250 %236\n%252 = OpIMul %5 %38 %117\n%253 = OpIMul %5 %38 %42\n%254 = OpCompositeExtract %5 %67 0\n%255 = OpCompositeExtract %5 %67 1\n%256 = OpIAdd %5 %253 %254\n%257 = OpULessThan %74 %253 %255\n%258 = OpSelect %5 %257 %256 %77\n%259 = OpAccessChain %78 %63 %37 %258\n%260 = OpLoad %11 %259\n%262 = OpIAdd %5 %258 %50\n%261 = OpAccessChain %78 %63 %37 %262\n%263 = OpLoad %11 %261\n%265 = OpCompositeConstruct %264 %260 %263\n%266 = OpCompositeExtract %11 %265 0\n%267 = OpCompositeExtract %11 %265 1\n%268 = OpCompositeExtract %5 %61 0\n%269 = OpCompositeExtract %5 %61 1\n%270 = OpIAdd %5 %38 %268\n%271 = OpULessThan %74 %38 %269\n%272 = OpSelect %5 %271 %270 %77\n%273 = OpAccessChain %78 %56 %37 %272\nOpStore %273 %266\n%275 = OpIAdd %5 %272 %50\n%274 = OpAccessChain %78 %56 %37 %275\nOpStore %274 %267\n%277 = OpIAdd %5 %272 %57\n%276 = OpAccessChain %78 %56 %37 %277\nOpStore %276 %91\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/cbuffer-heap.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _17[];\n\nlayout(set = 0, binding = 0) uniform texture3D _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) in vec3 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uvec4 _40 = floatBitsToUint(_17[nonuniformEXT(INDEX + 2u)]._m0[0u]);\n    vec4 _45 = texelFetch(_9[INDEX + 1u], ivec3(uvec3(_40.xyz)), int(_40.w));\n    SV_Target.x = _45.x;\n    SV_Target.y = _45.y;\n    SV_Target.z = _45.z;\n    SV_Target.w = _45.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %19 %22 %24\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"BindlessCBV\"\nOpName %19 \"INDEX\"\nOpName %22 \"UV\"\nOpName %24 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %13 ArrayStride 16\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %22 Location 1\nOpDecorate %24 Location 0\nOpDecorate %34 NonUniform\nOpDecorate %37 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 4096\n%13 = OpTypeArray %10 %12\n%14 = OpTypeStruct %13\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Input %11\n%19 = OpVariable %18 Input\n%20 = OpTypeVector %5 3\n%21 = OpTypePointer Input %20\n%22 = OpVariable %21 Input\n%23 = OpTypePointer Output %10\n%24 = OpVariable %23 Output\n%27 = OpConstant %11 1\n%28 = OpTypePointer UniformConstant %6\n%32 = OpConstant %11 2\n%33 = OpTypePointer Uniform %14\n%35 = OpConstant %11 0\n%36 = OpTypePointer Uniform %10\n%39 = OpTypeVector %11 4\n%46 = OpTypeVector %11 3\n%52 = OpTypePointer Output %5\n%57 = OpConstant %11 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %58\n%58 = OpLabel\n%25 = OpLoad %11 %19\n%26 = OpIAdd %11 %25 %27\n%29 = OpAccessChain %28 %9 %26\n%30 = OpLoad %6 %29\n%31 = OpIAdd %11 %25 %32\n%34 = OpAccessChain %33 %17 %31\n%37 = OpAccessChain %36 %34 %35 %35\n%38 = OpLoad %10 %37\n%40 = OpBitcast %39 %38\n%41 = OpCompositeExtract %11 %40 0\n%42 = OpCompositeExtract %11 %40 1\n%43 = OpCompositeExtract %11 %40 2\n%44 = OpCompositeExtract %11 %40 3\n%47 = OpCompositeConstruct %46 %41 %42 %43\n%45 = OpImageFetch %10 %30 %47 Lod %44\n%48 = OpCompositeExtract %5 %45 0\n%49 = OpCompositeExtract %5 %45 1\n%50 = OpCompositeExtract %5 %45 2\n%51 = OpCompositeExtract %5 %45 3\n%53 = OpAccessChain %52 %24 %35\nOpStore %53 %48\n%54 = OpAccessChain %52 %24 %27\nOpStore %54 %49\n%55 = OpAccessChain %52 %24 %32\nOpStore %55 %50\n%56 = OpAccessChain %52 %24 %57\nOpStore %56 %51\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/cbv.no-legacy-cbuf-layout.bindless.sm66.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct CBVComposite16x8\n{\n    float16_t _m0;\n    float16_t _m1;\n    float16_t _m2;\n    float16_t _m3;\n    float16_t _m4;\n    float16_t _m5;\n    float16_t _m6;\n    float16_t _m7;\n};\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    u64vec2 _m0[4096];\n} _16[];\n\nlayout(set = 5, binding = 0, std140) uniform _20_23\n{\n    vec4 _m0[4096];\n} _23[];\n\nlayout(set = 5, binding = 0, std140) uniform _27_30\n{\n    dvec2 _m0[4096];\n} _30[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _39 = registers._m5 + 2u;\n    uint _45 = registers._m5 + 1u;\n    f16vec2 _70 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].x));\n    f16vec2 _73 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].y));\n    f16vec2 _76 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].z));\n    f16vec2 _79 = unpackFloat2x16(floatBitsToUint(_23[registers._m5]._m0[1u].w));\n    CBVComposite16x8 _83 = CBVComposite16x8(_70.x, _70.y, _73.x, _73.y, _76.x, _76.y, _79.x, _79.y);\n    SV_Target.x = (((float(_83._m0) + _23[registers._m5]._m0[0u].x) + float(int64_t(_16[registers._m5]._m0[2u].x))) + _23[_45]._m0[0u].x) + float(_30[_39]._m0[0u].x);\n    SV_Target.y = (((float(_83._m1) + _23[registers._m5]._m0[0u].y) + float(int64_t(_16[registers._m5]._m0[2u].y))) + _23[_45]._m0[0u].y) + float(_30[_39]._m0[0u].y);\n    SV_Target.z = (((float(_83._m2) + _23[registers._m5]._m0[0u].z) + float(int64_t(_16[registers._m5]._m0[3u].x))) + _23[_45]._m0[0u].z) + float(_30[_39]._m0[1u].x);\n    SV_Target.w = (((float(_83._m3) + _23[registers._m5]._m0[0u].w) + float(int64_t(_16[registers._m5]._m0[3u].y))) + _23[_45]._m0[0u].w) + float(_30[_39]._m0[1u].y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 148\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Float64\nOpCapability Int64\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %32\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %13 \"BindlessCBV\"\nOpName %20 \"BindlessCBV\"\nOpName %27 \"BindlessCBV\"\nOpName %32 \"SV_Target\"\nOpName %82 \"CBVComposite16x8\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 ArrayStride 16\nOpDecorate %13 Block\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %16 DescriptorSet 5\nOpDecorate %16 Binding 0\nOpDecorate %19 ArrayStride 16\nOpDecorate %20 Block\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %23 DescriptorSet 5\nOpDecorate %23 Binding 0\nOpDecorate %26 ArrayStride 16\nOpDecorate %27 Block\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %30 DescriptorSet 5\nOpDecorate %30 Binding 0\nOpDecorate %32 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeInt 64 0\n%10 = OpTypeVector %9 2\n%11 = OpConstant %5 4096\n%12 = OpTypeArray %10 %11\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 4\n%19 = OpTypeArray %18 %11\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer Uniform %21\n%23 = OpVariable %22 Uniform\n%24 = OpTypeFloat 64\n%25 = OpTypeVector %24 2\n%26 = OpTypeArray %25 %11\n%27 = OpTypeStruct %26\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%31 = OpTypePointer Output %18\n%32 = OpVariable %31 Output\n%33 = OpTypePointer Uniform %27\n%35 = OpTypePointer PushConstant %5\n%37 = OpConstant %5 5\n%40 = OpConstant %5 2\n%41 = OpTypePointer Uniform %20\n%46 = OpConstant %5 1\n%47 = OpTypePointer Uniform %13\n%54 = OpConstant %5 0\n%55 = OpTypePointer Uniform %18\n%62 = OpTypeFloat 16\n%65 = OpTypeVector %62 2\n%82 = OpTypeStruct %62 %62 %62 %62 %62 %62 %62 %62\n%96 = OpTypePointer Uniform %10\n%101 = OpConstant %5 3\n%124 = OpTypePointer Uniform %25\n%141 = OpTypePointer Output %17\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %146\n%146 = OpLabel\n%36 = OpAccessChain %35 %8 %37\n%38 = OpLoad %5 %36\n%39 = OpIAdd %5 %38 %40\n%34 = OpAccessChain %33 %30 %39\n%43 = OpAccessChain %35 %8 %37\n%44 = OpLoad %5 %43\n%45 = OpIAdd %5 %44 %46\n%42 = OpAccessChain %41 %23 %45\n%49 = OpAccessChain %35 %8 %37\n%50 = OpLoad %5 %49\n%48 = OpAccessChain %47 %16 %50\n%52 = OpAccessChain %35 %8 %37\n%53 = OpLoad %5 %52\n%51 = OpAccessChain %41 %23 %53\n%56 = OpAccessChain %55 %51 %54 %54\n%57 = OpLoad %18 %56\n%58 = OpCompositeExtract %17 %57 0\n%59 = OpCompositeExtract %17 %57 1\n%60 = OpCompositeExtract %17 %57 2\n%61 = OpCompositeExtract %17 %57 3\n%63 = OpAccessChain %55 %51 %54 %46\n%64 = OpLoad %18 %63\n%66 = OpCompositeExtract %17 %64 0\n%67 = OpCompositeExtract %17 %64 1\n%68 = OpCompositeExtract %17 %64 2\n%69 = OpCompositeExtract %17 %64 3\n%70 = OpBitcast %65 %66\n%71 = OpCompositeExtract %62 %70 0\n%72 = OpCompositeExtract %62 %70 1\n%73 = OpBitcast %65 %67\n%74 = OpCompositeExtract %62 %73 0\n%75 = OpCompositeExtract %62 %73 1\n%76 = OpBitcast %65 %68\n%77 = OpCompositeExtract %62 %76 0\n%78 = OpCompositeExtract %62 %76 1\n%79 = OpBitcast %65 %69\n%80 = OpCompositeExtract %62 %79 0\n%81 = OpCompositeExtract %62 %79 1\n%83 = OpCompositeConstruct %82 %71 %72 %74 %75 %77 %78 %80 %81\n%84 = OpCompositeExtract %62 %83 0\n%85 = OpCompositeExtract %62 %83 1\n%86 = OpCompositeExtract %62 %83 2\n%87 = OpCompositeExtract %62 %83 3\n%88 = OpFConvert %17 %84\n%89 = OpFConvert %17 %85\n%90 = OpFConvert %17 %86\n%91 = OpFConvert %17 %87\n%92 = OpFAdd %17 %88 %58\n%93 = OpFAdd %17 %89 %59\n%94 = OpFAdd %17 %90 %60\n%95 = OpFAdd %17 %91 %61\n%97 = OpAccessChain %96 %48 %54 %40\n%98 = OpLoad %10 %97\n%99 = OpCompositeExtract %9 %98 0\n%100 = OpCompositeExtract %9 %98 1\n%102 = OpAccessChain %96 %48 %54 %101\n%103 = OpLoad %10 %102\n%104 = OpCompositeExtract %9 %103 0\n%105 = OpCompositeExtract %9 %103 1\n%106 = OpConvertSToF %17 %99\n%107 = OpConvertSToF %17 %100\n%108 = OpConvertSToF %17 %104\n%109 = OpConvertSToF %17 %105\n%110 = OpFAdd %17 %92 %106\n%111 = OpFAdd %17 %93 %107\n%112 = OpFAdd %17 %94 %108\n%113 = OpFAdd %17 %95 %109\n%114 = OpAccessChain %55 %42 %54 %54\n%115 = OpLoad %18 %114\n%116 = OpCompositeExtract %17 %115 0\n%117 = OpCompositeExtract %17 %115 1\n%118 = OpCompositeExtract %17 %115 2\n%119 = OpCompositeExtract %17 %115 3\n%120 = OpFAdd %17 %110 %116\n%121 = OpFAdd %17 %111 %117\n%122 = OpFAdd %17 %112 %118\n%123 = OpFAdd %17 %113 %119\n%125 = OpAccessChain %124 %34 %54 %54\n%126 = OpLoad %25 %125\n%127 = OpCompositeExtract %24 %126 0\n%128 = OpCompositeExtract %24 %126 1\n%129 = OpAccessChain %124 %34 %54 %46\n%130 = OpLoad %25 %129\n%131 = OpCompositeExtract %24 %130 0\n%132 = OpCompositeExtract %24 %130 1\n%133 = OpFConvert %17 %127\n%134 = OpFConvert %17 %128\n%135 = OpFConvert %17 %131\n%136 = OpFConvert %17 %132\n%137 = OpFAdd %17 %120 %133\n%138 = OpFAdd %17 %121 %134\n%139 = OpFAdd %17 %122 %135\n%140 = OpFAdd %17 %123 %136\n%142 = OpAccessChain %141 %32 %54\nOpStore %142 %137\n%143 = OpAccessChain %141 %32 %46\nOpStore %143 %138\n%144 = OpAccessChain %141 %32 %40\nOpStore %144 %139\n%145 = OpAccessChain %141 %32 %101\nOpStore %145 %140\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/cbv.no-legacy-cbuf-layout.sm66.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nstruct CBVComposite16x8\n{\n    float16_t _m0;\n    float16_t _m1;\n    float16_t _m2;\n    float16_t _m3;\n    float16_t _m4;\n    float16_t _m5;\n    float16_t _m6;\n    float16_t _m7;\n};\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    u64vec2 _m0[4];\n} _12;\n\nlayout(set = 0, binding = 0, std140) uniform _16_18\n{\n    vec4 _m0[4];\n} _18;\n\nlayout(set = 0, binding = 1, std140) uniform _21_23\n{\n    vec4 _m0[1];\n} _23;\n\nlayout(set = 0, binding = 2, std140) uniform _28_30\n{\n    dvec2 _m0[2];\n} _30;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    f16vec2 _49 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].x));\n    f16vec2 _52 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].y));\n    f16vec2 _55 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].z));\n    f16vec2 _58 = unpackFloat2x16(floatBitsToUint(_18._m0[1u].w));\n    CBVComposite16x8 _62 = CBVComposite16x8(_49.x, _49.y, _52.x, _52.y, _55.x, _55.y, _58.x, _58.y);\n    SV_Target.x = (((float(_62._m0) + _18._m0[0u].x) + float(int64_t(_12._m0[2u].x))) + _23._m0[0u].x) + float(_30._m0[0u].x);\n    SV_Target.y = (((float(_62._m1) + _18._m0[0u].y) + float(int64_t(_12._m0[2u].y))) + _23._m0[0u].y) + float(_30._m0[0u].y);\n    SV_Target.z = (((float(_62._m2) + _18._m0[0u].z) + float(int64_t(_12._m0[3u].x))) + _23._m0[0u].z) + float(_30._m0[1u].x);\n    SV_Target.w = (((float(_62._m3) + _18._m0[0u].w) + float(int64_t(_12._m0[3u].y))) + _23._m0[0u].w) + float(_30._m0[1u].y);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 127\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Float64\nOpCapability Int64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"\"\nOpName %21 \"\"\nOpName %28 \"\"\nOpName %32 \"SV_Target\"\nOpName %61 \"CBVComposite16x8\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %20 ArrayStride 16\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 1\nOpDecorate %27 ArrayStride 16\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 2\nOpDecorate %32 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 4\n%7 = OpTypeInt 64 0\n%8 = OpTypeVector %7 2\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypeArray %14 %6\n%16 = OpTypeStruct %15\n%17 = OpTypePointer Uniform %16\n%18 = OpVariable %17 Uniform\n%19 = OpConstant %5 1\n%20 = OpTypeArray %14 %19\n%21 = OpTypeStruct %20\n%22 = OpTypePointer Uniform %21\n%23 = OpVariable %22 Uniform\n%24 = OpConstant %5 2\n%25 = OpTypeFloat 64\n%26 = OpTypeVector %25 2\n%27 = OpTypeArray %26 %24\n%28 = OpTypeStruct %27\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%31 = OpTypePointer Output %14\n%32 = OpVariable %31 Output\n%33 = OpConstant %5 0\n%34 = OpTypePointer Uniform %14\n%41 = OpTypeFloat 16\n%44 = OpTypeVector %41 2\n%61 = OpTypeStruct %41 %41 %41 %41 %41 %41 %41 %41\n%75 = OpTypePointer Uniform %8\n%80 = OpConstant %5 3\n%103 = OpTypePointer Uniform %26\n%120 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %125\n%125 = OpLabel\n%35 = OpAccessChain %34 %18 %33 %33\n%36 = OpLoad %14 %35\n%37 = OpCompositeExtract %13 %36 0\n%38 = OpCompositeExtract %13 %36 1\n%39 = OpCompositeExtract %13 %36 2\n%40 = OpCompositeExtract %13 %36 3\n%42 = OpAccessChain %34 %18 %33 %19\n%43 = OpLoad %14 %42\n%45 = OpCompositeExtract %13 %43 0\n%46 = OpCompositeExtract %13 %43 1\n%47 = OpCompositeExtract %13 %43 2\n%48 = OpCompositeExtract %13 %43 3\n%49 = OpBitcast %44 %45\n%50 = OpCompositeExtract %41 %49 0\n%51 = OpCompositeExtract %41 %49 1\n%52 = OpBitcast %44 %46\n%53 = OpCompositeExtract %41 %52 0\n%54 = OpCompositeExtract %41 %52 1\n%55 = OpBitcast %44 %47\n%56 = OpCompositeExtract %41 %55 0\n%57 = OpCompositeExtract %41 %55 1\n%58 = OpBitcast %44 %48\n%59 = OpCompositeExtract %41 %58 0\n%60 = OpCompositeExtract %41 %58 1\n%62 = OpCompositeConstruct %61 %50 %51 %53 %54 %56 %57 %59 %60\n%63 = OpCompositeExtract %41 %62 0\n%64 = OpCompositeExtract %41 %62 1\n%65 = OpCompositeExtract %41 %62 2\n%66 = OpCompositeExtract %41 %62 3\n%67 = OpFConvert %13 %63\n%68 = OpFConvert %13 %64\n%69 = OpFConvert %13 %65\n%70 = OpFConvert %13 %66\n%71 = OpFAdd %13 %67 %37\n%72 = OpFAdd %13 %68 %38\n%73 = OpFAdd %13 %69 %39\n%74 = OpFAdd %13 %70 %40\n%76 = OpAccessChain %75 %12 %33 %24\n%77 = OpLoad %8 %76\n%78 = OpCompositeExtract %7 %77 0\n%79 = OpCompositeExtract %7 %77 1\n%81 = OpAccessChain %75 %12 %33 %80\n%82 = OpLoad %8 %81\n%83 = OpCompositeExtract %7 %82 0\n%84 = OpCompositeExtract %7 %82 1\n%85 = OpConvertSToF %13 %78\n%86 = OpConvertSToF %13 %79\n%87 = OpConvertSToF %13 %83\n%88 = OpConvertSToF %13 %84\n%89 = OpFAdd %13 %71 %85\n%90 = OpFAdd %13 %72 %86\n%91 = OpFAdd %13 %73 %87\n%92 = OpFAdd %13 %74 %88\n%93 = OpAccessChain %34 %23 %33 %33\n%94 = OpLoad %14 %93\n%95 = OpCompositeExtract %13 %94 0\n%96 = OpCompositeExtract %13 %94 1\n%97 = OpCompositeExtract %13 %94 2\n%98 = OpCompositeExtract %13 %94 3\n%99 = OpFAdd %13 %89 %95\n%100 = OpFAdd %13 %90 %96\n%101 = OpFAdd %13 %91 %97\n%102 = OpFAdd %13 %92 %98\n%104 = OpAccessChain %103 %30 %33 %33\n%105 = OpLoad %26 %104\n%106 = OpCompositeExtract %25 %105 0\n%107 = OpCompositeExtract %25 %105 1\n%108 = OpAccessChain %103 %30 %33 %19\n%109 = OpLoad %26 %108\n%110 = OpCompositeExtract %25 %109 0\n%111 = OpCompositeExtract %25 %109 1\n%112 = OpFConvert %13 %106\n%113 = OpFConvert %13 %107\n%114 = OpFConvert %13 %110\n%115 = OpFConvert %13 %111\n%116 = OpFAdd %13 %99 %112\n%117 = OpFAdd %13 %100 %113\n%118 = OpFAdd %13 %101 %114\n%119 = OpFAdd %13 %102 %115\n%121 = OpAccessChain %120 %32 %33\nOpStore %121 %116\n%122 = OpAccessChain %120 %32 %19\nOpStore %122 %117\n%123 = OpAccessChain %120 %32 %24\nOpStore %123 %118\n%124 = OpAccessChain %120 %32 %80\nOpStore %124 %119\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raw-buffer-heap.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _9[];\nlayout(set = 0, binding = 0, r32ui) uniform coherent writeonly uimageBuffer _13[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in ivec3 UV;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _37 = INDEX + 1u;\n    uint _41 = uint(UV.x) >> 2u;\n    uvec3 _53 = uvec3(texelFetch(_9[INDEX], int(_41)).x, texelFetch(_9[INDEX], int(_41 + 1u)).x, texelFetch(_9[INDEX], int(_41 + 2u)).x);\n    uint _54 = _53.x;\n    uint _55 = _53.y;\n    uint _56 = _53.z;\n    uint _60 = uint(UV.y) >> 2u;\n    imageStore(_13[_37], int(_60), uvec4(_54));\n    imageStore(_13[_37], int(_60 + 1u), uvec4(_55));\n    imageStore(_13[_37], int(_60 + 2u), uvec4(_56));\n    SV_Target.x = uintBitsToFloat(_54);\n    SV_Target.y = uintBitsToFloat(_55);\n    SV_Target.z = uintBitsToFloat(_56);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %15 %19 %23\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %15 \"INDEX\"\nOpName %19 \"UV\"\nOpName %23 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 Coherent\nOpDecorate %15 Flat\nOpDecorate %15 Location 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %19 Component 1\nOpDecorate %23 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%16 = OpTypeInt 32 1\n%17 = OpTypeVector %16 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypeFloat 32\n%21 = OpTypeVector %20 3\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpTypePointer Input %16\n%26 = OpConstant %5 0\n%30 = OpConstant %5 1\n%34 = OpTypePointer UniformConstant %6\n%38 = OpTypePointer UniformConstant %10\n%42 = OpConstant %5 2\n%43 = OpTypeVector %5 4\n%52 = OpTypeVector %5 3\n%66 = OpTypePointer Output %20\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %70\n%70 = OpLabel\n%25 = OpAccessChain %24 %19 %26\n%27 = OpLoad %16 %25\n%28 = OpBitcast %5 %27\n%29 = OpAccessChain %24 %19 %30\n%31 = OpLoad %16 %29\n%32 = OpBitcast %5 %31\n%33 = OpLoad %5 %15\n%35 = OpAccessChain %34 %9 %33\n%36 = OpLoad %6 %35\n%37 = OpIAdd %5 %33 %30\n%39 = OpAccessChain %38 %13 %37\n%40 = OpLoad %10 %39\n%41 = OpShiftRightLogical %5 %28 %42\n%44 = OpImageFetch %43 %36 %41\n%45 = OpCompositeExtract %5 %44 0\n%47 = OpIAdd %5 %41 %30\n%46 = OpImageFetch %43 %36 %47\n%48 = OpCompositeExtract %5 %46 0\n%50 = OpIAdd %5 %41 %42\n%49 = OpImageFetch %43 %36 %50\n%51 = OpCompositeExtract %5 %49 0\n%53 = OpCompositeConstruct %52 %45 %48 %51\n%54 = OpCompositeExtract %5 %53 0\n%55 = OpCompositeExtract %5 %53 1\n%56 = OpCompositeExtract %5 %53 2\n%57 = OpBitcast %20 %54\n%58 = OpBitcast %20 %55\n%59 = OpBitcast %20 %56\n%60 = OpShiftRightLogical %5 %32 %42\n%61 = OpCompositeConstruct %43 %54 %54 %54 %54\nOpImageWrite %40 %60 %61\n%62 = OpCompositeConstruct %43 %55 %55 %55 %55\n%63 = OpIAdd %5 %60 %30\nOpImageWrite %40 %63 %62\n%64 = OpCompositeConstruct %43 %56 %56 %56 %56\n%65 = OpIAdd %5 %60 %42\nOpImageWrite %40 %65 %64\n%67 = OpAccessChain %66 %23 %26\nOpStore %67 %57\n%68 = OpAccessChain %66 %23 %30\nOpStore %68 %58\n%69 = OpAccessChain %66 %23 %42\nOpStore %69 %59\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raw-buffer-heap.ssbo.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(set = 0, binding = 0, std430) coherent buffer _12_15\n{\n    uint _m0[];\n} _15[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in ivec3 UV;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _38 = INDEX + 1u;\n    uint _41 = uint(UV.x) >> 2u;\n    uvec3 _53 = uvec3(_10[INDEX]._m0[_41], _10[INDEX]._m0[_41 + 1u], _10[INDEX]._m0[_41 + 2u]);\n    uint _54 = _53.x;\n    uint _55 = _53.y;\n    uint _56 = _53.z;\n    uint _60 = uint(UV.y) >> 2u;\n    _15[_38]._m0[_60] = _54;\n    _15[_38]._m0[_60 + 1u] = _55;\n    _15[_38]._m0[_60 + 2u] = _56;\n    SV_Target.x = uintBitsToFloat(_54);\n    SV_Target.y = uintBitsToFloat(_55);\n    SV_Target.z = uintBitsToFloat(_56);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %21 %25\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %17 \"INDEX\"\nOpName %21 \"UV\"\nOpName %25 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 Coherent\nOpDecorate %17 Flat\nOpDecorate %17 Location 0\nOpDecorate %21 Flat\nOpDecorate %21 Location 0\nOpDecorate %21 Component 1\nOpDecorate %25 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypeRuntimeArray %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %5\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypePointer Input %5\n%17 = OpVariable %16 Input\n%18 = OpTypeInt 32 1\n%19 = OpTypeVector %18 3\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypeFloat 32\n%23 = OpTypeVector %22 3\n%24 = OpTypePointer Output %23\n%25 = OpVariable %24 Output\n%26 = OpTypePointer Input %18\n%28 = OpConstant %5 0\n%32 = OpConstant %5 1\n%36 = OpTypePointer StorageBuffer %7\n%39 = OpTypePointer StorageBuffer %12\n%42 = OpConstant %5 2\n%43 = OpTypePointer StorageBuffer %5\n%52 = OpTypeVector %5 3\n%66 = OpTypePointer Output %22\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %70\n%70 = OpLabel\n%27 = OpAccessChain %26 %21 %28\n%29 = OpLoad %18 %27\n%30 = OpBitcast %5 %29\n%31 = OpAccessChain %26 %21 %32\n%33 = OpLoad %18 %31\n%34 = OpBitcast %5 %33\n%35 = OpLoad %5 %17\n%37 = OpAccessChain %36 %10 %35\n%38 = OpIAdd %5 %35 %32\n%40 = OpAccessChain %39 %15 %38\n%41 = OpShiftRightLogical %5 %30 %42\n%44 = OpAccessChain %43 %37 %28 %41\n%45 = OpLoad %5 %44\n%47 = OpIAdd %5 %41 %32\n%46 = OpAccessChain %43 %37 %28 %47\n%48 = OpLoad %5 %46\n%50 = OpIAdd %5 %41 %42\n%49 = OpAccessChain %43 %37 %28 %50\n%51 = OpLoad %5 %49\n%53 = OpCompositeConstruct %52 %45 %48 %51\n%54 = OpCompositeExtract %5 %53 0\n%55 = OpCompositeExtract %5 %53 1\n%56 = OpCompositeExtract %5 %53 2\n%57 = OpBitcast %22 %54\n%58 = OpBitcast %22 %55\n%59 = OpBitcast %22 %56\n%60 = OpShiftRightLogical %5 %34 %42\n%61 = OpAccessChain %43 %40 %28 %60\nOpStore %61 %54\n%63 = OpIAdd %5 %60 %32\n%62 = OpAccessChain %43 %40 %28 %63\nOpStore %62 %55\n%65 = OpIAdd %5 %60 %42\n%64 = OpAccessChain %43 %40 %28 %65\nOpStore %64 %56\n%67 = OpAccessChain %66 %25 %28\nOpStore %67 %57\n%68 = OpAccessChain %66 %25 %32\nOpStore %68 %58\n%69 = OpAccessChain %66 %25 %42\nOpStore %69 %59\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raw-buffer-heap.typed-buffer-offset.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _17[];\nlayout(set = 0, binding = 0, r32ui) uniform coherent writeonly uimageBuffer _21[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in ivec3 UV;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _45 = subgroupBroadcastFirst(INDEX);\n    uint _50 = INDEX + 1u;\n    uint _54 = subgroupBroadcastFirst(_50);\n    uint _57 = uint(UV.x) >> 2u;\n    uint _64 = (_57 < _13._m0[_45].y) ? (_57 + _13._m0[_45].x) : 1073741820u;\n    uvec3 _76 = uvec3(texelFetch(_17[INDEX], int(_64)).x, texelFetch(_17[INDEX], int(_64 + 1u)).x, texelFetch(_17[INDEX], int(_64 + 2u)).x);\n    uint _77 = _76.x;\n    uint _78 = _76.y;\n    uint _79 = _76.z;\n    uint _83 = uint(UV.y) >> 2u;\n    uint _88 = (_83 < _13._m0[_54].y) ? (_83 + _13._m0[_54].x) : 1073741820u;\n    imageStore(_21[_50], int(_88), uvec4(_77));\n    imageStore(_21[_50], int(_88 + 1u), uvec4(_78));\n    imageStore(_21[_50], int(_88 + 2u), uvec4(_79));\n    SV_Target.x = uintBitsToFloat(_77);\n    SV_Target.y = uintBitsToFloat(_78);\n    SV_Target.z = uintBitsToFloat(_79);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 100\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %23 %27 %31\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %23 \"INDEX\"\nOpName %27 \"UV\"\nOpName %31 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 Coherent\nOpDecorate %23 Flat\nOpDecorate %23 Location 0\nOpDecorate %27 Flat\nOpDecorate %27 Location 0\nOpDecorate %27 Component 1\nOpDecorate %31 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypePointer Input %5\n%23 = OpVariable %22 Input\n%24 = OpTypeInt 32 1\n%25 = OpTypeVector %24 3\n%26 = OpTypePointer Input %25\n%27 = OpVariable %26 Input\n%28 = OpTypeFloat 32\n%29 = OpTypeVector %28 3\n%30 = OpTypePointer Output %29\n%31 = OpVariable %30 Output\n%32 = OpTypePointer Input %24\n%34 = OpConstant %5 0\n%38 = OpConstant %5 1\n%42 = OpTypePointer UniformConstant %14\n%46 = OpConstant %5 3\n%47 = OpTypePointer StorageBuffer %9\n%51 = OpTypePointer UniformConstant %18\n%58 = OpConstant %5 2\n%62 = OpTypeBool\n%65 = OpConstant %5 1073741820\n%66 = OpTypeVector %5 4\n%75 = OpTypeVector %5 3\n%94 = OpTypePointer Output %28\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %98\n%98 = OpLabel\n%33 = OpAccessChain %32 %27 %34\n%35 = OpLoad %24 %33\n%36 = OpBitcast %5 %35\n%37 = OpAccessChain %32 %27 %38\n%39 = OpLoad %24 %37\n%40 = OpBitcast %5 %39\n%41 = OpLoad %5 %23\n%43 = OpAccessChain %42 %17 %41\n%44 = OpLoad %14 %43\n%45 = OpGroupNonUniformBroadcastFirst %5 %46 %41\n%48 = OpAccessChain %47 %13 %34 %45\n%49 = OpLoad %9 %48\n%50 = OpIAdd %5 %41 %38\n%52 = OpAccessChain %51 %21 %50\n%53 = OpLoad %18 %52\n%54 = OpGroupNonUniformBroadcastFirst %5 %46 %50\n%55 = OpAccessChain %47 %13 %34 %54\n%56 = OpLoad %9 %55\n%57 = OpShiftRightLogical %5 %36 %58\n%59 = OpCompositeExtract %5 %49 0\n%60 = OpCompositeExtract %5 %49 1\n%61 = OpIAdd %5 %57 %59\n%63 = OpULessThan %62 %57 %60\n%64 = OpSelect %5 %63 %61 %65\n%67 = OpImageFetch %66 %44 %64\n%68 = OpCompositeExtract %5 %67 0\n%70 = OpIAdd %5 %64 %38\n%69 = OpImageFetch %66 %44 %70\n%71 = OpCompositeExtract %5 %69 0\n%73 = OpIAdd %5 %64 %58\n%72 = OpImageFetch %66 %44 %73\n%74 = OpCompositeExtract %5 %72 0\n%76 = OpCompositeConstruct %75 %68 %71 %74\n%77 = OpCompositeExtract %5 %76 0\n%78 = OpCompositeExtract %5 %76 1\n%79 = OpCompositeExtract %5 %76 2\n%80 = OpBitcast %28 %77\n%81 = OpBitcast %28 %78\n%82 = OpBitcast %28 %79\n%83 = OpShiftRightLogical %5 %40 %58\n%84 = OpCompositeExtract %5 %56 0\n%85 = OpCompositeExtract %5 %56 1\n%86 = OpIAdd %5 %83 %84\n%87 = OpULessThan %62 %83 %85\n%88 = OpSelect %5 %87 %86 %65\n%89 = OpCompositeConstruct %66 %77 %77 %77 %77\nOpImageWrite %53 %88 %89\n%90 = OpCompositeConstruct %66 %78 %78 %78 %78\n%91 = OpIAdd %5 %88 %38\nOpImageWrite %53 %91 %90\n%92 = OpCompositeConstruct %66 %79 %79 %79 %79\n%93 = OpIAdd %5 %88 %58\nOpImageWrite %53 %93 %92\n%95 = OpAccessChain %94 %31 %34\nOpStore %95 %80\n%96 = OpAccessChain %94 %31 %38\nOpStore %96 %81\n%97 = OpAccessChain %94 %31 %58\nOpStore %97 %82\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raw-buffers-binding.ssbo.bindless.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _13[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _17_20\n{\n    u16vec2 _m0[];\n} _20[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _23_26\n{\n    u16vec4 _m0[];\n} _26[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _29_32\n{\n    uvec4 _m0[];\n} _32[];\n\nlayout(set = 4, binding = 0, std430) readonly buffer _34_37\n{\n    uint _m0[];\n} _37[];\n\nlayout(set = 4, binding = 0, std430) readonly buffer _39_42\n{\n    u16vec2 _m0[];\n} _42[];\n\nlayout(set = 4, binding = 0, std430) buffer _44_47\n{\n    u16vec4 _m0[];\n} _47[];\n\nlayout(set = 4, binding = 0, std430) buffer _49_52\n{\n    uvec4 _m0[];\n} _52[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    f16vec2 _99 = uint16BitsToFloat16(_20[registers._m1 + 1u]._m0[uint(UV.y)]);\n    uint _111 = _37[registers._m4 + 2u]._m0[uint(UV.z)];\n    u16vec2 _120 = _42[registers._m4 + 3u]._m0[uint(UV.w)];\n    f16vec2 _121 = uint16BitsToFloat16(_120);\n    f16vec4 _141 = uint16BitsToFloat16(_26[registers._m1 + 4u]._m0[1u]);\n    vec4 _157 = uintBitsToFloat(_32[registers._m1 + 4u]._m0[1u]);\n    u16vec4 _178 = _47[registers._m4 + 5u]._m0[1u];\n    f16vec4 _179 = uint16BitsToFloat16(_178);\n    float _188 = (((float(_121.y) + uintBitsToFloat(_13[registers._m1]._m0[uint(UV.x)])) + float(_141.x)) + _157.x) + float(_179.x);\n    float _189 = ((float(_141.y) + float(_99.x)) + _157.y) + float(_179.y);\n    float _190 = (((uintBitsToFloat(_111) + float(_99.y)) + float(_141.z)) + _157.z) + float(_179.z);\n    float _191 = ((float(_141.w) + float(_121.x)) + _157.w) + float(_179.w);\n    _52[registers._m4 + 5u]._m0[1u] = uvec4(floatBitsToUint(_188), floatBitsToUint(_189), floatBitsToUint(_190), floatBitsToUint(_191));\n    SV_Target.x = _188;\n    SV_Target.y = _189;\n    SV_Target.z = _190;\n    SV_Target.w = _191;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 205\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %54 %58 %62\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %10 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %29 \"SSBO\"\nOpName %34 \"SSBO\"\nOpName %39 \"SSBO\"\nOpName %44 \"SSBO\"\nOpName %49 \"SSBO\"\nOpName %54 \"INDEX\"\nOpName %58 \"UV\"\nOpName %62 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %9 ArrayStride 4\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %13 DescriptorSet 1\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 ArrayStride 4\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %20 DescriptorSet 1\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %22 ArrayStride 8\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 0\nOpDecorate %26 NonWritable\nOpDecorate %26 Restrict\nOpDecorate %28 ArrayStride 16\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %32 DescriptorSet 1\nOpDecorate %32 Binding 0\nOpDecorate %32 NonWritable\nOpDecorate %32 Restrict\nOpDecorate %33 ArrayStride 4\nOpMemberDecorate %34 0 Offset 0\nOpDecorate %34 Block\nOpDecorate %37 DescriptorSet 4\nOpDecorate %37 Binding 0\nOpDecorate %37 NonWritable\nOpDecorate %38 ArrayStride 4\nOpMemberDecorate %39 0 Offset 0\nOpDecorate %39 Block\nOpDecorate %42 DescriptorSet 4\nOpDecorate %42 Binding 0\nOpDecorate %42 NonWritable\nOpDecorate %43 ArrayStride 8\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %44 Block\nOpDecorate %47 DescriptorSet 4\nOpDecorate %47 Binding 0\nOpDecorate %47 Aliased\nOpDecorate %48 ArrayStride 16\nOpMemberDecorate %49 0 Offset 0\nOpDecorate %49 Block\nOpDecorate %52 DescriptorSet 4\nOpDecorate %52 Binding 0\nOpDecorate %52 Aliased\nOpDecorate %54 Flat\nOpDecorate %54 Location 0\nOpDecorate %58 Flat\nOpDecorate %58 Location 1\nOpDecorate %62 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeRuntimeArray %5\n%10 = OpTypeStruct %9\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeVector %14 2\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeVector %14 4\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypeStruct %22\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeVector %5 4\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpTypeRuntimeArray %5\n%34 = OpTypeStruct %33\n%35 = OpTypeRuntimeArray %34\n%36 = OpTypePointer StorageBuffer %35\n%37 = OpVariable %36 StorageBuffer\n%38 = OpTypeRuntimeArray %15\n%39 = OpTypeStruct %38\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer StorageBuffer %40\n%42 = OpVariable %41 StorageBuffer\n%43 = OpTypeRuntimeArray %21\n%44 = OpTypeStruct %43\n%45 = OpTypeRuntimeArray %44\n%46 = OpTypePointer StorageBuffer %45\n%47 = OpVariable %46 StorageBuffer\n%48 = OpTypeRuntimeArray %27\n%49 = OpTypeStruct %48\n%50 = OpTypeRuntimeArray %49\n%51 = OpTypePointer StorageBuffer %50\n%52 = OpVariable %51 StorageBuffer\n%53 = OpTypePointer Input %5\n%54 = OpVariable %53 Input\n%55 = OpTypeInt 32 1\n%56 = OpTypeVector %55 4\n%57 = OpTypePointer Input %56\n%58 = OpVariable %57 Input\n%59 = OpTypeFloat 32\n%60 = OpTypeVector %59 4\n%61 = OpTypePointer Output %60\n%62 = OpVariable %61 Output\n%63 = OpTypePointer Input %55\n%65 = OpConstant %5 0\n%69 = OpConstant %5 1\n%73 = OpConstant %5 2\n%77 = OpConstant %5 3\n%80 = OpTypePointer StorageBuffer %10\n%82 = OpTypePointer PushConstant %5\n%85 = OpTypePointer StorageBuffer %5\n%89 = OpTypePointer StorageBuffer %17\n%94 = OpTypePointer StorageBuffer %15\n%97 = OpTypeFloat 16\n%98 = OpTypeVector %97 2\n%104 = OpTypePointer StorageBuffer %34\n%107 = OpConstant %5 4\n%114 = OpTypePointer StorageBuffer %39\n%127 = OpTypePointer StorageBuffer %23\n%132 = OpTypePointer StorageBuffer %29\n%137 = OpTypePointer StorageBuffer %21\n%140 = OpTypeVector %97 4\n%154 = OpTypePointer StorageBuffer %27\n%166 = OpTypePointer StorageBuffer %44\n%171 = OpConstant %5 5\n%172 = OpTypePointer StorageBuffer %49\n%198 = OpTypePointer Output %59\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %203\n%203 = OpLabel\n%64 = OpAccessChain %63 %58 %65\n%66 = OpLoad %55 %64\n%67 = OpBitcast %5 %66\n%68 = OpAccessChain %63 %58 %69\n%70 = OpLoad %55 %68\n%71 = OpBitcast %5 %70\n%72 = OpAccessChain %63 %58 %73\n%74 = OpLoad %55 %72\n%75 = OpBitcast %5 %74\n%76 = OpAccessChain %63 %58 %77\n%78 = OpLoad %55 %76\n%79 = OpBitcast %5 %78\n%83 = OpAccessChain %82 %8 %69\n%84 = OpLoad %5 %83\n%81 = OpAccessChain %80 %13 %84\n%86 = OpAccessChain %85 %81 %65 %67\n%87 = OpLoad %5 %86\n%88 = OpBitcast %59 %87\n%91 = OpAccessChain %82 %8 %69\n%92 = OpLoad %5 %91\n%93 = OpIAdd %5 %92 %69\n%90 = OpAccessChain %89 %20 %93\n%95 = OpAccessChain %94 %90 %65 %71\n%96 = OpLoad %15 %95\n%99 = OpBitcast %98 %96\n%100 = OpCompositeExtract %97 %99 0\n%101 = OpCompositeExtract %97 %99 1\n%102 = OpFConvert %59 %100\n%103 = OpFConvert %59 %101\n%106 = OpAccessChain %82 %8 %107\n%108 = OpLoad %5 %106\n%109 = OpIAdd %5 %108 %73\n%105 = OpAccessChain %104 %37 %109\n%110 = OpAccessChain %85 %105 %65 %75\n%111 = OpLoad %5 %110\n%112 = OpBitcast %59 %111\n%113 = OpFAdd %59 %112 %103\n%116 = OpAccessChain %82 %8 %107\n%117 = OpLoad %5 %116\n%118 = OpIAdd %5 %117 %77\n%115 = OpAccessChain %114 %42 %118\n%119 = OpAccessChain %94 %115 %65 %79\n%120 = OpLoad %15 %119\n%121 = OpBitcast %98 %120\n%122 = OpCompositeExtract %97 %121 0\n%123 = OpCompositeExtract %97 %121 1\n%124 = OpFConvert %59 %122\n%125 = OpFConvert %59 %123\n%126 = OpFAdd %59 %125 %88\n%129 = OpAccessChain %82 %8 %69\n%130 = OpLoad %5 %129\n%131 = OpIAdd %5 %130 %107\n%128 = OpAccessChain %127 %26 %131\n%134 = OpAccessChain %82 %8 %69\n%135 = OpLoad %5 %134\n%136 = OpIAdd %5 %135 %107\n%133 = OpAccessChain %132 %32 %136\n%138 = OpAccessChain %137 %128 %65 %69\n%139 = OpLoad %21 %138\n%141 = OpBitcast %140 %139\n%142 = OpCompositeExtract %97 %141 0\n%143 = OpCompositeExtract %97 %141 1\n%144 = OpCompositeExtract %97 %141 2\n%145 = OpCompositeExtract %97 %141 3\n%146 = OpFConvert %59 %142\n%147 = OpFConvert %59 %143\n%148 = OpFConvert %59 %144\n%149 = OpFConvert %59 %145\n%150 = OpFAdd %59 %126 %146\n%151 = OpFAdd %59 %147 %102\n%152 = OpFAdd %59 %113 %148\n%153 = OpFAdd %59 %149 %124\n%155 = OpAccessChain %154 %133 %65 %69\n%156 = OpLoad %27 %155\n%157 = OpBitcast %60 %156\n%158 = OpCompositeExtract %59 %157 0\n%159 = OpCompositeExtract %59 %157 1\n%160 = OpCompositeExtract %59 %157 2\n%161 = OpCompositeExtract %59 %157 3\n%162 = OpFAdd %59 %150 %158\n%163 = OpFAdd %59 %151 %159\n%164 = OpFAdd %59 %152 %160\n%165 = OpFAdd %59 %153 %161\n%168 = OpAccessChain %82 %8 %107\n%169 = OpLoad %5 %168\n%170 = OpIAdd %5 %169 %171\n%167 = OpAccessChain %166 %47 %170\n%174 = OpAccessChain %82 %8 %107\n%175 = OpLoad %5 %174\n%176 = OpIAdd %5 %175 %171\n%173 = OpAccessChain %172 %52 %176\n%177 = OpAccessChain %137 %167 %65 %69\n%178 = OpLoad %21 %177\n%179 = OpBitcast %140 %178\n%180 = OpCompositeExtract %97 %179 0\n%181 = OpCompositeExtract %97 %179 1\n%182 = OpCompositeExtract %97 %179 2\n%183 = OpCompositeExtract %97 %179 3\n%184 = OpFConvert %59 %180\n%185 = OpFConvert %59 %181\n%186 = OpFConvert %59 %182\n%187 = OpFConvert %59 %183\n%188 = OpFAdd %59 %162 %184\n%189 = OpFAdd %59 %163 %185\n%190 = OpFAdd %59 %164 %186\n%191 = OpFAdd %59 %165 %187\n%192 = OpBitcast %5 %188\n%193 = OpBitcast %5 %189\n%194 = OpBitcast %5 %190\n%195 = OpBitcast %5 %191\n%196 = OpCompositeConstruct %27 %192 %193 %194 %195\n%197 = OpAccessChain %154 %173 %65 %69\nOpStore %197 %196\n%199 = OpAccessChain %198 %62 %65\nOpStore %199 %188\n%200 = OpAccessChain %198 %62 %69\nOpStore %200 %189\n%201 = OpAccessChain %198 %62 %73\nOpStore %201 %190\n%202 = OpAccessChain %198 %62 %77\nOpStore %202 %191\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raw-buffers-binding.ssbo.bindless.ssbo-align.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _18[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _22_25\n{\n    u16vec2 _m0[];\n} _25[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _28_31\n{\n    u16vec4 _m0[];\n} _31[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _34_37\n{\n    uvec4 _m0[];\n} _37[];\n\nlayout(set = 4, binding = 0, std430) readonly buffer _39_42\n{\n    uint _m0[];\n} _42[];\n\nlayout(set = 4, binding = 0, std430) readonly buffer _44_47\n{\n    u16vec2 _m0[];\n} _47[];\n\nlayout(set = 4, binding = 0, std430) buffer _49_52\n{\n    u16vec4 _m0[];\n} _52[];\n\nlayout(set = 4, binding = 0, std430) buffer _54_57\n{\n    uvec4 _m0[];\n} _57[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _72 = uint(UV.x);\n    uint _76 = uint(UV.y);\n    uint _80 = uint(UV.z);\n    uint _84 = uint(UV.w);\n    uvec2 _94 = _13._m0[subgroupBroadcastFirst(registers._m1)] >> uvec2(2u);\n    uint _111 = registers._m1 + 1u;\n    uvec2 _115 = _13._m0[subgroupBroadcastFirst(_111)] >> uvec2(2u);\n    f16vec2 _127 = uint16BitsToFloat16(_25[_111]._m0[(_76 < _115.y) ? (_76 + _115.x) : 1073741823u]);\n    uint _137 = registers._m4 + 2u;\n    uvec2 _141 = _13._m0[subgroupBroadcastFirst(_137)] >> uvec2(2u);\n    uint _148 = _42[_137]._m0[(_80 < _141.y) ? (_80 + _141.x) : 1073741820u];\n    uint _155 = registers._m4 + 3u;\n    uvec2 _159 = _13._m0[subgroupBroadcastFirst(_155)] >> uvec2(2u);\n    u16vec2 _166 = _47[_155]._m0[(_84 < _159.y) ? (_84 + _159.x) : 1073741823u];\n    f16vec2 _167 = uint16BitsToFloat16(_166);\n    uint _182 = registers._m1 + 4u;\n    uint _183 = subgroupBroadcastFirst(_182);\n    uvec2 _186 = _13._m0[_183] >> uvec2(3u);\n    f16vec4 _198 = uint16BitsToFloat16(_31[registers._m1 + 4u]._m0[(1u < _186.y) ? (1u + _186.x) : 536870911u]);\n    uvec2 _211 = _13._m0[_183] >> uvec2(4u);\n    vec4 _222 = uintBitsToFloat(_37[_182]._m0[(1u < _211.y) ? (1u + _211.x) : 268435455u]);\n    uint _241 = registers._m4 + 5u;\n    uint _242 = subgroupBroadcastFirst(_241);\n    uvec2 _245 = _13._m0[_242] >> uvec2(3u);\n    u16vec4 _252 = _52[registers._m4 + 5u]._m0[(1u < _245.y) ? (1u + _245.x) : 536870911u];\n    f16vec4 _253 = uint16BitsToFloat16(_252);\n    float _262 = (((float(_167.y) + uintBitsToFloat(_18[registers._m1]._m0[(_72 < _94.y) ? (_72 + _94.x) : 1073741820u])) + float(_198.x)) + _222.x) + float(_253.x);\n    float _263 = ((float(_198.y) + float(_127.x)) + _222.y) + float(_253.y);\n    float _264 = (((uintBitsToFloat(_148) + float(_127.y)) + float(_198.z)) + _222.z) + float(_253.z);\n    float _265 = ((float(_198.w) + float(_167.x)) + _222.w) + float(_253.w);\n    uvec2 _266 = _13._m0[_242] >> uvec2(4u);\n    _57[_241]._m0[(1u < _266.y) ? (1u + _266.x) : 268435455u] = uvec4(floatBitsToUint(_262), floatBitsToUint(_263), floatBitsToUint(_264), floatBitsToUint(_265));\n    SV_Target.x = _262;\n    SV_Target.y = _263;\n    SV_Target.z = _264;\n    SV_Target.w = _265;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 285\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability GroupNonUniformBallot\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %59 %63 %67\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %15 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %28 \"SSBO\"\nOpName %34 \"SSBO\"\nOpName %39 \"SSBO\"\nOpName %44 \"SSBO\"\nOpName %49 \"SSBO\"\nOpName %54 \"SSBO\"\nOpName %59 \"INDEX\"\nOpName %63 \"UV\"\nOpName %67 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %14 ArrayStride 4\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 1\nOpDecorate %18 Binding 0\nOpDecorate %18 NonWritable\nOpDecorate %18 Restrict\nOpDecorate %21 ArrayStride 4\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %25 DescriptorSet 1\nOpDecorate %25 Binding 0\nOpDecorate %25 NonWritable\nOpDecorate %25 Restrict\nOpDecorate %27 ArrayStride 8\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %31 DescriptorSet 1\nOpDecorate %31 Binding 0\nOpDecorate %31 NonWritable\nOpDecorate %31 Restrict\nOpDecorate %33 ArrayStride 16\nOpMemberDecorate %34 0 Offset 0\nOpDecorate %34 Block\nOpDecorate %37 DescriptorSet 1\nOpDecorate %37 Binding 0\nOpDecorate %37 NonWritable\nOpDecorate %37 Restrict\nOpDecorate %38 ArrayStride 4\nOpMemberDecorate %39 0 Offset 0\nOpDecorate %39 Block\nOpDecorate %42 DescriptorSet 4\nOpDecorate %42 Binding 0\nOpDecorate %42 NonWritable\nOpDecorate %43 ArrayStride 4\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %44 Block\nOpDecorate %47 DescriptorSet 4\nOpDecorate %47 Binding 0\nOpDecorate %47 NonWritable\nOpDecorate %48 ArrayStride 8\nOpMemberDecorate %49 0 Offset 0\nOpDecorate %49 Block\nOpDecorate %52 DescriptorSet 4\nOpDecorate %52 Binding 0\nOpDecorate %52 Aliased\nOpDecorate %53 ArrayStride 16\nOpMemberDecorate %54 0 Offset 0\nOpDecorate %54 Block\nOpDecorate %57 DescriptorSet 4\nOpDecorate %57 Binding 0\nOpDecorate %57 Aliased\nOpDecorate %59 Flat\nOpDecorate %59 Location 0\nOpDecorate %63 Flat\nOpDecorate %63 Location 1\nOpDecorate %67 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeRuntimeArray %5\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeInt 16 0\n%20 = OpTypeVector %19 2\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypeStruct %21\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeVector %19 4\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypeStruct %27\n%29 = OpTypeRuntimeArray %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeVector %5 4\n%33 = OpTypeRuntimeArray %32\n%34 = OpTypeStruct %33\n%35 = OpTypeRuntimeArray %34\n%36 = OpTypePointer StorageBuffer %35\n%37 = OpVariable %36 StorageBuffer\n%38 = OpTypeRuntimeArray %5\n%39 = OpTypeStruct %38\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer StorageBuffer %40\n%42 = OpVariable %41 StorageBuffer\n%43 = OpTypeRuntimeArray %20\n%44 = OpTypeStruct %43\n%45 = OpTypeRuntimeArray %44\n%46 = OpTypePointer StorageBuffer %45\n%47 = OpVariable %46 StorageBuffer\n%48 = OpTypeRuntimeArray %26\n%49 = OpTypeStruct %48\n%50 = OpTypeRuntimeArray %49\n%51 = OpTypePointer StorageBuffer %50\n%52 = OpVariable %51 StorageBuffer\n%53 = OpTypeRuntimeArray %32\n%54 = OpTypeStruct %53\n%55 = OpTypeRuntimeArray %54\n%56 = OpTypePointer StorageBuffer %55\n%57 = OpVariable %56 StorageBuffer\n%58 = OpTypePointer Input %5\n%59 = OpVariable %58 Input\n%60 = OpTypeInt 32 1\n%61 = OpTypeVector %60 4\n%62 = OpTypePointer Input %61\n%63 = OpVariable %62 Input\n%64 = OpTypeFloat 32\n%65 = OpTypeVector %64 4\n%66 = OpTypePointer Output %65\n%67 = OpVariable %66 Output\n%68 = OpTypePointer Input %60\n%70 = OpConstant %5 0\n%74 = OpConstant %5 1\n%78 = OpConstant %5 2\n%82 = OpConstant %5 3\n%85 = OpTypePointer StorageBuffer %15\n%87 = OpTypePointer PushConstant %5\n%91 = OpTypePointer StorageBuffer %9\n%95 = OpConstantComposite %9 %78 %78\n%99 = OpTypeBool\n%102 = OpConstant %5 1073741820\n%103 = OpTypePointer StorageBuffer %5\n%107 = OpTypePointer StorageBuffer %22\n%121 = OpConstant %5 1073741823\n%122 = OpTypePointer StorageBuffer %20\n%125 = OpTypeFloat 16\n%126 = OpTypeVector %125 2\n%132 = OpTypePointer StorageBuffer %39\n%135 = OpConstant %5 4\n%151 = OpTypePointer StorageBuffer %44\n%173 = OpTypePointer StorageBuffer %28\n%178 = OpTypePointer StorageBuffer %34\n%187 = OpConstantComposite %9 %82 %82\n%193 = OpConstant %5 536870911\n%194 = OpTypePointer StorageBuffer %26\n%197 = OpTypeVector %125 4\n%212 = OpConstantComposite %9 %135 %135\n%218 = OpConstant %5 268435455\n%219 = OpTypePointer StorageBuffer %32\n%231 = OpTypePointer StorageBuffer %49\n%236 = OpConstant %5 5\n%237 = OpTypePointer StorageBuffer %54\n%278 = OpTypePointer Output %64\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %283\n%283 = OpLabel\n%69 = OpAccessChain %68 %63 %70\n%71 = OpLoad %60 %69\n%72 = OpBitcast %5 %71\n%73 = OpAccessChain %68 %63 %74\n%75 = OpLoad %60 %73\n%76 = OpBitcast %5 %75\n%77 = OpAccessChain %68 %63 %78\n%79 = OpLoad %60 %77\n%80 = OpBitcast %5 %79\n%81 = OpAccessChain %68 %63 %82\n%83 = OpLoad %60 %81\n%84 = OpBitcast %5 %83\n%88 = OpAccessChain %87 %8 %74\n%89 = OpLoad %5 %88\n%86 = OpAccessChain %85 %18 %89\n%90 = OpGroupNonUniformBroadcastFirst %5 %82 %89\n%92 = OpAccessChain %91 %13 %70 %90\n%93 = OpLoad %9 %92\n%94 = OpShiftRightLogical %9 %93 %95\n%96 = OpCompositeExtract %5 %94 0\n%97 = OpCompositeExtract %5 %94 1\n%98 = OpIAdd %5 %72 %96\n%100 = OpULessThan %99 %72 %97\n%101 = OpSelect %5 %100 %98 %102\n%104 = OpAccessChain %103 %86 %70 %101\n%105 = OpLoad %5 %104\n%106 = OpBitcast %64 %105\n%109 = OpAccessChain %87 %8 %74\n%110 = OpLoad %5 %109\n%111 = OpIAdd %5 %110 %74\n%108 = OpAccessChain %107 %25 %111\n%112 = OpGroupNonUniformBroadcastFirst %5 %82 %111\n%113 = OpAccessChain %91 %13 %70 %112\n%114 = OpLoad %9 %113\n%115 = OpShiftRightLogical %9 %114 %95\n%116 = OpCompositeExtract %5 %115 0\n%117 = OpCompositeExtract %5 %115 1\n%118 = OpIAdd %5 %76 %116\n%119 = OpULessThan %99 %76 %117\n%120 = OpSelect %5 %119 %118 %121\n%123 = OpAccessChain %122 %108 %70 %120\n%124 = OpLoad %20 %123\n%127 = OpBitcast %126 %124\n%128 = OpCompositeExtract %125 %127 0\n%129 = OpCompositeExtract %125 %127 1\n%130 = OpFConvert %64 %128\n%131 = OpFConvert %64 %129\n%134 = OpAccessChain %87 %8 %135\n%136 = OpLoad %5 %134\n%137 = OpIAdd %5 %136 %78\n%133 = OpAccessChain %132 %42 %137\n%138 = OpGroupNonUniformBroadcastFirst %5 %82 %137\n%139 = OpAccessChain %91 %13 %70 %138\n%140 = OpLoad %9 %139\n%141 = OpShiftRightLogical %9 %140 %95\n%142 = OpCompositeExtract %5 %141 0\n%143 = OpCompositeExtract %5 %141 1\n%144 = OpIAdd %5 %80 %142\n%145 = OpULessThan %99 %80 %143\n%146 = OpSelect %5 %145 %144 %102\n%147 = OpAccessChain %103 %133 %70 %146\n%148 = OpLoad %5 %147\n%149 = OpBitcast %64 %148\n%150 = OpFAdd %64 %149 %131\n%153 = OpAccessChain %87 %8 %135\n%154 = OpLoad %5 %153\n%155 = OpIAdd %5 %154 %82\n%152 = OpAccessChain %151 %47 %155\n%156 = OpGroupNonUniformBroadcastFirst %5 %82 %155\n%157 = OpAccessChain %91 %13 %70 %156\n%158 = OpLoad %9 %157\n%159 = OpShiftRightLogical %9 %158 %95\n%160 = OpCompositeExtract %5 %159 0\n%161 = OpCompositeExtract %5 %159 1\n%162 = OpIAdd %5 %84 %160\n%163 = OpULessThan %99 %84 %161\n%164 = OpSelect %5 %163 %162 %121\n%165 = OpAccessChain %122 %152 %70 %164\n%166 = OpLoad %20 %165\n%167 = OpBitcast %126 %166\n%168 = OpCompositeExtract %125 %167 0\n%169 = OpCompositeExtract %125 %167 1\n%170 = OpFConvert %64 %168\n%171 = OpFConvert %64 %169\n%172 = OpFAdd %64 %171 %106\n%175 = OpAccessChain %87 %8 %74\n%176 = OpLoad %5 %175\n%177 = OpIAdd %5 %176 %135\n%174 = OpAccessChain %173 %31 %177\n%180 = OpAccessChain %87 %8 %74\n%181 = OpLoad %5 %180\n%182 = OpIAdd %5 %181 %135\n%179 = OpAccessChain %178 %37 %182\n%183 = OpGroupNonUniformBroadcastFirst %5 %82 %182\n%184 = OpAccessChain %91 %13 %70 %183\n%185 = OpLoad %9 %184\n%186 = OpShiftRightLogical %9 %185 %187\n%188 = OpCompositeExtract %5 %186 0\n%189 = OpCompositeExtract %5 %186 1\n%190 = OpIAdd %5 %74 %188\n%191 = OpULessThan %99 %74 %189\n%192 = OpSelect %5 %191 %190 %193\n%195 = OpAccessChain %194 %174 %70 %192\n%196 = OpLoad %26 %195\n%198 = OpBitcast %197 %196\n%199 = OpCompositeExtract %125 %198 0\n%200 = OpCompositeExtract %125 %198 1\n%201 = OpCompositeExtract %125 %198 2\n%202 = OpCompositeExtract %125 %198 3\n%203 = OpFConvert %64 %199\n%204 = OpFConvert %64 %200\n%205 = OpFConvert %64 %201\n%206 = OpFConvert %64 %202\n%207 = OpFAdd %64 %172 %203\n%208 = OpFAdd %64 %204 %130\n%209 = OpFAdd %64 %150 %205\n%210 = OpFAdd %64 %206 %170\n%211 = OpShiftRightLogical %9 %185 %212\n%213 = OpCompositeExtract %5 %211 0\n%214 = OpCompositeExtract %5 %211 1\n%215 = OpIAdd %5 %74 %213\n%216 = OpULessThan %99 %74 %214\n%217 = OpSelect %5 %216 %215 %218\n%220 = OpAccessChain %219 %179 %70 %217\n%221 = OpLoad %32 %220\n%222 = OpBitcast %65 %221\n%223 = OpCompositeExtract %64 %222 0\n%224 = OpCompositeExtract %64 %222 1\n%225 = OpCompositeExtract %64 %222 2\n%226 = OpCompositeExtract %64 %222 3\n%227 = OpFAdd %64 %207 %223\n%228 = OpFAdd %64 %208 %224\n%229 = OpFAdd %64 %209 %225\n%230 = OpFAdd %64 %210 %226\n%233 = OpAccessChain %87 %8 %135\n%234 = OpLoad %5 %233\n%235 = OpIAdd %5 %234 %236\n%232 = OpAccessChain %231 %52 %235\n%239 = OpAccessChain %87 %8 %135\n%240 = OpLoad %5 %239\n%241 = OpIAdd %5 %240 %236\n%238 = OpAccessChain %237 %57 %241\n%242 = OpGroupNonUniformBroadcastFirst %5 %82 %241\n%243 = OpAccessChain %91 %13 %70 %242\n%244 = OpLoad %9 %243\n%245 = OpShiftRightLogical %9 %244 %187\n%246 = OpCompositeExtract %5 %245 0\n%247 = OpCompositeExtract %5 %245 1\n%248 = OpIAdd %5 %74 %246\n%249 = OpULessThan %99 %74 %247\n%250 = OpSelect %5 %249 %248 %193\n%251 = OpAccessChain %194 %232 %70 %250\n%252 = OpLoad %26 %251\n%253 = OpBitcast %197 %252\n%254 = OpCompositeExtract %125 %253 0\n%255 = OpCompositeExtract %125 %253 1\n%256 = OpCompositeExtract %125 %253 2\n%257 = OpCompositeExtract %125 %253 3\n%258 = OpFConvert %64 %254\n%259 = OpFConvert %64 %255\n%260 = OpFConvert %64 %256\n%261 = OpFConvert %64 %257\n%262 = OpFAdd %64 %227 %258\n%263 = OpFAdd %64 %228 %259\n%264 = OpFAdd %64 %229 %260\n%265 = OpFAdd %64 %230 %261\n%266 = OpShiftRightLogical %9 %244 %212\n%267 = OpCompositeExtract %5 %266 0\n%268 = OpCompositeExtract %5 %266 1\n%269 = OpIAdd %5 %74 %267\n%270 = OpULessThan %99 %74 %268\n%271 = OpSelect %5 %270 %269 %218\n%272 = OpBitcast %5 %262\n%273 = OpBitcast %5 %263\n%274 = OpBitcast %5 %264\n%275 = OpBitcast %5 %265\n%276 = OpCompositeConstruct %32 %272 %273 %274 %275\n%277 = OpAccessChain %219 %238 %70 %271\nOpStore %277 %276\n%279 = OpAccessChain %278 %67 %70\nOpStore %279 %262\n%280 = OpAccessChain %278 %67 %74\nOpStore %280 %263\n%281 = OpAccessChain %278 %67 %78\nOpStore %281 %264\n%282 = OpAccessChain %278 %67 %82\nOpStore %282 %265\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raw-buffers-binding.ssbo.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _12;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO_16bit\n{\n    uint16_t _m0[];\n} _14;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _16_18\n{\n    uint _m0[];\n} _18;\n\nlayout(set = 0, binding = 4, std430) restrict readonly buffer _20_22\n{\n    uint _m0[];\n} _22;\n\nlayout(set = 0, binding = 2, std430) buffer _24_26\n{\n    uint _m0[];\n} _26;\n\nlayout(set = 0, binding = 2, std430) buffer _28_30\n{\n    uint16_t _m0[];\n} _30;\n\nlayout(set = 0, binding = 3, std430) writeonly readonly buffer _32_34\n{\n    uint _m0[];\n} _34;\n\nlayout(set = 0, binding = 5, std430) writeonly readonly buffer _36_38\n{\n    uint _m0[];\n} _38;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nuint _104;\n\nvoid main()\n{\n    uint _70 = uint(UV.y) * 2u;\n    f16vec2 _81 = uint16BitsToFloat16(u16vec2(_14._m0[_70], _14._m0[_70 + 1u]));\n    uint _87 = _26._m0[uint(UV.z)];\n    uint _90 = uint(UV.w) * 2u;\n    uint16_t _92 = _30._m0[_90];\n    uint16_t _95 = _30._m0[_90 + 1u];\n    f16vec2 _97 = uint16BitsToFloat16(u16vec2(_92, _95));\n    uint _107 = (8u * 2u) + (_104 >> 1u);\n    f16vec4 _122 = uint16BitsToFloat16(u16vec4(_14._m0[_107], _14._m0[_107 + 1u], _14._m0[_107 + 2u], _14._m0[_107 + 3u]));\n    uint _137 = 16u + (_104 >> 2u);\n    vec4 _151 = uintBitsToFloat(uvec4(_12._m0[_137], _12._m0[_137 + 1u], _12._m0[_137 + 2u], _12._m0[_137 + 3u]));\n    uint _162 = (8u * 2u) + (_104 >> 1u);\n    uint16_t _164 = _30._m0[_162];\n    uint16_t _167 = _30._m0[_162 + 1u];\n    uint16_t _170 = _30._m0[_162 + 2u];\n    uint16_t _173 = _30._m0[_162 + 3u];\n    f16vec4 _175 = uint16BitsToFloat16(u16vec4(_164, _167, _170, _173));\n    float _184 = (((float(_97.y) + uintBitsToFloat(_12._m0[uint(UV.x)])) + float(_122.x)) + _151.x) + float(_175.x);\n    float _185 = ((float(_122.y) + float(_81.x)) + _151.y) + float(_175.y);\n    float _186 = (((uintBitsToFloat(_87) + float(_81.y)) + float(_122.z)) + _151.z) + float(_175.z);\n    float _187 = ((float(_122.w) + float(_97.x)) + _151.w) + float(_175.w);\n    uint _189 = 16u + (_104 >> 2u);\n    _26._m0[_189] = floatBitsToUint(_184);\n    _26._m0[_189 + 1u] = floatBitsToUint(_185);\n    _26._m0[_189 + 2u] = floatBitsToUint(_186);\n    _26._m0[_189 + 3u] = floatBitsToUint(_187);\n    SV_Target.x = _184;\n    SV_Target.y = _185;\n    SV_Target.z = _186;\n    SV_Target.w = _187;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 208\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %40 %44 %48\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %10 \"SSBO_16bit\"\nOpName %16 \"SSBO\"\nOpName %20 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %28 \"SSBO_16bit\"\nOpName %32 \"SSBO\"\nOpName %36 \"SSBO\"\nOpName %40 \"INDEX\"\nOpName %44 \"UV\"\nOpName %48 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 ArrayStride 2\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonWritable\nOpDecorate %12 Restrict\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 4\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 1\nOpDecorate %18 NonWritable\nOpDecorate %18 Restrict\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 4\nOpDecorate %22 NonWritable\nOpDecorate %22 Restrict\nOpDecorate %23 ArrayStride 4\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %27 ArrayStride 2\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 2\nOpDecorate %30 DescriptorSet 0\nOpDecorate %30 Binding 2\nOpDecorate %26 Aliased\nOpDecorate %30 Aliased\nOpDecorate %31 ArrayStride 4\nOpMemberDecorate %32 0 Offset 0\nOpDecorate %32 Block\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 3\nOpDecorate %34 NonReadable\nOpDecorate %34 NonWritable\nOpDecorate %35 ArrayStride 4\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 5\nOpDecorate %38 NonReadable\nOpDecorate %38 NonWritable\nOpDecorate %40 Flat\nOpDecorate %40 Location 0\nOpDecorate %44 Flat\nOpDecorate %44 Location 1\nOpDecorate %48 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypeInt 16 0\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypeStruct %9\n%11 = OpTypePointer StorageBuffer %7\n%12 = OpVariable %11 StorageBuffer\n%13 = OpTypePointer StorageBuffer %10\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %5\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %5\n%24 = OpTypeStruct %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeRuntimeArray %8\n%28 = OpTypeStruct %27\n%29 = OpTypePointer StorageBuffer %28\n%30 = OpVariable %29 StorageBuffer\n%31 = OpTypeRuntimeArray %5\n%32 = OpTypeStruct %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeRuntimeArray %5\n%36 = OpTypeStruct %35\n%37 = OpTypePointer StorageBuffer %36\n%38 = OpVariable %37 StorageBuffer\n%39 = OpTypePointer Input %5\n%40 = OpVariable %39 Input\n%41 = OpTypeInt 32 1\n%42 = OpTypeVector %41 4\n%43 = OpTypePointer Input %42\n%44 = OpVariable %43 Input\n%45 = OpTypeFloat 32\n%46 = OpTypeVector %45 4\n%47 = OpTypePointer Output %46\n%48 = OpVariable %47 Output\n%49 = OpTypePointer Input %41\n%51 = OpConstant %5 0\n%55 = OpConstant %5 1\n%59 = OpConstant %5 2\n%63 = OpConstant %5 3\n%66 = OpTypePointer StorageBuffer %5\n%71 = OpTypePointer StorageBuffer %8\n%77 = OpTypeVector %8 2\n%79 = OpTypeFloat 16\n%80 = OpTypeVector %79 2\n%103 = OpConstant %5 8\n%119 = OpTypeVector %8 4\n%121 = OpTypeVector %79 4\n%135 = OpConstant %5 16\n%149 = OpTypeVector %5 4\n%201 = OpTypePointer Output %45\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%104 = OpUndef %5\nOpBranch %206\n%206 = OpLabel\n%50 = OpAccessChain %49 %44 %51\n%52 = OpLoad %41 %50\n%53 = OpBitcast %5 %52\n%54 = OpAccessChain %49 %44 %55\n%56 = OpLoad %41 %54\n%57 = OpBitcast %5 %56\n%58 = OpAccessChain %49 %44 %59\n%60 = OpLoad %41 %58\n%61 = OpBitcast %5 %60\n%62 = OpAccessChain %49 %44 %63\n%64 = OpLoad %41 %62\n%65 = OpBitcast %5 %64\n%67 = OpAccessChain %66 %12 %51 %53\n%68 = OpLoad %5 %67\n%69 = OpBitcast %45 %68\n%70 = OpIMul %5 %57 %59\n%72 = OpAccessChain %71 %14 %51 %70\n%73 = OpLoad %8 %72\n%75 = OpIAdd %5 %70 %55\n%74 = OpAccessChain %71 %14 %51 %75\n%76 = OpLoad %8 %74\n%78 = OpCompositeConstruct %77 %73 %76\n%81 = OpBitcast %80 %78\n%82 = OpCompositeExtract %79 %81 0\n%83 = OpCompositeExtract %79 %81 1\n%84 = OpFConvert %45 %82\n%85 = OpFConvert %45 %83\n%86 = OpAccessChain %66 %26 %51 %61\n%87 = OpLoad %5 %86\n%88 = OpBitcast %45 %87\n%89 = OpFAdd %45 %88 %85\n%90 = OpIMul %5 %65 %59\n%91 = OpAccessChain %71 %30 %51 %90\n%92 = OpLoad %8 %91\n%94 = OpIAdd %5 %90 %55\n%93 = OpAccessChain %71 %30 %51 %94\n%95 = OpLoad %8 %93\n%96 = OpCompositeConstruct %77 %92 %95\n%97 = OpBitcast %80 %96\n%98 = OpCompositeExtract %79 %97 0\n%99 = OpCompositeExtract %79 %97 1\n%100 = OpFConvert %45 %98\n%101 = OpFConvert %45 %99\n%102 = OpFAdd %45 %101 %69\n%105 = OpIMul %5 %103 %59\n%106 = OpShiftRightLogical %5 %104 %55\n%107 = OpIAdd %5 %105 %106\n%108 = OpAccessChain %71 %14 %51 %107\n%109 = OpLoad %8 %108\n%111 = OpIAdd %5 %107 %55\n%110 = OpAccessChain %71 %14 %51 %111\n%112 = OpLoad %8 %110\n%114 = OpIAdd %5 %107 %59\n%113 = OpAccessChain %71 %14 %51 %114\n%115 = OpLoad %8 %113\n%117 = OpIAdd %5 %107 %63\n%116 = OpAccessChain %71 %14 %51 %117\n%118 = OpLoad %8 %116\n%120 = OpCompositeConstruct %119 %109 %112 %115 %118\n%122 = OpBitcast %121 %120\n%123 = OpCompositeExtract %79 %122 0\n%124 = OpCompositeExtract %79 %122 1\n%125 = OpCompositeExtract %79 %122 2\n%126 = OpCompositeExtract %79 %122 3\n%127 = OpFConvert %45 %123\n%128 = OpFConvert %45 %124\n%129 = OpFConvert %45 %125\n%130 = OpFConvert %45 %126\n%131 = OpFAdd %45 %102 %127\n%132 = OpFAdd %45 %128 %84\n%133 = OpFAdd %45 %89 %129\n%134 = OpFAdd %45 %130 %100\n%136 = OpShiftRightLogical %5 %104 %59\n%137 = OpIAdd %5 %135 %136\n%138 = OpAccessChain %66 %12 %51 %137\n%139 = OpLoad %5 %138\n%141 = OpIAdd %5 %137 %55\n%140 = OpAccessChain %66 %12 %51 %141\n%142 = OpLoad %5 %140\n%144 = OpIAdd %5 %137 %59\n%143 = OpAccessChain %66 %12 %51 %144\n%145 = OpLoad %5 %143\n%147 = OpIAdd %5 %137 %63\n%146 = OpAccessChain %66 %12 %51 %147\n%148 = OpLoad %5 %146\n%150 = OpCompositeConstruct %149 %139 %142 %145 %148\n%151 = OpBitcast %46 %150\n%152 = OpCompositeExtract %45 %151 0\n%153 = OpCompositeExtract %45 %151 1\n%154 = OpCompositeExtract %45 %151 2\n%155 = OpCompositeExtract %45 %151 3\n%156 = OpFAdd %45 %131 %152\n%157 = OpFAdd %45 %132 %153\n%158 = OpFAdd %45 %133 %154\n%159 = OpFAdd %45 %134 %155\n%160 = OpIMul %5 %103 %59\n%161 = OpShiftRightLogical %5 %104 %55\n%162 = OpIAdd %5 %160 %161\n%163 = OpAccessChain %71 %30 %51 %162\n%164 = OpLoad %8 %163\n%166 = OpIAdd %5 %162 %55\n%165 = OpAccessChain %71 %30 %51 %166\n%167 = OpLoad %8 %165\n%169 = OpIAdd %5 %162 %59\n%168 = OpAccessChain %71 %30 %51 %169\n%170 = OpLoad %8 %168\n%172 = OpIAdd %5 %162 %63\n%171 = OpAccessChain %71 %30 %51 %172\n%173 = OpLoad %8 %171\n%174 = OpCompositeConstruct %119 %164 %167 %170 %173\n%175 = OpBitcast %121 %174\n%176 = OpCompositeExtract %79 %175 0\n%177 = OpCompositeExtract %79 %175 1\n%178 = OpCompositeExtract %79 %175 2\n%179 = OpCompositeExtract %79 %175 3\n%180 = OpFConvert %45 %176\n%181 = OpFConvert %45 %177\n%182 = OpFConvert %45 %178\n%183 = OpFConvert %45 %179\n%184 = OpFAdd %45 %156 %180\n%185 = OpFAdd %45 %157 %181\n%186 = OpFAdd %45 %158 %182\n%187 = OpFAdd %45 %159 %183\n%188 = OpShiftRightLogical %5 %104 %59\n%189 = OpIAdd %5 %135 %188\n%190 = OpBitcast %5 %184\n%191 = OpBitcast %5 %185\n%192 = OpBitcast %5 %186\n%193 = OpBitcast %5 %187\n%194 = OpAccessChain %66 %26 %51 %189\nOpStore %194 %190\n%196 = OpIAdd %5 %189 %55\n%195 = OpAccessChain %66 %26 %51 %196\nOpStore %195 %191\n%198 = OpIAdd %5 %189 %59\n%197 = OpAccessChain %66 %26 %51 %198\nOpStore %197 %192\n%200 = OpIAdd %5 %189 %63\n%199 = OpAccessChain %66 %26 %51 %200\nOpStore %199 %193\n%202 = OpAccessChain %201 %48 %51\nOpStore %202 %184\n%203 = OpAccessChain %201 %48 %55\nOpStore %203 %185\n%204 = OpAccessChain %201 %48 %59\nOpStore %204 %186\n%205 = OpAccessChain %201 %48 %63\nOpStore %205 %187\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raygen-heap.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _14\n{\n    float _m0;\n};\n\nstruct _18\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT _8[];\nlayout(set = 0, binding = 0) uniform writeonly image2D _13[];\nlayout(location = 0) rayPayloadEXT _14 _16;\nlayout(location = 1) rayPayloadEXT _18 _20;\n\nvoid main()\n{\n    traceRayEXT(_8[0u], 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(_8[0u], 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(_13[1u], ivec2(uvec2(0u)), vec4(_16._m0 + _20._m0.x, _16._m0 + _20._m0.y, _16._m0 + _20._m0.z, _16._m0 + _20._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %13 %16 %20\nOpName %3 \"main\"\nOpName %14 \"\"\nOpName %18 \"\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeAccelerationStructureKHR\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeStruct %9\n%15 = OpTypePointer RayPayloadKHR %14\n%16 = OpVariable %15 RayPayloadKHR\n%17 = OpTypeVector %9 4\n%18 = OpTypeStruct %17\n%19 = OpTypePointer RayPayloadKHR %18\n%20 = OpVariable %19 RayPayloadKHR\n%21 = OpTypePointer UniformConstant %5\n%23 = OpTypeInt 32 0\n%24 = OpConstant %23 0\n%26 = OpTypePointer UniformConstant %10\n%28 = OpConstant %23 1\n%30 = OpConstant %9 1\n%31 = OpConstant %9 0\n%32 = OpConstant %9 2\n%33 = OpConstant %9 3\n%34 = OpConstant %9 4\n%35 = OpTypeVector %9 3\n%38 = OpTypePointer RayPayloadKHR %17\n%47 = OpTypePointer RayPayloadKHR %9\n%54 = OpTypeVector %23 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%22 = OpAccessChain %21 %8 %24\n%25 = OpLoad %5 %22\n%27 = OpAccessChain %26 %13 %28\n%29 = OpLoad %10 %27\n%36 = OpCompositeConstruct %35 %30 %32 %33\n%37 = OpCompositeConstruct %35 %31 %31 %30\nOpTraceRayKHR %25 %24 %24 %24 %24 %24 %36 %30 %37 %34 %20\n%39 = OpInBoundsAccessChain %38 %20 %24\n%40 = OpLoad %17 %39\n%41 = OpCompositeExtract %9 %40 0\n%42 = OpCompositeExtract %9 %40 1\n%43 = OpCompositeExtract %9 %40 2\n%44 = OpCompositeExtract %9 %40 3\n%45 = OpCompositeConstruct %35 %30 %32 %33\n%46 = OpCompositeConstruct %35 %31 %31 %30\nOpTraceRayKHR %25 %24 %28 %24 %24 %24 %45 %30 %46 %34 %16\n%48 = OpInBoundsAccessChain %47 %16 %24\n%49 = OpLoad %9 %48\n%50 = OpFAdd %9 %49 %41\n%51 = OpFAdd %9 %49 %42\n%52 = OpFAdd %9 %49 %43\n%53 = OpFAdd %9 %49 %44\n%55 = OpCompositeConstruct %54 %24 %24\n%56 = OpCompositeConstruct %17 %50 %51 %52 %53\nOpImageWrite %29 %55 %56\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raygen-heap.ssbo-rtas.raw-va-stride-offset.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _16\n{\n    float _m0;\n};\n\nstruct _20\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer RTASHeap\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 0) uniform writeonly image2D _15[];\nlayout(location = 0) rayPayloadEXT _16 _18;\nlayout(location = 1) rayPayloadEXT _20 _22;\n\nvoid main()\n{\n    uint _24 = subgroupBroadcastFirst(0u);\n    uvec2 _33 = _10._m0[(4u * _24) + 3u];\n    traceRayEXT(accelerationStructureEXT(_33), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(accelerationStructureEXT(_33), 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(_15[1u], ivec2(uvec2(0u)), vec4(_18._m0 + _22._m0.x, _18._m0 + _22._m0.y, _18._m0 + _22._m0.z, _18._m0 + _22._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %10 %15 %18 %22\nOpName %3 \"main\"\nOpName %8 \"RTASHeap\"\nOpName %16 \"\"\nOpName %20 \"\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeFloat 32\n%12 = OpTypeImage %11 2D 0 0 0 2 Unknown\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypeStruct %11\n%17 = OpTypePointer RayPayloadKHR %16\n%18 = OpVariable %17 RayPayloadKHR\n%19 = OpTypeVector %11 4\n%20 = OpTypeStruct %19\n%21 = OpTypePointer RayPayloadKHR %20\n%22 = OpVariable %21 RayPayloadKHR\n%23 = OpConstant %5 0\n%25 = OpConstant %5 3\n%27 = OpConstant %5 4\n%29 = OpTypePointer StorageBuffer %6\n%32 = OpTypeAccelerationStructureKHR\n%34 = OpTypePointer UniformConstant %12\n%36 = OpConstant %5 1\n%38 = OpConstant %11 1\n%39 = OpConstant %11 0\n%40 = OpConstant %11 2\n%41 = OpConstant %11 3\n%42 = OpConstant %11 4\n%43 = OpTypeVector %11 3\n%46 = OpTypePointer RayPayloadKHR %19\n%55 = OpTypePointer RayPayloadKHR %11\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%24 = OpGroupNonUniformBroadcastFirst %5 %25 %23\n%26 = OpIMul %5 %27 %24\n%28 = OpIAdd %5 %26 %25\n%30 = OpAccessChain %29 %10 %23 %28\n%31 = OpLoad %6 %30\n%33 = OpConvertUToAccelerationStructureKHR %32 %31\n%35 = OpAccessChain %34 %15 %36\n%37 = OpLoad %12 %35\n%44 = OpCompositeConstruct %43 %38 %40 %41\n%45 = OpCompositeConstruct %43 %39 %39 %38\nOpTraceRayKHR %33 %23 %23 %23 %23 %23 %44 %38 %45 %42 %22\n%47 = OpInBoundsAccessChain %46 %22 %23\n%48 = OpLoad %19 %47\n%49 = OpCompositeExtract %11 %48 0\n%50 = OpCompositeExtract %11 %48 1\n%51 = OpCompositeExtract %11 %48 2\n%52 = OpCompositeExtract %11 %48 3\n%53 = OpCompositeConstruct %43 %38 %40 %41\n%54 = OpCompositeConstruct %43 %39 %39 %38\nOpTraceRayKHR %33 %23 %36 %23 %23 %23 %53 %38 %54 %42 %18\n%56 = OpInBoundsAccessChain %55 %18 %23\n%57 = OpLoad %11 %56\n%58 = OpFAdd %11 %57 %49\n%59 = OpFAdd %11 %57 %50\n%60 = OpFAdd %11 %57 %51\n%61 = OpFAdd %11 %57 %52\n%62 = OpCompositeConstruct %6 %23 %23\n%63 = OpCompositeConstruct %19 %58 %59 %60 %61\nOpImageWrite %37 %62 %63\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raygen-heap.ssbo-rtas.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _16\n{\n    float _m0;\n};\n\nstruct _20\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer RTASHeap\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 0) uniform writeonly image2D _15[];\nlayout(location = 0) rayPayloadEXT _16 _18;\nlayout(location = 1) rayPayloadEXT _20 _22;\n\nvoid main()\n{\n    uint _24 = subgroupBroadcastFirst(0u);\n    uvec2 _30 = _10._m0[_24];\n    traceRayEXT(accelerationStructureEXT(_30), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(accelerationStructureEXT(_30), 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(_15[1u], ivec2(uvec2(0u)), vec4(_18._m0 + _22._m0.x, _18._m0 + _22._m0.y, _18._m0 + _22._m0.z, _18._m0 + _22._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 63\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %10 %15 %18 %22\nOpName %3 \"main\"\nOpName %8 \"RTASHeap\"\nOpName %16 \"\"\nOpName %20 \"\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeFloat 32\n%12 = OpTypeImage %11 2D 0 0 0 2 Unknown\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypeStruct %11\n%17 = OpTypePointer RayPayloadKHR %16\n%18 = OpVariable %17 RayPayloadKHR\n%19 = OpTypeVector %11 4\n%20 = OpTypeStruct %19\n%21 = OpTypePointer RayPayloadKHR %20\n%22 = OpVariable %21 RayPayloadKHR\n%23 = OpConstant %5 0\n%25 = OpConstant %5 3\n%26 = OpTypePointer StorageBuffer %6\n%29 = OpTypeAccelerationStructureKHR\n%31 = OpTypePointer UniformConstant %12\n%33 = OpConstant %5 1\n%35 = OpConstant %11 1\n%36 = OpConstant %11 0\n%37 = OpConstant %11 2\n%38 = OpConstant %11 3\n%39 = OpConstant %11 4\n%40 = OpTypeVector %11 3\n%43 = OpTypePointer RayPayloadKHR %19\n%52 = OpTypePointer RayPayloadKHR %11\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%24 = OpGroupNonUniformBroadcastFirst %5 %25 %23\n%27 = OpAccessChain %26 %10 %23 %24\n%28 = OpLoad %6 %27\n%30 = OpConvertUToAccelerationStructureKHR %29 %28\n%32 = OpAccessChain %31 %15 %33\n%34 = OpLoad %12 %32\n%41 = OpCompositeConstruct %40 %35 %37 %38\n%42 = OpCompositeConstruct %40 %36 %36 %35\nOpTraceRayKHR %30 %23 %23 %23 %23 %23 %41 %35 %42 %39 %22\n%44 = OpInBoundsAccessChain %43 %22 %23\n%45 = OpLoad %19 %44\n%46 = OpCompositeExtract %11 %45 0\n%47 = OpCompositeExtract %11 %45 1\n%48 = OpCompositeExtract %11 %45 2\n%49 = OpCompositeExtract %11 %45 3\n%50 = OpCompositeConstruct %40 %35 %37 %38\n%51 = OpCompositeConstruct %40 %36 %36 %35\nOpTraceRayKHR %30 %23 %33 %23 %23 %23 %50 %35 %51 %39 %18\n%53 = OpInBoundsAccessChain %52 %18 %23\n%54 = OpLoad %11 %53\n%55 = OpFAdd %11 %54 %46\n%56 = OpFAdd %11 %54 %47\n%57 = OpFAdd %11 %54 %48\n%58 = OpFAdd %11 %54 %49\n%59 = OpCompositeConstruct %6 %23 %23\n%60 = OpCompositeConstruct %19 %55 %56 %57 %58\nOpImageWrite %34 %59 %60\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raygen.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _13\n{\n    float _m0;\n};\n\nstruct _17\n{\n    vec4 _m0;\n};\n\nlayout(set = 40, binding = 30) uniform accelerationStructureEXT AS;\nlayout(set = 20, binding = 10) uniform writeonly image2D IMG;\nlayout(location = 0) rayPayloadEXT _13 _15;\nlayout(location = 1) rayPayloadEXT _17 _19;\n\nvoid main()\n{\n    traceRayEXT(AS, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(AS, 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(IMG, ivec2(uvec2(0u)), vec4(_15._m0 + _19._m0.x, _15._m0 + _19._m0.y, _15._m0 + _19._m0.z, _15._m0 + _19._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %15 %19\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %12 \"IMG\"\nOpName %13 \"\"\nOpName %17 \"\"\nOpDecorate %8 DescriptorSet 40\nOpDecorate %8 Binding 30\nOpDecorate %12 DescriptorSet 20\nOpDecorate %12 Binding 10\nOpDecorate %12 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeStruct %9\n%14 = OpTypePointer RayPayloadKHR %13\n%15 = OpVariable %14 RayPayloadKHR\n%16 = OpTypeVector %9 4\n%17 = OpTypeStruct %16\n%18 = OpTypePointer RayPayloadKHR %17\n%19 = OpVariable %18 RayPayloadKHR\n%21 = OpTypeInt 32 0\n%22 = OpConstant %21 0\n%23 = OpConstant %9 1\n%24 = OpConstant %9 0\n%25 = OpConstant %9 2\n%26 = OpConstant %9 3\n%27 = OpConstant %9 4\n%28 = OpTypeVector %9 3\n%31 = OpTypePointer RayPayloadKHR %16\n%39 = OpConstant %21 1\n%42 = OpTypePointer RayPayloadKHR %9\n%50 = OpTypeVector %21 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%20 = OpLoad %6 %8\n%29 = OpCompositeConstruct %28 %23 %25 %26\n%30 = OpCompositeConstruct %28 %24 %24 %23\nOpTraceRayKHR %20 %22 %22 %22 %22 %22 %29 %23 %30 %27 %19\n%32 = OpInBoundsAccessChain %31 %19 %22\n%33 = OpLoad %16 %32\n%34 = OpCompositeExtract %9 %33 0\n%35 = OpCompositeExtract %9 %33 1\n%36 = OpCompositeExtract %9 %33 2\n%37 = OpCompositeExtract %9 %33 3\n%38 = OpLoad %6 %8\n%40 = OpCompositeConstruct %28 %23 %25 %26\n%41 = OpCompositeConstruct %28 %24 %24 %23\nOpTraceRayKHR %38 %22 %39 %22 %22 %22 %40 %23 %41 %27 %15\n%43 = OpInBoundsAccessChain %42 %15 %22\n%44 = OpLoad %9 %43\n%45 = OpFAdd %9 %44 %34\n%46 = OpFAdd %9 %44 %35\n%47 = OpFAdd %9 %44 %36\n%48 = OpFAdd %9 %44 %37\n%49 = OpLoad %10 %12\n%51 = OpCompositeConstruct %50 %22 %22\n%52 = OpCompositeConstruct %16 %45 %46 %47 %48\nOpImageWrite %49 %51 %52\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raygen.ssbo-rtas.bindless.raw-va-stride-offset.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _19\n{\n    float _m0;\n};\n\nstruct _23\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer RTASHeap\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 3, binding = 0) uniform writeonly image2D _18[];\nlayout(location = 0) rayPayloadEXT _19 _21;\nlayout(location = 1) rayPayloadEXT _23 _25;\n\nvoid main()\n{\n    traceRayEXT(accelerationStructureEXT(_13._m0[(4u * subgroupBroadcastFirst(registers._m0 + 30u)) + 3u]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(accelerationStructureEXT(_13._m0[(4u * subgroupBroadcastFirst(registers._m0 + 30u)) + 3u]), 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(_18[registers._m3 + 10u], ivec2(uvec2(0u)), vec4(_21._m0 + _25._m0.x, _21._m0 + _25._m0.y, _21._m0 + _25._m0.z, _21._m0 + _25._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %13 %18 %21 %25\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"RTASHeap\"\nOpName %19 \"\"\nOpName %23 \"\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %18 DescriptorSet 3\nOpDecorate %18 Binding 0\nOpDecorate %18 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFloat 32\n%15 = OpTypeImage %14 2D 0 0 0 2 Unknown\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypeStruct %14\n%20 = OpTypePointer RayPayloadKHR %19\n%21 = OpVariable %20 RayPayloadKHR\n%22 = OpTypeVector %14 4\n%23 = OpTypeStruct %22\n%24 = OpTypePointer RayPayloadKHR %23\n%25 = OpVariable %24 RayPayloadKHR\n%26 = OpTypePointer PushConstant %5\n%28 = OpConstant %5 0\n%31 = OpConstant %5 30\n%33 = OpConstant %5 3\n%35 = OpConstant %5 4\n%37 = OpTypePointer StorageBuffer %9\n%40 = OpTypeAccelerationStructureKHR\n%42 = OpConstant %14 1\n%43 = OpConstant %14 0\n%44 = OpConstant %14 2\n%45 = OpConstant %14 3\n%46 = OpConstant %14 4\n%47 = OpTypeVector %14 3\n%50 = OpTypePointer RayPayloadKHR %22\n%66 = OpConstant %5 1\n%69 = OpTypePointer RayPayloadKHR %14\n%76 = OpTypePointer UniformConstant %15\n%81 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %85\n%85 = OpLabel\n%27 = OpAccessChain %26 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpIAdd %5 %29 %31\n%32 = OpGroupNonUniformBroadcastFirst %5 %33 %30\n%34 = OpIMul %5 %35 %32\n%36 = OpIAdd %5 %34 %33\n%38 = OpAccessChain %37 %13 %28 %36\n%39 = OpLoad %9 %38\n%41 = OpConvertUToAccelerationStructureKHR %40 %39\n%48 = OpCompositeConstruct %47 %42 %44 %45\n%49 = OpCompositeConstruct %47 %43 %43 %42\nOpTraceRayKHR %41 %28 %28 %28 %28 %28 %48 %42 %49 %46 %25\n%51 = OpInBoundsAccessChain %50 %25 %28\n%52 = OpLoad %22 %51\n%53 = OpCompositeExtract %14 %52 0\n%54 = OpCompositeExtract %14 %52 1\n%55 = OpCompositeExtract %14 %52 2\n%56 = OpCompositeExtract %14 %52 3\n%57 = OpAccessChain %26 %8 %28\n%58 = OpLoad %5 %57\n%59 = OpIAdd %5 %58 %31\n%60 = OpGroupNonUniformBroadcastFirst %5 %33 %59\n%61 = OpIMul %5 %35 %60\n%62 = OpIAdd %5 %61 %33\n%63 = OpAccessChain %37 %13 %28 %62\n%64 = OpLoad %9 %63\n%65 = OpConvertUToAccelerationStructureKHR %40 %64\n%67 = OpCompositeConstruct %47 %42 %44 %45\n%68 = OpCompositeConstruct %47 %43 %43 %42\nOpTraceRayKHR %65 %28 %66 %28 %28 %28 %67 %42 %68 %46 %21\n%70 = OpInBoundsAccessChain %69 %21 %28\n%71 = OpLoad %14 %70\n%72 = OpFAdd %14 %71 %53\n%73 = OpFAdd %14 %71 %54\n%74 = OpFAdd %14 %71 %55\n%75 = OpFAdd %14 %71 %56\n%78 = OpAccessChain %26 %8 %33\n%79 = OpLoad %5 %78\n%80 = OpIAdd %5 %79 %81\n%77 = OpAccessChain %76 %18 %80\n%82 = OpLoad %15 %77\n%83 = OpCompositeConstruct %9 %28 %28\n%84 = OpCompositeConstruct %22 %72 %73 %74 %75\nOpImageWrite %82 %83 %84\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/raygen.ssbo-rtas.bindless.sm66.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nstruct _19\n{\n    float _m0;\n};\n\nstruct _23\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer RTASHeap\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 3, binding = 0) uniform writeonly image2D _18[];\nlayout(location = 0) rayPayloadEXT _19 _21;\nlayout(location = 1) rayPayloadEXT _23 _25;\n\nvoid main()\n{\n    traceRayEXT(accelerationStructureEXT(_13._m0[subgroupBroadcastFirst(registers._m0 + 30u)]), 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(accelerationStructureEXT(_13._m0[subgroupBroadcastFirst(registers._m0 + 30u)]), 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(_18[registers._m3 + 10u], ivec2(uvec2(0u)), vec4(_21._m0 + _25._m0.x, _21._m0 + _25._m0.y, _21._m0 + _25._m0.z, _21._m0 + _25._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 82\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformBallot\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %13 %18 %21 %25\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"RTASHeap\"\nOpName %19 \"\"\nOpName %23 \"\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %18 DescriptorSet 3\nOpDecorate %18 Binding 0\nOpDecorate %18 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFloat 32\n%15 = OpTypeImage %14 2D 0 0 0 2 Unknown\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypeStruct %14\n%20 = OpTypePointer RayPayloadKHR %19\n%21 = OpVariable %20 RayPayloadKHR\n%22 = OpTypeVector %14 4\n%23 = OpTypeStruct %22\n%24 = OpTypePointer RayPayloadKHR %23\n%25 = OpVariable %24 RayPayloadKHR\n%26 = OpTypePointer PushConstant %5\n%28 = OpConstant %5 0\n%31 = OpConstant %5 30\n%33 = OpConstant %5 3\n%34 = OpTypePointer StorageBuffer %9\n%37 = OpTypeAccelerationStructureKHR\n%39 = OpConstant %14 1\n%40 = OpConstant %14 0\n%41 = OpConstant %14 2\n%42 = OpConstant %14 3\n%43 = OpConstant %14 4\n%44 = OpTypeVector %14 3\n%47 = OpTypePointer RayPayloadKHR %22\n%61 = OpConstant %5 1\n%64 = OpTypePointer RayPayloadKHR %14\n%71 = OpTypePointer UniformConstant %15\n%76 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %80\n%80 = OpLabel\n%27 = OpAccessChain %26 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpIAdd %5 %29 %31\n%32 = OpGroupNonUniformBroadcastFirst %5 %33 %30\n%35 = OpAccessChain %34 %13 %28 %32\n%36 = OpLoad %9 %35\n%38 = OpConvertUToAccelerationStructureKHR %37 %36\n%45 = OpCompositeConstruct %44 %39 %41 %42\n%46 = OpCompositeConstruct %44 %40 %40 %39\nOpTraceRayKHR %38 %28 %28 %28 %28 %28 %45 %39 %46 %43 %25\n%48 = OpInBoundsAccessChain %47 %25 %28\n%49 = OpLoad %22 %48\n%50 = OpCompositeExtract %14 %49 0\n%51 = OpCompositeExtract %14 %49 1\n%52 = OpCompositeExtract %14 %49 2\n%53 = OpCompositeExtract %14 %49 3\n%54 = OpAccessChain %26 %8 %28\n%55 = OpLoad %5 %54\n%56 = OpIAdd %5 %55 %31\n%57 = OpGroupNonUniformBroadcastFirst %5 %33 %56\n%58 = OpAccessChain %34 %13 %28 %57\n%59 = OpLoad %9 %58\n%60 = OpConvertUToAccelerationStructureKHR %37 %59\n%62 = OpCompositeConstruct %44 %39 %41 %42\n%63 = OpCompositeConstruct %44 %40 %40 %39\nOpTraceRayKHR %60 %28 %61 %28 %28 %28 %62 %39 %63 %43 %21\n%65 = OpInBoundsAccessChain %64 %21 %28\n%66 = OpLoad %14 %65\n%67 = OpFAdd %14 %66 %50\n%68 = OpFAdd %14 %66 %51\n%69 = OpFAdd %14 %66 %52\n%70 = OpFAdd %14 %66 %53\n%73 = OpAccessChain %26 %8 %33\n%74 = OpLoad %5 %73\n%75 = OpIAdd %5 %74 %76\n%72 = OpAccessChain %71 %18 %75\n%77 = OpLoad %15 %72\n%78 = OpCompositeConstruct %9 %28 %28\n%79 = OpCompositeConstruct %22 %67 %68 %69 %70\nOpImageWrite %77 %78 %79\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/rw-typed-binding.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _9[];\nlayout(set = 1, binding = 0) uniform writeonly uimageBuffer _14[];\nlayout(set = 2, binding = 0, r32i) uniform coherent iimage2D _19[];\nlayout(set = 3, binding = 0, r32ui) uniform coherent uimage1D _23[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in ivec3 UV;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _36 = uint(UV.x);\n    uint _40 = uint(UV.y);\n    uint _44 = uint(UV.z);\n    vec4 _51 = imageLoad(_9[INDEX + 0u], ivec2(uvec2(_36, _40)));\n    imageStore(_14[INDEX + 0u], int(_36), uvec4(_40));\n    uint _61 = INDEX + 0u;\n    ivec4 _66 = imageLoad(_19[_61], ivec2(uvec2(_40, _44)));\n    imageStore(_19[_61], ivec2(uvec2(_40, _44)), ivec4(uvec4(_36)));\n    uint _80 = imageAtomicAdd(_23[INDEX + 0u], int(_36), _40);\n    SV_Target.x = _51.x;\n    SV_Target.y = float(int(uvec4(_66).x));\n    SV_Target.z = float(_80);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 88\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability Image1D\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %25 %28 %31\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %25 \"INDEX\"\nOpName %28 \"UV\"\nOpName %31 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\nOpDecorate %14 NonReadable\nOpDecorate %19 DescriptorSet 2\nOpDecorate %19 Binding 0\nOpDecorate %19 Coherent\nOpDecorate %23 DescriptorSet 3\nOpDecorate %23 Binding 0\nOpDecorate %23 Coherent\nOpDecorate %25 Flat\nOpDecorate %25 Location 0\nOpDecorate %28 Flat\nOpDecorate %28 Location 0\nOpDecorate %28 Component 1\nOpDecorate %31 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpTypeImage %10 Buffer 0 0 0 2 Unknown\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeInt 32 1\n%16 = OpTypeImage %15 2D 0 0 0 2 R32i\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeImage %10 1D 0 0 0 2 R32ui\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypePointer Input %10\n%25 = OpVariable %24 Input\n%26 = OpTypeVector %15 3\n%27 = OpTypePointer Input %26\n%28 = OpVariable %27 Input\n%29 = OpTypeVector %5 3\n%30 = OpTypePointer Output %29\n%31 = OpVariable %30 Output\n%32 = OpTypePointer Input %15\n%34 = OpConstant %10 0\n%38 = OpConstant %10 1\n%42 = OpConstant %10 2\n%47 = OpTypePointer UniformConstant %6\n%50 = OpTypeVector %5 4\n%52 = OpTypeVector %10 2\n%56 = OpTypePointer UniformConstant %11\n%59 = OpTypeVector %10 4\n%62 = OpTypePointer UniformConstant %16\n%65 = OpTypeVector %15 4\n%75 = OpTypePointer UniformConstant %20\n%78 = OpTypePointer Image %10\n%82 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %86\n%86 = OpLabel\n%33 = OpAccessChain %32 %28 %34\n%35 = OpLoad %15 %33\n%36 = OpBitcast %10 %35\n%37 = OpAccessChain %32 %28 %38\n%39 = OpLoad %15 %37\n%40 = OpBitcast %10 %39\n%41 = OpAccessChain %32 %28 %42\n%43 = OpLoad %15 %41\n%44 = OpBitcast %10 %43\n%45 = OpLoad %10 %25\n%46 = OpIAdd %10 %45 %34\n%48 = OpAccessChain %47 %9 %46\n%49 = OpLoad %6 %48\n%53 = OpCompositeConstruct %52 %36 %40\n%51 = OpImageRead %50 %49 %53 None\n%54 = OpCompositeExtract %5 %51 0\n%55 = OpIAdd %10 %45 %34\n%57 = OpAccessChain %56 %14 %55\n%58 = OpLoad %11 %57\n%60 = OpCompositeConstruct %59 %40 %40 %40 %40\nOpImageWrite %58 %36 %60\n%61 = OpIAdd %10 %45 %34\n%63 = OpAccessChain %62 %19 %61\n%64 = OpLoad %16 %63\n%67 = OpCompositeConstruct %52 %40 %44\n%66 = OpImageRead %65 %64 %67 None\n%68 = OpBitcast %59 %66\n%69 = OpCompositeExtract %10 %68 0\n%70 = OpConvertSToF %5 %69\n%71 = OpCompositeConstruct %52 %40 %44\n%72 = OpCompositeConstruct %59 %36 %36 %36 %36\n%73 = OpBitcast %65 %72\nOpImageWrite %64 %71 %73\n%74 = OpIAdd %10 %45 %34\n%76 = OpAccessChain %75 %23 %74\n%77 = OpLoad %20 %76\n%79 = OpImageTexelPointer %78 %76 %36 %34\n%80 = OpAtomicIAdd %10 %79 %38 %34 %40\n%81 = OpConvertUToF %5 %80\n%83 = OpAccessChain %82 %31 %34\nOpStore %83 %54\n%84 = OpAccessChain %82 %31 %38\nOpStore %84 %70\n%85 = OpAccessChain %82 %31 %42\nOpStore %85 %81\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/rw-typed-heap.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _9[];\nlayout(set = 0, binding = 0) uniform writeonly uimageBuffer _14[];\nlayout(set = 0, binding = 0, r32i) uniform coherent iimage2D _19[];\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimage1D _23[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0, component = 1) flat in ivec3 UV;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _36 = uint(UV.x);\n    uint _40 = uint(UV.y);\n    uint _44 = uint(UV.z);\n    uint _53 = INDEX + 2u;\n    vec4 _63 = imageLoad(_9[INDEX], ivec2(uvec2(_36, _40)));\n    imageStore(_14[INDEX + 1u], int(_36), uvec4(_40));\n    ivec4 _70 = imageLoad(_19[_53], ivec2(uvec2(_40, _44)));\n    imageStore(_19[_53], ivec2(uvec2(_40, _44)), ivec4(uvec4(_36)));\n    uint _80 = imageAtomicAdd(_23[INDEX + 3u], int(_36), _40);\n    SV_Target.x = _63.x;\n    SV_Target.y = float(int(uvec4(_70).x));\n    SV_Target.z = float(_80);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 88\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %25 %28 %31\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %25 \"INDEX\"\nOpName %28 \"UV\"\nOpName %31 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonReadable\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %19 Coherent\nOpDecorate %23 DescriptorSet 0\nOpDecorate %23 Binding 0\nOpDecorate %23 Coherent\nOpDecorate %25 Flat\nOpDecorate %25 Location 0\nOpDecorate %28 Flat\nOpDecorate %28 Location 0\nOpDecorate %28 Component 1\nOpDecorate %31 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpTypeImage %10 Buffer 0 0 0 2 Unknown\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeInt 32 1\n%16 = OpTypeImage %15 2D 0 0 0 2 R32i\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeImage %10 1D 0 0 0 2 R32ui\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer UniformConstant %21\n%23 = OpVariable %22 UniformConstant\n%24 = OpTypePointer Input %10\n%25 = OpVariable %24 Input\n%26 = OpTypeVector %15 3\n%27 = OpTypePointer Input %26\n%28 = OpVariable %27 Input\n%29 = OpTypeVector %5 3\n%30 = OpTypePointer Output %29\n%31 = OpVariable %30 Output\n%32 = OpTypePointer Input %15\n%34 = OpConstant %10 0\n%38 = OpConstant %10 1\n%42 = OpConstant %10 2\n%46 = OpTypePointer UniformConstant %6\n%50 = OpTypePointer UniformConstant %11\n%54 = OpTypePointer UniformConstant %16\n%58 = OpConstant %10 3\n%59 = OpTypePointer UniformConstant %20\n%62 = OpTypeVector %5 4\n%64 = OpTypeVector %10 2\n%67 = OpTypeVector %10 4\n%69 = OpTypeVector %15 4\n%78 = OpTypePointer Image %10\n%82 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %86\n%86 = OpLabel\n%33 = OpAccessChain %32 %28 %34\n%35 = OpLoad %15 %33\n%36 = OpBitcast %10 %35\n%37 = OpAccessChain %32 %28 %38\n%39 = OpLoad %15 %37\n%40 = OpBitcast %10 %39\n%41 = OpAccessChain %32 %28 %42\n%43 = OpLoad %15 %41\n%44 = OpBitcast %10 %43\n%45 = OpLoad %10 %25\n%47 = OpAccessChain %46 %9 %45\n%48 = OpLoad %6 %47\n%49 = OpIAdd %10 %45 %38\n%51 = OpAccessChain %50 %14 %49\n%52 = OpLoad %11 %51\n%53 = OpIAdd %10 %45 %42\n%55 = OpAccessChain %54 %19 %53\n%56 = OpLoad %16 %55\n%57 = OpIAdd %10 %45 %58\n%60 = OpAccessChain %59 %23 %57\n%61 = OpLoad %20 %60\n%65 = OpCompositeConstruct %64 %36 %40\n%63 = OpImageRead %62 %48 %65 None\n%66 = OpCompositeExtract %5 %63 0\n%68 = OpCompositeConstruct %67 %40 %40 %40 %40\nOpImageWrite %52 %36 %68\n%71 = OpCompositeConstruct %64 %40 %44\n%70 = OpImageRead %69 %56 %71 None\n%72 = OpBitcast %67 %70\n%73 = OpCompositeExtract %10 %72 0\n%74 = OpConvertSToF %5 %73\n%75 = OpCompositeConstruct %64 %40 %44\n%76 = OpCompositeConstruct %67 %36 %36 %36 %36\n%77 = OpBitcast %69 %76\nOpImageWrite %56 %75 %77\n%79 = OpImageTexelPointer %78 %60 %36 %34\n%80 = OpAtomicIAdd %10 %79 %38 %34 %40\n%81 = OpConvertUToF %5 %80\n%83 = OpAccessChain %82 %31 %34\nOpStore %83 %66\n%84 = OpAccessChain %82 %31 %38\nOpStore %84 %74\n%85 = OpAccessChain %82 %31 %42\nOpStore %85 %81\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/sampled-types-binding.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 4) uniform texture2D _9[];\nlayout(set = 1, binding = 5) uniform samplerBuffer _15[1000];\nlayout(set = 2, binding = 6) uniform texture1D _18;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _35 = uint(int(UV.x));\n    uint _36 = uint(int(UV.y));\n    vec4 _42 = texelFetch(_9[nonuniformEXT(INDEX)], ivec2(uvec2(_35, _36)), int(0u));\n    uint _49 = INDEX + 1u;\n    vec4 _55 = texelFetch(_15[nonuniformEXT(_49)], int(_35));\n    vec4 _65 = texelFetch(_18, int(_35), int(_36));\n    SV_Target.x = (_55.x + _42.x) + _65.x;\n    SV_Target.y = (_55.y + _42.y) + _65.y;\n    SV_Target.z = (_55.z + _42.z) + _65.z;\n    SV_Target.w = (_55.w + _42.w) + _65.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 83\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability Sampled1D\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %23 %26\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %20 \"INDEX\"\nOpName %23 \"UV\"\nOpName %26 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 4\nOpDecorate %15 DescriptorSet 1\nOpDecorate %15 Binding 5\nOpDecorate %18 DescriptorSet 2\nOpDecorate %18 Binding 6\nOpDecorate %20 Flat\nOpDecorate %20 Location 0\nOpDecorate %23 Location 1\nOpDecorate %26 Location 0\nOpDecorate %34 NonUniform\nOpDecorate %41 NonUniform\nOpDecorate %49 NonUniform\nOpDecorate %54 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 1000\n%13 = OpTypeArray %10 %12\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypePointer Input %11\n%20 = OpVariable %19 Input\n%21 = OpTypeVector %5 2\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Output %24\n%26 = OpVariable %25 Output\n%27 = OpTypePointer Input %5\n%29 = OpConstant %11 0\n%32 = OpConstant %11 1\n%38 = OpConstant %11 4\n%39 = OpTypePointer UniformConstant %6\n%43 = OpTypeVector %11 2\n%51 = OpConstant %11 5\n%52 = OpTypePointer UniformConstant %10\n%74 = OpTypePointer Output %5\n%78 = OpConstant %11 2\n%80 = OpConstant %11 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %81\n%81 = OpLabel\n%28 = OpAccessChain %27 %23 %29\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %27 %23 %32\n%33 = OpLoad %5 %31\n%34 = OpLoad %11 %20\n%35 = OpConvertFToS %11 %30\n%36 = OpConvertFToS %11 %33\n%37 = OpIAdd %11 %34 %38\n%40 = OpAccessChain %39 %9 %34\n%41 = OpLoad %6 %40\n%44 = OpCompositeConstruct %43 %35 %36\n%42 = OpImageFetch %24 %41 %44 Lod %29\n%45 = OpCompositeExtract %5 %42 0\n%46 = OpCompositeExtract %5 %42 1\n%47 = OpCompositeExtract %5 %42 2\n%48 = OpCompositeExtract %5 %42 3\n%49 = OpIAdd %11 %34 %32\n%50 = OpIAdd %11 %49 %51\n%53 = OpAccessChain %52 %15 %49\n%54 = OpLoad %10 %53\n%55 = OpImageFetch %24 %54 %35\n%56 = OpCompositeExtract %5 %55 0\n%57 = OpCompositeExtract %5 %55 1\n%58 = OpCompositeExtract %5 %55 2\n%59 = OpCompositeExtract %5 %55 3\n%60 = OpFAdd %5 %56 %45\n%61 = OpFAdd %5 %57 %46\n%62 = OpFAdd %5 %58 %47\n%63 = OpFAdd %5 %59 %48\n%64 = OpLoad %16 %18\n%65 = OpImageFetch %24 %64 %35 Lod %36\n%66 = OpCompositeExtract %5 %65 0\n%67 = OpCompositeExtract %5 %65 1\n%68 = OpCompositeExtract %5 %65 2\n%69 = OpCompositeExtract %5 %65 3\n%70 = OpFAdd %5 %60 %66\n%71 = OpFAdd %5 %61 %67\n%72 = OpFAdd %5 %62 %68\n%73 = OpFAdd %5 %63 %69\n%75 = OpAccessChain %74 %26 %29\nOpStore %75 %70\n%76 = OpAccessChain %74 %26 %32\nOpStore %76 %71\n%77 = OpAccessChain %74 %26 %78\nOpStore %77 %72\n%79 = OpAccessChain %74 %26 %80\nOpStore %79 %73\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/sampled-types.sm66.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _9[];\nlayout(set = 0, binding = 0) uniform samplerBuffer _13[];\nlayout(set = 0, binding = 0) uniform texture1D _17[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) in vec2 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _47 = uint(int(UV.x));\n    uint _48 = uint(int(UV.y));\n    f16vec4 _54 = f16vec4(texelFetch(_9[nonuniformEXT(INDEX)], ivec2(uvec2(_47, _48)), int(0u)));\n    vec4 _63 = texelFetch(_13[nonuniformEXT(INDEX + 1u)], int(_47));\n    vec4 _72 = texelFetch(_17[nonuniformEXT(INDEX + 2u)], int(_48), int(_48));\n    SV_Target.x = (float(_54.x) + _63.x) + _72.x;\n    SV_Target.y = (float(_54.y) + _63.y) + _72.y;\n    SV_Target.z = (float(_54.z) + _63.z) + _72.z;\n    SV_Target.w = (float(_54.w) + _63.w) + _72.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 89\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Sampled1D\nOpCapability SampledBuffer\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %23 %26\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %20 \"INDEX\"\nOpName %23 \"UV\"\nOpName %26 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 RelaxedPrecision\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %20 Flat\nOpDecorate %20 Location 0\nOpDecorate %23 Location 1\nOpDecorate %26 Location 0\nOpDecorate %34 NonUniform\nOpDecorate %37 NonUniform\nOpDecorate %38 NonUniform\nOpDecorate %41 NonUniform\nOpDecorate %42 NonUniform\nOpDecorate %46 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %5 1D 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeInt 32 0\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypeVector %5 2\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%24 = OpTypeVector %5 4\n%25 = OpTypePointer Output %24\n%26 = OpVariable %25 Output\n%27 = OpTypePointer Input %5\n%29 = OpConstant %18 0\n%32 = OpConstant %18 1\n%35 = OpTypePointer UniformConstant %6\n%39 = OpTypePointer UniformConstant %10\n%43 = OpConstant %18 2\n%44 = OpTypePointer UniformConstant %14\n%50 = OpTypeVector %18 2\n%52 = OpTypeFloat 16\n%53 = OpTypeVector %52 4\n%81 = OpTypePointer Output %5\n%86 = OpConstant %18 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %87\n%87 = OpLabel\n%28 = OpAccessChain %27 %23 %29\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %27 %23 %32\n%33 = OpLoad %5 %31\n%34 = OpLoad %18 %20\n%36 = OpAccessChain %35 %9 %34\n%37 = OpLoad %6 %36\n%38 = OpIAdd %18 %34 %32\n%40 = OpAccessChain %39 %13 %38\n%41 = OpLoad %10 %40\n%42 = OpIAdd %18 %34 %43\n%45 = OpAccessChain %44 %17 %42\n%46 = OpLoad %14 %45\n%47 = OpConvertFToS %18 %30\n%48 = OpConvertFToS %18 %33\n%51 = OpCompositeConstruct %50 %47 %48\n%49 = OpImageFetch %24 %37 %51 Lod %29\n%54 = OpFConvert %53 %49\n%55 = OpCompositeExtract %52 %54 0\n%56 = OpCompositeExtract %52 %54 1\n%57 = OpCompositeExtract %52 %54 2\n%58 = OpCompositeExtract %52 %54 3\n%59 = OpFConvert %5 %55\n%60 = OpFConvert %5 %56\n%61 = OpFConvert %5 %57\n%62 = OpFConvert %5 %58\n%63 = OpImageFetch %24 %41 %47\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpCompositeExtract %5 %63 1\n%66 = OpCompositeExtract %5 %63 2\n%67 = OpCompositeExtract %5 %63 3\n%68 = OpFAdd %5 %59 %64\n%69 = OpFAdd %5 %60 %65\n%70 = OpFAdd %5 %61 %66\n%71 = OpFAdd %5 %62 %67\n%72 = OpImageFetch %24 %46 %48 Lod %48\n%73 = OpCompositeExtract %5 %72 0\n%74 = OpCompositeExtract %5 %72 1\n%75 = OpCompositeExtract %5 %72 2\n%76 = OpCompositeExtract %5 %72 3\n%77 = OpFAdd %5 %68 %73\n%78 = OpFAdd %5 %69 %74\n%79 = OpFAdd %5 %70 %75\n%80 = OpFAdd %5 %71 %76\n%82 = OpAccessChain %81 %26 %29\nOpStore %82 %77\n%83 = OpAccessChain %81 %26 %32\nOpStore %83 %78\n%84 = OpAccessChain %81 %26 %43\nOpStore %84 %79\n%85 = OpAccessChain %81 %26 %86\nOpStore %85 %80\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/sampler-binding.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 1) uniform texture3D _9[];\nlayout(set = 0, binding = 4) uniform sampler _13[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) in vec3 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _46 = texture(sampler3D(_9[INDEX], _13[INDEX]), vec3(UV.x, UV.y, UV.z));\n    SV_Target.x = _46.x;\n    SV_Target.y = _46.y;\n    SV_Target.z = _46.z;\n    SV_Target.w = _46.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %19 %22\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"INDEX\"\nOpName %19 \"UV\"\nOpName %22 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 4\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %19 Location 1\nOpDecorate %22 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeSampler\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeInt 32 0\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypeVector %5 4\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%23 = OpTypePointer Input %5\n%25 = OpConstant %14 0\n%28 = OpConstant %14 1\n%31 = OpConstant %14 2\n%35 = OpTypePointer UniformConstant %6\n%39 = OpConstant %14 4\n%40 = OpTypePointer UniformConstant %10\n%43 = OpTypeSampledImage %6\n%45 = OpConstant %5 0\n%52 = OpTypePointer Output %5\n%57 = OpConstant %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %58\n%58 = OpLabel\n%24 = OpAccessChain %23 %19 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %23 %19 %28\n%29 = OpLoad %5 %27\n%30 = OpAccessChain %23 %19 %31\n%32 = OpLoad %5 %30\n%33 = OpLoad %14 %16\n%34 = OpIAdd %14 %33 %28\n%36 = OpAccessChain %35 %9 %33\n%37 = OpLoad %6 %36\n%38 = OpIAdd %14 %33 %39\n%41 = OpAccessChain %40 %13 %33\n%42 = OpLoad %10 %41\n%44 = OpSampledImage %43 %37 %42\n%47 = OpCompositeConstruct %17 %26 %29 %32\n%46 = OpImageSampleImplicitLod %20 %44 %47 None\n%48 = OpCompositeExtract %5 %46 0\n%49 = OpCompositeExtract %5 %46 1\n%50 = OpCompositeExtract %5 %46 2\n%51 = OpCompositeExtract %5 %46 3\n%53 = OpAccessChain %52 %22 %25\nOpStore %53 %48\n%54 = OpAccessChain %52 %22 %28\nOpStore %54 %49\n%55 = OpAccessChain %52 %22 %31\nOpStore %55 %50\n%56 = OpAccessChain %52 %22 %57\nOpStore %56 %51\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/sampler-heap.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform texture3D _9[];\nlayout(set = 0, binding = 0) uniform sampler _13[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) in vec3 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _45 = texture(sampler3D(_9[INDEX + 1u], _13[INDEX + 2u]), vec3(UV.x, UV.y, UV.z));\n    SV_Target.x = _45.x;\n    SV_Target.y = _45.y;\n    SV_Target.z = _45.z;\n    SV_Target.w = _45.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %19 %22\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"INDEX\"\nOpName %19 \"UV\"\nOpName %22 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %19 Location 1\nOpDecorate %22 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 3D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeSampler\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeInt 32 0\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypeVector %5 4\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%23 = OpTypePointer Input %5\n%25 = OpConstant %14 0\n%28 = OpConstant %14 1\n%31 = OpConstant %14 2\n%35 = OpTypePointer UniformConstant %6\n%39 = OpTypePointer UniformConstant %10\n%42 = OpTypeSampledImage %6\n%44 = OpConstant %5 0\n%51 = OpTypePointer Output %5\n%56 = OpConstant %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %57\n%57 = OpLabel\n%24 = OpAccessChain %23 %19 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %23 %19 %28\n%29 = OpLoad %5 %27\n%30 = OpAccessChain %23 %19 %31\n%32 = OpLoad %5 %30\n%33 = OpLoad %14 %16\n%34 = OpIAdd %14 %33 %28\n%36 = OpAccessChain %35 %9 %34\n%37 = OpLoad %6 %36\n%38 = OpIAdd %14 %33 %31\n%40 = OpAccessChain %39 %13 %38\n%41 = OpLoad %10 %40\n%43 = OpSampledImage %42 %37 %41\n%46 = OpCompositeConstruct %17 %26 %29 %32\n%45 = OpImageSampleImplicitLod %20 %43 %46 None\n%47 = OpCompositeExtract %5 %45 0\n%48 = OpCompositeExtract %5 %45 1\n%49 = OpCompositeExtract %5 %45 2\n%50 = OpCompositeExtract %5 %45 3\n%52 = OpAccessChain %51 %22 %25\nOpStore %52 %47\n%53 = OpAccessChain %51 %22 %28\nOpStore %53 %48\n%54 = OpAccessChain %51 %22 %31\nOpStore %54 %49\n%55 = OpAccessChain %51 %22 %56\nOpStore %55 %50\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/structured-16bit-heap.ssbo.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _14_17\n{\n    u16vec2 _m0[];\n} _17[];\n\nlayout(set = 0, binding = 0, std430) buffer _19_22\n{\n    uint _m0[];\n} _22[];\n\nlayout(set = 0, binding = 0, std430) buffer _24_27\n{\n    u16vec2 _m0[];\n} _27[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _30_33\n{\n    u16vec4 _m0[];\n} _33[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _36_39\n{\n    uvec4 _m0[];\n} _39[];\n\nlayout(set = 0, binding = 0, std430) buffer _41_44\n{\n    u16vec4 _m0[];\n} _44[];\n\nlayout(set = 0, binding = 0, std430) buffer _46_49\n{\n    uvec4 _m0[];\n} _49[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _91 = INDEX + 8u;\n    uint _97 = INDEX + 9u;\n    f16vec2 _112 = uint16BitsToFloat16(_17[INDEX + 1u]._m0[uint(UV.y)]);\n    uint _118 = _22[INDEX + 4u]._m0[uint(UV.z)];\n    u16vec2 _122 = _27[INDEX + 5u]._m0[uint(UV.w)];\n    f16vec2 _123 = uint16BitsToFloat16(_122);\n    f16vec4 _133 = uint16BitsToFloat16(_33[_91]._m0[1u]);\n    vec4 _149 = uintBitsToFloat(_39[_91]._m0[1u]);\n    u16vec4 _159 = _44[_97]._m0[1u];\n    f16vec4 _160 = uint16BitsToFloat16(_159);\n    float _169 = (((float(_123.y) + uintBitsToFloat(_10[INDEX]._m0[uint(UV.x)])) + float(_133.x)) + _149.x) + float(_160.x);\n    float _170 = ((float(_133.y) + float(_112.x)) + _149.y) + float(_160.y);\n    float _171 = (((float(_112.y) + uintBitsToFloat(_118)) + float(_133.z)) + _149.z) + float(_160.z);\n    float _172 = ((float(_133.w) + float(_123.x)) + _149.w) + float(_160.w);\n    _49[_97]._m0[1u] = uvec4(floatBitsToUint(_169), floatBitsToUint(_170), floatBitsToUint(_171), floatBitsToUint(_172));\n    SV_Target.x = _169;\n    SV_Target.y = _170;\n    SV_Target.z = _171;\n    SV_Target.w = _172;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 186\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %51 %55 %59\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %14 \"SSBO\"\nOpName %19 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %30 \"SSBO\"\nOpName %36 \"SSBO\"\nOpName %41 \"SSBO\"\nOpName %46 \"SSBO\"\nOpName %51 \"INDEX\"\nOpName %55 \"UV\"\nOpName %59 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %13 ArrayStride 4\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 NonWritable\nOpDecorate %17 Restrict\nOpDecorate %18 ArrayStride 4\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 0\nOpDecorate %23 ArrayStride 4\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 0\nOpDecorate %29 ArrayStride 8\nOpMemberDecorate %30 0 Offset 0\nOpDecorate %30 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %33 NonWritable\nOpDecorate %33 Restrict\nOpDecorate %35 ArrayStride 16\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %36 Block\nOpDecorate %39 DescriptorSet 0\nOpDecorate %39 Binding 0\nOpDecorate %39 NonWritable\nOpDecorate %39 Restrict\nOpDecorate %40 ArrayStride 8\nOpMemberDecorate %41 0 Offset 0\nOpDecorate %41 Block\nOpDecorate %44 DescriptorSet 0\nOpDecorate %44 Binding 0\nOpDecorate %44 Aliased\nOpDecorate %45 ArrayStride 16\nOpMemberDecorate %46 0 Offset 0\nOpDecorate %46 Block\nOpDecorate %49 DescriptorSet 0\nOpDecorate %49 Binding 0\nOpDecorate %49 Aliased\nOpDecorate %51 Flat\nOpDecorate %51 Location 0\nOpDecorate %55 Flat\nOpDecorate %55 Location 1\nOpDecorate %59 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypeRuntimeArray %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeInt 16 0\n%12 = OpTypeVector %11 2\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypeStruct %13\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer StorageBuffer %15\n%17 = OpVariable %16 StorageBuffer\n%18 = OpTypeRuntimeArray %5\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %12\n%24 = OpTypeStruct %23\n%25 = OpTypeRuntimeArray %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeVector %11 4\n%29 = OpTypeRuntimeArray %28\n%30 = OpTypeStruct %29\n%31 = OpTypeRuntimeArray %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeVector %5 4\n%35 = OpTypeRuntimeArray %34\n%36 = OpTypeStruct %35\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypePointer StorageBuffer %37\n%39 = OpVariable %38 StorageBuffer\n%40 = OpTypeRuntimeArray %28\n%41 = OpTypeStruct %40\n%42 = OpTypeRuntimeArray %41\n%43 = OpTypePointer StorageBuffer %42\n%44 = OpVariable %43 StorageBuffer\n%45 = OpTypeRuntimeArray %34\n%46 = OpTypeStruct %45\n%47 = OpTypeRuntimeArray %46\n%48 = OpTypePointer StorageBuffer %47\n%49 = OpVariable %48 StorageBuffer\n%50 = OpTypePointer Input %5\n%51 = OpVariable %50 Input\n%52 = OpTypeInt 32 1\n%53 = OpTypeVector %52 4\n%54 = OpTypePointer Input %53\n%55 = OpVariable %54 Input\n%56 = OpTypeFloat 32\n%57 = OpTypeVector %56 4\n%58 = OpTypePointer Output %57\n%59 = OpVariable %58 Output\n%60 = OpTypePointer Input %52\n%62 = OpConstant %5 0\n%66 = OpConstant %5 1\n%70 = OpConstant %5 2\n%74 = OpConstant %5 3\n%78 = OpTypePointer StorageBuffer %7\n%81 = OpTypePointer StorageBuffer %14\n%84 = OpConstant %5 4\n%85 = OpTypePointer StorageBuffer %19\n%88 = OpConstant %5 5\n%89 = OpTypePointer StorageBuffer %24\n%92 = OpConstant %5 8\n%93 = OpTypePointer StorageBuffer %30\n%95 = OpTypePointer StorageBuffer %36\n%98 = OpConstant %5 9\n%99 = OpTypePointer StorageBuffer %41\n%101 = OpTypePointer StorageBuffer %46\n%103 = OpTypePointer StorageBuffer %5\n%107 = OpTypePointer StorageBuffer %12\n%110 = OpTypeFloat 16\n%111 = OpTypeVector %110 2\n%129 = OpTypePointer StorageBuffer %28\n%132 = OpTypeVector %110 4\n%146 = OpTypePointer StorageBuffer %34\n%179 = OpTypePointer Output %56\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %184\n%184 = OpLabel\n%61 = OpAccessChain %60 %55 %62\n%63 = OpLoad %52 %61\n%64 = OpBitcast %5 %63\n%65 = OpAccessChain %60 %55 %66\n%67 = OpLoad %52 %65\n%68 = OpBitcast %5 %67\n%69 = OpAccessChain %60 %55 %70\n%71 = OpLoad %52 %69\n%72 = OpBitcast %5 %71\n%73 = OpAccessChain %60 %55 %74\n%75 = OpLoad %52 %73\n%76 = OpBitcast %5 %75\n%77 = OpLoad %5 %51\n%79 = OpAccessChain %78 %10 %77\n%80 = OpIAdd %5 %77 %66\n%82 = OpAccessChain %81 %17 %80\n%83 = OpIAdd %5 %77 %84\n%86 = OpAccessChain %85 %22 %83\n%87 = OpIAdd %5 %77 %88\n%90 = OpAccessChain %89 %27 %87\n%91 = OpIAdd %5 %77 %92\n%94 = OpAccessChain %93 %33 %91\n%96 = OpAccessChain %95 %39 %91\n%97 = OpIAdd %5 %77 %98\n%100 = OpAccessChain %99 %44 %97\n%102 = OpAccessChain %101 %49 %97\n%104 = OpAccessChain %103 %79 %62 %64\n%105 = OpLoad %5 %104\n%106 = OpBitcast %56 %105\n%108 = OpAccessChain %107 %82 %62 %68\n%109 = OpLoad %12 %108\n%112 = OpBitcast %111 %109\n%113 = OpCompositeExtract %110 %112 0\n%114 = OpCompositeExtract %110 %112 1\n%115 = OpFConvert %56 %113\n%116 = OpFConvert %56 %114\n%117 = OpAccessChain %103 %86 %62 %72\n%118 = OpLoad %5 %117\n%119 = OpBitcast %56 %118\n%120 = OpFAdd %56 %116 %119\n%121 = OpAccessChain %107 %90 %62 %76\n%122 = OpLoad %12 %121\n%123 = OpBitcast %111 %122\n%124 = OpCompositeExtract %110 %123 0\n%125 = OpCompositeExtract %110 %123 1\n%126 = OpFConvert %56 %124\n%127 = OpFConvert %56 %125\n%128 = OpFAdd %56 %127 %106\n%130 = OpAccessChain %129 %94 %62 %66\n%131 = OpLoad %28 %130\n%133 = OpBitcast %132 %131\n%134 = OpCompositeExtract %110 %133 0\n%135 = OpCompositeExtract %110 %133 1\n%136 = OpCompositeExtract %110 %133 2\n%137 = OpCompositeExtract %110 %133 3\n%138 = OpFConvert %56 %134\n%139 = OpFConvert %56 %135\n%140 = OpFConvert %56 %136\n%141 = OpFConvert %56 %137\n%142 = OpFAdd %56 %128 %138\n%143 = OpFAdd %56 %139 %115\n%144 = OpFAdd %56 %120 %140\n%145 = OpFAdd %56 %141 %126\n%147 = OpAccessChain %146 %96 %62 %66\n%148 = OpLoad %34 %147\n%149 = OpBitcast %57 %148\n%150 = OpCompositeExtract %56 %149 0\n%151 = OpCompositeExtract %56 %149 1\n%152 = OpCompositeExtract %56 %149 2\n%153 = OpCompositeExtract %56 %149 3\n%154 = OpFAdd %56 %142 %150\n%155 = OpFAdd %56 %143 %151\n%156 = OpFAdd %56 %144 %152\n%157 = OpFAdd %56 %145 %153\n%158 = OpAccessChain %129 %100 %62 %66\n%159 = OpLoad %28 %158\n%160 = OpBitcast %132 %159\n%161 = OpCompositeExtract %110 %160 0\n%162 = OpCompositeExtract %110 %160 1\n%163 = OpCompositeExtract %110 %160 2\n%164 = OpCompositeExtract %110 %160 3\n%165 = OpFConvert %56 %161\n%166 = OpFConvert %56 %162\n%167 = OpFConvert %56 %163\n%168 = OpFConvert %56 %164\n%169 = OpFAdd %56 %154 %165\n%170 = OpFAdd %56 %155 %166\n%171 = OpFAdd %56 %156 %167\n%172 = OpFAdd %56 %157 %168\n%173 = OpBitcast %5 %169\n%174 = OpBitcast %5 %170\n%175 = OpBitcast %5 %171\n%176 = OpBitcast %5 %172\n%177 = OpCompositeConstruct %34 %173 %174 %175 %176\n%178 = OpAccessChain %146 %102 %62 %66\nOpStore %178 %177\n%180 = OpAccessChain %179 %59 %62\nOpStore %180 %169\n%181 = OpAccessChain %179 %59 %66\nOpStore %181 %170\n%182 = OpAccessChain %179 %59 %70\nOpStore %182 %171\n%183 = OpAccessChain %179 %59 %74\nOpStore %183 %172\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/structured-16bit-heap.ssbo.ssbo-align.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _15[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _19_22\n{\n    u16vec2 _m0[];\n} _22[];\n\nlayout(set = 0, binding = 0, std430) buffer _24_27\n{\n    uint _m0[];\n} _27[];\n\nlayout(set = 0, binding = 0, std430) buffer _29_32\n{\n    u16vec2 _m0[];\n} _32[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _35_38\n{\n    u16vec4 _m0[];\n} _38[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _41_44\n{\n    uvec4 _m0[];\n} _44[];\n\nlayout(set = 0, binding = 0, std430) buffer _46_49\n{\n    u16vec4 _m0[];\n} _49[];\n\nlayout(set = 0, binding = 0, std430) buffer _51_54\n{\n    uvec4 _m0[];\n} _54[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _69 = uint(UV.x);\n    uint _73 = uint(UV.y);\n    uint _77 = uint(UV.z);\n    uint _81 = uint(UV.w);\n    uvec2 _89 = _10._m0[subgroupBroadcastFirst(INDEX)] >> uvec2(2u);\n    uint _91 = INDEX + 1u;\n    uvec2 _97 = _10._m0[subgroupBroadcastFirst(_91)] >> uvec2(2u);\n    uint _98 = INDEX + 4u;\n    uvec2 _105 = _10._m0[subgroupBroadcastFirst(_98)] >> uvec2(2u);\n    uint _106 = INDEX + 5u;\n    uvec2 _113 = _10._m0[subgroupBroadcastFirst(_106)] >> uvec2(2u);\n    uint _114 = INDEX + 8u;\n    uint _120 = subgroupBroadcastFirst(_114);\n    uint _123 = INDEX + 9u;\n    uint _129 = subgroupBroadcastFirst(_123);\n    f16vec2 _154 = uint16BitsToFloat16(_22[_91]._m0[(_73 < _97.y) ? (_73 + _97.x) : 1073741823u]);\n    uint _165 = _27[_98]._m0[(_77 < _105.y) ? (_77 + _105.x) : 1073741820u];\n    u16vec2 _174 = _32[_106]._m0[(_81 < _113.y) ? (_81 + _113.x) : 1073741823u];\n    f16vec2 _175 = uint16BitsToFloat16(_174);\n    uvec2 _181 = _10._m0[_120] >> uvec2(3u);\n    f16vec4 _193 = uint16BitsToFloat16(_38[_114]._m0[(1u < _181.y) ? (1u + _181.x) : 536870911u]);\n    uvec2 _206 = _10._m0[_120] >> uvec2(4u);\n    vec4 _217 = uintBitsToFloat(_44[_114]._m0[(1u < _206.y) ? (1u + _206.x) : 268435455u]);\n    uvec2 _226 = _10._m0[_129] >> uvec2(3u);\n    u16vec4 _233 = _49[_123]._m0[(1u < _226.y) ? (1u + _226.x) : 536870911u];\n    f16vec4 _234 = uint16BitsToFloat16(_233);\n    float _243 = (((float(_175.y) + uintBitsToFloat(_15[INDEX]._m0[(_69 < _89.y) ? (_69 + _89.x) : 1073741820u])) + float(_193.x)) + _217.x) + float(_234.x);\n    float _244 = ((float(_193.y) + float(_154.x)) + _217.y) + float(_234.y);\n    float _245 = (((float(_154.y) + uintBitsToFloat(_165)) + float(_193.z)) + _217.z) + float(_234.z);\n    float _246 = ((float(_193.w) + float(_175.x)) + _217.w) + float(_234.w);\n    uvec2 _247 = _10._m0[_129] >> uvec2(4u);\n    _54[_123]._m0[(1u < _247.y) ? (1u + _247.x) : 268435455u] = uvec4(floatBitsToUint(_243), floatBitsToUint(_244), floatBitsToUint(_245), floatBitsToUint(_246));\n    SV_Target.x = _243;\n    SV_Target.y = _244;\n    SV_Target.z = _245;\n    SV_Target.w = _246;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 266\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability GroupNonUniformBallot\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %56 %60 %64\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"SSBO_Offsets\"\nOpName %12 \"SSBO\"\nOpName %19 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %29 \"SSBO\"\nOpName %35 \"SSBO\"\nOpName %41 \"SSBO\"\nOpName %46 \"SSBO\"\nOpName %51 \"SSBO\"\nOpName %56 \"INDEX\"\nOpName %60 \"UV\"\nOpName %64 \"SV_Target\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 15\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %18 ArrayStride 4\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 0\nOpDecorate %22 NonWritable\nOpDecorate %22 Restrict\nOpDecorate %23 ArrayStride 4\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 0\nOpDecorate %28 ArrayStride 4\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %32 DescriptorSet 0\nOpDecorate %32 Binding 0\nOpDecorate %34 ArrayStride 8\nOpMemberDecorate %35 0 Offset 0\nOpDecorate %35 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 0\nOpDecorate %38 NonWritable\nOpDecorate %38 Restrict\nOpDecorate %40 ArrayStride 16\nOpMemberDecorate %41 0 Offset 0\nOpDecorate %41 Block\nOpDecorate %44 DescriptorSet 0\nOpDecorate %44 Binding 0\nOpDecorate %44 NonWritable\nOpDecorate %44 Restrict\nOpDecorate %45 ArrayStride 8\nOpMemberDecorate %46 0 Offset 0\nOpDecorate %46 Block\nOpDecorate %49 DescriptorSet 0\nOpDecorate %49 Binding 0\nOpDecorate %49 Aliased\nOpDecorate %50 ArrayStride 16\nOpMemberDecorate %51 0 Offset 0\nOpDecorate %51 Block\nOpDecorate %54 DescriptorSet 0\nOpDecorate %54 Binding 0\nOpDecorate %54 Aliased\nOpDecorate %56 Flat\nOpDecorate %56 Location 0\nOpDecorate %60 Flat\nOpDecorate %60 Location 1\nOpDecorate %64 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %5\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeInt 16 0\n%17 = OpTypeVector %16 2\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %5\n%24 = OpTypeStruct %23\n%25 = OpTypeRuntimeArray %24\n%26 = OpTypePointer StorageBuffer %25\n%27 = OpVariable %26 StorageBuffer\n%28 = OpTypeRuntimeArray %17\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer StorageBuffer %30\n%32 = OpVariable %31 StorageBuffer\n%33 = OpTypeVector %16 4\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypeStruct %34\n%36 = OpTypeRuntimeArray %35\n%37 = OpTypePointer StorageBuffer %36\n%38 = OpVariable %37 StorageBuffer\n%39 = OpTypeVector %5 4\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypeStruct %40\n%42 = OpTypeRuntimeArray %41\n%43 = OpTypePointer StorageBuffer %42\n%44 = OpVariable %43 StorageBuffer\n%45 = OpTypeRuntimeArray %33\n%46 = OpTypeStruct %45\n%47 = OpTypeRuntimeArray %46\n%48 = OpTypePointer StorageBuffer %47\n%49 = OpVariable %48 StorageBuffer\n%50 = OpTypeRuntimeArray %39\n%51 = OpTypeStruct %50\n%52 = OpTypeRuntimeArray %51\n%53 = OpTypePointer StorageBuffer %52\n%54 = OpVariable %53 StorageBuffer\n%55 = OpTypePointer Input %5\n%56 = OpVariable %55 Input\n%57 = OpTypeInt 32 1\n%58 = OpTypeVector %57 4\n%59 = OpTypePointer Input %58\n%60 = OpVariable %59 Input\n%61 = OpTypeFloat 32\n%62 = OpTypeVector %61 4\n%63 = OpTypePointer Output %62\n%64 = OpVariable %63 Output\n%65 = OpTypePointer Input %57\n%67 = OpConstant %5 0\n%71 = OpConstant %5 1\n%75 = OpConstant %5 2\n%79 = OpConstant %5 3\n%83 = OpTypePointer StorageBuffer %12\n%86 = OpTypePointer StorageBuffer %6\n%90 = OpConstantComposite %6 %75 %75\n%92 = OpTypePointer StorageBuffer %19\n%99 = OpConstant %5 4\n%100 = OpTypePointer StorageBuffer %24\n%107 = OpConstant %5 5\n%108 = OpTypePointer StorageBuffer %29\n%115 = OpConstant %5 8\n%116 = OpTypePointer StorageBuffer %35\n%118 = OpTypePointer StorageBuffer %41\n%124 = OpConstant %5 9\n%125 = OpTypePointer StorageBuffer %46\n%127 = OpTypePointer StorageBuffer %51\n%135 = OpTypeBool\n%138 = OpConstant %5 1073741820\n%139 = OpTypePointer StorageBuffer %5\n%148 = OpConstant %5 1073741823\n%149 = OpTypePointer StorageBuffer %17\n%152 = OpTypeFloat 16\n%153 = OpTypeVector %152 2\n%182 = OpConstantComposite %6 %79 %79\n%188 = OpConstant %5 536870911\n%189 = OpTypePointer StorageBuffer %33\n%192 = OpTypeVector %152 4\n%207 = OpConstantComposite %6 %99 %99\n%213 = OpConstant %5 268435455\n%214 = OpTypePointer StorageBuffer %39\n%259 = OpTypePointer Output %61\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %264\n%264 = OpLabel\n%66 = OpAccessChain %65 %60 %67\n%68 = OpLoad %57 %66\n%69 = OpBitcast %5 %68\n%70 = OpAccessChain %65 %60 %71\n%72 = OpLoad %57 %70\n%73 = OpBitcast %5 %72\n%74 = OpAccessChain %65 %60 %75\n%76 = OpLoad %57 %74\n%77 = OpBitcast %5 %76\n%78 = OpAccessChain %65 %60 %79\n%80 = OpLoad %57 %78\n%81 = OpBitcast %5 %80\n%82 = OpLoad %5 %56\n%84 = OpAccessChain %83 %15 %82\n%85 = OpGroupNonUniformBroadcastFirst %5 %79 %82\n%87 = OpAccessChain %86 %10 %67 %85\n%88 = OpLoad %6 %87\n%89 = OpShiftRightLogical %6 %88 %90\n%91 = OpIAdd %5 %82 %71\n%93 = OpAccessChain %92 %22 %91\n%94 = OpGroupNonUniformBroadcastFirst %5 %79 %91\n%95 = OpAccessChain %86 %10 %67 %94\n%96 = OpLoad %6 %95\n%97 = OpShiftRightLogical %6 %96 %90\n%98 = OpIAdd %5 %82 %99\n%101 = OpAccessChain %100 %27 %98\n%102 = OpGroupNonUniformBroadcastFirst %5 %79 %98\n%103 = OpAccessChain %86 %10 %67 %102\n%104 = OpLoad %6 %103\n%105 = OpShiftRightLogical %6 %104 %90\n%106 = OpIAdd %5 %82 %107\n%109 = OpAccessChain %108 %32 %106\n%110 = OpGroupNonUniformBroadcastFirst %5 %79 %106\n%111 = OpAccessChain %86 %10 %67 %110\n%112 = OpLoad %6 %111\n%113 = OpShiftRightLogical %6 %112 %90\n%114 = OpIAdd %5 %82 %115\n%117 = OpAccessChain %116 %38 %114\n%119 = OpAccessChain %118 %44 %114\n%120 = OpGroupNonUniformBroadcastFirst %5 %79 %114\n%121 = OpAccessChain %86 %10 %67 %120\n%122 = OpLoad %6 %121\n%123 = OpIAdd %5 %82 %124\n%126 = OpAccessChain %125 %49 %123\n%128 = OpAccessChain %127 %54 %123\n%129 = OpGroupNonUniformBroadcastFirst %5 %79 %123\n%130 = OpAccessChain %86 %10 %67 %129\n%131 = OpLoad %6 %130\n%132 = OpCompositeExtract %5 %89 0\n%133 = OpCompositeExtract %5 %89 1\n%134 = OpIAdd %5 %69 %132\n%136 = OpULessThan %135 %69 %133\n%137 = OpSelect %5 %136 %134 %138\n%140 = OpAccessChain %139 %84 %67 %137\n%141 = OpLoad %5 %140\n%142 = OpBitcast %61 %141\n%143 = OpCompositeExtract %5 %97 0\n%144 = OpCompositeExtract %5 %97 1\n%145 = OpIAdd %5 %73 %143\n%146 = OpULessThan %135 %73 %144\n%147 = OpSelect %5 %146 %145 %148\n%150 = OpAccessChain %149 %93 %67 %147\n%151 = OpLoad %17 %150\n%154 = OpBitcast %153 %151\n%155 = OpCompositeExtract %152 %154 0\n%156 = OpCompositeExtract %152 %154 1\n%157 = OpFConvert %61 %155\n%158 = OpFConvert %61 %156\n%159 = OpCompositeExtract %5 %105 0\n%160 = OpCompositeExtract %5 %105 1\n%161 = OpIAdd %5 %77 %159\n%162 = OpULessThan %135 %77 %160\n%163 = OpSelect %5 %162 %161 %138\n%164 = OpAccessChain %139 %101 %67 %163\n%165 = OpLoad %5 %164\n%166 = OpBitcast %61 %165\n%167 = OpFAdd %61 %158 %166\n%168 = OpCompositeExtract %5 %113 0\n%169 = OpCompositeExtract %5 %113 1\n%170 = OpIAdd %5 %81 %168\n%171 = OpULessThan %135 %81 %169\n%172 = OpSelect %5 %171 %170 %148\n%173 = OpAccessChain %149 %109 %67 %172\n%174 = OpLoad %17 %173\n%175 = OpBitcast %153 %174\n%176 = OpCompositeExtract %152 %175 0\n%177 = OpCompositeExtract %152 %175 1\n%178 = OpFConvert %61 %176\n%179 = OpFConvert %61 %177\n%180 = OpFAdd %61 %179 %142\n%181 = OpShiftRightLogical %6 %122 %182\n%183 = OpCompositeExtract %5 %181 0\n%184 = OpCompositeExtract %5 %181 1\n%185 = OpIAdd %5 %71 %183\n%186 = OpULessThan %135 %71 %184\n%187 = OpSelect %5 %186 %185 %188\n%190 = OpAccessChain %189 %117 %67 %187\n%191 = OpLoad %33 %190\n%193 = OpBitcast %192 %191\n%194 = OpCompositeExtract %152 %193 0\n%195 = OpCompositeExtract %152 %193 1\n%196 = OpCompositeExtract %152 %193 2\n%197 = OpCompositeExtract %152 %193 3\n%198 = OpFConvert %61 %194\n%199 = OpFConvert %61 %195\n%200 = OpFConvert %61 %196\n%201 = OpFConvert %61 %197\n%202 = OpFAdd %61 %180 %198\n%203 = OpFAdd %61 %199 %157\n%204 = OpFAdd %61 %167 %200\n%205 = OpFAdd %61 %201 %178\n%206 = OpShiftRightLogical %6 %122 %207\n%208 = OpCompositeExtract %5 %206 0\n%209 = OpCompositeExtract %5 %206 1\n%210 = OpIAdd %5 %71 %208\n%211 = OpULessThan %135 %71 %209\n%212 = OpSelect %5 %211 %210 %213\n%215 = OpAccessChain %214 %119 %67 %212\n%216 = OpLoad %39 %215\n%217 = OpBitcast %62 %216\n%218 = OpCompositeExtract %61 %217 0\n%219 = OpCompositeExtract %61 %217 1\n%220 = OpCompositeExtract %61 %217 2\n%221 = OpCompositeExtract %61 %217 3\n%222 = OpFAdd %61 %202 %218\n%223 = OpFAdd %61 %203 %219\n%224 = OpFAdd %61 %204 %220\n%225 = OpFAdd %61 %205 %221\n%226 = OpShiftRightLogical %6 %131 %182\n%227 = OpCompositeExtract %5 %226 0\n%228 = OpCompositeExtract %5 %226 1\n%229 = OpIAdd %5 %71 %227\n%230 = OpULessThan %135 %71 %228\n%231 = OpSelect %5 %230 %229 %188\n%232 = OpAccessChain %189 %126 %67 %231\n%233 = OpLoad %33 %232\n%234 = OpBitcast %192 %233\n%235 = OpCompositeExtract %152 %234 0\n%236 = OpCompositeExtract %152 %234 1\n%237 = OpCompositeExtract %152 %234 2\n%238 = OpCompositeExtract %152 %234 3\n%239 = OpFConvert %61 %235\n%240 = OpFConvert %61 %236\n%241 = OpFConvert %61 %237\n%242 = OpFConvert %61 %238\n%243 = OpFAdd %61 %222 %239\n%244 = OpFAdd %61 %223 %240\n%245 = OpFAdd %61 %224 %241\n%246 = OpFAdd %61 %225 %242\n%247 = OpShiftRightLogical %6 %131 %207\n%248 = OpCompositeExtract %5 %247 0\n%249 = OpCompositeExtract %5 %247 1\n%250 = OpIAdd %5 %71 %248\n%251 = OpULessThan %135 %71 %249\n%252 = OpSelect %5 %251 %250 %213\n%253 = OpBitcast %5 %243\n%254 = OpBitcast %5 %244\n%255 = OpBitcast %5 %245\n%256 = OpBitcast %5 %246\n%257 = OpCompositeConstruct %39 %253 %254 %255 %256\n%258 = OpAccessChain %214 %128 %67 %252\nOpStore %258 %257\n%260 = OpAccessChain %259 %64 %67\nOpStore %260 %243\n%261 = OpAccessChain %259 %64 %71\nOpStore %261 %244\n%262 = OpAccessChain %259 %64 %75\nOpStore %262 %245\n%263 = OpAccessChain %259 %64 %79\nOpStore %263 %246\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/structured-buffer-heap.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _9[];\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _13[];\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _16[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _31 = uint(UV.x);\n    uint _35 = uint(UV.y);\n    uint _39 = uint(UV.z);\n    uint _43 = uint(UV.w);\n    uint _48 = INDEX + 1u;\n    uint _51 = INDEX + 2u;\n    uint _54 = INDEX + 3u;\n    uint _62 = INDEX + 5u;\n    uint _66 = INDEX + 6u;\n    uint _70 = INDEX + 7u;\n    uint _78 = INDEX + 9u;\n    uint _82 = INDEX + 10u;\n    uint _86 = INDEX + 11u;\n    uint _94 = _35 * 2u;\n    vec2 _103 = uintBitsToFloat(uvec2(texelFetch(_9[_48], int(_94)).x, texelFetch(_9[_48], int(_94 + 1u)).x));\n    uint _107 = _39 * 3u;\n    vec3 _119 = uintBitsToFloat(uvec3(texelFetch(_9[_51], int(_107)).x, texelFetch(_9[_51], int(_107 + 1u)).x, texelFetch(_9[_51], int(_107 + 2u)).x));\n    uint _125 = _43 * 4u;\n    vec4 _138 = uintBitsToFloat(uvec4(texelFetch(_9[_54], int(_125)).x, texelFetch(_9[_54], int(_125 + 1u)).x, texelFetch(_9[_54], int(_125 + 2u)).x, texelFetch(_9[_54], int(_125 + 3u)).x));\n    uvec4 _146 = imageLoad(_13[INDEX + 4u], int(_31));\n    uint _150 = _35 * 2u;\n    vec2 _157 = uintBitsToFloat(uvec2(imageLoad(_13[_62], int(_150)).x, imageLoad(_13[_62], int(_150 + 1u)).x));\n    uint _162 = _39 * 3u;\n    vec3 _172 = uintBitsToFloat(uvec3(imageLoad(_13[_66], int(_162)).x, imageLoad(_13[_66], int(_162 + 1u)).x, imageLoad(_13[_66], int(_162 + 2u)).x));\n    uint _179 = _43 * 4u;\n    uvec4 _180 = imageLoad(_13[_70], int(_179));\n    uvec4 _182 = imageLoad(_13[_70], int(_179 + 1u));\n    uvec4 _185 = imageLoad(_13[_70], int(_179 + 2u));\n    uvec4 _188 = imageLoad(_13[_70], int(_179 + 3u));\n    vec4 _192 = uintBitsToFloat(uvec4(_180.x, _182.x, _185.x, _188.x));\n    uvec4 _201 = imageLoad(_16[INDEX + 8u], int(_31));\n    uint _205 = _35 * 2u;\n    uvec4 _206 = imageLoad(_16[_78], int(_205));\n    uvec4 _208 = imageLoad(_16[_78], int(_205 + 1u));\n    vec2 _212 = uintBitsToFloat(uvec2(_206.x, _208.x));\n    uint _217 = _39 * 3u;\n    uvec4 _218 = imageLoad(_16[_82], int(_217));\n    uvec4 _220 = imageLoad(_16[_82], int(_217 + 1u));\n    uvec4 _223 = imageLoad(_16[_82], int(_217 + 2u));\n    vec3 _227 = uintBitsToFloat(uvec3(_218.x, _220.x, _223.x));\n    uint _234 = _43 * 4u;\n    uvec4 _235 = imageLoad(_16[_86], int(_234));\n    uvec4 _237 = imageLoad(_16[_86], int(_234 + 1u));\n    uvec4 _240 = imageLoad(_16[_86], int(_234 + 2u));\n    uvec4 _243 = imageLoad(_16[_86], int(_234 + 3u));\n    vec4 _247 = uintBitsToFloat(uvec4(_235.x, _237.x, _240.x, _243.x));\n    uint _256 = _31 * 2u;\n    imageStore(_13[_62], int(_256), uvec4(floatBitsToUint(20.0)));\n    imageStore(_13[_62], int(_256 + 1u), uvec4(floatBitsToUint(20.0)));\n    uint _263 = _35 * 3u;\n    imageStore(_16[_82], int(_263), uvec4(floatBitsToUint(30.0)));\n    imageStore(_16[_82], int(_263 + 1u), uvec4(floatBitsToUint(30.0)));\n    imageStore(_16[_82], int(_263 + 2u), uvec4(floatBitsToUint(30.0)));\n    SV_Target.x = ((((((((((_103.x + uintBitsToFloat(texelFetch(_9[INDEX], int(_31)).x)) + _119.x) + _138.x) + uintBitsToFloat(_146.x)) + _157.x) + _172.x) + _192.x) + uintBitsToFloat(_201.x)) + _212.x) + _227.x) + _247.x;\n    SV_Target.y = (((((((_119.y + _103.y) + _138.y) + _157.y) + _172.y) + _192.y) + _212.y) + _227.y) + _247.y;\n    SV_Target.z = ((((_138.z + _119.z) + _172.z) + _192.z) + _227.z) + _247.z;\n    SV_Target.w = (_192.w + _138.w) + _247.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 280\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %18 %22 %26\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %18 \"INDEX\"\nOpName %22 \"UV\"\nOpName %26 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %16 Coherent\nOpDecorate %18 Flat\nOpDecorate %18 Location 0\nOpDecorate %22 Flat\nOpDecorate %22 Location 1\nOpDecorate %26 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeRuntimeArray %10\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypeInt 32 1\n%20 = OpTypeVector %19 4\n%21 = OpTypePointer Input %20\n%22 = OpVariable %21 Input\n%23 = OpTypeFloat 32\n%24 = OpTypeVector %23 4\n%25 = OpTypePointer Output %24\n%26 = OpVariable %25 Output\n%27 = OpTypePointer Input %19\n%29 = OpConstant %5 0\n%33 = OpConstant %5 1\n%37 = OpConstant %5 2\n%41 = OpConstant %5 3\n%45 = OpTypePointer UniformConstant %6\n%58 = OpConstant %5 4\n%59 = OpTypePointer UniformConstant %10\n%63 = OpConstant %5 5\n%67 = OpConstant %5 6\n%71 = OpConstant %5 7\n%75 = OpConstant %5 8\n%79 = OpConstant %5 9\n%83 = OpConstant %5 10\n%87 = OpConstant %5 11\n%90 = OpTypeVector %5 4\n%100 = OpTypeVector %5 2\n%102 = OpTypeVector %23 2\n%116 = OpTypeVector %5 3\n%118 = OpTypeVector %23 3\n%257 = OpConstant %23 20\n%264 = OpConstant %23 30\n%273 = OpTypePointer Output %23\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %278\n%278 = OpLabel\n%28 = OpAccessChain %27 %22 %29\n%30 = OpLoad %19 %28\n%31 = OpBitcast %5 %30\n%32 = OpAccessChain %27 %22 %33\n%34 = OpLoad %19 %32\n%35 = OpBitcast %5 %34\n%36 = OpAccessChain %27 %22 %37\n%38 = OpLoad %19 %36\n%39 = OpBitcast %5 %38\n%40 = OpAccessChain %27 %22 %41\n%42 = OpLoad %19 %40\n%43 = OpBitcast %5 %42\n%44 = OpLoad %5 %18\n%46 = OpAccessChain %45 %9 %44\n%47 = OpLoad %6 %46\n%48 = OpIAdd %5 %44 %33\n%49 = OpAccessChain %45 %9 %48\n%50 = OpLoad %6 %49\n%51 = OpIAdd %5 %44 %37\n%52 = OpAccessChain %45 %9 %51\n%53 = OpLoad %6 %52\n%54 = OpIAdd %5 %44 %41\n%55 = OpAccessChain %45 %9 %54\n%56 = OpLoad %6 %55\n%57 = OpIAdd %5 %44 %58\n%60 = OpAccessChain %59 %13 %57\n%61 = OpLoad %10 %60\n%62 = OpIAdd %5 %44 %63\n%64 = OpAccessChain %59 %13 %62\n%65 = OpLoad %10 %64\n%66 = OpIAdd %5 %44 %67\n%68 = OpAccessChain %59 %13 %66\n%69 = OpLoad %10 %68\n%70 = OpIAdd %5 %44 %71\n%72 = OpAccessChain %59 %13 %70\n%73 = OpLoad %10 %72\n%74 = OpIAdd %5 %44 %75\n%76 = OpAccessChain %59 %16 %74\n%77 = OpLoad %10 %76\n%78 = OpIAdd %5 %44 %79\n%80 = OpAccessChain %59 %16 %78\n%81 = OpLoad %10 %80\n%82 = OpIAdd %5 %44 %83\n%84 = OpAccessChain %59 %16 %82\n%85 = OpLoad %10 %84\n%86 = OpIAdd %5 %44 %87\n%88 = OpAccessChain %59 %16 %86\n%89 = OpLoad %10 %88\n%91 = OpImageFetch %90 %47 %31\n%92 = OpCompositeExtract %5 %91 0\n%93 = OpBitcast %23 %92\n%94 = OpIMul %5 %35 %37\n%95 = OpImageFetch %90 %50 %94\n%96 = OpCompositeExtract %5 %95 0\n%98 = OpIAdd %5 %94 %33\n%97 = OpImageFetch %90 %50 %98\n%99 = OpCompositeExtract %5 %97 0\n%101 = OpCompositeConstruct %100 %96 %99\n%103 = OpBitcast %102 %101\n%104 = OpCompositeExtract %23 %103 0\n%105 = OpCompositeExtract %23 %103 1\n%106 = OpFAdd %23 %104 %93\n%107 = OpIMul %5 %39 %41\n%108 = OpImageFetch %90 %53 %107\n%109 = OpCompositeExtract %5 %108 0\n%111 = OpIAdd %5 %107 %33\n%110 = OpImageFetch %90 %53 %111\n%112 = OpCompositeExtract %5 %110 0\n%114 = OpIAdd %5 %107 %37\n%113 = OpImageFetch %90 %53 %114\n%115 = OpCompositeExtract %5 %113 0\n%117 = OpCompositeConstruct %116 %109 %112 %115\n%119 = OpBitcast %118 %117\n%120 = OpCompositeExtract %23 %119 0\n%121 = OpCompositeExtract %23 %119 1\n%122 = OpCompositeExtract %23 %119 2\n%123 = OpFAdd %23 %106 %120\n%124 = OpFAdd %23 %121 %105\n%125 = OpIMul %5 %43 %58\n%126 = OpImageFetch %90 %56 %125\n%127 = OpCompositeExtract %5 %126 0\n%129 = OpIAdd %5 %125 %33\n%128 = OpImageFetch %90 %56 %129\n%130 = OpCompositeExtract %5 %128 0\n%132 = OpIAdd %5 %125 %37\n%131 = OpImageFetch %90 %56 %132\n%133 = OpCompositeExtract %5 %131 0\n%135 = OpIAdd %5 %125 %41\n%134 = OpImageFetch %90 %56 %135\n%136 = OpCompositeExtract %5 %134 0\n%137 = OpCompositeConstruct %90 %127 %130 %133 %136\n%138 = OpBitcast %24 %137\n%139 = OpCompositeExtract %23 %138 0\n%140 = OpCompositeExtract %23 %138 1\n%141 = OpCompositeExtract %23 %138 2\n%142 = OpCompositeExtract %23 %138 3\n%143 = OpFAdd %23 %123 %139\n%144 = OpFAdd %23 %124 %140\n%145 = OpFAdd %23 %141 %122\n%146 = OpImageRead %90 %61 %31\n%147 = OpCompositeExtract %5 %146 0\n%148 = OpBitcast %23 %147\n%149 = OpFAdd %23 %143 %148\n%150 = OpIMul %5 %35 %37\n%151 = OpImageRead %90 %65 %150\n%152 = OpCompositeExtract %5 %151 0\n%154 = OpIAdd %5 %150 %33\n%153 = OpImageRead %90 %65 %154\n%155 = OpCompositeExtract %5 %153 0\n%156 = OpCompositeConstruct %100 %152 %155\n%157 = OpBitcast %102 %156\n%158 = OpCompositeExtract %23 %157 0\n%159 = OpCompositeExtract %23 %157 1\n%160 = OpFAdd %23 %149 %158\n%161 = OpFAdd %23 %144 %159\n%162 = OpIMul %5 %39 %41\n%163 = OpImageRead %90 %69 %162\n%164 = OpCompositeExtract %5 %163 0\n%166 = OpIAdd %5 %162 %33\n%165 = OpImageRead %90 %69 %166\n%167 = OpCompositeExtract %5 %165 0\n%169 = OpIAdd %5 %162 %37\n%168 = OpImageRead %90 %69 %169\n%170 = OpCompositeExtract %5 %168 0\n%171 = OpCompositeConstruct %116 %164 %167 %170\n%172 = OpBitcast %118 %171\n%173 = OpCompositeExtract %23 %172 0\n%174 = OpCompositeExtract %23 %172 1\n%175 = OpCompositeExtract %23 %172 2\n%176 = OpFAdd %23 %160 %173\n%177 = OpFAdd %23 %161 %174\n%178 = OpFAdd %23 %145 %175\n%179 = OpIMul %5 %43 %58\n%180 = OpImageRead %90 %73 %179\n%181 = OpCompositeExtract %5 %180 0\n%183 = OpIAdd %5 %179 %33\n%182 = OpImageRead %90 %73 %183\n%184 = OpCompositeExtract %5 %182 0\n%186 = OpIAdd %5 %179 %37\n%185 = OpImageRead %90 %73 %186\n%187 = OpCompositeExtract %5 %185 0\n%189 = OpIAdd %5 %179 %41\n%188 = OpImageRead %90 %73 %189\n%190 = OpCompositeExtract %5 %188 0\n%191 = OpCompositeConstruct %90 %181 %184 %187 %190\n%192 = OpBitcast %24 %191\n%193 = OpCompositeExtract %23 %192 0\n%194 = OpCompositeExtract %23 %192 1\n%195 = OpCompositeExtract %23 %192 2\n%196 = OpCompositeExtract %23 %192 3\n%197 = OpFAdd %23 %176 %193\n%198 = OpFAdd %23 %177 %194\n%199 = OpFAdd %23 %178 %195\n%200 = OpFAdd %23 %196 %142\n%201 = OpImageRead %90 %77 %31\n%202 = OpCompositeExtract %5 %201 0\n%203 = OpBitcast %23 %202\n%204 = OpFAdd %23 %197 %203\n%205 = OpIMul %5 %35 %37\n%206 = OpImageRead %90 %81 %205\n%207 = OpCompositeExtract %5 %206 0\n%209 = OpIAdd %5 %205 %33\n%208 = OpImageRead %90 %81 %209\n%210 = OpCompositeExtract %5 %208 0\n%211 = OpCompositeConstruct %100 %207 %210\n%212 = OpBitcast %102 %211\n%213 = OpCompositeExtract %23 %212 0\n%214 = OpCompositeExtract %23 %212 1\n%215 = OpFAdd %23 %204 %213\n%216 = OpFAdd %23 %198 %214\n%217 = OpIMul %5 %39 %41\n%218 = OpImageRead %90 %85 %217\n%219 = OpCompositeExtract %5 %218 0\n%221 = OpIAdd %5 %217 %33\n%220 = OpImageRead %90 %85 %221\n%222 = OpCompositeExtract %5 %220 0\n%224 = OpIAdd %5 %217 %37\n%223 = OpImageRead %90 %85 %224\n%225 = OpCompositeExtract %5 %223 0\n%226 = OpCompositeConstruct %116 %219 %222 %225\n%227 = OpBitcast %118 %226\n%228 = OpCompositeExtract %23 %227 0\n%229 = OpCompositeExtract %23 %227 1\n%230 = OpCompositeExtract %23 %227 2\n%231 = OpFAdd %23 %215 %228\n%232 = OpFAdd %23 %216 %229\n%233 = OpFAdd %23 %199 %230\n%234 = OpIMul %5 %43 %58\n%235 = OpImageRead %90 %89 %234\n%236 = OpCompositeExtract %5 %235 0\n%238 = OpIAdd %5 %234 %33\n%237 = OpImageRead %90 %89 %238\n%239 = OpCompositeExtract %5 %237 0\n%241 = OpIAdd %5 %234 %37\n%240 = OpImageRead %90 %89 %241\n%242 = OpCompositeExtract %5 %240 0\n%244 = OpIAdd %5 %234 %41\n%243 = OpImageRead %90 %89 %244\n%245 = OpCompositeExtract %5 %243 0\n%246 = OpCompositeConstruct %90 %236 %239 %242 %245\n%247 = OpBitcast %24 %246\n%248 = OpCompositeExtract %23 %247 0\n%249 = OpCompositeExtract %23 %247 1\n%250 = OpCompositeExtract %23 %247 2\n%251 = OpCompositeExtract %23 %247 3\n%252 = OpFAdd %23 %231 %248\n%253 = OpFAdd %23 %232 %249\n%254 = OpFAdd %23 %233 %250\n%255 = OpFAdd %23 %200 %251\n%256 = OpIMul %5 %31 %37\n%258 = OpBitcast %5 %257\n%259 = OpBitcast %5 %257\n%260 = OpCompositeConstruct %90 %258 %258 %258 %258\nOpImageWrite %65 %256 %260\n%261 = OpCompositeConstruct %90 %259 %259 %259 %259\n%262 = OpIAdd %5 %256 %33\nOpImageWrite %65 %262 %261\n%263 = OpIMul %5 %35 %41\n%265 = OpBitcast %5 %264\n%266 = OpBitcast %5 %264\n%267 = OpBitcast %5 %264\n%268 = OpCompositeConstruct %90 %265 %265 %265 %265\nOpImageWrite %85 %263 %268\n%269 = OpCompositeConstruct %90 %266 %266 %266 %266\n%270 = OpIAdd %5 %263 %33\nOpImageWrite %85 %270 %269\n%271 = OpCompositeConstruct %90 %267 %267 %267 %267\n%272 = OpIAdd %5 %263 %37\nOpImageWrite %85 %272 %271\n%274 = OpAccessChain %273 %26 %29\nOpStore %274 %252\n%275 = OpAccessChain %273 %26 %33\nOpStore %275 %253\n%276 = OpAccessChain %273 %26 %37\nOpStore %276 %254\n%277 = OpAccessChain %273 %26 %41\nOpStore %277 %255\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/structured-buffer-heap.ssbo.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _13_16\n{\n    uvec2 _m0[];\n} _16[];\n\nlayout(set = 0, binding = 0, scalar) restrict readonly buffer _19_22\n{\n    uvec3 _m0[];\n} _22[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _25_28\n{\n    uvec4 _m0[];\n} _28[];\n\nlayout(set = 0, binding = 0, std430) buffer _30_33\n{\n    uint _m0[];\n} _33[];\n\nlayout(set = 0, binding = 0, std430) buffer _35_38\n{\n    uvec2 _m0[];\n} _38[];\n\nlayout(set = 0, binding = 0, scalar) buffer _40_43\n{\n    uvec3 _m0[];\n} _43[];\n\nlayout(set = 0, binding = 0, std430) buffer _45_48\n{\n    uvec4 _m0[];\n} _48[];\n\nlayout(set = 0, binding = 0, std430) coherent buffer _50_53\n{\n    uint _m0[];\n} _53[];\n\nlayout(set = 0, binding = 0, std430) coherent buffer _55_58\n{\n    uvec2 _m0[];\n} _58[];\n\nlayout(set = 0, binding = 0, scalar) coherent buffer _60_63\n{\n    uvec3 _m0[];\n} _63[];\n\nlayout(set = 0, binding = 0, std430) coherent buffer _65_68\n{\n    uvec4 _m0[];\n} _68[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _83 = uint(UV.x);\n    uint _87 = uint(UV.y);\n    uint _91 = uint(UV.z);\n    uint _95 = uint(UV.w);\n    uint _112 = INDEX + 5u;\n    uint _132 = INDEX + 10u;\n    vec2 _148 = uintBitsToFloat(_16[INDEX + 1u]._m0[_87]);\n    vec3 _156 = uintBitsToFloat(_22[INDEX + 2u]._m0[_91]);\n    vec4 _165 = uintBitsToFloat(_28[INDEX + 3u]._m0[_95]);\n    uint _174 = _33[INDEX + 4u]._m0[_83];\n    vec2 _179 = uintBitsToFloat(_38[_112]._m0[_87]);\n    uvec3 _185 = _43[INDEX + 6u]._m0[_91];\n    vec3 _186 = uintBitsToFloat(_185);\n    uvec4 _194 = _48[INDEX + 7u]._m0[_95];\n    vec4 _195 = uintBitsToFloat(_194);\n    uint _205 = _53[INDEX + 8u]._m0[_83];\n    uvec2 _209 = _58[INDEX + 9u]._m0[_87];\n    vec2 _210 = uintBitsToFloat(_209);\n    uvec3 _216 = _63[_132]._m0[_91];\n    vec3 _217 = uintBitsToFloat(_216);\n    uvec4 _225 = _68[INDEX + 11u]._m0[_95];\n    vec4 _226 = uintBitsToFloat(_225);\n    _38[_112]._m0[_83] = uvec2(floatBitsToUint(20.0), floatBitsToUint(20.0));\n    _63[_132]._m0[_87] = uvec3(floatBitsToUint(30.0), floatBitsToUint(30.0), floatBitsToUint(30.0));\n    SV_Target.x = ((((((((((_148.x + uintBitsToFloat(_10[INDEX]._m0[_83])) + _156.x) + _165.x) + uintBitsToFloat(_174)) + _179.x) + _186.x) + _195.x) + uintBitsToFloat(_205)) + _210.x) + _217.x) + _226.x;\n    SV_Target.y = (((((((_156.y + _148.y) + _165.y) + _179.y) + _186.y) + _195.y) + _210.y) + _217.y) + _226.y;\n    SV_Target.z = ((((_165.z + _156.z) + _186.z) + _195.z) + _217.z) + _226.z;\n    SV_Target.w = (_195.w + _165.w) + _226.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 253\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %70 %74 %78\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %19 \"SSBO\"\nOpName %25 \"SSBO\"\nOpName %30 \"SSBO\"\nOpName %35 \"SSBO\"\nOpName %40 \"SSBO\"\nOpName %45 \"SSBO\"\nOpName %50 \"SSBO\"\nOpName %55 \"SSBO\"\nOpName %60 \"SSBO\"\nOpName %65 \"SSBO\"\nOpName %70 \"INDEX\"\nOpName %74 \"UV\"\nOpName %78 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %12 ArrayStride 8\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %16 NonWritable\nOpDecorate %16 Restrict\nOpDecorate %18 ArrayStride 12\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 0\nOpDecorate %22 NonWritable\nOpDecorate %22 Restrict\nOpDecorate %24 ArrayStride 16\nOpMemberDecorate %25 0 Offset 0\nOpDecorate %25 Block\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %28 NonWritable\nOpDecorate %28 Restrict\nOpDecorate %29 ArrayStride 4\nOpMemberDecorate %30 0 Offset 0\nOpDecorate %30 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %34 ArrayStride 8\nOpMemberDecorate %35 0 Offset 0\nOpDecorate %35 Block\nOpDecorate %38 DescriptorSet 0\nOpDecorate %38 Binding 0\nOpDecorate %39 ArrayStride 12\nOpMemberDecorate %40 0 Offset 0\nOpDecorate %40 Block\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 0\nOpDecorate %44 ArrayStride 16\nOpMemberDecorate %45 0 Offset 0\nOpDecorate %45 Block\nOpDecorate %48 DescriptorSet 0\nOpDecorate %48 Binding 0\nOpDecorate %49 ArrayStride 4\nOpMemberDecorate %50 0 Offset 0\nOpDecorate %50 Block\nOpDecorate %53 DescriptorSet 0\nOpDecorate %53 Binding 0\nOpDecorate %53 Coherent\nOpDecorate %54 ArrayStride 8\nOpMemberDecorate %55 0 Offset 0\nOpDecorate %55 Block\nOpDecorate %58 DescriptorSet 0\nOpDecorate %58 Binding 0\nOpDecorate %58 Coherent\nOpDecorate %59 ArrayStride 12\nOpMemberDecorate %60 0 Offset 0\nOpDecorate %60 Block\nOpDecorate %63 DescriptorSet 0\nOpDecorate %63 Binding 0\nOpDecorate %63 Coherent\nOpDecorate %64 ArrayStride 16\nOpMemberDecorate %65 0 Offset 0\nOpDecorate %65 Block\nOpDecorate %68 DescriptorSet 0\nOpDecorate %68 Binding 0\nOpDecorate %68 Coherent\nOpDecorate %70 Flat\nOpDecorate %70 Location 0\nOpDecorate %74 Flat\nOpDecorate %74 Location 1\nOpDecorate %78 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypeRuntimeArray %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeVector %5 2\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeVector %5 3\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeVector %5 4\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypeStruct %24\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypePointer StorageBuffer %26\n%28 = OpVariable %27 StorageBuffer\n%29 = OpTypeRuntimeArray %5\n%30 = OpTypeStruct %29\n%31 = OpTypeRuntimeArray %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeRuntimeArray %11\n%35 = OpTypeStruct %34\n%36 = OpTypeRuntimeArray %35\n%37 = OpTypePointer StorageBuffer %36\n%38 = OpVariable %37 StorageBuffer\n%39 = OpTypeRuntimeArray %17\n%40 = OpTypeStruct %39\n%41 = OpTypeRuntimeArray %40\n%42 = OpTypePointer StorageBuffer %41\n%43 = OpVariable %42 StorageBuffer\n%44 = OpTypeRuntimeArray %23\n%45 = OpTypeStruct %44\n%46 = OpTypeRuntimeArray %45\n%47 = OpTypePointer StorageBuffer %46\n%48 = OpVariable %47 StorageBuffer\n%49 = OpTypeRuntimeArray %5\n%50 = OpTypeStruct %49\n%51 = OpTypeRuntimeArray %50\n%52 = OpTypePointer StorageBuffer %51\n%53 = OpVariable %52 StorageBuffer\n%54 = OpTypeRuntimeArray %11\n%55 = OpTypeStruct %54\n%56 = OpTypeRuntimeArray %55\n%57 = OpTypePointer StorageBuffer %56\n%58 = OpVariable %57 StorageBuffer\n%59 = OpTypeRuntimeArray %17\n%60 = OpTypeStruct %59\n%61 = OpTypeRuntimeArray %60\n%62 = OpTypePointer StorageBuffer %61\n%63 = OpVariable %62 StorageBuffer\n%64 = OpTypeRuntimeArray %23\n%65 = OpTypeStruct %64\n%66 = OpTypeRuntimeArray %65\n%67 = OpTypePointer StorageBuffer %66\n%68 = OpVariable %67 StorageBuffer\n%69 = OpTypePointer Input %5\n%70 = OpVariable %69 Input\n%71 = OpTypeInt 32 1\n%72 = OpTypeVector %71 4\n%73 = OpTypePointer Input %72\n%74 = OpVariable %73 Input\n%75 = OpTypeFloat 32\n%76 = OpTypeVector %75 4\n%77 = OpTypePointer Output %76\n%78 = OpVariable %77 Output\n%79 = OpTypePointer Input %71\n%81 = OpConstant %5 0\n%85 = OpConstant %5 1\n%89 = OpConstant %5 2\n%93 = OpConstant %5 3\n%97 = OpTypePointer StorageBuffer %7\n%100 = OpTypePointer StorageBuffer %13\n%103 = OpTypePointer StorageBuffer %19\n%106 = OpTypePointer StorageBuffer %25\n%109 = OpConstant %5 4\n%110 = OpTypePointer StorageBuffer %30\n%113 = OpConstant %5 5\n%114 = OpTypePointer StorageBuffer %35\n%117 = OpConstant %5 6\n%118 = OpTypePointer StorageBuffer %40\n%121 = OpConstant %5 7\n%122 = OpTypePointer StorageBuffer %45\n%125 = OpConstant %5 8\n%126 = OpTypePointer StorageBuffer %50\n%129 = OpConstant %5 9\n%130 = OpTypePointer StorageBuffer %55\n%133 = OpConstant %5 10\n%134 = OpTypePointer StorageBuffer %60\n%137 = OpConstant %5 11\n%138 = OpTypePointer StorageBuffer %65\n%140 = OpTypePointer StorageBuffer %5\n%144 = OpTypePointer StorageBuffer %11\n%147 = OpTypeVector %75 2\n%152 = OpTypePointer StorageBuffer %17\n%155 = OpTypeVector %75 3\n%162 = OpTypePointer StorageBuffer %23\n%235 = OpConstant %75 20\n%240 = OpConstant %75 30\n%246 = OpTypePointer Output %75\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %251\n%251 = OpLabel\n%80 = OpAccessChain %79 %74 %81\n%82 = OpLoad %71 %80\n%83 = OpBitcast %5 %82\n%84 = OpAccessChain %79 %74 %85\n%86 = OpLoad %71 %84\n%87 = OpBitcast %5 %86\n%88 = OpAccessChain %79 %74 %89\n%90 = OpLoad %71 %88\n%91 = OpBitcast %5 %90\n%92 = OpAccessChain %79 %74 %93\n%94 = OpLoad %71 %92\n%95 = OpBitcast %5 %94\n%96 = OpLoad %5 %70\n%98 = OpAccessChain %97 %10 %96\n%99 = OpIAdd %5 %96 %85\n%101 = OpAccessChain %100 %16 %99\n%102 = OpIAdd %5 %96 %89\n%104 = OpAccessChain %103 %22 %102\n%105 = OpIAdd %5 %96 %93\n%107 = OpAccessChain %106 %28 %105\n%108 = OpIAdd %5 %96 %109\n%111 = OpAccessChain %110 %33 %108\n%112 = OpIAdd %5 %96 %113\n%115 = OpAccessChain %114 %38 %112\n%116 = OpIAdd %5 %96 %117\n%119 = OpAccessChain %118 %43 %116\n%120 = OpIAdd %5 %96 %121\n%123 = OpAccessChain %122 %48 %120\n%124 = OpIAdd %5 %96 %125\n%127 = OpAccessChain %126 %53 %124\n%128 = OpIAdd %5 %96 %129\n%131 = OpAccessChain %130 %58 %128\n%132 = OpIAdd %5 %96 %133\n%135 = OpAccessChain %134 %63 %132\n%136 = OpIAdd %5 %96 %137\n%139 = OpAccessChain %138 %68 %136\n%141 = OpAccessChain %140 %98 %81 %83\n%142 = OpLoad %5 %141\n%143 = OpBitcast %75 %142\n%145 = OpAccessChain %144 %101 %81 %87\n%146 = OpLoad %11 %145\n%148 = OpBitcast %147 %146\n%149 = OpCompositeExtract %75 %148 0\n%150 = OpCompositeExtract %75 %148 1\n%151 = OpFAdd %75 %149 %143\n%153 = OpAccessChain %152 %104 %81 %91\n%154 = OpLoad %17 %153\n%156 = OpBitcast %155 %154\n%157 = OpCompositeExtract %75 %156 0\n%158 = OpCompositeExtract %75 %156 1\n%159 = OpCompositeExtract %75 %156 2\n%160 = OpFAdd %75 %151 %157\n%161 = OpFAdd %75 %158 %150\n%163 = OpAccessChain %162 %107 %81 %95\n%164 = OpLoad %23 %163\n%165 = OpBitcast %76 %164\n%166 = OpCompositeExtract %75 %165 0\n%167 = OpCompositeExtract %75 %165 1\n%168 = OpCompositeExtract %75 %165 2\n%169 = OpCompositeExtract %75 %165 3\n%170 = OpFAdd %75 %160 %166\n%171 = OpFAdd %75 %161 %167\n%172 = OpFAdd %75 %168 %159\n%173 = OpAccessChain %140 %111 %81 %83\n%174 = OpLoad %5 %173\n%175 = OpBitcast %75 %174\n%176 = OpFAdd %75 %170 %175\n%177 = OpAccessChain %144 %115 %81 %87\n%178 = OpLoad %11 %177\n%179 = OpBitcast %147 %178\n%180 = OpCompositeExtract %75 %179 0\n%181 = OpCompositeExtract %75 %179 1\n%182 = OpFAdd %75 %176 %180\n%183 = OpFAdd %75 %171 %181\n%184 = OpAccessChain %152 %119 %81 %91\n%185 = OpLoad %17 %184\n%186 = OpBitcast %155 %185\n%187 = OpCompositeExtract %75 %186 0\n%188 = OpCompositeExtract %75 %186 1\n%189 = OpCompositeExtract %75 %186 2\n%190 = OpFAdd %75 %182 %187\n%191 = OpFAdd %75 %183 %188\n%192 = OpFAdd %75 %172 %189\n%193 = OpAccessChain %162 %123 %81 %95\n%194 = OpLoad %23 %193\n%195 = OpBitcast %76 %194\n%196 = OpCompositeExtract %75 %195 0\n%197 = OpCompositeExtract %75 %195 1\n%198 = OpCompositeExtract %75 %195 2\n%199 = OpCompositeExtract %75 %195 3\n%200 = OpFAdd %75 %190 %196\n%201 = OpFAdd %75 %191 %197\n%202 = OpFAdd %75 %192 %198\n%203 = OpFAdd %75 %199 %169\n%204 = OpAccessChain %140 %127 %81 %83\n%205 = OpLoad %5 %204\n%206 = OpBitcast %75 %205\n%207 = OpFAdd %75 %200 %206\n%208 = OpAccessChain %144 %131 %81 %87\n%209 = OpLoad %11 %208\n%210 = OpBitcast %147 %209\n%211 = OpCompositeExtract %75 %210 0\n%212 = OpCompositeExtract %75 %210 1\n%213 = OpFAdd %75 %207 %211\n%214 = OpFAdd %75 %201 %212\n%215 = OpAccessChain %152 %135 %81 %91\n%216 = OpLoad %17 %215\n%217 = OpBitcast %155 %216\n%218 = OpCompositeExtract %75 %217 0\n%219 = OpCompositeExtract %75 %217 1\n%220 = OpCompositeExtract %75 %217 2\n%221 = OpFAdd %75 %213 %218\n%222 = OpFAdd %75 %214 %219\n%223 = OpFAdd %75 %202 %220\n%224 = OpAccessChain %162 %139 %81 %95\n%225 = OpLoad %23 %224\n%226 = OpBitcast %76 %225\n%227 = OpCompositeExtract %75 %226 0\n%228 = OpCompositeExtract %75 %226 1\n%229 = OpCompositeExtract %75 %226 2\n%230 = OpCompositeExtract %75 %226 3\n%231 = OpFAdd %75 %221 %227\n%232 = OpFAdd %75 %222 %228\n%233 = OpFAdd %75 %223 %229\n%234 = OpFAdd %75 %203 %230\n%236 = OpBitcast %5 %235\n%237 = OpBitcast %5 %235\n%238 = OpCompositeConstruct %11 %236 %237\n%239 = OpAccessChain %144 %115 %81 %83\nOpStore %239 %238\n%241 = OpBitcast %5 %240\n%242 = OpBitcast %5 %240\n%243 = OpBitcast %5 %240\n%244 = OpCompositeConstruct %17 %241 %242 %243\n%245 = OpAccessChain %152 %135 %81 %87\nOpStore %245 %244\n%247 = OpAccessChain %246 %78 %81\nOpStore %247 %231\n%248 = OpAccessChain %246 %78 %85\nOpStore %248 %232\n%249 = OpAccessChain %246 %78 %89\nOpStore %249 %233\n%250 = OpAccessChain %246 %78 %93\nOpStore %250 %234\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/structured-buffer-heap.ssbo.ssbo-align.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _15[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _17_20\n{\n    uvec2 _m0[];\n} _20[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _23_26\n{\n    uvec4 _m0[];\n} _26[];\n\nlayout(set = 0, binding = 0, std430) buffer _28_31\n{\n    uint _m0[];\n} _31[];\n\nlayout(set = 0, binding = 0, std430) buffer _33_36\n{\n    uvec2 _m0[];\n} _36[];\n\nlayout(set = 0, binding = 0, std430) buffer _38_41\n{\n    uvec4 _m0[];\n} _41[];\n\nlayout(set = 0, binding = 0, std430) coherent buffer _43_46\n{\n    uint _m0[];\n} _46[];\n\nlayout(set = 0, binding = 0, std430) coherent buffer _48_51\n{\n    uvec2 _m0[];\n} _51[];\n\nlayout(set = 0, binding = 0, std430) coherent buffer _53_56\n{\n    uvec4 _m0[];\n} _56[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _71 = uint(UV.x);\n    uint _75 = uint(UV.y);\n    uint _79 = uint(UV.z);\n    uint _83 = uint(UV.w);\n    uvec2 _91 = _10._m0[subgroupBroadcastFirst(INDEX)] >> uvec2(2u);\n    uint _93 = INDEX + 1u;\n    uvec2 _99 = _10._m0[subgroupBroadcastFirst(_93)] >> uvec2(3u);\n    uint _101 = INDEX + 2u;\n    uvec2 _106 = _10._m0[subgroupBroadcastFirst(_101)] >> uvec2(2u);\n    uint _107 = INDEX + 3u;\n    uvec2 _113 = _10._m0[subgroupBroadcastFirst(_107)] >> uvec2(4u);\n    uint _116 = INDEX + 4u;\n    uvec2 _122 = _10._m0[subgroupBroadcastFirst(_116)] >> uvec2(2u);\n    uint _123 = INDEX + 5u;\n    uvec2 _130 = _10._m0[subgroupBroadcastFirst(_123)] >> uvec2(3u);\n    uint _131 = INDEX + 6u;\n    uvec2 _137 = _10._m0[subgroupBroadcastFirst(_131)] >> uvec2(2u);\n    uint _138 = INDEX + 7u;\n    uvec2 _145 = _10._m0[subgroupBroadcastFirst(_138)] >> uvec2(4u);\n    uint _146 = INDEX + 8u;\n    uvec2 _153 = _10._m0[subgroupBroadcastFirst(_146)] >> uvec2(2u);\n    uint _154 = INDEX + 9u;\n    uvec2 _161 = _10._m0[subgroupBroadcastFirst(_154)] >> uvec2(3u);\n    uint _162 = INDEX + 10u;\n    uvec2 _168 = _10._m0[subgroupBroadcastFirst(_162)] >> uvec2(2u);\n    uint _169 = INDEX + 11u;\n    uvec2 _176 = _10._m0[subgroupBroadcastFirst(_169)] >> uvec2(4u);\n    vec2 _197 = uintBitsToFloat(_20[_93]._m0[(_75 < _99.y) ? (_75 + _99.x) : 536870911u]);\n    uint _201 = _79 * 3u;\n    uint _206 = (_201 < _106.y) ? (_201 + _106.x) : 1073741820u;\n    vec3 _218 = uintBitsToFloat(uvec3(_15[_101]._m0[_206], _15[_101]._m0[_206 + 1u], _15[_101]._m0[_206 + 2u]));\n    vec4 _233 = uintBitsToFloat(_26[_107]._m0[(_83 < _113.y) ? (_83 + _113.x) : 268435455u]);\n    uint _247 = _31[_116]._m0[(_71 < _122.y) ? (_71 + _122.x) : 1073741820u];\n    vec2 _257 = uintBitsToFloat(_36[_123]._m0[(_75 < _130.y) ? (_75 + _130.x) : 536870911u]);\n    uint _262 = _79 * 3u;\n    uint _267 = (_262 < _137.y) ? (_262 + _137.x) : 1073741820u;\n    vec3 _277 = uintBitsToFloat(uvec3(_31[_131]._m0[_267], _31[_131]._m0[_267 + 1u], _31[_131]._m0[_267 + 2u]));\n    uvec4 _290 = _41[_138]._m0[(_83 < _145.y) ? (_83 + _145.x) : 268435455u];\n    vec4 _291 = uintBitsToFloat(_290);\n    uint _306 = _46[_146]._m0[(_71 < _153.y) ? (_71 + _153.x) : 1073741820u];\n    uvec2 _315 = _51[_154]._m0[(_75 < _161.y) ? (_75 + _161.x) : 536870911u];\n    vec2 _316 = uintBitsToFloat(_315);\n    uint _321 = _79 * 3u;\n    uint _326 = (_321 < _168.y) ? (_321 + _168.x) : 1073741820u;\n    uint _328 = _46[_162]._m0[_326];\n    uint _331 = _46[_162]._m0[_326 + 1u];\n    uint _334 = _46[_162]._m0[_326 + 2u];\n    vec3 _336 = uintBitsToFloat(uvec3(_328, _331, _334));\n    uvec4 _349 = _56[_169]._m0[(_83 < _176.y) ? (_83 + _176.x) : 268435455u];\n    vec4 _350 = uintBitsToFloat(_349);\n    _36[_123]._m0[(_71 < _130.y) ? (_71 + _130.x) : 536870911u] = uvec2(floatBitsToUint(20.0), floatBitsToUint(20.0));\n    uint _369 = _75 * 3u;\n    uint _374 = (_369 < _168.y) ? (_369 + _168.x) : 1073741820u;\n    _46[_162]._m0[_374] = floatBitsToUint(30.0);\n    _46[_162]._m0[_374 + 1u] = floatBitsToUint(30.0);\n    _46[_162]._m0[_374 + 2u] = floatBitsToUint(30.0);\n    SV_Target.x = ((((((((((_197.x + uintBitsToFloat(_15[INDEX]._m0[(_71 < _91.y) ? (_71 + _91.x) : 1073741820u])) + _218.x) + _233.x) + uintBitsToFloat(_247)) + _257.x) + _277.x) + _291.x) + uintBitsToFloat(_306)) + _316.x) + _336.x) + _350.x;\n    SV_Target.y = (((((((_218.y + _197.y) + _233.y) + _257.y) + _277.y) + _291.y) + _316.y) + _336.y) + _350.y;\n    SV_Target.z = ((((_233.z + _218.z) + _277.z) + _291.z) + _336.z) + _350.z;\n    SV_Target.w = (_291.w + _233.w) + _350.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 391\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %58 %62 %66\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SSBO_Offsets\"\nOpName %12 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %23 \"SSBO\"\nOpName %28 \"SSBO\"\nOpName %33 \"SSBO\"\nOpName %38 \"SSBO\"\nOpName %43 \"SSBO\"\nOpName %48 \"SSBO\"\nOpName %53 \"SSBO\"\nOpName %58 \"INDEX\"\nOpName %62 \"UV\"\nOpName %66 \"SV_Target\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 15\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %16 ArrayStride 8\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %22 ArrayStride 16\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %23 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %26 NonWritable\nOpDecorate %26 Restrict\nOpDecorate %27 ArrayStride 4\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 0\nOpDecorate %32 ArrayStride 8\nOpMemberDecorate %33 0 Offset 0\nOpDecorate %33 Block\nOpDecorate %36 DescriptorSet 0\nOpDecorate %36 Binding 0\nOpDecorate %37 ArrayStride 16\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpDecorate %41 DescriptorSet 0\nOpDecorate %41 Binding 0\nOpDecorate %42 ArrayStride 4\nOpMemberDecorate %43 0 Offset 0\nOpDecorate %43 Block\nOpDecorate %46 DescriptorSet 0\nOpDecorate %46 Binding 0\nOpDecorate %46 Coherent\nOpDecorate %47 ArrayStride 8\nOpMemberDecorate %48 0 Offset 0\nOpDecorate %48 Block\nOpDecorate %51 DescriptorSet 0\nOpDecorate %51 Binding 0\nOpDecorate %51 Coherent\nOpDecorate %52 ArrayStride 16\nOpMemberDecorate %53 0 Offset 0\nOpDecorate %53 Block\nOpDecorate %56 DescriptorSet 0\nOpDecorate %56 Binding 0\nOpDecorate %56 Coherent\nOpDecorate %58 Flat\nOpDecorate %58 Location 0\nOpDecorate %62 Flat\nOpDecorate %62 Location 1\nOpDecorate %66 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %5\n%12 = OpTypeStruct %11\n%13 = OpTypeRuntimeArray %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeRuntimeArray %6\n%17 = OpTypeStruct %16\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeVector %5 4\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypeStruct %22\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpTypeRuntimeArray %5\n%28 = OpTypeStruct %27\n%29 = OpTypeRuntimeArray %28\n%30 = OpTypePointer StorageBuffer %29\n%31 = OpVariable %30 StorageBuffer\n%32 = OpTypeRuntimeArray %6\n%33 = OpTypeStruct %32\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypePointer StorageBuffer %34\n%36 = OpVariable %35 StorageBuffer\n%37 = OpTypeRuntimeArray %21\n%38 = OpTypeStruct %37\n%39 = OpTypeRuntimeArray %38\n%40 = OpTypePointer StorageBuffer %39\n%41 = OpVariable %40 StorageBuffer\n%42 = OpTypeRuntimeArray %5\n%43 = OpTypeStruct %42\n%44 = OpTypeRuntimeArray %43\n%45 = OpTypePointer StorageBuffer %44\n%46 = OpVariable %45 StorageBuffer\n%47 = OpTypeRuntimeArray %6\n%48 = OpTypeStruct %47\n%49 = OpTypeRuntimeArray %48\n%50 = OpTypePointer StorageBuffer %49\n%51 = OpVariable %50 StorageBuffer\n%52 = OpTypeRuntimeArray %21\n%53 = OpTypeStruct %52\n%54 = OpTypeRuntimeArray %53\n%55 = OpTypePointer StorageBuffer %54\n%56 = OpVariable %55 StorageBuffer\n%57 = OpTypePointer Input %5\n%58 = OpVariable %57 Input\n%59 = OpTypeInt 32 1\n%60 = OpTypeVector %59 4\n%61 = OpTypePointer Input %60\n%62 = OpVariable %61 Input\n%63 = OpTypeFloat 32\n%64 = OpTypeVector %63 4\n%65 = OpTypePointer Output %64\n%66 = OpVariable %65 Output\n%67 = OpTypePointer Input %59\n%69 = OpConstant %5 0\n%73 = OpConstant %5 1\n%77 = OpConstant %5 2\n%81 = OpConstant %5 3\n%85 = OpTypePointer StorageBuffer %12\n%88 = OpTypePointer StorageBuffer %6\n%92 = OpConstantComposite %6 %77 %77\n%94 = OpTypePointer StorageBuffer %17\n%100 = OpConstantComposite %6 %81 %81\n%108 = OpTypePointer StorageBuffer %23\n%114 = OpConstant %5 4\n%115 = OpConstantComposite %6 %114 %114\n%117 = OpTypePointer StorageBuffer %28\n%124 = OpConstant %5 5\n%125 = OpTypePointer StorageBuffer %33\n%132 = OpConstant %5 6\n%139 = OpConstant %5 7\n%140 = OpTypePointer StorageBuffer %38\n%147 = OpConstant %5 8\n%148 = OpTypePointer StorageBuffer %43\n%155 = OpConstant %5 9\n%156 = OpTypePointer StorageBuffer %48\n%163 = OpConstant %5 10\n%170 = OpConstant %5 11\n%171 = OpTypePointer StorageBuffer %53\n%180 = OpTypeBool\n%183 = OpConstant %5 1073741820\n%184 = OpTypePointer StorageBuffer %5\n%193 = OpConstant %5 536870911\n%196 = OpTypeVector %63 2\n%215 = OpTypeVector %5 3\n%217 = OpTypeVector %63 3\n%229 = OpConstant %5 268435455\n%230 = OpTypePointer StorageBuffer %21\n%364 = OpConstant %63 20\n%375 = OpConstant %63 30\n%384 = OpTypePointer Output %63\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %389\n%389 = OpLabel\n%68 = OpAccessChain %67 %62 %69\n%70 = OpLoad %59 %68\n%71 = OpBitcast %5 %70\n%72 = OpAccessChain %67 %62 %73\n%74 = OpLoad %59 %72\n%75 = OpBitcast %5 %74\n%76 = OpAccessChain %67 %62 %77\n%78 = OpLoad %59 %76\n%79 = OpBitcast %5 %78\n%80 = OpAccessChain %67 %62 %81\n%82 = OpLoad %59 %80\n%83 = OpBitcast %5 %82\n%84 = OpLoad %5 %58\n%86 = OpAccessChain %85 %15 %84\n%87 = OpGroupNonUniformBroadcastFirst %5 %81 %84\n%89 = OpAccessChain %88 %10 %69 %87\n%90 = OpLoad %6 %89\n%91 = OpShiftRightLogical %6 %90 %92\n%93 = OpIAdd %5 %84 %73\n%95 = OpAccessChain %94 %20 %93\n%96 = OpGroupNonUniformBroadcastFirst %5 %81 %93\n%97 = OpAccessChain %88 %10 %69 %96\n%98 = OpLoad %6 %97\n%99 = OpShiftRightLogical %6 %98 %100\n%101 = OpIAdd %5 %84 %77\n%102 = OpAccessChain %85 %15 %101\n%103 = OpGroupNonUniformBroadcastFirst %5 %81 %101\n%104 = OpAccessChain %88 %10 %69 %103\n%105 = OpLoad %6 %104\n%106 = OpShiftRightLogical %6 %105 %92\n%107 = OpIAdd %5 %84 %81\n%109 = OpAccessChain %108 %26 %107\n%110 = OpGroupNonUniformBroadcastFirst %5 %81 %107\n%111 = OpAccessChain %88 %10 %69 %110\n%112 = OpLoad %6 %111\n%113 = OpShiftRightLogical %6 %112 %115\n%116 = OpIAdd %5 %84 %114\n%118 = OpAccessChain %117 %31 %116\n%119 = OpGroupNonUniformBroadcastFirst %5 %81 %116\n%120 = OpAccessChain %88 %10 %69 %119\n%121 = OpLoad %6 %120\n%122 = OpShiftRightLogical %6 %121 %92\n%123 = OpIAdd %5 %84 %124\n%126 = OpAccessChain %125 %36 %123\n%127 = OpGroupNonUniformBroadcastFirst %5 %81 %123\n%128 = OpAccessChain %88 %10 %69 %127\n%129 = OpLoad %6 %128\n%130 = OpShiftRightLogical %6 %129 %100\n%131 = OpIAdd %5 %84 %132\n%133 = OpAccessChain %117 %31 %131\n%134 = OpGroupNonUniformBroadcastFirst %5 %81 %131\n%135 = OpAccessChain %88 %10 %69 %134\n%136 = OpLoad %6 %135\n%137 = OpShiftRightLogical %6 %136 %92\n%138 = OpIAdd %5 %84 %139\n%141 = OpAccessChain %140 %41 %138\n%142 = OpGroupNonUniformBroadcastFirst %5 %81 %138\n%143 = OpAccessChain %88 %10 %69 %142\n%144 = OpLoad %6 %143\n%145 = OpShiftRightLogical %6 %144 %115\n%146 = OpIAdd %5 %84 %147\n%149 = OpAccessChain %148 %46 %146\n%150 = OpGroupNonUniformBroadcastFirst %5 %81 %146\n%151 = OpAccessChain %88 %10 %69 %150\n%152 = OpLoad %6 %151\n%153 = OpShiftRightLogical %6 %152 %92\n%154 = OpIAdd %5 %84 %155\n%157 = OpAccessChain %156 %51 %154\n%158 = OpGroupNonUniformBroadcastFirst %5 %81 %154\n%159 = OpAccessChain %88 %10 %69 %158\n%160 = OpLoad %6 %159\n%161 = OpShiftRightLogical %6 %160 %100\n%162 = OpIAdd %5 %84 %163\n%164 = OpAccessChain %148 %46 %162\n%165 = OpGroupNonUniformBroadcastFirst %5 %81 %162\n%166 = OpAccessChain %88 %10 %69 %165\n%167 = OpLoad %6 %166\n%168 = OpShiftRightLogical %6 %167 %92\n%169 = OpIAdd %5 %84 %170\n%172 = OpAccessChain %171 %56 %169\n%173 = OpGroupNonUniformBroadcastFirst %5 %81 %169\n%174 = OpAccessChain %88 %10 %69 %173\n%175 = OpLoad %6 %174\n%176 = OpShiftRightLogical %6 %175 %115\n%177 = OpCompositeExtract %5 %91 0\n%178 = OpCompositeExtract %5 %91 1\n%179 = OpIAdd %5 %71 %177\n%181 = OpULessThan %180 %71 %178\n%182 = OpSelect %5 %181 %179 %183\n%185 = OpAccessChain %184 %86 %69 %182\n%186 = OpLoad %5 %185\n%187 = OpBitcast %63 %186\n%188 = OpCompositeExtract %5 %99 0\n%189 = OpCompositeExtract %5 %99 1\n%190 = OpIAdd %5 %75 %188\n%191 = OpULessThan %180 %75 %189\n%192 = OpSelect %5 %191 %190 %193\n%194 = OpAccessChain %88 %95 %69 %192\n%195 = OpLoad %6 %194\n%197 = OpBitcast %196 %195\n%198 = OpCompositeExtract %63 %197 0\n%199 = OpCompositeExtract %63 %197 1\n%200 = OpFAdd %63 %198 %187\n%201 = OpIMul %5 %79 %81\n%202 = OpCompositeExtract %5 %106 0\n%203 = OpCompositeExtract %5 %106 1\n%204 = OpIAdd %5 %201 %202\n%205 = OpULessThan %180 %201 %203\n%206 = OpSelect %5 %205 %204 %183\n%207 = OpAccessChain %184 %102 %69 %206\n%208 = OpLoad %5 %207\n%210 = OpIAdd %5 %206 %73\n%209 = OpAccessChain %184 %102 %69 %210\n%211 = OpLoad %5 %209\n%213 = OpIAdd %5 %206 %77\n%212 = OpAccessChain %184 %102 %69 %213\n%214 = OpLoad %5 %212\n%216 = OpCompositeConstruct %215 %208 %211 %214\n%218 = OpBitcast %217 %216\n%219 = OpCompositeExtract %63 %218 0\n%220 = OpCompositeExtract %63 %218 1\n%221 = OpCompositeExtract %63 %218 2\n%222 = OpFAdd %63 %200 %219\n%223 = OpFAdd %63 %220 %199\n%224 = OpCompositeExtract %5 %113 0\n%225 = OpCompositeExtract %5 %113 1\n%226 = OpIAdd %5 %83 %224\n%227 = OpULessThan %180 %83 %225\n%228 = OpSelect %5 %227 %226 %229\n%231 = OpAccessChain %230 %109 %69 %228\n%232 = OpLoad %21 %231\n%233 = OpBitcast %64 %232\n%234 = OpCompositeExtract %63 %233 0\n%235 = OpCompositeExtract %63 %233 1\n%236 = OpCompositeExtract %63 %233 2\n%237 = OpCompositeExtract %63 %233 3\n%238 = OpFAdd %63 %222 %234\n%239 = OpFAdd %63 %223 %235\n%240 = OpFAdd %63 %236 %221\n%241 = OpCompositeExtract %5 %122 0\n%242 = OpCompositeExtract %5 %122 1\n%243 = OpIAdd %5 %71 %241\n%244 = OpULessThan %180 %71 %242\n%245 = OpSelect %5 %244 %243 %183\n%246 = OpAccessChain %184 %118 %69 %245\n%247 = OpLoad %5 %246\n%248 = OpBitcast %63 %247\n%249 = OpFAdd %63 %238 %248\n%250 = OpCompositeExtract %5 %130 0\n%251 = OpCompositeExtract %5 %130 1\n%252 = OpIAdd %5 %75 %250\n%253 = OpULessThan %180 %75 %251\n%254 = OpSelect %5 %253 %252 %193\n%255 = OpAccessChain %88 %126 %69 %254\n%256 = OpLoad %6 %255\n%257 = OpBitcast %196 %256\n%258 = OpCompositeExtract %63 %257 0\n%259 = OpCompositeExtract %63 %257 1\n%260 = OpFAdd %63 %249 %258\n%261 = OpFAdd %63 %239 %259\n%262 = OpIMul %5 %79 %81\n%263 = OpCompositeExtract %5 %137 0\n%264 = OpCompositeExtract %5 %137 1\n%265 = OpIAdd %5 %262 %263\n%266 = OpULessThan %180 %262 %264\n%267 = OpSelect %5 %266 %265 %183\n%268 = OpAccessChain %184 %133 %69 %267\n%269 = OpLoad %5 %268\n%271 = OpIAdd %5 %267 %73\n%270 = OpAccessChain %184 %133 %69 %271\n%272 = OpLoad %5 %270\n%274 = OpIAdd %5 %267 %77\n%273 = OpAccessChain %184 %133 %69 %274\n%275 = OpLoad %5 %273\n%276 = OpCompositeConstruct %215 %269 %272 %275\n%277 = OpBitcast %217 %276\n%278 = OpCompositeExtract %63 %277 0\n%279 = OpCompositeExtract %63 %277 1\n%280 = OpCompositeExtract %63 %277 2\n%281 = OpFAdd %63 %260 %278\n%282 = OpFAdd %63 %261 %279\n%283 = OpFAdd %63 %240 %280\n%284 = OpCompositeExtract %5 %145 0\n%285 = OpCompositeExtract %5 %145 1\n%286 = OpIAdd %5 %83 %284\n%287 = OpULessThan %180 %83 %285\n%288 = OpSelect %5 %287 %286 %229\n%289 = OpAccessChain %230 %141 %69 %288\n%290 = OpLoad %21 %289\n%291 = OpBitcast %64 %290\n%292 = OpCompositeExtract %63 %291 0\n%293 = OpCompositeExtract %63 %291 1\n%294 = OpCompositeExtract %63 %291 2\n%295 = OpCompositeExtract %63 %291 3\n%296 = OpFAdd %63 %281 %292\n%297 = OpFAdd %63 %282 %293\n%298 = OpFAdd %63 %283 %294\n%299 = OpFAdd %63 %295 %237\n%300 = OpCompositeExtract %5 %153 0\n%301 = OpCompositeExtract %5 %153 1\n%302 = OpIAdd %5 %71 %300\n%303 = OpULessThan %180 %71 %301\n%304 = OpSelect %5 %303 %302 %183\n%305 = OpAccessChain %184 %149 %69 %304\n%306 = OpLoad %5 %305\n%307 = OpBitcast %63 %306\n%308 = OpFAdd %63 %296 %307\n%309 = OpCompositeExtract %5 %161 0\n%310 = OpCompositeExtract %5 %161 1\n%311 = OpIAdd %5 %75 %309\n%312 = OpULessThan %180 %75 %310\n%313 = OpSelect %5 %312 %311 %193\n%314 = OpAccessChain %88 %157 %69 %313\n%315 = OpLoad %6 %314\n%316 = OpBitcast %196 %315\n%317 = OpCompositeExtract %63 %316 0\n%318 = OpCompositeExtract %63 %316 1\n%319 = OpFAdd %63 %308 %317\n%320 = OpFAdd %63 %297 %318\n%321 = OpIMul %5 %79 %81\n%322 = OpCompositeExtract %5 %168 0\n%323 = OpCompositeExtract %5 %168 1\n%324 = OpIAdd %5 %321 %322\n%325 = OpULessThan %180 %321 %323\n%326 = OpSelect %5 %325 %324 %183\n%327 = OpAccessChain %184 %164 %69 %326\n%328 = OpLoad %5 %327\n%330 = OpIAdd %5 %326 %73\n%329 = OpAccessChain %184 %164 %69 %330\n%331 = OpLoad %5 %329\n%333 = OpIAdd %5 %326 %77\n%332 = OpAccessChain %184 %164 %69 %333\n%334 = OpLoad %5 %332\n%335 = OpCompositeConstruct %215 %328 %331 %334\n%336 = OpBitcast %217 %335\n%337 = OpCompositeExtract %63 %336 0\n%338 = OpCompositeExtract %63 %336 1\n%339 = OpCompositeExtract %63 %336 2\n%340 = OpFAdd %63 %319 %337\n%341 = OpFAdd %63 %320 %338\n%342 = OpFAdd %63 %298 %339\n%343 = OpCompositeExtract %5 %176 0\n%344 = OpCompositeExtract %5 %176 1\n%345 = OpIAdd %5 %83 %343\n%346 = OpULessThan %180 %83 %344\n%347 = OpSelect %5 %346 %345 %229\n%348 = OpAccessChain %230 %172 %69 %347\n%349 = OpLoad %21 %348\n%350 = OpBitcast %64 %349\n%351 = OpCompositeExtract %63 %350 0\n%352 = OpCompositeExtract %63 %350 1\n%353 = OpCompositeExtract %63 %350 2\n%354 = OpCompositeExtract %63 %350 3\n%355 = OpFAdd %63 %340 %351\n%356 = OpFAdd %63 %341 %352\n%357 = OpFAdd %63 %342 %353\n%358 = OpFAdd %63 %299 %354\n%359 = OpCompositeExtract %5 %130 0\n%360 = OpCompositeExtract %5 %130 1\n%361 = OpIAdd %5 %71 %359\n%362 = OpULessThan %180 %71 %360\n%363 = OpSelect %5 %362 %361 %193\n%365 = OpBitcast %5 %364\n%366 = OpBitcast %5 %364\n%367 = OpCompositeConstruct %6 %365 %366\n%368 = OpAccessChain %88 %126 %69 %363\nOpStore %368 %367\n%369 = OpIMul %5 %75 %81\n%370 = OpCompositeExtract %5 %168 0\n%371 = OpCompositeExtract %5 %168 1\n%372 = OpIAdd %5 %369 %370\n%373 = OpULessThan %180 %369 %371\n%374 = OpSelect %5 %373 %372 %183\n%376 = OpBitcast %5 %375\n%377 = OpBitcast %5 %375\n%378 = OpBitcast %5 %375\n%379 = OpAccessChain %184 %164 %69 %374\nOpStore %379 %376\n%381 = OpIAdd %5 %374 %73\n%380 = OpAccessChain %184 %164 %69 %381\nOpStore %380 %377\n%383 = OpIAdd %5 %374 %77\n%382 = OpAccessChain %184 %164 %69 %383\nOpStore %382 %378\n%385 = OpAccessChain %384 %66 %69\nOpStore %385 %355\n%386 = OpAccessChain %384 %66 %73\nOpStore %386 %356\n%387 = OpAccessChain %384 %66 %77\nOpStore %387 %357\n%388 = OpAccessChain %384 %66 %81\nOpStore %388 %358\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/sm66/structured-buffer-heap.typed-buffer-offset.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _17[];\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _21[];\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _24[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 1) flat in ivec4 UV;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _39 = uint(UV.x);\n    uint _43 = uint(UV.y);\n    uint _47 = uint(UV.z);\n    uint _51 = uint(UV.w);\n    uint _56 = subgroupBroadcastFirst(INDEX);\n    uint _60 = INDEX + 1u;\n    uint _63 = subgroupBroadcastFirst(_60);\n    uint _66 = INDEX + 2u;\n    uint _69 = subgroupBroadcastFirst(_66);\n    uint _72 = INDEX + 3u;\n    uint _75 = subgroupBroadcastFirst(_72);\n    uint _78 = INDEX + 4u;\n    uint _83 = subgroupBroadcastFirst(_78);\n    uint _86 = INDEX + 5u;\n    uint _90 = subgroupBroadcastFirst(_86);\n    uint _93 = INDEX + 6u;\n    uint _97 = subgroupBroadcastFirst(_93);\n    uint _100 = INDEX + 7u;\n    uint _104 = subgroupBroadcastFirst(_100);\n    uint _107 = INDEX + 8u;\n    uint _111 = subgroupBroadcastFirst(_107);\n    uint _114 = INDEX + 9u;\n    uint _118 = subgroupBroadcastFirst(_114);\n    uint _121 = INDEX + 10u;\n    uint _125 = subgroupBroadcastFirst(_121);\n    uint _128 = INDEX + 11u;\n    uint _132 = subgroupBroadcastFirst(_128);\n    uint _146 = _43 * 2u;\n    uint _151 = (_146 < _13._m0[_63].y) ? (_146 + _13._m0[_63].x) : 1073741820u;\n    vec2 _159 = uintBitsToFloat(uvec2(texelFetch(_17[_60], int(_151)).x, texelFetch(_17[_60], int(_151 + 1u)).x));\n    uint _163 = _47 * 3u;\n    uint _168 = (_163 < _13._m0[_69].y) ? (_163 + _13._m0[_69].x) : 1073741820u;\n    vec3 _180 = uintBitsToFloat(uvec3(texelFetch(_17[_66], int(_168)).x, texelFetch(_17[_66], int(_168 + 1u)).x, texelFetch(_17[_66], int(_168 + 2u)).x));\n    uint _186 = _51 * 4u;\n    uint _191 = (_186 < _13._m0[_75].y) ? (_186 + _13._m0[_75].x) : 1073741820u;\n    vec4 _204 = uintBitsToFloat(uvec4(texelFetch(_17[_72], int(_191)).x, texelFetch(_17[_72], int(_191 + 1u)).x, texelFetch(_17[_72], int(_191 + 2u)).x, texelFetch(_17[_72], int(_191 + 3u)).x));\n    uvec4 _217 = imageLoad(_21[_78], int((_39 < _13._m0[_83].y) ? (_39 + _13._m0[_83].x) : 1073741820u));\n    uint _221 = _43 * 2u;\n    uint _226 = (_221 < _13._m0[_90].y) ? (_221 + _13._m0[_90].x) : 1073741820u;\n    vec2 _233 = uintBitsToFloat(uvec2(imageLoad(_21[_86], int(_226)).x, imageLoad(_21[_86], int(_226 + 1u)).x));\n    uint _238 = _47 * 3u;\n    uint _243 = (_238 < _13._m0[_97].y) ? (_238 + _13._m0[_97].x) : 1073741820u;\n    uvec4 _244 = imageLoad(_21[_93], int(_243));\n    uvec4 _246 = imageLoad(_21[_93], int(_243 + 1u));\n    uvec4 _249 = imageLoad(_21[_93], int(_243 + 2u));\n    vec3 _253 = uintBitsToFloat(uvec3(_244.x, _246.x, _249.x));\n    uint _260 = _51 * 4u;\n    uint _265 = (_260 < _13._m0[_104].y) ? (_260 + _13._m0[_104].x) : 1073741820u;\n    uvec4 _266 = imageLoad(_21[_100], int(_265));\n    uvec4 _268 = imageLoad(_21[_100], int(_265 + 1u));\n    uvec4 _271 = imageLoad(_21[_100], int(_265 + 2u));\n    uvec4 _274 = imageLoad(_21[_100], int(_265 + 3u));\n    vec4 _278 = uintBitsToFloat(uvec4(_266.x, _268.x, _271.x, _274.x));\n    uvec4 _292 = imageLoad(_24[_107], int((_39 < _13._m0[_111].y) ? (_39 + _13._m0[_111].x) : 1073741820u));\n    uint _296 = _43 * 2u;\n    uint _301 = (_296 < _13._m0[_118].y) ? (_296 + _13._m0[_118].x) : 1073741820u;\n    uvec4 _302 = imageLoad(_24[_114], int(_301));\n    uvec4 _304 = imageLoad(_24[_114], int(_301 + 1u));\n    vec2 _308 = uintBitsToFloat(uvec2(_302.x, _304.x));\n    uint _313 = _47 * 3u;\n    uint _318 = (_313 < _13._m0[_125].y) ? (_313 + _13._m0[_125].x) : 1073741820u;\n    uvec4 _319 = imageLoad(_24[_121], int(_318));\n    uvec4 _321 = imageLoad(_24[_121], int(_318 + 1u));\n    uvec4 _324 = imageLoad(_24[_121], int(_318 + 2u));\n    vec3 _328 = uintBitsToFloat(uvec3(_319.x, _321.x, _324.x));\n    uint _335 = _51 * 4u;\n    uint _340 = (_335 < _13._m0[_132].y) ? (_335 + _13._m0[_132].x) : 1073741820u;\n    uvec4 _341 = imageLoad(_24[_128], int(_340));\n    uvec4 _343 = imageLoad(_24[_128], int(_340 + 1u));\n    uvec4 _346 = imageLoad(_24[_128], int(_340 + 2u));\n    uvec4 _349 = imageLoad(_24[_128], int(_340 + 3u));\n    vec4 _353 = uintBitsToFloat(uvec4(_341.x, _343.x, _346.x, _349.x));\n    uint _362 = _39 * 2u;\n    uint _367 = (_362 < _13._m0[_90].y) ? (_362 + _13._m0[_90].x) : 1073741820u;\n    imageStore(_21[_86], int(_367), uvec4(floatBitsToUint(20.0)));\n    imageStore(_21[_86], int(_367 + 1u), uvec4(floatBitsToUint(20.0)));\n    uint _374 = _43 * 3u;\n    uint _379 = (_374 < _13._m0[_125].y) ? (_374 + _13._m0[_125].x) : 1073741820u;\n    imageStore(_24[_121], int(_379), uvec4(floatBitsToUint(30.0)));\n    imageStore(_24[_121], int(_379 + 1u), uvec4(floatBitsToUint(30.0)));\n    imageStore(_24[_121], int(_379 + 2u), uvec4(floatBitsToUint(30.0)));\n    SV_Target.x = ((((((((((_159.x + uintBitsToFloat(texelFetch(_17[INDEX], int((_39 < _13._m0[_56].y) ? (_39 + _13._m0[_56].x) : 1073741820u)).x)) + _180.x) + _204.x) + uintBitsToFloat(_217.x)) + _233.x) + _253.x) + _278.x) + uintBitsToFloat(_292.x)) + _308.x) + _328.x) + _353.x;\n    SV_Target.y = (((((((_180.y + _159.y) + _204.y) + _233.y) + _253.y) + _278.y) + _308.y) + _328.y) + _353.y;\n    SV_Target.z = ((((_204.z + _180.z) + _253.z) + _278.z) + _328.z) + _353.z;\n    SV_Target.w = (_278.w + _204.w) + _353.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 396\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %26 %30 %34\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %26 \"INDEX\"\nOpName %30 \"UV\"\nOpName %34 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 Coherent\nOpDecorate %26 Flat\nOpDecorate %26 Location 0\nOpDecorate %30 Flat\nOpDecorate %30 Location 1\nOpDecorate %34 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeRuntimeArray %18\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypePointer Input %5\n%26 = OpVariable %25 Input\n%27 = OpTypeInt 32 1\n%28 = OpTypeVector %27 4\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%31 = OpTypeFloat 32\n%32 = OpTypeVector %31 4\n%33 = OpTypePointer Output %32\n%34 = OpVariable %33 Output\n%35 = OpTypePointer Input %27\n%37 = OpConstant %5 0\n%41 = OpConstant %5 1\n%45 = OpConstant %5 2\n%49 = OpConstant %5 3\n%53 = OpTypePointer UniformConstant %14\n%57 = OpTypePointer StorageBuffer %9\n%79 = OpConstant %5 4\n%80 = OpTypePointer UniformConstant %18\n%87 = OpConstant %5 5\n%94 = OpConstant %5 6\n%101 = OpConstant %5 7\n%108 = OpConstant %5 8\n%115 = OpConstant %5 9\n%122 = OpConstant %5 10\n%129 = OpConstant %5 11\n%138 = OpTypeBool\n%141 = OpConstant %5 1073741820\n%142 = OpTypeVector %5 4\n%158 = OpTypeVector %31 2\n%177 = OpTypeVector %5 3\n%179 = OpTypeVector %31 3\n%368 = OpConstant %31 20\n%380 = OpConstant %31 30\n%389 = OpTypePointer Output %31\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %394\n%394 = OpLabel\n%36 = OpAccessChain %35 %30 %37\n%38 = OpLoad %27 %36\n%39 = OpBitcast %5 %38\n%40 = OpAccessChain %35 %30 %41\n%42 = OpLoad %27 %40\n%43 = OpBitcast %5 %42\n%44 = OpAccessChain %35 %30 %45\n%46 = OpLoad %27 %44\n%47 = OpBitcast %5 %46\n%48 = OpAccessChain %35 %30 %49\n%50 = OpLoad %27 %48\n%51 = OpBitcast %5 %50\n%52 = OpLoad %5 %26\n%54 = OpAccessChain %53 %17 %52\n%55 = OpLoad %14 %54\n%56 = OpGroupNonUniformBroadcastFirst %5 %49 %52\n%58 = OpAccessChain %57 %13 %37 %56\n%59 = OpLoad %9 %58\n%60 = OpIAdd %5 %52 %41\n%61 = OpAccessChain %53 %17 %60\n%62 = OpLoad %14 %61\n%63 = OpGroupNonUniformBroadcastFirst %5 %49 %60\n%64 = OpAccessChain %57 %13 %37 %63\n%65 = OpLoad %9 %64\n%66 = OpIAdd %5 %52 %45\n%67 = OpAccessChain %53 %17 %66\n%68 = OpLoad %14 %67\n%69 = OpGroupNonUniformBroadcastFirst %5 %49 %66\n%70 = OpAccessChain %57 %13 %37 %69\n%71 = OpLoad %9 %70\n%72 = OpIAdd %5 %52 %49\n%73 = OpAccessChain %53 %17 %72\n%74 = OpLoad %14 %73\n%75 = OpGroupNonUniformBroadcastFirst %5 %49 %72\n%76 = OpAccessChain %57 %13 %37 %75\n%77 = OpLoad %9 %76\n%78 = OpIAdd %5 %52 %79\n%81 = OpAccessChain %80 %21 %78\n%82 = OpLoad %18 %81\n%83 = OpGroupNonUniformBroadcastFirst %5 %49 %78\n%84 = OpAccessChain %57 %13 %37 %83\n%85 = OpLoad %9 %84\n%86 = OpIAdd %5 %52 %87\n%88 = OpAccessChain %80 %21 %86\n%89 = OpLoad %18 %88\n%90 = OpGroupNonUniformBroadcastFirst %5 %49 %86\n%91 = OpAccessChain %57 %13 %37 %90\n%92 = OpLoad %9 %91\n%93 = OpIAdd %5 %52 %94\n%95 = OpAccessChain %80 %21 %93\n%96 = OpLoad %18 %95\n%97 = OpGroupNonUniformBroadcastFirst %5 %49 %93\n%98 = OpAccessChain %57 %13 %37 %97\n%99 = OpLoad %9 %98\n%100 = OpIAdd %5 %52 %101\n%102 = OpAccessChain %80 %21 %100\n%103 = OpLoad %18 %102\n%104 = OpGroupNonUniformBroadcastFirst %5 %49 %100\n%105 = OpAccessChain %57 %13 %37 %104\n%106 = OpLoad %9 %105\n%107 = OpIAdd %5 %52 %108\n%109 = OpAccessChain %80 %24 %107\n%110 = OpLoad %18 %109\n%111 = OpGroupNonUniformBroadcastFirst %5 %49 %107\n%112 = OpAccessChain %57 %13 %37 %111\n%113 = OpLoad %9 %112\n%114 = OpIAdd %5 %52 %115\n%116 = OpAccessChain %80 %24 %114\n%117 = OpLoad %18 %116\n%118 = OpGroupNonUniformBroadcastFirst %5 %49 %114\n%119 = OpAccessChain %57 %13 %37 %118\n%120 = OpLoad %9 %119\n%121 = OpIAdd %5 %52 %122\n%123 = OpAccessChain %80 %24 %121\n%124 = OpLoad %18 %123\n%125 = OpGroupNonUniformBroadcastFirst %5 %49 %121\n%126 = OpAccessChain %57 %13 %37 %125\n%127 = OpLoad %9 %126\n%128 = OpIAdd %5 %52 %129\n%130 = OpAccessChain %80 %24 %128\n%131 = OpLoad %18 %130\n%132 = OpGroupNonUniformBroadcastFirst %5 %49 %128\n%133 = OpAccessChain %57 %13 %37 %132\n%134 = OpLoad %9 %133\n%135 = OpCompositeExtract %5 %59 0\n%136 = OpCompositeExtract %5 %59 1\n%137 = OpIAdd %5 %39 %135\n%139 = OpULessThan %138 %39 %136\n%140 = OpSelect %5 %139 %137 %141\n%143 = OpImageFetch %142 %55 %140\n%144 = OpCompositeExtract %5 %143 0\n%145 = OpBitcast %31 %144\n%146 = OpIMul %5 %43 %45\n%147 = OpCompositeExtract %5 %65 0\n%148 = OpCompositeExtract %5 %65 1\n%149 = OpIAdd %5 %146 %147\n%150 = OpULessThan %138 %146 %148\n%151 = OpSelect %5 %150 %149 %141\n%152 = OpImageFetch %142 %62 %151\n%153 = OpCompositeExtract %5 %152 0\n%155 = OpIAdd %5 %151 %41\n%154 = OpImageFetch %142 %62 %155\n%156 = OpCompositeExtract %5 %154 0\n%157 = OpCompositeConstruct %9 %153 %156\n%159 = OpBitcast %158 %157\n%160 = OpCompositeExtract %31 %159 0\n%161 = OpCompositeExtract %31 %159 1\n%162 = OpFAdd %31 %160 %145\n%163 = OpIMul %5 %47 %49\n%164 = OpCompositeExtract %5 %71 0\n%165 = OpCompositeExtract %5 %71 1\n%166 = OpIAdd %5 %163 %164\n%167 = OpULessThan %138 %163 %165\n%168 = OpSelect %5 %167 %166 %141\n%169 = OpImageFetch %142 %68 %168\n%170 = OpCompositeExtract %5 %169 0\n%172 = OpIAdd %5 %168 %41\n%171 = OpImageFetch %142 %68 %172\n%173 = OpCompositeExtract %5 %171 0\n%175 = OpIAdd %5 %168 %45\n%174 = OpImageFetch %142 %68 %175\n%176 = OpCompositeExtract %5 %174 0\n%178 = OpCompositeConstruct %177 %170 %173 %176\n%180 = OpBitcast %179 %178\n%181 = OpCompositeExtract %31 %180 0\n%182 = OpCompositeExtract %31 %180 1\n%183 = OpCompositeExtract %31 %180 2\n%184 = OpFAdd %31 %162 %181\n%185 = OpFAdd %31 %182 %161\n%186 = OpIMul %5 %51 %79\n%187 = OpCompositeExtract %5 %77 0\n%188 = OpCompositeExtract %5 %77 1\n%189 = OpIAdd %5 %186 %187\n%190 = OpULessThan %138 %186 %188\n%191 = OpSelect %5 %190 %189 %141\n%192 = OpImageFetch %142 %74 %191\n%193 = OpCompositeExtract %5 %192 0\n%195 = OpIAdd %5 %191 %41\n%194 = OpImageFetch %142 %74 %195\n%196 = OpCompositeExtract %5 %194 0\n%198 = OpIAdd %5 %191 %45\n%197 = OpImageFetch %142 %74 %198\n%199 = OpCompositeExtract %5 %197 0\n%201 = OpIAdd %5 %191 %49\n%200 = OpImageFetch %142 %74 %201\n%202 = OpCompositeExtract %5 %200 0\n%203 = OpCompositeConstruct %142 %193 %196 %199 %202\n%204 = OpBitcast %32 %203\n%205 = OpCompositeExtract %31 %204 0\n%206 = OpCompositeExtract %31 %204 1\n%207 = OpCompositeExtract %31 %204 2\n%208 = OpCompositeExtract %31 %204 3\n%209 = OpFAdd %31 %184 %205\n%210 = OpFAdd %31 %185 %206\n%211 = OpFAdd %31 %207 %183\n%212 = OpCompositeExtract %5 %85 0\n%213 = OpCompositeExtract %5 %85 1\n%214 = OpIAdd %5 %39 %212\n%215 = OpULessThan %138 %39 %213\n%216 = OpSelect %5 %215 %214 %141\n%217 = OpImageRead %142 %82 %216\n%218 = OpCompositeExtract %5 %217 0\n%219 = OpBitcast %31 %218\n%220 = OpFAdd %31 %209 %219\n%221 = OpIMul %5 %43 %45\n%222 = OpCompositeExtract %5 %92 0\n%223 = OpCompositeExtract %5 %92 1\n%224 = OpIAdd %5 %221 %222\n%225 = OpULessThan %138 %221 %223\n%226 = OpSelect %5 %225 %224 %141\n%227 = OpImageRead %142 %89 %226\n%228 = OpCompositeExtract %5 %227 0\n%230 = OpIAdd %5 %226 %41\n%229 = OpImageRead %142 %89 %230\n%231 = OpCompositeExtract %5 %229 0\n%232 = OpCompositeConstruct %9 %228 %231\n%233 = OpBitcast %158 %232\n%234 = OpCompositeExtract %31 %233 0\n%235 = OpCompositeExtract %31 %233 1\n%236 = OpFAdd %31 %220 %234\n%237 = OpFAdd %31 %210 %235\n%238 = OpIMul %5 %47 %49\n%239 = OpCompositeExtract %5 %99 0\n%240 = OpCompositeExtract %5 %99 1\n%241 = OpIAdd %5 %238 %239\n%242 = OpULessThan %138 %238 %240\n%243 = OpSelect %5 %242 %241 %141\n%244 = OpImageRead %142 %96 %243\n%245 = OpCompositeExtract %5 %244 0\n%247 = OpIAdd %5 %243 %41\n%246 = OpImageRead %142 %96 %247\n%248 = OpCompositeExtract %5 %246 0\n%250 = OpIAdd %5 %243 %45\n%249 = OpImageRead %142 %96 %250\n%251 = OpCompositeExtract %5 %249 0\n%252 = OpCompositeConstruct %177 %245 %248 %251\n%253 = OpBitcast %179 %252\n%254 = OpCompositeExtract %31 %253 0\n%255 = OpCompositeExtract %31 %253 1\n%256 = OpCompositeExtract %31 %253 2\n%257 = OpFAdd %31 %236 %254\n%258 = OpFAdd %31 %237 %255\n%259 = OpFAdd %31 %211 %256\n%260 = OpIMul %5 %51 %79\n%261 = OpCompositeExtract %5 %106 0\n%262 = OpCompositeExtract %5 %106 1\n%263 = OpIAdd %5 %260 %261\n%264 = OpULessThan %138 %260 %262\n%265 = OpSelect %5 %264 %263 %141\n%266 = OpImageRead %142 %103 %265\n%267 = OpCompositeExtract %5 %266 0\n%269 = OpIAdd %5 %265 %41\n%268 = OpImageRead %142 %103 %269\n%270 = OpCompositeExtract %5 %268 0\n%272 = OpIAdd %5 %265 %45\n%271 = OpImageRead %142 %103 %272\n%273 = OpCompositeExtract %5 %271 0\n%275 = OpIAdd %5 %265 %49\n%274 = OpImageRead %142 %103 %275\n%276 = OpCompositeExtract %5 %274 0\n%277 = OpCompositeConstruct %142 %267 %270 %273 %276\n%278 = OpBitcast %32 %277\n%279 = OpCompositeExtract %31 %278 0\n%280 = OpCompositeExtract %31 %278 1\n%281 = OpCompositeExtract %31 %278 2\n%282 = OpCompositeExtract %31 %278 3\n%283 = OpFAdd %31 %257 %279\n%284 = OpFAdd %31 %258 %280\n%285 = OpFAdd %31 %259 %281\n%286 = OpFAdd %31 %282 %208\n%287 = OpCompositeExtract %5 %113 0\n%288 = OpCompositeExtract %5 %113 1\n%289 = OpIAdd %5 %39 %287\n%290 = OpULessThan %138 %39 %288\n%291 = OpSelect %5 %290 %289 %141\n%292 = OpImageRead %142 %110 %291\n%293 = OpCompositeExtract %5 %292 0\n%294 = OpBitcast %31 %293\n%295 = OpFAdd %31 %283 %294\n%296 = OpIMul %5 %43 %45\n%297 = OpCompositeExtract %5 %120 0\n%298 = OpCompositeExtract %5 %120 1\n%299 = OpIAdd %5 %296 %297\n%300 = OpULessThan %138 %296 %298\n%301 = OpSelect %5 %300 %299 %141\n%302 = OpImageRead %142 %117 %301\n%303 = OpCompositeExtract %5 %302 0\n%305 = OpIAdd %5 %301 %41\n%304 = OpImageRead %142 %117 %305\n%306 = OpCompositeExtract %5 %304 0\n%307 = OpCompositeConstruct %9 %303 %306\n%308 = OpBitcast %158 %307\n%309 = OpCompositeExtract %31 %308 0\n%310 = OpCompositeExtract %31 %308 1\n%311 = OpFAdd %31 %295 %309\n%312 = OpFAdd %31 %284 %310\n%313 = OpIMul %5 %47 %49\n%314 = OpCompositeExtract %5 %127 0\n%315 = OpCompositeExtract %5 %127 1\n%316 = OpIAdd %5 %313 %314\n%317 = OpULessThan %138 %313 %315\n%318 = OpSelect %5 %317 %316 %141\n%319 = OpImageRead %142 %124 %318\n%320 = OpCompositeExtract %5 %319 0\n%322 = OpIAdd %5 %318 %41\n%321 = OpImageRead %142 %124 %322\n%323 = OpCompositeExtract %5 %321 0\n%325 = OpIAdd %5 %318 %45\n%324 = OpImageRead %142 %124 %325\n%326 = OpCompositeExtract %5 %324 0\n%327 = OpCompositeConstruct %177 %320 %323 %326\n%328 = OpBitcast %179 %327\n%329 = OpCompositeExtract %31 %328 0\n%330 = OpCompositeExtract %31 %328 1\n%331 = OpCompositeExtract %31 %328 2\n%332 = OpFAdd %31 %311 %329\n%333 = OpFAdd %31 %312 %330\n%334 = OpFAdd %31 %285 %331\n%335 = OpIMul %5 %51 %79\n%336 = OpCompositeExtract %5 %134 0\n%337 = OpCompositeExtract %5 %134 1\n%338 = OpIAdd %5 %335 %336\n%339 = OpULessThan %138 %335 %337\n%340 = OpSelect %5 %339 %338 %141\n%341 = OpImageRead %142 %131 %340\n%342 = OpCompositeExtract %5 %341 0\n%344 = OpIAdd %5 %340 %41\n%343 = OpImageRead %142 %131 %344\n%345 = OpCompositeExtract %5 %343 0\n%347 = OpIAdd %5 %340 %45\n%346 = OpImageRead %142 %131 %347\n%348 = OpCompositeExtract %5 %346 0\n%350 = OpIAdd %5 %340 %49\n%349 = OpImageRead %142 %131 %350\n%351 = OpCompositeExtract %5 %349 0\n%352 = OpCompositeConstruct %142 %342 %345 %348 %351\n%353 = OpBitcast %32 %352\n%354 = OpCompositeExtract %31 %353 0\n%355 = OpCompositeExtract %31 %353 1\n%356 = OpCompositeExtract %31 %353 2\n%357 = OpCompositeExtract %31 %353 3\n%358 = OpFAdd %31 %332 %354\n%359 = OpFAdd %31 %333 %355\n%360 = OpFAdd %31 %334 %356\n%361 = OpFAdd %31 %286 %357\n%362 = OpIMul %5 %39 %45\n%363 = OpCompositeExtract %5 %92 0\n%364 = OpCompositeExtract %5 %92 1\n%365 = OpIAdd %5 %362 %363\n%366 = OpULessThan %138 %362 %364\n%367 = OpSelect %5 %366 %365 %141\n%369 = OpBitcast %5 %368\n%370 = OpBitcast %5 %368\n%371 = OpCompositeConstruct %142 %369 %369 %369 %369\nOpImageWrite %89 %367 %371\n%372 = OpCompositeConstruct %142 %370 %370 %370 %370\n%373 = OpIAdd %5 %367 %41\nOpImageWrite %89 %373 %372\n%374 = OpIMul %5 %43 %49\n%375 = OpCompositeExtract %5 %127 0\n%376 = OpCompositeExtract %5 %127 1\n%377 = OpIAdd %5 %374 %375\n%378 = OpULessThan %138 %374 %376\n%379 = OpSelect %5 %378 %377 %141\n%381 = OpBitcast %5 %380\n%382 = OpBitcast %5 %380\n%383 = OpBitcast %5 %380\n%384 = OpCompositeConstruct %142 %381 %381 %381 %381\nOpImageWrite %124 %379 %384\n%385 = OpCompositeConstruct %142 %382 %382 %382 %382\n%386 = OpIAdd %5 %379 %41\nOpImageWrite %124 %386 %385\n%387 = OpCompositeConstruct %142 %383 %383 %383 %383\n%388 = OpIAdd %5 %379 %45\nOpImageWrite %124 %388 %387\n%390 = OpAccessChain %389 %34 %37\nOpStore %390 %358\n%391 = OpAccessChain %389 %34 %41\nOpStore %391 %359\n%392 = OpAccessChain %389 %34 %45\nOpStore %392 %360\n%393 = OpAccessChain %389 %34 %49\nOpStore %393 %361\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-raw-buffer-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _19 = INDEX + 0u;\n    uint _24 = INDEX * 4u;\n    uvec4 _40 = uvec4(texelFetch(_9[nonuniformEXT(_19)], int(_24)).x, texelFetch(_9[nonuniformEXT(_19)], int(_24 + 1u)).x, texelFetch(_9[nonuniformEXT(_19)], int(_24 + 2u)).x, texelFetch(_9[nonuniformEXT(_19)], int(_24 + 3u)).x);\n    SV_Target.x = uintBitsToFloat(_40.x);\n    SV_Target.y = uintBitsToFloat(_40.y);\n    SV_Target.z = uintBitsToFloat(_40.z);\n    SV_Target.w = uintBitsToFloat(_40.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\nOpDecorate %19 NonUniform\nOpDecorate %23 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 4\n%20 = OpConstant %5 0\n%21 = OpTypePointer UniformConstant %6\n%25 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%34 = OpConstant %5 2\n%38 = OpConstant %5 3\n%49 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpShiftLeftLogical %5 %16 %18\n%19 = OpIAdd %5 %16 %20\n%22 = OpAccessChain %21 %9 %19\n%23 = OpLoad %6 %22\n%24 = OpIMul %5 %16 %18\n%26 = OpImageFetch %25 %23 %24\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpIAdd %5 %24 %30\n%28 = OpImageFetch %25 %23 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %24 %34\n%32 = OpImageFetch %25 %23 %33\n%35 = OpCompositeExtract %5 %32 0\n%37 = OpIAdd %5 %24 %38\n%36 = OpImageFetch %25 %23 %37\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeConstruct %25 %27 %31 %35 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpBitcast %12 %41\n%46 = OpBitcast %12 %42\n%47 = OpBitcast %12 %43\n%48 = OpBitcast %12 %44\n%50 = OpAccessChain %49 %15 %20\nOpStore %50 %45\n%51 = OpAccessChain %49 %15 %30\nOpStore %51 %46\n%52 = OpAccessChain %49 %15 %34\nOpStore %52 %47\n%53 = OpAccessChain %49 %15 %38\nOpStore %53 %48\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-raw-buffer.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _19 = INDEX + 0u;\n    uint _24 = INDEX * 4u;\n    uvec4 _40 = uvec4(texelFetch(_9[_19], int(_24)).x, texelFetch(_9[_19], int(_24 + 1u)).x, texelFetch(_9[_19], int(_24 + 2u)).x, texelFetch(_9[_19], int(_24 + 3u)).x);\n    SV_Target.x = uintBitsToFloat(_40.x);\n    SV_Target.y = uintBitsToFloat(_40.y);\n    SV_Target.z = uintBitsToFloat(_40.z);\n    SV_Target.w = uintBitsToFloat(_40.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 4\n%20 = OpConstant %5 0\n%21 = OpTypePointer UniformConstant %6\n%25 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%34 = OpConstant %5 2\n%38 = OpConstant %5 3\n%49 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpShiftLeftLogical %5 %16 %18\n%19 = OpIAdd %5 %16 %20\n%22 = OpAccessChain %21 %9 %19\n%23 = OpLoad %6 %22\n%24 = OpIMul %5 %16 %18\n%26 = OpImageFetch %25 %23 %24\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpIAdd %5 %24 %30\n%28 = OpImageFetch %25 %23 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %24 %34\n%32 = OpImageFetch %25 %23 %33\n%35 = OpCompositeExtract %5 %32 0\n%37 = OpIAdd %5 %24 %38\n%36 = OpImageFetch %25 %23 %37\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeConstruct %25 %27 %31 %35 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpBitcast %12 %41\n%46 = OpBitcast %12 %42\n%47 = OpBitcast %12 %43\n%48 = OpBitcast %12 %44\n%50 = OpAccessChain %49 %15 %20\nOpStore %50 %45\n%51 = OpAccessChain %49 %15 %30\nOpStore %51 %46\n%52 = OpAccessChain %49 %15 %34\nOpStore %52 %47\n%53 = OpAccessChain %49 %15 %38\nOpStore %53 %48\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-structured-buffer-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _17 = INDEX + 0u;\n    uint _22 = INDEX * 4u;\n    vec4 _40 = uintBitsToFloat(uvec4(texelFetch(_9[nonuniformEXT(_17)], int(_22)).x, texelFetch(_9[nonuniformEXT(_17)], int(_22 + 1u)).x, texelFetch(_9[nonuniformEXT(_17)], int(_22 + 2u)).x, texelFetch(_9[nonuniformEXT(_17)], int(_22 + 3u)).x));\n    SV_Target.x = _40.x;\n    SV_Target.y = _40.y;\n    SV_Target.z = _40.z;\n    SV_Target.w = _40.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\nOpDecorate %17 NonUniform\nOpDecorate %21 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 0\n%19 = OpTypePointer UniformConstant %6\n%23 = OpConstant %5 4\n%24 = OpTypeVector %5 4\n%29 = OpConstant %5 1\n%33 = OpConstant %5 2\n%37 = OpConstant %5 3\n%45 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpIAdd %5 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpIMul %5 %16 %23\n%25 = OpImageFetch %24 %21 %22\n%26 = OpCompositeExtract %5 %25 0\n%28 = OpIAdd %5 %22 %29\n%27 = OpImageFetch %24 %21 %28\n%30 = OpCompositeExtract %5 %27 0\n%32 = OpIAdd %5 %22 %33\n%31 = OpImageFetch %24 %21 %32\n%34 = OpCompositeExtract %5 %31 0\n%36 = OpIAdd %5 %22 %37\n%35 = OpImageFetch %24 %21 %36\n%38 = OpCompositeExtract %5 %35 0\n%39 = OpCompositeConstruct %24 %26 %30 %34 %38\n%40 = OpBitcast %13 %39\n%41 = OpCompositeExtract %12 %40 0\n%42 = OpCompositeExtract %12 %40 1\n%43 = OpCompositeExtract %12 %40 2\n%44 = OpCompositeExtract %12 %40 3\n%46 = OpAccessChain %45 %15 %18\nOpStore %46 %41\n%47 = OpAccessChain %45 %15 %29\nOpStore %47 %42\n%48 = OpAccessChain %45 %15 %33\nOpStore %48 %43\n%49 = OpAccessChain %45 %15 %37\nOpStore %49 %44\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-structured-buffer.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _17 = INDEX + 0u;\n    uint _22 = INDEX * 4u;\n    vec4 _40 = uintBitsToFloat(uvec4(texelFetch(_9[_17], int(_22)).x, texelFetch(_9[_17], int(_22 + 1u)).x, texelFetch(_9[_17], int(_22 + 2u)).x, texelFetch(_9[_17], int(_22 + 3u)).x));\n    SV_Target.x = _40.x;\n    SV_Target.y = _40.y;\n    SV_Target.z = _40.z;\n    SV_Target.w = _40.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 0\n%19 = OpTypePointer UniformConstant %6\n%23 = OpConstant %5 4\n%24 = OpTypeVector %5 4\n%29 = OpConstant %5 1\n%33 = OpConstant %5 2\n%37 = OpConstant %5 3\n%45 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpIAdd %5 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpIMul %5 %16 %23\n%25 = OpImageFetch %24 %21 %22\n%26 = OpCompositeExtract %5 %25 0\n%28 = OpIAdd %5 %22 %29\n%27 = OpImageFetch %24 %21 %28\n%30 = OpCompositeExtract %5 %27 0\n%32 = OpIAdd %5 %22 %33\n%31 = OpImageFetch %24 %21 %32\n%34 = OpCompositeExtract %5 %31 0\n%36 = OpIAdd %5 %22 %37\n%35 = OpImageFetch %24 %21 %36\n%38 = OpCompositeExtract %5 %35 0\n%39 = OpCompositeConstruct %24 %26 %30 %34 %38\n%40 = OpBitcast %13 %39\n%41 = OpCompositeExtract %12 %40 0\n%42 = OpCompositeExtract %12 %40 1\n%43 = OpCompositeExtract %12 %40 2\n%44 = OpCompositeExtract %12 %40 3\n%46 = OpAccessChain %45 %15 %18\nOpStore %46 %41\n%47 = OpAccessChain %45 %15 %29\nOpStore %47 %42\n%48 = OpAccessChain %45 %15 %33\nOpStore %48 %43\n%49 = OpAccessChain %45 %15 %37\nOpStore %49 %44\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-texture-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\nlayout(set = 1, binding = 0) uniform texture2D _14[100];\nlayout(set = 0, binding = 0) uniform sampler _17;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _34 = texture(nonuniformEXT(sampler2D(_9[INDEX + 0u], _17)), vec2(0.5));\n    vec4 _47 = texture(nonuniformEXT(sampler2D(_14[(INDEX ^ 1u) + 0u], _17)), vec2(0.5));\n    SV_Target.x = _47.x + _34.x;\n    SV_Target.y = _47.y + _34.y;\n    SV_Target.z = _47.z + _34.z;\n    SV_Target.w = _47.w + _34.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability SampledImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %19 %22\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %19 \"INDEX\"\nOpName %22 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %22 Location 0\nOpDecorate %25 NonUniform\nOpDecorate %29 NonUniform\nOpDecorate %31 NonUniform\nOpDecorate %43 NonUniform\nOpDecorate %45 NonUniform\nOpDecorate %46 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpConstant %10 100\n%12 = OpTypeArray %6 %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeSampler\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypePointer Input %10\n%19 = OpVariable %18 Input\n%20 = OpTypeVector %5 4\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%26 = OpConstant %10 0\n%27 = OpTypePointer UniformConstant %6\n%30 = OpTypeSampledImage %6\n%32 = OpConstant %5 0.5\n%33 = OpConstant %5 0\n%35 = OpTypeVector %5 2\n%42 = OpConstant %10 1\n%57 = OpTypePointer Output %5\n%61 = OpConstant %10 2\n%63 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%23 = OpLoad %15 %17\n%24 = OpLoad %10 %19\n%25 = OpIAdd %10 %24 %26\n%28 = OpAccessChain %27 %9 %25\n%29 = OpLoad %6 %28\n%31 = OpSampledImage %30 %29 %23\n%36 = OpCompositeConstruct %35 %32 %32\n%34 = OpImageSampleImplicitLod %20 %31 %36 None\n%37 = OpCompositeExtract %5 %34 0\n%38 = OpCompositeExtract %5 %34 1\n%39 = OpCompositeExtract %5 %34 2\n%40 = OpCompositeExtract %5 %34 3\n%41 = OpBitwiseXor %10 %24 %42\n%43 = OpIAdd %10 %41 %26\n%44 = OpAccessChain %27 %14 %43\n%45 = OpLoad %6 %44\n%46 = OpSampledImage %30 %45 %23\n%48 = OpCompositeConstruct %35 %32 %32\n%47 = OpImageSampleImplicitLod %20 %46 %48 None\n%49 = OpCompositeExtract %5 %47 0\n%50 = OpCompositeExtract %5 %47 1\n%51 = OpCompositeExtract %5 %47 2\n%52 = OpCompositeExtract %5 %47 3\n%53 = OpFAdd %5 %49 %37\n%54 = OpFAdd %5 %50 %38\n%55 = OpFAdd %5 %51 %39\n%56 = OpFAdd %5 %52 %40\n%58 = OpAccessChain %57 %22 %26\nOpStore %58 %53\n%59 = OpAccessChain %57 %22 %42\nOpStore %59 %54\n%60 = OpAccessChain %57 %22 %61\nOpStore %60 %55\n%62 = OpAccessChain %57 %22 %63\nOpStore %62 %56\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-texture.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\nlayout(set = 1, binding = 0) uniform texture2D _14[100];\nlayout(set = 0, binding = 0) uniform sampler _17;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _34 = texture(sampler2D(_9[INDEX + 0u], _17), vec2(0.5));\n    vec4 _47 = texture(sampler2D(_14[(INDEX ^ 1u) + 0u], _17), vec2(0.5));\n    SV_Target.x = _47.x + _34.x;\n    SV_Target.y = _47.y + _34.y;\n    SV_Target.z = _47.z + _34.z;\n    SV_Target.w = _47.w + _34.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %19 %22\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %19 \"INDEX\"\nOpName %22 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %19 Flat\nOpDecorate %19 Location 0\nOpDecorate %22 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpConstant %10 100\n%12 = OpTypeArray %6 %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeSampler\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypePointer Input %10\n%19 = OpVariable %18 Input\n%20 = OpTypeVector %5 4\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%26 = OpConstant %10 0\n%27 = OpTypePointer UniformConstant %6\n%30 = OpTypeSampledImage %6\n%32 = OpConstant %5 0.5\n%33 = OpConstant %5 0\n%35 = OpTypeVector %5 2\n%42 = OpConstant %10 1\n%57 = OpTypePointer Output %5\n%61 = OpConstant %10 2\n%63 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%23 = OpLoad %15 %17\n%24 = OpLoad %10 %19\n%25 = OpIAdd %10 %24 %26\n%28 = OpAccessChain %27 %9 %25\n%29 = OpLoad %6 %28\n%31 = OpSampledImage %30 %29 %23\n%36 = OpCompositeConstruct %35 %32 %32\n%34 = OpImageSampleImplicitLod %20 %31 %36 None\n%37 = OpCompositeExtract %5 %34 0\n%38 = OpCompositeExtract %5 %34 1\n%39 = OpCompositeExtract %5 %34 2\n%40 = OpCompositeExtract %5 %34 3\n%41 = OpBitwiseXor %10 %24 %42\n%43 = OpIAdd %10 %41 %26\n%44 = OpAccessChain %27 %14 %43\n%45 = OpLoad %6 %44\n%46 = OpSampledImage %30 %45 %23\n%48 = OpCompositeConstruct %35 %32 %32\n%47 = OpImageSampleImplicitLod %20 %46 %48 None\n%49 = OpCompositeExtract %5 %47 0\n%50 = OpCompositeExtract %5 %47 1\n%51 = OpCompositeExtract %5 %47 2\n%52 = OpCompositeExtract %5 %47 3\n%53 = OpFAdd %5 %49 %37\n%54 = OpFAdd %5 %50 %38\n%55 = OpFAdd %5 %51 %39\n%56 = OpFAdd %5 %52 %40\n%58 = OpAccessChain %57 %22 %26\nOpStore %58 %53\n%59 = OpAccessChain %57 %22 %42\nOpStore %59 %54\n%60 = OpAccessChain %57 %22 %61\nOpStore %60 %55\n%62 = OpAccessChain %57 %22 %63\nOpStore %62 %56\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-typed-buffer-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = texelFetch(_9[nonuniformEXT(INDEX + 0u)], int(INDEX));\n    SV_Target.x = _22.x;\n    SV_Target.y = _22.y;\n    SV_Target.z = _22.z;\n    SV_Target.w = _22.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %15 Location 0\nOpDecorate %17 NonUniform\nOpDecorate %21 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeVector %5 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %10 0\n%19 = OpTypePointer UniformConstant %6\n%27 = OpTypePointer Output %5\n%30 = OpConstant %10 1\n%32 = OpConstant %10 2\n%34 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%16 = OpLoad %10 %12\n%17 = OpIAdd %10 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpImageFetch %13 %21 %16\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpCompositeExtract %5 %22 1\n%25 = OpCompositeExtract %5 %22 2\n%26 = OpCompositeExtract %5 %22 3\n%28 = OpAccessChain %27 %15 %18\nOpStore %28 %23\n%29 = OpAccessChain %27 %15 %30\nOpStore %29 %24\n%31 = OpAccessChain %27 %15 %32\nOpStore %31 %25\n%33 = OpAccessChain %27 %15 %34\nOpStore %33 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-array-typed-buffer.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = texelFetch(_9[INDEX + 0u], int(INDEX));\n    SV_Target.x = _22.x;\n    SV_Target.y = _22.y;\n    SV_Target.z = _22.z;\n    SV_Target.w = _22.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeVector %5 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %10 0\n%19 = OpTypePointer UniformConstant %6\n%27 = OpTypePointer Output %5\n%30 = OpConstant %10 1\n%32 = OpConstant %10 2\n%34 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%16 = OpLoad %10 %12\n%17 = OpIAdd %10 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpImageFetch %13 %21 %16\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpCompositeExtract %5 %22 1\n%25 = OpCompositeExtract %5 %22 2\n%26 = OpCompositeExtract %5 %22 3\n%28 = OpAccessChain %27 %15 %18\nOpStore %28 %23\n%29 = OpAccessChain %27 %15 %30\nOpStore %29 %24\n%31 = OpAccessChain %27 %15 %32\nOpStore %31 %25\n%33 = OpAccessChain %27 %15 %34\nOpStore %33 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-indexing.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 5) uniform texture2D _11[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = texelFetch(_11[0u], ivec2(uvec2(0u)), int(0u));\n    vec4 _32 = texelFetch(_11[2u], ivec2(uvec2(0u)), int(0u));\n    vec4 _46 = texelFetch(_11[V], ivec2(uvec2(0u)), int(0u));\n    SV_Target.x = (_32.x + _22.x) + _46.x;\n    SV_Target.y = (_32.y + _22.y) + _46.y;\n    SV_Target.z = (_32.z + _22.z) + _46.z;\n    SV_Target.w = (_32.w + _22.w) + _46.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %16\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"V\"\nOpName %16 \"SV_Target\"\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 5\nOpDecorate %13 Flat\nOpDecorate %13 Location 0\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypePointer Input %7\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%18 = OpTypePointer UniformConstant %6\n%20 = OpConstant %7 0\n%23 = OpTypeVector %7 2\n%30 = OpConstant %7 2\n%43 = OpConstant %7 5\n%56 = OpTypePointer Output %5\n%59 = OpConstant %7 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%17 = OpLoad %7 %13\n%19 = OpAccessChain %18 %11 %20\n%21 = OpLoad %6 %19\n%24 = OpCompositeConstruct %23 %20 %20\n%22 = OpImageFetch %14 %21 %24 Lod %20\n%25 = OpCompositeExtract %5 %22 0\n%26 = OpCompositeExtract %5 %22 1\n%27 = OpCompositeExtract %5 %22 2\n%28 = OpCompositeExtract %5 %22 3\n%29 = OpAccessChain %18 %11 %30\n%31 = OpLoad %6 %29\n%33 = OpCompositeConstruct %23 %20 %20\n%32 = OpImageFetch %14 %31 %33 Lod %20\n%34 = OpCompositeExtract %5 %32 0\n%35 = OpCompositeExtract %5 %32 1\n%36 = OpCompositeExtract %5 %32 2\n%37 = OpCompositeExtract %5 %32 3\n%38 = OpFAdd %5 %34 %25\n%39 = OpFAdd %5 %35 %26\n%40 = OpFAdd %5 %36 %27\n%41 = OpFAdd %5 %37 %28\n%42 = OpIAdd %7 %17 %43\n%44 = OpAccessChain %18 %11 %17\n%45 = OpLoad %6 %44\n%47 = OpCompositeConstruct %23 %20 %20\n%46 = OpImageFetch %14 %45 %47 Lod %20\n%48 = OpCompositeExtract %5 %46 0\n%49 = OpCompositeExtract %5 %46 1\n%50 = OpCompositeExtract %5 %46 2\n%51 = OpCompositeExtract %5 %46 3\n%52 = OpFAdd %5 %38 %48\n%53 = OpFAdd %5 %39 %49\n%54 = OpFAdd %5 %40 %50\n%55 = OpFAdd %5 %41 %51\n%57 = OpAccessChain %56 %16 %20\nOpStore %57 %52\n%58 = OpAccessChain %56 %16 %59\nOpStore %58 %53\n%60 = OpAccessChain %56 %16 %30\nOpStore %60 %54\n%61 = OpAccessChain %56 %16 %8\nOpStore %61 %55\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-indexing.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 5) uniform texture2D _11[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = texelFetch(_11[0u], ivec2(uvec2(0u)), int(0u));\n    vec4 _32 = texelFetch(_11[2u], ivec2(uvec2(0u)), int(0u));\n    vec4 _46 = texelFetch(_11[V], ivec2(uvec2(0u)), int(0u));\n    SV_Target.x = (_32.x + _22.x) + _46.x;\n    SV_Target.y = (_32.y + _22.y) + _46.y;\n    SV_Target.z = (_32.z + _22.z) + _46.z;\n    SV_Target.w = (_32.w + _22.w) + _46.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %16\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"V\"\nOpName %16 \"SV_Target\"\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 5\nOpDecorate %13 Flat\nOpDecorate %13 Location 0\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypePointer Input %7\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%18 = OpTypePointer UniformConstant %6\n%20 = OpConstant %7 0\n%23 = OpTypeVector %7 2\n%30 = OpConstant %7 2\n%43 = OpConstant %7 5\n%56 = OpTypePointer Output %5\n%59 = OpConstant %7 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%17 = OpLoad %7 %13\n%19 = OpAccessChain %18 %11 %20\n%21 = OpLoad %6 %19\n%24 = OpCompositeConstruct %23 %20 %20\n%22 = OpImageFetch %14 %21 %24 Lod %20\n%25 = OpCompositeExtract %5 %22 0\n%26 = OpCompositeExtract %5 %22 1\n%27 = OpCompositeExtract %5 %22 2\n%28 = OpCompositeExtract %5 %22 3\n%29 = OpAccessChain %18 %11 %30\n%31 = OpLoad %6 %29\n%33 = OpCompositeConstruct %23 %20 %20\n%32 = OpImageFetch %14 %31 %33 Lod %20\n%34 = OpCompositeExtract %5 %32 0\n%35 = OpCompositeExtract %5 %32 1\n%36 = OpCompositeExtract %5 %32 2\n%37 = OpCompositeExtract %5 %32 3\n%38 = OpFAdd %5 %34 %25\n%39 = OpFAdd %5 %35 %26\n%40 = OpFAdd %5 %36 %27\n%41 = OpFAdd %5 %37 %28\n%42 = OpIAdd %7 %17 %43\n%44 = OpAccessChain %18 %11 %17\n%45 = OpLoad %6 %44\n%47 = OpCompositeConstruct %23 %20 %20\n%46 = OpImageFetch %14 %45 %47 Lod %20\n%48 = OpCompositeExtract %5 %46 0\n%49 = OpCompositeExtract %5 %46 1\n%50 = OpCompositeExtract %5 %46 2\n%51 = OpCompositeExtract %5 %46 3\n%52 = OpFAdd %5 %38 %48\n%53 = OpFAdd %5 %39 %49\n%54 = OpFAdd %5 %40 %50\n%55 = OpFAdd %5 %41 %51\n%57 = OpAccessChain %56 %16 %20\nOpStore %57 %52\n%58 = OpAccessChain %56 %16 %59\nOpStore %58 %53\n%60 = OpAccessChain %56 %16 %30\nOpStore %60 %54\n%61 = OpAccessChain %56 %16 %8\nOpStore %61 %55\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-raw-buffer.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 1, binding = 0) uniform usamplerBuffer _12[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out uvec2 SV_Target;\n\nvoid main()\n{\n    uint _28 = registers._m1 + 3u;\n    uint _36 = uint(int(gl_FragCoord.x));\n    uint _38 = _36 * 2u;\n    uvec2 _46 = uvec2(texelFetch(_12[_28], int(_38)).x, texelFetch(_12[_28], int(_38 + 1u)).x);\n    uint _67 = registers._m1 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u);\n    uint _69 = _36 * 2u;\n    uvec2 _75 = uvec2(texelFetch(_12[_67], int(_69)).x, texelFetch(_12[_67], int(_69 + 1u)).x);\n    uint _85 = registers._m1 + (INDEX + 100u);\n    uint _87 = _36 * 2u;\n    uvec2 _93 = uvec2(texelFetch(_12[nonuniformEXT(_85)], int(_87)).x, texelFetch(_12[nonuniformEXT(_85)], int(_87 + 1u)).x);\n    SV_Target.x = (_75.x + _46.x) + _93.x;\n    SV_Target.y = (_75.y + _46.y) + _93.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 103\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18 %21\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpName %18 \"INDEX\"\nOpName %21 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 1\nOpDecorate %12 Binding 0\nOpDecorate %16 BuiltIn FragCoord\nOpDecorate %18 Flat\nOpDecorate %18 Location 1\nOpDecorate %21 Location 0\nOpDecorate %85 NonUniform\nOpDecorate %86 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypeVector %5 2\n%20 = OpTypePointer Output %19\n%21 = OpVariable %20 Output\n%22 = OpTypePointer UniformConstant %9\n%24 = OpTypePointer PushConstant %5\n%26 = OpConstant %5 1\n%29 = OpConstant %5 3\n%32 = OpTypePointer Input %13\n%34 = OpConstant %5 0\n%39 = OpConstant %5 2\n%40 = OpTypeVector %5 4\n%50 = OpConstant %5 4\n%53 = OpConstant %5 5\n%56 = OpConstant %5 6\n%59 = OpConstant %5 7\n%81 = OpConstant %5 100\n%98 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %101\n%101 = OpLabel\n%25 = OpAccessChain %24 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpIAdd %5 %27 %29\n%23 = OpAccessChain %22 %12 %28\n%30 = OpLoad %9 %23\n%31 = OpLoad %5 %18\n%33 = OpAccessChain %32 %16 %34\n%35 = OpLoad %13 %33\n%36 = OpConvertFToS %5 %35\n%37 = OpShiftLeftLogical %5 %36 %29\n%38 = OpIMul %5 %36 %39\n%41 = OpImageFetch %40 %30 %38\n%42 = OpCompositeExtract %5 %41 0\n%44 = OpIAdd %5 %38 %26\n%43 = OpImageFetch %40 %30 %44\n%45 = OpCompositeExtract %5 %43 0\n%46 = OpCompositeConstruct %19 %42 %45\n%47 = OpCompositeExtract %5 %46 0\n%48 = OpCompositeExtract %5 %46 1\n%49 = OpAccessChain %24 %8 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %24 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %24 %8 %56\n%57 = OpLoad %5 %55\n%58 = OpAccessChain %24 %8 %59\n%60 = OpLoad %5 %58\n%61 = OpCompositeConstruct %40 %51 %54 %57 %60\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpIAdd %5 %62 %50\n%65 = OpAccessChain %24 %8 %26\n%66 = OpLoad %5 %65\n%67 = OpIAdd %5 %66 %63\n%64 = OpAccessChain %22 %12 %67\n%68 = OpLoad %9 %64\n%69 = OpIMul %5 %36 %39\n%70 = OpImageFetch %40 %68 %69\n%71 = OpCompositeExtract %5 %70 0\n%73 = OpIAdd %5 %69 %26\n%72 = OpImageFetch %40 %68 %73\n%74 = OpCompositeExtract %5 %72 0\n%75 = OpCompositeConstruct %19 %71 %74\n%76 = OpCompositeExtract %5 %75 0\n%77 = OpCompositeExtract %5 %75 1\n%78 = OpIAdd %5 %76 %47\n%79 = OpIAdd %5 %77 %48\n%80 = OpIAdd %5 %31 %81\n%83 = OpAccessChain %24 %8 %26\n%84 = OpLoad %5 %83\n%85 = OpIAdd %5 %84 %80\n%82 = OpAccessChain %22 %12 %85\n%86 = OpLoad %9 %82\n%87 = OpIMul %5 %36 %39\n%88 = OpImageFetch %40 %86 %87\n%89 = OpCompositeExtract %5 %88 0\n%91 = OpIAdd %5 %87 %26\n%90 = OpImageFetch %40 %86 %91\n%92 = OpCompositeExtract %5 %90 0\n%93 = OpCompositeConstruct %19 %89 %92\n%94 = OpCompositeExtract %5 %93 0\n%95 = OpCompositeExtract %5 %93 1\n%96 = OpIAdd %5 %78 %94\n%97 = OpIAdd %5 %79 %95\n%99 = OpAccessChain %98 %21 %34\nOpStore %99 %96\n%100 = OpAccessChain %98 %21 %26\nOpStore %100 %97\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-raw-buffer.bindless.root-constant.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _14[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out uvec2 SV_Target;\n\nvoid main()\n{\n    uint _29 = registers._m1 + 3u;\n    uint _36 = uint(int(gl_FragCoord.x));\n    uint _62 = registers._m1 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u);\n    uint _74 = registers._m1 + (INDEX + 100u);\n    SV_Target.x = (_14[_62]._m0[_36].x + _14[_29]._m0[_36].x) + _14[nonuniformEXT(_74)]._m0[_36].x;\n    SV_Target.y = (_14[_62]._m0[_36].y + _14[_29]._m0[_36].y) + _14[nonuniformEXT(_74)]._m0[_36].y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 86\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %18 %20 %22\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO\"\nOpName %18 \"SV_Position\"\nOpName %20 \"INDEX\"\nOpName %22 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %18 BuiltIn FragCoord\nOpDecorate %20 Flat\nOpDecorate %20 Location 1\nOpDecorate %22 Location 0\nOpDecorate %74 NonUniform\nOpDecorate %71 NonUniform\nOpDecorate %75 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeFloat 32\n%16 = OpTypeVector %15 4\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %5\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Output %9\n%22 = OpVariable %21 Output\n%23 = OpTypePointer StorageBuffer %11\n%25 = OpTypePointer PushConstant %5\n%27 = OpConstant %5 1\n%30 = OpConstant %5 3\n%32 = OpTypePointer Input %15\n%34 = OpConstant %5 0\n%38 = OpTypePointer StorageBuffer %9\n%44 = OpConstant %5 4\n%47 = OpConstant %5 5\n%50 = OpConstant %5 6\n%53 = OpConstant %5 7\n%55 = OpTypeVector %5 4\n%70 = OpConstant %5 100\n%81 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %84\n%84 = OpLabel\n%26 = OpAccessChain %25 %8 %27\n%28 = OpLoad %5 %26\n%29 = OpIAdd %5 %28 %30\n%24 = OpAccessChain %23 %14 %29\n%31 = OpLoad %5 %20\n%33 = OpAccessChain %32 %18 %34\n%35 = OpLoad %15 %33\n%36 = OpConvertFToS %5 %35\n%37 = OpShiftLeftLogical %5 %36 %30\n%39 = OpAccessChain %38 %24 %34 %36\n%40 = OpLoad %9 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpAccessChain %25 %8 %44\n%45 = OpLoad %5 %43\n%46 = OpAccessChain %25 %8 %47\n%48 = OpLoad %5 %46\n%49 = OpAccessChain %25 %8 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %25 %8 %53\n%54 = OpLoad %5 %52\n%56 = OpCompositeConstruct %55 %45 %48 %51 %54\n%57 = OpCompositeExtract %5 %56 0\n%58 = OpIAdd %5 %57 %44\n%60 = OpAccessChain %25 %8 %27\n%61 = OpLoad %5 %60\n%62 = OpIAdd %5 %61 %58\n%59 = OpAccessChain %23 %14 %62\n%63 = OpAccessChain %38 %59 %34 %36\n%64 = OpLoad %9 %63\n%65 = OpCompositeExtract %5 %64 0\n%66 = OpCompositeExtract %5 %64 1\n%67 = OpIAdd %5 %65 %41\n%68 = OpIAdd %5 %66 %42\n%69 = OpIAdd %5 %31 %70\n%72 = OpAccessChain %25 %8 %27\n%73 = OpLoad %5 %72\n%74 = OpIAdd %5 %73 %69\n%71 = OpAccessChain %23 %14 %74\n%75 = OpAccessChain %38 %71 %34 %36\n%76 = OpLoad %9 %75\n%77 = OpCompositeExtract %5 %76 0\n%78 = OpCompositeExtract %5 %76 1\n%79 = OpIAdd %5 %67 %77\n%80 = OpIAdd %5 %68 %78\n%82 = OpAccessChain %81 %22 %34\nOpStore %82 %79\n%83 = OpAccessChain %81 %22 %27\nOpStore %83 %80\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-raw-buffer.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 3, std430) restrict readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 4, std430) restrict readonly buffer _12_16\n{\n    uvec2 _m0[];\n} _16[64];\n\nlayout(set = 0, binding = 100, std430) restrict readonly buffer _18_21\n{\n    uvec2 _m0[];\n} _21[];\n\nlayout(set = 0, binding = 0, std140) uniform _26_28\n{\n    vec4 _m0[1];\n} _28;\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out uvec2 SV_Target;\n\nvoid main()\n{\n    uint _40 = uint(int(gl_FragCoord.x));\n    uvec4 _52 = floatBitsToUint(_28._m0[0u]);\n    uint _53 = _52.x;\n    SV_Target.x = (_16[_53]._m0[_40].x + _10._m0[_40].x) + _21[nonuniformEXT(INDEX)]._m0[_40].x;\n    SV_Target.y = (_16[_53]._m0[_40].y + _10._m0[_40].y) + _21[nonuniformEXT(INDEX)]._m0[_40].y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %30 %32 %34\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %18 \"SSBO\"\nOpName %26 \"\"\nOpName %30 \"SV_Position\"\nOpName %32 \"INDEX\"\nOpName %34 \"SV_Target\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 3\nOpDecorate %10 NonWritable\nOpDecorate %10 Restrict\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 4\nOpDecorate %16 NonWritable\nOpDecorate %16 Restrict\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 100\nOpDecorate %21 NonWritable\nOpDecorate %21 Restrict\nOpDecorate %25 ArrayStride 16\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %30 BuiltIn FragCoord\nOpDecorate %32 Flat\nOpDecorate %32 Location 1\nOpDecorate %34 Location 0\nOpDecorate %35 NonUniform\nOpDecorate %67 NonUniform\nOpDecorate %68 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpConstant %5 64\n%14 = OpTypeArray %12 %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeRuntimeArray %6\n%18 = OpTypeStruct %17\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpConstant %5 1\n%23 = OpTypeFloat 32\n%24 = OpTypeVector %23 4\n%25 = OpTypeArray %24 %22\n%26 = OpTypeStruct %25\n%27 = OpTypePointer Uniform %26\n%28 = OpVariable %27 Uniform\n%29 = OpTypePointer Input %24\n%30 = OpVariable %29 Input\n%31 = OpTypePointer Input %5\n%32 = OpVariable %31 Input\n%33 = OpTypePointer Output %6\n%34 = OpVariable %33 Output\n%36 = OpTypePointer Input %23\n%38 = OpConstant %5 0\n%42 = OpConstant %5 3\n%43 = OpTypePointer StorageBuffer %6\n%48 = OpTypePointer Uniform %24\n%51 = OpTypeVector %5 4\n%55 = OpConstant %5 4\n%56 = OpTypePointer StorageBuffer %12\n%65 = OpConstant %5 100\n%66 = OpTypePointer StorageBuffer %18\n%74 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %77\n%77 = OpLabel\n%35 = OpLoad %5 %32\n%37 = OpAccessChain %36 %30 %38\n%39 = OpLoad %23 %37\n%40 = OpConvertFToS %5 %39\n%41 = OpShiftLeftLogical %5 %40 %42\n%44 = OpAccessChain %43 %10 %38 %40\n%45 = OpLoad %6 %44\n%46 = OpCompositeExtract %5 %45 0\n%47 = OpCompositeExtract %5 %45 1\n%49 = OpAccessChain %48 %28 %38 %38\n%50 = OpLoad %24 %49\n%52 = OpBitcast %51 %50\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpIAdd %5 %53 %55\n%57 = OpAccessChain %56 %16 %53\n%58 = OpAccessChain %43 %57 %38 %40\n%59 = OpLoad %6 %58\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpCompositeExtract %5 %59 1\n%62 = OpIAdd %5 %60 %46\n%63 = OpIAdd %5 %61 %47\n%64 = OpIAdd %5 %35 %65\n%67 = OpAccessChain %66 %21 %35\n%68 = OpAccessChain %43 %67 %38 %40\n%69 = OpLoad %6 %68\n%70 = OpCompositeExtract %5 %69 0\n%71 = OpCompositeExtract %5 %69 1\n%72 = OpIAdd %5 %62 %70\n%73 = OpIAdd %5 %63 %71\n%75 = OpAccessChain %74 %34 %38\nOpStore %75 %72\n%76 = OpAccessChain %74 %34 %22\nOpStore %76 %73\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-structured-buffer.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 1, binding = 0) uniform usamplerBuffer _12[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _36 = uint(int(gl_FragCoord.x));\n    float _40 = uintBitsToFloat(texelFetch(_12[registers._m1 + 3u], int(_36)).x);\n    uint _59 = registers._m1 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u);\n    uint _61 = _36 * 2u;\n    vec2 _71 = uintBitsToFloat(uvec2(texelFetch(_12[_59], int(_61)).x, texelFetch(_12[_59], int(_61 + 1u)).x));\n    float _74 = _71.x + _40;\n    uint _81 = registers._m1 + (INDEX + 100u);\n    uint _83 = _36 * 3u;\n    vec3 _94 = uintBitsToFloat(uvec3(texelFetch(_12[nonuniformEXT(_81)], int(_83)).x, texelFetch(_12[nonuniformEXT(_81)], int(_83 + 1u)).x, texelFetch(_12[nonuniformEXT(_81)], int(_83 + 2u)).x));\n    SV_Target.x = _94.x + _74;\n    SV_Target.y = (_71.y + _40) + _94.y;\n    SV_Target.z = _94.z + _74;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18 %21\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpName %18 \"INDEX\"\nOpName %21 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 1\nOpDecorate %12 Binding 0\nOpDecorate %16 BuiltIn FragCoord\nOpDecorate %18 Flat\nOpDecorate %18 Location 1\nOpDecorate %21 Location 0\nOpDecorate %81 NonUniform\nOpDecorate %82 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypeVector %13 3\n%20 = OpTypePointer Output %19\n%21 = OpVariable %20 Output\n%22 = OpTypePointer UniformConstant %9\n%24 = OpTypePointer PushConstant %5\n%26 = OpConstant %5 1\n%29 = OpConstant %5 3\n%32 = OpTypePointer Input %13\n%34 = OpConstant %5 0\n%37 = OpTypeVector %5 4\n%42 = OpConstant %5 4\n%45 = OpConstant %5 5\n%48 = OpConstant %5 6\n%51 = OpConstant %5 7\n%62 = OpConstant %5 2\n%68 = OpTypeVector %5 2\n%70 = OpTypeVector %13 2\n%77 = OpConstant %5 100\n%92 = OpTypeVector %5 3\n%101 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %105\n%105 = OpLabel\n%25 = OpAccessChain %24 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpIAdd %5 %27 %29\n%23 = OpAccessChain %22 %12 %28\n%30 = OpLoad %9 %23\n%31 = OpLoad %5 %18\n%33 = OpAccessChain %32 %16 %34\n%35 = OpLoad %13 %33\n%36 = OpConvertFToS %5 %35\n%38 = OpImageFetch %37 %30 %36\n%39 = OpCompositeExtract %5 %38 0\n%40 = OpBitcast %13 %39\n%41 = OpAccessChain %24 %8 %42\n%43 = OpLoad %5 %41\n%44 = OpAccessChain %24 %8 %45\n%46 = OpLoad %5 %44\n%47 = OpAccessChain %24 %8 %48\n%49 = OpLoad %5 %47\n%50 = OpAccessChain %24 %8 %51\n%52 = OpLoad %5 %50\n%53 = OpCompositeConstruct %37 %43 %46 %49 %52\n%54 = OpCompositeExtract %5 %53 0\n%55 = OpIAdd %5 %54 %42\n%57 = OpAccessChain %24 %8 %26\n%58 = OpLoad %5 %57\n%59 = OpIAdd %5 %58 %55\n%56 = OpAccessChain %22 %12 %59\n%60 = OpLoad %9 %56\n%61 = OpIMul %5 %36 %62\n%63 = OpImageFetch %37 %60 %61\n%64 = OpCompositeExtract %5 %63 0\n%66 = OpIAdd %5 %61 %26\n%65 = OpImageFetch %37 %60 %66\n%67 = OpCompositeExtract %5 %65 0\n%69 = OpCompositeConstruct %68 %64 %67\n%71 = OpBitcast %70 %69\n%72 = OpCompositeExtract %13 %71 0\n%73 = OpCompositeExtract %13 %71 1\n%74 = OpFAdd %13 %72 %40\n%75 = OpFAdd %13 %73 %40\n%76 = OpIAdd %5 %31 %77\n%79 = OpAccessChain %24 %8 %26\n%80 = OpLoad %5 %79\n%81 = OpIAdd %5 %80 %76\n%78 = OpAccessChain %22 %12 %81\n%82 = OpLoad %9 %78\n%83 = OpIMul %5 %36 %29\n%84 = OpImageFetch %37 %82 %83\n%85 = OpCompositeExtract %5 %84 0\n%87 = OpIAdd %5 %83 %26\n%86 = OpImageFetch %37 %82 %87\n%88 = OpCompositeExtract %5 %86 0\n%90 = OpIAdd %5 %83 %62\n%89 = OpImageFetch %37 %82 %90\n%91 = OpCompositeExtract %5 %89 0\n%93 = OpCompositeConstruct %92 %85 %88 %91\n%94 = OpBitcast %19 %93\n%95 = OpCompositeExtract %13 %94 0\n%96 = OpCompositeExtract %13 %94 1\n%97 = OpCompositeExtract %13 %94 2\n%98 = OpFAdd %13 %95 %74\n%99 = OpFAdd %13 %75 %96\n%100 = OpFAdd %13 %97 %74\n%102 = OpAccessChain %101 %21 %34\nOpStore %102 %98\n%103 = OpAccessChain %101 %21 %26\nOpStore %103 %99\n%104 = OpAccessChain %101 %21 %62\nOpStore %104 %100\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-structured-buffer.bindless.root-constant.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _13[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _16_19\n{\n    uvec2 _m0[];\n} _19[];\n\nlayout(set = 1, binding = 0, scalar) restrict readonly buffer _22_25\n{\n    uvec3 _m0[];\n} _25[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _48 = uint(int(gl_FragCoord.x));\n    float _52 = uintBitsToFloat(_13[registers._m1 + 3u]._m0[_48]);\n    vec2 _78 = uintBitsToFloat(_19[registers._m1 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u)]._m0[_48]);\n    float _81 = _78.x + _52;\n    vec3 _93 = uintBitsToFloat(_25[nonuniformEXT(registers._m1 + (INDEX + 100u))]._m0[_48]);\n    SV_Target.x = _93.x + _81;\n    SV_Target.y = (_78.y + _52) + _93.y;\n    SV_Target.z = _93.z + _81;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %29 %31 %34\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %10 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %29 \"SV_Position\"\nOpName %31 \"INDEX\"\nOpName %34 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %9 ArrayStride 4\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %13 DescriptorSet 1\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %15 ArrayStride 8\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %21 ArrayStride 12\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %25 DescriptorSet 1\nOpDecorate %25 Binding 0\nOpDecorate %25 NonWritable\nOpDecorate %25 Restrict\nOpDecorate %29 BuiltIn FragCoord\nOpDecorate %31 Flat\nOpDecorate %31 Location 1\nOpDecorate %34 Location 0\nOpDecorate %89 NonUniform\nOpDecorate %86 NonUniform\nOpDecorate %91 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeRuntimeArray %5\n%10 = OpTypeStruct %9\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeVector %5 2\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeVector %5 3\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypeStruct %21\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypeFloat 32\n%27 = OpTypeVector %26 4\n%28 = OpTypePointer Input %27\n%29 = OpVariable %28 Input\n%30 = OpTypePointer Input %5\n%31 = OpVariable %30 Input\n%32 = OpTypeVector %26 3\n%33 = OpTypePointer Output %32\n%34 = OpVariable %33 Output\n%35 = OpTypePointer StorageBuffer %10\n%37 = OpTypePointer PushConstant %5\n%39 = OpConstant %5 1\n%42 = OpConstant %5 3\n%44 = OpTypePointer Input %26\n%46 = OpConstant %5 0\n%49 = OpTypePointer StorageBuffer %5\n%54 = OpConstant %5 4\n%57 = OpConstant %5 5\n%60 = OpConstant %5 6\n%63 = OpConstant %5 7\n%65 = OpTypeVector %5 4\n%69 = OpTypePointer StorageBuffer %16\n%74 = OpTypePointer StorageBuffer %14\n%77 = OpTypeVector %26 2\n%84 = OpConstant %5 100\n%85 = OpTypePointer StorageBuffer %22\n%90 = OpTypePointer StorageBuffer %20\n%100 = OpTypePointer Output %26\n%104 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %105\n%105 = OpLabel\n%38 = OpAccessChain %37 %8 %39\n%40 = OpLoad %5 %38\n%41 = OpIAdd %5 %40 %42\n%36 = OpAccessChain %35 %13 %41\n%43 = OpLoad %5 %31\n%45 = OpAccessChain %44 %29 %46\n%47 = OpLoad %26 %45\n%48 = OpConvertFToS %5 %47\n%50 = OpAccessChain %49 %36 %46 %48\n%51 = OpLoad %5 %50\n%52 = OpBitcast %26 %51\n%53 = OpAccessChain %37 %8 %54\n%55 = OpLoad %5 %53\n%56 = OpAccessChain %37 %8 %57\n%58 = OpLoad %5 %56\n%59 = OpAccessChain %37 %8 %60\n%61 = OpLoad %5 %59\n%62 = OpAccessChain %37 %8 %63\n%64 = OpLoad %5 %62\n%66 = OpCompositeConstruct %65 %55 %58 %61 %64\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpIAdd %5 %67 %54\n%71 = OpAccessChain %37 %8 %39\n%72 = OpLoad %5 %71\n%73 = OpIAdd %5 %72 %68\n%70 = OpAccessChain %69 %19 %73\n%75 = OpAccessChain %74 %70 %46 %48\n%76 = OpLoad %14 %75\n%78 = OpBitcast %77 %76\n%79 = OpCompositeExtract %26 %78 0\n%80 = OpCompositeExtract %26 %78 1\n%81 = OpFAdd %26 %79 %52\n%82 = OpFAdd %26 %80 %52\n%83 = OpIAdd %5 %43 %84\n%87 = OpAccessChain %37 %8 %39\n%88 = OpLoad %5 %87\n%89 = OpIAdd %5 %88 %83\n%86 = OpAccessChain %85 %25 %89\n%91 = OpAccessChain %90 %86 %46 %48\n%92 = OpLoad %20 %91\n%93 = OpBitcast %32 %92\n%94 = OpCompositeExtract %26 %93 0\n%95 = OpCompositeExtract %26 %93 1\n%96 = OpCompositeExtract %26 %93 2\n%97 = OpFAdd %26 %94 %81\n%98 = OpFAdd %26 %82 %95\n%99 = OpFAdd %26 %96 %81\n%101 = OpAccessChain %100 %34 %46\nOpStore %101 %97\n%102 = OpAccessChain %100 %34 %39\nOpStore %102 %98\n%103 = OpAccessChain %100 %34 %104\nOpStore %103 %99\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-structured-buffer.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 3, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 4, std430) restrict readonly buffer _12_16\n{\n    uvec2 _m0[];\n} _16[64];\n\nlayout(set = 0, binding = 100, scalar) restrict readonly buffer _19_22\n{\n    uvec3 _m0[];\n} _22[];\n\nlayout(set = 0, binding = 0, std140) uniform _27_29\n{\n    vec4 _m0[1];\n} _29;\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _42 = uint(int(gl_FragCoord.x));\n    float _46 = uintBitsToFloat(_9._m0[_42]);\n    uvec4 _51 = floatBitsToUint(_29._m0[0u]);\n    uint _52 = _51.x;\n    vec2 _61 = uintBitsToFloat(_16[_52]._m0[_42]);\n    float _64 = _61.x + _46;\n    vec3 _73 = uintBitsToFloat(_22[nonuniformEXT(INDEX)]._m0[_42]);\n    SV_Target.x = _73.x + _64;\n    SV_Target.y = (_61.y + _46) + _73.y;\n    SV_Target.z = _73.z + _64;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %31 %33 %36\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %19 \"SSBO\"\nOpName %27 \"\"\nOpName %31 \"SV_Position\"\nOpName %33 \"INDEX\"\nOpName %36 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 3\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 4\nOpDecorate %16 NonWritable\nOpDecorate %16 Restrict\nOpDecorate %18 ArrayStride 12\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 100\nOpDecorate %22 NonWritable\nOpDecorate %22 Restrict\nOpDecorate %26 ArrayStride 16\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %31 BuiltIn FragCoord\nOpDecorate %33 Flat\nOpDecorate %33 Location 1\nOpDecorate %36 Location 0\nOpDecorate %37 NonUniform\nOpDecorate %69 NonUniform\nOpDecorate %71 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpConstant %5 64\n%14 = OpTypeArray %12 %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeVector %5 3\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypeStruct %18\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpConstant %5 1\n%24 = OpTypeFloat 32\n%25 = OpTypeVector %24 4\n%26 = OpTypeArray %25 %23\n%27 = OpTypeStruct %26\n%28 = OpTypePointer Uniform %27\n%29 = OpVariable %28 Uniform\n%30 = OpTypePointer Input %25\n%31 = OpVariable %30 Input\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%34 = OpTypeVector %24 3\n%35 = OpTypePointer Output %34\n%36 = OpVariable %35 Output\n%38 = OpTypePointer Input %24\n%40 = OpConstant %5 0\n%43 = OpTypePointer StorageBuffer %5\n%47 = OpTypePointer Uniform %25\n%50 = OpTypeVector %5 4\n%54 = OpConstant %5 4\n%55 = OpTypePointer StorageBuffer %12\n%57 = OpTypePointer StorageBuffer %10\n%60 = OpTypeVector %24 2\n%67 = OpConstant %5 100\n%68 = OpTypePointer StorageBuffer %19\n%70 = OpTypePointer StorageBuffer %17\n%80 = OpTypePointer Output %24\n%84 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %85\n%85 = OpLabel\n%37 = OpLoad %5 %33\n%39 = OpAccessChain %38 %31 %40\n%41 = OpLoad %24 %39\n%42 = OpConvertFToS %5 %41\n%44 = OpAccessChain %43 %9 %40 %42\n%45 = OpLoad %5 %44\n%46 = OpBitcast %24 %45\n%48 = OpAccessChain %47 %29 %40 %40\n%49 = OpLoad %25 %48\n%51 = OpBitcast %50 %49\n%52 = OpCompositeExtract %5 %51 0\n%53 = OpIAdd %5 %52 %54\n%56 = OpAccessChain %55 %16 %52\n%58 = OpAccessChain %57 %56 %40 %42\n%59 = OpLoad %10 %58\n%61 = OpBitcast %60 %59\n%62 = OpCompositeExtract %24 %61 0\n%63 = OpCompositeExtract %24 %61 1\n%64 = OpFAdd %24 %62 %46\n%65 = OpFAdd %24 %63 %46\n%66 = OpIAdd %5 %37 %67\n%69 = OpAccessChain %68 %22 %37\n%71 = OpAccessChain %70 %69 %40 %42\n%72 = OpLoad %17 %71\n%73 = OpBitcast %34 %72\n%74 = OpCompositeExtract %24 %73 0\n%75 = OpCompositeExtract %24 %73 1\n%76 = OpCompositeExtract %24 %73 2\n%77 = OpFAdd %24 %74 %64\n%78 = OpFAdd %24 %65 %75\n%79 = OpFAdd %24 %76 %64\n%81 = OpAccessChain %80 %36 %40\nOpStore %81 %77\n%82 = OpAccessChain %80 %36 %23\nOpStore %82 %78\n%83 = OpAccessChain %80 %36 %84\nOpStore %83 %79\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-texture.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _37 = uint(int(gl_FragCoord.x));\n    uint _38 = uint(int(gl_FragCoord.y));\n    vec4 _39 = texelFetch(_13[registers._m0 + 3u], ivec2(uvec2(_37, _38)), int(0u));\n    vec4 _67 = texelFetch(_13[registers._m0 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u)], ivec2(uvec2(_37, _38)), int(0u));\n    vec4 _84 = texelFetch(_13[nonuniformEXT(registers._m0 + (INDEX + 100u))], ivec2(uvec2(_37, _38)), int(0u));\n    vec4 _100 = texelFetch(_13[registers._m0 + 101u], ivec2(uvec2(_37, _38)), int(0u));\n    SV_Target.x = ((_67.x + _39.x) + _84.x) + _100.x;\n    SV_Target.y = ((_67.y + _39.y) + _84.y) + _100.y;\n    SV_Target.z = ((_67.z + _39.z) + _84.z) + _100.z;\n    SV_Target.w = ((_67.w + _39.w) + _84.w) + _100.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 118\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18 %20\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpName %18 \"INDEX\"\nOpName %20 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 BuiltIn FragCoord\nOpDecorate %18 Flat\nOpDecorate %18 Location 1\nOpDecorate %20 Location 0\nOpDecorate %82 NonUniform\nOpDecorate %83 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Output %14\n%20 = OpVariable %19 Output\n%21 = OpTypePointer UniformConstant %10\n%23 = OpTypePointer PushConstant %5\n%25 = OpConstant %5 0\n%28 = OpConstant %5 3\n%31 = OpTypePointer Input %9\n%35 = OpConstant %5 1\n%40 = OpTypeVector %5 2\n%47 = OpConstant %5 4\n%50 = OpConstant %5 5\n%53 = OpConstant %5 6\n%56 = OpConstant %5 7\n%58 = OpTypeVector %5 4\n%78 = OpConstant %5 100\n%98 = OpConstant %5 101\n%110 = OpTypePointer Output %9\n%114 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %116\n%116 = OpLabel\n%24 = OpAccessChain %23 %8 %25\n%26 = OpLoad %5 %24\n%27 = OpIAdd %5 %26 %28\n%22 = OpAccessChain %21 %13 %27\n%29 = OpLoad %10 %22\n%30 = OpLoad %5 %18\n%32 = OpAccessChain %31 %16 %25\n%33 = OpLoad %9 %32\n%34 = OpAccessChain %31 %16 %35\n%36 = OpLoad %9 %34\n%37 = OpConvertFToS %5 %33\n%38 = OpConvertFToS %5 %36\n%41 = OpCompositeConstruct %40 %37 %38\n%39 = OpImageFetch %14 %29 %41 Lod %25\n%42 = OpCompositeExtract %9 %39 0\n%43 = OpCompositeExtract %9 %39 1\n%44 = OpCompositeExtract %9 %39 2\n%45 = OpCompositeExtract %9 %39 3\n%46 = OpAccessChain %23 %8 %47\n%48 = OpLoad %5 %46\n%49 = OpAccessChain %23 %8 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %23 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %23 %8 %56\n%57 = OpLoad %5 %55\n%59 = OpCompositeConstruct %58 %48 %51 %54 %57\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpIAdd %5 %60 %47\n%63 = OpAccessChain %23 %8 %25\n%64 = OpLoad %5 %63\n%65 = OpIAdd %5 %64 %61\n%62 = OpAccessChain %21 %13 %65\n%66 = OpLoad %10 %62\n%68 = OpCompositeConstruct %40 %37 %38\n%67 = OpImageFetch %14 %66 %68 Lod %25\n%69 = OpCompositeExtract %9 %67 0\n%70 = OpCompositeExtract %9 %67 1\n%71 = OpCompositeExtract %9 %67 2\n%72 = OpCompositeExtract %9 %67 3\n%73 = OpFAdd %9 %69 %42\n%74 = OpFAdd %9 %70 %43\n%75 = OpFAdd %9 %71 %44\n%76 = OpFAdd %9 %72 %45\n%77 = OpIAdd %5 %30 %78\n%80 = OpAccessChain %23 %8 %25\n%81 = OpLoad %5 %80\n%82 = OpIAdd %5 %81 %77\n%79 = OpAccessChain %21 %13 %82\n%83 = OpLoad %10 %79\n%85 = OpCompositeConstruct %40 %37 %38\n%84 = OpImageFetch %14 %83 %85 Lod %25\n%86 = OpCompositeExtract %9 %84 0\n%87 = OpCompositeExtract %9 %84 1\n%88 = OpCompositeExtract %9 %84 2\n%89 = OpCompositeExtract %9 %84 3\n%90 = OpFAdd %9 %73 %86\n%91 = OpFAdd %9 %74 %87\n%92 = OpFAdd %9 %75 %88\n%93 = OpFAdd %9 %76 %89\n%95 = OpAccessChain %23 %8 %25\n%96 = OpLoad %5 %95\n%97 = OpIAdd %5 %96 %98\n%94 = OpAccessChain %21 %13 %97\n%99 = OpLoad %10 %94\n%101 = OpCompositeConstruct %40 %37 %38\n%100 = OpImageFetch %14 %99 %101 Lod %25\n%102 = OpCompositeExtract %9 %100 0\n%103 = OpCompositeExtract %9 %100 1\n%104 = OpCompositeExtract %9 %100 2\n%105 = OpCompositeExtract %9 %100 3\n%106 = OpFAdd %9 %90 %102\n%107 = OpFAdd %9 %91 %103\n%108 = OpFAdd %9 %92 %104\n%109 = OpFAdd %9 %93 %105\n%111 = OpAccessChain %110 %20 %25\nOpStore %111 %106\n%112 = OpAccessChain %110 %20 %35\nOpStore %112 %107\n%113 = OpAccessChain %110 %20 %114\nOpStore %113 %108\n%115 = OpAccessChain %110 %20 %28\nOpStore %115 %109\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-texture.bindless.root-constant.inline-ubo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 6, binding = 1, std140) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _37 = uint(int(gl_FragCoord.x));\n    uint _38 = uint(int(gl_FragCoord.y));\n    vec4 _39 = texelFetch(_13[registers._m0 + 3u], ivec2(uvec2(_37, _38)), int(0u));\n    vec4 _67 = texelFetch(_13[registers._m0 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u)], ivec2(uvec2(_37, _38)), int(0u));\n    vec4 _84 = texelFetch(_13[nonuniformEXT(registers._m0 + (INDEX + 100u))], ivec2(uvec2(_37, _38)), int(0u));\n    vec4 _100 = texelFetch(_13[registers._m0 + 101u], ivec2(uvec2(_37, _38)), int(0u));\n    SV_Target.x = ((_67.x + _39.x) + _84.x) + _100.x;\n    SV_Target.y = ((_67.y + _39.y) + _84.y) + _100.y;\n    SV_Target.z = ((_67.z + _39.z) + _84.z) + _100.z;\n    SV_Target.w = ((_67.w + _39.w) + _84.w) + _100.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 118\n; Schema: 0\nOpCapability Shader\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18 %20\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpName %18 \"INDEX\"\nOpName %20 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %8 DescriptorSet 6\nOpDecorate %8 Binding 1\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 BuiltIn FragCoord\nOpDecorate %18 Flat\nOpDecorate %18 Location 1\nOpDecorate %20 Location 0\nOpDecorate %82 NonUniform\nOpDecorate %83 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer Uniform %6\n%8 = OpVariable %7 Uniform\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Output %14\n%20 = OpVariable %19 Output\n%21 = OpTypePointer UniformConstant %10\n%23 = OpTypePointer Uniform %5\n%25 = OpConstant %5 0\n%28 = OpConstant %5 3\n%31 = OpTypePointer Input %9\n%35 = OpConstant %5 1\n%40 = OpTypeVector %5 2\n%47 = OpConstant %5 4\n%50 = OpConstant %5 5\n%53 = OpConstant %5 6\n%56 = OpConstant %5 7\n%58 = OpTypeVector %5 4\n%78 = OpConstant %5 100\n%98 = OpConstant %5 101\n%110 = OpTypePointer Output %9\n%114 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %116\n%116 = OpLabel\n%24 = OpAccessChain %23 %8 %25\n%26 = OpLoad %5 %24\n%27 = OpIAdd %5 %26 %28\n%22 = OpAccessChain %21 %13 %27\n%29 = OpLoad %10 %22\n%30 = OpLoad %5 %18\n%32 = OpAccessChain %31 %16 %25\n%33 = OpLoad %9 %32\n%34 = OpAccessChain %31 %16 %35\n%36 = OpLoad %9 %34\n%37 = OpConvertFToS %5 %33\n%38 = OpConvertFToS %5 %36\n%41 = OpCompositeConstruct %40 %37 %38\n%39 = OpImageFetch %14 %29 %41 Lod %25\n%42 = OpCompositeExtract %9 %39 0\n%43 = OpCompositeExtract %9 %39 1\n%44 = OpCompositeExtract %9 %39 2\n%45 = OpCompositeExtract %9 %39 3\n%46 = OpAccessChain %23 %8 %47\n%48 = OpLoad %5 %46\n%49 = OpAccessChain %23 %8 %50\n%51 = OpLoad %5 %49\n%52 = OpAccessChain %23 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %23 %8 %56\n%57 = OpLoad %5 %55\n%59 = OpCompositeConstruct %58 %48 %51 %54 %57\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpIAdd %5 %60 %47\n%63 = OpAccessChain %23 %8 %25\n%64 = OpLoad %5 %63\n%65 = OpIAdd %5 %64 %61\n%62 = OpAccessChain %21 %13 %65\n%66 = OpLoad %10 %62\n%68 = OpCompositeConstruct %40 %37 %38\n%67 = OpImageFetch %14 %66 %68 Lod %25\n%69 = OpCompositeExtract %9 %67 0\n%70 = OpCompositeExtract %9 %67 1\n%71 = OpCompositeExtract %9 %67 2\n%72 = OpCompositeExtract %9 %67 3\n%73 = OpFAdd %9 %69 %42\n%74 = OpFAdd %9 %70 %43\n%75 = OpFAdd %9 %71 %44\n%76 = OpFAdd %9 %72 %45\n%77 = OpIAdd %5 %30 %78\n%80 = OpAccessChain %23 %8 %25\n%81 = OpLoad %5 %80\n%82 = OpIAdd %5 %81 %77\n%79 = OpAccessChain %21 %13 %82\n%83 = OpLoad %10 %79\n%85 = OpCompositeConstruct %40 %37 %38\n%84 = OpImageFetch %14 %83 %85 Lod %25\n%86 = OpCompositeExtract %9 %84 0\n%87 = OpCompositeExtract %9 %84 1\n%88 = OpCompositeExtract %9 %84 2\n%89 = OpCompositeExtract %9 %84 3\n%90 = OpFAdd %9 %73 %86\n%91 = OpFAdd %9 %74 %87\n%92 = OpFAdd %9 %75 %88\n%93 = OpFAdd %9 %76 %89\n%95 = OpAccessChain %23 %8 %25\n%96 = OpLoad %5 %95\n%97 = OpIAdd %5 %96 %98\n%94 = OpAccessChain %21 %13 %97\n%99 = OpLoad %10 %94\n%101 = OpCompositeConstruct %40 %37 %38\n%100 = OpImageFetch %14 %99 %101 Lod %25\n%102 = OpCompositeExtract %9 %100 0\n%103 = OpCompositeExtract %9 %100 1\n%104 = OpCompositeExtract %9 %100 2\n%105 = OpCompositeExtract %9 %100 3\n%106 = OpFAdd %9 %90 %102\n%107 = OpFAdd %9 %91 %103\n%108 = OpFAdd %9 %92 %104\n%109 = OpFAdd %9 %93 %105\n%111 = OpAccessChain %110 %20 %25\nOpStore %111 %106\n%112 = OpAccessChain %110 %20 %35\nOpStore %112 %107\n%113 = OpAccessChain %110 %20 %114\nOpStore %113 %108\n%115 = OpAccessChain %110 %20 %28\nOpStore %115 %109\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-typed-buffer.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 1, binding = 0) uniform samplerBuffer _13[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _17[];\nlayout(set = 1, binding = 0) uniform isamplerBuffer _22[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _44 = uint(int(gl_FragCoord.x));\n    vec4 _45 = texelFetch(_13[registers._m1 + 3u], int(_44));\n    uvec4 _72 = texelFetch(_17[registers._m1 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u)], int(_44));\n    uvec4 _95 = uvec4(texelFetch(_22[nonuniformEXT(registers._m1 + (INDEX + 100u))], int(_44)));\n    SV_Target.x = (float(_72.x) + _45.x) + float(int(_95.x));\n    SV_Target.y = (float(_72.y) + _45.y) + float(int(_95.y));\n    SV_Target.z = (float(_72.z) + _45.z) + float(int(_95.z));\n    SV_Target.w = (float(_72.w) + _45.w) + float(int(_95.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 116\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %25 %27 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %25 \"SV_Position\"\nOpName %27 \"INDEX\"\nOpName %29 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %13 DescriptorSet 1\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %22 DescriptorSet 1\nOpDecorate %22 Binding 0\nOpDecorate %25 BuiltIn FragCoord\nOpDecorate %27 Flat\nOpDecorate %27 Location 1\nOpDecorate %29 Location 0\nOpDecorate %91 NonUniform\nOpDecorate %92 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeInt 32 1\n%19 = OpTypeImage %18 Buffer 0 0 0 1 Unknown\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeVector %9 4\n%24 = OpTypePointer Input %23\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Input %5\n%27 = OpVariable %26 Input\n%28 = OpTypePointer Output %23\n%29 = OpVariable %28 Output\n%30 = OpTypePointer UniformConstant %10\n%32 = OpTypePointer PushConstant %5\n%34 = OpConstant %5 1\n%37 = OpConstant %5 3\n%40 = OpTypePointer Input %9\n%42 = OpConstant %5 0\n%51 = OpConstant %5 4\n%54 = OpConstant %5 5\n%57 = OpConstant %5 6\n%60 = OpConstant %5 7\n%62 = OpTypeVector %5 4\n%66 = OpTypePointer UniformConstant %14\n%86 = OpConstant %5 100\n%87 = OpTypePointer UniformConstant %19\n%93 = OpTypeVector %18 4\n%108 = OpTypePointer Output %9\n%112 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%33 = OpAccessChain %32 %8 %34\n%35 = OpLoad %5 %33\n%36 = OpIAdd %5 %35 %37\n%31 = OpAccessChain %30 %13 %36\n%38 = OpLoad %10 %31\n%39 = OpLoad %5 %27\n%41 = OpAccessChain %40 %25 %42\n%43 = OpLoad %9 %41\n%44 = OpConvertFToS %5 %43\n%45 = OpImageFetch %23 %38 %44\n%46 = OpCompositeExtract %9 %45 0\n%47 = OpCompositeExtract %9 %45 1\n%48 = OpCompositeExtract %9 %45 2\n%49 = OpCompositeExtract %9 %45 3\n%50 = OpAccessChain %32 %8 %51\n%52 = OpLoad %5 %50\n%53 = OpAccessChain %32 %8 %54\n%55 = OpLoad %5 %53\n%56 = OpAccessChain %32 %8 %57\n%58 = OpLoad %5 %56\n%59 = OpAccessChain %32 %8 %60\n%61 = OpLoad %5 %59\n%63 = OpCompositeConstruct %62 %52 %55 %58 %61\n%64 = OpCompositeExtract %5 %63 0\n%65 = OpIAdd %5 %64 %51\n%68 = OpAccessChain %32 %8 %34\n%69 = OpLoad %5 %68\n%70 = OpIAdd %5 %69 %65\n%67 = OpAccessChain %66 %17 %70\n%71 = OpLoad %14 %67\n%72 = OpImageFetch %62 %71 %44\n%73 = OpCompositeExtract %5 %72 0\n%74 = OpCompositeExtract %5 %72 1\n%75 = OpCompositeExtract %5 %72 2\n%76 = OpCompositeExtract %5 %72 3\n%77 = OpConvertUToF %9 %73\n%78 = OpConvertUToF %9 %74\n%79 = OpConvertUToF %9 %75\n%80 = OpConvertUToF %9 %76\n%81 = OpFAdd %9 %77 %46\n%82 = OpFAdd %9 %78 %47\n%83 = OpFAdd %9 %79 %48\n%84 = OpFAdd %9 %80 %49\n%85 = OpIAdd %5 %39 %86\n%89 = OpAccessChain %32 %8 %34\n%90 = OpLoad %5 %89\n%91 = OpIAdd %5 %90 %85\n%88 = OpAccessChain %87 %22 %91\n%92 = OpLoad %19 %88\n%94 = OpImageFetch %93 %92 %44\n%95 = OpBitcast %62 %94\n%96 = OpCompositeExtract %5 %95 0\n%97 = OpCompositeExtract %5 %95 1\n%98 = OpCompositeExtract %5 %95 2\n%99 = OpCompositeExtract %5 %95 3\n%100 = OpConvertSToF %9 %96\n%101 = OpConvertSToF %9 %97\n%102 = OpConvertSToF %9 %98\n%103 = OpConvertSToF %9 %99\n%104 = OpFAdd %9 %81 %100\n%105 = OpFAdd %9 %82 %101\n%106 = OpFAdd %9 %83 %102\n%107 = OpFAdd %9 %84 %103\n%109 = OpAccessChain %108 %29 %42\nOpStore %109 %104\n%110 = OpAccessChain %108 %29 %34\nOpStore %110 %105\n%111 = OpAccessChain %108 %29 %112\nOpStore %111 %106\n%113 = OpAccessChain %108 %29 %37\nOpStore %113 %107\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-uav-raw.typed-buffer-offset.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 1, binding = 0) uniform usamplerBuffer _17[];\nlayout(set = 4, binding = 0, r32ui) uniform uimageBuffer _21[];\nlayout(set = 4, binding = 0, r32ui) uniform uimageBuffer _24[];\n\nvoid main()\n{\n    uint _31 = registers._m4 + 2u;\n    uint _34 = subgroupBroadcastFirst(_31);\n    uint _44 = subgroupBroadcastFirst(registers._m4);\n    uint _52 = registers._m1 + 1u;\n    uint _54 = subgroupBroadcastFirst(_52);\n    uint _70 = (gl_GlobalInvocationID.x * 4u) + 16u;\n    uint _76 = (_70 < _13._m0[_44].y) ? (_70 + _13._m0[_44].x) : 1073741820u;\n    uvec4 _79 = imageLoad(_21[registers._m4], int(_76));\n    uvec4 _81 = imageLoad(_21[registers._m4], int(_76 + 1u));\n    uvec4 _84 = imageLoad(_21[registers._m4], int(_76 + 2u));\n    uvec4 _87 = imageLoad(_21[registers._m4], int(_76 + 3u));\n    vec4 _93 = uintBitsToFloat(uvec4(_79.x, _81.x, _84.x, _87.x));\n    uint _102 = (gl_GlobalInvocationID.x * 4u) + 4096u;\n    uint _107 = (_102 < _13._m0[_44].y) ? (_102 + _13._m0[_44].x) : 1073741820u;\n    imageStore(_21[registers._m4], int(_107), uvec4(floatBitsToUint(_93.x)));\n    imageStore(_21[registers._m4], int(_107 + 1u), uvec4(floatBitsToUint(_93.y)));\n    imageStore(_21[registers._m4], int(_107 + 2u), uvec4(floatBitsToUint(_93.z)));\n    imageStore(_21[registers._m4], int(_107 + 3u), uvec4(floatBitsToUint(_93.w)));\n    uint _122 = (gl_GlobalInvocationID.x * 4u) + 8u;\n    uint _127 = (_122 < _13._m0[_54].y) ? (_122 + _13._m0[_54].x) : 1073741820u;\n    vec4 _140 = uintBitsToFloat(uvec4(texelFetch(_17[_52], int(_127)).x, texelFetch(_17[_52], int(_127 + 1u)).x, texelFetch(_17[_52], int(_127 + 2u)).x, texelFetch(_17[_52], int(_127 + 3u)).x));\n    uint _149 = (gl_GlobalInvocationID.x * 4u) + 8192u;\n    uint _154 = (_149 < _13._m0[_44].y) ? (_149 + _13._m0[_44].x) : 1073741820u;\n    imageStore(_21[registers._m4], int(_154), uvec4(floatBitsToUint(_140.x)));\n    imageStore(_21[registers._m4], int(_154 + 1u), uvec4(floatBitsToUint(_140.y)));\n    imageStore(_21[registers._m4], int(_154 + 2u), uvec4(floatBitsToUint(_140.z)));\n    imageStore(_21[registers._m4], int(_154 + 3u), uvec4(floatBitsToUint(_140.w)));\n    uint _174 = imageAtomicAdd(_24[_31], int((gl_GlobalInvocationID.x < _13._m0[_34].y) ? (gl_GlobalInvocationID.x + _13._m0[_34].x) : 1073741820u), 40u);\n    uint _183 = imageAtomicCompSwap(_24[_31], int((gl_GlobalInvocationID.y < _13._m0[_34].y) ? (gl_GlobalInvocationID.y + _13._m0[_34].x) : 1073741820u), 40u, 50u);\n    float _187 = float(_13._m0[_44].y / 4u);\n    uint _192 = (0u < _13._m0[_44].y) ? (0u + _13._m0[_44].x) : 1073741820u;\n    imageStore(_21[registers._m4], int(_192), uvec4(floatBitsToUint(_187)));\n    imageStore(_21[registers._m4], int(_192 + 1u), uvec4(floatBitsToUint(_187)));\n    imageStore(_21[registers._m4], int(_192 + 2u), uvec4(floatBitsToUint(_187)));\n    imageStore(_21[registers._m4], int(_192 + 3u), uvec4(floatBitsToUint(_187)));\n    float _206 = float(_13._m0[_54].y / 4u);\n    uint _211 = (4u < _13._m0[_44].y) ? (4u + _13._m0[_44].x) : 1073741820u;\n    imageStore(_21[registers._m4], int(_211), uvec4(floatBitsToUint(_206)));\n    imageStore(_21[registers._m4], int(_211 + 1u), uvec4(floatBitsToUint(_206)));\n    imageStore(_21[registers._m4], int(_211 + 2u), uvec4(floatBitsToUint(_206)));\n    imageStore(_21[registers._m4], int(_211 + 3u), uvec4(floatBitsToUint(_206)));\n    uint _227 = registers._m4 + (gl_GlobalInvocationID.z + 0u);\n    uint _232 = (gl_GlobalInvocationID.x * 4u) + 16u;\n    uint _237 = (_232 < _13._m0[_227].y) ? (_232 + _13._m0[_227].x) : 1073741820u;\n    uvec4 _238 = imageLoad(_21[nonuniformEXT(_227)], int(_237));\n    uvec4 _240 = imageLoad(_21[nonuniformEXT(_227)], int(_237 + 1u));\n    uvec4 _243 = imageLoad(_21[nonuniformEXT(_227)], int(_237 + 2u));\n    uvec4 _246 = imageLoad(_21[nonuniformEXT(_227)], int(_237 + 3u));\n    vec4 _250 = uintBitsToFloat(uvec4(_238.x, _240.x, _243.x, _246.x));\n    uint _256 = (gl_GlobalInvocationID.x * 4u) + 4096u;\n    uint _261 = (_256 < _13._m0[_227].y) ? (_256 + _13._m0[_227].x) : 1073741820u;\n    imageStore(_21[nonuniformEXT(_227)], int(_261), uvec4(floatBitsToUint(_250.x)));\n    imageStore(_21[nonuniformEXT(_227)], int(_261 + 1u), uvec4(floatBitsToUint(_250.y)));\n    imageStore(_21[nonuniformEXT(_227)], int(_261 + 2u), uvec4(floatBitsToUint(_250.z)));\n    imageStore(_21[nonuniformEXT(_227)], int(_261 + 3u), uvec4(floatBitsToUint(_250.w)));\n    uint _277 = registers._m1 + (gl_GlobalInvocationID.z + 0u);\n    uint _282 = (gl_GlobalInvocationID.x * 4u) + 16u;\n    uint _287 = (_282 < _13._m0[_277].y) ? (_282 + _13._m0[_277].x) : 1073741820u;\n    vec4 _300 = uintBitsToFloat(uvec4(texelFetch(_17[nonuniformEXT(_277)], int(_287)).x, texelFetch(_17[nonuniformEXT(_277)], int(_287 + 1u)).x, texelFetch(_17[nonuniformEXT(_277)], int(_287 + 2u)).x, texelFetch(_17[nonuniformEXT(_277)], int(_287 + 3u)).x));\n    uint _306 = (gl_GlobalInvocationID.x * 4u) + 8192u;\n    uint _311 = (_306 < _13._m0[_227].y) ? (_306 + _13._m0[_227].x) : 1073741820u;\n    imageStore(_21[nonuniformEXT(_227)], int(_311), uvec4(floatBitsToUint(_300.x)));\n    imageStore(_21[nonuniformEXT(_227)], int(_311 + 1u), uvec4(floatBitsToUint(_300.y)));\n    imageStore(_21[nonuniformEXT(_227)], int(_311 + 2u), uvec4(floatBitsToUint(_300.z)));\n    imageStore(_21[nonuniformEXT(_227)], int(_311 + 3u), uvec4(floatBitsToUint(_300.w)));\n    uint _327 = registers._m4 + (gl_GlobalInvocationID.z + 0u);\n    uint _337 = imageAtomicAdd(_24[nonuniformEXT(_327)], int((gl_GlobalInvocationID.y < _13._m0[_327].y) ? (gl_GlobalInvocationID.y + _13._m0[_327].x) : 1073741820u), 40u);\n    uint _344 = imageAtomicCompSwap(_24[nonuniformEXT(_327)], int((gl_GlobalInvocationID.y < _13._m0[_327].y) ? (gl_GlobalInvocationID.y + _13._m0[_327].x) : 1073741820u), 40u, 70u);\n    float _348 = float(_13._m0[_227].y / 4u);\n    uint _353 = (8u < _13._m0[_44].y) ? (8u + _13._m0[_44].x) : 1073741820u;\n    imageStore(_21[registers._m4], int(_353), uvec4(floatBitsToUint(_348)));\n    imageStore(_21[registers._m4], int(_353 + 1u), uvec4(floatBitsToUint(_348)));\n    imageStore(_21[registers._m4], int(_353 + 2u), uvec4(floatBitsToUint(_348)));\n    imageStore(_21[registers._m4], int(_353 + 3u), uvec4(floatBitsToUint(_348)));\n    float _367 = float(_13._m0[_277].y / 4u);\n    uint _373 = (12u < _13._m0[_44].y) ? (12u + _13._m0[_44].x) : 1073741820u;\n    imageStore(_21[registers._m4], int(_373), uvec4(floatBitsToUint(_367)));\n    imageStore(_21[registers._m4], int(_373 + 1u), uvec4(floatBitsToUint(_367)));\n    imageStore(_21[registers._m4], int(_373 + 2u), uvec4(floatBitsToUint(_367)));\n    imageStore(_21[registers._m4], int(_373 + 3u), uvec4(floatBitsToUint(_367)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 387\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %59\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 4\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 4\nOpDecorate %24 Binding 0\nOpDecorate %59 BuiltIn GlobalInvocationId\nOpDecorate %227 NonUniform\nOpDecorate %228 NonUniform\nOpDecorate %277 NonUniform\nOpDecorate %278 NonUniform\nOpDecorate %327 NonUniform\nOpDecorate %328 NonUniform\nOpDecorate %336 NonUniform\nOpDecorate %343 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeRuntimeArray %18\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypePointer UniformConstant %18\n%27 = OpTypePointer PushConstant %5\n%29 = OpConstant %5 4\n%32 = OpConstant %5 2\n%35 = OpConstant %5 3\n%36 = OpTypePointer StorageBuffer %9\n%38 = OpConstant %5 0\n%47 = OpTypePointer UniformConstant %14\n%50 = OpConstant %5 1\n%57 = OpTypeVector %5 3\n%58 = OpTypePointer Input %57\n%59 = OpVariable %58 Input\n%60 = OpTypePointer Input %5\n%69 = OpConstant %5 16\n%74 = OpTypeBool\n%77 = OpConstant %5 1073741820\n%78 = OpTypeVector %5 4\n%91 = OpTypeFloat 32\n%92 = OpTypeVector %91 4\n%99 = OpConstant %5 1024\n%101 = OpConstant %5 4096\n%121 = OpConstant %5 8\n%146 = OpConstant %5 2048\n%148 = OpConstant %5 8192\n%172 = OpTypePointer Image %5\n%175 = OpConstant %5 40\n%184 = OpConstant %5 50\n%345 = OpConstant %5 70\n%368 = OpConstant %5 12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %385\n%385 = OpLabel\n%28 = OpAccessChain %27 %8 %29\n%30 = OpLoad %5 %28\n%31 = OpIAdd %5 %30 %32\n%26 = OpAccessChain %25 %24 %31\n%33 = OpLoad %18 %26\n%34 = OpGroupNonUniformBroadcastFirst %5 %35 %31\n%37 = OpAccessChain %36 %13 %38 %34\n%39 = OpLoad %9 %37\n%41 = OpAccessChain %27 %8 %29\n%42 = OpLoad %5 %41\n%40 = OpAccessChain %25 %21 %42\n%43 = OpLoad %18 %40\n%44 = OpGroupNonUniformBroadcastFirst %5 %35 %42\n%45 = OpAccessChain %36 %13 %38 %44\n%46 = OpLoad %9 %45\n%49 = OpAccessChain %27 %8 %50\n%51 = OpLoad %5 %49\n%52 = OpIAdd %5 %51 %50\n%48 = OpAccessChain %47 %17 %52\n%53 = OpLoad %14 %48\n%54 = OpGroupNonUniformBroadcastFirst %5 %35 %52\n%55 = OpAccessChain %36 %13 %38 %54\n%56 = OpLoad %9 %55\n%61 = OpAccessChain %60 %59 %38\n%62 = OpLoad %5 %61\n%63 = OpAccessChain %60 %59 %50\n%64 = OpLoad %5 %63\n%65 = OpAccessChain %60 %59 %32\n%66 = OpLoad %5 %65\n%67 = OpIAdd %5 %62 %29\n%68 = OpIMul %5 %62 %29\n%70 = OpIAdd %5 %68 %69\n%71 = OpCompositeExtract %5 %46 0\n%72 = OpCompositeExtract %5 %46 1\n%73 = OpIAdd %5 %70 %71\n%75 = OpULessThan %74 %70 %72\n%76 = OpSelect %5 %75 %73 %77\n%79 = OpImageRead %78 %43 %76\n%80 = OpCompositeExtract %5 %79 0\n%82 = OpIAdd %5 %76 %50\n%81 = OpImageRead %78 %43 %82\n%83 = OpCompositeExtract %5 %81 0\n%85 = OpIAdd %5 %76 %32\n%84 = OpImageRead %78 %43 %85\n%86 = OpCompositeExtract %5 %84 0\n%88 = OpIAdd %5 %76 %35\n%87 = OpImageRead %78 %43 %88\n%89 = OpCompositeExtract %5 %87 0\n%90 = OpCompositeConstruct %78 %80 %83 %86 %89\n%93 = OpBitcast %92 %90\n%94 = OpCompositeExtract %91 %93 0\n%95 = OpCompositeExtract %91 %93 1\n%96 = OpCompositeExtract %91 %93 2\n%97 = OpCompositeExtract %91 %93 3\n%98 = OpIAdd %5 %62 %99\n%100 = OpIMul %5 %62 %29\n%102 = OpIAdd %5 %100 %101\n%103 = OpCompositeExtract %5 %46 0\n%104 = OpCompositeExtract %5 %46 1\n%105 = OpIAdd %5 %102 %103\n%106 = OpULessThan %74 %102 %104\n%107 = OpSelect %5 %106 %105 %77\n%108 = OpBitcast %5 %94\n%109 = OpBitcast %5 %95\n%110 = OpBitcast %5 %96\n%111 = OpBitcast %5 %97\n%112 = OpCompositeConstruct %78 %108 %108 %108 %108\nOpImageWrite %43 %107 %112\n%113 = OpCompositeConstruct %78 %109 %109 %109 %109\n%114 = OpIAdd %5 %107 %50\nOpImageWrite %43 %114 %113\n%115 = OpCompositeConstruct %78 %110 %110 %110 %110\n%116 = OpIAdd %5 %107 %32\nOpImageWrite %43 %116 %115\n%117 = OpCompositeConstruct %78 %111 %111 %111 %111\n%118 = OpIAdd %5 %107 %35\nOpImageWrite %43 %118 %117\n%119 = OpIAdd %5 %62 %32\n%120 = OpIMul %5 %62 %29\n%122 = OpIAdd %5 %120 %121\n%123 = OpCompositeExtract %5 %56 0\n%124 = OpCompositeExtract %5 %56 1\n%125 = OpIAdd %5 %122 %123\n%126 = OpULessThan %74 %122 %124\n%127 = OpSelect %5 %126 %125 %77\n%128 = OpImageFetch %78 %53 %127\n%129 = OpCompositeExtract %5 %128 0\n%131 = OpIAdd %5 %127 %50\n%130 = OpImageFetch %78 %53 %131\n%132 = OpCompositeExtract %5 %130 0\n%134 = OpIAdd %5 %127 %32\n%133 = OpImageFetch %78 %53 %134\n%135 = OpCompositeExtract %5 %133 0\n%137 = OpIAdd %5 %127 %35\n%136 = OpImageFetch %78 %53 %137\n%138 = OpCompositeExtract %5 %136 0\n%139 = OpCompositeConstruct %78 %129 %132 %135 %138\n%140 = OpBitcast %92 %139\n%141 = OpCompositeExtract %91 %140 0\n%142 = OpCompositeExtract %91 %140 1\n%143 = OpCompositeExtract %91 %140 2\n%144 = OpCompositeExtract %91 %140 3\n%145 = OpIAdd %5 %62 %146\n%147 = OpIMul %5 %62 %29\n%149 = OpIAdd %5 %147 %148\n%150 = OpCompositeExtract %5 %46 0\n%151 = OpCompositeExtract %5 %46 1\n%152 = OpIAdd %5 %149 %150\n%153 = OpULessThan %74 %149 %151\n%154 = OpSelect %5 %153 %152 %77\n%155 = OpBitcast %5 %141\n%156 = OpBitcast %5 %142\n%157 = OpBitcast %5 %143\n%158 = OpBitcast %5 %144\n%159 = OpCompositeConstruct %78 %155 %155 %155 %155\nOpImageWrite %43 %154 %159\n%160 = OpCompositeConstruct %78 %156 %156 %156 %156\n%161 = OpIAdd %5 %154 %50\nOpImageWrite %43 %161 %160\n%162 = OpCompositeConstruct %78 %157 %157 %157 %157\n%163 = OpIAdd %5 %154 %32\nOpImageWrite %43 %163 %162\n%164 = OpCompositeConstruct %78 %158 %158 %158 %158\n%165 = OpIAdd %5 %154 %35\nOpImageWrite %43 %165 %164\n%166 = OpShiftLeftLogical %5 %62 %32\n%167 = OpCompositeExtract %5 %39 0\n%168 = OpCompositeExtract %5 %39 1\n%169 = OpIAdd %5 %62 %167\n%170 = OpULessThan %74 %62 %168\n%171 = OpSelect %5 %170 %169 %77\n%173 = OpImageTexelPointer %172 %26 %171 %38\n%174 = OpAtomicIAdd %5 %173 %50 %38 %175\n%176 = OpShiftLeftLogical %5 %64 %32\n%177 = OpCompositeExtract %5 %39 0\n%178 = OpCompositeExtract %5 %39 1\n%179 = OpIAdd %5 %64 %177\n%180 = OpULessThan %74 %64 %178\n%181 = OpSelect %5 %180 %179 %77\n%182 = OpImageTexelPointer %172 %26 %181 %38\n%183 = OpAtomicCompareExchange %5 %182 %50 %38 %38 %184 %175\n%185 = OpCompositeExtract %5 %46 1\n%186 = OpUDiv %5 %185 %29\n%187 = OpConvertUToF %91 %186\n%188 = OpCompositeExtract %5 %46 0\n%189 = OpCompositeExtract %5 %46 1\n%190 = OpIAdd %5 %38 %188\n%191 = OpULessThan %74 %38 %189\n%192 = OpSelect %5 %191 %190 %77\n%193 = OpBitcast %5 %187\n%194 = OpBitcast %5 %187\n%195 = OpBitcast %5 %187\n%196 = OpBitcast %5 %187\n%197 = OpCompositeConstruct %78 %193 %193 %193 %193\nOpImageWrite %43 %192 %197\n%198 = OpCompositeConstruct %78 %194 %194 %194 %194\n%199 = OpIAdd %5 %192 %50\nOpImageWrite %43 %199 %198\n%200 = OpCompositeConstruct %78 %195 %195 %195 %195\n%201 = OpIAdd %5 %192 %32\nOpImageWrite %43 %201 %200\n%202 = OpCompositeConstruct %78 %196 %196 %196 %196\n%203 = OpIAdd %5 %192 %35\nOpImageWrite %43 %203 %202\n%204 = OpCompositeExtract %5 %56 1\n%205 = OpUDiv %5 %204 %29\n%206 = OpConvertUToF %91 %205\n%207 = OpCompositeExtract %5 %46 0\n%208 = OpCompositeExtract %5 %46 1\n%209 = OpIAdd %5 %29 %207\n%210 = OpULessThan %74 %29 %208\n%211 = OpSelect %5 %210 %209 %77\n%212 = OpBitcast %5 %206\n%213 = OpBitcast %5 %206\n%214 = OpBitcast %5 %206\n%215 = OpBitcast %5 %206\n%216 = OpCompositeConstruct %78 %212 %212 %212 %212\nOpImageWrite %43 %211 %216\n%217 = OpCompositeConstruct %78 %213 %213 %213 %213\n%218 = OpIAdd %5 %211 %50\nOpImageWrite %43 %218 %217\n%219 = OpCompositeConstruct %78 %214 %214 %214 %214\n%220 = OpIAdd %5 %211 %32\nOpImageWrite %43 %220 %219\n%221 = OpCompositeConstruct %78 %215 %215 %215 %215\n%222 = OpIAdd %5 %211 %35\nOpImageWrite %43 %222 %221\n%223 = OpIAdd %5 %66 %38\n%225 = OpAccessChain %27 %8 %29\n%226 = OpLoad %5 %225\n%227 = OpIAdd %5 %226 %223\n%224 = OpAccessChain %25 %21 %227\n%228 = OpLoad %18 %224\n%229 = OpAccessChain %36 %13 %38 %227\n%230 = OpLoad %9 %229\n%231 = OpIMul %5 %62 %29\n%232 = OpIAdd %5 %231 %69\n%233 = OpCompositeExtract %5 %230 0\n%234 = OpCompositeExtract %5 %230 1\n%235 = OpIAdd %5 %232 %233\n%236 = OpULessThan %74 %232 %234\n%237 = OpSelect %5 %236 %235 %77\n%238 = OpImageRead %78 %228 %237\n%239 = OpCompositeExtract %5 %238 0\n%241 = OpIAdd %5 %237 %50\n%240 = OpImageRead %78 %228 %241\n%242 = OpCompositeExtract %5 %240 0\n%244 = OpIAdd %5 %237 %32\n%243 = OpImageRead %78 %228 %244\n%245 = OpCompositeExtract %5 %243 0\n%247 = OpIAdd %5 %237 %35\n%246 = OpImageRead %78 %228 %247\n%248 = OpCompositeExtract %5 %246 0\n%249 = OpCompositeConstruct %78 %239 %242 %245 %248\n%250 = OpBitcast %92 %249\n%251 = OpCompositeExtract %91 %250 0\n%252 = OpCompositeExtract %91 %250 1\n%253 = OpCompositeExtract %91 %250 2\n%254 = OpCompositeExtract %91 %250 3\n%255 = OpIMul %5 %62 %29\n%256 = OpIAdd %5 %255 %101\n%257 = OpCompositeExtract %5 %230 0\n%258 = OpCompositeExtract %5 %230 1\n%259 = OpIAdd %5 %256 %257\n%260 = OpULessThan %74 %256 %258\n%261 = OpSelect %5 %260 %259 %77\n%262 = OpBitcast %5 %251\n%263 = OpBitcast %5 %252\n%264 = OpBitcast %5 %253\n%265 = OpBitcast %5 %254\n%266 = OpCompositeConstruct %78 %262 %262 %262 %262\nOpImageWrite %228 %261 %266\n%267 = OpCompositeConstruct %78 %263 %263 %263 %263\n%268 = OpIAdd %5 %261 %50\nOpImageWrite %228 %268 %267\n%269 = OpCompositeConstruct %78 %264 %264 %264 %264\n%270 = OpIAdd %5 %261 %32\nOpImageWrite %228 %270 %269\n%271 = OpCompositeConstruct %78 %265 %265 %265 %265\n%272 = OpIAdd %5 %261 %35\nOpImageWrite %228 %272 %271\n%273 = OpIAdd %5 %66 %38\n%275 = OpAccessChain %27 %8 %50\n%276 = OpLoad %5 %275\n%277 = OpIAdd %5 %276 %273\n%274 = OpAccessChain %47 %17 %277\n%278 = OpLoad %14 %274\n%279 = OpAccessChain %36 %13 %38 %277\n%280 = OpLoad %9 %279\n%281 = OpIMul %5 %62 %29\n%282 = OpIAdd %5 %281 %69\n%283 = OpCompositeExtract %5 %280 0\n%284 = OpCompositeExtract %5 %280 1\n%285 = OpIAdd %5 %282 %283\n%286 = OpULessThan %74 %282 %284\n%287 = OpSelect %5 %286 %285 %77\n%288 = OpImageFetch %78 %278 %287\n%289 = OpCompositeExtract %5 %288 0\n%291 = OpIAdd %5 %287 %50\n%290 = OpImageFetch %78 %278 %291\n%292 = OpCompositeExtract %5 %290 0\n%294 = OpIAdd %5 %287 %32\n%293 = OpImageFetch %78 %278 %294\n%295 = OpCompositeExtract %5 %293 0\n%297 = OpIAdd %5 %287 %35\n%296 = OpImageFetch %78 %278 %297\n%298 = OpCompositeExtract %5 %296 0\n%299 = OpCompositeConstruct %78 %289 %292 %295 %298\n%300 = OpBitcast %92 %299\n%301 = OpCompositeExtract %91 %300 0\n%302 = OpCompositeExtract %91 %300 1\n%303 = OpCompositeExtract %91 %300 2\n%304 = OpCompositeExtract %91 %300 3\n%305 = OpIMul %5 %62 %29\n%306 = OpIAdd %5 %305 %148\n%307 = OpCompositeExtract %5 %230 0\n%308 = OpCompositeExtract %5 %230 1\n%309 = OpIAdd %5 %306 %307\n%310 = OpULessThan %74 %306 %308\n%311 = OpSelect %5 %310 %309 %77\n%312 = OpBitcast %5 %301\n%313 = OpBitcast %5 %302\n%314 = OpBitcast %5 %303\n%315 = OpBitcast %5 %304\n%316 = OpCompositeConstruct %78 %312 %312 %312 %312\nOpImageWrite %228 %311 %316\n%317 = OpCompositeConstruct %78 %313 %313 %313 %313\n%318 = OpIAdd %5 %311 %50\nOpImageWrite %228 %318 %317\n%319 = OpCompositeConstruct %78 %314 %314 %314 %314\n%320 = OpIAdd %5 %311 %32\nOpImageWrite %228 %320 %319\n%321 = OpCompositeConstruct %78 %315 %315 %315 %315\n%322 = OpIAdd %5 %311 %35\nOpImageWrite %228 %322 %321\n%323 = OpIAdd %5 %66 %38\n%325 = OpAccessChain %27 %8 %29\n%326 = OpLoad %5 %325\n%327 = OpIAdd %5 %326 %323\n%324 = OpAccessChain %25 %24 %327\n%328 = OpLoad %18 %324\n%329 = OpAccessChain %36 %13 %38 %327\n%330 = OpLoad %9 %329\n%331 = OpCompositeExtract %5 %330 0\n%332 = OpCompositeExtract %5 %330 1\n%333 = OpIAdd %5 %64 %331\n%334 = OpULessThan %74 %64 %332\n%335 = OpSelect %5 %334 %333 %77\n%336 = OpImageTexelPointer %172 %324 %335 %38\n%337 = OpAtomicIAdd %5 %336 %50 %38 %175\n%338 = OpCompositeExtract %5 %330 0\n%339 = OpCompositeExtract %5 %330 1\n%340 = OpIAdd %5 %64 %338\n%341 = OpULessThan %74 %64 %339\n%342 = OpSelect %5 %341 %340 %77\n%343 = OpImageTexelPointer %172 %324 %342 %38\n%344 = OpAtomicCompareExchange %5 %343 %50 %38 %38 %345 %175\n%346 = OpCompositeExtract %5 %230 1\n%347 = OpUDiv %5 %346 %29\n%348 = OpConvertUToF %91 %347\n%349 = OpCompositeExtract %5 %46 0\n%350 = OpCompositeExtract %5 %46 1\n%351 = OpIAdd %5 %121 %349\n%352 = OpULessThan %74 %121 %350\n%353 = OpSelect %5 %352 %351 %77\n%354 = OpBitcast %5 %348\n%355 = OpBitcast %5 %348\n%356 = OpBitcast %5 %348\n%357 = OpBitcast %5 %348\n%358 = OpCompositeConstruct %78 %354 %354 %354 %354\nOpImageWrite %43 %353 %358\n%359 = OpCompositeConstruct %78 %355 %355 %355 %355\n%360 = OpIAdd %5 %353 %50\nOpImageWrite %43 %360 %359\n%361 = OpCompositeConstruct %78 %356 %356 %356 %356\n%362 = OpIAdd %5 %353 %32\nOpImageWrite %43 %362 %361\n%363 = OpCompositeConstruct %78 %357 %357 %357 %357\n%364 = OpIAdd %5 %353 %35\nOpImageWrite %43 %364 %363\n%365 = OpCompositeExtract %5 %280 1\n%366 = OpUDiv %5 %365 %29\n%367 = OpConvertUToF %91 %366\n%369 = OpCompositeExtract %5 %46 0\n%370 = OpCompositeExtract %5 %46 1\n%371 = OpIAdd %5 %368 %369\n%372 = OpULessThan %74 %368 %370\n%373 = OpSelect %5 %372 %371 %77\n%374 = OpBitcast %5 %367\n%375 = OpBitcast %5 %367\n%376 = OpBitcast %5 %367\n%377 = OpBitcast %5 %367\n%378 = OpCompositeConstruct %78 %374 %374 %374 %374\nOpImageWrite %43 %373 %378\n%379 = OpCompositeConstruct %78 %375 %375 %375 %375\n%380 = OpIAdd %5 %373 %50\nOpImageWrite %43 %380 %379\n%381 = OpCompositeConstruct %78 %376 %376 %376 %376\n%382 = OpIAdd %5 %373 %32\nOpImageWrite %43 %382 %381\n%383 = OpCompositeConstruct %78 %377 %377 %377 %377\n%384 = OpIAdd %5 %373 %35\nOpImageWrite %43 %384 %383\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/srv-uav.typed-buffer-offset.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 1, binding = 0) uniform samplerBuffer _18[];\nlayout(set = 4, binding = 0, r32f) uniform imageBuffer _22[];\nlayout(set = 4, binding = 0, r32ui) uniform uimageBuffer _26[];\n\nvoid main()\n{\n    uint _33 = registers._m4 + 2u;\n    uint _36 = subgroupBroadcastFirst(_33);\n    uint _47 = subgroupBroadcastFirst(registers._m4);\n    uint _55 = registers._m1 + 1u;\n    uint _57 = subgroupBroadcastFirst(_55);\n    uint _70 = gl_GlobalInvocationID.x + 4u;\n    uint _84 = gl_GlobalInvocationID.x + 1024u;\n    imageStore(_22[registers._m4], int((_84 < _13._m0[_47].y) ? (_84 + _13._m0[_47].x) : 4294967295u), vec4(imageLoad(_22[registers._m4], int((_70 < _13._m0[_47].y) ? (_70 + _13._m0[_47].x) : 4294967295u))));\n    uint _92 = gl_GlobalInvocationID.x + 2u;\n    uint _103 = gl_GlobalInvocationID.x + 2048u;\n    imageStore(_22[registers._m4], int((_103 < _13._m0[_47].y) ? (_103 + _13._m0[_47].x) : 4294967295u), vec4(texelFetch(_18[_55], int((_92 < _13._m0[_57].y) ? (_92 + _13._m0[_57].x) : 4294967295u))));\n    uint _118 = imageAtomicAdd(_26[_33], int((gl_GlobalInvocationID.x < _13._m0[_36].y) ? (gl_GlobalInvocationID.x + _13._m0[_36].x) : 4294967295u), 40u);\n    uint _126 = imageAtomicCompSwap(_26[_33], int((gl_GlobalInvocationID.y < _13._m0[_36].y) ? (gl_GlobalInvocationID.y + _13._m0[_36].x) : 4294967295u), 40u, 50u);\n    imageStore(_22[registers._m4], int((0u < _13._m0[_47].y) ? (0u + _13._m0[_47].x) : 4294967295u), vec4(float(_13._m0[_47].y)));\n    imageStore(_22[registers._m4], int((1u < _13._m0[_47].y) ? (1u + _13._m0[_47].x) : 4294967295u), vec4(float(_13._m0[_57].y)));\n    uint _148 = registers._m4 + (gl_GlobalInvocationID.z + 0u);\n    imageStore(_22[nonuniformEXT(_148)], int((_84 < _13._m0[_148].y) ? (_84 + _13._m0[_148].x) : 4294967295u), vec4(imageLoad(_22[nonuniformEXT(_148)], int((_70 < _13._m0[_148].y) ? (_70 + _13._m0[_148].x) : 4294967295u))));\n    uint _172 = registers._m1 + (gl_GlobalInvocationID.z + 0u);\n    imageStore(_22[nonuniformEXT(_148)], int((_103 < _13._m0[_148].y) ? (_103 + _13._m0[_148].x) : 4294967295u), vec4(texelFetch(_18[nonuniformEXT(_172)], int((_70 < _13._m0[_172].y) ? (_70 + _13._m0[_172].x) : 4294967295u))));\n    uint _196 = registers._m4 + (gl_GlobalInvocationID.z + 0u);\n    uint _206 = imageAtomicAdd(_26[nonuniformEXT(_196)], int((gl_GlobalInvocationID.y < _13._m0[_196].y) ? (gl_GlobalInvocationID.y + _13._m0[_196].x) : 4294967295u), 40u);\n    uint _213 = imageAtomicCompSwap(_26[nonuniformEXT(_196)], int((gl_GlobalInvocationID.y < _13._m0[_196].y) ? (gl_GlobalInvocationID.y + _13._m0[_196].x) : 4294967295u), 40u, 70u);\n    imageStore(_22[registers._m4], int((2u < _13._m0[_47].y) ? (2u + _13._m0[_47].x) : 4294967295u), vec4(float(_13._m0[_148].y)));\n    imageStore(_22[registers._m4], int((3u < _13._m0[_47].y) ? (3u + _13._m0[_47].x) : 4294967295u), vec4(float(_13._m0[_172].y)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 233\n; Schema: 0\nOpCapability Shader\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability ImageQuery\nOpCapability StorageImageWriteWithoutFormat\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability UniformTexelBufferArrayNonUniformIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %62\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %18 DescriptorSet 1\nOpDecorate %18 Binding 0\nOpDecorate %22 DescriptorSet 4\nOpDecorate %22 Binding 0\nOpDecorate %26 DescriptorSet 4\nOpDecorate %26 Binding 0\nOpDecorate %62 BuiltIn GlobalInvocationId\nOpDecorate %148 NonUniform\nOpDecorate %149 NonUniform\nOpDecorate %172 NonUniform\nOpDecorate %173 NonUniform\nOpDecorate %196 NonUniform\nOpDecorate %197 NonUniform\nOpDecorate %205 NonUniform\nOpDecorate %212 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFloat 32\n%15 = OpTypeImage %14 Buffer 0 0 0 1 Unknown\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypeImage %14 Buffer 0 0 0 2 R32f\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypePointer UniformConstant %23\n%29 = OpTypePointer PushConstant %5\n%31 = OpConstant %5 4\n%34 = OpConstant %5 2\n%37 = OpConstant %5 3\n%38 = OpTypePointer StorageBuffer %9\n%40 = OpConstant %5 0\n%42 = OpTypePointer UniformConstant %19\n%50 = OpTypePointer UniformConstant %15\n%53 = OpConstant %5 1\n%60 = OpTypeVector %5 3\n%61 = OpTypePointer Input %60\n%62 = OpVariable %61 Input\n%63 = OpTypePointer Input %5\n%74 = OpTypeBool\n%77 = OpConstant %5 4294967295\n%78 = OpTypeVector %14 4\n%85 = OpConstant %5 1024\n%104 = OpConstant %5 2048\n%116 = OpTypePointer Image %5\n%119 = OpConstant %5 40\n%127 = OpConstant %5 50\n%214 = OpConstant %5 70\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %231\n%231 = OpLabel\n%30 = OpAccessChain %29 %8 %31\n%32 = OpLoad %5 %30\n%33 = OpIAdd %5 %32 %34\n%28 = OpAccessChain %27 %26 %33\n%35 = OpLoad %23 %28\n%36 = OpGroupNonUniformBroadcastFirst %5 %37 %33\n%39 = OpAccessChain %38 %13 %40 %36\n%41 = OpLoad %9 %39\n%44 = OpAccessChain %29 %8 %31\n%45 = OpLoad %5 %44\n%43 = OpAccessChain %42 %22 %45\n%46 = OpLoad %19 %43\n%47 = OpGroupNonUniformBroadcastFirst %5 %37 %45\n%48 = OpAccessChain %38 %13 %40 %47\n%49 = OpLoad %9 %48\n%52 = OpAccessChain %29 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpIAdd %5 %54 %53\n%51 = OpAccessChain %50 %18 %55\n%56 = OpLoad %15 %51\n%57 = OpGroupNonUniformBroadcastFirst %5 %37 %55\n%58 = OpAccessChain %38 %13 %40 %57\n%59 = OpLoad %9 %58\n%64 = OpAccessChain %63 %62 %40\n%65 = OpLoad %5 %64\n%66 = OpAccessChain %63 %62 %53\n%67 = OpLoad %5 %66\n%68 = OpAccessChain %63 %62 %34\n%69 = OpLoad %5 %68\n%70 = OpIAdd %5 %65 %31\n%71 = OpCompositeExtract %5 %49 0\n%72 = OpCompositeExtract %5 %49 1\n%73 = OpIAdd %5 %70 %71\n%75 = OpULessThan %74 %70 %72\n%76 = OpSelect %5 %75 %73 %77\n%79 = OpImageRead %78 %46 %76\n%80 = OpCompositeExtract %14 %79 0\n%81 = OpCompositeExtract %14 %79 1\n%82 = OpCompositeExtract %14 %79 2\n%83 = OpCompositeExtract %14 %79 3\n%84 = OpIAdd %5 %65 %85\n%86 = OpCompositeExtract %5 %49 0\n%87 = OpCompositeExtract %5 %49 1\n%88 = OpIAdd %5 %84 %86\n%89 = OpULessThan %74 %84 %87\n%90 = OpSelect %5 %89 %88 %77\n%91 = OpCompositeConstruct %78 %80 %81 %82 %83\nOpImageWrite %46 %90 %91\n%92 = OpIAdd %5 %65 %34\n%93 = OpCompositeExtract %5 %59 0\n%94 = OpCompositeExtract %5 %59 1\n%95 = OpIAdd %5 %92 %93\n%96 = OpULessThan %74 %92 %94\n%97 = OpSelect %5 %96 %95 %77\n%98 = OpImageFetch %78 %56 %97\n%99 = OpCompositeExtract %14 %98 0\n%100 = OpCompositeExtract %14 %98 1\n%101 = OpCompositeExtract %14 %98 2\n%102 = OpCompositeExtract %14 %98 3\n%103 = OpIAdd %5 %65 %104\n%105 = OpCompositeExtract %5 %49 0\n%106 = OpCompositeExtract %5 %49 1\n%107 = OpIAdd %5 %103 %105\n%108 = OpULessThan %74 %103 %106\n%109 = OpSelect %5 %108 %107 %77\n%110 = OpCompositeConstruct %78 %99 %100 %101 %102\nOpImageWrite %46 %109 %110\n%111 = OpCompositeExtract %5 %41 0\n%112 = OpCompositeExtract %5 %41 1\n%113 = OpIAdd %5 %65 %111\n%114 = OpULessThan %74 %65 %112\n%115 = OpSelect %5 %114 %113 %77\n%117 = OpImageTexelPointer %116 %28 %115 %40\n%118 = OpAtomicIAdd %5 %117 %53 %40 %119\n%120 = OpCompositeExtract %5 %41 0\n%121 = OpCompositeExtract %5 %41 1\n%122 = OpIAdd %5 %67 %120\n%123 = OpULessThan %74 %67 %121\n%124 = OpSelect %5 %123 %122 %77\n%125 = OpImageTexelPointer %116 %28 %124 %40\n%126 = OpAtomicCompareExchange %5 %125 %53 %40 %40 %127 %119\n%128 = OpCompositeExtract %5 %49 1\n%129 = OpConvertUToF %14 %128\n%130 = OpCompositeExtract %5 %49 0\n%131 = OpCompositeExtract %5 %49 1\n%132 = OpIAdd %5 %40 %130\n%133 = OpULessThan %74 %40 %131\n%134 = OpSelect %5 %133 %132 %77\n%135 = OpCompositeConstruct %78 %129 %129 %129 %129\nOpImageWrite %46 %134 %135\n%136 = OpCompositeExtract %5 %59 1\n%137 = OpConvertUToF %14 %136\n%138 = OpCompositeExtract %5 %49 0\n%139 = OpCompositeExtract %5 %49 1\n%140 = OpIAdd %5 %53 %138\n%141 = OpULessThan %74 %53 %139\n%142 = OpSelect %5 %141 %140 %77\n%143 = OpCompositeConstruct %78 %137 %137 %137 %137\nOpImageWrite %46 %142 %143\n%144 = OpIAdd %5 %69 %40\n%146 = OpAccessChain %29 %8 %31\n%147 = OpLoad %5 %146\n%148 = OpIAdd %5 %147 %144\n%145 = OpAccessChain %42 %22 %148\n%149 = OpLoad %19 %145\n%150 = OpAccessChain %38 %13 %40 %148\n%151 = OpLoad %9 %150\n%152 = OpCompositeExtract %5 %151 0\n%153 = OpCompositeExtract %5 %151 1\n%154 = OpIAdd %5 %70 %152\n%155 = OpULessThan %74 %70 %153\n%156 = OpSelect %5 %155 %154 %77\n%157 = OpImageRead %78 %149 %156\n%158 = OpCompositeExtract %14 %157 0\n%159 = OpCompositeExtract %14 %157 1\n%160 = OpCompositeExtract %14 %157 2\n%161 = OpCompositeExtract %14 %157 3\n%162 = OpCompositeExtract %5 %151 0\n%163 = OpCompositeExtract %5 %151 1\n%164 = OpIAdd %5 %84 %162\n%165 = OpULessThan %74 %84 %163\n%166 = OpSelect %5 %165 %164 %77\n%167 = OpCompositeConstruct %78 %158 %159 %160 %161\nOpImageWrite %149 %166 %167\n%168 = OpIAdd %5 %69 %40\n%170 = OpAccessChain %29 %8 %53\n%171 = OpLoad %5 %170\n%172 = OpIAdd %5 %171 %168\n%169 = OpAccessChain %50 %18 %172\n%173 = OpLoad %15 %169\n%174 = OpAccessChain %38 %13 %40 %172\n%175 = OpLoad %9 %174\n%176 = OpCompositeExtract %5 %175 0\n%177 = OpCompositeExtract %5 %175 1\n%178 = OpIAdd %5 %70 %176\n%179 = OpULessThan %74 %70 %177\n%180 = OpSelect %5 %179 %178 %77\n%181 = OpImageFetch %78 %173 %180\n%182 = OpCompositeExtract %14 %181 0\n%183 = OpCompositeExtract %14 %181 1\n%184 = OpCompositeExtract %14 %181 2\n%185 = OpCompositeExtract %14 %181 3\n%186 = OpCompositeExtract %5 %151 0\n%187 = OpCompositeExtract %5 %151 1\n%188 = OpIAdd %5 %103 %186\n%189 = OpULessThan %74 %103 %187\n%190 = OpSelect %5 %189 %188 %77\n%191 = OpCompositeConstruct %78 %182 %183 %184 %185\nOpImageWrite %149 %190 %191\n%192 = OpIAdd %5 %69 %40\n%194 = OpAccessChain %29 %8 %31\n%195 = OpLoad %5 %194\n%196 = OpIAdd %5 %195 %192\n%193 = OpAccessChain %27 %26 %196\n%197 = OpLoad %23 %193\n%198 = OpAccessChain %38 %13 %40 %196\n%199 = OpLoad %9 %198\n%200 = OpCompositeExtract %5 %199 0\n%201 = OpCompositeExtract %5 %199 1\n%202 = OpIAdd %5 %67 %200\n%203 = OpULessThan %74 %67 %201\n%204 = OpSelect %5 %203 %202 %77\n%205 = OpImageTexelPointer %116 %193 %204 %40\n%206 = OpAtomicIAdd %5 %205 %53 %40 %119\n%207 = OpCompositeExtract %5 %199 0\n%208 = OpCompositeExtract %5 %199 1\n%209 = OpIAdd %5 %67 %207\n%210 = OpULessThan %74 %67 %208\n%211 = OpSelect %5 %210 %209 %77\n%212 = OpImageTexelPointer %116 %193 %211 %40\n%213 = OpAtomicCompareExchange %5 %212 %53 %40 %40 %214 %119\n%215 = OpCompositeExtract %5 %151 1\n%216 = OpConvertUToF %14 %215\n%217 = OpCompositeExtract %5 %49 0\n%218 = OpCompositeExtract %5 %49 1\n%219 = OpIAdd %5 %34 %217\n%220 = OpULessThan %74 %34 %218\n%221 = OpSelect %5 %220 %219 %77\n%222 = OpCompositeConstruct %78 %216 %216 %216 %216\nOpImageWrite %46 %221 %222\n%223 = OpCompositeExtract %5 %175 1\n%224 = OpConvertUToF %14 %223\n%225 = OpCompositeExtract %5 %49 0\n%226 = OpCompositeExtract %5 %49 1\n%227 = OpIAdd %5 %37 %225\n%228 = OpULessThan %74 %37 %226\n%229 = OpSelect %5 %228 %227 %77\n%230 = OpCompositeConstruct %78 %224 %224 %224 %224\nOpImageWrite %46 %229 %230\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/ssbo-minprecision.sm60.native-fp16.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n\nlayout(set = 0, binding = 0) uniform usamplerBuffer _8;\nlayout(set = 0, binding = 1) uniform usamplerBuffer _9;\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _12;\nlayout(set = 0, binding = 1, r32ui) uniform writeonly uimageBuffer _13;\n\nlayout(location = 0) flat in mediump int A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint16_t _25 = uint16_t(A);\n    uint _26 = uint(int16_t(_25));\n    uint _36 = uint(int16_t(_25 + 1us));\n    imageStore(_12, int(_26), uvec4(floatBitsToUint(float(float16_t(uintBitsToFloat(texelFetch(_8, int(_36)).x)) + float16_t(uintBitsToFloat(texelFetch(_8, int(_26)).x))))));\n    imageStore(_13, int(_26), uvec4(uint(uint16_t(texelFetch(_9, int(_36)).x) + uint16_t(texelFetch(_9, int(_26)).x))));\n    SV_Target = int(10u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 58\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %16 \"A\"\nOpName %18 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonReadable\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %18 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpVariable %11 UniformConstant\n%14 = OpTypeInt 32 1\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %14\n%18 = OpVariable %17 Output\n%24 = OpTypeInt 16 0\n%27 = OpTypeVector %5 4\n%30 = OpTypeFloat 32\n%32 = OpTypeFloat 16\n%35 = OpConstant %24 1\n%54 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %56\n%56 = OpLabel\n%19 = OpLoad %10 %13\n%20 = OpLoad %10 %12\n%21 = OpLoad %6 %9\n%22 = OpLoad %6 %8\n%23 = OpLoad %14 %16\n%25 = OpSConvert %24 %23\n%26 = OpSConvert %5 %25\n%28 = OpImageFetch %27 %22 %26\n%29 = OpCompositeExtract %5 %28 0\n%31 = OpBitcast %30 %29\n%33 = OpFConvert %32 %31\n%34 = OpIAdd %24 %25 %35\n%36 = OpSConvert %5 %34\n%37 = OpImageFetch %27 %22 %36\n%38 = OpCompositeExtract %5 %37 0\n%39 = OpBitcast %30 %38\n%40 = OpFConvert %32 %39\n%41 = OpFAdd %32 %40 %33\n%42 = OpFConvert %30 %41\n%43 = OpBitcast %5 %42\n%44 = OpCompositeConstruct %27 %43 %43 %43 %43\nOpImageWrite %20 %26 %44\n%45 = OpImageFetch %27 %21 %26\n%46 = OpCompositeExtract %5 %45 0\n%47 = OpUConvert %24 %46\n%48 = OpImageFetch %27 %21 %36\n%49 = OpCompositeExtract %5 %48 0\n%50 = OpUConvert %24 %49\n%51 = OpIAdd %24 %50 %47\n%52 = OpUConvert %5 %51\n%53 = OpCompositeConstruct %27 %52 %52 %52 %52\nOpImageWrite %19 %26 %53\n%55 = OpBitcast %14 %54\nOpStore %18 %55\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/ssbo-minprecision.sm60.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nlayout(location = 0) flat in mediump int A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint16_t _21 = uint16_t(A);\n    uint _22 = uint(int16_t(_21));\n    float _28 = uintBitsToFloat(_9._m0[_22]);\n    mediump float mp_copy_28 = _28;\n    float _34 = uintBitsToFloat(_9._m0[uint(int16_t(_21 + 1us))]);\n    mediump float mp_copy_34 = _34;\n    _13._m0[_22] = floatBitsToUint(mp_copy_34 + mp_copy_28);\n    SV_Target = int(10u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %16 \"A\"\nOpName %18 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 NonReadable\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %18 Location 0\nOpDecorate %35 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 32 1\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %14\n%18 = OpVariable %17 Output\n%20 = OpTypeInt 16 0\n%23 = OpTypePointer StorageBuffer %5\n%25 = OpConstant %5 0\n%27 = OpTypeFloat 32\n%30 = OpConstant %20 1\n%38 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%19 = OpLoad %14 %16\n%21 = OpSConvert %20 %19\n%22 = OpSConvert %5 %21\n%24 = OpAccessChain %23 %9 %25 %22\n%26 = OpLoad %5 %24\n%28 = OpBitcast %27 %26\n%29 = OpIAdd %20 %21 %30\n%31 = OpSConvert %5 %29\n%32 = OpAccessChain %23 %9 %25 %31\n%33 = OpLoad %5 %32\n%34 = OpBitcast %27 %33\n%35 = OpFAdd %27 %34 %28\n%36 = OpBitcast %5 %35\n%37 = OpAccessChain %23 %13 %25 %22\nOpStore %37 %36\n%39 = OpBitcast %14 %38\nOpStore %18 %39\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/ssbo-minprecision.sm60.ssbo.native-fp16.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _15_17\n{\n    uint _m0[];\n} _17;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _19_21\n{\n    uint _m0[];\n} _21;\n\nlayout(location = 0) flat in mediump int A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint16_t _29 = uint16_t(A);\n    uint _30 = uint(int16_t(_29));\n    uint _41 = uint(int16_t(_29 + 1us));\n    _17._m0[_30] = floatBitsToUint(float(float16_t(uintBitsToFloat(_9._m0[_41])) + float16_t(uintBitsToFloat(_9._m0[_30]))));\n    _21._m0[_30] = uint(uint16_t(_13._m0[_41]) + uint16_t(_13._m0[_30]));\n    SV_Target = int(10u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 63\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %24 %26\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %11 \"SSBO\"\nOpName %15 \"SSBO\"\nOpName %19 \"SSBO\"\nOpName %24 \"A\"\nOpName %26 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %14 ArrayStride 4\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 NonReadable\nOpDecorate %18 ArrayStride 4\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %19 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 1\nOpDecorate %21 NonReadable\nOpDecorate %24 RelaxedPrecision\nOpDecorate %24 Flat\nOpDecorate %24 Location 0\nOpDecorate %26 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeRuntimeArray %5\n%15 = OpTypeStruct %14\n%16 = OpTypePointer StorageBuffer %15\n%17 = OpVariable %16 StorageBuffer\n%18 = OpTypeRuntimeArray %5\n%19 = OpTypeStruct %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpTypeInt 32 1\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpTypePointer Output %22\n%26 = OpVariable %25 Output\n%28 = OpTypeInt 16 0\n%31 = OpTypePointer StorageBuffer %5\n%33 = OpConstant %5 0\n%35 = OpTypeFloat 32\n%37 = OpTypeFloat 16\n%40 = OpConstant %28 1\n%59 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%27 = OpLoad %22 %24\n%29 = OpSConvert %28 %27\n%30 = OpSConvert %5 %29\n%32 = OpAccessChain %31 %9 %33 %30\n%34 = OpLoad %5 %32\n%36 = OpBitcast %35 %34\n%38 = OpFConvert %37 %36\n%39 = OpIAdd %28 %29 %40\n%41 = OpSConvert %5 %39\n%42 = OpAccessChain %31 %9 %33 %41\n%43 = OpLoad %5 %42\n%44 = OpBitcast %35 %43\n%45 = OpFConvert %37 %44\n%46 = OpFAdd %37 %45 %38\n%47 = OpFConvert %35 %46\n%48 = OpBitcast %5 %47\n%49 = OpAccessChain %31 %17 %33 %30\nOpStore %49 %48\n%50 = OpAccessChain %31 %13 %33 %30\n%51 = OpLoad %5 %50\n%52 = OpUConvert %28 %51\n%53 = OpAccessChain %31 %13 %33 %41\n%54 = OpLoad %5 %53\n%55 = OpUConvert %28 %54\n%56 = OpIAdd %28 %55 %52\n%57 = OpUConvert %5 %56\n%58 = OpAccessChain %31 %21 %33 %30\nOpStore %58 %57\n%60 = OpBitcast %22 %59\nOpStore %26 %60\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/ssbo-minprecision.sm60.ssbo.native-fp16.root-descriptor.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloatNonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatArray;\nlayout(buffer_reference) buffer PhysicalPointerUintArray;\n\nfloat16_t _57;\nuint16_t _73;\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerFloatNonWriteArray\n{\n    float value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerFloatArray\n{\n    float value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerUintArray\n{\n    uint value[];\n};\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _13;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) flat in mediump int A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint16_t _31 = uint16_t(A);\n    uint _32 = uint(int16_t(_31));\n    uint _46 = uint(int16_t(_31 + 1us));\n    PhysicalPointerFloatArray(registers._m2).value[_32] = float(float16_t(PhysicalPointerFloatNonWriteArray(registers._m1).value[_46]) + float16_t(PhysicalPointerFloatNonWriteArray(registers._m1).value[_32]));\n    PhysicalPointerUintArray(registers._m3).value[_32] = uint(uint16_t(_13._m0[_46]) + uint16_t(_13._m0[_32]));\n    SV_Target = int(10u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability DenormPreserve\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %11 \"SSBO\"\nOpName %16 \"A\"\nOpName %18 \"SV_Target\"\nOpName %35 \"PhysicalPointerFloatNonWriteArray\"\nOpMemberName %35 0 \"value\"\nOpName %53 \"PhysicalPointerFloatArray\"\nOpMemberName %53 0 \"value\"\nOpName %68 \"PhysicalPointerUintArray\"\nOpMemberName %68 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %10 ArrayStride 4\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 1\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %18 Location 0\nOpDecorate %34 ArrayStride 4\nOpMemberDecorate %35 0 Offset 0\nOpDecorate %35 Block\nOpMemberDecorate %35 0 NonWritable\nOpDecorate %52 ArrayStride 4\nOpMemberDecorate %53 0 Offset 0\nOpDecorate %53 Block\nOpDecorate %67 ArrayStride 4\nOpMemberDecorate %68 0 Offset 0\nOpDecorate %68 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeRuntimeArray %5\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 32 1\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %14\n%18 = OpVariable %17 Output\n%19 = OpTypePointer PushConstant %6\n%21 = OpConstant %5 3\n%24 = OpConstant %5 2\n%27 = OpConstant %5 1\n%30 = OpTypeInt 16 0\n%33 = OpTypeFloat 32\n%34 = OpTypeRuntimeArray %33\n%35 = OpTypeStruct %34\n%36 = OpTypePointer PhysicalStorageBuffer %35\n%38 = OpTypePointer PhysicalStorageBuffer %33\n%40 = OpConstant %5 0\n%42 = OpTypeFloat 16\n%45 = OpConstant %30 1\n%52 = OpTypeRuntimeArray %33\n%53 = OpTypeStruct %52\n%54 = OpTypePointer PhysicalStorageBuffer %53\n%59 = OpTypePointer StorageBuffer %5\n%67 = OpTypeRuntimeArray %5\n%68 = OpTypeStruct %67\n%69 = OpTypePointer PhysicalStorageBuffer %68\n%71 = OpTypePointer PhysicalStorageBuffer %5\n%75 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%57 = OpUndef %42\n%73 = OpUndef %30\nOpBranch %77\n%77 = OpLabel\n%20 = OpAccessChain %19 %9 %21\n%22 = OpLoad %6 %20\n%23 = OpAccessChain %19 %9 %24\n%25 = OpLoad %6 %23\n%26 = OpAccessChain %19 %9 %27\n%28 = OpLoad %6 %26\n%29 = OpLoad %14 %16\n%31 = OpSConvert %30 %29\n%32 = OpSConvert %5 %31\n%37 = OpBitcast %36 %28\n%39 = OpInBoundsAccessChain %38 %37 %40 %32\n%41 = OpLoad %33 %39 Aligned 4\n%43 = OpFConvert %42 %41\n%44 = OpIAdd %30 %31 %45\n%46 = OpSConvert %5 %44\n%47 = OpBitcast %36 %28\n%48 = OpInBoundsAccessChain %38 %47 %40 %46\n%49 = OpLoad %33 %48 Aligned 4\n%50 = OpFConvert %42 %49\n%51 = OpFAdd %42 %50 %43\n%55 = OpBitcast %54 %25\n%56 = OpInBoundsAccessChain %38 %55 %40 %32\n%58 = OpFConvert %33 %51\nOpStore %56 %58 Aligned 4\n%60 = OpAccessChain %59 %13 %40 %32\n%61 = OpLoad %5 %60\n%62 = OpUConvert %30 %61\n%63 = OpAccessChain %59 %13 %40 %46\n%64 = OpLoad %5 %63\n%65 = OpUConvert %30 %64\n%66 = OpIAdd %30 %65 %62\n%70 = OpBitcast %69 %22\n%72 = OpInBoundsAccessChain %71 %70 %40 %32\n%74 = OpUConvert %5 %66\nOpStore %72 %74 Aligned 4\n%76 = OpBitcast %14 %75\nOpStore %18 %76\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/ssbo-minprecision.sm60.ssbo.root-descriptor.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer PhysicalPointerFloatNonWriteArray;\nlayout(buffer_reference) buffer PhysicalPointerFloatArray;\n\nfloat _47;\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerFloatNonWriteArray\n{\n    float value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer PhysicalPointerFloatArray\n{\n    float value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nlayout(location = 0) flat in mediump int A;\nlayout(location = 0) out int SV_Target;\n\nvoid main()\n{\n    uint16_t _24 = uint16_t(A);\n    uint _25 = uint(int16_t(_24));\n    float _34 = PhysicalPointerFloatNonWriteArray(registers._m1).value[_25];\n    mediump float mp_copy_34 = _34;\n    float _40 = PhysicalPointerFloatNonWriteArray(registers._m1).value[uint(int16_t(_24 + 1us))];\n    mediump float mp_copy_40 = _40;\n    PhysicalPointerFloatArray(registers._m2).value[_25] = mp_copy_40 + mp_copy_34;\n    SV_Target = int(10u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %14\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"A\"\nOpName %14 \"SV_Target\"\nOpName %28 \"PhysicalPointerFloatNonWriteArray\"\nOpMemberName %28 0 \"value\"\nOpName %43 \"PhysicalPointerFloatArray\"\nOpMemberName %43 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %14 Location 0\nOpDecorate %27 ArrayStride 4\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %28 Block\nOpMemberDecorate %28 0 NonWritable\nOpDecorate %41 RelaxedPrecision\nOpDecorate %42 ArrayStride 4\nOpMemberDecorate %43 0 Offset 0\nOpDecorate %43 Block\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeInt 32 1\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Output %10\n%14 = OpVariable %13 Output\n%15 = OpTypePointer PushConstant %6\n%17 = OpConstant %5 2\n%20 = OpConstant %5 1\n%23 = OpTypeInt 16 0\n%26 = OpTypeFloat 32\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypeStruct %27\n%29 = OpTypePointer PhysicalStorageBuffer %28\n%31 = OpTypePointer PhysicalStorageBuffer %26\n%33 = OpConstant %5 0\n%36 = OpConstant %23 1\n%42 = OpTypeRuntimeArray %26\n%43 = OpTypeStruct %42\n%44 = OpTypePointer PhysicalStorageBuffer %43\n%48 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%47 = OpUndef %26\nOpBranch %50\n%50 = OpLabel\n%16 = OpAccessChain %15 %9 %17\n%18 = OpLoad %6 %16\n%19 = OpAccessChain %15 %9 %20\n%21 = OpLoad %6 %19\n%22 = OpLoad %10 %12\n%24 = OpSConvert %23 %22\n%25 = OpSConvert %5 %24\n%30 = OpBitcast %29 %21\n%32 = OpInBoundsAccessChain %31 %30 %33 %25\n%34 = OpLoad %26 %32 Aligned 4\n%35 = OpIAdd %23 %24 %36\n%37 = OpSConvert %5 %35\n%38 = OpBitcast %29 %21\n%39 = OpInBoundsAccessChain %31 %38 %33 %37\n%40 = OpLoad %26 %39 Aligned 4\n%41 = OpFAdd %26 %40 %34\n%45 = OpBitcast %44 %18\n%46 = OpInBoundsAccessChain %31 %45 %33 %25\nOpStore %46 %41 Aligned 4\n%49 = OpBitcast %10 %48\nOpStore %14 %49\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/subobject-parsing.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nvoid main()\n{\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 7\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\"\nOpName %3 \"main\"\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %5\n%5 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n#if 0\n==== RDAT ====\nShaderConfig sconf = { maxPayloadSize = 80, maxAttributeSize = 60 };\nRaytracingPipelineConfig1 pconf0 = { maxRecursion = 4, flags = 0 };\nRaytracingPipelineConfig1 pconf1 = { maxRecursion = 5, flags = 256 };\nShaderConfig soc = { flags = 1 };\nTriangleHitGroup tri_hg = { ahit = \"a\", chit = \"b\", intersection = \"\" };\nTriangleHitGroup tri_hg2 = { ahit = \"\", chit = \"b\", intersection = \"\" };\nProceduralHitGroup aabb_hg = { ahit = \"c\", chit = \"d\", intersection = \"e\" };\nSubobjectToExportsAssociation assoc1 = { A, { foo, bar, meow, nyaa, frog } };\nSubobjectToExportsAssociation assoc2 = { B, { meep, frog } };\n============\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/typed-resources-16bit-sparse.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_ARB_sparse_texture2 : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _74\n{\n    float16_t _m0;\n    float16_t _m1;\n    float16_t _m2;\n    float16_t _m3;\n    uint _m4;\n};\n\nstruct SparseTexel_1\n{\n    uint _m0;\n    ivec4 _m1;\n};\n\nstruct _98\n{\n    uint16_t _m0;\n    uint16_t _m1;\n    uint16_t _m2;\n    uint16_t _m3;\n    uint _m4;\n};\n\nstruct SparseTexel_2\n{\n    uint _m0;\n    uvec4 _m1;\n};\n\nstruct SparseTexel_3\n{\n    uint _m0;\n    float _m1;\n};\n\nstruct _204\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _8;\nlayout(set = 0, binding = 1) uniform mediump itexture2D _12;\nlayout(set = 0, binding = 2) uniform mediump utexture2D _16;\nlayout(set = 0, binding = 3) uniform mediump samplerBuffer _19;\nlayout(set = 0, binding = 4) uniform mediump isamplerBuffer _22;\nlayout(set = 0, binding = 5) uniform mediump usamplerBuffer _25;\nlayout(set = 0, binding = 0) uniform sampler _28;\nlayout(set = 0, binding = 1) uniform samplerShadow _29;\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out mediump vec4 SV_Target;\nlayout(location = 1) out mediump ivec4 SV_Target_1;\nlayout(location = 2) out mediump uvec4 SV_Target_2;\nlayout(location = 3) out uint SV_Target_3;\n\nvoid main()\n{\n    uint _422;\n    vec4 _423;\n    _422 = sparseTextureARB(sampler2D(_8, _28), vec2(UV.x, UV.y), _423);\n    SparseTexel _63 = SparseTexel(_422, _423);\n    f16vec4 _69 = f16vec4(_63._m1);\n    _74 _75 = _74(_69.x, _69.y, _69.z, _69.w, _63._m0);\n    uint _424;\n    ivec4 _425;\n    _424 = sparseTexelFetchARB(_12, ivec2(uvec2(1u, 2u)), int(3u), _425);\n    SparseTexel_1 _86 = SparseTexel_1(_424, _425);\n    u16vec4 _93 = u16vec4(_86._m1);\n    _98 _99 = _98(_93.x, _93.y, _93.z, _93.w, _86._m0);\n    uint _426;\n    uvec4 _427;\n    _426 = sparseTexelFetchARB(_16, ivec2(uvec2(4u, 5u)), int(6u), _427);\n    SparseTexel_2 _111 = SparseTexel_2(_426, _427);\n    u16vec4 _115 = u16vec4(_111._m1);\n    _98 _120 = _98(_115.x, _115.y, _115.z, _115.w, _111._m0);\n    uint _428;\n    vec4 _429;\n    _428 = sparseTextureGatherARB(sampler2D(_8, _28), vec2(UV.x, UV.y), _429);\n    SparseTexel _129 = SparseTexel(_428, _429);\n    f16vec4 _132 = f16vec4(_129._m1);\n    _74 _137 = _74(_132.x, _132.y, _132.z, _132.w, _129._m0);\n    uint _430;\n    ivec4 _431;\n    _430 = sparseTextureGatherARB(isampler2D(_12, _28), vec2(UV.x, UV.y), _431, int(1u));\n    SparseTexel_1 _152 = SparseTexel_1(_430, _431);\n    u16vec4 _155 = u16vec4(_152._m1);\n    _98 _160 = _98(_155.x, _155.y, _155.z, _155.w, _152._m0);\n    uint _432;\n    uvec4 _433;\n    _432 = sparseTextureGatherARB(usampler2D(_16, _28), vec2(UV.x, UV.y), _433, int(2u));\n    SparseTexel_2 _175 = SparseTexel_2(_432, _433);\n    u16vec4 _178 = u16vec4(_175._m1);\n    _98 _183 = _98(_178.x, _178.y, _178.z, _178.w, _175._m0);\n    uint _434;\n    float _435;\n    _434 = sparseTextureARB(sampler2DShadow(_8, _29), vec3(vec2(UV.x, UV.y), 0.5), _435);\n    SparseTexel_3 _200 = SparseTexel_3(_434, _435);\n    mediump float _203 = _200._m1;\n    _204 _205 = _204(_203, _203, _203, _203, _200._m0);\n    mediump float _206 = _205._m0;\n    float _213 = _206 + float(_137._m0 + _75._m0);\n    float _214 = _206 + float(_137._m1 + _75._m1);\n    float _215 = _206 + float(_137._m2 + _75._m2);\n    float _216 = _206 + float(_137._m3 + _75._m3);\n    uint _436;\n    float _437;\n    _436 = sparseTextureLodARB(sampler2DShadow(_8, _29), vec3(vec2(UV.x, UV.y), 0.5), 0.0, _437);\n    SparseTexel_3 _222 = SparseTexel_3(_436, _437);\n    mediump float _225 = _222._m1;\n    _204 _226 = _204(_225, _225, _225, _225, _222._m0);\n    mediump float _227 = _226._m0;\n    vec2 _243 = vec2(UV.x, UV.y);\n    uint _438;\n    vec4 _439;\n    _438 = sparseTextureGatherARB(sampler2DShadow(_8, _29), _243, 0.5, _439);\n    SparseTexel _244 = SparseTexel(_438, _439);\n    f16vec4 _247 = f16vec4(_244._m1);\n    _74 _252 = _74(_247.x, _247.y, _247.z, _247.w, _244._m0);\n    uint _440;\n    vec4 _441;\n    _440 = sparseTextureLodARB(sampler2D(_8, _28), vec2(UV.x, UV.y), 0.0, _441);\n    SparseTexel _264 = SparseTexel(_440, _441);\n    f16vec4 _268 = f16vec4(_264._m1);\n    _74 _273 = _74(_268.x, _268.y, _268.z, _268.w, _264._m0);\n    uint _442;\n    vec4 _443;\n    _442 = sparseTextureGradARB(sampler2D(_8, _28), vec2(UV.x, UV.y), vec2(0.20000000298023223876953125, 0.300000011920928955078125), vec2(0.4000000059604644775390625, 0.5), _443);\n    SparseTexel _288 = SparseTexel(_442, _443);\n    f16vec4 _294 = f16vec4(_288._m1);\n    _74 _299 = _74(_294.x, _294.y, _294.z, _294.w, _288._m0);\n    uint _444;\n    vec4 _445;\n    _444 = sparseTextureARB(sampler2D(_8, _28), vec2(UV.x, UV.y), _445, 0.5);\n    SparseTexel _311 = SparseTexel(_444, _445);\n    f16vec4 _315 = f16vec4(_311._m1);\n    _74 _320 = _74(_315.x, _315.y, _315.z, _315.w, _311._m0);\n    uint _332 = uint(int(UV.x));\n    uint _446;\n    vec4 _447;\n    _446 = sparseTexelFetchARB(_19, int(_332), _447);\n    SparseTexel _333 = SparseTexel(_446, _447);\n    f16vec4 _336 = f16vec4(_333._m1);\n    _74 _341 = _74(_336.x, _336.y, _336.z, _336.w, _333._m0);\n    uint _448;\n    ivec4 _449;\n    _448 = sparseTexelFetchARB(_22, int(_332), _449);\n    SparseTexel_1 _353 = SparseTexel_1(_448, _449);\n    u16vec4 _356 = u16vec4(_353._m1);\n    _98 _361 = _98(_356.x, _356.y, _356.z, _356.w, _353._m0);\n    uint _450;\n    uvec4 _451;\n    _450 = sparseTexelFetchARB(_25, int(_332), _451);\n    SparseTexel_2 _373 = SparseTexel_2(_450, _451);\n    u16vec4 _376 = u16vec4(_373._m1);\n    _98 _381 = _98(_376.x, _376.y, _376.z, _376.w, _373._m0);\n    SV_Target.x = float(((((float16_t(unpackHalf2x16(packHalf2x16(vec2(_213))).x + _227) + _252._m0) + _273._m0) + _299._m0) + _320._m0) + _341._m0);\n    SV_Target.y = float(((((float16_t(unpackHalf2x16(packHalf2x16(vec2(_214))).x + _227) + _252._m1) + _273._m1) + _299._m1) + _320._m1) + _341._m1);\n    SV_Target.z = float(((((float16_t(unpackHalf2x16(packHalf2x16(vec2(_215))).x + _227) + _252._m2) + _273._m2) + _299._m2) + _320._m2) + _341._m2);\n    SV_Target.w = float(((((float16_t(unpackHalf2x16(packHalf2x16(vec2(_216))).x + _227) + _252._m3) + _273._m3) + _299._m3) + _320._m3) + _341._m3);\n    SV_Target_1.x = int(int16_t((_160._m0 + _99._m0) + _361._m0));\n    SV_Target_1.y = int(int16_t((_160._m1 + _99._m1) + _361._m1));\n    SV_Target_1.z = int(int16_t((_160._m2 + _99._m2) + _361._m2));\n    SV_Target_1.w = int(int16_t((_160._m3 + _99._m3) + _361._m3));\n    SV_Target_2.x = uint((_183._m0 + _120._m0) + _381._m0);\n    SV_Target_2.y = uint((_183._m1 + _120._m1) + _381._m1);\n    SV_Target_2.z = uint((_183._m2 + _120._m2) + _381._m2);\n    SV_Target_2.w = uint((_183._m3 + _120._m3) + _381._m3);\n    SV_Target_3 = uint((((((((((((((sparseTexelsResidentARB(int(_75._m4)) || sparseTexelsResidentARB(int(_99._m4))) || sparseTexelsResidentARB(int(_120._m4))) || sparseTexelsResidentARB(int(_137._m4))) || sparseTexelsResidentARB(int(_160._m4))) || sparseTexelsResidentARB(int(_183._m4))) || sparseTexelsResidentARB(int(_205._m4))) || sparseTexelsResidentARB(int(_226._m4))) || sparseTexelsResidentARB(int(_252._m4))) || sparseTexelsResidentARB(int(_273._m4))) || sparseTexelsResidentARB(int(_299._m4))) || sparseTexelsResidentARB(int(_320._m4))) || sparseTexelsResidentARB(int(_341._m4))) || sparseTexelsResidentARB(int(_361._m4))) || sparseTexelsResidentARB(int(_381._m4)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 422\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability SparseResidency\nOpCapability SampledBuffer\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %32 %35 %38 %41 %43\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %32 \"UV\"\nOpName %35 \"SV_Target\"\nOpName %38 \"SV_Target_1\"\nOpName %41 \"SV_Target_2\"\nOpName %43 \"SV_Target_3\"\nOpName %62 \"SparseTexel\"\nOpName %74 \"\"\nOpName %85 \"SparseTexel\"\nOpName %98 \"\"\nOpName %110 \"SparseTexel\"\nOpName %199 \"SparseTexel\"\nOpName %204 \"\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 2\nOpDecorate %19 RelaxedPrecision\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 3\nOpDecorate %22 RelaxedPrecision\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 4\nOpDecorate %25 RelaxedPrecision\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 5\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 1\nOpDecorate %32 Location 0\nOpDecorate %35 RelaxedPrecision\nOpDecorate %35 Location 0\nOpDecorate %38 RelaxedPrecision\nOpDecorate %38 Location 1\nOpDecorate %41 RelaxedPrecision\nOpDecorate %41 Location 2\nOpDecorate %43 Location 3\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 1\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeInt 32 0\n%14 = OpTypeImage %13 2D 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeSampler\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpVariable %27 UniformConstant\n%30 = OpTypeVector %5 2\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%33 = OpTypeVector %5 4\n%34 = OpTypePointer Output %33\n%35 = OpVariable %34 Output\n%36 = OpTypeVector %9 4\n%37 = OpTypePointer Output %36\n%38 = OpVariable %37 Output\n%39 = OpTypeVector %13 4\n%40 = OpTypePointer Output %39\n%41 = OpVariable %40 Output\n%42 = OpTypePointer Output %13\n%43 = OpVariable %42 Output\n%52 = OpTypePointer Input %5\n%54 = OpConstant %13 0\n%57 = OpConstant %13 1\n%59 = OpTypeSampledImage %6\n%61 = OpConstant %5 0\n%62 = OpTypeStruct %13 %33\n%67 = OpTypeFloat 16\n%68 = OpTypeVector %67 4\n%74 = OpTypeStruct %67 %67 %67 %67 %13\n%81 = OpTypeBool\n%83 = OpConstant %13 3\n%84 = OpConstant %13 2\n%85 = OpTypeStruct %13 %36\n%87 = OpTypeVector %13 2\n%91 = OpTypeInt 16 0\n%92 = OpTypeVector %91 4\n%98 = OpTypeStruct %91 %91 %91 %91 %13\n%107 = OpConstant %13 6\n%108 = OpConstant %13 4\n%109 = OpConstant %13 5\n%110 = OpTypeStruct %13 %39\n%149 = OpTypeSampledImage %10\n%172 = OpTypeSampledImage %14\n%195 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%196 = OpTypeSampledImage %195\n%198 = OpConstant %5 0.5\n%199 = OpTypeStruct %13 %5\n%204 = OpTypeStruct %5 %5 %5 %5 %13\n%285 = OpConstant %5 0.200000003\n%286 = OpConstant %5 0.300000012\n%287 = OpConstant %5 0.400000006\n%394 = OpTypePointer Output %5\n%403 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %420\n%420 = OpLabel\n%44 = OpLoad %23 %25\n%45 = OpLoad %20 %22\n%46 = OpLoad %17 %19\n%47 = OpLoad %14 %16\n%48 = OpLoad %10 %12\n%49 = OpLoad %6 %8\n%50 = OpLoad %26 %29\n%51 = OpLoad %26 %28\n%53 = OpAccessChain %52 %32 %54\n%55 = OpLoad %5 %53\n%56 = OpAccessChain %52 %32 %57\n%58 = OpLoad %5 %56\n%60 = OpSampledImage %59 %49 %51\n%64 = OpCompositeConstruct %30 %55 %58\n%63 = OpImageSparseSampleImplicitLod %62 %60 %64 None\n%65 = OpCompositeExtract %13 %63 0\n%66 = OpCompositeExtract %33 %63 1\n%69 = OpFConvert %68 %66\n%70 = OpCompositeExtract %67 %69 0\n%71 = OpCompositeExtract %67 %69 1\n%72 = OpCompositeExtract %67 %69 2\n%73 = OpCompositeExtract %67 %69 3\n%75 = OpCompositeConstruct %74 %70 %71 %72 %73 %65\n%76 = OpCompositeExtract %67 %75 0\n%77 = OpCompositeExtract %67 %75 1\n%78 = OpCompositeExtract %67 %75 2\n%79 = OpCompositeExtract %67 %75 3\n%80 = OpCompositeExtract %13 %75 4\n%82 = OpImageSparseTexelsResident %81 %80\n%88 = OpCompositeConstruct %87 %57 %84\n%86 = OpImageSparseFetch %85 %48 %88 Lod %83\n%89 = OpCompositeExtract %13 %86 0\n%90 = OpCompositeExtract %36 %86 1\n%93 = OpSConvert %92 %90\n%94 = OpCompositeExtract %91 %93 0\n%95 = OpCompositeExtract %91 %93 1\n%96 = OpCompositeExtract %91 %93 2\n%97 = OpCompositeExtract %91 %93 3\n%99 = OpCompositeConstruct %98 %94 %95 %96 %97 %89\n%100 = OpCompositeExtract %91 %99 0\n%101 = OpCompositeExtract %91 %99 1\n%102 = OpCompositeExtract %91 %99 2\n%103 = OpCompositeExtract %91 %99 3\n%104 = OpCompositeExtract %13 %99 4\n%105 = OpImageSparseTexelsResident %81 %104\n%106 = OpLogicalOr %81 %82 %105\n%112 = OpCompositeConstruct %87 %108 %109\n%111 = OpImageSparseFetch %110 %47 %112 Lod %107\n%113 = OpCompositeExtract %13 %111 0\n%114 = OpCompositeExtract %39 %111 1\n%115 = OpUConvert %92 %114\n%116 = OpCompositeExtract %91 %115 0\n%117 = OpCompositeExtract %91 %115 1\n%118 = OpCompositeExtract %91 %115 2\n%119 = OpCompositeExtract %91 %115 3\n%120 = OpCompositeConstruct %98 %116 %117 %118 %119 %113\n%121 = OpCompositeExtract %91 %120 0\n%122 = OpCompositeExtract %91 %120 1\n%123 = OpCompositeExtract %91 %120 2\n%124 = OpCompositeExtract %91 %120 3\n%125 = OpCompositeExtract %13 %120 4\n%126 = OpImageSparseTexelsResident %81 %125\n%127 = OpLogicalOr %81 %106 %126\n%128 = OpCompositeConstruct %30 %55 %58\n%129 = OpImageSparseGather %62 %60 %128 %54\n%130 = OpCompositeExtract %13 %129 0\n%131 = OpCompositeExtract %33 %129 1\n%132 = OpFConvert %68 %131\n%133 = OpCompositeExtract %67 %132 0\n%134 = OpCompositeExtract %67 %132 1\n%135 = OpCompositeExtract %67 %132 2\n%136 = OpCompositeExtract %67 %132 3\n%137 = OpCompositeConstruct %74 %133 %134 %135 %136 %130\n%138 = OpCompositeExtract %67 %137 0\n%139 = OpCompositeExtract %67 %137 1\n%140 = OpCompositeExtract %67 %137 2\n%141 = OpCompositeExtract %67 %137 3\n%142 = OpCompositeExtract %13 %137 4\n%143 = OpImageSparseTexelsResident %81 %142\n%144 = OpFAdd %67 %138 %76\n%145 = OpFAdd %67 %139 %77\n%146 = OpFAdd %67 %140 %78\n%147 = OpFAdd %67 %141 %79\n%148 = OpLogicalOr %81 %127 %143\n%150 = OpSampledImage %149 %48 %51\n%151 = OpCompositeConstruct %30 %55 %58\n%152 = OpImageSparseGather %85 %150 %151 %57\n%153 = OpCompositeExtract %13 %152 0\n%154 = OpCompositeExtract %36 %152 1\n%155 = OpSConvert %92 %154\n%156 = OpCompositeExtract %91 %155 0\n%157 = OpCompositeExtract %91 %155 1\n%158 = OpCompositeExtract %91 %155 2\n%159 = OpCompositeExtract %91 %155 3\n%160 = OpCompositeConstruct %98 %156 %157 %158 %159 %153\n%161 = OpCompositeExtract %91 %160 0\n%162 = OpCompositeExtract %91 %160 1\n%163 = OpCompositeExtract %91 %160 2\n%164 = OpCompositeExtract %91 %160 3\n%165 = OpCompositeExtract %13 %160 4\n%166 = OpImageSparseTexelsResident %81 %165\n%167 = OpIAdd %91 %161 %100\n%168 = OpIAdd %91 %162 %101\n%169 = OpIAdd %91 %163 %102\n%170 = OpIAdd %91 %164 %103\n%171 = OpLogicalOr %81 %148 %166\n%173 = OpSampledImage %172 %47 %51\n%174 = OpCompositeConstruct %30 %55 %58\n%175 = OpImageSparseGather %110 %173 %174 %84\n%176 = OpCompositeExtract %13 %175 0\n%177 = OpCompositeExtract %39 %175 1\n%178 = OpUConvert %92 %177\n%179 = OpCompositeExtract %91 %178 0\n%180 = OpCompositeExtract %91 %178 1\n%181 = OpCompositeExtract %91 %178 2\n%182 = OpCompositeExtract %91 %178 3\n%183 = OpCompositeConstruct %98 %179 %180 %181 %182 %176\n%184 = OpCompositeExtract %91 %183 0\n%185 = OpCompositeExtract %91 %183 1\n%186 = OpCompositeExtract %91 %183 2\n%187 = OpCompositeExtract %91 %183 3\n%188 = OpCompositeExtract %13 %183 4\n%189 = OpImageSparseTexelsResident %81 %188\n%190 = OpIAdd %91 %184 %121\n%191 = OpIAdd %91 %185 %122\n%192 = OpIAdd %91 %186 %123\n%193 = OpIAdd %91 %187 %124\n%194 = OpLogicalOr %81 %171 %189\n%197 = OpSampledImage %196 %49 %50\n%201 = OpCompositeConstruct %30 %55 %58\n%200 = OpImageSparseSampleDrefImplicitLod %199 %197 %201 %198 None\n%202 = OpCompositeExtract %13 %200 0\n%203 = OpCompositeExtract %5 %200 1\n%205 = OpCompositeConstruct %204 %203 %203 %203 %203 %202\n%206 = OpCompositeExtract %5 %205 0\n%207 = OpCompositeExtract %13 %205 4\n%208 = OpImageSparseTexelsResident %81 %207\n%209 = OpFConvert %5 %144\n%210 = OpFConvert %5 %145\n%211 = OpFConvert %5 %146\n%212 = OpFConvert %5 %147\n%213 = OpFAdd %5 %206 %209\n%214 = OpFAdd %5 %206 %210\n%215 = OpFAdd %5 %206 %211\n%216 = OpFAdd %5 %206 %212\n%217 = OpFConvert %67 %213\n%218 = OpFConvert %67 %214\n%219 = OpFConvert %67 %215\n%220 = OpFConvert %67 %216\n%221 = OpLogicalOr %81 %194 %208\n%223 = OpCompositeConstruct %30 %55 %58\n%222 = OpImageSparseSampleDrefExplicitLod %199 %197 %223 %198 Lod %61\n%224 = OpCompositeExtract %13 %222 0\n%225 = OpCompositeExtract %5 %222 1\n%226 = OpCompositeConstruct %204 %225 %225 %225 %225 %224\n%227 = OpCompositeExtract %5 %226 0\n%228 = OpCompositeExtract %13 %226 4\n%229 = OpImageSparseTexelsResident %81 %228\n%230 = OpQuantizeToF16 %5 %213\n%231 = OpQuantizeToF16 %5 %214\n%232 = OpQuantizeToF16 %5 %215\n%233 = OpQuantizeToF16 %5 %216\n%234 = OpFAdd %5 %230 %227\n%235 = OpFAdd %5 %231 %227\n%236 = OpFAdd %5 %232 %227\n%237 = OpFAdd %5 %233 %227\n%238 = OpFConvert %67 %234\n%239 = OpFConvert %67 %235\n%240 = OpFConvert %67 %236\n%241 = OpFConvert %67 %237\n%242 = OpLogicalOr %81 %221 %229\n%243 = OpCompositeConstruct %30 %55 %58\n%244 = OpImageSparseDrefGather %62 %197 %243 %198\n%245 = OpCompositeExtract %13 %244 0\n%246 = OpCompositeExtract %33 %244 1\n%247 = OpFConvert %68 %246\n%248 = OpCompositeExtract %67 %247 0\n%249 = OpCompositeExtract %67 %247 1\n%250 = OpCompositeExtract %67 %247 2\n%251 = OpCompositeExtract %67 %247 3\n%252 = OpCompositeConstruct %74 %248 %249 %250 %251 %245\n%253 = OpCompositeExtract %67 %252 0\n%254 = OpCompositeExtract %67 %252 1\n%255 = OpCompositeExtract %67 %252 2\n%256 = OpCompositeExtract %67 %252 3\n%257 = OpCompositeExtract %13 %252 4\n%258 = OpImageSparseTexelsResident %81 %257\n%259 = OpFAdd %67 %238 %253\n%260 = OpFAdd %67 %239 %254\n%261 = OpFAdd %67 %240 %255\n%262 = OpFAdd %67 %241 %256\n%263 = OpLogicalOr %81 %242 %258\n%265 = OpCompositeConstruct %30 %55 %58\n%264 = OpImageSparseSampleExplicitLod %62 %60 %265 Lod %61\n%266 = OpCompositeExtract %13 %264 0\n%267 = OpCompositeExtract %33 %264 1\n%268 = OpFConvert %68 %267\n%269 = OpCompositeExtract %67 %268 0\n%270 = OpCompositeExtract %67 %268 1\n%271 = OpCompositeExtract %67 %268 2\n%272 = OpCompositeExtract %67 %268 3\n%273 = OpCompositeConstruct %74 %269 %270 %271 %272 %266\n%274 = OpCompositeExtract %67 %273 0\n%275 = OpCompositeExtract %67 %273 1\n%276 = OpCompositeExtract %67 %273 2\n%277 = OpCompositeExtract %67 %273 3\n%278 = OpCompositeExtract %13 %273 4\n%279 = OpImageSparseTexelsResident %81 %278\n%280 = OpFAdd %67 %259 %274\n%281 = OpFAdd %67 %260 %275\n%282 = OpFAdd %67 %261 %276\n%283 = OpFAdd %67 %262 %277\n%284 = OpLogicalOr %81 %263 %279\n%289 = OpCompositeConstruct %30 %55 %58\n%290 = OpCompositeConstruct %30 %285 %286\n%291 = OpCompositeConstruct %30 %287 %198\n%288 = OpImageSparseSampleExplicitLod %62 %60 %289 Grad %290 %291\n%292 = OpCompositeExtract %13 %288 0\n%293 = OpCompositeExtract %33 %288 1\n%294 = OpFConvert %68 %293\n%295 = OpCompositeExtract %67 %294 0\n%296 = OpCompositeExtract %67 %294 1\n%297 = OpCompositeExtract %67 %294 2\n%298 = OpCompositeExtract %67 %294 3\n%299 = OpCompositeConstruct %74 %295 %296 %297 %298 %292\n%300 = OpCompositeExtract %67 %299 0\n%301 = OpCompositeExtract %67 %299 1\n%302 = OpCompositeExtract %67 %299 2\n%303 = OpCompositeExtract %67 %299 3\n%304 = OpCompositeExtract %13 %299 4\n%305 = OpImageSparseTexelsResident %81 %304\n%306 = OpFAdd %67 %280 %300\n%307 = OpFAdd %67 %281 %301\n%308 = OpFAdd %67 %282 %302\n%309 = OpFAdd %67 %283 %303\n%310 = OpLogicalOr %81 %284 %305\n%312 = OpCompositeConstruct %30 %55 %58\n%311 = OpImageSparseSampleImplicitLod %62 %60 %312 Bias %198\n%313 = OpCompositeExtract %13 %311 0\n%314 = OpCompositeExtract %33 %311 1\n%315 = OpFConvert %68 %314\n%316 = OpCompositeExtract %67 %315 0\n%317 = OpCompositeExtract %67 %315 1\n%318 = OpCompositeExtract %67 %315 2\n%319 = OpCompositeExtract %67 %315 3\n%320 = OpCompositeConstruct %74 %316 %317 %318 %319 %313\n%321 = OpCompositeExtract %67 %320 0\n%322 = OpCompositeExtract %67 %320 1\n%323 = OpCompositeExtract %67 %320 2\n%324 = OpCompositeExtract %67 %320 3\n%325 = OpCompositeExtract %13 %320 4\n%326 = OpImageSparseTexelsResident %81 %325\n%327 = OpFAdd %67 %306 %321\n%328 = OpFAdd %67 %307 %322\n%329 = OpFAdd %67 %308 %323\n%330 = OpFAdd %67 %309 %324\n%331 = OpLogicalOr %81 %310 %326\n%332 = OpConvertFToS %13 %55\n%333 = OpImageSparseFetch %62 %46 %332\n%334 = OpCompositeExtract %13 %333 0\n%335 = OpCompositeExtract %33 %333 1\n%336 = OpFConvert %68 %335\n%337 = OpCompositeExtract %67 %336 0\n%338 = OpCompositeExtract %67 %336 1\n%339 = OpCompositeExtract %67 %336 2\n%340 = OpCompositeExtract %67 %336 3\n%341 = OpCompositeConstruct %74 %337 %338 %339 %340 %334\n%342 = OpCompositeExtract %67 %341 0\n%343 = OpCompositeExtract %67 %341 1\n%344 = OpCompositeExtract %67 %341 2\n%345 = OpCompositeExtract %67 %341 3\n%346 = OpCompositeExtract %13 %341 4\n%347 = OpImageSparseTexelsResident %81 %346\n%348 = OpFAdd %67 %327 %342\n%349 = OpFAdd %67 %328 %343\n%350 = OpFAdd %67 %329 %344\n%351 = OpFAdd %67 %330 %345\n%352 = OpLogicalOr %81 %331 %347\n%353 = OpImageSparseFetch %85 %45 %332\n%354 = OpCompositeExtract %13 %353 0\n%355 = OpCompositeExtract %36 %353 1\n%356 = OpSConvert %92 %355\n%357 = OpCompositeExtract %91 %356 0\n%358 = OpCompositeExtract %91 %356 1\n%359 = OpCompositeExtract %91 %356 2\n%360 = OpCompositeExtract %91 %356 3\n%361 = OpCompositeConstruct %98 %357 %358 %359 %360 %354\n%362 = OpCompositeExtract %91 %361 0\n%363 = OpCompositeExtract %91 %361 1\n%364 = OpCompositeExtract %91 %361 2\n%365 = OpCompositeExtract %91 %361 3\n%366 = OpCompositeExtract %13 %361 4\n%367 = OpImageSparseTexelsResident %81 %366\n%368 = OpIAdd %91 %167 %362\n%369 = OpIAdd %91 %168 %363\n%370 = OpIAdd %91 %169 %364\n%371 = OpIAdd %91 %170 %365\n%372 = OpLogicalOr %81 %352 %367\n%373 = OpImageSparseFetch %110 %44 %332\n%374 = OpCompositeExtract %13 %373 0\n%375 = OpCompositeExtract %39 %373 1\n%376 = OpUConvert %92 %375\n%377 = OpCompositeExtract %91 %376 0\n%378 = OpCompositeExtract %91 %376 1\n%379 = OpCompositeExtract %91 %376 2\n%380 = OpCompositeExtract %91 %376 3\n%381 = OpCompositeConstruct %98 %377 %378 %379 %380 %374\n%382 = OpCompositeExtract %91 %381 0\n%383 = OpCompositeExtract %91 %381 1\n%384 = OpCompositeExtract %91 %381 2\n%385 = OpCompositeExtract %91 %381 3\n%386 = OpCompositeExtract %13 %381 4\n%387 = OpImageSparseTexelsResident %81 %386\n%388 = OpIAdd %91 %190 %382\n%389 = OpIAdd %91 %191 %383\n%390 = OpIAdd %91 %192 %384\n%391 = OpIAdd %91 %193 %385\n%392 = OpLogicalOr %81 %372 %387\n%393 = OpSelect %13 %392 %57 %54\n%395 = OpAccessChain %394 %35 %54\n%396 = OpFConvert %5 %348\nOpStore %395 %396\n%397 = OpAccessChain %394 %35 %57\n%398 = OpFConvert %5 %349\nOpStore %397 %398\n%399 = OpAccessChain %394 %35 %84\n%400 = OpFConvert %5 %350\nOpStore %399 %400\n%401 = OpAccessChain %394 %35 %83\n%402 = OpFConvert %5 %351\nOpStore %401 %402\n%404 = OpAccessChain %403 %38 %54\n%405 = OpSConvert %9 %368\nOpStore %404 %405\n%406 = OpAccessChain %403 %38 %57\n%407 = OpSConvert %9 %369\nOpStore %406 %407\n%408 = OpAccessChain %403 %38 %84\n%409 = OpSConvert %9 %370\nOpStore %408 %409\n%410 = OpAccessChain %403 %38 %83\n%411 = OpSConvert %9 %371\nOpStore %410 %411\n%412 = OpAccessChain %42 %41 %54\n%413 = OpUConvert %13 %388\nOpStore %412 %413\n%414 = OpAccessChain %42 %41 %57\n%415 = OpUConvert %13 %389\nOpStore %414 %415\n%416 = OpAccessChain %42 %41 %84\n%417 = OpUConvert %13 %390\nOpStore %416 %417\n%418 = OpAccessChain %42 %41 %83\n%419 = OpUConvert %13 %391\nOpStore %418 %419\nOpStore %43 %393\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/typed-resources-16bit.bindless.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _13[];\nlayout(set = 0, binding = 0) uniform mediump itexture2D _18[];\nlayout(set = 0, binding = 0) uniform mediump utexture2D _22[];\nlayout(set = 1, binding = 0) uniform mediump samplerBuffer _26[];\nlayout(set = 1, binding = 0) uniform mediump isamplerBuffer _30[];\nlayout(set = 1, binding = 0) uniform mediump usamplerBuffer _34[];\nlayout(set = 3, binding = 0) uniform writeonly mediump image2D _38[];\nlayout(set = 3, binding = 0) uniform writeonly mediump iimage2D _42[];\nlayout(set = 3, binding = 0) uniform writeonly mediump uimage2D _46[];\nlayout(set = 4, binding = 0) uniform writeonly mediump imageBuffer _50[];\nlayout(set = 4, binding = 0) uniform writeonly mediump iimageBuffer _54[];\nlayout(set = 4, binding = 0) uniform writeonly mediump uimageBuffer _58[];\nlayout(set = 2, binding = 0) uniform samplerShadow _62[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out mediump vec4 SV_Target;\nlayout(location = 1) out mediump ivec4 SV_Target_1;\nlayout(location = 2) out mediump uvec4 SV_Target_2;\n\nvoid main()\n{\n    uint _139 = registers._m0 + 2u;\n    uint _145 = registers._m0 + 1u;\n    float16_t _168 = float16_t(UV.x);\n    float16_t _169 = float16_t(UV.y);\n    uint _170 = uint(int(UV.x));\n    uint _171 = uint(int(UV.y));\n    imageStore(_38[registers._m3], ivec2(uvec2(_170, _171)), vec4(f16vec4(_168, _169, _168, _169)));\n    uint16_t _178 = uint16_t(int16_t(UV.x));\n    uint16_t _179 = uint16_t(int16_t(UV.y));\n    imageStore(_42[registers._m3 + 1u], ivec2(uvec2(_170, _171)), ivec4(i16vec4(u16vec4(_178, _179, _178, _179))));\n    uint16_t _184 = uint16_t(UV.x);\n    uint16_t _185 = uint16_t(UV.y);\n    imageStore(_46[registers._m3 + 2u], ivec2(uvec2(_170, _171)), uvec4(u16vec4(_184, _185, _184, _185)));\n    imageStore(_50[registers._m4 + 3u], int(_170), vec4(f16vec4(float16_t(8.0))));\n    imageStore(_54[registers._m4 + 4u], int(_170), ivec4(i16vec4(u16vec4(65516us))));\n    imageStore(_58[registers._m4 + 5u], int(_170), uvec4(u16vec4(80us)));\n    f16vec4 _203 = f16vec4(texture(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y)));\n    u16vec4 _210 = u16vec4(texelFetch(_18[_145], ivec2(uvec2(1u, 2u)), int(3u)));\n    u16vec4 _218 = u16vec4(texelFetch(_22[_139], ivec2(uvec2(4u, 5u)), int(6u)));\n    f16vec4 _225 = f16vec4(textureGather(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y)));\n    u16vec4 _238 = u16vec4(textureGather(isampler2D(_18[_145], _62[registers._m2]), vec2(UV.x, UV.y), int(1u)));\n    u16vec4 _251 = u16vec4(textureGather(usampler2D(_22[_139], _62[registers._m2]), vec2(UV.x, UV.y), int(2u)));\n    mediump vec4 _266 = vec4(texture(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), vec3(vec2(UV.x, UV.y), 0.5)));\n    mediump float _267 = _266.x;\n    float _272 = _267 + float(_225.x + _203.x);\n    float _273 = _267 + float(_225.y + _203.y);\n    float _274 = _267 + float(_225.z + _203.z);\n    float _275 = _267 + float(_225.w + _203.w);\n    mediump vec4 _282 = vec4(textureLod(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), vec3(vec2(UV.x, UV.y), 0.5), 0.0));\n    mediump float _283 = _282.x;\n    vec2 _296 = vec2(UV.x, UV.y);\n    f16vec4 _298 = f16vec4(textureGather(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), _296, 0.5));\n    f16vec4 _305 = f16vec4(textureLod(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), 0.0));\n    f16vec4 _317 = f16vec4(textureGrad(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), vec2(0.20000000298023223876953125, 0.300000011920928955078125), vec2(0.4000000059604644775390625, 0.5)));\n    f16vec4 _324 = f16vec4(texture(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), 0.5));\n    f16vec4 _330 = f16vec4(texelFetch(_26[registers._m1 + 3u], int(_170)));\n    u16vec4 _356 = u16vec4(texelFetch(_30[registers._m1 + 4u], int(_170)));\n    u16vec4 _366 = u16vec4(texelFetch(_34[registers._m1 + 5u], int(_170)));\n    SV_Target.x = float(((((_305.x + _298.x) + _317.x) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_272))).x + _283)) + _324.x) + _330.x);\n    SV_Target.y = float(((((_305.y + _298.y) + _317.y) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_273))).x + _283)) + _324.y) + _330.y);\n    SV_Target.z = float(((((_305.z + _298.z) + _317.z) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_274))).x + _283)) + _324.z) + _330.z);\n    SV_Target.w = float(((((_305.w + _298.w) + _317.w) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_275))).x + _283)) + _324.w) + _330.w);\n    SV_Target_1.x = int(int16_t((_238.x + _210.x) + _356.x));\n    SV_Target_1.y = int(int16_t((_238.y + _210.y) + _356.y));\n    SV_Target_1.z = int(int16_t((_238.z + _210.z) + _356.z));\n    SV_Target_1.w = int(int16_t((_238.w + _210.w) + _356.w));\n    SV_Target_2.x = uint((_251.x + _218.x) + _366.x);\n    SV_Target_2.y = uint((_251.y + _218.y) + _366.y);\n    SV_Target_2.z = uint((_251.z + _218.z) + _366.z);\n    SV_Target_2.w = uint((_251.w + _218.w) + _366.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 404\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %65 %68 %71 %74\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %65 \"UV\"\nOpName %68 \"SV_Target\"\nOpName %71 \"SV_Target_1\"\nOpName %74 \"SV_Target_2\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 RelaxedPrecision\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %18 RelaxedPrecision\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 0\nOpDecorate %22 RelaxedPrecision\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 0\nOpDecorate %26 RelaxedPrecision\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 0\nOpDecorate %30 RelaxedPrecision\nOpDecorate %34 DescriptorSet 1\nOpDecorate %34 Binding 0\nOpDecorate %34 RelaxedPrecision\nOpDecorate %38 DescriptorSet 3\nOpDecorate %38 Binding 0\nOpDecorate %38 RelaxedPrecision\nOpDecorate %38 NonReadable\nOpDecorate %42 DescriptorSet 3\nOpDecorate %42 Binding 0\nOpDecorate %42 RelaxedPrecision\nOpDecorate %42 NonReadable\nOpDecorate %46 DescriptorSet 3\nOpDecorate %46 Binding 0\nOpDecorate %46 RelaxedPrecision\nOpDecorate %46 NonReadable\nOpDecorate %50 DescriptorSet 4\nOpDecorate %50 Binding 0\nOpDecorate %50 RelaxedPrecision\nOpDecorate %50 NonReadable\nOpDecorate %54 DescriptorSet 4\nOpDecorate %54 Binding 0\nOpDecorate %54 RelaxedPrecision\nOpDecorate %54 NonReadable\nOpDecorate %58 DescriptorSet 4\nOpDecorate %58 Binding 0\nOpDecorate %58 RelaxedPrecision\nOpDecorate %58 NonReadable\nOpDecorate %62 DescriptorSet 2\nOpDecorate %62 Binding 0\nOpDecorate %65 Location 0\nOpDecorate %68 RelaxedPrecision\nOpDecorate %68 Location 0\nOpDecorate %71 RelaxedPrecision\nOpDecorate %71 Location 1\nOpDecorate %74 RelaxedPrecision\nOpDecorate %74 Location 2\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeInt 32 1\n%15 = OpTypeImage %14 2D 0 0 0 1 Unknown\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %14 Buffer 0 0 0 1 Unknown\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer UniformConstant %32\n%34 = OpVariable %33 UniformConstant\n%35 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%36 = OpTypeRuntimeArray %35\n%37 = OpTypePointer UniformConstant %36\n%38 = OpVariable %37 UniformConstant\n%39 = OpTypeImage %14 2D 0 0 0 2 Unknown\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer UniformConstant %40\n%42 = OpVariable %41 UniformConstant\n%43 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%44 = OpTypeRuntimeArray %43\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%48 = OpTypeRuntimeArray %47\n%49 = OpTypePointer UniformConstant %48\n%50 = OpVariable %49 UniformConstant\n%51 = OpTypeImage %14 Buffer 0 0 0 2 Unknown\n%52 = OpTypeRuntimeArray %51\n%53 = OpTypePointer UniformConstant %52\n%54 = OpVariable %53 UniformConstant\n%55 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%56 = OpTypeRuntimeArray %55\n%57 = OpTypePointer UniformConstant %56\n%58 = OpVariable %57 UniformConstant\n%59 = OpTypeSampler\n%60 = OpTypeRuntimeArray %59\n%61 = OpTypePointer UniformConstant %60\n%62 = OpVariable %61 UniformConstant\n%63 = OpTypeVector %9 2\n%64 = OpTypePointer Input %63\n%65 = OpVariable %64 Input\n%66 = OpTypeVector %9 4\n%67 = OpTypePointer Output %66\n%68 = OpVariable %67 Output\n%69 = OpTypeVector %14 4\n%70 = OpTypePointer Output %69\n%71 = OpVariable %70 Output\n%72 = OpTypeVector %5 4\n%73 = OpTypePointer Output %72\n%74 = OpVariable %73 Output\n%75 = OpTypePointer UniformConstant %55\n%77 = OpTypePointer PushConstant %5\n%79 = OpConstant %5 4\n%82 = OpConstant %5 5\n%84 = OpTypePointer UniformConstant %51\n%90 = OpTypePointer UniformConstant %47\n%95 = OpConstant %5 3\n%97 = OpTypePointer UniformConstant %43\n%102 = OpConstant %5 2\n%104 = OpTypePointer UniformConstant %39\n%109 = OpConstant %5 1\n%111 = OpTypePointer UniformConstant %35\n%116 = OpTypePointer UniformConstant %31\n%122 = OpTypePointer UniformConstant %27\n%128 = OpTypePointer UniformConstant %23\n%134 = OpTypePointer UniformConstant %19\n%137 = OpConstant %5 0\n%141 = OpTypePointer UniformConstant %15\n%147 = OpTypePointer UniformConstant %10\n%152 = OpTypePointer UniformConstant %59\n%162 = OpTypePointer Input %9\n%167 = OpTypeFloat 16\n%172 = OpTypeVector %5 2\n%174 = OpTypeVector %167 4\n%177 = OpTypeInt 16 0\n%181 = OpTypeVector %177 4\n%189 = OpConstant %167 0x1p+3\n%192 = OpConstant %177 65516\n%195 = OpConstant %177 80\n%198 = OpTypeSampledImage %10\n%200 = OpConstant %9 0\n%215 = OpConstant %5 6\n%234 = OpTypeSampledImage %15\n%247 = OpTypeSampledImage %19\n%260 = OpTypeImage %9 2D 1 0 0 1 Unknown\n%261 = OpTypeSampledImage %260\n%263 = OpConstant %9 0.5\n%310 = OpConstant %9 0.200000003\n%311 = OpConstant %9 0.300000012\n%312 = OpConstant %9 0.400000006\n%375 = OpTypePointer Output %9\n%384 = OpTypePointer Output %14\n%393 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %402\n%402 = OpLabel\n%78 = OpAccessChain %77 %8 %79\n%80 = OpLoad %5 %78\n%81 = OpIAdd %5 %80 %82\n%76 = OpAccessChain %75 %58 %81\n%83 = OpLoad %55 %76\n%86 = OpAccessChain %77 %8 %79\n%87 = OpLoad %5 %86\n%88 = OpIAdd %5 %87 %79\n%85 = OpAccessChain %84 %54 %88\n%89 = OpLoad %51 %85\n%92 = OpAccessChain %77 %8 %79\n%93 = OpLoad %5 %92\n%94 = OpIAdd %5 %93 %95\n%91 = OpAccessChain %90 %50 %94\n%96 = OpLoad %47 %91\n%99 = OpAccessChain %77 %8 %95\n%100 = OpLoad %5 %99\n%101 = OpIAdd %5 %100 %102\n%98 = OpAccessChain %97 %46 %101\n%103 = OpLoad %43 %98\n%106 = OpAccessChain %77 %8 %95\n%107 = OpLoad %5 %106\n%108 = OpIAdd %5 %107 %109\n%105 = OpAccessChain %104 %42 %108\n%110 = OpLoad %39 %105\n%113 = OpAccessChain %77 %8 %95\n%114 = OpLoad %5 %113\n%112 = OpAccessChain %111 %38 %114\n%115 = OpLoad %35 %112\n%118 = OpAccessChain %77 %8 %109\n%119 = OpLoad %5 %118\n%120 = OpIAdd %5 %119 %82\n%117 = OpAccessChain %116 %34 %120\n%121 = OpLoad %31 %117\n%124 = OpAccessChain %77 %8 %109\n%125 = OpLoad %5 %124\n%126 = OpIAdd %5 %125 %79\n%123 = OpAccessChain %122 %30 %126\n%127 = OpLoad %27 %123\n%130 = OpAccessChain %77 %8 %109\n%131 = OpLoad %5 %130\n%132 = OpIAdd %5 %131 %95\n%129 = OpAccessChain %128 %26 %132\n%133 = OpLoad %23 %129\n%136 = OpAccessChain %77 %8 %137\n%138 = OpLoad %5 %136\n%139 = OpIAdd %5 %138 %102\n%135 = OpAccessChain %134 %22 %139\n%140 = OpLoad %19 %135\n%143 = OpAccessChain %77 %8 %137\n%144 = OpLoad %5 %143\n%145 = OpIAdd %5 %144 %109\n%142 = OpAccessChain %141 %18 %145\n%146 = OpLoad %15 %142\n%149 = OpAccessChain %77 %8 %137\n%150 = OpLoad %5 %149\n%148 = OpAccessChain %147 %13 %150\n%151 = OpLoad %10 %148\n%154 = OpAccessChain %77 %8 %102\n%155 = OpLoad %5 %154\n%156 = OpIAdd %5 %155 %109\n%153 = OpAccessChain %152 %62 %156\n%157 = OpLoad %59 %153\n%159 = OpAccessChain %77 %8 %102\n%160 = OpLoad %5 %159\n%158 = OpAccessChain %152 %62 %160\n%161 = OpLoad %59 %158\n%163 = OpAccessChain %162 %65 %137\n%164 = OpLoad %9 %163\n%165 = OpAccessChain %162 %65 %109\n%166 = OpLoad %9 %165\n%168 = OpFConvert %167 %164\n%169 = OpFConvert %167 %166\n%170 = OpConvertFToS %5 %164\n%171 = OpConvertFToS %5 %166\n%173 = OpCompositeConstruct %172 %170 %171\n%175 = OpCompositeConstruct %174 %168 %169 %168 %169\n%176 = OpFConvert %66 %175\nOpImageWrite %115 %173 %176\n%178 = OpConvertFToS %177 %164\n%179 = OpConvertFToS %177 %166\n%180 = OpCompositeConstruct %172 %170 %171\n%182 = OpCompositeConstruct %181 %178 %179 %178 %179\n%183 = OpSConvert %69 %182\nOpImageWrite %110 %180 %183\n%184 = OpConvertFToU %177 %164\n%185 = OpConvertFToU %177 %166\n%186 = OpCompositeConstruct %172 %170 %171\n%187 = OpCompositeConstruct %181 %184 %185 %184 %185\n%188 = OpUConvert %72 %187\nOpImageWrite %103 %186 %188\n%190 = OpCompositeConstruct %174 %189 %189 %189 %189\n%191 = OpFConvert %66 %190\nOpImageWrite %96 %170 %191\n%193 = OpCompositeConstruct %181 %192 %192 %192 %192\n%194 = OpSConvert %69 %193\nOpImageWrite %89 %170 %194\n%196 = OpCompositeConstruct %181 %195 %195 %195 %195\n%197 = OpUConvert %72 %196\nOpImageWrite %83 %170 %197\n%199 = OpSampledImage %198 %151 %161\n%202 = OpCompositeConstruct %63 %164 %166\n%201 = OpImageSampleImplicitLod %66 %199 %202 None\n%203 = OpFConvert %174 %201\n%204 = OpCompositeExtract %167 %203 0\n%205 = OpCompositeExtract %167 %203 1\n%206 = OpCompositeExtract %167 %203 2\n%207 = OpCompositeExtract %167 %203 3\n%209 = OpCompositeConstruct %172 %109 %102\n%208 = OpImageFetch %69 %146 %209 Lod %95\n%210 = OpSConvert %181 %208\n%211 = OpCompositeExtract %177 %210 0\n%212 = OpCompositeExtract %177 %210 1\n%213 = OpCompositeExtract %177 %210 2\n%214 = OpCompositeExtract %177 %210 3\n%217 = OpCompositeConstruct %172 %79 %82\n%216 = OpImageFetch %72 %140 %217 Lod %215\n%218 = OpUConvert %181 %216\n%219 = OpCompositeExtract %177 %218 0\n%220 = OpCompositeExtract %177 %218 1\n%221 = OpCompositeExtract %177 %218 2\n%222 = OpCompositeExtract %177 %218 3\n%223 = OpCompositeConstruct %63 %164 %166\n%224 = OpImageGather %66 %199 %223 %137\n%225 = OpFConvert %174 %224\n%226 = OpCompositeExtract %167 %225 0\n%227 = OpCompositeExtract %167 %225 1\n%228 = OpCompositeExtract %167 %225 2\n%229 = OpCompositeExtract %167 %225 3\n%230 = OpFAdd %167 %226 %204\n%231 = OpFAdd %167 %227 %205\n%232 = OpFAdd %167 %228 %206\n%233 = OpFAdd %167 %229 %207\n%235 = OpSampledImage %234 %146 %161\n%236 = OpCompositeConstruct %63 %164 %166\n%237 = OpImageGather %69 %235 %236 %109\n%238 = OpSConvert %181 %237\n%239 = OpCompositeExtract %177 %238 0\n%240 = OpCompositeExtract %177 %238 1\n%241 = OpCompositeExtract %177 %238 2\n%242 = OpCompositeExtract %177 %238 3\n%243 = OpIAdd %177 %239 %211\n%244 = OpIAdd %177 %240 %212\n%245 = OpIAdd %177 %241 %213\n%246 = OpIAdd %177 %242 %214\n%248 = OpSampledImage %247 %140 %161\n%249 = OpCompositeConstruct %63 %164 %166\n%250 = OpImageGather %72 %248 %249 %102\n%251 = OpUConvert %181 %250\n%252 = OpCompositeExtract %177 %251 0\n%253 = OpCompositeExtract %177 %251 1\n%254 = OpCompositeExtract %177 %251 2\n%255 = OpCompositeExtract %177 %251 3\n%256 = OpIAdd %177 %252 %219\n%257 = OpIAdd %177 %253 %220\n%258 = OpIAdd %177 %254 %221\n%259 = OpIAdd %177 %255 %222\n%262 = OpSampledImage %261 %151 %157\n%265 = OpCompositeConstruct %63 %164 %166\n%264 = OpImageSampleDrefImplicitLod %9 %262 %265 %263 None\n%266 = OpCompositeConstruct %66 %264 %264 %264 %264\n%267 = OpCompositeExtract %9 %266 0\n%268 = OpFConvert %9 %230\n%269 = OpFConvert %9 %231\n%270 = OpFConvert %9 %232\n%271 = OpFConvert %9 %233\n%272 = OpFAdd %9 %267 %268\n%273 = OpFAdd %9 %267 %269\n%274 = OpFAdd %9 %267 %270\n%275 = OpFAdd %9 %267 %271\n%276 = OpFConvert %167 %272\n%277 = OpFConvert %167 %273\n%278 = OpFConvert %167 %274\n%279 = OpFConvert %167 %275\n%281 = OpCompositeConstruct %63 %164 %166\n%280 = OpImageSampleDrefExplicitLod %9 %262 %281 %263 Lod %200\n%282 = OpCompositeConstruct %66 %280 %280 %280 %280\n%283 = OpCompositeExtract %9 %282 0\n%284 = OpQuantizeToF16 %9 %272\n%285 = OpQuantizeToF16 %9 %273\n%286 = OpQuantizeToF16 %9 %274\n%287 = OpQuantizeToF16 %9 %275\n%288 = OpFAdd %9 %284 %283\n%289 = OpFAdd %9 %285 %283\n%290 = OpFAdd %9 %286 %283\n%291 = OpFAdd %9 %287 %283\n%292 = OpFConvert %167 %288\n%293 = OpFConvert %167 %289\n%294 = OpFConvert %167 %290\n%295 = OpFConvert %167 %291\n%296 = OpCompositeConstruct %63 %164 %166\n%297 = OpImageDrefGather %66 %262 %296 %263\n%298 = OpFConvert %174 %297\n%299 = OpCompositeExtract %167 %298 0\n%300 = OpCompositeExtract %167 %298 1\n%301 = OpCompositeExtract %167 %298 2\n%302 = OpCompositeExtract %167 %298 3\n%304 = OpCompositeConstruct %63 %164 %166\n%303 = OpImageSampleExplicitLod %66 %199 %304 Lod %200\n%305 = OpFConvert %174 %303\n%306 = OpCompositeExtract %167 %305 0\n%307 = OpCompositeExtract %167 %305 1\n%308 = OpCompositeExtract %167 %305 2\n%309 = OpCompositeExtract %167 %305 3\n%314 = OpCompositeConstruct %63 %164 %166\n%315 = OpCompositeConstruct %63 %310 %311\n%316 = OpCompositeConstruct %63 %312 %263\n%313 = OpImageSampleExplicitLod %66 %199 %314 Grad %315 %316\n%317 = OpFConvert %174 %313\n%318 = OpCompositeExtract %167 %317 0\n%319 = OpCompositeExtract %167 %317 1\n%320 = OpCompositeExtract %167 %317 2\n%321 = OpCompositeExtract %167 %317 3\n%323 = OpCompositeConstruct %63 %164 %166\n%322 = OpImageSampleImplicitLod %66 %199 %323 Bias %263\n%324 = OpFConvert %174 %322\n%325 = OpCompositeExtract %167 %324 0\n%326 = OpCompositeExtract %167 %324 1\n%327 = OpCompositeExtract %167 %324 2\n%328 = OpCompositeExtract %167 %324 3\n%329 = OpImageFetch %66 %133 %170\n%330 = OpFConvert %174 %329\n%331 = OpCompositeExtract %167 %330 0\n%332 = OpCompositeExtract %167 %330 1\n%333 = OpCompositeExtract %167 %330 2\n%334 = OpCompositeExtract %167 %330 3\n%335 = OpFAdd %167 %306 %299\n%336 = OpFAdd %167 %335 %318\n%337 = OpFAdd %167 %336 %292\n%338 = OpFAdd %167 %337 %325\n%339 = OpFAdd %167 %338 %331\n%340 = OpFAdd %167 %307 %300\n%341 = OpFAdd %167 %340 %319\n%342 = OpFAdd %167 %341 %293\n%343 = OpFAdd %167 %342 %326\n%344 = OpFAdd %167 %343 %332\n%345 = OpFAdd %167 %308 %301\n%346 = OpFAdd %167 %345 %320\n%347 = OpFAdd %167 %346 %294\n%348 = OpFAdd %167 %347 %327\n%349 = OpFAdd %167 %348 %333\n%350 = OpFAdd %167 %309 %302\n%351 = OpFAdd %167 %350 %321\n%352 = OpFAdd %167 %351 %295\n%353 = OpFAdd %167 %352 %328\n%354 = OpFAdd %167 %353 %334\n%355 = OpImageFetch %69 %127 %170\n%356 = OpSConvert %181 %355\n%357 = OpCompositeExtract %177 %356 0\n%358 = OpCompositeExtract %177 %356 1\n%359 = OpCompositeExtract %177 %356 2\n%360 = OpCompositeExtract %177 %356 3\n%361 = OpIAdd %177 %243 %357\n%362 = OpIAdd %177 %244 %358\n%363 = OpIAdd %177 %245 %359\n%364 = OpIAdd %177 %246 %360\n%365 = OpImageFetch %72 %121 %170\n%366 = OpUConvert %181 %365\n%367 = OpCompositeExtract %177 %366 0\n%368 = OpCompositeExtract %177 %366 1\n%369 = OpCompositeExtract %177 %366 2\n%370 = OpCompositeExtract %177 %366 3\n%371 = OpIAdd %177 %256 %367\n%372 = OpIAdd %177 %257 %368\n%373 = OpIAdd %177 %258 %369\n%374 = OpIAdd %177 %259 %370\n%376 = OpAccessChain %375 %68 %137\n%377 = OpFConvert %9 %339\nOpStore %376 %377\n%378 = OpAccessChain %375 %68 %109\n%379 = OpFConvert %9 %344\nOpStore %378 %379\n%380 = OpAccessChain %375 %68 %102\n%381 = OpFConvert %9 %349\nOpStore %380 %381\n%382 = OpAccessChain %375 %68 %95\n%383 = OpFConvert %9 %354\nOpStore %382 %383\n%385 = OpAccessChain %384 %71 %137\n%386 = OpSConvert %14 %361\nOpStore %385 %386\n%387 = OpAccessChain %384 %71 %109\n%388 = OpSConvert %14 %362\nOpStore %387 %388\n%389 = OpAccessChain %384 %71 %102\n%390 = OpSConvert %14 %363\nOpStore %389 %390\n%391 = OpAccessChain %384 %71 %95\n%392 = OpSConvert %14 %364\nOpStore %391 %392\n%394 = OpAccessChain %393 %74 %137\n%395 = OpUConvert %5 %371\nOpStore %394 %395\n%396 = OpAccessChain %393 %74 %109\n%397 = OpUConvert %5 %372\nOpStore %396 %397\n%398 = OpAccessChain %393 %74 %102\n%399 = OpUConvert %5 %373\nOpStore %398 %399\n%400 = OpAccessChain %393 %74 %95\n%401 = OpUConvert %5 %374\nOpStore %400 %401\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/typed-resources-16bit.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _8;\nlayout(set = 0, binding = 1) uniform mediump itexture2D _12;\nlayout(set = 0, binding = 2) uniform mediump utexture2D _16;\nlayout(set = 0, binding = 3) uniform mediump samplerBuffer _19;\nlayout(set = 0, binding = 4) uniform mediump isamplerBuffer _22;\nlayout(set = 0, binding = 5) uniform mediump usamplerBuffer _25;\nlayout(set = 0, binding = 0) uniform writeonly mediump image2D _28;\nlayout(set = 0, binding = 1) uniform writeonly mediump iimage2D _31;\nlayout(set = 0, binding = 2) uniform writeonly mediump uimage2D _34;\nlayout(set = 0, binding = 3) uniform writeonly mediump imageBuffer _37;\nlayout(set = 0, binding = 4) uniform writeonly mediump iimageBuffer _40;\nlayout(set = 0, binding = 5) uniform writeonly mediump uimageBuffer _43;\nlayout(set = 0, binding = 0) uniform sampler _46;\nlayout(set = 0, binding = 1) uniform samplerShadow _47;\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out mediump vec4 SV_Target;\nlayout(location = 1) out mediump ivec4 SV_Target_1;\nlayout(location = 2) out mediump uvec4 SV_Target_2;\n\nvoid main()\n{\n    float16_t _82 = float16_t(UV.x);\n    float16_t _83 = float16_t(UV.y);\n    uint _84 = uint(int(UV.x));\n    uint _85 = uint(int(UV.y));\n    imageStore(_28, ivec2(uvec2(_84, _85)), vec4(f16vec4(_82, _83, _82, _83)));\n    uint16_t _92 = uint16_t(int16_t(UV.x));\n    uint16_t _93 = uint16_t(int16_t(UV.y));\n    imageStore(_31, ivec2(uvec2(_84, _85)), ivec4(i16vec4(u16vec4(_92, _93, _92, _93))));\n    uint16_t _98 = uint16_t(UV.x);\n    uint16_t _99 = uint16_t(UV.y);\n    imageStore(_34, ivec2(uvec2(_84, _85)), uvec4(u16vec4(_98, _99, _98, _99)));\n    imageStore(_37, int(_84), vec4(f16vec4(float16_t(8.0))));\n    imageStore(_40, int(_84), ivec4(i16vec4(u16vec4(65516us))));\n    imageStore(_43, int(_84), uvec4(u16vec4(80us)));\n    f16vec4 _117 = f16vec4(texture(sampler2D(_8, _46), vec2(UV.x, UV.y)));\n    u16vec4 _126 = u16vec4(texelFetch(_12, ivec2(uvec2(1u, 2u)), int(3u)));\n    u16vec4 _136 = u16vec4(texelFetch(_16, ivec2(uvec2(4u, 5u)), int(6u)));\n    f16vec4 _143 = f16vec4(textureGather(sampler2D(_8, _46), vec2(UV.x, UV.y)));\n    u16vec4 _156 = u16vec4(textureGather(isampler2D(_12, _46), vec2(UV.x, UV.y), int(1u)));\n    u16vec4 _169 = u16vec4(textureGather(usampler2D(_16, _46), vec2(UV.x, UV.y), int(2u)));\n    mediump vec4 _184 = vec4(texture(sampler2DShadow(_8, _47), vec3(vec2(UV.x, UV.y), 0.5)));\n    mediump float _185 = _184.x;\n    float _190 = _185 + float(_143.x + _117.x);\n    float _191 = _185 + float(_143.y + _117.y);\n    float _192 = _185 + float(_143.z + _117.z);\n    float _193 = _185 + float(_143.w + _117.w);\n    mediump vec4 _200 = vec4(textureLod(sampler2DShadow(_8, _47), vec3(vec2(UV.x, UV.y), 0.5), 0.0));\n    mediump float _201 = _200.x;\n    vec2 _214 = vec2(UV.x, UV.y);\n    f16vec4 _216 = f16vec4(textureGather(sampler2DShadow(_8, _47), _214, 0.5));\n    f16vec4 _223 = f16vec4(textureLod(sampler2D(_8, _46), vec2(UV.x, UV.y), 0.0));\n    f16vec4 _235 = f16vec4(textureGrad(sampler2D(_8, _46), vec2(UV.x, UV.y), vec2(0.20000000298023223876953125, 0.300000011920928955078125), vec2(0.4000000059604644775390625, 0.5)));\n    f16vec4 _242 = f16vec4(texture(sampler2D(_8, _46), vec2(UV.x, UV.y), 0.5));\n    f16vec4 _248 = f16vec4(texelFetch(_19, int(_84)));\n    u16vec4 _274 = u16vec4(texelFetch(_22, int(_84)));\n    u16vec4 _284 = u16vec4(texelFetch(_25, int(_84)));\n    SV_Target.x = float(((((_223.x + _216.x) + _235.x) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_190))).x + _201)) + _242.x) + _248.x);\n    SV_Target.y = float(((((_223.y + _216.y) + _235.y) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_191))).x + _201)) + _242.y) + _248.y);\n    SV_Target.z = float(((((_223.z + _216.z) + _235.z) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_192))).x + _201)) + _242.z) + _248.z);\n    SV_Target.w = float(((((_223.w + _216.w) + _235.w) + float16_t(unpackHalf2x16(packHalf2x16(vec2(_193))).x + _201)) + _242.w) + _248.w);\n    SV_Target_1.x = int(int16_t((_156.x + _126.x) + _274.x));\n    SV_Target_1.y = int(int16_t((_156.y + _126.y) + _274.y));\n    SV_Target_1.z = int(int16_t((_156.z + _126.z) + _274.z));\n    SV_Target_1.w = int(int16_t((_156.w + _126.w) + _274.w));\n    SV_Target_2.x = uint((_169.x + _136.x) + _284.x);\n    SV_Target_2.y = uint((_169.y + _136.y) + _284.y);\n    SV_Target_2.z = uint((_169.z + _136.z) + _284.z);\n    SV_Target_2.w = uint((_169.w + _136.w) + _284.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 322\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %50 %53 %56 %59\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %50 \"UV\"\nOpName %53 \"SV_Target\"\nOpName %56 \"SV_Target_1\"\nOpName %59 \"SV_Target_2\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 2\nOpDecorate %19 RelaxedPrecision\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 3\nOpDecorate %22 RelaxedPrecision\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 4\nOpDecorate %25 RelaxedPrecision\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 5\nOpDecorate %28 RelaxedPrecision\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %31 RelaxedPrecision\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 1\nOpDecorate %31 NonReadable\nOpDecorate %34 RelaxedPrecision\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 2\nOpDecorate %34 NonReadable\nOpDecorate %37 RelaxedPrecision\nOpDecorate %37 DescriptorSet 0\nOpDecorate %37 Binding 3\nOpDecorate %37 NonReadable\nOpDecorate %40 RelaxedPrecision\nOpDecorate %40 DescriptorSet 0\nOpDecorate %40 Binding 4\nOpDecorate %40 NonReadable\nOpDecorate %43 RelaxedPrecision\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 5\nOpDecorate %43 NonReadable\nOpDecorate %46 DescriptorSet 0\nOpDecorate %46 Binding 0\nOpDecorate %47 DescriptorSet 0\nOpDecorate %47 Binding 1\nOpDecorate %50 Location 0\nOpDecorate %53 RelaxedPrecision\nOpDecorate %53 Location 0\nOpDecorate %56 RelaxedPrecision\nOpDecorate %56 Location 1\nOpDecorate %59 RelaxedPrecision\nOpDecorate %59 Location 2\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 1\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeInt 32 0\n%14 = OpTypeImage %13 2D 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%30 = OpTypePointer UniformConstant %29\n%31 = OpVariable %30 UniformConstant\n%32 = OpTypeImage %13 2D 0 0 0 2 Unknown\n%33 = OpTypePointer UniformConstant %32\n%34 = OpVariable %33 UniformConstant\n%35 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%36 = OpTypePointer UniformConstant %35\n%37 = OpVariable %36 UniformConstant\n%38 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%39 = OpTypePointer UniformConstant %38\n%40 = OpVariable %39 UniformConstant\n%41 = OpTypeImage %13 Buffer 0 0 0 2 Unknown\n%42 = OpTypePointer UniformConstant %41\n%43 = OpVariable %42 UniformConstant\n%44 = OpTypeSampler\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpVariable %45 UniformConstant\n%48 = OpTypeVector %5 2\n%49 = OpTypePointer Input %48\n%50 = OpVariable %49 Input\n%51 = OpTypeVector %5 4\n%52 = OpTypePointer Output %51\n%53 = OpVariable %52 Output\n%54 = OpTypeVector %9 4\n%55 = OpTypePointer Output %54\n%56 = OpVariable %55 Output\n%57 = OpTypeVector %13 4\n%58 = OpTypePointer Output %57\n%59 = OpVariable %58 Output\n%74 = OpTypePointer Input %5\n%76 = OpConstant %13 0\n%79 = OpConstant %13 1\n%81 = OpTypeFloat 16\n%86 = OpTypeVector %13 2\n%88 = OpTypeVector %81 4\n%91 = OpTypeInt 16 0\n%95 = OpTypeVector %91 4\n%103 = OpConstant %81 0x1p+3\n%106 = OpConstant %91 65516\n%109 = OpConstant %91 80\n%112 = OpTypeSampledImage %6\n%114 = OpConstant %5 0\n%122 = OpConstant %13 3\n%123 = OpConstant %13 2\n%131 = OpConstant %13 6\n%132 = OpConstant %13 4\n%133 = OpConstant %13 5\n%152 = OpTypeSampledImage %10\n%165 = OpTypeSampledImage %14\n%178 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%179 = OpTypeSampledImage %178\n%181 = OpConstant %5 0.5\n%228 = OpConstant %5 0.200000003\n%229 = OpConstant %5 0.300000012\n%230 = OpConstant %5 0.400000006\n%293 = OpTypePointer Output %5\n%302 = OpTypePointer Output %9\n%311 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %320\n%320 = OpLabel\n%60 = OpLoad %41 %43\n%61 = OpLoad %38 %40\n%62 = OpLoad %35 %37\n%63 = OpLoad %32 %34\n%64 = OpLoad %29 %31\n%65 = OpLoad %26 %28\n%66 = OpLoad %23 %25\n%67 = OpLoad %20 %22\n%68 = OpLoad %17 %19\n%69 = OpLoad %14 %16\n%70 = OpLoad %10 %12\n%71 = OpLoad %6 %8\n%72 = OpLoad %44 %47\n%73 = OpLoad %44 %46\n%75 = OpAccessChain %74 %50 %76\n%77 = OpLoad %5 %75\n%78 = OpAccessChain %74 %50 %79\n%80 = OpLoad %5 %78\n%82 = OpFConvert %81 %77\n%83 = OpFConvert %81 %80\n%84 = OpConvertFToS %13 %77\n%85 = OpConvertFToS %13 %80\n%87 = OpCompositeConstruct %86 %84 %85\n%89 = OpCompositeConstruct %88 %82 %83 %82 %83\n%90 = OpFConvert %51 %89\nOpImageWrite %65 %87 %90\n%92 = OpConvertFToS %91 %77\n%93 = OpConvertFToS %91 %80\n%94 = OpCompositeConstruct %86 %84 %85\n%96 = OpCompositeConstruct %95 %92 %93 %92 %93\n%97 = OpSConvert %54 %96\nOpImageWrite %64 %94 %97\n%98 = OpConvertFToU %91 %77\n%99 = OpConvertFToU %91 %80\n%100 = OpCompositeConstruct %86 %84 %85\n%101 = OpCompositeConstruct %95 %98 %99 %98 %99\n%102 = OpUConvert %57 %101\nOpImageWrite %63 %100 %102\n%104 = OpCompositeConstruct %88 %103 %103 %103 %103\n%105 = OpFConvert %51 %104\nOpImageWrite %62 %84 %105\n%107 = OpCompositeConstruct %95 %106 %106 %106 %106\n%108 = OpSConvert %54 %107\nOpImageWrite %61 %84 %108\n%110 = OpCompositeConstruct %95 %109 %109 %109 %109\n%111 = OpUConvert %57 %110\nOpImageWrite %60 %84 %111\n%113 = OpSampledImage %112 %71 %73\n%116 = OpCompositeConstruct %48 %77 %80\n%115 = OpImageSampleImplicitLod %51 %113 %116 None\n%117 = OpFConvert %88 %115\n%118 = OpCompositeExtract %81 %117 0\n%119 = OpCompositeExtract %81 %117 1\n%120 = OpCompositeExtract %81 %117 2\n%121 = OpCompositeExtract %81 %117 3\n%125 = OpCompositeConstruct %86 %79 %123\n%124 = OpImageFetch %54 %70 %125 Lod %122\n%126 = OpSConvert %95 %124\n%127 = OpCompositeExtract %91 %126 0\n%128 = OpCompositeExtract %91 %126 1\n%129 = OpCompositeExtract %91 %126 2\n%130 = OpCompositeExtract %91 %126 3\n%135 = OpCompositeConstruct %86 %132 %133\n%134 = OpImageFetch %57 %69 %135 Lod %131\n%136 = OpUConvert %95 %134\n%137 = OpCompositeExtract %91 %136 0\n%138 = OpCompositeExtract %91 %136 1\n%139 = OpCompositeExtract %91 %136 2\n%140 = OpCompositeExtract %91 %136 3\n%141 = OpCompositeConstruct %48 %77 %80\n%142 = OpImageGather %51 %113 %141 %76\n%143 = OpFConvert %88 %142\n%144 = OpCompositeExtract %81 %143 0\n%145 = OpCompositeExtract %81 %143 1\n%146 = OpCompositeExtract %81 %143 2\n%147 = OpCompositeExtract %81 %143 3\n%148 = OpFAdd %81 %144 %118\n%149 = OpFAdd %81 %145 %119\n%150 = OpFAdd %81 %146 %120\n%151 = OpFAdd %81 %147 %121\n%153 = OpSampledImage %152 %70 %73\n%154 = OpCompositeConstruct %48 %77 %80\n%155 = OpImageGather %54 %153 %154 %79\n%156 = OpSConvert %95 %155\n%157 = OpCompositeExtract %91 %156 0\n%158 = OpCompositeExtract %91 %156 1\n%159 = OpCompositeExtract %91 %156 2\n%160 = OpCompositeExtract %91 %156 3\n%161 = OpIAdd %91 %157 %127\n%162 = OpIAdd %91 %158 %128\n%163 = OpIAdd %91 %159 %129\n%164 = OpIAdd %91 %160 %130\n%166 = OpSampledImage %165 %69 %73\n%167 = OpCompositeConstruct %48 %77 %80\n%168 = OpImageGather %57 %166 %167 %123\n%169 = OpUConvert %95 %168\n%170 = OpCompositeExtract %91 %169 0\n%171 = OpCompositeExtract %91 %169 1\n%172 = OpCompositeExtract %91 %169 2\n%173 = OpCompositeExtract %91 %169 3\n%174 = OpIAdd %91 %170 %137\n%175 = OpIAdd %91 %171 %138\n%176 = OpIAdd %91 %172 %139\n%177 = OpIAdd %91 %173 %140\n%180 = OpSampledImage %179 %71 %72\n%183 = OpCompositeConstruct %48 %77 %80\n%182 = OpImageSampleDrefImplicitLod %5 %180 %183 %181 None\n%184 = OpCompositeConstruct %51 %182 %182 %182 %182\n%185 = OpCompositeExtract %5 %184 0\n%186 = OpFConvert %5 %148\n%187 = OpFConvert %5 %149\n%188 = OpFConvert %5 %150\n%189 = OpFConvert %5 %151\n%190 = OpFAdd %5 %185 %186\n%191 = OpFAdd %5 %185 %187\n%192 = OpFAdd %5 %185 %188\n%193 = OpFAdd %5 %185 %189\n%194 = OpFConvert %81 %190\n%195 = OpFConvert %81 %191\n%196 = OpFConvert %81 %192\n%197 = OpFConvert %81 %193\n%199 = OpCompositeConstruct %48 %77 %80\n%198 = OpImageSampleDrefExplicitLod %5 %180 %199 %181 Lod %114\n%200 = OpCompositeConstruct %51 %198 %198 %198 %198\n%201 = OpCompositeExtract %5 %200 0\n%202 = OpQuantizeToF16 %5 %190\n%203 = OpQuantizeToF16 %5 %191\n%204 = OpQuantizeToF16 %5 %192\n%205 = OpQuantizeToF16 %5 %193\n%206 = OpFAdd %5 %202 %201\n%207 = OpFAdd %5 %203 %201\n%208 = OpFAdd %5 %204 %201\n%209 = OpFAdd %5 %205 %201\n%210 = OpFConvert %81 %206\n%211 = OpFConvert %81 %207\n%212 = OpFConvert %81 %208\n%213 = OpFConvert %81 %209\n%214 = OpCompositeConstruct %48 %77 %80\n%215 = OpImageDrefGather %51 %180 %214 %181\n%216 = OpFConvert %88 %215\n%217 = OpCompositeExtract %81 %216 0\n%218 = OpCompositeExtract %81 %216 1\n%219 = OpCompositeExtract %81 %216 2\n%220 = OpCompositeExtract %81 %216 3\n%222 = OpCompositeConstruct %48 %77 %80\n%221 = OpImageSampleExplicitLod %51 %113 %222 Lod %114\n%223 = OpFConvert %88 %221\n%224 = OpCompositeExtract %81 %223 0\n%225 = OpCompositeExtract %81 %223 1\n%226 = OpCompositeExtract %81 %223 2\n%227 = OpCompositeExtract %81 %223 3\n%232 = OpCompositeConstruct %48 %77 %80\n%233 = OpCompositeConstruct %48 %228 %229\n%234 = OpCompositeConstruct %48 %230 %181\n%231 = OpImageSampleExplicitLod %51 %113 %232 Grad %233 %234\n%235 = OpFConvert %88 %231\n%236 = OpCompositeExtract %81 %235 0\n%237 = OpCompositeExtract %81 %235 1\n%238 = OpCompositeExtract %81 %235 2\n%239 = OpCompositeExtract %81 %235 3\n%241 = OpCompositeConstruct %48 %77 %80\n%240 = OpImageSampleImplicitLod %51 %113 %241 Bias %181\n%242 = OpFConvert %88 %240\n%243 = OpCompositeExtract %81 %242 0\n%244 = OpCompositeExtract %81 %242 1\n%245 = OpCompositeExtract %81 %242 2\n%246 = OpCompositeExtract %81 %242 3\n%247 = OpImageFetch %51 %68 %84\n%248 = OpFConvert %88 %247\n%249 = OpCompositeExtract %81 %248 0\n%250 = OpCompositeExtract %81 %248 1\n%251 = OpCompositeExtract %81 %248 2\n%252 = OpCompositeExtract %81 %248 3\n%253 = OpFAdd %81 %224 %217\n%254 = OpFAdd %81 %253 %236\n%255 = OpFAdd %81 %254 %210\n%256 = OpFAdd %81 %255 %243\n%257 = OpFAdd %81 %256 %249\n%258 = OpFAdd %81 %225 %218\n%259 = OpFAdd %81 %258 %237\n%260 = OpFAdd %81 %259 %211\n%261 = OpFAdd %81 %260 %244\n%262 = OpFAdd %81 %261 %250\n%263 = OpFAdd %81 %226 %219\n%264 = OpFAdd %81 %263 %238\n%265 = OpFAdd %81 %264 %212\n%266 = OpFAdd %81 %265 %245\n%267 = OpFAdd %81 %266 %251\n%268 = OpFAdd %81 %227 %220\n%269 = OpFAdd %81 %268 %239\n%270 = OpFAdd %81 %269 %213\n%271 = OpFAdd %81 %270 %246\n%272 = OpFAdd %81 %271 %252\n%273 = OpImageFetch %54 %67 %84\n%274 = OpSConvert %95 %273\n%275 = OpCompositeExtract %91 %274 0\n%276 = OpCompositeExtract %91 %274 1\n%277 = OpCompositeExtract %91 %274 2\n%278 = OpCompositeExtract %91 %274 3\n%279 = OpIAdd %91 %161 %275\n%280 = OpIAdd %91 %162 %276\n%281 = OpIAdd %91 %163 %277\n%282 = OpIAdd %91 %164 %278\n%283 = OpImageFetch %57 %66 %84\n%284 = OpUConvert %95 %283\n%285 = OpCompositeExtract %91 %284 0\n%286 = OpCompositeExtract %91 %284 1\n%287 = OpCompositeExtract %91 %284 2\n%288 = OpCompositeExtract %91 %284 3\n%289 = OpIAdd %91 %174 %285\n%290 = OpIAdd %91 %175 %286\n%291 = OpIAdd %91 %176 %287\n%292 = OpIAdd %91 %177 %288\n%294 = OpAccessChain %293 %53 %76\n%295 = OpFConvert %5 %257\nOpStore %294 %295\n%296 = OpAccessChain %293 %53 %79\n%297 = OpFConvert %5 %262\nOpStore %296 %297\n%298 = OpAccessChain %293 %53 %123\n%299 = OpFConvert %5 %267\nOpStore %298 %299\n%300 = OpAccessChain %293 %53 %122\n%301 = OpFConvert %5 %272\nOpStore %300 %301\n%303 = OpAccessChain %302 %56 %76\n%304 = OpSConvert %9 %279\nOpStore %303 %304\n%305 = OpAccessChain %302 %56 %79\n%306 = OpSConvert %9 %280\nOpStore %305 %306\n%307 = OpAccessChain %302 %56 %123\n%308 = OpSConvert %9 %281\nOpStore %307 %308\n%309 = OpAccessChain %302 %56 %122\n%310 = OpSConvert %9 %282\nOpStore %309 %310\n%312 = OpAccessChain %311 %59 %76\n%313 = OpUConvert %13 %289\nOpStore %312 %313\n%314 = OpAccessChain %311 %59 %79\n%315 = OpUConvert %13 %290\nOpStore %314 %315\n%316 = OpAccessChain %311 %59 %123\n%317 = OpUConvert %13 %291\nOpStore %316 %317\n%318 = OpAccessChain %311 %59 %122\n%319 = OpUConvert %13 %292\nOpStore %318 %319\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/typed-resources-16bit.sm60.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _13[];\nlayout(set = 0, binding = 0) uniform mediump itexture2D _18[];\nlayout(set = 0, binding = 0) uniform mediump utexture2D _22[];\nlayout(set = 1, binding = 0) uniform mediump samplerBuffer _26[];\nlayout(set = 1, binding = 0) uniform mediump isamplerBuffer _30[];\nlayout(set = 1, binding = 0) uniform mediump usamplerBuffer _34[];\nlayout(set = 3, binding = 0) uniform writeonly mediump image2D _38[];\nlayout(set = 3, binding = 0) uniform writeonly mediump iimage2D _42[];\nlayout(set = 3, binding = 0) uniform writeonly mediump uimage2D _46[];\nlayout(set = 4, binding = 0) uniform writeonly mediump imageBuffer _50[];\nlayout(set = 4, binding = 0) uniform writeonly mediump iimageBuffer _54[];\nlayout(set = 4, binding = 0) uniform writeonly mediump uimageBuffer _58[];\nlayout(set = 2, binding = 0) uniform samplerShadow _62[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out mediump vec4 SV_Target;\nlayout(location = 1) out mediump ivec4 SV_Target_1;\nlayout(location = 2) out mediump uvec4 SV_Target_2;\n\nvoid main()\n{\n    uint _139 = registers._m0 + 2u;\n    uint _145 = registers._m0 + 1u;\n    mediump float _167 = UV.x;\n    mediump float _168 = UV.y;\n    uint _169 = uint(int(UV.x));\n    uint _170 = uint(int(UV.y));\n    imageStore(_38[registers._m3], ivec2(uvec2(_169, _170)), vec4(_167, _168, _167, _168));\n    uint16_t _175 = uint16_t(int16_t(UV.x));\n    uint16_t _176 = uint16_t(int16_t(UV.y));\n    imageStore(_42[registers._m3 + 1u], ivec2(uvec2(_169, _170)), ivec4(i16vec4(u16vec4(_175, _176, _175, _176))));\n    uint16_t _181 = uint16_t(UV.x);\n    uint16_t _182 = uint16_t(UV.y);\n    imageStore(_46[registers._m3 + 2u], ivec2(uvec2(_169, _170)), uvec4(u16vec4(_181, _182, _181, _182)));\n    imageStore(_50[registers._m4 + 3u], int(_169), vec4(8.0));\n    imageStore(_54[registers._m4 + 4u], int(_169), ivec4(i16vec4(u16vec4(65516us))));\n    imageStore(_58[registers._m4 + 5u], int(_169), uvec4(u16vec4(80us)));\n    mediump vec4 _197 = texture(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y));\n    u16vec4 _205 = u16vec4(texelFetch(_18[_145], ivec2(uvec2(1u, 2u)), int(3u)));\n    u16vec4 _213 = u16vec4(texelFetch(_22[_139], ivec2(uvec2(4u, 5u)), int(6u)));\n    mediump vec4 _219 = textureGather(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y));\n    mediump float _224 = _219.x + _197.x;\n    float hp_copy_224 = _224;\n    mediump float _225 = _219.y + _197.y;\n    float hp_copy_225 = _225;\n    mediump float _226 = _219.z + _197.z;\n    float hp_copy_226 = _226;\n    mediump float _227 = _219.w + _197.w;\n    float hp_copy_227 = _227;\n    u16vec4 _232 = u16vec4(textureGather(isampler2D(_18[_145], _62[registers._m2]), vec2(UV.x, UV.y), int(1u)));\n    u16vec4 _245 = u16vec4(textureGather(usampler2D(_22[_139], _62[registers._m2]), vec2(UV.x, UV.y), int(2u)));\n    mediump float _261 = vec4(texture(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), vec3(vec2(UV.x, UV.y), 0.5))).x;\n    float hp_copy_261 = _261;\n    mediump float _266 = hp_copy_261 + hp_copy_224;\n    float hp_copy_266 = _266;\n    mediump float _267 = hp_copy_261 + hp_copy_225;\n    float hp_copy_267 = _267;\n    mediump float _268 = hp_copy_261 + hp_copy_226;\n    float hp_copy_268 = _268;\n    mediump float _269 = hp_copy_261 + hp_copy_227;\n    float hp_copy_269 = _269;\n    mediump float _273 = vec4(textureLod(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), vec3(vec2(UV.x, UV.y), 0.5), 0.0)).x;\n    float hp_copy_273 = _273;\n    mediump float _278 = hp_copy_266 + hp_copy_273;\n    mediump float _279 = hp_copy_267 + hp_copy_273;\n    mediump float _280 = hp_copy_268 + hp_copy_273;\n    mediump float _281 = hp_copy_269 + hp_copy_273;\n    vec2 _282 = vec2(UV.x, UV.y);\n    mediump vec4 _283 = textureGather(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), _282, 0.5);\n    mediump vec4 _288 = textureLod(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), 0.0);\n    mediump vec4 _297 = textureGrad(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), vec2(0.20000000298023223876953125, 0.300000011920928955078125), vec2(0.4000000059604644775390625, 0.5));\n    mediump vec4 _305 = texture(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), 0.5);\n    mediump vec4 _311 = texelFetch(_26[registers._m1 + 3u], int(_169));\n    u16vec4 _337 = u16vec4(texelFetch(_30[registers._m1 + 4u], int(_169)));\n    u16vec4 _347 = u16vec4(texelFetch(_34[registers._m1 + 5u], int(_169)));\n    SV_Target.x = ((((_288.x + _283.x) + _297.x) + _278) + _305.x) + _311.x;\n    SV_Target.y = ((((_288.y + _283.y) + _297.y) + _279) + _305.y) + _311.y;\n    SV_Target.z = ((((_288.z + _283.z) + _297.z) + _280) + _305.z) + _311.z;\n    SV_Target.w = ((((_288.w + _283.w) + _297.w) + _281) + _305.w) + _311.w;\n    SV_Target_1.x = int(int16_t((_232.x + _205.x) + _337.x));\n    SV_Target_1.y = int(int16_t((_232.y + _205.y) + _337.y));\n    SV_Target_1.z = int(int16_t((_232.z + _205.z) + _337.z));\n    SV_Target_1.w = int(int16_t((_232.w + _205.w) + _337.w));\n    SV_Target_2.x = uint((_245.x + _213.x) + _347.x);\n    SV_Target_2.y = uint((_245.y + _213.y) + _347.y);\n    SV_Target_2.z = uint((_245.z + _213.z) + _347.z);\n    SV_Target_2.w = uint((_245.w + _213.w) + _347.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 381\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %65 %68 %71 %74\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %65 \"UV\"\nOpName %68 \"SV_Target\"\nOpName %71 \"SV_Target_1\"\nOpName %74 \"SV_Target_2\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 RelaxedPrecision\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %18 RelaxedPrecision\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 0\nOpDecorate %22 RelaxedPrecision\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 0\nOpDecorate %26 RelaxedPrecision\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 0\nOpDecorate %30 RelaxedPrecision\nOpDecorate %34 DescriptorSet 1\nOpDecorate %34 Binding 0\nOpDecorate %34 RelaxedPrecision\nOpDecorate %38 DescriptorSet 3\nOpDecorate %38 Binding 0\nOpDecorate %38 RelaxedPrecision\nOpDecorate %38 NonReadable\nOpDecorate %42 DescriptorSet 3\nOpDecorate %42 Binding 0\nOpDecorate %42 RelaxedPrecision\nOpDecorate %42 NonReadable\nOpDecorate %46 DescriptorSet 3\nOpDecorate %46 Binding 0\nOpDecorate %46 RelaxedPrecision\nOpDecorate %46 NonReadable\nOpDecorate %50 DescriptorSet 4\nOpDecorate %50 Binding 0\nOpDecorate %50 RelaxedPrecision\nOpDecorate %50 NonReadable\nOpDecorate %54 DescriptorSet 4\nOpDecorate %54 Binding 0\nOpDecorate %54 RelaxedPrecision\nOpDecorate %54 NonReadable\nOpDecorate %58 DescriptorSet 4\nOpDecorate %58 Binding 0\nOpDecorate %58 RelaxedPrecision\nOpDecorate %58 NonReadable\nOpDecorate %62 DescriptorSet 2\nOpDecorate %62 Binding 0\nOpDecorate %65 Location 0\nOpDecorate %68 RelaxedPrecision\nOpDecorate %68 Location 0\nOpDecorate %71 RelaxedPrecision\nOpDecorate %71 Location 1\nOpDecorate %74 RelaxedPrecision\nOpDecorate %74 Location 2\nOpDecorate %167 RelaxedPrecision\nOpDecorate %168 RelaxedPrecision\nOpDecorate %197 RelaxedPrecision\nOpDecorate %199 RelaxedPrecision\nOpDecorate %200 RelaxedPrecision\nOpDecorate %201 RelaxedPrecision\nOpDecorate %202 RelaxedPrecision\nOpDecorate %203 RelaxedPrecision\nOpDecorate %211 RelaxedPrecision\nOpDecorate %219 RelaxedPrecision\nOpDecorate %220 RelaxedPrecision\nOpDecorate %221 RelaxedPrecision\nOpDecorate %222 RelaxedPrecision\nOpDecorate %223 RelaxedPrecision\nOpDecorate %224 RelaxedPrecision\nOpDecorate %225 RelaxedPrecision\nOpDecorate %226 RelaxedPrecision\nOpDecorate %227 RelaxedPrecision\nOpDecorate %231 RelaxedPrecision\nOpDecorate %244 RelaxedPrecision\nOpDecorate %266 RelaxedPrecision\nOpDecorate %267 RelaxedPrecision\nOpDecorate %268 RelaxedPrecision\nOpDecorate %269 RelaxedPrecision\nOpDecorate %278 RelaxedPrecision\nOpDecorate %279 RelaxedPrecision\nOpDecorate %280 RelaxedPrecision\nOpDecorate %281 RelaxedPrecision\nOpDecorate %283 RelaxedPrecision\nOpDecorate %284 RelaxedPrecision\nOpDecorate %285 RelaxedPrecision\nOpDecorate %286 RelaxedPrecision\nOpDecorate %287 RelaxedPrecision\nOpDecorate %288 RelaxedPrecision\nOpDecorate %290 RelaxedPrecision\nOpDecorate %291 RelaxedPrecision\nOpDecorate %292 RelaxedPrecision\nOpDecorate %293 RelaxedPrecision\nOpDecorate %297 RelaxedPrecision\nOpDecorate %301 RelaxedPrecision\nOpDecorate %302 RelaxedPrecision\nOpDecorate %303 RelaxedPrecision\nOpDecorate %304 RelaxedPrecision\nOpDecorate %305 RelaxedPrecision\nOpDecorate %307 RelaxedPrecision\nOpDecorate %308 RelaxedPrecision\nOpDecorate %309 RelaxedPrecision\nOpDecorate %310 RelaxedPrecision\nOpDecorate %311 RelaxedPrecision\nOpDecorate %312 RelaxedPrecision\nOpDecorate %313 RelaxedPrecision\nOpDecorate %314 RelaxedPrecision\nOpDecorate %315 RelaxedPrecision\nOpDecorate %316 RelaxedPrecision\nOpDecorate %317 RelaxedPrecision\nOpDecorate %318 RelaxedPrecision\nOpDecorate %319 RelaxedPrecision\nOpDecorate %320 RelaxedPrecision\nOpDecorate %321 RelaxedPrecision\nOpDecorate %322 RelaxedPrecision\nOpDecorate %323 RelaxedPrecision\nOpDecorate %324 RelaxedPrecision\nOpDecorate %325 RelaxedPrecision\nOpDecorate %326 RelaxedPrecision\nOpDecorate %327 RelaxedPrecision\nOpDecorate %328 RelaxedPrecision\nOpDecorate %329 RelaxedPrecision\nOpDecorate %330 RelaxedPrecision\nOpDecorate %331 RelaxedPrecision\nOpDecorate %332 RelaxedPrecision\nOpDecorate %333 RelaxedPrecision\nOpDecorate %334 RelaxedPrecision\nOpDecorate %335 RelaxedPrecision\nOpDecorate %336 RelaxedPrecision\nOpDecorate %346 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeInt 32 1\n%15 = OpTypeImage %14 2D 0 0 0 1 Unknown\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %14 Buffer 0 0 0 1 Unknown\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer UniformConstant %32\n%34 = OpVariable %33 UniformConstant\n%35 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%36 = OpTypeRuntimeArray %35\n%37 = OpTypePointer UniformConstant %36\n%38 = OpVariable %37 UniformConstant\n%39 = OpTypeImage %14 2D 0 0 0 2 Unknown\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer UniformConstant %40\n%42 = OpVariable %41 UniformConstant\n%43 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%44 = OpTypeRuntimeArray %43\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%48 = OpTypeRuntimeArray %47\n%49 = OpTypePointer UniformConstant %48\n%50 = OpVariable %49 UniformConstant\n%51 = OpTypeImage %14 Buffer 0 0 0 2 Unknown\n%52 = OpTypeRuntimeArray %51\n%53 = OpTypePointer UniformConstant %52\n%54 = OpVariable %53 UniformConstant\n%55 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%56 = OpTypeRuntimeArray %55\n%57 = OpTypePointer UniformConstant %56\n%58 = OpVariable %57 UniformConstant\n%59 = OpTypeSampler\n%60 = OpTypeRuntimeArray %59\n%61 = OpTypePointer UniformConstant %60\n%62 = OpVariable %61 UniformConstant\n%63 = OpTypeVector %9 2\n%64 = OpTypePointer Input %63\n%65 = OpVariable %64 Input\n%66 = OpTypeVector %9 4\n%67 = OpTypePointer Output %66\n%68 = OpVariable %67 Output\n%69 = OpTypeVector %14 4\n%70 = OpTypePointer Output %69\n%71 = OpVariable %70 Output\n%72 = OpTypeVector %5 4\n%73 = OpTypePointer Output %72\n%74 = OpVariable %73 Output\n%75 = OpTypePointer UniformConstant %55\n%77 = OpTypePointer PushConstant %5\n%79 = OpConstant %5 4\n%82 = OpConstant %5 5\n%84 = OpTypePointer UniformConstant %51\n%90 = OpTypePointer UniformConstant %47\n%95 = OpConstant %5 3\n%97 = OpTypePointer UniformConstant %43\n%102 = OpConstant %5 2\n%104 = OpTypePointer UniformConstant %39\n%109 = OpConstant %5 1\n%111 = OpTypePointer UniformConstant %35\n%116 = OpTypePointer UniformConstant %31\n%122 = OpTypePointer UniformConstant %27\n%128 = OpTypePointer UniformConstant %23\n%134 = OpTypePointer UniformConstant %19\n%137 = OpConstant %5 0\n%141 = OpTypePointer UniformConstant %15\n%147 = OpTypePointer UniformConstant %10\n%152 = OpTypePointer UniformConstant %59\n%162 = OpTypePointer Input %9\n%171 = OpTypeVector %5 2\n%174 = OpTypeInt 16 0\n%178 = OpTypeVector %174 4\n%186 = OpConstant %9 8\n%188 = OpConstant %174 65516\n%191 = OpConstant %174 80\n%194 = OpTypeSampledImage %10\n%196 = OpConstant %9 0\n%210 = OpConstant %5 6\n%228 = OpTypeSampledImage %15\n%241 = OpTypeSampledImage %19\n%254 = OpTypeImage %9 2D 1 0 0 1 Unknown\n%255 = OpTypeSampledImage %254\n%257 = OpConstant %9 0.5\n%294 = OpConstant %9 0.200000003\n%295 = OpConstant %9 0.300000012\n%296 = OpConstant %9 0.400000006\n%356 = OpTypePointer Output %9\n%361 = OpTypePointer Output %14\n%370 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %379\n%379 = OpLabel\n%78 = OpAccessChain %77 %8 %79\n%80 = OpLoad %5 %78\n%81 = OpIAdd %5 %80 %82\n%76 = OpAccessChain %75 %58 %81\n%83 = OpLoad %55 %76\n%86 = OpAccessChain %77 %8 %79\n%87 = OpLoad %5 %86\n%88 = OpIAdd %5 %87 %79\n%85 = OpAccessChain %84 %54 %88\n%89 = OpLoad %51 %85\n%92 = OpAccessChain %77 %8 %79\n%93 = OpLoad %5 %92\n%94 = OpIAdd %5 %93 %95\n%91 = OpAccessChain %90 %50 %94\n%96 = OpLoad %47 %91\n%99 = OpAccessChain %77 %8 %95\n%100 = OpLoad %5 %99\n%101 = OpIAdd %5 %100 %102\n%98 = OpAccessChain %97 %46 %101\n%103 = OpLoad %43 %98\n%106 = OpAccessChain %77 %8 %95\n%107 = OpLoad %5 %106\n%108 = OpIAdd %5 %107 %109\n%105 = OpAccessChain %104 %42 %108\n%110 = OpLoad %39 %105\n%113 = OpAccessChain %77 %8 %95\n%114 = OpLoad %5 %113\n%112 = OpAccessChain %111 %38 %114\n%115 = OpLoad %35 %112\n%118 = OpAccessChain %77 %8 %109\n%119 = OpLoad %5 %118\n%120 = OpIAdd %5 %119 %82\n%117 = OpAccessChain %116 %34 %120\n%121 = OpLoad %31 %117\n%124 = OpAccessChain %77 %8 %109\n%125 = OpLoad %5 %124\n%126 = OpIAdd %5 %125 %79\n%123 = OpAccessChain %122 %30 %126\n%127 = OpLoad %27 %123\n%130 = OpAccessChain %77 %8 %109\n%131 = OpLoad %5 %130\n%132 = OpIAdd %5 %131 %95\n%129 = OpAccessChain %128 %26 %132\n%133 = OpLoad %23 %129\n%136 = OpAccessChain %77 %8 %137\n%138 = OpLoad %5 %136\n%139 = OpIAdd %5 %138 %102\n%135 = OpAccessChain %134 %22 %139\n%140 = OpLoad %19 %135\n%143 = OpAccessChain %77 %8 %137\n%144 = OpLoad %5 %143\n%145 = OpIAdd %5 %144 %109\n%142 = OpAccessChain %141 %18 %145\n%146 = OpLoad %15 %142\n%149 = OpAccessChain %77 %8 %137\n%150 = OpLoad %5 %149\n%148 = OpAccessChain %147 %13 %150\n%151 = OpLoad %10 %148\n%154 = OpAccessChain %77 %8 %102\n%155 = OpLoad %5 %154\n%156 = OpIAdd %5 %155 %109\n%153 = OpAccessChain %152 %62 %156\n%157 = OpLoad %59 %153\n%159 = OpAccessChain %77 %8 %102\n%160 = OpLoad %5 %159\n%158 = OpAccessChain %152 %62 %160\n%161 = OpLoad %59 %158\n%163 = OpAccessChain %162 %65 %137\n%164 = OpLoad %9 %163\n%165 = OpAccessChain %162 %65 %109\n%166 = OpLoad %9 %165\n%167 = OpCopyObject %9 %164\n%168 = OpCopyObject %9 %166\n%169 = OpConvertFToS %5 %164\n%170 = OpConvertFToS %5 %166\n%172 = OpCompositeConstruct %171 %169 %170\n%173 = OpCompositeConstruct %66 %167 %168 %167 %168\nOpImageWrite %115 %172 %173\n%175 = OpConvertFToS %174 %164\n%176 = OpConvertFToS %174 %166\n%177 = OpCompositeConstruct %171 %169 %170\n%179 = OpCompositeConstruct %178 %175 %176 %175 %176\n%180 = OpSConvert %69 %179\nOpImageWrite %110 %177 %180\n%181 = OpConvertFToU %174 %164\n%182 = OpConvertFToU %174 %166\n%183 = OpCompositeConstruct %171 %169 %170\n%184 = OpCompositeConstruct %178 %181 %182 %181 %182\n%185 = OpUConvert %72 %184\nOpImageWrite %103 %183 %185\n%187 = OpCompositeConstruct %66 %186 %186 %186 %186\nOpImageWrite %96 %169 %187\n%189 = OpCompositeConstruct %178 %188 %188 %188 %188\n%190 = OpSConvert %69 %189\nOpImageWrite %89 %169 %190\n%192 = OpCompositeConstruct %178 %191 %191 %191 %191\n%193 = OpUConvert %72 %192\nOpImageWrite %83 %169 %193\n%195 = OpSampledImage %194 %151 %161\n%198 = OpCompositeConstruct %63 %164 %166\n%197 = OpImageSampleImplicitLod %66 %195 %198 None\n%199 = OpCompositeExtract %9 %197 0\n%200 = OpCompositeExtract %9 %197 1\n%201 = OpCompositeExtract %9 %197 2\n%202 = OpCompositeExtract %9 %197 3\n%204 = OpCompositeConstruct %171 %109 %102\n%203 = OpImageFetch %69 %146 %204 Lod %95\n%205 = OpSConvert %178 %203\n%206 = OpCompositeExtract %174 %205 0\n%207 = OpCompositeExtract %174 %205 1\n%208 = OpCompositeExtract %174 %205 2\n%209 = OpCompositeExtract %174 %205 3\n%212 = OpCompositeConstruct %171 %79 %82\n%211 = OpImageFetch %72 %140 %212 Lod %210\n%213 = OpUConvert %178 %211\n%214 = OpCompositeExtract %174 %213 0\n%215 = OpCompositeExtract %174 %213 1\n%216 = OpCompositeExtract %174 %213 2\n%217 = OpCompositeExtract %174 %213 3\n%218 = OpCompositeConstruct %63 %164 %166\n%219 = OpImageGather %66 %195 %218 %137\n%220 = OpCompositeExtract %9 %219 0\n%221 = OpCompositeExtract %9 %219 1\n%222 = OpCompositeExtract %9 %219 2\n%223 = OpCompositeExtract %9 %219 3\n%224 = OpFAdd %9 %220 %199\n%225 = OpFAdd %9 %221 %200\n%226 = OpFAdd %9 %222 %201\n%227 = OpFAdd %9 %223 %202\n%229 = OpSampledImage %228 %146 %161\n%230 = OpCompositeConstruct %63 %164 %166\n%231 = OpImageGather %69 %229 %230 %109\n%232 = OpSConvert %178 %231\n%233 = OpCompositeExtract %174 %232 0\n%234 = OpCompositeExtract %174 %232 1\n%235 = OpCompositeExtract %174 %232 2\n%236 = OpCompositeExtract %174 %232 3\n%237 = OpIAdd %174 %233 %206\n%238 = OpIAdd %174 %234 %207\n%239 = OpIAdd %174 %235 %208\n%240 = OpIAdd %174 %236 %209\n%242 = OpSampledImage %241 %140 %161\n%243 = OpCompositeConstruct %63 %164 %166\n%244 = OpImageGather %72 %242 %243 %102\n%245 = OpUConvert %178 %244\n%246 = OpCompositeExtract %174 %245 0\n%247 = OpCompositeExtract %174 %245 1\n%248 = OpCompositeExtract %174 %245 2\n%249 = OpCompositeExtract %174 %245 3\n%250 = OpIAdd %174 %246 %214\n%251 = OpIAdd %174 %247 %215\n%252 = OpIAdd %174 %248 %216\n%253 = OpIAdd %174 %249 %217\n%256 = OpSampledImage %255 %151 %157\n%259 = OpCompositeConstruct %63 %164 %166\n%258 = OpImageSampleDrefImplicitLod %9 %256 %259 %257 None\n%260 = OpCompositeConstruct %66 %258 %258 %258 %258\n%261 = OpCompositeExtract %9 %260 0\n%262 = OpFAdd %9 %261 %224\n%263 = OpFAdd %9 %261 %225\n%264 = OpFAdd %9 %261 %226\n%265 = OpFAdd %9 %261 %227\n%266 = OpCopyObject %9 %262\n%267 = OpCopyObject %9 %263\n%268 = OpCopyObject %9 %264\n%269 = OpCopyObject %9 %265\n%271 = OpCompositeConstruct %63 %164 %166\n%270 = OpImageSampleDrefExplicitLod %9 %256 %271 %257 Lod %196\n%272 = OpCompositeConstruct %66 %270 %270 %270 %270\n%273 = OpCompositeExtract %9 %272 0\n%274 = OpFAdd %9 %266 %273\n%275 = OpFAdd %9 %267 %273\n%276 = OpFAdd %9 %268 %273\n%277 = OpFAdd %9 %269 %273\n%278 = OpCopyObject %9 %274\n%279 = OpCopyObject %9 %275\n%280 = OpCopyObject %9 %276\n%281 = OpCopyObject %9 %277\n%282 = OpCompositeConstruct %63 %164 %166\n%283 = OpImageDrefGather %66 %256 %282 %257\n%284 = OpCompositeExtract %9 %283 0\n%285 = OpCompositeExtract %9 %283 1\n%286 = OpCompositeExtract %9 %283 2\n%287 = OpCompositeExtract %9 %283 3\n%289 = OpCompositeConstruct %63 %164 %166\n%288 = OpImageSampleExplicitLod %66 %195 %289 Lod %196\n%290 = OpCompositeExtract %9 %288 0\n%291 = OpCompositeExtract %9 %288 1\n%292 = OpCompositeExtract %9 %288 2\n%293 = OpCompositeExtract %9 %288 3\n%298 = OpCompositeConstruct %63 %164 %166\n%299 = OpCompositeConstruct %63 %294 %295\n%300 = OpCompositeConstruct %63 %296 %257\n%297 = OpImageSampleExplicitLod %66 %195 %298 Grad %299 %300\n%301 = OpCompositeExtract %9 %297 0\n%302 = OpCompositeExtract %9 %297 1\n%303 = OpCompositeExtract %9 %297 2\n%304 = OpCompositeExtract %9 %297 3\n%306 = OpCompositeConstruct %63 %164 %166\n%305 = OpImageSampleImplicitLod %66 %195 %306 Bias %257\n%307 = OpCompositeExtract %9 %305 0\n%308 = OpCompositeExtract %9 %305 1\n%309 = OpCompositeExtract %9 %305 2\n%310 = OpCompositeExtract %9 %305 3\n%311 = OpImageFetch %66 %133 %169\n%312 = OpCompositeExtract %9 %311 0\n%313 = OpCompositeExtract %9 %311 1\n%314 = OpCompositeExtract %9 %311 2\n%315 = OpCompositeExtract %9 %311 3\n%316 = OpFAdd %9 %290 %284\n%317 = OpFAdd %9 %316 %301\n%318 = OpFAdd %9 %317 %278\n%319 = OpFAdd %9 %318 %307\n%320 = OpFAdd %9 %319 %312\n%321 = OpFAdd %9 %291 %285\n%322 = OpFAdd %9 %321 %302\n%323 = OpFAdd %9 %322 %279\n%324 = OpFAdd %9 %323 %308\n%325 = OpFAdd %9 %324 %313\n%326 = OpFAdd %9 %292 %286\n%327 = OpFAdd %9 %326 %303\n%328 = OpFAdd %9 %327 %280\n%329 = OpFAdd %9 %328 %309\n%330 = OpFAdd %9 %329 %314\n%331 = OpFAdd %9 %293 %287\n%332 = OpFAdd %9 %331 %304\n%333 = OpFAdd %9 %332 %281\n%334 = OpFAdd %9 %333 %310\n%335 = OpFAdd %9 %334 %315\n%336 = OpImageFetch %69 %127 %169\n%337 = OpSConvert %178 %336\n%338 = OpCompositeExtract %174 %337 0\n%339 = OpCompositeExtract %174 %337 1\n%340 = OpCompositeExtract %174 %337 2\n%341 = OpCompositeExtract %174 %337 3\n%342 = OpIAdd %174 %237 %338\n%343 = OpIAdd %174 %238 %339\n%344 = OpIAdd %174 %239 %340\n%345 = OpIAdd %174 %240 %341\n%346 = OpImageFetch %72 %121 %169\n%347 = OpUConvert %178 %346\n%348 = OpCompositeExtract %174 %347 0\n%349 = OpCompositeExtract %174 %347 1\n%350 = OpCompositeExtract %174 %347 2\n%351 = OpCompositeExtract %174 %347 3\n%352 = OpIAdd %174 %250 %348\n%353 = OpIAdd %174 %251 %349\n%354 = OpIAdd %174 %252 %350\n%355 = OpIAdd %174 %253 %351\n%357 = OpAccessChain %356 %68 %137\nOpStore %357 %320\n%358 = OpAccessChain %356 %68 %109\nOpStore %358 %325\n%359 = OpAccessChain %356 %68 %102\nOpStore %359 %330\n%360 = OpAccessChain %356 %68 %95\nOpStore %360 %335\n%362 = OpAccessChain %361 %71 %137\n%363 = OpSConvert %14 %342\nOpStore %362 %363\n%364 = OpAccessChain %361 %71 %109\n%365 = OpSConvert %14 %343\nOpStore %364 %365\n%366 = OpAccessChain %361 %71 %102\n%367 = OpSConvert %14 %344\nOpStore %366 %367\n%368 = OpAccessChain %361 %71 %95\n%369 = OpSConvert %14 %345\nOpStore %368 %369\n%371 = OpAccessChain %370 %74 %137\n%372 = OpUConvert %5 %352\nOpStore %371 %372\n%373 = OpAccessChain %370 %74 %109\n%374 = OpUConvert %5 %353\nOpStore %373 %374\n%375 = OpAccessChain %370 %74 %102\n%376 = OpUConvert %5 %354\nOpStore %375 %376\n%377 = OpAccessChain %370 %74 %95\n%378 = OpUConvert %5 %355\nOpStore %377 %378\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/typed-resources-16bit.sm60.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _8;\nlayout(set = 0, binding = 1) uniform mediump itexture2D _12;\nlayout(set = 0, binding = 2) uniform mediump utexture2D _16;\nlayout(set = 0, binding = 3) uniform mediump samplerBuffer _19;\nlayout(set = 0, binding = 4) uniform mediump isamplerBuffer _22;\nlayout(set = 0, binding = 5) uniform mediump usamplerBuffer _25;\nlayout(set = 0, binding = 0) uniform writeonly mediump image2D _28;\nlayout(set = 0, binding = 1) uniform writeonly mediump iimage2D _31;\nlayout(set = 0, binding = 2) uniform writeonly mediump uimage2D _34;\nlayout(set = 0, binding = 3) uniform writeonly mediump imageBuffer _37;\nlayout(set = 0, binding = 4) uniform writeonly mediump iimageBuffer _40;\nlayout(set = 0, binding = 5) uniform writeonly mediump uimageBuffer _43;\nlayout(set = 0, binding = 0) uniform sampler _46;\nlayout(set = 0, binding = 1) uniform samplerShadow _47;\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out mediump vec4 SV_Target;\nlayout(location = 1) out mediump ivec4 SV_Target_1;\nlayout(location = 2) out mediump uvec4 SV_Target_2;\n\nvoid main()\n{\n    mediump float _81 = UV.x;\n    mediump float _82 = UV.y;\n    uint _83 = uint(int(UV.x));\n    uint _84 = uint(int(UV.y));\n    imageStore(_28, ivec2(uvec2(_83, _84)), vec4(_81, _82, _81, _82));\n    uint16_t _89 = uint16_t(int16_t(UV.x));\n    uint16_t _90 = uint16_t(int16_t(UV.y));\n    imageStore(_31, ivec2(uvec2(_83, _84)), ivec4(i16vec4(u16vec4(_89, _90, _89, _90))));\n    uint16_t _95 = uint16_t(UV.x);\n    uint16_t _96 = uint16_t(UV.y);\n    imageStore(_34, ivec2(uvec2(_83, _84)), uvec4(u16vec4(_95, _96, _95, _96)));\n    imageStore(_37, int(_83), vec4(8.0));\n    imageStore(_40, int(_83), ivec4(i16vec4(u16vec4(65516us))));\n    imageStore(_43, int(_83), uvec4(u16vec4(80us)));\n    mediump vec4 _111 = texture(sampler2D(_8, _46), vec2(UV.x, UV.y));\n    u16vec4 _121 = u16vec4(texelFetch(_12, ivec2(uvec2(1u, 2u)), int(3u)));\n    u16vec4 _131 = u16vec4(texelFetch(_16, ivec2(uvec2(4u, 5u)), int(6u)));\n    mediump vec4 _137 = textureGather(sampler2D(_8, _46), vec2(UV.x, UV.y));\n    mediump float _142 = _137.x + _111.x;\n    float hp_copy_142 = _142;\n    mediump float _143 = _137.y + _111.y;\n    float hp_copy_143 = _143;\n    mediump float _144 = _137.z + _111.z;\n    float hp_copy_144 = _144;\n    mediump float _145 = _137.w + _111.w;\n    float hp_copy_145 = _145;\n    u16vec4 _150 = u16vec4(textureGather(isampler2D(_12, _46), vec2(UV.x, UV.y), int(1u)));\n    u16vec4 _163 = u16vec4(textureGather(usampler2D(_16, _46), vec2(UV.x, UV.y), int(2u)));\n    mediump float _179 = vec4(texture(sampler2DShadow(_8, _47), vec3(vec2(UV.x, UV.y), 0.5))).x;\n    float hp_copy_179 = _179;\n    mediump float _184 = hp_copy_179 + hp_copy_142;\n    float hp_copy_184 = _184;\n    mediump float _185 = hp_copy_179 + hp_copy_143;\n    float hp_copy_185 = _185;\n    mediump float _186 = hp_copy_179 + hp_copy_144;\n    float hp_copy_186 = _186;\n    mediump float _187 = hp_copy_179 + hp_copy_145;\n    float hp_copy_187 = _187;\n    mediump float _191 = vec4(textureLod(sampler2DShadow(_8, _47), vec3(vec2(UV.x, UV.y), 0.5), 0.0)).x;\n    float hp_copy_191 = _191;\n    mediump float _196 = hp_copy_184 + hp_copy_191;\n    mediump float _197 = hp_copy_185 + hp_copy_191;\n    mediump float _198 = hp_copy_186 + hp_copy_191;\n    mediump float _199 = hp_copy_187 + hp_copy_191;\n    vec2 _200 = vec2(UV.x, UV.y);\n    mediump vec4 _201 = textureGather(sampler2DShadow(_8, _47), _200, 0.5);\n    mediump vec4 _206 = textureLod(sampler2D(_8, _46), vec2(UV.x, UV.y), 0.0);\n    mediump vec4 _215 = textureGrad(sampler2D(_8, _46), vec2(UV.x, UV.y), vec2(0.20000000298023223876953125, 0.300000011920928955078125), vec2(0.4000000059604644775390625, 0.5));\n    mediump vec4 _223 = texture(sampler2D(_8, _46), vec2(UV.x, UV.y), 0.5);\n    mediump vec4 _229 = texelFetch(_19, int(_83));\n    u16vec4 _255 = u16vec4(texelFetch(_22, int(_83)));\n    u16vec4 _265 = u16vec4(texelFetch(_25, int(_83)));\n    SV_Target.x = ((((_206.x + _201.x) + _215.x) + _196) + _223.x) + _229.x;\n    SV_Target.y = ((((_206.y + _201.y) + _215.y) + _197) + _223.y) + _229.y;\n    SV_Target.z = ((((_206.z + _201.z) + _215.z) + _198) + _223.z) + _229.z;\n    SV_Target.w = ((((_206.w + _201.w) + _215.w) + _199) + _223.w) + _229.w;\n    SV_Target_1.x = int(int16_t((_150.x + _121.x) + _255.x));\n    SV_Target_1.y = int(int16_t((_150.y + _121.y) + _255.y));\n    SV_Target_1.z = int(int16_t((_150.z + _121.z) + _255.z));\n    SV_Target_1.w = int(int16_t((_150.w + _121.w) + _255.w));\n    SV_Target_2.x = uint((_163.x + _131.x) + _265.x);\n    SV_Target_2.y = uint((_163.y + _131.y) + _265.y);\n    SV_Target_2.z = uint((_163.z + _131.z) + _265.z);\n    SV_Target_2.w = uint((_163.w + _131.w) + _265.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 299\n; Schema: 0\nOpCapability Shader\nOpCapability Int16\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %50 %53 %56 %59\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %50 \"UV\"\nOpName %53 \"SV_Target\"\nOpName %56 \"SV_Target_1\"\nOpName %59 \"SV_Target_2\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 2\nOpDecorate %19 RelaxedPrecision\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 3\nOpDecorate %22 RelaxedPrecision\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 4\nOpDecorate %25 RelaxedPrecision\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 5\nOpDecorate %28 RelaxedPrecision\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %31 RelaxedPrecision\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 1\nOpDecorate %31 NonReadable\nOpDecorate %34 RelaxedPrecision\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 2\nOpDecorate %34 NonReadable\nOpDecorate %37 RelaxedPrecision\nOpDecorate %37 DescriptorSet 0\nOpDecorate %37 Binding 3\nOpDecorate %37 NonReadable\nOpDecorate %40 RelaxedPrecision\nOpDecorate %40 DescriptorSet 0\nOpDecorate %40 Binding 4\nOpDecorate %40 NonReadable\nOpDecorate %43 RelaxedPrecision\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 5\nOpDecorate %43 NonReadable\nOpDecorate %46 DescriptorSet 0\nOpDecorate %46 Binding 0\nOpDecorate %47 DescriptorSet 0\nOpDecorate %47 Binding 1\nOpDecorate %50 Location 0\nOpDecorate %53 RelaxedPrecision\nOpDecorate %53 Location 0\nOpDecorate %56 RelaxedPrecision\nOpDecorate %56 Location 1\nOpDecorate %59 RelaxedPrecision\nOpDecorate %59 Location 2\nOpDecorate %81 RelaxedPrecision\nOpDecorate %82 RelaxedPrecision\nOpDecorate %111 RelaxedPrecision\nOpDecorate %113 RelaxedPrecision\nOpDecorate %114 RelaxedPrecision\nOpDecorate %115 RelaxedPrecision\nOpDecorate %116 RelaxedPrecision\nOpDecorate %119 RelaxedPrecision\nOpDecorate %129 RelaxedPrecision\nOpDecorate %137 RelaxedPrecision\nOpDecorate %138 RelaxedPrecision\nOpDecorate %139 RelaxedPrecision\nOpDecorate %140 RelaxedPrecision\nOpDecorate %141 RelaxedPrecision\nOpDecorate %142 RelaxedPrecision\nOpDecorate %143 RelaxedPrecision\nOpDecorate %144 RelaxedPrecision\nOpDecorate %145 RelaxedPrecision\nOpDecorate %149 RelaxedPrecision\nOpDecorate %162 RelaxedPrecision\nOpDecorate %184 RelaxedPrecision\nOpDecorate %185 RelaxedPrecision\nOpDecorate %186 RelaxedPrecision\nOpDecorate %187 RelaxedPrecision\nOpDecorate %196 RelaxedPrecision\nOpDecorate %197 RelaxedPrecision\nOpDecorate %198 RelaxedPrecision\nOpDecorate %199 RelaxedPrecision\nOpDecorate %201 RelaxedPrecision\nOpDecorate %202 RelaxedPrecision\nOpDecorate %203 RelaxedPrecision\nOpDecorate %204 RelaxedPrecision\nOpDecorate %205 RelaxedPrecision\nOpDecorate %206 RelaxedPrecision\nOpDecorate %208 RelaxedPrecision\nOpDecorate %209 RelaxedPrecision\nOpDecorate %210 RelaxedPrecision\nOpDecorate %211 RelaxedPrecision\nOpDecorate %215 RelaxedPrecision\nOpDecorate %219 RelaxedPrecision\nOpDecorate %220 RelaxedPrecision\nOpDecorate %221 RelaxedPrecision\nOpDecorate %222 RelaxedPrecision\nOpDecorate %223 RelaxedPrecision\nOpDecorate %225 RelaxedPrecision\nOpDecorate %226 RelaxedPrecision\nOpDecorate %227 RelaxedPrecision\nOpDecorate %228 RelaxedPrecision\nOpDecorate %229 RelaxedPrecision\nOpDecorate %230 RelaxedPrecision\nOpDecorate %231 RelaxedPrecision\nOpDecorate %232 RelaxedPrecision\nOpDecorate %233 RelaxedPrecision\nOpDecorate %234 RelaxedPrecision\nOpDecorate %235 RelaxedPrecision\nOpDecorate %236 RelaxedPrecision\nOpDecorate %237 RelaxedPrecision\nOpDecorate %238 RelaxedPrecision\nOpDecorate %239 RelaxedPrecision\nOpDecorate %240 RelaxedPrecision\nOpDecorate %241 RelaxedPrecision\nOpDecorate %242 RelaxedPrecision\nOpDecorate %243 RelaxedPrecision\nOpDecorate %244 RelaxedPrecision\nOpDecorate %245 RelaxedPrecision\nOpDecorate %246 RelaxedPrecision\nOpDecorate %247 RelaxedPrecision\nOpDecorate %248 RelaxedPrecision\nOpDecorate %249 RelaxedPrecision\nOpDecorate %250 RelaxedPrecision\nOpDecorate %251 RelaxedPrecision\nOpDecorate %252 RelaxedPrecision\nOpDecorate %253 RelaxedPrecision\nOpDecorate %254 RelaxedPrecision\nOpDecorate %264 RelaxedPrecision\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 1\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeInt 32 0\n%14 = OpTypeImage %13 2D 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%30 = OpTypePointer UniformConstant %29\n%31 = OpVariable %30 UniformConstant\n%32 = OpTypeImage %13 2D 0 0 0 2 Unknown\n%33 = OpTypePointer UniformConstant %32\n%34 = OpVariable %33 UniformConstant\n%35 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%36 = OpTypePointer UniformConstant %35\n%37 = OpVariable %36 UniformConstant\n%38 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%39 = OpTypePointer UniformConstant %38\n%40 = OpVariable %39 UniformConstant\n%41 = OpTypeImage %13 Buffer 0 0 0 2 Unknown\n%42 = OpTypePointer UniformConstant %41\n%43 = OpVariable %42 UniformConstant\n%44 = OpTypeSampler\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpVariable %45 UniformConstant\n%48 = OpTypeVector %5 2\n%49 = OpTypePointer Input %48\n%50 = OpVariable %49 Input\n%51 = OpTypeVector %5 4\n%52 = OpTypePointer Output %51\n%53 = OpVariable %52 Output\n%54 = OpTypeVector %9 4\n%55 = OpTypePointer Output %54\n%56 = OpVariable %55 Output\n%57 = OpTypeVector %13 4\n%58 = OpTypePointer Output %57\n%59 = OpVariable %58 Output\n%74 = OpTypePointer Input %5\n%76 = OpConstant %13 0\n%79 = OpConstant %13 1\n%85 = OpTypeVector %13 2\n%88 = OpTypeInt 16 0\n%92 = OpTypeVector %88 4\n%100 = OpConstant %5 8\n%102 = OpConstant %88 65516\n%105 = OpConstant %88 80\n%108 = OpTypeSampledImage %6\n%110 = OpConstant %5 0\n%117 = OpConstant %13 3\n%118 = OpConstant %13 2\n%126 = OpConstant %13 6\n%127 = OpConstant %13 4\n%128 = OpConstant %13 5\n%146 = OpTypeSampledImage %10\n%159 = OpTypeSampledImage %14\n%172 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%173 = OpTypeSampledImage %172\n%175 = OpConstant %5 0.5\n%212 = OpConstant %5 0.200000003\n%213 = OpConstant %5 0.300000012\n%214 = OpConstant %5 0.400000006\n%274 = OpTypePointer Output %5\n%279 = OpTypePointer Output %9\n%288 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %297\n%297 = OpLabel\n%60 = OpLoad %41 %43\n%61 = OpLoad %38 %40\n%62 = OpLoad %35 %37\n%63 = OpLoad %32 %34\n%64 = OpLoad %29 %31\n%65 = OpLoad %26 %28\n%66 = OpLoad %23 %25\n%67 = OpLoad %20 %22\n%68 = OpLoad %17 %19\n%69 = OpLoad %14 %16\n%70 = OpLoad %10 %12\n%71 = OpLoad %6 %8\n%72 = OpLoad %44 %47\n%73 = OpLoad %44 %46\n%75 = OpAccessChain %74 %50 %76\n%77 = OpLoad %5 %75\n%78 = OpAccessChain %74 %50 %79\n%80 = OpLoad %5 %78\n%81 = OpCopyObject %5 %77\n%82 = OpCopyObject %5 %80\n%83 = OpConvertFToS %13 %77\n%84 = OpConvertFToS %13 %80\n%86 = OpCompositeConstruct %85 %83 %84\n%87 = OpCompositeConstruct %51 %81 %82 %81 %82\nOpImageWrite %65 %86 %87\n%89 = OpConvertFToS %88 %77\n%90 = OpConvertFToS %88 %80\n%91 = OpCompositeConstruct %85 %83 %84\n%93 = OpCompositeConstruct %92 %89 %90 %89 %90\n%94 = OpSConvert %54 %93\nOpImageWrite %64 %91 %94\n%95 = OpConvertFToU %88 %77\n%96 = OpConvertFToU %88 %80\n%97 = OpCompositeConstruct %85 %83 %84\n%98 = OpCompositeConstruct %92 %95 %96 %95 %96\n%99 = OpUConvert %57 %98\nOpImageWrite %63 %97 %99\n%101 = OpCompositeConstruct %51 %100 %100 %100 %100\nOpImageWrite %62 %83 %101\n%103 = OpCompositeConstruct %92 %102 %102 %102 %102\n%104 = OpSConvert %54 %103\nOpImageWrite %61 %83 %104\n%106 = OpCompositeConstruct %92 %105 %105 %105 %105\n%107 = OpUConvert %57 %106\nOpImageWrite %60 %83 %107\n%109 = OpSampledImage %108 %71 %73\n%112 = OpCompositeConstruct %48 %77 %80\n%111 = OpImageSampleImplicitLod %51 %109 %112 None\n%113 = OpCompositeExtract %5 %111 0\n%114 = OpCompositeExtract %5 %111 1\n%115 = OpCompositeExtract %5 %111 2\n%116 = OpCompositeExtract %5 %111 3\n%120 = OpCompositeConstruct %85 %79 %118\n%119 = OpImageFetch %54 %70 %120 Lod %117\n%121 = OpSConvert %92 %119\n%122 = OpCompositeExtract %88 %121 0\n%123 = OpCompositeExtract %88 %121 1\n%124 = OpCompositeExtract %88 %121 2\n%125 = OpCompositeExtract %88 %121 3\n%130 = OpCompositeConstruct %85 %127 %128\n%129 = OpImageFetch %57 %69 %130 Lod %126\n%131 = OpUConvert %92 %129\n%132 = OpCompositeExtract %88 %131 0\n%133 = OpCompositeExtract %88 %131 1\n%134 = OpCompositeExtract %88 %131 2\n%135 = OpCompositeExtract %88 %131 3\n%136 = OpCompositeConstruct %48 %77 %80\n%137 = OpImageGather %51 %109 %136 %76\n%138 = OpCompositeExtract %5 %137 0\n%139 = OpCompositeExtract %5 %137 1\n%140 = OpCompositeExtract %5 %137 2\n%141 = OpCompositeExtract %5 %137 3\n%142 = OpFAdd %5 %138 %113\n%143 = OpFAdd %5 %139 %114\n%144 = OpFAdd %5 %140 %115\n%145 = OpFAdd %5 %141 %116\n%147 = OpSampledImage %146 %70 %73\n%148 = OpCompositeConstruct %48 %77 %80\n%149 = OpImageGather %54 %147 %148 %79\n%150 = OpSConvert %92 %149\n%151 = OpCompositeExtract %88 %150 0\n%152 = OpCompositeExtract %88 %150 1\n%153 = OpCompositeExtract %88 %150 2\n%154 = OpCompositeExtract %88 %150 3\n%155 = OpIAdd %88 %151 %122\n%156 = OpIAdd %88 %152 %123\n%157 = OpIAdd %88 %153 %124\n%158 = OpIAdd %88 %154 %125\n%160 = OpSampledImage %159 %69 %73\n%161 = OpCompositeConstruct %48 %77 %80\n%162 = OpImageGather %57 %160 %161 %118\n%163 = OpUConvert %92 %162\n%164 = OpCompositeExtract %88 %163 0\n%165 = OpCompositeExtract %88 %163 1\n%166 = OpCompositeExtract %88 %163 2\n%167 = OpCompositeExtract %88 %163 3\n%168 = OpIAdd %88 %164 %132\n%169 = OpIAdd %88 %165 %133\n%170 = OpIAdd %88 %166 %134\n%171 = OpIAdd %88 %167 %135\n%174 = OpSampledImage %173 %71 %72\n%177 = OpCompositeConstruct %48 %77 %80\n%176 = OpImageSampleDrefImplicitLod %5 %174 %177 %175 None\n%178 = OpCompositeConstruct %51 %176 %176 %176 %176\n%179 = OpCompositeExtract %5 %178 0\n%180 = OpFAdd %5 %179 %142\n%181 = OpFAdd %5 %179 %143\n%182 = OpFAdd %5 %179 %144\n%183 = OpFAdd %5 %179 %145\n%184 = OpCopyObject %5 %180\n%185 = OpCopyObject %5 %181\n%186 = OpCopyObject %5 %182\n%187 = OpCopyObject %5 %183\n%189 = OpCompositeConstruct %48 %77 %80\n%188 = OpImageSampleDrefExplicitLod %5 %174 %189 %175 Lod %110\n%190 = OpCompositeConstruct %51 %188 %188 %188 %188\n%191 = OpCompositeExtract %5 %190 0\n%192 = OpFAdd %5 %184 %191\n%193 = OpFAdd %5 %185 %191\n%194 = OpFAdd %5 %186 %191\n%195 = OpFAdd %5 %187 %191\n%196 = OpCopyObject %5 %192\n%197 = OpCopyObject %5 %193\n%198 = OpCopyObject %5 %194\n%199 = OpCopyObject %5 %195\n%200 = OpCompositeConstruct %48 %77 %80\n%201 = OpImageDrefGather %51 %174 %200 %175\n%202 = OpCompositeExtract %5 %201 0\n%203 = OpCompositeExtract %5 %201 1\n%204 = OpCompositeExtract %5 %201 2\n%205 = OpCompositeExtract %5 %201 3\n%207 = OpCompositeConstruct %48 %77 %80\n%206 = OpImageSampleExplicitLod %51 %109 %207 Lod %110\n%208 = OpCompositeExtract %5 %206 0\n%209 = OpCompositeExtract %5 %206 1\n%210 = OpCompositeExtract %5 %206 2\n%211 = OpCompositeExtract %5 %206 3\n%216 = OpCompositeConstruct %48 %77 %80\n%217 = OpCompositeConstruct %48 %212 %213\n%218 = OpCompositeConstruct %48 %214 %175\n%215 = OpImageSampleExplicitLod %51 %109 %216 Grad %217 %218\n%219 = OpCompositeExtract %5 %215 0\n%220 = OpCompositeExtract %5 %215 1\n%221 = OpCompositeExtract %5 %215 2\n%222 = OpCompositeExtract %5 %215 3\n%224 = OpCompositeConstruct %48 %77 %80\n%223 = OpImageSampleImplicitLod %51 %109 %224 Bias %175\n%225 = OpCompositeExtract %5 %223 0\n%226 = OpCompositeExtract %5 %223 1\n%227 = OpCompositeExtract %5 %223 2\n%228 = OpCompositeExtract %5 %223 3\n%229 = OpImageFetch %51 %68 %83\n%230 = OpCompositeExtract %5 %229 0\n%231 = OpCompositeExtract %5 %229 1\n%232 = OpCompositeExtract %5 %229 2\n%233 = OpCompositeExtract %5 %229 3\n%234 = OpFAdd %5 %208 %202\n%235 = OpFAdd %5 %234 %219\n%236 = OpFAdd %5 %235 %196\n%237 = OpFAdd %5 %236 %225\n%238 = OpFAdd %5 %237 %230\n%239 = OpFAdd %5 %209 %203\n%240 = OpFAdd %5 %239 %220\n%241 = OpFAdd %5 %240 %197\n%242 = OpFAdd %5 %241 %226\n%243 = OpFAdd %5 %242 %231\n%244 = OpFAdd %5 %210 %204\n%245 = OpFAdd %5 %244 %221\n%246 = OpFAdd %5 %245 %198\n%247 = OpFAdd %5 %246 %227\n%248 = OpFAdd %5 %247 %232\n%249 = OpFAdd %5 %211 %205\n%250 = OpFAdd %5 %249 %222\n%251 = OpFAdd %5 %250 %199\n%252 = OpFAdd %5 %251 %228\n%253 = OpFAdd %5 %252 %233\n%254 = OpImageFetch %54 %67 %83\n%255 = OpSConvert %92 %254\n%256 = OpCompositeExtract %88 %255 0\n%257 = OpCompositeExtract %88 %255 1\n%258 = OpCompositeExtract %88 %255 2\n%259 = OpCompositeExtract %88 %255 3\n%260 = OpIAdd %88 %155 %256\n%261 = OpIAdd %88 %156 %257\n%262 = OpIAdd %88 %157 %258\n%263 = OpIAdd %88 %158 %259\n%264 = OpImageFetch %57 %66 %83\n%265 = OpUConvert %92 %264\n%266 = OpCompositeExtract %88 %265 0\n%267 = OpCompositeExtract %88 %265 1\n%268 = OpCompositeExtract %88 %265 2\n%269 = OpCompositeExtract %88 %265 3\n%270 = OpIAdd %88 %168 %266\n%271 = OpIAdd %88 %169 %267\n%272 = OpIAdd %88 %170 %268\n%273 = OpIAdd %88 %171 %269\n%275 = OpAccessChain %274 %53 %76\nOpStore %275 %238\n%276 = OpAccessChain %274 %53 %79\nOpStore %276 %243\n%277 = OpAccessChain %274 %53 %118\nOpStore %277 %248\n%278 = OpAccessChain %274 %53 %117\nOpStore %278 %253\n%280 = OpAccessChain %279 %56 %76\n%281 = OpSConvert %9 %260\nOpStore %280 %281\n%282 = OpAccessChain %279 %56 %79\n%283 = OpSConvert %9 %261\nOpStore %282 %283\n%284 = OpAccessChain %279 %56 %118\n%285 = OpSConvert %9 %262\nOpStore %284 %285\n%286 = OpAccessChain %279 %56 %117\n%287 = OpSConvert %9 %263\nOpStore %286 %287\n%289 = OpAccessChain %288 %59 %76\n%290 = OpUConvert %13 %270\nOpStore %289 %290\n%291 = OpAccessChain %288 %59 %79\n%292 = OpUConvert %13 %271\nOpStore %291 %292\n%293 = OpAccessChain %288 %59 %118\n%294 = OpUConvert %13 %272\nOpStore %293 %294\n%295 = OpAccessChain %288 %59 %117\n%296 = OpUConvert %13 %273\nOpStore %295 %296\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/typed-resources-16bit.sm60.native-fp16.bindless.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _13[];\nlayout(set = 0, binding = 0) uniform mediump itexture2D _18[];\nlayout(set = 0, binding = 0) uniform mediump utexture2D _22[];\nlayout(set = 1, binding = 0) uniform mediump samplerBuffer _26[];\nlayout(set = 1, binding = 0) uniform mediump isamplerBuffer _30[];\nlayout(set = 1, binding = 0) uniform mediump usamplerBuffer _34[];\nlayout(set = 3, binding = 0) uniform writeonly mediump image2D _38[];\nlayout(set = 3, binding = 0) uniform writeonly mediump iimage2D _42[];\nlayout(set = 3, binding = 0) uniform writeonly mediump uimage2D _46[];\nlayout(set = 4, binding = 0) uniform writeonly mediump imageBuffer _50[];\nlayout(set = 4, binding = 0) uniform writeonly mediump iimageBuffer _54[];\nlayout(set = 4, binding = 0) uniform writeonly mediump uimageBuffer _58[];\nlayout(set = 2, binding = 0) uniform samplerShadow _62[];\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out mediump vec4 SV_Target;\nlayout(location = 1) out mediump ivec4 SV_Target_1;\nlayout(location = 2) out mediump uvec4 SV_Target_2;\n\nvoid main()\n{\n    uint _139 = registers._m0 + 2u;\n    uint _145 = registers._m0 + 1u;\n    float16_t _168 = float16_t(UV.x);\n    float16_t _169 = float16_t(UV.y);\n    uint _170 = uint(int(UV.x));\n    uint _171 = uint(int(UV.y));\n    imageStore(_38[registers._m3], ivec2(uvec2(_170, _171)), vec4(f16vec4(_168, _169, _168, _169)));\n    uint16_t _178 = uint16_t(int16_t(UV.x));\n    uint16_t _179 = uint16_t(int16_t(UV.y));\n    imageStore(_42[registers._m3 + 1u], ivec2(uvec2(_170, _171)), ivec4(i16vec4(u16vec4(_178, _179, _178, _179))));\n    uint16_t _184 = uint16_t(UV.x);\n    uint16_t _185 = uint16_t(UV.y);\n    imageStore(_46[registers._m3 + 2u], ivec2(uvec2(_170, _171)), uvec4(u16vec4(_184, _185, _184, _185)));\n    imageStore(_50[registers._m4 + 3u], int(_170), vec4(f16vec4(float16_t(8.0))));\n    imageStore(_54[registers._m4 + 4u], int(_170), ivec4(i16vec4(u16vec4(65516us))));\n    imageStore(_58[registers._m4 + 5u], int(_170), uvec4(u16vec4(80us)));\n    f16vec4 _203 = f16vec4(texture(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y)));\n    u16vec4 _210 = u16vec4(texelFetch(_18[_145], ivec2(uvec2(1u, 2u)), int(3u)));\n    u16vec4 _218 = u16vec4(texelFetch(_22[_139], ivec2(uvec2(4u, 5u)), int(6u)));\n    f16vec4 _225 = f16vec4(textureGather(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y)));\n    u16vec4 _238 = u16vec4(textureGather(isampler2D(_18[_145], _62[registers._m2]), vec2(UV.x, UV.y), int(1u)));\n    u16vec4 _251 = u16vec4(textureGather(usampler2D(_22[_139], _62[registers._m2]), vec2(UV.x, UV.y), int(2u)));\n    mediump vec4 _266 = vec4(texture(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), vec3(vec2(UV.x, UV.y), 0.5)));\n    mediump float _267 = _266.x;\n    mediump vec4 _282 = vec4(textureLod(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), vec3(vec2(UV.x, UV.y), 0.5), 0.0));\n    mediump float _283 = _282.x;\n    vec2 _296 = vec2(UV.x, UV.y);\n    f16vec4 _298 = f16vec4(textureGather(sampler2DShadow(_13[registers._m0], _62[registers._m2 + 1u]), _296, 0.5));\n    f16vec4 _305 = f16vec4(textureLod(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), 0.0));\n    f16vec4 _317 = f16vec4(textureGrad(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), vec2(0.20000000298023223876953125, 0.300000011920928955078125), vec2(0.4000000059604644775390625, 0.5)));\n    f16vec4 _324 = f16vec4(texture(sampler2D(_13[registers._m0], _62[registers._m2]), vec2(UV.x, UV.y), 0.5));\n    f16vec4 _330 = f16vec4(texelFetch(_26[registers._m1 + 3u], int(_170)));\n    u16vec4 _356 = u16vec4(texelFetch(_30[registers._m1 + 4u], int(_170)));\n    u16vec4 _366 = u16vec4(texelFetch(_34[registers._m1 + 5u], int(_170)));\n    SV_Target.x = float(((((_305.x + _298.x) + _317.x) + float16_t(float(float16_t(_267 + float(_225.x + _203.x))) + _283)) + _324.x) + _330.x);\n    SV_Target.y = float(((((_305.y + _298.y) + _317.y) + float16_t(float(float16_t(_267 + float(_225.y + _203.y))) + _283)) + _324.y) + _330.y);\n    SV_Target.z = float(((((_305.z + _298.z) + _317.z) + float16_t(float(float16_t(_267 + float(_225.z + _203.z))) + _283)) + _324.z) + _330.z);\n    SV_Target.w = float(((((_305.w + _298.w) + _317.w) + float16_t(float(float16_t(_267 + float(_225.w + _203.w))) + _283)) + _324.w) + _330.w);\n    SV_Target_1.x = int(int16_t((_238.x + _210.x) + _356.x));\n    SV_Target_1.y = int(int16_t((_238.y + _210.y) + _356.y));\n    SV_Target_1.z = int(int16_t((_238.z + _210.z) + _356.z));\n    SV_Target_1.w = int(int16_t((_238.w + _210.w) + _356.w));\n    SV_Target_2.x = uint((_251.x + _218.x) + _366.x);\n    SV_Target_2.y = uint((_251.y + _218.y) + _366.y);\n    SV_Target_2.z = uint((_251.z + _218.z) + _366.z);\n    SV_Target_2.w = uint((_251.w + _218.w) + _366.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 404\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %65 %68 %71 %74\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %65 \"UV\"\nOpName %68 \"SV_Target\"\nOpName %71 \"SV_Target_1\"\nOpName %74 \"SV_Target_2\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %13 RelaxedPrecision\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %18 RelaxedPrecision\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 0\nOpDecorate %22 RelaxedPrecision\nOpDecorate %26 DescriptorSet 1\nOpDecorate %26 Binding 0\nOpDecorate %26 RelaxedPrecision\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 0\nOpDecorate %30 RelaxedPrecision\nOpDecorate %34 DescriptorSet 1\nOpDecorate %34 Binding 0\nOpDecorate %34 RelaxedPrecision\nOpDecorate %38 DescriptorSet 3\nOpDecorate %38 Binding 0\nOpDecorate %38 RelaxedPrecision\nOpDecorate %38 NonReadable\nOpDecorate %42 DescriptorSet 3\nOpDecorate %42 Binding 0\nOpDecorate %42 RelaxedPrecision\nOpDecorate %42 NonReadable\nOpDecorate %46 DescriptorSet 3\nOpDecorate %46 Binding 0\nOpDecorate %46 RelaxedPrecision\nOpDecorate %46 NonReadable\nOpDecorate %50 DescriptorSet 4\nOpDecorate %50 Binding 0\nOpDecorate %50 RelaxedPrecision\nOpDecorate %50 NonReadable\nOpDecorate %54 DescriptorSet 4\nOpDecorate %54 Binding 0\nOpDecorate %54 RelaxedPrecision\nOpDecorate %54 NonReadable\nOpDecorate %58 DescriptorSet 4\nOpDecorate %58 Binding 0\nOpDecorate %58 RelaxedPrecision\nOpDecorate %58 NonReadable\nOpDecorate %62 DescriptorSet 2\nOpDecorate %62 Binding 0\nOpDecorate %65 Location 0\nOpDecorate %68 RelaxedPrecision\nOpDecorate %68 Location 0\nOpDecorate %71 RelaxedPrecision\nOpDecorate %71 Location 1\nOpDecorate %74 RelaxedPrecision\nOpDecorate %74 Location 2\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeInt 32 1\n%15 = OpTypeImage %14 2D 0 0 0 1 Unknown\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer UniformConstant %16\n%18 = OpVariable %17 UniformConstant\n%19 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%24 = OpTypeRuntimeArray %23\n%25 = OpTypePointer UniformConstant %24\n%26 = OpVariable %25 UniformConstant\n%27 = OpTypeImage %14 Buffer 0 0 0 1 Unknown\n%28 = OpTypeRuntimeArray %27\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer UniformConstant %32\n%34 = OpVariable %33 UniformConstant\n%35 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%36 = OpTypeRuntimeArray %35\n%37 = OpTypePointer UniformConstant %36\n%38 = OpVariable %37 UniformConstant\n%39 = OpTypeImage %14 2D 0 0 0 2 Unknown\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer UniformConstant %40\n%42 = OpVariable %41 UniformConstant\n%43 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%44 = OpTypeRuntimeArray %43\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%48 = OpTypeRuntimeArray %47\n%49 = OpTypePointer UniformConstant %48\n%50 = OpVariable %49 UniformConstant\n%51 = OpTypeImage %14 Buffer 0 0 0 2 Unknown\n%52 = OpTypeRuntimeArray %51\n%53 = OpTypePointer UniformConstant %52\n%54 = OpVariable %53 UniformConstant\n%55 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%56 = OpTypeRuntimeArray %55\n%57 = OpTypePointer UniformConstant %56\n%58 = OpVariable %57 UniformConstant\n%59 = OpTypeSampler\n%60 = OpTypeRuntimeArray %59\n%61 = OpTypePointer UniformConstant %60\n%62 = OpVariable %61 UniformConstant\n%63 = OpTypeVector %9 2\n%64 = OpTypePointer Input %63\n%65 = OpVariable %64 Input\n%66 = OpTypeVector %9 4\n%67 = OpTypePointer Output %66\n%68 = OpVariable %67 Output\n%69 = OpTypeVector %14 4\n%70 = OpTypePointer Output %69\n%71 = OpVariable %70 Output\n%72 = OpTypeVector %5 4\n%73 = OpTypePointer Output %72\n%74 = OpVariable %73 Output\n%75 = OpTypePointer UniformConstant %55\n%77 = OpTypePointer PushConstant %5\n%79 = OpConstant %5 4\n%82 = OpConstant %5 5\n%84 = OpTypePointer UniformConstant %51\n%90 = OpTypePointer UniformConstant %47\n%95 = OpConstant %5 3\n%97 = OpTypePointer UniformConstant %43\n%102 = OpConstant %5 2\n%104 = OpTypePointer UniformConstant %39\n%109 = OpConstant %5 1\n%111 = OpTypePointer UniformConstant %35\n%116 = OpTypePointer UniformConstant %31\n%122 = OpTypePointer UniformConstant %27\n%128 = OpTypePointer UniformConstant %23\n%134 = OpTypePointer UniformConstant %19\n%137 = OpConstant %5 0\n%141 = OpTypePointer UniformConstant %15\n%147 = OpTypePointer UniformConstant %10\n%152 = OpTypePointer UniformConstant %59\n%162 = OpTypePointer Input %9\n%167 = OpTypeFloat 16\n%172 = OpTypeVector %5 2\n%174 = OpTypeVector %167 4\n%177 = OpTypeInt 16 0\n%181 = OpTypeVector %177 4\n%189 = OpConstant %167 0x1p+3\n%192 = OpConstant %177 65516\n%195 = OpConstant %177 80\n%198 = OpTypeSampledImage %10\n%200 = OpConstant %9 0\n%215 = OpConstant %5 6\n%234 = OpTypeSampledImage %15\n%247 = OpTypeSampledImage %19\n%260 = OpTypeImage %9 2D 1 0 0 1 Unknown\n%261 = OpTypeSampledImage %260\n%263 = OpConstant %9 0.5\n%310 = OpConstant %9 0.200000003\n%311 = OpConstant %9 0.300000012\n%312 = OpConstant %9 0.400000006\n%375 = OpTypePointer Output %9\n%384 = OpTypePointer Output %14\n%393 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %402\n%402 = OpLabel\n%78 = OpAccessChain %77 %8 %79\n%80 = OpLoad %5 %78\n%81 = OpIAdd %5 %80 %82\n%76 = OpAccessChain %75 %58 %81\n%83 = OpLoad %55 %76\n%86 = OpAccessChain %77 %8 %79\n%87 = OpLoad %5 %86\n%88 = OpIAdd %5 %87 %79\n%85 = OpAccessChain %84 %54 %88\n%89 = OpLoad %51 %85\n%92 = OpAccessChain %77 %8 %79\n%93 = OpLoad %5 %92\n%94 = OpIAdd %5 %93 %95\n%91 = OpAccessChain %90 %50 %94\n%96 = OpLoad %47 %91\n%99 = OpAccessChain %77 %8 %95\n%100 = OpLoad %5 %99\n%101 = OpIAdd %5 %100 %102\n%98 = OpAccessChain %97 %46 %101\n%103 = OpLoad %43 %98\n%106 = OpAccessChain %77 %8 %95\n%107 = OpLoad %5 %106\n%108 = OpIAdd %5 %107 %109\n%105 = OpAccessChain %104 %42 %108\n%110 = OpLoad %39 %105\n%113 = OpAccessChain %77 %8 %95\n%114 = OpLoad %5 %113\n%112 = OpAccessChain %111 %38 %114\n%115 = OpLoad %35 %112\n%118 = OpAccessChain %77 %8 %109\n%119 = OpLoad %5 %118\n%120 = OpIAdd %5 %119 %82\n%117 = OpAccessChain %116 %34 %120\n%121 = OpLoad %31 %117\n%124 = OpAccessChain %77 %8 %109\n%125 = OpLoad %5 %124\n%126 = OpIAdd %5 %125 %79\n%123 = OpAccessChain %122 %30 %126\n%127 = OpLoad %27 %123\n%130 = OpAccessChain %77 %8 %109\n%131 = OpLoad %5 %130\n%132 = OpIAdd %5 %131 %95\n%129 = OpAccessChain %128 %26 %132\n%133 = OpLoad %23 %129\n%136 = OpAccessChain %77 %8 %137\n%138 = OpLoad %5 %136\n%139 = OpIAdd %5 %138 %102\n%135 = OpAccessChain %134 %22 %139\n%140 = OpLoad %19 %135\n%143 = OpAccessChain %77 %8 %137\n%144 = OpLoad %5 %143\n%145 = OpIAdd %5 %144 %109\n%142 = OpAccessChain %141 %18 %145\n%146 = OpLoad %15 %142\n%149 = OpAccessChain %77 %8 %137\n%150 = OpLoad %5 %149\n%148 = OpAccessChain %147 %13 %150\n%151 = OpLoad %10 %148\n%154 = OpAccessChain %77 %8 %102\n%155 = OpLoad %5 %154\n%156 = OpIAdd %5 %155 %109\n%153 = OpAccessChain %152 %62 %156\n%157 = OpLoad %59 %153\n%159 = OpAccessChain %77 %8 %102\n%160 = OpLoad %5 %159\n%158 = OpAccessChain %152 %62 %160\n%161 = OpLoad %59 %158\n%163 = OpAccessChain %162 %65 %137\n%164 = OpLoad %9 %163\n%165 = OpAccessChain %162 %65 %109\n%166 = OpLoad %9 %165\n%168 = OpFConvert %167 %164\n%169 = OpFConvert %167 %166\n%170 = OpConvertFToS %5 %164\n%171 = OpConvertFToS %5 %166\n%173 = OpCompositeConstruct %172 %170 %171\n%175 = OpCompositeConstruct %174 %168 %169 %168 %169\n%176 = OpFConvert %66 %175\nOpImageWrite %115 %173 %176\n%178 = OpConvertFToS %177 %164\n%179 = OpConvertFToS %177 %166\n%180 = OpCompositeConstruct %172 %170 %171\n%182 = OpCompositeConstruct %181 %178 %179 %178 %179\n%183 = OpSConvert %69 %182\nOpImageWrite %110 %180 %183\n%184 = OpConvertFToU %177 %164\n%185 = OpConvertFToU %177 %166\n%186 = OpCompositeConstruct %172 %170 %171\n%187 = OpCompositeConstruct %181 %184 %185 %184 %185\n%188 = OpUConvert %72 %187\nOpImageWrite %103 %186 %188\n%190 = OpCompositeConstruct %174 %189 %189 %189 %189\n%191 = OpFConvert %66 %190\nOpImageWrite %96 %170 %191\n%193 = OpCompositeConstruct %181 %192 %192 %192 %192\n%194 = OpSConvert %69 %193\nOpImageWrite %89 %170 %194\n%196 = OpCompositeConstruct %181 %195 %195 %195 %195\n%197 = OpUConvert %72 %196\nOpImageWrite %83 %170 %197\n%199 = OpSampledImage %198 %151 %161\n%202 = OpCompositeConstruct %63 %164 %166\n%201 = OpImageSampleImplicitLod %66 %199 %202 None\n%203 = OpFConvert %174 %201\n%204 = OpCompositeExtract %167 %203 0\n%205 = OpCompositeExtract %167 %203 1\n%206 = OpCompositeExtract %167 %203 2\n%207 = OpCompositeExtract %167 %203 3\n%209 = OpCompositeConstruct %172 %109 %102\n%208 = OpImageFetch %69 %146 %209 Lod %95\n%210 = OpSConvert %181 %208\n%211 = OpCompositeExtract %177 %210 0\n%212 = OpCompositeExtract %177 %210 1\n%213 = OpCompositeExtract %177 %210 2\n%214 = OpCompositeExtract %177 %210 3\n%217 = OpCompositeConstruct %172 %79 %82\n%216 = OpImageFetch %72 %140 %217 Lod %215\n%218 = OpUConvert %181 %216\n%219 = OpCompositeExtract %177 %218 0\n%220 = OpCompositeExtract %177 %218 1\n%221 = OpCompositeExtract %177 %218 2\n%222 = OpCompositeExtract %177 %218 3\n%223 = OpCompositeConstruct %63 %164 %166\n%224 = OpImageGather %66 %199 %223 %137\n%225 = OpFConvert %174 %224\n%226 = OpCompositeExtract %167 %225 0\n%227 = OpCompositeExtract %167 %225 1\n%228 = OpCompositeExtract %167 %225 2\n%229 = OpCompositeExtract %167 %225 3\n%230 = OpFAdd %167 %226 %204\n%231 = OpFAdd %167 %227 %205\n%232 = OpFAdd %167 %228 %206\n%233 = OpFAdd %167 %229 %207\n%235 = OpSampledImage %234 %146 %161\n%236 = OpCompositeConstruct %63 %164 %166\n%237 = OpImageGather %69 %235 %236 %109\n%238 = OpSConvert %181 %237\n%239 = OpCompositeExtract %177 %238 0\n%240 = OpCompositeExtract %177 %238 1\n%241 = OpCompositeExtract %177 %238 2\n%242 = OpCompositeExtract %177 %238 3\n%243 = OpIAdd %177 %239 %211\n%244 = OpIAdd %177 %240 %212\n%245 = OpIAdd %177 %241 %213\n%246 = OpIAdd %177 %242 %214\n%248 = OpSampledImage %247 %140 %161\n%249 = OpCompositeConstruct %63 %164 %166\n%250 = OpImageGather %72 %248 %249 %102\n%251 = OpUConvert %181 %250\n%252 = OpCompositeExtract %177 %251 0\n%253 = OpCompositeExtract %177 %251 1\n%254 = OpCompositeExtract %177 %251 2\n%255 = OpCompositeExtract %177 %251 3\n%256 = OpIAdd %177 %252 %219\n%257 = OpIAdd %177 %253 %220\n%258 = OpIAdd %177 %254 %221\n%259 = OpIAdd %177 %255 %222\n%262 = OpSampledImage %261 %151 %157\n%265 = OpCompositeConstruct %63 %164 %166\n%264 = OpImageSampleDrefImplicitLod %9 %262 %265 %263 None\n%266 = OpCompositeConstruct %66 %264 %264 %264 %264\n%267 = OpCompositeExtract %9 %266 0\n%268 = OpFConvert %9 %230\n%269 = OpFConvert %9 %231\n%270 = OpFConvert %9 %232\n%271 = OpFConvert %9 %233\n%272 = OpFAdd %9 %267 %268\n%273 = OpFAdd %9 %267 %269\n%274 = OpFAdd %9 %267 %270\n%275 = OpFAdd %9 %267 %271\n%276 = OpFConvert %167 %272\n%277 = OpFConvert %167 %273\n%278 = OpFConvert %167 %274\n%279 = OpFConvert %167 %275\n%281 = OpCompositeConstruct %63 %164 %166\n%280 = OpImageSampleDrefExplicitLod %9 %262 %281 %263 Lod %200\n%282 = OpCompositeConstruct %66 %280 %280 %280 %280\n%283 = OpCompositeExtract %9 %282 0\n%284 = OpFConvert %9 %276\n%285 = OpFConvert %9 %277\n%286 = OpFConvert %9 %278\n%287 = OpFConvert %9 %279\n%288 = OpFAdd %9 %284 %283\n%289 = OpFAdd %9 %285 %283\n%290 = OpFAdd %9 %286 %283\n%291 = OpFAdd %9 %287 %283\n%292 = OpFConvert %167 %288\n%293 = OpFConvert %167 %289\n%294 = OpFConvert %167 %290\n%295 = OpFConvert %167 %291\n%296 = OpCompositeConstruct %63 %164 %166\n%297 = OpImageDrefGather %66 %262 %296 %263\n%298 = OpFConvert %174 %297\n%299 = OpCompositeExtract %167 %298 0\n%300 = OpCompositeExtract %167 %298 1\n%301 = OpCompositeExtract %167 %298 2\n%302 = OpCompositeExtract %167 %298 3\n%304 = OpCompositeConstruct %63 %164 %166\n%303 = OpImageSampleExplicitLod %66 %199 %304 Lod %200\n%305 = OpFConvert %174 %303\n%306 = OpCompositeExtract %167 %305 0\n%307 = OpCompositeExtract %167 %305 1\n%308 = OpCompositeExtract %167 %305 2\n%309 = OpCompositeExtract %167 %305 3\n%314 = OpCompositeConstruct %63 %164 %166\n%315 = OpCompositeConstruct %63 %310 %311\n%316 = OpCompositeConstruct %63 %312 %263\n%313 = OpImageSampleExplicitLod %66 %199 %314 Grad %315 %316\n%317 = OpFConvert %174 %313\n%318 = OpCompositeExtract %167 %317 0\n%319 = OpCompositeExtract %167 %317 1\n%320 = OpCompositeExtract %167 %317 2\n%321 = OpCompositeExtract %167 %317 3\n%323 = OpCompositeConstruct %63 %164 %166\n%322 = OpImageSampleImplicitLod %66 %199 %323 Bias %263\n%324 = OpFConvert %174 %322\n%325 = OpCompositeExtract %167 %324 0\n%326 = OpCompositeExtract %167 %324 1\n%327 = OpCompositeExtract %167 %324 2\n%328 = OpCompositeExtract %167 %324 3\n%329 = OpImageFetch %66 %133 %170\n%330 = OpFConvert %174 %329\n%331 = OpCompositeExtract %167 %330 0\n%332 = OpCompositeExtract %167 %330 1\n%333 = OpCompositeExtract %167 %330 2\n%334 = OpCompositeExtract %167 %330 3\n%335 = OpFAdd %167 %306 %299\n%336 = OpFAdd %167 %335 %318\n%337 = OpFAdd %167 %336 %292\n%338 = OpFAdd %167 %337 %325\n%339 = OpFAdd %167 %338 %331\n%340 = OpFAdd %167 %307 %300\n%341 = OpFAdd %167 %340 %319\n%342 = OpFAdd %167 %341 %293\n%343 = OpFAdd %167 %342 %326\n%344 = OpFAdd %167 %343 %332\n%345 = OpFAdd %167 %308 %301\n%346 = OpFAdd %167 %345 %320\n%347 = OpFAdd %167 %346 %294\n%348 = OpFAdd %167 %347 %327\n%349 = OpFAdd %167 %348 %333\n%350 = OpFAdd %167 %309 %302\n%351 = OpFAdd %167 %350 %321\n%352 = OpFAdd %167 %351 %295\n%353 = OpFAdd %167 %352 %328\n%354 = OpFAdd %167 %353 %334\n%355 = OpImageFetch %69 %127 %170\n%356 = OpSConvert %181 %355\n%357 = OpCompositeExtract %177 %356 0\n%358 = OpCompositeExtract %177 %356 1\n%359 = OpCompositeExtract %177 %356 2\n%360 = OpCompositeExtract %177 %356 3\n%361 = OpIAdd %177 %243 %357\n%362 = OpIAdd %177 %244 %358\n%363 = OpIAdd %177 %245 %359\n%364 = OpIAdd %177 %246 %360\n%365 = OpImageFetch %72 %121 %170\n%366 = OpUConvert %181 %365\n%367 = OpCompositeExtract %177 %366 0\n%368 = OpCompositeExtract %177 %366 1\n%369 = OpCompositeExtract %177 %366 2\n%370 = OpCompositeExtract %177 %366 3\n%371 = OpIAdd %177 %256 %367\n%372 = OpIAdd %177 %257 %368\n%373 = OpIAdd %177 %258 %369\n%374 = OpIAdd %177 %259 %370\n%376 = OpAccessChain %375 %68 %137\n%377 = OpFConvert %9 %339\nOpStore %376 %377\n%378 = OpAccessChain %375 %68 %109\n%379 = OpFConvert %9 %344\nOpStore %378 %379\n%380 = OpAccessChain %375 %68 %102\n%381 = OpFConvert %9 %349\nOpStore %380 %381\n%382 = OpAccessChain %375 %68 %95\n%383 = OpFConvert %9 %354\nOpStore %382 %383\n%385 = OpAccessChain %384 %71 %137\n%386 = OpSConvert %14 %361\nOpStore %385 %386\n%387 = OpAccessChain %384 %71 %109\n%388 = OpSConvert %14 %362\nOpStore %387 %388\n%389 = OpAccessChain %384 %71 %102\n%390 = OpSConvert %14 %363\nOpStore %389 %390\n%391 = OpAccessChain %384 %71 %95\n%392 = OpSConvert %14 %364\nOpStore %391 %392\n%394 = OpAccessChain %393 %74 %137\n%395 = OpUConvert %5 %371\nOpStore %394 %395\n%396 = OpAccessChain %393 %74 %109\n%397 = OpUConvert %5 %372\nOpStore %396 %397\n%398 = OpAccessChain %393 %74 %102\n%399 = OpUConvert %5 %373\nOpStore %398 %399\n%400 = OpAccessChain %393 %74 %95\n%401 = OpUConvert %5 %374\nOpStore %400 %401\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/typed-resources-16bit.sm60.native-fp16.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform mediump texture2D _8;\nlayout(set = 0, binding = 1) uniform mediump itexture2D _12;\nlayout(set = 0, binding = 2) uniform mediump utexture2D _16;\nlayout(set = 0, binding = 3) uniform mediump samplerBuffer _19;\nlayout(set = 0, binding = 4) uniform mediump isamplerBuffer _22;\nlayout(set = 0, binding = 5) uniform mediump usamplerBuffer _25;\nlayout(set = 0, binding = 0) uniform writeonly mediump image2D _28;\nlayout(set = 0, binding = 1) uniform writeonly mediump iimage2D _31;\nlayout(set = 0, binding = 2) uniform writeonly mediump uimage2D _34;\nlayout(set = 0, binding = 3) uniform writeonly mediump imageBuffer _37;\nlayout(set = 0, binding = 4) uniform writeonly mediump iimageBuffer _40;\nlayout(set = 0, binding = 5) uniform writeonly mediump uimageBuffer _43;\nlayout(set = 0, binding = 0) uniform sampler _46;\nlayout(set = 0, binding = 1) uniform samplerShadow _47;\n\nlayout(location = 0) in vec2 UV;\nlayout(location = 0) out mediump vec4 SV_Target;\nlayout(location = 1) out mediump ivec4 SV_Target_1;\nlayout(location = 2) out mediump uvec4 SV_Target_2;\n\nvoid main()\n{\n    float16_t _82 = float16_t(UV.x);\n    float16_t _83 = float16_t(UV.y);\n    uint _84 = uint(int(UV.x));\n    uint _85 = uint(int(UV.y));\n    imageStore(_28, ivec2(uvec2(_84, _85)), vec4(f16vec4(_82, _83, _82, _83)));\n    uint16_t _92 = uint16_t(int16_t(UV.x));\n    uint16_t _93 = uint16_t(int16_t(UV.y));\n    imageStore(_31, ivec2(uvec2(_84, _85)), ivec4(i16vec4(u16vec4(_92, _93, _92, _93))));\n    uint16_t _98 = uint16_t(UV.x);\n    uint16_t _99 = uint16_t(UV.y);\n    imageStore(_34, ivec2(uvec2(_84, _85)), uvec4(u16vec4(_98, _99, _98, _99)));\n    imageStore(_37, int(_84), vec4(f16vec4(float16_t(8.0))));\n    imageStore(_40, int(_84), ivec4(i16vec4(u16vec4(65516us))));\n    imageStore(_43, int(_84), uvec4(u16vec4(80us)));\n    f16vec4 _117 = f16vec4(texture(sampler2D(_8, _46), vec2(UV.x, UV.y)));\n    u16vec4 _126 = u16vec4(texelFetch(_12, ivec2(uvec2(1u, 2u)), int(3u)));\n    u16vec4 _136 = u16vec4(texelFetch(_16, ivec2(uvec2(4u, 5u)), int(6u)));\n    f16vec4 _143 = f16vec4(textureGather(sampler2D(_8, _46), vec2(UV.x, UV.y)));\n    u16vec4 _156 = u16vec4(textureGather(isampler2D(_12, _46), vec2(UV.x, UV.y), int(1u)));\n    u16vec4 _169 = u16vec4(textureGather(usampler2D(_16, _46), vec2(UV.x, UV.y), int(2u)));\n    mediump vec4 _184 = vec4(texture(sampler2DShadow(_8, _47), vec3(vec2(UV.x, UV.y), 0.5)));\n    mediump float _185 = _184.x;\n    mediump vec4 _200 = vec4(textureLod(sampler2DShadow(_8, _47), vec3(vec2(UV.x, UV.y), 0.5), 0.0));\n    mediump float _201 = _200.x;\n    vec2 _214 = vec2(UV.x, UV.y);\n    f16vec4 _216 = f16vec4(textureGather(sampler2DShadow(_8, _47), _214, 0.5));\n    f16vec4 _223 = f16vec4(textureLod(sampler2D(_8, _46), vec2(UV.x, UV.y), 0.0));\n    f16vec4 _235 = f16vec4(textureGrad(sampler2D(_8, _46), vec2(UV.x, UV.y), vec2(0.20000000298023223876953125, 0.300000011920928955078125), vec2(0.4000000059604644775390625, 0.5)));\n    f16vec4 _242 = f16vec4(texture(sampler2D(_8, _46), vec2(UV.x, UV.y), 0.5));\n    f16vec4 _248 = f16vec4(texelFetch(_19, int(_84)));\n    u16vec4 _274 = u16vec4(texelFetch(_22, int(_84)));\n    u16vec4 _284 = u16vec4(texelFetch(_25, int(_84)));\n    SV_Target.x = float(((((_223.x + _216.x) + _235.x) + float16_t(float(float16_t(_185 + float(_143.x + _117.x))) + _201)) + _242.x) + _248.x);\n    SV_Target.y = float(((((_223.y + _216.y) + _235.y) + float16_t(float(float16_t(_185 + float(_143.y + _117.y))) + _201)) + _242.y) + _248.y);\n    SV_Target.z = float(((((_223.z + _216.z) + _235.z) + float16_t(float(float16_t(_185 + float(_143.z + _117.z))) + _201)) + _242.z) + _248.z);\n    SV_Target.w = float(((((_223.w + _216.w) + _235.w) + float16_t(float(float16_t(_185 + float(_143.w + _117.w))) + _201)) + _242.w) + _248.w);\n    SV_Target_1.x = int(int16_t((_156.x + _126.x) + _274.x));\n    SV_Target_1.y = int(int16_t((_156.y + _126.y) + _274.y));\n    SV_Target_1.z = int(int16_t((_156.z + _126.z) + _274.z));\n    SV_Target_1.w = int(int16_t((_156.w + _126.w) + _274.w));\n    SV_Target_2.x = uint((_169.x + _136.x) + _284.x);\n    SV_Target_2.y = uint((_169.y + _136.y) + _284.y);\n    SV_Target_2.z = uint((_169.z + _136.z) + _284.z);\n    SV_Target_2.w = uint((_169.w + _136.w) + _284.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 322\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %50 %53 %56 %59\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %50 \"UV\"\nOpName %53 \"SV_Target\"\nOpName %56 \"SV_Target_1\"\nOpName %59 \"SV_Target_2\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %16 RelaxedPrecision\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 2\nOpDecorate %19 RelaxedPrecision\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 3\nOpDecorate %22 RelaxedPrecision\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 4\nOpDecorate %25 RelaxedPrecision\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 5\nOpDecorate %28 RelaxedPrecision\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %31 RelaxedPrecision\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 1\nOpDecorate %31 NonReadable\nOpDecorate %34 RelaxedPrecision\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 2\nOpDecorate %34 NonReadable\nOpDecorate %37 RelaxedPrecision\nOpDecorate %37 DescriptorSet 0\nOpDecorate %37 Binding 3\nOpDecorate %37 NonReadable\nOpDecorate %40 RelaxedPrecision\nOpDecorate %40 DescriptorSet 0\nOpDecorate %40 Binding 4\nOpDecorate %40 NonReadable\nOpDecorate %43 RelaxedPrecision\nOpDecorate %43 DescriptorSet 0\nOpDecorate %43 Binding 5\nOpDecorate %43 NonReadable\nOpDecorate %46 DescriptorSet 0\nOpDecorate %46 Binding 0\nOpDecorate %47 DescriptorSet 0\nOpDecorate %47 Binding 1\nOpDecorate %50 Location 0\nOpDecorate %53 RelaxedPrecision\nOpDecorate %53 Location 0\nOpDecorate %56 RelaxedPrecision\nOpDecorate %56 Location 1\nOpDecorate %59 RelaxedPrecision\nOpDecorate %59 Location 2\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeInt 32 1\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeInt 32 0\n%14 = OpTypeImage %13 2D 0 0 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeImage %13 Buffer 0 0 0 1 Unknown\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%30 = OpTypePointer UniformConstant %29\n%31 = OpVariable %30 UniformConstant\n%32 = OpTypeImage %13 2D 0 0 0 2 Unknown\n%33 = OpTypePointer UniformConstant %32\n%34 = OpVariable %33 UniformConstant\n%35 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%36 = OpTypePointer UniformConstant %35\n%37 = OpVariable %36 UniformConstant\n%38 = OpTypeImage %9 Buffer 0 0 0 2 Unknown\n%39 = OpTypePointer UniformConstant %38\n%40 = OpVariable %39 UniformConstant\n%41 = OpTypeImage %13 Buffer 0 0 0 2 Unknown\n%42 = OpTypePointer UniformConstant %41\n%43 = OpVariable %42 UniformConstant\n%44 = OpTypeSampler\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%47 = OpVariable %45 UniformConstant\n%48 = OpTypeVector %5 2\n%49 = OpTypePointer Input %48\n%50 = OpVariable %49 Input\n%51 = OpTypeVector %5 4\n%52 = OpTypePointer Output %51\n%53 = OpVariable %52 Output\n%54 = OpTypeVector %9 4\n%55 = OpTypePointer Output %54\n%56 = OpVariable %55 Output\n%57 = OpTypeVector %13 4\n%58 = OpTypePointer Output %57\n%59 = OpVariable %58 Output\n%74 = OpTypePointer Input %5\n%76 = OpConstant %13 0\n%79 = OpConstant %13 1\n%81 = OpTypeFloat 16\n%86 = OpTypeVector %13 2\n%88 = OpTypeVector %81 4\n%91 = OpTypeInt 16 0\n%95 = OpTypeVector %91 4\n%103 = OpConstant %81 0x1p+3\n%106 = OpConstant %91 65516\n%109 = OpConstant %91 80\n%112 = OpTypeSampledImage %6\n%114 = OpConstant %5 0\n%122 = OpConstant %13 3\n%123 = OpConstant %13 2\n%131 = OpConstant %13 6\n%132 = OpConstant %13 4\n%133 = OpConstant %13 5\n%152 = OpTypeSampledImage %10\n%165 = OpTypeSampledImage %14\n%178 = OpTypeImage %5 2D 1 0 0 1 Unknown\n%179 = OpTypeSampledImage %178\n%181 = OpConstant %5 0.5\n%228 = OpConstant %5 0.200000003\n%229 = OpConstant %5 0.300000012\n%230 = OpConstant %5 0.400000006\n%293 = OpTypePointer Output %5\n%302 = OpTypePointer Output %9\n%311 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %320\n%320 = OpLabel\n%60 = OpLoad %41 %43\n%61 = OpLoad %38 %40\n%62 = OpLoad %35 %37\n%63 = OpLoad %32 %34\n%64 = OpLoad %29 %31\n%65 = OpLoad %26 %28\n%66 = OpLoad %23 %25\n%67 = OpLoad %20 %22\n%68 = OpLoad %17 %19\n%69 = OpLoad %14 %16\n%70 = OpLoad %10 %12\n%71 = OpLoad %6 %8\n%72 = OpLoad %44 %47\n%73 = OpLoad %44 %46\n%75 = OpAccessChain %74 %50 %76\n%77 = OpLoad %5 %75\n%78 = OpAccessChain %74 %50 %79\n%80 = OpLoad %5 %78\n%82 = OpFConvert %81 %77\n%83 = OpFConvert %81 %80\n%84 = OpConvertFToS %13 %77\n%85 = OpConvertFToS %13 %80\n%87 = OpCompositeConstruct %86 %84 %85\n%89 = OpCompositeConstruct %88 %82 %83 %82 %83\n%90 = OpFConvert %51 %89\nOpImageWrite %65 %87 %90\n%92 = OpConvertFToS %91 %77\n%93 = OpConvertFToS %91 %80\n%94 = OpCompositeConstruct %86 %84 %85\n%96 = OpCompositeConstruct %95 %92 %93 %92 %93\n%97 = OpSConvert %54 %96\nOpImageWrite %64 %94 %97\n%98 = OpConvertFToU %91 %77\n%99 = OpConvertFToU %91 %80\n%100 = OpCompositeConstruct %86 %84 %85\n%101 = OpCompositeConstruct %95 %98 %99 %98 %99\n%102 = OpUConvert %57 %101\nOpImageWrite %63 %100 %102\n%104 = OpCompositeConstruct %88 %103 %103 %103 %103\n%105 = OpFConvert %51 %104\nOpImageWrite %62 %84 %105\n%107 = OpCompositeConstruct %95 %106 %106 %106 %106\n%108 = OpSConvert %54 %107\nOpImageWrite %61 %84 %108\n%110 = OpCompositeConstruct %95 %109 %109 %109 %109\n%111 = OpUConvert %57 %110\nOpImageWrite %60 %84 %111\n%113 = OpSampledImage %112 %71 %73\n%116 = OpCompositeConstruct %48 %77 %80\n%115 = OpImageSampleImplicitLod %51 %113 %116 None\n%117 = OpFConvert %88 %115\n%118 = OpCompositeExtract %81 %117 0\n%119 = OpCompositeExtract %81 %117 1\n%120 = OpCompositeExtract %81 %117 2\n%121 = OpCompositeExtract %81 %117 3\n%125 = OpCompositeConstruct %86 %79 %123\n%124 = OpImageFetch %54 %70 %125 Lod %122\n%126 = OpSConvert %95 %124\n%127 = OpCompositeExtract %91 %126 0\n%128 = OpCompositeExtract %91 %126 1\n%129 = OpCompositeExtract %91 %126 2\n%130 = OpCompositeExtract %91 %126 3\n%135 = OpCompositeConstruct %86 %132 %133\n%134 = OpImageFetch %57 %69 %135 Lod %131\n%136 = OpUConvert %95 %134\n%137 = OpCompositeExtract %91 %136 0\n%138 = OpCompositeExtract %91 %136 1\n%139 = OpCompositeExtract %91 %136 2\n%140 = OpCompositeExtract %91 %136 3\n%141 = OpCompositeConstruct %48 %77 %80\n%142 = OpImageGather %51 %113 %141 %76\n%143 = OpFConvert %88 %142\n%144 = OpCompositeExtract %81 %143 0\n%145 = OpCompositeExtract %81 %143 1\n%146 = OpCompositeExtract %81 %143 2\n%147 = OpCompositeExtract %81 %143 3\n%148 = OpFAdd %81 %144 %118\n%149 = OpFAdd %81 %145 %119\n%150 = OpFAdd %81 %146 %120\n%151 = OpFAdd %81 %147 %121\n%153 = OpSampledImage %152 %70 %73\n%154 = OpCompositeConstruct %48 %77 %80\n%155 = OpImageGather %54 %153 %154 %79\n%156 = OpSConvert %95 %155\n%157 = OpCompositeExtract %91 %156 0\n%158 = OpCompositeExtract %91 %156 1\n%159 = OpCompositeExtract %91 %156 2\n%160 = OpCompositeExtract %91 %156 3\n%161 = OpIAdd %91 %157 %127\n%162 = OpIAdd %91 %158 %128\n%163 = OpIAdd %91 %159 %129\n%164 = OpIAdd %91 %160 %130\n%166 = OpSampledImage %165 %69 %73\n%167 = OpCompositeConstruct %48 %77 %80\n%168 = OpImageGather %57 %166 %167 %123\n%169 = OpUConvert %95 %168\n%170 = OpCompositeExtract %91 %169 0\n%171 = OpCompositeExtract %91 %169 1\n%172 = OpCompositeExtract %91 %169 2\n%173 = OpCompositeExtract %91 %169 3\n%174 = OpIAdd %91 %170 %137\n%175 = OpIAdd %91 %171 %138\n%176 = OpIAdd %91 %172 %139\n%177 = OpIAdd %91 %173 %140\n%180 = OpSampledImage %179 %71 %72\n%183 = OpCompositeConstruct %48 %77 %80\n%182 = OpImageSampleDrefImplicitLod %5 %180 %183 %181 None\n%184 = OpCompositeConstruct %51 %182 %182 %182 %182\n%185 = OpCompositeExtract %5 %184 0\n%186 = OpFConvert %5 %148\n%187 = OpFConvert %5 %149\n%188 = OpFConvert %5 %150\n%189 = OpFConvert %5 %151\n%190 = OpFAdd %5 %185 %186\n%191 = OpFAdd %5 %185 %187\n%192 = OpFAdd %5 %185 %188\n%193 = OpFAdd %5 %185 %189\n%194 = OpFConvert %81 %190\n%195 = OpFConvert %81 %191\n%196 = OpFConvert %81 %192\n%197 = OpFConvert %81 %193\n%199 = OpCompositeConstruct %48 %77 %80\n%198 = OpImageSampleDrefExplicitLod %5 %180 %199 %181 Lod %114\n%200 = OpCompositeConstruct %51 %198 %198 %198 %198\n%201 = OpCompositeExtract %5 %200 0\n%202 = OpFConvert %5 %194\n%203 = OpFConvert %5 %195\n%204 = OpFConvert %5 %196\n%205 = OpFConvert %5 %197\n%206 = OpFAdd %5 %202 %201\n%207 = OpFAdd %5 %203 %201\n%208 = OpFAdd %5 %204 %201\n%209 = OpFAdd %5 %205 %201\n%210 = OpFConvert %81 %206\n%211 = OpFConvert %81 %207\n%212 = OpFConvert %81 %208\n%213 = OpFConvert %81 %209\n%214 = OpCompositeConstruct %48 %77 %80\n%215 = OpImageDrefGather %51 %180 %214 %181\n%216 = OpFConvert %88 %215\n%217 = OpCompositeExtract %81 %216 0\n%218 = OpCompositeExtract %81 %216 1\n%219 = OpCompositeExtract %81 %216 2\n%220 = OpCompositeExtract %81 %216 3\n%222 = OpCompositeConstruct %48 %77 %80\n%221 = OpImageSampleExplicitLod %51 %113 %222 Lod %114\n%223 = OpFConvert %88 %221\n%224 = OpCompositeExtract %81 %223 0\n%225 = OpCompositeExtract %81 %223 1\n%226 = OpCompositeExtract %81 %223 2\n%227 = OpCompositeExtract %81 %223 3\n%232 = OpCompositeConstruct %48 %77 %80\n%233 = OpCompositeConstruct %48 %228 %229\n%234 = OpCompositeConstruct %48 %230 %181\n%231 = OpImageSampleExplicitLod %51 %113 %232 Grad %233 %234\n%235 = OpFConvert %88 %231\n%236 = OpCompositeExtract %81 %235 0\n%237 = OpCompositeExtract %81 %235 1\n%238 = OpCompositeExtract %81 %235 2\n%239 = OpCompositeExtract %81 %235 3\n%241 = OpCompositeConstruct %48 %77 %80\n%240 = OpImageSampleImplicitLod %51 %113 %241 Bias %181\n%242 = OpFConvert %88 %240\n%243 = OpCompositeExtract %81 %242 0\n%244 = OpCompositeExtract %81 %242 1\n%245 = OpCompositeExtract %81 %242 2\n%246 = OpCompositeExtract %81 %242 3\n%247 = OpImageFetch %51 %68 %84\n%248 = OpFConvert %88 %247\n%249 = OpCompositeExtract %81 %248 0\n%250 = OpCompositeExtract %81 %248 1\n%251 = OpCompositeExtract %81 %248 2\n%252 = OpCompositeExtract %81 %248 3\n%253 = OpFAdd %81 %224 %217\n%254 = OpFAdd %81 %253 %236\n%255 = OpFAdd %81 %254 %210\n%256 = OpFAdd %81 %255 %243\n%257 = OpFAdd %81 %256 %249\n%258 = OpFAdd %81 %225 %218\n%259 = OpFAdd %81 %258 %237\n%260 = OpFAdd %81 %259 %211\n%261 = OpFAdd %81 %260 %244\n%262 = OpFAdd %81 %261 %250\n%263 = OpFAdd %81 %226 %219\n%264 = OpFAdd %81 %263 %238\n%265 = OpFAdd %81 %264 %212\n%266 = OpFAdd %81 %265 %245\n%267 = OpFAdd %81 %266 %251\n%268 = OpFAdd %81 %227 %220\n%269 = OpFAdd %81 %268 %239\n%270 = OpFAdd %81 %269 %213\n%271 = OpFAdd %81 %270 %246\n%272 = OpFAdd %81 %271 %252\n%273 = OpImageFetch %54 %67 %84\n%274 = OpSConvert %95 %273\n%275 = OpCompositeExtract %91 %274 0\n%276 = OpCompositeExtract %91 %274 1\n%277 = OpCompositeExtract %91 %274 2\n%278 = OpCompositeExtract %91 %274 3\n%279 = OpIAdd %91 %161 %275\n%280 = OpIAdd %91 %162 %276\n%281 = OpIAdd %91 %163 %277\n%282 = OpIAdd %91 %164 %278\n%283 = OpImageFetch %57 %66 %84\n%284 = OpUConvert %95 %283\n%285 = OpCompositeExtract %91 %284 0\n%286 = OpCompositeExtract %91 %284 1\n%287 = OpCompositeExtract %91 %284 2\n%288 = OpCompositeExtract %91 %284 3\n%289 = OpIAdd %91 %174 %285\n%290 = OpIAdd %91 %175 %286\n%291 = OpIAdd %91 %176 %287\n%292 = OpIAdd %91 %177 %288\n%294 = OpAccessChain %293 %53 %76\n%295 = OpFConvert %5 %257\nOpStore %294 %295\n%296 = OpAccessChain %293 %53 %79\n%297 = OpFConvert %5 %262\nOpStore %296 %297\n%298 = OpAccessChain %293 %53 %123\n%299 = OpFConvert %5 %267\nOpStore %298 %299\n%300 = OpAccessChain %293 %53 %122\n%301 = OpFConvert %5 %272\nOpStore %300 %301\n%303 = OpAccessChain %302 %56 %76\n%304 = OpSConvert %9 %279\nOpStore %303 %304\n%305 = OpAccessChain %302 %56 %79\n%306 = OpSConvert %9 %280\nOpStore %305 %306\n%307 = OpAccessChain %302 %56 %123\n%308 = OpSConvert %9 %281\nOpStore %307 %308\n%309 = OpAccessChain %302 %56 %122\n%310 = OpSConvert %9 %282\nOpStore %309 %310\n%312 = OpAccessChain %311 %59 %76\n%313 = OpUConvert %13 %289\nOpStore %312 %313\n%314 = OpAccessChain %311 %59 %79\n%315 = OpUConvert %13 %290\nOpStore %314 %315\n%316 = OpAccessChain %311 %59 %123\n%317 = OpUConvert %13 %291\nOpStore %316 %317\n%318 = OpAccessChain %311 %59 %122\n%319 = OpUConvert %13 %292\nOpStore %318 %319\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-raw-buffer-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _19 = INDEX + 0u;\n    uint _24 = INDEX * 4u;\n    uvec4 _40 = uvec4(imageLoad(_9[nonuniformEXT(_19)], int(_24)).x, imageLoad(_9[nonuniformEXT(_19)], int(_24 + 1u)).x, imageLoad(_9[nonuniformEXT(_19)], int(_24 + 2u)).x, imageLoad(_9[nonuniformEXT(_19)], int(_24 + 3u)).x);\n    SV_Target.x = uintBitsToFloat(_40.x);\n    SV_Target.y = uintBitsToFloat(_40.y);\n    SV_Target.z = uintBitsToFloat(_40.z);\n    SV_Target.w = uintBitsToFloat(_40.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\nOpDecorate %19 NonUniform\nOpDecorate %23 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 4\n%20 = OpConstant %5 0\n%21 = OpTypePointer UniformConstant %6\n%25 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%34 = OpConstant %5 2\n%38 = OpConstant %5 3\n%49 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpShiftLeftLogical %5 %16 %18\n%19 = OpIAdd %5 %16 %20\n%22 = OpAccessChain %21 %9 %19\n%23 = OpLoad %6 %22\n%24 = OpIMul %5 %16 %18\n%26 = OpImageRead %25 %23 %24\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpIAdd %5 %24 %30\n%28 = OpImageRead %25 %23 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %24 %34\n%32 = OpImageRead %25 %23 %33\n%35 = OpCompositeExtract %5 %32 0\n%37 = OpIAdd %5 %24 %38\n%36 = OpImageRead %25 %23 %37\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeConstruct %25 %27 %31 %35 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpBitcast %12 %41\n%46 = OpBitcast %12 %42\n%47 = OpBitcast %12 %43\n%48 = OpBitcast %12 %44\n%50 = OpAccessChain %49 %15 %20\nOpStore %50 %45\n%51 = OpAccessChain %49 %15 %30\nOpStore %51 %46\n%52 = OpAccessChain %49 %15 %34\nOpStore %52 %47\n%53 = OpAccessChain %49 %15 %38\nOpStore %53 %48\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-raw-buffer.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _19 = INDEX + 0u;\n    uint _24 = INDEX * 4u;\n    uvec4 _40 = uvec4(imageLoad(_9[_19], int(_24)).x, imageLoad(_9[_19], int(_24 + 1u)).x, imageLoad(_9[_19], int(_24 + 2u)).x, imageLoad(_9[_19], int(_24 + 3u)).x);\n    SV_Target.x = uintBitsToFloat(_40.x);\n    SV_Target.y = uintBitsToFloat(_40.y);\n    SV_Target.z = uintBitsToFloat(_40.z);\n    SV_Target.w = uintBitsToFloat(_40.w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 4\n%20 = OpConstant %5 0\n%21 = OpTypePointer UniformConstant %6\n%25 = OpTypeVector %5 4\n%30 = OpConstant %5 1\n%34 = OpConstant %5 2\n%38 = OpConstant %5 3\n%49 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpShiftLeftLogical %5 %16 %18\n%19 = OpIAdd %5 %16 %20\n%22 = OpAccessChain %21 %9 %19\n%23 = OpLoad %6 %22\n%24 = OpIMul %5 %16 %18\n%26 = OpImageRead %25 %23 %24\n%27 = OpCompositeExtract %5 %26 0\n%29 = OpIAdd %5 %24 %30\n%28 = OpImageRead %25 %23 %29\n%31 = OpCompositeExtract %5 %28 0\n%33 = OpIAdd %5 %24 %34\n%32 = OpImageRead %25 %23 %33\n%35 = OpCompositeExtract %5 %32 0\n%37 = OpIAdd %5 %24 %38\n%36 = OpImageRead %25 %23 %37\n%39 = OpCompositeExtract %5 %36 0\n%40 = OpCompositeConstruct %25 %27 %31 %35 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpBitcast %12 %41\n%46 = OpBitcast %12 %42\n%47 = OpBitcast %12 %43\n%48 = OpBitcast %12 %44\n%50 = OpAccessChain %49 %15 %20\nOpStore %50 %45\n%51 = OpAccessChain %49 %15 %30\nOpStore %51 %46\n%52 = OpAccessChain %49 %15 %34\nOpStore %52 %47\n%53 = OpAccessChain %49 %15 %38\nOpStore %53 %48\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-structured-buffer-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _17 = INDEX + 0u;\n    uint _22 = INDEX * 4u;\n    vec4 _40 = uintBitsToFloat(uvec4(imageLoad(_9[nonuniformEXT(_17)], int(_22)).x, imageLoad(_9[nonuniformEXT(_17)], int(_22 + 1u)).x, imageLoad(_9[nonuniformEXT(_17)], int(_22 + 2u)).x, imageLoad(_9[nonuniformEXT(_17)], int(_22 + 3u)).x));\n    SV_Target.x = _40.x;\n    SV_Target.y = _40.y;\n    SV_Target.z = _40.z;\n    SV_Target.w = _40.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\nOpDecorate %17 NonUniform\nOpDecorate %21 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 0\n%19 = OpTypePointer UniformConstant %6\n%23 = OpConstant %5 4\n%24 = OpTypeVector %5 4\n%29 = OpConstant %5 1\n%33 = OpConstant %5 2\n%37 = OpConstant %5 3\n%45 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpIAdd %5 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpIMul %5 %16 %23\n%25 = OpImageRead %24 %21 %22\n%26 = OpCompositeExtract %5 %25 0\n%28 = OpIAdd %5 %22 %29\n%27 = OpImageRead %24 %21 %28\n%30 = OpCompositeExtract %5 %27 0\n%32 = OpIAdd %5 %22 %33\n%31 = OpImageRead %24 %21 %32\n%34 = OpCompositeExtract %5 %31 0\n%36 = OpIAdd %5 %22 %37\n%35 = OpImageRead %24 %21 %36\n%38 = OpCompositeExtract %5 %35 0\n%39 = OpCompositeConstruct %24 %26 %30 %34 %38\n%40 = OpBitcast %13 %39\n%41 = OpCompositeExtract %12 %40 0\n%42 = OpCompositeExtract %12 %40 1\n%43 = OpCompositeExtract %12 %40 2\n%44 = OpCompositeExtract %12 %40 3\n%46 = OpAccessChain %45 %15 %18\nOpStore %46 %41\n%47 = OpAccessChain %45 %15 %29\nOpStore %47 %42\n%48 = OpAccessChain %45 %15 %33\nOpStore %48 %43\n%49 = OpAccessChain %45 %15 %37\nOpStore %49 %44\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-structured-buffer-nonuniform.ssbo.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _14[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _34 = uintBitsToFloat(_14[nonuniformEXT(registers._m4 + (INDEX + 0u))]._m0[INDEX]);\n    SV_Target.x = _34.x;\n    SV_Target.y = _34.y;\n    SV_Target.z = _34.z;\n    SV_Target.w = _34.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %20\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO\"\nOpName %16 \"INDEX\"\nOpName %20 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %10 ArrayStride 16\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %14 DescriptorSet 4\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %20 Location 0\nOpDecorate %30 NonUniform\nOpDecorate %25 NonUniform\nOpDecorate %32 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypePointer Input %5\n%16 = OpVariable %15 Input\n%17 = OpTypeFloat 32\n%18 = OpTypeVector %17 4\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%23 = OpConstant %5 0\n%24 = OpTypePointer StorageBuffer %11\n%26 = OpTypePointer PushConstant %5\n%28 = OpConstant %5 4\n%31 = OpTypePointer StorageBuffer %9\n%39 = OpTypePointer Output %17\n%42 = OpConstant %5 1\n%44 = OpConstant %5 2\n%46 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %47\n%47 = OpLabel\n%21 = OpLoad %5 %16\n%22 = OpIAdd %5 %21 %23\n%27 = OpAccessChain %26 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpIAdd %5 %29 %22\n%25 = OpAccessChain %24 %14 %30\n%32 = OpAccessChain %31 %25 %23 %21\n%33 = OpLoad %9 %32\n%34 = OpBitcast %18 %33\n%35 = OpCompositeExtract %17 %34 0\n%36 = OpCompositeExtract %17 %34 1\n%37 = OpCompositeExtract %17 %34 2\n%38 = OpCompositeExtract %17 %34 3\n%40 = OpAccessChain %39 %20 %23\nOpStore %40 %35\n%41 = OpAccessChain %39 %20 %42\nOpStore %41 %36\n%43 = OpAccessChain %39 %20 %44\nOpStore %43 %37\n%45 = OpAccessChain %39 %20 %46\nOpStore %45 %38\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-structured-buffer-nonuniform.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _11[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _26 = uintBitsToFloat(_11[nonuniformEXT(INDEX + 0u)]._m0[INDEX]);\n    SV_Target.x = _26.x;\n    SV_Target.y = _26.y;\n    SV_Target.z = _26.z;\n    SV_Target.w = _26.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %17\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %13 \"INDEX\"\nOpName %17 \"SV_Target\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %11 NonWritable\nOpDecorate %13 Flat\nOpDecorate %13 Location 0\nOpDecorate %17 Location 0\nOpDecorate %19 NonUniform\nOpDecorate %22 NonUniform\nOpDecorate %24 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypePointer Input %5\n%13 = OpVariable %12 Input\n%14 = OpTypeFloat 32\n%15 = OpTypeVector %14 4\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%20 = OpConstant %5 0\n%21 = OpTypePointer StorageBuffer %8\n%23 = OpTypePointer StorageBuffer %6\n%31 = OpTypePointer Output %14\n%34 = OpConstant %5 1\n%36 = OpConstant %5 2\n%38 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%18 = OpLoad %5 %13\n%19 = OpIAdd %5 %18 %20\n%22 = OpAccessChain %21 %11 %19\n%24 = OpAccessChain %23 %22 %20 %18\n%25 = OpLoad %6 %24\n%26 = OpBitcast %15 %25\n%27 = OpCompositeExtract %14 %26 0\n%28 = OpCompositeExtract %14 %26 1\n%29 = OpCompositeExtract %14 %26 2\n%30 = OpCompositeExtract %14 %26 3\n%32 = OpAccessChain %31 %17 %20\nOpStore %32 %27\n%33 = OpAccessChain %31 %17 %34\nOpStore %33 %28\n%35 = OpAccessChain %31 %17 %36\nOpStore %35 %29\n%37 = OpAccessChain %31 %17 %38\nOpStore %37 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-structured-buffer.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32ui) uniform readonly uimageBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _17 = INDEX + 0u;\n    uint _22 = INDEX * 4u;\n    vec4 _40 = uintBitsToFloat(uvec4(imageLoad(_9[_17], int(_22)).x, imageLoad(_9[_17], int(_22 + 1u)).x, imageLoad(_9[_17], int(_22 + 2u)).x, imageLoad(_9[_17], int(_22 + 3u)).x));\n    SV_Target.x = _40.x;\n    SV_Target.y = _40.y;\n    SV_Target.z = _40.z;\n    SV_Target.w = _40.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %11 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %11 Flat\nOpDecorate %11 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypePointer Input %5\n%11 = OpVariable %10 Input\n%12 = OpTypeFloat 32\n%13 = OpTypeVector %12 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %5 0\n%19 = OpTypePointer UniformConstant %6\n%23 = OpConstant %5 4\n%24 = OpTypeVector %5 4\n%29 = OpConstant %5 1\n%33 = OpConstant %5 2\n%37 = OpConstant %5 3\n%45 = OpTypePointer Output %12\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%16 = OpLoad %5 %11\n%17 = OpIAdd %5 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpIMul %5 %16 %23\n%25 = OpImageRead %24 %21 %22\n%26 = OpCompositeExtract %5 %25 0\n%28 = OpIAdd %5 %22 %29\n%27 = OpImageRead %24 %21 %28\n%30 = OpCompositeExtract %5 %27 0\n%32 = OpIAdd %5 %22 %33\n%31 = OpImageRead %24 %21 %32\n%34 = OpCompositeExtract %5 %31 0\n%36 = OpIAdd %5 %22 %37\n%35 = OpImageRead %24 %21 %36\n%38 = OpCompositeExtract %5 %35 0\n%39 = OpCompositeConstruct %24 %26 %30 %34 %38\n%40 = OpBitcast %13 %39\n%41 = OpCompositeExtract %12 %40 0\n%42 = OpCompositeExtract %12 %40 1\n%43 = OpCompositeExtract %12 %40 2\n%44 = OpCompositeExtract %12 %40 3\n%46 = OpAccessChain %45 %15 %18\nOpStore %46 %41\n%47 = OpAccessChain %45 %15 %29\nOpStore %47 %42\n%48 = OpAccessChain %45 %15 %33\nOpStore %48 %43\n%49 = OpAccessChain %45 %15 %37\nOpStore %49 %44\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-texture-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _9[];\nlayout(set = 1, binding = 0, r32f) uniform readonly image2D _14[100];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _26 = imageLoad(_9[nonuniformEXT(INDEX + 0u)], ivec2(uvec2(0u)));\n    vec4 _38 = imageLoad(_14[nonuniformEXT((INDEX ^ 1u) + 0u)], ivec2(uvec2(0u)));\n    SV_Target.x = _38.x + _26.x;\n    SV_Target.y = _38.y + _26.y;\n    SV_Target.z = _38.z + _26.z;\n    SV_Target.w = _38.w + _26.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 57\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"INDEX\"\nOpName %19 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %19 Location 0\nOpDecorate %21 NonUniform\nOpDecorate %25 NonUniform\nOpDecorate %35 NonUniform\nOpDecorate %37 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpConstant %10 100\n%12 = OpTypeArray %6 %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypePointer Input %10\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 4\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%22 = OpConstant %10 0\n%23 = OpTypePointer UniformConstant %6\n%27 = OpTypeVector %10 2\n%34 = OpConstant %10 1\n%48 = OpTypePointer Output %5\n%52 = OpConstant %10 2\n%54 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %55\n%55 = OpLabel\n%20 = OpLoad %10 %16\n%21 = OpIAdd %10 %20 %22\n%24 = OpAccessChain %23 %9 %21\n%25 = OpLoad %6 %24\n%28 = OpCompositeConstruct %27 %22 %22\n%26 = OpImageRead %17 %25 %28 None\n%29 = OpCompositeExtract %5 %26 0\n%30 = OpCompositeExtract %5 %26 1\n%31 = OpCompositeExtract %5 %26 2\n%32 = OpCompositeExtract %5 %26 3\n%33 = OpBitwiseXor %10 %20 %34\n%35 = OpIAdd %10 %33 %22\n%36 = OpAccessChain %23 %14 %35\n%37 = OpLoad %6 %36\n%39 = OpCompositeConstruct %27 %22 %22\n%38 = OpImageRead %17 %37 %39 None\n%40 = OpCompositeExtract %5 %38 0\n%41 = OpCompositeExtract %5 %38 1\n%42 = OpCompositeExtract %5 %38 2\n%43 = OpCompositeExtract %5 %38 3\n%44 = OpFAdd %5 %40 %29\n%45 = OpFAdd %5 %41 %30\n%46 = OpFAdd %5 %42 %31\n%47 = OpFAdd %5 %43 %32\n%49 = OpAccessChain %48 %19 %22\nOpStore %49 %44\n%50 = OpAccessChain %48 %19 %34\nOpStore %50 %45\n%51 = OpAccessChain %48 %19 %52\nOpStore %51 %46\n%53 = OpAccessChain %48 %19 %54\nOpStore %53 %47\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-texture.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _9[];\nlayout(set = 1, binding = 0, r32f) uniform readonly image2D _14[100];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _26 = imageLoad(_9[INDEX + 0u], ivec2(uvec2(0u)));\n    vec4 _38 = imageLoad(_14[(INDEX ^ 1u) + 0u], ivec2(uvec2(0u)));\n    SV_Target.x = _38.x + _26.x;\n    SV_Target.y = _38.y + _26.y;\n    SV_Target.z = _38.z + _26.z;\n    SV_Target.w = _38.w + _26.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 57\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"INDEX\"\nOpName %19 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %16 Flat\nOpDecorate %16 Location 0\nOpDecorate %19 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpConstant %10 100\n%12 = OpTypeArray %6 %11\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypePointer Input %10\n%16 = OpVariable %15 Input\n%17 = OpTypeVector %5 4\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%22 = OpConstant %10 0\n%23 = OpTypePointer UniformConstant %6\n%27 = OpTypeVector %10 2\n%34 = OpConstant %10 1\n%48 = OpTypePointer Output %5\n%52 = OpConstant %10 2\n%54 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %55\n%55 = OpLabel\n%20 = OpLoad %10 %16\n%21 = OpIAdd %10 %20 %22\n%24 = OpAccessChain %23 %9 %21\n%25 = OpLoad %6 %24\n%28 = OpCompositeConstruct %27 %22 %22\n%26 = OpImageRead %17 %25 %28 None\n%29 = OpCompositeExtract %5 %26 0\n%30 = OpCompositeExtract %5 %26 1\n%31 = OpCompositeExtract %5 %26 2\n%32 = OpCompositeExtract %5 %26 3\n%33 = OpBitwiseXor %10 %20 %34\n%35 = OpIAdd %10 %33 %22\n%36 = OpAccessChain %23 %14 %35\n%37 = OpLoad %6 %36\n%39 = OpCompositeConstruct %27 %22 %22\n%38 = OpImageRead %17 %37 %39 None\n%40 = OpCompositeExtract %5 %38 0\n%41 = OpCompositeExtract %5 %38 1\n%42 = OpCompositeExtract %5 %38 2\n%43 = OpCompositeExtract %5 %38 3\n%44 = OpFAdd %5 %40 %29\n%45 = OpFAdd %5 %41 %30\n%46 = OpFAdd %5 %42 %31\n%47 = OpFAdd %5 %43 %32\n%49 = OpAccessChain %48 %19 %22\nOpStore %49 %44\n%50 = OpAccessChain %48 %19 %34\nOpStore %50 %45\n%51 = OpAccessChain %48 %19 %52\nOpStore %51 %46\n%53 = OpAccessChain %48 %19 %54\nOpStore %53 %47\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-typed-buffer-nonuniform.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = imageLoad(_9[nonuniformEXT(INDEX + 0u)], int(INDEX));\n    SV_Target.x = _22.x;\n    SV_Target.y = _22.y;\n    SV_Target.z = _22.z;\n    SV_Target.w = _22.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %15 Location 0\nOpDecorate %17 NonUniform\nOpDecorate %21 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32f\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeVector %5 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %10 0\n%19 = OpTypePointer UniformConstant %6\n%27 = OpTypePointer Output %5\n%30 = OpConstant %10 1\n%32 = OpConstant %10 2\n%34 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%16 = OpLoad %10 %12\n%17 = OpIAdd %10 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpImageRead %13 %21 %16\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpCompositeExtract %5 %22 1\n%25 = OpCompositeExtract %5 %22 2\n%26 = OpCompositeExtract %5 %22 3\n%28 = OpAccessChain %27 %15 %18\nOpStore %28 %23\n%29 = OpAccessChain %27 %15 %30\nOpStore %29 %24\n%31 = OpAccessChain %27 %15 %32\nOpStore %31 %25\n%33 = OpAccessChain %27 %15 %34\nOpStore %33 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-array-typed-buffer.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _9[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = imageLoad(_9[INDEX + 0u], int(INDEX));\n    SV_Target.x = _22.x;\n    SV_Target.y = _22.y;\n    SV_Target.z = _22.z;\n    SV_Target.w = _22.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %12 \"INDEX\"\nOpName %15 \"SV_Target\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %12 Flat\nOpDecorate %12 Location 0\nOpDecorate %15 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32f\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeInt 32 0\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeVector %5 4\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%18 = OpConstant %10 0\n%19 = OpTypePointer UniformConstant %6\n%27 = OpTypePointer Output %5\n%30 = OpConstant %10 1\n%32 = OpConstant %10 2\n%34 = OpConstant %10 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%16 = OpLoad %10 %12\n%17 = OpIAdd %10 %16 %18\n%20 = OpAccessChain %19 %9 %17\n%21 = OpLoad %6 %20\n%22 = OpImageRead %13 %21 %16\n%23 = OpCompositeExtract %5 %22 0\n%24 = OpCompositeExtract %5 %22 1\n%25 = OpCompositeExtract %5 %22 2\n%26 = OpCompositeExtract %5 %22 3\n%28 = OpAccessChain %27 %15 %18\nOpStore %28 %23\n%29 = OpAccessChain %27 %15 %30\nOpStore %29 %24\n%31 = OpAccessChain %27 %15 %32\nOpStore %31 %25\n%33 = OpAccessChain %27 %15 %34\nOpStore %33 %26\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter-array.ssbo.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 10, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _11[5];\n\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _15[5];\n\nlayout(location = 0) flat in uint I;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _30 = imageAtomicAdd(_15[nonuniformEXT(I)], int(0u), 1u);\n    SV_Target = _30;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %17 \"I\"\nOpName %19 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 10\nOpDecorate %11 NonReadable\nOpDecorate %11 NonWritable\nOpDecorate %15 DescriptorSet 7\nOpDecorate %15 Binding 0\nOpDecorate %17 Flat\nOpDecorate %17 Location 0\nOpDecorate %19 Location 0\nOpDecorate %20 NonUniform\nOpDecorate %24 NonUniform\nOpDecorate %28 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 5\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%13 = OpTypeArray %12 %8\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypePointer Input %5\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %5\n%19 = OpVariable %18 Output\n%22 = OpConstant %5 10\n%23 = OpTypePointer StorageBuffer %7\n%25 = OpTypePointer UniformConstant %12\n%27 = OpTypePointer Image %5\n%29 = OpConstant %5 0\n%31 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%20 = OpLoad %5 %17\n%21 = OpIAdd %5 %20 %22\n%24 = OpAccessChain %23 %11 %20\n%26 = OpAccessChain %25 %15 %20\n%28 = OpImageTexelPointer %27 %26 %29 %29\n%30 = OpAtomicIAdd %5 %28 %31 %29 %31\nOpStore %19 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter-array.ssbo.sm66.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 10, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _11[5];\n\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _15[5];\n\nlayout(location = 0) flat in uint I;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _30 = imageAtomicAdd(_15[nonuniformEXT(I)], int(0u), 1u);\n    SV_Target = _30;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %17 \"I\"\nOpName %19 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 10\nOpDecorate %11 NonReadable\nOpDecorate %11 NonWritable\nOpDecorate %15 DescriptorSet 7\nOpDecorate %15 Binding 0\nOpDecorate %17 Flat\nOpDecorate %17 Location 0\nOpDecorate %19 Location 0\nOpDecorate %20 NonUniform\nOpDecorate %24 NonUniform\nOpDecorate %28 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 5\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%13 = OpTypeArray %12 %8\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypePointer Input %5\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %5\n%19 = OpVariable %18 Output\n%22 = OpConstant %5 10\n%23 = OpTypePointer StorageBuffer %7\n%25 = OpTypePointer UniformConstant %12\n%27 = OpTypePointer Image %5\n%29 = OpConstant %5 0\n%31 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%20 = OpLoad %5 %17\n%21 = OpIAdd %5 %20 %22\n%24 = OpAccessChain %23 %11 %20\n%26 = OpAccessChain %25 %15 %20\n%28 = OpImageTexelPointer %27 %26 %29 %29\n%30 = OpAtomicIAdd %5 %28 %31 %29 %31\nOpStore %19 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter-array.ssbo.sm66.uav-counter-ssbo.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 10, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _11[5];\n\nlayout(set = 7, binding = 0, std430) buffer AtomicCounterSSBO\n{\n    uint counter;\n} _15[5];\n\nlayout(location = 0) flat in uint I;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _28 = atomicAdd(_15[nonuniformEXT(I)].counter, 1u);\n    SV_Target = _28;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"AtomicCounterSSBO\"\nOpMemberName %12 0 \"counter\"\nOpName %17 \"I\"\nOpName %19 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 10\nOpDecorate %11 NonReadable\nOpDecorate %11 NonWritable\nOpDecorate %12 Block\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %15 DescriptorSet 7\nOpDecorate %15 Binding 0\nOpDecorate %17 Flat\nOpDecorate %17 Location 0\nOpDecorate %19 Location 0\nOpDecorate %20 NonUniform\nOpDecorate %24 NonUniform\nOpDecorate %26 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 5\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeStruct %5\n%13 = OpTypeArray %12 %8\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypePointer Input %5\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %5\n%19 = OpVariable %18 Output\n%22 = OpConstant %5 10\n%23 = OpTypePointer StorageBuffer %7\n%25 = OpTypePointer StorageBuffer %5\n%27 = OpConstant %5 0\n%29 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%20 = OpLoad %5 %17\n%21 = OpIAdd %5 %20 %22\n%24 = OpAccessChain %23 %11 %20\n%26 = OpAccessChain %25 %15 %20 %27\n%28 = OpAtomicIAdd %5 %26 %29 %27 %29\nOpStore %19 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter-array.ssbo.uav-counter-ssbo.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 10, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _11[5];\n\nlayout(set = 7, binding = 0, std430) buffer AtomicCounterSSBO\n{\n    uint counter;\n} _15[5];\n\nlayout(location = 0) flat in uint I;\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    uint _28 = atomicAdd(_15[nonuniformEXT(I)].counter, 1u);\n    SV_Target = _28;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %17 %19\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"AtomicCounterSSBO\"\nOpMemberName %12 0 \"counter\"\nOpName %17 \"I\"\nOpName %19 \"SV_Target\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 10\nOpDecorate %11 NonReadable\nOpDecorate %11 NonWritable\nOpDecorate %12 Block\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %15 DescriptorSet 7\nOpDecorate %15 Binding 0\nOpDecorate %17 Flat\nOpDecorate %17 Location 0\nOpDecorate %19 Location 0\nOpDecorate %20 NonUniform\nOpDecorate %24 NonUniform\nOpDecorate %26 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpConstant %5 5\n%9 = OpTypeArray %7 %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeStruct %5\n%13 = OpTypeArray %12 %8\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypePointer Input %5\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Output %5\n%19 = OpVariable %18 Output\n%22 = OpConstant %5 10\n%23 = OpTypePointer StorageBuffer %7\n%25 = OpTypePointer StorageBuffer %5\n%27 = OpConstant %5 0\n%29 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%20 = OpLoad %5 %17\n%21 = OpIAdd %5 %20 %22\n%24 = OpAccessChain %23 %11 %20\n%26 = OpAccessChain %25 %15 %20 %27\n%28 = OpAtomicIAdd %5 %26 %29 %27 %29\nOpStore %19 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter-heap.sm66.bindless.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _13;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _19[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) flat in uint I;\nlayout(location = 0) out vec4 SV_Target;\n\nuint RobustPhysicalAtomicCounter(uvec2 _34, uint _35, uint _36)\n{\n    uint _51;\n    if (any(notEqual(_34, uvec2(0u))))\n    {\n        uint _48 = atomicAdd(uintPointer(_34).value, _35);\n        _51 = _48 + _36;\n    }\n    else\n    {\n        _51 = 0u;\n    }\n    return _51;\n}\n\nvoid main()\n{\n    uvec2 _32 = _13.counters[14u];\n    uint _53 = RobustPhysicalAtomicCounter(_32, 1u, 0u);\n    vec4 _57 = uintBitsToFloat(_19[14u]._m0[_53]);\n    SV_Target.x = _57.x;\n    SV_Target.y = _57.y;\n    SV_Target.z = _57.z;\n    SV_Target.w = _57.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %21 %25\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"AtomicCounters\"\nOpMemberName %11 0 \"counters\"\nOpName %16 \"SSBO\"\nOpName %21 \"I\"\nOpName %25 \"SV_Target\"\nOpName %37 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpDecorate %11 Block\nOpMemberDecorate %11 0 Offset 0\nOpMemberDecorate %11 0 NonWritable\nOpDecorate %13 DescriptorSet 7\nOpDecorate %13 Binding 0\nOpDecorate %13 AliasedPointer\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %21 Flat\nOpDecorate %21 Location 0\nOpDecorate %25 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeVector %5 4\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypePointer Input %5\n%21 = OpVariable %20 Input\n%22 = OpTypeFloat 32\n%23 = OpTypeVector %22 4\n%24 = OpTypePointer Output %23\n%25 = OpVariable %24 Output\n%26 = OpTypePointer StorageBuffer %16\n%28 = OpConstant %5 14\n%29 = OpTypePointer StorageBuffer %9\n%31 = OpConstant %5 0\n%33 = OpTypeFunction %5 %9 %5 %5\n%41 = OpTypeBool\n%42 = OpTypeVector %41 2\n%43 = OpConstantNull %9\n%46 = OpTypePointer PhysicalStorageBuffer %5\n%49 = OpConstant %5 1\n%54 = OpTypePointer StorageBuffer %14\n%62 = OpTypePointer Output %22\n%66 = OpConstant %5 2\n%68 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %69\n%69 = OpLabel\n%27 = OpAccessChain %26 %19 %28\n%30 = OpAccessChain %29 %13 %31 %28\n%32 = OpLoad %9 %30\n%53 = OpFunctionCall %5 %37 %32 %49 %31\n%55 = OpAccessChain %54 %27 %31 %53\n%56 = OpLoad %14 %55\n%57 = OpBitcast %23 %56\n%58 = OpCompositeExtract %22 %57 0\n%59 = OpCompositeExtract %22 %57 1\n%60 = OpCompositeExtract %22 %57 2\n%61 = OpCompositeExtract %22 %57 3\n%63 = OpAccessChain %62 %25 %31\nOpStore %63 %58\n%64 = OpAccessChain %62 %25 %49\nOpStore %64 %59\n%65 = OpAccessChain %62 %25 %66\nOpStore %65 %60\n%67 = OpAccessChain %62 %25 %68\nOpStore %67 %61\nOpReturn\nOpFunctionEnd\n%37 = OpFunction %5 None %33\n%34 = OpFunctionParameter %9\n%35 = OpFunctionParameter %5\n%36 = OpFunctionParameter %5\n%38 = OpLabel\n%44 = OpINotEqual %42 %34 %43\n%45 = OpAny %41 %44\nOpSelectionMerge %40 None\nOpBranchConditional %45 %39 %40\n%39 = OpLabel\n%47 = OpBitcast %46 %34\n%48 = OpAtomicIAdd %5 %47 %49 %31 %35\n%50 = OpIAdd %5 %48 %36\nOpBranch %40\n%40 = OpLabel\n%51 = OpPhi %5 %31 %38 %50 %39\nOpReturnValue %51\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter-heap.sm66.uav-counter-ssbo.bindless.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 7, binding = 0, std430) buffer AtomicCounters\n{\n    uint counter;\n} _12[];\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _18[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(location = 0) flat in uint I;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _33 = atomicAdd(_12[14u].counter, 1u);\n    vec4 _38 = uintBitsToFloat(_18[14u]._m0[_33]);\n    SV_Target.x = _38.x;\n    SV_Target.y = _38.y;\n    SV_Target.z = _38.z;\n    SV_Target.w = _38.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %24\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %9 \"AtomicCounters\"\nOpMemberName %9 0 \"counter\"\nOpName %15 \"SSBO\"\nOpName %20 \"I\"\nOpName %24 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %9 Block\nOpMemberDecorate %9 0 Offset 0\nOpDecorate %12 DescriptorSet 7\nOpDecorate %12 Binding 0\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %20 Flat\nOpDecorate %20 Location 0\nOpDecorate %24 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeStruct %5\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer StorageBuffer %10\n%12 = OpVariable %11 StorageBuffer\n%13 = OpTypeVector %5 4\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypePointer Input %5\n%20 = OpVariable %19 Input\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypePointer Output %22\n%24 = OpVariable %23 Output\n%25 = OpTypePointer StorageBuffer %15\n%27 = OpConstant %5 14\n%28 = OpTypePointer StorageBuffer %9\n%30 = OpTypePointer StorageBuffer %5\n%32 = OpConstant %5 0\n%34 = OpConstant %5 1\n%35 = OpTypePointer StorageBuffer %13\n%43 = OpTypePointer Output %21\n%47 = OpConstant %5 2\n%49 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%26 = OpAccessChain %25 %18 %27\n%29 = OpAccessChain %28 %12 %27\n%31 = OpAccessChain %30 %29 %32\n%33 = OpAtomicIAdd %5 %31 %34 %32 %34\n%36 = OpAccessChain %35 %26 %32 %33\n%37 = OpLoad %13 %36\n%38 = OpBitcast %22 %37\n%39 = OpCompositeExtract %21 %38 0\n%40 = OpCompositeExtract %21 %38 1\n%41 = OpCompositeExtract %21 %38 2\n%42 = OpCompositeExtract %21 %38 3\n%44 = OpAccessChain %43 %24 %32\nOpStore %44 %39\n%45 = OpAccessChain %43 %24 %34\nOpStore %45 %40\n%46 = OpAccessChain %43 %24 %47\nOpStore %46 %41\n%48 = OpAccessChain %43 %24 %49\nOpStore %48 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter-heap.sm66.uav-counter-texel-buffer.bindless.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _18[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _12[];\n\nlayout(location = 0) flat in uint I;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _33 = imageAtomicAdd(_12[14u], int(0u), 1u);\n    vec4 _38 = uintBitsToFloat(_18[14u]._m0[_33]);\n    SV_Target.x = _38.x;\n    SV_Target.y = _38.y;\n    SV_Target.z = _38.z;\n    SV_Target.w = _38.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %20 %24\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"SSBO\"\nOpName %20 \"I\"\nOpName %24 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 DescriptorSet 7\nOpDecorate %12 Binding 0\nOpDecorate %14 ArrayStride 16\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %20 Flat\nOpDecorate %20 Location 0\nOpDecorate %24 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %5 4\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypePointer Input %5\n%20 = OpVariable %19 Input\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypePointer Output %22\n%24 = OpVariable %23 Output\n%25 = OpTypePointer StorageBuffer %15\n%27 = OpConstant %5 14\n%28 = OpTypePointer UniformConstant %9\n%30 = OpTypePointer Image %5\n%32 = OpConstant %5 0\n%34 = OpConstant %5 1\n%35 = OpTypePointer StorageBuffer %13\n%43 = OpTypePointer Output %21\n%47 = OpConstant %5 2\n%49 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%26 = OpAccessChain %25 %18 %27\n%29 = OpAccessChain %28 %12 %27\n%31 = OpImageTexelPointer %30 %29 %32 %32\n%33 = OpAtomicIAdd %5 %31 %34 %32 %34\n%36 = OpAccessChain %35 %26 %32 %33\n%37 = OpLoad %13 %36\n%38 = OpBitcast %22 %37\n%39 = OpCompositeExtract %21 %38 0\n%40 = OpCompositeExtract %21 %38 1\n%41 = OpCompositeExtract %21 %38 2\n%42 = OpCompositeExtract %21 %38 3\n%44 = OpAccessChain %43 %24 %32\nOpStore %44 %39\n%45 = OpAccessChain %43 %24 %34\nOpStore %45 %40\n%46 = OpAccessChain %43 %24 %47\nOpStore %46 %41\n%48 = OpAccessChain %43 %24 %49\nOpStore %48 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.bindless.nobda.root-constant.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _12[];\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _15[];\n\nvoid main()\n{\n    uint _23 = gl_GlobalInvocationID.x + 2u;\n    uint _39 = imageAtomicAdd(_15[nonuniformEXT(registers._m4 + _23)], int(0u), 1u);\n    uint _42 = (gl_GlobalInvocationID.x ^ 1u) + 2u;\n    uint _53 = imageAtomicAdd(_15[nonuniformEXT(registers._m4 + _42)], int(0u), 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %12 NonWritable\nOpDecorate %15 DescriptorSet 7\nOpDecorate %15 Binding 0\nOpDecorate %18 BuiltIn GlobalInvocationId\nOpDecorate %31 NonUniform\nOpDecorate %32 NonUniform\nOpDecorate %36 NonUniform\nOpDecorate %38 NonUniform\nOpDecorate %46 NonUniform\nOpDecorate %47 NonUniform\nOpDecorate %51 NonUniform\nOpDecorate %52 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeRuntimeArray %9\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypeVector %5 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %5\n%21 = OpConstant %5 0\n%24 = OpConstant %5 2\n%25 = OpTypePointer UniformConstant %9\n%27 = OpTypePointer PushConstant %5\n%29 = OpConstant %5 4\n%37 = OpTypePointer Image %5\n%40 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpIAdd %5 %22 %24\n%28 = OpAccessChain %27 %8 %29\n%30 = OpLoad %5 %28\n%31 = OpIAdd %5 %30 %23\n%26 = OpAccessChain %25 %12 %31\n%32 = OpLoad %9 %26\n%34 = OpAccessChain %27 %8 %29\n%35 = OpLoad %5 %34\n%36 = OpIAdd %5 %35 %23\n%33 = OpAccessChain %25 %15 %36\n%38 = OpImageTexelPointer %37 %33 %21 %21\n%39 = OpAtomicIAdd %5 %38 %40 %21 %40\n%41 = OpBitwiseXor %5 %22 %40\n%42 = OpIAdd %5 %41 %24\n%44 = OpAccessChain %27 %8 %29\n%45 = OpLoad %5 %44\n%46 = OpIAdd %5 %45 %42\n%43 = OpAccessChain %25 %12 %46\n%47 = OpLoad %9 %43\n%49 = OpAccessChain %27 %8 %29\n%50 = OpLoad %5 %49\n%51 = OpIAdd %5 %50 %42\n%48 = OpAccessChain %25 %15 %51\n%52 = OpImageTexelPointer %37 %48 %21 %21\n%53 = OpAtomicIAdd %5 %52 %40 %21 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.bindless.nobda.root-constant.raw-va-stride-offset.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _12[];\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _15[];\n\nvoid main()\n{\n    uint _23 = gl_GlobalInvocationID.x + 2u;\n    uint _39 = imageAtomicAdd(_15[nonuniformEXT(registers._m4 + _23)], int(0u), 1u);\n    uint _42 = (gl_GlobalInvocationID.x ^ 1u) + 2u;\n    uint _53 = imageAtomicAdd(_15[nonuniformEXT(registers._m4 + _42)], int(0u), 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %12 NonWritable\nOpDecorate %15 DescriptorSet 7\nOpDecorate %15 Binding 0\nOpDecorate %18 BuiltIn GlobalInvocationId\nOpDecorate %31 NonUniform\nOpDecorate %32 NonUniform\nOpDecorate %36 NonUniform\nOpDecorate %38 NonUniform\nOpDecorate %46 NonUniform\nOpDecorate %47 NonUniform\nOpDecorate %51 NonUniform\nOpDecorate %52 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeRuntimeArray %9\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%16 = OpTypeVector %5 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %5\n%21 = OpConstant %5 0\n%24 = OpConstant %5 2\n%25 = OpTypePointer UniformConstant %9\n%27 = OpTypePointer PushConstant %5\n%29 = OpConstant %5 4\n%37 = OpTypePointer Image %5\n%40 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpIAdd %5 %22 %24\n%28 = OpAccessChain %27 %8 %29\n%30 = OpLoad %5 %28\n%31 = OpIAdd %5 %30 %23\n%26 = OpAccessChain %25 %12 %31\n%32 = OpLoad %9 %26\n%34 = OpAccessChain %27 %8 %29\n%35 = OpLoad %5 %34\n%36 = OpIAdd %5 %35 %23\n%33 = OpAccessChain %25 %15 %36\n%38 = OpImageTexelPointer %37 %33 %21 %21\n%39 = OpAtomicIAdd %5 %38 %40 %21 %40\n%41 = OpBitwiseXor %5 %22 %40\n%42 = OpIAdd %5 %41 %24\n%44 = OpAccessChain %27 %8 %29\n%45 = OpLoad %5 %44\n%46 = OpIAdd %5 %45 %42\n%43 = OpAccessChain %25 %12 %46\n%47 = OpLoad %9 %43\n%49 = OpAccessChain %27 %8 %29\n%50 = OpLoad %5 %49\n%51 = OpIAdd %5 %50 %42\n%48 = OpAccessChain %25 %15 %51\n%52 = OpImageTexelPointer %37 %48 %21 %21\n%53 = OpAtomicIAdd %5 %52 %40 %21 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.bindless.root-constant.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _17;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _12[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _42, uint _43, uint _44)\n{\n    uint _59;\n    if (any(notEqual(_42, uvec2(0u))))\n    {\n        uint _56 = atomicAdd(uintPointer(_42).value, _43);\n        _59 = _56 + _44;\n    }\n    else\n    {\n        _59 = 0u;\n    }\n    return _59;\n}\n\nvoid main()\n{\n    uint _25 = gl_GlobalInvocationID.x + 2u;\n    uvec2 _40 = _17.counters[registers._m4 + _25];\n    uint _61 = RobustPhysicalAtomicCounter(_40, 1u, 0u);\n    uint _63 = (gl_GlobalInvocationID.x ^ 1u) + 2u;\n    uvec2 _73 = _17.counters[registers._m4 + _63];\n    uint _74 = RobustPhysicalAtomicCounter(_73, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 77\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %20\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"AtomicCounters\"\nOpMemberName %15 0 \"counters\"\nOpName %45 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %12 NonWritable\nOpDecorate %14 ArrayStride 8\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpMemberDecorate %15 0 NonWritable\nOpDecorate %17 DescriptorSet 7\nOpDecorate %17 Binding 0\nOpDecorate %17 AliasedPointer\nOpDecorate %20 BuiltIn GlobalInvocationId\nOpDecorate %33 NonUniform\nOpDecorate %34 NonUniform\nOpDecorate %67 NonUniform\nOpDecorate %68 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %5 2\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypeStruct %14\n%16 = OpTypePointer StorageBuffer %15\n%17 = OpVariable %16 StorageBuffer\n%18 = OpTypeVector %5 3\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Input %5\n%23 = OpConstant %5 0\n%26 = OpConstant %5 2\n%27 = OpTypePointer UniformConstant %9\n%29 = OpTypePointer PushConstant %5\n%31 = OpConstant %5 4\n%35 = OpTypePointer StorageBuffer %13\n%41 = OpTypeFunction %5 %13 %5 %5\n%49 = OpTypeBool\n%50 = OpTypeVector %49 2\n%51 = OpConstantNull %13\n%54 = OpTypePointer PhysicalStorageBuffer %5\n%57 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpIAdd %5 %24 %26\n%30 = OpAccessChain %29 %8 %31\n%32 = OpLoad %5 %30\n%33 = OpIAdd %5 %32 %25\n%28 = OpAccessChain %27 %12 %33\n%34 = OpLoad %9 %28\n%37 = OpAccessChain %29 %8 %31\n%38 = OpLoad %5 %37\n%39 = OpIAdd %5 %38 %25\n%36 = OpAccessChain %35 %17 %23 %39\n%40 = OpLoad %13 %36\n%61 = OpFunctionCall %5 %45 %40 %57 %23\n%62 = OpBitwiseXor %5 %24 %57\n%63 = OpIAdd %5 %62 %26\n%65 = OpAccessChain %29 %8 %31\n%66 = OpLoad %5 %65\n%67 = OpIAdd %5 %66 %63\n%64 = OpAccessChain %27 %12 %67\n%68 = OpLoad %9 %64\n%70 = OpAccessChain %29 %8 %31\n%71 = OpLoad %5 %70\n%72 = OpIAdd %5 %71 %63\n%69 = OpAccessChain %35 %17 %23 %72\n%73 = OpLoad %13 %69\n%74 = OpFunctionCall %5 %45 %73 %57 %23\nOpReturn\nOpFunctionEnd\n%45 = OpFunction %5 None %41\n%42 = OpFunctionParameter %13\n%43 = OpFunctionParameter %5\n%44 = OpFunctionParameter %5\n%46 = OpLabel\n%52 = OpINotEqual %50 %42 %51\n%53 = OpAny %49 %52\nOpSelectionMerge %48 None\nOpBranchConditional %53 %47 %48\n%47 = OpLabel\n%55 = OpBitcast %54 %42\n%56 = OpAtomicIAdd %5 %55 %57 %23 %43\n%58 = OpIAdd %5 %56 %44\nOpBranch %48\n%48 = OpLabel\n%59 = OpPhi %5 %23 %46 %58 %47\nOpReturnValue %59\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.bindless.root-constant.raw-va-stride-offset.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _17;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _12[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _45, uint _46, uint _47)\n{\n    uint _62;\n    if (any(notEqual(_45, uvec2(0u))))\n    {\n        uint _59 = atomicAdd(uintPointer(_45).value, _46);\n        _62 = _59 + _47;\n    }\n    else\n    {\n        _62 = 0u;\n    }\n    return _62;\n}\n\nvoid main()\n{\n    uint _25 = gl_GlobalInvocationID.x + 2u;\n    uvec2 _43 = _17.counters[(4u * (registers._m4 + _25)) + 3u];\n    uint _64 = RobustPhysicalAtomicCounter(_43, 1u, 0u);\n    uint _66 = (gl_GlobalInvocationID.x ^ 1u) + 2u;\n    uvec2 _78 = _17.counters[(4u * (registers._m4 + _66)) + 3u];\n    uint _79 = RobustPhysicalAtomicCounter(_78, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 82\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %20\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %15 \"AtomicCounters\"\nOpMemberName %15 0 \"counters\"\nOpName %48 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %12 NonWritable\nOpDecorate %14 ArrayStride 8\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpMemberDecorate %15 0 NonWritable\nOpDecorate %17 DescriptorSet 7\nOpDecorate %17 Binding 0\nOpDecorate %17 AliasedPointer\nOpDecorate %20 BuiltIn GlobalInvocationId\nOpDecorate %33 NonUniform\nOpDecorate %34 NonUniform\nOpDecorate %70 NonUniform\nOpDecorate %71 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %5 2\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypeStruct %14\n%16 = OpTypePointer StorageBuffer %15\n%17 = OpVariable %16 StorageBuffer\n%18 = OpTypeVector %5 3\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Input %5\n%23 = OpConstant %5 0\n%26 = OpConstant %5 2\n%27 = OpTypePointer UniformConstant %9\n%29 = OpTypePointer PushConstant %5\n%31 = OpConstant %5 4\n%35 = OpTypePointer StorageBuffer %13\n%42 = OpConstant %5 3\n%44 = OpTypeFunction %5 %13 %5 %5\n%52 = OpTypeBool\n%53 = OpTypeVector %52 2\n%54 = OpConstantNull %13\n%57 = OpTypePointer PhysicalStorageBuffer %5\n%60 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %80\n%80 = OpLabel\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpIAdd %5 %24 %26\n%30 = OpAccessChain %29 %8 %31\n%32 = OpLoad %5 %30\n%33 = OpIAdd %5 %32 %25\n%28 = OpAccessChain %27 %12 %33\n%34 = OpLoad %9 %28\n%37 = OpAccessChain %29 %8 %31\n%38 = OpLoad %5 %37\n%39 = OpIAdd %5 %38 %25\n%40 = OpIMul %5 %31 %39\n%41 = OpIAdd %5 %40 %42\n%36 = OpAccessChain %35 %17 %23 %41\n%43 = OpLoad %13 %36\n%64 = OpFunctionCall %5 %48 %43 %60 %23\n%65 = OpBitwiseXor %5 %24 %60\n%66 = OpIAdd %5 %65 %26\n%68 = OpAccessChain %29 %8 %31\n%69 = OpLoad %5 %68\n%70 = OpIAdd %5 %69 %66\n%67 = OpAccessChain %27 %12 %70\n%71 = OpLoad %9 %67\n%73 = OpAccessChain %29 %8 %31\n%74 = OpLoad %5 %73\n%75 = OpIAdd %5 %74 %66\n%76 = OpIMul %5 %31 %75\n%77 = OpIAdd %5 %76 %42\n%72 = OpAccessChain %35 %17 %23 %77\n%78 = OpLoad %13 %72\n%79 = OpFunctionCall %5 %48 %78 %60 %23\nOpReturn\nOpFunctionEnd\n%48 = OpFunction %5 None %44\n%45 = OpFunctionParameter %13\n%46 = OpFunctionParameter %5\n%47 = OpFunctionParameter %5\n%49 = OpLabel\n%55 = OpINotEqual %53 %45 %54\n%56 = OpAny %52 %55\nOpSelectionMerge %51 None\nOpBranchConditional %56 %50 %51\n%50 = OpLabel\n%58 = OpBitcast %57 %45\n%59 = OpAtomicIAdd %5 %58 %60 %23 %46\n%61 = OpIAdd %5 %59 %47\nOpBranch %51\n%51 = OpLabel\n%62 = OpPhi %5 %23 %49 %61 %50\nOpReturnValue %62\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.bindless.root-constant.raw-va-stride-offset.heap-raw-va-cbv.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer DescriptorHeapRawBlock;\nlayout(buffer_reference) buffer uintPointer;\n\nstruct DescriptorHeapRawPayload\n{\n    uvec2 _m0[4];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) readonly buffer DescriptorHeapRawBlock\n{\n    DescriptorHeapRawPayload descriptors[];\n};\n\nlayout(set = 10, binding = 21, std140) uniform DescriptorHeapRawPayloadPtr\n{\n    DescriptorHeapRawBlock ptr;\n} DescriptorHeapRaw;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _12[];\n\nuint RobustPhysicalAtomicCounter(uvec2 _50, uint _51, uint _52)\n{\n    uint _67;\n    if (any(notEqual(_50, uvec2(0u))))\n    {\n        uint _64 = atomicAdd(uintPointer(_50).value, _51);\n        _67 = _64 + _52;\n    }\n    else\n    {\n        _67 = 0u;\n    }\n    return _67;\n}\n\nvoid main()\n{\n    uint _30 = gl_GlobalInvocationID.x + 2u;\n    uint _69 = RobustPhysicalAtomicCounter(DescriptorHeapRaw.ptr.descriptors[registers._m4 + _30]._m0[3u], 1u, 0u);\n    uint _71 = (gl_GlobalInvocationID.x ^ 1u) + 2u;\n    uint _84 = RobustPhysicalAtomicCounter(DescriptorHeapRaw.ptr.descriptors[registers._m4 + _71]._m0[3u], 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %25\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"DescriptorHeapRawPayload\"\nOpName %18 \"DescriptorHeapRawBlock\"\nOpMemberName %18 0 \"descriptors\"\nOpName %20 \"DescriptorHeapRawPayloadPtr\"\nOpMemberName %20 0 \"ptr\"\nOpName %22 \"DescriptorHeapRaw\"\nOpName %53 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %12 NonWritable\nOpDecorate %15 ArrayStride 8\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %17 ArrayStride 32\nOpDecorate %18 Block\nOpMemberDecorate %18 0 Offset 0\nOpMemberDecorate %18 0 NonWritable\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 10\nOpDecorate %22 Binding 21\nOpDecorate %25 BuiltIn GlobalInvocationId\nOpDecorate %37 NonUniform\nOpDecorate %38 NonUniform\nOpDecorate %75 NonUniform\nOpDecorate %76 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %5 2\n%14 = OpConstant %5 4\n%15 = OpTypeArray %13 %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer PhysicalStorageBuffer %18\n%20 = OpTypeStruct %19\n%21 = OpTypePointer Uniform %20\n%22 = OpVariable %21 Uniform\n%23 = OpTypeVector %5 3\n%24 = OpTypePointer Input %23\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Input %5\n%28 = OpConstant %5 0\n%31 = OpConstant %5 2\n%32 = OpTypePointer UniformConstant %9\n%34 = OpTypePointer PushConstant %5\n%39 = OpTypePointer Uniform %19\n%42 = OpTypePointer PhysicalStorageBuffer %13\n%47 = OpConstant %5 3\n%49 = OpTypeFunction %5 %13 %5 %5\n%57 = OpTypeBool\n%58 = OpTypeVector %57 2\n%59 = OpConstantNull %13\n%62 = OpTypePointer PhysicalStorageBuffer %5\n%65 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %85\n%85 = OpLabel\n%27 = OpAccessChain %26 %25 %28\n%29 = OpLoad %5 %27\n%30 = OpIAdd %5 %29 %31\n%35 = OpAccessChain %34 %8 %14\n%36 = OpLoad %5 %35\n%37 = OpIAdd %5 %36 %30\n%33 = OpAccessChain %32 %12 %37\n%38 = OpLoad %9 %33\n%40 = OpAccessChain %39 %22 %28\n%41 = OpLoad %19 %40\n%44 = OpAccessChain %34 %8 %14\n%45 = OpLoad %5 %44\n%46 = OpIAdd %5 %45 %30\n%43 = OpInBoundsAccessChain %42 %41 %28 %46 %28 %47\n%48 = OpLoad %13 %43 Aligned 8\n%69 = OpFunctionCall %5 %53 %48 %65 %28\n%70 = OpBitwiseXor %5 %29 %65\n%71 = OpIAdd %5 %70 %31\n%73 = OpAccessChain %34 %8 %14\n%74 = OpLoad %5 %73\n%75 = OpIAdd %5 %74 %71\n%72 = OpAccessChain %32 %12 %75\n%76 = OpLoad %9 %72\n%77 = OpAccessChain %39 %22 %28\n%78 = OpLoad %19 %77\n%80 = OpAccessChain %34 %8 %14\n%81 = OpLoad %5 %80\n%82 = OpIAdd %5 %81 %71\n%79 = OpInBoundsAccessChain %42 %78 %28 %82 %28 %47\n%83 = OpLoad %13 %79 Aligned 8\n%84 = OpFunctionCall %5 %53 %83 %65 %28\nOpReturn\nOpFunctionEnd\n%53 = OpFunction %5 None %49\n%50 = OpFunctionParameter %13\n%51 = OpFunctionParameter %5\n%52 = OpFunctionParameter %5\n%54 = OpLabel\n%60 = OpINotEqual %58 %50 %59\n%61 = OpAny %57 %60\nOpSelectionMerge %56 None\nOpBranchConditional %61 %55 %56\n%55 = OpLabel\n%63 = OpBitcast %62 %50\n%64 = OpAtomicIAdd %5 %63 %65 %28 %51\n%66 = OpIAdd %5 %64 %52\nOpBranch %56\n%56 = OpLabel\n%67 = OpPhi %5 %28 %54 %66 %55\nOpReturnValue %67\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.bindless.root-constant.uav-counter-ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 7, binding = 0, std430) buffer AtomicCounters\n{\n    uint counter;\n} _16[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly writeonly uimageBuffer _12[];\n\nvoid main()\n{\n    uint _24 = gl_GlobalInvocationID.x + 2u;\n    uint _41 = atomicAdd(_16[nonuniformEXT(registers._m4 + _24)].counter, 1u);\n    uint _44 = (gl_GlobalInvocationID.x ^ 1u) + 2u;\n    uint _55 = atomicAdd(_16[nonuniformEXT(registers._m4 + _44)].counter, 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 58\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %19\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %13 \"AtomicCounters\"\nOpMemberName %13 0 \"counter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonReadable\nOpDecorate %12 NonWritable\nOpDecorate %13 Block\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %16 DescriptorSet 7\nOpDecorate %16 Binding 0\nOpDecorate %19 BuiltIn GlobalInvocationId\nOpDecorate %32 NonUniform\nOpDecorate %33 NonUniform\nOpDecorate %38 NonUniform\nOpDecorate %40 NonUniform\nOpDecorate %48 NonUniform\nOpDecorate %49 NonUniform\nOpDecorate %53 NonUniform\nOpDecorate %54 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeStruct %5\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeVector %5 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %5\n%22 = OpConstant %5 0\n%25 = OpConstant %5 2\n%26 = OpTypePointer UniformConstant %9\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 4\n%34 = OpTypePointer StorageBuffer %13\n%39 = OpTypePointer StorageBuffer %5\n%42 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %56\n%56 = OpLabel\n%21 = OpAccessChain %20 %19 %22\n%23 = OpLoad %5 %21\n%24 = OpIAdd %5 %23 %25\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%32 = OpIAdd %5 %31 %24\n%27 = OpAccessChain %26 %12 %32\n%33 = OpLoad %9 %27\n%36 = OpAccessChain %28 %8 %30\n%37 = OpLoad %5 %36\n%38 = OpIAdd %5 %37 %24\n%35 = OpAccessChain %34 %16 %38\n%40 = OpAccessChain %39 %35 %22\n%41 = OpAtomicIAdd %5 %40 %42 %22 %42\n%43 = OpBitwiseXor %5 %23 %42\n%44 = OpIAdd %5 %43 %25\n%46 = OpAccessChain %28 %8 %30\n%47 = OpLoad %5 %46\n%48 = OpIAdd %5 %47 %44\n%45 = OpAccessChain %26 %12 %48\n%49 = OpLoad %9 %45\n%51 = OpAccessChain %28 %8 %30\n%52 = OpLoad %5 %51\n%53 = OpIAdd %5 %52 %44\n%50 = OpAccessChain %34 %16 %53\n%54 = OpAccessChain %39 %50 %22\n%55 = OpAtomicIAdd %5 %54 %42 %22 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 1, binding = 2, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 2, binding = 2, std430) writeonly readonly buffer _14_16\n{\n    uint _m0[];\n} _16;\n\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _12;\nlayout(set = 7, binding = 1, r32ui) uniform uimageBuffer _17;\n\nvoid main()\n{\n    uint _21 = imageAtomicAdd(_12, int(0u), 1u);\n    uint _24 = imageAtomicAdd(_17, int(0u), 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %14 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 1\nOpDecorate %9 Binding 2\nOpDecorate %9 NonReadable\nOpDecorate %9 NonWritable\nOpDecorate %12 DescriptorSet 7\nOpDecorate %12 Binding 0\nOpDecorate %13 ArrayStride 4\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 2\nOpDecorate %16 Binding 2\nOpDecorate %16 NonReadable\nOpDecorate %16 NonWritable\nOpDecorate %17 DescriptorSet 7\nOpDecorate %17 Binding 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeRuntimeArray %5\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpVariable %11 UniformConstant\n%18 = OpTypePointer Image %5\n%20 = OpConstant %5 0\n%22 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%19 = OpImageTexelPointer %18 %12 %20 %20\n%21 = OpAtomicIAdd %5 %19 %22 %20 %22\n%23 = OpImageTexelPointer %18 %17 %20 %20\n%24 = OpAtomicIAdd %5 %23 %22 %20 %22\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.ssbo.raw-va-stride-offset.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 1, binding = 2, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 2, binding = 2, std430) writeonly readonly buffer _14_16\n{\n    uint _m0[];\n} _16;\n\nlayout(set = 7, binding = 0, r32ui) uniform uimageBuffer _12;\nlayout(set = 7, binding = 1, r32ui) uniform uimageBuffer _17;\n\nvoid main()\n{\n    uint _21 = imageAtomicAdd(_12, int(0u), 1u);\n    uint _24 = imageAtomicAdd(_17, int(0u), 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %14 \"SSBO\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 1\nOpDecorate %9 Binding 2\nOpDecorate %9 NonReadable\nOpDecorate %9 NonWritable\nOpDecorate %12 DescriptorSet 7\nOpDecorate %12 Binding 0\nOpDecorate %13 ArrayStride 4\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 2\nOpDecorate %16 Binding 2\nOpDecorate %16 NonReadable\nOpDecorate %16 NonWritable\nOpDecorate %17 DescriptorSet 7\nOpDecorate %17 Binding 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeRuntimeArray %5\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpVariable %11 UniformConstant\n%18 = OpTypePointer Image %5\n%20 = OpConstant %5 0\n%22 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%19 = OpImageTexelPointer %18 %12 %20 %20\n%21 = OpAtomicIAdd %5 %19 %22 %20 %22\n%23 = OpImageTexelPointer %18 %17 %20 %20\n%24 = OpAtomicIAdd %5 %23 %22 %20 %22\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-counter.ssbo.uav-counter-ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 1, binding = 2, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 7, binding = 0, std430) buffer AtomicCounterSSBO\n{\n    uint counter;\n} _12;\n\nlayout(set = 2, binding = 2, std430) writeonly readonly buffer _14_16\n{\n    uint _m0[];\n} _16;\n\nlayout(set = 7, binding = 1, std430) buffer _17_19\n{\n    uint counter;\n} _19;\n\nvoid main()\n{\n    uint _24 = atomicAdd(_12.counter, 1u);\n    uint _26 = atomicAdd(_19.counter, 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\"\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %10 \"AtomicCounterSSBO\"\nOpMemberName %10 0 \"counter\"\nOpName %14 \"SSBO\"\nOpName %17 \"AtomicCounterSSBO\"\nOpMemberName %17 0 \"counter\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 1\nOpDecorate %9 Binding 2\nOpDecorate %9 NonReadable\nOpDecorate %9 NonWritable\nOpDecorate %10 Block\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %12 DescriptorSet 7\nOpDecorate %12 Binding 0\nOpDecorate %13 ArrayStride 4\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %14 Block\nOpDecorate %16 DescriptorSet 2\nOpDecorate %16 Binding 2\nOpDecorate %16 NonReadable\nOpDecorate %16 NonWritable\nOpDecorate %17 Block\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %19 DescriptorSet 7\nOpDecorate %19 Binding 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeStruct %5\n%11 = OpTypePointer StorageBuffer %10\n%12 = OpVariable %11 StorageBuffer\n%13 = OpTypeRuntimeArray %5\n%14 = OpTypeStruct %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeStruct %5\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypePointer StorageBuffer %5\n%22 = OpConstant %5 0\n%25 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%21 = OpAccessChain %20 %19 %22\n%23 = OpAccessChain %20 %12 %22\n%24 = OpAtomicIAdd %5 %23 %25 %22 %25\n%26 = OpAtomicIAdd %5 %21 %25 %22 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-indexing.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 5, r32f) uniform readonly image2D _11[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = imageLoad(_11[0u], ivec2(uvec2(0u)));\n    vec4 _32 = imageLoad(_11[2u], ivec2(uvec2(0u)));\n    vec4 _46 = imageLoad(_11[V], ivec2(uvec2(0u)));\n    SV_Target.x = (_32.x + _22.x) + _46.x;\n    SV_Target.y = (_32.y + _22.y) + _46.y;\n    SV_Target.z = (_32.z + _22.z) + _46.z;\n    SV_Target.w = (_32.w + _22.w) + _46.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %16\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"V\"\nOpName %16 \"SV_Target\"\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 5\nOpDecorate %11 NonWritable\nOpDecorate %13 Flat\nOpDecorate %13 Location 0\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypePointer Input %7\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%18 = OpTypePointer UniformConstant %6\n%20 = OpConstant %7 0\n%23 = OpTypeVector %7 2\n%30 = OpConstant %7 2\n%43 = OpConstant %7 5\n%56 = OpTypePointer Output %5\n%59 = OpConstant %7 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%17 = OpLoad %7 %13\n%19 = OpAccessChain %18 %11 %20\n%21 = OpLoad %6 %19\n%24 = OpCompositeConstruct %23 %20 %20\n%22 = OpImageRead %14 %21 %24 None\n%25 = OpCompositeExtract %5 %22 0\n%26 = OpCompositeExtract %5 %22 1\n%27 = OpCompositeExtract %5 %22 2\n%28 = OpCompositeExtract %5 %22 3\n%29 = OpAccessChain %18 %11 %30\n%31 = OpLoad %6 %29\n%33 = OpCompositeConstruct %23 %20 %20\n%32 = OpImageRead %14 %31 %33 None\n%34 = OpCompositeExtract %5 %32 0\n%35 = OpCompositeExtract %5 %32 1\n%36 = OpCompositeExtract %5 %32 2\n%37 = OpCompositeExtract %5 %32 3\n%38 = OpFAdd %5 %34 %25\n%39 = OpFAdd %5 %35 %26\n%40 = OpFAdd %5 %36 %27\n%41 = OpFAdd %5 %37 %28\n%42 = OpIAdd %7 %17 %43\n%44 = OpAccessChain %18 %11 %17\n%45 = OpLoad %6 %44\n%47 = OpCompositeConstruct %23 %20 %20\n%46 = OpImageRead %14 %45 %47 None\n%48 = OpCompositeExtract %5 %46 0\n%49 = OpCompositeExtract %5 %46 1\n%50 = OpCompositeExtract %5 %46 2\n%51 = OpCompositeExtract %5 %46 3\n%52 = OpFAdd %5 %38 %48\n%53 = OpFAdd %5 %39 %49\n%54 = OpFAdd %5 %40 %50\n%55 = OpFAdd %5 %41 %51\n%57 = OpAccessChain %56 %16 %20\nOpStore %57 %52\n%58 = OpAccessChain %56 %16 %59\nOpStore %58 %53\n%60 = OpAccessChain %56 %16 %30\nOpStore %60 %54\n%61 = OpAccessChain %56 %16 %8\nOpStore %61 %55\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-indexing.sm66.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 5, r32f) uniform readonly image2D _11[3];\n\nlayout(location = 0) flat in uint V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    vec4 _22 = imageLoad(_11[0u], ivec2(uvec2(0u)));\n    vec4 _32 = imageLoad(_11[2u], ivec2(uvec2(0u)));\n    vec4 _46 = imageLoad(_11[V], ivec2(uvec2(0u)));\n    SV_Target.x = (_32.x + _22.x) + _46.x;\n    SV_Target.y = (_32.y + _22.y) + _46.y;\n    SV_Target.z = (_32.z + _22.z) + _46.z;\n    SV_Target.w = (_32.w + _22.w) + _46.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageArrayDynamicIndexing\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %16\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"V\"\nOpName %16 \"SV_Target\"\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 5\nOpDecorate %11 NonWritable\nOpDecorate %13 Flat\nOpDecorate %13 Location 0\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypePointer Input %7\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%18 = OpTypePointer UniformConstant %6\n%20 = OpConstant %7 0\n%23 = OpTypeVector %7 2\n%30 = OpConstant %7 2\n%43 = OpConstant %7 5\n%56 = OpTypePointer Output %5\n%59 = OpConstant %7 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%17 = OpLoad %7 %13\n%19 = OpAccessChain %18 %11 %20\n%21 = OpLoad %6 %19\n%24 = OpCompositeConstruct %23 %20 %20\n%22 = OpImageRead %14 %21 %24 None\n%25 = OpCompositeExtract %5 %22 0\n%26 = OpCompositeExtract %5 %22 1\n%27 = OpCompositeExtract %5 %22 2\n%28 = OpCompositeExtract %5 %22 3\n%29 = OpAccessChain %18 %11 %30\n%31 = OpLoad %6 %29\n%33 = OpCompositeConstruct %23 %20 %20\n%32 = OpImageRead %14 %31 %33 None\n%34 = OpCompositeExtract %5 %32 0\n%35 = OpCompositeExtract %5 %32 1\n%36 = OpCompositeExtract %5 %32 2\n%37 = OpCompositeExtract %5 %32 3\n%38 = OpFAdd %5 %34 %25\n%39 = OpFAdd %5 %35 %26\n%40 = OpFAdd %5 %36 %27\n%41 = OpFAdd %5 %37 %28\n%42 = OpIAdd %7 %17 %43\n%44 = OpAccessChain %18 %11 %17\n%45 = OpLoad %6 %44\n%47 = OpCompositeConstruct %23 %20 %20\n%46 = OpImageRead %14 %45 %47 None\n%48 = OpCompositeExtract %5 %46 0\n%49 = OpCompositeExtract %5 %46 1\n%50 = OpCompositeExtract %5 %46 2\n%51 = OpCompositeExtract %5 %46 3\n%52 = OpFAdd %5 %38 %48\n%53 = OpFAdd %5 %39 %49\n%54 = OpFAdd %5 %40 %50\n%55 = OpFAdd %5 %41 %51\n%57 = OpAccessChain %56 %16 %20\nOpStore %57 %52\n%58 = OpAccessChain %56 %16 %59\nOpStore %58 %53\n%60 = OpAccessChain %56 %16 %30\nOpStore %60 %54\n%61 = OpAccessChain %56 %16 %8\nOpStore %61 %55\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-raw-buffer.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly uimageBuffer _12[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out uvec2 SV_Target;\n\nvoid main()\n{\n    uint _28 = registers._m4 + 3u;\n    uint _36 = uint(int(gl_FragCoord.x));\n    uint _38 = _36 * 2u;\n    uvec2 _47 = uvec2(imageLoad(_12[_28], int(_38)).x, imageLoad(_12[_28], int(_38 + 1u)).x);\n    uint _67 = registers._m4 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u);\n    uint _69 = _36 * 2u;\n    uvec2 _75 = uvec2(imageLoad(_12[_67], int(_69)).x, imageLoad(_12[_67], int(_69 + 1u)).x);\n    uint _85 = registers._m4 + (INDEX + 100u);\n    uint _87 = _36 * 2u;\n    uvec2 _93 = uvec2(imageLoad(_12[nonuniformEXT(_85)], int(_87)).x, imageLoad(_12[nonuniformEXT(_85)], int(_87 + 1u)).x);\n    SV_Target.x = (_75.x + _47.x) + _93.x;\n    SV_Target.y = (_75.y + _47.y) + _93.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 103\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18 %21\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpName %18 \"INDEX\"\nOpName %21 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonWritable\nOpDecorate %16 BuiltIn FragCoord\nOpDecorate %18 Flat\nOpDecorate %18 Location 1\nOpDecorate %21 Location 0\nOpDecorate %85 NonUniform\nOpDecorate %86 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypeVector %5 2\n%20 = OpTypePointer Output %19\n%21 = OpVariable %20 Output\n%22 = OpTypePointer UniformConstant %9\n%24 = OpTypePointer PushConstant %5\n%26 = OpConstant %5 4\n%29 = OpConstant %5 3\n%32 = OpTypePointer Input %13\n%34 = OpConstant %5 0\n%39 = OpConstant %5 2\n%40 = OpTypeVector %5 4\n%45 = OpConstant %5 1\n%53 = OpConstant %5 5\n%56 = OpConstant %5 6\n%59 = OpConstant %5 7\n%81 = OpConstant %5 100\n%98 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %101\n%101 = OpLabel\n%25 = OpAccessChain %24 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpIAdd %5 %27 %29\n%23 = OpAccessChain %22 %12 %28\n%30 = OpLoad %9 %23\n%31 = OpLoad %5 %18\n%33 = OpAccessChain %32 %16 %34\n%35 = OpLoad %13 %33\n%36 = OpConvertFToS %5 %35\n%37 = OpShiftLeftLogical %5 %36 %29\n%38 = OpIMul %5 %36 %39\n%41 = OpImageRead %40 %30 %38\n%42 = OpCompositeExtract %5 %41 0\n%44 = OpIAdd %5 %38 %45\n%43 = OpImageRead %40 %30 %44\n%46 = OpCompositeExtract %5 %43 0\n%47 = OpCompositeConstruct %19 %42 %46\n%48 = OpCompositeExtract %5 %47 0\n%49 = OpCompositeExtract %5 %47 1\n%50 = OpAccessChain %24 %8 %26\n%51 = OpLoad %5 %50\n%52 = OpAccessChain %24 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %24 %8 %56\n%57 = OpLoad %5 %55\n%58 = OpAccessChain %24 %8 %59\n%60 = OpLoad %5 %58\n%61 = OpCompositeConstruct %40 %51 %54 %57 %60\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpIAdd %5 %62 %26\n%65 = OpAccessChain %24 %8 %26\n%66 = OpLoad %5 %65\n%67 = OpIAdd %5 %66 %63\n%64 = OpAccessChain %22 %12 %67\n%68 = OpLoad %9 %64\n%69 = OpIMul %5 %36 %39\n%70 = OpImageRead %40 %68 %69\n%71 = OpCompositeExtract %5 %70 0\n%73 = OpIAdd %5 %69 %45\n%72 = OpImageRead %40 %68 %73\n%74 = OpCompositeExtract %5 %72 0\n%75 = OpCompositeConstruct %19 %71 %74\n%76 = OpCompositeExtract %5 %75 0\n%77 = OpCompositeExtract %5 %75 1\n%78 = OpIAdd %5 %76 %48\n%79 = OpIAdd %5 %77 %49\n%80 = OpIAdd %5 %31 %81\n%83 = OpAccessChain %24 %8 %26\n%84 = OpLoad %5 %83\n%85 = OpIAdd %5 %84 %80\n%82 = OpAccessChain %22 %12 %85\n%86 = OpLoad %9 %82\n%87 = OpIMul %5 %36 %39\n%88 = OpImageRead %40 %86 %87\n%89 = OpCompositeExtract %5 %88 0\n%91 = OpIAdd %5 %87 %45\n%90 = OpImageRead %40 %86 %91\n%92 = OpCompositeExtract %5 %90 0\n%93 = OpCompositeConstruct %19 %89 %92\n%94 = OpCompositeExtract %5 %93 0\n%95 = OpCompositeExtract %5 %93 1\n%96 = OpIAdd %5 %78 %94\n%97 = OpIAdd %5 %79 %95\n%99 = OpAccessChain %98 %21 %34\nOpStore %99 %96\n%100 = OpAccessChain %98 %21 %45\nOpStore %100 %97\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-raw-buffer.ssbo.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 3, std430) readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 4, std430) readonly buffer _12_16\n{\n    uvec2 _m0[];\n} _16[64];\n\nlayout(set = 0, binding = 100, std430) readonly buffer _18_21\n{\n    uvec2 _m0[];\n} _21[];\n\nlayout(set = 0, binding = 0, std140) uniform _26_28\n{\n    vec4 _m0[1];\n} _28;\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out uvec2 SV_Target;\n\nvoid main()\n{\n    uint _40 = uint(int(gl_FragCoord.x));\n    uvec4 _52 = floatBitsToUint(_28._m0[0u]);\n    uint _53 = _52.x;\n    SV_Target.x = (_16[_53]._m0[_40].x + _10._m0[_40].x) + _21[nonuniformEXT(INDEX)]._m0[_40].x;\n    SV_Target.y = (_16[_53]._m0[_40].y + _10._m0[_40].y) + _21[nonuniformEXT(INDEX)]._m0[_40].y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability RuntimeDescriptorArray\nOpCapability StorageBufferArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %30 %32 %34\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %18 \"SSBO\"\nOpName %26 \"\"\nOpName %30 \"SV_Position\"\nOpName %32 \"INDEX\"\nOpName %34 \"SV_Target\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 3\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 4\nOpDecorate %16 NonWritable\nOpDecorate %17 ArrayStride 8\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 100\nOpDecorate %21 NonWritable\nOpDecorate %25 ArrayStride 16\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %28 DescriptorSet 0\nOpDecorate %28 Binding 0\nOpDecorate %30 BuiltIn FragCoord\nOpDecorate %32 Flat\nOpDecorate %32 Location 1\nOpDecorate %34 Location 0\nOpDecorate %35 NonUniform\nOpDecorate %67 NonUniform\nOpDecorate %68 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpConstant %5 64\n%14 = OpTypeArray %12 %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeRuntimeArray %6\n%18 = OpTypeStruct %17\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer StorageBuffer %19\n%21 = OpVariable %20 StorageBuffer\n%22 = OpConstant %5 1\n%23 = OpTypeFloat 32\n%24 = OpTypeVector %23 4\n%25 = OpTypeArray %24 %22\n%26 = OpTypeStruct %25\n%27 = OpTypePointer Uniform %26\n%28 = OpVariable %27 Uniform\n%29 = OpTypePointer Input %24\n%30 = OpVariable %29 Input\n%31 = OpTypePointer Input %5\n%32 = OpVariable %31 Input\n%33 = OpTypePointer Output %6\n%34 = OpVariable %33 Output\n%36 = OpTypePointer Input %23\n%38 = OpConstant %5 0\n%42 = OpConstant %5 3\n%43 = OpTypePointer StorageBuffer %6\n%48 = OpTypePointer Uniform %24\n%51 = OpTypeVector %5 4\n%55 = OpConstant %5 4\n%56 = OpTypePointer StorageBuffer %12\n%65 = OpConstant %5 100\n%66 = OpTypePointer StorageBuffer %18\n%74 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %77\n%77 = OpLabel\n%35 = OpLoad %5 %32\n%37 = OpAccessChain %36 %30 %38\n%39 = OpLoad %23 %37\n%40 = OpConvertFToS %5 %39\n%41 = OpShiftLeftLogical %5 %40 %42\n%44 = OpAccessChain %43 %10 %38 %40\n%45 = OpLoad %6 %44\n%46 = OpCompositeExtract %5 %45 0\n%47 = OpCompositeExtract %5 %45 1\n%49 = OpAccessChain %48 %28 %38 %38\n%50 = OpLoad %24 %49\n%52 = OpBitcast %51 %50\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpIAdd %5 %53 %55\n%57 = OpAccessChain %56 %16 %53\n%58 = OpAccessChain %43 %57 %38 %40\n%59 = OpLoad %6 %58\n%60 = OpCompositeExtract %5 %59 0\n%61 = OpCompositeExtract %5 %59 1\n%62 = OpIAdd %5 %60 %46\n%63 = OpIAdd %5 %61 %47\n%64 = OpIAdd %5 %35 %65\n%67 = OpAccessChain %66 %21 %35\n%68 = OpAccessChain %43 %67 %38 %40\n%69 = OpLoad %6 %68\n%70 = OpCompositeExtract %5 %69 0\n%71 = OpCompositeExtract %5 %69 1\n%72 = OpIAdd %5 %62 %70\n%73 = OpIAdd %5 %63 %71\n%75 = OpAccessChain %74 %34 %38\nOpStore %75 %72\n%76 = OpAccessChain %74 %34 %22\nOpStore %76 %73\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-structured-buffer.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform readonly uimageBuffer _12[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    uint _36 = uint(int(gl_FragCoord.x));\n    float _40 = uintBitsToFloat(imageLoad(_12[registers._m4 + 3u], int(_36)).x);\n    uint _58 = registers._m4 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u);\n    uint _60 = _36 * 2u;\n    vec2 _71 = uintBitsToFloat(uvec2(imageLoad(_12[_58], int(_60)).x, imageLoad(_12[_58], int(_60 + 1u)).x));\n    float _74 = _71.x + _40;\n    uint _81 = registers._m4 + (INDEX + 100u);\n    uint _83 = _36 * 3u;\n    vec3 _94 = uintBitsToFloat(uvec3(imageLoad(_12[nonuniformEXT(_81)], int(_83)).x, imageLoad(_12[nonuniformEXT(_81)], int(_83 + 1u)).x, imageLoad(_12[nonuniformEXT(_81)], int(_83 + 2u)).x));\n    SV_Target.x = _94.x + _74;\n    SV_Target.y = (_71.y + _40) + _94.y;\n    SV_Target.z = _94.z + _74;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16 %18 %21\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpName %18 \"INDEX\"\nOpName %21 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 NonWritable\nOpDecorate %16 BuiltIn FragCoord\nOpDecorate %18 Flat\nOpDecorate %18 Location 1\nOpDecorate %21 Location 0\nOpDecorate %81 NonUniform\nOpDecorate %82 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%18 = OpVariable %17 Input\n%19 = OpTypeVector %13 3\n%20 = OpTypePointer Output %19\n%21 = OpVariable %20 Output\n%22 = OpTypePointer UniformConstant %9\n%24 = OpTypePointer PushConstant %5\n%26 = OpConstant %5 4\n%29 = OpConstant %5 3\n%32 = OpTypePointer Input %13\n%34 = OpConstant %5 0\n%37 = OpTypeVector %5 4\n%44 = OpConstant %5 5\n%47 = OpConstant %5 6\n%50 = OpConstant %5 7\n%61 = OpConstant %5 2\n%66 = OpConstant %5 1\n%68 = OpTypeVector %5 2\n%70 = OpTypeVector %13 2\n%77 = OpConstant %5 100\n%92 = OpTypeVector %5 3\n%101 = OpTypePointer Output %13\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %105\n%105 = OpLabel\n%25 = OpAccessChain %24 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpIAdd %5 %27 %29\n%23 = OpAccessChain %22 %12 %28\n%30 = OpLoad %9 %23\n%31 = OpLoad %5 %18\n%33 = OpAccessChain %32 %16 %34\n%35 = OpLoad %13 %33\n%36 = OpConvertFToS %5 %35\n%38 = OpImageRead %37 %30 %36\n%39 = OpCompositeExtract %5 %38 0\n%40 = OpBitcast %13 %39\n%41 = OpAccessChain %24 %8 %26\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %24 %8 %44\n%45 = OpLoad %5 %43\n%46 = OpAccessChain %24 %8 %47\n%48 = OpLoad %5 %46\n%49 = OpAccessChain %24 %8 %50\n%51 = OpLoad %5 %49\n%52 = OpCompositeConstruct %37 %42 %45 %48 %51\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpIAdd %5 %53 %26\n%56 = OpAccessChain %24 %8 %26\n%57 = OpLoad %5 %56\n%58 = OpIAdd %5 %57 %54\n%55 = OpAccessChain %22 %12 %58\n%59 = OpLoad %9 %55\n%60 = OpIMul %5 %36 %61\n%62 = OpImageRead %37 %59 %60\n%63 = OpCompositeExtract %5 %62 0\n%65 = OpIAdd %5 %60 %66\n%64 = OpImageRead %37 %59 %65\n%67 = OpCompositeExtract %5 %64 0\n%69 = OpCompositeConstruct %68 %63 %67\n%71 = OpBitcast %70 %69\n%72 = OpCompositeExtract %13 %71 0\n%73 = OpCompositeExtract %13 %71 1\n%74 = OpFAdd %13 %72 %40\n%75 = OpFAdd %13 %73 %40\n%76 = OpIAdd %5 %31 %77\n%79 = OpAccessChain %24 %8 %26\n%80 = OpLoad %5 %79\n%81 = OpIAdd %5 %80 %76\n%78 = OpAccessChain %22 %12 %81\n%82 = OpLoad %9 %78\n%83 = OpIMul %5 %36 %29\n%84 = OpImageRead %37 %82 %83\n%85 = OpCompositeExtract %5 %84 0\n%87 = OpIAdd %5 %83 %66\n%86 = OpImageRead %37 %82 %87\n%88 = OpCompositeExtract %5 %86 0\n%90 = OpIAdd %5 %83 %61\n%89 = OpImageRead %37 %82 %90\n%91 = OpCompositeExtract %5 %89 0\n%93 = OpCompositeConstruct %92 %85 %88 %91\n%94 = OpBitcast %19 %93\n%95 = OpCompositeExtract %13 %94 0\n%96 = OpCompositeExtract %13 %94 1\n%97 = OpCompositeExtract %13 %94 2\n%98 = OpFAdd %13 %95 %74\n%99 = OpFAdd %13 %75 %96\n%100 = OpFAdd %13 %97 %74\n%102 = OpAccessChain %101 %21 %34\nOpStore %102 %98\n%103 = OpAccessChain %101 %21 %66\nOpStore %103 %99\n%104 = OpAccessChain %101 %21 %61\nOpStore %104 %100\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-typed-buffer.bindless.root-constant.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n    uint _m8;\n    uint _m9;\n    uint _m10;\n    uint _m11;\n    uint _m12;\n    uint _m13;\n    uint _m14;\n    uint _m15;\n} registers;\n\nlayout(set = 4, binding = 0, r32f) uniform readonly imageBuffer _13[];\nlayout(set = 4, binding = 0, r32ui) uniform readonly uimageBuffer _17[];\nlayout(set = 4, binding = 0, r32i) uniform readonly iimageBuffer _22[];\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    uint _44 = uint(int(gl_FragCoord.x));\n    vec4 _45 = imageLoad(_13[registers._m4 + 3u], int(_44));\n    uvec4 _71 = imageLoad(_17[registers._m4 + (uvec4(registers._m4, registers._m5, registers._m6, registers._m7).x + 4u)], int(_44));\n    uvec4 _94 = uvec4(imageLoad(_22[nonuniformEXT(registers._m4 + (INDEX + 100u))], int(_44)));\n    SV_Target.x = (float(_71.x) + _45.x) + float(int(_94.x));\n    SV_Target.y = (float(_71.y) + _45.y) + float(int(_94.y));\n    SV_Target.z = (float(_71.z) + _45.z) + float(int(_94.z));\n    SV_Target.w = (float(_71.w) + _45.w) + float(int(_94.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 116\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayNonUniformIndexing\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %25 %27 %29\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %25 \"SV_Position\"\nOpName %27 \"INDEX\"\nOpName %29 \"SV_Target\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpMemberDecorate %6 8 Offset 32\nOpMemberDecorate %6 9 Offset 36\nOpMemberDecorate %6 10 Offset 40\nOpMemberDecorate %6 11 Offset 44\nOpMemberDecorate %6 12 Offset 48\nOpMemberDecorate %6 13 Offset 52\nOpMemberDecorate %6 14 Offset 56\nOpMemberDecorate %6 15 Offset 60\nOpDecorate %13 DescriptorSet 4\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %17 DescriptorSet 4\nOpDecorate %17 Binding 0\nOpDecorate %17 NonWritable\nOpDecorate %22 DescriptorSet 4\nOpDecorate %22 Binding 0\nOpDecorate %22 NonWritable\nOpDecorate %25 BuiltIn FragCoord\nOpDecorate %27 Flat\nOpDecorate %27 Location 1\nOpDecorate %29 Location 0\nOpDecorate %90 NonUniform\nOpDecorate %91 NonUniform\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 Buffer 0 0 0 2 R32f\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeInt 32 1\n%19 = OpTypeImage %18 Buffer 0 0 0 2 R32i\n%20 = OpTypeRuntimeArray %19\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypeVector %9 4\n%24 = OpTypePointer Input %23\n%25 = OpVariable %24 Input\n%26 = OpTypePointer Input %5\n%27 = OpVariable %26 Input\n%28 = OpTypePointer Output %23\n%29 = OpVariable %28 Output\n%30 = OpTypePointer UniformConstant %10\n%32 = OpTypePointer PushConstant %5\n%34 = OpConstant %5 4\n%37 = OpConstant %5 3\n%40 = OpTypePointer Input %9\n%42 = OpConstant %5 0\n%53 = OpConstant %5 5\n%56 = OpConstant %5 6\n%59 = OpConstant %5 7\n%61 = OpTypeVector %5 4\n%65 = OpTypePointer UniformConstant %14\n%85 = OpConstant %5 100\n%86 = OpTypePointer UniformConstant %19\n%92 = OpTypeVector %18 4\n%107 = OpTypePointer Output %9\n%110 = OpConstant %5 1\n%112 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%33 = OpAccessChain %32 %8 %34\n%35 = OpLoad %5 %33\n%36 = OpIAdd %5 %35 %37\n%31 = OpAccessChain %30 %13 %36\n%38 = OpLoad %10 %31\n%39 = OpLoad %5 %27\n%41 = OpAccessChain %40 %25 %42\n%43 = OpLoad %9 %41\n%44 = OpConvertFToS %5 %43\n%45 = OpImageRead %23 %38 %44\n%46 = OpCompositeExtract %9 %45 0\n%47 = OpCompositeExtract %9 %45 1\n%48 = OpCompositeExtract %9 %45 2\n%49 = OpCompositeExtract %9 %45 3\n%50 = OpAccessChain %32 %8 %34\n%51 = OpLoad %5 %50\n%52 = OpAccessChain %32 %8 %53\n%54 = OpLoad %5 %52\n%55 = OpAccessChain %32 %8 %56\n%57 = OpLoad %5 %55\n%58 = OpAccessChain %32 %8 %59\n%60 = OpLoad %5 %58\n%62 = OpCompositeConstruct %61 %51 %54 %57 %60\n%63 = OpCompositeExtract %5 %62 0\n%64 = OpIAdd %5 %63 %34\n%67 = OpAccessChain %32 %8 %34\n%68 = OpLoad %5 %67\n%69 = OpIAdd %5 %68 %64\n%66 = OpAccessChain %65 %17 %69\n%70 = OpLoad %14 %66\n%71 = OpImageRead %61 %70 %44\n%72 = OpCompositeExtract %5 %71 0\n%73 = OpCompositeExtract %5 %71 1\n%74 = OpCompositeExtract %5 %71 2\n%75 = OpCompositeExtract %5 %71 3\n%76 = OpConvertUToF %9 %72\n%77 = OpConvertUToF %9 %73\n%78 = OpConvertUToF %9 %74\n%79 = OpConvertUToF %9 %75\n%80 = OpFAdd %9 %76 %46\n%81 = OpFAdd %9 %77 %47\n%82 = OpFAdd %9 %78 %48\n%83 = OpFAdd %9 %79 %49\n%84 = OpIAdd %5 %39 %85\n%88 = OpAccessChain %32 %8 %34\n%89 = OpLoad %5 %88\n%90 = OpIAdd %5 %89 %84\n%87 = OpAccessChain %86 %22 %90\n%91 = OpLoad %19 %87\n%93 = OpImageRead %92 %91 %44\n%94 = OpBitcast %61 %93\n%95 = OpCompositeExtract %5 %94 0\n%96 = OpCompositeExtract %5 %94 1\n%97 = OpCompositeExtract %5 %94 2\n%98 = OpCompositeExtract %5 %94 3\n%99 = OpConvertSToF %9 %95\n%100 = OpConvertSToF %9 %96\n%101 = OpConvertSToF %9 %97\n%102 = OpConvertSToF %9 %98\n%103 = OpFAdd %9 %80 %99\n%104 = OpFAdd %9 %81 %100\n%105 = OpFAdd %9 %82 %101\n%106 = OpFAdd %9 %83 %102\n%108 = OpAccessChain %107 %29 %42\nOpStore %108 %103\n%109 = OpAccessChain %107 %29 %110\nOpStore %109 %104\n%111 = OpAccessChain %107 %29 %112\nOpStore %111 %105\n%113 = OpAccessChain %107 %29 %37\nOpStore %113 %106\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/resources/uav-typed.typed-uav-without-format.comp",
    "content": "#version 460\n#extension GL_EXT_shader_image_load_formatted : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform image2D _8;\nlayout(set = 0, binding = 1) uniform imageBuffer _11;\nlayout(set = 0, binding = 2, r32ui) uniform uimageBuffer _15;\n\nvoid main()\n{\n    vec4 _30 = imageLoad(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)));\n    imageStore(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), vec4(_30.x + 2.0, _30.y + 2.0, _30.z + 2.0, _30.w + 2.0));\n    vec4 _44 = imageLoad(_11, int(gl_GlobalInvocationID.x));\n    imageStore(_11, int(gl_GlobalInvocationID.x), vec4(_44.x + 3.0, _44.y + 3.0, _44.z + 3.0, _44.w + 3.0));\n    uint _57 = imageAtomicAdd(_15, int(gl_GlobalInvocationID.y), 10u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability StorageImageReadWithoutFormat\nOpCapability StorageImageWriteWithoutFormat\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %21\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 2\nOpDecorate %21 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeInt 32 0\n%13 = OpTypeImage %12 Buffer 0 0 0 2 R32ui\n%14 = OpTypePointer UniformConstant %13\n%15 = OpVariable %14 UniformConstant\n%19 = OpTypeVector %12 3\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypePointer Input %12\n%24 = OpConstant %12 0\n%27 = OpConstant %12 1\n%29 = OpTypeVector %5 4\n%31 = OpTypeVector %12 2\n%38 = OpConstant %5 2\n%50 = OpConstant %5 3\n%55 = OpTypePointer Image %12\n%58 = OpConstant %12 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%16 = OpLoad %13 %15\n%17 = OpLoad %9 %11\n%18 = OpLoad %6 %8\n%23 = OpAccessChain %22 %21 %24\n%25 = OpLoad %12 %23\n%26 = OpAccessChain %22 %21 %27\n%28 = OpLoad %12 %26\n%32 = OpCompositeConstruct %31 %25 %28\n%30 = OpImageRead %29 %18 %32 None\n%33 = OpCompositeExtract %5 %30 0\n%34 = OpCompositeExtract %5 %30 1\n%35 = OpCompositeExtract %5 %30 2\n%36 = OpCompositeExtract %5 %30 3\n%37 = OpFAdd %5 %33 %38\n%39 = OpFAdd %5 %34 %38\n%40 = OpFAdd %5 %35 %38\n%41 = OpFAdd %5 %36 %38\n%42 = OpCompositeConstruct %31 %25 %28\n%43 = OpCompositeConstruct %29 %37 %39 %40 %41\nOpImageWrite %18 %42 %43\n%44 = OpImageRead %29 %17 %25\n%45 = OpCompositeExtract %5 %44 0\n%46 = OpCompositeExtract %5 %44 1\n%47 = OpCompositeExtract %5 %44 2\n%48 = OpCompositeExtract %5 %44 3\n%49 = OpFAdd %5 %45 %50\n%51 = OpFAdd %5 %46 %50\n%52 = OpFAdd %5 %47 %50\n%53 = OpFAdd %5 %48 %50\n%54 = OpCompositeConstruct %29 %49 %51 %52 %53\nOpImageWrite %17 %25 %54\n%56 = OpImageTexelPointer %55 %15 %28 %24\n%57 = OpAtomicIAdd %12 %56 %27 %24 %58\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-bab.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform coherent uimageBuffer _12[];\n\nvoid main()\n{\n    uint _35 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    uint _37 = _35 * 4u;\n    SPIRV_Cross_beginInvocationInterlock();\n    uvec4 _39 = imageLoad(_12[registers._m4], int(_37));\n    uvec4 _41 = imageLoad(_12[registers._m4], int(_37 + 1u));\n    uvec4 _44 = imageLoad(_12[registers._m4], int(_37 + 2u));\n    uvec4 _48 = imageLoad(_12[registers._m4], int(_37 + 3u));\n    uvec4 _52 = uvec4(_39.x, _41.x, _44.x, _48.x);\n    uint _61 = _35 * 4u;\n    imageStore(_12[registers._m4], int(_61), uvec4(_52.x + 1u));\n    imageStore(_12[registers._m4], int(_61 + 1u), uvec4(_52.y + 2u));\n    imageStore(_12[registers._m4], int(_61 + 2u), uvec4(_52.z + 3u));\n    imageStore(_12[registers._m4], int(_61 + 3u), uvec4(_52.w + 4u));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 Coherent\nOpDecorate %16 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer UniformConstant %9\n%19 = OpTypePointer PushConstant %5\n%21 = OpConstant %5 4\n%24 = OpTypePointer Input %13\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%34 = OpConstant %5 1000\n%38 = OpTypeVector %5 4\n%46 = OpConstant %5 2\n%50 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %69\n%69 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%18 = OpAccessChain %17 %12 %22\n%23 = OpLoad %9 %18\n%25 = OpAccessChain %24 %16 %26\n%27 = OpLoad %13 %25\n%28 = OpAccessChain %24 %16 %29\n%30 = OpLoad %13 %28\n%31 = OpConvertFToU %5 %27\n%32 = OpConvertFToU %5 %30\n%33 = OpIMul %5 %32 %34\n%35 = OpIAdd %5 %33 %31\n%36 = OpShiftLeftLogical %5 %35 %21\n%37 = OpIMul %5 %35 %21\nOpBeginInvocationInterlockEXT\n%39 = OpImageRead %38 %23 %37\n%40 = OpCompositeExtract %5 %39 0\n%42 = OpIAdd %5 %37 %29\n%41 = OpImageRead %38 %23 %42\n%43 = OpCompositeExtract %5 %41 0\n%45 = OpIAdd %5 %37 %46\n%44 = OpImageRead %38 %23 %45\n%47 = OpCompositeExtract %5 %44 0\n%49 = OpIAdd %5 %37 %50\n%48 = OpImageRead %38 %23 %49\n%51 = OpCompositeExtract %5 %48 0\n%52 = OpCompositeConstruct %38 %40 %43 %47 %51\n%53 = OpCompositeExtract %5 %52 0\n%54 = OpCompositeExtract %5 %52 1\n%55 = OpCompositeExtract %5 %52 2\n%56 = OpCompositeExtract %5 %52 3\n%57 = OpIAdd %5 %53 %29\n%58 = OpIAdd %5 %54 %46\n%59 = OpIAdd %5 %55 %50\n%60 = OpIAdd %5 %56 %21\n%61 = OpIMul %5 %35 %21\n%62 = OpCompositeConstruct %38 %57 %57 %57 %57\nOpImageWrite %23 %61 %62\n%63 = OpCompositeConstruct %38 %58 %58 %58 %58\n%64 = OpIAdd %5 %61 %29\nOpImageWrite %23 %64 %63\n%65 = OpCompositeConstruct %38 %59 %59 %59 %59\n%66 = OpIAdd %5 %61 %46\nOpImageWrite %23 %66 %65\n%67 = OpCompositeConstruct %38 %60 %60 %60 %60\n%68 = OpIAdd %5 %61 %50\nOpImageWrite %23 %68 %67\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-bab.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _8;\n\nvoid main()\n{\n    uint _25 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    uint _28 = _25 * 4u;\n    SPIRV_Cross_beginInvocationInterlock();\n    uvec4 _30 = imageLoad(_8, int(_28));\n    uvec4 _32 = imageLoad(_8, int(_28 + 1u));\n    uvec4 _35 = imageLoad(_8, int(_28 + 2u));\n    uvec4 _39 = imageLoad(_8, int(_28 + 3u));\n    uvec4 _43 = uvec4(_30.x, _32.x, _35.x, _39.x);\n    uint _52 = _25 * 4u;\n    imageStore(_8, int(_52), uvec4(_43.x + 1u));\n    imageStore(_8, int(_52 + 1u), uvec4(_43.y + 2u));\n    imageStore(_8, int(_52 + 2u), uvec4(_43.z + 3u));\n    imageStore(_8, int(_52 + 3u), uvec4(_43.w + 4u));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %12 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%14 = OpTypePointer Input %9\n%16 = OpConstant %5 0\n%19 = OpConstant %5 1\n%24 = OpConstant %5 1000\n%27 = OpConstant %5 4\n%29 = OpTypeVector %5 4\n%37 = OpConstant %5 2\n%41 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%13 = OpLoad %6 %8\n%15 = OpAccessChain %14 %12 %16\n%17 = OpLoad %9 %15\n%18 = OpAccessChain %14 %12 %19\n%20 = OpLoad %9 %18\n%21 = OpConvertFToU %5 %17\n%22 = OpConvertFToU %5 %20\n%23 = OpIMul %5 %22 %24\n%25 = OpIAdd %5 %23 %21\n%26 = OpShiftLeftLogical %5 %25 %27\n%28 = OpIMul %5 %25 %27\nOpBeginInvocationInterlockEXT\n%30 = OpImageRead %29 %13 %28\n%31 = OpCompositeExtract %5 %30 0\n%33 = OpIAdd %5 %28 %19\n%32 = OpImageRead %29 %13 %33\n%34 = OpCompositeExtract %5 %32 0\n%36 = OpIAdd %5 %28 %37\n%35 = OpImageRead %29 %13 %36\n%38 = OpCompositeExtract %5 %35 0\n%40 = OpIAdd %5 %28 %41\n%39 = OpImageRead %29 %13 %40\n%42 = OpCompositeExtract %5 %39 0\n%43 = OpCompositeConstruct %29 %31 %34 %38 %42\n%44 = OpCompositeExtract %5 %43 0\n%45 = OpCompositeExtract %5 %43 1\n%46 = OpCompositeExtract %5 %43 2\n%47 = OpCompositeExtract %5 %43 3\n%48 = OpIAdd %5 %44 %19\n%49 = OpIAdd %5 %45 %37\n%50 = OpIAdd %5 %46 %41\n%51 = OpIAdd %5 %47 %27\n%52 = OpIMul %5 %25 %27\n%53 = OpCompositeConstruct %29 %48 %48 %48 %48\nOpImageWrite %13 %52 %53\n%54 = OpCompositeConstruct %29 %49 %49 %49 %49\n%55 = OpIAdd %5 %52 %19\nOpImageWrite %13 %55 %54\n%56 = OpCompositeConstruct %29 %50 %50 %50 %50\n%57 = OpIAdd %5 %52 %37\nOpImageWrite %13 %57 %56\n%58 = OpCompositeConstruct %29 %51 %51 %51 %51\n%59 = OpIAdd %5 %52 %41\nOpImageWrite %13 %59 %58\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-bab.ssbo.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 4, binding = 0, std430) coherent buffer SSBO\n{\n    uvec4 _m0[];\n} _14[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _36 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    SPIRV_Cross_beginInvocationInterlock();\n    _14[registers._m4]._m0[_36] = uvec4(_14[registers._m4]._m0[_36].x + 1u, _14[registers._m4]._m0[_36].y + 2u, _14[registers._m4]._m0[_36].z + 3u, _14[registers._m4]._m0[_36].w + 4u);\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %18\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO\"\nOpName %18 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 16\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %14 DescriptorSet 4\nOpDecorate %14 Binding 0\nOpDecorate %14 Coherent\nOpDecorate %18 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeFloat 32\n%16 = OpTypeVector %15 4\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer StorageBuffer %11\n%21 = OpTypePointer PushConstant %5\n%23 = OpConstant %5 4\n%25 = OpTypePointer Input %15\n%27 = OpConstant %5 0\n%30 = OpConstant %5 1\n%35 = OpConstant %5 1000\n%38 = OpTypePointer StorageBuffer %9\n%47 = OpConstant %5 2\n%49 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%22 = OpAccessChain %21 %8 %23\n%24 = OpLoad %5 %22\n%20 = OpAccessChain %19 %14 %24\n%26 = OpAccessChain %25 %18 %27\n%28 = OpLoad %15 %26\n%29 = OpAccessChain %25 %18 %30\n%31 = OpLoad %15 %29\n%32 = OpConvertFToU %5 %28\n%33 = OpConvertFToU %5 %31\n%34 = OpIMul %5 %33 %35\n%36 = OpIAdd %5 %34 %32\n%37 = OpShiftLeftLogical %5 %36 %23\n%39 = OpAccessChain %38 %20 %27 %36\nOpBeginInvocationInterlockEXT\n%40 = OpLoad %9 %39\n%41 = OpCompositeExtract %5 %40 0\n%42 = OpCompositeExtract %5 %40 1\n%43 = OpCompositeExtract %5 %40 2\n%44 = OpCompositeExtract %5 %40 3\n%45 = OpIAdd %5 %41 %30\n%46 = OpIAdd %5 %42 %47\n%48 = OpIAdd %5 %43 %49\n%50 = OpIAdd %5 %44 %23\n%51 = OpCompositeConstruct %9 %45 %46 %48 %50\n%52 = OpAccessChain %38 %20 %27 %36\nOpStore %52 %51\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-bab.ssbo.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, std430) coherent buffer SSBO\n{\n    uvec4 _m0[];\n} _10;\n\nvoid main()\n{\n    uint _26 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    SPIRV_Cross_beginInvocationInterlock();\n    _10._m0[_26] = uvec4(_10._m0[_26].x + 1u, _10._m0[_26].y + 2u, _10._m0[_26].z + 3u, _10._m0[_26].w + 4u);\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\nOpCapability Shader\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %14 \"SV_Position\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 Coherent\nOpDecorate %14 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %11\n%17 = OpConstant %5 0\n%20 = OpConstant %5 1\n%25 = OpConstant %5 1000\n%28 = OpConstant %5 4\n%29 = OpTypePointer StorageBuffer %6\n%38 = OpConstant %5 2\n%40 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %11 %16\n%19 = OpAccessChain %15 %14 %20\n%21 = OpLoad %11 %19\n%22 = OpConvertFToU %5 %18\n%23 = OpConvertFToU %5 %21\n%24 = OpIMul %5 %23 %25\n%26 = OpIAdd %5 %24 %22\n%27 = OpShiftLeftLogical %5 %26 %28\n%30 = OpAccessChain %29 %10 %17 %26\nOpBeginInvocationInterlockEXT\n%31 = OpLoad %6 %30\n%32 = OpCompositeExtract %5 %31 0\n%33 = OpCompositeExtract %5 %31 1\n%34 = OpCompositeExtract %5 %31 2\n%35 = OpCompositeExtract %5 %31 3\n%36 = OpIAdd %5 %32 %20\n%37 = OpIAdd %5 %33 %38\n%39 = OpIAdd %5 %34 %40\n%41 = OpIAdd %5 %35 %28\n%42 = OpCompositeConstruct %6 %36 %37 %39 %41\n%43 = OpAccessChain %29 %10 %17 %26\nOpStore %43 %42\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-bab.ssbo.root-descriptor.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#extension GL_EXT_buffer_reference_uvec2 : require\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(buffer_reference) buffer PhysicalPointerUint4CoherentArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) coherent buffer PhysicalPointerUint4CoherentArray\n{\n    uvec4 value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    uint _29 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    PhysicalPointerUint4CoherentArray _36 = PhysicalPointerUint4CoherentArray(registers._m2);\n    SPIRV_Cross_beginInvocationInterlock();\n    PhysicalPointerUint4CoherentArray(registers._m2).value[_29] = uvec4(_36.value[_29].x + 1u, _36.value[_29].y + 2u, _36.value[_29].z + 3u, _36.value[_29].w + 4u);\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %13 \"SV_Position\"\nOpName %34 \"PhysicalPointerUint4CoherentArray\"\nOpMemberName %34 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %13 BuiltIn FragCoord\nOpDecorate %33 ArrayStride 16\nOpMemberDecorate %34 0 Offset 0\nOpDecorate %34 Block\nOpMemberDecorate %34 0 Coherent\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeVector %10 4\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%14 = OpTypePointer PushConstant %6\n%16 = OpConstant %5 2\n%18 = OpTypePointer Input %10\n%20 = OpConstant %5 0\n%23 = OpConstant %5 1\n%28 = OpConstant %5 1000\n%31 = OpConstant %5 4\n%32 = OpTypeVector %5 4\n%33 = OpTypeRuntimeArray %32\n%34 = OpTypeStruct %33\n%35 = OpTypePointer PhysicalStorageBuffer %34\n%37 = OpTypePointer PhysicalStorageBuffer %32\n%47 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %52\n%52 = OpLabel\n%15 = OpAccessChain %14 %9 %16\n%17 = OpLoad %6 %15\n%19 = OpAccessChain %18 %13 %20\n%21 = OpLoad %10 %19\n%22 = OpAccessChain %18 %13 %23\n%24 = OpLoad %10 %22\n%25 = OpConvertFToU %5 %21\n%26 = OpConvertFToU %5 %24\n%27 = OpIMul %5 %26 %28\n%29 = OpIAdd %5 %27 %25\n%30 = OpShiftLeftLogical %5 %29 %31\n%36 = OpBitcast %35 %17\n%38 = OpInBoundsAccessChain %37 %36 %20 %29\nOpBeginInvocationInterlockEXT\n%39 = OpLoad %32 %38 Aligned 16\n%40 = OpCompositeExtract %5 %39 0\n%41 = OpCompositeExtract %5 %39 1\n%42 = OpCompositeExtract %5 %39 2\n%43 = OpCompositeExtract %5 %39 3\n%44 = OpIAdd %5 %40 %23\n%45 = OpIAdd %5 %41 %16\n%46 = OpIAdd %5 %42 %47\n%48 = OpIAdd %5 %43 %31\n%49 = OpBitcast %35 %17\n%50 = OpInBoundsAccessChain %37 %49 %20 %29\n%51 = OpCompositeConstruct %32 %44 %45 %46 %48\nOpStore %50 %51 Aligned 16\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-branch-early-return.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _8;\nlayout(set = 0, binding = 1, r32f) uniform coherent image2D _9;\nlayout(set = 0, binding = 2, r32f) uniform image2D _10;\n\nvoid main()\n{\n    uint _25;\n    uint _26;\n    bool _45;\n    for (;;)\n    {\n        _25 = uint(gl_FragCoord.x);\n        _26 = uint(gl_FragCoord.y);\n        vec4 _27 = imageLoad(_10, ivec2(uvec2(_25, _26)));\n        imageStore(_10, ivec2(uvec2(_25, _26)), vec4(_27.x + 1.0, _27.y + 2.0, _27.z + 3.0, _27.w + 4.0));\n        _45 = gl_FragCoord.x < 10.0;\n        SPIRV_Cross_beginInvocationInterlock();\n        if (_45)\n        {\n            vec4 _47 = imageLoad(_8, ivec2(uvec2(_25, _26)));\n            imageStore(_8, ivec2(uvec2(_25, _26)), vec4(_47.x + 1.0, _47.y + 2.0, _47.z + 3.0, _47.w + 4.0));\n            if (imageLoad(_10, ivec2(uvec2(_25, _26))).z > 100.0)\n            {\n                break;\n            }\n        }\n        else\n        {\n            vec4 _64 = imageLoad(_9, ivec2(uvec2(_25, _26)));\n            imageStore(_9, ivec2(uvec2(_25, _26)), vec4(_64.x + 1.0, _64.y + 2.0, _64.z + 3.0, _64.w + 4.0));\n        }\n        uint _76 = _25 ^ 1u;\n        uint _77 = _26 ^ 1u;\n        vec4 _78 = imageLoad(_10, ivec2(uvec2(_76, _77)));\n        imageStore(_10, ivec2(uvec2(_76, _77)), vec4(_78.x + 1.0, _78.y + 2.0, _78.z + 3.0, _78.w + 4.0));\n        break;\n    }\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %13 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 Coherent\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %13 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypeVector %5 4\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%17 = OpTypePointer Input %5\n%19 = OpTypeInt 32 0\n%20 = OpConstant %19 0\n%23 = OpConstant %19 1\n%28 = OpTypeVector %19 2\n%35 = OpConstant %5 1\n%37 = OpConstant %5 2\n%39 = OpConstant %5 3\n%41 = OpConstant %5 4\n%44 = OpTypeBool\n%46 = OpConstant %5 10\n%63 = OpConstant %5 100\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %90\n%90 = OpLabel\n%14 = OpLoad %6 %10\n%15 = OpLoad %6 %9\n%16 = OpLoad %6 %8\n%18 = OpAccessChain %17 %13 %20\n%21 = OpLoad %5 %18\n%22 = OpAccessChain %17 %13 %23\n%24 = OpLoad %5 %22\n%25 = OpConvertFToU %19 %21\n%26 = OpConvertFToU %19 %24\n%29 = OpCompositeConstruct %28 %25 %26\n%27 = OpImageRead %11 %14 %29 None\n%30 = OpCompositeExtract %5 %27 0\n%31 = OpCompositeExtract %5 %27 1\n%32 = OpCompositeExtract %5 %27 2\n%33 = OpCompositeExtract %5 %27 3\n%34 = OpFAdd %5 %30 %35\n%36 = OpFAdd %5 %31 %37\n%38 = OpFAdd %5 %32 %39\n%40 = OpFAdd %5 %33 %41\n%42 = OpCompositeConstruct %28 %25 %26\n%43 = OpCompositeConstruct %11 %34 %36 %38 %40\nOpImageWrite %14 %42 %43\n%45 = OpFOrdLessThan %44 %21 %46\nOpBeginInvocationInterlockEXT\nOpLoopMerge %96 %97 None\nOpBranch %91\n%91 = OpLabel\nOpSelectionMerge %95 None\nOpBranchConditional %45 %93 %92\n%93 = OpLabel\n%48 = OpCompositeConstruct %28 %25 %26\n%47 = OpImageRead %11 %16 %48 None\n%49 = OpCompositeExtract %5 %47 0\n%50 = OpCompositeExtract %5 %47 1\n%51 = OpCompositeExtract %5 %47 2\n%52 = OpCompositeExtract %5 %47 3\n%53 = OpFAdd %5 %49 %35\n%54 = OpFAdd %5 %50 %37\n%55 = OpFAdd %5 %51 %39\n%56 = OpFAdd %5 %52 %41\n%57 = OpCompositeConstruct %28 %25 %26\n%58 = OpCompositeConstruct %11 %53 %54 %55 %56\nOpImageWrite %16 %57 %58\n%60 = OpCompositeConstruct %28 %25 %26\n%59 = OpImageRead %11 %14 %60 None\n%61 = OpCompositeExtract %5 %59 2\n%62 = OpFOrdGreaterThan %44 %61 %63\nOpSelectionMerge %94 None\nOpBranchConditional %62 %96 %94\n%94 = OpLabel\nOpBranch %95\n%92 = OpLabel\n%65 = OpCompositeConstruct %28 %25 %26\n%64 = OpImageRead %11 %15 %65 None\n%66 = OpCompositeExtract %5 %64 0\n%67 = OpCompositeExtract %5 %64 1\n%68 = OpCompositeExtract %5 %64 2\n%69 = OpCompositeExtract %5 %64 3\n%70 = OpFAdd %5 %66 %35\n%71 = OpFAdd %5 %67 %37\n%72 = OpFAdd %5 %68 %39\n%73 = OpFAdd %5 %69 %41\n%74 = OpCompositeConstruct %28 %25 %26\n%75 = OpCompositeConstruct %11 %70 %71 %72 %73\nOpImageWrite %15 %74 %75\nOpBranch %95\n%95 = OpLabel\n%76 = OpBitwiseXor %19 %25 %23\n%77 = OpBitwiseXor %19 %26 %23\n%79 = OpCompositeConstruct %28 %76 %77\n%78 = OpImageRead %11 %14 %79 None\n%80 = OpCompositeExtract %5 %78 0\n%81 = OpCompositeExtract %5 %78 1\n%82 = OpCompositeExtract %5 %78 2\n%83 = OpCompositeExtract %5 %78 3\n%84 = OpFAdd %5 %80 %35\n%85 = OpFAdd %5 %81 %37\n%86 = OpFAdd %5 %82 %39\n%87 = OpFAdd %5 %83 %41\n%88 = OpCompositeConstruct %28 %76 %77\n%89 = OpCompositeConstruct %11 %84 %85 %86 %87\nOpImageWrite %14 %88 %89\nOpBranch %96\n%97 = OpLabel\nOpBranch %90\n%96 = OpLabel\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-branch.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _8;\nlayout(set = 0, binding = 1, r32f) uniform coherent image2D _9;\nlayout(set = 0, binding = 2, r32f) uniform image2D _10;\n\nvoid main()\n{\n    uint _25 = uint(gl_FragCoord.x);\n    uint _26 = uint(gl_FragCoord.y);\n    vec4 _27 = imageLoad(_10, ivec2(uvec2(_25, _26)));\n    imageStore(_10, ivec2(uvec2(_25, _26)), vec4(_27.x + 1.0, _27.y + 2.0, _27.z + 3.0, _27.w + 4.0));\n    SPIRV_Cross_beginInvocationInterlock();\n    if (gl_FragCoord.x < 10.0)\n    {\n        vec4 _47 = imageLoad(_8, ivec2(uvec2(_25, _26)));\n        imageStore(_8, ivec2(uvec2(_25, _26)), vec4(_47.x + 1.0, _47.y + 2.0, _47.z + 3.0, _47.w + 4.0));\n    }\n    else\n    {\n        vec4 _59 = imageLoad(_9, ivec2(uvec2(_25, _26)));\n        imageStore(_9, ivec2(uvec2(_25, _26)), vec4(_59.x + 1.0, _59.y + 2.0, _59.z + 3.0, _59.w + 4.0));\n    }\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 76\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %13 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 1\nOpDecorate %9 Coherent\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 2\nOpDecorate %13 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpVariable %7 UniformConstant\n%11 = OpTypeVector %5 4\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%17 = OpTypePointer Input %5\n%19 = OpTypeInt 32 0\n%20 = OpConstant %19 0\n%23 = OpConstant %19 1\n%28 = OpTypeVector %19 2\n%35 = OpConstant %5 1\n%37 = OpConstant %5 2\n%39 = OpConstant %5 3\n%41 = OpConstant %5 4\n%44 = OpTypeBool\n%46 = OpConstant %5 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %71\n%71 = OpLabel\n%14 = OpLoad %6 %10\n%15 = OpLoad %6 %9\n%16 = OpLoad %6 %8\n%18 = OpAccessChain %17 %13 %20\n%21 = OpLoad %5 %18\n%22 = OpAccessChain %17 %13 %23\n%24 = OpLoad %5 %22\n%25 = OpConvertFToU %19 %21\n%26 = OpConvertFToU %19 %24\n%29 = OpCompositeConstruct %28 %25 %26\n%27 = OpImageRead %11 %14 %29 None\n%30 = OpCompositeExtract %5 %27 0\n%31 = OpCompositeExtract %5 %27 1\n%32 = OpCompositeExtract %5 %27 2\n%33 = OpCompositeExtract %5 %27 3\n%34 = OpFAdd %5 %30 %35\n%36 = OpFAdd %5 %31 %37\n%38 = OpFAdd %5 %32 %39\n%40 = OpFAdd %5 %33 %41\n%42 = OpCompositeConstruct %28 %25 %26\n%43 = OpCompositeConstruct %11 %34 %36 %38 %40\nOpImageWrite %14 %42 %43\n%45 = OpFOrdLessThan %44 %21 %46\nOpBeginInvocationInterlockEXT\nOpSelectionMerge %74 None\nOpBranchConditional %45 %73 %72\n%73 = OpLabel\n%48 = OpCompositeConstruct %28 %25 %26\n%47 = OpImageRead %11 %16 %48 None\n%49 = OpCompositeExtract %5 %47 0\n%50 = OpCompositeExtract %5 %47 1\n%51 = OpCompositeExtract %5 %47 2\n%52 = OpCompositeExtract %5 %47 3\n%53 = OpFAdd %5 %49 %35\n%54 = OpFAdd %5 %50 %37\n%55 = OpFAdd %5 %51 %39\n%56 = OpFAdd %5 %52 %41\n%57 = OpCompositeConstruct %28 %25 %26\n%58 = OpCompositeConstruct %11 %53 %54 %55 %56\nOpImageWrite %16 %57 %58\nOpBranch %74\n%72 = OpLabel\n%60 = OpCompositeConstruct %28 %25 %26\n%59 = OpImageRead %11 %15 %60 None\n%61 = OpCompositeExtract %5 %59 0\n%62 = OpCompositeExtract %5 %59 1\n%63 = OpCompositeExtract %5 %59 2\n%64 = OpCompositeExtract %5 %59 3\n%65 = OpFAdd %5 %61 %35\n%66 = OpFAdd %5 %62 %37\n%67 = OpFAdd %5 %63 %39\n%68 = OpFAdd %5 %64 %41\n%69 = OpCompositeConstruct %28 %25 %26\n%70 = OpCompositeConstruct %11 %65 %66 %67 %68\nOpImageWrite %15 %69 %70\nOpBranch %74\n%74 = OpLabel\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-buffer.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent imageBuffer _8;\n\nvoid main()\n{\n    uint _25 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _26 = imageLoad(_8, int(_25));\n    imageStore(_8, int(_25), vec4(_26.x + 1.0, _26.y + 2.0, _26.z + 3.0, _26.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %11 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%24 = OpConstant %15 1000\n%32 = OpConstant %5 1\n%34 = OpConstant %5 2\n%36 = OpConstant %5 3\n%38 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpConvertFToU %15 %17\n%22 = OpConvertFToU %15 %20\n%23 = OpIMul %15 %22 %24\n%25 = OpIAdd %15 %23 %21\nOpBeginInvocationInterlockEXT\n%26 = OpImageRead %9 %12 %25\n%27 = OpCompositeExtract %5 %26 0\n%28 = OpCompositeExtract %5 %26 1\n%29 = OpCompositeExtract %5 %26 2\n%30 = OpCompositeExtract %5 %26 3\n%31 = OpFAdd %5 %27 %32\n%33 = OpFAdd %5 %28 %34\n%35 = OpFAdd %5 %29 %36\n%37 = OpFAdd %5 %30 %38\n%39 = OpCompositeConstruct %9 %31 %33 %35 %37\nOpImageWrite %12 %25 %39\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-inloop-2.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _8;\nlayout(set = 0, binding = 2, r32f) uniform image2D _9;\n\nvoid main()\n{\n    uint _26 = uint(gl_FragCoord.x);\n    uint _27 = uint(gl_FragCoord.y);\n    vec4 _28 = imageLoad(_9, ivec2(uvec2(_26, _27)));\n    imageStore(_9, ivec2(uvec2(_26, _27)), vec4(_28.x + 1.0, _28.y + 2.0, _28.z + 3.0, _28.w + 4.0));\n    uint _45 = uint(gl_FragCoord.z);\n    SPIRV_Cross_beginInvocationInterlock();\n    if (!(_45 == 0u))\n    {\n        uint _48;\n        _48 = 0u;\n        for (;;)\n        {\n            vec4 _50 = imageLoad(_8, ivec2(uvec2(_26, _27)));\n            imageStore(_8, ivec2(uvec2(_26, _27)), vec4(_50.x + 1.0, _50.y + 2.0, _50.z + 3.0, _50.w + 4.0));\n            uint _49 = _48 + 1u;\n            if (_49 < _45)\n            {\n                _48 = _49;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 69\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 2\nOpDecorate %12 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%15 = OpTypePointer Input %5\n%17 = OpTypeInt 32 0\n%18 = OpConstant %17 0\n%21 = OpConstant %17 1\n%24 = OpConstant %17 2\n%29 = OpTypeVector %17 2\n%36 = OpConstant %5 1\n%38 = OpConstant %5 2\n%40 = OpConstant %5 3\n%42 = OpConstant %5 4\n%46 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %63\n%63 = OpLabel\n%13 = OpLoad %6 %9\n%14 = OpLoad %6 %8\n%16 = OpAccessChain %15 %12 %18\n%19 = OpLoad %5 %16\n%20 = OpAccessChain %15 %12 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %15 %12 %24\n%25 = OpLoad %5 %23\n%26 = OpConvertFToU %17 %19\n%27 = OpConvertFToU %17 %22\n%30 = OpCompositeConstruct %29 %26 %27\n%28 = OpImageRead %10 %13 %30 None\n%31 = OpCompositeExtract %5 %28 0\n%32 = OpCompositeExtract %5 %28 1\n%33 = OpCompositeExtract %5 %28 2\n%34 = OpCompositeExtract %5 %28 3\n%35 = OpFAdd %5 %31 %36\n%37 = OpFAdd %5 %32 %38\n%39 = OpFAdd %5 %33 %40\n%41 = OpFAdd %5 %34 %42\n%43 = OpCompositeConstruct %29 %26 %27\n%44 = OpCompositeConstruct %10 %35 %37 %39 %41\nOpImageWrite %13 %43 %44\n%45 = OpConvertFToU %17 %25\n%47 = OpIEqual %46 %45 %18\nOpBeginInvocationInterlockEXT\nOpSelectionMerge %67 None\nOpBranchConditional %47 %67 %64\n%64 = OpLabel\nOpBranch %65\n%65 = OpLabel\n%48 = OpPhi %17 %18 %64 %49 %65\n%51 = OpCompositeConstruct %29 %26 %27\n%50 = OpImageRead %10 %14 %51 None\n%52 = OpCompositeExtract %5 %50 0\n%53 = OpCompositeExtract %5 %50 1\n%54 = OpCompositeExtract %5 %50 2\n%55 = OpCompositeExtract %5 %50 3\n%56 = OpFAdd %5 %52 %36\n%57 = OpFAdd %5 %53 %38\n%58 = OpFAdd %5 %54 %40\n%59 = OpFAdd %5 %55 %42\n%60 = OpCompositeConstruct %29 %26 %27\n%61 = OpCompositeConstruct %10 %56 %57 %58 %59\nOpImageWrite %14 %60 %61\n%49 = OpIAdd %17 %48 %21\n%62 = OpULessThan %46 %49 %45\nOpLoopMerge %66 %65 None\nOpBranchConditional %62 %65 %66\n%66 = OpLabel\nOpBranch %67\n%67 = OpLabel\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-inloop.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _8;\nlayout(set = 0, binding = 2, r32f) uniform image2D _9;\n\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    uint _29 = uint(gl_FragCoord.x);\n    uint _30 = uint(gl_FragCoord.y);\n    float _28[8];\n    _28[0u] = 0.0;\n    _28[1u] = 1.0;\n    _28[2u] = 2.0;\n    _28[3u] = 3.0;\n    _28[4u] = 4.0;\n    _28[5u] = 5.0;\n    _28[6u] = 6.0;\n    _28[7u] = 7.0;\n    vec4 _54 = imageLoad(_9, ivec2(uvec2(_29, _30)));\n    imageStore(_9, ivec2(uvec2(_29, _30)), vec4(_54.x + 1.0, _54.y + 2.0, _54.z + 3.0, _54.w + 4.0));\n    SPIRV_Cross_beginInvocationInterlock();\n    uint _67;\n    _67 = 0u;\n    for (;;)\n    {\n        vec4 _69 = imageLoad(_8, ivec2(uvec2(_29, _30)));\n        imageStore(_8, ivec2(uvec2(_29, _30)), vec4(_69.x + 1.0, _69.y + 2.0, _69.z + 3.0, _69.w + 4.0));\n        _28[_67] = imageLoad(_8, ivec2(uvec2(_29, _30))).y;\n        uint _68 = _67 + 1u;\n        if (_68 == 4u)\n        {\n            break;\n        }\n        else\n        {\n            _67 = _68;\n        }\n    }\n    SPIRV_Cross_endInvocationInterlock();\n    SV_Target = _28[uint((1.0 / gl_FragCoord.w) * 7.0)];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 98\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12 %14\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %12 \"SV_Position\"\nOpName %14 \"SV_Target\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 2\nOpDecorate %12 BuiltIn FragCoord\nOpDecorate %14 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypePointer Output %5\n%14 = OpVariable %13 Output\n%17 = OpTypePointer Input %5\n%19 = OpTypeInt 32 0\n%20 = OpConstant %19 0\n%23 = OpConstant %19 1\n%25 = OpConstant %19 8\n%26 = OpTypeArray %5 %25\n%27 = OpTypePointer Function %26\n%31 = OpTypePointer Function %5\n%33 = OpConstant %5 0\n%35 = OpConstant %5 1\n%37 = OpConstant %19 2\n%38 = OpConstant %5 2\n%40 = OpConstant %19 3\n%41 = OpConstant %5 3\n%43 = OpConstant %19 4\n%44 = OpConstant %5 4\n%46 = OpConstant %19 5\n%47 = OpConstant %5 5\n%49 = OpConstant %19 6\n%50 = OpConstant %5 6\n%52 = OpConstant %19 7\n%53 = OpConstant %5 7\n%55 = OpTypeVector %19 2\n%85 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%28 = OpVariable %27 Function\nOpBranch %94\n%94 = OpLabel\n%15 = OpLoad %6 %9\n%16 = OpLoad %6 %8\n%18 = OpAccessChain %17 %12 %20\n%21 = OpLoad %5 %18\n%22 = OpAccessChain %17 %12 %23\n%24 = OpLoad %5 %22\n%29 = OpConvertFToU %19 %21\n%30 = OpConvertFToU %19 %24\n%32 = OpInBoundsAccessChain %31 %28 %20\nOpStore %32 %33\n%34 = OpInBoundsAccessChain %31 %28 %23\nOpStore %34 %35\n%36 = OpInBoundsAccessChain %31 %28 %37\nOpStore %36 %38\n%39 = OpInBoundsAccessChain %31 %28 %40\nOpStore %39 %41\n%42 = OpInBoundsAccessChain %31 %28 %43\nOpStore %42 %44\n%45 = OpInBoundsAccessChain %31 %28 %46\nOpStore %45 %47\n%48 = OpInBoundsAccessChain %31 %28 %49\nOpStore %48 %50\n%51 = OpInBoundsAccessChain %31 %28 %52\nOpStore %51 %53\n%56 = OpCompositeConstruct %55 %29 %30\n%54 = OpImageRead %10 %15 %56 None\n%57 = OpCompositeExtract %5 %54 0\n%58 = OpCompositeExtract %5 %54 1\n%59 = OpCompositeExtract %5 %54 2\n%60 = OpCompositeExtract %5 %54 3\n%61 = OpFAdd %5 %57 %35\n%62 = OpFAdd %5 %58 %38\n%63 = OpFAdd %5 %59 %41\n%64 = OpFAdd %5 %60 %44\n%65 = OpCompositeConstruct %55 %29 %30\n%66 = OpCompositeConstruct %10 %61 %62 %63 %64\nOpImageWrite %15 %65 %66\nOpBeginInvocationInterlockEXT\nOpBranch %95\n%95 = OpLabel\n%67 = OpPhi %19 %20 %94 %68 %95\n%70 = OpCompositeConstruct %55 %29 %30\n%69 = OpImageRead %10 %16 %70 None\n%71 = OpCompositeExtract %5 %69 0\n%72 = OpCompositeExtract %5 %69 1\n%73 = OpCompositeExtract %5 %69 2\n%74 = OpCompositeExtract %5 %69 3\n%75 = OpFAdd %5 %71 %35\n%76 = OpFAdd %5 %72 %38\n%77 = OpFAdd %5 %73 %41\n%78 = OpFAdd %5 %74 %44\n%79 = OpCompositeConstruct %55 %29 %30\n%80 = OpCompositeConstruct %10 %75 %76 %77 %78\nOpImageWrite %16 %79 %80\n%82 = OpCompositeConstruct %55 %29 %30\n%81 = OpImageRead %10 %16 %82 None\n%83 = OpCompositeExtract %5 %81 1\n%84 = OpInBoundsAccessChain %31 %28 %67\nOpStore %84 %83\n%68 = OpIAdd %19 %67 %23\n%86 = OpIEqual %85 %68 %43\nOpLoopMerge %96 %95 None\nOpBranchConditional %86 %96 %95\n%96 = OpLabel\nOpEndInvocationInterlockEXT\n%87 = OpAccessChain %17 %12 %40\n%88 = OpLoad %5 %87\n%89 = OpFDiv %5 %35 %88\n%90 = OpFMul %5 %89 %53\n%91 = OpConvertFToU %19 %90\n%92 = OpInBoundsAccessChain %31 %28 %91\n%93 = OpLoad %5 %92\nOpStore %14 %93\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-per-sample.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(sample_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _9[];\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _12[];\nlayout(set = 0, binding = 0, r32f) uniform coherent imageBuffer _17[];\nlayout(set = 0, binding = 0, r32f) uniform coherent image1D _21[];\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _25[];\n\nvoid main()\n{\n    uint _41 = uint(gl_SampleID) + uint(gl_FragCoord.x);\n    uint _42 = uint(gl_FragCoord.y) + uint(gl_SampleID);\n    uint _48 = (_42 * 1000u) + _41;\n    uint _51 = _48 * 4u;\n    SPIRV_Cross_beginInvocationInterlock();\n    uvec4 _53 = imageLoad(_9[0u], int(_51));\n    uvec4 _55 = imageLoad(_9[0u], int(_51 + 1u));\n    uvec4 _58 = imageLoad(_9[0u], int(_51 + 2u));\n    uvec4 _62 = imageLoad(_9[0u], int(_51 + 3u));\n    uvec4 _66 = uvec4(_53.x, _55.x, _58.x, _62.x);\n    uint _75 = _48 * 4u;\n    imageStore(_9[0u], int(_75), uvec4(_66.x + 1u));\n    imageStore(_9[0u], int(_75 + 1u), uvec4(_66.y + 2u));\n    imageStore(_9[0u], int(_75 + 2u), uvec4(_66.z + 3u));\n    imageStore(_9[0u], int(_75 + 3u), uvec4(_66.w + 4u));\n    uint _85 = _48 * 4u;\n    uvec4 _86 = imageLoad(_12[1u], int(_85));\n    uvec4 _88 = imageLoad(_12[1u], int(_85 + 1u));\n    uvec4 _91 = imageLoad(_12[1u], int(_85 + 2u));\n    uvec4 _94 = imageLoad(_12[1u], int(_85 + 3u));\n    vec4 _98 = uintBitsToFloat(uvec4(_86.x, _88.x, _91.x, _94.x));\n    uint _111 = _48 * 4u;\n    imageStore(_12[1u], int(_111), uvec4(floatBitsToUint(_98.x + 1.0)));\n    imageStore(_12[1u], int(_111 + 1u), uvec4(floatBitsToUint(_98.y + 2.0)));\n    imageStore(_12[1u], int(_111 + 2u), uvec4(floatBitsToUint(_98.z + 3.0)));\n    imageStore(_12[1u], int(_111 + 3u), uvec4(floatBitsToUint(_98.w + 4.0)));\n    vec4 _126 = imageLoad(_17[2u], int(_48));\n    imageStore(_17[2u], int(_48), vec4(_126.x + 1.0, _126.y + 2.0, _126.z + 3.0, _126.w + 4.0));\n    vec4 _139 = imageLoad(_21[3u], int(_48));\n    imageStore(_21[3u], int(_48), vec4(_139.x + 1.0, _139.y + 2.0, _139.z + 3.0, _139.w + 4.0));\n    vec4 _152 = imageLoad(_25[4u], ivec2(uvec2(_41, _42)));\n    imageStore(_25[4u], ivec2(uvec2(_41, _42)), vec4(_152.x + 1.0, _152.y + 2.0, _152.z + 3.0, _152.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 167\n; Schema: 0\nOpCapability Shader\nOpCapability SampleRateShading\nOpCapability Image1D\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability FragmentShaderSampleInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %28 %30\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 SampleInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %28 \"SV_Position\"\nOpName %30 \"SV_SampleIndex\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 Coherent\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 Coherent\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 Coherent\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 Coherent\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 Coherent\nOpDecorate %28 BuiltIn FragCoord\nOpDecorate %30 BuiltIn SampleId\nOpDecorate %30 Flat\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeRuntimeArray %6\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeImage %13 Buffer 0 0 0 2 R32f\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %13 1D 0 0 0 2 R32f\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %13 2D 0 0 0 2 R32f\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %13 4\n%27 = OpTypePointer Input %26\n%28 = OpVariable %27 Input\n%29 = OpTypePointer Input %5\n%30 = OpVariable %29 Input\n%31 = OpTypePointer Input %13\n%33 = OpConstant %5 0\n%36 = OpConstant %5 1\n%43 = OpTypePointer UniformConstant %6\n%47 = OpConstant %5 1000\n%50 = OpConstant %5 4\n%52 = OpTypeVector %5 4\n%60 = OpConstant %5 2\n%64 = OpConstant %5 3\n%104 = OpConstant %13 1\n%106 = OpConstant %13 2\n%108 = OpConstant %13 3\n%110 = OpConstant %13 4\n%123 = OpTypePointer UniformConstant %14\n%136 = OpTypePointer UniformConstant %18\n%149 = OpTypePointer UniformConstant %22\n%153 = OpTypeVector %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %165\n%165 = OpLabel\n%32 = OpAccessChain %31 %28 %33\n%34 = OpLoad %13 %32\n%35 = OpAccessChain %31 %28 %36\n%37 = OpLoad %13 %35\n%38 = OpLoad %5 %30\n%39 = OpConvertFToU %5 %34\n%40 = OpConvertFToU %5 %37\n%41 = OpIAdd %5 %38 %39\n%42 = OpIAdd %5 %40 %38\n%44 = OpAccessChain %43 %9 %33\n%45 = OpLoad %6 %44\n%46 = OpIMul %5 %42 %47\n%48 = OpIAdd %5 %46 %41\n%49 = OpShiftLeftLogical %5 %48 %50\n%51 = OpIMul %5 %48 %50\nOpBeginInvocationInterlockEXT\n%53 = OpImageRead %52 %45 %51\n%54 = OpCompositeExtract %5 %53 0\n%56 = OpIAdd %5 %51 %36\n%55 = OpImageRead %52 %45 %56\n%57 = OpCompositeExtract %5 %55 0\n%59 = OpIAdd %5 %51 %60\n%58 = OpImageRead %52 %45 %59\n%61 = OpCompositeExtract %5 %58 0\n%63 = OpIAdd %5 %51 %64\n%62 = OpImageRead %52 %45 %63\n%65 = OpCompositeExtract %5 %62 0\n%66 = OpCompositeConstruct %52 %54 %57 %61 %65\n%67 = OpCompositeExtract %5 %66 0\n%68 = OpCompositeExtract %5 %66 1\n%69 = OpCompositeExtract %5 %66 2\n%70 = OpCompositeExtract %5 %66 3\n%71 = OpIAdd %5 %67 %36\n%72 = OpIAdd %5 %68 %60\n%73 = OpIAdd %5 %69 %64\n%74 = OpIAdd %5 %70 %50\n%75 = OpIMul %5 %48 %50\n%76 = OpCompositeConstruct %52 %71 %71 %71 %71\nOpImageWrite %45 %75 %76\n%77 = OpCompositeConstruct %52 %72 %72 %72 %72\n%78 = OpIAdd %5 %75 %36\nOpImageWrite %45 %78 %77\n%79 = OpCompositeConstruct %52 %73 %73 %73 %73\n%80 = OpIAdd %5 %75 %60\nOpImageWrite %45 %80 %79\n%81 = OpCompositeConstruct %52 %74 %74 %74 %74\n%82 = OpIAdd %5 %75 %64\nOpImageWrite %45 %82 %81\n%83 = OpAccessChain %43 %12 %36\n%84 = OpLoad %6 %83\n%85 = OpIMul %5 %48 %50\n%86 = OpImageRead %52 %84 %85\n%87 = OpCompositeExtract %5 %86 0\n%89 = OpIAdd %5 %85 %36\n%88 = OpImageRead %52 %84 %89\n%90 = OpCompositeExtract %5 %88 0\n%92 = OpIAdd %5 %85 %60\n%91 = OpImageRead %52 %84 %92\n%93 = OpCompositeExtract %5 %91 0\n%95 = OpIAdd %5 %85 %64\n%94 = OpImageRead %52 %84 %95\n%96 = OpCompositeExtract %5 %94 0\n%97 = OpCompositeConstruct %52 %87 %90 %93 %96\n%98 = OpBitcast %26 %97\n%99 = OpCompositeExtract %13 %98 0\n%100 = OpCompositeExtract %13 %98 1\n%101 = OpCompositeExtract %13 %98 2\n%102 = OpCompositeExtract %13 %98 3\n%103 = OpFAdd %13 %99 %104\n%105 = OpFAdd %13 %100 %106\n%107 = OpFAdd %13 %101 %108\n%109 = OpFAdd %13 %102 %110\n%111 = OpIMul %5 %48 %50\n%112 = OpBitcast %5 %103\n%113 = OpBitcast %5 %105\n%114 = OpBitcast %5 %107\n%115 = OpBitcast %5 %109\n%116 = OpCompositeConstruct %52 %112 %112 %112 %112\nOpImageWrite %84 %111 %116\n%117 = OpCompositeConstruct %52 %113 %113 %113 %113\n%118 = OpIAdd %5 %111 %36\nOpImageWrite %84 %118 %117\n%119 = OpCompositeConstruct %52 %114 %114 %114 %114\n%120 = OpIAdd %5 %111 %60\nOpImageWrite %84 %120 %119\n%121 = OpCompositeConstruct %52 %115 %115 %115 %115\n%122 = OpIAdd %5 %111 %64\nOpImageWrite %84 %122 %121\n%124 = OpAccessChain %123 %17 %60\n%125 = OpLoad %14 %124\n%126 = OpImageRead %26 %125 %48\n%127 = OpCompositeExtract %13 %126 0\n%128 = OpCompositeExtract %13 %126 1\n%129 = OpCompositeExtract %13 %126 2\n%130 = OpCompositeExtract %13 %126 3\n%131 = OpFAdd %13 %127 %104\n%132 = OpFAdd %13 %128 %106\n%133 = OpFAdd %13 %129 %108\n%134 = OpFAdd %13 %130 %110\n%135 = OpCompositeConstruct %26 %131 %132 %133 %134\nOpImageWrite %125 %48 %135\n%137 = OpAccessChain %136 %21 %64\n%138 = OpLoad %18 %137\n%139 = OpImageRead %26 %138 %48 None\n%140 = OpCompositeExtract %13 %139 0\n%141 = OpCompositeExtract %13 %139 1\n%142 = OpCompositeExtract %13 %139 2\n%143 = OpCompositeExtract %13 %139 3\n%144 = OpFAdd %13 %140 %104\n%145 = OpFAdd %13 %141 %106\n%146 = OpFAdd %13 %142 %108\n%147 = OpFAdd %13 %143 %110\n%148 = OpCompositeConstruct %26 %144 %145 %146 %147\nOpImageWrite %138 %48 %148\n%150 = OpAccessChain %149 %25 %50\n%151 = OpLoad %22 %150\n%154 = OpCompositeConstruct %153 %41 %42\n%152 = OpImageRead %26 %151 %154 None\n%155 = OpCompositeExtract %13 %152 0\n%156 = OpCompositeExtract %13 %152 1\n%157 = OpCompositeExtract %13 %152 2\n%158 = OpCompositeExtract %13 %152 3\n%159 = OpFAdd %13 %155 %104\n%160 = OpFAdd %13 %156 %106\n%161 = OpFAdd %13 %157 %108\n%162 = OpFAdd %13 %158 %110\n%163 = OpCompositeConstruct %153 %41 %42\n%164 = OpCompositeConstruct %26 %159 %160 %161 %162\nOpImageWrite %151 %163 %164\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-postloop.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _8;\nlayout(set = 0, binding = 2, r32f) uniform image2D _9;\n\nvoid main()\n{\n    uint _23 = uint(gl_FragCoord.x);\n    uint _24 = uint(gl_FragCoord.y);\n    uint _25;\n    _25 = 0u;\n    for (;;)\n    {\n        vec4 _27 = imageLoad(_9, ivec2(uvec2(_23, _24)));\n        imageStore(_9, ivec2(uvec2(_23, _24)), vec4(_27.x + 1.0, _27.y + 2.0, _27.z + 3.0, _27.w + 4.0));\n        uint _26 = _25 + 1u;\n        if (_26 == 4u)\n        {\n            break;\n        }\n        else\n        {\n            _25 = _26;\n        }\n    }\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _47 = imageLoad(_8, ivec2(uvec2(_23, _24)));\n    imageStore(_8, ivec2(uvec2(_23, _24)), vec4(_47.x + 1.0, _47.y + 2.0, _47.z + 3.0, _47.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 63\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 2\nOpDecorate %12 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpVariable %7 UniformConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%15 = OpTypePointer Input %5\n%17 = OpTypeInt 32 0\n%18 = OpConstant %17 0\n%21 = OpConstant %17 1\n%28 = OpTypeVector %17 2\n%35 = OpConstant %5 1\n%37 = OpConstant %5 2\n%39 = OpConstant %5 3\n%41 = OpConstant %5 4\n%44 = OpTypeBool\n%46 = OpConstant %17 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%13 = OpLoad %6 %9\n%14 = OpLoad %6 %8\n%16 = OpAccessChain %15 %12 %18\n%19 = OpLoad %5 %16\n%20 = OpAccessChain %15 %12 %21\n%22 = OpLoad %5 %20\n%23 = OpConvertFToU %17 %19\n%24 = OpConvertFToU %17 %22\nOpBranch %60\n%60 = OpLabel\n%25 = OpPhi %17 %18 %59 %26 %60\n%29 = OpCompositeConstruct %28 %23 %24\n%27 = OpImageRead %10 %13 %29 None\n%30 = OpCompositeExtract %5 %27 0\n%31 = OpCompositeExtract %5 %27 1\n%32 = OpCompositeExtract %5 %27 2\n%33 = OpCompositeExtract %5 %27 3\n%34 = OpFAdd %5 %30 %35\n%36 = OpFAdd %5 %31 %37\n%38 = OpFAdd %5 %32 %39\n%40 = OpFAdd %5 %33 %41\n%42 = OpCompositeConstruct %28 %23 %24\n%43 = OpCompositeConstruct %10 %34 %36 %38 %40\nOpImageWrite %13 %42 %43\n%26 = OpIAdd %17 %25 %21\n%45 = OpIEqual %44 %26 %46\nOpLoopMerge %61 %60 None\nOpBranchConditional %45 %61 %60\n%61 = OpLabel\n%48 = OpCompositeConstruct %28 %23 %24\nOpBeginInvocationInterlockEXT\n%47 = OpImageRead %10 %14 %48 None\n%49 = OpCompositeExtract %5 %47 0\n%50 = OpCompositeExtract %5 %47 1\n%51 = OpCompositeExtract %5 %47 2\n%52 = OpCompositeExtract %5 %47 3\n%53 = OpFAdd %5 %49 %35\n%54 = OpFAdd %5 %50 %37\n%55 = OpFAdd %5 %51 %39\n%56 = OpFAdd %5 %52 %41\n%57 = OpCompositeConstruct %28 %23 %24\n%58 = OpCompositeConstruct %10 %53 %54 %55 %56\nOpImageWrite %14 %57 %58\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-structured.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 4, binding = 0, r32ui) uniform coherent uimageBuffer _12[];\n\nvoid main()\n{\n    uint _35 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    uint _36 = _35 * 4u;\n    SPIRV_Cross_beginInvocationInterlock();\n    uvec4 _38 = imageLoad(_12[registers._m4], int(_36));\n    uvec4 _40 = imageLoad(_12[registers._m4], int(_36 + 1u));\n    uvec4 _43 = imageLoad(_12[registers._m4], int(_36 + 2u));\n    uvec4 _47 = imageLoad(_12[registers._m4], int(_36 + 3u));\n    vec4 _52 = uintBitsToFloat(uvec4(_38.x, _40.x, _43.x, _47.x));\n    uint _65 = _35 * 4u;\n    imageStore(_12[registers._m4], int(_65), uvec4(floatBitsToUint(_52.x + 1.0)));\n    imageStore(_12[registers._m4], int(_65 + 1u), uvec4(floatBitsToUint(_52.y + 2.0)));\n    imageStore(_12[registers._m4], int(_65 + 2u), uvec4(floatBitsToUint(_52.z + 3.0)));\n    imageStore(_12[registers._m4], int(_65 + 3u), uvec4(floatBitsToUint(_52.w + 4.0)));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %12 DescriptorSet 4\nOpDecorate %12 Binding 0\nOpDecorate %12 Coherent\nOpDecorate %16 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeVector %13 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer UniformConstant %9\n%19 = OpTypePointer PushConstant %5\n%21 = OpConstant %5 4\n%24 = OpTypePointer Input %13\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%34 = OpConstant %5 1000\n%37 = OpTypeVector %5 4\n%45 = OpConstant %5 2\n%49 = OpConstant %5 3\n%58 = OpConstant %13 1\n%60 = OpConstant %13 2\n%62 = OpConstant %13 3\n%64 = OpConstant %13 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %77\n%77 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%18 = OpAccessChain %17 %12 %22\n%23 = OpLoad %9 %18\n%25 = OpAccessChain %24 %16 %26\n%27 = OpLoad %13 %25\n%28 = OpAccessChain %24 %16 %29\n%30 = OpLoad %13 %28\n%31 = OpConvertFToU %5 %27\n%32 = OpConvertFToU %5 %30\n%33 = OpIMul %5 %32 %34\n%35 = OpIAdd %5 %33 %31\n%36 = OpIMul %5 %35 %21\nOpBeginInvocationInterlockEXT\n%38 = OpImageRead %37 %23 %36\n%39 = OpCompositeExtract %5 %38 0\n%41 = OpIAdd %5 %36 %29\n%40 = OpImageRead %37 %23 %41\n%42 = OpCompositeExtract %5 %40 0\n%44 = OpIAdd %5 %36 %45\n%43 = OpImageRead %37 %23 %44\n%46 = OpCompositeExtract %5 %43 0\n%48 = OpIAdd %5 %36 %49\n%47 = OpImageRead %37 %23 %48\n%50 = OpCompositeExtract %5 %47 0\n%51 = OpCompositeConstruct %37 %39 %42 %46 %50\n%52 = OpBitcast %14 %51\n%53 = OpCompositeExtract %13 %52 0\n%54 = OpCompositeExtract %13 %52 1\n%55 = OpCompositeExtract %13 %52 2\n%56 = OpCompositeExtract %13 %52 3\n%57 = OpFAdd %13 %53 %58\n%59 = OpFAdd %13 %54 %60\n%61 = OpFAdd %13 %55 %62\n%63 = OpFAdd %13 %56 %64\n%65 = OpIMul %5 %35 %21\n%66 = OpBitcast %5 %57\n%67 = OpBitcast %5 %59\n%68 = OpBitcast %5 %61\n%69 = OpBitcast %5 %63\n%70 = OpCompositeConstruct %37 %66 %66 %66 %66\nOpImageWrite %23 %65 %70\n%71 = OpCompositeConstruct %37 %67 %67 %67 %67\n%72 = OpIAdd %5 %65 %29\nOpImageWrite %23 %72 %71\n%73 = OpCompositeConstruct %37 %68 %68 %68 %68\n%74 = OpIAdd %5 %65 %45\nOpImageWrite %23 %74 %73\n%75 = OpCompositeConstruct %37 %69 %69 %69 %69\n%76 = OpIAdd %5 %65 %49\nOpImageWrite %23 %76 %75\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-structured.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _8;\n\nvoid main()\n{\n    uint _25 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    uint _26 = _25 * 4u;\n    SPIRV_Cross_beginInvocationInterlock();\n    uvec4 _29 = imageLoad(_8, int(_26));\n    uvec4 _31 = imageLoad(_8, int(_26 + 1u));\n    uvec4 _34 = imageLoad(_8, int(_26 + 2u));\n    uvec4 _38 = imageLoad(_8, int(_26 + 3u));\n    vec4 _43 = uintBitsToFloat(uvec4(_29.x, _31.x, _34.x, _38.x));\n    uint _56 = _25 * 4u;\n    imageStore(_8, int(_56), uvec4(floatBitsToUint(_43.x + 1.0)));\n    imageStore(_8, int(_56 + 1u), uvec4(floatBitsToUint(_43.y + 2.0)));\n    imageStore(_8, int(_56 + 2u), uvec4(floatBitsToUint(_43.z + 3.0)));\n    imageStore(_8, int(_56 + 3u), uvec4(floatBitsToUint(_43.w + 4.0)));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 70\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %12 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%14 = OpTypePointer Input %9\n%16 = OpConstant %5 0\n%19 = OpConstant %5 1\n%24 = OpConstant %5 1000\n%27 = OpConstant %5 4\n%28 = OpTypeVector %5 4\n%36 = OpConstant %5 2\n%40 = OpConstant %5 3\n%49 = OpConstant %9 1\n%51 = OpConstant %9 2\n%53 = OpConstant %9 3\n%55 = OpConstant %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %68\n%68 = OpLabel\n%13 = OpLoad %6 %8\n%15 = OpAccessChain %14 %12 %16\n%17 = OpLoad %9 %15\n%18 = OpAccessChain %14 %12 %19\n%20 = OpLoad %9 %18\n%21 = OpConvertFToU %5 %17\n%22 = OpConvertFToU %5 %20\n%23 = OpIMul %5 %22 %24\n%25 = OpIAdd %5 %23 %21\n%26 = OpIMul %5 %25 %27\nOpBeginInvocationInterlockEXT\n%29 = OpImageRead %28 %13 %26\n%30 = OpCompositeExtract %5 %29 0\n%32 = OpIAdd %5 %26 %19\n%31 = OpImageRead %28 %13 %32\n%33 = OpCompositeExtract %5 %31 0\n%35 = OpIAdd %5 %26 %36\n%34 = OpImageRead %28 %13 %35\n%37 = OpCompositeExtract %5 %34 0\n%39 = OpIAdd %5 %26 %40\n%38 = OpImageRead %28 %13 %39\n%41 = OpCompositeExtract %5 %38 0\n%42 = OpCompositeConstruct %28 %30 %33 %37 %41\n%43 = OpBitcast %10 %42\n%44 = OpCompositeExtract %9 %43 0\n%45 = OpCompositeExtract %9 %43 1\n%46 = OpCompositeExtract %9 %43 2\n%47 = OpCompositeExtract %9 %43 3\n%48 = OpFAdd %9 %44 %49\n%50 = OpFAdd %9 %45 %51\n%52 = OpFAdd %9 %46 %53\n%54 = OpFAdd %9 %47 %55\n%56 = OpIMul %5 %25 %27\n%57 = OpBitcast %5 %48\n%58 = OpBitcast %5 %50\n%59 = OpBitcast %5 %52\n%60 = OpBitcast %5 %54\n%61 = OpCompositeConstruct %28 %57 %57 %57 %57\nOpImageWrite %13 %56 %61\n%62 = OpCompositeConstruct %28 %58 %58 %58 %58\n%63 = OpIAdd %5 %56 %19\nOpImageWrite %13 %63 %62\n%64 = OpCompositeConstruct %28 %59 %59 %59 %59\n%65 = OpIAdd %5 %56 %36\nOpImageWrite %13 %65 %64\n%66 = OpCompositeConstruct %28 %60 %60 %60 %60\n%67 = OpIAdd %5 %56 %40\nOpImageWrite %13 %67 %66\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-structured.ssbo.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 4, binding = 0, std430) coherent buffer SSBO\n{\n    uvec4 _m0[];\n} _14[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _36 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _40 = uintBitsToFloat(_14[registers._m4]._m0[_36]);\n    _14[registers._m4]._m0[_36] = uvec4(floatBitsToUint(_40.x + 1.0), floatBitsToUint(_40.y + 2.0), floatBitsToUint(_40.z + 3.0), floatBitsToUint(_40.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %18\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO\"\nOpName %18 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 16\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %14 DescriptorSet 4\nOpDecorate %14 Binding 0\nOpDecorate %14 Coherent\nOpDecorate %18 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeFloat 32\n%16 = OpTypeVector %15 4\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer StorageBuffer %11\n%21 = OpTypePointer PushConstant %5\n%23 = OpConstant %5 4\n%25 = OpTypePointer Input %15\n%27 = OpConstant %5 0\n%30 = OpConstant %5 1\n%35 = OpConstant %5 1000\n%37 = OpTypePointer StorageBuffer %9\n%46 = OpConstant %15 1\n%48 = OpConstant %15 2\n%50 = OpConstant %15 3\n%52 = OpConstant %15 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %59\n%59 = OpLabel\n%22 = OpAccessChain %21 %8 %23\n%24 = OpLoad %5 %22\n%20 = OpAccessChain %19 %14 %24\n%26 = OpAccessChain %25 %18 %27\n%28 = OpLoad %15 %26\n%29 = OpAccessChain %25 %18 %30\n%31 = OpLoad %15 %29\n%32 = OpConvertFToU %5 %28\n%33 = OpConvertFToU %5 %31\n%34 = OpIMul %5 %33 %35\n%36 = OpIAdd %5 %34 %32\n%38 = OpAccessChain %37 %20 %27 %36\nOpBeginInvocationInterlockEXT\n%39 = OpLoad %9 %38\n%40 = OpBitcast %16 %39\n%41 = OpCompositeExtract %15 %40 0\n%42 = OpCompositeExtract %15 %40 1\n%43 = OpCompositeExtract %15 %40 2\n%44 = OpCompositeExtract %15 %40 3\n%45 = OpFAdd %15 %41 %46\n%47 = OpFAdd %15 %42 %48\n%49 = OpFAdd %15 %43 %50\n%51 = OpFAdd %15 %44 %52\n%53 = OpBitcast %5 %45\n%54 = OpBitcast %5 %47\n%55 = OpBitcast %5 %49\n%56 = OpBitcast %5 %51\n%57 = OpCompositeConstruct %9 %53 %54 %55 %56\n%58 = OpAccessChain %37 %20 %27 %36\nOpStore %58 %57\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-structured.ssbo.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, std430) coherent buffer SSBO\n{\n    uvec4 _m0[];\n} _10;\n\nvoid main()\n{\n    uint _26 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _30 = uintBitsToFloat(_10._m0[_26]);\n    _10._m0[_26] = uvec4(floatBitsToUint(_30.x + 1.0), floatBitsToUint(_30.y + 2.0), floatBitsToUint(_30.z + 3.0), floatBitsToUint(_30.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 51\n; Schema: 0\nOpCapability Shader\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %14 \"SV_Position\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 Coherent\nOpDecorate %14 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeFloat 32\n%12 = OpTypeVector %11 4\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Input %11\n%17 = OpConstant %5 0\n%20 = OpConstant %5 1\n%25 = OpConstant %5 1000\n%27 = OpTypePointer StorageBuffer %6\n%36 = OpConstant %11 1\n%38 = OpConstant %11 2\n%40 = OpConstant %11 3\n%42 = OpConstant %11 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %49\n%49 = OpLabel\n%16 = OpAccessChain %15 %14 %17\n%18 = OpLoad %11 %16\n%19 = OpAccessChain %15 %14 %20\n%21 = OpLoad %11 %19\n%22 = OpConvertFToU %5 %18\n%23 = OpConvertFToU %5 %21\n%24 = OpIMul %5 %23 %25\n%26 = OpIAdd %5 %24 %22\n%28 = OpAccessChain %27 %10 %17 %26\nOpBeginInvocationInterlockEXT\n%29 = OpLoad %6 %28\n%30 = OpBitcast %12 %29\n%31 = OpCompositeExtract %11 %30 0\n%32 = OpCompositeExtract %11 %30 1\n%33 = OpCompositeExtract %11 %30 2\n%34 = OpCompositeExtract %11 %30 3\n%35 = OpFAdd %11 %31 %36\n%37 = OpFAdd %11 %32 %38\n%39 = OpFAdd %11 %33 %40\n%41 = OpFAdd %11 %34 %42\n%43 = OpBitcast %5 %35\n%44 = OpBitcast %5 %37\n%45 = OpBitcast %5 %39\n%46 = OpBitcast %5 %41\n%47 = OpCompositeConstruct %6 %43 %44 %45 %46\n%48 = OpAccessChain %27 %10 %17 %26\nOpStore %48 %47\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-structured.ssbo.root-descriptor.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#extension GL_EXT_buffer_reference_uvec2 : require\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4CoherentArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) coherent buffer PhysicalPointerFloat4CoherentArray\n{\n    vec4 value[];\n};\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    uint _29 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    PhysicalPointerFloat4CoherentArray _33 = PhysicalPointerFloat4CoherentArray(registers._m2);\n    SPIRV_Cross_beginInvocationInterlock();\n    PhysicalPointerFloat4CoherentArray(registers._m2).value[_29] = vec4(_33.value[_29].x + 1.0, _33.value[_29].y + 2.0, _33.value[_29].z + 3.0, _33.value[_29].w + 4.0);\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\nOpCapability Shader\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %13 \"SV_Position\"\nOpName %31 \"PhysicalPointerFloat4CoherentArray\"\nOpMemberName %31 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %13 BuiltIn FragCoord\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpMemberDecorate %31 0 Coherent\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeVector %10 4\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%14 = OpTypePointer PushConstant %6\n%16 = OpConstant %5 2\n%18 = OpTypePointer Input %10\n%20 = OpConstant %5 0\n%23 = OpConstant %5 1\n%28 = OpConstant %5 1000\n%30 = OpTypeRuntimeArray %11\n%31 = OpTypeStruct %30\n%32 = OpTypePointer PhysicalStorageBuffer %31\n%34 = OpTypePointer PhysicalStorageBuffer %11\n%42 = OpConstant %10 1\n%44 = OpConstant %10 2\n%46 = OpConstant %10 3\n%48 = OpConstant %10 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %52\n%52 = OpLabel\n%15 = OpAccessChain %14 %9 %16\n%17 = OpLoad %6 %15\n%19 = OpAccessChain %18 %13 %20\n%21 = OpLoad %10 %19\n%22 = OpAccessChain %18 %13 %23\n%24 = OpLoad %10 %22\n%25 = OpConvertFToU %5 %21\n%26 = OpConvertFToU %5 %24\n%27 = OpIMul %5 %26 %28\n%29 = OpIAdd %5 %27 %25\n%33 = OpBitcast %32 %17\n%35 = OpInBoundsAccessChain %34 %33 %20 %29\nOpBeginInvocationInterlockEXT\n%36 = OpLoad %11 %35 Aligned 16\n%37 = OpCompositeExtract %10 %36 0\n%38 = OpCompositeExtract %10 %36 1\n%39 = OpCompositeExtract %10 %36 2\n%40 = OpCompositeExtract %10 %36 3\n%41 = OpFAdd %10 %37 %42\n%43 = OpFAdd %10 %38 %44\n%45 = OpFAdd %10 %39 %46\n%47 = OpFAdd %10 %40 %48\n%49 = OpBitcast %32 %17\n%50 = OpInBoundsAccessChain %34 %49 %20 %29\n%51 = OpCompositeConstruct %11 %41 %43 %45 %47\nOpStore %50 %51 Aligned 16\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex1d.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 3, binding = 0, r32f) uniform coherent image1D _13[];\n\nvoid main()\n{\n    uint _35 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _36 = imageLoad(_13[registers._m3], int(_35));\n    imageStore(_13[registers._m3], int(_35), vec4(_36.x + 1.0, _36.y + 2.0, _36.z + 3.0, _36.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 3\nOpDecorate %13 Binding 0\nOpDecorate %13 Coherent\nOpDecorate %16 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 1D 0 0 0 2 R32f\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer UniformConstant %10\n%19 = OpTypePointer PushConstant %5\n%21 = OpConstant %5 3\n%24 = OpTypePointer Input %9\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%34 = OpConstant %5 1000\n%42 = OpConstant %9 1\n%44 = OpConstant %9 2\n%46 = OpConstant %9 3\n%48 = OpConstant %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%18 = OpAccessChain %17 %13 %22\n%23 = OpLoad %10 %18\n%25 = OpAccessChain %24 %16 %26\n%27 = OpLoad %9 %25\n%28 = OpAccessChain %24 %16 %29\n%30 = OpLoad %9 %28\n%31 = OpConvertFToU %5 %27\n%32 = OpConvertFToU %5 %30\n%33 = OpIMul %5 %32 %34\n%35 = OpIAdd %5 %33 %31\nOpBeginInvocationInterlockEXT\n%36 = OpImageRead %14 %23 %35 None\n%37 = OpCompositeExtract %9 %36 0\n%38 = OpCompositeExtract %9 %36 1\n%39 = OpCompositeExtract %9 %36 2\n%40 = OpCompositeExtract %9 %36 3\n%41 = OpFAdd %9 %37 %42\n%43 = OpFAdd %9 %38 %44\n%45 = OpFAdd %9 %39 %46\n%47 = OpFAdd %9 %40 %48\n%49 = OpCompositeConstruct %14 %41 %43 %45 %47\nOpImageWrite %23 %35 %49\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex1d.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image1D _8;\n\nvoid main()\n{\n    uint _25 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _26 = imageLoad(_8, int(_25));\n    imageStore(_8, int(_25), vec4(_26.x + 1.0, _26.y + 2.0, _26.z + 3.0, _26.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %11 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%24 = OpConstant %15 1000\n%32 = OpConstant %5 1\n%34 = OpConstant %5 2\n%36 = OpConstant %5 3\n%38 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpConvertFToU %15 %17\n%22 = OpConvertFToU %15 %20\n%23 = OpIMul %15 %22 %24\n%25 = OpIAdd %15 %23 %21\nOpBeginInvocationInterlockEXT\n%26 = OpImageRead %9 %12 %25 None\n%27 = OpCompositeExtract %5 %26 0\n%28 = OpCompositeExtract %5 %26 1\n%29 = OpCompositeExtract %5 %26 2\n%30 = OpCompositeExtract %5 %26 3\n%31 = OpFAdd %5 %27 %32\n%33 = OpFAdd %5 %28 %34\n%35 = OpFAdd %5 %29 %36\n%37 = OpFAdd %5 %30 %38\n%39 = OpCompositeConstruct %9 %31 %33 %35 %37\nOpImageWrite %12 %25 %39\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex1darray.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 3, binding = 0, r32f) uniform coherent image1DArray _13[];\n\nvoid main()\n{\n    uint _31 = uint(gl_FragCoord.x);\n    uint _32 = uint(gl_FragCoord.y);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _33 = imageLoad(_13[registers._m3], ivec2(uvec2(_31, _32)));\n    imageStore(_13[registers._m3], ivec2(uvec2(_31, _32)), vec4(_33.x + 1.0, _33.y + 2.0, _33.z + 3.0, _33.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 3\nOpDecorate %13 Binding 0\nOpDecorate %13 Coherent\nOpDecorate %16 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 1D 0 1 0 2 R32f\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer UniformConstant %10\n%19 = OpTypePointer PushConstant %5\n%21 = OpConstant %5 3\n%24 = OpTypePointer Input %9\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%34 = OpTypeVector %5 2\n%41 = OpConstant %9 1\n%43 = OpConstant %9 2\n%45 = OpConstant %9 3\n%47 = OpConstant %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%18 = OpAccessChain %17 %13 %22\n%23 = OpLoad %10 %18\n%25 = OpAccessChain %24 %16 %26\n%27 = OpLoad %9 %25\n%28 = OpAccessChain %24 %16 %29\n%30 = OpLoad %9 %28\n%31 = OpConvertFToU %5 %27\n%32 = OpConvertFToU %5 %30\n%35 = OpCompositeConstruct %34 %31 %32\nOpBeginInvocationInterlockEXT\n%33 = OpImageRead %14 %23 %35 None\n%36 = OpCompositeExtract %9 %33 0\n%37 = OpCompositeExtract %9 %33 1\n%38 = OpCompositeExtract %9 %33 2\n%39 = OpCompositeExtract %9 %33 3\n%40 = OpFAdd %9 %36 %41\n%42 = OpFAdd %9 %37 %43\n%44 = OpFAdd %9 %38 %45\n%46 = OpFAdd %9 %39 %47\n%48 = OpCompositeConstruct %34 %31 %32\n%49 = OpCompositeConstruct %14 %40 %42 %44 %46\nOpImageWrite %23 %48 %49\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex1darray.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image1DArray _8;\n\nvoid main()\n{\n    uint _21 = uint(gl_FragCoord.x);\n    uint _22 = uint(gl_FragCoord.y);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _23 = imageLoad(_8, ivec2(uvec2(_21, _22)));\n    imageStore(_8, ivec2(uvec2(_21, _22)), vec4(_23.x + 1.0, _23.y + 2.0, _23.z + 3.0, _23.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %11 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 1D 0 1 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%24 = OpTypeVector %15 2\n%31 = OpConstant %5 1\n%33 = OpConstant %5 2\n%35 = OpConstant %5 3\n%37 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpConvertFToU %15 %17\n%22 = OpConvertFToU %15 %20\n%25 = OpCompositeConstruct %24 %21 %22\nOpBeginInvocationInterlockEXT\n%23 = OpImageRead %9 %12 %25 None\n%26 = OpCompositeExtract %5 %23 0\n%27 = OpCompositeExtract %5 %23 1\n%28 = OpCompositeExtract %5 %23 2\n%29 = OpCompositeExtract %5 %23 3\n%30 = OpFAdd %5 %26 %31\n%32 = OpFAdd %5 %27 %33\n%34 = OpFAdd %5 %28 %35\n%36 = OpFAdd %5 %29 %37\n%38 = OpCompositeConstruct %24 %21 %22\n%39 = OpCompositeConstruct %9 %30 %32 %34 %36\nOpImageWrite %12 %38 %39\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex2d.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 3, binding = 0, r32f) uniform coherent image2D _13[];\n\nvoid main()\n{\n    uint _31 = uint(gl_FragCoord.x);\n    uint _32 = uint(gl_FragCoord.y);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _33 = imageLoad(_13[registers._m3], ivec2(uvec2(_31, _32)));\n    imageStore(_13[registers._m3], ivec2(uvec2(_31, _32)), vec4(_33.x + 1.0, _33.y + 2.0, _33.z + 3.0, _33.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 3\nOpDecorate %13 Binding 0\nOpDecorate %13 Coherent\nOpDecorate %16 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 R32f\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer UniformConstant %10\n%19 = OpTypePointer PushConstant %5\n%21 = OpConstant %5 3\n%24 = OpTypePointer Input %9\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%34 = OpTypeVector %5 2\n%41 = OpConstant %9 1\n%43 = OpConstant %9 2\n%45 = OpConstant %9 3\n%47 = OpConstant %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %50\n%50 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%18 = OpAccessChain %17 %13 %22\n%23 = OpLoad %10 %18\n%25 = OpAccessChain %24 %16 %26\n%27 = OpLoad %9 %25\n%28 = OpAccessChain %24 %16 %29\n%30 = OpLoad %9 %28\n%31 = OpConvertFToU %5 %27\n%32 = OpConvertFToU %5 %30\n%35 = OpCompositeConstruct %34 %31 %32\nOpBeginInvocationInterlockEXT\n%33 = OpImageRead %14 %23 %35 None\n%36 = OpCompositeExtract %9 %33 0\n%37 = OpCompositeExtract %9 %33 1\n%38 = OpCompositeExtract %9 %33 2\n%39 = OpCompositeExtract %9 %33 3\n%40 = OpFAdd %9 %36 %41\n%42 = OpFAdd %9 %37 %43\n%44 = OpFAdd %9 %38 %45\n%46 = OpFAdd %9 %39 %47\n%48 = OpCompositeConstruct %34 %31 %32\n%49 = OpCompositeConstruct %14 %40 %42 %44 %46\nOpImageWrite %23 %48 %49\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex2d.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _8;\n\nvoid main()\n{\n    uint _21 = uint(gl_FragCoord.x);\n    uint _22 = uint(gl_FragCoord.y);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _23 = imageLoad(_8, ivec2(uvec2(_21, _22)));\n    imageStore(_8, ivec2(uvec2(_21, _22)), vec4(_23.x + 1.0, _23.y + 2.0, _23.z + 3.0, _23.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %11 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%24 = OpTypeVector %15 2\n%31 = OpConstant %5 1\n%33 = OpConstant %5 2\n%35 = OpConstant %5 3\n%37 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpConvertFToU %15 %17\n%22 = OpConvertFToU %15 %20\n%25 = OpCompositeConstruct %24 %21 %22\nOpBeginInvocationInterlockEXT\n%23 = OpImageRead %9 %12 %25 None\n%26 = OpCompositeExtract %5 %23 0\n%27 = OpCompositeExtract %5 %23 1\n%28 = OpCompositeExtract %5 %23 2\n%29 = OpCompositeExtract %5 %23 3\n%30 = OpFAdd %5 %26 %31\n%32 = OpFAdd %5 %27 %33\n%34 = OpFAdd %5 %28 %35\n%36 = OpFAdd %5 %29 %37\n%38 = OpCompositeConstruct %24 %21 %22\n%39 = OpCompositeConstruct %9 %30 %32 %34 %36\nOpImageWrite %12 %38 %39\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex2darray.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 3, binding = 0, r32f) uniform coherent image2DArray _13[];\n\nvoid main()\n{\n    uint _34 = uint(gl_FragCoord.x);\n    uint _35 = uint(gl_FragCoord.y);\n    uint _36 = uint(gl_FragCoord.z);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _37 = imageLoad(_13[registers._m3], ivec3(uvec3(_34, _35, _36)));\n    imageStore(_13[registers._m3], ivec3(uvec3(_34, _35, _36)), vec4(_37.x + 1.0, _37.y + 2.0, _37.z + 3.0, _37.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 3\nOpDecorate %13 Binding 0\nOpDecorate %13 Coherent\nOpDecorate %16 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 1 0 2 R32f\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer UniformConstant %10\n%19 = OpTypePointer PushConstant %5\n%21 = OpConstant %5 3\n%24 = OpTypePointer Input %9\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%32 = OpConstant %5 2\n%38 = OpTypeVector %5 3\n%45 = OpConstant %9 1\n%47 = OpConstant %9 2\n%49 = OpConstant %9 3\n%51 = OpConstant %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%18 = OpAccessChain %17 %13 %22\n%23 = OpLoad %10 %18\n%25 = OpAccessChain %24 %16 %26\n%27 = OpLoad %9 %25\n%28 = OpAccessChain %24 %16 %29\n%30 = OpLoad %9 %28\n%31 = OpAccessChain %24 %16 %32\n%33 = OpLoad %9 %31\n%34 = OpConvertFToU %5 %27\n%35 = OpConvertFToU %5 %30\n%36 = OpConvertFToU %5 %33\n%39 = OpCompositeConstruct %38 %34 %35 %36\nOpBeginInvocationInterlockEXT\n%37 = OpImageRead %14 %23 %39 None\n%40 = OpCompositeExtract %9 %37 0\n%41 = OpCompositeExtract %9 %37 1\n%42 = OpCompositeExtract %9 %37 2\n%43 = OpCompositeExtract %9 %37 3\n%44 = OpFAdd %9 %40 %45\n%46 = OpFAdd %9 %41 %47\n%48 = OpFAdd %9 %42 %49\n%50 = OpFAdd %9 %43 %51\n%52 = OpCompositeConstruct %38 %34 %35 %36\n%53 = OpCompositeConstruct %14 %44 %46 %48 %50\nOpImageWrite %23 %52 %53\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex2darray.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image2DArray _8;\n\nvoid main()\n{\n    uint _24 = uint(gl_FragCoord.x);\n    uint _25 = uint(gl_FragCoord.y);\n    uint _26 = uint(gl_FragCoord.z);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _27 = imageLoad(_8, ivec3(uvec3(_24, _25, _26)));\n    imageStore(_8, ivec3(uvec3(_24, _25, _26)), vec4(_27.x + 1.0, _27.y + 2.0, _27.z + 3.0, _27.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %11 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 1 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%22 = OpConstant %15 2\n%28 = OpTypeVector %15 3\n%35 = OpConstant %5 1\n%37 = OpConstant %5 2\n%39 = OpConstant %5 3\n%41 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %13 %11 %22\n%23 = OpLoad %5 %21\n%24 = OpConvertFToU %15 %17\n%25 = OpConvertFToU %15 %20\n%26 = OpConvertFToU %15 %23\n%29 = OpCompositeConstruct %28 %24 %25 %26\nOpBeginInvocationInterlockEXT\n%27 = OpImageRead %9 %12 %29 None\n%30 = OpCompositeExtract %5 %27 0\n%31 = OpCompositeExtract %5 %27 1\n%32 = OpCompositeExtract %5 %27 2\n%33 = OpCompositeExtract %5 %27 3\n%34 = OpFAdd %5 %30 %35\n%36 = OpFAdd %5 %31 %37\n%38 = OpFAdd %5 %32 %39\n%40 = OpFAdd %5 %33 %41\n%42 = OpCompositeConstruct %28 %24 %25 %26\n%43 = OpCompositeConstruct %9 %34 %36 %38 %40\nOpImageWrite %12 %42 %43\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex3d.bindless.frag",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 3, binding = 0, r32f) uniform coherent image3D _13[];\n\nvoid main()\n{\n    uint _34 = uint(gl_FragCoord.x);\n    uint _35 = uint(gl_FragCoord.y);\n    uint _36 = uint(gl_FragCoord.z);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _37 = imageLoad(_13[registers._m3], ivec3(uvec3(_34, _35, _36)));\n    imageStore(_13[registers._m3], ivec3(uvec3(_34, _35, _36)), vec4(_37.x + 1.0, _37.y + 2.0, _37.z + 3.0, _37.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint Fragment %3 \"main\" %16\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %16 \"SV_Position\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 3\nOpDecorate %13 Binding 0\nOpDecorate %13 Coherent\nOpDecorate %16 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 3D 0 0 0 2 R32f\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeVector %9 4\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer UniformConstant %10\n%19 = OpTypePointer PushConstant %5\n%21 = OpConstant %5 3\n%24 = OpTypePointer Input %9\n%26 = OpConstant %5 0\n%29 = OpConstant %5 1\n%32 = OpConstant %5 2\n%38 = OpTypeVector %5 3\n%45 = OpConstant %9 1\n%47 = OpConstant %9 2\n%49 = OpConstant %9 3\n%51 = OpConstant %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%18 = OpAccessChain %17 %13 %22\n%23 = OpLoad %10 %18\n%25 = OpAccessChain %24 %16 %26\n%27 = OpLoad %9 %25\n%28 = OpAccessChain %24 %16 %29\n%30 = OpLoad %9 %28\n%31 = OpAccessChain %24 %16 %32\n%33 = OpLoad %9 %31\n%34 = OpConvertFToU %5 %27\n%35 = OpConvertFToU %5 %30\n%36 = OpConvertFToU %5 %33\n%39 = OpCompositeConstruct %38 %34 %35 %36\nOpBeginInvocationInterlockEXT\n%37 = OpImageRead %14 %23 %39 None\n%40 = OpCompositeExtract %9 %37 0\n%41 = OpCompositeExtract %9 %37 1\n%42 = OpCompositeExtract %9 %37 2\n%43 = OpCompositeExtract %9 %37 3\n%44 = OpFAdd %9 %40 %45\n%46 = OpFAdd %9 %41 %47\n%48 = OpFAdd %9 %42 %49\n%50 = OpFAdd %9 %43 %51\n%52 = OpCompositeConstruct %38 %34 %35 %36\n%53 = OpCompositeConstruct %14 %44 %46 %48 %50\nOpImageWrite %23 %52 %53\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-tex3d.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform coherent image3D _8;\n\nvoid main()\n{\n    uint _24 = uint(gl_FragCoord.x);\n    uint _25 = uint(gl_FragCoord.y);\n    uint _26 = uint(gl_FragCoord.z);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _27 = imageLoad(_8, ivec3(uvec3(_24, _25, _26)));\n    imageStore(_8, ivec3(uvec3(_24, _25, _26)), vec4(_27.x + 1.0, _27.y + 2.0, _27.z + 3.0, _27.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %11 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 3D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%22 = OpConstant %15 2\n%28 = OpTypeVector %15 3\n%35 = OpConstant %5 1\n%37 = OpConstant %5 2\n%39 = OpConstant %5 3\n%41 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %44\n%44 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %13 %11 %22\n%23 = OpLoad %5 %21\n%24 = OpConvertFToU %15 %17\n%25 = OpConvertFToU %15 %20\n%26 = OpConvertFToU %15 %23\n%29 = OpCompositeConstruct %28 %24 %25 %26\nOpBeginInvocationInterlockEXT\n%27 = OpImageRead %9 %12 %29 None\n%30 = OpCompositeExtract %5 %27 0\n%31 = OpCompositeExtract %5 %27 1\n%32 = OpCompositeExtract %5 %27 2\n%33 = OpCompositeExtract %5 %27 3\n%34 = OpFAdd %5 %30 %35\n%36 = OpFAdd %5 %31 %37\n%38 = OpFAdd %5 %32 %39\n%40 = OpFAdd %5 %33 %41\n%42 = OpCompositeConstruct %28 %24 %25 %26\n%43 = OpCompositeConstruct %9 %34 %36 %38 %40\nOpImageWrite %12 %42 %43\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov-undef.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nuint _37;\n\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _8;\n\nvoid main()\n{\n    SPIRV_Cross_beginInvocationInterlock();\n    uint _36;\n    uint _38;\n    if (gl_FragCoord.x > 1000.0)\n    {\n        uvec4 _24 = imageLoad(_8, int(0u));\n        uint _27 = 0u + 1u;\n        uvec4 _26 = imageLoad(_8, int(_27));\n        uvec2 _31 = uvec2(_24.x, _26.x);\n        imageStore(_8, int(0u), uvec4(50u));\n        _36 = _31.x;\n        _38 = _31.y;\n    }\n    else\n    {\n        _36 = _37;\n        _38 = _37;\n    }\n    if (gl_FragCoord.x > 1100.0)\n    {\n        uint _41 = (_38 * 1000u) + _36;\n        uint _44 = _41 * 4u;\n        uvec4 _45 = imageLoad(_8, int(_44));\n        uvec4 _47 = imageLoad(_8, int(_44 + 1u));\n        uvec4 _50 = imageLoad(_8, int(_44 + 2u));\n        uvec4 _54 = imageLoad(_8, int(_44 + 3u));\n        uvec4 _58 = uvec4(_45.x, _47.x, _50.x, _54.x);\n        uint _67 = _41 * 4u;\n        imageStore(_8, int(_67), uvec4(_58.x + 1u));\n        imageStore(_8, int(_67 + 1u), uvec4(_58.y + 2u));\n        imageStore(_8, int(_67 + 2u), uvec4(_58.z + 3u));\n        imageStore(_8, int(_67 + 3u), uvec4(_58.w + 4u));\n    }\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 81\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %12\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 Coherent\nOpDecorate %12 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%14 = OpTypePointer Input %9\n%16 = OpConstant %5 0\n%18 = OpTypeBool\n%20 = OpConstant %9 1000\n%22 = OpConstant %9 1100\n%23 = OpTypeVector %5 4\n%28 = OpConstant %5 1\n%30 = OpTypeVector %5 2\n%34 = OpConstant %5 50\n%40 = OpConstant %5 1000\n%43 = OpConstant %5 4\n%52 = OpConstant %5 2\n%56 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%37 = OpUndef %5\nOpBranch %75\n%75 = OpLabel\n%13 = OpLoad %6 %8\n%15 = OpAccessChain %14 %12 %16\n%17 = OpLoad %9 %15\n%19 = OpFOrdGreaterThan %18 %17 %20\n%21 = OpFOrdGreaterThan %18 %17 %22\nOpBeginInvocationInterlockEXT\nOpSelectionMerge %77 None\nOpBranchConditional %19 %76 %77\n%76 = OpLabel\n%24 = OpImageRead %23 %13 %16\n%25 = OpCompositeExtract %5 %24 0\n%27 = OpIAdd %5 %16 %28\n%26 = OpImageRead %23 %13 %27\n%29 = OpCompositeExtract %5 %26 0\n%31 = OpCompositeConstruct %30 %25 %29\n%32 = OpCompositeExtract %5 %31 0\n%33 = OpCompositeExtract %5 %31 1\n%35 = OpCompositeConstruct %23 %34 %34 %34 %34\nOpImageWrite %13 %16 %35\nOpBranch %77\n%77 = OpLabel\n%36 = OpPhi %5 %37 %75 %32 %76\n%38 = OpPhi %5 %37 %75 %33 %76\nOpSelectionMerge %79 None\nOpBranchConditional %21 %78 %79\n%78 = OpLabel\n%39 = OpIMul %5 %38 %40\n%41 = OpIAdd %5 %39 %36\n%42 = OpShiftLeftLogical %5 %41 %43\n%44 = OpIMul %5 %41 %43\n%45 = OpImageRead %23 %13 %44\n%46 = OpCompositeExtract %5 %45 0\n%48 = OpIAdd %5 %44 %28\n%47 = OpImageRead %23 %13 %48\n%49 = OpCompositeExtract %5 %47 0\n%51 = OpIAdd %5 %44 %52\n%50 = OpImageRead %23 %13 %51\n%53 = OpCompositeExtract %5 %50 0\n%55 = OpIAdd %5 %44 %56\n%54 = OpImageRead %23 %13 %55\n%57 = OpCompositeExtract %5 %54 0\n%58 = OpCompositeConstruct %23 %46 %49 %53 %57\n%59 = OpCompositeExtract %5 %58 0\n%60 = OpCompositeExtract %5 %58 1\n%61 = OpCompositeExtract %5 %58 2\n%62 = OpCompositeExtract %5 %58 3\n%63 = OpIAdd %5 %59 %28\n%64 = OpIAdd %5 %60 %52\n%65 = OpIAdd %5 %61 %56\n%66 = OpIAdd %5 %62 %43\n%67 = OpIMul %5 %41 %43\n%68 = OpCompositeConstruct %23 %63 %63 %63 %63\nOpImageWrite %13 %67 %68\n%69 = OpCompositeConstruct %23 %64 %64 %64 %64\n%70 = OpIAdd %5 %67 %28\nOpImageWrite %13 %70 %69\n%71 = OpCompositeConstruct %23 %65 %65 %65 %65\n%72 = OpIAdd %5 %67 %52\nOpImageWrite %13 %72 %71\n%73 = OpCompositeConstruct %23 %66 %66 %66 %66\n%74 = OpIAdd %5 %67 %56\nOpImageWrite %13 %74 %73\nOpBranch %79\n%79 = OpLabel\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/rov/rov.sm66.frag",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _9[];\nlayout(set = 0, binding = 0, r32ui) uniform coherent uimageBuffer _12[];\nlayout(set = 0, binding = 0, r32f) uniform coherent imageBuffer _17[];\nlayout(set = 0, binding = 0, r32f) uniform coherent image1D _21[];\nlayout(set = 0, binding = 0, r32f) uniform coherent image2D _25[];\n\nvoid main()\n{\n    uint _36 = uint(gl_FragCoord.x);\n    uint _37 = uint(gl_FragCoord.y);\n    uint _43 = (_37 * 1000u) + _36;\n    uint _46 = _43 * 4u;\n    SPIRV_Cross_beginInvocationInterlock();\n    uvec4 _48 = imageLoad(_9[0u], int(_46));\n    uvec4 _50 = imageLoad(_9[0u], int(_46 + 1u));\n    uvec4 _53 = imageLoad(_9[0u], int(_46 + 2u));\n    uvec4 _57 = imageLoad(_9[0u], int(_46 + 3u));\n    uvec4 _61 = uvec4(_48.x, _50.x, _53.x, _57.x);\n    uint _70 = _43 * 4u;\n    imageStore(_9[0u], int(_70), uvec4(_61.x + 1u));\n    imageStore(_9[0u], int(_70 + 1u), uvec4(_61.y + 2u));\n    imageStore(_9[0u], int(_70 + 2u), uvec4(_61.z + 3u));\n    imageStore(_9[0u], int(_70 + 3u), uvec4(_61.w + 4u));\n    uint _80 = _43 * 4u;\n    uvec4 _81 = imageLoad(_12[1u], int(_80));\n    uvec4 _83 = imageLoad(_12[1u], int(_80 + 1u));\n    uvec4 _86 = imageLoad(_12[1u], int(_80 + 2u));\n    uvec4 _89 = imageLoad(_12[1u], int(_80 + 3u));\n    vec4 _93 = uintBitsToFloat(uvec4(_81.x, _83.x, _86.x, _89.x));\n    uint _106 = _43 * 4u;\n    imageStore(_12[1u], int(_106), uvec4(floatBitsToUint(_93.x + 1.0)));\n    imageStore(_12[1u], int(_106 + 1u), uvec4(floatBitsToUint(_93.y + 2.0)));\n    imageStore(_12[1u], int(_106 + 2u), uvec4(floatBitsToUint(_93.z + 3.0)));\n    imageStore(_12[1u], int(_106 + 3u), uvec4(floatBitsToUint(_93.w + 4.0)));\n    vec4 _121 = imageLoad(_17[2u], int(_43));\n    imageStore(_17[2u], int(_43), vec4(_121.x + 1.0, _121.y + 2.0, _121.z + 3.0, _121.w + 4.0));\n    vec4 _134 = imageLoad(_21[3u], int(_43));\n    imageStore(_21[3u], int(_43), vec4(_134.x + 1.0, _134.y + 2.0, _134.z + 3.0, _134.w + 4.0));\n    vec4 _147 = imageLoad(_25[4u], ivec2(uvec2(_36, _37)));\n    imageStore(_25[4u], ivec2(uvec2(_36, _37)), vec4(_147.x + 1.0, _147.y + 2.0, _147.z + 3.0, _147.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 162\n; Schema: 0\nOpCapability Shader\nOpCapability Image1D\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %28\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %28 \"SV_Position\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 Coherent\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %12 Coherent\nOpDecorate %17 DescriptorSet 0\nOpDecorate %17 Binding 0\nOpDecorate %17 Coherent\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %21 Coherent\nOpDecorate %25 DescriptorSet 0\nOpDecorate %25 Binding 0\nOpDecorate %25 Coherent\nOpDecorate %28 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeRuntimeArray %6\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeFloat 32\n%14 = OpTypeImage %13 Buffer 0 0 0 2 R32f\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %13 1D 0 0 0 2 R32f\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %13 2D 0 0 0 2 R32f\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer UniformConstant %23\n%25 = OpVariable %24 UniformConstant\n%26 = OpTypeVector %13 4\n%27 = OpTypePointer Input %26\n%28 = OpVariable %27 Input\n%29 = OpTypePointer Input %13\n%31 = OpConstant %5 0\n%34 = OpConstant %5 1\n%38 = OpTypePointer UniformConstant %6\n%42 = OpConstant %5 1000\n%45 = OpConstant %5 4\n%47 = OpTypeVector %5 4\n%55 = OpConstant %5 2\n%59 = OpConstant %5 3\n%99 = OpConstant %13 1\n%101 = OpConstant %13 2\n%103 = OpConstant %13 3\n%105 = OpConstant %13 4\n%118 = OpTypePointer UniformConstant %14\n%131 = OpTypePointer UniformConstant %18\n%144 = OpTypePointer UniformConstant %22\n%148 = OpTypeVector %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %160\n%160 = OpLabel\n%30 = OpAccessChain %29 %28 %31\n%32 = OpLoad %13 %30\n%33 = OpAccessChain %29 %28 %34\n%35 = OpLoad %13 %33\n%36 = OpConvertFToU %5 %32\n%37 = OpConvertFToU %5 %35\n%39 = OpAccessChain %38 %9 %31\n%40 = OpLoad %6 %39\n%41 = OpIMul %5 %37 %42\n%43 = OpIAdd %5 %41 %36\n%44 = OpShiftLeftLogical %5 %43 %45\n%46 = OpIMul %5 %43 %45\nOpBeginInvocationInterlockEXT\n%48 = OpImageRead %47 %40 %46\n%49 = OpCompositeExtract %5 %48 0\n%51 = OpIAdd %5 %46 %34\n%50 = OpImageRead %47 %40 %51\n%52 = OpCompositeExtract %5 %50 0\n%54 = OpIAdd %5 %46 %55\n%53 = OpImageRead %47 %40 %54\n%56 = OpCompositeExtract %5 %53 0\n%58 = OpIAdd %5 %46 %59\n%57 = OpImageRead %47 %40 %58\n%60 = OpCompositeExtract %5 %57 0\n%61 = OpCompositeConstruct %47 %49 %52 %56 %60\n%62 = OpCompositeExtract %5 %61 0\n%63 = OpCompositeExtract %5 %61 1\n%64 = OpCompositeExtract %5 %61 2\n%65 = OpCompositeExtract %5 %61 3\n%66 = OpIAdd %5 %62 %34\n%67 = OpIAdd %5 %63 %55\n%68 = OpIAdd %5 %64 %59\n%69 = OpIAdd %5 %65 %45\n%70 = OpIMul %5 %43 %45\n%71 = OpCompositeConstruct %47 %66 %66 %66 %66\nOpImageWrite %40 %70 %71\n%72 = OpCompositeConstruct %47 %67 %67 %67 %67\n%73 = OpIAdd %5 %70 %34\nOpImageWrite %40 %73 %72\n%74 = OpCompositeConstruct %47 %68 %68 %68 %68\n%75 = OpIAdd %5 %70 %55\nOpImageWrite %40 %75 %74\n%76 = OpCompositeConstruct %47 %69 %69 %69 %69\n%77 = OpIAdd %5 %70 %59\nOpImageWrite %40 %77 %76\n%78 = OpAccessChain %38 %12 %34\n%79 = OpLoad %6 %78\n%80 = OpIMul %5 %43 %45\n%81 = OpImageRead %47 %79 %80\n%82 = OpCompositeExtract %5 %81 0\n%84 = OpIAdd %5 %80 %34\n%83 = OpImageRead %47 %79 %84\n%85 = OpCompositeExtract %5 %83 0\n%87 = OpIAdd %5 %80 %55\n%86 = OpImageRead %47 %79 %87\n%88 = OpCompositeExtract %5 %86 0\n%90 = OpIAdd %5 %80 %59\n%89 = OpImageRead %47 %79 %90\n%91 = OpCompositeExtract %5 %89 0\n%92 = OpCompositeConstruct %47 %82 %85 %88 %91\n%93 = OpBitcast %26 %92\n%94 = OpCompositeExtract %13 %93 0\n%95 = OpCompositeExtract %13 %93 1\n%96 = OpCompositeExtract %13 %93 2\n%97 = OpCompositeExtract %13 %93 3\n%98 = OpFAdd %13 %94 %99\n%100 = OpFAdd %13 %95 %101\n%102 = OpFAdd %13 %96 %103\n%104 = OpFAdd %13 %97 %105\n%106 = OpIMul %5 %43 %45\n%107 = OpBitcast %5 %98\n%108 = OpBitcast %5 %100\n%109 = OpBitcast %5 %102\n%110 = OpBitcast %5 %104\n%111 = OpCompositeConstruct %47 %107 %107 %107 %107\nOpImageWrite %79 %106 %111\n%112 = OpCompositeConstruct %47 %108 %108 %108 %108\n%113 = OpIAdd %5 %106 %34\nOpImageWrite %79 %113 %112\n%114 = OpCompositeConstruct %47 %109 %109 %109 %109\n%115 = OpIAdd %5 %106 %55\nOpImageWrite %79 %115 %114\n%116 = OpCompositeConstruct %47 %110 %110 %110 %110\n%117 = OpIAdd %5 %106 %59\nOpImageWrite %79 %117 %116\n%119 = OpAccessChain %118 %17 %55\n%120 = OpLoad %14 %119\n%121 = OpImageRead %26 %120 %43\n%122 = OpCompositeExtract %13 %121 0\n%123 = OpCompositeExtract %13 %121 1\n%124 = OpCompositeExtract %13 %121 2\n%125 = OpCompositeExtract %13 %121 3\n%126 = OpFAdd %13 %122 %99\n%127 = OpFAdd %13 %123 %101\n%128 = OpFAdd %13 %124 %103\n%129 = OpFAdd %13 %125 %105\n%130 = OpCompositeConstruct %26 %126 %127 %128 %129\nOpImageWrite %120 %43 %130\n%132 = OpAccessChain %131 %21 %59\n%133 = OpLoad %18 %132\n%134 = OpImageRead %26 %133 %43 None\n%135 = OpCompositeExtract %13 %134 0\n%136 = OpCompositeExtract %13 %134 1\n%137 = OpCompositeExtract %13 %134 2\n%138 = OpCompositeExtract %13 %134 3\n%139 = OpFAdd %13 %135 %99\n%140 = OpFAdd %13 %136 %101\n%141 = OpFAdd %13 %137 %103\n%142 = OpFAdd %13 %138 %105\n%143 = OpCompositeConstruct %26 %139 %140 %141 %142\nOpImageWrite %133 %43 %143\n%145 = OpAccessChain %144 %25 %45\n%146 = OpLoad %22 %145\n%149 = OpCompositeConstruct %148 %36 %37\n%147 = OpImageRead %26 %146 %149 None\n%150 = OpCompositeExtract %13 %147 0\n%151 = OpCompositeExtract %13 %147 1\n%152 = OpCompositeExtract %13 %147 2\n%153 = OpCompositeExtract %13 %147 3\n%154 = OpFAdd %13 %150 %99\n%155 = OpFAdd %13 %151 %101\n%156 = OpFAdd %13 %152 %103\n%157 = OpFAdd %13 %153 %105\n%158 = OpCompositeConstruct %148 %36 %37\n%159 = OpCompositeConstruct %26 %154 %155 %156 %157\nOpImageWrite %146 %158 %159\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/sampler-feedback/sampler-feedback.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_image_int64 : require\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_samplerless_texture_functions : require\n#extension GL_EXT_spirv_intrinsics : require\n#extension GL_KHR_shader_subgroup_quad : require\n\nstruct ResType\n{\n    vec2 _m0;\n    ivec2 _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 1) uniform texture2DArray _11;\nlayout(set = 1, binding = 0) uniform texture2D _14[];\nlayout(set = 2, binding = 0) uniform texture2DArray _17[];\nlayout(set = 0, binding = 0, r64ui) uniform readonly writeonly u64image2D _21;\nlayout(set = 0, binding = 1, r64ui) uniform readonly writeonly u64image2DArray _24;\nlayout(set = 1, binding = 0, r64ui) uniform readonly writeonly u64image2D _27[];\nlayout(set = 2, binding = 0, r64ui) uniform readonly writeonly u64image2DArray _30[];\nlayout(set = 0, binding = 0) uniform sampler _33;\nlayout(set = 1, binding = 0) uniform sampler _36[];\n\nlayout(location = 1) in vec2 GRADX;\nlayout(location = 1, component = 2) in vec2 GRADY;\nlayout(location = 2) in float CLAMP;\nlayout(location = 3) flat in uint IDX;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float spvNClamp(float, float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec2 spvNClamp(vec2, vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec3 spvNClamp(vec3, vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec4 spvNClamp(vec4, vec4, vec4);\n\nvoid WriteFeedback(u64image2D img, ivec2 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _184 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _184;\n            if (_184)\n            {\n                uint64_t _185 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _188 = imageAtomicOr(img, coord, _185);\n                }\n            }\n        }\n    }\n}\n\nvoid WriteFeedbackArray(u64image2DArray img, ivec3 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _847 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _847;\n            if (_847)\n            {\n                uint64_t _848 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _851 = imageAtomicOr(img, coord, _848);\n                }\n            }\n        }\n    }\n}\n\nvoid WriteFeedbackNonUniform(u64image2D img, ivec2 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _1555 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _1555;\n            if (_1555)\n            {\n                uint64_t _1556 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _1559 = imageAtomicOr(img, coord, _1556);\n                }\n            }\n        }\n    }\n}\n\nvoid WriteFeedbackArrayNonUniform(u64image2DArray img, ivec3 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _1688 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _1688;\n            if (_1688)\n            {\n                uint64_t _1689 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _1692 = imageAtomicOr(img, coord, _1689);\n                }\n            }\n        }\n    }\n}\n\nvoid main()\n{\n    float _76 = 1.0 / gl_FragCoord.w;\n    vec2 _83 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _85 = imageSize(_21) & ivec2(15);\n    vec2 _93 = textureQueryLod(sampler2D(_8, _33), _83);\n    float _94 = _93.x;\n    int _95 = int(_94);\n    int _98 = int(_94 + 0.9970703125);\n    vec2 _103 = abs(dFdx(_83));\n    vec2 _104 = abs(dFdy(_83));\n    vec2 _111 = vec2(max(_103.x, _104.x), max(_103.y, _104.y));\n    vec2 _112 = fract(_83);\n    vec2 _113 = vec2(textureSize(_8, _95));\n    ivec2 _115 = -_85;\n    vec2 _117 = _112 * ldexp(_113, _115);\n    ResType _123;\n    _123._m0 = frexp((_111 * _113) - vec2(0.00390625), _123._m1);\n    vec2 _134 = min(ldexp(vec2(0.5), clamp(_123._m1, ivec2(0), ivec2(4)) + _115), vec2(0.5));\n    ivec2 _140 = ivec2(max(_117 - _134, vec2(0.0)));\n    bvec2 _142 = notEqual(_140, ivec2(_117 + _134));\n    bool _143 = _142.x;\n    bool _144 = _142.y;\n    WriteFeedback(_21, _140, uint64_t(((1 | (_143 ? 2 : 0)) | (_144 ? 4 : 0)) | ((_143 && _144) ? 8 : 0)) << uint64_t(_95 * 4), !gl_HelperInvocation);\n    vec2 _191 = vec2(textureSize(_8, _98));\n    ivec2 _193 = -_85;\n    vec2 _195 = _112 * ldexp(_191, _193);\n    ResType _198;\n    _198._m0 = frexp((_111 * _191) - vec2(0.00390625), _198._m1);\n    vec2 _203 = min(ldexp(vec2(0.5), clamp(_198._m1, ivec2(0), ivec2(4)) + _193), vec2(0.5));\n    ivec2 _207 = ivec2(max(_195 - _203, vec2(0.0)));\n    bvec2 _209 = notEqual(_207, ivec2(_195 + _203));\n    bool _210 = _209.x;\n    bool _211 = _209.y;\n    WriteFeedback(_21, _207, uint64_t(((1 | (_210 ? 2 : 0)) | (_211 ? 4 : 0)) | ((_210 && _211) ? 8 : 0)) << uint64_t(_98 * 4), (!gl_HelperInvocation) && (_95 != _98));\n    vec2 _227 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _229 = imageSize(_21) & ivec2(15);\n    float _235 = min(max(textureQueryLod(sampler2D(_8, _33), _227).x, CLAMP), 14.0);\n    int _237 = int(_235);\n    int _239 = int(_235 + 0.9970703125);\n    vec2 _244 = abs(dFdx(_227));\n    vec2 _245 = abs(dFdy(_227));\n    vec2 _252 = vec2(max(_244.x, _245.x), max(_244.y, _245.y));\n    vec2 _253 = fract(_227);\n    vec2 _254 = vec2(textureSize(_8, _237));\n    ivec2 _256 = -_229;\n    vec2 _258 = _253 * ldexp(_254, _256);\n    ResType _261;\n    _261._m0 = frexp((_252 * _254) - vec2(0.00390625), _261._m1);\n    vec2 _266 = min(ldexp(vec2(0.5), clamp(_261._m1, ivec2(0), ivec2(4)) + _256), vec2(0.5));\n    ivec2 _270 = ivec2(max(_258 - _266, vec2(0.0)));\n    bvec2 _272 = notEqual(_270, ivec2(_258 + _266));\n    bool _273 = _272.x;\n    bool _274 = _272.y;\n    WriteFeedback(_21, _270, uint64_t(((1 | (_273 ? 2 : 0)) | (_274 ? 4 : 0)) | ((_273 && _274) ? 8 : 0)) << uint64_t(_237 * 4), !gl_HelperInvocation);\n    vec2 _289 = vec2(textureSize(_8, _239));\n    ivec2 _291 = -_229;\n    vec2 _293 = _253 * ldexp(_289, _291);\n    ResType _296;\n    _296._m0 = frexp((_252 * _289) - vec2(0.00390625), _296._m1);\n    vec2 _301 = min(ldexp(vec2(0.5), clamp(_296._m1, ivec2(0), ivec2(4)) + _291), vec2(0.5));\n    ivec2 _305 = ivec2(max(_293 - _301, vec2(0.0)));\n    bvec2 _307 = notEqual(_305, ivec2(_293 + _301));\n    bool _308 = _307.x;\n    bool _309 = _307.y;\n    WriteFeedback(_21, _305, uint64_t(((1 | (_308 ? 2 : 0)) | (_309 ? 4 : 0)) | ((_308 && _309) ? 8 : 0)) << uint64_t(_239 * 4), (!gl_HelperInvocation) && (_237 != _239));\n    ivec2 _327 = imageSize(_21) & ivec2(15);\n    int _329 = textureQueryLevels(_8) - 1;\n    float _331 = spvNClamp(gl_FragCoord.z, 0.0, float(_329));\n    int _332 = int(_331);\n    int _334 = int(_331 + 0.9970703125);\n    vec2 _337 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _340 = -_327;\n    vec2 _342 = _337 * ldexp(vec2(textureSize(_8, _332)), _340);\n    vec2 _343 = ldexp(vec2(0.5), _340);\n    ivec2 _347 = ivec2(max(_342 - _343, vec2(0.0)));\n    bvec2 _349 = notEqual(_347, ivec2(_342 + _343));\n    bool _350 = _349.x;\n    bool _351 = _349.y;\n    WriteFeedback(_21, _347, uint64_t(((1 | (_350 ? 2 : 0)) | (_351 ? 4 : 0)) | ((_350 && _351) ? 8 : 0)) << uint64_t(_332 * 4), !gl_HelperInvocation);\n    ivec2 _368 = -_327;\n    vec2 _370 = _337 * ldexp(vec2(textureSize(_8, _334)), _368);\n    vec2 _371 = ldexp(vec2(0.5), _368);\n    ivec2 _375 = ivec2(max(_370 - _371, vec2(0.0)));\n    bvec2 _377 = notEqual(_375, ivec2(_370 + _371));\n    bool _378 = _377.x;\n    bool _379 = _377.y;\n    WriteFeedback(_21, _375, uint64_t(((1 | (_378 ? 2 : 0)) | (_379 ? 4 : 0)) | ((_378 && _379) ? 8 : 0)) << uint64_t(_334 * 4), (!gl_HelperInvocation) && (_332 != _334));\n    ivec2 _397 = imageSize(_21) & ivec2(15);\n    int _399 = textureQueryLevels(_8) - 1;\n    vec2 _400 = vec2(textureSize(_8, 0));\n    vec2 _404 = _400 * vec2(GRADX.x, GRADX.y);\n    vec2 _405 = _400 * vec2(GRADY.x, GRADY.y);\n    float _412 = spvNClamp(log2(max(dot(_404, _404), dot(_405, _405))) * 0.5, 0.0, float(_399));\n    int _413 = int(_412);\n    int _415 = int(_412 + 0.9970703125);\n    vec2 _418 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _421 = -_397;\n    vec2 _423 = _418 * ldexp(vec2(textureSize(_8, _413)), _421);\n    vec2 _424 = ldexp(vec2(0.5), _421);\n    ivec2 _428 = ivec2(max(_423 - _424, vec2(0.0)));\n    bvec2 _430 = notEqual(_428, ivec2(_423 + _424));\n    bool _431 = _430.x;\n    bool _432 = _430.y;\n    WriteFeedback(_21, _428, uint64_t(((1 | (_431 ? 2 : 0)) | (_432 ? 4 : 0)) | ((_431 && _432) ? 8 : 0)) << uint64_t(_413 * 4), !gl_HelperInvocation);\n    ivec2 _449 = -_397;\n    vec2 _451 = _418 * ldexp(vec2(textureSize(_8, _415)), _449);\n    vec2 _452 = ldexp(vec2(0.5), _449);\n    ivec2 _456 = ivec2(max(_451 - _452, vec2(0.0)));\n    bvec2 _458 = notEqual(_456, ivec2(_451 + _452));\n    bool _459 = _458.x;\n    bool _460 = _458.y;\n    WriteFeedback(_21, _456, uint64_t(((1 | (_459 ? 2 : 0)) | (_460 ? 4 : 0)) | ((_459 && _460) ? 8 : 0)) << uint64_t(_415 * 4), (!gl_HelperInvocation) && (_413 != _415));\n    ivec2 _478 = imageSize(_21) & ivec2(15);\n    int _480 = textureQueryLevels(_8) - 1;\n    vec2 _481 = vec2(textureSize(_8, 0));\n    vec2 _485 = _481 * vec2(GRADX.x, GRADX.y);\n    vec2 _486 = _481 * vec2(GRADY.x, GRADY.y);\n    float _495 = min(max(spvNClamp(log2(max(dot(_485, _485), dot(_486, _486))) * 0.5, 0.0, float(_480)), CLAMP), 14.0);\n    int _496 = int(_495);\n    int _498 = int(_495 + 0.9970703125);\n    vec2 _501 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _504 = -_478;\n    vec2 _506 = _501 * ldexp(vec2(textureSize(_8, _496)), _504);\n    vec2 _507 = ldexp(vec2(0.5), _504);\n    ivec2 _511 = ivec2(max(_506 - _507, vec2(0.0)));\n    bvec2 _513 = notEqual(_511, ivec2(_506 + _507));\n    bool _514 = _513.x;\n    bool _515 = _513.y;\n    WriteFeedback(_21, _511, uint64_t(((1 | (_514 ? 2 : 0)) | (_515 ? 4 : 0)) | ((_514 && _515) ? 8 : 0)) << uint64_t(_496 * 4), !gl_HelperInvocation);\n    ivec2 _532 = -_478;\n    vec2 _534 = _501 * ldexp(vec2(textureSize(_8, _498)), _532);\n    vec2 _535 = ldexp(vec2(0.5), _532);\n    ivec2 _539 = ivec2(max(_534 - _535, vec2(0.0)));\n    bvec2 _541 = notEqual(_539, ivec2(_534 + _535));\n    bool _542 = _541.x;\n    bool _543 = _541.y;\n    WriteFeedback(_21, _539, uint64_t(((1 | (_542 ? 2 : 0)) | (_543 ? 4 : 0)) | ((_542 && _543) ? 8 : 0)) << uint64_t(_498 * 4), (!gl_HelperInvocation) && (_496 != _498));\n    vec2 _559 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _561 = imageSize(_21) & ivec2(15);\n    float _564 = exp2(gl_FragCoord.z);\n    vec2 _567 = textureQueryLod(sampler2D(_8, _33), _559 * subgroupQuadBroadcast(_564, 0u));\n    float _568 = _567.x;\n    int _569 = int(_568);\n    int _571 = int(_568 + 0.9970703125);\n    vec2 _576 = abs(dFdx(_559));\n    vec2 _577 = abs(dFdy(_559));\n    vec2 _585 = vec2(max(_576.x, _577.x), max(_576.y, _577.y)) * _564;\n    vec2 _586 = fract(_559);\n    vec2 _587 = vec2(textureSize(_8, _569));\n    ivec2 _589 = -_561;\n    vec2 _591 = _586 * ldexp(_587, _589);\n    ResType _594;\n    _594._m0 = frexp((_585 * _587) - vec2(0.00390625), _594._m1);\n    vec2 _599 = min(ldexp(vec2(0.5), clamp(_594._m1, ivec2(0), ivec2(4)) + _589), vec2(0.5));\n    ivec2 _603 = ivec2(max(_591 - _599, vec2(0.0)));\n    bvec2 _605 = notEqual(_603, ivec2(_591 + _599));\n    bool _606 = _605.x;\n    bool _607 = _605.y;\n    WriteFeedback(_21, _603, uint64_t(((1 | (_606 ? 2 : 0)) | (_607 ? 4 : 0)) | ((_606 && _607) ? 8 : 0)) << uint64_t(_569 * 4), !gl_HelperInvocation);\n    vec2 _622 = vec2(textureSize(_8, _571));\n    ivec2 _624 = -_561;\n    vec2 _626 = _586 * ldexp(_622, _624);\n    ResType _629;\n    _629._m0 = frexp((_585 * _622) - vec2(0.00390625), _629._m1);\n    vec2 _634 = min(ldexp(vec2(0.5), clamp(_629._m1, ivec2(0), ivec2(4)) + _624), vec2(0.5));\n    ivec2 _638 = ivec2(max(_626 - _634, vec2(0.0)));\n    bvec2 _640 = notEqual(_638, ivec2(_626 + _634));\n    bool _641 = _640.x;\n    bool _642 = _640.y;\n    WriteFeedback(_21, _638, uint64_t(((1 | (_641 ? 2 : 0)) | (_642 ? 4 : 0)) | ((_641 && _642) ? 8 : 0)) << uint64_t(_571 * 4), (!gl_HelperInvocation) && (_569 != _571));\n    vec2 _658 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _660 = imageSize(_21) & ivec2(15);\n    float _663 = exp2(gl_FragCoord.z);\n    float _669 = min(max(textureQueryLod(sampler2D(_8, _33), _658 * subgroupQuadBroadcast(_663, 0u)).x, CLAMP), 14.0);\n    int _670 = int(_669);\n    int _672 = int(_669 + 0.9970703125);\n    vec2 _677 = abs(dFdx(_658));\n    vec2 _678 = abs(dFdy(_658));\n    vec2 _686 = vec2(max(_677.x, _678.x), max(_677.y, _678.y)) * _663;\n    vec2 _687 = fract(_658);\n    vec2 _688 = vec2(textureSize(_8, _670));\n    ivec2 _690 = -_660;\n    vec2 _692 = _687 * ldexp(_688, _690);\n    ResType _695;\n    _695._m0 = frexp((_686 * _688) - vec2(0.00390625), _695._m1);\n    vec2 _700 = min(ldexp(vec2(0.5), clamp(_695._m1, ivec2(0), ivec2(4)) + _690), vec2(0.5));\n    ivec2 _704 = ivec2(max(_692 - _700, vec2(0.0)));\n    bvec2 _706 = notEqual(_704, ivec2(_692 + _700));\n    bool _707 = _706.x;\n    bool _708 = _706.y;\n    WriteFeedback(_21, _704, uint64_t(((1 | (_707 ? 2 : 0)) | (_708 ? 4 : 0)) | ((_707 && _708) ? 8 : 0)) << uint64_t(_670 * 4), !gl_HelperInvocation);\n    vec2 _723 = vec2(textureSize(_8, _672));\n    ivec2 _725 = -_660;\n    vec2 _727 = _687 * ldexp(_723, _725);\n    ResType _730;\n    _730._m0 = frexp((_686 * _723) - vec2(0.00390625), _730._m1);\n    vec2 _735 = min(ldexp(vec2(0.5), clamp(_730._m1, ivec2(0), ivec2(4)) + _725), vec2(0.5));\n    ivec2 _739 = ivec2(max(_727 - _735, vec2(0.0)));\n    bvec2 _741 = notEqual(_739, ivec2(_727 + _735));\n    bool _742 = _741.x;\n    bool _743 = _741.y;\n    WriteFeedback(_21, _739, uint64_t(((1 | (_742 ? 2 : 0)) | (_743 ? 4 : 0)) | ((_742 && _743) ? 8 : 0)) << uint64_t(_672 * 4), (!gl_HelperInvocation) && (_670 != _672));\n    int _760 = int(roundEven(gl_FragCoord.z));\n    vec2 _761 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _765 = imageSize(_24).xy & ivec2(15);\n    vec2 _770 = textureQueryLod(sampler2DArray(_11, _33), _761);\n    float _771 = _770.x;\n    int _772 = int(_771);\n    int _774 = int(_771 + 0.9970703125);\n    vec2 _779 = abs(dFdx(_761));\n    vec2 _780 = abs(dFdy(_761));\n    vec2 _787 = vec2(max(_779.x, _780.x), max(_779.y, _780.y));\n    vec2 _788 = fract(_761);\n    vec2 _789 = vec2(textureSize(_11, _772).xy);\n    ivec2 _792 = -_765;\n    vec2 _794 = _788 * ldexp(_789, _792);\n    ResType _797;\n    _797._m0 = frexp((_787 * _789) - vec2(0.00390625), _797._m1);\n    vec2 _802 = min(ldexp(vec2(0.5), clamp(_797._m1, ivec2(0), ivec2(4)) + _792), vec2(0.5));\n    ivec2 _806 = ivec2(max(_794 - _802, vec2(0.0)));\n    bvec2 _808 = notEqual(_806, ivec2(_794 + _802));\n    bool _809 = _808.x;\n    bool _810 = _808.y;\n    WriteFeedbackArray(_24, ivec3(_806, _760), uint64_t(((1 | (_809 ? 2 : 0)) | (_810 ? 4 : 0)) | ((_809 && _810) ? 8 : 0)) << uint64_t(_772 * 4), !gl_HelperInvocation);\n    vec2 _854 = vec2(textureSize(_11, _774).xy);\n    ivec2 _857 = -_765;\n    vec2 _859 = _788 * ldexp(_854, _857);\n    ResType _862;\n    _862._m0 = frexp((_787 * _854) - vec2(0.00390625), _862._m1);\n    vec2 _867 = min(ldexp(vec2(0.5), clamp(_862._m1, ivec2(0), ivec2(4)) + _857), vec2(0.5));\n    ivec2 _871 = ivec2(max(_859 - _867, vec2(0.0)));\n    bvec2 _873 = notEqual(_871, ivec2(_859 + _867));\n    bool _874 = _873.x;\n    bool _875 = _873.y;\n    WriteFeedbackArray(_24, ivec3(_871, _760), uint64_t(((1 | (_874 ? 2 : 0)) | (_875 ? 4 : 0)) | ((_874 && _875) ? 8 : 0)) << uint64_t(_774 * 4), (!gl_HelperInvocation) && (_772 != _774));\n    int _893 = int(roundEven(gl_FragCoord.z));\n    vec2 _894 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _897 = imageSize(_24).xy & ivec2(15);\n    float _903 = min(max(textureQueryLod(sampler2DArray(_11, _33), _894).x, CLAMP), 14.0);\n    int _904 = int(_903);\n    int _906 = int(_903 + 0.9970703125);\n    vec2 _911 = abs(dFdx(_894));\n    vec2 _912 = abs(dFdy(_894));\n    vec2 _919 = vec2(max(_911.x, _912.x), max(_911.y, _912.y));\n    vec2 _920 = fract(_894);\n    vec2 _921 = vec2(textureSize(_11, _904).xy);\n    ivec2 _924 = -_897;\n    vec2 _926 = _920 * ldexp(_921, _924);\n    ResType _929;\n    _929._m0 = frexp((_919 * _921) - vec2(0.00390625), _929._m1);\n    vec2 _934 = min(ldexp(vec2(0.5), clamp(_929._m1, ivec2(0), ivec2(4)) + _924), vec2(0.5));\n    ivec2 _938 = ivec2(max(_926 - _934, vec2(0.0)));\n    bvec2 _940 = notEqual(_938, ivec2(_926 + _934));\n    bool _941 = _940.x;\n    bool _942 = _940.y;\n    WriteFeedbackArray(_24, ivec3(_938, _893), uint64_t(((1 | (_941 ? 2 : 0)) | (_942 ? 4 : 0)) | ((_941 && _942) ? 8 : 0)) << uint64_t(_904 * 4), !gl_HelperInvocation);\n    vec2 _958 = vec2(textureSize(_11, _906).xy);\n    ivec2 _961 = -_897;\n    vec2 _963 = _920 * ldexp(_958, _961);\n    ResType _966;\n    _966._m0 = frexp((_919 * _958) - vec2(0.00390625), _966._m1);\n    vec2 _971 = min(ldexp(vec2(0.5), clamp(_966._m1, ivec2(0), ivec2(4)) + _961), vec2(0.5));\n    ivec2 _975 = ivec2(max(_963 - _971, vec2(0.0)));\n    bvec2 _977 = notEqual(_975, ivec2(_963 + _971));\n    bool _978 = _977.x;\n    bool _979 = _977.y;\n    WriteFeedbackArray(_24, ivec3(_975, _893), uint64_t(((1 | (_978 ? 2 : 0)) | (_979 ? 4 : 0)) | ((_978 && _979) ? 8 : 0)) << uint64_t(_906 * 4), (!gl_HelperInvocation) && (_904 != _906));\n    int _997 = int(roundEven(gl_FragCoord.z));\n    ivec2 _1001 = imageSize(_24).xy & ivec2(15);\n    int _1003 = textureQueryLevels(_11) - 1;\n    float _1005 = spvNClamp(_76, 0.0, float(_1003));\n    int _1006 = int(_1005);\n    int _1008 = int(_1005 + 0.9970703125);\n    vec2 _1011 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _1015 = -_1001;\n    vec2 _1017 = _1011 * ldexp(vec2(textureSize(_11, _1006).xy), _1015);\n    vec2 _1018 = ldexp(vec2(0.5), _1015);\n    ivec2 _1022 = ivec2(max(_1017 - _1018, vec2(0.0)));\n    bvec2 _1024 = notEqual(_1022, ivec2(_1017 + _1018));\n    bool _1025 = _1024.x;\n    bool _1026 = _1024.y;\n    WriteFeedbackArray(_24, ivec3(_1022, _997), uint64_t(((1 | (_1025 ? 2 : 0)) | (_1026 ? 4 : 0)) | ((_1025 && _1026) ? 8 : 0)) << uint64_t(_1006 * 4), !gl_HelperInvocation);\n    ivec2 _1045 = -_1001;\n    vec2 _1047 = _1011 * ldexp(vec2(textureSize(_11, _1008).xy), _1045);\n    vec2 _1048 = ldexp(vec2(0.5), _1045);\n    ivec2 _1052 = ivec2(max(_1047 - _1048, vec2(0.0)));\n    bvec2 _1054 = notEqual(_1052, ivec2(_1047 + _1048));\n    bool _1055 = _1054.x;\n    bool _1056 = _1054.y;\n    WriteFeedbackArray(_24, ivec3(_1052, _997), uint64_t(((1 | (_1055 ? 2 : 0)) | (_1056 ? 4 : 0)) | ((_1055 && _1056) ? 8 : 0)) << uint64_t(_1008 * 4), (!gl_HelperInvocation) && (_1006 != _1008));\n    int _1074 = int(roundEven(gl_FragCoord.z));\n    ivec2 _1078 = imageSize(_24).xy & ivec2(15);\n    int _1080 = textureQueryLevels(_11) - 1;\n    vec2 _1081 = vec2(textureSize(_11, 0).xy);\n    vec2 _1086 = _1081 * vec2(GRADX.x, GRADX.y);\n    vec2 _1087 = _1081 * vec2(GRADY.x, GRADY.y);\n    float _1094 = spvNClamp(log2(max(dot(_1086, _1086), dot(_1087, _1087))) * 0.5, 0.0, float(_1080));\n    int _1095 = int(_1094);\n    int _1097 = int(_1094 + 0.9970703125);\n    vec2 _1100 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _1104 = -_1078;\n    vec2 _1106 = _1100 * ldexp(vec2(textureSize(_11, _1095).xy), _1104);\n    vec2 _1107 = ldexp(vec2(0.5), _1104);\n    ivec2 _1111 = ivec2(max(_1106 - _1107, vec2(0.0)));\n    bvec2 _1113 = notEqual(_1111, ivec2(_1106 + _1107));\n    bool _1114 = _1113.x;\n    bool _1115 = _1113.y;\n    WriteFeedbackArray(_24, ivec3(_1111, _1074), uint64_t(((1 | (_1114 ? 2 : 0)) | (_1115 ? 4 : 0)) | ((_1114 && _1115) ? 8 : 0)) << uint64_t(_1095 * 4), !gl_HelperInvocation);\n    ivec2 _1134 = -_1078;\n    vec2 _1136 = _1100 * ldexp(vec2(textureSize(_11, _1097).xy), _1134);\n    vec2 _1137 = ldexp(vec2(0.5), _1134);\n    ivec2 _1141 = ivec2(max(_1136 - _1137, vec2(0.0)));\n    bvec2 _1143 = notEqual(_1141, ivec2(_1136 + _1137));\n    bool _1144 = _1143.x;\n    bool _1145 = _1143.y;\n    WriteFeedbackArray(_24, ivec3(_1141, _1074), uint64_t(((1 | (_1144 ? 2 : 0)) | (_1145 ? 4 : 0)) | ((_1144 && _1145) ? 8 : 0)) << uint64_t(_1097 * 4), (!gl_HelperInvocation) && (_1095 != _1097));\n    int _1163 = int(roundEven(gl_FragCoord.z));\n    ivec2 _1167 = imageSize(_24).xy & ivec2(15);\n    int _1169 = textureQueryLevels(_11) - 1;\n    vec2 _1170 = vec2(textureSize(_11, 0).xy);\n    vec2 _1175 = _1170 * vec2(GRADX.x, GRADX.y);\n    vec2 _1176 = _1170 * vec2(GRADY.x, GRADY.y);\n    float _1185 = min(max(spvNClamp(log2(max(dot(_1175, _1175), dot(_1176, _1176))) * 0.5, 0.0, float(_1169)), CLAMP), 14.0);\n    int _1186 = int(_1185);\n    int _1188 = int(_1185 + 0.9970703125);\n    vec2 _1191 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _1195 = -_1167;\n    vec2 _1197 = _1191 * ldexp(vec2(textureSize(_11, _1186).xy), _1195);\n    vec2 _1198 = ldexp(vec2(0.5), _1195);\n    ivec2 _1202 = ivec2(max(_1197 - _1198, vec2(0.0)));\n    bvec2 _1204 = notEqual(_1202, ivec2(_1197 + _1198));\n    bool _1205 = _1204.x;\n    bool _1206 = _1204.y;\n    WriteFeedbackArray(_24, ivec3(_1202, _1163), uint64_t(((1 | (_1205 ? 2 : 0)) | (_1206 ? 4 : 0)) | ((_1205 && _1206) ? 8 : 0)) << uint64_t(_1186 * 4), !gl_HelperInvocation);\n    ivec2 _1225 = -_1167;\n    vec2 _1227 = _1191 * ldexp(vec2(textureSize(_11, _1188).xy), _1225);\n    vec2 _1228 = ldexp(vec2(0.5), _1225);\n    ivec2 _1232 = ivec2(max(_1227 - _1228, vec2(0.0)));\n    bvec2 _1234 = notEqual(_1232, ivec2(_1227 + _1228));\n    bool _1235 = _1234.x;\n    bool _1236 = _1234.y;\n    WriteFeedbackArray(_24, ivec3(_1232, _1163), uint64_t(((1 | (_1235 ? 2 : 0)) | (_1236 ? 4 : 0)) | ((_1235 && _1236) ? 8 : 0)) << uint64_t(_1188 * 4), (!gl_HelperInvocation) && (_1186 != _1188));\n    int _1254 = int(roundEven(gl_FragCoord.z));\n    vec2 _1255 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1258 = imageSize(_24).xy & ivec2(15);\n    float _1261 = exp2(gl_FragCoord.z);\n    vec2 _1264 = textureQueryLod(sampler2DArray(_11, _33), _1255 * subgroupQuadBroadcast(_1261, 0u));\n    float _1265 = _1264.x;\n    int _1266 = int(_1265);\n    int _1268 = int(_1265 + 0.9970703125);\n    vec2 _1273 = abs(dFdx(_1255));\n    vec2 _1274 = abs(dFdy(_1255));\n    vec2 _1282 = vec2(max(_1273.x, _1274.x), max(_1273.y, _1274.y)) * _1261;\n    vec2 _1283 = fract(_1255);\n    vec2 _1284 = vec2(textureSize(_11, _1266).xy);\n    ivec2 _1287 = -_1258;\n    vec2 _1289 = _1283 * ldexp(_1284, _1287);\n    ResType _1292;\n    _1292._m0 = frexp((_1282 * _1284) - vec2(0.00390625), _1292._m1);\n    vec2 _1297 = min(ldexp(vec2(0.5), clamp(_1292._m1, ivec2(0), ivec2(4)) + _1287), vec2(0.5));\n    ivec2 _1301 = ivec2(max(_1289 - _1297, vec2(0.0)));\n    bvec2 _1303 = notEqual(_1301, ivec2(_1289 + _1297));\n    bool _1304 = _1303.x;\n    bool _1305 = _1303.y;\n    WriteFeedbackArray(_24, ivec3(_1301, _1254), uint64_t(((1 | (_1304 ? 2 : 0)) | (_1305 ? 4 : 0)) | ((_1304 && _1305) ? 8 : 0)) << uint64_t(_1266 * 4), !gl_HelperInvocation);\n    vec2 _1321 = vec2(textureSize(_11, _1268).xy);\n    ivec2 _1324 = -_1258;\n    vec2 _1326 = _1283 * ldexp(_1321, _1324);\n    ResType _1329;\n    _1329._m0 = frexp((_1282 * _1321) - vec2(0.00390625), _1329._m1);\n    vec2 _1334 = min(ldexp(vec2(0.5), clamp(_1329._m1, ivec2(0), ivec2(4)) + _1324), vec2(0.5));\n    ivec2 _1338 = ivec2(max(_1326 - _1334, vec2(0.0)));\n    bvec2 _1340 = notEqual(_1338, ivec2(_1326 + _1334));\n    bool _1341 = _1340.x;\n    bool _1342 = _1340.y;\n    WriteFeedbackArray(_24, ivec3(_1338, _1254), uint64_t(((1 | (_1341 ? 2 : 0)) | (_1342 ? 4 : 0)) | ((_1341 && _1342) ? 8 : 0)) << uint64_t(_1268 * 4), (!gl_HelperInvocation) && (_1266 != _1268));\n    int _1360 = int(roundEven(gl_FragCoord.z));\n    vec2 _1361 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1364 = imageSize(_24).xy & ivec2(15);\n    float _1367 = exp2(_76);\n    float _1373 = min(max(textureQueryLod(sampler2DArray(_11, _33), _1361 * subgroupQuadBroadcast(_1367, 0u)).x, CLAMP), 14.0);\n    int _1374 = int(_1373);\n    int _1376 = int(_1373 + 0.9970703125);\n    vec2 _1381 = abs(dFdx(_1361));\n    vec2 _1382 = abs(dFdy(_1361));\n    vec2 _1390 = vec2(max(_1381.x, _1382.x), max(_1381.y, _1382.y)) * _1367;\n    vec2 _1391 = fract(_1361);\n    vec2 _1392 = vec2(textureSize(_11, _1374).xy);\n    ivec2 _1395 = -_1364;\n    vec2 _1397 = _1391 * ldexp(_1392, _1395);\n    ResType _1400;\n    _1400._m0 = frexp((_1390 * _1392) - vec2(0.00390625), _1400._m1);\n    vec2 _1405 = min(ldexp(vec2(0.5), clamp(_1400._m1, ivec2(0), ivec2(4)) + _1395), vec2(0.5));\n    ivec2 _1409 = ivec2(max(_1397 - _1405, vec2(0.0)));\n    bvec2 _1411 = notEqual(_1409, ivec2(_1397 + _1405));\n    bool _1412 = _1411.x;\n    bool _1413 = _1411.y;\n    WriteFeedbackArray(_24, ivec3(_1409, _1360), uint64_t(((1 | (_1412 ? 2 : 0)) | (_1413 ? 4 : 0)) | ((_1412 && _1413) ? 8 : 0)) << uint64_t(_1374 * 4), !gl_HelperInvocation);\n    vec2 _1429 = vec2(textureSize(_11, _1376).xy);\n    ivec2 _1432 = -_1364;\n    vec2 _1434 = _1391 * ldexp(_1429, _1432);\n    ResType _1437;\n    _1437._m0 = frexp((_1390 * _1429) - vec2(0.00390625), _1437._m1);\n    vec2 _1442 = min(ldexp(vec2(0.5), clamp(_1437._m1, ivec2(0), ivec2(4)) + _1432), vec2(0.5));\n    ivec2 _1446 = ivec2(max(_1434 - _1442, vec2(0.0)));\n    bvec2 _1448 = notEqual(_1446, ivec2(_1434 + _1442));\n    bool _1449 = _1448.x;\n    bool _1450 = _1448.y;\n    WriteFeedbackArray(_24, ivec3(_1446, _1360), uint64_t(((1 | (_1449 ? 2 : 0)) | (_1450 ? 4 : 0)) | ((_1449 && _1450) ? 8 : 0)) << uint64_t(_1376 * 4), (!gl_HelperInvocation) && (_1374 != _1376));\n    uint _1467 = IDX + 0u;\n    uint _1470 = IDX + 0u;\n    uint _1473 = IDX + 0u;\n    vec2 _1476 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1478 = imageSize(_27[nonuniformEXT(_1467)]) & ivec2(15);\n    vec2 _1482 = textureQueryLod(nonuniformEXT(sampler2D(_14[_1470], _36[_1473])), _1476);\n    float _1483 = _1482.x;\n    int _1484 = int(_1483);\n    int _1486 = int(_1483 + 0.9970703125);\n    vec2 _1491 = abs(dFdx(_1476));\n    vec2 _1492 = abs(dFdy(_1476));\n    vec2 _1499 = vec2(max(_1491.x, _1492.x), max(_1491.y, _1492.y));\n    vec2 _1500 = fract(_1476);\n    vec2 _1501 = vec2(textureSize(_14[nonuniformEXT(_1470)], _1484));\n    ivec2 _1503 = -_1478;\n    vec2 _1505 = _1500 * ldexp(_1501, _1503);\n    ResType _1508;\n    _1508._m0 = frexp((_1499 * _1501) - vec2(0.00390625), _1508._m1);\n    vec2 _1513 = min(ldexp(vec2(0.5), clamp(_1508._m1, ivec2(0), ivec2(4)) + _1503), vec2(0.5));\n    ivec2 _1517 = ivec2(max(_1505 - _1513, vec2(0.0)));\n    bvec2 _1519 = notEqual(_1517, ivec2(_1505 + _1513));\n    bool _1520 = _1519.x;\n    bool _1521 = _1519.y;\n    WriteFeedbackNonUniform(_27[_1467], _1517, uint64_t(((1 | (_1520 ? 2 : 0)) | (_1521 ? 4 : 0)) | ((_1520 && _1521) ? 8 : 0)) << uint64_t(_1484 * 4), !gl_HelperInvocation);\n    vec2 _1562 = vec2(textureSize(_14[nonuniformEXT(_1470)], _1486));\n    ivec2 _1564 = -_1478;\n    vec2 _1566 = _1500 * ldexp(_1562, _1564);\n    ResType _1569;\n    _1569._m0 = frexp((_1499 * _1562) - vec2(0.00390625), _1569._m1);\n    vec2 _1574 = min(ldexp(vec2(0.5), clamp(_1569._m1, ivec2(0), ivec2(4)) + _1564), vec2(0.5));\n    ivec2 _1578 = ivec2(max(_1566 - _1574, vec2(0.0)));\n    bvec2 _1580 = notEqual(_1578, ivec2(_1566 + _1574));\n    bool _1581 = _1580.x;\n    bool _1582 = _1580.y;\n    WriteFeedbackNonUniform(_27[_1467], _1578, uint64_t(((1 | (_1581 ? 2 : 0)) | (_1582 ? 4 : 0)) | ((_1581 && _1582) ? 8 : 0)) << uint64_t(_1486 * 4), (!gl_HelperInvocation) && (_1484 != _1486));\n    uint _1598 = IDX + 0u;\n    uint _1601 = IDX + 0u;\n    int _1605 = int(roundEven(gl_FragCoord.z));\n    vec2 _1606 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1609 = imageSize(_30[nonuniformEXT(_1598)]).xy & ivec2(15);\n    vec2 _1613 = textureQueryLod(nonuniformEXT(sampler2DArray(_17[_1601], _36[_1473])), _1606);\n    float _1614 = _1613.x;\n    int _1615 = int(_1614);\n    int _1617 = int(_1614 + 0.9970703125);\n    vec2 _1622 = abs(dFdx(_1606));\n    vec2 _1623 = abs(dFdy(_1606));\n    vec2 _1630 = vec2(max(_1622.x, _1623.x), max(_1622.y, _1623.y));\n    vec2 _1631 = fract(_1606);\n    vec2 _1632 = vec2(textureSize(_17[nonuniformEXT(_1601)], _1615).xy);\n    ivec2 _1635 = -_1609;\n    vec2 _1637 = _1631 * ldexp(_1632, _1635);\n    ResType _1640;\n    _1640._m0 = frexp((_1630 * _1632) - vec2(0.00390625), _1640._m1);\n    vec2 _1645 = min(ldexp(vec2(0.5), clamp(_1640._m1, ivec2(0), ivec2(4)) + _1635), vec2(0.5));\n    ivec2 _1649 = ivec2(max(_1637 - _1645, vec2(0.0)));\n    bvec2 _1651 = notEqual(_1649, ivec2(_1637 + _1645));\n    bool _1652 = _1651.x;\n    bool _1653 = _1651.y;\n    WriteFeedbackArrayNonUniform(_30[_1598], ivec3(_1649, _1605), uint64_t(((1 | (_1652 ? 2 : 0)) | (_1653 ? 4 : 0)) | ((_1652 && _1653) ? 8 : 0)) << uint64_t(_1615 * 4), !gl_HelperInvocation);\n    vec2 _1695 = vec2(textureSize(_17[nonuniformEXT(_1601)], _1617).xy);\n    ivec2 _1698 = -_1609;\n    vec2 _1700 = _1631 * ldexp(_1695, _1698);\n    ResType _1703;\n    _1703._m0 = frexp((_1630 * _1695) - vec2(0.00390625), _1703._m1);\n    vec2 _1708 = min(ldexp(vec2(0.5), clamp(_1703._m1, ivec2(0), ivec2(4)) + _1698), vec2(0.5));\n    ivec2 _1712 = ivec2(max(_1700 - _1708, vec2(0.0)));\n    bvec2 _1714 = notEqual(_1712, ivec2(_1700 + _1708));\n    bool _1715 = _1714.x;\n    bool _1716 = _1714.y;\n    WriteFeedbackArrayNonUniform(_30[_1598], ivec3(_1712, _1605), uint64_t(((1 | (_1715 ? 2 : 0)) | (_1716 ? 4 : 0)) | ((_1715 && _1716) ? 8 : 0)) << uint64_t(_1617 * 4), (!gl_HelperInvocation) && (_1615 != _1617));\n    vec2 _1733 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1735 = imageSize(_27[nonuniformEXT(_1467)]) & ivec2(15);\n    vec2 _1738 = textureQueryLod(nonuniformEXT(sampler2D(_14[_1470], _36[_1473])), _1733);\n    float _1739 = _1738.x;\n    int _1740 = int(_1739);\n    int _1742 = int(_1739 + 0.9970703125);\n    vec2 _1747 = abs(dFdx(_1733));\n    vec2 _1748 = abs(dFdy(_1733));\n    vec2 _1755 = vec2(max(_1747.x, _1748.x), max(_1747.y, _1748.y));\n    vec2 _1756 = fract(_1733);\n    vec2 _1757 = vec2(textureSize(_14[nonuniformEXT(_1470)], _1740));\n    ivec2 _1759 = -_1735;\n    vec2 _1761 = _1756 * ldexp(_1757, _1759);\n    ResType _1764;\n    _1764._m0 = frexp((_1755 * _1757) - vec2(0.00390625), _1764._m1);\n    vec2 _1769 = min(ldexp(vec2(0.5), clamp(_1764._m1, ivec2(0), ivec2(4)) + _1759), vec2(0.5));\n    ivec2 _1773 = ivec2(max(_1761 - _1769, vec2(0.0)));\n    bvec2 _1775 = notEqual(_1773, ivec2(_1761 + _1769));\n    bool _1776 = _1775.x;\n    bool _1777 = _1775.y;\n    WriteFeedbackNonUniform(_27[_1467], _1773, uint64_t(((1 | (_1776 ? 2 : 0)) | (_1777 ? 4 : 0)) | ((_1776 && _1777) ? 8 : 0)) << uint64_t(_1740 * 4), !gl_HelperInvocation);\n    vec2 _1792 = vec2(textureSize(_14[nonuniformEXT(_1470)], _1742));\n    ivec2 _1794 = -_1735;\n    vec2 _1796 = _1756 * ldexp(_1792, _1794);\n    ResType _1799;\n    _1799._m0 = frexp((_1755 * _1792) - vec2(0.00390625), _1799._m1);\n    vec2 _1804 = min(ldexp(vec2(0.5), clamp(_1799._m1, ivec2(0), ivec2(4)) + _1794), vec2(0.5));\n    ivec2 _1808 = ivec2(max(_1796 - _1804, vec2(0.0)));\n    bvec2 _1810 = notEqual(_1808, ivec2(_1796 + _1804));\n    bool _1811 = _1810.x;\n    bool _1812 = _1810.y;\n    WriteFeedbackNonUniform(_27[_1467], _1808, uint64_t(((1 | (_1811 ? 2 : 0)) | (_1812 ? 4 : 0)) | ((_1811 && _1812) ? 8 : 0)) << uint64_t(_1742 * 4), (!gl_HelperInvocation) && (_1740 != _1742));\n    int _1829 = int(roundEven(gl_FragCoord.z));\n    vec2 _1830 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1833 = imageSize(_30[nonuniformEXT(_1598)]).xy & ivec2(15);\n    vec2 _1836 = textureQueryLod(nonuniformEXT(sampler2DArray(_17[_1601], _36[_1473])), _1830);\n    float _1837 = _1836.x;\n    int _1838 = int(_1837);\n    int _1840 = int(_1837 + 0.9970703125);\n    vec2 _1845 = abs(dFdx(_1830));\n    vec2 _1846 = abs(dFdy(_1830));\n    vec2 _1853 = vec2(max(_1845.x, _1846.x), max(_1845.y, _1846.y));\n    vec2 _1854 = fract(_1830);\n    vec2 _1855 = vec2(textureSize(_17[nonuniformEXT(_1601)], _1838).xy);\n    ivec2 _1858 = -_1833;\n    vec2 _1860 = _1854 * ldexp(_1855, _1858);\n    ResType _1863;\n    _1863._m0 = frexp((_1853 * _1855) - vec2(0.00390625), _1863._m1);\n    vec2 _1868 = min(ldexp(vec2(0.5), clamp(_1863._m1, ivec2(0), ivec2(4)) + _1858), vec2(0.5));\n    ivec2 _1872 = ivec2(max(_1860 - _1868, vec2(0.0)));\n    bvec2 _1874 = notEqual(_1872, ivec2(_1860 + _1868));\n    bool _1875 = _1874.x;\n    bool _1876 = _1874.y;\n    WriteFeedbackArrayNonUniform(_30[_1598], ivec3(_1872, _1829), uint64_t(((1 | (_1875 ? 2 : 0)) | (_1876 ? 4 : 0)) | ((_1875 && _1876) ? 8 : 0)) << uint64_t(_1838 * 4), !gl_HelperInvocation);\n    vec2 _1892 = vec2(textureSize(_17[nonuniformEXT(_1601)], _1840).xy);\n    ivec2 _1895 = -_1833;\n    vec2 _1897 = _1854 * ldexp(_1892, _1895);\n    ResType _1900;\n    _1900._m0 = frexp((_1853 * _1892) - vec2(0.00390625), _1900._m1);\n    vec2 _1905 = min(ldexp(vec2(0.5), clamp(_1900._m1, ivec2(0), ivec2(4)) + _1895), vec2(0.5));\n    ivec2 _1909 = ivec2(max(_1897 - _1905, vec2(0.0)));\n    bvec2 _1911 = notEqual(_1909, ivec2(_1897 + _1905));\n    bool _1912 = _1911.x;\n    bool _1913 = _1911.y;\n    WriteFeedbackArrayNonUniform(_30[_1598], ivec3(_1909, _1829), uint64_t(((1 | (_1912 ? 2 : 0)) | (_1913 ? 4 : 0)) | ((_1912 && _1913) ? 8 : 0)) << uint64_t(_1840 * 4), (!gl_HelperInvocation) && (_1838 != _1840));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 1934\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageQuery\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability GroupNonUniformQuad\nOpCapability Int64ImageEXT\nOpCapability RuntimeDescriptorArray\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_shader_image_int64\"\n%78 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %39 %42 %43 %45 %48 %1932\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %39 \"SV_Position\"\nOpName %42 \"GRADX\"\nOpName %43 \"GRADY\"\nOpName %45 \"CLAMP\"\nOpName %48 \"IDX\"\nOpName %122 \"ResType\"\nOpName %166 \"WriteFeedback\"\nOpName %162 \"img\"\nOpName %163 \"coord\"\nOpName %164 \"value\"\nOpName %165 \"active_lane\"\nOpName %179 \"is_done\"\nOpName %831 \"WriteFeedbackArray\"\nOpName %827 \"img\"\nOpName %828 \"coord\"\nOpName %829 \"value\"\nOpName %830 \"active_lane\"\nOpName %842 \"is_done\"\nOpName %1539 \"WriteFeedbackNonUniform\"\nOpName %1535 \"img\"\nOpName %1536 \"coord\"\nOpName %1537 \"value\"\nOpName %1538 \"active_lane\"\nOpName %1550 \"is_done\"\nOpName %1672 \"WriteFeedbackArrayNonUniform\"\nOpName %1668 \"img\"\nOpName %1669 \"coord\"\nOpName %1670 \"value\"\nOpName %1671 \"active_lane\"\nOpName %1683 \"is_done\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 1\nOpDecorate %14 DescriptorSet 1\nOpDecorate %14 Binding 0\nOpDecorate %17 DescriptorSet 2\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 0\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 1\nOpDecorate %27 DescriptorSet 1\nOpDecorate %27 Binding 0\nOpDecorate %30 DescriptorSet 2\nOpDecorate %30 Binding 0\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %36 DescriptorSet 1\nOpDecorate %36 Binding 0\nOpDecorate %39 BuiltIn FragCoord\nOpDecorate %42 Location 1\nOpDecorate %43 Location 1\nOpDecorate %43 Component 2\nOpDecorate %45 Location 2\nOpDecorate %48 Flat\nOpDecorate %48 Location 3\nOpDecorate %1467 NonUniform\nOpDecorate %1469 NonUniform\nOpDecorate %1470 NonUniform\nOpDecorate %1472 NonUniform\nOpDecorate %1473 NonUniform\nOpDecorate %1475 NonUniform\nOpDecorate %1481 NonUniform\nOpDecorate %1558 NonUniform\nOpDecorate %1598 NonUniform\nOpDecorate %1600 NonUniform\nOpDecorate %1601 NonUniform\nOpDecorate %1603 NonUniform\nOpDecorate %1612 NonUniform\nOpDecorate %1691 NonUniform\nOpDecorate %1932 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 1 0 1 Unknown\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpTypeRuntimeArray %6\n%13 = OpTypePointer UniformConstant %12\n%14 = OpVariable %13 UniformConstant\n%15 = OpTypeRuntimeArray %9\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeInt 64 0\n%19 = OpTypeImage %18 2D 0 0 0 2 R64ui\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeImage %18 2D 0 1 0 2 R64ui\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeRuntimeArray %19\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeRuntimeArray %22\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeSampler\n%32 = OpTypePointer UniformConstant %31\n%33 = OpVariable %32 UniformConstant\n%34 = OpTypeRuntimeArray %31\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeVector %5 4\n%38 = OpTypePointer Input %37\n%39 = OpVariable %38 Input\n%40 = OpTypeVector %5 2\n%41 = OpTypePointer Input %40\n%42 = OpVariable %41 Input\n%43 = OpVariable %41 Input\n%44 = OpTypePointer Input %5\n%45 = OpVariable %44 Input\n%46 = OpTypeInt 32 0\n%47 = OpTypePointer Input %46\n%48 = OpVariable %47 Input\n%57 = OpConstant %46 0\n%60 = OpConstant %46 1\n%71 = OpConstant %46 2\n%74 = OpConstant %46 3\n%77 = OpConstant %5 1\n%79 = OpTypeBool\n%80 = OpTypeInt 32 1\n%81 = OpTypeVector %79 2\n%82 = OpTypeVector %80 2\n%86 = OpConstant %80 15\n%87 = OpConstantComposite %82 %86 %86\n%90 = OpConstant %80 1\n%91 = OpTypeSampledImage %6\n%97 = OpConstant %5 0.997070312\n%120 = OpConstant %5 0.00390625\n%121 = OpConstantComposite %40 %120 %120\n%122 = OpTypeStruct %40 %82\n%126 = OpConstant %80 0\n%127 = OpConstantComposite %82 %126 %126\n%128 = OpConstant %80 4\n%129 = OpConstantComposite %82 %128 %128\n%132 = OpConstant %5 0.5\n%133 = OpConstantComposite %40 %132 %132\n%137 = OpConstant %5 0\n%138 = OpConstantComposite %40 %137 %137\n%147 = OpConstant %80 2\n%152 = OpConstant %80 8\n%160 = OpTypePointer Image %18\n%161 = OpTypeFunction %1 %20 %82 %18 %79\n%177 = OpConstantFalse %79\n%178 = OpTypePointer Function %79\n%236 = OpConstant %5 14\n%762 = OpTypeVector %80 3\n%768 = OpTypeSampledImage %9\n%825 = OpTypeVector %79 3\n%826 = OpTypeFunction %1 %23 %762 %18 %79\n%1931 = OpTypePointer Input %79\n%1932 = OpVariable %1931 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %1930\n%1930 = OpLabel\n%49 = OpLoad %22 %24\n%50 = OpLoad %19 %21\n%51 = OpLoad %9 %11\n%52 = OpLoad %6 %8\n%53 = OpLoad %31 %33\n%54 = OpLoad %46 %48\n%55 = OpLoad %5 %45\n%56 = OpAccessChain %44 %43 %57\n%58 = OpLoad %5 %56\n%59 = OpAccessChain %44 %43 %60\n%61 = OpLoad %5 %59\n%62 = OpAccessChain %44 %42 %57\n%63 = OpLoad %5 %62\n%64 = OpAccessChain %44 %42 %60\n%65 = OpLoad %5 %64\n%66 = OpAccessChain %44 %39 %57\n%67 = OpLoad %5 %66\n%68 = OpAccessChain %44 %39 %60\n%69 = OpLoad %5 %68\n%70 = OpAccessChain %44 %39 %71\n%72 = OpLoad %5 %70\n%73 = OpAccessChain %44 %39 %74\n%75 = OpLoad %5 %73\n%76 = OpFDiv %5 %77 %75\n%83 = OpCompositeConstruct %40 %67 %69\n%84 = OpImageQuerySize %82 %50\n%85 = OpBitwiseAnd %82 %84 %87\n%88 = OpImageQueryLevels %80 %52\n%89 = OpISub %80 %88 %90\n%92 = OpSampledImage %91 %52 %53\n%93 = OpImageQueryLod %40 %92 %83\n%94 = OpCompositeExtract %5 %93 0\n%95 = OpConvertFToS %80 %94\n%96 = OpFAdd %5 %94 %97\n%98 = OpConvertFToS %80 %96\n%99 = OpExtInst %80 %78 SMin %98 %89\n%100 = OpINotEqual %79 %95 %98\n%101 = OpDPdx %40 %83\n%102 = OpDPdy %40 %83\n%103 = OpExtInst %40 %78 FAbs %101\n%104 = OpExtInst %40 %78 FAbs %102\n%105 = OpCompositeExtract %5 %103 0\n%106 = OpCompositeExtract %5 %104 0\n%107 = OpCompositeExtract %5 %103 1\n%108 = OpCompositeExtract %5 %104 1\n%109 = OpExtInst %5 %78 FMax %105 %106\n%110 = OpExtInst %5 %78 FMax %107 %108\n%111 = OpCompositeConstruct %40 %109 %110\n%112 = OpExtInst %40 %78 Fract %83\n%114 = OpImageQuerySizeLod %82 %52 %95\n%113 = OpConvertSToF %40 %114\n%115 = OpSNegate %82 %85\n%116 = OpExtInst %40 %78 Ldexp %113 %115\n%117 = OpFMul %40 %112 %116\n%118 = OpFMul %40 %111 %113\n%119 = OpFSub %40 %118 %121\n%123 = OpExtInst %122 %78 FrexpStruct %119\n%124 = OpCompositeExtract %82 %123 1\n%125 = OpExtInst %82 %78 SClamp %124 %127 %129\n%130 = OpIAdd %82 %125 %115\n%131 = OpExtInst %40 %78 Ldexp %133 %130\n%134 = OpExtInst %40 %78 FMin %131 %133\n%135 = OpFSub %40 %117 %134\n%136 = OpExtInst %40 %78 FMax %135 %138\n%139 = OpFAdd %40 %117 %134\n%140 = OpConvertFToS %82 %136\n%141 = OpConvertFToS %82 %139\n%142 = OpINotEqual %81 %140 %141\n%143 = OpCompositeExtract %79 %142 0\n%144 = OpCompositeExtract %79 %142 1\n%145 = OpLogicalAnd %79 %143 %144\n%146 = OpSelect %80 %143 %147 %126\n%148 = OpBitwiseOr %80 %90 %146\n%149 = OpSelect %80 %144 %128 %126\n%150 = OpBitwiseOr %80 %148 %149\n%151 = OpSelect %80 %145 %152 %126\n%153 = OpBitwiseOr %80 %150 %151\n%154 = OpSConvert %18 %153\n%155 = OpIMul %80 %95 %128\n%156 = OpSConvert %18 %155\n%157 = OpShiftLeftLogical %18 %154 %156\n%158 = OpLoad %79 %1932\n%159 = OpLogicalNot %79 %158\n%190 = OpFunctionCall %1 %166 %21 %140 %157 %159\n%192 = OpImageQuerySizeLod %82 %52 %98\n%191 = OpConvertSToF %40 %192\n%193 = OpSNegate %82 %85\n%194 = OpExtInst %40 %78 Ldexp %191 %193\n%195 = OpFMul %40 %112 %194\n%196 = OpFMul %40 %111 %191\n%197 = OpFSub %40 %196 %121\n%198 = OpExtInst %122 %78 FrexpStruct %197\n%199 = OpCompositeExtract %82 %198 1\n%200 = OpExtInst %82 %78 SClamp %199 %127 %129\n%201 = OpIAdd %82 %200 %193\n%202 = OpExtInst %40 %78 Ldexp %133 %201\n%203 = OpExtInst %40 %78 FMin %202 %133\n%204 = OpFSub %40 %195 %203\n%205 = OpExtInst %40 %78 FMax %204 %138\n%206 = OpFAdd %40 %195 %203\n%207 = OpConvertFToS %82 %205\n%208 = OpConvertFToS %82 %206\n%209 = OpINotEqual %81 %207 %208\n%210 = OpCompositeExtract %79 %209 0\n%211 = OpCompositeExtract %79 %209 1\n%212 = OpLogicalAnd %79 %210 %211\n%213 = OpSelect %80 %210 %147 %126\n%214 = OpBitwiseOr %80 %90 %213\n%215 = OpSelect %80 %211 %128 %126\n%216 = OpBitwiseOr %80 %214 %215\n%217 = OpSelect %80 %212 %152 %126\n%218 = OpBitwiseOr %80 %216 %217\n%219 = OpSConvert %18 %218\n%220 = OpIMul %80 %98 %128\n%221 = OpSConvert %18 %220\n%222 = OpShiftLeftLogical %18 %219 %221\n%223 = OpLoad %79 %1932\n%224 = OpLogicalNot %79 %223\n%225 = OpLogicalAnd %79 %224 %100\n%226 = OpFunctionCall %1 %166 %21 %207 %222 %225\n%227 = OpCompositeConstruct %40 %67 %69\n%228 = OpImageQuerySize %82 %50\n%229 = OpBitwiseAnd %82 %228 %87\n%230 = OpImageQueryLevels %80 %52\n%231 = OpISub %80 %230 %90\n%232 = OpImageQueryLod %40 %92 %227\n%233 = OpCompositeExtract %5 %232 0\n%234 = OpExtInst %5 %78 FMax %233 %55\n%235 = OpExtInst %5 %78 FMin %234 %236\n%237 = OpConvertFToS %80 %235\n%238 = OpFAdd %5 %235 %97\n%239 = OpConvertFToS %80 %238\n%240 = OpExtInst %80 %78 SMin %239 %231\n%241 = OpINotEqual %79 %237 %239\n%242 = OpDPdx %40 %227\n%243 = OpDPdy %40 %227\n%244 = OpExtInst %40 %78 FAbs %242\n%245 = OpExtInst %40 %78 FAbs %243\n%246 = OpCompositeExtract %5 %244 0\n%247 = OpCompositeExtract %5 %245 0\n%248 = OpCompositeExtract %5 %244 1\n%249 = OpCompositeExtract %5 %245 1\n%250 = OpExtInst %5 %78 FMax %246 %247\n%251 = OpExtInst %5 %78 FMax %248 %249\n%252 = OpCompositeConstruct %40 %250 %251\n%253 = OpExtInst %40 %78 Fract %227\n%255 = OpImageQuerySizeLod %82 %52 %237\n%254 = OpConvertSToF %40 %255\n%256 = OpSNegate %82 %229\n%257 = OpExtInst %40 %78 Ldexp %254 %256\n%258 = OpFMul %40 %253 %257\n%259 = OpFMul %40 %252 %254\n%260 = OpFSub %40 %259 %121\n%261 = OpExtInst %122 %78 FrexpStruct %260\n%262 = OpCompositeExtract %82 %261 1\n%263 = OpExtInst %82 %78 SClamp %262 %127 %129\n%264 = OpIAdd %82 %263 %256\n%265 = OpExtInst %40 %78 Ldexp %133 %264\n%266 = OpExtInst %40 %78 FMin %265 %133\n%267 = OpFSub %40 %258 %266\n%268 = OpExtInst %40 %78 FMax %267 %138\n%269 = OpFAdd %40 %258 %266\n%270 = OpConvertFToS %82 %268\n%271 = OpConvertFToS %82 %269\n%272 = OpINotEqual %81 %270 %271\n%273 = OpCompositeExtract %79 %272 0\n%274 = OpCompositeExtract %79 %272 1\n%275 = OpLogicalAnd %79 %273 %274\n%276 = OpSelect %80 %273 %147 %126\n%277 = OpBitwiseOr %80 %90 %276\n%278 = OpSelect %80 %274 %128 %126\n%279 = OpBitwiseOr %80 %277 %278\n%280 = OpSelect %80 %275 %152 %126\n%281 = OpBitwiseOr %80 %279 %280\n%282 = OpSConvert %18 %281\n%283 = OpIMul %80 %237 %128\n%284 = OpSConvert %18 %283\n%285 = OpShiftLeftLogical %18 %282 %284\n%286 = OpLoad %79 %1932\n%287 = OpLogicalNot %79 %286\n%288 = OpFunctionCall %1 %166 %21 %270 %285 %287\n%290 = OpImageQuerySizeLod %82 %52 %239\n%289 = OpConvertSToF %40 %290\n%291 = OpSNegate %82 %229\n%292 = OpExtInst %40 %78 Ldexp %289 %291\n%293 = OpFMul %40 %253 %292\n%294 = OpFMul %40 %252 %289\n%295 = OpFSub %40 %294 %121\n%296 = OpExtInst %122 %78 FrexpStruct %295\n%297 = OpCompositeExtract %82 %296 1\n%298 = OpExtInst %82 %78 SClamp %297 %127 %129\n%299 = OpIAdd %82 %298 %291\n%300 = OpExtInst %40 %78 Ldexp %133 %299\n%301 = OpExtInst %40 %78 FMin %300 %133\n%302 = OpFSub %40 %293 %301\n%303 = OpExtInst %40 %78 FMax %302 %138\n%304 = OpFAdd %40 %293 %301\n%305 = OpConvertFToS %82 %303\n%306 = OpConvertFToS %82 %304\n%307 = OpINotEqual %81 %305 %306\n%308 = OpCompositeExtract %79 %307 0\n%309 = OpCompositeExtract %79 %307 1\n%310 = OpLogicalAnd %79 %308 %309\n%311 = OpSelect %80 %308 %147 %126\n%312 = OpBitwiseOr %80 %90 %311\n%313 = OpSelect %80 %309 %128 %126\n%314 = OpBitwiseOr %80 %312 %313\n%315 = OpSelect %80 %310 %152 %126\n%316 = OpBitwiseOr %80 %314 %315\n%317 = OpSConvert %18 %316\n%318 = OpIMul %80 %239 %128\n%319 = OpSConvert %18 %318\n%320 = OpShiftLeftLogical %18 %317 %319\n%321 = OpLoad %79 %1932\n%322 = OpLogicalNot %79 %321\n%323 = OpLogicalAnd %79 %322 %241\n%324 = OpFunctionCall %1 %166 %21 %305 %320 %323\n%325 = OpCompositeConstruct %40 %67 %69\n%326 = OpImageQuerySize %82 %50\n%327 = OpBitwiseAnd %82 %326 %87\n%328 = OpImageQueryLevels %80 %52\n%329 = OpISub %80 %328 %90\n%330 = OpConvertSToF %5 %329\n%331 = OpExtInst %5 %78 NClamp %72 %137 %330\n%332 = OpConvertFToS %80 %331\n%333 = OpFAdd %5 %331 %97\n%334 = OpConvertFToS %80 %333\n%335 = OpExtInst %80 %78 SMin %334 %329\n%336 = OpINotEqual %79 %332 %334\n%337 = OpExtInst %40 %78 Fract %325\n%339 = OpImageQuerySizeLod %82 %52 %332\n%338 = OpConvertSToF %40 %339\n%340 = OpSNegate %82 %327\n%341 = OpExtInst %40 %78 Ldexp %338 %340\n%342 = OpFMul %40 %337 %341\n%343 = OpExtInst %40 %78 Ldexp %133 %340\n%344 = OpFSub %40 %342 %343\n%345 = OpExtInst %40 %78 FMax %344 %138\n%346 = OpFAdd %40 %342 %343\n%347 = OpConvertFToS %82 %345\n%348 = OpConvertFToS %82 %346\n%349 = OpINotEqual %81 %347 %348\n%350 = OpCompositeExtract %79 %349 0\n%351 = OpCompositeExtract %79 %349 1\n%352 = OpLogicalAnd %79 %350 %351\n%353 = OpSelect %80 %350 %147 %126\n%354 = OpBitwiseOr %80 %90 %353\n%355 = OpSelect %80 %351 %128 %126\n%356 = OpBitwiseOr %80 %354 %355\n%357 = OpSelect %80 %352 %152 %126\n%358 = OpBitwiseOr %80 %356 %357\n%359 = OpSConvert %18 %358\n%360 = OpIMul %80 %332 %128\n%361 = OpSConvert %18 %360\n%362 = OpShiftLeftLogical %18 %359 %361\n%363 = OpLoad %79 %1932\n%364 = OpLogicalNot %79 %363\n%365 = OpFunctionCall %1 %166 %21 %347 %362 %364\n%367 = OpImageQuerySizeLod %82 %52 %334\n%366 = OpConvertSToF %40 %367\n%368 = OpSNegate %82 %327\n%369 = OpExtInst %40 %78 Ldexp %366 %368\n%370 = OpFMul %40 %337 %369\n%371 = OpExtInst %40 %78 Ldexp %133 %368\n%372 = OpFSub %40 %370 %371\n%373 = OpExtInst %40 %78 FMax %372 %138\n%374 = OpFAdd %40 %370 %371\n%375 = OpConvertFToS %82 %373\n%376 = OpConvertFToS %82 %374\n%377 = OpINotEqual %81 %375 %376\n%378 = OpCompositeExtract %79 %377 0\n%379 = OpCompositeExtract %79 %377 1\n%380 = OpLogicalAnd %79 %378 %379\n%381 = OpSelect %80 %378 %147 %126\n%382 = OpBitwiseOr %80 %90 %381\n%383 = OpSelect %80 %379 %128 %126\n%384 = OpBitwiseOr %80 %382 %383\n%385 = OpSelect %80 %380 %152 %126\n%386 = OpBitwiseOr %80 %384 %385\n%387 = OpSConvert %18 %386\n%388 = OpIMul %80 %334 %128\n%389 = OpSConvert %18 %388\n%390 = OpShiftLeftLogical %18 %387 %389\n%391 = OpLoad %79 %1932\n%392 = OpLogicalNot %79 %391\n%393 = OpLogicalAnd %79 %392 %336\n%394 = OpFunctionCall %1 %166 %21 %375 %390 %393\n%395 = OpCompositeConstruct %40 %67 %69\n%396 = OpImageQuerySize %82 %50\n%397 = OpBitwiseAnd %82 %396 %87\n%398 = OpImageQueryLevels %80 %52\n%399 = OpISub %80 %398 %90\n%401 = OpImageQuerySizeLod %82 %52 %126\n%400 = OpConvertSToF %40 %401\n%402 = OpCompositeConstruct %40 %63 %65\n%403 = OpCompositeConstruct %40 %58 %61\n%404 = OpFMul %40 %400 %402\n%405 = OpFMul %40 %400 %403\n%406 = OpDot %5 %404 %404\n%407 = OpDot %5 %405 %405\n%408 = OpExtInst %5 %78 FMax %406 %407\n%409 = OpExtInst %5 %78 Log2 %408\n%410 = OpFMul %5 %409 %132\n%411 = OpConvertSToF %5 %399\n%412 = OpExtInst %5 %78 NClamp %410 %137 %411\n%413 = OpConvertFToS %80 %412\n%414 = OpFAdd %5 %412 %97\n%415 = OpConvertFToS %80 %414\n%416 = OpExtInst %80 %78 SMin %415 %399\n%417 = OpINotEqual %79 %413 %415\n%418 = OpExtInst %40 %78 Fract %395\n%420 = OpImageQuerySizeLod %82 %52 %413\n%419 = OpConvertSToF %40 %420\n%421 = OpSNegate %82 %397\n%422 = OpExtInst %40 %78 Ldexp %419 %421\n%423 = OpFMul %40 %418 %422\n%424 = OpExtInst %40 %78 Ldexp %133 %421\n%425 = OpFSub %40 %423 %424\n%426 = OpExtInst %40 %78 FMax %425 %138\n%427 = OpFAdd %40 %423 %424\n%428 = OpConvertFToS %82 %426\n%429 = OpConvertFToS %82 %427\n%430 = OpINotEqual %81 %428 %429\n%431 = OpCompositeExtract %79 %430 0\n%432 = OpCompositeExtract %79 %430 1\n%433 = OpLogicalAnd %79 %431 %432\n%434 = OpSelect %80 %431 %147 %126\n%435 = OpBitwiseOr %80 %90 %434\n%436 = OpSelect %80 %432 %128 %126\n%437 = OpBitwiseOr %80 %435 %436\n%438 = OpSelect %80 %433 %152 %126\n%439 = OpBitwiseOr %80 %437 %438\n%440 = OpSConvert %18 %439\n%441 = OpIMul %80 %413 %128\n%442 = OpSConvert %18 %441\n%443 = OpShiftLeftLogical %18 %440 %442\n%444 = OpLoad %79 %1932\n%445 = OpLogicalNot %79 %444\n%446 = OpFunctionCall %1 %166 %21 %428 %443 %445\n%448 = OpImageQuerySizeLod %82 %52 %415\n%447 = OpConvertSToF %40 %448\n%449 = OpSNegate %82 %397\n%450 = OpExtInst %40 %78 Ldexp %447 %449\n%451 = OpFMul %40 %418 %450\n%452 = OpExtInst %40 %78 Ldexp %133 %449\n%453 = OpFSub %40 %451 %452\n%454 = OpExtInst %40 %78 FMax %453 %138\n%455 = OpFAdd %40 %451 %452\n%456 = OpConvertFToS %82 %454\n%457 = OpConvertFToS %82 %455\n%458 = OpINotEqual %81 %456 %457\n%459 = OpCompositeExtract %79 %458 0\n%460 = OpCompositeExtract %79 %458 1\n%461 = OpLogicalAnd %79 %459 %460\n%462 = OpSelect %80 %459 %147 %126\n%463 = OpBitwiseOr %80 %90 %462\n%464 = OpSelect %80 %460 %128 %126\n%465 = OpBitwiseOr %80 %463 %464\n%466 = OpSelect %80 %461 %152 %126\n%467 = OpBitwiseOr %80 %465 %466\n%468 = OpSConvert %18 %467\n%469 = OpIMul %80 %415 %128\n%470 = OpSConvert %18 %469\n%471 = OpShiftLeftLogical %18 %468 %470\n%472 = OpLoad %79 %1932\n%473 = OpLogicalNot %79 %472\n%474 = OpLogicalAnd %79 %473 %417\n%475 = OpFunctionCall %1 %166 %21 %456 %471 %474\n%476 = OpCompositeConstruct %40 %67 %69\n%477 = OpImageQuerySize %82 %50\n%478 = OpBitwiseAnd %82 %477 %87\n%479 = OpImageQueryLevels %80 %52\n%480 = OpISub %80 %479 %90\n%482 = OpImageQuerySizeLod %82 %52 %126\n%481 = OpConvertSToF %40 %482\n%483 = OpCompositeConstruct %40 %63 %65\n%484 = OpCompositeConstruct %40 %58 %61\n%485 = OpFMul %40 %481 %483\n%486 = OpFMul %40 %481 %484\n%487 = OpDot %5 %485 %485\n%488 = OpDot %5 %486 %486\n%489 = OpExtInst %5 %78 FMax %487 %488\n%490 = OpExtInst %5 %78 Log2 %489\n%491 = OpFMul %5 %490 %132\n%492 = OpConvertSToF %5 %480\n%493 = OpExtInst %5 %78 NClamp %491 %137 %492\n%494 = OpExtInst %5 %78 FMax %493 %55\n%495 = OpExtInst %5 %78 FMin %494 %236\n%496 = OpConvertFToS %80 %495\n%497 = OpFAdd %5 %495 %97\n%498 = OpConvertFToS %80 %497\n%499 = OpExtInst %80 %78 SMin %498 %480\n%500 = OpINotEqual %79 %496 %498\n%501 = OpExtInst %40 %78 Fract %476\n%503 = OpImageQuerySizeLod %82 %52 %496\n%502 = OpConvertSToF %40 %503\n%504 = OpSNegate %82 %478\n%505 = OpExtInst %40 %78 Ldexp %502 %504\n%506 = OpFMul %40 %501 %505\n%507 = OpExtInst %40 %78 Ldexp %133 %504\n%508 = OpFSub %40 %506 %507\n%509 = OpExtInst %40 %78 FMax %508 %138\n%510 = OpFAdd %40 %506 %507\n%511 = OpConvertFToS %82 %509\n%512 = OpConvertFToS %82 %510\n%513 = OpINotEqual %81 %511 %512\n%514 = OpCompositeExtract %79 %513 0\n%515 = OpCompositeExtract %79 %513 1\n%516 = OpLogicalAnd %79 %514 %515\n%517 = OpSelect %80 %514 %147 %126\n%518 = OpBitwiseOr %80 %90 %517\n%519 = OpSelect %80 %515 %128 %126\n%520 = OpBitwiseOr %80 %518 %519\n%521 = OpSelect %80 %516 %152 %126\n%522 = OpBitwiseOr %80 %520 %521\n%523 = OpSConvert %18 %522\n%524 = OpIMul %80 %496 %128\n%525 = OpSConvert %18 %524\n%526 = OpShiftLeftLogical %18 %523 %525\n%527 = OpLoad %79 %1932\n%528 = OpLogicalNot %79 %527\n%529 = OpFunctionCall %1 %166 %21 %511 %526 %528\n%531 = OpImageQuerySizeLod %82 %52 %498\n%530 = OpConvertSToF %40 %531\n%532 = OpSNegate %82 %478\n%533 = OpExtInst %40 %78 Ldexp %530 %532\n%534 = OpFMul %40 %501 %533\n%535 = OpExtInst %40 %78 Ldexp %133 %532\n%536 = OpFSub %40 %534 %535\n%537 = OpExtInst %40 %78 FMax %536 %138\n%538 = OpFAdd %40 %534 %535\n%539 = OpConvertFToS %82 %537\n%540 = OpConvertFToS %82 %538\n%541 = OpINotEqual %81 %539 %540\n%542 = OpCompositeExtract %79 %541 0\n%543 = OpCompositeExtract %79 %541 1\n%544 = OpLogicalAnd %79 %542 %543\n%545 = OpSelect %80 %542 %147 %126\n%546 = OpBitwiseOr %80 %90 %545\n%547 = OpSelect %80 %543 %128 %126\n%548 = OpBitwiseOr %80 %546 %547\n%549 = OpSelect %80 %544 %152 %126\n%550 = OpBitwiseOr %80 %548 %549\n%551 = OpSConvert %18 %550\n%552 = OpIMul %80 %498 %128\n%553 = OpSConvert %18 %552\n%554 = OpShiftLeftLogical %18 %551 %553\n%555 = OpLoad %79 %1932\n%556 = OpLogicalNot %79 %555\n%557 = OpLogicalAnd %79 %556 %500\n%558 = OpFunctionCall %1 %166 %21 %539 %554 %557\n%559 = OpCompositeConstruct %40 %67 %69\n%560 = OpImageQuerySize %82 %50\n%561 = OpBitwiseAnd %82 %560 %87\n%562 = OpImageQueryLevels %80 %52\n%563 = OpISub %80 %562 %90\n%564 = OpExtInst %5 %78 Exp2 %72\n%565 = OpGroupNonUniformQuadBroadcast %5 %74 %564 %57\n%566 = OpVectorTimesScalar %40 %559 %565\n%567 = OpImageQueryLod %40 %92 %566\n%568 = OpCompositeExtract %5 %567 0\n%569 = OpConvertFToS %80 %568\n%570 = OpFAdd %5 %568 %97\n%571 = OpConvertFToS %80 %570\n%572 = OpExtInst %80 %78 SMin %571 %563\n%573 = OpINotEqual %79 %569 %571\n%574 = OpDPdx %40 %559\n%575 = OpDPdy %40 %559\n%576 = OpExtInst %40 %78 FAbs %574\n%577 = OpExtInst %40 %78 FAbs %575\n%578 = OpCompositeExtract %5 %576 0\n%579 = OpCompositeExtract %5 %577 0\n%580 = OpCompositeExtract %5 %576 1\n%581 = OpCompositeExtract %5 %577 1\n%582 = OpExtInst %5 %78 FMax %578 %579\n%583 = OpExtInst %5 %78 FMax %580 %581\n%584 = OpCompositeConstruct %40 %582 %583\n%585 = OpVectorTimesScalar %40 %584 %564\n%586 = OpExtInst %40 %78 Fract %559\n%588 = OpImageQuerySizeLod %82 %52 %569\n%587 = OpConvertSToF %40 %588\n%589 = OpSNegate %82 %561\n%590 = OpExtInst %40 %78 Ldexp %587 %589\n%591 = OpFMul %40 %586 %590\n%592 = OpFMul %40 %585 %587\n%593 = OpFSub %40 %592 %121\n%594 = OpExtInst %122 %78 FrexpStruct %593\n%595 = OpCompositeExtract %82 %594 1\n%596 = OpExtInst %82 %78 SClamp %595 %127 %129\n%597 = OpIAdd %82 %596 %589\n%598 = OpExtInst %40 %78 Ldexp %133 %597\n%599 = OpExtInst %40 %78 FMin %598 %133\n%600 = OpFSub %40 %591 %599\n%601 = OpExtInst %40 %78 FMax %600 %138\n%602 = OpFAdd %40 %591 %599\n%603 = OpConvertFToS %82 %601\n%604 = OpConvertFToS %82 %602\n%605 = OpINotEqual %81 %603 %604\n%606 = OpCompositeExtract %79 %605 0\n%607 = OpCompositeExtract %79 %605 1\n%608 = OpLogicalAnd %79 %606 %607\n%609 = OpSelect %80 %606 %147 %126\n%610 = OpBitwiseOr %80 %90 %609\n%611 = OpSelect %80 %607 %128 %126\n%612 = OpBitwiseOr %80 %610 %611\n%613 = OpSelect %80 %608 %152 %126\n%614 = OpBitwiseOr %80 %612 %613\n%615 = OpSConvert %18 %614\n%616 = OpIMul %80 %569 %128\n%617 = OpSConvert %18 %616\n%618 = OpShiftLeftLogical %18 %615 %617\n%619 = OpLoad %79 %1932\n%620 = OpLogicalNot %79 %619\n%621 = OpFunctionCall %1 %166 %21 %603 %618 %620\n%623 = OpImageQuerySizeLod %82 %52 %571\n%622 = OpConvertSToF %40 %623\n%624 = OpSNegate %82 %561\n%625 = OpExtInst %40 %78 Ldexp %622 %624\n%626 = OpFMul %40 %586 %625\n%627 = OpFMul %40 %585 %622\n%628 = OpFSub %40 %627 %121\n%629 = OpExtInst %122 %78 FrexpStruct %628\n%630 = OpCompositeExtract %82 %629 1\n%631 = OpExtInst %82 %78 SClamp %630 %127 %129\n%632 = OpIAdd %82 %631 %624\n%633 = OpExtInst %40 %78 Ldexp %133 %632\n%634 = OpExtInst %40 %78 FMin %633 %133\n%635 = OpFSub %40 %626 %634\n%636 = OpExtInst %40 %78 FMax %635 %138\n%637 = OpFAdd %40 %626 %634\n%638 = OpConvertFToS %82 %636\n%639 = OpConvertFToS %82 %637\n%640 = OpINotEqual %81 %638 %639\n%641 = OpCompositeExtract %79 %640 0\n%642 = OpCompositeExtract %79 %640 1\n%643 = OpLogicalAnd %79 %641 %642\n%644 = OpSelect %80 %641 %147 %126\n%645 = OpBitwiseOr %80 %90 %644\n%646 = OpSelect %80 %642 %128 %126\n%647 = OpBitwiseOr %80 %645 %646\n%648 = OpSelect %80 %643 %152 %126\n%649 = OpBitwiseOr %80 %647 %648\n%650 = OpSConvert %18 %649\n%651 = OpIMul %80 %571 %128\n%652 = OpSConvert %18 %651\n%653 = OpShiftLeftLogical %18 %650 %652\n%654 = OpLoad %79 %1932\n%655 = OpLogicalNot %79 %654\n%656 = OpLogicalAnd %79 %655 %573\n%657 = OpFunctionCall %1 %166 %21 %638 %653 %656\n%658 = OpCompositeConstruct %40 %67 %69\n%659 = OpImageQuerySize %82 %50\n%660 = OpBitwiseAnd %82 %659 %87\n%661 = OpImageQueryLevels %80 %52\n%662 = OpISub %80 %661 %90\n%663 = OpExtInst %5 %78 Exp2 %72\n%664 = OpGroupNonUniformQuadBroadcast %5 %74 %663 %57\n%665 = OpVectorTimesScalar %40 %658 %664\n%666 = OpImageQueryLod %40 %92 %665\n%667 = OpCompositeExtract %5 %666 0\n%668 = OpExtInst %5 %78 FMax %667 %55\n%669 = OpExtInst %5 %78 FMin %668 %236\n%670 = OpConvertFToS %80 %669\n%671 = OpFAdd %5 %669 %97\n%672 = OpConvertFToS %80 %671\n%673 = OpExtInst %80 %78 SMin %672 %662\n%674 = OpINotEqual %79 %670 %672\n%675 = OpDPdx %40 %658\n%676 = OpDPdy %40 %658\n%677 = OpExtInst %40 %78 FAbs %675\n%678 = OpExtInst %40 %78 FAbs %676\n%679 = OpCompositeExtract %5 %677 0\n%680 = OpCompositeExtract %5 %678 0\n%681 = OpCompositeExtract %5 %677 1\n%682 = OpCompositeExtract %5 %678 1\n%683 = OpExtInst %5 %78 FMax %679 %680\n%684 = OpExtInst %5 %78 FMax %681 %682\n%685 = OpCompositeConstruct %40 %683 %684\n%686 = OpVectorTimesScalar %40 %685 %663\n%687 = OpExtInst %40 %78 Fract %658\n%689 = OpImageQuerySizeLod %82 %52 %670\n%688 = OpConvertSToF %40 %689\n%690 = OpSNegate %82 %660\n%691 = OpExtInst %40 %78 Ldexp %688 %690\n%692 = OpFMul %40 %687 %691\n%693 = OpFMul %40 %686 %688\n%694 = OpFSub %40 %693 %121\n%695 = OpExtInst %122 %78 FrexpStruct %694\n%696 = OpCompositeExtract %82 %695 1\n%697 = OpExtInst %82 %78 SClamp %696 %127 %129\n%698 = OpIAdd %82 %697 %690\n%699 = OpExtInst %40 %78 Ldexp %133 %698\n%700 = OpExtInst %40 %78 FMin %699 %133\n%701 = OpFSub %40 %692 %700\n%702 = OpExtInst %40 %78 FMax %701 %138\n%703 = OpFAdd %40 %692 %700\n%704 = OpConvertFToS %82 %702\n%705 = OpConvertFToS %82 %703\n%706 = OpINotEqual %81 %704 %705\n%707 = OpCompositeExtract %79 %706 0\n%708 = OpCompositeExtract %79 %706 1\n%709 = OpLogicalAnd %79 %707 %708\n%710 = OpSelect %80 %707 %147 %126\n%711 = OpBitwiseOr %80 %90 %710\n%712 = OpSelect %80 %708 %128 %126\n%713 = OpBitwiseOr %80 %711 %712\n%714 = OpSelect %80 %709 %152 %126\n%715 = OpBitwiseOr %80 %713 %714\n%716 = OpSConvert %18 %715\n%717 = OpIMul %80 %670 %128\n%718 = OpSConvert %18 %717\n%719 = OpShiftLeftLogical %18 %716 %718\n%720 = OpLoad %79 %1932\n%721 = OpLogicalNot %79 %720\n%722 = OpFunctionCall %1 %166 %21 %704 %719 %721\n%724 = OpImageQuerySizeLod %82 %52 %672\n%723 = OpConvertSToF %40 %724\n%725 = OpSNegate %82 %660\n%726 = OpExtInst %40 %78 Ldexp %723 %725\n%727 = OpFMul %40 %687 %726\n%728 = OpFMul %40 %686 %723\n%729 = OpFSub %40 %728 %121\n%730 = OpExtInst %122 %78 FrexpStruct %729\n%731 = OpCompositeExtract %82 %730 1\n%732 = OpExtInst %82 %78 SClamp %731 %127 %129\n%733 = OpIAdd %82 %732 %725\n%734 = OpExtInst %40 %78 Ldexp %133 %733\n%735 = OpExtInst %40 %78 FMin %734 %133\n%736 = OpFSub %40 %727 %735\n%737 = OpExtInst %40 %78 FMax %736 %138\n%738 = OpFAdd %40 %727 %735\n%739 = OpConvertFToS %82 %737\n%740 = OpConvertFToS %82 %738\n%741 = OpINotEqual %81 %739 %740\n%742 = OpCompositeExtract %79 %741 0\n%743 = OpCompositeExtract %79 %741 1\n%744 = OpLogicalAnd %79 %742 %743\n%745 = OpSelect %80 %742 %147 %126\n%746 = OpBitwiseOr %80 %90 %745\n%747 = OpSelect %80 %743 %128 %126\n%748 = OpBitwiseOr %80 %746 %747\n%749 = OpSelect %80 %744 %152 %126\n%750 = OpBitwiseOr %80 %748 %749\n%751 = OpSConvert %18 %750\n%752 = OpIMul %80 %672 %128\n%753 = OpSConvert %18 %752\n%754 = OpShiftLeftLogical %18 %751 %753\n%755 = OpLoad %79 %1932\n%756 = OpLogicalNot %79 %755\n%757 = OpLogicalAnd %79 %756 %674\n%758 = OpFunctionCall %1 %166 %21 %739 %754 %757\n%759 = OpExtInst %5 %78 RoundEven %72\n%760 = OpConvertFToS %80 %759\n%761 = OpCompositeConstruct %40 %67 %69\n%763 = OpImageQuerySize %762 %49\n%764 = OpVectorShuffle %82 %763 %763 0 1\n%765 = OpBitwiseAnd %82 %764 %87\n%766 = OpImageQueryLevels %80 %51\n%767 = OpISub %80 %766 %90\n%769 = OpSampledImage %768 %51 %53\n%770 = OpImageQueryLod %40 %769 %761\n%771 = OpCompositeExtract %5 %770 0\n%772 = OpConvertFToS %80 %771\n%773 = OpFAdd %5 %771 %97\n%774 = OpConvertFToS %80 %773\n%775 = OpExtInst %80 %78 SMin %774 %767\n%776 = OpINotEqual %79 %772 %774\n%777 = OpDPdx %40 %761\n%778 = OpDPdy %40 %761\n%779 = OpExtInst %40 %78 FAbs %777\n%780 = OpExtInst %40 %78 FAbs %778\n%781 = OpCompositeExtract %5 %779 0\n%782 = OpCompositeExtract %5 %780 0\n%783 = OpCompositeExtract %5 %779 1\n%784 = OpCompositeExtract %5 %780 1\n%785 = OpExtInst %5 %78 FMax %781 %782\n%786 = OpExtInst %5 %78 FMax %783 %784\n%787 = OpCompositeConstruct %40 %785 %786\n%788 = OpExtInst %40 %78 Fract %761\n%790 = OpImageQuerySizeLod %762 %51 %772\n%791 = OpVectorShuffle %82 %790 %790 0 1\n%789 = OpConvertSToF %40 %791\n%792 = OpSNegate %82 %765\n%793 = OpExtInst %40 %78 Ldexp %789 %792\n%794 = OpFMul %40 %788 %793\n%795 = OpFMul %40 %787 %789\n%796 = OpFSub %40 %795 %121\n%797 = OpExtInst %122 %78 FrexpStruct %796\n%798 = OpCompositeExtract %82 %797 1\n%799 = OpExtInst %82 %78 SClamp %798 %127 %129\n%800 = OpIAdd %82 %799 %792\n%801 = OpExtInst %40 %78 Ldexp %133 %800\n%802 = OpExtInst %40 %78 FMin %801 %133\n%803 = OpFSub %40 %794 %802\n%804 = OpExtInst %40 %78 FMax %803 %138\n%805 = OpFAdd %40 %794 %802\n%806 = OpConvertFToS %82 %804\n%807 = OpConvertFToS %82 %805\n%808 = OpINotEqual %81 %806 %807\n%809 = OpCompositeExtract %79 %808 0\n%810 = OpCompositeExtract %79 %808 1\n%811 = OpLogicalAnd %79 %809 %810\n%812 = OpSelect %80 %809 %147 %126\n%813 = OpBitwiseOr %80 %90 %812\n%814 = OpSelect %80 %810 %128 %126\n%815 = OpBitwiseOr %80 %813 %814\n%816 = OpSelect %80 %811 %152 %126\n%817 = OpBitwiseOr %80 %815 %816\n%818 = OpSConvert %18 %817\n%819 = OpIMul %80 %772 %128\n%820 = OpSConvert %18 %819\n%821 = OpShiftLeftLogical %18 %818 %820\n%822 = OpCompositeConstruct %762 %806 %760\n%823 = OpLoad %79 %1932\n%824 = OpLogicalNot %79 %823\n%853 = OpFunctionCall %1 %831 %24 %822 %821 %824\n%855 = OpImageQuerySizeLod %762 %51 %774\n%856 = OpVectorShuffle %82 %855 %855 0 1\n%854 = OpConvertSToF %40 %856\n%857 = OpSNegate %82 %765\n%858 = OpExtInst %40 %78 Ldexp %854 %857\n%859 = OpFMul %40 %788 %858\n%860 = OpFMul %40 %787 %854\n%861 = OpFSub %40 %860 %121\n%862 = OpExtInst %122 %78 FrexpStruct %861\n%863 = OpCompositeExtract %82 %862 1\n%864 = OpExtInst %82 %78 SClamp %863 %127 %129\n%865 = OpIAdd %82 %864 %857\n%866 = OpExtInst %40 %78 Ldexp %133 %865\n%867 = OpExtInst %40 %78 FMin %866 %133\n%868 = OpFSub %40 %859 %867\n%869 = OpExtInst %40 %78 FMax %868 %138\n%870 = OpFAdd %40 %859 %867\n%871 = OpConvertFToS %82 %869\n%872 = OpConvertFToS %82 %870\n%873 = OpINotEqual %81 %871 %872\n%874 = OpCompositeExtract %79 %873 0\n%875 = OpCompositeExtract %79 %873 1\n%876 = OpLogicalAnd %79 %874 %875\n%877 = OpSelect %80 %874 %147 %126\n%878 = OpBitwiseOr %80 %90 %877\n%879 = OpSelect %80 %875 %128 %126\n%880 = OpBitwiseOr %80 %878 %879\n%881 = OpSelect %80 %876 %152 %126\n%882 = OpBitwiseOr %80 %880 %881\n%883 = OpSConvert %18 %882\n%884 = OpIMul %80 %774 %128\n%885 = OpSConvert %18 %884\n%886 = OpShiftLeftLogical %18 %883 %885\n%887 = OpCompositeConstruct %762 %871 %760\n%888 = OpLoad %79 %1932\n%889 = OpLogicalNot %79 %888\n%890 = OpLogicalAnd %79 %889 %776\n%891 = OpFunctionCall %1 %831 %24 %887 %886 %890\n%892 = OpExtInst %5 %78 RoundEven %72\n%893 = OpConvertFToS %80 %892\n%894 = OpCompositeConstruct %40 %67 %69\n%895 = OpImageQuerySize %762 %49\n%896 = OpVectorShuffle %82 %895 %895 0 1\n%897 = OpBitwiseAnd %82 %896 %87\n%898 = OpImageQueryLevels %80 %51\n%899 = OpISub %80 %898 %90\n%900 = OpImageQueryLod %40 %769 %894\n%901 = OpCompositeExtract %5 %900 0\n%902 = OpExtInst %5 %78 FMax %901 %55\n%903 = OpExtInst %5 %78 FMin %902 %236\n%904 = OpConvertFToS %80 %903\n%905 = OpFAdd %5 %903 %97\n%906 = OpConvertFToS %80 %905\n%907 = OpExtInst %80 %78 SMin %906 %899\n%908 = OpINotEqual %79 %904 %906\n%909 = OpDPdx %40 %894\n%910 = OpDPdy %40 %894\n%911 = OpExtInst %40 %78 FAbs %909\n%912 = OpExtInst %40 %78 FAbs %910\n%913 = OpCompositeExtract %5 %911 0\n%914 = OpCompositeExtract %5 %912 0\n%915 = OpCompositeExtract %5 %911 1\n%916 = OpCompositeExtract %5 %912 1\n%917 = OpExtInst %5 %78 FMax %913 %914\n%918 = OpExtInst %5 %78 FMax %915 %916\n%919 = OpCompositeConstruct %40 %917 %918\n%920 = OpExtInst %40 %78 Fract %894\n%922 = OpImageQuerySizeLod %762 %51 %904\n%923 = OpVectorShuffle %82 %922 %922 0 1\n%921 = OpConvertSToF %40 %923\n%924 = OpSNegate %82 %897\n%925 = OpExtInst %40 %78 Ldexp %921 %924\n%926 = OpFMul %40 %920 %925\n%927 = OpFMul %40 %919 %921\n%928 = OpFSub %40 %927 %121\n%929 = OpExtInst %122 %78 FrexpStruct %928\n%930 = OpCompositeExtract %82 %929 1\n%931 = OpExtInst %82 %78 SClamp %930 %127 %129\n%932 = OpIAdd %82 %931 %924\n%933 = OpExtInst %40 %78 Ldexp %133 %932\n%934 = OpExtInst %40 %78 FMin %933 %133\n%935 = OpFSub %40 %926 %934\n%936 = OpExtInst %40 %78 FMax %935 %138\n%937 = OpFAdd %40 %926 %934\n%938 = OpConvertFToS %82 %936\n%939 = OpConvertFToS %82 %937\n%940 = OpINotEqual %81 %938 %939\n%941 = OpCompositeExtract %79 %940 0\n%942 = OpCompositeExtract %79 %940 1\n%943 = OpLogicalAnd %79 %941 %942\n%944 = OpSelect %80 %941 %147 %126\n%945 = OpBitwiseOr %80 %90 %944\n%946 = OpSelect %80 %942 %128 %126\n%947 = OpBitwiseOr %80 %945 %946\n%948 = OpSelect %80 %943 %152 %126\n%949 = OpBitwiseOr %80 %947 %948\n%950 = OpSConvert %18 %949\n%951 = OpIMul %80 %904 %128\n%952 = OpSConvert %18 %951\n%953 = OpShiftLeftLogical %18 %950 %952\n%954 = OpCompositeConstruct %762 %938 %893\n%955 = OpLoad %79 %1932\n%956 = OpLogicalNot %79 %955\n%957 = OpFunctionCall %1 %831 %24 %954 %953 %956\n%959 = OpImageQuerySizeLod %762 %51 %906\n%960 = OpVectorShuffle %82 %959 %959 0 1\n%958 = OpConvertSToF %40 %960\n%961 = OpSNegate %82 %897\n%962 = OpExtInst %40 %78 Ldexp %958 %961\n%963 = OpFMul %40 %920 %962\n%964 = OpFMul %40 %919 %958\n%965 = OpFSub %40 %964 %121\n%966 = OpExtInst %122 %78 FrexpStruct %965\n%967 = OpCompositeExtract %82 %966 1\n%968 = OpExtInst %82 %78 SClamp %967 %127 %129\n%969 = OpIAdd %82 %968 %961\n%970 = OpExtInst %40 %78 Ldexp %133 %969\n%971 = OpExtInst %40 %78 FMin %970 %133\n%972 = OpFSub %40 %963 %971\n%973 = OpExtInst %40 %78 FMax %972 %138\n%974 = OpFAdd %40 %963 %971\n%975 = OpConvertFToS %82 %973\n%976 = OpConvertFToS %82 %974\n%977 = OpINotEqual %81 %975 %976\n%978 = OpCompositeExtract %79 %977 0\n%979 = OpCompositeExtract %79 %977 1\n%980 = OpLogicalAnd %79 %978 %979\n%981 = OpSelect %80 %978 %147 %126\n%982 = OpBitwiseOr %80 %90 %981\n%983 = OpSelect %80 %979 %128 %126\n%984 = OpBitwiseOr %80 %982 %983\n%985 = OpSelect %80 %980 %152 %126\n%986 = OpBitwiseOr %80 %984 %985\n%987 = OpSConvert %18 %986\n%988 = OpIMul %80 %906 %128\n%989 = OpSConvert %18 %988\n%990 = OpShiftLeftLogical %18 %987 %989\n%991 = OpCompositeConstruct %762 %975 %893\n%992 = OpLoad %79 %1932\n%993 = OpLogicalNot %79 %992\n%994 = OpLogicalAnd %79 %993 %908\n%995 = OpFunctionCall %1 %831 %24 %991 %990 %994\n%996 = OpExtInst %5 %78 RoundEven %72\n%997 = OpConvertFToS %80 %996\n%998 = OpCompositeConstruct %40 %67 %69\n%999 = OpImageQuerySize %762 %49\n%1000 = OpVectorShuffle %82 %999 %999 0 1\n%1001 = OpBitwiseAnd %82 %1000 %87\n%1002 = OpImageQueryLevels %80 %51\n%1003 = OpISub %80 %1002 %90\n%1004 = OpConvertSToF %5 %1003\n%1005 = OpExtInst %5 %78 NClamp %76 %137 %1004\n%1006 = OpConvertFToS %80 %1005\n%1007 = OpFAdd %5 %1005 %97\n%1008 = OpConvertFToS %80 %1007\n%1009 = OpExtInst %80 %78 SMin %1008 %1003\n%1010 = OpINotEqual %79 %1006 %1008\n%1011 = OpExtInst %40 %78 Fract %998\n%1013 = OpImageQuerySizeLod %762 %51 %1006\n%1014 = OpVectorShuffle %82 %1013 %1013 0 1\n%1012 = OpConvertSToF %40 %1014\n%1015 = OpSNegate %82 %1001\n%1016 = OpExtInst %40 %78 Ldexp %1012 %1015\n%1017 = OpFMul %40 %1011 %1016\n%1018 = OpExtInst %40 %78 Ldexp %133 %1015\n%1019 = OpFSub %40 %1017 %1018\n%1020 = OpExtInst %40 %78 FMax %1019 %138\n%1021 = OpFAdd %40 %1017 %1018\n%1022 = OpConvertFToS %82 %1020\n%1023 = OpConvertFToS %82 %1021\n%1024 = OpINotEqual %81 %1022 %1023\n%1025 = OpCompositeExtract %79 %1024 0\n%1026 = OpCompositeExtract %79 %1024 1\n%1027 = OpLogicalAnd %79 %1025 %1026\n%1028 = OpSelect %80 %1025 %147 %126\n%1029 = OpBitwiseOr %80 %90 %1028\n%1030 = OpSelect %80 %1026 %128 %126\n%1031 = OpBitwiseOr %80 %1029 %1030\n%1032 = OpSelect %80 %1027 %152 %126\n%1033 = OpBitwiseOr %80 %1031 %1032\n%1034 = OpSConvert %18 %1033\n%1035 = OpIMul %80 %1006 %128\n%1036 = OpSConvert %18 %1035\n%1037 = OpShiftLeftLogical %18 %1034 %1036\n%1038 = OpCompositeConstruct %762 %1022 %997\n%1039 = OpLoad %79 %1932\n%1040 = OpLogicalNot %79 %1039\n%1041 = OpFunctionCall %1 %831 %24 %1038 %1037 %1040\n%1043 = OpImageQuerySizeLod %762 %51 %1008\n%1044 = OpVectorShuffle %82 %1043 %1043 0 1\n%1042 = OpConvertSToF %40 %1044\n%1045 = OpSNegate %82 %1001\n%1046 = OpExtInst %40 %78 Ldexp %1042 %1045\n%1047 = OpFMul %40 %1011 %1046\n%1048 = OpExtInst %40 %78 Ldexp %133 %1045\n%1049 = OpFSub %40 %1047 %1048\n%1050 = OpExtInst %40 %78 FMax %1049 %138\n%1051 = OpFAdd %40 %1047 %1048\n%1052 = OpConvertFToS %82 %1050\n%1053 = OpConvertFToS %82 %1051\n%1054 = OpINotEqual %81 %1052 %1053\n%1055 = OpCompositeExtract %79 %1054 0\n%1056 = OpCompositeExtract %79 %1054 1\n%1057 = OpLogicalAnd %79 %1055 %1056\n%1058 = OpSelect %80 %1055 %147 %126\n%1059 = OpBitwiseOr %80 %90 %1058\n%1060 = OpSelect %80 %1056 %128 %126\n%1061 = OpBitwiseOr %80 %1059 %1060\n%1062 = OpSelect %80 %1057 %152 %126\n%1063 = OpBitwiseOr %80 %1061 %1062\n%1064 = OpSConvert %18 %1063\n%1065 = OpIMul %80 %1008 %128\n%1066 = OpSConvert %18 %1065\n%1067 = OpShiftLeftLogical %18 %1064 %1066\n%1068 = OpCompositeConstruct %762 %1052 %997\n%1069 = OpLoad %79 %1932\n%1070 = OpLogicalNot %79 %1069\n%1071 = OpLogicalAnd %79 %1070 %1010\n%1072 = OpFunctionCall %1 %831 %24 %1068 %1067 %1071\n%1073 = OpExtInst %5 %78 RoundEven %72\n%1074 = OpConvertFToS %80 %1073\n%1075 = OpCompositeConstruct %40 %67 %69\n%1076 = OpImageQuerySize %762 %49\n%1077 = OpVectorShuffle %82 %1076 %1076 0 1\n%1078 = OpBitwiseAnd %82 %1077 %87\n%1079 = OpImageQueryLevels %80 %51\n%1080 = OpISub %80 %1079 %90\n%1082 = OpImageQuerySizeLod %762 %51 %126\n%1083 = OpVectorShuffle %82 %1082 %1082 0 1\n%1081 = OpConvertSToF %40 %1083\n%1084 = OpCompositeConstruct %40 %63 %65\n%1085 = OpCompositeConstruct %40 %58 %61\n%1086 = OpFMul %40 %1081 %1084\n%1087 = OpFMul %40 %1081 %1085\n%1088 = OpDot %5 %1086 %1086\n%1089 = OpDot %5 %1087 %1087\n%1090 = OpExtInst %5 %78 FMax %1088 %1089\n%1091 = OpExtInst %5 %78 Log2 %1090\n%1092 = OpFMul %5 %1091 %132\n%1093 = OpConvertSToF %5 %1080\n%1094 = OpExtInst %5 %78 NClamp %1092 %137 %1093\n%1095 = OpConvertFToS %80 %1094\n%1096 = OpFAdd %5 %1094 %97\n%1097 = OpConvertFToS %80 %1096\n%1098 = OpExtInst %80 %78 SMin %1097 %1080\n%1099 = OpINotEqual %79 %1095 %1097\n%1100 = OpExtInst %40 %78 Fract %1075\n%1102 = OpImageQuerySizeLod %762 %51 %1095\n%1103 = OpVectorShuffle %82 %1102 %1102 0 1\n%1101 = OpConvertSToF %40 %1103\n%1104 = OpSNegate %82 %1078\n%1105 = OpExtInst %40 %78 Ldexp %1101 %1104\n%1106 = OpFMul %40 %1100 %1105\n%1107 = OpExtInst %40 %78 Ldexp %133 %1104\n%1108 = OpFSub %40 %1106 %1107\n%1109 = OpExtInst %40 %78 FMax %1108 %138\n%1110 = OpFAdd %40 %1106 %1107\n%1111 = OpConvertFToS %82 %1109\n%1112 = OpConvertFToS %82 %1110\n%1113 = OpINotEqual %81 %1111 %1112\n%1114 = OpCompositeExtract %79 %1113 0\n%1115 = OpCompositeExtract %79 %1113 1\n%1116 = OpLogicalAnd %79 %1114 %1115\n%1117 = OpSelect %80 %1114 %147 %126\n%1118 = OpBitwiseOr %80 %90 %1117\n%1119 = OpSelect %80 %1115 %128 %126\n%1120 = OpBitwiseOr %80 %1118 %1119\n%1121 = OpSelect %80 %1116 %152 %126\n%1122 = OpBitwiseOr %80 %1120 %1121\n%1123 = OpSConvert %18 %1122\n%1124 = OpIMul %80 %1095 %128\n%1125 = OpSConvert %18 %1124\n%1126 = OpShiftLeftLogical %18 %1123 %1125\n%1127 = OpCompositeConstruct %762 %1111 %1074\n%1128 = OpLoad %79 %1932\n%1129 = OpLogicalNot %79 %1128\n%1130 = OpFunctionCall %1 %831 %24 %1127 %1126 %1129\n%1132 = OpImageQuerySizeLod %762 %51 %1097\n%1133 = OpVectorShuffle %82 %1132 %1132 0 1\n%1131 = OpConvertSToF %40 %1133\n%1134 = OpSNegate %82 %1078\n%1135 = OpExtInst %40 %78 Ldexp %1131 %1134\n%1136 = OpFMul %40 %1100 %1135\n%1137 = OpExtInst %40 %78 Ldexp %133 %1134\n%1138 = OpFSub %40 %1136 %1137\n%1139 = OpExtInst %40 %78 FMax %1138 %138\n%1140 = OpFAdd %40 %1136 %1137\n%1141 = OpConvertFToS %82 %1139\n%1142 = OpConvertFToS %82 %1140\n%1143 = OpINotEqual %81 %1141 %1142\n%1144 = OpCompositeExtract %79 %1143 0\n%1145 = OpCompositeExtract %79 %1143 1\n%1146 = OpLogicalAnd %79 %1144 %1145\n%1147 = OpSelect %80 %1144 %147 %126\n%1148 = OpBitwiseOr %80 %90 %1147\n%1149 = OpSelect %80 %1145 %128 %126\n%1150 = OpBitwiseOr %80 %1148 %1149\n%1151 = OpSelect %80 %1146 %152 %126\n%1152 = OpBitwiseOr %80 %1150 %1151\n%1153 = OpSConvert %18 %1152\n%1154 = OpIMul %80 %1097 %128\n%1155 = OpSConvert %18 %1154\n%1156 = OpShiftLeftLogical %18 %1153 %1155\n%1157 = OpCompositeConstruct %762 %1141 %1074\n%1158 = OpLoad %79 %1932\n%1159 = OpLogicalNot %79 %1158\n%1160 = OpLogicalAnd %79 %1159 %1099\n%1161 = OpFunctionCall %1 %831 %24 %1157 %1156 %1160\n%1162 = OpExtInst %5 %78 RoundEven %72\n%1163 = OpConvertFToS %80 %1162\n%1164 = OpCompositeConstruct %40 %67 %69\n%1165 = OpImageQuerySize %762 %49\n%1166 = OpVectorShuffle %82 %1165 %1165 0 1\n%1167 = OpBitwiseAnd %82 %1166 %87\n%1168 = OpImageQueryLevels %80 %51\n%1169 = OpISub %80 %1168 %90\n%1171 = OpImageQuerySizeLod %762 %51 %126\n%1172 = OpVectorShuffle %82 %1171 %1171 0 1\n%1170 = OpConvertSToF %40 %1172\n%1173 = OpCompositeConstruct %40 %63 %65\n%1174 = OpCompositeConstruct %40 %58 %61\n%1175 = OpFMul %40 %1170 %1173\n%1176 = OpFMul %40 %1170 %1174\n%1177 = OpDot %5 %1175 %1175\n%1178 = OpDot %5 %1176 %1176\n%1179 = OpExtInst %5 %78 FMax %1177 %1178\n%1180 = OpExtInst %5 %78 Log2 %1179\n%1181 = OpFMul %5 %1180 %132\n%1182 = OpConvertSToF %5 %1169\n%1183 = OpExtInst %5 %78 NClamp %1181 %137 %1182\n%1184 = OpExtInst %5 %78 FMax %1183 %55\n%1185 = OpExtInst %5 %78 FMin %1184 %236\n%1186 = OpConvertFToS %80 %1185\n%1187 = OpFAdd %5 %1185 %97\n%1188 = OpConvertFToS %80 %1187\n%1189 = OpExtInst %80 %78 SMin %1188 %1169\n%1190 = OpINotEqual %79 %1186 %1188\n%1191 = OpExtInst %40 %78 Fract %1164\n%1193 = OpImageQuerySizeLod %762 %51 %1186\n%1194 = OpVectorShuffle %82 %1193 %1193 0 1\n%1192 = OpConvertSToF %40 %1194\n%1195 = OpSNegate %82 %1167\n%1196 = OpExtInst %40 %78 Ldexp %1192 %1195\n%1197 = OpFMul %40 %1191 %1196\n%1198 = OpExtInst %40 %78 Ldexp %133 %1195\n%1199 = OpFSub %40 %1197 %1198\n%1200 = OpExtInst %40 %78 FMax %1199 %138\n%1201 = OpFAdd %40 %1197 %1198\n%1202 = OpConvertFToS %82 %1200\n%1203 = OpConvertFToS %82 %1201\n%1204 = OpINotEqual %81 %1202 %1203\n%1205 = OpCompositeExtract %79 %1204 0\n%1206 = OpCompositeExtract %79 %1204 1\n%1207 = OpLogicalAnd %79 %1205 %1206\n%1208 = OpSelect %80 %1205 %147 %126\n%1209 = OpBitwiseOr %80 %90 %1208\n%1210 = OpSelect %80 %1206 %128 %126\n%1211 = OpBitwiseOr %80 %1209 %1210\n%1212 = OpSelect %80 %1207 %152 %126\n%1213 = OpBitwiseOr %80 %1211 %1212\n%1214 = OpSConvert %18 %1213\n%1215 = OpIMul %80 %1186 %128\n%1216 = OpSConvert %18 %1215\n%1217 = OpShiftLeftLogical %18 %1214 %1216\n%1218 = OpCompositeConstruct %762 %1202 %1163\n%1219 = OpLoad %79 %1932\n%1220 = OpLogicalNot %79 %1219\n%1221 = OpFunctionCall %1 %831 %24 %1218 %1217 %1220\n%1223 = OpImageQuerySizeLod %762 %51 %1188\n%1224 = OpVectorShuffle %82 %1223 %1223 0 1\n%1222 = OpConvertSToF %40 %1224\n%1225 = OpSNegate %82 %1167\n%1226 = OpExtInst %40 %78 Ldexp %1222 %1225\n%1227 = OpFMul %40 %1191 %1226\n%1228 = OpExtInst %40 %78 Ldexp %133 %1225\n%1229 = OpFSub %40 %1227 %1228\n%1230 = OpExtInst %40 %78 FMax %1229 %138\n%1231 = OpFAdd %40 %1227 %1228\n%1232 = OpConvertFToS %82 %1230\n%1233 = OpConvertFToS %82 %1231\n%1234 = OpINotEqual %81 %1232 %1233\n%1235 = OpCompositeExtract %79 %1234 0\n%1236 = OpCompositeExtract %79 %1234 1\n%1237 = OpLogicalAnd %79 %1235 %1236\n%1238 = OpSelect %80 %1235 %147 %126\n%1239 = OpBitwiseOr %80 %90 %1238\n%1240 = OpSelect %80 %1236 %128 %126\n%1241 = OpBitwiseOr %80 %1239 %1240\n%1242 = OpSelect %80 %1237 %152 %126\n%1243 = OpBitwiseOr %80 %1241 %1242\n%1244 = OpSConvert %18 %1243\n%1245 = OpIMul %80 %1188 %128\n%1246 = OpSConvert %18 %1245\n%1247 = OpShiftLeftLogical %18 %1244 %1246\n%1248 = OpCompositeConstruct %762 %1232 %1163\n%1249 = OpLoad %79 %1932\n%1250 = OpLogicalNot %79 %1249\n%1251 = OpLogicalAnd %79 %1250 %1190\n%1252 = OpFunctionCall %1 %831 %24 %1248 %1247 %1251\n%1253 = OpExtInst %5 %78 RoundEven %72\n%1254 = OpConvertFToS %80 %1253\n%1255 = OpCompositeConstruct %40 %67 %69\n%1256 = OpImageQuerySize %762 %49\n%1257 = OpVectorShuffle %82 %1256 %1256 0 1\n%1258 = OpBitwiseAnd %82 %1257 %87\n%1259 = OpImageQueryLevels %80 %51\n%1260 = OpISub %80 %1259 %90\n%1261 = OpExtInst %5 %78 Exp2 %72\n%1262 = OpGroupNonUniformQuadBroadcast %5 %74 %1261 %57\n%1263 = OpVectorTimesScalar %40 %1255 %1262\n%1264 = OpImageQueryLod %40 %769 %1263\n%1265 = OpCompositeExtract %5 %1264 0\n%1266 = OpConvertFToS %80 %1265\n%1267 = OpFAdd %5 %1265 %97\n%1268 = OpConvertFToS %80 %1267\n%1269 = OpExtInst %80 %78 SMin %1268 %1260\n%1270 = OpINotEqual %79 %1266 %1268\n%1271 = OpDPdx %40 %1255\n%1272 = OpDPdy %40 %1255\n%1273 = OpExtInst %40 %78 FAbs %1271\n%1274 = OpExtInst %40 %78 FAbs %1272\n%1275 = OpCompositeExtract %5 %1273 0\n%1276 = OpCompositeExtract %5 %1274 0\n%1277 = OpCompositeExtract %5 %1273 1\n%1278 = OpCompositeExtract %5 %1274 1\n%1279 = OpExtInst %5 %78 FMax %1275 %1276\n%1280 = OpExtInst %5 %78 FMax %1277 %1278\n%1281 = OpCompositeConstruct %40 %1279 %1280\n%1282 = OpVectorTimesScalar %40 %1281 %1261\n%1283 = OpExtInst %40 %78 Fract %1255\n%1285 = OpImageQuerySizeLod %762 %51 %1266\n%1286 = OpVectorShuffle %82 %1285 %1285 0 1\n%1284 = OpConvertSToF %40 %1286\n%1287 = OpSNegate %82 %1258\n%1288 = OpExtInst %40 %78 Ldexp %1284 %1287\n%1289 = OpFMul %40 %1283 %1288\n%1290 = OpFMul %40 %1282 %1284\n%1291 = OpFSub %40 %1290 %121\n%1292 = OpExtInst %122 %78 FrexpStruct %1291\n%1293 = OpCompositeExtract %82 %1292 1\n%1294 = OpExtInst %82 %78 SClamp %1293 %127 %129\n%1295 = OpIAdd %82 %1294 %1287\n%1296 = OpExtInst %40 %78 Ldexp %133 %1295\n%1297 = OpExtInst %40 %78 FMin %1296 %133\n%1298 = OpFSub %40 %1289 %1297\n%1299 = OpExtInst %40 %78 FMax %1298 %138\n%1300 = OpFAdd %40 %1289 %1297\n%1301 = OpConvertFToS %82 %1299\n%1302 = OpConvertFToS %82 %1300\n%1303 = OpINotEqual %81 %1301 %1302\n%1304 = OpCompositeExtract %79 %1303 0\n%1305 = OpCompositeExtract %79 %1303 1\n%1306 = OpLogicalAnd %79 %1304 %1305\n%1307 = OpSelect %80 %1304 %147 %126\n%1308 = OpBitwiseOr %80 %90 %1307\n%1309 = OpSelect %80 %1305 %128 %126\n%1310 = OpBitwiseOr %80 %1308 %1309\n%1311 = OpSelect %80 %1306 %152 %126\n%1312 = OpBitwiseOr %80 %1310 %1311\n%1313 = OpSConvert %18 %1312\n%1314 = OpIMul %80 %1266 %128\n%1315 = OpSConvert %18 %1314\n%1316 = OpShiftLeftLogical %18 %1313 %1315\n%1317 = OpCompositeConstruct %762 %1301 %1254\n%1318 = OpLoad %79 %1932\n%1319 = OpLogicalNot %79 %1318\n%1320 = OpFunctionCall %1 %831 %24 %1317 %1316 %1319\n%1322 = OpImageQuerySizeLod %762 %51 %1268\n%1323 = OpVectorShuffle %82 %1322 %1322 0 1\n%1321 = OpConvertSToF %40 %1323\n%1324 = OpSNegate %82 %1258\n%1325 = OpExtInst %40 %78 Ldexp %1321 %1324\n%1326 = OpFMul %40 %1283 %1325\n%1327 = OpFMul %40 %1282 %1321\n%1328 = OpFSub %40 %1327 %121\n%1329 = OpExtInst %122 %78 FrexpStruct %1328\n%1330 = OpCompositeExtract %82 %1329 1\n%1331 = OpExtInst %82 %78 SClamp %1330 %127 %129\n%1332 = OpIAdd %82 %1331 %1324\n%1333 = OpExtInst %40 %78 Ldexp %133 %1332\n%1334 = OpExtInst %40 %78 FMin %1333 %133\n%1335 = OpFSub %40 %1326 %1334\n%1336 = OpExtInst %40 %78 FMax %1335 %138\n%1337 = OpFAdd %40 %1326 %1334\n%1338 = OpConvertFToS %82 %1336\n%1339 = OpConvertFToS %82 %1337\n%1340 = OpINotEqual %81 %1338 %1339\n%1341 = OpCompositeExtract %79 %1340 0\n%1342 = OpCompositeExtract %79 %1340 1\n%1343 = OpLogicalAnd %79 %1341 %1342\n%1344 = OpSelect %80 %1341 %147 %126\n%1345 = OpBitwiseOr %80 %90 %1344\n%1346 = OpSelect %80 %1342 %128 %126\n%1347 = OpBitwiseOr %80 %1345 %1346\n%1348 = OpSelect %80 %1343 %152 %126\n%1349 = OpBitwiseOr %80 %1347 %1348\n%1350 = OpSConvert %18 %1349\n%1351 = OpIMul %80 %1268 %128\n%1352 = OpSConvert %18 %1351\n%1353 = OpShiftLeftLogical %18 %1350 %1352\n%1354 = OpCompositeConstruct %762 %1338 %1254\n%1355 = OpLoad %79 %1932\n%1356 = OpLogicalNot %79 %1355\n%1357 = OpLogicalAnd %79 %1356 %1270\n%1358 = OpFunctionCall %1 %831 %24 %1354 %1353 %1357\n%1359 = OpExtInst %5 %78 RoundEven %72\n%1360 = OpConvertFToS %80 %1359\n%1361 = OpCompositeConstruct %40 %67 %69\n%1362 = OpImageQuerySize %762 %49\n%1363 = OpVectorShuffle %82 %1362 %1362 0 1\n%1364 = OpBitwiseAnd %82 %1363 %87\n%1365 = OpImageQueryLevels %80 %51\n%1366 = OpISub %80 %1365 %90\n%1367 = OpExtInst %5 %78 Exp2 %76\n%1368 = OpGroupNonUniformQuadBroadcast %5 %74 %1367 %57\n%1369 = OpVectorTimesScalar %40 %1361 %1368\n%1370 = OpImageQueryLod %40 %769 %1369\n%1371 = OpCompositeExtract %5 %1370 0\n%1372 = OpExtInst %5 %78 FMax %1371 %55\n%1373 = OpExtInst %5 %78 FMin %1372 %236\n%1374 = OpConvertFToS %80 %1373\n%1375 = OpFAdd %5 %1373 %97\n%1376 = OpConvertFToS %80 %1375\n%1377 = OpExtInst %80 %78 SMin %1376 %1366\n%1378 = OpINotEqual %79 %1374 %1376\n%1379 = OpDPdx %40 %1361\n%1380 = OpDPdy %40 %1361\n%1381 = OpExtInst %40 %78 FAbs %1379\n%1382 = OpExtInst %40 %78 FAbs %1380\n%1383 = OpCompositeExtract %5 %1381 0\n%1384 = OpCompositeExtract %5 %1382 0\n%1385 = OpCompositeExtract %5 %1381 1\n%1386 = OpCompositeExtract %5 %1382 1\n%1387 = OpExtInst %5 %78 FMax %1383 %1384\n%1388 = OpExtInst %5 %78 FMax %1385 %1386\n%1389 = OpCompositeConstruct %40 %1387 %1388\n%1390 = OpVectorTimesScalar %40 %1389 %1367\n%1391 = OpExtInst %40 %78 Fract %1361\n%1393 = OpImageQuerySizeLod %762 %51 %1374\n%1394 = OpVectorShuffle %82 %1393 %1393 0 1\n%1392 = OpConvertSToF %40 %1394\n%1395 = OpSNegate %82 %1364\n%1396 = OpExtInst %40 %78 Ldexp %1392 %1395\n%1397 = OpFMul %40 %1391 %1396\n%1398 = OpFMul %40 %1390 %1392\n%1399 = OpFSub %40 %1398 %121\n%1400 = OpExtInst %122 %78 FrexpStruct %1399\n%1401 = OpCompositeExtract %82 %1400 1\n%1402 = OpExtInst %82 %78 SClamp %1401 %127 %129\n%1403 = OpIAdd %82 %1402 %1395\n%1404 = OpExtInst %40 %78 Ldexp %133 %1403\n%1405 = OpExtInst %40 %78 FMin %1404 %133\n%1406 = OpFSub %40 %1397 %1405\n%1407 = OpExtInst %40 %78 FMax %1406 %138\n%1408 = OpFAdd %40 %1397 %1405\n%1409 = OpConvertFToS %82 %1407\n%1410 = OpConvertFToS %82 %1408\n%1411 = OpINotEqual %81 %1409 %1410\n%1412 = OpCompositeExtract %79 %1411 0\n%1413 = OpCompositeExtract %79 %1411 1\n%1414 = OpLogicalAnd %79 %1412 %1413\n%1415 = OpSelect %80 %1412 %147 %126\n%1416 = OpBitwiseOr %80 %90 %1415\n%1417 = OpSelect %80 %1413 %128 %126\n%1418 = OpBitwiseOr %80 %1416 %1417\n%1419 = OpSelect %80 %1414 %152 %126\n%1420 = OpBitwiseOr %80 %1418 %1419\n%1421 = OpSConvert %18 %1420\n%1422 = OpIMul %80 %1374 %128\n%1423 = OpSConvert %18 %1422\n%1424 = OpShiftLeftLogical %18 %1421 %1423\n%1425 = OpCompositeConstruct %762 %1409 %1360\n%1426 = OpLoad %79 %1932\n%1427 = OpLogicalNot %79 %1426\n%1428 = OpFunctionCall %1 %831 %24 %1425 %1424 %1427\n%1430 = OpImageQuerySizeLod %762 %51 %1376\n%1431 = OpVectorShuffle %82 %1430 %1430 0 1\n%1429 = OpConvertSToF %40 %1431\n%1432 = OpSNegate %82 %1364\n%1433 = OpExtInst %40 %78 Ldexp %1429 %1432\n%1434 = OpFMul %40 %1391 %1433\n%1435 = OpFMul %40 %1390 %1429\n%1436 = OpFSub %40 %1435 %121\n%1437 = OpExtInst %122 %78 FrexpStruct %1436\n%1438 = OpCompositeExtract %82 %1437 1\n%1439 = OpExtInst %82 %78 SClamp %1438 %127 %129\n%1440 = OpIAdd %82 %1439 %1432\n%1441 = OpExtInst %40 %78 Ldexp %133 %1440\n%1442 = OpExtInst %40 %78 FMin %1441 %133\n%1443 = OpFSub %40 %1434 %1442\n%1444 = OpExtInst %40 %78 FMax %1443 %138\n%1445 = OpFAdd %40 %1434 %1442\n%1446 = OpConvertFToS %82 %1444\n%1447 = OpConvertFToS %82 %1445\n%1448 = OpINotEqual %81 %1446 %1447\n%1449 = OpCompositeExtract %79 %1448 0\n%1450 = OpCompositeExtract %79 %1448 1\n%1451 = OpLogicalAnd %79 %1449 %1450\n%1452 = OpSelect %80 %1449 %147 %126\n%1453 = OpBitwiseOr %80 %90 %1452\n%1454 = OpSelect %80 %1450 %128 %126\n%1455 = OpBitwiseOr %80 %1453 %1454\n%1456 = OpSelect %80 %1451 %152 %126\n%1457 = OpBitwiseOr %80 %1455 %1456\n%1458 = OpSConvert %18 %1457\n%1459 = OpIMul %80 %1376 %128\n%1460 = OpSConvert %18 %1459\n%1461 = OpShiftLeftLogical %18 %1458 %1460\n%1462 = OpCompositeConstruct %762 %1446 %1360\n%1463 = OpLoad %79 %1932\n%1464 = OpLogicalNot %79 %1463\n%1465 = OpLogicalAnd %79 %1464 %1378\n%1466 = OpFunctionCall %1 %831 %24 %1462 %1461 %1465\n%1467 = OpIAdd %46 %54 %57\n%1468 = OpAccessChain %20 %27 %1467\n%1469 = OpLoad %19 %1468\n%1470 = OpIAdd %46 %54 %57\n%1471 = OpAccessChain %7 %14 %1470\n%1472 = OpLoad %6 %1471\n%1473 = OpIAdd %46 %54 %57\n%1474 = OpAccessChain %32 %36 %1473\n%1475 = OpLoad %31 %1474\n%1476 = OpCompositeConstruct %40 %67 %69\n%1477 = OpImageQuerySize %82 %1469\n%1478 = OpBitwiseAnd %82 %1477 %87\n%1479 = OpImageQueryLevels %80 %1472\n%1480 = OpISub %80 %1479 %90\n%1481 = OpSampledImage %91 %1472 %1475\n%1482 = OpImageQueryLod %40 %1481 %1476\n%1483 = OpCompositeExtract %5 %1482 0\n%1484 = OpConvertFToS %80 %1483\n%1485 = OpFAdd %5 %1483 %97\n%1486 = OpConvertFToS %80 %1485\n%1487 = OpExtInst %80 %78 SMin %1486 %1480\n%1488 = OpINotEqual %79 %1484 %1486\n%1489 = OpDPdx %40 %1476\n%1490 = OpDPdy %40 %1476\n%1491 = OpExtInst %40 %78 FAbs %1489\n%1492 = OpExtInst %40 %78 FAbs %1490\n%1493 = OpCompositeExtract %5 %1491 0\n%1494 = OpCompositeExtract %5 %1492 0\n%1495 = OpCompositeExtract %5 %1491 1\n%1496 = OpCompositeExtract %5 %1492 1\n%1497 = OpExtInst %5 %78 FMax %1493 %1494\n%1498 = OpExtInst %5 %78 FMax %1495 %1496\n%1499 = OpCompositeConstruct %40 %1497 %1498\n%1500 = OpExtInst %40 %78 Fract %1476\n%1502 = OpImageQuerySizeLod %82 %1472 %1484\n%1501 = OpConvertSToF %40 %1502\n%1503 = OpSNegate %82 %1478\n%1504 = OpExtInst %40 %78 Ldexp %1501 %1503\n%1505 = OpFMul %40 %1500 %1504\n%1506 = OpFMul %40 %1499 %1501\n%1507 = OpFSub %40 %1506 %121\n%1508 = OpExtInst %122 %78 FrexpStruct %1507\n%1509 = OpCompositeExtract %82 %1508 1\n%1510 = OpExtInst %82 %78 SClamp %1509 %127 %129\n%1511 = OpIAdd %82 %1510 %1503\n%1512 = OpExtInst %40 %78 Ldexp %133 %1511\n%1513 = OpExtInst %40 %78 FMin %1512 %133\n%1514 = OpFSub %40 %1505 %1513\n%1515 = OpExtInst %40 %78 FMax %1514 %138\n%1516 = OpFAdd %40 %1505 %1513\n%1517 = OpConvertFToS %82 %1515\n%1518 = OpConvertFToS %82 %1516\n%1519 = OpINotEqual %81 %1517 %1518\n%1520 = OpCompositeExtract %79 %1519 0\n%1521 = OpCompositeExtract %79 %1519 1\n%1522 = OpLogicalAnd %79 %1520 %1521\n%1523 = OpSelect %80 %1520 %147 %126\n%1524 = OpBitwiseOr %80 %90 %1523\n%1525 = OpSelect %80 %1521 %128 %126\n%1526 = OpBitwiseOr %80 %1524 %1525\n%1527 = OpSelect %80 %1522 %152 %126\n%1528 = OpBitwiseOr %80 %1526 %1527\n%1529 = OpSConvert %18 %1528\n%1530 = OpIMul %80 %1484 %128\n%1531 = OpSConvert %18 %1530\n%1532 = OpShiftLeftLogical %18 %1529 %1531\n%1533 = OpLoad %79 %1932\n%1534 = OpLogicalNot %79 %1533\n%1561 = OpFunctionCall %1 %1539 %1468 %1517 %1532 %1534\n%1563 = OpImageQuerySizeLod %82 %1472 %1486\n%1562 = OpConvertSToF %40 %1563\n%1564 = OpSNegate %82 %1478\n%1565 = OpExtInst %40 %78 Ldexp %1562 %1564\n%1566 = OpFMul %40 %1500 %1565\n%1567 = OpFMul %40 %1499 %1562\n%1568 = OpFSub %40 %1567 %121\n%1569 = OpExtInst %122 %78 FrexpStruct %1568\n%1570 = OpCompositeExtract %82 %1569 1\n%1571 = OpExtInst %82 %78 SClamp %1570 %127 %129\n%1572 = OpIAdd %82 %1571 %1564\n%1573 = OpExtInst %40 %78 Ldexp %133 %1572\n%1574 = OpExtInst %40 %78 FMin %1573 %133\n%1575 = OpFSub %40 %1566 %1574\n%1576 = OpExtInst %40 %78 FMax %1575 %138\n%1577 = OpFAdd %40 %1566 %1574\n%1578 = OpConvertFToS %82 %1576\n%1579 = OpConvertFToS %82 %1577\n%1580 = OpINotEqual %81 %1578 %1579\n%1581 = OpCompositeExtract %79 %1580 0\n%1582 = OpCompositeExtract %79 %1580 1\n%1583 = OpLogicalAnd %79 %1581 %1582\n%1584 = OpSelect %80 %1581 %147 %126\n%1585 = OpBitwiseOr %80 %90 %1584\n%1586 = OpSelect %80 %1582 %128 %126\n%1587 = OpBitwiseOr %80 %1585 %1586\n%1588 = OpSelect %80 %1583 %152 %126\n%1589 = OpBitwiseOr %80 %1587 %1588\n%1590 = OpSConvert %18 %1589\n%1591 = OpIMul %80 %1486 %128\n%1592 = OpSConvert %18 %1591\n%1593 = OpShiftLeftLogical %18 %1590 %1592\n%1594 = OpLoad %79 %1932\n%1595 = OpLogicalNot %79 %1594\n%1596 = OpLogicalAnd %79 %1595 %1488\n%1597 = OpFunctionCall %1 %1539 %1468 %1578 %1593 %1596\n%1598 = OpIAdd %46 %54 %57\n%1599 = OpAccessChain %23 %30 %1598\n%1600 = OpLoad %22 %1599\n%1601 = OpIAdd %46 %54 %57\n%1602 = OpAccessChain %10 %17 %1601\n%1603 = OpLoad %9 %1602\n%1604 = OpExtInst %5 %78 RoundEven %72\n%1605 = OpConvertFToS %80 %1604\n%1606 = OpCompositeConstruct %40 %67 %69\n%1607 = OpImageQuerySize %762 %1600\n%1608 = OpVectorShuffle %82 %1607 %1607 0 1\n%1609 = OpBitwiseAnd %82 %1608 %87\n%1610 = OpImageQueryLevels %80 %1603\n%1611 = OpISub %80 %1610 %90\n%1612 = OpSampledImage %768 %1603 %1475\n%1613 = OpImageQueryLod %40 %1612 %1606\n%1614 = OpCompositeExtract %5 %1613 0\n%1615 = OpConvertFToS %80 %1614\n%1616 = OpFAdd %5 %1614 %97\n%1617 = OpConvertFToS %80 %1616\n%1618 = OpExtInst %80 %78 SMin %1617 %1611\n%1619 = OpINotEqual %79 %1615 %1617\n%1620 = OpDPdx %40 %1606\n%1621 = OpDPdy %40 %1606\n%1622 = OpExtInst %40 %78 FAbs %1620\n%1623 = OpExtInst %40 %78 FAbs %1621\n%1624 = OpCompositeExtract %5 %1622 0\n%1625 = OpCompositeExtract %5 %1623 0\n%1626 = OpCompositeExtract %5 %1622 1\n%1627 = OpCompositeExtract %5 %1623 1\n%1628 = OpExtInst %5 %78 FMax %1624 %1625\n%1629 = OpExtInst %5 %78 FMax %1626 %1627\n%1630 = OpCompositeConstruct %40 %1628 %1629\n%1631 = OpExtInst %40 %78 Fract %1606\n%1633 = OpImageQuerySizeLod %762 %1603 %1615\n%1634 = OpVectorShuffle %82 %1633 %1633 0 1\n%1632 = OpConvertSToF %40 %1634\n%1635 = OpSNegate %82 %1609\n%1636 = OpExtInst %40 %78 Ldexp %1632 %1635\n%1637 = OpFMul %40 %1631 %1636\n%1638 = OpFMul %40 %1630 %1632\n%1639 = OpFSub %40 %1638 %121\n%1640 = OpExtInst %122 %78 FrexpStruct %1639\n%1641 = OpCompositeExtract %82 %1640 1\n%1642 = OpExtInst %82 %78 SClamp %1641 %127 %129\n%1643 = OpIAdd %82 %1642 %1635\n%1644 = OpExtInst %40 %78 Ldexp %133 %1643\n%1645 = OpExtInst %40 %78 FMin %1644 %133\n%1646 = OpFSub %40 %1637 %1645\n%1647 = OpExtInst %40 %78 FMax %1646 %138\n%1648 = OpFAdd %40 %1637 %1645\n%1649 = OpConvertFToS %82 %1647\n%1650 = OpConvertFToS %82 %1648\n%1651 = OpINotEqual %81 %1649 %1650\n%1652 = OpCompositeExtract %79 %1651 0\n%1653 = OpCompositeExtract %79 %1651 1\n%1654 = OpLogicalAnd %79 %1652 %1653\n%1655 = OpSelect %80 %1652 %147 %126\n%1656 = OpBitwiseOr %80 %90 %1655\n%1657 = OpSelect %80 %1653 %128 %126\n%1658 = OpBitwiseOr %80 %1656 %1657\n%1659 = OpSelect %80 %1654 %152 %126\n%1660 = OpBitwiseOr %80 %1658 %1659\n%1661 = OpSConvert %18 %1660\n%1662 = OpIMul %80 %1615 %128\n%1663 = OpSConvert %18 %1662\n%1664 = OpShiftLeftLogical %18 %1661 %1663\n%1665 = OpCompositeConstruct %762 %1649 %1605\n%1666 = OpLoad %79 %1932\n%1667 = OpLogicalNot %79 %1666\n%1694 = OpFunctionCall %1 %1672 %1599 %1665 %1664 %1667\n%1696 = OpImageQuerySizeLod %762 %1603 %1617\n%1697 = OpVectorShuffle %82 %1696 %1696 0 1\n%1695 = OpConvertSToF %40 %1697\n%1698 = OpSNegate %82 %1609\n%1699 = OpExtInst %40 %78 Ldexp %1695 %1698\n%1700 = OpFMul %40 %1631 %1699\n%1701 = OpFMul %40 %1630 %1695\n%1702 = OpFSub %40 %1701 %121\n%1703 = OpExtInst %122 %78 FrexpStruct %1702\n%1704 = OpCompositeExtract %82 %1703 1\n%1705 = OpExtInst %82 %78 SClamp %1704 %127 %129\n%1706 = OpIAdd %82 %1705 %1698\n%1707 = OpExtInst %40 %78 Ldexp %133 %1706\n%1708 = OpExtInst %40 %78 FMin %1707 %133\n%1709 = OpFSub %40 %1700 %1708\n%1710 = OpExtInst %40 %78 FMax %1709 %138\n%1711 = OpFAdd %40 %1700 %1708\n%1712 = OpConvertFToS %82 %1710\n%1713 = OpConvertFToS %82 %1711\n%1714 = OpINotEqual %81 %1712 %1713\n%1715 = OpCompositeExtract %79 %1714 0\n%1716 = OpCompositeExtract %79 %1714 1\n%1717 = OpLogicalAnd %79 %1715 %1716\n%1718 = OpSelect %80 %1715 %147 %126\n%1719 = OpBitwiseOr %80 %90 %1718\n%1720 = OpSelect %80 %1716 %128 %126\n%1721 = OpBitwiseOr %80 %1719 %1720\n%1722 = OpSelect %80 %1717 %152 %126\n%1723 = OpBitwiseOr %80 %1721 %1722\n%1724 = OpSConvert %18 %1723\n%1725 = OpIMul %80 %1617 %128\n%1726 = OpSConvert %18 %1725\n%1727 = OpShiftLeftLogical %18 %1724 %1726\n%1728 = OpCompositeConstruct %762 %1712 %1605\n%1729 = OpLoad %79 %1932\n%1730 = OpLogicalNot %79 %1729\n%1731 = OpLogicalAnd %79 %1730 %1619\n%1732 = OpFunctionCall %1 %1672 %1599 %1728 %1727 %1731\n%1733 = OpCompositeConstruct %40 %67 %69\n%1734 = OpImageQuerySize %82 %1469\n%1735 = OpBitwiseAnd %82 %1734 %87\n%1736 = OpImageQueryLevels %80 %1472\n%1737 = OpISub %80 %1736 %90\n%1738 = OpImageQueryLod %40 %1481 %1733\n%1739 = OpCompositeExtract %5 %1738 0\n%1740 = OpConvertFToS %80 %1739\n%1741 = OpFAdd %5 %1739 %97\n%1742 = OpConvertFToS %80 %1741\n%1743 = OpExtInst %80 %78 SMin %1742 %1737\n%1744 = OpINotEqual %79 %1740 %1742\n%1745 = OpDPdx %40 %1733\n%1746 = OpDPdy %40 %1733\n%1747 = OpExtInst %40 %78 FAbs %1745\n%1748 = OpExtInst %40 %78 FAbs %1746\n%1749 = OpCompositeExtract %5 %1747 0\n%1750 = OpCompositeExtract %5 %1748 0\n%1751 = OpCompositeExtract %5 %1747 1\n%1752 = OpCompositeExtract %5 %1748 1\n%1753 = OpExtInst %5 %78 FMax %1749 %1750\n%1754 = OpExtInst %5 %78 FMax %1751 %1752\n%1755 = OpCompositeConstruct %40 %1753 %1754\n%1756 = OpExtInst %40 %78 Fract %1733\n%1758 = OpImageQuerySizeLod %82 %1472 %1740\n%1757 = OpConvertSToF %40 %1758\n%1759 = OpSNegate %82 %1735\n%1760 = OpExtInst %40 %78 Ldexp %1757 %1759\n%1761 = OpFMul %40 %1756 %1760\n%1762 = OpFMul %40 %1755 %1757\n%1763 = OpFSub %40 %1762 %121\n%1764 = OpExtInst %122 %78 FrexpStruct %1763\n%1765 = OpCompositeExtract %82 %1764 1\n%1766 = OpExtInst %82 %78 SClamp %1765 %127 %129\n%1767 = OpIAdd %82 %1766 %1759\n%1768 = OpExtInst %40 %78 Ldexp %133 %1767\n%1769 = OpExtInst %40 %78 FMin %1768 %133\n%1770 = OpFSub %40 %1761 %1769\n%1771 = OpExtInst %40 %78 FMax %1770 %138\n%1772 = OpFAdd %40 %1761 %1769\n%1773 = OpConvertFToS %82 %1771\n%1774 = OpConvertFToS %82 %1772\n%1775 = OpINotEqual %81 %1773 %1774\n%1776 = OpCompositeExtract %79 %1775 0\n%1777 = OpCompositeExtract %79 %1775 1\n%1778 = OpLogicalAnd %79 %1776 %1777\n%1779 = OpSelect %80 %1776 %147 %126\n%1780 = OpBitwiseOr %80 %90 %1779\n%1781 = OpSelect %80 %1777 %128 %126\n%1782 = OpBitwiseOr %80 %1780 %1781\n%1783 = OpSelect %80 %1778 %152 %126\n%1784 = OpBitwiseOr %80 %1782 %1783\n%1785 = OpSConvert %18 %1784\n%1786 = OpIMul %80 %1740 %128\n%1787 = OpSConvert %18 %1786\n%1788 = OpShiftLeftLogical %18 %1785 %1787\n%1789 = OpLoad %79 %1932\n%1790 = OpLogicalNot %79 %1789\n%1791 = OpFunctionCall %1 %1539 %1468 %1773 %1788 %1790\n%1793 = OpImageQuerySizeLod %82 %1472 %1742\n%1792 = OpConvertSToF %40 %1793\n%1794 = OpSNegate %82 %1735\n%1795 = OpExtInst %40 %78 Ldexp %1792 %1794\n%1796 = OpFMul %40 %1756 %1795\n%1797 = OpFMul %40 %1755 %1792\n%1798 = OpFSub %40 %1797 %121\n%1799 = OpExtInst %122 %78 FrexpStruct %1798\n%1800 = OpCompositeExtract %82 %1799 1\n%1801 = OpExtInst %82 %78 SClamp %1800 %127 %129\n%1802 = OpIAdd %82 %1801 %1794\n%1803 = OpExtInst %40 %78 Ldexp %133 %1802\n%1804 = OpExtInst %40 %78 FMin %1803 %133\n%1805 = OpFSub %40 %1796 %1804\n%1806 = OpExtInst %40 %78 FMax %1805 %138\n%1807 = OpFAdd %40 %1796 %1804\n%1808 = OpConvertFToS %82 %1806\n%1809 = OpConvertFToS %82 %1807\n%1810 = OpINotEqual %81 %1808 %1809\n%1811 = OpCompositeExtract %79 %1810 0\n%1812 = OpCompositeExtract %79 %1810 1\n%1813 = OpLogicalAnd %79 %1811 %1812\n%1814 = OpSelect %80 %1811 %147 %126\n%1815 = OpBitwiseOr %80 %90 %1814\n%1816 = OpSelect %80 %1812 %128 %126\n%1817 = OpBitwiseOr %80 %1815 %1816\n%1818 = OpSelect %80 %1813 %152 %126\n%1819 = OpBitwiseOr %80 %1817 %1818\n%1820 = OpSConvert %18 %1819\n%1821 = OpIMul %80 %1742 %128\n%1822 = OpSConvert %18 %1821\n%1823 = OpShiftLeftLogical %18 %1820 %1822\n%1824 = OpLoad %79 %1932\n%1825 = OpLogicalNot %79 %1824\n%1826 = OpLogicalAnd %79 %1825 %1744\n%1827 = OpFunctionCall %1 %1539 %1468 %1808 %1823 %1826\n%1828 = OpExtInst %5 %78 RoundEven %72\n%1829 = OpConvertFToS %80 %1828\n%1830 = OpCompositeConstruct %40 %67 %69\n%1831 = OpImageQuerySize %762 %1600\n%1832 = OpVectorShuffle %82 %1831 %1831 0 1\n%1833 = OpBitwiseAnd %82 %1832 %87\n%1834 = OpImageQueryLevels %80 %1603\n%1835 = OpISub %80 %1834 %90\n%1836 = OpImageQueryLod %40 %1612 %1830\n%1837 = OpCompositeExtract %5 %1836 0\n%1838 = OpConvertFToS %80 %1837\n%1839 = OpFAdd %5 %1837 %97\n%1840 = OpConvertFToS %80 %1839\n%1841 = OpExtInst %80 %78 SMin %1840 %1835\n%1842 = OpINotEqual %79 %1838 %1840\n%1843 = OpDPdx %40 %1830\n%1844 = OpDPdy %40 %1830\n%1845 = OpExtInst %40 %78 FAbs %1843\n%1846 = OpExtInst %40 %78 FAbs %1844\n%1847 = OpCompositeExtract %5 %1845 0\n%1848 = OpCompositeExtract %5 %1846 0\n%1849 = OpCompositeExtract %5 %1845 1\n%1850 = OpCompositeExtract %5 %1846 1\n%1851 = OpExtInst %5 %78 FMax %1847 %1848\n%1852 = OpExtInst %5 %78 FMax %1849 %1850\n%1853 = OpCompositeConstruct %40 %1851 %1852\n%1854 = OpExtInst %40 %78 Fract %1830\n%1856 = OpImageQuerySizeLod %762 %1603 %1838\n%1857 = OpVectorShuffle %82 %1856 %1856 0 1\n%1855 = OpConvertSToF %40 %1857\n%1858 = OpSNegate %82 %1833\n%1859 = OpExtInst %40 %78 Ldexp %1855 %1858\n%1860 = OpFMul %40 %1854 %1859\n%1861 = OpFMul %40 %1853 %1855\n%1862 = OpFSub %40 %1861 %121\n%1863 = OpExtInst %122 %78 FrexpStruct %1862\n%1864 = OpCompositeExtract %82 %1863 1\n%1865 = OpExtInst %82 %78 SClamp %1864 %127 %129\n%1866 = OpIAdd %82 %1865 %1858\n%1867 = OpExtInst %40 %78 Ldexp %133 %1866\n%1868 = OpExtInst %40 %78 FMin %1867 %133\n%1869 = OpFSub %40 %1860 %1868\n%1870 = OpExtInst %40 %78 FMax %1869 %138\n%1871 = OpFAdd %40 %1860 %1868\n%1872 = OpConvertFToS %82 %1870\n%1873 = OpConvertFToS %82 %1871\n%1874 = OpINotEqual %81 %1872 %1873\n%1875 = OpCompositeExtract %79 %1874 0\n%1876 = OpCompositeExtract %79 %1874 1\n%1877 = OpLogicalAnd %79 %1875 %1876\n%1878 = OpSelect %80 %1875 %147 %126\n%1879 = OpBitwiseOr %80 %90 %1878\n%1880 = OpSelect %80 %1876 %128 %126\n%1881 = OpBitwiseOr %80 %1879 %1880\n%1882 = OpSelect %80 %1877 %152 %126\n%1883 = OpBitwiseOr %80 %1881 %1882\n%1884 = OpSConvert %18 %1883\n%1885 = OpIMul %80 %1838 %128\n%1886 = OpSConvert %18 %1885\n%1887 = OpShiftLeftLogical %18 %1884 %1886\n%1888 = OpCompositeConstruct %762 %1872 %1829\n%1889 = OpLoad %79 %1932\n%1890 = OpLogicalNot %79 %1889\n%1891 = OpFunctionCall %1 %1672 %1599 %1888 %1887 %1890\n%1893 = OpImageQuerySizeLod %762 %1603 %1840\n%1894 = OpVectorShuffle %82 %1893 %1893 0 1\n%1892 = OpConvertSToF %40 %1894\n%1895 = OpSNegate %82 %1833\n%1896 = OpExtInst %40 %78 Ldexp %1892 %1895\n%1897 = OpFMul %40 %1854 %1896\n%1898 = OpFMul %40 %1853 %1892\n%1899 = OpFSub %40 %1898 %121\n%1900 = OpExtInst %122 %78 FrexpStruct %1899\n%1901 = OpCompositeExtract %82 %1900 1\n%1902 = OpExtInst %82 %78 SClamp %1901 %127 %129\n%1903 = OpIAdd %82 %1902 %1895\n%1904 = OpExtInst %40 %78 Ldexp %133 %1903\n%1905 = OpExtInst %40 %78 FMin %1904 %133\n%1906 = OpFSub %40 %1897 %1905\n%1907 = OpExtInst %40 %78 FMax %1906 %138\n%1908 = OpFAdd %40 %1897 %1905\n%1909 = OpConvertFToS %82 %1907\n%1910 = OpConvertFToS %82 %1908\n%1911 = OpINotEqual %81 %1909 %1910\n%1912 = OpCompositeExtract %79 %1911 0\n%1913 = OpCompositeExtract %79 %1911 1\n%1914 = OpLogicalAnd %79 %1912 %1913\n%1915 = OpSelect %80 %1912 %147 %126\n%1916 = OpBitwiseOr %80 %90 %1915\n%1917 = OpSelect %80 %1913 %128 %126\n%1918 = OpBitwiseOr %80 %1916 %1917\n%1919 = OpSelect %80 %1914 %152 %126\n%1920 = OpBitwiseOr %80 %1918 %1919\n%1921 = OpSConvert %18 %1920\n%1922 = OpIMul %80 %1840 %128\n%1923 = OpSConvert %18 %1922\n%1924 = OpShiftLeftLogical %18 %1921 %1923\n%1925 = OpCompositeConstruct %762 %1909 %1829\n%1926 = OpLoad %79 %1932\n%1927 = OpLogicalNot %79 %1926\n%1928 = OpLogicalAnd %79 %1927 %1842\n%1929 = OpFunctionCall %1 %1672 %1599 %1925 %1924 %1928\nOpReturn\nOpFunctionEnd\n%166 = OpFunction %1 None %161\n%162 = OpFunctionParameter %20\n%163 = OpFunctionParameter %82\n%164 = OpFunctionParameter %18\n%165 = OpFunctionParameter %79\n%167 = OpLabel\n%179 = OpVariable %178 Function %177\nOpSelectionMerge %169 None\nOpBranchConditional %165 %168 %169\n%168 = OpLabel\n%180 = OpLoad %79 %179\n%181 = OpLogicalNot %79 %180\nOpLoopMerge %170 %172 None\nOpBranchConditional %181 %171 %170\n%171 = OpLabel\n%182 = OpGroupNonUniformBroadcastFirst %82 %74 %163\n%183 = OpIEqual %81 %163 %182\n%184 = OpAll %79 %183\nOpStore %179 %184\nOpSelectionMerge %174 None\nOpBranchConditional %184 %173 %174\n%173 = OpLabel\n%185 = OpGroupNonUniformBitwiseOr %18 %74 Reduce %164\n%186 = OpGroupNonUniformElect %79 %74\nOpSelectionMerge %176 None\nOpBranchConditional %186 %175 %176\n%175 = OpLabel\n%187 = OpImageTexelPointer %160 %162 %163 %126\n%188 = OpAtomicOr %18 %187 %60 %57 %185\nOpBranch %176\n%176 = OpLabel\nOpBranch %174\n%174 = OpLabel\nOpBranch %172\n%172 = OpLabel\nOpBranch %168\n%170 = OpLabel\nOpBranch %169\n%169 = OpLabel\nOpReturn\nOpFunctionEnd\n%831 = OpFunction %1 None %826\n%827 = OpFunctionParameter %23\n%828 = OpFunctionParameter %762\n%829 = OpFunctionParameter %18\n%830 = OpFunctionParameter %79\n%832 = OpLabel\n%842 = OpVariable %178 Function %177\nOpSelectionMerge %834 None\nOpBranchConditional %830 %833 %834\n%833 = OpLabel\n%843 = OpLoad %79 %842\n%844 = OpLogicalNot %79 %843\nOpLoopMerge %835 %837 None\nOpBranchConditional %844 %836 %835\n%836 = OpLabel\n%845 = OpGroupNonUniformBroadcastFirst %762 %74 %828\n%846 = OpIEqual %825 %828 %845\n%847 = OpAll %79 %846\nOpStore %842 %847\nOpSelectionMerge %839 None\nOpBranchConditional %847 %838 %839\n%838 = OpLabel\n%848 = OpGroupNonUniformBitwiseOr %18 %74 Reduce %829\n%849 = OpGroupNonUniformElect %79 %74\nOpSelectionMerge %841 None\nOpBranchConditional %849 %840 %841\n%840 = OpLabel\n%850 = OpImageTexelPointer %160 %827 %828 %126\n%851 = OpAtomicOr %18 %850 %60 %57 %848\nOpBranch %841\n%841 = OpLabel\nOpBranch %839\n%839 = OpLabel\nOpBranch %837\n%837 = OpLabel\nOpBranch %833\n%835 = OpLabel\nOpBranch %834\n%834 = OpLabel\nOpReturn\nOpFunctionEnd\n%1539 = OpFunction %1 None %161\n%1535 = OpFunctionParameter %20\n%1536 = OpFunctionParameter %82\n%1537 = OpFunctionParameter %18\n%1538 = OpFunctionParameter %79\n%1540 = OpLabel\n%1550 = OpVariable %178 Function %177\nOpSelectionMerge %1542 None\nOpBranchConditional %1538 %1541 %1542\n%1541 = OpLabel\n%1551 = OpLoad %79 %1550\n%1552 = OpLogicalNot %79 %1551\nOpLoopMerge %1543 %1545 None\nOpBranchConditional %1552 %1544 %1543\n%1544 = OpLabel\n%1553 = OpGroupNonUniformBroadcastFirst %82 %74 %1536\n%1554 = OpIEqual %81 %1536 %1553\n%1555 = OpAll %79 %1554\nOpStore %1550 %1555\nOpSelectionMerge %1547 None\nOpBranchConditional %1555 %1546 %1547\n%1546 = OpLabel\n%1556 = OpGroupNonUniformBitwiseOr %18 %74 Reduce %1537\n%1557 = OpGroupNonUniformElect %79 %74\nOpSelectionMerge %1549 None\nOpBranchConditional %1557 %1548 %1549\n%1548 = OpLabel\n%1558 = OpImageTexelPointer %160 %1535 %1536 %126\n%1559 = OpAtomicOr %18 %1558 %60 %57 %1556\nOpBranch %1549\n%1549 = OpLabel\nOpBranch %1547\n%1547 = OpLabel\nOpBranch %1545\n%1545 = OpLabel\nOpBranch %1541\n%1543 = OpLabel\nOpBranch %1542\n%1542 = OpLabel\nOpReturn\nOpFunctionEnd\n%1672 = OpFunction %1 None %826\n%1668 = OpFunctionParameter %23\n%1669 = OpFunctionParameter %762\n%1670 = OpFunctionParameter %18\n%1671 = OpFunctionParameter %79\n%1673 = OpLabel\n%1683 = OpVariable %178 Function %177\nOpSelectionMerge %1675 None\nOpBranchConditional %1671 %1674 %1675\n%1674 = OpLabel\n%1684 = OpLoad %79 %1683\n%1685 = OpLogicalNot %79 %1684\nOpLoopMerge %1676 %1678 None\nOpBranchConditional %1685 %1677 %1676\n%1677 = OpLabel\n%1686 = OpGroupNonUniformBroadcastFirst %762 %74 %1669\n%1687 = OpIEqual %825 %1669 %1686\n%1688 = OpAll %79 %1687\nOpStore %1683 %1688\nOpSelectionMerge %1680 None\nOpBranchConditional %1688 %1679 %1680\n%1679 = OpLabel\n%1689 = OpGroupNonUniformBitwiseOr %18 %74 Reduce %1670\n%1690 = OpGroupNonUniformElect %79 %74\nOpSelectionMerge %1682 None\nOpBranchConditional %1690 %1681 %1682\n%1681 = OpLabel\n%1691 = OpImageTexelPointer %160 %1668 %1669 %126\n%1692 = OpAtomicOr %18 %1691 %60 %57 %1689\nOpBranch %1682\n%1682 = OpLabel\nOpBranch %1680\n%1680 = OpLabel\nOpBranch %1678\n%1678 = OpLabel\nOpBranch %1674\n%1676 = OpLabel\nOpBranch %1675\n%1675 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/sampler-feedback/sampler-feedback.sm66.frag",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_shader_image_int64 : require\n#extension GL_KHR_shader_subgroup_ballot : require\n#extension GL_KHR_shader_subgroup_arithmetic : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_EXT_shader_atomic_int64 : require\n#extension GL_EXT_samplerless_texture_functions : require\n#extension GL_EXT_spirv_intrinsics : require\n#extension GL_KHR_shader_subgroup_quad : require\n\nstruct ResType\n{\n    vec2 _m0;\n    ivec2 _m1;\n};\n\nlayout(set = 0, binding = 0, r64ui) uniform readonly writeonly u64image2D _9[];\nlayout(set = 0, binding = 0) uniform texture2D _13;\nlayout(set = 0, binding = 1) uniform texture2DArray _16;\nlayout(set = 1, binding = 0) uniform texture2D _19[];\nlayout(set = 2, binding = 0) uniform texture2DArray _22[];\nlayout(set = 0, binding = 0, r64ui) uniform readonly writeonly u64image2D _24;\nlayout(set = 0, binding = 1, r64ui) uniform readonly writeonly u64image2DArray _27;\nlayout(set = 1, binding = 0, r64ui) uniform readonly writeonly u64image2D _30[];\nlayout(set = 2, binding = 0, r64ui) uniform readonly writeonly u64image2DArray _33[];\nlayout(set = 0, binding = 0) uniform sampler _36;\nlayout(set = 1, binding = 0) uniform sampler _39[];\n\nlayout(location = 1) in vec2 GRADX;\nlayout(location = 1, component = 2) in vec2 GRADY;\nlayout(location = 2) in float CLAMP;\nlayout(location = 3) flat in uint IDX;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float spvNClamp(float, float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec2 spvNClamp(vec2, vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec3 spvNClamp(vec3, vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec4 spvNClamp(vec4, vec4, vec4);\n\nvoid WriteFeedback(u64image2D img, ivec2 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _185 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _185;\n            if (_185)\n            {\n                uint64_t _186 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _189 = imageAtomicOr(img, coord, _186);\n                }\n            }\n        }\n    }\n}\n\nvoid WriteFeedbackArray(u64image2DArray img, ivec3 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _872 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _872;\n            if (_872)\n            {\n                uint64_t _873 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _876 = imageAtomicOr(img, coord, _873);\n                }\n            }\n        }\n    }\n}\n\nvoid WriteFeedbackNonUniform(u64image2D img, ivec2 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _1601 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _1601;\n            if (_1601)\n            {\n                uint64_t _1602 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _1605 = imageAtomicOr(img, coord, _1602);\n                }\n            }\n        }\n    }\n}\n\nvoid WriteFeedbackArrayNonUniform(u64image2DArray img, ivec3 coord, uint64_t value, bool active_lane)\n{\n    bool is_done = false;\n    if (active_lane)\n    {\n        while (!is_done)\n        {\n            bool _1736 = all(equal(coord, subgroupBroadcastFirst(coord)));\n            is_done = _1736;\n            if (_1736)\n            {\n                uint64_t _1737 = subgroupOr(value);\n                if (subgroupElect())\n                {\n                    uint64_t _1740 = imageAtomicOr(img, coord, _1737);\n                }\n            }\n        }\n    }\n}\n\nvoid main()\n{\n    float _74 = 1.0 / gl_FragCoord.w;\n    vec2 _84 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _86 = imageSize(_24) & ivec2(15);\n    vec2 _94 = textureQueryLod(sampler2D(_13, _36), _84);\n    float _95 = _94.x;\n    int _96 = int(_95);\n    int _99 = int(_95 + 0.9970703125);\n    vec2 _104 = abs(dFdx(_84));\n    vec2 _105 = abs(dFdy(_84));\n    vec2 _112 = vec2(max(_104.x, _105.x), max(_104.y, _105.y));\n    vec2 _113 = fract(_84);\n    vec2 _114 = vec2(textureSize(_13, _96));\n    ivec2 _116 = -_86;\n    vec2 _118 = _113 * ldexp(_114, _116);\n    ResType _124;\n    _124._m0 = frexp((_112 * _114) - vec2(0.00390625), _124._m1);\n    vec2 _135 = min(ldexp(vec2(0.5), clamp(_124._m1, ivec2(0), ivec2(4)) + _116), vec2(0.5));\n    ivec2 _141 = ivec2(max(_118 - _135, vec2(0.0)));\n    bvec2 _143 = notEqual(_141, ivec2(_118 + _135));\n    bool _144 = _143.x;\n    bool _145 = _143.y;\n    WriteFeedback(_24, _141, uint64_t(((1 | (_144 ? 2 : 0)) | (_145 ? 4 : 0)) | ((_144 && _145) ? 8 : 0)) << uint64_t(_96 * 4), !gl_HelperInvocation);\n    vec2 _192 = vec2(textureSize(_13, _99));\n    ivec2 _194 = -_86;\n    vec2 _196 = _113 * ldexp(_192, _194);\n    ResType _199;\n    _199._m0 = frexp((_112 * _192) - vec2(0.00390625), _199._m1);\n    vec2 _204 = min(ldexp(vec2(0.5), clamp(_199._m1, ivec2(0), ivec2(4)) + _194), vec2(0.5));\n    ivec2 _208 = ivec2(max(_196 - _204, vec2(0.0)));\n    bvec2 _210 = notEqual(_208, ivec2(_196 + _204));\n    bool _211 = _210.x;\n    bool _212 = _210.y;\n    WriteFeedback(_24, _208, uint64_t(((1 | (_211 ? 2 : 0)) | (_212 ? 4 : 0)) | ((_211 && _212) ? 8 : 0)) << uint64_t(_99 * 4), (!gl_HelperInvocation) && (_96 != _99));\n    vec2 _231 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _233 = imageSize(_24) & ivec2(15);\n    float _240 = min(max(textureQueryLod(sampler2D(_13, _36), _231).x, CLAMP), 14.0);\n    int _242 = int(_240);\n    int _244 = int(_240 + 0.9970703125);\n    vec2 _249 = abs(dFdx(_231));\n    vec2 _250 = abs(dFdy(_231));\n    vec2 _257 = vec2(max(_249.x, _250.x), max(_249.y, _250.y));\n    vec2 _258 = fract(_231);\n    vec2 _259 = vec2(textureSize(_13, _242));\n    ivec2 _261 = -_233;\n    vec2 _263 = _258 * ldexp(_259, _261);\n    ResType _266;\n    _266._m0 = frexp((_257 * _259) - vec2(0.00390625), _266._m1);\n    vec2 _271 = min(ldexp(vec2(0.5), clamp(_266._m1, ivec2(0), ivec2(4)) + _261), vec2(0.5));\n    ivec2 _275 = ivec2(max(_263 - _271, vec2(0.0)));\n    bvec2 _277 = notEqual(_275, ivec2(_263 + _271));\n    bool _278 = _277.x;\n    bool _279 = _277.y;\n    WriteFeedback(_24, _275, uint64_t(((1 | (_278 ? 2 : 0)) | (_279 ? 4 : 0)) | ((_278 && _279) ? 8 : 0)) << uint64_t(_242 * 4), !gl_HelperInvocation);\n    vec2 _294 = vec2(textureSize(_13, _244));\n    ivec2 _296 = -_233;\n    vec2 _298 = _258 * ldexp(_294, _296);\n    ResType _301;\n    _301._m0 = frexp((_257 * _294) - vec2(0.00390625), _301._m1);\n    vec2 _306 = min(ldexp(vec2(0.5), clamp(_301._m1, ivec2(0), ivec2(4)) + _296), vec2(0.5));\n    ivec2 _310 = ivec2(max(_298 - _306, vec2(0.0)));\n    bvec2 _312 = notEqual(_310, ivec2(_298 + _306));\n    bool _313 = _312.x;\n    bool _314 = _312.y;\n    WriteFeedback(_24, _310, uint64_t(((1 | (_313 ? 2 : 0)) | (_314 ? 4 : 0)) | ((_313 && _314) ? 8 : 0)) << uint64_t(_244 * 4), (!gl_HelperInvocation) && (_242 != _244));\n    ivec2 _335 = imageSize(_24) & ivec2(15);\n    int _337 = textureQueryLevels(_13) - 1;\n    float _339 = spvNClamp(gl_FragCoord.z, 0.0, float(_337));\n    int _340 = int(_339);\n    int _342 = int(_339 + 0.9970703125);\n    vec2 _345 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _348 = -_335;\n    vec2 _350 = _345 * ldexp(vec2(textureSize(_13, _340)), _348);\n    vec2 _351 = ldexp(vec2(0.5), _348);\n    ivec2 _355 = ivec2(max(_350 - _351, vec2(0.0)));\n    bvec2 _357 = notEqual(_355, ivec2(_350 + _351));\n    bool _358 = _357.x;\n    bool _359 = _357.y;\n    WriteFeedback(_24, _355, uint64_t(((1 | (_358 ? 2 : 0)) | (_359 ? 4 : 0)) | ((_358 && _359) ? 8 : 0)) << uint64_t(_340 * 4), !gl_HelperInvocation);\n    ivec2 _376 = -_335;\n    vec2 _378 = _345 * ldexp(vec2(textureSize(_13, _342)), _376);\n    vec2 _379 = ldexp(vec2(0.5), _376);\n    ivec2 _383 = ivec2(max(_378 - _379, vec2(0.0)));\n    bvec2 _385 = notEqual(_383, ivec2(_378 + _379));\n    bool _386 = _385.x;\n    bool _387 = _385.y;\n    WriteFeedback(_24, _383, uint64_t(((1 | (_386 ? 2 : 0)) | (_387 ? 4 : 0)) | ((_386 && _387) ? 8 : 0)) << uint64_t(_342 * 4), (!gl_HelperInvocation) && (_340 != _342));\n    ivec2 _408 = imageSize(_24) & ivec2(15);\n    int _410 = textureQueryLevels(_13) - 1;\n    vec2 _411 = vec2(textureSize(_13, 0));\n    vec2 _415 = _411 * vec2(GRADX.x, GRADX.y);\n    vec2 _416 = _411 * vec2(GRADY.x, GRADY.y);\n    float _423 = spvNClamp(log2(max(dot(_415, _415), dot(_416, _416))) * 0.5, 0.0, float(_410));\n    int _424 = int(_423);\n    int _426 = int(_423 + 0.9970703125);\n    vec2 _429 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _432 = -_408;\n    vec2 _434 = _429 * ldexp(vec2(textureSize(_13, _424)), _432);\n    vec2 _435 = ldexp(vec2(0.5), _432);\n    ivec2 _439 = ivec2(max(_434 - _435, vec2(0.0)));\n    bvec2 _441 = notEqual(_439, ivec2(_434 + _435));\n    bool _442 = _441.x;\n    bool _443 = _441.y;\n    WriteFeedback(_24, _439, uint64_t(((1 | (_442 ? 2 : 0)) | (_443 ? 4 : 0)) | ((_442 && _443) ? 8 : 0)) << uint64_t(_424 * 4), !gl_HelperInvocation);\n    ivec2 _460 = -_408;\n    vec2 _462 = _429 * ldexp(vec2(textureSize(_13, _426)), _460);\n    vec2 _463 = ldexp(vec2(0.5), _460);\n    ivec2 _467 = ivec2(max(_462 - _463, vec2(0.0)));\n    bvec2 _469 = notEqual(_467, ivec2(_462 + _463));\n    bool _470 = _469.x;\n    bool _471 = _469.y;\n    WriteFeedback(_24, _467, uint64_t(((1 | (_470 ? 2 : 0)) | (_471 ? 4 : 0)) | ((_470 && _471) ? 8 : 0)) << uint64_t(_426 * 4), (!gl_HelperInvocation) && (_424 != _426));\n    ivec2 _492 = imageSize(_24) & ivec2(15);\n    int _494 = textureQueryLevels(_13) - 1;\n    vec2 _495 = vec2(textureSize(_13, 0));\n    vec2 _499 = _495 * vec2(GRADX.x, GRADX.y);\n    vec2 _500 = _495 * vec2(GRADY.x, GRADY.y);\n    float _509 = min(max(spvNClamp(log2(max(dot(_499, _499), dot(_500, _500))) * 0.5, 0.0, float(_494)), CLAMP), 14.0);\n    int _510 = int(_509);\n    int _512 = int(_509 + 0.9970703125);\n    vec2 _515 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _518 = -_492;\n    vec2 _520 = _515 * ldexp(vec2(textureSize(_13, _510)), _518);\n    vec2 _521 = ldexp(vec2(0.5), _518);\n    ivec2 _525 = ivec2(max(_520 - _521, vec2(0.0)));\n    bvec2 _527 = notEqual(_525, ivec2(_520 + _521));\n    bool _528 = _527.x;\n    bool _529 = _527.y;\n    WriteFeedback(_24, _525, uint64_t(((1 | (_528 ? 2 : 0)) | (_529 ? 4 : 0)) | ((_528 && _529) ? 8 : 0)) << uint64_t(_510 * 4), !gl_HelperInvocation);\n    ivec2 _546 = -_492;\n    vec2 _548 = _515 * ldexp(vec2(textureSize(_13, _512)), _546);\n    vec2 _549 = ldexp(vec2(0.5), _546);\n    ivec2 _553 = ivec2(max(_548 - _549, vec2(0.0)));\n    bvec2 _555 = notEqual(_553, ivec2(_548 + _549));\n    bool _556 = _555.x;\n    bool _557 = _555.y;\n    WriteFeedback(_24, _553, uint64_t(((1 | (_556 ? 2 : 0)) | (_557 ? 4 : 0)) | ((_556 && _557) ? 8 : 0)) << uint64_t(_512 * 4), (!gl_HelperInvocation) && (_510 != _512));\n    vec2 _576 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _578 = imageSize(_24) & ivec2(15);\n    float _582 = exp2(gl_FragCoord.z);\n    vec2 _585 = textureQueryLod(sampler2D(_13, _36), _576 * subgroupQuadBroadcast(_582, 0u));\n    float _586 = _585.x;\n    int _587 = int(_586);\n    int _589 = int(_586 + 0.9970703125);\n    vec2 _594 = abs(dFdx(_576));\n    vec2 _595 = abs(dFdy(_576));\n    vec2 _603 = vec2(max(_594.x, _595.x), max(_594.y, _595.y)) * _582;\n    vec2 _604 = fract(_576);\n    vec2 _605 = vec2(textureSize(_13, _587));\n    ivec2 _607 = -_578;\n    vec2 _609 = _604 * ldexp(_605, _607);\n    ResType _612;\n    _612._m0 = frexp((_603 * _605) - vec2(0.00390625), _612._m1);\n    vec2 _617 = min(ldexp(vec2(0.5), clamp(_612._m1, ivec2(0), ivec2(4)) + _607), vec2(0.5));\n    ivec2 _621 = ivec2(max(_609 - _617, vec2(0.0)));\n    bvec2 _623 = notEqual(_621, ivec2(_609 + _617));\n    bool _624 = _623.x;\n    bool _625 = _623.y;\n    WriteFeedback(_24, _621, uint64_t(((1 | (_624 ? 2 : 0)) | (_625 ? 4 : 0)) | ((_624 && _625) ? 8 : 0)) << uint64_t(_587 * 4), !gl_HelperInvocation);\n    vec2 _640 = vec2(textureSize(_13, _589));\n    ivec2 _642 = -_578;\n    vec2 _644 = _604 * ldexp(_640, _642);\n    ResType _647;\n    _647._m0 = frexp((_603 * _640) - vec2(0.00390625), _647._m1);\n    vec2 _652 = min(ldexp(vec2(0.5), clamp(_647._m1, ivec2(0), ivec2(4)) + _642), vec2(0.5));\n    ivec2 _656 = ivec2(max(_644 - _652, vec2(0.0)));\n    bvec2 _658 = notEqual(_656, ivec2(_644 + _652));\n    bool _659 = _658.x;\n    bool _660 = _658.y;\n    WriteFeedback(_24, _656, uint64_t(((1 | (_659 ? 2 : 0)) | (_660 ? 4 : 0)) | ((_659 && _660) ? 8 : 0)) << uint64_t(_589 * 4), (!gl_HelperInvocation) && (_587 != _589));\n    vec2 _679 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _681 = imageSize(_24) & ivec2(15);\n    float _685 = exp2(gl_FragCoord.z);\n    float _691 = min(max(textureQueryLod(sampler2D(_13, _36), _679 * subgroupQuadBroadcast(_685, 0u)).x, CLAMP), 14.0);\n    int _692 = int(_691);\n    int _694 = int(_691 + 0.9970703125);\n    vec2 _699 = abs(dFdx(_679));\n    vec2 _700 = abs(dFdy(_679));\n    vec2 _708 = vec2(max(_699.x, _700.x), max(_699.y, _700.y)) * _685;\n    vec2 _709 = fract(_679);\n    vec2 _710 = vec2(textureSize(_13, _692));\n    ivec2 _712 = -_681;\n    vec2 _714 = _709 * ldexp(_710, _712);\n    ResType _717;\n    _717._m0 = frexp((_708 * _710) - vec2(0.00390625), _717._m1);\n    vec2 _722 = min(ldexp(vec2(0.5), clamp(_717._m1, ivec2(0), ivec2(4)) + _712), vec2(0.5));\n    ivec2 _726 = ivec2(max(_714 - _722, vec2(0.0)));\n    bvec2 _728 = notEqual(_726, ivec2(_714 + _722));\n    bool _729 = _728.x;\n    bool _730 = _728.y;\n    WriteFeedback(_24, _726, uint64_t(((1 | (_729 ? 2 : 0)) | (_730 ? 4 : 0)) | ((_729 && _730) ? 8 : 0)) << uint64_t(_692 * 4), !gl_HelperInvocation);\n    vec2 _745 = vec2(textureSize(_13, _694));\n    ivec2 _747 = -_681;\n    vec2 _749 = _709 * ldexp(_745, _747);\n    ResType _752;\n    _752._m0 = frexp((_708 * _745) - vec2(0.00390625), _752._m1);\n    vec2 _757 = min(ldexp(vec2(0.5), clamp(_752._m1, ivec2(0), ivec2(4)) + _747), vec2(0.5));\n    ivec2 _761 = ivec2(max(_749 - _757, vec2(0.0)));\n    bvec2 _763 = notEqual(_761, ivec2(_749 + _757));\n    bool _764 = _763.x;\n    bool _765 = _763.y;\n    WriteFeedback(_24, _761, uint64_t(((1 | (_764 ? 2 : 0)) | (_765 ? 4 : 0)) | ((_764 && _765) ? 8 : 0)) << uint64_t(_694 * 4), (!gl_HelperInvocation) && (_692 != _694));\n    int _785 = int(roundEven(gl_FragCoord.z));\n    vec2 _786 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _790 = imageSize(_27).xy & ivec2(15);\n    vec2 _795 = textureQueryLod(sampler2DArray(_16, _36), _786);\n    float _796 = _795.x;\n    int _797 = int(_796);\n    int _799 = int(_796 + 0.9970703125);\n    vec2 _804 = abs(dFdx(_786));\n    vec2 _805 = abs(dFdy(_786));\n    vec2 _812 = vec2(max(_804.x, _805.x), max(_804.y, _805.y));\n    vec2 _813 = fract(_786);\n    vec2 _814 = vec2(textureSize(_16, _797).xy);\n    ivec2 _817 = -_790;\n    vec2 _819 = _813 * ldexp(_814, _817);\n    ResType _822;\n    _822._m0 = frexp((_812 * _814) - vec2(0.00390625), _822._m1);\n    vec2 _827 = min(ldexp(vec2(0.5), clamp(_822._m1, ivec2(0), ivec2(4)) + _817), vec2(0.5));\n    ivec2 _831 = ivec2(max(_819 - _827, vec2(0.0)));\n    bvec2 _833 = notEqual(_831, ivec2(_819 + _827));\n    bool _834 = _833.x;\n    bool _835 = _833.y;\n    WriteFeedbackArray(_27, ivec3(_831, _785), uint64_t(((1 | (_834 ? 2 : 0)) | (_835 ? 4 : 0)) | ((_834 && _835) ? 8 : 0)) << uint64_t(_797 * 4), !gl_HelperInvocation);\n    vec2 _879 = vec2(textureSize(_16, _799).xy);\n    ivec2 _882 = -_790;\n    vec2 _884 = _813 * ldexp(_879, _882);\n    ResType _887;\n    _887._m0 = frexp((_812 * _879) - vec2(0.00390625), _887._m1);\n    vec2 _892 = min(ldexp(vec2(0.5), clamp(_887._m1, ivec2(0), ivec2(4)) + _882), vec2(0.5));\n    ivec2 _896 = ivec2(max(_884 - _892, vec2(0.0)));\n    bvec2 _898 = notEqual(_896, ivec2(_884 + _892));\n    bool _899 = _898.x;\n    bool _900 = _898.y;\n    WriteFeedbackArray(_27, ivec3(_896, _785), uint64_t(((1 | (_899 ? 2 : 0)) | (_900 ? 4 : 0)) | ((_899 && _900) ? 8 : 0)) << uint64_t(_799 * 4), (!gl_HelperInvocation) && (_797 != _799));\n    int _921 = int(roundEven(gl_FragCoord.z));\n    vec2 _922 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _925 = imageSize(_27).xy & ivec2(15);\n    float _932 = min(max(textureQueryLod(sampler2DArray(_16, _36), _922).x, CLAMP), 14.0);\n    int _933 = int(_932);\n    int _935 = int(_932 + 0.9970703125);\n    vec2 _940 = abs(dFdx(_922));\n    vec2 _941 = abs(dFdy(_922));\n    vec2 _948 = vec2(max(_940.x, _941.x), max(_940.y, _941.y));\n    vec2 _949 = fract(_922);\n    vec2 _950 = vec2(textureSize(_16, _933).xy);\n    ivec2 _953 = -_925;\n    vec2 _955 = _949 * ldexp(_950, _953);\n    ResType _958;\n    _958._m0 = frexp((_948 * _950) - vec2(0.00390625), _958._m1);\n    vec2 _963 = min(ldexp(vec2(0.5), clamp(_958._m1, ivec2(0), ivec2(4)) + _953), vec2(0.5));\n    ivec2 _967 = ivec2(max(_955 - _963, vec2(0.0)));\n    bvec2 _969 = notEqual(_967, ivec2(_955 + _963));\n    bool _970 = _969.x;\n    bool _971 = _969.y;\n    WriteFeedbackArray(_27, ivec3(_967, _921), uint64_t(((1 | (_970 ? 2 : 0)) | (_971 ? 4 : 0)) | ((_970 && _971) ? 8 : 0)) << uint64_t(_933 * 4), !gl_HelperInvocation);\n    vec2 _987 = vec2(textureSize(_16, _935).xy);\n    ivec2 _990 = -_925;\n    vec2 _992 = _949 * ldexp(_987, _990);\n    ResType _995;\n    _995._m0 = frexp((_948 * _987) - vec2(0.00390625), _995._m1);\n    vec2 _1000 = min(ldexp(vec2(0.5), clamp(_995._m1, ivec2(0), ivec2(4)) + _990), vec2(0.5));\n    ivec2 _1004 = ivec2(max(_992 - _1000, vec2(0.0)));\n    bvec2 _1006 = notEqual(_1004, ivec2(_992 + _1000));\n    bool _1007 = _1006.x;\n    bool _1008 = _1006.y;\n    WriteFeedbackArray(_27, ivec3(_1004, _921), uint64_t(((1 | (_1007 ? 2 : 0)) | (_1008 ? 4 : 0)) | ((_1007 && _1008) ? 8 : 0)) << uint64_t(_935 * 4), (!gl_HelperInvocation) && (_933 != _935));\n    int _1029 = int(roundEven(gl_FragCoord.z));\n    ivec2 _1033 = imageSize(_27).xy & ivec2(15);\n    int _1035 = textureQueryLevels(_16) - 1;\n    float _1037 = spvNClamp(_74, 0.0, float(_1035));\n    int _1038 = int(_1037);\n    int _1040 = int(_1037 + 0.9970703125);\n    vec2 _1043 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _1047 = -_1033;\n    vec2 _1049 = _1043 * ldexp(vec2(textureSize(_16, _1038).xy), _1047);\n    vec2 _1050 = ldexp(vec2(0.5), _1047);\n    ivec2 _1054 = ivec2(max(_1049 - _1050, vec2(0.0)));\n    bvec2 _1056 = notEqual(_1054, ivec2(_1049 + _1050));\n    bool _1057 = _1056.x;\n    bool _1058 = _1056.y;\n    WriteFeedbackArray(_27, ivec3(_1054, _1029), uint64_t(((1 | (_1057 ? 2 : 0)) | (_1058 ? 4 : 0)) | ((_1057 && _1058) ? 8 : 0)) << uint64_t(_1038 * 4), !gl_HelperInvocation);\n    ivec2 _1077 = -_1033;\n    vec2 _1079 = _1043 * ldexp(vec2(textureSize(_16, _1040).xy), _1077);\n    vec2 _1080 = ldexp(vec2(0.5), _1077);\n    ivec2 _1084 = ivec2(max(_1079 - _1080, vec2(0.0)));\n    bvec2 _1086 = notEqual(_1084, ivec2(_1079 + _1080));\n    bool _1087 = _1086.x;\n    bool _1088 = _1086.y;\n    WriteFeedbackArray(_27, ivec3(_1084, _1029), uint64_t(((1 | (_1087 ? 2 : 0)) | (_1088 ? 4 : 0)) | ((_1087 && _1088) ? 8 : 0)) << uint64_t(_1040 * 4), (!gl_HelperInvocation) && (_1038 != _1040));\n    int _1109 = int(roundEven(gl_FragCoord.z));\n    ivec2 _1113 = imageSize(_27).xy & ivec2(15);\n    int _1115 = textureQueryLevels(_16) - 1;\n    vec2 _1116 = vec2(textureSize(_16, 0).xy);\n    vec2 _1121 = _1116 * vec2(GRADX.x, GRADX.y);\n    vec2 _1122 = _1116 * vec2(GRADY.x, GRADY.y);\n    float _1129 = spvNClamp(log2(max(dot(_1121, _1121), dot(_1122, _1122))) * 0.5, 0.0, float(_1115));\n    int _1130 = int(_1129);\n    int _1132 = int(_1129 + 0.9970703125);\n    vec2 _1135 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _1139 = -_1113;\n    vec2 _1141 = _1135 * ldexp(vec2(textureSize(_16, _1130).xy), _1139);\n    vec2 _1142 = ldexp(vec2(0.5), _1139);\n    ivec2 _1146 = ivec2(max(_1141 - _1142, vec2(0.0)));\n    bvec2 _1148 = notEqual(_1146, ivec2(_1141 + _1142));\n    bool _1149 = _1148.x;\n    bool _1150 = _1148.y;\n    WriteFeedbackArray(_27, ivec3(_1146, _1109), uint64_t(((1 | (_1149 ? 2 : 0)) | (_1150 ? 4 : 0)) | ((_1149 && _1150) ? 8 : 0)) << uint64_t(_1130 * 4), !gl_HelperInvocation);\n    ivec2 _1169 = -_1113;\n    vec2 _1171 = _1135 * ldexp(vec2(textureSize(_16, _1132).xy), _1169);\n    vec2 _1172 = ldexp(vec2(0.5), _1169);\n    ivec2 _1176 = ivec2(max(_1171 - _1172, vec2(0.0)));\n    bvec2 _1178 = notEqual(_1176, ivec2(_1171 + _1172));\n    bool _1179 = _1178.x;\n    bool _1180 = _1178.y;\n    WriteFeedbackArray(_27, ivec3(_1176, _1109), uint64_t(((1 | (_1179 ? 2 : 0)) | (_1180 ? 4 : 0)) | ((_1179 && _1180) ? 8 : 0)) << uint64_t(_1132 * 4), (!gl_HelperInvocation) && (_1130 != _1132));\n    int _1201 = int(roundEven(gl_FragCoord.z));\n    ivec2 _1205 = imageSize(_27).xy & ivec2(15);\n    int _1207 = textureQueryLevels(_16) - 1;\n    vec2 _1208 = vec2(textureSize(_16, 0).xy);\n    vec2 _1213 = _1208 * vec2(GRADX.x, GRADX.y);\n    vec2 _1214 = _1208 * vec2(GRADY.x, GRADY.y);\n    float _1223 = min(max(spvNClamp(log2(max(dot(_1213, _1213), dot(_1214, _1214))) * 0.5, 0.0, float(_1207)), CLAMP), 14.0);\n    int _1224 = int(_1223);\n    int _1226 = int(_1223 + 0.9970703125);\n    vec2 _1229 = fract(vec2(gl_FragCoord.x, gl_FragCoord.y));\n    ivec2 _1233 = -_1205;\n    vec2 _1235 = _1229 * ldexp(vec2(textureSize(_16, _1224).xy), _1233);\n    vec2 _1236 = ldexp(vec2(0.5), _1233);\n    ivec2 _1240 = ivec2(max(_1235 - _1236, vec2(0.0)));\n    bvec2 _1242 = notEqual(_1240, ivec2(_1235 + _1236));\n    bool _1243 = _1242.x;\n    bool _1244 = _1242.y;\n    WriteFeedbackArray(_27, ivec3(_1240, _1201), uint64_t(((1 | (_1243 ? 2 : 0)) | (_1244 ? 4 : 0)) | ((_1243 && _1244) ? 8 : 0)) << uint64_t(_1224 * 4), !gl_HelperInvocation);\n    ivec2 _1263 = -_1205;\n    vec2 _1265 = _1229 * ldexp(vec2(textureSize(_16, _1226).xy), _1263);\n    vec2 _1266 = ldexp(vec2(0.5), _1263);\n    ivec2 _1270 = ivec2(max(_1265 - _1266, vec2(0.0)));\n    bvec2 _1272 = notEqual(_1270, ivec2(_1265 + _1266));\n    bool _1273 = _1272.x;\n    bool _1274 = _1272.y;\n    WriteFeedbackArray(_27, ivec3(_1270, _1201), uint64_t(((1 | (_1273 ? 2 : 0)) | (_1274 ? 4 : 0)) | ((_1273 && _1274) ? 8 : 0)) << uint64_t(_1226 * 4), (!gl_HelperInvocation) && (_1224 != _1226));\n    int _1295 = int(roundEven(gl_FragCoord.z));\n    vec2 _1296 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1299 = imageSize(_27).xy & ivec2(15);\n    float _1303 = exp2(gl_FragCoord.z);\n    vec2 _1306 = textureQueryLod(sampler2DArray(_16, _36), _1296 * subgroupQuadBroadcast(_1303, 0u));\n    float _1307 = _1306.x;\n    int _1308 = int(_1307);\n    int _1310 = int(_1307 + 0.9970703125);\n    vec2 _1315 = abs(dFdx(_1296));\n    vec2 _1316 = abs(dFdy(_1296));\n    vec2 _1324 = vec2(max(_1315.x, _1316.x), max(_1315.y, _1316.y)) * _1303;\n    vec2 _1325 = fract(_1296);\n    vec2 _1326 = vec2(textureSize(_16, _1308).xy);\n    ivec2 _1329 = -_1299;\n    vec2 _1331 = _1325 * ldexp(_1326, _1329);\n    ResType _1334;\n    _1334._m0 = frexp((_1324 * _1326) - vec2(0.00390625), _1334._m1);\n    vec2 _1339 = min(ldexp(vec2(0.5), clamp(_1334._m1, ivec2(0), ivec2(4)) + _1329), vec2(0.5));\n    ivec2 _1343 = ivec2(max(_1331 - _1339, vec2(0.0)));\n    bvec2 _1345 = notEqual(_1343, ivec2(_1331 + _1339));\n    bool _1346 = _1345.x;\n    bool _1347 = _1345.y;\n    WriteFeedbackArray(_27, ivec3(_1343, _1295), uint64_t(((1 | (_1346 ? 2 : 0)) | (_1347 ? 4 : 0)) | ((_1346 && _1347) ? 8 : 0)) << uint64_t(_1308 * 4), !gl_HelperInvocation);\n    vec2 _1363 = vec2(textureSize(_16, _1310).xy);\n    ivec2 _1366 = -_1299;\n    vec2 _1368 = _1325 * ldexp(_1363, _1366);\n    ResType _1371;\n    _1371._m0 = frexp((_1324 * _1363) - vec2(0.00390625), _1371._m1);\n    vec2 _1376 = min(ldexp(vec2(0.5), clamp(_1371._m1, ivec2(0), ivec2(4)) + _1366), vec2(0.5));\n    ivec2 _1380 = ivec2(max(_1368 - _1376, vec2(0.0)));\n    bvec2 _1382 = notEqual(_1380, ivec2(_1368 + _1376));\n    bool _1383 = _1382.x;\n    bool _1384 = _1382.y;\n    WriteFeedbackArray(_27, ivec3(_1380, _1295), uint64_t(((1 | (_1383 ? 2 : 0)) | (_1384 ? 4 : 0)) | ((_1383 && _1384) ? 8 : 0)) << uint64_t(_1310 * 4), (!gl_HelperInvocation) && (_1308 != _1310));\n    int _1405 = int(roundEven(gl_FragCoord.z));\n    vec2 _1406 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1409 = imageSize(_27).xy & ivec2(15);\n    float _1413 = exp2(_74);\n    float _1419 = min(max(textureQueryLod(sampler2DArray(_16, _36), _1406 * subgroupQuadBroadcast(_1413, 0u)).x, CLAMP), 14.0);\n    int _1420 = int(_1419);\n    int _1422 = int(_1419 + 0.9970703125);\n    vec2 _1427 = abs(dFdx(_1406));\n    vec2 _1428 = abs(dFdy(_1406));\n    vec2 _1436 = vec2(max(_1427.x, _1428.x), max(_1427.y, _1428.y)) * _1413;\n    vec2 _1437 = fract(_1406);\n    vec2 _1438 = vec2(textureSize(_16, _1420).xy);\n    ivec2 _1441 = -_1409;\n    vec2 _1443 = _1437 * ldexp(_1438, _1441);\n    ResType _1446;\n    _1446._m0 = frexp((_1436 * _1438) - vec2(0.00390625), _1446._m1);\n    vec2 _1451 = min(ldexp(vec2(0.5), clamp(_1446._m1, ivec2(0), ivec2(4)) + _1441), vec2(0.5));\n    ivec2 _1455 = ivec2(max(_1443 - _1451, vec2(0.0)));\n    bvec2 _1457 = notEqual(_1455, ivec2(_1443 + _1451));\n    bool _1458 = _1457.x;\n    bool _1459 = _1457.y;\n    WriteFeedbackArray(_27, ivec3(_1455, _1405), uint64_t(((1 | (_1458 ? 2 : 0)) | (_1459 ? 4 : 0)) | ((_1458 && _1459) ? 8 : 0)) << uint64_t(_1420 * 4), !gl_HelperInvocation);\n    vec2 _1475 = vec2(textureSize(_16, _1422).xy);\n    ivec2 _1478 = -_1409;\n    vec2 _1480 = _1437 * ldexp(_1475, _1478);\n    ResType _1483;\n    _1483._m0 = frexp((_1436 * _1475) - vec2(0.00390625), _1483._m1);\n    vec2 _1488 = min(ldexp(vec2(0.5), clamp(_1483._m1, ivec2(0), ivec2(4)) + _1478), vec2(0.5));\n    ivec2 _1492 = ivec2(max(_1480 - _1488, vec2(0.0)));\n    bvec2 _1494 = notEqual(_1492, ivec2(_1480 + _1488));\n    bool _1495 = _1494.x;\n    bool _1496 = _1494.y;\n    WriteFeedbackArray(_27, ivec3(_1492, _1405), uint64_t(((1 | (_1495 ? 2 : 0)) | (_1496 ? 4 : 0)) | ((_1495 && _1496) ? 8 : 0)) << uint64_t(_1422 * 4), (!gl_HelperInvocation) && (_1420 != _1422));\n    uint _1513 = IDX + 0u;\n    uint _1516 = IDX + 0u;\n    uint _1519 = IDX + 0u;\n    vec2 _1522 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1524 = imageSize(_30[nonuniformEXT(_1513)]) & ivec2(15);\n    vec2 _1528 = textureQueryLod(nonuniformEXT(sampler2D(_19[_1516], _39[_1519])), _1522);\n    float _1529 = _1528.x;\n    int _1530 = int(_1529);\n    int _1532 = int(_1529 + 0.9970703125);\n    vec2 _1537 = abs(dFdx(_1522));\n    vec2 _1538 = abs(dFdy(_1522));\n    vec2 _1545 = vec2(max(_1537.x, _1538.x), max(_1537.y, _1538.y));\n    vec2 _1546 = fract(_1522);\n    vec2 _1547 = vec2(textureSize(_19[nonuniformEXT(_1516)], _1530));\n    ivec2 _1549 = -_1524;\n    vec2 _1551 = _1546 * ldexp(_1547, _1549);\n    ResType _1554;\n    _1554._m0 = frexp((_1545 * _1547) - vec2(0.00390625), _1554._m1);\n    vec2 _1559 = min(ldexp(vec2(0.5), clamp(_1554._m1, ivec2(0), ivec2(4)) + _1549), vec2(0.5));\n    ivec2 _1563 = ivec2(max(_1551 - _1559, vec2(0.0)));\n    bvec2 _1565 = notEqual(_1563, ivec2(_1551 + _1559));\n    bool _1566 = _1565.x;\n    bool _1567 = _1565.y;\n    WriteFeedbackNonUniform(_30[_1513], _1563, uint64_t(((1 | (_1566 ? 2 : 0)) | (_1567 ? 4 : 0)) | ((_1566 && _1567) ? 8 : 0)) << uint64_t(_1530 * 4), !gl_HelperInvocation);\n    vec2 _1608 = vec2(textureSize(_19[nonuniformEXT(_1516)], _1532));\n    ivec2 _1610 = -_1524;\n    vec2 _1612 = _1546 * ldexp(_1608, _1610);\n    ResType _1615;\n    _1615._m0 = frexp((_1545 * _1608) - vec2(0.00390625), _1615._m1);\n    vec2 _1620 = min(ldexp(vec2(0.5), clamp(_1615._m1, ivec2(0), ivec2(4)) + _1610), vec2(0.5));\n    ivec2 _1624 = ivec2(max(_1612 - _1620, vec2(0.0)));\n    bvec2 _1626 = notEqual(_1624, ivec2(_1612 + _1620));\n    bool _1627 = _1626.x;\n    bool _1628 = _1626.y;\n    WriteFeedbackNonUniform(_30[_1513], _1624, uint64_t(((1 | (_1627 ? 2 : 0)) | (_1628 ? 4 : 0)) | ((_1627 && _1628) ? 8 : 0)) << uint64_t(_1532 * 4), (!gl_HelperInvocation) && (_1530 != _1532));\n    uint _1644 = IDX + 0u;\n    uint _1647 = IDX + 0u;\n    int _1653 = int(roundEven(gl_FragCoord.z));\n    vec2 _1654 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1657 = imageSize(_33[nonuniformEXT(_1644)]).xy & ivec2(15);\n    vec2 _1661 = textureQueryLod(nonuniformEXT(sampler2DArray(_22[_1647], _39[_1519])), _1654);\n    float _1662 = _1661.x;\n    int _1663 = int(_1662);\n    int _1665 = int(_1662 + 0.9970703125);\n    vec2 _1670 = abs(dFdx(_1654));\n    vec2 _1671 = abs(dFdy(_1654));\n    vec2 _1678 = vec2(max(_1670.x, _1671.x), max(_1670.y, _1671.y));\n    vec2 _1679 = fract(_1654);\n    vec2 _1680 = vec2(textureSize(_22[nonuniformEXT(_1647)], _1663).xy);\n    ivec2 _1683 = -_1657;\n    vec2 _1685 = _1679 * ldexp(_1680, _1683);\n    ResType _1688;\n    _1688._m0 = frexp((_1678 * _1680) - vec2(0.00390625), _1688._m1);\n    vec2 _1693 = min(ldexp(vec2(0.5), clamp(_1688._m1, ivec2(0), ivec2(4)) + _1683), vec2(0.5));\n    ivec2 _1697 = ivec2(max(_1685 - _1693, vec2(0.0)));\n    bvec2 _1699 = notEqual(_1697, ivec2(_1685 + _1693));\n    bool _1700 = _1699.x;\n    bool _1701 = _1699.y;\n    WriteFeedbackArrayNonUniform(_33[_1644], ivec3(_1697, _1653), uint64_t(((1 | (_1700 ? 2 : 0)) | (_1701 ? 4 : 0)) | ((_1700 && _1701) ? 8 : 0)) << uint64_t(_1663 * 4), !gl_HelperInvocation);\n    vec2 _1743 = vec2(textureSize(_22[nonuniformEXT(_1647)], _1665).xy);\n    ivec2 _1746 = -_1657;\n    vec2 _1748 = _1679 * ldexp(_1743, _1746);\n    ResType _1751;\n    _1751._m0 = frexp((_1678 * _1743) - vec2(0.00390625), _1751._m1);\n    vec2 _1756 = min(ldexp(vec2(0.5), clamp(_1751._m1, ivec2(0), ivec2(4)) + _1746), vec2(0.5));\n    ivec2 _1760 = ivec2(max(_1748 - _1756, vec2(0.0)));\n    bvec2 _1762 = notEqual(_1760, ivec2(_1748 + _1756));\n    bool _1763 = _1762.x;\n    bool _1764 = _1762.y;\n    WriteFeedbackArrayNonUniform(_33[_1644], ivec3(_1760, _1653), uint64_t(((1 | (_1763 ? 2 : 0)) | (_1764 ? 4 : 0)) | ((_1763 && _1764) ? 8 : 0)) << uint64_t(_1665 * 4), (!gl_HelperInvocation) && (_1663 != _1665));\n    vec2 _1787 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1789 = imageSize(_30[nonuniformEXT(_1513)]) & ivec2(15);\n    vec2 _1793 = textureQueryLod(nonuniformEXT(sampler2D(_19[_1516], _39[_1519])), _1787);\n    float _1794 = _1793.x;\n    int _1795 = int(_1794);\n    int _1797 = int(_1794 + 0.9970703125);\n    vec2 _1802 = abs(dFdx(_1787));\n    vec2 _1803 = abs(dFdy(_1787));\n    vec2 _1810 = vec2(max(_1802.x, _1803.x), max(_1802.y, _1803.y));\n    vec2 _1811 = fract(_1787);\n    vec2 _1812 = vec2(textureSize(_19[nonuniformEXT(_1516)], _1795));\n    ivec2 _1814 = -_1789;\n    vec2 _1816 = _1811 * ldexp(_1812, _1814);\n    ResType _1819;\n    _1819._m0 = frexp((_1810 * _1812) - vec2(0.00390625), _1819._m1);\n    vec2 _1824 = min(ldexp(vec2(0.5), clamp(_1819._m1, ivec2(0), ivec2(4)) + _1814), vec2(0.5));\n    ivec2 _1828 = ivec2(max(_1816 - _1824, vec2(0.0)));\n    bvec2 _1830 = notEqual(_1828, ivec2(_1816 + _1824));\n    bool _1831 = _1830.x;\n    bool _1832 = _1830.y;\n    WriteFeedbackNonUniform(_30[_1513], _1828, uint64_t(((1 | (_1831 ? 2 : 0)) | (_1832 ? 4 : 0)) | ((_1831 && _1832) ? 8 : 0)) << uint64_t(_1795 * 4), !gl_HelperInvocation);\n    vec2 _1847 = vec2(textureSize(_19[nonuniformEXT(_1516)], _1797));\n    ivec2 _1849 = -_1789;\n    vec2 _1851 = _1811 * ldexp(_1847, _1849);\n    ResType _1854;\n    _1854._m0 = frexp((_1810 * _1847) - vec2(0.00390625), _1854._m1);\n    vec2 _1859 = min(ldexp(vec2(0.5), clamp(_1854._m1, ivec2(0), ivec2(4)) + _1849), vec2(0.5));\n    ivec2 _1863 = ivec2(max(_1851 - _1859, vec2(0.0)));\n    bvec2 _1865 = notEqual(_1863, ivec2(_1851 + _1859));\n    bool _1866 = _1865.x;\n    bool _1867 = _1865.y;\n    WriteFeedbackNonUniform(_30[_1513], _1863, uint64_t(((1 | (_1866 ? 2 : 0)) | (_1867 ? 4 : 0)) | ((_1866 && _1867) ? 8 : 0)) << uint64_t(_1797 * 4), (!gl_HelperInvocation) && (_1795 != _1797));\n    int _1890 = int(roundEven(gl_FragCoord.z));\n    vec2 _1891 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1894 = imageSize(_33[nonuniformEXT(_1644)]).xy & ivec2(15);\n    vec2 _1898 = textureQueryLod(nonuniformEXT(sampler2DArray(_22[_1647], _39[_1519])), _1891);\n    float _1899 = _1898.x;\n    int _1900 = int(_1899);\n    int _1902 = int(_1899 + 0.9970703125);\n    vec2 _1907 = abs(dFdx(_1891));\n    vec2 _1908 = abs(dFdy(_1891));\n    vec2 _1915 = vec2(max(_1907.x, _1908.x), max(_1907.y, _1908.y));\n    vec2 _1916 = fract(_1891);\n    vec2 _1917 = vec2(textureSize(_22[nonuniformEXT(_1647)], _1900).xy);\n    ivec2 _1920 = -_1894;\n    vec2 _1922 = _1916 * ldexp(_1917, _1920);\n    ResType _1925;\n    _1925._m0 = frexp((_1915 * _1917) - vec2(0.00390625), _1925._m1);\n    vec2 _1930 = min(ldexp(vec2(0.5), clamp(_1925._m1, ivec2(0), ivec2(4)) + _1920), vec2(0.5));\n    ivec2 _1934 = ivec2(max(_1922 - _1930, vec2(0.0)));\n    bvec2 _1936 = notEqual(_1934, ivec2(_1922 + _1930));\n    bool _1937 = _1936.x;\n    bool _1938 = _1936.y;\n    WriteFeedbackArrayNonUniform(_33[_1644], ivec3(_1934, _1890), uint64_t(((1 | (_1937 ? 2 : 0)) | (_1938 ? 4 : 0)) | ((_1937 && _1938) ? 8 : 0)) << uint64_t(_1900 * 4), !gl_HelperInvocation);\n    vec2 _1954 = vec2(textureSize(_22[nonuniformEXT(_1647)], _1902).xy);\n    ivec2 _1957 = -_1894;\n    vec2 _1959 = _1916 * ldexp(_1954, _1957);\n    ResType _1962;\n    _1962._m0 = frexp((_1915 * _1954) - vec2(0.00390625), _1962._m1);\n    vec2 _1967 = min(ldexp(vec2(0.5), clamp(_1962._m1, ivec2(0), ivec2(4)) + _1957), vec2(0.5));\n    ivec2 _1971 = ivec2(max(_1959 - _1967, vec2(0.0)));\n    bvec2 _1973 = notEqual(_1971, ivec2(_1959 + _1967));\n    bool _1974 = _1973.x;\n    bool _1975 = _1973.y;\n    WriteFeedbackArrayNonUniform(_33[_1644], ivec3(_1971, _1890), uint64_t(((1 | (_1974 ? 2 : 0)) | (_1975 ? 4 : 0)) | ((_1974 && _1975) ? 8 : 0)) << uint64_t(_1902 * 4), (!gl_HelperInvocation) && (_1900 != _1902));\n    vec2 _1996 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _1998 = imageSize(_9[nonuniformEXT(IDX)]) & ivec2(15);\n    vec2 _2002 = textureQueryLod(sampler2D(_13, _36), _1996);\n    float _2003 = _2002.x;\n    int _2004 = int(_2003);\n    int _2006 = int(_2003 + 0.9970703125);\n    vec2 _2011 = abs(dFdx(_1996));\n    vec2 _2012 = abs(dFdy(_1996));\n    vec2 _2019 = vec2(max(_2011.x, _2012.x), max(_2011.y, _2012.y));\n    vec2 _2020 = fract(_1996);\n    vec2 _2021 = vec2(textureSize(_13, _2004));\n    ivec2 _2023 = -_1998;\n    vec2 _2025 = _2020 * ldexp(_2021, _2023);\n    ResType _2028;\n    _2028._m0 = frexp((_2019 * _2021) - vec2(0.00390625), _2028._m1);\n    vec2 _2033 = min(ldexp(vec2(0.5), clamp(_2028._m1, ivec2(0), ivec2(4)) + _2023), vec2(0.5));\n    ivec2 _2037 = ivec2(max(_2025 - _2033, vec2(0.0)));\n    bvec2 _2039 = notEqual(_2037, ivec2(_2025 + _2033));\n    bool _2040 = _2039.x;\n    bool _2041 = _2039.y;\n    WriteFeedbackNonUniform(_9[IDX], _2037, uint64_t(((1 | (_2040 ? 2 : 0)) | (_2041 ? 4 : 0)) | ((_2040 && _2041) ? 8 : 0)) << uint64_t(_2004 * 4), !gl_HelperInvocation);\n    vec2 _2056 = vec2(textureSize(_13, _2006));\n    ivec2 _2058 = -_1998;\n    vec2 _2060 = _2020 * ldexp(_2056, _2058);\n    ResType _2063;\n    _2063._m0 = frexp((_2019 * _2056) - vec2(0.00390625), _2063._m1);\n    vec2 _2068 = min(ldexp(vec2(0.5), clamp(_2063._m1, ivec2(0), ivec2(4)) + _2058), vec2(0.5));\n    ivec2 _2072 = ivec2(max(_2060 - _2068, vec2(0.0)));\n    bvec2 _2074 = notEqual(_2072, ivec2(_2060 + _2068));\n    bool _2075 = _2074.x;\n    bool _2076 = _2074.y;\n    WriteFeedbackNonUniform(_9[IDX], _2072, uint64_t(((1 | (_2075 ? 2 : 0)) | (_2076 ? 4 : 0)) | ((_2075 && _2076) ? 8 : 0)) << uint64_t(_2006 * 4), (!gl_HelperInvocation) && (_2004 != _2006));\n    vec2 _2094 = vec2(gl_FragCoord.x, gl_FragCoord.y);\n    ivec2 _2096 = imageSize(_9[nonuniformEXT(IDX)]) & ivec2(15);\n    vec2 _2100 = textureQueryLod(sampler2D(_13, _36), _2094);\n    float _2101 = _2100.x;\n    int _2102 = int(_2101);\n    int _2104 = int(_2101 + 0.9970703125);\n    vec2 _2109 = abs(dFdx(_2094));\n    vec2 _2110 = abs(dFdy(_2094));\n    vec2 _2117 = vec2(max(_2109.x, _2110.x), max(_2109.y, _2110.y));\n    vec2 _2118 = fract(_2094);\n    vec2 _2119 = vec2(textureSize(_13, _2102));\n    ivec2 _2121 = -_2096;\n    vec2 _2123 = _2118 * ldexp(_2119, _2121);\n    ResType _2126;\n    _2126._m0 = frexp((_2117 * _2119) - vec2(0.00390625), _2126._m1);\n    vec2 _2131 = min(ldexp(vec2(0.5), clamp(_2126._m1, ivec2(0), ivec2(4)) + _2121), vec2(0.5));\n    ivec2 _2135 = ivec2(max(_2123 - _2131, vec2(0.0)));\n    bvec2 _2137 = notEqual(_2135, ivec2(_2123 + _2131));\n    bool _2138 = _2137.x;\n    bool _2139 = _2137.y;\n    WriteFeedbackNonUniform(_9[IDX], _2135, uint64_t(((1 | (_2138 ? 2 : 0)) | (_2139 ? 4 : 0)) | ((_2138 && _2139) ? 8 : 0)) << uint64_t(_2102 * 4), !gl_HelperInvocation);\n    vec2 _2154 = vec2(textureSize(_13, _2104));\n    ivec2 _2156 = -_2096;\n    vec2 _2158 = _2118 * ldexp(_2154, _2156);\n    ResType _2161;\n    _2161._m0 = frexp((_2117 * _2154) - vec2(0.00390625), _2161._m1);\n    vec2 _2166 = min(ldexp(vec2(0.5), clamp(_2161._m1, ivec2(0), ivec2(4)) + _2156), vec2(0.5));\n    ivec2 _2170 = ivec2(max(_2158 - _2166, vec2(0.0)));\n    bvec2 _2172 = notEqual(_2170, ivec2(_2158 + _2166));\n    bool _2173 = _2172.x;\n    bool _2174 = _2172.y;\n    WriteFeedbackNonUniform(_9[IDX], _2170, uint64_t(((1 | (_2173 ? 2 : 0)) | (_2174 ? 4 : 0)) | ((_2173 && _2174) ? 8 : 0)) << uint64_t(_2104 * 4), (!gl_HelperInvocation) && (_2102 != _2104));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 2194\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability Int64Atomics\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability ImageQuery\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformArithmetic\nOpCapability GroupNonUniformBallot\nOpCapability GroupNonUniformQuad\nOpCapability Int64ImageEXT\nOpCapability RuntimeDescriptorArray\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_EXT_shader_image_int64\"\n%79 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %42 %45 %46 %48 %51 %2192\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %42 \"SV_Position\"\nOpName %45 \"GRADX\"\nOpName %46 \"GRADY\"\nOpName %48 \"CLAMP\"\nOpName %51 \"IDX\"\nOpName %123 \"ResType\"\nOpName %167 \"WriteFeedback\"\nOpName %163 \"img\"\nOpName %164 \"coord\"\nOpName %165 \"value\"\nOpName %166 \"active_lane\"\nOpName %180 \"is_done\"\nOpName %856 \"WriteFeedbackArray\"\nOpName %852 \"img\"\nOpName %853 \"coord\"\nOpName %854 \"value\"\nOpName %855 \"active_lane\"\nOpName %867 \"is_done\"\nOpName %1585 \"WriteFeedbackNonUniform\"\nOpName %1581 \"img\"\nOpName %1582 \"coord\"\nOpName %1583 \"value\"\nOpName %1584 \"active_lane\"\nOpName %1596 \"is_done\"\nOpName %1720 \"WriteFeedbackArrayNonUniform\"\nOpName %1716 \"img\"\nOpName %1717 \"coord\"\nOpName %1718 \"value\"\nOpName %1719 \"active_lane\"\nOpName %1731 \"is_done\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 1\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %22 DescriptorSet 2\nOpDecorate %22 Binding 0\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %27 DescriptorSet 0\nOpDecorate %27 Binding 1\nOpDecorate %30 DescriptorSet 1\nOpDecorate %30 Binding 0\nOpDecorate %33 DescriptorSet 2\nOpDecorate %33 Binding 0\nOpDecorate %36 DescriptorSet 0\nOpDecorate %36 Binding 0\nOpDecorate %39 DescriptorSet 1\nOpDecorate %39 Binding 0\nOpDecorate %42 BuiltIn FragCoord\nOpDecorate %45 Location 1\nOpDecorate %46 Location 1\nOpDecorate %46 Component 2\nOpDecorate %48 Location 2\nOpDecorate %51 Flat\nOpDecorate %51 Location 3\nOpDecorate %1513 NonUniform\nOpDecorate %1515 NonUniform\nOpDecorate %1516 NonUniform\nOpDecorate %1518 NonUniform\nOpDecorate %1519 NonUniform\nOpDecorate %1521 NonUniform\nOpDecorate %1527 NonUniform\nOpDecorate %1604 NonUniform\nOpDecorate %1644 NonUniform\nOpDecorate %1646 NonUniform\nOpDecorate %1647 NonUniform\nOpDecorate %1649 NonUniform\nOpDecorate %1651 NonUniform\nOpDecorate %1660 NonUniform\nOpDecorate %1739 NonUniform\nOpDecorate %1782 NonUniform\nOpDecorate %1784 NonUniform\nOpDecorate %1786 NonUniform\nOpDecorate %1792 NonUniform\nOpDecorate %1884 NonUniform\nOpDecorate %1886 NonUniform\nOpDecorate %1888 NonUniform\nOpDecorate %1897 NonUniform\nOpDecorate %52 NonUniform\nOpDecorate %1993 NonUniform\nOpDecorate %2192 BuiltIn HelperInvocation\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 64 0\n%6 = OpTypeImage %5 2D 0 0 0 2 R64ui\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeFloat 32\n%11 = OpTypeImage %10 2D 0 0 0 1 Unknown\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %10 2D 0 1 0 1 Unknown\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeRuntimeArray %11\n%18 = OpTypePointer UniformConstant %17\n%19 = OpVariable %18 UniformConstant\n%20 = OpTypeRuntimeArray %14\n%21 = OpTypePointer UniformConstant %20\n%22 = OpVariable %21 UniformConstant\n%23 = OpTypePointer UniformConstant %6\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeImage %5 2D 0 1 0 2 R64ui\n%26 = OpTypePointer UniformConstant %25\n%27 = OpVariable %26 UniformConstant\n%28 = OpTypeRuntimeArray %6\n%29 = OpTypePointer UniformConstant %28\n%30 = OpVariable %29 UniformConstant\n%31 = OpTypeRuntimeArray %25\n%32 = OpTypePointer UniformConstant %31\n%33 = OpVariable %32 UniformConstant\n%34 = OpTypeSampler\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeRuntimeArray %34\n%38 = OpTypePointer UniformConstant %37\n%39 = OpVariable %38 UniformConstant\n%40 = OpTypeVector %10 4\n%41 = OpTypePointer Input %40\n%42 = OpVariable %41 Input\n%43 = OpTypeVector %10 2\n%44 = OpTypePointer Input %43\n%45 = OpVariable %44 Input\n%46 = OpVariable %44 Input\n%47 = OpTypePointer Input %10\n%48 = OpVariable %47 Input\n%49 = OpTypeInt 32 0\n%50 = OpTypePointer Input %49\n%51 = OpVariable %50 Input\n%55 = OpConstant %49 0\n%58 = OpConstant %49 1\n%69 = OpConstant %49 2\n%72 = OpConstant %49 3\n%75 = OpConstant %10 1\n%80 = OpTypeBool\n%81 = OpTypeInt 32 1\n%82 = OpTypeVector %80 2\n%83 = OpTypeVector %81 2\n%87 = OpConstant %81 15\n%88 = OpConstantComposite %83 %87 %87\n%91 = OpConstant %81 1\n%92 = OpTypeSampledImage %11\n%98 = OpConstant %10 0.997070312\n%121 = OpConstant %10 0.00390625\n%122 = OpConstantComposite %43 %121 %121\n%123 = OpTypeStruct %43 %83\n%127 = OpConstant %81 0\n%128 = OpConstantComposite %83 %127 %127\n%129 = OpConstant %81 4\n%130 = OpConstantComposite %83 %129 %129\n%133 = OpConstant %10 0.5\n%134 = OpConstantComposite %43 %133 %133\n%138 = OpConstant %10 0\n%139 = OpConstantComposite %43 %138 %138\n%148 = OpConstant %81 2\n%153 = OpConstant %81 8\n%161 = OpTypePointer Image %5\n%162 = OpTypeFunction %1 %23 %83 %5 %80\n%178 = OpConstantFalse %80\n%179 = OpTypePointer Function %80\n%241 = OpConstant %10 14\n%787 = OpTypeVector %81 3\n%793 = OpTypeSampledImage %14\n%850 = OpTypeVector %80 3\n%851 = OpTypeFunction %1 %26 %787 %5 %80\n%2191 = OpTypePointer Input %80\n%2192 = OpVariable %2191 Input\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %2190\n%2190 = OpLabel\n%52 = OpLoad %49 %51\n%53 = OpLoad %10 %48\n%54 = OpAccessChain %47 %46 %55\n%56 = OpLoad %10 %54\n%57 = OpAccessChain %47 %46 %58\n%59 = OpLoad %10 %57\n%60 = OpAccessChain %47 %45 %55\n%61 = OpLoad %10 %60\n%62 = OpAccessChain %47 %45 %58\n%63 = OpLoad %10 %62\n%64 = OpAccessChain %47 %42 %55\n%65 = OpLoad %10 %64\n%66 = OpAccessChain %47 %42 %58\n%67 = OpLoad %10 %66\n%68 = OpAccessChain %47 %42 %69\n%70 = OpLoad %10 %68\n%71 = OpAccessChain %47 %42 %72\n%73 = OpLoad %10 %71\n%74 = OpFDiv %10 %75 %73\n%76 = OpLoad %6 %24\n%77 = OpLoad %11 %13\n%78 = OpLoad %34 %36\n%84 = OpCompositeConstruct %43 %65 %67\n%85 = OpImageQuerySize %83 %76\n%86 = OpBitwiseAnd %83 %85 %88\n%89 = OpImageQueryLevels %81 %77\n%90 = OpISub %81 %89 %91\n%93 = OpSampledImage %92 %77 %78\n%94 = OpImageQueryLod %43 %93 %84\n%95 = OpCompositeExtract %10 %94 0\n%96 = OpConvertFToS %81 %95\n%97 = OpFAdd %10 %95 %98\n%99 = OpConvertFToS %81 %97\n%100 = OpExtInst %81 %79 SMin %99 %90\n%101 = OpINotEqual %80 %96 %99\n%102 = OpDPdx %43 %84\n%103 = OpDPdy %43 %84\n%104 = OpExtInst %43 %79 FAbs %102\n%105 = OpExtInst %43 %79 FAbs %103\n%106 = OpCompositeExtract %10 %104 0\n%107 = OpCompositeExtract %10 %105 0\n%108 = OpCompositeExtract %10 %104 1\n%109 = OpCompositeExtract %10 %105 1\n%110 = OpExtInst %10 %79 FMax %106 %107\n%111 = OpExtInst %10 %79 FMax %108 %109\n%112 = OpCompositeConstruct %43 %110 %111\n%113 = OpExtInst %43 %79 Fract %84\n%115 = OpImageQuerySizeLod %83 %77 %96\n%114 = OpConvertSToF %43 %115\n%116 = OpSNegate %83 %86\n%117 = OpExtInst %43 %79 Ldexp %114 %116\n%118 = OpFMul %43 %113 %117\n%119 = OpFMul %43 %112 %114\n%120 = OpFSub %43 %119 %122\n%124 = OpExtInst %123 %79 FrexpStruct %120\n%125 = OpCompositeExtract %83 %124 1\n%126 = OpExtInst %83 %79 SClamp %125 %128 %130\n%131 = OpIAdd %83 %126 %116\n%132 = OpExtInst %43 %79 Ldexp %134 %131\n%135 = OpExtInst %43 %79 FMin %132 %134\n%136 = OpFSub %43 %118 %135\n%137 = OpExtInst %43 %79 FMax %136 %139\n%140 = OpFAdd %43 %118 %135\n%141 = OpConvertFToS %83 %137\n%142 = OpConvertFToS %83 %140\n%143 = OpINotEqual %82 %141 %142\n%144 = OpCompositeExtract %80 %143 0\n%145 = OpCompositeExtract %80 %143 1\n%146 = OpLogicalAnd %80 %144 %145\n%147 = OpSelect %81 %144 %148 %127\n%149 = OpBitwiseOr %81 %91 %147\n%150 = OpSelect %81 %145 %129 %127\n%151 = OpBitwiseOr %81 %149 %150\n%152 = OpSelect %81 %146 %153 %127\n%154 = OpBitwiseOr %81 %151 %152\n%155 = OpSConvert %5 %154\n%156 = OpIMul %81 %96 %129\n%157 = OpSConvert %5 %156\n%158 = OpShiftLeftLogical %5 %155 %157\n%159 = OpLoad %80 %2192\n%160 = OpLogicalNot %80 %159\n%191 = OpFunctionCall %1 %167 %24 %141 %158 %160\n%193 = OpImageQuerySizeLod %83 %77 %99\n%192 = OpConvertSToF %43 %193\n%194 = OpSNegate %83 %86\n%195 = OpExtInst %43 %79 Ldexp %192 %194\n%196 = OpFMul %43 %113 %195\n%197 = OpFMul %43 %112 %192\n%198 = OpFSub %43 %197 %122\n%199 = OpExtInst %123 %79 FrexpStruct %198\n%200 = OpCompositeExtract %83 %199 1\n%201 = OpExtInst %83 %79 SClamp %200 %128 %130\n%202 = OpIAdd %83 %201 %194\n%203 = OpExtInst %43 %79 Ldexp %134 %202\n%204 = OpExtInst %43 %79 FMin %203 %134\n%205 = OpFSub %43 %196 %204\n%206 = OpExtInst %43 %79 FMax %205 %139\n%207 = OpFAdd %43 %196 %204\n%208 = OpConvertFToS %83 %206\n%209 = OpConvertFToS %83 %207\n%210 = OpINotEqual %82 %208 %209\n%211 = OpCompositeExtract %80 %210 0\n%212 = OpCompositeExtract %80 %210 1\n%213 = OpLogicalAnd %80 %211 %212\n%214 = OpSelect %81 %211 %148 %127\n%215 = OpBitwiseOr %81 %91 %214\n%216 = OpSelect %81 %212 %129 %127\n%217 = OpBitwiseOr %81 %215 %216\n%218 = OpSelect %81 %213 %153 %127\n%219 = OpBitwiseOr %81 %217 %218\n%220 = OpSConvert %5 %219\n%221 = OpIMul %81 %99 %129\n%222 = OpSConvert %5 %221\n%223 = OpShiftLeftLogical %5 %220 %222\n%224 = OpLoad %80 %2192\n%225 = OpLogicalNot %80 %224\n%226 = OpLogicalAnd %80 %225 %101\n%227 = OpFunctionCall %1 %167 %24 %208 %223 %226\n%228 = OpLoad %6 %24\n%229 = OpLoad %11 %13\n%230 = OpLoad %34 %36\n%231 = OpCompositeConstruct %43 %65 %67\n%232 = OpImageQuerySize %83 %228\n%233 = OpBitwiseAnd %83 %232 %88\n%234 = OpImageQueryLevels %81 %229\n%235 = OpISub %81 %234 %91\n%236 = OpSampledImage %92 %229 %230\n%237 = OpImageQueryLod %43 %236 %231\n%238 = OpCompositeExtract %10 %237 0\n%239 = OpExtInst %10 %79 FMax %238 %53\n%240 = OpExtInst %10 %79 FMin %239 %241\n%242 = OpConvertFToS %81 %240\n%243 = OpFAdd %10 %240 %98\n%244 = OpConvertFToS %81 %243\n%245 = OpExtInst %81 %79 SMin %244 %235\n%246 = OpINotEqual %80 %242 %244\n%247 = OpDPdx %43 %231\n%248 = OpDPdy %43 %231\n%249 = OpExtInst %43 %79 FAbs %247\n%250 = OpExtInst %43 %79 FAbs %248\n%251 = OpCompositeExtract %10 %249 0\n%252 = OpCompositeExtract %10 %250 0\n%253 = OpCompositeExtract %10 %249 1\n%254 = OpCompositeExtract %10 %250 1\n%255 = OpExtInst %10 %79 FMax %251 %252\n%256 = OpExtInst %10 %79 FMax %253 %254\n%257 = OpCompositeConstruct %43 %255 %256\n%258 = OpExtInst %43 %79 Fract %231\n%260 = OpImageQuerySizeLod %83 %229 %242\n%259 = OpConvertSToF %43 %260\n%261 = OpSNegate %83 %233\n%262 = OpExtInst %43 %79 Ldexp %259 %261\n%263 = OpFMul %43 %258 %262\n%264 = OpFMul %43 %257 %259\n%265 = OpFSub %43 %264 %122\n%266 = OpExtInst %123 %79 FrexpStruct %265\n%267 = OpCompositeExtract %83 %266 1\n%268 = OpExtInst %83 %79 SClamp %267 %128 %130\n%269 = OpIAdd %83 %268 %261\n%270 = OpExtInst %43 %79 Ldexp %134 %269\n%271 = OpExtInst %43 %79 FMin %270 %134\n%272 = OpFSub %43 %263 %271\n%273 = OpExtInst %43 %79 FMax %272 %139\n%274 = OpFAdd %43 %263 %271\n%275 = OpConvertFToS %83 %273\n%276 = OpConvertFToS %83 %274\n%277 = OpINotEqual %82 %275 %276\n%278 = OpCompositeExtract %80 %277 0\n%279 = OpCompositeExtract %80 %277 1\n%280 = OpLogicalAnd %80 %278 %279\n%281 = OpSelect %81 %278 %148 %127\n%282 = OpBitwiseOr %81 %91 %281\n%283 = OpSelect %81 %279 %129 %127\n%284 = OpBitwiseOr %81 %282 %283\n%285 = OpSelect %81 %280 %153 %127\n%286 = OpBitwiseOr %81 %284 %285\n%287 = OpSConvert %5 %286\n%288 = OpIMul %81 %242 %129\n%289 = OpSConvert %5 %288\n%290 = OpShiftLeftLogical %5 %287 %289\n%291 = OpLoad %80 %2192\n%292 = OpLogicalNot %80 %291\n%293 = OpFunctionCall %1 %167 %24 %275 %290 %292\n%295 = OpImageQuerySizeLod %83 %229 %244\n%294 = OpConvertSToF %43 %295\n%296 = OpSNegate %83 %233\n%297 = OpExtInst %43 %79 Ldexp %294 %296\n%298 = OpFMul %43 %258 %297\n%299 = OpFMul %43 %257 %294\n%300 = OpFSub %43 %299 %122\n%301 = OpExtInst %123 %79 FrexpStruct %300\n%302 = OpCompositeExtract %83 %301 1\n%303 = OpExtInst %83 %79 SClamp %302 %128 %130\n%304 = OpIAdd %83 %303 %296\n%305 = OpExtInst %43 %79 Ldexp %134 %304\n%306 = OpExtInst %43 %79 FMin %305 %134\n%307 = OpFSub %43 %298 %306\n%308 = OpExtInst %43 %79 FMax %307 %139\n%309 = OpFAdd %43 %298 %306\n%310 = OpConvertFToS %83 %308\n%311 = OpConvertFToS %83 %309\n%312 = OpINotEqual %82 %310 %311\n%313 = OpCompositeExtract %80 %312 0\n%314 = OpCompositeExtract %80 %312 1\n%315 = OpLogicalAnd %80 %313 %314\n%316 = OpSelect %81 %313 %148 %127\n%317 = OpBitwiseOr %81 %91 %316\n%318 = OpSelect %81 %314 %129 %127\n%319 = OpBitwiseOr %81 %317 %318\n%320 = OpSelect %81 %315 %153 %127\n%321 = OpBitwiseOr %81 %319 %320\n%322 = OpSConvert %5 %321\n%323 = OpIMul %81 %244 %129\n%324 = OpSConvert %5 %323\n%325 = OpShiftLeftLogical %5 %322 %324\n%326 = OpLoad %80 %2192\n%327 = OpLogicalNot %80 %326\n%328 = OpLogicalAnd %80 %327 %246\n%329 = OpFunctionCall %1 %167 %24 %310 %325 %328\n%330 = OpLoad %6 %24\n%331 = OpLoad %11 %13\n%332 = OpLoad %34 %36\n%333 = OpCompositeConstruct %43 %65 %67\n%334 = OpImageQuerySize %83 %330\n%335 = OpBitwiseAnd %83 %334 %88\n%336 = OpImageQueryLevels %81 %331\n%337 = OpISub %81 %336 %91\n%338 = OpConvertSToF %10 %337\n%339 = OpExtInst %10 %79 NClamp %70 %138 %338\n%340 = OpConvertFToS %81 %339\n%341 = OpFAdd %10 %339 %98\n%342 = OpConvertFToS %81 %341\n%343 = OpExtInst %81 %79 SMin %342 %337\n%344 = OpINotEqual %80 %340 %342\n%345 = OpExtInst %43 %79 Fract %333\n%347 = OpImageQuerySizeLod %83 %331 %340\n%346 = OpConvertSToF %43 %347\n%348 = OpSNegate %83 %335\n%349 = OpExtInst %43 %79 Ldexp %346 %348\n%350 = OpFMul %43 %345 %349\n%351 = OpExtInst %43 %79 Ldexp %134 %348\n%352 = OpFSub %43 %350 %351\n%353 = OpExtInst %43 %79 FMax %352 %139\n%354 = OpFAdd %43 %350 %351\n%355 = OpConvertFToS %83 %353\n%356 = OpConvertFToS %83 %354\n%357 = OpINotEqual %82 %355 %356\n%358 = OpCompositeExtract %80 %357 0\n%359 = OpCompositeExtract %80 %357 1\n%360 = OpLogicalAnd %80 %358 %359\n%361 = OpSelect %81 %358 %148 %127\n%362 = OpBitwiseOr %81 %91 %361\n%363 = OpSelect %81 %359 %129 %127\n%364 = OpBitwiseOr %81 %362 %363\n%365 = OpSelect %81 %360 %153 %127\n%366 = OpBitwiseOr %81 %364 %365\n%367 = OpSConvert %5 %366\n%368 = OpIMul %81 %340 %129\n%369 = OpSConvert %5 %368\n%370 = OpShiftLeftLogical %5 %367 %369\n%371 = OpLoad %80 %2192\n%372 = OpLogicalNot %80 %371\n%373 = OpFunctionCall %1 %167 %24 %355 %370 %372\n%375 = OpImageQuerySizeLod %83 %331 %342\n%374 = OpConvertSToF %43 %375\n%376 = OpSNegate %83 %335\n%377 = OpExtInst %43 %79 Ldexp %374 %376\n%378 = OpFMul %43 %345 %377\n%379 = OpExtInst %43 %79 Ldexp %134 %376\n%380 = OpFSub %43 %378 %379\n%381 = OpExtInst %43 %79 FMax %380 %139\n%382 = OpFAdd %43 %378 %379\n%383 = OpConvertFToS %83 %381\n%384 = OpConvertFToS %83 %382\n%385 = OpINotEqual %82 %383 %384\n%386 = OpCompositeExtract %80 %385 0\n%387 = OpCompositeExtract %80 %385 1\n%388 = OpLogicalAnd %80 %386 %387\n%389 = OpSelect %81 %386 %148 %127\n%390 = OpBitwiseOr %81 %91 %389\n%391 = OpSelect %81 %387 %129 %127\n%392 = OpBitwiseOr %81 %390 %391\n%393 = OpSelect %81 %388 %153 %127\n%394 = OpBitwiseOr %81 %392 %393\n%395 = OpSConvert %5 %394\n%396 = OpIMul %81 %342 %129\n%397 = OpSConvert %5 %396\n%398 = OpShiftLeftLogical %5 %395 %397\n%399 = OpLoad %80 %2192\n%400 = OpLogicalNot %80 %399\n%401 = OpLogicalAnd %80 %400 %344\n%402 = OpFunctionCall %1 %167 %24 %383 %398 %401\n%403 = OpLoad %6 %24\n%404 = OpLoad %11 %13\n%405 = OpLoad %34 %36\n%406 = OpCompositeConstruct %43 %65 %67\n%407 = OpImageQuerySize %83 %403\n%408 = OpBitwiseAnd %83 %407 %88\n%409 = OpImageQueryLevels %81 %404\n%410 = OpISub %81 %409 %91\n%412 = OpImageQuerySizeLod %83 %404 %127\n%411 = OpConvertSToF %43 %412\n%413 = OpCompositeConstruct %43 %61 %63\n%414 = OpCompositeConstruct %43 %56 %59\n%415 = OpFMul %43 %411 %413\n%416 = OpFMul %43 %411 %414\n%417 = OpDot %10 %415 %415\n%418 = OpDot %10 %416 %416\n%419 = OpExtInst %10 %79 FMax %417 %418\n%420 = OpExtInst %10 %79 Log2 %419\n%421 = OpFMul %10 %420 %133\n%422 = OpConvertSToF %10 %410\n%423 = OpExtInst %10 %79 NClamp %421 %138 %422\n%424 = OpConvertFToS %81 %423\n%425 = OpFAdd %10 %423 %98\n%426 = OpConvertFToS %81 %425\n%427 = OpExtInst %81 %79 SMin %426 %410\n%428 = OpINotEqual %80 %424 %426\n%429 = OpExtInst %43 %79 Fract %406\n%431 = OpImageQuerySizeLod %83 %404 %424\n%430 = OpConvertSToF %43 %431\n%432 = OpSNegate %83 %408\n%433 = OpExtInst %43 %79 Ldexp %430 %432\n%434 = OpFMul %43 %429 %433\n%435 = OpExtInst %43 %79 Ldexp %134 %432\n%436 = OpFSub %43 %434 %435\n%437 = OpExtInst %43 %79 FMax %436 %139\n%438 = OpFAdd %43 %434 %435\n%439 = OpConvertFToS %83 %437\n%440 = OpConvertFToS %83 %438\n%441 = OpINotEqual %82 %439 %440\n%442 = OpCompositeExtract %80 %441 0\n%443 = OpCompositeExtract %80 %441 1\n%444 = OpLogicalAnd %80 %442 %443\n%445 = OpSelect %81 %442 %148 %127\n%446 = OpBitwiseOr %81 %91 %445\n%447 = OpSelect %81 %443 %129 %127\n%448 = OpBitwiseOr %81 %446 %447\n%449 = OpSelect %81 %444 %153 %127\n%450 = OpBitwiseOr %81 %448 %449\n%451 = OpSConvert %5 %450\n%452 = OpIMul %81 %424 %129\n%453 = OpSConvert %5 %452\n%454 = OpShiftLeftLogical %5 %451 %453\n%455 = OpLoad %80 %2192\n%456 = OpLogicalNot %80 %455\n%457 = OpFunctionCall %1 %167 %24 %439 %454 %456\n%459 = OpImageQuerySizeLod %83 %404 %426\n%458 = OpConvertSToF %43 %459\n%460 = OpSNegate %83 %408\n%461 = OpExtInst %43 %79 Ldexp %458 %460\n%462 = OpFMul %43 %429 %461\n%463 = OpExtInst %43 %79 Ldexp %134 %460\n%464 = OpFSub %43 %462 %463\n%465 = OpExtInst %43 %79 FMax %464 %139\n%466 = OpFAdd %43 %462 %463\n%467 = OpConvertFToS %83 %465\n%468 = OpConvertFToS %83 %466\n%469 = OpINotEqual %82 %467 %468\n%470 = OpCompositeExtract %80 %469 0\n%471 = OpCompositeExtract %80 %469 1\n%472 = OpLogicalAnd %80 %470 %471\n%473 = OpSelect %81 %470 %148 %127\n%474 = OpBitwiseOr %81 %91 %473\n%475 = OpSelect %81 %471 %129 %127\n%476 = OpBitwiseOr %81 %474 %475\n%477 = OpSelect %81 %472 %153 %127\n%478 = OpBitwiseOr %81 %476 %477\n%479 = OpSConvert %5 %478\n%480 = OpIMul %81 %426 %129\n%481 = OpSConvert %5 %480\n%482 = OpShiftLeftLogical %5 %479 %481\n%483 = OpLoad %80 %2192\n%484 = OpLogicalNot %80 %483\n%485 = OpLogicalAnd %80 %484 %428\n%486 = OpFunctionCall %1 %167 %24 %467 %482 %485\n%487 = OpLoad %6 %24\n%488 = OpLoad %11 %13\n%489 = OpLoad %34 %36\n%490 = OpCompositeConstruct %43 %65 %67\n%491 = OpImageQuerySize %83 %487\n%492 = OpBitwiseAnd %83 %491 %88\n%493 = OpImageQueryLevels %81 %488\n%494 = OpISub %81 %493 %91\n%496 = OpImageQuerySizeLod %83 %488 %127\n%495 = OpConvertSToF %43 %496\n%497 = OpCompositeConstruct %43 %61 %63\n%498 = OpCompositeConstruct %43 %56 %59\n%499 = OpFMul %43 %495 %497\n%500 = OpFMul %43 %495 %498\n%501 = OpDot %10 %499 %499\n%502 = OpDot %10 %500 %500\n%503 = OpExtInst %10 %79 FMax %501 %502\n%504 = OpExtInst %10 %79 Log2 %503\n%505 = OpFMul %10 %504 %133\n%506 = OpConvertSToF %10 %494\n%507 = OpExtInst %10 %79 NClamp %505 %138 %506\n%508 = OpExtInst %10 %79 FMax %507 %53\n%509 = OpExtInst %10 %79 FMin %508 %241\n%510 = OpConvertFToS %81 %509\n%511 = OpFAdd %10 %509 %98\n%512 = OpConvertFToS %81 %511\n%513 = OpExtInst %81 %79 SMin %512 %494\n%514 = OpINotEqual %80 %510 %512\n%515 = OpExtInst %43 %79 Fract %490\n%517 = OpImageQuerySizeLod %83 %488 %510\n%516 = OpConvertSToF %43 %517\n%518 = OpSNegate %83 %492\n%519 = OpExtInst %43 %79 Ldexp %516 %518\n%520 = OpFMul %43 %515 %519\n%521 = OpExtInst %43 %79 Ldexp %134 %518\n%522 = OpFSub %43 %520 %521\n%523 = OpExtInst %43 %79 FMax %522 %139\n%524 = OpFAdd %43 %520 %521\n%525 = OpConvertFToS %83 %523\n%526 = OpConvertFToS %83 %524\n%527 = OpINotEqual %82 %525 %526\n%528 = OpCompositeExtract %80 %527 0\n%529 = OpCompositeExtract %80 %527 1\n%530 = OpLogicalAnd %80 %528 %529\n%531 = OpSelect %81 %528 %148 %127\n%532 = OpBitwiseOr %81 %91 %531\n%533 = OpSelect %81 %529 %129 %127\n%534 = OpBitwiseOr %81 %532 %533\n%535 = OpSelect %81 %530 %153 %127\n%536 = OpBitwiseOr %81 %534 %535\n%537 = OpSConvert %5 %536\n%538 = OpIMul %81 %510 %129\n%539 = OpSConvert %5 %538\n%540 = OpShiftLeftLogical %5 %537 %539\n%541 = OpLoad %80 %2192\n%542 = OpLogicalNot %80 %541\n%543 = OpFunctionCall %1 %167 %24 %525 %540 %542\n%545 = OpImageQuerySizeLod %83 %488 %512\n%544 = OpConvertSToF %43 %545\n%546 = OpSNegate %83 %492\n%547 = OpExtInst %43 %79 Ldexp %544 %546\n%548 = OpFMul %43 %515 %547\n%549 = OpExtInst %43 %79 Ldexp %134 %546\n%550 = OpFSub %43 %548 %549\n%551 = OpExtInst %43 %79 FMax %550 %139\n%552 = OpFAdd %43 %548 %549\n%553 = OpConvertFToS %83 %551\n%554 = OpConvertFToS %83 %552\n%555 = OpINotEqual %82 %553 %554\n%556 = OpCompositeExtract %80 %555 0\n%557 = OpCompositeExtract %80 %555 1\n%558 = OpLogicalAnd %80 %556 %557\n%559 = OpSelect %81 %556 %148 %127\n%560 = OpBitwiseOr %81 %91 %559\n%561 = OpSelect %81 %557 %129 %127\n%562 = OpBitwiseOr %81 %560 %561\n%563 = OpSelect %81 %558 %153 %127\n%564 = OpBitwiseOr %81 %562 %563\n%565 = OpSConvert %5 %564\n%566 = OpIMul %81 %512 %129\n%567 = OpSConvert %5 %566\n%568 = OpShiftLeftLogical %5 %565 %567\n%569 = OpLoad %80 %2192\n%570 = OpLogicalNot %80 %569\n%571 = OpLogicalAnd %80 %570 %514\n%572 = OpFunctionCall %1 %167 %24 %553 %568 %571\n%573 = OpLoad %6 %24\n%574 = OpLoad %11 %13\n%575 = OpLoad %34 %36\n%576 = OpCompositeConstruct %43 %65 %67\n%577 = OpImageQuerySize %83 %573\n%578 = OpBitwiseAnd %83 %577 %88\n%579 = OpImageQueryLevels %81 %574\n%580 = OpISub %81 %579 %91\n%581 = OpSampledImage %92 %574 %575\n%582 = OpExtInst %10 %79 Exp2 %70\n%583 = OpGroupNonUniformQuadBroadcast %10 %72 %582 %55\n%584 = OpVectorTimesScalar %43 %576 %583\n%585 = OpImageQueryLod %43 %581 %584\n%586 = OpCompositeExtract %10 %585 0\n%587 = OpConvertFToS %81 %586\n%588 = OpFAdd %10 %586 %98\n%589 = OpConvertFToS %81 %588\n%590 = OpExtInst %81 %79 SMin %589 %580\n%591 = OpINotEqual %80 %587 %589\n%592 = OpDPdx %43 %576\n%593 = OpDPdy %43 %576\n%594 = OpExtInst %43 %79 FAbs %592\n%595 = OpExtInst %43 %79 FAbs %593\n%596 = OpCompositeExtract %10 %594 0\n%597 = OpCompositeExtract %10 %595 0\n%598 = OpCompositeExtract %10 %594 1\n%599 = OpCompositeExtract %10 %595 1\n%600 = OpExtInst %10 %79 FMax %596 %597\n%601 = OpExtInst %10 %79 FMax %598 %599\n%602 = OpCompositeConstruct %43 %600 %601\n%603 = OpVectorTimesScalar %43 %602 %582\n%604 = OpExtInst %43 %79 Fract %576\n%606 = OpImageQuerySizeLod %83 %574 %587\n%605 = OpConvertSToF %43 %606\n%607 = OpSNegate %83 %578\n%608 = OpExtInst %43 %79 Ldexp %605 %607\n%609 = OpFMul %43 %604 %608\n%610 = OpFMul %43 %603 %605\n%611 = OpFSub %43 %610 %122\n%612 = OpExtInst %123 %79 FrexpStruct %611\n%613 = OpCompositeExtract %83 %612 1\n%614 = OpExtInst %83 %79 SClamp %613 %128 %130\n%615 = OpIAdd %83 %614 %607\n%616 = OpExtInst %43 %79 Ldexp %134 %615\n%617 = OpExtInst %43 %79 FMin %616 %134\n%618 = OpFSub %43 %609 %617\n%619 = OpExtInst %43 %79 FMax %618 %139\n%620 = OpFAdd %43 %609 %617\n%621 = OpConvertFToS %83 %619\n%622 = OpConvertFToS %83 %620\n%623 = OpINotEqual %82 %621 %622\n%624 = OpCompositeExtract %80 %623 0\n%625 = OpCompositeExtract %80 %623 1\n%626 = OpLogicalAnd %80 %624 %625\n%627 = OpSelect %81 %624 %148 %127\n%628 = OpBitwiseOr %81 %91 %627\n%629 = OpSelect %81 %625 %129 %127\n%630 = OpBitwiseOr %81 %628 %629\n%631 = OpSelect %81 %626 %153 %127\n%632 = OpBitwiseOr %81 %630 %631\n%633 = OpSConvert %5 %632\n%634 = OpIMul %81 %587 %129\n%635 = OpSConvert %5 %634\n%636 = OpShiftLeftLogical %5 %633 %635\n%637 = OpLoad %80 %2192\n%638 = OpLogicalNot %80 %637\n%639 = OpFunctionCall %1 %167 %24 %621 %636 %638\n%641 = OpImageQuerySizeLod %83 %574 %589\n%640 = OpConvertSToF %43 %641\n%642 = OpSNegate %83 %578\n%643 = OpExtInst %43 %79 Ldexp %640 %642\n%644 = OpFMul %43 %604 %643\n%645 = OpFMul %43 %603 %640\n%646 = OpFSub %43 %645 %122\n%647 = OpExtInst %123 %79 FrexpStruct %646\n%648 = OpCompositeExtract %83 %647 1\n%649 = OpExtInst %83 %79 SClamp %648 %128 %130\n%650 = OpIAdd %83 %649 %642\n%651 = OpExtInst %43 %79 Ldexp %134 %650\n%652 = OpExtInst %43 %79 FMin %651 %134\n%653 = OpFSub %43 %644 %652\n%654 = OpExtInst %43 %79 FMax %653 %139\n%655 = OpFAdd %43 %644 %652\n%656 = OpConvertFToS %83 %654\n%657 = OpConvertFToS %83 %655\n%658 = OpINotEqual %82 %656 %657\n%659 = OpCompositeExtract %80 %658 0\n%660 = OpCompositeExtract %80 %658 1\n%661 = OpLogicalAnd %80 %659 %660\n%662 = OpSelect %81 %659 %148 %127\n%663 = OpBitwiseOr %81 %91 %662\n%664 = OpSelect %81 %660 %129 %127\n%665 = OpBitwiseOr %81 %663 %664\n%666 = OpSelect %81 %661 %153 %127\n%667 = OpBitwiseOr %81 %665 %666\n%668 = OpSConvert %5 %667\n%669 = OpIMul %81 %589 %129\n%670 = OpSConvert %5 %669\n%671 = OpShiftLeftLogical %5 %668 %670\n%672 = OpLoad %80 %2192\n%673 = OpLogicalNot %80 %672\n%674 = OpLogicalAnd %80 %673 %591\n%675 = OpFunctionCall %1 %167 %24 %656 %671 %674\n%676 = OpLoad %6 %24\n%677 = OpLoad %11 %13\n%678 = OpLoad %34 %36\n%679 = OpCompositeConstruct %43 %65 %67\n%680 = OpImageQuerySize %83 %676\n%681 = OpBitwiseAnd %83 %680 %88\n%682 = OpImageQueryLevels %81 %677\n%683 = OpISub %81 %682 %91\n%684 = OpSampledImage %92 %677 %678\n%685 = OpExtInst %10 %79 Exp2 %70\n%686 = OpGroupNonUniformQuadBroadcast %10 %72 %685 %55\n%687 = OpVectorTimesScalar %43 %679 %686\n%688 = OpImageQueryLod %43 %684 %687\n%689 = OpCompositeExtract %10 %688 0\n%690 = OpExtInst %10 %79 FMax %689 %53\n%691 = OpExtInst %10 %79 FMin %690 %241\n%692 = OpConvertFToS %81 %691\n%693 = OpFAdd %10 %691 %98\n%694 = OpConvertFToS %81 %693\n%695 = OpExtInst %81 %79 SMin %694 %683\n%696 = OpINotEqual %80 %692 %694\n%697 = OpDPdx %43 %679\n%698 = OpDPdy %43 %679\n%699 = OpExtInst %43 %79 FAbs %697\n%700 = OpExtInst %43 %79 FAbs %698\n%701 = OpCompositeExtract %10 %699 0\n%702 = OpCompositeExtract %10 %700 0\n%703 = OpCompositeExtract %10 %699 1\n%704 = OpCompositeExtract %10 %700 1\n%705 = OpExtInst %10 %79 FMax %701 %702\n%706 = OpExtInst %10 %79 FMax %703 %704\n%707 = OpCompositeConstruct %43 %705 %706\n%708 = OpVectorTimesScalar %43 %707 %685\n%709 = OpExtInst %43 %79 Fract %679\n%711 = OpImageQuerySizeLod %83 %677 %692\n%710 = OpConvertSToF %43 %711\n%712 = OpSNegate %83 %681\n%713 = OpExtInst %43 %79 Ldexp %710 %712\n%714 = OpFMul %43 %709 %713\n%715 = OpFMul %43 %708 %710\n%716 = OpFSub %43 %715 %122\n%717 = OpExtInst %123 %79 FrexpStruct %716\n%718 = OpCompositeExtract %83 %717 1\n%719 = OpExtInst %83 %79 SClamp %718 %128 %130\n%720 = OpIAdd %83 %719 %712\n%721 = OpExtInst %43 %79 Ldexp %134 %720\n%722 = OpExtInst %43 %79 FMin %721 %134\n%723 = OpFSub %43 %714 %722\n%724 = OpExtInst %43 %79 FMax %723 %139\n%725 = OpFAdd %43 %714 %722\n%726 = OpConvertFToS %83 %724\n%727 = OpConvertFToS %83 %725\n%728 = OpINotEqual %82 %726 %727\n%729 = OpCompositeExtract %80 %728 0\n%730 = OpCompositeExtract %80 %728 1\n%731 = OpLogicalAnd %80 %729 %730\n%732 = OpSelect %81 %729 %148 %127\n%733 = OpBitwiseOr %81 %91 %732\n%734 = OpSelect %81 %730 %129 %127\n%735 = OpBitwiseOr %81 %733 %734\n%736 = OpSelect %81 %731 %153 %127\n%737 = OpBitwiseOr %81 %735 %736\n%738 = OpSConvert %5 %737\n%739 = OpIMul %81 %692 %129\n%740 = OpSConvert %5 %739\n%741 = OpShiftLeftLogical %5 %738 %740\n%742 = OpLoad %80 %2192\n%743 = OpLogicalNot %80 %742\n%744 = OpFunctionCall %1 %167 %24 %726 %741 %743\n%746 = OpImageQuerySizeLod %83 %677 %694\n%745 = OpConvertSToF %43 %746\n%747 = OpSNegate %83 %681\n%748 = OpExtInst %43 %79 Ldexp %745 %747\n%749 = OpFMul %43 %709 %748\n%750 = OpFMul %43 %708 %745\n%751 = OpFSub %43 %750 %122\n%752 = OpExtInst %123 %79 FrexpStruct %751\n%753 = OpCompositeExtract %83 %752 1\n%754 = OpExtInst %83 %79 SClamp %753 %128 %130\n%755 = OpIAdd %83 %754 %747\n%756 = OpExtInst %43 %79 Ldexp %134 %755\n%757 = OpExtInst %43 %79 FMin %756 %134\n%758 = OpFSub %43 %749 %757\n%759 = OpExtInst %43 %79 FMax %758 %139\n%760 = OpFAdd %43 %749 %757\n%761 = OpConvertFToS %83 %759\n%762 = OpConvertFToS %83 %760\n%763 = OpINotEqual %82 %761 %762\n%764 = OpCompositeExtract %80 %763 0\n%765 = OpCompositeExtract %80 %763 1\n%766 = OpLogicalAnd %80 %764 %765\n%767 = OpSelect %81 %764 %148 %127\n%768 = OpBitwiseOr %81 %91 %767\n%769 = OpSelect %81 %765 %129 %127\n%770 = OpBitwiseOr %81 %768 %769\n%771 = OpSelect %81 %766 %153 %127\n%772 = OpBitwiseOr %81 %770 %771\n%773 = OpSConvert %5 %772\n%774 = OpIMul %81 %694 %129\n%775 = OpSConvert %5 %774\n%776 = OpShiftLeftLogical %5 %773 %775\n%777 = OpLoad %80 %2192\n%778 = OpLogicalNot %80 %777\n%779 = OpLogicalAnd %80 %778 %696\n%780 = OpFunctionCall %1 %167 %24 %761 %776 %779\n%781 = OpLoad %25 %27\n%782 = OpLoad %14 %16\n%783 = OpLoad %34 %36\n%784 = OpExtInst %10 %79 RoundEven %70\n%785 = OpConvertFToS %81 %784\n%786 = OpCompositeConstruct %43 %65 %67\n%788 = OpImageQuerySize %787 %781\n%789 = OpVectorShuffle %83 %788 %788 0 1\n%790 = OpBitwiseAnd %83 %789 %88\n%791 = OpImageQueryLevels %81 %782\n%792 = OpISub %81 %791 %91\n%794 = OpSampledImage %793 %782 %783\n%795 = OpImageQueryLod %43 %794 %786\n%796 = OpCompositeExtract %10 %795 0\n%797 = OpConvertFToS %81 %796\n%798 = OpFAdd %10 %796 %98\n%799 = OpConvertFToS %81 %798\n%800 = OpExtInst %81 %79 SMin %799 %792\n%801 = OpINotEqual %80 %797 %799\n%802 = OpDPdx %43 %786\n%803 = OpDPdy %43 %786\n%804 = OpExtInst %43 %79 FAbs %802\n%805 = OpExtInst %43 %79 FAbs %803\n%806 = OpCompositeExtract %10 %804 0\n%807 = OpCompositeExtract %10 %805 0\n%808 = OpCompositeExtract %10 %804 1\n%809 = OpCompositeExtract %10 %805 1\n%810 = OpExtInst %10 %79 FMax %806 %807\n%811 = OpExtInst %10 %79 FMax %808 %809\n%812 = OpCompositeConstruct %43 %810 %811\n%813 = OpExtInst %43 %79 Fract %786\n%815 = OpImageQuerySizeLod %787 %782 %797\n%816 = OpVectorShuffle %83 %815 %815 0 1\n%814 = OpConvertSToF %43 %816\n%817 = OpSNegate %83 %790\n%818 = OpExtInst %43 %79 Ldexp %814 %817\n%819 = OpFMul %43 %813 %818\n%820 = OpFMul %43 %812 %814\n%821 = OpFSub %43 %820 %122\n%822 = OpExtInst %123 %79 FrexpStruct %821\n%823 = OpCompositeExtract %83 %822 1\n%824 = OpExtInst %83 %79 SClamp %823 %128 %130\n%825 = OpIAdd %83 %824 %817\n%826 = OpExtInst %43 %79 Ldexp %134 %825\n%827 = OpExtInst %43 %79 FMin %826 %134\n%828 = OpFSub %43 %819 %827\n%829 = OpExtInst %43 %79 FMax %828 %139\n%830 = OpFAdd %43 %819 %827\n%831 = OpConvertFToS %83 %829\n%832 = OpConvertFToS %83 %830\n%833 = OpINotEqual %82 %831 %832\n%834 = OpCompositeExtract %80 %833 0\n%835 = OpCompositeExtract %80 %833 1\n%836 = OpLogicalAnd %80 %834 %835\n%837 = OpSelect %81 %834 %148 %127\n%838 = OpBitwiseOr %81 %91 %837\n%839 = OpSelect %81 %835 %129 %127\n%840 = OpBitwiseOr %81 %838 %839\n%841 = OpSelect %81 %836 %153 %127\n%842 = OpBitwiseOr %81 %840 %841\n%843 = OpSConvert %5 %842\n%844 = OpIMul %81 %797 %129\n%845 = OpSConvert %5 %844\n%846 = OpShiftLeftLogical %5 %843 %845\n%847 = OpCompositeConstruct %787 %831 %785\n%848 = OpLoad %80 %2192\n%849 = OpLogicalNot %80 %848\n%878 = OpFunctionCall %1 %856 %27 %847 %846 %849\n%880 = OpImageQuerySizeLod %787 %782 %799\n%881 = OpVectorShuffle %83 %880 %880 0 1\n%879 = OpConvertSToF %43 %881\n%882 = OpSNegate %83 %790\n%883 = OpExtInst %43 %79 Ldexp %879 %882\n%884 = OpFMul %43 %813 %883\n%885 = OpFMul %43 %812 %879\n%886 = OpFSub %43 %885 %122\n%887 = OpExtInst %123 %79 FrexpStruct %886\n%888 = OpCompositeExtract %83 %887 1\n%889 = OpExtInst %83 %79 SClamp %888 %128 %130\n%890 = OpIAdd %83 %889 %882\n%891 = OpExtInst %43 %79 Ldexp %134 %890\n%892 = OpExtInst %43 %79 FMin %891 %134\n%893 = OpFSub %43 %884 %892\n%894 = OpExtInst %43 %79 FMax %893 %139\n%895 = OpFAdd %43 %884 %892\n%896 = OpConvertFToS %83 %894\n%897 = OpConvertFToS %83 %895\n%898 = OpINotEqual %82 %896 %897\n%899 = OpCompositeExtract %80 %898 0\n%900 = OpCompositeExtract %80 %898 1\n%901 = OpLogicalAnd %80 %899 %900\n%902 = OpSelect %81 %899 %148 %127\n%903 = OpBitwiseOr %81 %91 %902\n%904 = OpSelect %81 %900 %129 %127\n%905 = OpBitwiseOr %81 %903 %904\n%906 = OpSelect %81 %901 %153 %127\n%907 = OpBitwiseOr %81 %905 %906\n%908 = OpSConvert %5 %907\n%909 = OpIMul %81 %799 %129\n%910 = OpSConvert %5 %909\n%911 = OpShiftLeftLogical %5 %908 %910\n%912 = OpCompositeConstruct %787 %896 %785\n%913 = OpLoad %80 %2192\n%914 = OpLogicalNot %80 %913\n%915 = OpLogicalAnd %80 %914 %801\n%916 = OpFunctionCall %1 %856 %27 %912 %911 %915\n%917 = OpLoad %25 %27\n%918 = OpLoad %14 %16\n%919 = OpLoad %34 %36\n%920 = OpExtInst %10 %79 RoundEven %70\n%921 = OpConvertFToS %81 %920\n%922 = OpCompositeConstruct %43 %65 %67\n%923 = OpImageQuerySize %787 %917\n%924 = OpVectorShuffle %83 %923 %923 0 1\n%925 = OpBitwiseAnd %83 %924 %88\n%926 = OpImageQueryLevels %81 %918\n%927 = OpISub %81 %926 %91\n%928 = OpSampledImage %793 %918 %919\n%929 = OpImageQueryLod %43 %928 %922\n%930 = OpCompositeExtract %10 %929 0\n%931 = OpExtInst %10 %79 FMax %930 %53\n%932 = OpExtInst %10 %79 FMin %931 %241\n%933 = OpConvertFToS %81 %932\n%934 = OpFAdd %10 %932 %98\n%935 = OpConvertFToS %81 %934\n%936 = OpExtInst %81 %79 SMin %935 %927\n%937 = OpINotEqual %80 %933 %935\n%938 = OpDPdx %43 %922\n%939 = OpDPdy %43 %922\n%940 = OpExtInst %43 %79 FAbs %938\n%941 = OpExtInst %43 %79 FAbs %939\n%942 = OpCompositeExtract %10 %940 0\n%943 = OpCompositeExtract %10 %941 0\n%944 = OpCompositeExtract %10 %940 1\n%945 = OpCompositeExtract %10 %941 1\n%946 = OpExtInst %10 %79 FMax %942 %943\n%947 = OpExtInst %10 %79 FMax %944 %945\n%948 = OpCompositeConstruct %43 %946 %947\n%949 = OpExtInst %43 %79 Fract %922\n%951 = OpImageQuerySizeLod %787 %918 %933\n%952 = OpVectorShuffle %83 %951 %951 0 1\n%950 = OpConvertSToF %43 %952\n%953 = OpSNegate %83 %925\n%954 = OpExtInst %43 %79 Ldexp %950 %953\n%955 = OpFMul %43 %949 %954\n%956 = OpFMul %43 %948 %950\n%957 = OpFSub %43 %956 %122\n%958 = OpExtInst %123 %79 FrexpStruct %957\n%959 = OpCompositeExtract %83 %958 1\n%960 = OpExtInst %83 %79 SClamp %959 %128 %130\n%961 = OpIAdd %83 %960 %953\n%962 = OpExtInst %43 %79 Ldexp %134 %961\n%963 = OpExtInst %43 %79 FMin %962 %134\n%964 = OpFSub %43 %955 %963\n%965 = OpExtInst %43 %79 FMax %964 %139\n%966 = OpFAdd %43 %955 %963\n%967 = OpConvertFToS %83 %965\n%968 = OpConvertFToS %83 %966\n%969 = OpINotEqual %82 %967 %968\n%970 = OpCompositeExtract %80 %969 0\n%971 = OpCompositeExtract %80 %969 1\n%972 = OpLogicalAnd %80 %970 %971\n%973 = OpSelect %81 %970 %148 %127\n%974 = OpBitwiseOr %81 %91 %973\n%975 = OpSelect %81 %971 %129 %127\n%976 = OpBitwiseOr %81 %974 %975\n%977 = OpSelect %81 %972 %153 %127\n%978 = OpBitwiseOr %81 %976 %977\n%979 = OpSConvert %5 %978\n%980 = OpIMul %81 %933 %129\n%981 = OpSConvert %5 %980\n%982 = OpShiftLeftLogical %5 %979 %981\n%983 = OpCompositeConstruct %787 %967 %921\n%984 = OpLoad %80 %2192\n%985 = OpLogicalNot %80 %984\n%986 = OpFunctionCall %1 %856 %27 %983 %982 %985\n%988 = OpImageQuerySizeLod %787 %918 %935\n%989 = OpVectorShuffle %83 %988 %988 0 1\n%987 = OpConvertSToF %43 %989\n%990 = OpSNegate %83 %925\n%991 = OpExtInst %43 %79 Ldexp %987 %990\n%992 = OpFMul %43 %949 %991\n%993 = OpFMul %43 %948 %987\n%994 = OpFSub %43 %993 %122\n%995 = OpExtInst %123 %79 FrexpStruct %994\n%996 = OpCompositeExtract %83 %995 1\n%997 = OpExtInst %83 %79 SClamp %996 %128 %130\n%998 = OpIAdd %83 %997 %990\n%999 = OpExtInst %43 %79 Ldexp %134 %998\n%1000 = OpExtInst %43 %79 FMin %999 %134\n%1001 = OpFSub %43 %992 %1000\n%1002 = OpExtInst %43 %79 FMax %1001 %139\n%1003 = OpFAdd %43 %992 %1000\n%1004 = OpConvertFToS %83 %1002\n%1005 = OpConvertFToS %83 %1003\n%1006 = OpINotEqual %82 %1004 %1005\n%1007 = OpCompositeExtract %80 %1006 0\n%1008 = OpCompositeExtract %80 %1006 1\n%1009 = OpLogicalAnd %80 %1007 %1008\n%1010 = OpSelect %81 %1007 %148 %127\n%1011 = OpBitwiseOr %81 %91 %1010\n%1012 = OpSelect %81 %1008 %129 %127\n%1013 = OpBitwiseOr %81 %1011 %1012\n%1014 = OpSelect %81 %1009 %153 %127\n%1015 = OpBitwiseOr %81 %1013 %1014\n%1016 = OpSConvert %5 %1015\n%1017 = OpIMul %81 %935 %129\n%1018 = OpSConvert %5 %1017\n%1019 = OpShiftLeftLogical %5 %1016 %1018\n%1020 = OpCompositeConstruct %787 %1004 %921\n%1021 = OpLoad %80 %2192\n%1022 = OpLogicalNot %80 %1021\n%1023 = OpLogicalAnd %80 %1022 %937\n%1024 = OpFunctionCall %1 %856 %27 %1020 %1019 %1023\n%1025 = OpLoad %25 %27\n%1026 = OpLoad %14 %16\n%1027 = OpLoad %34 %36\n%1028 = OpExtInst %10 %79 RoundEven %70\n%1029 = OpConvertFToS %81 %1028\n%1030 = OpCompositeConstruct %43 %65 %67\n%1031 = OpImageQuerySize %787 %1025\n%1032 = OpVectorShuffle %83 %1031 %1031 0 1\n%1033 = OpBitwiseAnd %83 %1032 %88\n%1034 = OpImageQueryLevels %81 %1026\n%1035 = OpISub %81 %1034 %91\n%1036 = OpConvertSToF %10 %1035\n%1037 = OpExtInst %10 %79 NClamp %74 %138 %1036\n%1038 = OpConvertFToS %81 %1037\n%1039 = OpFAdd %10 %1037 %98\n%1040 = OpConvertFToS %81 %1039\n%1041 = OpExtInst %81 %79 SMin %1040 %1035\n%1042 = OpINotEqual %80 %1038 %1040\n%1043 = OpExtInst %43 %79 Fract %1030\n%1045 = OpImageQuerySizeLod %787 %1026 %1038\n%1046 = OpVectorShuffle %83 %1045 %1045 0 1\n%1044 = OpConvertSToF %43 %1046\n%1047 = OpSNegate %83 %1033\n%1048 = OpExtInst %43 %79 Ldexp %1044 %1047\n%1049 = OpFMul %43 %1043 %1048\n%1050 = OpExtInst %43 %79 Ldexp %134 %1047\n%1051 = OpFSub %43 %1049 %1050\n%1052 = OpExtInst %43 %79 FMax %1051 %139\n%1053 = OpFAdd %43 %1049 %1050\n%1054 = OpConvertFToS %83 %1052\n%1055 = OpConvertFToS %83 %1053\n%1056 = OpINotEqual %82 %1054 %1055\n%1057 = OpCompositeExtract %80 %1056 0\n%1058 = OpCompositeExtract %80 %1056 1\n%1059 = OpLogicalAnd %80 %1057 %1058\n%1060 = OpSelect %81 %1057 %148 %127\n%1061 = OpBitwiseOr %81 %91 %1060\n%1062 = OpSelect %81 %1058 %129 %127\n%1063 = OpBitwiseOr %81 %1061 %1062\n%1064 = OpSelect %81 %1059 %153 %127\n%1065 = OpBitwiseOr %81 %1063 %1064\n%1066 = OpSConvert %5 %1065\n%1067 = OpIMul %81 %1038 %129\n%1068 = OpSConvert %5 %1067\n%1069 = OpShiftLeftLogical %5 %1066 %1068\n%1070 = OpCompositeConstruct %787 %1054 %1029\n%1071 = OpLoad %80 %2192\n%1072 = OpLogicalNot %80 %1071\n%1073 = OpFunctionCall %1 %856 %27 %1070 %1069 %1072\n%1075 = OpImageQuerySizeLod %787 %1026 %1040\n%1076 = OpVectorShuffle %83 %1075 %1075 0 1\n%1074 = OpConvertSToF %43 %1076\n%1077 = OpSNegate %83 %1033\n%1078 = OpExtInst %43 %79 Ldexp %1074 %1077\n%1079 = OpFMul %43 %1043 %1078\n%1080 = OpExtInst %43 %79 Ldexp %134 %1077\n%1081 = OpFSub %43 %1079 %1080\n%1082 = OpExtInst %43 %79 FMax %1081 %139\n%1083 = OpFAdd %43 %1079 %1080\n%1084 = OpConvertFToS %83 %1082\n%1085 = OpConvertFToS %83 %1083\n%1086 = OpINotEqual %82 %1084 %1085\n%1087 = OpCompositeExtract %80 %1086 0\n%1088 = OpCompositeExtract %80 %1086 1\n%1089 = OpLogicalAnd %80 %1087 %1088\n%1090 = OpSelect %81 %1087 %148 %127\n%1091 = OpBitwiseOr %81 %91 %1090\n%1092 = OpSelect %81 %1088 %129 %127\n%1093 = OpBitwiseOr %81 %1091 %1092\n%1094 = OpSelect %81 %1089 %153 %127\n%1095 = OpBitwiseOr %81 %1093 %1094\n%1096 = OpSConvert %5 %1095\n%1097 = OpIMul %81 %1040 %129\n%1098 = OpSConvert %5 %1097\n%1099 = OpShiftLeftLogical %5 %1096 %1098\n%1100 = OpCompositeConstruct %787 %1084 %1029\n%1101 = OpLoad %80 %2192\n%1102 = OpLogicalNot %80 %1101\n%1103 = OpLogicalAnd %80 %1102 %1042\n%1104 = OpFunctionCall %1 %856 %27 %1100 %1099 %1103\n%1105 = OpLoad %25 %27\n%1106 = OpLoad %14 %16\n%1107 = OpLoad %34 %36\n%1108 = OpExtInst %10 %79 RoundEven %70\n%1109 = OpConvertFToS %81 %1108\n%1110 = OpCompositeConstruct %43 %65 %67\n%1111 = OpImageQuerySize %787 %1105\n%1112 = OpVectorShuffle %83 %1111 %1111 0 1\n%1113 = OpBitwiseAnd %83 %1112 %88\n%1114 = OpImageQueryLevels %81 %1106\n%1115 = OpISub %81 %1114 %91\n%1117 = OpImageQuerySizeLod %787 %1106 %127\n%1118 = OpVectorShuffle %83 %1117 %1117 0 1\n%1116 = OpConvertSToF %43 %1118\n%1119 = OpCompositeConstruct %43 %61 %63\n%1120 = OpCompositeConstruct %43 %56 %59\n%1121 = OpFMul %43 %1116 %1119\n%1122 = OpFMul %43 %1116 %1120\n%1123 = OpDot %10 %1121 %1121\n%1124 = OpDot %10 %1122 %1122\n%1125 = OpExtInst %10 %79 FMax %1123 %1124\n%1126 = OpExtInst %10 %79 Log2 %1125\n%1127 = OpFMul %10 %1126 %133\n%1128 = OpConvertSToF %10 %1115\n%1129 = OpExtInst %10 %79 NClamp %1127 %138 %1128\n%1130 = OpConvertFToS %81 %1129\n%1131 = OpFAdd %10 %1129 %98\n%1132 = OpConvertFToS %81 %1131\n%1133 = OpExtInst %81 %79 SMin %1132 %1115\n%1134 = OpINotEqual %80 %1130 %1132\n%1135 = OpExtInst %43 %79 Fract %1110\n%1137 = OpImageQuerySizeLod %787 %1106 %1130\n%1138 = OpVectorShuffle %83 %1137 %1137 0 1\n%1136 = OpConvertSToF %43 %1138\n%1139 = OpSNegate %83 %1113\n%1140 = OpExtInst %43 %79 Ldexp %1136 %1139\n%1141 = OpFMul %43 %1135 %1140\n%1142 = OpExtInst %43 %79 Ldexp %134 %1139\n%1143 = OpFSub %43 %1141 %1142\n%1144 = OpExtInst %43 %79 FMax %1143 %139\n%1145 = OpFAdd %43 %1141 %1142\n%1146 = OpConvertFToS %83 %1144\n%1147 = OpConvertFToS %83 %1145\n%1148 = OpINotEqual %82 %1146 %1147\n%1149 = OpCompositeExtract %80 %1148 0\n%1150 = OpCompositeExtract %80 %1148 1\n%1151 = OpLogicalAnd %80 %1149 %1150\n%1152 = OpSelect %81 %1149 %148 %127\n%1153 = OpBitwiseOr %81 %91 %1152\n%1154 = OpSelect %81 %1150 %129 %127\n%1155 = OpBitwiseOr %81 %1153 %1154\n%1156 = OpSelect %81 %1151 %153 %127\n%1157 = OpBitwiseOr %81 %1155 %1156\n%1158 = OpSConvert %5 %1157\n%1159 = OpIMul %81 %1130 %129\n%1160 = OpSConvert %5 %1159\n%1161 = OpShiftLeftLogical %5 %1158 %1160\n%1162 = OpCompositeConstruct %787 %1146 %1109\n%1163 = OpLoad %80 %2192\n%1164 = OpLogicalNot %80 %1163\n%1165 = OpFunctionCall %1 %856 %27 %1162 %1161 %1164\n%1167 = OpImageQuerySizeLod %787 %1106 %1132\n%1168 = OpVectorShuffle %83 %1167 %1167 0 1\n%1166 = OpConvertSToF %43 %1168\n%1169 = OpSNegate %83 %1113\n%1170 = OpExtInst %43 %79 Ldexp %1166 %1169\n%1171 = OpFMul %43 %1135 %1170\n%1172 = OpExtInst %43 %79 Ldexp %134 %1169\n%1173 = OpFSub %43 %1171 %1172\n%1174 = OpExtInst %43 %79 FMax %1173 %139\n%1175 = OpFAdd %43 %1171 %1172\n%1176 = OpConvertFToS %83 %1174\n%1177 = OpConvertFToS %83 %1175\n%1178 = OpINotEqual %82 %1176 %1177\n%1179 = OpCompositeExtract %80 %1178 0\n%1180 = OpCompositeExtract %80 %1178 1\n%1181 = OpLogicalAnd %80 %1179 %1180\n%1182 = OpSelect %81 %1179 %148 %127\n%1183 = OpBitwiseOr %81 %91 %1182\n%1184 = OpSelect %81 %1180 %129 %127\n%1185 = OpBitwiseOr %81 %1183 %1184\n%1186 = OpSelect %81 %1181 %153 %127\n%1187 = OpBitwiseOr %81 %1185 %1186\n%1188 = OpSConvert %5 %1187\n%1189 = OpIMul %81 %1132 %129\n%1190 = OpSConvert %5 %1189\n%1191 = OpShiftLeftLogical %5 %1188 %1190\n%1192 = OpCompositeConstruct %787 %1176 %1109\n%1193 = OpLoad %80 %2192\n%1194 = OpLogicalNot %80 %1193\n%1195 = OpLogicalAnd %80 %1194 %1134\n%1196 = OpFunctionCall %1 %856 %27 %1192 %1191 %1195\n%1197 = OpLoad %25 %27\n%1198 = OpLoad %14 %16\n%1199 = OpLoad %34 %36\n%1200 = OpExtInst %10 %79 RoundEven %70\n%1201 = OpConvertFToS %81 %1200\n%1202 = OpCompositeConstruct %43 %65 %67\n%1203 = OpImageQuerySize %787 %1197\n%1204 = OpVectorShuffle %83 %1203 %1203 0 1\n%1205 = OpBitwiseAnd %83 %1204 %88\n%1206 = OpImageQueryLevels %81 %1198\n%1207 = OpISub %81 %1206 %91\n%1209 = OpImageQuerySizeLod %787 %1198 %127\n%1210 = OpVectorShuffle %83 %1209 %1209 0 1\n%1208 = OpConvertSToF %43 %1210\n%1211 = OpCompositeConstruct %43 %61 %63\n%1212 = OpCompositeConstruct %43 %56 %59\n%1213 = OpFMul %43 %1208 %1211\n%1214 = OpFMul %43 %1208 %1212\n%1215 = OpDot %10 %1213 %1213\n%1216 = OpDot %10 %1214 %1214\n%1217 = OpExtInst %10 %79 FMax %1215 %1216\n%1218 = OpExtInst %10 %79 Log2 %1217\n%1219 = OpFMul %10 %1218 %133\n%1220 = OpConvertSToF %10 %1207\n%1221 = OpExtInst %10 %79 NClamp %1219 %138 %1220\n%1222 = OpExtInst %10 %79 FMax %1221 %53\n%1223 = OpExtInst %10 %79 FMin %1222 %241\n%1224 = OpConvertFToS %81 %1223\n%1225 = OpFAdd %10 %1223 %98\n%1226 = OpConvertFToS %81 %1225\n%1227 = OpExtInst %81 %79 SMin %1226 %1207\n%1228 = OpINotEqual %80 %1224 %1226\n%1229 = OpExtInst %43 %79 Fract %1202\n%1231 = OpImageQuerySizeLod %787 %1198 %1224\n%1232 = OpVectorShuffle %83 %1231 %1231 0 1\n%1230 = OpConvertSToF %43 %1232\n%1233 = OpSNegate %83 %1205\n%1234 = OpExtInst %43 %79 Ldexp %1230 %1233\n%1235 = OpFMul %43 %1229 %1234\n%1236 = OpExtInst %43 %79 Ldexp %134 %1233\n%1237 = OpFSub %43 %1235 %1236\n%1238 = OpExtInst %43 %79 FMax %1237 %139\n%1239 = OpFAdd %43 %1235 %1236\n%1240 = OpConvertFToS %83 %1238\n%1241 = OpConvertFToS %83 %1239\n%1242 = OpINotEqual %82 %1240 %1241\n%1243 = OpCompositeExtract %80 %1242 0\n%1244 = OpCompositeExtract %80 %1242 1\n%1245 = OpLogicalAnd %80 %1243 %1244\n%1246 = OpSelect %81 %1243 %148 %127\n%1247 = OpBitwiseOr %81 %91 %1246\n%1248 = OpSelect %81 %1244 %129 %127\n%1249 = OpBitwiseOr %81 %1247 %1248\n%1250 = OpSelect %81 %1245 %153 %127\n%1251 = OpBitwiseOr %81 %1249 %1250\n%1252 = OpSConvert %5 %1251\n%1253 = OpIMul %81 %1224 %129\n%1254 = OpSConvert %5 %1253\n%1255 = OpShiftLeftLogical %5 %1252 %1254\n%1256 = OpCompositeConstruct %787 %1240 %1201\n%1257 = OpLoad %80 %2192\n%1258 = OpLogicalNot %80 %1257\n%1259 = OpFunctionCall %1 %856 %27 %1256 %1255 %1258\n%1261 = OpImageQuerySizeLod %787 %1198 %1226\n%1262 = OpVectorShuffle %83 %1261 %1261 0 1\n%1260 = OpConvertSToF %43 %1262\n%1263 = OpSNegate %83 %1205\n%1264 = OpExtInst %43 %79 Ldexp %1260 %1263\n%1265 = OpFMul %43 %1229 %1264\n%1266 = OpExtInst %43 %79 Ldexp %134 %1263\n%1267 = OpFSub %43 %1265 %1266\n%1268 = OpExtInst %43 %79 FMax %1267 %139\n%1269 = OpFAdd %43 %1265 %1266\n%1270 = OpConvertFToS %83 %1268\n%1271 = OpConvertFToS %83 %1269\n%1272 = OpINotEqual %82 %1270 %1271\n%1273 = OpCompositeExtract %80 %1272 0\n%1274 = OpCompositeExtract %80 %1272 1\n%1275 = OpLogicalAnd %80 %1273 %1274\n%1276 = OpSelect %81 %1273 %148 %127\n%1277 = OpBitwiseOr %81 %91 %1276\n%1278 = OpSelect %81 %1274 %129 %127\n%1279 = OpBitwiseOr %81 %1277 %1278\n%1280 = OpSelect %81 %1275 %153 %127\n%1281 = OpBitwiseOr %81 %1279 %1280\n%1282 = OpSConvert %5 %1281\n%1283 = OpIMul %81 %1226 %129\n%1284 = OpSConvert %5 %1283\n%1285 = OpShiftLeftLogical %5 %1282 %1284\n%1286 = OpCompositeConstruct %787 %1270 %1201\n%1287 = OpLoad %80 %2192\n%1288 = OpLogicalNot %80 %1287\n%1289 = OpLogicalAnd %80 %1288 %1228\n%1290 = OpFunctionCall %1 %856 %27 %1286 %1285 %1289\n%1291 = OpLoad %25 %27\n%1292 = OpLoad %14 %16\n%1293 = OpLoad %34 %36\n%1294 = OpExtInst %10 %79 RoundEven %70\n%1295 = OpConvertFToS %81 %1294\n%1296 = OpCompositeConstruct %43 %65 %67\n%1297 = OpImageQuerySize %787 %1291\n%1298 = OpVectorShuffle %83 %1297 %1297 0 1\n%1299 = OpBitwiseAnd %83 %1298 %88\n%1300 = OpImageQueryLevels %81 %1292\n%1301 = OpISub %81 %1300 %91\n%1302 = OpSampledImage %793 %1292 %1293\n%1303 = OpExtInst %10 %79 Exp2 %70\n%1304 = OpGroupNonUniformQuadBroadcast %10 %72 %1303 %55\n%1305 = OpVectorTimesScalar %43 %1296 %1304\n%1306 = OpImageQueryLod %43 %1302 %1305\n%1307 = OpCompositeExtract %10 %1306 0\n%1308 = OpConvertFToS %81 %1307\n%1309 = OpFAdd %10 %1307 %98\n%1310 = OpConvertFToS %81 %1309\n%1311 = OpExtInst %81 %79 SMin %1310 %1301\n%1312 = OpINotEqual %80 %1308 %1310\n%1313 = OpDPdx %43 %1296\n%1314 = OpDPdy %43 %1296\n%1315 = OpExtInst %43 %79 FAbs %1313\n%1316 = OpExtInst %43 %79 FAbs %1314\n%1317 = OpCompositeExtract %10 %1315 0\n%1318 = OpCompositeExtract %10 %1316 0\n%1319 = OpCompositeExtract %10 %1315 1\n%1320 = OpCompositeExtract %10 %1316 1\n%1321 = OpExtInst %10 %79 FMax %1317 %1318\n%1322 = OpExtInst %10 %79 FMax %1319 %1320\n%1323 = OpCompositeConstruct %43 %1321 %1322\n%1324 = OpVectorTimesScalar %43 %1323 %1303\n%1325 = OpExtInst %43 %79 Fract %1296\n%1327 = OpImageQuerySizeLod %787 %1292 %1308\n%1328 = OpVectorShuffle %83 %1327 %1327 0 1\n%1326 = OpConvertSToF %43 %1328\n%1329 = OpSNegate %83 %1299\n%1330 = OpExtInst %43 %79 Ldexp %1326 %1329\n%1331 = OpFMul %43 %1325 %1330\n%1332 = OpFMul %43 %1324 %1326\n%1333 = OpFSub %43 %1332 %122\n%1334 = OpExtInst %123 %79 FrexpStruct %1333\n%1335 = OpCompositeExtract %83 %1334 1\n%1336 = OpExtInst %83 %79 SClamp %1335 %128 %130\n%1337 = OpIAdd %83 %1336 %1329\n%1338 = OpExtInst %43 %79 Ldexp %134 %1337\n%1339 = OpExtInst %43 %79 FMin %1338 %134\n%1340 = OpFSub %43 %1331 %1339\n%1341 = OpExtInst %43 %79 FMax %1340 %139\n%1342 = OpFAdd %43 %1331 %1339\n%1343 = OpConvertFToS %83 %1341\n%1344 = OpConvertFToS %83 %1342\n%1345 = OpINotEqual %82 %1343 %1344\n%1346 = OpCompositeExtract %80 %1345 0\n%1347 = OpCompositeExtract %80 %1345 1\n%1348 = OpLogicalAnd %80 %1346 %1347\n%1349 = OpSelect %81 %1346 %148 %127\n%1350 = OpBitwiseOr %81 %91 %1349\n%1351 = OpSelect %81 %1347 %129 %127\n%1352 = OpBitwiseOr %81 %1350 %1351\n%1353 = OpSelect %81 %1348 %153 %127\n%1354 = OpBitwiseOr %81 %1352 %1353\n%1355 = OpSConvert %5 %1354\n%1356 = OpIMul %81 %1308 %129\n%1357 = OpSConvert %5 %1356\n%1358 = OpShiftLeftLogical %5 %1355 %1357\n%1359 = OpCompositeConstruct %787 %1343 %1295\n%1360 = OpLoad %80 %2192\n%1361 = OpLogicalNot %80 %1360\n%1362 = OpFunctionCall %1 %856 %27 %1359 %1358 %1361\n%1364 = OpImageQuerySizeLod %787 %1292 %1310\n%1365 = OpVectorShuffle %83 %1364 %1364 0 1\n%1363 = OpConvertSToF %43 %1365\n%1366 = OpSNegate %83 %1299\n%1367 = OpExtInst %43 %79 Ldexp %1363 %1366\n%1368 = OpFMul %43 %1325 %1367\n%1369 = OpFMul %43 %1324 %1363\n%1370 = OpFSub %43 %1369 %122\n%1371 = OpExtInst %123 %79 FrexpStruct %1370\n%1372 = OpCompositeExtract %83 %1371 1\n%1373 = OpExtInst %83 %79 SClamp %1372 %128 %130\n%1374 = OpIAdd %83 %1373 %1366\n%1375 = OpExtInst %43 %79 Ldexp %134 %1374\n%1376 = OpExtInst %43 %79 FMin %1375 %134\n%1377 = OpFSub %43 %1368 %1376\n%1378 = OpExtInst %43 %79 FMax %1377 %139\n%1379 = OpFAdd %43 %1368 %1376\n%1380 = OpConvertFToS %83 %1378\n%1381 = OpConvertFToS %83 %1379\n%1382 = OpINotEqual %82 %1380 %1381\n%1383 = OpCompositeExtract %80 %1382 0\n%1384 = OpCompositeExtract %80 %1382 1\n%1385 = OpLogicalAnd %80 %1383 %1384\n%1386 = OpSelect %81 %1383 %148 %127\n%1387 = OpBitwiseOr %81 %91 %1386\n%1388 = OpSelect %81 %1384 %129 %127\n%1389 = OpBitwiseOr %81 %1387 %1388\n%1390 = OpSelect %81 %1385 %153 %127\n%1391 = OpBitwiseOr %81 %1389 %1390\n%1392 = OpSConvert %5 %1391\n%1393 = OpIMul %81 %1310 %129\n%1394 = OpSConvert %5 %1393\n%1395 = OpShiftLeftLogical %5 %1392 %1394\n%1396 = OpCompositeConstruct %787 %1380 %1295\n%1397 = OpLoad %80 %2192\n%1398 = OpLogicalNot %80 %1397\n%1399 = OpLogicalAnd %80 %1398 %1312\n%1400 = OpFunctionCall %1 %856 %27 %1396 %1395 %1399\n%1401 = OpLoad %25 %27\n%1402 = OpLoad %14 %16\n%1403 = OpLoad %34 %36\n%1404 = OpExtInst %10 %79 RoundEven %70\n%1405 = OpConvertFToS %81 %1404\n%1406 = OpCompositeConstruct %43 %65 %67\n%1407 = OpImageQuerySize %787 %1401\n%1408 = OpVectorShuffle %83 %1407 %1407 0 1\n%1409 = OpBitwiseAnd %83 %1408 %88\n%1410 = OpImageQueryLevels %81 %1402\n%1411 = OpISub %81 %1410 %91\n%1412 = OpSampledImage %793 %1402 %1403\n%1413 = OpExtInst %10 %79 Exp2 %74\n%1414 = OpGroupNonUniformQuadBroadcast %10 %72 %1413 %55\n%1415 = OpVectorTimesScalar %43 %1406 %1414\n%1416 = OpImageQueryLod %43 %1412 %1415\n%1417 = OpCompositeExtract %10 %1416 0\n%1418 = OpExtInst %10 %79 FMax %1417 %53\n%1419 = OpExtInst %10 %79 FMin %1418 %241\n%1420 = OpConvertFToS %81 %1419\n%1421 = OpFAdd %10 %1419 %98\n%1422 = OpConvertFToS %81 %1421\n%1423 = OpExtInst %81 %79 SMin %1422 %1411\n%1424 = OpINotEqual %80 %1420 %1422\n%1425 = OpDPdx %43 %1406\n%1426 = OpDPdy %43 %1406\n%1427 = OpExtInst %43 %79 FAbs %1425\n%1428 = OpExtInst %43 %79 FAbs %1426\n%1429 = OpCompositeExtract %10 %1427 0\n%1430 = OpCompositeExtract %10 %1428 0\n%1431 = OpCompositeExtract %10 %1427 1\n%1432 = OpCompositeExtract %10 %1428 1\n%1433 = OpExtInst %10 %79 FMax %1429 %1430\n%1434 = OpExtInst %10 %79 FMax %1431 %1432\n%1435 = OpCompositeConstruct %43 %1433 %1434\n%1436 = OpVectorTimesScalar %43 %1435 %1413\n%1437 = OpExtInst %43 %79 Fract %1406\n%1439 = OpImageQuerySizeLod %787 %1402 %1420\n%1440 = OpVectorShuffle %83 %1439 %1439 0 1\n%1438 = OpConvertSToF %43 %1440\n%1441 = OpSNegate %83 %1409\n%1442 = OpExtInst %43 %79 Ldexp %1438 %1441\n%1443 = OpFMul %43 %1437 %1442\n%1444 = OpFMul %43 %1436 %1438\n%1445 = OpFSub %43 %1444 %122\n%1446 = OpExtInst %123 %79 FrexpStruct %1445\n%1447 = OpCompositeExtract %83 %1446 1\n%1448 = OpExtInst %83 %79 SClamp %1447 %128 %130\n%1449 = OpIAdd %83 %1448 %1441\n%1450 = OpExtInst %43 %79 Ldexp %134 %1449\n%1451 = OpExtInst %43 %79 FMin %1450 %134\n%1452 = OpFSub %43 %1443 %1451\n%1453 = OpExtInst %43 %79 FMax %1452 %139\n%1454 = OpFAdd %43 %1443 %1451\n%1455 = OpConvertFToS %83 %1453\n%1456 = OpConvertFToS %83 %1454\n%1457 = OpINotEqual %82 %1455 %1456\n%1458 = OpCompositeExtract %80 %1457 0\n%1459 = OpCompositeExtract %80 %1457 1\n%1460 = OpLogicalAnd %80 %1458 %1459\n%1461 = OpSelect %81 %1458 %148 %127\n%1462 = OpBitwiseOr %81 %91 %1461\n%1463 = OpSelect %81 %1459 %129 %127\n%1464 = OpBitwiseOr %81 %1462 %1463\n%1465 = OpSelect %81 %1460 %153 %127\n%1466 = OpBitwiseOr %81 %1464 %1465\n%1467 = OpSConvert %5 %1466\n%1468 = OpIMul %81 %1420 %129\n%1469 = OpSConvert %5 %1468\n%1470 = OpShiftLeftLogical %5 %1467 %1469\n%1471 = OpCompositeConstruct %787 %1455 %1405\n%1472 = OpLoad %80 %2192\n%1473 = OpLogicalNot %80 %1472\n%1474 = OpFunctionCall %1 %856 %27 %1471 %1470 %1473\n%1476 = OpImageQuerySizeLod %787 %1402 %1422\n%1477 = OpVectorShuffle %83 %1476 %1476 0 1\n%1475 = OpConvertSToF %43 %1477\n%1478 = OpSNegate %83 %1409\n%1479 = OpExtInst %43 %79 Ldexp %1475 %1478\n%1480 = OpFMul %43 %1437 %1479\n%1481 = OpFMul %43 %1436 %1475\n%1482 = OpFSub %43 %1481 %122\n%1483 = OpExtInst %123 %79 FrexpStruct %1482\n%1484 = OpCompositeExtract %83 %1483 1\n%1485 = OpExtInst %83 %79 SClamp %1484 %128 %130\n%1486 = OpIAdd %83 %1485 %1478\n%1487 = OpExtInst %43 %79 Ldexp %134 %1486\n%1488 = OpExtInst %43 %79 FMin %1487 %134\n%1489 = OpFSub %43 %1480 %1488\n%1490 = OpExtInst %43 %79 FMax %1489 %139\n%1491 = OpFAdd %43 %1480 %1488\n%1492 = OpConvertFToS %83 %1490\n%1493 = OpConvertFToS %83 %1491\n%1494 = OpINotEqual %82 %1492 %1493\n%1495 = OpCompositeExtract %80 %1494 0\n%1496 = OpCompositeExtract %80 %1494 1\n%1497 = OpLogicalAnd %80 %1495 %1496\n%1498 = OpSelect %81 %1495 %148 %127\n%1499 = OpBitwiseOr %81 %91 %1498\n%1500 = OpSelect %81 %1496 %129 %127\n%1501 = OpBitwiseOr %81 %1499 %1500\n%1502 = OpSelect %81 %1497 %153 %127\n%1503 = OpBitwiseOr %81 %1501 %1502\n%1504 = OpSConvert %5 %1503\n%1505 = OpIMul %81 %1422 %129\n%1506 = OpSConvert %5 %1505\n%1507 = OpShiftLeftLogical %5 %1504 %1506\n%1508 = OpCompositeConstruct %787 %1492 %1405\n%1509 = OpLoad %80 %2192\n%1510 = OpLogicalNot %80 %1509\n%1511 = OpLogicalAnd %80 %1510 %1424\n%1512 = OpFunctionCall %1 %856 %27 %1508 %1507 %1511\n%1513 = OpIAdd %49 %52 %55\n%1514 = OpAccessChain %23 %30 %1513\n%1515 = OpLoad %6 %1514\n%1516 = OpIAdd %49 %52 %55\n%1517 = OpAccessChain %12 %19 %1516\n%1518 = OpLoad %11 %1517\n%1519 = OpIAdd %49 %52 %55\n%1520 = OpAccessChain %35 %39 %1519\n%1521 = OpLoad %34 %1520\n%1522 = OpCompositeConstruct %43 %65 %67\n%1523 = OpImageQuerySize %83 %1515\n%1524 = OpBitwiseAnd %83 %1523 %88\n%1525 = OpImageQueryLevels %81 %1518\n%1526 = OpISub %81 %1525 %91\n%1527 = OpSampledImage %92 %1518 %1521\n%1528 = OpImageQueryLod %43 %1527 %1522\n%1529 = OpCompositeExtract %10 %1528 0\n%1530 = OpConvertFToS %81 %1529\n%1531 = OpFAdd %10 %1529 %98\n%1532 = OpConvertFToS %81 %1531\n%1533 = OpExtInst %81 %79 SMin %1532 %1526\n%1534 = OpINotEqual %80 %1530 %1532\n%1535 = OpDPdx %43 %1522\n%1536 = OpDPdy %43 %1522\n%1537 = OpExtInst %43 %79 FAbs %1535\n%1538 = OpExtInst %43 %79 FAbs %1536\n%1539 = OpCompositeExtract %10 %1537 0\n%1540 = OpCompositeExtract %10 %1538 0\n%1541 = OpCompositeExtract %10 %1537 1\n%1542 = OpCompositeExtract %10 %1538 1\n%1543 = OpExtInst %10 %79 FMax %1539 %1540\n%1544 = OpExtInst %10 %79 FMax %1541 %1542\n%1545 = OpCompositeConstruct %43 %1543 %1544\n%1546 = OpExtInst %43 %79 Fract %1522\n%1548 = OpImageQuerySizeLod %83 %1518 %1530\n%1547 = OpConvertSToF %43 %1548\n%1549 = OpSNegate %83 %1524\n%1550 = OpExtInst %43 %79 Ldexp %1547 %1549\n%1551 = OpFMul %43 %1546 %1550\n%1552 = OpFMul %43 %1545 %1547\n%1553 = OpFSub %43 %1552 %122\n%1554 = OpExtInst %123 %79 FrexpStruct %1553\n%1555 = OpCompositeExtract %83 %1554 1\n%1556 = OpExtInst %83 %79 SClamp %1555 %128 %130\n%1557 = OpIAdd %83 %1556 %1549\n%1558 = OpExtInst %43 %79 Ldexp %134 %1557\n%1559 = OpExtInst %43 %79 FMin %1558 %134\n%1560 = OpFSub %43 %1551 %1559\n%1561 = OpExtInst %43 %79 FMax %1560 %139\n%1562 = OpFAdd %43 %1551 %1559\n%1563 = OpConvertFToS %83 %1561\n%1564 = OpConvertFToS %83 %1562\n%1565 = OpINotEqual %82 %1563 %1564\n%1566 = OpCompositeExtract %80 %1565 0\n%1567 = OpCompositeExtract %80 %1565 1\n%1568 = OpLogicalAnd %80 %1566 %1567\n%1569 = OpSelect %81 %1566 %148 %127\n%1570 = OpBitwiseOr %81 %91 %1569\n%1571 = OpSelect %81 %1567 %129 %127\n%1572 = OpBitwiseOr %81 %1570 %1571\n%1573 = OpSelect %81 %1568 %153 %127\n%1574 = OpBitwiseOr %81 %1572 %1573\n%1575 = OpSConvert %5 %1574\n%1576 = OpIMul %81 %1530 %129\n%1577 = OpSConvert %5 %1576\n%1578 = OpShiftLeftLogical %5 %1575 %1577\n%1579 = OpLoad %80 %2192\n%1580 = OpLogicalNot %80 %1579\n%1607 = OpFunctionCall %1 %1585 %1514 %1563 %1578 %1580\n%1609 = OpImageQuerySizeLod %83 %1518 %1532\n%1608 = OpConvertSToF %43 %1609\n%1610 = OpSNegate %83 %1524\n%1611 = OpExtInst %43 %79 Ldexp %1608 %1610\n%1612 = OpFMul %43 %1546 %1611\n%1613 = OpFMul %43 %1545 %1608\n%1614 = OpFSub %43 %1613 %122\n%1615 = OpExtInst %123 %79 FrexpStruct %1614\n%1616 = OpCompositeExtract %83 %1615 1\n%1617 = OpExtInst %83 %79 SClamp %1616 %128 %130\n%1618 = OpIAdd %83 %1617 %1610\n%1619 = OpExtInst %43 %79 Ldexp %134 %1618\n%1620 = OpExtInst %43 %79 FMin %1619 %134\n%1621 = OpFSub %43 %1612 %1620\n%1622 = OpExtInst %43 %79 FMax %1621 %139\n%1623 = OpFAdd %43 %1612 %1620\n%1624 = OpConvertFToS %83 %1622\n%1625 = OpConvertFToS %83 %1623\n%1626 = OpINotEqual %82 %1624 %1625\n%1627 = OpCompositeExtract %80 %1626 0\n%1628 = OpCompositeExtract %80 %1626 1\n%1629 = OpLogicalAnd %80 %1627 %1628\n%1630 = OpSelect %81 %1627 %148 %127\n%1631 = OpBitwiseOr %81 %91 %1630\n%1632 = OpSelect %81 %1628 %129 %127\n%1633 = OpBitwiseOr %81 %1631 %1632\n%1634 = OpSelect %81 %1629 %153 %127\n%1635 = OpBitwiseOr %81 %1633 %1634\n%1636 = OpSConvert %5 %1635\n%1637 = OpIMul %81 %1532 %129\n%1638 = OpSConvert %5 %1637\n%1639 = OpShiftLeftLogical %5 %1636 %1638\n%1640 = OpLoad %80 %2192\n%1641 = OpLogicalNot %80 %1640\n%1642 = OpLogicalAnd %80 %1641 %1534\n%1643 = OpFunctionCall %1 %1585 %1514 %1624 %1639 %1642\n%1644 = OpIAdd %49 %52 %55\n%1645 = OpAccessChain %26 %33 %1644\n%1646 = OpLoad %25 %1645\n%1647 = OpIAdd %49 %52 %55\n%1648 = OpAccessChain %15 %22 %1647\n%1649 = OpLoad %14 %1648\n%1650 = OpAccessChain %35 %39 %1519\n%1651 = OpLoad %34 %1650\n%1652 = OpExtInst %10 %79 RoundEven %70\n%1653 = OpConvertFToS %81 %1652\n%1654 = OpCompositeConstruct %43 %65 %67\n%1655 = OpImageQuerySize %787 %1646\n%1656 = OpVectorShuffle %83 %1655 %1655 0 1\n%1657 = OpBitwiseAnd %83 %1656 %88\n%1658 = OpImageQueryLevels %81 %1649\n%1659 = OpISub %81 %1658 %91\n%1660 = OpSampledImage %793 %1649 %1651\n%1661 = OpImageQueryLod %43 %1660 %1654\n%1662 = OpCompositeExtract %10 %1661 0\n%1663 = OpConvertFToS %81 %1662\n%1664 = OpFAdd %10 %1662 %98\n%1665 = OpConvertFToS %81 %1664\n%1666 = OpExtInst %81 %79 SMin %1665 %1659\n%1667 = OpINotEqual %80 %1663 %1665\n%1668 = OpDPdx %43 %1654\n%1669 = OpDPdy %43 %1654\n%1670 = OpExtInst %43 %79 FAbs %1668\n%1671 = OpExtInst %43 %79 FAbs %1669\n%1672 = OpCompositeExtract %10 %1670 0\n%1673 = OpCompositeExtract %10 %1671 0\n%1674 = OpCompositeExtract %10 %1670 1\n%1675 = OpCompositeExtract %10 %1671 1\n%1676 = OpExtInst %10 %79 FMax %1672 %1673\n%1677 = OpExtInst %10 %79 FMax %1674 %1675\n%1678 = OpCompositeConstruct %43 %1676 %1677\n%1679 = OpExtInst %43 %79 Fract %1654\n%1681 = OpImageQuerySizeLod %787 %1649 %1663\n%1682 = OpVectorShuffle %83 %1681 %1681 0 1\n%1680 = OpConvertSToF %43 %1682\n%1683 = OpSNegate %83 %1657\n%1684 = OpExtInst %43 %79 Ldexp %1680 %1683\n%1685 = OpFMul %43 %1679 %1684\n%1686 = OpFMul %43 %1678 %1680\n%1687 = OpFSub %43 %1686 %122\n%1688 = OpExtInst %123 %79 FrexpStruct %1687\n%1689 = OpCompositeExtract %83 %1688 1\n%1690 = OpExtInst %83 %79 SClamp %1689 %128 %130\n%1691 = OpIAdd %83 %1690 %1683\n%1692 = OpExtInst %43 %79 Ldexp %134 %1691\n%1693 = OpExtInst %43 %79 FMin %1692 %134\n%1694 = OpFSub %43 %1685 %1693\n%1695 = OpExtInst %43 %79 FMax %1694 %139\n%1696 = OpFAdd %43 %1685 %1693\n%1697 = OpConvertFToS %83 %1695\n%1698 = OpConvertFToS %83 %1696\n%1699 = OpINotEqual %82 %1697 %1698\n%1700 = OpCompositeExtract %80 %1699 0\n%1701 = OpCompositeExtract %80 %1699 1\n%1702 = OpLogicalAnd %80 %1700 %1701\n%1703 = OpSelect %81 %1700 %148 %127\n%1704 = OpBitwiseOr %81 %91 %1703\n%1705 = OpSelect %81 %1701 %129 %127\n%1706 = OpBitwiseOr %81 %1704 %1705\n%1707 = OpSelect %81 %1702 %153 %127\n%1708 = OpBitwiseOr %81 %1706 %1707\n%1709 = OpSConvert %5 %1708\n%1710 = OpIMul %81 %1663 %129\n%1711 = OpSConvert %5 %1710\n%1712 = OpShiftLeftLogical %5 %1709 %1711\n%1713 = OpCompositeConstruct %787 %1697 %1653\n%1714 = OpLoad %80 %2192\n%1715 = OpLogicalNot %80 %1714\n%1742 = OpFunctionCall %1 %1720 %1645 %1713 %1712 %1715\n%1744 = OpImageQuerySizeLod %787 %1649 %1665\n%1745 = OpVectorShuffle %83 %1744 %1744 0 1\n%1743 = OpConvertSToF %43 %1745\n%1746 = OpSNegate %83 %1657\n%1747 = OpExtInst %43 %79 Ldexp %1743 %1746\n%1748 = OpFMul %43 %1679 %1747\n%1749 = OpFMul %43 %1678 %1743\n%1750 = OpFSub %43 %1749 %122\n%1751 = OpExtInst %123 %79 FrexpStruct %1750\n%1752 = OpCompositeExtract %83 %1751 1\n%1753 = OpExtInst %83 %79 SClamp %1752 %128 %130\n%1754 = OpIAdd %83 %1753 %1746\n%1755 = OpExtInst %43 %79 Ldexp %134 %1754\n%1756 = OpExtInst %43 %79 FMin %1755 %134\n%1757 = OpFSub %43 %1748 %1756\n%1758 = OpExtInst %43 %79 FMax %1757 %139\n%1759 = OpFAdd %43 %1748 %1756\n%1760 = OpConvertFToS %83 %1758\n%1761 = OpConvertFToS %83 %1759\n%1762 = OpINotEqual %82 %1760 %1761\n%1763 = OpCompositeExtract %80 %1762 0\n%1764 = OpCompositeExtract %80 %1762 1\n%1765 = OpLogicalAnd %80 %1763 %1764\n%1766 = OpSelect %81 %1763 %148 %127\n%1767 = OpBitwiseOr %81 %91 %1766\n%1768 = OpSelect %81 %1764 %129 %127\n%1769 = OpBitwiseOr %81 %1767 %1768\n%1770 = OpSelect %81 %1765 %153 %127\n%1771 = OpBitwiseOr %81 %1769 %1770\n%1772 = OpSConvert %5 %1771\n%1773 = OpIMul %81 %1665 %129\n%1774 = OpSConvert %5 %1773\n%1775 = OpShiftLeftLogical %5 %1772 %1774\n%1776 = OpCompositeConstruct %787 %1760 %1653\n%1777 = OpLoad %80 %2192\n%1778 = OpLogicalNot %80 %1777\n%1779 = OpLogicalAnd %80 %1778 %1667\n%1780 = OpFunctionCall %1 %1720 %1645 %1776 %1775 %1779\n%1781 = OpAccessChain %23 %30 %1513\n%1782 = OpLoad %6 %1781\n%1783 = OpAccessChain %12 %19 %1516\n%1784 = OpLoad %11 %1783\n%1785 = OpAccessChain %35 %39 %1519\n%1786 = OpLoad %34 %1785\n%1787 = OpCompositeConstruct %43 %65 %67\n%1788 = OpImageQuerySize %83 %1782\n%1789 = OpBitwiseAnd %83 %1788 %88\n%1790 = OpImageQueryLevels %81 %1784\n%1791 = OpISub %81 %1790 %91\n%1792 = OpSampledImage %92 %1784 %1786\n%1793 = OpImageQueryLod %43 %1792 %1787\n%1794 = OpCompositeExtract %10 %1793 0\n%1795 = OpConvertFToS %81 %1794\n%1796 = OpFAdd %10 %1794 %98\n%1797 = OpConvertFToS %81 %1796\n%1798 = OpExtInst %81 %79 SMin %1797 %1791\n%1799 = OpINotEqual %80 %1795 %1797\n%1800 = OpDPdx %43 %1787\n%1801 = OpDPdy %43 %1787\n%1802 = OpExtInst %43 %79 FAbs %1800\n%1803 = OpExtInst %43 %79 FAbs %1801\n%1804 = OpCompositeExtract %10 %1802 0\n%1805 = OpCompositeExtract %10 %1803 0\n%1806 = OpCompositeExtract %10 %1802 1\n%1807 = OpCompositeExtract %10 %1803 1\n%1808 = OpExtInst %10 %79 FMax %1804 %1805\n%1809 = OpExtInst %10 %79 FMax %1806 %1807\n%1810 = OpCompositeConstruct %43 %1808 %1809\n%1811 = OpExtInst %43 %79 Fract %1787\n%1813 = OpImageQuerySizeLod %83 %1784 %1795\n%1812 = OpConvertSToF %43 %1813\n%1814 = OpSNegate %83 %1789\n%1815 = OpExtInst %43 %79 Ldexp %1812 %1814\n%1816 = OpFMul %43 %1811 %1815\n%1817 = OpFMul %43 %1810 %1812\n%1818 = OpFSub %43 %1817 %122\n%1819 = OpExtInst %123 %79 FrexpStruct %1818\n%1820 = OpCompositeExtract %83 %1819 1\n%1821 = OpExtInst %83 %79 SClamp %1820 %128 %130\n%1822 = OpIAdd %83 %1821 %1814\n%1823 = OpExtInst %43 %79 Ldexp %134 %1822\n%1824 = OpExtInst %43 %79 FMin %1823 %134\n%1825 = OpFSub %43 %1816 %1824\n%1826 = OpExtInst %43 %79 FMax %1825 %139\n%1827 = OpFAdd %43 %1816 %1824\n%1828 = OpConvertFToS %83 %1826\n%1829 = OpConvertFToS %83 %1827\n%1830 = OpINotEqual %82 %1828 %1829\n%1831 = OpCompositeExtract %80 %1830 0\n%1832 = OpCompositeExtract %80 %1830 1\n%1833 = OpLogicalAnd %80 %1831 %1832\n%1834 = OpSelect %81 %1831 %148 %127\n%1835 = OpBitwiseOr %81 %91 %1834\n%1836 = OpSelect %81 %1832 %129 %127\n%1837 = OpBitwiseOr %81 %1835 %1836\n%1838 = OpSelect %81 %1833 %153 %127\n%1839 = OpBitwiseOr %81 %1837 %1838\n%1840 = OpSConvert %5 %1839\n%1841 = OpIMul %81 %1795 %129\n%1842 = OpSConvert %5 %1841\n%1843 = OpShiftLeftLogical %5 %1840 %1842\n%1844 = OpLoad %80 %2192\n%1845 = OpLogicalNot %80 %1844\n%1846 = OpFunctionCall %1 %1585 %1781 %1828 %1843 %1845\n%1848 = OpImageQuerySizeLod %83 %1784 %1797\n%1847 = OpConvertSToF %43 %1848\n%1849 = OpSNegate %83 %1789\n%1850 = OpExtInst %43 %79 Ldexp %1847 %1849\n%1851 = OpFMul %43 %1811 %1850\n%1852 = OpFMul %43 %1810 %1847\n%1853 = OpFSub %43 %1852 %122\n%1854 = OpExtInst %123 %79 FrexpStruct %1853\n%1855 = OpCompositeExtract %83 %1854 1\n%1856 = OpExtInst %83 %79 SClamp %1855 %128 %130\n%1857 = OpIAdd %83 %1856 %1849\n%1858 = OpExtInst %43 %79 Ldexp %134 %1857\n%1859 = OpExtInst %43 %79 FMin %1858 %134\n%1860 = OpFSub %43 %1851 %1859\n%1861 = OpExtInst %43 %79 FMax %1860 %139\n%1862 = OpFAdd %43 %1851 %1859\n%1863 = OpConvertFToS %83 %1861\n%1864 = OpConvertFToS %83 %1862\n%1865 = OpINotEqual %82 %1863 %1864\n%1866 = OpCompositeExtract %80 %1865 0\n%1867 = OpCompositeExtract %80 %1865 1\n%1868 = OpLogicalAnd %80 %1866 %1867\n%1869 = OpSelect %81 %1866 %148 %127\n%1870 = OpBitwiseOr %81 %91 %1869\n%1871 = OpSelect %81 %1867 %129 %127\n%1872 = OpBitwiseOr %81 %1870 %1871\n%1873 = OpSelect %81 %1868 %153 %127\n%1874 = OpBitwiseOr %81 %1872 %1873\n%1875 = OpSConvert %5 %1874\n%1876 = OpIMul %81 %1797 %129\n%1877 = OpSConvert %5 %1876\n%1878 = OpShiftLeftLogical %5 %1875 %1877\n%1879 = OpLoad %80 %2192\n%1880 = OpLogicalNot %80 %1879\n%1881 = OpLogicalAnd %80 %1880 %1799\n%1882 = OpFunctionCall %1 %1585 %1781 %1863 %1878 %1881\n%1883 = OpAccessChain %26 %33 %1644\n%1884 = OpLoad %25 %1883\n%1885 = OpAccessChain %15 %22 %1647\n%1886 = OpLoad %14 %1885\n%1887 = OpAccessChain %35 %39 %1519\n%1888 = OpLoad %34 %1887\n%1889 = OpExtInst %10 %79 RoundEven %70\n%1890 = OpConvertFToS %81 %1889\n%1891 = OpCompositeConstruct %43 %65 %67\n%1892 = OpImageQuerySize %787 %1884\n%1893 = OpVectorShuffle %83 %1892 %1892 0 1\n%1894 = OpBitwiseAnd %83 %1893 %88\n%1895 = OpImageQueryLevels %81 %1886\n%1896 = OpISub %81 %1895 %91\n%1897 = OpSampledImage %793 %1886 %1888\n%1898 = OpImageQueryLod %43 %1897 %1891\n%1899 = OpCompositeExtract %10 %1898 0\n%1900 = OpConvertFToS %81 %1899\n%1901 = OpFAdd %10 %1899 %98\n%1902 = OpConvertFToS %81 %1901\n%1903 = OpExtInst %81 %79 SMin %1902 %1896\n%1904 = OpINotEqual %80 %1900 %1902\n%1905 = OpDPdx %43 %1891\n%1906 = OpDPdy %43 %1891\n%1907 = OpExtInst %43 %79 FAbs %1905\n%1908 = OpExtInst %43 %79 FAbs %1906\n%1909 = OpCompositeExtract %10 %1907 0\n%1910 = OpCompositeExtract %10 %1908 0\n%1911 = OpCompositeExtract %10 %1907 1\n%1912 = OpCompositeExtract %10 %1908 1\n%1913 = OpExtInst %10 %79 FMax %1909 %1910\n%1914 = OpExtInst %10 %79 FMax %1911 %1912\n%1915 = OpCompositeConstruct %43 %1913 %1914\n%1916 = OpExtInst %43 %79 Fract %1891\n%1918 = OpImageQuerySizeLod %787 %1886 %1900\n%1919 = OpVectorShuffle %83 %1918 %1918 0 1\n%1917 = OpConvertSToF %43 %1919\n%1920 = OpSNegate %83 %1894\n%1921 = OpExtInst %43 %79 Ldexp %1917 %1920\n%1922 = OpFMul %43 %1916 %1921\n%1923 = OpFMul %43 %1915 %1917\n%1924 = OpFSub %43 %1923 %122\n%1925 = OpExtInst %123 %79 FrexpStruct %1924\n%1926 = OpCompositeExtract %83 %1925 1\n%1927 = OpExtInst %83 %79 SClamp %1926 %128 %130\n%1928 = OpIAdd %83 %1927 %1920\n%1929 = OpExtInst %43 %79 Ldexp %134 %1928\n%1930 = OpExtInst %43 %79 FMin %1929 %134\n%1931 = OpFSub %43 %1922 %1930\n%1932 = OpExtInst %43 %79 FMax %1931 %139\n%1933 = OpFAdd %43 %1922 %1930\n%1934 = OpConvertFToS %83 %1932\n%1935 = OpConvertFToS %83 %1933\n%1936 = OpINotEqual %82 %1934 %1935\n%1937 = OpCompositeExtract %80 %1936 0\n%1938 = OpCompositeExtract %80 %1936 1\n%1939 = OpLogicalAnd %80 %1937 %1938\n%1940 = OpSelect %81 %1937 %148 %127\n%1941 = OpBitwiseOr %81 %91 %1940\n%1942 = OpSelect %81 %1938 %129 %127\n%1943 = OpBitwiseOr %81 %1941 %1942\n%1944 = OpSelect %81 %1939 %153 %127\n%1945 = OpBitwiseOr %81 %1943 %1944\n%1946 = OpSConvert %5 %1945\n%1947 = OpIMul %81 %1900 %129\n%1948 = OpSConvert %5 %1947\n%1949 = OpShiftLeftLogical %5 %1946 %1948\n%1950 = OpCompositeConstruct %787 %1934 %1890\n%1951 = OpLoad %80 %2192\n%1952 = OpLogicalNot %80 %1951\n%1953 = OpFunctionCall %1 %1720 %1883 %1950 %1949 %1952\n%1955 = OpImageQuerySizeLod %787 %1886 %1902\n%1956 = OpVectorShuffle %83 %1955 %1955 0 1\n%1954 = OpConvertSToF %43 %1956\n%1957 = OpSNegate %83 %1894\n%1958 = OpExtInst %43 %79 Ldexp %1954 %1957\n%1959 = OpFMul %43 %1916 %1958\n%1960 = OpFMul %43 %1915 %1954\n%1961 = OpFSub %43 %1960 %122\n%1962 = OpExtInst %123 %79 FrexpStruct %1961\n%1963 = OpCompositeExtract %83 %1962 1\n%1964 = OpExtInst %83 %79 SClamp %1963 %128 %130\n%1965 = OpIAdd %83 %1964 %1957\n%1966 = OpExtInst %43 %79 Ldexp %134 %1965\n%1967 = OpExtInst %43 %79 FMin %1966 %134\n%1968 = OpFSub %43 %1959 %1967\n%1969 = OpExtInst %43 %79 FMax %1968 %139\n%1970 = OpFAdd %43 %1959 %1967\n%1971 = OpConvertFToS %83 %1969\n%1972 = OpConvertFToS %83 %1970\n%1973 = OpINotEqual %82 %1971 %1972\n%1974 = OpCompositeExtract %80 %1973 0\n%1975 = OpCompositeExtract %80 %1973 1\n%1976 = OpLogicalAnd %80 %1974 %1975\n%1977 = OpSelect %81 %1974 %148 %127\n%1978 = OpBitwiseOr %81 %91 %1977\n%1979 = OpSelect %81 %1975 %129 %127\n%1980 = OpBitwiseOr %81 %1978 %1979\n%1981 = OpSelect %81 %1976 %153 %127\n%1982 = OpBitwiseOr %81 %1980 %1981\n%1983 = OpSConvert %5 %1982\n%1984 = OpIMul %81 %1902 %129\n%1985 = OpSConvert %5 %1984\n%1986 = OpShiftLeftLogical %5 %1983 %1985\n%1987 = OpCompositeConstruct %787 %1971 %1890\n%1988 = OpLoad %80 %2192\n%1989 = OpLogicalNot %80 %1988\n%1990 = OpLogicalAnd %80 %1989 %1904\n%1991 = OpFunctionCall %1 %1720 %1883 %1987 %1986 %1990\n%1992 = OpAccessChain %23 %9 %52\n%1993 = OpLoad %6 %1992\n%1994 = OpLoad %11 %13\n%1995 = OpLoad %34 %36\n%1996 = OpCompositeConstruct %43 %65 %67\n%1997 = OpImageQuerySize %83 %1993\n%1998 = OpBitwiseAnd %83 %1997 %88\n%1999 = OpImageQueryLevels %81 %1994\n%2000 = OpISub %81 %1999 %91\n%2001 = OpSampledImage %92 %1994 %1995\n%2002 = OpImageQueryLod %43 %2001 %1996\n%2003 = OpCompositeExtract %10 %2002 0\n%2004 = OpConvertFToS %81 %2003\n%2005 = OpFAdd %10 %2003 %98\n%2006 = OpConvertFToS %81 %2005\n%2007 = OpExtInst %81 %79 SMin %2006 %2000\n%2008 = OpINotEqual %80 %2004 %2006\n%2009 = OpDPdx %43 %1996\n%2010 = OpDPdy %43 %1996\n%2011 = OpExtInst %43 %79 FAbs %2009\n%2012 = OpExtInst %43 %79 FAbs %2010\n%2013 = OpCompositeExtract %10 %2011 0\n%2014 = OpCompositeExtract %10 %2012 0\n%2015 = OpCompositeExtract %10 %2011 1\n%2016 = OpCompositeExtract %10 %2012 1\n%2017 = OpExtInst %10 %79 FMax %2013 %2014\n%2018 = OpExtInst %10 %79 FMax %2015 %2016\n%2019 = OpCompositeConstruct %43 %2017 %2018\n%2020 = OpExtInst %43 %79 Fract %1996\n%2022 = OpImageQuerySizeLod %83 %1994 %2004\n%2021 = OpConvertSToF %43 %2022\n%2023 = OpSNegate %83 %1998\n%2024 = OpExtInst %43 %79 Ldexp %2021 %2023\n%2025 = OpFMul %43 %2020 %2024\n%2026 = OpFMul %43 %2019 %2021\n%2027 = OpFSub %43 %2026 %122\n%2028 = OpExtInst %123 %79 FrexpStruct %2027\n%2029 = OpCompositeExtract %83 %2028 1\n%2030 = OpExtInst %83 %79 SClamp %2029 %128 %130\n%2031 = OpIAdd %83 %2030 %2023\n%2032 = OpExtInst %43 %79 Ldexp %134 %2031\n%2033 = OpExtInst %43 %79 FMin %2032 %134\n%2034 = OpFSub %43 %2025 %2033\n%2035 = OpExtInst %43 %79 FMax %2034 %139\n%2036 = OpFAdd %43 %2025 %2033\n%2037 = OpConvertFToS %83 %2035\n%2038 = OpConvertFToS %83 %2036\n%2039 = OpINotEqual %82 %2037 %2038\n%2040 = OpCompositeExtract %80 %2039 0\n%2041 = OpCompositeExtract %80 %2039 1\n%2042 = OpLogicalAnd %80 %2040 %2041\n%2043 = OpSelect %81 %2040 %148 %127\n%2044 = OpBitwiseOr %81 %91 %2043\n%2045 = OpSelect %81 %2041 %129 %127\n%2046 = OpBitwiseOr %81 %2044 %2045\n%2047 = OpSelect %81 %2042 %153 %127\n%2048 = OpBitwiseOr %81 %2046 %2047\n%2049 = OpSConvert %5 %2048\n%2050 = OpIMul %81 %2004 %129\n%2051 = OpSConvert %5 %2050\n%2052 = OpShiftLeftLogical %5 %2049 %2051\n%2053 = OpLoad %80 %2192\n%2054 = OpLogicalNot %80 %2053\n%2055 = OpFunctionCall %1 %1585 %1992 %2037 %2052 %2054\n%2057 = OpImageQuerySizeLod %83 %1994 %2006\n%2056 = OpConvertSToF %43 %2057\n%2058 = OpSNegate %83 %1998\n%2059 = OpExtInst %43 %79 Ldexp %2056 %2058\n%2060 = OpFMul %43 %2020 %2059\n%2061 = OpFMul %43 %2019 %2056\n%2062 = OpFSub %43 %2061 %122\n%2063 = OpExtInst %123 %79 FrexpStruct %2062\n%2064 = OpCompositeExtract %83 %2063 1\n%2065 = OpExtInst %83 %79 SClamp %2064 %128 %130\n%2066 = OpIAdd %83 %2065 %2058\n%2067 = OpExtInst %43 %79 Ldexp %134 %2066\n%2068 = OpExtInst %43 %79 FMin %2067 %134\n%2069 = OpFSub %43 %2060 %2068\n%2070 = OpExtInst %43 %79 FMax %2069 %139\n%2071 = OpFAdd %43 %2060 %2068\n%2072 = OpConvertFToS %83 %2070\n%2073 = OpConvertFToS %83 %2071\n%2074 = OpINotEqual %82 %2072 %2073\n%2075 = OpCompositeExtract %80 %2074 0\n%2076 = OpCompositeExtract %80 %2074 1\n%2077 = OpLogicalAnd %80 %2075 %2076\n%2078 = OpSelect %81 %2075 %148 %127\n%2079 = OpBitwiseOr %81 %91 %2078\n%2080 = OpSelect %81 %2076 %129 %127\n%2081 = OpBitwiseOr %81 %2079 %2080\n%2082 = OpSelect %81 %2077 %153 %127\n%2083 = OpBitwiseOr %81 %2081 %2082\n%2084 = OpSConvert %5 %2083\n%2085 = OpIMul %81 %2006 %129\n%2086 = OpSConvert %5 %2085\n%2087 = OpShiftLeftLogical %5 %2084 %2086\n%2088 = OpLoad %80 %2192\n%2089 = OpLogicalNot %80 %2088\n%2090 = OpLogicalAnd %80 %2089 %2008\n%2091 = OpFunctionCall %1 %1585 %1992 %2072 %2087 %2090\n%2092 = OpLoad %11 %13\n%2093 = OpLoad %34 %36\n%2094 = OpCompositeConstruct %43 %65 %67\n%2095 = OpImageQuerySize %83 %1993\n%2096 = OpBitwiseAnd %83 %2095 %88\n%2097 = OpImageQueryLevels %81 %2092\n%2098 = OpISub %81 %2097 %91\n%2099 = OpSampledImage %92 %2092 %2093\n%2100 = OpImageQueryLod %43 %2099 %2094\n%2101 = OpCompositeExtract %10 %2100 0\n%2102 = OpConvertFToS %81 %2101\n%2103 = OpFAdd %10 %2101 %98\n%2104 = OpConvertFToS %81 %2103\n%2105 = OpExtInst %81 %79 SMin %2104 %2098\n%2106 = OpINotEqual %80 %2102 %2104\n%2107 = OpDPdx %43 %2094\n%2108 = OpDPdy %43 %2094\n%2109 = OpExtInst %43 %79 FAbs %2107\n%2110 = OpExtInst %43 %79 FAbs %2108\n%2111 = OpCompositeExtract %10 %2109 0\n%2112 = OpCompositeExtract %10 %2110 0\n%2113 = OpCompositeExtract %10 %2109 1\n%2114 = OpCompositeExtract %10 %2110 1\n%2115 = OpExtInst %10 %79 FMax %2111 %2112\n%2116 = OpExtInst %10 %79 FMax %2113 %2114\n%2117 = OpCompositeConstruct %43 %2115 %2116\n%2118 = OpExtInst %43 %79 Fract %2094\n%2120 = OpImageQuerySizeLod %83 %2092 %2102\n%2119 = OpConvertSToF %43 %2120\n%2121 = OpSNegate %83 %2096\n%2122 = OpExtInst %43 %79 Ldexp %2119 %2121\n%2123 = OpFMul %43 %2118 %2122\n%2124 = OpFMul %43 %2117 %2119\n%2125 = OpFSub %43 %2124 %122\n%2126 = OpExtInst %123 %79 FrexpStruct %2125\n%2127 = OpCompositeExtract %83 %2126 1\n%2128 = OpExtInst %83 %79 SClamp %2127 %128 %130\n%2129 = OpIAdd %83 %2128 %2121\n%2130 = OpExtInst %43 %79 Ldexp %134 %2129\n%2131 = OpExtInst %43 %79 FMin %2130 %134\n%2132 = OpFSub %43 %2123 %2131\n%2133 = OpExtInst %43 %79 FMax %2132 %139\n%2134 = OpFAdd %43 %2123 %2131\n%2135 = OpConvertFToS %83 %2133\n%2136 = OpConvertFToS %83 %2134\n%2137 = OpINotEqual %82 %2135 %2136\n%2138 = OpCompositeExtract %80 %2137 0\n%2139 = OpCompositeExtract %80 %2137 1\n%2140 = OpLogicalAnd %80 %2138 %2139\n%2141 = OpSelect %81 %2138 %148 %127\n%2142 = OpBitwiseOr %81 %91 %2141\n%2143 = OpSelect %81 %2139 %129 %127\n%2144 = OpBitwiseOr %81 %2142 %2143\n%2145 = OpSelect %81 %2140 %153 %127\n%2146 = OpBitwiseOr %81 %2144 %2145\n%2147 = OpSConvert %5 %2146\n%2148 = OpIMul %81 %2102 %129\n%2149 = OpSConvert %5 %2148\n%2150 = OpShiftLeftLogical %5 %2147 %2149\n%2151 = OpLoad %80 %2192\n%2152 = OpLogicalNot %80 %2151\n%2153 = OpFunctionCall %1 %1585 %1992 %2135 %2150 %2152\n%2155 = OpImageQuerySizeLod %83 %2092 %2104\n%2154 = OpConvertSToF %43 %2155\n%2156 = OpSNegate %83 %2096\n%2157 = OpExtInst %43 %79 Ldexp %2154 %2156\n%2158 = OpFMul %43 %2118 %2157\n%2159 = OpFMul %43 %2117 %2154\n%2160 = OpFSub %43 %2159 %122\n%2161 = OpExtInst %123 %79 FrexpStruct %2160\n%2162 = OpCompositeExtract %83 %2161 1\n%2163 = OpExtInst %83 %79 SClamp %2162 %128 %130\n%2164 = OpIAdd %83 %2163 %2156\n%2165 = OpExtInst %43 %79 Ldexp %134 %2164\n%2166 = OpExtInst %43 %79 FMin %2165 %134\n%2167 = OpFSub %43 %2158 %2166\n%2168 = OpExtInst %43 %79 FMax %2167 %139\n%2169 = OpFAdd %43 %2158 %2166\n%2170 = OpConvertFToS %83 %2168\n%2171 = OpConvertFToS %83 %2169\n%2172 = OpINotEqual %82 %2170 %2171\n%2173 = OpCompositeExtract %80 %2172 0\n%2174 = OpCompositeExtract %80 %2172 1\n%2175 = OpLogicalAnd %80 %2173 %2174\n%2176 = OpSelect %81 %2173 %148 %127\n%2177 = OpBitwiseOr %81 %91 %2176\n%2178 = OpSelect %81 %2174 %129 %127\n%2179 = OpBitwiseOr %81 %2177 %2178\n%2180 = OpSelect %81 %2175 %153 %127\n%2181 = OpBitwiseOr %81 %2179 %2180\n%2182 = OpSConvert %5 %2181\n%2183 = OpIMul %81 %2104 %129\n%2184 = OpSConvert %5 %2183\n%2185 = OpShiftLeftLogical %5 %2182 %2184\n%2186 = OpLoad %80 %2192\n%2187 = OpLogicalNot %80 %2186\n%2188 = OpLogicalAnd %80 %2187 %2106\n%2189 = OpFunctionCall %1 %1585 %1992 %2170 %2185 %2188\nOpReturn\nOpFunctionEnd\n%167 = OpFunction %1 None %162\n%163 = OpFunctionParameter %23\n%164 = OpFunctionParameter %83\n%165 = OpFunctionParameter %5\n%166 = OpFunctionParameter %80\n%168 = OpLabel\n%180 = OpVariable %179 Function %178\nOpSelectionMerge %170 None\nOpBranchConditional %166 %169 %170\n%169 = OpLabel\n%181 = OpLoad %80 %180\n%182 = OpLogicalNot %80 %181\nOpLoopMerge %171 %173 None\nOpBranchConditional %182 %172 %171\n%172 = OpLabel\n%183 = OpGroupNonUniformBroadcastFirst %83 %72 %164\n%184 = OpIEqual %82 %164 %183\n%185 = OpAll %80 %184\nOpStore %180 %185\nOpSelectionMerge %175 None\nOpBranchConditional %185 %174 %175\n%174 = OpLabel\n%186 = OpGroupNonUniformBitwiseOr %5 %72 Reduce %165\n%187 = OpGroupNonUniformElect %80 %72\nOpSelectionMerge %177 None\nOpBranchConditional %187 %176 %177\n%176 = OpLabel\n%188 = OpImageTexelPointer %161 %163 %164 %127\n%189 = OpAtomicOr %5 %188 %58 %55 %186\nOpBranch %177\n%177 = OpLabel\nOpBranch %175\n%175 = OpLabel\nOpBranch %173\n%173 = OpLabel\nOpBranch %169\n%171 = OpLabel\nOpBranch %170\n%170 = OpLabel\nOpReturn\nOpFunctionEnd\n%856 = OpFunction %1 None %851\n%852 = OpFunctionParameter %26\n%853 = OpFunctionParameter %787\n%854 = OpFunctionParameter %5\n%855 = OpFunctionParameter %80\n%857 = OpLabel\n%867 = OpVariable %179 Function %178\nOpSelectionMerge %859 None\nOpBranchConditional %855 %858 %859\n%858 = OpLabel\n%868 = OpLoad %80 %867\n%869 = OpLogicalNot %80 %868\nOpLoopMerge %860 %862 None\nOpBranchConditional %869 %861 %860\n%861 = OpLabel\n%870 = OpGroupNonUniformBroadcastFirst %787 %72 %853\n%871 = OpIEqual %850 %853 %870\n%872 = OpAll %80 %871\nOpStore %867 %872\nOpSelectionMerge %864 None\nOpBranchConditional %872 %863 %864\n%863 = OpLabel\n%873 = OpGroupNonUniformBitwiseOr %5 %72 Reduce %854\n%874 = OpGroupNonUniformElect %80 %72\nOpSelectionMerge %866 None\nOpBranchConditional %874 %865 %866\n%865 = OpLabel\n%875 = OpImageTexelPointer %161 %852 %853 %127\n%876 = OpAtomicOr %5 %875 %58 %55 %873\nOpBranch %866\n%866 = OpLabel\nOpBranch %864\n%864 = OpLabel\nOpBranch %862\n%862 = OpLabel\nOpBranch %858\n%860 = OpLabel\nOpBranch %859\n%859 = OpLabel\nOpReturn\nOpFunctionEnd\n%1585 = OpFunction %1 None %162\n%1581 = OpFunctionParameter %23\n%1582 = OpFunctionParameter %83\n%1583 = OpFunctionParameter %5\n%1584 = OpFunctionParameter %80\n%1586 = OpLabel\n%1596 = OpVariable %179 Function %178\nOpSelectionMerge %1588 None\nOpBranchConditional %1584 %1587 %1588\n%1587 = OpLabel\n%1597 = OpLoad %80 %1596\n%1598 = OpLogicalNot %80 %1597\nOpLoopMerge %1589 %1591 None\nOpBranchConditional %1598 %1590 %1589\n%1590 = OpLabel\n%1599 = OpGroupNonUniformBroadcastFirst %83 %72 %1582\n%1600 = OpIEqual %82 %1582 %1599\n%1601 = OpAll %80 %1600\nOpStore %1596 %1601\nOpSelectionMerge %1593 None\nOpBranchConditional %1601 %1592 %1593\n%1592 = OpLabel\n%1602 = OpGroupNonUniformBitwiseOr %5 %72 Reduce %1583\n%1603 = OpGroupNonUniformElect %80 %72\nOpSelectionMerge %1595 None\nOpBranchConditional %1603 %1594 %1595\n%1594 = OpLabel\n%1604 = OpImageTexelPointer %161 %1581 %1582 %127\n%1605 = OpAtomicOr %5 %1604 %58 %55 %1602\nOpBranch %1595\n%1595 = OpLabel\nOpBranch %1593\n%1593 = OpLabel\nOpBranch %1591\n%1591 = OpLabel\nOpBranch %1587\n%1589 = OpLabel\nOpBranch %1588\n%1588 = OpLabel\nOpReturn\nOpFunctionEnd\n%1720 = OpFunction %1 None %851\n%1716 = OpFunctionParameter %26\n%1717 = OpFunctionParameter %787\n%1718 = OpFunctionParameter %5\n%1719 = OpFunctionParameter %80\n%1721 = OpLabel\n%1731 = OpVariable %179 Function %178\nOpSelectionMerge %1723 None\nOpBranchConditional %1719 %1722 %1723\n%1722 = OpLabel\n%1732 = OpLoad %80 %1731\n%1733 = OpLogicalNot %80 %1732\nOpLoopMerge %1724 %1726 None\nOpBranchConditional %1733 %1725 %1724\n%1725 = OpLabel\n%1734 = OpGroupNonUniformBroadcastFirst %787 %72 %1717\n%1735 = OpIEqual %850 %1717 %1734\n%1736 = OpAll %80 %1735\nOpStore %1731 %1736\nOpSelectionMerge %1728 None\nOpBranchConditional %1736 %1727 %1728\n%1727 = OpLabel\n%1737 = OpGroupNonUniformBitwiseOr %5 %72 Reduce %1718\n%1738 = OpGroupNonUniformElect %80 %72\nOpSelectionMerge %1730 None\nOpBranchConditional %1738 %1729 %1730\n%1729 = OpLabel\n%1739 = OpImageTexelPointer %161 %1716 %1717 %127\n%1740 = OpAtomicOr %5 %1739 %58 %55 %1737\nOpBranch %1730\n%1730 = OpLabel\nOpBranch %1728\n%1728 = OpLabel\nOpBranch %1726\n%1726 = OpLabel\nOpBranch %1722\n%1724 = OpLabel\nOpBranch %1723\n%1723 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-cull-distance.vert",
    "content": "#version 460\n\nout float gl_ClipDistance[4];\nout float gl_CullDistance[4];\n\nlayout(location = 0) in vec4 POS;\nlayout(location = 1) in vec4 CLIP;\nlayout(location = 2) in vec4 CULL;\n\nvoid main()\n{\n    gl_Position.x = POS.x;\n    gl_Position.y = POS.y;\n    gl_Position.z = POS.z;\n    gl_Position.w = POS.w;\n    gl_ClipDistance[0u] = CLIP.x;\n    gl_ClipDistance[1u] = CLIP.y;\n    gl_ClipDistance[2u] = CLIP.z;\n    gl_ClipDistance[3u] = CLIP.w;\n    gl_CullDistance[0u] = CULL.x;\n    gl_CullDistance[1u] = CULL.y;\n    gl_CullDistance[2u] = CULL.z;\n    gl_CullDistance[3u] = CULL.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 63\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpCapability CullDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %9 %10 %12 %17 %18\nOpName %3 \"main\"\nOpName %8 \"POS\"\nOpName %9 \"CLIP\"\nOpName %10 \"CULL\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %10 Location 2\nOpDecorate %12 BuiltIn Position\nOpDecorate %17 BuiltIn ClipDistance\nOpDecorate %18 BuiltIn CullDistance\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpVariable %7 Input\n%11 = OpTypePointer Output %6\n%12 = OpVariable %11 Output\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 4\n%15 = OpTypeArray %5 %14\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%18 = OpVariable %16 Output\n%19 = OpTypePointer Input %5\n%21 = OpConstant %13 0\n%24 = OpConstant %13 1\n%27 = OpConstant %13 2\n%30 = OpConstant %13 3\n%48 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%20 = OpAccessChain %19 %10 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %19 %10 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %19 %10 %27\n%28 = OpLoad %5 %26\n%29 = OpAccessChain %19 %10 %30\n%31 = OpLoad %5 %29\n%32 = OpAccessChain %19 %9 %21\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %19 %9 %24\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %19 %9 %27\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %19 %9 %30\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %19 %8 %21\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %19 %8 %24\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %19 %8 %27\n%45 = OpLoad %5 %44\n%46 = OpAccessChain %19 %8 %30\n%47 = OpLoad %5 %46\n%49 = OpAccessChain %48 %12 %21\nOpStore %49 %41\n%50 = OpAccessChain %48 %12 %24\nOpStore %50 %43\n%51 = OpAccessChain %48 %12 %27\nOpStore %51 %45\n%52 = OpAccessChain %48 %12 %30\nOpStore %52 %47\n%53 = OpAccessChain %48 %17 %21\nOpStore %53 %33\n%54 = OpAccessChain %48 %17 %24\nOpStore %54 %35\n%55 = OpAccessChain %48 %17 %27\nOpStore %55 %37\n%56 = OpAccessChain %48 %17 %30\nOpStore %56 %39\n%57 = OpAccessChain %48 %18 %21\nOpStore %57 %22\n%58 = OpAccessChain %48 %18 %24\nOpStore %58 %25\n%59 = OpAccessChain %48 %18 %27\nOpStore %59 %28\n%60 = OpAccessChain %48 %18 %30\nOpStore %60 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-cull.frag",
    "content": "#version 460\n\nin float gl_ClipDistance[4];\nin float gl_CullDistance[3];\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _37 = gl_CullDistance[0u] + gl_CullDistance[2u];\n    float _39 = gl_CullDistance[1u] + gl_CullDistance[2u];\n    SV_Target.x = gl_ClipDistance[0u] + _37;\n    SV_Target.y = gl_ClipDistance[1u] + _39;\n    SV_Target.z = gl_ClipDistance[2u] + _37;\n    SV_Target.w = _39 + gl_ClipDistance[3u];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 50\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpCapability CullDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %15 %18\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %18 \"SV_Target\"\nOpDecorate %11 BuiltIn ClipDistance\nOpDecorate %15 BuiltIn CullDistance\nOpDecorate %18 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 4\n%9 = OpTypeArray %5 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpConstant %7 3\n%13 = OpTypeArray %5 %12\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%16 = OpTypeVector %5 4\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %5\n%21 = OpConstant %7 2\n%24 = OpConstant %7 0\n%27 = OpConstant %7 1\n%43 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %48\n%48 = OpLabel\n%20 = OpAccessChain %19 %15 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %19 %15 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %19 %15 %27\n%28 = OpLoad %5 %26\n%29 = OpAccessChain %19 %11 %12\n%30 = OpLoad %5 %29\n%31 = OpAccessChain %19 %11 %21\n%32 = OpLoad %5 %31\n%33 = OpAccessChain %19 %11 %24\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %19 %11 %27\n%36 = OpLoad %5 %35\n%37 = OpFAdd %5 %25 %22\n%38 = OpFAdd %5 %34 %37\n%39 = OpFAdd %5 %28 %22\n%40 = OpFAdd %5 %36 %39\n%41 = OpFAdd %5 %32 %37\n%42 = OpFAdd %5 %39 %30\n%44 = OpAccessChain %43 %18 %24\nOpStore %44 %38\n%45 = OpAccessChain %43 %18 %27\nOpStore %45 %40\n%46 = OpAccessChain %43 %18 %21\nOpStore %46 %41\n%47 = OpAccessChain %43 %18 %12\nOpStore %47 %42\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-distance-cols.frag",
    "content": "#version 460\n\nin float gl_ClipDistance[2];\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = gl_ClipDistance[0u];\n    SV_Target.y = gl_ClipDistance[1u];\n    SV_Target.z = gl_ClipDistance[1u];\n    SV_Target.w = gl_ClipDistance[0u];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %11 %14\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %14 \"SV_Target\"\nOpDecorate %11 BuiltIn ClipDistance\nOpDecorate %14 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 2\n%9 = OpTypeArray %5 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypeVector %5 4\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpTypePointer Input %5\n%17 = OpConstant %7 0\n%20 = OpConstant %7 1\n%22 = OpTypePointer Output %5\n%27 = OpConstant %7 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%16 = OpAccessChain %15 %11 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %15 %11 %20\n%21 = OpLoad %5 %19\n%23 = OpAccessChain %22 %14 %17\nOpStore %23 %18\n%24 = OpAccessChain %22 %14 %20\nOpStore %24 %21\n%25 = OpAccessChain %22 %14 %8\nOpStore %25 %21\n%26 = OpAccessChain %22 %14 %27\nOpStore %26 %18\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-distance-cols.vert",
    "content": "#version 460\n\nout float gl_ClipDistance[2];\n\nlayout(location = 0) in vec4 POS;\nlayout(location = 1) in vec2 CLIP;\n\nvoid main()\n{\n    gl_Position.x = POS.x;\n    gl_Position.y = POS.y;\n    gl_Position.z = POS.z;\n    gl_Position.w = POS.w;\n    gl_ClipDistance[0u] = CLIP.x;\n    gl_ClipDistance[1u] = CLIP.y;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %11 %13 %18\nOpName %3 \"main\"\nOpName %8 \"POS\"\nOpName %11 \"CLIP\"\nOpName %13 \"SV_Position\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 1\nOpDecorate %13 BuiltIn Position\nOpDecorate %18 BuiltIn ClipDistance\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 2\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Output %6\n%13 = OpVariable %12 Output\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 2\n%16 = OpTypeArray %5 %15\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %5\n%21 = OpConstant %14 0\n%24 = OpConstant %14 1\n%33 = OpConstant %14 3\n%35 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %42\n%42 = OpLabel\n%20 = OpAccessChain %19 %11 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %19 %11 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %19 %8 %21\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %19 %8 %24\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %19 %8 %15\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %19 %8 %33\n%34 = OpLoad %5 %32\n%36 = OpAccessChain %35 %13 %21\nOpStore %36 %27\n%37 = OpAccessChain %35 %13 %24\nOpStore %37 %29\n%38 = OpAccessChain %35 %13 %15\nOpStore %38 %31\n%39 = OpAccessChain %35 %13 %33\nOpStore %39 %34\n%40 = OpAccessChain %35 %18 %21\nOpStore %40 %22\n%41 = OpAccessChain %35 %18 %24\nOpStore %41 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-distance-flatten.frag",
    "content": "#version 460\n\nin float gl_ClipDistance[4];\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = gl_ClipDistance[0u];\n    SV_Target.y = gl_ClipDistance[1u];\n    SV_Target.z = gl_ClipDistance[2u];\n    SV_Target.w = gl_ClipDistance[3u];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %13 %16\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %16 \"SV_Target\"\nOpDecorate %13 BuiltIn ClipDistance\nOpDecorate %16 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 2\n%9 = OpTypeArray %6 %8\n%10 = OpConstant %7 4\n%11 = OpTypeArray %5 %10\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Input %5\n%19 = OpConstant %7 0\n%22 = OpConstant %7 1\n%27 = OpConstant %7 3\n%29 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%18 = OpAccessChain %17 %13 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %17 %13 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %17 %13 %8\n%25 = OpLoad %5 %24\n%26 = OpAccessChain %17 %13 %27\n%28 = OpLoad %5 %26\n%30 = OpAccessChain %29 %16 %19\nOpStore %30 %20\n%31 = OpAccessChain %29 %16 %22\nOpStore %31 %23\n%32 = OpAccessChain %29 %16 %8\nOpStore %32 %25\n%33 = OpAccessChain %29 %16 %27\nOpStore %33 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-distance-flatten.vert",
    "content": "#version 460\n\nout float gl_ClipDistance[4];\n\nlayout(location = 0) in vec4 POS;\nlayout(location = 1) in vec2 CLIP;\n\nvoid main()\n{\n    gl_Position.x = POS.x;\n    gl_Position.y = POS.y;\n    gl_Position.z = POS.z;\n    gl_Position.w = POS.w;\n    gl_ClipDistance[0u] = CLIP.x;\n    gl_ClipDistance[1u] = CLIP.y;\n    gl_ClipDistance[2u] = CLIP.x + 1.0;\n    gl_ClipDistance[3u] = CLIP.y + 1.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 51\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %11 %13 %20\nOpName %3 \"main\"\nOpName %8 \"POS\"\nOpName %11 \"CLIP\"\nOpName %13 \"SV_Position\"\nOpDecorate %8 Location 0\nOpDecorate %11 Location 1\nOpDecorate %13 BuiltIn Position\nOpDecorate %20 BuiltIn ClipDistance\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeVector %5 2\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Output %6\n%13 = OpVariable %12 Output\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 2\n%16 = OpTypeArray %9 %15\n%17 = OpConstant %14 4\n%18 = OpTypeArray %5 %17\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%21 = OpTypePointer Input %5\n%23 = OpConstant %14 0\n%26 = OpConstant %14 1\n%35 = OpConstant %14 3\n%38 = OpConstant %5 1\n%40 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %49\n%49 = OpLabel\n%22 = OpAccessChain %21 %11 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %21 %11 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %21 %8 %23\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %21 %8 %26\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %21 %8 %15\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %21 %8 %35\n%36 = OpLoad %5 %34\n%37 = OpFAdd %5 %24 %38\n%39 = OpFAdd %5 %27 %38\n%41 = OpAccessChain %40 %13 %23\nOpStore %41 %29\n%42 = OpAccessChain %40 %13 %26\nOpStore %42 %31\n%43 = OpAccessChain %40 %13 %15\nOpStore %43 %33\n%44 = OpAccessChain %40 %13 %35\nOpStore %44 %36\n%45 = OpAccessChain %40 %20 %23\nOpStore %45 %24\n%46 = OpAccessChain %40 %20 %26\nOpStore %46 %27\n%47 = OpAccessChain %40 %20 %15\nOpStore %47 %37\n%48 = OpAccessChain %40 %20 %35\nOpStore %48 %39\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-distance-rows.frag",
    "content": "#version 460\n\nin float gl_ClipDistance[2];\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = gl_ClipDistance[0u];\n    SV_Target.y = gl_ClipDistance[0u];\n    SV_Target.z = gl_ClipDistance[1u];\n    SV_Target.w = gl_ClipDistance[1u];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %10 %13\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %13 \"SV_Target\"\nOpDecorate %10 BuiltIn ClipDistance\nOpDecorate %13 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 2\n%8 = OpTypeArray %5 %7\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpTypeVector %5 4\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%14 = OpTypePointer Input %5\n%16 = OpConstant %6 0\n%19 = OpConstant %6 1\n%21 = OpTypePointer Output %5\n%26 = OpConstant %6 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%15 = OpAccessChain %14 %10 %16\n%17 = OpLoad %5 %15\n%18 = OpAccessChain %14 %10 %19\n%20 = OpLoad %5 %18\n%22 = OpAccessChain %21 %13 %16\nOpStore %22 %17\n%23 = OpAccessChain %21 %13 %19\nOpStore %23 %17\n%24 = OpAccessChain %21 %13 %7\nOpStore %24 %20\n%25 = OpAccessChain %21 %13 %26\nOpStore %25 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-distance-rows.vert",
    "content": "#version 460\n\nout float gl_ClipDistance[2];\n\nlayout(location = 0) in vec4 POS;\nlayout(location = 1) in float CLIP;\n\nvoid main()\n{\n    gl_Position.x = POS.x;\n    gl_Position.y = POS.y;\n    gl_Position.z = POS.z;\n    gl_Position.w = POS.w;\n    gl_ClipDistance[0u] = CLIP;\n    gl_ClipDistance[1u] = CLIP + 1.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %10 %12 %17\nOpName %3 \"main\"\nOpName %8 \"POS\"\nOpName %10 \"CLIP\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 1\nOpDecorate %12 BuiltIn Position\nOpDecorate %17 BuiltIn ClipDistance\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%11 = OpTypePointer Output %6\n%12 = OpVariable %11 Output\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 2\n%15 = OpTypeArray %5 %14\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%20 = OpConstant %13 0\n%23 = OpConstant %13 1\n%28 = OpConstant %13 3\n%31 = OpConstant %5 1\n%32 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%18 = OpLoad %5 %10\n%19 = OpAccessChain %9 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %9 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %9 %8 %14\n%26 = OpLoad %5 %25\n%27 = OpAccessChain %9 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpFAdd %5 %18 %31\n%33 = OpAccessChain %32 %12 %20\nOpStore %33 %21\n%34 = OpAccessChain %32 %12 %23\nOpStore %34 %24\n%35 = OpAccessChain %32 %12 %14\nOpStore %35 %26\n%36 = OpAccessChain %32 %12 %28\nOpStore %36 %29\n%37 = OpAccessChain %32 %17 %20\nOpStore %37 %18\n%38 = OpAccessChain %32 %17 %23\nOpStore %38 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/clip-distance-single.vert",
    "content": "#version 460\n\nout float gl_ClipDistance[1];\n\nlayout(location = 0) in vec4 POS;\nlayout(location = 1) in float CLIP;\n\nvoid main()\n{\n    gl_Position.x = POS.x;\n    gl_Position.y = POS.y;\n    gl_Position.z = POS.z;\n    gl_Position.w = POS.w;\n    gl_ClipDistance[0u] = CLIP;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %10 %12 %17\nOpName %3 \"main\"\nOpName %8 \"POS\"\nOpName %10 \"CLIP\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 1\nOpDecorate %12 BuiltIn Position\nOpDecorate %17 BuiltIn ClipDistance\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%11 = OpTypePointer Output %6\n%12 = OpVariable %11 Output\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 1\n%15 = OpTypeArray %5 %14\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%20 = OpConstant %13 0\n%25 = OpConstant %13 2\n%28 = OpConstant %13 3\n%30 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %36\n%36 = OpLabel\n%18 = OpLoad %5 %10\n%19 = OpAccessChain %9 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %9 %8 %14\n%23 = OpLoad %5 %22\n%24 = OpAccessChain %9 %8 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %9 %8 %28\n%29 = OpLoad %5 %27\n%31 = OpAccessChain %30 %12 %20\nOpStore %31 %21\n%32 = OpAccessChain %30 %12 %14\nOpStore %32 %23\n%33 = OpAccessChain %30 %12 %25\nOpStore %33 %26\n%34 = OpAccessChain %30 %12 %28\nOpStore %34 %29\n%35 = OpAccessChain %30 %17 %20\nOpStore %35 %18\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/coverage.frag",
    "content": "#version 460\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = 1.0;\n    SV_Target.y = 1.0;\n    SV_Target.z = 1.0;\n    SV_Target.w = 1.0;\n    gl_SampleMask[0u] = int(uint(gl_SampleMaskIn[0u]) & 3u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %13 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SV_Target\"\nOpName %13 \"SV_Coverage\"\nOpDecorate %8 Location 0\nOpDecorate %13 BuiltIn SampleMask\nOpDecorate %15 BuiltIn SampleMask\nOpDecorate %15 Flat\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpConstant %9 1\n%11 = OpTypeArray %9 %10\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%14 = OpTypePointer Input %11\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Input %9\n%18 = OpConstant %9 0\n%21 = OpConstant %9 3\n%22 = OpTypePointer Output %5\n%24 = OpConstant %5 1\n%27 = OpConstant %9 2\n%29 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %31\n%31 = OpLabel\n%17 = OpAccessChain %16 %15 %18\n%19 = OpLoad %9 %17\n%20 = OpBitwiseAnd %9 %19 %21\n%23 = OpAccessChain %22 %8 %18\nOpStore %23 %24\n%25 = OpAccessChain %22 %8 %10\nOpStore %25 %24\n%26 = OpAccessChain %22 %8 %27\nOpStore %26 %24\n%28 = OpAccessChain %22 %8 %21\nOpStore %28 %24\n%30 = OpAccessChain %29 %13 %18\nOpStore %30 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/depth-greater-equal.frag",
    "content": "#version 460\nlayout(depth_greater) out float gl_FragDepth;\n\nlayout(location = 0) in float D;\n\nvoid main()\n{\n    gl_FragDepth = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DepthReplacing\nOpExecutionMode %3 DepthGreater\nOpName %3 \"main\"\nOpName %7 \"D\"\nOpName %9 \"SV_DepthGreaterEqual\"\nOpDecorate %7 Location 0\nOpDecorate %9 BuiltIn FragDepth\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/depth-less-equal.frag",
    "content": "#version 460\nlayout(depth_less) out float gl_FragDepth;\n\nlayout(location = 0) in float D;\n\nvoid main()\n{\n    gl_FragDepth = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DepthReplacing\nOpExecutionMode %3 DepthLess\nOpName %3 \"main\"\nOpName %7 \"D\"\nOpName %9 \"SV_DepthLessEqual\"\nOpDecorate %7 Location 0\nOpDecorate %9 BuiltIn FragDepth\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/depth.frag",
    "content": "#version 460\n\nlayout(location = 0) in float D;\n\nvoid main()\n{\n    gl_FragDepth = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DepthReplacing\nOpName %3 \"main\"\nOpName %7 \"D\"\nOpName %9 \"SV_Depth\"\nOpDecorate %7 Location 0\nOpDecorate %9 BuiltIn FragDepth\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/early-depth-stencil.frag",
    "content": "#version 460\nlayout(early_fragment_tests) in;\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = 1.0;\n    SV_Target.y = 1.0;\n    SV_Target.z = 1.0;\n    SV_Target.w = 1.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpName %3 \"main\"\nOpName %8 \"SV_Target\"\nOpDecorate %8 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypePointer Output %5\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 0\n%13 = OpConstant %5 1\n%15 = OpConstant %11 1\n%17 = OpConstant %11 2\n%19 = OpConstant %11 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%10 = OpAccessChain %9 %8 %12\nOpStore %10 %13\n%14 = OpAccessChain %9 %8 %15\nOpStore %14 %13\n%16 = OpAccessChain %9 %8 %17\nOpStore %16 %13\n%18 = OpAccessChain %9 %8 %19\nOpStore %18 %13\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/inner-coverage.noglsl.frag",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\nOpCapability Shader\nOpCapability FragmentFullyCoveredEXT\nOpExtension \"SPV_EXT_fragment_fully_covered\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_Target\"\nOpName %18 \"discard_state\"\nOpName %25 \"discard_exit\"\nOpDecorate %7 Location 0\nOpDecorate %10 BuiltIn FullyCoveredEXT\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Output %5\n%7 = OpVariable %6 Output\n%8 = OpTypeBool\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%12 = OpTypeInt 32 0\n%14 = OpConstant %12 1\n%15 = OpConstant %12 0\n%17 = OpTypePointer Private %8\n%18 = OpVariable %17 Private\n%19 = OpConstantFalse %8\n%20 = OpConstant %5 1\n%24 = OpConstantTrue %8\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpStore %18 %19\nOpBranch %21\n%21 = OpLabel\n%11 = OpLoad %8 %10\n%13 = OpSelect %12 %11 %14 %15\n%16 = OpIEqual %8 %13 %15\nOpSelectionMerge %23 None\nOpBranchConditional %16 %22 %23\n%22 = OpLabel\nOpStore %18 %24\nOpBranch %23\n%23 = OpLabel\nOpStore %7 %20\n%31 = OpFunctionCall %1 %25\nOpReturn\nOpFunctionEnd\n%25 = OpFunction %1 None %2\n%26 = OpLabel\n%29 = OpLoad %8 %18\nOpSelectionMerge %28 None\nOpBranchConditional %29 %27 %28\n%27 = OpLabel\nOpKill\n%28 = OpLabel\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/semantics/is-front-face.frag",
    "content": "#version 460\n\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    SV_Target = float((gl_FrontFacing ? 4294967295u : 0u) != 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SV_IsFrontFace\"\nOpName %11 \"SV_Target\"\nOpDecorate %8 BuiltIn FrontFacing\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeBool\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeFloat 32\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%14 = OpConstant %5 4294967295\n%15 = OpConstant %5 0\n%18 = OpConstant %9 1\n%19 = OpConstant %9 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %20\n%20 = OpLabel\n%12 = OpLoad %6 %8\n%13 = OpSelect %5 %12 %14 %15\n%16 = OpINotEqual %6 %13 %15\n%17 = OpSelect %9 %16 %18 %19\nOpStore %11 %17\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/position-short.frag",
    "content": "#version 460\n\nlayout(location = 0) out vec3 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = gl_FragCoord.x;\n    SV_Target.y = gl_FragCoord.y;\n    SV_Target.z = gl_FragCoord.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %9 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %9 \"SV_Position\"\nOpName %11 \"SV_Target\"\nOpDecorate %9 BuiltIn FragCoord\nOpDecorate %11 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeVector %5 4\n%8 = OpTypePointer Input %7\n%9 = OpVariable %8 Input\n%10 = OpTypePointer Output %6\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%23 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%13 = OpAccessChain %12 %9 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %9 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %9 %21\n%22 = OpLoad %5 %20\n%24 = OpAccessChain %23 %11 %15\nOpStore %24 %16\n%25 = OpAccessChain %23 %11 %18\nOpStore %25 %19\n%26 = OpAccessChain %23 %11 %21\nOpStore %26 %22\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/position-short.vert",
    "content": "#version 460\n\nvoid main()\n{\n    gl_Position.x = 1.0;\n    gl_Position.y = 1.0;\n    gl_Position.z = 1.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %9\nOpName %3 \"main\"\nOpName %9 \"SV_Position\"\nOpDecorate %9 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeVector %5 4\n%8 = OpTypePointer Output %7\n%9 = OpVariable %8 Output\n%10 = OpTypePointer Output %5\n%12 = OpTypeInt 32 0\n%13 = OpConstant %12 0\n%14 = OpConstant %5 1\n%16 = OpConstant %12 1\n%18 = OpConstant %12 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %19\n%19 = OpLabel\n%11 = OpAccessChain %10 %9 %13\nOpStore %11 %14\n%15 = OpAccessChain %10 %9 %16\nOpStore %15 %14\n%17 = OpAccessChain %10 %9 %18\nOpStore %17 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/position.frag",
    "content": "#version 460\n\nlayout(location = 1) flat in uint INDEX;\nlayout(location = 0) out float SV_Target;\n\nvoid main()\n{\n    float _33[4];\n    _33[0u] = gl_FragCoord.x;\n    _33[1u] = gl_FragCoord.y;\n    _33[2u] = gl_FragCoord.z;\n    _33[3u] = 1.0 / gl_FragCoord.w;\n    SV_Target = _33[INDEX];\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %11 %13\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %11 \"INDEX\"\nOpName %13 \"SV_Target\"\nOpDecorate %8 BuiltIn FragCoord\nOpDecorate %11 Flat\nOpDecorate %11 Location 1\nOpDecorate %13 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeInt 32 0\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpTypePointer Input %5\n%17 = OpConstant %9 0\n%20 = OpConstant %9 1\n%23 = OpConstant %9 2\n%26 = OpConstant %9 3\n%29 = OpConstant %5 1\n%30 = OpConstant %9 4\n%31 = OpTypeArray %5 %30\n%32 = OpTypePointer Function %31\n%34 = OpTypePointer Function %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%33 = OpVariable %32 Function\nOpBranch %41\n%41 = OpLabel\n%14 = OpLoad %9 %11\n%16 = OpAccessChain %15 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %15 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %15 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %15 %8 %26\n%27 = OpLoad %5 %25\n%28 = OpFDiv %5 %29 %27\n%35 = OpInBoundsAccessChain %34 %33 %17\nOpStore %35 %18\n%36 = OpInBoundsAccessChain %34 %33 %20\nOpStore %36 %21\n%37 = OpInBoundsAccessChain %34 %33 %23\nOpStore %37 %24\n%38 = OpInBoundsAccessChain %34 %33 %26\nOpStore %38 %28\n%39 = OpAccessChain %34 %33 %14\n%40 = OpLoad %5 %39\nOpStore %13 %40\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/primitive-id.frag",
    "content": "#version 460\n\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(gl_PrimitiveID);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_PrimitiveID\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 BuiltIn PrimitiveId\nOpDecorate %7 Flat\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/primitive-id.geom",
    "content": "#version 460\nlayout(points) in;\nlayout(max_vertices = 1, points) out;\n\nlayout(location = 0) in vec4 A[1];\n\nvoid main()\n{\n    gl_Position.x = A[0u].x;\n    gl_Position.y = A[0u].y;\n    gl_Position.z = A[0u].z;\n    gl_Position.w = A[0u].w;\n    gl_PrimitiveID = int(uint(gl_PrimitiveIDIn) + 1u);\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %13 %15 %17\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 1\nOpExecutionMode %3 InputPoints\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"SV_PrimitiveID\"\nOpName %15 \"SV_Position\"\nOpName %17 \"SV_PrimitiveID\"\nOpDecorate %11 Location 0\nOpDecorate %13 BuiltIn PrimitiveId\nOpDecorate %15 BuiltIn Position\nOpDecorate %17 BuiltIn PrimitiveId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 1\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %7\n%13 = OpVariable %12 Input\n%14 = OpTypePointer Output %6\n%15 = OpVariable %14 Output\n%16 = OpTypePointer Output %7\n%17 = OpVariable %16 Output\n%19 = OpTypePointer Input %5\n%21 = OpConstant %7 0\n%26 = OpConstant %7 2\n%29 = OpConstant %7 3\n%32 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%18 = OpLoad %7 %13\n%20 = OpAccessChain %19 %11 %21 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %19 %11 %21 %8\n%24 = OpLoad %5 %23\n%25 = OpAccessChain %19 %11 %21 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %19 %11 %21 %29\n%30 = OpLoad %5 %28\n%31 = OpIAdd %7 %18 %8\n%33 = OpAccessChain %32 %15 %21\nOpStore %33 %22\n%34 = OpAccessChain %32 %15 %8\nOpStore %34 %24\n%35 = OpAccessChain %32 %15 %26\nOpStore %35 %27\n%36 = OpAccessChain %32 %15 %29\nOpStore %36 %30\nOpStore %17 %31\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/render-target-array-index.frag",
    "content": "#version 460\n\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(gl_Layer);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_RenderTargetArrayIndex\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 BuiltIn Layer\nOpDecorate %7 Flat\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/render-target-array-index.geom",
    "content": "#version 460\nlayout(points) in;\nlayout(max_vertices = 2, points) out;\n\nlayout(location = 0) in vec4 A[1];\nlayout(location = 1) in vec4 B[1];\n\nvoid main()\n{\n    gl_Position.x = A[0u].x;\n    gl_Position.y = A[0u].y;\n    gl_Position.z = A[0u].z;\n    gl_Position.w = A[0u].w;\n    gl_Layer = int(0u);\n    EmitVertex();\n    gl_Position.x = B[0u].x;\n    gl_Position.y = B[0u].y;\n    gl_Position.z = B[0u].z;\n    gl_Position.w = B[0u].w;\n    gl_Layer = int(1u);\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %16\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 2\nOpExecutionMode %3 InputPoints\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %12 \"B\"\nOpName %14 \"SV_Position\"\nOpName %16 \"SV_RenderTargetArrayIndex\"\nOpDecorate %11 Location 0\nOpDecorate %12 Location 1\nOpDecorate %14 BuiltIn Position\nOpDecorate %16 BuiltIn Layer\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 1\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpTypePointer Output %7\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Input %5\n%19 = OpConstant %7 0\n%24 = OpConstant %7 2\n%27 = OpConstant %7 3\n%29 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%18 = OpAccessChain %17 %11 %19 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %17 %11 %19 %8\n%22 = OpLoad %5 %21\n%23 = OpAccessChain %17 %11 %19 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %17 %11 %19 %27\n%28 = OpLoad %5 %26\n%30 = OpAccessChain %29 %14 %19\nOpStore %30 %20\n%31 = OpAccessChain %29 %14 %8\nOpStore %31 %22\n%32 = OpAccessChain %29 %14 %24\nOpStore %32 %25\n%33 = OpAccessChain %29 %14 %27\nOpStore %33 %28\nOpStore %16 %19\nOpEmitVertex\n%34 = OpAccessChain %17 %12 %19 %19\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %17 %12 %19 %8\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %17 %12 %19 %24\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %17 %12 %19 %27\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %29 %14 %19\nOpStore %42 %35\n%43 = OpAccessChain %29 %14 %8\nOpStore %43 %37\n%44 = OpAccessChain %29 %14 %24\nOpStore %44 %39\n%45 = OpAccessChain %29 %14 %27\nOpStore %45 %41\nOpStore %16 %8\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/sample-rate-pos.frag",
    "content": "#version 460\n\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = gl_FragCoord.x;\n    SV_Target.y = gl_FragCoord.y;\n    SV_Target.z = gl_FragCoord.z;\n    SV_Target.w = 1.0 / gl_FragCoord.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpCapability SampleRateShading\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 BuiltIn FragCoord\nOpDecorate %8 Sample\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%26 = OpConstant %5 1\n%27 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpFDiv %5 %26 %24\n%28 = OpAccessChain %27 %10 %14\nOpStore %28 %15\n%29 = OpAccessChain %27 %10 %17\nOpStore %29 %18\n%30 = OpAccessChain %27 %10 %20\nOpStore %30 %21\n%31 = OpAccessChain %27 %10 %23\nOpStore %31 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/stencil-ref.frag",
    "content": "#version 460\n#extension GL_ARB_shader_stencil_export : require\n\nlayout(location = 0) in float V;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    SV_Target.x = V;\n    SV_Target.y = V;\n    SV_Target.z = V;\n    SV_Target.w = V;\n    gl_FragStencilRefARB = int(uint(V));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\nOpCapability Shader\nOpCapability StencilExportEXT\nOpExtension \"SPV_EXT_shader_stencil_export\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %10 %13\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 StencilRefReplacingEXT\nOpName %3 \"main\"\nOpName %7 \"V\"\nOpName %10 \"SV_Target\"\nOpName %13 \"SV_StencilRef\"\nOpDecorate %7 Location 0\nOpDecorate %10 Location 0\nOpDecorate %13 BuiltIn FragStencilRefEXT\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeVector %5 4\n%9 = OpTypePointer Output %8\n%10 = OpVariable %9 Output\n%11 = OpTypeInt 32 0\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%16 = OpTypePointer Output %5\n%18 = OpConstant %11 0\n%20 = OpConstant %11 1\n%22 = OpConstant %11 2\n%24 = OpConstant %11 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %25\n%25 = OpLabel\n%14 = OpLoad %5 %7\n%15 = OpConvertFToU %11 %14\n%17 = OpAccessChain %16 %10 %18\nOpStore %17 %14\n%19 = OpAccessChain %16 %10 %20\nOpStore %19 %14\n%21 = OpAccessChain %16 %10 %22\nOpStore %21 %14\n%23 = OpAccessChain %16 %10 %24\nOpStore %23 %14\nOpStore %13 %15\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/sv-shading-rate.noglsl.frag",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpCapability FragmentShadingRateKHR\nOpExtension \"SPV_KHR_fragment_shading_rate\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_ShadingRate\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 BuiltIn ShadingRateKHR\nOpDecorate %7 Flat\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/semantics/sv-shading-rate.noglsl.vert",
    "content": "; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 25\n; Schema: 0\nOpCapability Shader\nOpCapability FragmentShadingRateKHR\nOpExtension \"SPV_KHR_fragment_shading_rate\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %11\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %11 \"SV_ShadingRate\"\nOpDecorate %8 BuiltIn Position\nOpDecorate %11 BuiltIn PrimitiveShadingRateKHR\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%14 = OpConstant %9 0\n%15 = OpConstant %5 1\n%17 = OpConstant %9 1\n%19 = OpConstant %9 2\n%21 = OpConstant %9 3\n%22 = OpConstant %9 10\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %23\n%23 = OpLabel\n%13 = OpAccessChain %12 %8 %14\nOpStore %13 %15\n%16 = OpAccessChain %12 %8 %17\nOpStore %16 %15\n%18 = OpAccessChain %12 %8 %19\nOpStore %18 %15\n%20 = OpAccessChain %12 %8 %21\nOpStore %20 %15\nOpStore %11 %22\nOpReturn\nOpFunctionEnd\n\n"
  },
  {
    "path": "reference/shaders/semantics/view-id.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 POSITION;\nlayout(location = 0) out vec4 SV_Target;\n\nvoid main()\n{\n    float _25 = float(0u);\n    SV_Target.x = _25 + POSITION.x;\n    SV_Target.y = _25 + POSITION.y;\n    SV_Target.z = _25 + POSITION.z;\n    SV_Target.w = _25 + POSITION.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"POSITION\"\nOpName %10 \"SV_Target\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%30 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpConvertUToF %5 %14\n%26 = OpFAdd %5 %25 %15\n%27 = OpFAdd %5 %25 %18\n%28 = OpFAdd %5 %25 %21\n%29 = OpFAdd %5 %25 %24\n%31 = OpAccessChain %30 %10 %14\nOpStore %31 %26\n%32 = OpAccessChain %30 %10 %17\nOpStore %32 %27\n%33 = OpAccessChain %30 %10 %20\nOpStore %33 %28\n%34 = OpAccessChain %30 %10 %23\nOpStore %34 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/view-id.vert",
    "content": "#version 460\n\nlayout(location = 0) in vec4 POSITION;\n\nvoid main()\n{\n    float _25 = float(0u);\n    gl_Position.x = _25 + POSITION.x;\n    gl_Position.y = _25 + POSITION.y;\n    gl_Position.z = _25 + POSITION.z;\n    gl_Position.w = _25 + POSITION.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %10\nOpName %3 \"main\"\nOpName %8 \"POSITION\"\nOpName %10 \"SV_Position\"\nOpDecorate %8 Location 0\nOpDecorate %10 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypePointer Input %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%17 = OpConstant %13 1\n%20 = OpConstant %13 2\n%23 = OpConstant %13 3\n%30 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%12 = OpAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%16 = OpAccessChain %11 %8 %17\n%18 = OpLoad %5 %16\n%19 = OpAccessChain %11 %8 %20\n%21 = OpLoad %5 %19\n%22 = OpAccessChain %11 %8 %23\n%24 = OpLoad %5 %22\n%25 = OpConvertUToF %5 %14\n%26 = OpFAdd %5 %25 %15\n%27 = OpFAdd %5 %25 %18\n%28 = OpFAdd %5 %25 %21\n%29 = OpFAdd %5 %25 %24\n%31 = OpAccessChain %30 %10 %14\nOpStore %31 %26\n%32 = OpAccessChain %30 %10 %17\nOpStore %32 %27\n%33 = OpAccessChain %30 %10 %20\nOpStore %33 %28\n%34 = OpAccessChain %30 %10 %23\nOpStore %34 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/viewport-array-index.frag",
    "content": "#version 460\n\nlayout(location = 0) out uint SV_Target;\n\nvoid main()\n{\n    SV_Target = uint(gl_ViewportIndex);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\nOpCapability Shader\nOpCapability MultiViewport\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %7 %9\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %7 \"SV_ViewportArrayIndex\"\nOpName %9 \"SV_Target\"\nOpDecorate %7 BuiltIn ViewportIndex\nOpDecorate %7 Flat\nOpDecorate %9 Location 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypePointer Output %5\n%9 = OpVariable %8 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %11\n%11 = OpLabel\n%10 = OpLoad %5 %7\nOpStore %9 %10\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/semantics/viewport-array-index.geom",
    "content": "#version 460\nlayout(points) in;\nlayout(max_vertices = 2, points) out;\n\nlayout(location = 0) in vec4 A[1];\nlayout(location = 1) in vec4 B[1];\n\nvoid main()\n{\n    gl_Position.x = A[0u].x;\n    gl_Position.y = A[0u].y;\n    gl_Position.z = A[0u].z;\n    gl_Position.w = A[0u].w;\n    gl_ViewportIndex = int(0u);\n    EmitVertex();\n    gl_Position.x = B[0u].x;\n    gl_Position.y = B[0u].y;\n    gl_Position.z = B[0u].z;\n    gl_Position.w = B[0u].w;\n    gl_ViewportIndex = int(1u);\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %16\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 2\nOpExecutionMode %3 InputPoints\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %12 \"B\"\nOpName %14 \"SV_Position\"\nOpName %16 \"SV_ViewportArrayIndex\"\nOpDecorate %11 Location 0\nOpDecorate %12 Location 1\nOpDecorate %14 BuiltIn Position\nOpDecorate %16 BuiltIn ViewportIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 1\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpTypePointer Output %7\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Input %5\n%19 = OpConstant %7 0\n%24 = OpConstant %7 2\n%27 = OpConstant %7 3\n%29 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%18 = OpAccessChain %17 %11 %19 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %17 %11 %19 %8\n%22 = OpLoad %5 %21\n%23 = OpAccessChain %17 %11 %19 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %17 %11 %19 %27\n%28 = OpLoad %5 %26\n%30 = OpAccessChain %29 %14 %19\nOpStore %30 %20\n%31 = OpAccessChain %29 %14 %8\nOpStore %31 %22\n%32 = OpAccessChain %29 %14 %24\nOpStore %32 %25\n%33 = OpAccessChain %29 %14 %27\nOpStore %33 %28\nOpStore %16 %19\nOpEmitVertex\n%34 = OpAccessChain %17 %12 %19 %19\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %17 %12 %19 %8\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %17 %12 %19 %24\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %17 %12 %19 %27\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %29 %14 %19\nOpStore %42 %35\n%43 = OpAccessChain %29 %14 %8\nOpStore %43 %37\n%44 = OpAccessChain %29 %14 %24\nOpStore %44 %39\n%45 = OpAccessChain %29 %14 %27\nOpStore %45 %41\nOpStore %16 %8\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/boolean-io.vert",
    "content": "#version 460\n\nlayout(location = 0) in uint A;\nlayout(location = 1) flat out uint V;\n\nvoid main()\n{\n    gl_Position.x = 1.0;\n    gl_Position.y = 1.0;\n    gl_Position.z = 1.0;\n    gl_Position.w = 1.0;\n    V = 1u;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 26\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"A\"\nOpName %11 \"SV_Position\"\nOpName %13 \"V\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 Flat\nOpDecorate %13 Location 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%14 = OpTypePointer Output %8\n%16 = OpConstant %5 0\n%17 = OpConstant %8 1\n%19 = OpConstant %5 1\n%21 = OpConstant %5 2\n%23 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %24\n%24 = OpLabel\n%15 = OpAccessChain %14 %11 %16\nOpStore %15 %17\n%18 = OpAccessChain %14 %11 %19\nOpStore %18 %17\n%20 = OpAccessChain %14 %11 %21\nOpStore %20 %17\n%22 = OpAccessChain %14 %11 %23\nOpStore %22 %17\nOpStore %13 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/callable-chain.rcall",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    float _m0;\n};\n\nlayout(location = 0) callableDataInEXT _6 payload;\nlayout(location = 1) callableDataEXT _6 _10;\n\nvoid main()\n{\n    _10._m0 = payload._m0;\n    executeCallableEXT(0u, 1);\n    payload._m0 = _10._m0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint CallableKHR %3 \"main\" %8 %10\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingCallableDataKHR %6\n%8 = OpVariable %7 IncomingCallableDataKHR\n%9 = OpTypePointer CallableDataKHR %6\n%10 = OpVariable %9 CallableDataKHR\n%11 = OpTypePointer IncomingCallableDataKHR %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%16 = OpTypePointer CallableDataKHR %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %19\n%19 = OpLabel\n%12 = OpInBoundsAccessChain %11 %8 %14\n%15 = OpLoad %5 %12\n%17 = OpInBoundsAccessChain %16 %10 %14\nOpStore %17 %15\nOpExecuteCallableKHR %14 %10\n%18 = OpLoad %5 %17\nOpStore %12 %18\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/callable.rcall",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _6\n{\n    float _m0;\n};\n\nlayout(location = 0) callableDataInEXT _6 payload;\n\nvoid main()\n{\n    payload._m0 = 1.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 16\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint CallableKHR %3 \"main\" %8\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"payload\"\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeStruct %5\n%7 = OpTypePointer IncomingCallableDataKHR %6\n%8 = OpVariable %7 IncomingCallableDataKHR\n%9 = OpTypePointer IncomingCallableDataKHR %5\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 0\n%13 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %14\n%14 = OpLabel\n%10 = OpInBoundsAccessChain %9 %8 %12\nOpStore %10 %13\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/closesthit.rclosest",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec4 _m0;\n};\n\nstruct _11\n{\n    vec2 _m0;\n};\n\nvec2 _20;\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\nhitAttributeEXT _11 hit;\n\nvoid main()\n{\n    payload._m0 = hit._m0.xyxy;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 25\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint ClosestHitKHR %3 \"main\" %9 %13\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\nOpName %11 \"\"\nOpName %13 \"hit\"\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypeVector %5 2\n%11 = OpTypeStruct %10\n%12 = OpTypePointer HitAttributeKHR %11\n%13 = OpVariable %12 HitAttributeKHR\n%14 = OpTypePointer HitAttributeKHR %10\n%16 = OpTypeInt 32 0\n%17 = OpConstant %16 0\n%21 = OpTypePointer IncomingRayPayloadKHR %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%20 = OpUndef %10\nOpBranch %23\n%23 = OpLabel\n%15 = OpInBoundsAccessChain %14 %13 %17\n%18 = OpLoad %10 %15\n%19 = OpVectorShuffle %6 %18 %20 0 1 0 1\n%22 = OpInBoundsAccessChain %21 %9 %17\nOpStore %22 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/domain-clip-cull.tese",
    "content": "#version 460\nlayout(triangles) in;\n\nout float gl_ClipDistance[1];\n\nlayout(location = 0) in vec3 SV_CullDistance[];\nlayout(location = 0, component = 3) in float SV_ClipDistance[];\nlayout(location = 1) patch in float C[3];\nlayout(location = 1, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Position.x = (((SV_CullDistance[1u].y + SV_ClipDistance[1u]) * gl_TessCoord.y) + ((SV_CullDistance[0u].z + SV_ClipDistance[0u]) * gl_TessCoord.x)) + ((SV_CullDistance[2u].x + SV_ClipDistance[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n    gl_ClipDistance[0u] = 5.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %14 %17 %21 %22 %24 %27\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"SV_CullDistance\"\nOpName %14 \"SV_ClipDistance\"\nOpName %17 \"SV_Position\"\nOpName %22 \"C\"\nOpName %24 \"D\"\nOpDecorate %11 Location 0\nOpDecorate %14 Location 0\nOpDecorate %14 Component 3\nOpDecorate %17 BuiltIn Position\nOpDecorate %21 BuiltIn ClipDistance\nOpDecorate %22 Location 1\nOpDecorate %22 Patch\nOpDecorate %24 Location 1\nOpDecorate %24 Component 1\nOpDecorate %24 Patch\nOpDecorate %27 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 3\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypeVector %5 4\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%18 = OpConstant %7 1\n%19 = OpTypeArray %5 %18\n%20 = OpTypePointer Output %19\n%21 = OpVariable %20 Output\n%22 = OpVariable %13 Input\n%23 = OpTypePointer Input %5\n%24 = OpVariable %23 Input\n%26 = OpTypePointer Input %6\n%27 = OpVariable %26 Input\n%29 = OpConstant %7 0\n%34 = OpConstant %7 2\n%63 = OpTypePointer Output %5\n%69 = OpConstant %5 5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %70\n%70 = OpLabel\n%25 = OpLoad %5 %24\n%28 = OpAccessChain %23 %27 %29\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %23 %27 %18\n%32 = OpLoad %5 %31\n%33 = OpAccessChain %23 %27 %34\n%35 = OpLoad %5 %33\n%36 = OpAccessChain %23 %14 %29\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %23 %14 %18\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %23 %14 %34\n%41 = OpLoad %5 %40\n%42 = OpAccessChain %23 %11 %29 %34\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %23 %11 %18 %18\n%45 = OpLoad %5 %44\n%46 = OpAccessChain %23 %11 %34 %29\n%47 = OpLoad %5 %46\n%48 = OpFAdd %5 %47 %41\n%49 = OpFMul %5 %48 %35\n%50 = OpFAdd %5 %45 %39\n%51 = OpFMul %5 %50 %32\n%52 = OpFAdd %5 %43 %37\n%53 = OpFMul %5 %52 %30\n%54 = OpFAdd %5 %51 %53\n%55 = OpFAdd %5 %54 %49\n%56 = OpAccessChain %23 %22 %29\n%57 = OpLoad %5 %56\n%58 = OpAccessChain %23 %22 %18\n%59 = OpLoad %5 %58\n%60 = OpFAdd %5 %59 %57\n%61 = OpAccessChain %23 %22 %34\n%62 = OpLoad %5 %61\n%64 = OpAccessChain %63 %17 %29\nOpStore %64 %55\n%65 = OpAccessChain %63 %17 %18\nOpStore %65 %60\n%66 = OpAccessChain %63 %17 %34\nOpStore %66 %62\n%67 = OpAccessChain %63 %17 %8\nOpStore %67 %25\n%68 = OpAccessChain %63 %21 %29\nOpStore %68 %69\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/domain-patch-input-integer-io.tese",
    "content": "#version 460\nlayout(triangles) in;\n\nlayout(location = 0) in float A[];\nlayout(location = 1) patch in int B;\nlayout(location = 1, component = 1) patch in uint C;\nlayout(location = 2) patch in ivec4 BV;\nlayout(location = 3) patch in uvec4 CV;\nlayout(location = 4) patch in int BVS[2];\nlayout(location = 4, component = 1) patch in uint CVS[2];\nlayout(location = 6) patch in ivec4 BVSS[2];\nlayout(location = 8) patch in uvec4 CVSS[2];\n\nvoid main()\n{\n    float _111 = float(CVS[1u]) + float(int(uint(BVS[0u])));\n    gl_Position.x = ((((float(CV.x) + float(int(uint(BV.x)))) + A[0u]) + _111) + float(int(uint(BVSS[0u].x)))) + float(CVSS[1u].x);\n    gl_Position.y = ((((float(int(uint(BV.y))) + float(int(uint(B)))) + float(CV.y)) + _111) + float(int(uint(BVSS[0u].y)))) + float(CVSS[1u].y);\n    gl_Position.z = ((((float(int(uint(BV.z))) + float(C)) + float(CV.z)) + _111) + float(int(uint(BVSS[0u].z)))) + float(CVSS[1u].z);\n    gl_Position.w = ((((float(int(uint(BV.w))) + 1.0) + float(CV.w)) + _111) + float(int(uint(BVSS[0u].w)))) + float(CVSS[1u].w);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 140\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %10 %13 %16 %18 %21 %24 %28 %31 %34 %37\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %10 \"A\"\nOpName %13 \"SV_Position\"\nOpName %16 \"B\"\nOpName %18 \"C\"\nOpName %21 \"BV\"\nOpName %24 \"CV\"\nOpName %28 \"BVS\"\nOpName %31 \"CVS\"\nOpName %34 \"BVSS\"\nOpName %37 \"CVSS\"\nOpDecorate %10 Location 0\nOpDecorate %13 BuiltIn Position\nOpDecorate %16 Location 1\nOpDecorate %16 Patch\nOpDecorate %18 Location 1\nOpDecorate %18 Component 1\nOpDecorate %18 Patch\nOpDecorate %21 Location 2\nOpDecorate %21 Patch\nOpDecorate %24 Location 3\nOpDecorate %24 Patch\nOpDecorate %28 Location 4\nOpDecorate %28 Patch\nOpDecorate %31 Location 4\nOpDecorate %31 Component 1\nOpDecorate %31 Patch\nOpDecorate %34 Location 6\nOpDecorate %34 Patch\nOpDecorate %37 Location 8\nOpDecorate %37 Patch\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpTypeVector %5 4\n%12 = OpTypePointer Output %11\n%13 = OpVariable %12 Output\n%14 = OpTypeInt 32 1\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %6\n%18 = OpVariable %17 Input\n%19 = OpTypeVector %14 4\n%20 = OpTypePointer Input %19\n%21 = OpVariable %20 Input\n%22 = OpTypeVector %6 4\n%23 = OpTypePointer Input %22\n%24 = OpVariable %23 Input\n%25 = OpConstant %6 2\n%26 = OpTypeArray %14 %25\n%27 = OpTypePointer Input %26\n%28 = OpVariable %27 Input\n%29 = OpTypeArray %6 %25\n%30 = OpTypePointer Input %29\n%31 = OpVariable %30 Input\n%32 = OpTypeArray %19 %25\n%33 = OpTypePointer Input %32\n%34 = OpVariable %33 Input\n%35 = OpTypeArray %22 %25\n%36 = OpTypePointer Input %35\n%37 = OpVariable %36 Input\n%42 = OpConstant %6 0\n%46 = OpConstant %6 1\n%63 = OpTypePointer Input %5\n%128 = OpConstant %5 1\n%133 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %138\n%138 = OpLabel\n%38 = OpLoad %14 %16\n%39 = OpBitcast %6 %38\n%40 = OpLoad %6 %18\n%41 = OpAccessChain %15 %21 %42\n%43 = OpLoad %14 %41\n%44 = OpBitcast %6 %43\n%45 = OpAccessChain %15 %21 %46\n%47 = OpLoad %14 %45\n%48 = OpBitcast %6 %47\n%49 = OpAccessChain %15 %21 %25\n%50 = OpLoad %14 %49\n%51 = OpBitcast %6 %50\n%52 = OpAccessChain %15 %21 %7\n%53 = OpLoad %14 %52\n%54 = OpBitcast %6 %53\n%55 = OpAccessChain %17 %24 %42\n%56 = OpLoad %6 %55\n%57 = OpAccessChain %17 %24 %46\n%58 = OpLoad %6 %57\n%59 = OpAccessChain %17 %24 %25\n%60 = OpLoad %6 %59\n%61 = OpAccessChain %17 %24 %7\n%62 = OpLoad %6 %61\n%64 = OpAccessChain %63 %10 %42\n%65 = OpLoad %5 %64\n%66 = OpConvertSToF %5 %39\n%67 = OpConvertUToF %5 %40\n%68 = OpConvertSToF %5 %44\n%69 = OpConvertSToF %5 %48\n%70 = OpConvertSToF %5 %51\n%71 = OpConvertSToF %5 %54\n%72 = OpConvertUToF %5 %56\n%73 = OpConvertUToF %5 %58\n%74 = OpConvertUToF %5 %60\n%75 = OpConvertUToF %5 %62\n%76 = OpAccessChain %15 %28 %42\n%77 = OpLoad %14 %76\n%78 = OpBitcast %6 %77\n%79 = OpConvertSToF %5 %78\n%80 = OpAccessChain %17 %31 %46\n%81 = OpLoad %6 %80\n%82 = OpConvertUToF %5 %81\n%83 = OpAccessChain %15 %34 %42 %42\n%84 = OpLoad %14 %83\n%85 = OpBitcast %6 %84\n%86 = OpAccessChain %15 %34 %42 %46\n%87 = OpLoad %14 %86\n%88 = OpBitcast %6 %87\n%89 = OpAccessChain %15 %34 %42 %25\n%90 = OpLoad %14 %89\n%91 = OpBitcast %6 %90\n%92 = OpAccessChain %15 %34 %42 %7\n%93 = OpLoad %14 %92\n%94 = OpBitcast %6 %93\n%95 = OpConvertSToF %5 %85\n%96 = OpConvertSToF %5 %88\n%97 = OpConvertSToF %5 %91\n%98 = OpConvertSToF %5 %94\n%99 = OpAccessChain %17 %37 %46 %42\n%100 = OpLoad %6 %99\n%101 = OpAccessChain %17 %37 %46 %46\n%102 = OpLoad %6 %101\n%103 = OpAccessChain %17 %37 %46 %25\n%104 = OpLoad %6 %103\n%105 = OpAccessChain %17 %37 %46 %7\n%106 = OpLoad %6 %105\n%107 = OpConvertUToF %5 %100\n%108 = OpConvertUToF %5 %102\n%109 = OpConvertUToF %5 %104\n%110 = OpConvertUToF %5 %106\n%111 = OpFAdd %5 %82 %79\n%112 = OpFAdd %5 %72 %68\n%113 = OpFAdd %5 %112 %65\n%114 = OpFAdd %5 %113 %111\n%115 = OpFAdd %5 %114 %95\n%116 = OpFAdd %5 %115 %107\n%117 = OpFAdd %5 %69 %66\n%118 = OpFAdd %5 %117 %73\n%119 = OpFAdd %5 %118 %111\n%120 = OpFAdd %5 %119 %96\n%121 = OpFAdd %5 %120 %108\n%122 = OpFAdd %5 %70 %67\n%123 = OpFAdd %5 %122 %74\n%124 = OpFAdd %5 %123 %111\n%125 = OpFAdd %5 %124 %97\n%126 = OpFAdd %5 %125 %109\n%127 = OpFAdd %5 %71 %128\n%129 = OpFAdd %5 %127 %75\n%130 = OpFAdd %5 %129 %111\n%131 = OpFAdd %5 %130 %98\n%132 = OpFAdd %5 %131 %110\n%134 = OpAccessChain %133 %13 %42\nOpStore %134 %116\n%135 = OpAccessChain %133 %13 %46\nOpStore %135 %121\n%136 = OpAccessChain %133 %13 %25\nOpStore %136 %126\n%137 = OpAccessChain %133 %13 %7\nOpStore %137 %132\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/domain.tese",
    "content": "#version 460\nlayout(triangles) in;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Position.x = (((A[1u][1u] + B[1u]) * gl_TessCoord.y) + ((A[0u][2u] + B[0u]) * gl_TessCoord.x)) + ((A[2u][0u] + B[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 67\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %17 %19 %23\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %17 \"C\"\nOpName %19 \"D\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %17 Location 3\nOpDecorate %17 Patch\nOpDecorate %19 Location 3\nOpDecorate %19 Component 1\nOpDecorate %19 Patch\nOpDecorate %23 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %12 Input\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%21 = OpTypeVector %5 3\n%22 = OpTypePointer Input %21\n%23 = OpVariable %22 Input\n%25 = OpConstant %6 0\n%28 = OpConstant %6 1\n%31 = OpConstant %6 2\n%60 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %65\n%65 = OpLabel\n%20 = OpLoad %5 %19\n%24 = OpAccessChain %18 %23 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %18 %23 %28\n%29 = OpLoad %5 %27\n%30 = OpAccessChain %18 %23 %31\n%32 = OpLoad %5 %30\n%33 = OpAccessChain %18 %13 %25\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %18 %13 %28\n%36 = OpLoad %5 %35\n%37 = OpAccessChain %18 %13 %31\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %18 %11 %25 %31\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %18 %11 %28 %28\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %18 %11 %31 %25\n%44 = OpLoad %5 %43\n%45 = OpFAdd %5 %44 %38\n%46 = OpFMul %5 %45 %32\n%47 = OpFAdd %5 %42 %36\n%48 = OpFMul %5 %47 %29\n%49 = OpFAdd %5 %40 %34\n%50 = OpFMul %5 %49 %26\n%51 = OpFAdd %5 %48 %50\n%52 = OpFAdd %5 %51 %46\n%53 = OpAccessChain %18 %17 %25\n%54 = OpLoad %5 %53\n%55 = OpAccessChain %18 %17 %28\n%56 = OpLoad %5 %55\n%57 = OpFAdd %5 %56 %54\n%58 = OpAccessChain %18 %17 %31\n%59 = OpLoad %5 %58\n%61 = OpAccessChain %60 %16 %25\nOpStore %61 %52\n%62 = OpAccessChain %60 %16 %28\nOpStore %62 %57\n%63 = OpAccessChain %60 %16 %31\nOpStore %63 %59\n%64 = OpAccessChain %60 %16 %7\nOpStore %64 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/extra_output.dual-source-blending.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[3];\n} _12;\n\nlayout(location = 0, index = 0) out vec4 SV_Target;\nlayout(location = 0, index = 1) out vec4 SV_Target_1;\n\nvoid main()\n{\n    SV_Target.x = _12._m0[0u].x;\n    SV_Target.y = _12._m0[0u].y;\n    SV_Target.z = _12._m0[0u].z;\n    SV_Target.w = _12._m0[0u].w;\n    SV_Target_1.x = _12._m0[1u].x;\n    SV_Target_1.y = _12._m0[1u].y;\n    SV_Target_1.z = _12._m0[1u].z;\n    SV_Target_1.w = _12._m0[1u].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"SV_Target\"\nOpName %15 \"SV_Target_1\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Location 0\nOpDecorate %14 Index 0\nOpDecorate %15 Location 0\nOpDecorate %15 Index 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 3\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Output %8\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpConstant %5 0\n%17 = OpTypePointer Uniform %8\n%24 = OpTypePointer Output %7\n%27 = OpConstant %5 1\n%29 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %47\n%47 = OpLabel\n%18 = OpAccessChain %17 %12 %16 %16\n%19 = OpLoad %8 %18\n%20 = OpCompositeExtract %7 %19 0\n%21 = OpCompositeExtract %7 %19 1\n%22 = OpCompositeExtract %7 %19 2\n%23 = OpCompositeExtract %7 %19 3\n%25 = OpAccessChain %24 %14 %16\nOpStore %25 %20\n%26 = OpAccessChain %24 %14 %27\nOpStore %26 %21\n%28 = OpAccessChain %24 %14 %29\nOpStore %28 %22\n%30 = OpAccessChain %24 %14 %6\nOpStore %30 %23\n%31 = OpAccessChain %17 %12 %16 %27\n%32 = OpLoad %8 %31\n%33 = OpCompositeExtract %7 %32 0\n%34 = OpCompositeExtract %7 %32 1\n%35 = OpCompositeExtract %7 %32 2\n%36 = OpCompositeExtract %7 %32 3\n%37 = OpAccessChain %24 %15 %16\nOpStore %37 %33\n%38 = OpAccessChain %24 %15 %27\nOpStore %38 %34\n%39 = OpAccessChain %24 %15 %29\nOpStore %39 %35\n%40 = OpAccessChain %24 %15 %6\nOpStore %40 %36\n%41 = OpAccessChain %17 %12 %16 %29\n%42 = OpLoad %8 %41\n%43 = OpCompositeExtract %7 %42 0\n%44 = OpCompositeExtract %7 %42 1\n%45 = OpCompositeExtract %7 %42 2\n%46 = OpCompositeExtract %7 %42 3\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/extra_output_reordered.dual-source-blending.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[3];\n} _12;\n\nlayout(location = 0, index = 0) out vec4 SV_Target;\nlayout(location = 0, index = 1) out vec4 SV_Target_1;\n\nvoid main()\n{\n    SV_Target.x = _12._m0[0u].x;\n    SV_Target.y = _12._m0[0u].y;\n    SV_Target.z = _12._m0[0u].z;\n    SV_Target.w = _12._m0[0u].w;\n    SV_Target_1.x = _12._m0[1u].x;\n    SV_Target_1.y = _12._m0[1u].y;\n    SV_Target_1.z = _12._m0[1u].z;\n    SV_Target_1.w = _12._m0[1u].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"SV_Target\"\nOpName %15 \"SV_Target_1\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Location 0\nOpDecorate %14 Index 0\nOpDecorate %15 Location 0\nOpDecorate %15 Index 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 3\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Output %8\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpConstant %5 0\n%17 = OpTypePointer Uniform %8\n%24 = OpTypePointer Output %7\n%27 = OpConstant %5 1\n%29 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %47\n%47 = OpLabel\n%18 = OpAccessChain %17 %12 %16 %16\n%19 = OpLoad %8 %18\n%20 = OpCompositeExtract %7 %19 0\n%21 = OpCompositeExtract %7 %19 1\n%22 = OpCompositeExtract %7 %19 2\n%23 = OpCompositeExtract %7 %19 3\n%25 = OpAccessChain %24 %14 %16\nOpStore %25 %20\n%26 = OpAccessChain %24 %14 %27\nOpStore %26 %21\n%28 = OpAccessChain %24 %14 %29\nOpStore %28 %22\n%30 = OpAccessChain %24 %14 %6\nOpStore %30 %23\n%31 = OpAccessChain %17 %12 %16 %27\n%32 = OpLoad %8 %31\n%33 = OpCompositeExtract %7 %32 0\n%34 = OpCompositeExtract %7 %32 1\n%35 = OpCompositeExtract %7 %32 2\n%36 = OpCompositeExtract %7 %32 3\n%37 = OpAccessChain %24 %15 %16\nOpStore %37 %33\n%38 = OpAccessChain %24 %15 %27\nOpStore %38 %34\n%39 = OpAccessChain %24 %15 %29\nOpStore %39 %35\n%40 = OpAccessChain %24 %15 %6\nOpStore %40 %36\n%41 = OpAccessChain %17 %12 %16 %29\n%42 = OpLoad %8 %41\n%43 = OpCompositeExtract %7 %42 0\n%44 = OpCompositeExtract %7 %42 1\n%45 = OpCompositeExtract %7 %42 2\n%46 = OpCompositeExtract %7 %42 3\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-clip-cull.geom",
    "content": "#version 460\nlayout(triangles) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nout float gl_ClipDistance[4];\n\nvoid main()\n{\n    gl_ClipDistance[0u] = gl_in[0u].gl_ClipDistance[0u];\n    gl_ClipDistance[1u] = gl_in[0u].gl_ClipDistance[1u];\n    gl_ClipDistance[2u] = gl_in[0u].gl_ClipDistance[2u];\n    gl_ClipDistance[3u] = gl_in[0u].gl_ClipDistance[3u];\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    gl_ClipDistance[0u] = gl_in[1u].gl_ClipDistance[0u];\n    gl_ClipDistance[1u] = gl_in[1u].gl_ClipDistance[1u];\n    gl_ClipDistance[2u] = gl_in[1u].gl_ClipDistance[2u];\n    gl_ClipDistance[3u] = gl_in[1u].gl_ClipDistance[3u];\n    gl_Position.x = gl_in[1u].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    float _68 = gl_in[1u].gl_Position.x + 0.0199999995529651641845703125;\n    gl_ClipDistance[0u] = gl_in[1u].gl_ClipDistance[0u];\n    gl_ClipDistance[1u] = gl_in[1u].gl_ClipDistance[1u];\n    gl_ClipDistance[2u] = gl_in[1u].gl_ClipDistance[2u];\n    gl_ClipDistance[3u] = gl_in[1u].gl_ClipDistance[3u];\n    gl_Position.x = _68;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    EndPrimitive();\n    gl_ClipDistance[0u] = gl_in[1u].gl_ClipDistance[0u];\n    gl_ClipDistance[1u] = gl_in[1u].gl_ClipDistance[1u];\n    gl_ClipDistance[2u] = gl_in[1u].gl_ClipDistance[2u];\n    gl_ClipDistance[3u] = gl_in[1u].gl_ClipDistance[3u];\n    gl_Position.x = _68;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    gl_ClipDistance[0u] = gl_in[1u].gl_ClipDistance[0u];\n    gl_ClipDistance[1u] = gl_in[1u].gl_ClipDistance[1u];\n    gl_ClipDistance[2u] = gl_in[1u].gl_ClipDistance[2u];\n    gl_ClipDistance[3u] = gl_in[1u].gl_ClipDistance[3u];\n    gl_Position.x = _68;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    gl_ClipDistance[0u] = gl_in[1u].gl_ClipDistance[0u];\n    gl_ClipDistance[1u] = gl_in[1u].gl_ClipDistance[1u];\n    gl_ClipDistance[2u] = gl_in[1u].gl_ClipDistance[2u];\n    gl_ClipDistance[3u] = gl_in[1u].gl_ClipDistance[3u];\n    gl_Position.x = _68;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 104\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability ClipDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %16 %18 %20\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 6\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputTriangleStrip\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %18 \"SV_Position\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %16 BuiltIn ClipDistance\nOpDecorate %18 BuiltIn Position\nOpDecorate %20 BuiltIn ClipDistance\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpConstant %7 4\n%13 = OpTypeArray %5 %12\n%14 = OpTypeArray %13 %8\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Output %6\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Output %13\n%20 = OpVariable %19 Output\n%21 = OpTypePointer Input %5\n%23 = OpConstant %7 0\n%26 = OpConstant %7 1\n%29 = OpConstant %7 2\n%41 = OpTypePointer Output %5\n%59 = OpConstant %5 0.00999999978\n%69 = OpConstant %5 0.0199999996\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %102\n%102 = OpLabel\n%22 = OpAccessChain %21 %16 %23 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %21 %16 %23 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %21 %16 %23 %29\n%30 = OpLoad %5 %28\n%31 = OpAccessChain %21 %16 %23 %8\n%32 = OpLoad %5 %31\n%33 = OpAccessChain %21 %11 %26 %23\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %21 %11 %26 %26\n%36 = OpLoad %5 %35\n%37 = OpAccessChain %21 %11 %26 %29\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %21 %11 %26 %8\n%40 = OpLoad %5 %39\n%42 = OpAccessChain %41 %20 %23\nOpStore %42 %24\n%43 = OpAccessChain %41 %20 %26\nOpStore %43 %27\n%44 = OpAccessChain %41 %20 %29\nOpStore %44 %30\n%45 = OpAccessChain %41 %20 %8\nOpStore %45 %32\n%46 = OpAccessChain %41 %18 %23\nOpStore %46 %34\n%47 = OpAccessChain %41 %18 %26\nOpStore %47 %36\n%48 = OpAccessChain %41 %18 %29\nOpStore %48 %38\n%49 = OpAccessChain %41 %18 %8\nOpStore %49 %40\nOpEmitVertex\n%50 = OpAccessChain %21 %16 %26 %23\n%51 = OpLoad %5 %50\n%52 = OpAccessChain %21 %16 %26 %26\n%53 = OpLoad %5 %52\n%54 = OpAccessChain %21 %16 %26 %29\n%55 = OpLoad %5 %54\n%56 = OpAccessChain %21 %16 %26 %8\n%57 = OpLoad %5 %56\n%58 = OpFAdd %5 %34 %59\n%60 = OpAccessChain %41 %20 %23\nOpStore %60 %51\n%61 = OpAccessChain %41 %20 %26\nOpStore %61 %53\n%62 = OpAccessChain %41 %20 %29\nOpStore %62 %55\n%63 = OpAccessChain %41 %20 %8\nOpStore %63 %57\n%64 = OpAccessChain %41 %18 %23\nOpStore %64 %58\n%65 = OpAccessChain %41 %18 %26\nOpStore %65 %36\n%66 = OpAccessChain %41 %18 %29\nOpStore %66 %38\n%67 = OpAccessChain %41 %18 %8\nOpStore %67 %40\nOpEmitVertex\n%68 = OpFAdd %5 %34 %69\n%70 = OpAccessChain %41 %20 %23\nOpStore %70 %51\n%71 = OpAccessChain %41 %20 %26\nOpStore %71 %53\n%72 = OpAccessChain %41 %20 %29\nOpStore %72 %55\n%73 = OpAccessChain %41 %20 %8\nOpStore %73 %57\n%74 = OpAccessChain %41 %18 %23\nOpStore %74 %68\n%75 = OpAccessChain %41 %18 %26\nOpStore %75 %36\n%76 = OpAccessChain %41 %18 %29\nOpStore %76 %38\n%77 = OpAccessChain %41 %18 %8\nOpStore %77 %40\nOpEmitVertex\nOpEndPrimitive\n%78 = OpAccessChain %41 %20 %23\nOpStore %78 %51\n%79 = OpAccessChain %41 %20 %26\nOpStore %79 %53\n%80 = OpAccessChain %41 %20 %29\nOpStore %80 %55\n%81 = OpAccessChain %41 %20 %8\nOpStore %81 %57\n%82 = OpAccessChain %41 %18 %23\nOpStore %82 %68\n%83 = OpAccessChain %41 %18 %26\nOpStore %83 %36\n%84 = OpAccessChain %41 %18 %29\nOpStore %84 %38\n%85 = OpAccessChain %41 %18 %8\nOpStore %85 %40\nOpEmitVertex\n%86 = OpAccessChain %41 %20 %23\nOpStore %86 %51\n%87 = OpAccessChain %41 %20 %26\nOpStore %87 %53\n%88 = OpAccessChain %41 %20 %29\nOpStore %88 %55\n%89 = OpAccessChain %41 %20 %8\nOpStore %89 %57\n%90 = OpAccessChain %41 %18 %23\nOpStore %90 %68\n%91 = OpAccessChain %41 %18 %26\nOpStore %91 %36\n%92 = OpAccessChain %41 %18 %29\nOpStore %92 %38\n%93 = OpAccessChain %41 %18 %8\nOpStore %93 %40\nOpEmitVertex\n%94 = OpAccessChain %41 %20 %23\nOpStore %94 %51\n%95 = OpAccessChain %41 %20 %26\nOpStore %95 %53\n%96 = OpAccessChain %41 %20 %29\nOpStore %96 %55\n%97 = OpAccessChain %41 %20 %8\nOpStore %97 %57\n%98 = OpAccessChain %41 %18 %23\nOpStore %98 %68\n%99 = OpAccessChain %41 %18 %26\nOpStore %99 %36\n%100 = OpAccessChain %41 %18 %29\nOpStore %100 %38\n%101 = OpAccessChain %41 %18 %8\nOpStore %101 %40\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-input-line.geom",
    "content": "#version 460\nlayout(lines) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nlayout(location = 0) in vec4 TEXCOORD[2];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    float _55 = gl_in[1u].gl_Position.x + 0.0199999995529651641845703125;\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    EndPrimitive();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 6\nOpExecutionMode %3 InputLines\nOpExecutionMode %3 OutputTriangleStrip\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 2\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%26 = OpConstant %7 3\n%36 = OpTypePointer Output %5\n%46 = OpConstant %5 0.00999999978\n%56 = OpConstant %5 0.0199999996\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %89\n%89 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %8\n%24 = OpLoad %5 %23\n%25 = OpAccessChain %16 %11 %18 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %16 %12 %21 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %21 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %21 %8\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %21 %26\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %21\nOpStore %38 %22\n%39 = OpAccessChain %36 %14 %8\nOpStore %39 %24\n%40 = OpAccessChain %36 %14 %26\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %21\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %8\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %26\nOpStore %44 %35\nOpEmitVertex\n%45 = OpFAdd %5 %29 %46\n%47 = OpAccessChain %36 %14 %18\nOpStore %47 %19\n%48 = OpAccessChain %36 %14 %21\nOpStore %48 %22\n%49 = OpAccessChain %36 %14 %8\nOpStore %49 %24\n%50 = OpAccessChain %36 %14 %26\nOpStore %50 %27\n%51 = OpAccessChain %36 %15 %18\nOpStore %51 %45\n%52 = OpAccessChain %36 %15 %21\nOpStore %52 %31\n%53 = OpAccessChain %36 %15 %8\nOpStore %53 %33\n%54 = OpAccessChain %36 %15 %26\nOpStore %54 %35\nOpEmitVertex\n%55 = OpFAdd %5 %29 %56\n%57 = OpAccessChain %36 %14 %18\nOpStore %57 %19\n%58 = OpAccessChain %36 %14 %21\nOpStore %58 %22\n%59 = OpAccessChain %36 %14 %8\nOpStore %59 %24\n%60 = OpAccessChain %36 %14 %26\nOpStore %60 %27\n%61 = OpAccessChain %36 %15 %18\nOpStore %61 %55\n%62 = OpAccessChain %36 %15 %21\nOpStore %62 %31\n%63 = OpAccessChain %36 %15 %8\nOpStore %63 %33\n%64 = OpAccessChain %36 %15 %26\nOpStore %64 %35\nOpEmitVertex\nOpEndPrimitive\n%65 = OpAccessChain %36 %14 %18\nOpStore %65 %19\n%66 = OpAccessChain %36 %14 %21\nOpStore %66 %22\n%67 = OpAccessChain %36 %14 %8\nOpStore %67 %24\n%68 = OpAccessChain %36 %14 %26\nOpStore %68 %27\n%69 = OpAccessChain %36 %15 %18\nOpStore %69 %55\n%70 = OpAccessChain %36 %15 %21\nOpStore %70 %31\n%71 = OpAccessChain %36 %15 %8\nOpStore %71 %33\n%72 = OpAccessChain %36 %15 %26\nOpStore %72 %35\nOpEmitVertex\n%73 = OpAccessChain %36 %14 %18\nOpStore %73 %19\n%74 = OpAccessChain %36 %14 %21\nOpStore %74 %22\n%75 = OpAccessChain %36 %14 %8\nOpStore %75 %24\n%76 = OpAccessChain %36 %14 %26\nOpStore %76 %27\n%77 = OpAccessChain %36 %15 %18\nOpStore %77 %55\n%78 = OpAccessChain %36 %15 %21\nOpStore %78 %31\n%79 = OpAccessChain %36 %15 %8\nOpStore %79 %33\n%80 = OpAccessChain %36 %15 %26\nOpStore %80 %35\nOpEmitVertex\n%81 = OpAccessChain %36 %14 %18\nOpStore %81 %19\n%82 = OpAccessChain %36 %14 %21\nOpStore %82 %22\n%83 = OpAccessChain %36 %14 %8\nOpStore %83 %24\n%84 = OpAccessChain %36 %14 %26\nOpStore %84 %27\n%85 = OpAccessChain %36 %15 %18\nOpStore %85 %55\n%86 = OpAccessChain %36 %15 %21\nOpStore %86 %31\n%87 = OpAccessChain %36 %15 %8\nOpStore %87 %33\n%88 = OpAccessChain %36 %15 %26\nOpStore %88 %35\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-input-lineadj.geom",
    "content": "#version 460\nlayout(lines_adjacency) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nlayout(location = 0) in vec4 TEXCOORD[4];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[3u].gl_Position.x;\n    gl_Position.y = gl_in[3u].gl_Position.y;\n    gl_Position.z = gl_in[3u].gl_Position.z;\n    gl_Position.w = gl_in[3u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[3u].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[3u].gl_Position.y;\n    gl_Position.z = gl_in[3u].gl_Position.z;\n    gl_Position.w = gl_in[3u].gl_Position.w;\n    EmitVertex();\n    float _56 = gl_in[3u].gl_Position.x + 0.0199999995529651641845703125;\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _56;\n    gl_Position.y = gl_in[3u].gl_Position.y;\n    gl_Position.z = gl_in[3u].gl_Position.z;\n    gl_Position.w = gl_in[3u].gl_Position.w;\n    EmitVertex();\n    EndPrimitive();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _56;\n    gl_Position.y = gl_in[3u].gl_Position.y;\n    gl_Position.z = gl_in[3u].gl_Position.z;\n    gl_Position.w = gl_in[3u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _56;\n    gl_Position.y = gl_in[3u].gl_Position.y;\n    gl_Position.z = gl_in[3u].gl_Position.z;\n    gl_Position.w = gl_in[3u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _56;\n    gl_Position.y = gl_in[3u].gl_Position.y;\n    gl_Position.z = gl_in[3u].gl_Position.z;\n    gl_Position.w = gl_in[3u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 92\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 6\nOpExecutionMode %3 InputLinesAdjacency\nOpExecutionMode %3 OutputTriangleStrip\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 4\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%27 = OpConstant %7 3\n%37 = OpTypePointer Output %5\n%47 = OpConstant %5 0.00999999978\n%57 = OpConstant %5 0.0199999996\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %90\n%90 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %27\n%28 = OpLoad %5 %26\n%29 = OpAccessChain %16 %12 %27 %18\n%30 = OpLoad %5 %29\n%31 = OpAccessChain %16 %12 %27 %21\n%32 = OpLoad %5 %31\n%33 = OpAccessChain %16 %12 %27 %24\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %16 %12 %27 %27\n%36 = OpLoad %5 %35\n%38 = OpAccessChain %37 %14 %18\nOpStore %38 %19\n%39 = OpAccessChain %37 %14 %21\nOpStore %39 %22\n%40 = OpAccessChain %37 %14 %24\nOpStore %40 %25\n%41 = OpAccessChain %37 %14 %27\nOpStore %41 %28\n%42 = OpAccessChain %37 %15 %18\nOpStore %42 %30\n%43 = OpAccessChain %37 %15 %21\nOpStore %43 %32\n%44 = OpAccessChain %37 %15 %24\nOpStore %44 %34\n%45 = OpAccessChain %37 %15 %27\nOpStore %45 %36\nOpEmitVertex\n%46 = OpFAdd %5 %30 %47\n%48 = OpAccessChain %37 %14 %18\nOpStore %48 %19\n%49 = OpAccessChain %37 %14 %21\nOpStore %49 %22\n%50 = OpAccessChain %37 %14 %24\nOpStore %50 %25\n%51 = OpAccessChain %37 %14 %27\nOpStore %51 %28\n%52 = OpAccessChain %37 %15 %18\nOpStore %52 %46\n%53 = OpAccessChain %37 %15 %21\nOpStore %53 %32\n%54 = OpAccessChain %37 %15 %24\nOpStore %54 %34\n%55 = OpAccessChain %37 %15 %27\nOpStore %55 %36\nOpEmitVertex\n%56 = OpFAdd %5 %30 %57\n%58 = OpAccessChain %37 %14 %18\nOpStore %58 %19\n%59 = OpAccessChain %37 %14 %21\nOpStore %59 %22\n%60 = OpAccessChain %37 %14 %24\nOpStore %60 %25\n%61 = OpAccessChain %37 %14 %27\nOpStore %61 %28\n%62 = OpAccessChain %37 %15 %18\nOpStore %62 %56\n%63 = OpAccessChain %37 %15 %21\nOpStore %63 %32\n%64 = OpAccessChain %37 %15 %24\nOpStore %64 %34\n%65 = OpAccessChain %37 %15 %27\nOpStore %65 %36\nOpEmitVertex\nOpEndPrimitive\n%66 = OpAccessChain %37 %14 %18\nOpStore %66 %19\n%67 = OpAccessChain %37 %14 %21\nOpStore %67 %22\n%68 = OpAccessChain %37 %14 %24\nOpStore %68 %25\n%69 = OpAccessChain %37 %14 %27\nOpStore %69 %28\n%70 = OpAccessChain %37 %15 %18\nOpStore %70 %56\n%71 = OpAccessChain %37 %15 %21\nOpStore %71 %32\n%72 = OpAccessChain %37 %15 %24\nOpStore %72 %34\n%73 = OpAccessChain %37 %15 %27\nOpStore %73 %36\nOpEmitVertex\n%74 = OpAccessChain %37 %14 %18\nOpStore %74 %19\n%75 = OpAccessChain %37 %14 %21\nOpStore %75 %22\n%76 = OpAccessChain %37 %14 %24\nOpStore %76 %25\n%77 = OpAccessChain %37 %14 %27\nOpStore %77 %28\n%78 = OpAccessChain %37 %15 %18\nOpStore %78 %56\n%79 = OpAccessChain %37 %15 %21\nOpStore %79 %32\n%80 = OpAccessChain %37 %15 %24\nOpStore %80 %34\n%81 = OpAccessChain %37 %15 %27\nOpStore %81 %36\nOpEmitVertex\n%82 = OpAccessChain %37 %14 %18\nOpStore %82 %19\n%83 = OpAccessChain %37 %14 %21\nOpStore %83 %22\n%84 = OpAccessChain %37 %14 %24\nOpStore %84 %25\n%85 = OpAccessChain %37 %14 %27\nOpStore %85 %28\n%86 = OpAccessChain %37 %15 %18\nOpStore %86 %56\n%87 = OpAccessChain %37 %15 %21\nOpStore %87 %32\n%88 = OpAccessChain %37 %15 %24\nOpStore %88 %34\n%89 = OpAccessChain %37 %15 %27\nOpStore %89 %36\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-input-point.geom",
    "content": "#version 460\nlayout(points) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nlayout(location = 0) in vec4 TEXCOORD[1];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[0u].gl_Position.x;\n    gl_Position.y = gl_in[0u].gl_Position.y;\n    gl_Position.z = gl_in[0u].gl_Position.z;\n    gl_Position.w = gl_in[0u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[0u].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[0u].gl_Position.y;\n    gl_Position.z = gl_in[0u].gl_Position.z;\n    gl_Position.w = gl_in[0u].gl_Position.w;\n    EmitVertex();\n    float _55 = gl_in[0u].gl_Position.x + 0.0199999995529651641845703125;\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[0u].gl_Position.y;\n    gl_Position.z = gl_in[0u].gl_Position.z;\n    gl_Position.w = gl_in[0u].gl_Position.w;\n    EmitVertex();\n    EndPrimitive();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[0u].gl_Position.y;\n    gl_Position.z = gl_in[0u].gl_Position.z;\n    gl_Position.w = gl_in[0u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[0u].gl_Position.y;\n    gl_Position.z = gl_in[0u].gl_Position.z;\n    gl_Position.w = gl_in[0u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[0u].gl_Position.y;\n    gl_Position.z = gl_in[0u].gl_Position.z;\n    gl_Position.w = gl_in[0u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 6\nOpExecutionMode %3 InputPoints\nOpExecutionMode %3 OutputTriangleStrip\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 1\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%23 = OpConstant %7 2\n%26 = OpConstant %7 3\n%36 = OpTypePointer Output %5\n%46 = OpConstant %5 0.00999999978\n%56 = OpConstant %5 0.0199999996\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %89\n%89 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %8\n%21 = OpLoad %5 %20\n%22 = OpAccessChain %16 %11 %18 %23\n%24 = OpLoad %5 %22\n%25 = OpAccessChain %16 %11 %18 %26\n%27 = OpLoad %5 %25\n%28 = OpAccessChain %16 %12 %18 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %18 %8\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %18 %23\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %18 %26\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %8\nOpStore %38 %21\n%39 = OpAccessChain %36 %14 %23\nOpStore %39 %24\n%40 = OpAccessChain %36 %14 %26\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %8\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %23\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %26\nOpStore %44 %35\nOpEmitVertex\n%45 = OpFAdd %5 %29 %46\n%47 = OpAccessChain %36 %14 %18\nOpStore %47 %19\n%48 = OpAccessChain %36 %14 %8\nOpStore %48 %21\n%49 = OpAccessChain %36 %14 %23\nOpStore %49 %24\n%50 = OpAccessChain %36 %14 %26\nOpStore %50 %27\n%51 = OpAccessChain %36 %15 %18\nOpStore %51 %45\n%52 = OpAccessChain %36 %15 %8\nOpStore %52 %31\n%53 = OpAccessChain %36 %15 %23\nOpStore %53 %33\n%54 = OpAccessChain %36 %15 %26\nOpStore %54 %35\nOpEmitVertex\n%55 = OpFAdd %5 %29 %56\n%57 = OpAccessChain %36 %14 %18\nOpStore %57 %19\n%58 = OpAccessChain %36 %14 %8\nOpStore %58 %21\n%59 = OpAccessChain %36 %14 %23\nOpStore %59 %24\n%60 = OpAccessChain %36 %14 %26\nOpStore %60 %27\n%61 = OpAccessChain %36 %15 %18\nOpStore %61 %55\n%62 = OpAccessChain %36 %15 %8\nOpStore %62 %31\n%63 = OpAccessChain %36 %15 %23\nOpStore %63 %33\n%64 = OpAccessChain %36 %15 %26\nOpStore %64 %35\nOpEmitVertex\nOpEndPrimitive\n%65 = OpAccessChain %36 %14 %18\nOpStore %65 %19\n%66 = OpAccessChain %36 %14 %8\nOpStore %66 %21\n%67 = OpAccessChain %36 %14 %23\nOpStore %67 %24\n%68 = OpAccessChain %36 %14 %26\nOpStore %68 %27\n%69 = OpAccessChain %36 %15 %18\nOpStore %69 %55\n%70 = OpAccessChain %36 %15 %8\nOpStore %70 %31\n%71 = OpAccessChain %36 %15 %23\nOpStore %71 %33\n%72 = OpAccessChain %36 %15 %26\nOpStore %72 %35\nOpEmitVertex\n%73 = OpAccessChain %36 %14 %18\nOpStore %73 %19\n%74 = OpAccessChain %36 %14 %8\nOpStore %74 %21\n%75 = OpAccessChain %36 %14 %23\nOpStore %75 %24\n%76 = OpAccessChain %36 %14 %26\nOpStore %76 %27\n%77 = OpAccessChain %36 %15 %18\nOpStore %77 %55\n%78 = OpAccessChain %36 %15 %8\nOpStore %78 %31\n%79 = OpAccessChain %36 %15 %23\nOpStore %79 %33\n%80 = OpAccessChain %36 %15 %26\nOpStore %80 %35\nOpEmitVertex\n%81 = OpAccessChain %36 %14 %18\nOpStore %81 %19\n%82 = OpAccessChain %36 %14 %8\nOpStore %82 %21\n%83 = OpAccessChain %36 %14 %23\nOpStore %83 %24\n%84 = OpAccessChain %36 %14 %26\nOpStore %84 %27\n%85 = OpAccessChain %36 %15 %18\nOpStore %85 %55\n%86 = OpAccessChain %36 %15 %8\nOpStore %86 %31\n%87 = OpAccessChain %36 %15 %23\nOpStore %87 %33\n%88 = OpAccessChain %36 %15 %26\nOpStore %88 %35\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-input-triangle.geom",
    "content": "#version 460\nlayout(triangles) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    float _55 = gl_in[1u].gl_Position.x + 0.0199999995529651641845703125;\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    EndPrimitive();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _55;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 6\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputTriangleStrip\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%36 = OpTypePointer Output %5\n%46 = OpConstant %5 0.00999999978\n%56 = OpConstant %5 0.0199999996\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %89\n%89 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %8\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %16 %12 %21 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %21 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %21 %24\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %21 %8\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %21\nOpStore %38 %22\n%39 = OpAccessChain %36 %14 %24\nOpStore %39 %25\n%40 = OpAccessChain %36 %14 %8\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %21\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %24\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %8\nOpStore %44 %35\nOpEmitVertex\n%45 = OpFAdd %5 %29 %46\n%47 = OpAccessChain %36 %14 %18\nOpStore %47 %19\n%48 = OpAccessChain %36 %14 %21\nOpStore %48 %22\n%49 = OpAccessChain %36 %14 %24\nOpStore %49 %25\n%50 = OpAccessChain %36 %14 %8\nOpStore %50 %27\n%51 = OpAccessChain %36 %15 %18\nOpStore %51 %45\n%52 = OpAccessChain %36 %15 %21\nOpStore %52 %31\n%53 = OpAccessChain %36 %15 %24\nOpStore %53 %33\n%54 = OpAccessChain %36 %15 %8\nOpStore %54 %35\nOpEmitVertex\n%55 = OpFAdd %5 %29 %56\n%57 = OpAccessChain %36 %14 %18\nOpStore %57 %19\n%58 = OpAccessChain %36 %14 %21\nOpStore %58 %22\n%59 = OpAccessChain %36 %14 %24\nOpStore %59 %25\n%60 = OpAccessChain %36 %14 %8\nOpStore %60 %27\n%61 = OpAccessChain %36 %15 %18\nOpStore %61 %55\n%62 = OpAccessChain %36 %15 %21\nOpStore %62 %31\n%63 = OpAccessChain %36 %15 %24\nOpStore %63 %33\n%64 = OpAccessChain %36 %15 %8\nOpStore %64 %35\nOpEmitVertex\nOpEndPrimitive\n%65 = OpAccessChain %36 %14 %18\nOpStore %65 %19\n%66 = OpAccessChain %36 %14 %21\nOpStore %66 %22\n%67 = OpAccessChain %36 %14 %24\nOpStore %67 %25\n%68 = OpAccessChain %36 %14 %8\nOpStore %68 %27\n%69 = OpAccessChain %36 %15 %18\nOpStore %69 %55\n%70 = OpAccessChain %36 %15 %21\nOpStore %70 %31\n%71 = OpAccessChain %36 %15 %24\nOpStore %71 %33\n%72 = OpAccessChain %36 %15 %8\nOpStore %72 %35\nOpEmitVertex\n%73 = OpAccessChain %36 %14 %18\nOpStore %73 %19\n%74 = OpAccessChain %36 %14 %21\nOpStore %74 %22\n%75 = OpAccessChain %36 %14 %24\nOpStore %75 %25\n%76 = OpAccessChain %36 %14 %8\nOpStore %76 %27\n%77 = OpAccessChain %36 %15 %18\nOpStore %77 %55\n%78 = OpAccessChain %36 %15 %21\nOpStore %78 %31\n%79 = OpAccessChain %36 %15 %24\nOpStore %79 %33\n%80 = OpAccessChain %36 %15 %8\nOpStore %80 %35\nOpEmitVertex\n%81 = OpAccessChain %36 %14 %18\nOpStore %81 %19\n%82 = OpAccessChain %36 %14 %21\nOpStore %82 %22\n%83 = OpAccessChain %36 %14 %24\nOpStore %83 %25\n%84 = OpAccessChain %36 %14 %8\nOpStore %84 %27\n%85 = OpAccessChain %36 %15 %18\nOpStore %85 %55\n%86 = OpAccessChain %36 %15 %21\nOpStore %86 %31\n%87 = OpAccessChain %36 %15 %24\nOpStore %87 %33\n%88 = OpAccessChain %36 %15 %8\nOpStore %88 %35\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-input-triangleadj.geom",
    "content": "#version 460\nlayout(triangles_adjacency) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nlayout(location = 0) in vec4 TEXCOORD[6];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[5u].gl_Position.x;\n    gl_Position.y = gl_in[5u].gl_Position.y;\n    gl_Position.z = gl_in[5u].gl_Position.z;\n    gl_Position.w = gl_in[5u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[5u].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[5u].gl_Position.y;\n    gl_Position.z = gl_in[5u].gl_Position.z;\n    gl_Position.w = gl_in[5u].gl_Position.w;\n    EmitVertex();\n    float _57 = gl_in[5u].gl_Position.x + 0.0199999995529651641845703125;\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _57;\n    gl_Position.y = gl_in[5u].gl_Position.y;\n    gl_Position.z = gl_in[5u].gl_Position.z;\n    gl_Position.w = gl_in[5u].gl_Position.w;\n    EmitVertex();\n    EndPrimitive();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _57;\n    gl_Position.y = gl_in[5u].gl_Position.y;\n    gl_Position.z = gl_in[5u].gl_Position.z;\n    gl_Position.w = gl_in[5u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _57;\n    gl_Position.y = gl_in[5u].gl_Position.y;\n    gl_Position.z = gl_in[5u].gl_Position.z;\n    gl_Position.w = gl_in[5u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = _57;\n    gl_Position.y = gl_in[5u].gl_Position.y;\n    gl_Position.z = gl_in[5u].gl_Position.z;\n    gl_Position.w = gl_in[5u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 93\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 6\nOpExecutionMode %3 InputTrianglesAdjacency\nOpExecutionMode %3 OutputTriangleStrip\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 6\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%27 = OpConstant %7 3\n%30 = OpConstant %7 5\n%38 = OpTypePointer Output %5\n%48 = OpConstant %5 0.00999999978\n%58 = OpConstant %5 0.0199999996\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %91\n%91 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %27\n%28 = OpLoad %5 %26\n%29 = OpAccessChain %16 %12 %30 %18\n%31 = OpLoad %5 %29\n%32 = OpAccessChain %16 %12 %30 %21\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %30 %24\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %16 %12 %30 %27\n%37 = OpLoad %5 %36\n%39 = OpAccessChain %38 %14 %18\nOpStore %39 %19\n%40 = OpAccessChain %38 %14 %21\nOpStore %40 %22\n%41 = OpAccessChain %38 %14 %24\nOpStore %41 %25\n%42 = OpAccessChain %38 %14 %27\nOpStore %42 %28\n%43 = OpAccessChain %38 %15 %18\nOpStore %43 %31\n%44 = OpAccessChain %38 %15 %21\nOpStore %44 %33\n%45 = OpAccessChain %38 %15 %24\nOpStore %45 %35\n%46 = OpAccessChain %38 %15 %27\nOpStore %46 %37\nOpEmitVertex\n%47 = OpFAdd %5 %31 %48\n%49 = OpAccessChain %38 %14 %18\nOpStore %49 %19\n%50 = OpAccessChain %38 %14 %21\nOpStore %50 %22\n%51 = OpAccessChain %38 %14 %24\nOpStore %51 %25\n%52 = OpAccessChain %38 %14 %27\nOpStore %52 %28\n%53 = OpAccessChain %38 %15 %18\nOpStore %53 %47\n%54 = OpAccessChain %38 %15 %21\nOpStore %54 %33\n%55 = OpAccessChain %38 %15 %24\nOpStore %55 %35\n%56 = OpAccessChain %38 %15 %27\nOpStore %56 %37\nOpEmitVertex\n%57 = OpFAdd %5 %31 %58\n%59 = OpAccessChain %38 %14 %18\nOpStore %59 %19\n%60 = OpAccessChain %38 %14 %21\nOpStore %60 %22\n%61 = OpAccessChain %38 %14 %24\nOpStore %61 %25\n%62 = OpAccessChain %38 %14 %27\nOpStore %62 %28\n%63 = OpAccessChain %38 %15 %18\nOpStore %63 %57\n%64 = OpAccessChain %38 %15 %21\nOpStore %64 %33\n%65 = OpAccessChain %38 %15 %24\nOpStore %65 %35\n%66 = OpAccessChain %38 %15 %27\nOpStore %66 %37\nOpEmitVertex\nOpEndPrimitive\n%67 = OpAccessChain %38 %14 %18\nOpStore %67 %19\n%68 = OpAccessChain %38 %14 %21\nOpStore %68 %22\n%69 = OpAccessChain %38 %14 %24\nOpStore %69 %25\n%70 = OpAccessChain %38 %14 %27\nOpStore %70 %28\n%71 = OpAccessChain %38 %15 %18\nOpStore %71 %57\n%72 = OpAccessChain %38 %15 %21\nOpStore %72 %33\n%73 = OpAccessChain %38 %15 %24\nOpStore %73 %35\n%74 = OpAccessChain %38 %15 %27\nOpStore %74 %37\nOpEmitVertex\n%75 = OpAccessChain %38 %14 %18\nOpStore %75 %19\n%76 = OpAccessChain %38 %14 %21\nOpStore %76 %22\n%77 = OpAccessChain %38 %14 %24\nOpStore %77 %25\n%78 = OpAccessChain %38 %14 %27\nOpStore %78 %28\n%79 = OpAccessChain %38 %15 %18\nOpStore %79 %57\n%80 = OpAccessChain %38 %15 %21\nOpStore %80 %33\n%81 = OpAccessChain %38 %15 %24\nOpStore %81 %35\n%82 = OpAccessChain %38 %15 %27\nOpStore %82 %37\nOpEmitVertex\n%83 = OpAccessChain %38 %14 %18\nOpStore %83 %19\n%84 = OpAccessChain %38 %14 %21\nOpStore %84 %22\n%85 = OpAccessChain %38 %14 %24\nOpStore %85 %25\n%86 = OpAccessChain %38 %14 %27\nOpStore %86 %28\n%87 = OpAccessChain %38 %15 %18\nOpStore %87 %57\n%88 = OpAccessChain %38 %15 %21\nOpStore %88 %33\n%89 = OpAccessChain %38 %15 %24\nOpStore %89 %35\n%90 = OpAccessChain %38 %15 %27\nOpStore %90 %37\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-instancing.geom",
    "content": "#version 460\nlayout(invocations = 2, triangles) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    uint _31 = gl_InvocationID ^ 1u;\n    TEXCOORD_1.x = TEXCOORD[gl_InvocationID].x;\n    TEXCOORD_1.y = TEXCOORD[gl_InvocationID].y;\n    TEXCOORD_1.z = TEXCOORD[gl_InvocationID].z;\n    TEXCOORD_1.w = TEXCOORD[gl_InvocationID].w;\n    gl_Position.x = gl_in[_31].gl_Position.x;\n    gl_Position.y = gl_in[_31].gl_Position.y;\n    gl_Position.z = gl_in[_31].gl_Position.z;\n    gl_Position.w = gl_in[_31].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[gl_InvocationID].x;\n    TEXCOORD_1.y = TEXCOORD[gl_InvocationID].y;\n    TEXCOORD_1.z = TEXCOORD[gl_InvocationID].z;\n    TEXCOORD_1.w = TEXCOORD[gl_InvocationID].w;\n    gl_Position.x = gl_in[_31].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[_31].gl_Position.y;\n    gl_Position.z = gl_in[_31].gl_Position.z;\n    gl_Position.w = gl_in[_31].gl_Position.w;\n    EmitVertex();\n    float _59 = gl_in[_31].gl_Position.x + 0.0199999995529651641845703125;\n    TEXCOORD_1.x = TEXCOORD[gl_InvocationID].x;\n    TEXCOORD_1.y = TEXCOORD[gl_InvocationID].y;\n    TEXCOORD_1.z = TEXCOORD[gl_InvocationID].z;\n    TEXCOORD_1.w = TEXCOORD[gl_InvocationID].w;\n    gl_Position.x = _59;\n    gl_Position.y = gl_in[_31].gl_Position.y;\n    gl_Position.z = gl_in[_31].gl_Position.z;\n    gl_Position.w = gl_in[_31].gl_Position.w;\n    EmitVertex();\n    EndPrimitive();\n    TEXCOORD_1.x = TEXCOORD[gl_InvocationID].x;\n    TEXCOORD_1.y = TEXCOORD[gl_InvocationID].y;\n    TEXCOORD_1.z = TEXCOORD[gl_InvocationID].z;\n    TEXCOORD_1.w = TEXCOORD[gl_InvocationID].w;\n    gl_Position.x = _59;\n    gl_Position.y = gl_in[_31].gl_Position.y;\n    gl_Position.z = gl_in[_31].gl_Position.z;\n    gl_Position.w = gl_in[_31].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[gl_InvocationID].x;\n    TEXCOORD_1.y = TEXCOORD[gl_InvocationID].y;\n    TEXCOORD_1.z = TEXCOORD[gl_InvocationID].z;\n    TEXCOORD_1.w = TEXCOORD[gl_InvocationID].w;\n    gl_Position.x = _59;\n    gl_Position.y = gl_in[_31].gl_Position.y;\n    gl_Position.z = gl_in[_31].gl_Position.z;\n    gl_Position.w = gl_in[_31].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[gl_InvocationID].x;\n    TEXCOORD_1.y = TEXCOORD[gl_InvocationID].y;\n    TEXCOORD_1.z = TEXCOORD[gl_InvocationID].z;\n    TEXCOORD_1.w = TEXCOORD[gl_InvocationID].w;\n    gl_Position.x = _59;\n    gl_Position.y = gl_in[_31].gl_Position.y;\n    gl_Position.z = gl_in[_31].gl_Position.z;\n    gl_Position.w = gl_in[_31].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15 %17\nOpExecutionMode %3 Invocations 2\nOpExecutionMode %3 OutputVertices 6\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputTriangleStrip\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\nOpDecorate %17 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %7\n%17 = OpVariable %16 Input\n%19 = OpTypePointer Input %5\n%21 = OpConstant %7 0\n%24 = OpConstant %7 1\n%27 = OpConstant %7 2\n%40 = OpTypePointer Output %5\n%50 = OpConstant %5 0.00999999978\n%60 = OpConstant %5 0.0199999996\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%18 = OpLoad %7 %17\n%20 = OpAccessChain %19 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %19 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %19 %11 %18 %27\n%28 = OpLoad %5 %26\n%29 = OpAccessChain %19 %11 %18 %8\n%30 = OpLoad %5 %29\n%31 = OpBitwiseXor %7 %18 %24\n%32 = OpAccessChain %19 %12 %31 %21\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %19 %12 %31 %24\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %19 %12 %31 %27\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %19 %12 %31 %8\n%39 = OpLoad %5 %38\n%41 = OpAccessChain %40 %14 %21\nOpStore %41 %22\n%42 = OpAccessChain %40 %14 %24\nOpStore %42 %25\n%43 = OpAccessChain %40 %14 %27\nOpStore %43 %28\n%44 = OpAccessChain %40 %14 %8\nOpStore %44 %30\n%45 = OpAccessChain %40 %15 %21\nOpStore %45 %33\n%46 = OpAccessChain %40 %15 %24\nOpStore %46 %35\n%47 = OpAccessChain %40 %15 %27\nOpStore %47 %37\n%48 = OpAccessChain %40 %15 %8\nOpStore %48 %39\nOpEmitVertex\n%49 = OpFAdd %5 %33 %50\n%51 = OpAccessChain %40 %14 %21\nOpStore %51 %22\n%52 = OpAccessChain %40 %14 %24\nOpStore %52 %25\n%53 = OpAccessChain %40 %14 %27\nOpStore %53 %28\n%54 = OpAccessChain %40 %14 %8\nOpStore %54 %30\n%55 = OpAccessChain %40 %15 %21\nOpStore %55 %49\n%56 = OpAccessChain %40 %15 %24\nOpStore %56 %35\n%57 = OpAccessChain %40 %15 %27\nOpStore %57 %37\n%58 = OpAccessChain %40 %15 %8\nOpStore %58 %39\nOpEmitVertex\n%59 = OpFAdd %5 %33 %60\n%61 = OpAccessChain %40 %14 %21\nOpStore %61 %22\n%62 = OpAccessChain %40 %14 %24\nOpStore %62 %25\n%63 = OpAccessChain %40 %14 %27\nOpStore %63 %28\n%64 = OpAccessChain %40 %14 %8\nOpStore %64 %30\n%65 = OpAccessChain %40 %15 %21\nOpStore %65 %59\n%66 = OpAccessChain %40 %15 %24\nOpStore %66 %35\n%67 = OpAccessChain %40 %15 %27\nOpStore %67 %37\n%68 = OpAccessChain %40 %15 %8\nOpStore %68 %39\nOpEmitVertex\nOpEndPrimitive\n%69 = OpAccessChain %40 %14 %21\nOpStore %69 %22\n%70 = OpAccessChain %40 %14 %24\nOpStore %70 %25\n%71 = OpAccessChain %40 %14 %27\nOpStore %71 %28\n%72 = OpAccessChain %40 %14 %8\nOpStore %72 %30\n%73 = OpAccessChain %40 %15 %21\nOpStore %73 %59\n%74 = OpAccessChain %40 %15 %24\nOpStore %74 %35\n%75 = OpAccessChain %40 %15 %27\nOpStore %75 %37\n%76 = OpAccessChain %40 %15 %8\nOpStore %76 %39\nOpEmitVertex\n%77 = OpAccessChain %40 %14 %21\nOpStore %77 %22\n%78 = OpAccessChain %40 %14 %24\nOpStore %78 %25\n%79 = OpAccessChain %40 %14 %27\nOpStore %79 %28\n%80 = OpAccessChain %40 %14 %8\nOpStore %80 %30\n%81 = OpAccessChain %40 %15 %21\nOpStore %81 %59\n%82 = OpAccessChain %40 %15 %24\nOpStore %82 %35\n%83 = OpAccessChain %40 %15 %27\nOpStore %83 %37\n%84 = OpAccessChain %40 %15 %8\nOpStore %84 %39\nOpEmitVertex\n%85 = OpAccessChain %40 %14 %21\nOpStore %85 %22\n%86 = OpAccessChain %40 %14 %24\nOpStore %86 %25\n%87 = OpAccessChain %40 %14 %27\nOpStore %87 %28\n%88 = OpAccessChain %40 %14 %8\nOpStore %88 %30\n%89 = OpAccessChain %40 %15 %21\nOpStore %89 %59\n%90 = OpAccessChain %40 %15 %24\nOpStore %90 %35\n%91 = OpAccessChain %40 %15 %27\nOpStore %91 %37\n%92 = OpAccessChain %40 %15 %8\nOpStore %92 %39\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-output-line.geom",
    "content": "#version 460\nlayout(triangles) in;\nlayout(max_vertices = 2, line_strip) out;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x + 0.00999999977648258209228515625;\n    gl_Position.y = gl_in[1u].gl_Position.y + 0.00999999977648258209228515625;\n    gl_Position.z = gl_in[1u].gl_Position.z + 0.00999999977648258209228515625;\n    gl_Position.w = gl_in[1u].gl_Position.w + 0.00999999977648258209228515625;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 2\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputLineStrip\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%36 = OpTypePointer Output %5\n%46 = OpConstant %5 0.00999999978\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %58\n%58 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %8\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %16 %12 %21 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %21 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %21 %24\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %21 %8\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %21\nOpStore %38 %22\n%39 = OpAccessChain %36 %14 %24\nOpStore %39 %25\n%40 = OpAccessChain %36 %14 %8\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %21\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %24\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %8\nOpStore %44 %35\nOpEmitVertex\n%45 = OpFAdd %5 %29 %46\n%47 = OpFAdd %5 %31 %46\n%48 = OpFAdd %5 %33 %46\n%49 = OpFAdd %5 %35 %46\n%50 = OpAccessChain %36 %14 %18\nOpStore %50 %19\n%51 = OpAccessChain %36 %14 %21\nOpStore %51 %22\n%52 = OpAccessChain %36 %14 %24\nOpStore %52 %25\n%53 = OpAccessChain %36 %14 %8\nOpStore %53 %27\n%54 = OpAccessChain %36 %15 %18\nOpStore %54 %45\n%55 = OpAccessChain %36 %15 %21\nOpStore %55 %47\n%56 = OpAccessChain %36 %15 %24\nOpStore %56 %48\n%57 = OpAccessChain %36 %15 %8\nOpStore %57 %49\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-output-point.geom",
    "content": "#version 460\nlayout(triangles) in;\nlayout(max_vertices = 1, points) out;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 1\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%36 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %45\n%45 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %8\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %16 %12 %21 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %21 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %21 %24\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %21 %8\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %21\nOpStore %38 %22\n%39 = OpAccessChain %36 %14 %24\nOpStore %39 %25\n%40 = OpAccessChain %36 %14 %8\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %21\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %24\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %8\nOpStore %44 %35\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/geometry-streams.geom",
    "content": "#version 460\nlayout(points) in;\nlayout(max_vertices = 3, points) out;\n\nlayout(location = 0) in vec4 TEXCOORD[1];\nlayout(location = 0) out vec4 A;\nlayout(location = 2, stream = 1) out vec4 B;\nlayout(location = 3, stream = 1) out vec4 D[2];\nlayout(location = 5, stream = 2) out vec4 C;\nlayout(location = 6, stream = 2) out vec4 E;\n\nvoid main()\n{\n    A.x = TEXCOORD[0u].x;\n    A.y = TEXCOORD[0u].y;\n    A.z = TEXCOORD[0u].z;\n    A.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[0u].gl_Position.x;\n    gl_Position.y = gl_in[0u].gl_Position.y;\n    gl_Position.z = gl_in[0u].gl_Position.z;\n    gl_Position.w = gl_in[0u].gl_Position.w;\n    EmitStreamVertex(int(0u));\n    B.x = TEXCOORD[0u].x + 1.0;\n    B.y = TEXCOORD[0u].y + 1.0;\n    B.z = TEXCOORD[0u].z + 1.0;\n    B.w = TEXCOORD[0u].w + 1.0;\n    D[0u].x = 1.0;\n    D[0u].y = 1.0;\n    D[0u].z = 1.0;\n    D[0u].w = 1.0;\n    D[1u].x = 3.0;\n    D[1u].y = 3.0;\n    D[1u].z = 3.0;\n    D[1u].w = 3.0;\n    EmitStreamVertex(int(1u));\n    C.x = TEXCOORD[0u].x + 2.0;\n    C.y = TEXCOORD[0u].y + 2.0;\n    C.z = TEXCOORD[0u].z + 2.0;\n    C.w = TEXCOORD[0u].w + 2.0;\n    E.x = TEXCOORD[0u].x + 3.0;\n    E.y = TEXCOORD[0u].y + 3.0;\n    E.z = TEXCOORD[0u].z + 3.0;\n    E.w = TEXCOORD[0u].w + 3.0;\n    EmitStreamVertex(int(2u));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 88\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability GeometryStreams\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15 %16 %20 %21 %22\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 3\nOpExecutionMode %3 InputPoints\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"A\"\nOpName %15 \"SV_Position\"\nOpName %16 \"B\"\nOpName %20 \"D\"\nOpName %21 \"C\"\nOpName %22 \"E\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\nOpDecorate %16 Stream 1\nOpDecorate %16 Location 2\nOpDecorate %20 Stream 1\nOpDecorate %20 Location 3\nOpDecorate %21 Stream 2\nOpDecorate %21 Location 5\nOpDecorate %22 Stream 2\nOpDecorate %22 Location 6\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 1\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpVariable %13 Output\n%17 = OpConstant %7 2\n%18 = OpTypeArray %6 %17\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%21 = OpVariable %13 Output\n%22 = OpVariable %13 Output\n%23 = OpTypePointer Input %5\n%25 = OpConstant %7 0\n%32 = OpConstant %7 3\n%42 = OpTypePointer Output %5\n%52 = OpConstant %5 1\n%65 = OpConstant %5 3\n%70 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %86\n%86 = OpLabel\n%24 = OpAccessChain %23 %11 %25 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %23 %11 %25 %8\n%28 = OpLoad %5 %27\n%29 = OpAccessChain %23 %11 %25 %17\n%30 = OpLoad %5 %29\n%31 = OpAccessChain %23 %11 %25 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %23 %12 %25 %25\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %23 %12 %25 %8\n%37 = OpLoad %5 %36\n%38 = OpAccessChain %23 %12 %25 %17\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %23 %12 %25 %32\n%41 = OpLoad %5 %40\n%43 = OpAccessChain %42 %14 %25\nOpStore %43 %26\n%44 = OpAccessChain %42 %14 %8\nOpStore %44 %28\n%45 = OpAccessChain %42 %14 %17\nOpStore %45 %30\n%46 = OpAccessChain %42 %14 %32\nOpStore %46 %33\n%47 = OpAccessChain %42 %15 %25\nOpStore %47 %35\n%48 = OpAccessChain %42 %15 %8\nOpStore %48 %37\n%49 = OpAccessChain %42 %15 %17\nOpStore %49 %39\n%50 = OpAccessChain %42 %15 %32\nOpStore %50 %41\nOpEmitStreamVertex %25\n%51 = OpFAdd %5 %26 %52\n%53 = OpFAdd %5 %28 %52\n%54 = OpFAdd %5 %30 %52\n%55 = OpFAdd %5 %33 %52\n%56 = OpAccessChain %42 %16 %25\nOpStore %56 %51\n%57 = OpAccessChain %42 %16 %8\nOpStore %57 %53\n%58 = OpAccessChain %42 %16 %17\nOpStore %58 %54\n%59 = OpAccessChain %42 %16 %32\nOpStore %59 %55\n%60 = OpAccessChain %42 %20 %25 %25\nOpStore %60 %52\n%61 = OpAccessChain %42 %20 %25 %8\nOpStore %61 %52\n%62 = OpAccessChain %42 %20 %25 %17\nOpStore %62 %52\n%63 = OpAccessChain %42 %20 %25 %32\nOpStore %63 %52\n%64 = OpAccessChain %42 %20 %8 %25\nOpStore %64 %65\n%66 = OpAccessChain %42 %20 %8 %8\nOpStore %66 %65\n%67 = OpAccessChain %42 %20 %8 %17\nOpStore %67 %65\n%68 = OpAccessChain %42 %20 %8 %32\nOpStore %68 %65\nOpEmitStreamVertex %8\n%69 = OpFAdd %5 %26 %70\n%71 = OpFAdd %5 %28 %70\n%72 = OpFAdd %5 %30 %70\n%73 = OpFAdd %5 %33 %70\n%74 = OpFAdd %5 %26 %65\n%75 = OpFAdd %5 %28 %65\n%76 = OpFAdd %5 %30 %65\n%77 = OpFAdd %5 %33 %65\n%78 = OpAccessChain %42 %21 %25\nOpStore %78 %69\n%79 = OpAccessChain %42 %21 %8\nOpStore %79 %71\n%80 = OpAccessChain %42 %21 %17\nOpStore %80 %72\n%81 = OpAccessChain %42 %21 %32\nOpStore %81 %73\n%82 = OpAccessChain %42 %22 %25\nOpStore %82 %74\n%83 = OpAccessChain %42 %22 %8\nOpStore %83 %75\n%84 = OpAccessChain %42 %22 %17\nOpStore %84 %76\n%85 = OpAccessChain %42 %22 %32\nOpStore %85 %77\nOpEmitStreamVertex %17\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/hull-arrays.tesc",
    "content": "#version 460\nlayout(vertices = 2) out;\n\nlayout(location = 0) in float VSValue[][3];\nlayout(location = 0) out float HSValue[2][3];\nlayout(location = 3) patch out float PATCH[2];\n\nvoid hull_main()\n{\n    float _39 = (VSValue[1u][1u] + VSValue[0u][0u]) + VSValue[2u][2u];\n    HSValue[gl_InvocationID][0u] = _39;\n    HSValue[gl_InvocationID][1u] = _39 + 1.0;\n    HSValue[gl_InvocationID][2u] = _39 + 2.0;\n}\n\nvoid patch_main()\n{\n    gl_TessLevelOuter[0u] = VSValue[0u][2u];\n    gl_TessLevelOuter[1u] = VSValue[1u][1u];\n    gl_TessLevelOuter[2u] = VSValue[2u][0u];\n    gl_TessLevelInner[0u] = HSValue[1u][2u] + HSValue[0u][1u];\n    PATCH[0u] = VSValue[3u][2u];\n    PATCH[1u] = VSValue[4u][1u];\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationControl %3 \"main\" %12 %16 %20 %23 %24 %47\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCcw\nOpExecutionMode %3 OutputVertices 2\nOpName %3 \"main\"\nOpName %12 \"VSValue\"\nOpName %16 \"HSValue\"\nOpName %20 \"SV_TessFactor\"\nOpName %23 \"SV_InsideTessFactor\"\nOpName %24 \"PATCH\"\nOpName %25 \"hull_main\"\nOpName %27 \"patch_main\"\nOpDecorate %12 Location 0\nOpDecorate %16 Location 0\nOpDecorate %20 BuiltIn TessLevelOuter\nOpDecorate %20 Patch\nOpDecorate %23 BuiltIn TessLevelInner\nOpDecorate %23 Patch\nOpDecorate %24 Location 3\nOpDecorate %24 Patch\nOpDecorate %47 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpConstant %6 32\n%10 = OpTypeArray %8 %9\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpConstant %6 2\n%14 = OpTypeArray %8 %13\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpConstant %6 4\n%18 = OpTypeArray %5 %17\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%21 = OpTypeArray %5 %13\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpVariable %22 Output\n%29 = OpTypePointer Input %5\n%31 = OpConstant %6 0\n%34 = OpConstant %6 1\n%41 = OpConstant %5 1\n%43 = OpConstant %5 2\n%44 = OpTypePointer Output %5\n%46 = OpTypePointer Input %6\n%47 = OpVariable %46 Input\n%76 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %79\n%79 = OpLabel\n%74 = OpFunctionCall %1 %25\n%75 = OpLoad %6 %47\n%77 = OpIEqual %76 %75 %31\nOpControlBarrier %13 %17 %31\nOpSelectionMerge %81 None\nOpBranchConditional %77 %80 %81\n%80 = OpLabel\n%78 = OpFunctionCall %1 %27\nOpBranch %81\n%81 = OpLabel\nOpReturn\nOpFunctionEnd\n%25 = OpFunction %1 None %2\n%26 = OpLabel\nOpBranch %83\n%83 = OpLabel\n%30 = OpAccessChain %29 %12 %31 %31\n%32 = OpLoad %5 %30\n%33 = OpAccessChain %29 %12 %34 %34\n%35 = OpLoad %5 %33\n%36 = OpFAdd %5 %35 %32\n%37 = OpAccessChain %29 %12 %13 %13\n%38 = OpLoad %5 %37\n%39 = OpFAdd %5 %36 %38\n%40 = OpFAdd %5 %39 %41\n%42 = OpFAdd %5 %39 %43\n%48 = OpLoad %6 %47\n%45 = OpAccessChain %44 %16 %48 %31\nOpStore %45 %39\n%50 = OpLoad %6 %47\n%49 = OpAccessChain %44 %16 %50 %34\nOpStore %49 %40\n%52 = OpLoad %6 %47\n%51 = OpAccessChain %44 %16 %52 %13\nOpStore %51 %42\nOpReturn\nOpFunctionEnd\n%27 = OpFunction %1 None %2\n%28 = OpLabel\nOpBranch %85\n%85 = OpLabel\n%53 = OpAccessChain %44 %16 %31 %34\n%54 = OpLoad %5 %53\n%55 = OpAccessChain %44 %16 %34 %13\n%56 = OpLoad %5 %55\n%57 = OpFAdd %5 %56 %54\n%58 = OpAccessChain %29 %12 %31 %13\n%59 = OpLoad %5 %58\n%60 = OpAccessChain %29 %12 %34 %34\n%61 = OpLoad %5 %60\n%62 = OpAccessChain %29 %12 %13 %31\n%63 = OpLoad %5 %62\n%64 = OpAccessChain %29 %12 %7 %13\n%65 = OpLoad %5 %64\n%66 = OpAccessChain %29 %12 %17 %34\n%67 = OpLoad %5 %66\n%68 = OpAccessChain %44 %20 %31\nOpStore %68 %59\n%69 = OpAccessChain %44 %20 %34\nOpStore %69 %61\n%70 = OpAccessChain %44 %20 %13\nOpStore %70 %63\n%71 = OpAccessChain %44 %23 %31\nOpStore %71 %57\n%72 = OpAccessChain %44 %24 %31\nOpStore %72 %65\n%73 = OpAccessChain %44 %24 %34\nOpStore %73 %67\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/hull-clip-cull.tesc",
    "content": "#version 460\nlayout(vertices = 4) out;\n\nlayout(location = 0) out vec2 HSValue[4];\nlayout(location = 1) out vec2 SV_ClipDistance[4];\nlayout(location = 1, component = 2) out float SV_CullDistance[4][2];\n\nvoid hull_main()\n{\n    float _46 = gl_in[gl_InvocationID].gl_CullDistance[1u] + gl_in[gl_InvocationID].gl_CullDistance[0u];\n    HSValue[gl_InvocationID].x = _46 + gl_in[gl_InvocationID].gl_ClipDistance[0u];\n    HSValue[gl_InvocationID].y = _46 + gl_in[gl_InvocationID].gl_ClipDistance[1u];\n    SV_ClipDistance[gl_InvocationID].x = 1.0;\n    SV_ClipDistance[gl_InvocationID].y = 2.0;\n    SV_CullDistance[gl_InvocationID][0u] = 3.0;\n    SV_CullDistance[gl_InvocationID][1u] = 4.0;\n}\n\nvoid patch_main()\n{\n    gl_TessLevelOuter[0u] = 0.0;\n    gl_TessLevelOuter[1u] = 0.0;\n    gl_TessLevelOuter[2u] = 0.0;\n    gl_TessLevelOuter[3u] = 0.0;\n    gl_TessLevelInner[0u] = 0.0;\n    gl_TessLevelInner[1u] = 0.0;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpCapability ClipDistance\nOpCapability CullDistance\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationControl %3 \"main\" %13 %14 %18 %19 %22 %25 %27 %33\nOpExecutionMode %3 Quads\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCw\nOpExecutionMode %3 OutputVertices 4\nOpName %3 \"main\"\nOpName %18 \"HSValue\"\nOpName %19 \"SV_ClipDistance\"\nOpName %22 \"SV_CullDistance\"\nOpName %25 \"SV_TessFactor\"\nOpName %27 \"SV_InsideTessFactor\"\nOpName %28 \"hull_main\"\nOpName %30 \"patch_main\"\nOpDecorate %13 BuiltIn ClipDistance\nOpDecorate %14 BuiltIn CullDistance\nOpDecorate %18 Location 0\nOpDecorate %19 Location 1\nOpDecorate %22 Location 1\nOpDecorate %22 Component 2\nOpDecorate %25 BuiltIn TessLevelOuter\nOpDecorate %25 Patch\nOpDecorate %27 BuiltIn TessLevelInner\nOpDecorate %27 Patch\nOpDecorate %33 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 2\n%9 = OpTypeArray %5 %8\n%10 = OpConstant %7 32\n%11 = OpTypeArray %9 %10\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%14 = OpVariable %12 Input\n%15 = OpConstant %7 4\n%16 = OpTypeArray %6 %15\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpVariable %17 Output\n%20 = OpTypeArray %9 %15\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%23 = OpTypeArray %5 %15\n%24 = OpTypePointer Output %23\n%25 = OpVariable %24 Output\n%26 = OpTypePointer Output %9\n%27 = OpVariable %26 Output\n%32 = OpTypePointer Input %7\n%33 = OpVariable %32 Input\n%35 = OpTypePointer Input %5\n%37 = OpConstant %7 0\n%40 = OpConstant %7 1\n%49 = OpTypePointer Output %5\n%56 = OpConstant %5 1\n%59 = OpConstant %5 2\n%62 = OpConstant %5 3\n%65 = OpConstant %5 4\n%67 = OpConstant %5 0\n%71 = OpConstant %7 3\n%76 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %79\n%79 = OpLabel\n%74 = OpFunctionCall %1 %28\n%75 = OpLoad %7 %33\n%77 = OpIEqual %76 %75 %37\nOpControlBarrier %8 %15 %37\nOpSelectionMerge %81 None\nOpBranchConditional %77 %80 %81\n%80 = OpLabel\n%78 = OpFunctionCall %1 %30\nOpBranch %81\n%81 = OpLabel\nOpReturn\nOpFunctionEnd\n%28 = OpFunction %1 None %2\n%29 = OpLabel\nOpBranch %83\n%83 = OpLabel\n%34 = OpLoad %7 %33\n%36 = OpAccessChain %35 %13 %34 %37\n%38 = OpLoad %5 %36\n%39 = OpAccessChain %35 %13 %34 %40\n%41 = OpLoad %5 %39\n%42 = OpAccessChain %35 %14 %34 %37\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %35 %14 %34 %40\n%45 = OpLoad %5 %44\n%46 = OpFAdd %5 %45 %43\n%47 = OpFAdd %5 %46 %38\n%48 = OpFAdd %5 %46 %41\n%51 = OpLoad %7 %33\n%50 = OpAccessChain %49 %18 %51 %37\nOpStore %50 %47\n%53 = OpLoad %7 %33\n%52 = OpAccessChain %49 %18 %53 %40\nOpStore %52 %48\n%55 = OpLoad %7 %33\n%54 = OpAccessChain %49 %19 %55 %37\nOpStore %54 %56\n%58 = OpLoad %7 %33\n%57 = OpAccessChain %49 %19 %58 %40\nOpStore %57 %59\n%61 = OpLoad %7 %33\n%60 = OpAccessChain %49 %22 %61 %37\nOpStore %60 %62\n%64 = OpLoad %7 %33\n%63 = OpAccessChain %49 %22 %64 %40\nOpStore %63 %65\nOpReturn\nOpFunctionEnd\n%30 = OpFunction %1 None %2\n%31 = OpLabel\nOpBranch %85\n%85 = OpLabel\n%66 = OpAccessChain %49 %25 %37\nOpStore %66 %67\n%68 = OpAccessChain %49 %25 %40\nOpStore %68 %67\n%69 = OpAccessChain %49 %25 %8\nOpStore %69 %67\n%70 = OpAccessChain %49 %25 %71\nOpStore %70 %67\n%72 = OpAccessChain %49 %27 %37\nOpStore %72 %67\n%73 = OpAccessChain %49 %27 %40\nOpStore %73 %67\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/hull-patch-output-integer-io.tesc",
    "content": "#version 460\nlayout(vertices = 3) out;\n\nlayout(location = 0) in int A[];\nlayout(location = 0, component = 1) in uint B[];\nlayout(location = 0) out float A_1[3];\nlayout(location = 1) patch out int B_1;\nlayout(location = 1, component = 1) patch out uint C;\nlayout(location = 5) patch out ivec4 BV;\nlayout(location = 6) patch out uvec4 CV;\nlayout(location = 1, component = 2) patch out int BVS[2];\nlayout(location = 2) patch out uint CVS[2];\nlayout(location = 7) patch out ivec4 BVSS[2];\nlayout(location = 9) patch out uvec4 CVSS[2];\n\nvoid hull_main()\n{\n    A_1[gl_InvocationID] = float(B[1u]) + float(int(uint(A[0u])));\n}\n\nvoid patch_main()\n{\n    gl_TessLevelOuter[0u] = float(int(uint(A[0u])));\n    gl_TessLevelOuter[1u] = float(B[1u]);\n    gl_TessLevelOuter[2u] = 4.0;\n    gl_TessLevelInner[0u] = A_1[1u] + A_1[0u];\n    B_1 = int(10u);\n    C = 20u;\n    BV.x = int(1u);\n    BV.y = int(2u);\n    BV.z = int(3u);\n    BV.w = int(4u);\n    CV.x = 5u;\n    CV.y = 6u;\n    CV.z = 7u;\n    CV.w = 8u;\n    BVS[0u] = int(50u);\n    BVS[1u] = int(60u);\n    CVS[0u] = 70u;\n    CVS[1u] = 80u;\n    BVSS[0u].x = int(50u);\n    BVSS[0u].y = int(60u);\n    BVSS[0u].z = int(70u);\n    BVSS[0u].w = int(80u);\n    BVSS[1u].x = int(51u);\n    BVSS[1u].y = int(52u);\n    BVSS[1u].z = int(53u);\n    BVSS[1u].w = int(54u);\n    CVSS[0u].x = 70u;\n    CVSS[0u].y = 71u;\n    CVSS[0u].z = 72u;\n    CVSS[0u].w = 73u;\n    CVSS[1u].x = 80u;\n    CVSS[1u].y = 81u;\n    CVSS[1u].z = 82u;\n    CVSS[1u].w = 83u;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 162\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationControl %3 \"main\" %10 %13 %18 %22 %26 %28 %30 %33 %36 %39 %42 %45 %48 %67\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCcw\nOpExecutionMode %3 OutputVertices 3\nOpName %3 \"main\"\nOpName %10 \"A\"\nOpName %13 \"B\"\nOpName %18 \"A\"\nOpName %22 \"SV_TessFactor\"\nOpName %26 \"SV_InsideTessFactor\"\nOpName %28 \"B\"\nOpName %30 \"C\"\nOpName %33 \"BV\"\nOpName %36 \"CV\"\nOpName %39 \"BVS\"\nOpName %42 \"CVS\"\nOpName %45 \"BVSS\"\nOpName %48 \"CVSS\"\nOpName %49 \"hull_main\"\nOpName %51 \"patch_main\"\nOpDecorate %10 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %18 Location 0\nOpDecorate %22 BuiltIn TessLevelOuter\nOpDecorate %22 Patch\nOpDecorate %26 BuiltIn TessLevelInner\nOpDecorate %26 Patch\nOpDecorate %28 Location 1\nOpDecorate %28 Patch\nOpDecorate %30 Location 1\nOpDecorate %30 Component 1\nOpDecorate %30 Patch\nOpDecorate %33 Location 5\nOpDecorate %33 Patch\nOpDecorate %36 Location 6\nOpDecorate %36 Patch\nOpDecorate %39 Location 1\nOpDecorate %39 Component 2\nOpDecorate %39 Patch\nOpDecorate %42 Location 2\nOpDecorate %42 Patch\nOpDecorate %45 Location 7\nOpDecorate %45 Patch\nOpDecorate %48 Location 9\nOpDecorate %48 Patch\nOpDecorate %67 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 32\n%8 = OpTypeArray %5 %7\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpTypeArray %6 %7\n%12 = OpTypePointer Input %11\n%13 = OpVariable %12 Input\n%14 = OpTypeFloat 32\n%15 = OpConstant %6 3\n%16 = OpTypeArray %14 %15\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpConstant %6 4\n%20 = OpTypeArray %14 %19\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%23 = OpConstant %6 2\n%24 = OpTypeArray %14 %23\n%25 = OpTypePointer Output %24\n%26 = OpVariable %25 Output\n%27 = OpTypePointer Output %5\n%28 = OpVariable %27 Output\n%29 = OpTypePointer Output %6\n%30 = OpVariable %29 Output\n%31 = OpTypeVector %5 4\n%32 = OpTypePointer Output %31\n%33 = OpVariable %32 Output\n%34 = OpTypeVector %6 4\n%35 = OpTypePointer Output %34\n%36 = OpVariable %35 Output\n%37 = OpTypeArray %5 %23\n%38 = OpTypePointer Output %37\n%39 = OpVariable %38 Output\n%40 = OpTypeArray %6 %23\n%41 = OpTypePointer Output %40\n%42 = OpVariable %41 Output\n%43 = OpTypeArray %31 %23\n%44 = OpTypePointer Output %43\n%45 = OpVariable %44 Output\n%46 = OpTypeArray %34 %23\n%47 = OpTypePointer Output %46\n%48 = OpVariable %47 Output\n%53 = OpTypePointer Input %5\n%55 = OpConstant %6 0\n%59 = OpTypePointer Input %6\n%61 = OpConstant %6 1\n%65 = OpTypePointer Output %14\n%67 = OpVariable %59 Input\n%84 = OpConstant %14 4\n%86 = OpConstant %6 10\n%88 = OpConstant %6 20\n%98 = OpConstant %6 5\n%100 = OpConstant %6 6\n%102 = OpConstant %6 7\n%104 = OpConstant %6 8\n%106 = OpConstant %6 50\n%109 = OpConstant %6 60\n%112 = OpConstant %6 70\n%114 = OpConstant %6 80\n%124 = OpConstant %6 51\n%127 = OpConstant %6 52\n%130 = OpConstant %6 53\n%133 = OpConstant %6 54\n%137 = OpConstant %6 71\n%139 = OpConstant %6 72\n%141 = OpConstant %6 73\n%144 = OpConstant %6 81\n%146 = OpConstant %6 82\n%148 = OpConstant %6 83\n%151 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %154\n%154 = OpLabel\n%149 = OpFunctionCall %1 %49\n%150 = OpLoad %6 %67\n%152 = OpIEqual %151 %150 %55\nOpControlBarrier %23 %19 %55\nOpSelectionMerge %156 None\nOpBranchConditional %152 %155 %156\n%155 = OpLabel\n%153 = OpFunctionCall %1 %51\nOpBranch %156\n%156 = OpLabel\nOpReturn\nOpFunctionEnd\n%49 = OpFunction %1 None %2\n%50 = OpLabel\nOpBranch %158\n%158 = OpLabel\n%54 = OpAccessChain %53 %10 %55\n%56 = OpLoad %5 %54\n%57 = OpBitcast %6 %56\n%58 = OpConvertSToF %14 %57\n%60 = OpAccessChain %59 %13 %61\n%62 = OpLoad %6 %60\n%63 = OpConvertUToF %14 %62\n%64 = OpFAdd %14 %63 %58\n%68 = OpLoad %6 %67\n%66 = OpAccessChain %65 %18 %68\nOpStore %66 %64\nOpReturn\nOpFunctionEnd\n%51 = OpFunction %1 None %2\n%52 = OpLabel\nOpBranch %160\n%160 = OpLabel\n%69 = OpAccessChain %65 %18 %55\n%70 = OpLoad %14 %69\n%71 = OpAccessChain %65 %18 %61\n%72 = OpLoad %14 %71\n%73 = OpFAdd %14 %72 %70\n%74 = OpAccessChain %53 %10 %55\n%75 = OpLoad %5 %74\n%76 = OpBitcast %6 %75\n%77 = OpConvertSToF %14 %76\n%78 = OpAccessChain %59 %13 %61\n%79 = OpLoad %6 %78\n%80 = OpConvertUToF %14 %79\n%81 = OpAccessChain %65 %22 %55\nOpStore %81 %77\n%82 = OpAccessChain %65 %22 %61\nOpStore %82 %80\n%83 = OpAccessChain %65 %22 %23\nOpStore %83 %84\n%85 = OpAccessChain %65 %26 %55\nOpStore %85 %73\n%87 = OpBitcast %5 %86\nOpStore %28 %87\nOpStore %30 %88\n%89 = OpAccessChain %27 %33 %55\n%90 = OpBitcast %5 %61\nOpStore %89 %90\n%91 = OpAccessChain %27 %33 %61\n%92 = OpBitcast %5 %23\nOpStore %91 %92\n%93 = OpAccessChain %27 %33 %23\n%94 = OpBitcast %5 %15\nOpStore %93 %94\n%95 = OpAccessChain %27 %33 %15\n%96 = OpBitcast %5 %19\nOpStore %95 %96\n%97 = OpAccessChain %29 %36 %55\nOpStore %97 %98\n%99 = OpAccessChain %29 %36 %61\nOpStore %99 %100\n%101 = OpAccessChain %29 %36 %23\nOpStore %101 %102\n%103 = OpAccessChain %29 %36 %15\nOpStore %103 %104\n%105 = OpAccessChain %27 %39 %55\n%107 = OpBitcast %5 %106\nOpStore %105 %107\n%108 = OpAccessChain %27 %39 %61\n%110 = OpBitcast %5 %109\nOpStore %108 %110\n%111 = OpAccessChain %29 %42 %55\nOpStore %111 %112\n%113 = OpAccessChain %29 %42 %61\nOpStore %113 %114\n%115 = OpAccessChain %27 %45 %55 %55\n%116 = OpBitcast %5 %106\nOpStore %115 %116\n%117 = OpAccessChain %27 %45 %55 %61\n%118 = OpBitcast %5 %109\nOpStore %117 %118\n%119 = OpAccessChain %27 %45 %55 %23\n%120 = OpBitcast %5 %112\nOpStore %119 %120\n%121 = OpAccessChain %27 %45 %55 %15\n%122 = OpBitcast %5 %114\nOpStore %121 %122\n%123 = OpAccessChain %27 %45 %61 %55\n%125 = OpBitcast %5 %124\nOpStore %123 %125\n%126 = OpAccessChain %27 %45 %61 %61\n%128 = OpBitcast %5 %127\nOpStore %126 %128\n%129 = OpAccessChain %27 %45 %61 %23\n%131 = OpBitcast %5 %130\nOpStore %129 %131\n%132 = OpAccessChain %27 %45 %61 %15\n%134 = OpBitcast %5 %133\nOpStore %132 %134\n%135 = OpAccessChain %29 %48 %55 %55\nOpStore %135 %112\n%136 = OpAccessChain %29 %48 %55 %61\nOpStore %136 %137\n%138 = OpAccessChain %29 %48 %55 %23\nOpStore %138 %139\n%140 = OpAccessChain %29 %48 %55 %15\nOpStore %140 %141\n%142 = OpAccessChain %29 %48 %61 %55\nOpStore %142 %114\n%143 = OpAccessChain %29 %48 %61 %61\nOpStore %143 %144\n%145 = OpAccessChain %29 %48 %61 %23\nOpStore %145 %146\n%147 = OpAccessChain %29 %48 %61 %15\nOpStore %147 %148\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/hull-single-cp.tesc",
    "content": "#version 460\nlayout(vertices = 1) out;\n\nlayout(location = 0) in float VSValue[];\nlayout(location = 0) out float HSValue[1];\nlayout(location = 1) patch out float PATCH;\n\nvoid hull_main()\n{\n    HSValue[gl_InvocationID] = (VSValue[1u] + VSValue[0u]) + VSValue[2u];\n}\n\nvoid patch_main()\n{\n    gl_TessLevelOuter[0u] = VSValue[0u];\n    gl_TessLevelOuter[1u] = VSValue[1u];\n    gl_TessLevelOuter[2u] = VSValue[2u];\n    gl_TessLevelInner[0u] = HSValue[0u];\n    PATCH = VSValue[3u];\n}\n\nvoid main()\n{\n    hull_main();\n    patch_main();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationControl %3 \"main\" %10 %14 %18 %22 %24 %41\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCcw\nOpExecutionMode %3 OutputVertices 1\nOpName %3 \"main\"\nOpName %10 \"VSValue\"\nOpName %14 \"HSValue\"\nOpName %18 \"SV_TessFactor\"\nOpName %22 \"SV_InsideTessFactor\"\nOpName %24 \"PATCH\"\nOpName %25 \"hull_main\"\nOpName %27 \"patch_main\"\nOpDecorate %10 Location 0\nOpDecorate %14 Location 0\nOpDecorate %18 BuiltIn TessLevelOuter\nOpDecorate %18 Patch\nOpDecorate %22 BuiltIn TessLevelInner\nOpDecorate %22 Patch\nOpDecorate %24 Location 1\nOpDecorate %24 Patch\nOpDecorate %41 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 32\n%8 = OpTypeArray %5 %7\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpConstant %6 1\n%12 = OpTypeArray %5 %11\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %6 4\n%16 = OpTypeArray %5 %15\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpConstant %6 2\n%20 = OpTypeArray %5 %19\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%23 = OpTypePointer Output %5\n%24 = OpVariable %23 Output\n%29 = OpTypePointer Input %5\n%31 = OpConstant %6 0\n%40 = OpTypePointer Input %6\n%41 = OpVariable %40 Input\n%52 = OpConstant %6 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %60\n%60 = OpLabel\n%58 = OpFunctionCall %1 %25\n%59 = OpFunctionCall %1 %27\nOpReturn\nOpFunctionEnd\n%25 = OpFunction %1 None %2\n%26 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%30 = OpAccessChain %29 %10 %31\n%32 = OpLoad %5 %30\n%33 = OpAccessChain %29 %10 %11\n%34 = OpLoad %5 %33\n%35 = OpFAdd %5 %34 %32\n%36 = OpAccessChain %29 %10 %19\n%37 = OpLoad %5 %36\n%38 = OpFAdd %5 %35 %37\n%42 = OpLoad %6 %41\n%39 = OpAccessChain %23 %14 %42\nOpStore %39 %38\nOpReturn\nOpFunctionEnd\n%27 = OpFunction %1 None %2\n%28 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%43 = OpAccessChain %23 %14 %31\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %29 %10 %31\n%46 = OpLoad %5 %45\n%47 = OpAccessChain %29 %10 %11\n%48 = OpLoad %5 %47\n%49 = OpAccessChain %29 %10 %19\n%50 = OpLoad %5 %49\n%51 = OpAccessChain %29 %10 %52\n%53 = OpLoad %5 %51\n%54 = OpAccessChain %23 %18 %31\nOpStore %54 %46\n%55 = OpAccessChain %23 %18 %11\nOpStore %55 %48\n%56 = OpAccessChain %23 %18 %19\nOpStore %56 %50\n%57 = OpAccessChain %23 %22 %31\nOpStore %57 %44\nOpStore %24 %53\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/hull.tesc",
    "content": "#version 460\nlayout(vertices = 4) out;\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[1];\n} _12;\n\nlayout(location = 0) in float VSValue[];\nlayout(location = 0) out float HSValue[4];\nlayout(location = 1) patch out float PATCH;\n\nvoid hull_main()\n{\n    float _36[4];\n    _36[0u] = VSValue[0u];\n    _36[1u] = VSValue[1u];\n    _36[2u] = VSValue[2u];\n    _36[3u] = VSValue[3u];\n    uint _53 = uint(int(VSValue[0u]));\n    _36[_53] += 40.0;\n    HSValue[gl_InvocationID] = (((VSValue[0u] + float(gl_InvocationID)) + VSValue[1u]) + VSValue[2u]) + _36[3u];\n}\n\nvoid patch_main()\n{\n    float _66[4];\n    _66[0u] = VSValue[0u];\n    _66[1u] = VSValue[1u];\n    _66[2u] = VSValue[2u];\n    _66[3u] = VSValue[3u];\n    uint _79 = uint(int(VSValue[0u]));\n    _66[_79] += 40.0;\n    gl_TessLevelOuter[0u] = VSValue[0u];\n    gl_TessLevelOuter[1u] = VSValue[1u];\n    gl_TessLevelOuter[2u] = VSValue[2u];\n    gl_TessLevelOuter[3u] = HSValue[0u] + VSValue[0u];\n    gl_TessLevelInner[0u] = HSValue[0u];\n    gl_TessLevelInner[1u] = HSValue[1u];\n    PATCH = _12._m0[0u].x + _66[3u];\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 113\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationControl %3 \"main\" %16 %20 %21 %25 %27 %33\nOpExecutionMode %3 Quads\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCw\nOpExecutionMode %3 OutputVertices 4\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"VSValue\"\nOpName %20 \"HSValue\"\nOpName %21 \"SV_TessFactor\"\nOpName %25 \"SV_InsideTessFactor\"\nOpName %27 \"PATCH\"\nOpName %28 \"hull_main\"\nOpName %30 \"patch_main\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %16 Location 0\nOpDecorate %20 Location 0\nOpDecorate %21 BuiltIn TessLevelOuter\nOpDecorate %21 Patch\nOpDecorate %25 BuiltIn TessLevelInner\nOpDecorate %25 Patch\nOpDecorate %27 Location 1\nOpDecorate %27 Patch\nOpDecorate %33 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpConstant %5 32\n%14 = OpTypeArray %7 %13\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpConstant %5 4\n%18 = OpTypeArray %7 %17\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%21 = OpVariable %19 Output\n%22 = OpConstant %5 2\n%23 = OpTypeArray %7 %22\n%24 = OpTypePointer Output %23\n%25 = OpVariable %24 Output\n%26 = OpTypePointer Output %7\n%27 = OpVariable %26 Output\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%35 = OpTypePointer Function %18\n%37 = OpTypePointer Input %7\n%39 = OpConstant %5 0\n%41 = OpTypePointer Function %7\n%50 = OpConstant %5 3\n%57 = OpConstant %7 40\n%89 = OpTypePointer Uniform %8\n%102 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %105\n%105 = OpLabel\n%100 = OpFunctionCall %1 %28\n%101 = OpLoad %5 %33\n%103 = OpIEqual %102 %101 %39\nOpControlBarrier %22 %17 %39\nOpSelectionMerge %107 None\nOpBranchConditional %103 %106 %107\n%106 = OpLabel\n%104 = OpFunctionCall %1 %30\nOpBranch %107\n%107 = OpLabel\nOpReturn\nOpFunctionEnd\n%28 = OpFunction %1 None %2\n%29 = OpLabel\n%36 = OpVariable %35 Function\nOpBranch %109\n%109 = OpLabel\n%34 = OpLoad %5 %33\n%38 = OpAccessChain %37 %16 %39\n%40 = OpLoad %7 %38\n%42 = OpAccessChain %41 %36 %39\nOpStore %42 %40\n%43 = OpAccessChain %37 %16 %6\n%44 = OpLoad %7 %43\n%45 = OpAccessChain %41 %36 %6\nOpStore %45 %44\n%46 = OpAccessChain %37 %16 %22\n%47 = OpLoad %7 %46\n%48 = OpAccessChain %41 %36 %22\nOpStore %48 %47\n%49 = OpAccessChain %37 %16 %50\n%51 = OpLoad %7 %49\n%52 = OpAccessChain %41 %36 %50\nOpStore %52 %51\n%53 = OpConvertFToS %5 %40\n%54 = OpAccessChain %41 %36 %53\n%55 = OpLoad %7 %54\n%56 = OpFAdd %7 %55 %57\nOpStore %54 %56\n%58 = OpLoad %7 %52\n%59 = OpConvertUToF %7 %34\n%60 = OpFAdd %7 %40 %59\n%61 = OpFAdd %7 %60 %44\n%62 = OpFAdd %7 %61 %47\n%63 = OpFAdd %7 %62 %58\n%65 = OpLoad %5 %33\n%64 = OpAccessChain %26 %20 %65\nOpStore %64 %63\nOpReturn\nOpFunctionEnd\n%30 = OpFunction %1 None %2\n%31 = OpLabel\n%66 = OpVariable %35 Function\nOpBranch %111\n%111 = OpLabel\n%67 = OpAccessChain %37 %16 %39\n%68 = OpLoad %7 %67\n%69 = OpAccessChain %41 %66 %39\nOpStore %69 %68\n%70 = OpAccessChain %37 %16 %6\n%71 = OpLoad %7 %70\n%72 = OpAccessChain %41 %66 %6\nOpStore %72 %71\n%73 = OpAccessChain %37 %16 %22\n%74 = OpLoad %7 %73\n%75 = OpAccessChain %41 %66 %22\nOpStore %75 %74\n%76 = OpAccessChain %37 %16 %50\n%77 = OpLoad %7 %76\n%78 = OpAccessChain %41 %66 %50\nOpStore %78 %77\n%79 = OpConvertFToS %5 %68\n%80 = OpAccessChain %41 %66 %79\n%81 = OpLoad %7 %80\n%82 = OpFAdd %7 %81 %57\nOpStore %80 %82\n%83 = OpAccessChain %26 %20 %39\n%84 = OpLoad %7 %83\n%85 = OpAccessChain %26 %20 %6\n%86 = OpLoad %7 %85\n%87 = OpFAdd %7 %84 %68\n%88 = OpLoad %7 %78\n%90 = OpAccessChain %89 %12 %39 %39\n%91 = OpLoad %8 %90\n%92 = OpCompositeExtract %7 %91 0\n%93 = OpFAdd %7 %92 %88\n%94 = OpAccessChain %26 %21 %39\nOpStore %94 %68\n%95 = OpAccessChain %26 %21 %6\nOpStore %95 %71\n%96 = OpAccessChain %26 %21 %22\nOpStore %96 %74\n%97 = OpAccessChain %26 %21 %50\nOpStore %97 %87\n%98 = OpAccessChain %26 %25 %39\nOpStore %98 %84\n%99 = OpAccessChain %26 %25 %6\nOpStore %99 %86\nOpStore %27 %93\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/mesh-basic-line.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, lines) out;\n\nstruct _36\n{\n    float _m0;\n};\n\nlayout(location = 1) out vec4 B[24];\nlayout(location = 3) perprimitiveEXT out vec4 C[8];\nshared float _32[64];\ntaskPayloadSharedEXT _36 _38;\n\nvoid main()\n{\n    _32[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex);\n    barrier();\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _32[gl_LocalInvocationIndex];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _32[gl_LocalInvocationIndex];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _32[gl_LocalInvocationIndex];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _32[gl_LocalInvocationIndex];\n    float _68 = _38._m0 + _32[gl_LocalInvocationIndex ^ 1u];\n    B[gl_LocalInvocationIndex].x = _68;\n    B[gl_LocalInvocationIndex].y = _68;\n    B[gl_LocalInvocationIndex].z = _68;\n    B[gl_LocalInvocationIndex].w = _68;\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _74 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveLineIndicesEXT[gl_LocalInvocationIndex] = uvec2(_74, _74 + 1u);\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_CullPrimitiveEXT = (gl_LocalInvocationIndex & 1u) != 0u;\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = int(gl_LocalInvocationIndex);\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = int(gl_LocalInvocationIndex);\n        uint _86 = gl_LocalInvocationIndex ^ 2u;\n        C[gl_LocalInvocationIndex].x = _32[_86];\n        C[gl_LocalInvocationIndex].y = _32[_86];\n        C[gl_LocalInvocationIndex].z = _32[_86];\n        C[gl_LocalInvocationIndex].w = _32[_86];\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 100\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %12 %17 %20 %21 %24 %28 %32 %34 %38 %44\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputLinesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %12 \"B\"\nOpName %17 \"SV_CullPrimitive\"\nOpName %20 \"SV_RenderTargetArrayIndex\"\nOpName %21 \"SV_PrimitiveID\"\nOpName %24 \"C\"\nOpName %28 \"indices\"\nOpName %36 \"\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %12 Location 1\nOpDecorate %17 BuiltIn CullPrimitiveEXT\nOpDecorate %17 PerPrimitiveEXT\nOpDecorate %20 BuiltIn Layer\nOpDecorate %20 PerPrimitiveEXT\nOpDecorate %21 BuiltIn PrimitiveId\nOpDecorate %21 PerPrimitiveEXT\nOpDecorate %24 Location 3\nOpDecorate %24 PerPrimitiveEXT\nOpDecorate %28 BuiltIn PrimitiveLineIndicesEXT\nOpDecorate %34 BuiltIn LocalInvocationIndex\nOpDecorate %44 BuiltIn NumSubgroups\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpVariable %10 Output\n%13 = OpTypeBool\n%14 = OpConstant %7 8\n%15 = OpTypeArray %13 %14\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%18 = OpTypeArray %7 %14\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%21 = OpVariable %19 Output\n%22 = OpTypeArray %6 %14\n%23 = OpTypePointer Output %22\n%24 = OpVariable %23 Output\n%25 = OpTypeVector %7 2\n%26 = OpTypeArray %25 %14\n%27 = OpTypePointer Output %26\n%28 = OpVariable %27 Output\n%29 = OpConstant %7 64\n%30 = OpTypeArray %5 %29\n%31 = OpTypePointer Workgroup %30\n%32 = OpVariable %31 Workgroup\n%33 = OpTypePointer Input %7\n%34 = OpVariable %33 Input\n%36 = OpTypeStruct %5\n%37 = OpTypePointer TaskPayloadWorkgroupEXT %36\n%38 = OpVariable %37 TaskPayloadWorkgroupEXT\n%40 = OpTypePointer Workgroup %5\n%42 = OpConstant %7 2\n%43 = OpConstant %7 264\n%44 = OpVariable %33 Input\n%47 = OpConstant %7 1\n%49 = OpConstant %7 3\n%52 = OpConstant %7 0\n%57 = OpTypePointer Output %5\n%65 = OpTypePointer TaskPayloadWorkgroupEXT %5\n%77 = OpTypePointer Output %25\n%81 = OpTypePointer Output %13\n%83 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%35 = OpLoad %7 %34\n%39 = OpConvertUToF %5 %35\n%41 = OpAccessChain %40 %32 %35\nOpStore %41 %39\nOpControlBarrier %42 %42 %43\nOpSetMeshOutputsEXT %8 %14\n%45 = OpLoad %7 %44\n%46 = OpIEqual %13 %45 %47\n%48 = OpGroupNonUniformBroadcastFirst %7 %49 %8\n%50 = OpGroupNonUniformBroadcastFirst %7 %49 %14\n%51 = OpIEqual %13 %48 %52\n%53 = OpIEqual %13 %50 %52\n%54 = OpLogicalOr %13 %51 %53\n%55 = OpLogicalAnd %13 %46 %54\nOpSelectionMerge %97 None\nOpBranchConditional %55 %96 %97\n%96 = OpLabel\nOpReturn\n%97 = OpLabel\n%56 = OpLoad %5 %41\n%58 = OpAccessChain %57 %11 %35 %52\nOpStore %58 %56\n%59 = OpAccessChain %57 %11 %35 %47\nOpStore %59 %56\n%60 = OpAccessChain %57 %11 %35 %42\nOpStore %60 %56\n%61 = OpAccessChain %57 %11 %35 %49\nOpStore %61 %56\n%62 = OpBitwiseXor %7 %35 %47\n%63 = OpAccessChain %40 %32 %62\n%64 = OpLoad %5 %63\n%66 = OpInBoundsAccessChain %65 %38 %52\n%67 = OpLoad %5 %66\n%68 = OpFAdd %5 %67 %64\n%69 = OpAccessChain %57 %12 %35 %52\nOpStore %69 %68\n%70 = OpAccessChain %57 %12 %35 %47\nOpStore %70 %68\n%71 = OpAccessChain %57 %12 %35 %42\nOpStore %71 %68\n%72 = OpAccessChain %57 %12 %35 %49\nOpStore %72 %68\n%73 = OpULessThan %13 %35 %14\nOpSelectionMerge %95 None\nOpBranchConditional %73 %94 %95\n%94 = OpLabel\n%74 = OpIMul %7 %35 %49\n%75 = OpIAdd %7 %74 %47\n%76 = OpCompositeConstruct %25 %74 %75\n%78 = OpAccessChain %77 %28 %35\nOpStore %78 %76\n%79 = OpBitwiseAnd %7 %35 %47\n%80 = OpINotEqual %13 %79 %52\n%82 = OpAccessChain %81 %17 %35\nOpStore %82 %80\n%84 = OpAccessChain %83 %21 %35\nOpStore %84 %35\n%85 = OpAccessChain %83 %20 %35\nOpStore %85 %35\n%86 = OpBitwiseXor %7 %35 %42\n%87 = OpAccessChain %40 %32 %86\n%88 = OpLoad %5 %87\n%89 = OpAccessChain %57 %24 %35 %52\nOpStore %89 %88\n%90 = OpAccessChain %57 %24 %35 %47\nOpStore %90 %88\n%91 = OpAccessChain %57 %24 %35 %42\nOpStore %91 %88\n%92 = OpAccessChain %57 %24 %35 %49\nOpStore %92 %88\nOpBranch %95\n%95 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/mesh-basic.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nstruct _36\n{\n    float _m0;\n};\n\nlayout(location = 1) out vec4 B[24];\nlayout(location = 3) perprimitiveEXT out vec4 C[8];\nshared float _32[64];\ntaskPayloadSharedEXT _36 _38;\n\nvoid main()\n{\n    _32[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex);\n    barrier();\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _32[gl_LocalInvocationIndex];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _32[gl_LocalInvocationIndex];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _32[gl_LocalInvocationIndex];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _32[gl_LocalInvocationIndex];\n    float _68 = _38._m0 + _32[gl_LocalInvocationIndex ^ 1u];\n    B[gl_LocalInvocationIndex].x = _68;\n    B[gl_LocalInvocationIndex].y = _68;\n    B[gl_LocalInvocationIndex].z = _68;\n    B[gl_LocalInvocationIndex].w = _68;\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _74 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_74, _74 + 1u, _74 + 2u);\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_CullPrimitiveEXT = (gl_LocalInvocationIndex & 1u) != 0u;\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = int(gl_LocalInvocationIndex);\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = int(gl_LocalInvocationIndex);\n        uint _87 = gl_LocalInvocationIndex ^ 2u;\n        C[gl_LocalInvocationIndex].x = _32[_87];\n        C[gl_LocalInvocationIndex].y = _32[_87];\n        C[gl_LocalInvocationIndex].z = _32[_87];\n        C[gl_LocalInvocationIndex].w = _32[_87];\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 101\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %12 %17 %20 %21 %24 %28 %32 %34 %38 %44\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %12 \"B\"\nOpName %17 \"SV_CullPrimitive\"\nOpName %20 \"SV_RenderTargetArrayIndex\"\nOpName %21 \"SV_PrimitiveID\"\nOpName %24 \"C\"\nOpName %28 \"indices\"\nOpName %36 \"\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %12 Location 1\nOpDecorate %17 BuiltIn CullPrimitiveEXT\nOpDecorate %17 PerPrimitiveEXT\nOpDecorate %20 BuiltIn Layer\nOpDecorate %20 PerPrimitiveEXT\nOpDecorate %21 BuiltIn PrimitiveId\nOpDecorate %21 PerPrimitiveEXT\nOpDecorate %24 Location 3\nOpDecorate %24 PerPrimitiveEXT\nOpDecorate %28 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %34 BuiltIn LocalInvocationIndex\nOpDecorate %44 BuiltIn NumSubgroups\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpVariable %10 Output\n%13 = OpTypeBool\n%14 = OpConstant %7 8\n%15 = OpTypeArray %13 %14\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%18 = OpTypeArray %7 %14\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%21 = OpVariable %19 Output\n%22 = OpTypeArray %6 %14\n%23 = OpTypePointer Output %22\n%24 = OpVariable %23 Output\n%25 = OpTypeVector %7 3\n%26 = OpTypeArray %25 %14\n%27 = OpTypePointer Output %26\n%28 = OpVariable %27 Output\n%29 = OpConstant %7 64\n%30 = OpTypeArray %5 %29\n%31 = OpTypePointer Workgroup %30\n%32 = OpVariable %31 Workgroup\n%33 = OpTypePointer Input %7\n%34 = OpVariable %33 Input\n%36 = OpTypeStruct %5\n%37 = OpTypePointer TaskPayloadWorkgroupEXT %36\n%38 = OpVariable %37 TaskPayloadWorkgroupEXT\n%40 = OpTypePointer Workgroup %5\n%42 = OpConstant %7 2\n%43 = OpConstant %7 264\n%44 = OpVariable %33 Input\n%47 = OpConstant %7 1\n%49 = OpConstant %7 3\n%52 = OpConstant %7 0\n%57 = OpTypePointer Output %5\n%65 = OpTypePointer TaskPayloadWorkgroupEXT %5\n%78 = OpTypePointer Output %25\n%82 = OpTypePointer Output %13\n%84 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %94\n%94 = OpLabel\n%35 = OpLoad %7 %34\n%39 = OpConvertUToF %5 %35\n%41 = OpAccessChain %40 %32 %35\nOpStore %41 %39\nOpControlBarrier %42 %42 %43\nOpSetMeshOutputsEXT %8 %14\n%45 = OpLoad %7 %44\n%46 = OpIEqual %13 %45 %47\n%48 = OpGroupNonUniformBroadcastFirst %7 %49 %8\n%50 = OpGroupNonUniformBroadcastFirst %7 %49 %14\n%51 = OpIEqual %13 %48 %52\n%53 = OpIEqual %13 %50 %52\n%54 = OpLogicalOr %13 %51 %53\n%55 = OpLogicalAnd %13 %46 %54\nOpSelectionMerge %98 None\nOpBranchConditional %55 %97 %98\n%97 = OpLabel\nOpReturn\n%98 = OpLabel\n%56 = OpLoad %5 %41\n%58 = OpAccessChain %57 %11 %35 %52\nOpStore %58 %56\n%59 = OpAccessChain %57 %11 %35 %47\nOpStore %59 %56\n%60 = OpAccessChain %57 %11 %35 %42\nOpStore %60 %56\n%61 = OpAccessChain %57 %11 %35 %49\nOpStore %61 %56\n%62 = OpBitwiseXor %7 %35 %47\n%63 = OpAccessChain %40 %32 %62\n%64 = OpLoad %5 %63\n%66 = OpInBoundsAccessChain %65 %38 %52\n%67 = OpLoad %5 %66\n%68 = OpFAdd %5 %67 %64\n%69 = OpAccessChain %57 %12 %35 %52\nOpStore %69 %68\n%70 = OpAccessChain %57 %12 %35 %47\nOpStore %70 %68\n%71 = OpAccessChain %57 %12 %35 %42\nOpStore %71 %68\n%72 = OpAccessChain %57 %12 %35 %49\nOpStore %72 %68\n%73 = OpULessThan %13 %35 %14\nOpSelectionMerge %96 None\nOpBranchConditional %73 %95 %96\n%95 = OpLabel\n%74 = OpIMul %7 %35 %49\n%75 = OpIAdd %7 %74 %47\n%76 = OpIAdd %7 %74 %42\n%77 = OpCompositeConstruct %25 %74 %75 %76\n%79 = OpAccessChain %78 %28 %35\nOpStore %79 %77\n%80 = OpBitwiseAnd %7 %35 %47\n%81 = OpINotEqual %13 %80 %52\n%83 = OpAccessChain %82 %17 %35\nOpStore %83 %81\n%85 = OpAccessChain %84 %21 %35\nOpStore %85 %35\n%86 = OpAccessChain %84 %20 %35\nOpStore %86 %35\n%87 = OpBitwiseXor %7 %35 %42\n%88 = OpAccessChain %40 %32 %87\n%89 = OpLoad %5 %88\n%90 = OpAccessChain %57 %24 %35 %52\nOpStore %90 %89\n%91 = OpAccessChain %57 %24 %35 %47\nOpStore %91 %89\n%92 = OpAccessChain %57 %24 %35 %42\nOpStore %92 %89\n%93 = OpAccessChain %57 %24 %35 %49\nOpStore %93 %89\nOpBranch %96\n%96 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/mesh-clip-cull.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nout gl_MeshPerVertexEXT\n{\n    vec4 gl_Position;\n    float gl_ClipDistance[4];\n    float gl_CullDistance[4];\n} gl_MeshVerticesEXT[];\n\nstruct _26\n{\n    float _m0[24][4];\n    float _m1[24][4];\n    float _m2[24][4];\n};\n\ntaskPayloadSharedEXT _26 _28;\n\nvoid main()\n{\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _28._m0[gl_LocalInvocationIndex][0u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _28._m0[gl_LocalInvocationIndex][1u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _28._m0[gl_LocalInvocationIndex][2u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _28._m0[gl_LocalInvocationIndex][3u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0u] = _28._m1[gl_LocalInvocationIndex][0u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[1u] = _28._m1[gl_LocalInvocationIndex][1u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[2u] = _28._m1[gl_LocalInvocationIndex][2u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[3u] = _28._m1[gl_LocalInvocationIndex][3u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[0u] = _28._m2[gl_LocalInvocationIndex][0u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1u] = _28._m2[gl_LocalInvocationIndex][1u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[2u] = _28._m2[gl_LocalInvocationIndex][2u];\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[3u] = _28._m2[gl_LocalInvocationIndex][3u];\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _82 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_82, _82 + 1u, _82 + 2u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability ClipDistance\nOpCapability CullDistance\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %16 %17 %22 %24 %28 %29\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %22 \"indices\"\nOpName %26 \"\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %16 BuiltIn ClipDistance\nOpDecorate %17 BuiltIn CullDistance\nOpDecorate %22 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %24 BuiltIn LocalInvocationIndex\nOpDecorate %29 BuiltIn NumSubgroups\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpConstant %7 4\n%13 = OpTypeArray %5 %12\n%14 = OpTypeArray %13 %8\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %15 Output\n%18 = OpConstant %7 8\n%19 = OpTypeVector %7 3\n%20 = OpTypeArray %19 %18\n%21 = OpTypePointer Output %20\n%22 = OpVariable %21 Output\n%23 = OpTypePointer Input %7\n%24 = OpVariable %23 Input\n%26 = OpTypeStruct %14 %14 %14\n%27 = OpTypePointer TaskPayloadWorkgroupEXT %26\n%28 = OpVariable %27 TaskPayloadWorkgroupEXT\n%29 = OpVariable %23 Input\n%31 = OpTypeBool\n%33 = OpConstant %7 1\n%35 = OpConstant %7 3\n%38 = OpConstant %7 0\n%42 = OpTypePointer TaskPayloadWorkgroupEXT %5\n%48 = OpConstant %7 2\n%52 = OpTypePointer Output %5\n%86 = OpTypePointer Output %19\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %88\n%88 = OpLabel\n%25 = OpLoad %7 %24\nOpSetMeshOutputsEXT %8 %18\n%30 = OpLoad %7 %29\n%32 = OpIEqual %31 %30 %33\n%34 = OpGroupNonUniformBroadcastFirst %7 %35 %8\n%36 = OpGroupNonUniformBroadcastFirst %7 %35 %18\n%37 = OpIEqual %31 %34 %38\n%39 = OpIEqual %31 %36 %38\n%40 = OpLogicalOr %31 %37 %39\n%41 = OpLogicalAnd %31 %32 %40\nOpSelectionMerge %92 None\nOpBranchConditional %41 %91 %92\n%91 = OpLabel\nOpReturn\n%92 = OpLabel\n%43 = OpInBoundsAccessChain %42 %28 %38 %25 %38\n%44 = OpLoad %5 %43\n%45 = OpInBoundsAccessChain %42 %28 %38 %25 %33\n%46 = OpLoad %5 %45\n%47 = OpInBoundsAccessChain %42 %28 %38 %25 %48\n%49 = OpLoad %5 %47\n%50 = OpInBoundsAccessChain %42 %28 %38 %25 %35\n%51 = OpLoad %5 %50\n%53 = OpAccessChain %52 %11 %25 %38\nOpStore %53 %44\n%54 = OpAccessChain %52 %11 %25 %33\nOpStore %54 %46\n%55 = OpAccessChain %52 %11 %25 %48\nOpStore %55 %49\n%56 = OpAccessChain %52 %11 %25 %35\nOpStore %56 %51\n%57 = OpInBoundsAccessChain %42 %28 %33 %25 %38\n%58 = OpLoad %5 %57\n%59 = OpInBoundsAccessChain %42 %28 %33 %25 %33\n%60 = OpLoad %5 %59\n%61 = OpInBoundsAccessChain %42 %28 %33 %25 %48\n%62 = OpLoad %5 %61\n%63 = OpInBoundsAccessChain %42 %28 %33 %25 %35\n%64 = OpLoad %5 %63\n%65 = OpAccessChain %52 %16 %25 %38\nOpStore %65 %58\n%66 = OpAccessChain %52 %16 %25 %33\nOpStore %66 %60\n%67 = OpAccessChain %52 %16 %25 %48\nOpStore %67 %62\n%68 = OpAccessChain %52 %16 %25 %35\nOpStore %68 %64\n%69 = OpInBoundsAccessChain %42 %28 %48 %25 %38\n%70 = OpLoad %5 %69\n%71 = OpInBoundsAccessChain %42 %28 %48 %25 %33\n%72 = OpLoad %5 %71\n%73 = OpInBoundsAccessChain %42 %28 %48 %25 %48\n%74 = OpLoad %5 %73\n%75 = OpInBoundsAccessChain %42 %28 %48 %25 %35\n%76 = OpLoad %5 %75\n%77 = OpAccessChain %52 %17 %25 %38\nOpStore %77 %70\n%78 = OpAccessChain %52 %17 %25 %33\nOpStore %78 %72\n%79 = OpAccessChain %52 %17 %25 %48\nOpStore %79 %74\n%80 = OpAccessChain %52 %17 %25 %35\nOpStore %80 %76\n%81 = OpULessThan %31 %25 %18\nOpSelectionMerge %90 None\nOpBranchConditional %81 %89 %90\n%89 = OpLabel\n%82 = OpIMul %7 %25 %35\n%83 = OpIAdd %7 %82 %33\n%84 = OpIAdd %7 %82 %48\n%85 = OpCompositeConstruct %19 %82 %83 %84\n%87 = OpAccessChain %86 %22 %25\nOpStore %87 %85\nOpBranch %90\n%90 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/raygen-complex-storage-class.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _14\n{\n    vec4 _m0;\n};\n\nstruct _18\n{\n    _14 _m0;\n    _14 _m1;\n};\n\nlayout(set = 40, binding = 30) uniform accelerationStructureEXT AS;\nlayout(set = 20, binding = 10) uniform writeonly image2D IMG;\nlayout(location = 0) callableDataEXT _14 _16;\nlayout(location = 1) callableDataEXT _14 _17;\nlayout(location = 2) callableDataEXT _18 _20;\nlayout(location = 3) rayPayloadEXT _14 _22;\nlayout(location = 4) rayPayloadEXT _14 _23;\nlayout(location = 5) rayPayloadEXT _18 _25;\n\nvoid main()\n{\n    traceRayEXT(AS, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 5);\n    _23._m0 = _25._m0._m0;\n    traceRayEXT(AS, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 4);\n    _22._m0 = _25._m1._m0;\n    traceRayEXT(AS, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 3);\n    _20._m0._m0 = _23._m0;\n    _20._m1._m0 = _22._m0;\n    executeCallableEXT(0u, 2);\n    _17._m0 = _20._m0._m0;\n    executeCallableEXT(0u, 1);\n    _16._m0 = _20._m1._m0;\n    executeCallableEXT(0u, 0);\n    imageStore(IMG, ivec2(uvec2(0u)), vec4(_16._m0.x + _17._m0.x, _16._m0.y + _17._m0.y, _16._m0.z + _17._m0.z, _16._m0.w + _17._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 80\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %16 %17 %20 %22 %23 %25\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %12 \"IMG\"\nOpName %14 \"\"\nOpName %18 \"\"\nOpDecorate %8 DescriptorSet 40\nOpDecorate %8 Binding 30\nOpDecorate %12 DescriptorSet 20\nOpDecorate %12 Binding 10\nOpDecorate %12 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeVector %9 4\n%14 = OpTypeStruct %13\n%15 = OpTypePointer CallableDataKHR %14\n%16 = OpVariable %15 CallableDataKHR\n%17 = OpVariable %15 CallableDataKHR\n%18 = OpTypeStruct %14 %14\n%19 = OpTypePointer CallableDataKHR %18\n%20 = OpVariable %19 CallableDataKHR\n%21 = OpTypePointer RayPayloadKHR %14\n%22 = OpVariable %21 RayPayloadKHR\n%23 = OpVariable %21 RayPayloadKHR\n%24 = OpTypePointer RayPayloadKHR %18\n%25 = OpVariable %24 RayPayloadKHR\n%27 = OpTypeInt 32 0\n%28 = OpConstant %27 0\n%29 = OpConstant %9 1\n%30 = OpConstant %9 0\n%31 = OpConstant %9 2\n%32 = OpConstant %9 3\n%33 = OpConstant %9 4\n%34 = OpTypeVector %9 3\n%37 = OpTypePointer RayPayloadKHR %13\n%41 = OpConstant %27 1\n%53 = OpTypePointer CallableDataKHR %13\n%75 = OpTypeVector %27 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %78\n%78 = OpLabel\n%26 = OpLoad %6 %8\n%35 = OpCompositeConstruct %34 %29 %31 %32\n%36 = OpCompositeConstruct %34 %30 %30 %29\nOpTraceRayKHR %26 %28 %28 %28 %28 %28 %35 %29 %36 %33 %25\n%38 = OpInBoundsAccessChain %37 %25 %28 %28\n%39 = OpLoad %13 %38\n%40 = OpInBoundsAccessChain %37 %25 %41 %28\n%42 = OpLoad %13 %40\n%43 = OpLoad %6 %8\n%44 = OpInBoundsAccessChain %37 %23 %28\nOpStore %44 %39\n%45 = OpCompositeConstruct %34 %29 %31 %32\n%46 = OpCompositeConstruct %34 %30 %30 %29\nOpTraceRayKHR %43 %28 %28 %28 %28 %28 %45 %29 %46 %33 %23\n%47 = OpLoad %13 %44\n%48 = OpLoad %6 %8\n%49 = OpInBoundsAccessChain %37 %22 %28\nOpStore %49 %42\n%50 = OpCompositeConstruct %34 %29 %31 %32\n%51 = OpCompositeConstruct %34 %30 %30 %29\nOpTraceRayKHR %48 %28 %28 %28 %28 %28 %50 %29 %51 %33 %22\n%52 = OpLoad %13 %49\n%54 = OpInBoundsAccessChain %53 %20 %28 %28\nOpStore %54 %47\n%55 = OpInBoundsAccessChain %53 %20 %41 %28\nOpStore %55 %52\nOpExecuteCallableKHR %28 %20\n%56 = OpLoad %13 %54\n%57 = OpLoad %13 %55\n%58 = OpInBoundsAccessChain %53 %17 %28\nOpStore %58 %56\nOpExecuteCallableKHR %28 %17\n%59 = OpLoad %13 %58\n%60 = OpCompositeExtract %9 %59 0\n%61 = OpCompositeExtract %9 %59 1\n%62 = OpCompositeExtract %9 %59 2\n%63 = OpCompositeExtract %9 %59 3\n%64 = OpInBoundsAccessChain %53 %16 %28\nOpStore %64 %57\nOpExecuteCallableKHR %28 %16\n%65 = OpLoad %13 %64\n%66 = OpCompositeExtract %9 %65 0\n%67 = OpFAdd %9 %66 %60\n%68 = OpCompositeExtract %9 %65 1\n%69 = OpFAdd %9 %68 %61\n%70 = OpCompositeExtract %9 %65 2\n%71 = OpFAdd %9 %70 %62\n%72 = OpCompositeExtract %9 %65 3\n%73 = OpFAdd %9 %72 %63\n%74 = OpLoad %10 %12\n%76 = OpCompositeConstruct %75 %28 %28\n%77 = OpCompositeConstruct %13 %67 %69 %71 %73\nOpImageWrite %74 %76 %77\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/raygen-skip-inactive-resources.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _13\n{\n    float _m0;\n};\n\nstruct _17\n{\n    vec4 _m0;\n};\n\nlayout(set = 40, binding = 30) uniform accelerationStructureEXT AS;\nlayout(set = 20, binding = 10) uniform writeonly image2D IMG;\nlayout(location = 0) rayPayloadEXT _13 _15;\nlayout(location = 1) rayPayloadEXT _17 _19;\n\nvoid main()\n{\n    traceRayEXT(AS, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(AS, 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(IMG, ivec2(uvec2(0u)), vec4(_15._m0 + _19._m0.x, _15._m0 + _19._m0.y, _15._m0 + _19._m0.z, _15._m0 + _19._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %15 %19\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %12 \"IMG\"\nOpName %13 \"\"\nOpName %17 \"\"\nOpDecorate %8 DescriptorSet 40\nOpDecorate %8 Binding 30\nOpDecorate %12 DescriptorSet 20\nOpDecorate %12 Binding 10\nOpDecorate %12 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeStruct %9\n%14 = OpTypePointer RayPayloadKHR %13\n%15 = OpVariable %14 RayPayloadKHR\n%16 = OpTypeVector %9 4\n%17 = OpTypeStruct %16\n%18 = OpTypePointer RayPayloadKHR %17\n%19 = OpVariable %18 RayPayloadKHR\n%21 = OpTypeInt 32 0\n%22 = OpConstant %21 0\n%23 = OpConstant %9 1\n%24 = OpConstant %9 0\n%25 = OpConstant %9 2\n%26 = OpConstant %9 3\n%27 = OpConstant %9 4\n%28 = OpTypeVector %9 3\n%31 = OpTypePointer RayPayloadKHR %16\n%39 = OpConstant %21 1\n%42 = OpTypePointer RayPayloadKHR %9\n%50 = OpTypeVector %21 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%20 = OpLoad %6 %8\n%29 = OpCompositeConstruct %28 %23 %25 %26\n%30 = OpCompositeConstruct %28 %24 %24 %23\nOpTraceRayKHR %20 %22 %22 %22 %22 %22 %29 %23 %30 %27 %19\n%32 = OpInBoundsAccessChain %31 %19 %22\n%33 = OpLoad %16 %32\n%34 = OpCompositeExtract %9 %33 0\n%35 = OpCompositeExtract %9 %33 1\n%36 = OpCompositeExtract %9 %33 2\n%37 = OpCompositeExtract %9 %33 3\n%38 = OpLoad %6 %8\n%40 = OpCompositeConstruct %28 %23 %25 %26\n%41 = OpCompositeConstruct %28 %24 %24 %23\nOpTraceRayKHR %38 %22 %39 %22 %22 %22 %40 %23 %41 %27 %15\n%43 = OpInBoundsAccessChain %42 %15 %22\n%44 = OpLoad %9 %43\n%45 = OpFAdd %9 %44 %34\n%46 = OpFAdd %9 %44 %35\n%47 = OpFAdd %9 %44 %36\n%48 = OpFAdd %9 %44 %37\n%49 = OpLoad %10 %12\n%51 = OpCompositeConstruct %50 %22 %22\n%52 = OpCompositeConstruct %16 %45 %46 %47 %48\nOpImageWrite %49 %51 %52\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/raygen.rgen",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _13\n{\n    float _m0;\n};\n\nstruct _17\n{\n    vec4 _m0;\n};\n\nlayout(set = 40, binding = 30) uniform accelerationStructureEXT AS;\nlayout(set = 20, binding = 10) uniform writeonly image2D IMG;\nlayout(location = 0) rayPayloadEXT _13 _15;\nlayout(location = 1) rayPayloadEXT _17 _19;\n\nvoid main()\n{\n    traceRayEXT(AS, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    traceRayEXT(AS, 0u, 1u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 0);\n    imageStore(IMG, ivec2(uvec2(0u)), vec4(_15._m0 + _19._m0.x, _15._m0 + _19._m0.y, _15._m0 + _19._m0.z, _15._m0 + _19._m0.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint RayGenerationKHR %3 \"main\" %8 %12 %15 %19\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %12 \"IMG\"\nOpName %13 \"\"\nOpName %17 \"\"\nOpDecorate %8 DescriptorSet 40\nOpDecorate %8 Binding 30\nOpDecorate %12 DescriptorSet 20\nOpDecorate %12 Binding 10\nOpDecorate %12 NonReadable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeStruct %9\n%14 = OpTypePointer RayPayloadKHR %13\n%15 = OpVariable %14 RayPayloadKHR\n%16 = OpTypeVector %9 4\n%17 = OpTypeStruct %16\n%18 = OpTypePointer RayPayloadKHR %17\n%19 = OpVariable %18 RayPayloadKHR\n%21 = OpTypeInt 32 0\n%22 = OpConstant %21 0\n%23 = OpConstant %9 1\n%24 = OpConstant %9 0\n%25 = OpConstant %9 2\n%26 = OpConstant %9 3\n%27 = OpConstant %9 4\n%28 = OpTypeVector %9 3\n%31 = OpTypePointer RayPayloadKHR %16\n%39 = OpConstant %21 1\n%42 = OpTypePointer RayPayloadKHR %9\n%50 = OpTypeVector %21 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%20 = OpLoad %6 %8\n%29 = OpCompositeConstruct %28 %23 %25 %26\n%30 = OpCompositeConstruct %28 %24 %24 %23\nOpTraceRayKHR %20 %22 %22 %22 %22 %22 %29 %23 %30 %27 %19\n%32 = OpInBoundsAccessChain %31 %19 %22\n%33 = OpLoad %16 %32\n%34 = OpCompositeExtract %9 %33 0\n%35 = OpCompositeExtract %9 %33 1\n%36 = OpCompositeExtract %9 %33 2\n%37 = OpCompositeExtract %9 %33 3\n%38 = OpLoad %6 %8\n%40 = OpCompositeConstruct %28 %23 %25 %26\n%41 = OpCompositeConstruct %28 %24 %24 %23\nOpTraceRayKHR %38 %22 %39 %22 %22 %22 %40 %23 %41 %27 %15\n%43 = OpInBoundsAccessChain %42 %15 %22\n%44 = OpLoad %9 %43\n%45 = OpFAdd %9 %44 %34\n%46 = OpFAdd %9 %44 %35\n%47 = OpFAdd %9 %44 %36\n%48 = OpFAdd %9 %44 %37\n%49 = OpLoad %10 %12\n%51 = OpCompositeConstruct %50 %22 %22\n%52 = OpCompositeConstruct %16 %45 %46 %47 %48\nOpImageWrite %49 %51 %52\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/raymiss-chain.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _11\n{\n    vec4 _m0;\n};\n\nlayout(set = 0, binding = 0) uniform accelerationStructureEXT AS;\nlayout(location = 0) rayPayloadInEXT _11 payload;\nlayout(location = 1) rayPayloadEXT _11 _15;\n\nvoid main()\n{\n    _15._m0 = payload._m0;\n    traceRayEXT(AS, 0u, 0u, 0u, 0u, 0u, vec3(1.0, 2.0, 3.0), 1.0, vec3(0.0, 0.0, 1.0), 4.0, 1);\n    payload._m0 = _15._m0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MissKHR %3 \"main\" %8 %13 %15\nOpName %3 \"main\"\nOpName %8 \"AS\"\nOpName %11 \"\"\nOpName %13 \"payload\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 1\n%6 = OpTypeAccelerationStructureKHR\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypeStruct %10\n%12 = OpTypePointer IncomingRayPayloadKHR %11\n%13 = OpVariable %12 IncomingRayPayloadKHR\n%14 = OpTypePointer RayPayloadKHR %11\n%15 = OpVariable %14 RayPayloadKHR\n%16 = OpTypePointer IncomingRayPayloadKHR %10\n%18 = OpTypeInt 32 0\n%19 = OpConstant %18 0\n%22 = OpTypePointer RayPayloadKHR %10\n%24 = OpConstant %9 1\n%25 = OpConstant %9 0\n%26 = OpConstant %9 2\n%27 = OpConstant %9 3\n%28 = OpConstant %9 4\n%29 = OpTypeVector %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%17 = OpInBoundsAccessChain %16 %13 %19\n%20 = OpLoad %10 %17\n%21 = OpLoad %6 %8\n%23 = OpInBoundsAccessChain %22 %15 %19\nOpStore %23 %20\n%30 = OpCompositeConstruct %29 %24 %26 %27\n%31 = OpCompositeConstruct %29 %25 %25 %24\nOpTraceRayKHR %21 %19 %19 %19 %19 %19 %30 %24 %31 %28 %15\n%32 = OpLoad %10 %23\nOpStore %17 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/raymiss.rmiss",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n\nstruct _7\n{\n    vec4 _m0;\n};\n\nlayout(location = 0) rayPayloadInEXT _7 payload;\n\nvoid main()\n{\n    payload._m0 = vec4(1.0, 2.0, 3.0, 4.0);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MissKHR %3 \"main\" %9\nOpName %3 \"main\"\nOpName %7 \"\"\nOpName %9 \"payload\"\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeStruct %6\n%8 = OpTypePointer IncomingRayPayloadKHR %7\n%9 = OpVariable %8 IncomingRayPayloadKHR\n%10 = OpTypePointer IncomingRayPayloadKHR %6\n%12 = OpTypeInt 32 0\n%13 = OpConstant %12 0\n%14 = OpConstant %5 1\n%15 = OpConstant %5 2\n%16 = OpConstant %5 3\n%17 = OpConstant %5 4\n%18 = OpConstantComposite %6 %14 %15 %16 %17\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %19\n%19 = OpLabel\n%11 = OpInBoundsAccessChain %10 %9 %13\nOpStore %11 %18\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/simple.dual-source-blending.frag",
    "content": "#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[2];\n} _12;\n\nlayout(location = 0, index = 0) out vec4 SV_Target;\nlayout(location = 0, index = 1) out vec4 SV_Target_1;\n\nvoid main()\n{\n    SV_Target.x = _12._m0[0u].x;\n    SV_Target.y = _12._m0[0u].y;\n    SV_Target.z = _12._m0[0u].z;\n    SV_Target.w = _12._m0[0u].w;\n    SV_Target_1.x = _12._m0[1u].x;\n    SV_Target_1.y = _12._m0[1u].y;\n    SV_Target_1.z = _12._m0[1u].z;\n    SV_Target_1.w = _12._m0[1u].w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %14 %15\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %14 \"SV_Target\"\nOpName %15 \"SV_Target_1\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %14 Location 0\nOpDecorate %14 Index 0\nOpDecorate %15 Location 0\nOpDecorate %15 Index 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 2\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Output %8\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpConstant %5 0\n%17 = OpTypePointer Uniform %8\n%24 = OpTypePointer Output %7\n%27 = OpConstant %5 1\n%30 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%18 = OpAccessChain %17 %12 %16 %16\n%19 = OpLoad %8 %18\n%20 = OpCompositeExtract %7 %19 0\n%21 = OpCompositeExtract %7 %19 1\n%22 = OpCompositeExtract %7 %19 2\n%23 = OpCompositeExtract %7 %19 3\n%25 = OpAccessChain %24 %14 %16\nOpStore %25 %20\n%26 = OpAccessChain %24 %14 %27\nOpStore %26 %21\n%28 = OpAccessChain %24 %14 %6\nOpStore %28 %22\n%29 = OpAccessChain %24 %14 %30\nOpStore %29 %23\n%31 = OpAccessChain %17 %12 %16 %27\n%32 = OpLoad %8 %31\n%33 = OpCompositeExtract %7 %32 0\n%34 = OpCompositeExtract %7 %32 1\n%35 = OpCompositeExtract %7 %32 2\n%36 = OpCompositeExtract %7 %32 3\n%37 = OpAccessChain %24 %15 %16\nOpStore %37 %33\n%38 = OpAccessChain %24 %15 %27\nOpStore %38 %34\n%39 = OpAccessChain %24 %15 %6\nOpStore %39 %35\n%40 = OpAccessChain %24 %15 %30\nOpStore %40 %36\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/simple.invariant.vert",
    "content": "#version 460\n\ninvariant gl_Position;\n\nlayout(location = 0) in vec4 A;\nlayout(location = 1) in vec4 B;\nlayout(location = 2) in vec4 C;\n\nvoid main()\n{\n    float _44 = fma(A.x, B.x, C.x);\n    float _45 = fma(A.y, B.y, C.y);\n    float _46 = fma(A.z, B.z, C.z);\n    float _47 = fma(A.w, B.w, C.w);\n    gl_Position.x = _44;\n    gl_Position.y = _45;\n    gl_Position.z = _46;\n    gl_Position.w = _47;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\nOpCapability Shader\n%43 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %9 %10 %12\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %9 \"B\"\nOpName %10 \"C\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 Location 0\nOpDecorate %9 Location 1\nOpDecorate %10 Location 2\nOpDecorate %12 BuiltIn Position\nOpDecorate %12 Invariant\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpVariable %7 Input\n%10 = OpVariable %7 Input\n%11 = OpTypePointer Output %6\n%12 = OpVariable %11 Output\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%22 = OpConstant %15 2\n%25 = OpConstant %15 3\n%48 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %53\n%53 = OpLabel\n%14 = OpAccessChain %13 %10 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %10 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %13 %10 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %13 %10 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %13 %9 %16\n%28 = OpLoad %5 %27\n%29 = OpAccessChain %13 %9 %19\n%30 = OpLoad %5 %29\n%31 = OpAccessChain %13 %9 %22\n%32 = OpLoad %5 %31\n%33 = OpAccessChain %13 %9 %25\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %13 %8 %16\n%36 = OpLoad %5 %35\n%37 = OpAccessChain %13 %8 %19\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %13 %8 %22\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %13 %8 %25\n%42 = OpLoad %5 %41\n%44 = OpExtInst %5 %43 Fma %36 %28 %17\n%45 = OpExtInst %5 %43 Fma %38 %30 %20\n%46 = OpExtInst %5 %43 Fma %40 %32 %23\n%47 = OpExtInst %5 %43 Fma %42 %34 %26\n%49 = OpAccessChain %48 %12 %16\nOpStore %49 %44\n%50 = OpAccessChain %48 %12 %19\nOpStore %50 %45\n%51 = OpAccessChain %48 %12 %22\nOpStore %51 %46\n%52 = OpAccessChain %48 %12 %25\nOpStore %52 %47\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/stage-input-output.16bit-io.frag",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n\nlayout(location = 0) in f16vec2 A;\nlayout(location = 1) flat in i16vec2 B;\nlayout(location = 1, component = 2) flat in uint16_t C;\nlayout(location = 0) out f16vec2 SV_Target;\nlayout(location = 1) out i16vec2 SV_Target_1;\nlayout(location = 2) out uint16_t SV_Target_2;\n\nvoid main()\n{\n    SV_Target.x = A.x * float16_t(8.0);\n    SV_Target.y = A.y * float16_t(8.0);\n    SV_Target_1.x = int16_t(uint16_t(B.x) * 65528us);\n    SV_Target_1.y = int16_t(uint16_t(B.y) * 65528us);\n    SV_Target_2 = C << 2us;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageInputOutput16\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %12 %15 %17 %19 %21\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %12 \"B\"\nOpName %15 \"C\"\nOpName %17 \"SV_Target\"\nOpName %19 \"SV_Target_1\"\nOpName %21 \"SV_Target_2\"\nOpDecorate %8 Location 0\nOpDecorate %12 Flat\nOpDecorate %12 Location 1\nOpDecorate %15 Flat\nOpDecorate %15 Location 1\nOpDecorate %15 Component 2\nOpDecorate %17 Location 0\nOpDecorate %19 Location 1\nOpDecorate %21 Location 2\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 16\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeInt 16 1\n%10 = OpTypeVector %9 2\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeInt 16 0\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Output %6\n%17 = OpVariable %16 Output\n%18 = OpTypePointer Output %10\n%19 = OpVariable %18 Output\n%20 = OpTypePointer Output %13\n%21 = OpVariable %20 Output\n%23 = OpTypePointer Input %9\n%25 = OpTypeInt 32 0\n%26 = OpConstant %25 0\n%30 = OpConstant %25 1\n%33 = OpTypePointer Input %5\n%39 = OpConstant %5 0x1p+3\n%42 = OpConstant %13 65528\n%45 = OpConstant %13 2\n%46 = OpTypePointer Output %5\n%49 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%22 = OpLoad %13 %15\n%24 = OpAccessChain %23 %12 %26\n%27 = OpLoad %9 %24\n%28 = OpBitcast %13 %27\n%29 = OpAccessChain %23 %12 %30\n%31 = OpLoad %9 %29\n%32 = OpBitcast %13 %31\n%34 = OpAccessChain %33 %8 %26\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %33 %8 %30\n%37 = OpLoad %5 %36\n%38 = OpFMul %5 %35 %39\n%40 = OpFMul %5 %37 %39\n%41 = OpIMul %13 %28 %42\n%43 = OpIMul %13 %32 %42\n%44 = OpShiftLeftLogical %13 %22 %45\n%47 = OpAccessChain %46 %17 %26\nOpStore %47 %38\n%48 = OpAccessChain %46 %17 %30\nOpStore %48 %40\n%50 = OpAccessChain %49 %19 %26\n%51 = OpBitcast %9 %41\nOpStore %50 %51\n%52 = OpAccessChain %49 %19 %30\n%53 = OpBitcast %9 %43\nOpStore %52 %53\nOpStore %21 %44\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/stage-input-output.frag",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n\nlayout(location = 0) in mediump vec2 A;\nlayout(location = 1) flat in mediump ivec2 B;\nlayout(location = 1, component = 2) flat in mediump uint C;\nlayout(location = 0) out mediump vec2 SV_Target;\nlayout(location = 1) out mediump ivec2 SV_Target_1;\nlayout(location = 2) out mediump uint SV_Target_2;\n\nvoid main()\n{\n    SV_Target.x = float(float16_t(A.x) * float16_t(8.0));\n    SV_Target.y = float(float16_t(A.y) * float16_t(8.0));\n    SV_Target_1.x = int(int16_t(uint16_t(B.x) * 65528us));\n    SV_Target_1.y = int(int16_t(uint16_t(B.y) * 65528us));\n    SV_Target_2 = uint(uint16_t(C) << 2us);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 63\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %12 %15 %17 %19 %21\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"A\"\nOpName %12 \"B\"\nOpName %15 \"C\"\nOpName %17 \"SV_Target\"\nOpName %19 \"SV_Target_1\"\nOpName %21 \"SV_Target_2\"\nOpDecorate %8 RelaxedPrecision\nOpDecorate %8 Location 0\nOpDecorate %12 RelaxedPrecision\nOpDecorate %12 Flat\nOpDecorate %12 Location 1\nOpDecorate %15 RelaxedPrecision\nOpDecorate %15 Flat\nOpDecorate %15 Location 1\nOpDecorate %15 Component 2\nOpDecorate %17 RelaxedPrecision\nOpDecorate %17 Location 0\nOpDecorate %19 RelaxedPrecision\nOpDecorate %19 Location 1\nOpDecorate %21 RelaxedPrecision\nOpDecorate %21 Location 2\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 2\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypeInt 32 1\n%10 = OpTypeVector %9 2\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%13 = OpTypeInt 32 0\n%14 = OpTypePointer Input %13\n%15 = OpVariable %14 Input\n%16 = OpTypePointer Output %6\n%17 = OpVariable %16 Output\n%18 = OpTypePointer Output %10\n%19 = OpVariable %18 Output\n%20 = OpTypePointer Output %13\n%21 = OpVariable %20 Output\n%23 = OpTypeInt 16 0\n%25 = OpTypePointer Input %9\n%27 = OpConstant %13 0\n%31 = OpConstant %13 1\n%34 = OpTypePointer Input %5\n%37 = OpTypeFloat 16\n%43 = OpConstant %37 0x1p+3\n%46 = OpConstant %23 65528\n%49 = OpConstant %23 2\n%50 = OpTypePointer Output %5\n%55 = OpTypePointer Output %9\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%22 = OpLoad %13 %15\n%24 = OpUConvert %23 %22\n%26 = OpAccessChain %25 %12 %27\n%28 = OpLoad %9 %26\n%29 = OpSConvert %23 %28\n%30 = OpAccessChain %25 %12 %31\n%32 = OpLoad %9 %30\n%33 = OpSConvert %23 %32\n%35 = OpAccessChain %34 %8 %27\n%36 = OpLoad %5 %35\n%38 = OpFConvert %37 %36\n%39 = OpAccessChain %34 %8 %31\n%40 = OpLoad %5 %39\n%41 = OpFConvert %37 %40\n%42 = OpFMul %37 %38 %43\n%44 = OpFMul %37 %41 %43\n%45 = OpIMul %23 %29 %46\n%47 = OpIMul %23 %33 %46\n%48 = OpShiftLeftLogical %23 %24 %49\n%51 = OpAccessChain %50 %17 %27\n%52 = OpFConvert %5 %42\nOpStore %51 %52\n%53 = OpAccessChain %50 %17 %31\n%54 = OpFConvert %5 %44\nOpStore %53 %54\n%56 = OpAccessChain %55 %19 %27\n%57 = OpSConvert %9 %45\nOpStore %56 %57\n%58 = OpAccessChain %55 %19 %31\n%59 = OpSConvert %9 %47\nOpStore %58 %59\n%60 = OpUConvert %13 %48\nOpStore %21 %60\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/stream-out.stream-out.vert",
    "content": "#version 460\n\nlayout(xfb_buffer = 1, xfb_stride = 32) out gl_PerVertex\n{\n    layout(xfb_offset = 16) vec4 gl_Position;\n};\n\nlayout(location = 1, xfb_buffer = 0, xfb_stride = 32, xfb_offset = 0) out vec4 StreamOut;\nlayout(location = 2, xfb_buffer = 1, xfb_stride = 16, xfb_offset = 0) out vec4 StreamOut_1;\n\nvoid main()\n{\n    gl_Position.x = 2.0;\n    gl_Position.y = 2.0;\n    gl_Position.z = 2.0;\n    gl_Position.w = 2.0;\n    StreamOut.x = 4.0;\n    StreamOut.y = 4.0;\n    StreamOut.z = 4.0;\n    StreamOut.w = 4.0;\n    StreamOut_1.x = 6.0;\n    StreamOut_1.y = 6.0;\n    StreamOut_1.z = 6.0;\n    StreamOut_1.w = 6.0;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpCapability TransformFeedback\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %9 %10\nOpExecutionMode %3 Xfb\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %9 \"StreamOut\"\nOpName %10 \"StreamOut_1\"\nOpDecorate %8 Offset 16\nOpDecorate %8 XfbStride 32\nOpDecorate %8 XfbBuffer 1\nOpDecorate %8 BuiltIn Position\nOpDecorate %9 Offset 0\nOpDecorate %9 XfbStride 32\nOpDecorate %9 XfbBuffer 0\nOpDecorate %9 Location 1\nOpDecorate %10 Offset 0\nOpDecorate %10 XfbStride 16\nOpDecorate %10 XfbBuffer 1\nOpDecorate %10 Location 2\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpVariable %7 Output\n%10 = OpVariable %7 Output\n%11 = OpTypePointer Output %5\n%13 = OpTypeInt 32 0\n%14 = OpConstant %13 0\n%15 = OpConstant %5 2\n%17 = OpConstant %13 1\n%19 = OpConstant %13 2\n%21 = OpConstant %13 3\n%23 = OpConstant %5 4\n%28 = OpConstant %5 6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%12 = OpAccessChain %11 %8 %14\nOpStore %12 %15\n%16 = OpAccessChain %11 %8 %17\nOpStore %16 %15\n%18 = OpAccessChain %11 %8 %19\nOpStore %18 %15\n%20 = OpAccessChain %11 %8 %21\nOpStore %20 %15\n%22 = OpAccessChain %11 %9 %14\nOpStore %22 %23\n%24 = OpAccessChain %11 %9 %17\nOpStore %24 %23\n%25 = OpAccessChain %11 %9 %19\nOpStore %25 %23\n%26 = OpAccessChain %11 %9 %21\nOpStore %26 %23\n%27 = OpAccessChain %11 %10 %14\nOpStore %27 %28\n%29 = OpAccessChain %11 %10 %17\nOpStore %29 %28\n%30 = OpAccessChain %11 %10 %19\nOpStore %30 %28\n%31 = OpAccessChain %11 %10 %21\nOpStore %31 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/swizzle.rt-swizzle.frag",
    "content": "#version 460\n\nlayout(location = 0) in vec4 TEXCOORD;\nlayout(location = 0) out vec4 SV_Target;\nlayout(location = 1) out vec4 SV_Target_1;\n\nvoid main()\n{\n    SV_Target.y = TEXCOORD.x;\n    SV_Target.z = TEXCOORD.y;\n    SV_Target.w = TEXCOORD.z;\n    SV_Target.x = TEXCOORD.w;\n    SV_Target_1.y = TEXCOORD.x;\n    SV_Target_1.x = TEXCOORD.y;\n    SV_Target_1.w = TEXCOORD.z;\n    SV_Target_1.z = TEXCOORD.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Fragment %3 \"main\" %8 %10 %11\nOpExecutionMode %3 OriginUpperLeft\nOpName %3 \"main\"\nOpName %8 \"TEXCOORD\"\nOpName %10 \"SV_Target\"\nOpName %11 \"SV_Target_1\"\nOpDecorate %8 Location 0\nOpDecorate %10 Location 0\nOpDecorate %11 Location 1\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpVariable %9 Output\n%12 = OpTypePointer Input %5\n%14 = OpTypeInt 32 0\n%15 = OpConstant %14 0\n%18 = OpConstant %14 1\n%21 = OpConstant %14 2\n%24 = OpConstant %14 3\n%26 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%13 = OpAccessChain %12 %8 %15\n%16 = OpLoad %5 %13\n%17 = OpAccessChain %12 %8 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %12 %8 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %12 %8 %24\n%25 = OpLoad %5 %23\n%27 = OpAccessChain %26 %10 %18\nOpStore %27 %16\n%28 = OpAccessChain %26 %10 %21\nOpStore %28 %19\n%29 = OpAccessChain %26 %10 %24\nOpStore %29 %22\n%30 = OpAccessChain %26 %10 %15\nOpStore %30 %25\n%31 = OpAccessChain %26 %11 %18\nOpStore %31 %16\n%32 = OpAccessChain %26 %11 %15\nOpStore %32 %19\n%33 = OpAccessChain %26 %11 %24\nOpStore %33 %22\n%34 = OpAccessChain %26 %11 %21\nOpStore %34 %25\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/task-basic.task",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nstruct _11\n{\n    float _m0[64][4];\n};\n\ntaskPayloadSharedEXT _11 _13;\n\nvoid main()\n{\n    float _17 = float(gl_LocalInvocationIndex);\n    _13._m0[gl_LocalInvocationIndex][0u] = _17;\n    _13._m0[gl_LocalInvocationIndex][1u] = _17;\n    _13._m0[gl_LocalInvocationIndex][2u] = _17;\n    _13._m0[gl_LocalInvocationIndex][3u] = _17;\n    EmitMeshTasksEXT(2u, 3u, 4u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint TaskEXT %3 \"main\" %13 %15\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpName %11 \"\"\nOpDecorate %15 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 64\n%7 = OpConstant %5 4\n%8 = OpTypeFloat 32\n%9 = OpTypeArray %8 %7\n%10 = OpTypeArray %9 %6\n%11 = OpTypeStruct %10\n%12 = OpTypePointer TaskPayloadWorkgroupEXT %11\n%13 = OpVariable %12 TaskPayloadWorkgroupEXT\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%18 = OpTypePointer TaskPayloadWorkgroupEXT %8\n%20 = OpConstant %5 0\n%22 = OpConstant %5 1\n%24 = OpConstant %5 2\n%26 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%16 = OpLoad %5 %15\n%17 = OpConvertUToF %8 %16\n%19 = OpAccessChain %18 %13 %20 %16 %20\nOpStore %19 %17\n%21 = OpAccessChain %18 %13 %20 %16 %22\nOpStore %21 %17\n%23 = OpAccessChain %18 %13 %20 %16 %24\nOpStore %23 %17\n%25 = OpAccessChain %18 %13 %20 %16 %26\nOpStore %25 %17\nOpEmitMeshTasksEXT %24 %26 %7 %13\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/vertex-array-input.vert",
    "content": "#version 460\n\nlayout(location = 0) in vec4 ATTR[4];\nlayout(location = 4) in float ATTR_4[4];\n\nvoid main()\n{\n    float _46 = ATTR_4[2u] + ATTR_4[1u];\n    gl_Position.x = (ATTR[3u].x + ATTR[0u].x) + _46;\n    gl_Position.y = (ATTR[3u].y + ATTR[0u].y) + _46;\n    gl_Position.z = (ATTR[3u].z + ATTR[0u].z) + _46;\n    gl_Position.w = (ATTR[3u].w + ATTR[0u].w) + _46;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 58\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %11 %14 %16\nOpName %3 \"main\"\nOpName %11 \"ATTR\"\nOpName %14 \"ATTR_4\"\nOpName %16 \"SV_Position\"\nOpDecorate %11 Location 0\nOpDecorate %14 Location 4\nOpDecorate %16 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 4\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Input %12\n%14 = OpVariable %13 Input\n%15 = OpTypePointer Output %6\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Input %5\n%19 = OpConstant %7 0\n%22 = OpConstant %7 1\n%25 = OpConstant %7 2\n%28 = OpConstant %7 3\n%51 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %56\n%56 = OpLabel\n%18 = OpAccessChain %17 %11 %19 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %17 %11 %19 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %17 %11 %19 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %17 %11 %19 %28\n%29 = OpLoad %5 %27\n%30 = OpAccessChain %17 %11 %28 %19\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %17 %11 %28 %22\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %17 %11 %28 %25\n%35 = OpLoad %5 %34\n%36 = OpAccessChain %17 %11 %28 %28\n%37 = OpLoad %5 %36\n%38 = OpFAdd %5 %31 %20\n%39 = OpFAdd %5 %33 %23\n%40 = OpFAdd %5 %35 %26\n%41 = OpFAdd %5 %37 %29\n%42 = OpAccessChain %17 %14 %22\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %17 %14 %25\n%45 = OpLoad %5 %44\n%46 = OpFAdd %5 %45 %43\n%47 = OpFAdd %5 %38 %46\n%48 = OpFAdd %5 %39 %46\n%49 = OpFAdd %5 %40 %46\n%50 = OpFAdd %5 %41 %46\n%52 = OpAccessChain %51 %16 %19\nOpStore %52 %47\n%53 = OpAccessChain %51 %16 %22\nOpStore %53 %48\n%54 = OpAccessChain %51 %16 %25\nOpStore %54 %49\n%55 = OpAccessChain %51 %16 %28\nOpStore %55 %50\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/vertex-array-output.vert",
    "content": "#version 460\n\nlayout(location = 0) in vec4 POSITION;\nlayout(location = 1) out vec4 ATTR[4];\nlayout(location = 5) out float ATTR_4[4];\n\nvoid main()\n{\n    gl_Position.x = POSITION.x;\n    gl_Position.y = POSITION.y;\n    gl_Position.z = POSITION.z;\n    gl_Position.w = POSITION.w;\n    ATTR[0u].x = POSITION.x;\n    ATTR[0u].y = POSITION.y;\n    ATTR[0u].z = POSITION.z;\n    ATTR[0u].w = POSITION.w;\n    ATTR[1u].x = POSITION.x + 1.0;\n    ATTR[1u].y = POSITION.y + 1.0;\n    ATTR[1u].z = POSITION.z + 1.0;\n    ATTR[1u].w = POSITION.w + 1.0;\n    ATTR[2u].x = POSITION.x + 2.0;\n    ATTR[2u].y = POSITION.y + 2.0;\n    ATTR[2u].z = POSITION.z + 2.0;\n    ATTR[2u].w = POSITION.w + 2.0;\n    ATTR[3u].x = POSITION.x + 3.0;\n    ATTR[3u].y = POSITION.y + 3.0;\n    ATTR[3u].z = POSITION.z + 3.0;\n    ATTR[3u].w = POSITION.w + 3.0;\n    ATTR_4[0u] = POSITION.x;\n    ATTR_4[1u] = POSITION.y;\n    ATTR_4[2u] = POSITION.z;\n    ATTR_4[3u] = POSITION.w;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 74\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %10 %15 %18\nOpName %3 \"main\"\nOpName %8 \"POSITION\"\nOpName %10 \"SV_Position\"\nOpName %15 \"ATTR\"\nOpName %18 \"ATTR_4\"\nOpDecorate %8 Location 0\nOpDecorate %10 BuiltIn Position\nOpDecorate %15 Location 1\nOpDecorate %18 Location 5\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Output %6\n%10 = OpVariable %9 Output\n%11 = OpTypeInt 32 0\n%12 = OpConstant %11 4\n%13 = OpTypeArray %6 %12\n%14 = OpTypePointer Output %13\n%15 = OpVariable %14 Output\n%16 = OpTypeArray %5 %12\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpTypePointer Input %5\n%21 = OpConstant %11 0\n%24 = OpConstant %11 1\n%27 = OpConstant %11 2\n%30 = OpConstant %11 3\n%33 = OpConstant %5 1\n%38 = OpConstant %5 2\n%43 = OpConstant %5 3\n%47 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %72\n%72 = OpLabel\n%20 = OpAccessChain %19 %8 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %19 %8 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %19 %8 %27\n%28 = OpLoad %5 %26\n%29 = OpAccessChain %19 %8 %30\n%31 = OpLoad %5 %29\n%32 = OpFAdd %5 %22 %33\n%34 = OpFAdd %5 %25 %33\n%35 = OpFAdd %5 %28 %33\n%36 = OpFAdd %5 %31 %33\n%37 = OpFAdd %5 %22 %38\n%39 = OpFAdd %5 %25 %38\n%40 = OpFAdd %5 %28 %38\n%41 = OpFAdd %5 %31 %38\n%42 = OpFAdd %5 %22 %43\n%44 = OpFAdd %5 %25 %43\n%45 = OpFAdd %5 %28 %43\n%46 = OpFAdd %5 %31 %43\n%48 = OpAccessChain %47 %10 %21\nOpStore %48 %22\n%49 = OpAccessChain %47 %10 %24\nOpStore %49 %25\n%50 = OpAccessChain %47 %10 %27\nOpStore %50 %28\n%51 = OpAccessChain %47 %10 %30\nOpStore %51 %31\n%52 = OpAccessChain %47 %15 %21 %21\nOpStore %52 %22\n%53 = OpAccessChain %47 %15 %21 %24\nOpStore %53 %25\n%54 = OpAccessChain %47 %15 %21 %27\nOpStore %54 %28\n%55 = OpAccessChain %47 %15 %21 %30\nOpStore %55 %31\n%56 = OpAccessChain %47 %15 %24 %21\nOpStore %56 %32\n%57 = OpAccessChain %47 %15 %24 %24\nOpStore %57 %34\n%58 = OpAccessChain %47 %15 %24 %27\nOpStore %58 %35\n%59 = OpAccessChain %47 %15 %24 %30\nOpStore %59 %36\n%60 = OpAccessChain %47 %15 %27 %21\nOpStore %60 %37\n%61 = OpAccessChain %47 %15 %27 %24\nOpStore %61 %39\n%62 = OpAccessChain %47 %15 %27 %27\nOpStore %62 %40\n%63 = OpAccessChain %47 %15 %27 %30\nOpStore %63 %41\n%64 = OpAccessChain %47 %15 %30 %21\nOpStore %64 %42\n%65 = OpAccessChain %47 %15 %30 %24\nOpStore %65 %44\n%66 = OpAccessChain %47 %15 %30 %27\nOpStore %66 %45\n%67 = OpAccessChain %47 %15 %30 %30\nOpStore %67 %46\n%68 = OpAccessChain %47 %18 %21\nOpStore %68 %22\n%69 = OpAccessChain %47 %18 %24\nOpStore %69 %25\n%70 = OpAccessChain %47 %18 %27\nOpStore %70 %28\n%71 = OpAccessChain %47 %18 %30\nOpStore %71 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/stages/vertex-input-remapping.vert",
    "content": "#version 460\n\nlayout(location = 2) in vec4 ATTR_2;\nlayout(location = 4) in float ATTR_4;\n\nvoid main()\n{\n    gl_Position.x = ATTR_2.x + ATTR_4;\n    gl_Position.y = ATTR_2.y + ATTR_4;\n    gl_Position.z = ATTR_2.z + ATTR_4;\n    gl_Position.w = ATTR_2.w + ATTR_4;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %10 %12\nOpName %3 \"main\"\nOpName %8 \"ATTR_2\"\nOpName %10 \"ATTR_4\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 Location 2\nOpDecorate %10 Location 4\nOpDecorate %12 BuiltIn Position\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Input %6\n%8 = OpVariable %7 Input\n%9 = OpTypePointer Input %5\n%10 = OpVariable %9 Input\n%11 = OpTypePointer Output %6\n%12 = OpVariable %11 Output\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%22 = OpConstant %15 2\n%25 = OpConstant %15 3\n%31 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %36\n%36 = OpLabel\n%13 = OpLoad %5 %10\n%14 = OpAccessChain %9 %8 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %9 %8 %19\n%20 = OpLoad %5 %18\n%21 = OpAccessChain %9 %8 %22\n%23 = OpLoad %5 %21\n%24 = OpAccessChain %9 %8 %25\n%26 = OpLoad %5 %24\n%27 = OpFAdd %5 %17 %13\n%28 = OpFAdd %5 %20 %13\n%29 = OpFAdd %5 %23 %13\n%30 = OpFAdd %5 %26 %13\n%32 = OpAccessChain %31 %12 %16\nOpStore %32 %27\n%33 = OpAccessChain %31 %12 %19\nOpStore %33 %28\n%34 = OpAccessChain %31 %12 %22\nOpStore %34 %29\n%35 = OpAccessChain %31 %12 %25\nOpStore %35 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-byte-address.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint16_t _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _12_14\n{\n    u16vec2 _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, scalar) readonly buffer _17_19\n{\n    u16vec3 _m0[];\n} _19;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _22_24\n{\n    u16vec4 _m0[];\n} _24;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _27_29\n{\n    uint _m0[];\n} _29;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _32_34\n{\n    uvec2 _m0[];\n} _34;\n\nlayout(set = 0, binding = 0, scalar) readonly buffer _37_39\n{\n    uvec3 _m0[];\n} _39;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _42_44\n{\n    uvec4 _m0[];\n} _44;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _47_49\n{\n    double _m0[];\n} _49;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _52_54\n{\n    dvec2 _m0[];\n} _54;\n\nlayout(set = 0, binding = 0, scalar) readonly buffer _57_59\n{\n    dvec3 _m0[];\n} _59;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _62_64\n{\n    dvec4 _m0[];\n} _64;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _66_68\n{\n    uint16_t _m0[];\n} _68;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _70_72\n{\n    u16vec2 _m0[];\n} _72;\n\nlayout(set = 0, binding = 1, scalar) writeonly buffer _74_76\n{\n    u16vec3 _m0[];\n} _76;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _78_80\n{\n    u16vec4 _m0[];\n} _80;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _82_84\n{\n    uint _m0[];\n} _84;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _86_88\n{\n    uvec2 _m0[];\n} _88;\n\nlayout(set = 0, binding = 1, scalar) writeonly buffer _90_92\n{\n    uvec3 _m0[];\n} _92;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _94_96\n{\n    uvec4 _m0[];\n} _96;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _98_100\n{\n    double _m0[];\n} _100;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _102_104\n{\n    dvec2 _m0[];\n} _104;\n\nlayout(set = 0, binding = 1, scalar) writeonly buffer _106_108\n{\n    dvec3 _m0[];\n} _108;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _110_112\n{\n    dvec4 _m0[];\n} _112;\n\nvoid main()\n{\n    uint _121 = gl_LocalInvocationIndex + gl_GlobalInvocationID.x;\n    _112._m0[(_121 * 3u) + 3u] = dvec4(_64._m0[(_121 * 3u) + 3u]);\n    _108._m0[(_121 * 4u) + 4u] = dvec3(_59._m0[(_121 * 4u) + 4u]);\n    _104._m0[(_121 * 6u) + 6u] = dvec2(_54._m0[(_121 * 6u) + 6u]);\n    _100._m0[(_121 * 12u) + 12u] = _49._m0[(_121 * 12u) + 12u];\n    vec4 _180 = uintBitsToFloat(_44._m0[(_121 * 6u) + 6u]);\n    _96._m0[(_121 * 6u) + 6u] = uvec4(floatBitsToUint(_180.x), floatBitsToUint(_180.y), floatBitsToUint(_180.z), floatBitsToUint(_180.w));\n    vec3 _200 = uintBitsToFloat(_39._m0[(_121 * 8u) + 8u]);\n    _92._m0[(_121 * 8u) + 8u] = uvec3(floatBitsToUint(_200.x), floatBitsToUint(_200.y), floatBitsToUint(_200.z));\n    vec2 _217 = uintBitsToFloat(_34._m0[(_121 * 12u) + 12u]);\n    _88._m0[(_121 * 12u) + 12u] = uvec2(floatBitsToUint(_217.x), floatBitsToUint(_217.y));\n    _84._m0[(_121 * 24u) + 24u] = floatBitsToUint(uintBitsToFloat(_29._m0[(_121 * 24u) + 24u]));\n    f16vec4 _244 = uint16BitsToFloat16(_24._m0[(_121 * 12u) + 12u]);\n    _80._m0[(_121 * 12u) + 12u] = u16vec4(float16BitsToUint16(_244.x), float16BitsToUint16(_244.y), float16BitsToUint16(_244.z), float16BitsToUint16(_244.w));\n    f16vec3 _264 = uint16BitsToFloat16(_19._m0[(_121 * 16u) + 16u]);\n    _76._m0[(_121 * 16u) + 16u] = u16vec3(float16BitsToUint16(_264.x), float16BitsToUint16(_264.y), float16BitsToUint16(_264.z));\n    f16vec2 _281 = uint16BitsToFloat16(_14._m0[(_121 * 24u) + 24u]);\n    _72._m0[(_121 * 24u) + 24u] = u16vec2(float16BitsToUint16(_281.x), float16BitsToUint16(_281.y));\n    _68._m0[(_121 * 48u) + 48u] = float16BitsToUint16(uint16BitsToFloat16(_9._m0[(_121 * 48u) + 48u]));\n    _112._m0[6u] = dvec4(_64._m0[6u]);\n    vec4 _311 = uintBitsToFloat(_44._m0[12u]);\n    _96._m0[12u] = uvec4(floatBitsToUint(_311.x), floatBitsToUint(_311.y), floatBitsToUint(_311.z), floatBitsToUint(_311.w));\n    f16vec4 _324 = uint16BitsToFloat16(_24._m0[24u]);\n    _80._m0[24u] = u16vec4(float16BitsToUint16(_324.x), float16BitsToUint16(_324.y), float16BitsToUint16(_324.z), float16BitsToUint16(_324.w));\n    _112._m0[gl_GlobalInvocationID.x * 6u] = dvec4(_64._m0[gl_GlobalInvocationID.x * 6u]);\n    vec4 _350 = uintBitsToFloat(_44._m0[gl_GlobalInvocationID.x * 12u]);\n    _96._m0[gl_GlobalInvocationID.x * 12u] = uvec4(floatBitsToUint(_350.x), floatBitsToUint(_350.y), floatBitsToUint(_350.z), floatBitsToUint(_350.w));\n    f16vec4 _365 = uint16BitsToFloat16(_24._m0[gl_GlobalInvocationID.x * 24u]);\n    _80._m0[gl_GlobalInvocationID.x * 24u] = u16vec4(float16BitsToUint16(_365.x), float16BitsToUint16(_365.y), float16BitsToUint16(_365.z), float16BitsToUint16(_365.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 379\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Float64\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %114 %119\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %27 \"SSBO\"\nOpName %32 \"SSBO\"\nOpName %37 \"SSBO\"\nOpName %42 \"SSBO\"\nOpName %47 \"SSBO\"\nOpName %52 \"SSBO\"\nOpName %57 \"SSBO\"\nOpName %62 \"SSBO\"\nOpName %66 \"SSBO\"\nOpName %70 \"SSBO\"\nOpName %74 \"SSBO\"\nOpName %78 \"SSBO\"\nOpName %82 \"SSBO\"\nOpName %86 \"SSBO\"\nOpName %90 \"SSBO\"\nOpName %94 \"SSBO\"\nOpName %98 \"SSBO\"\nOpName %102 \"SSBO\"\nOpName %106 \"SSBO\"\nOpName %110 \"SSBO\"\nOpDecorate %6 ArrayStride 2\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %16 ArrayStride 6\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %21 ArrayStride 8\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %26 ArrayStride 4\nOpMemberDecorate %27 0 Offset 0\nOpDecorate %27 Block\nOpDecorate %31 ArrayStride 8\nOpMemberDecorate %32 0 Offset 0\nOpDecorate %32 Block\nOpDecorate %36 ArrayStride 12\nOpMemberDecorate %37 0 Offset 0\nOpDecorate %37 Block\nOpDecorate %41 ArrayStride 16\nOpMemberDecorate %42 0 Offset 0\nOpDecorate %42 Block\nOpDecorate %46 ArrayStride 8\nOpMemberDecorate %47 0 Offset 0\nOpDecorate %47 Block\nOpDecorate %51 ArrayStride 16\nOpMemberDecorate %52 0 Offset 0\nOpDecorate %52 Block\nOpDecorate %56 ArrayStride 24\nOpMemberDecorate %57 0 Offset 0\nOpDecorate %57 Block\nOpDecorate %61 ArrayStride 32\nOpMemberDecorate %62 0 Offset 0\nOpDecorate %62 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Aliased\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %14 NonWritable\nOpDecorate %14 Aliased\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %19 Aliased\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Aliased\nOpDecorate %29 DescriptorSet 0\nOpDecorate %29 Binding 0\nOpDecorate %29 NonWritable\nOpDecorate %29 Aliased\nOpDecorate %34 DescriptorSet 0\nOpDecorate %34 Binding 0\nOpDecorate %34 NonWritable\nOpDecorate %34 Aliased\nOpDecorate %39 DescriptorSet 0\nOpDecorate %39 Binding 0\nOpDecorate %39 NonWritable\nOpDecorate %39 Aliased\nOpDecorate %44 DescriptorSet 0\nOpDecorate %44 Binding 0\nOpDecorate %44 NonWritable\nOpDecorate %44 Aliased\nOpDecorate %49 DescriptorSet 0\nOpDecorate %49 Binding 0\nOpDecorate %49 NonWritable\nOpDecorate %49 Aliased\nOpDecorate %54 DescriptorSet 0\nOpDecorate %54 Binding 0\nOpDecorate %54 NonWritable\nOpDecorate %54 Aliased\nOpDecorate %59 DescriptorSet 0\nOpDecorate %59 Binding 0\nOpDecorate %59 NonWritable\nOpDecorate %59 Aliased\nOpDecorate %64 DescriptorSet 0\nOpDecorate %64 Binding 0\nOpDecorate %64 NonWritable\nOpDecorate %64 Aliased\nOpDecorate %65 ArrayStride 2\nOpMemberDecorate %66 0 Offset 0\nOpDecorate %66 Block\nOpDecorate %69 ArrayStride 4\nOpMemberDecorate %70 0 Offset 0\nOpDecorate %70 Block\nOpDecorate %73 ArrayStride 6\nOpMemberDecorate %74 0 Offset 0\nOpDecorate %74 Block\nOpDecorate %77 ArrayStride 8\nOpMemberDecorate %78 0 Offset 0\nOpDecorate %78 Block\nOpDecorate %81 ArrayStride 4\nOpMemberDecorate %82 0 Offset 0\nOpDecorate %82 Block\nOpDecorate %85 ArrayStride 8\nOpMemberDecorate %86 0 Offset 0\nOpDecorate %86 Block\nOpDecorate %89 ArrayStride 12\nOpMemberDecorate %90 0 Offset 0\nOpDecorate %90 Block\nOpDecorate %93 ArrayStride 16\nOpMemberDecorate %94 0 Offset 0\nOpDecorate %94 Block\nOpDecorate %97 ArrayStride 8\nOpMemberDecorate %98 0 Offset 0\nOpDecorate %98 Block\nOpDecorate %101 ArrayStride 16\nOpMemberDecorate %102 0 Offset 0\nOpDecorate %102 Block\nOpDecorate %105 ArrayStride 24\nOpMemberDecorate %106 0 Offset 0\nOpDecorate %106 Block\nOpDecorate %109 ArrayStride 32\nOpMemberDecorate %110 0 Offset 0\nOpDecorate %110 Block\nOpDecorate %68 DescriptorSet 0\nOpDecorate %68 Binding 1\nOpDecorate %68 NonReadable\nOpDecorate %68 Aliased\nOpDecorate %72 DescriptorSet 0\nOpDecorate %72 Binding 1\nOpDecorate %72 NonReadable\nOpDecorate %72 Aliased\nOpDecorate %76 DescriptorSet 0\nOpDecorate %76 Binding 1\nOpDecorate %76 NonReadable\nOpDecorate %76 Aliased\nOpDecorate %80 DescriptorSet 0\nOpDecorate %80 Binding 1\nOpDecorate %80 NonReadable\nOpDecorate %80 Aliased\nOpDecorate %84 DescriptorSet 0\nOpDecorate %84 Binding 1\nOpDecorate %84 NonReadable\nOpDecorate %84 Aliased\nOpDecorate %88 DescriptorSet 0\nOpDecorate %88 Binding 1\nOpDecorate %88 NonReadable\nOpDecorate %88 Aliased\nOpDecorate %92 DescriptorSet 0\nOpDecorate %92 Binding 1\nOpDecorate %92 NonReadable\nOpDecorate %92 Aliased\nOpDecorate %96 DescriptorSet 0\nOpDecorate %96 Binding 1\nOpDecorate %96 NonReadable\nOpDecorate %96 Aliased\nOpDecorate %100 DescriptorSet 0\nOpDecorate %100 Binding 1\nOpDecorate %100 NonReadable\nOpDecorate %100 Aliased\nOpDecorate %104 DescriptorSet 0\nOpDecorate %104 Binding 1\nOpDecorate %104 NonReadable\nOpDecorate %104 Aliased\nOpDecorate %108 DescriptorSet 0\nOpDecorate %108 Binding 1\nOpDecorate %108 NonReadable\nOpDecorate %108 Aliased\nOpDecorate %112 DescriptorSet 0\nOpDecorate %112 Binding 1\nOpDecorate %112 NonReadable\nOpDecorate %112 Aliased\nOpDecorate %114 BuiltIn GlobalInvocationId\nOpDecorate %119 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 16 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 2\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 3\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeVector %5 4\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeInt 32 0\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypeStruct %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeVector %25 2\n%31 = OpTypeRuntimeArray %30\n%32 = OpTypeStruct %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeVector %25 3\n%36 = OpTypeRuntimeArray %35\n%37 = OpTypeStruct %36\n%38 = OpTypePointer StorageBuffer %37\n%39 = OpVariable %38 StorageBuffer\n%40 = OpTypeVector %25 4\n%41 = OpTypeRuntimeArray %40\n%42 = OpTypeStruct %41\n%43 = OpTypePointer StorageBuffer %42\n%44 = OpVariable %43 StorageBuffer\n%45 = OpTypeFloat 64\n%46 = OpTypeRuntimeArray %45\n%47 = OpTypeStruct %46\n%48 = OpTypePointer StorageBuffer %47\n%49 = OpVariable %48 StorageBuffer\n%50 = OpTypeVector %45 2\n%51 = OpTypeRuntimeArray %50\n%52 = OpTypeStruct %51\n%53 = OpTypePointer StorageBuffer %52\n%54 = OpVariable %53 StorageBuffer\n%55 = OpTypeVector %45 3\n%56 = OpTypeRuntimeArray %55\n%57 = OpTypeStruct %56\n%58 = OpTypePointer StorageBuffer %57\n%59 = OpVariable %58 StorageBuffer\n%60 = OpTypeVector %45 4\n%61 = OpTypeRuntimeArray %60\n%62 = OpTypeStruct %61\n%63 = OpTypePointer StorageBuffer %62\n%64 = OpVariable %63 StorageBuffer\n%65 = OpTypeRuntimeArray %5\n%66 = OpTypeStruct %65\n%67 = OpTypePointer StorageBuffer %66\n%68 = OpVariable %67 StorageBuffer\n%69 = OpTypeRuntimeArray %10\n%70 = OpTypeStruct %69\n%71 = OpTypePointer StorageBuffer %70\n%72 = OpVariable %71 StorageBuffer\n%73 = OpTypeRuntimeArray %15\n%74 = OpTypeStruct %73\n%75 = OpTypePointer StorageBuffer %74\n%76 = OpVariable %75 StorageBuffer\n%77 = OpTypeRuntimeArray %20\n%78 = OpTypeStruct %77\n%79 = OpTypePointer StorageBuffer %78\n%80 = OpVariable %79 StorageBuffer\n%81 = OpTypeRuntimeArray %25\n%82 = OpTypeStruct %81\n%83 = OpTypePointer StorageBuffer %82\n%84 = OpVariable %83 StorageBuffer\n%85 = OpTypeRuntimeArray %30\n%86 = OpTypeStruct %85\n%87 = OpTypePointer StorageBuffer %86\n%88 = OpVariable %87 StorageBuffer\n%89 = OpTypeRuntimeArray %35\n%90 = OpTypeStruct %89\n%91 = OpTypePointer StorageBuffer %90\n%92 = OpVariable %91 StorageBuffer\n%93 = OpTypeRuntimeArray %40\n%94 = OpTypeStruct %93\n%95 = OpTypePointer StorageBuffer %94\n%96 = OpVariable %95 StorageBuffer\n%97 = OpTypeRuntimeArray %45\n%98 = OpTypeStruct %97\n%99 = OpTypePointer StorageBuffer %98\n%100 = OpVariable %99 StorageBuffer\n%101 = OpTypeRuntimeArray %50\n%102 = OpTypeStruct %101\n%103 = OpTypePointer StorageBuffer %102\n%104 = OpVariable %103 StorageBuffer\n%105 = OpTypeRuntimeArray %55\n%106 = OpTypeStruct %105\n%107 = OpTypePointer StorageBuffer %106\n%108 = OpVariable %107 StorageBuffer\n%109 = OpTypeRuntimeArray %60\n%110 = OpTypeStruct %109\n%111 = OpTypePointer StorageBuffer %110\n%112 = OpVariable %111 StorageBuffer\n%113 = OpTypePointer Input %35\n%114 = OpVariable %113 Input\n%115 = OpTypePointer Input %25\n%117 = OpConstant %25 0\n%119 = OpVariable %115 Input\n%123 = OpConstant %25 96\n%126 = OpConstant %25 3\n%128 = OpTypePointer StorageBuffer %60\n%140 = OpConstant %25 4\n%142 = OpTypePointer StorageBuffer %55\n%153 = OpConstant %25 6\n%155 = OpTypePointer StorageBuffer %50\n%165 = OpConstant %25 12\n%167 = OpTypePointer StorageBuffer %45\n%175 = OpTypePointer StorageBuffer %40\n%178 = OpTypeFloat 32\n%179 = OpTypeVector %178 4\n%194 = OpConstant %25 8\n%196 = OpTypePointer StorageBuffer %35\n%199 = OpTypeVector %178 3\n%213 = OpTypePointer StorageBuffer %30\n%216 = OpTypeVector %178 2\n%227 = OpConstant %25 24\n%229 = OpTypePointer StorageBuffer %25\n%239 = OpTypePointer StorageBuffer %20\n%242 = OpTypeFloat 16\n%243 = OpTypeVector %242 4\n%258 = OpConstant %25 16\n%260 = OpTypePointer StorageBuffer %15\n%263 = OpTypeVector %242 3\n%277 = OpTypePointer StorageBuffer %10\n%280 = OpTypeVector %242 2\n%291 = OpConstant %25 48\n%293 = OpTypePointer StorageBuffer %5\n%336 = OpConstant %25 192\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %377\n%377 = OpLabel\n%116 = OpAccessChain %115 %114 %117\n%118 = OpLoad %25 %116\n%120 = OpLoad %25 %119\n%121 = OpIAdd %25 %120 %118\n%122 = OpIMul %25 %121 %123\n%124 = OpIAdd %25 %122 %123\n%125 = OpIMul %25 %121 %126\n%127 = OpIAdd %25 %125 %126\n%129 = OpAccessChain %128 %64 %117 %127\n%130 = OpLoad %60 %129\n%131 = OpCompositeExtract %45 %130 0\n%132 = OpCompositeExtract %45 %130 1\n%133 = OpCompositeExtract %45 %130 2\n%134 = OpCompositeExtract %45 %130 3\n%135 = OpIMul %25 %121 %126\n%136 = OpIAdd %25 %135 %126\n%137 = OpCompositeConstruct %60 %131 %132 %133 %134\n%138 = OpAccessChain %128 %112 %117 %136\nOpStore %138 %137\n%139 = OpIMul %25 %121 %140\n%141 = OpIAdd %25 %139 %140\n%143 = OpAccessChain %142 %59 %117 %141\n%144 = OpLoad %55 %143\n%145 = OpCompositeExtract %45 %144 0\n%146 = OpCompositeExtract %45 %144 1\n%147 = OpCompositeExtract %45 %144 2\n%148 = OpIMul %25 %121 %140\n%149 = OpIAdd %25 %148 %140\n%150 = OpCompositeConstruct %55 %145 %146 %147\n%151 = OpAccessChain %142 %108 %117 %149\nOpStore %151 %150\n%152 = OpIMul %25 %121 %153\n%154 = OpIAdd %25 %152 %153\n%156 = OpAccessChain %155 %54 %117 %154\n%157 = OpLoad %50 %156\n%158 = OpCompositeExtract %45 %157 0\n%159 = OpCompositeExtract %45 %157 1\n%160 = OpIMul %25 %121 %153\n%161 = OpIAdd %25 %160 %153\n%162 = OpCompositeConstruct %50 %158 %159\n%163 = OpAccessChain %155 %104 %117 %161\nOpStore %163 %162\n%164 = OpIMul %25 %121 %165\n%166 = OpIAdd %25 %164 %165\n%168 = OpAccessChain %167 %49 %117 %166\n%169 = OpLoad %45 %168\n%170 = OpIMul %25 %121 %165\n%171 = OpIAdd %25 %170 %165\n%172 = OpAccessChain %167 %100 %117 %171\nOpStore %172 %169\n%173 = OpIMul %25 %121 %153\n%174 = OpIAdd %25 %173 %153\n%176 = OpAccessChain %175 %44 %117 %174\n%177 = OpLoad %40 %176\n%180 = OpBitcast %179 %177\n%181 = OpCompositeExtract %178 %180 0\n%182 = OpCompositeExtract %178 %180 1\n%183 = OpCompositeExtract %178 %180 2\n%184 = OpCompositeExtract %178 %180 3\n%185 = OpIMul %25 %121 %153\n%186 = OpIAdd %25 %185 %153\n%187 = OpBitcast %25 %181\n%188 = OpBitcast %25 %182\n%189 = OpBitcast %25 %183\n%190 = OpBitcast %25 %184\n%191 = OpCompositeConstruct %40 %187 %188 %189 %190\n%192 = OpAccessChain %175 %96 %117 %186\nOpStore %192 %191\n%193 = OpIMul %25 %121 %194\n%195 = OpIAdd %25 %193 %194\n%197 = OpAccessChain %196 %39 %117 %195\n%198 = OpLoad %35 %197\n%200 = OpBitcast %199 %198\n%201 = OpCompositeExtract %178 %200 0\n%202 = OpCompositeExtract %178 %200 1\n%203 = OpCompositeExtract %178 %200 2\n%204 = OpIMul %25 %121 %194\n%205 = OpIAdd %25 %204 %194\n%206 = OpBitcast %25 %201\n%207 = OpBitcast %25 %202\n%208 = OpBitcast %25 %203\n%209 = OpCompositeConstruct %35 %206 %207 %208\n%210 = OpAccessChain %196 %92 %117 %205\nOpStore %210 %209\n%211 = OpIMul %25 %121 %165\n%212 = OpIAdd %25 %211 %165\n%214 = OpAccessChain %213 %34 %117 %212\n%215 = OpLoad %30 %214\n%217 = OpBitcast %216 %215\n%218 = OpCompositeExtract %178 %217 0\n%219 = OpCompositeExtract %178 %217 1\n%220 = OpIMul %25 %121 %165\n%221 = OpIAdd %25 %220 %165\n%222 = OpBitcast %25 %218\n%223 = OpBitcast %25 %219\n%224 = OpCompositeConstruct %30 %222 %223\n%225 = OpAccessChain %213 %88 %117 %221\nOpStore %225 %224\n%226 = OpIMul %25 %121 %227\n%228 = OpIAdd %25 %226 %227\n%230 = OpAccessChain %229 %29 %117 %228\n%231 = OpLoad %25 %230\n%232 = OpBitcast %178 %231\n%233 = OpIMul %25 %121 %227\n%234 = OpIAdd %25 %233 %227\n%235 = OpBitcast %25 %232\n%236 = OpAccessChain %229 %84 %117 %234\nOpStore %236 %235\n%237 = OpIMul %25 %121 %165\n%238 = OpIAdd %25 %237 %165\n%240 = OpAccessChain %239 %24 %117 %238\n%241 = OpLoad %20 %240\n%244 = OpBitcast %243 %241\n%245 = OpCompositeExtract %242 %244 0\n%246 = OpCompositeExtract %242 %244 1\n%247 = OpCompositeExtract %242 %244 2\n%248 = OpCompositeExtract %242 %244 3\n%249 = OpIMul %25 %121 %165\n%250 = OpIAdd %25 %249 %165\n%251 = OpBitcast %5 %245\n%252 = OpBitcast %5 %246\n%253 = OpBitcast %5 %247\n%254 = OpBitcast %5 %248\n%255 = OpCompositeConstruct %20 %251 %252 %253 %254\n%256 = OpAccessChain %239 %80 %117 %250\nOpStore %256 %255\n%257 = OpIMul %25 %121 %258\n%259 = OpIAdd %25 %257 %258\n%261 = OpAccessChain %260 %19 %117 %259\n%262 = OpLoad %15 %261\n%264 = OpBitcast %263 %262\n%265 = OpCompositeExtract %242 %264 0\n%266 = OpCompositeExtract %242 %264 1\n%267 = OpCompositeExtract %242 %264 2\n%268 = OpIMul %25 %121 %258\n%269 = OpIAdd %25 %268 %258\n%270 = OpBitcast %5 %265\n%271 = OpBitcast %5 %266\n%272 = OpBitcast %5 %267\n%273 = OpCompositeConstruct %15 %270 %271 %272\n%274 = OpAccessChain %260 %76 %117 %269\nOpStore %274 %273\n%275 = OpIMul %25 %121 %227\n%276 = OpIAdd %25 %275 %227\n%278 = OpAccessChain %277 %14 %117 %276\n%279 = OpLoad %10 %278\n%281 = OpBitcast %280 %279\n%282 = OpCompositeExtract %242 %281 0\n%283 = OpCompositeExtract %242 %281 1\n%284 = OpIMul %25 %121 %227\n%285 = OpIAdd %25 %284 %227\n%286 = OpBitcast %5 %282\n%287 = OpBitcast %5 %283\n%288 = OpCompositeConstruct %10 %286 %287\n%289 = OpAccessChain %277 %72 %117 %285\nOpStore %289 %288\n%290 = OpIMul %25 %121 %291\n%292 = OpIAdd %25 %290 %291\n%294 = OpAccessChain %293 %9 %117 %292\n%295 = OpLoad %5 %294\n%296 = OpBitcast %242 %295\n%297 = OpIMul %25 %121 %291\n%298 = OpIAdd %25 %297 %291\n%299 = OpBitcast %5 %296\n%300 = OpAccessChain %293 %68 %117 %298\nOpStore %300 %299\n%301 = OpAccessChain %128 %64 %117 %153\n%302 = OpLoad %60 %301\n%303 = OpCompositeExtract %45 %302 0\n%304 = OpCompositeExtract %45 %302 1\n%305 = OpCompositeExtract %45 %302 2\n%306 = OpCompositeExtract %45 %302 3\n%307 = OpCompositeConstruct %60 %303 %304 %305 %306\n%308 = OpAccessChain %128 %112 %117 %153\nOpStore %308 %307\n%309 = OpAccessChain %175 %44 %117 %165\n%310 = OpLoad %40 %309\n%311 = OpBitcast %179 %310\n%312 = OpCompositeExtract %178 %311 0\n%313 = OpCompositeExtract %178 %311 1\n%314 = OpCompositeExtract %178 %311 2\n%315 = OpCompositeExtract %178 %311 3\n%316 = OpBitcast %25 %312\n%317 = OpBitcast %25 %313\n%318 = OpBitcast %25 %314\n%319 = OpBitcast %25 %315\n%320 = OpCompositeConstruct %40 %316 %317 %318 %319\n%321 = OpAccessChain %175 %96 %117 %165\nOpStore %321 %320\n%322 = OpAccessChain %239 %24 %117 %227\n%323 = OpLoad %20 %322\n%324 = OpBitcast %243 %323\n%325 = OpCompositeExtract %242 %324 0\n%326 = OpCompositeExtract %242 %324 1\n%327 = OpCompositeExtract %242 %324 2\n%328 = OpCompositeExtract %242 %324 3\n%329 = OpBitcast %5 %325\n%330 = OpBitcast %5 %326\n%331 = OpBitcast %5 %327\n%332 = OpBitcast %5 %328\n%333 = OpCompositeConstruct %20 %329 %330 %331 %332\n%334 = OpAccessChain %239 %80 %117 %227\nOpStore %334 %333\n%335 = OpIMul %25 %118 %336\n%337 = OpIMul %25 %118 %153\n%338 = OpAccessChain %128 %64 %117 %337\n%339 = OpLoad %60 %338\n%340 = OpCompositeExtract %45 %339 0\n%341 = OpCompositeExtract %45 %339 1\n%342 = OpCompositeExtract %45 %339 2\n%343 = OpCompositeExtract %45 %339 3\n%344 = OpIMul %25 %118 %153\n%345 = OpCompositeConstruct %60 %340 %341 %342 %343\n%346 = OpAccessChain %128 %112 %117 %344\nOpStore %346 %345\n%347 = OpIMul %25 %118 %165\n%348 = OpAccessChain %175 %44 %117 %347\n%349 = OpLoad %40 %348\n%350 = OpBitcast %179 %349\n%351 = OpCompositeExtract %178 %350 0\n%352 = OpCompositeExtract %178 %350 1\n%353 = OpCompositeExtract %178 %350 2\n%354 = OpCompositeExtract %178 %350 3\n%355 = OpIMul %25 %118 %165\n%356 = OpBitcast %25 %351\n%357 = OpBitcast %25 %352\n%358 = OpBitcast %25 %353\n%359 = OpBitcast %25 %354\n%360 = OpCompositeConstruct %40 %356 %357 %358 %359\n%361 = OpAccessChain %175 %96 %117 %355\nOpStore %361 %360\n%362 = OpIMul %25 %118 %227\n%363 = OpAccessChain %239 %24 %117 %362\n%364 = OpLoad %20 %363\n%365 = OpBitcast %243 %364\n%366 = OpCompositeExtract %242 %365 0\n%367 = OpCompositeExtract %242 %365 1\n%368 = OpCompositeExtract %242 %365 2\n%369 = OpCompositeExtract %242 %365 3\n%370 = OpIMul %25 %118 %227\n%371 = OpBitcast %5 %366\n%372 = OpBitcast %5 %367\n%373 = OpBitcast %5 %368\n%374 = OpBitcast %5 %369\n%375 = OpCompositeConstruct %20 %371 %372 %373 %374\n%376 = OpAccessChain %239 %80 %117 %370\nOpStore %376 %375\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-composite-2.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nvoid main()\n{\n    vec4 _37 = uintBitsToFloat(_10._m0[((gl_GlobalInvocationID.x * 4u) + gl_LocalInvocationIndex) + 1u]);\n    _14._m0[(gl_GlobalInvocationID.x * 4u) + gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_37.x), floatBitsToUint(_37.y), floatBitsToUint(_37.z), floatBitsToUint(_37.w));\n    vec4 _54 = uintBitsToFloat(_10._m0[(gl_GlobalInvocationID.x * 4u) + gl_LocalInvocationIndex]);\n    _14._m0[((gl_GlobalInvocationID.x * 4u) + gl_LocalInvocationIndex) + 1u] = uvec4(floatBitsToUint(_54.x), floatBitsToUint(_54.y), floatBitsToUint(_54.z), floatBitsToUint(_54.w));\n    vec4 _80 = uintBitsToFloat(_10._m0[((gl_GlobalInvocationID.x * 4u) + (3u * gl_LocalInvocationIndex)) + 4294967295u]);\n    _14._m0[((gl_GlobalInvocationID.x * 4u) + (2u * gl_LocalInvocationIndex)) + 1u] = uvec4(floatBitsToUint(_80.x), floatBitsToUint(_80.y), floatBitsToUint(_80.z), floatBitsToUint(_80.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 101\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17 %22\nOpExecutionMode %3 LocalSize 2 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %17 BuiltIn GlobalInvocationId\nOpDecorate %22 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %5\n%20 = OpConstant %5 0\n%22 = OpVariable %18 Input\n%25 = OpConstant %5 4\n%27 = OpConstant %5 16\n%29 = OpConstant %5 1\n%32 = OpTypePointer StorageBuffer %6\n%35 = OpTypeFloat 32\n%36 = OpTypeVector %35 4\n%69 = OpConstant %5 48\n%71 = OpConstant %5 4294967280\n%74 = OpConstant %5 3\n%75 = OpConstant %5 4294967295\n%86 = OpConstant %5 5\n%90 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %99\n%99 = OpLabel\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%23 = OpLoad %5 %22\n%24 = OpShiftLeftLogical %5 %23 %25\n%26 = OpIAdd %5 %24 %27\n%28 = OpIMul %5 %21 %25\n%30 = OpIAdd %5 %28 %23\n%31 = OpIAdd %5 %30 %29\n%33 = OpAccessChain %32 %10 %20 %31\n%34 = OpLoad %6 %33\n%37 = OpBitcast %36 %34\n%38 = OpCompositeExtract %35 %37 0\n%39 = OpCompositeExtract %35 %37 1\n%40 = OpCompositeExtract %35 %37 2\n%41 = OpCompositeExtract %35 %37 3\n%42 = OpIMul %5 %21 %25\n%43 = OpIAdd %5 %42 %23\n%44 = OpBitcast %5 %38\n%45 = OpBitcast %5 %39\n%46 = OpBitcast %5 %40\n%47 = OpBitcast %5 %41\n%48 = OpCompositeConstruct %6 %44 %45 %46 %47\n%49 = OpAccessChain %32 %14 %20 %43\nOpStore %49 %48\n%50 = OpIMul %5 %21 %25\n%51 = OpIAdd %5 %50 %23\n%52 = OpAccessChain %32 %10 %20 %51\n%53 = OpLoad %6 %52\n%54 = OpBitcast %36 %53\n%55 = OpCompositeExtract %35 %54 0\n%56 = OpCompositeExtract %35 %54 1\n%57 = OpCompositeExtract %35 %54 2\n%58 = OpCompositeExtract %35 %54 3\n%59 = OpIMul %5 %21 %25\n%60 = OpIAdd %5 %59 %23\n%61 = OpIAdd %5 %60 %29\n%62 = OpBitcast %5 %55\n%63 = OpBitcast %5 %56\n%64 = OpBitcast %5 %57\n%65 = OpBitcast %5 %58\n%66 = OpCompositeConstruct %6 %62 %63 %64 %65\n%67 = OpAccessChain %32 %14 %20 %61\nOpStore %67 %66\n%68 = OpIMul %5 %23 %69\n%70 = OpIAdd %5 %68 %71\n%72 = OpIMul %5 %21 %25\n%73 = OpIMul %5 %74 %23\n%76 = OpIAdd %5 %72 %73\n%77 = OpIAdd %5 %76 %75\n%78 = OpAccessChain %32 %10 %20 %77\n%79 = OpLoad %6 %78\n%80 = OpBitcast %36 %79\n%81 = OpCompositeExtract %35 %80 0\n%82 = OpCompositeExtract %35 %80 1\n%83 = OpCompositeExtract %35 %80 2\n%84 = OpCompositeExtract %35 %80 3\n%85 = OpShiftLeftLogical %5 %23 %86\n%87 = OpBitwiseOr %5 %85 %27\n%88 = OpIMul %5 %21 %25\n%89 = OpIMul %5 %90 %23\n%91 = OpIAdd %5 %88 %89\n%92 = OpIAdd %5 %91 %29\n%93 = OpBitcast %5 %81\n%94 = OpBitcast %5 %82\n%95 = OpBitcast %5 %83\n%96 = OpBitcast %5 %84\n%97 = OpCompositeConstruct %6 %93 %94 %95 %96\n%98 = OpAccessChain %32 %14 %20 %92\nOpStore %98 %97\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-composite.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, scalar) readonly buffer SSBO\n{\n    uvec3 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, scalar) writeonly buffer _12_14\n{\n    uvec3 _m0[];\n} _14;\n\nvoid main()\n{\n    vec3 _28 = uintBitsToFloat(_10._m0[gl_GlobalInvocationID.x * 2u]);\n    _14._m0[gl_GlobalInvocationID.x * 2u] = uvec3(floatBitsToUint(_28.x), floatBitsToUint(_28.y), floatBitsToUint(_28.z));\n    vec3 _43 = uintBitsToFloat(_10._m0[(gl_GlobalInvocationID.x * 2u) + 1u]);\n    _14._m0[(gl_GlobalInvocationID.x * 2u) + 1u] = uvec3(floatBitsToUint(_43.x), floatBitsToUint(_43.y), floatBitsToUint(_43.z));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 12\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 12\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 3\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypePointer Input %6\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 2\n%23 = OpTypePointer StorageBuffer %6\n%26 = OpTypeFloat 32\n%27 = OpTypeVector %26 3\n%39 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %54\n%54 = OpLabel\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%21 = OpIMul %5 %20 %22\n%24 = OpAccessChain %23 %10 %19 %21\n%25 = OpLoad %6 %24\n%28 = OpBitcast %27 %25\n%29 = OpCompositeExtract %26 %28 0\n%30 = OpCompositeExtract %26 %28 1\n%31 = OpCompositeExtract %26 %28 2\n%32 = OpIMul %5 %20 %22\n%33 = OpBitcast %5 %29\n%34 = OpBitcast %5 %30\n%35 = OpBitcast %5 %31\n%36 = OpCompositeConstruct %6 %33 %34 %35\n%37 = OpAccessChain %23 %14 %19 %32\nOpStore %37 %36\n%38 = OpIMul %5 %20 %22\n%40 = OpIAdd %5 %38 %39\n%41 = OpAccessChain %23 %10 %19 %40\n%42 = OpLoad %6 %41\n%43 = OpBitcast %27 %42\n%44 = OpCompositeExtract %26 %43 0\n%45 = OpCompositeExtract %26 %43 1\n%46 = OpCompositeExtract %26 %43 2\n%47 = OpIMul %5 %20 %22\n%48 = OpIAdd %5 %47 %39\n%49 = OpBitcast %5 %44\n%50 = OpBitcast %5 %45\n%51 = OpBitcast %5 %46\n%52 = OpCompositeConstruct %6 %49 %50 %51\n%53 = OpAccessChain %23 %14 %19 %48\nOpStore %53 %52\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-composite.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _18[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _20_23\n{\n    uint _m0[];\n} _23[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _30 = registers._m4 + 1u;\n    uvec2 _38 = _13._m0[subgroupBroadcastFirst(_30)] >> uvec2(2u);\n    uvec2 _48 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(2u);\n    uint _55 = gl_GlobalInvocationID.x * 6u;\n    uint _62 = (_55 < _48.y) ? (_55 + _48.x) : 1073741820u;\n    uint _66 = _18[registers._m4]._m0[_62];\n    uint _69 = _18[registers._m4]._m0[_62 + 1u];\n    uint _72 = _18[registers._m4]._m0[_62 + 2u];\n    vec3 _76 = uintBitsToFloat(uvec3(_66, _69, _72));\n    uint _80 = gl_GlobalInvocationID.x * 6u;\n    uint _85 = (_80 < _38.y) ? (_80 + _38.x) : 1073741820u;\n    _23[_30]._m0[_85] = floatBitsToUint(_76.x);\n    _23[_30]._m0[_85 + 1u] = floatBitsToUint(_76.y);\n    _23[_30]._m0[_85 + 2u] = floatBitsToUint(_76.z);\n    uint _95 = (gl_GlobalInvocationID.x * 6u) + 3u;\n    uint _100 = (_95 < _48.y) ? (_95 + _48.x) : 1073741820u;\n    uint _102 = _18[registers._m4]._m0[_100];\n    uint _105 = _18[registers._m4]._m0[_100 + 1u];\n    uint _108 = _18[registers._m4]._m0[_100 + 2u];\n    vec3 _110 = uintBitsToFloat(uvec3(_102, _105, _108));\n    uint _115 = (gl_GlobalInvocationID.x * 6u) + 3u;\n    uint _120 = (_115 < _38.y) ? (_115 + _38.x) : 1073741820u;\n    _23[_30]._m0[_120] = floatBitsToUint(_110.x);\n    _23[_30]._m0[_120 + 1u] = floatBitsToUint(_110.y);\n    _23[_30]._m0[_120 + 2u] = floatBitsToUint(_110.z);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 131\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %51\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %15 \"SSBO\"\nOpName %20 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %14 ArrayStride 4\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 4\nOpDecorate %18 Binding 0\nOpDecorate %18 NonWritable\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %23 DescriptorSet 4\nOpDecorate %23 Binding 0\nOpDecorate %23 NonReadable\nOpDecorate %51 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeRuntimeArray %5\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypePointer StorageBuffer %20\n%26 = OpTypePointer PushConstant %5\n%28 = OpConstant %5 4\n%31 = OpConstant %5 1\n%33 = OpConstant %5 3\n%34 = OpTypePointer StorageBuffer %9\n%36 = OpConstant %5 0\n%39 = OpConstant %5 2\n%40 = OpConstantComposite %9 %39 %39\n%41 = OpTypePointer StorageBuffer %15\n%49 = OpTypeVector %5 3\n%50 = OpTypePointer Input %49\n%51 = OpVariable %50 Input\n%52 = OpTypePointer Input %5\n%56 = OpConstant %5 6\n%60 = OpTypeBool\n%63 = OpConstant %5 1073741820\n%64 = OpTypePointer StorageBuffer %5\n%74 = OpTypeFloat 32\n%75 = OpTypeVector %74 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %129\n%129 = OpLabel\n%27 = OpAccessChain %26 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpIAdd %5 %29 %31\n%25 = OpAccessChain %24 %23 %30\n%32 = OpGroupNonUniformBroadcastFirst %5 %33 %30\n%35 = OpAccessChain %34 %13 %36 %32\n%37 = OpLoad %9 %35\n%38 = OpShiftRightLogical %9 %37 %40\n%43 = OpAccessChain %26 %8 %28\n%44 = OpLoad %5 %43\n%42 = OpAccessChain %41 %18 %44\n%45 = OpGroupNonUniformBroadcastFirst %5 %33 %44\n%46 = OpAccessChain %34 %13 %36 %45\n%47 = OpLoad %9 %46\n%48 = OpShiftRightLogical %9 %47 %40\n%53 = OpAccessChain %52 %51 %36\n%54 = OpLoad %5 %53\n%55 = OpIMul %5 %54 %56\n%57 = OpCompositeExtract %5 %48 0\n%58 = OpCompositeExtract %5 %48 1\n%59 = OpIAdd %5 %55 %57\n%61 = OpULessThan %60 %55 %58\n%62 = OpSelect %5 %61 %59 %63\n%65 = OpAccessChain %64 %42 %36 %62\n%66 = OpLoad %5 %65\n%68 = OpIAdd %5 %62 %31\n%67 = OpAccessChain %64 %42 %36 %68\n%69 = OpLoad %5 %67\n%71 = OpIAdd %5 %62 %39\n%70 = OpAccessChain %64 %42 %36 %71\n%72 = OpLoad %5 %70\n%73 = OpCompositeConstruct %49 %66 %69 %72\n%76 = OpBitcast %75 %73\n%77 = OpCompositeExtract %74 %76 0\n%78 = OpCompositeExtract %74 %76 1\n%79 = OpCompositeExtract %74 %76 2\n%80 = OpIMul %5 %54 %56\n%81 = OpCompositeExtract %5 %38 0\n%82 = OpCompositeExtract %5 %38 1\n%83 = OpIAdd %5 %80 %81\n%84 = OpULessThan %60 %80 %82\n%85 = OpSelect %5 %84 %83 %63\n%86 = OpBitcast %5 %77\n%87 = OpBitcast %5 %78\n%88 = OpBitcast %5 %79\n%89 = OpAccessChain %64 %25 %36 %85\nOpStore %89 %86\n%91 = OpIAdd %5 %85 %31\n%90 = OpAccessChain %64 %25 %36 %91\nOpStore %90 %87\n%93 = OpIAdd %5 %85 %39\n%92 = OpAccessChain %64 %25 %36 %93\nOpStore %92 %88\n%94 = OpIMul %5 %54 %56\n%95 = OpIAdd %5 %94 %33\n%96 = OpCompositeExtract %5 %48 0\n%97 = OpCompositeExtract %5 %48 1\n%98 = OpIAdd %5 %95 %96\n%99 = OpULessThan %60 %95 %97\n%100 = OpSelect %5 %99 %98 %63\n%101 = OpAccessChain %64 %42 %36 %100\n%102 = OpLoad %5 %101\n%104 = OpIAdd %5 %100 %31\n%103 = OpAccessChain %64 %42 %36 %104\n%105 = OpLoad %5 %103\n%107 = OpIAdd %5 %100 %39\n%106 = OpAccessChain %64 %42 %36 %107\n%108 = OpLoad %5 %106\n%109 = OpCompositeConstruct %49 %102 %105 %108\n%110 = OpBitcast %75 %109\n%111 = OpCompositeExtract %74 %110 0\n%112 = OpCompositeExtract %74 %110 1\n%113 = OpCompositeExtract %74 %110 2\n%114 = OpIMul %5 %54 %56\n%115 = OpIAdd %5 %114 %33\n%116 = OpCompositeExtract %5 %38 0\n%117 = OpCompositeExtract %5 %38 1\n%118 = OpIAdd %5 %115 %116\n%119 = OpULessThan %60 %115 %117\n%120 = OpSelect %5 %119 %118 %63\n%121 = OpBitcast %5 %111\n%122 = OpBitcast %5 %112\n%123 = OpBitcast %5 %113\n%124 = OpAccessChain %64 %25 %36 %120\nOpStore %124 %121\n%126 = OpIAdd %5 %120 %31\n%125 = OpAccessChain %64 %25 %36 %126\nOpStore %125 %122\n%128 = OpIAdd %5 %120 %39\n%127 = OpAccessChain %64 %25 %36 %128\nOpStore %127 %123\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-double2.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    dvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    dvec2 _m0[];\n} _14;\n\nvoid main()\n{\n    _14._m0[gl_GlobalInvocationID.x] = dvec2(_10._m0[gl_GlobalInvocationID.x]);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 64\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 32 0\n%16 = OpTypeVector %15 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %15\n%21 = OpConstant %15 0\n%23 = OpTypePointer StorageBuffer %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %15 %20\n%24 = OpAccessChain %23 %10 %21 %22\n%25 = OpLoad %6 %24\n%26 = OpCompositeExtract %5 %25 0\n%27 = OpCompositeExtract %5 %25 1\n%28 = OpCompositeConstruct %6 %26 %27\n%29 = OpAccessChain %23 %14 %21 %22\nOpStore %29 %28\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-double2.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    dvec2 _m0[];\n} _20[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _22_25\n{\n    dvec2 _m0[];\n} _25[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _32 = registers._m4 + 1u;\n    uvec2 _40 = _13._m0[subgroupBroadcastFirst(_32)] >> uvec2(4u);\n    uvec2 _49 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(4u);\n    _25[_32]._m0[(gl_GlobalInvocationID.x < _40.y) ? (gl_GlobalInvocationID.x + _40.x) : 268435455u] = dvec2(_20[registers._m4]._m0[(gl_GlobalInvocationID.x < _49.y) ? (gl_GlobalInvocationID.x + _49.x) : 268435455u]);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 77\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability GroupNonUniformBallot\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %52\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %17 \"SSBO\"\nOpName %22 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 ArrayStride 16\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %20 DescriptorSet 4\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %21 ArrayStride 16\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %25 DescriptorSet 4\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %52 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFloat 64\n%15 = OpTypeVector %14 2\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %15\n%22 = OpTypeStruct %21\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypePointer StorageBuffer %22\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 4\n%33 = OpConstant %5 1\n%35 = OpConstant %5 3\n%36 = OpTypePointer StorageBuffer %9\n%38 = OpConstant %5 0\n%41 = OpConstantComposite %9 %30 %30\n%42 = OpTypePointer StorageBuffer %17\n%50 = OpTypeVector %5 3\n%51 = OpTypePointer Input %50\n%52 = OpVariable %51 Input\n%53 = OpTypePointer Input %5\n%59 = OpTypeBool\n%62 = OpConstant %5 268435455\n%63 = OpTypePointer StorageBuffer %15\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%32 = OpIAdd %5 %31 %33\n%27 = OpAccessChain %26 %25 %32\n%34 = OpGroupNonUniformBroadcastFirst %5 %35 %32\n%37 = OpAccessChain %36 %13 %38 %34\n%39 = OpLoad %9 %37\n%40 = OpShiftRightLogical %9 %39 %41\n%44 = OpAccessChain %28 %8 %30\n%45 = OpLoad %5 %44\n%43 = OpAccessChain %42 %20 %45\n%46 = OpGroupNonUniformBroadcastFirst %5 %35 %45\n%47 = OpAccessChain %36 %13 %38 %46\n%48 = OpLoad %9 %47\n%49 = OpShiftRightLogical %9 %48 %41\n%54 = OpAccessChain %53 %52 %38\n%55 = OpLoad %5 %54\n%56 = OpCompositeExtract %5 %49 0\n%57 = OpCompositeExtract %5 %49 1\n%58 = OpIAdd %5 %55 %56\n%60 = OpULessThan %59 %55 %57\n%61 = OpSelect %5 %60 %58 %62\n%64 = OpAccessChain %63 %43 %38 %61\n%65 = OpLoad %15 %64\n%66 = OpCompositeExtract %14 %65 0\n%67 = OpCompositeExtract %14 %65 1\n%68 = OpCompositeExtract %5 %40 0\n%69 = OpCompositeExtract %5 %40 1\n%70 = OpIAdd %5 %55 %68\n%71 = OpULessThan %59 %55 %69\n%72 = OpSelect %5 %71 %70 %62\n%73 = OpCompositeConstruct %15 %66 %67\n%74 = OpAccessChain %63 %27 %38 %72\nOpStore %74 %73\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-double3.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, scalar) readonly buffer SSBO\n{\n    dvec3 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, scalar) writeonly buffer _12_14\n{\n    dvec3 _m0[];\n} _14;\n\nvoid main()\n{\n    _14._m0[gl_GlobalInvocationID.x] = dvec3(_10._m0[gl_GlobalInvocationID.x]);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 24\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 24\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 64\n%6 = OpTypeVector %5 3\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 32 0\n%16 = OpTypeVector %15 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %15\n%21 = OpConstant %15 0\n%23 = OpTypePointer StorageBuffer %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %31\n%31 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %15 %20\n%24 = OpAccessChain %23 %10 %21 %22\n%25 = OpLoad %6 %24\n%26 = OpCompositeExtract %5 %25 0\n%27 = OpCompositeExtract %5 %25 1\n%28 = OpCompositeExtract %5 %25 2\n%29 = OpCompositeConstruct %6 %26 %27 %28\n%30 = OpAccessChain %23 %14 %21 %22\nOpStore %30 %29\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-double3.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    double _m0[];\n} _19[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _21_24\n{\n    double _m0[];\n} _24[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _31 = registers._m4 + 1u;\n    uvec2 _39 = _13._m0[subgroupBroadcastFirst(_31)] >> uvec2(3u);\n    uvec2 _48 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(3u);\n    uint _55 = gl_GlobalInvocationID.x * 3u;\n    uint _61 = (_55 < _48.y) ? (_55 + _48.x) : 536870908u;\n    double _65 = _19[registers._m4]._m0[_61];\n    double _68 = _19[registers._m4]._m0[_61 + 1u];\n    double _72 = _19[registers._m4]._m0[_61 + 2u];\n    dvec3 _74 = dvec3(_65, _68, _72);\n    uint _78 = gl_GlobalInvocationID.x * 3u;\n    uint _83 = (_78 < _39.y) ? (_78 + _39.x) : 536870908u;\n    _24[_31]._m0[_83] = _74.x;\n    _24[_31]._m0[_83 + 1u] = _74.y;\n    _24[_31]._m0[_83 + 2u] = _74.z;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability GroupNonUniformBallot\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %51\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %15 ArrayStride 8\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 4\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %20 ArrayStride 8\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 4\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\nOpDecorate %51 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeFloat 64\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %14\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypePointer StorageBuffer %21\n%27 = OpTypePointer PushConstant %5\n%29 = OpConstant %5 4\n%32 = OpConstant %5 1\n%34 = OpConstant %5 3\n%35 = OpTypePointer StorageBuffer %9\n%37 = OpConstant %5 0\n%40 = OpConstantComposite %9 %34 %34\n%41 = OpTypePointer StorageBuffer %16\n%49 = OpTypeVector %5 3\n%50 = OpTypePointer Input %49\n%51 = OpVariable %50 Input\n%52 = OpTypePointer Input %5\n%59 = OpTypeBool\n%62 = OpConstant %5 536870908\n%63 = OpTypePointer StorageBuffer %14\n%71 = OpConstant %5 2\n%73 = OpTypeVector %14 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %89\n%89 = OpLabel\n%28 = OpAccessChain %27 %8 %29\n%30 = OpLoad %5 %28\n%31 = OpIAdd %5 %30 %32\n%26 = OpAccessChain %25 %24 %31\n%33 = OpGroupNonUniformBroadcastFirst %5 %34 %31\n%36 = OpAccessChain %35 %13 %37 %33\n%38 = OpLoad %9 %36\n%39 = OpShiftRightLogical %9 %38 %40\n%43 = OpAccessChain %27 %8 %29\n%44 = OpLoad %5 %43\n%42 = OpAccessChain %41 %19 %44\n%45 = OpGroupNonUniformBroadcastFirst %5 %34 %44\n%46 = OpAccessChain %35 %13 %37 %45\n%47 = OpLoad %9 %46\n%48 = OpShiftRightLogical %9 %47 %40\n%53 = OpAccessChain %52 %51 %37\n%54 = OpLoad %5 %53\n%55 = OpIMul %5 %54 %34\n%56 = OpCompositeExtract %5 %48 0\n%57 = OpCompositeExtract %5 %48 1\n%58 = OpIAdd %5 %55 %56\n%60 = OpULessThan %59 %55 %57\n%61 = OpSelect %5 %60 %58 %62\n%64 = OpAccessChain %63 %42 %37 %61\n%65 = OpLoad %14 %64\n%67 = OpIAdd %5 %61 %32\n%66 = OpAccessChain %63 %42 %37 %67\n%68 = OpLoad %14 %66\n%70 = OpIAdd %5 %61 %71\n%69 = OpAccessChain %63 %42 %37 %70\n%72 = OpLoad %14 %69\n%74 = OpCompositeConstruct %73 %65 %68 %72\n%75 = OpCompositeExtract %14 %74 0\n%76 = OpCompositeExtract %14 %74 1\n%77 = OpCompositeExtract %14 %74 2\n%78 = OpIMul %5 %54 %34\n%79 = OpCompositeExtract %5 %39 0\n%80 = OpCompositeExtract %5 %39 1\n%81 = OpIAdd %5 %78 %79\n%82 = OpULessThan %59 %78 %80\n%83 = OpSelect %5 %82 %81 %62\n%84 = OpAccessChain %63 %26 %37 %83\nOpStore %84 %75\n%86 = OpIAdd %5 %83 %32\n%85 = OpAccessChain %63 %26 %37 %86\nOpStore %85 %76\n%88 = OpIAdd %5 %83 %71\n%87 = OpAccessChain %63 %26 %37 %88\nOpStore %87 %77\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-double4.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    dvec4 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    dvec4 _m0[];\n} _14;\n\nvoid main()\n{\n    _14._m0[gl_GlobalInvocationID.x] = dvec4(_10._m0[gl_GlobalInvocationID.x]);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\nOpCapability Shader\nOpCapability Float64\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 64\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 32\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 32\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 64\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 32 0\n%16 = OpTypeVector %15 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %15\n%21 = OpConstant %15 0\n%23 = OpTypePointer StorageBuffer %6\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %32\n%32 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %15 %20\n%24 = OpAccessChain %23 %10 %21 %22\n%25 = OpLoad %6 %24\n%26 = OpCompositeExtract %5 %25 0\n%27 = OpCompositeExtract %5 %25 1\n%28 = OpCompositeExtract %5 %25 2\n%29 = OpCompositeExtract %5 %25 3\n%30 = OpCompositeConstruct %6 %26 %27 %28 %29\n%31 = OpAccessChain %23 %14 %21 %22\nOpStore %31 %30\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-float2.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    uvec2 _m0[];\n} _14;\n\nvoid main()\n{\n    vec2 _27 = uintBitsToFloat(_10._m0[gl_GlobalInvocationID.x]);\n    _14._m0[gl_GlobalInvocationID.x] = uvec2(floatBitsToUint(_27.x), floatBitsToUint(_27.y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %17 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %5\n%20 = OpConstant %5 0\n%22 = OpTypePointer StorageBuffer %6\n%25 = OpTypeFloat 32\n%26 = OpTypeVector %25 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %34\n%34 = OpLabel\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%23 = OpAccessChain %22 %10 %20 %21\n%24 = OpLoad %6 %23\n%27 = OpBitcast %26 %24\n%28 = OpCompositeExtract %25 %27 0\n%29 = OpCompositeExtract %25 %27 1\n%30 = OpBitcast %5 %28\n%31 = OpBitcast %5 %29\n%32 = OpCompositeConstruct %6 %30 %31\n%33 = OpAccessChain %22 %14 %20 %21\nOpStore %33 %32\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-float2.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _18[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _20_23\n{\n    uvec2 _m0[];\n} _23[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _30 = registers._m4 + 1u;\n    uvec2 _38 = _13._m0[subgroupBroadcastFirst(_30)] >> uvec2(3u);\n    uvec2 _47 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(3u);\n    vec2 _65 = uintBitsToFloat(_18[registers._m4]._m0[(gl_GlobalInvocationID.x < _47.y) ? (gl_GlobalInvocationID.x + _47.x) : 536870911u]);\n    _23[_30]._m0[(gl_GlobalInvocationID.x < _38.y) ? (gl_GlobalInvocationID.x + _38.x) : 536870911u] = uvec2(floatBitsToUint(_65.x), floatBitsToUint(_65.y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %50\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %15 \"SSBO\"\nOpName %20 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %14 ArrayStride 8\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 4\nOpDecorate %18 Binding 0\nOpDecorate %18 NonWritable\nOpDecorate %19 ArrayStride 8\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %23 DescriptorSet 4\nOpDecorate %23 Binding 0\nOpDecorate %23 NonReadable\nOpDecorate %50 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeRuntimeArray %9\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %9\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypePointer StorageBuffer %20\n%26 = OpTypePointer PushConstant %5\n%28 = OpConstant %5 4\n%31 = OpConstant %5 1\n%33 = OpConstant %5 3\n%34 = OpTypePointer StorageBuffer %9\n%36 = OpConstant %5 0\n%39 = OpConstantComposite %9 %33 %33\n%40 = OpTypePointer StorageBuffer %15\n%48 = OpTypeVector %5 3\n%49 = OpTypePointer Input %48\n%50 = OpVariable %49 Input\n%51 = OpTypePointer Input %5\n%57 = OpTypeBool\n%60 = OpConstant %5 536870911\n%63 = OpTypeFloat 32\n%64 = OpTypeVector %63 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %77\n%77 = OpLabel\n%27 = OpAccessChain %26 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpIAdd %5 %29 %31\n%25 = OpAccessChain %24 %23 %30\n%32 = OpGroupNonUniformBroadcastFirst %5 %33 %30\n%35 = OpAccessChain %34 %13 %36 %32\n%37 = OpLoad %9 %35\n%38 = OpShiftRightLogical %9 %37 %39\n%42 = OpAccessChain %26 %8 %28\n%43 = OpLoad %5 %42\n%41 = OpAccessChain %40 %18 %43\n%44 = OpGroupNonUniformBroadcastFirst %5 %33 %43\n%45 = OpAccessChain %34 %13 %36 %44\n%46 = OpLoad %9 %45\n%47 = OpShiftRightLogical %9 %46 %39\n%52 = OpAccessChain %51 %50 %36\n%53 = OpLoad %5 %52\n%54 = OpCompositeExtract %5 %47 0\n%55 = OpCompositeExtract %5 %47 1\n%56 = OpIAdd %5 %53 %54\n%58 = OpULessThan %57 %53 %55\n%59 = OpSelect %5 %58 %56 %60\n%61 = OpAccessChain %34 %41 %36 %59\n%62 = OpLoad %9 %61\n%65 = OpBitcast %64 %62\n%66 = OpCompositeExtract %63 %65 0\n%67 = OpCompositeExtract %63 %65 1\n%68 = OpCompositeExtract %5 %38 0\n%69 = OpCompositeExtract %5 %38 1\n%70 = OpIAdd %5 %53 %68\n%71 = OpULessThan %57 %53 %69\n%72 = OpSelect %5 %71 %70 %60\n%73 = OpBitcast %5 %66\n%74 = OpBitcast %5 %67\n%75 = OpCompositeConstruct %9 %73 %74\n%76 = OpAccessChain %34 %25 %36 %72\nOpStore %76 %75\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-float2x2.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nvoid main()\n{\n    vec4 _27 = uintBitsToFloat(_10._m0[gl_GlobalInvocationID.x]);\n    _14._m0[gl_GlobalInvocationID.x] = uvec4(floatBitsToUint(_27.x), floatBitsToUint(_27.y), floatBitsToUint(_27.z), floatBitsToUint(_27.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %17 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %5\n%20 = OpConstant %5 0\n%22 = OpTypePointer StorageBuffer %6\n%25 = OpTypeFloat 32\n%26 = OpTypeVector %25 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %38\n%38 = OpLabel\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%23 = OpAccessChain %22 %10 %20 %21\n%24 = OpLoad %6 %23\n%27 = OpBitcast %26 %24\n%28 = OpCompositeExtract %25 %27 0\n%29 = OpCompositeExtract %25 %27 1\n%30 = OpCompositeExtract %25 %27 2\n%31 = OpCompositeExtract %25 %27 3\n%32 = OpBitcast %5 %28\n%33 = OpBitcast %5 %29\n%34 = OpBitcast %5 %30\n%35 = OpBitcast %5 %31\n%36 = OpCompositeConstruct %6 %32 %33 %34 %35\n%37 = OpAccessChain %22 %14 %20 %21\nOpStore %37 %36\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-float3.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, scalar) readonly buffer SSBO\n{\n    uvec3 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, scalar) writeonly buffer _12_14\n{\n    uvec3 _m0[];\n} _14;\n\nvoid main()\n{\n    vec3 _26 = uintBitsToFloat(_10._m0[gl_GlobalInvocationID.x]);\n    _14._m0[gl_GlobalInvocationID.x] = uvec3(floatBitsToUint(_26.x), floatBitsToUint(_26.y), floatBitsToUint(_26.z));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %16\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 12\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 12\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %16 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 3\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypePointer Input %6\n%16 = OpVariable %15 Input\n%17 = OpTypePointer Input %5\n%19 = OpConstant %5 0\n%21 = OpTypePointer StorageBuffer %6\n%24 = OpTypeFloat 32\n%25 = OpTypeVector %24 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%22 = OpAccessChain %21 %10 %19 %20\n%23 = OpLoad %6 %22\n%26 = OpBitcast %25 %23\n%27 = OpCompositeExtract %24 %26 0\n%28 = OpCompositeExtract %24 %26 1\n%29 = OpCompositeExtract %24 %26 2\n%30 = OpBitcast %5 %27\n%31 = OpBitcast %5 %28\n%32 = OpBitcast %5 %29\n%33 = OpCompositeConstruct %6 %30 %31 %32\n%34 = OpAccessChain %21 %14 %19 %20\nOpStore %34 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-float3.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _18[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _20_23\n{\n    uint _m0[];\n} _23[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _30 = registers._m4 + 1u;\n    uvec2 _38 = _13._m0[subgroupBroadcastFirst(_30)] >> uvec2(2u);\n    uvec2 _48 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(2u);\n    uint _55 = gl_GlobalInvocationID.x * 3u;\n    uint _61 = (_55 < _48.y) ? (_55 + _48.x) : 1073741820u;\n    uint _65 = _18[registers._m4]._m0[_61];\n    uint _68 = _18[registers._m4]._m0[_61 + 1u];\n    uint _71 = _18[registers._m4]._m0[_61 + 2u];\n    vec3 _75 = uintBitsToFloat(uvec3(_65, _68, _71));\n    uint _79 = gl_GlobalInvocationID.x * 3u;\n    uint _84 = (_79 < _38.y) ? (_79 + _38.x) : 1073741820u;\n    _23[_30]._m0[_84] = floatBitsToUint(_75.x);\n    _23[_30]._m0[_84 + 1u] = floatBitsToUint(_75.y);\n    _23[_30]._m0[_84 + 2u] = floatBitsToUint(_75.z);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniformBallot\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %51\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %15 \"SSBO\"\nOpName %20 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %14 ArrayStride 4\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %15 Block\nOpDecorate %18 DescriptorSet 4\nOpDecorate %18 Binding 0\nOpDecorate %18 NonWritable\nOpDecorate %19 ArrayStride 4\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %23 DescriptorSet 4\nOpDecorate %23 Binding 0\nOpDecorate %23 NonReadable\nOpDecorate %51 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeRuntimeArray %5\n%15 = OpTypeStruct %14\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %5\n%20 = OpTypeStruct %19\n%21 = OpTypeRuntimeArray %20\n%22 = OpTypePointer StorageBuffer %21\n%23 = OpVariable %22 StorageBuffer\n%24 = OpTypePointer StorageBuffer %20\n%26 = OpTypePointer PushConstant %5\n%28 = OpConstant %5 4\n%31 = OpConstant %5 1\n%33 = OpConstant %5 3\n%34 = OpTypePointer StorageBuffer %9\n%36 = OpConstant %5 0\n%39 = OpConstant %5 2\n%40 = OpConstantComposite %9 %39 %39\n%41 = OpTypePointer StorageBuffer %15\n%49 = OpTypeVector %5 3\n%50 = OpTypePointer Input %49\n%51 = OpVariable %50 Input\n%52 = OpTypePointer Input %5\n%59 = OpTypeBool\n%62 = OpConstant %5 1073741820\n%63 = OpTypePointer StorageBuffer %5\n%73 = OpTypeFloat 32\n%74 = OpTypeVector %73 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %93\n%93 = OpLabel\n%27 = OpAccessChain %26 %8 %28\n%29 = OpLoad %5 %27\n%30 = OpIAdd %5 %29 %31\n%25 = OpAccessChain %24 %23 %30\n%32 = OpGroupNonUniformBroadcastFirst %5 %33 %30\n%35 = OpAccessChain %34 %13 %36 %32\n%37 = OpLoad %9 %35\n%38 = OpShiftRightLogical %9 %37 %40\n%43 = OpAccessChain %26 %8 %28\n%44 = OpLoad %5 %43\n%42 = OpAccessChain %41 %18 %44\n%45 = OpGroupNonUniformBroadcastFirst %5 %33 %44\n%46 = OpAccessChain %34 %13 %36 %45\n%47 = OpLoad %9 %46\n%48 = OpShiftRightLogical %9 %47 %40\n%53 = OpAccessChain %52 %51 %36\n%54 = OpLoad %5 %53\n%55 = OpIMul %5 %54 %33\n%56 = OpCompositeExtract %5 %48 0\n%57 = OpCompositeExtract %5 %48 1\n%58 = OpIAdd %5 %55 %56\n%60 = OpULessThan %59 %55 %57\n%61 = OpSelect %5 %60 %58 %62\n%64 = OpAccessChain %63 %42 %36 %61\n%65 = OpLoad %5 %64\n%67 = OpIAdd %5 %61 %31\n%66 = OpAccessChain %63 %42 %36 %67\n%68 = OpLoad %5 %66\n%70 = OpIAdd %5 %61 %39\n%69 = OpAccessChain %63 %42 %36 %70\n%71 = OpLoad %5 %69\n%72 = OpCompositeConstruct %49 %65 %68 %71\n%75 = OpBitcast %74 %72\n%76 = OpCompositeExtract %73 %75 0\n%77 = OpCompositeExtract %73 %75 1\n%78 = OpCompositeExtract %73 %75 2\n%79 = OpIMul %5 %54 %33\n%80 = OpCompositeExtract %5 %38 0\n%81 = OpCompositeExtract %5 %38 1\n%82 = OpIAdd %5 %79 %80\n%83 = OpULessThan %59 %79 %81\n%84 = OpSelect %5 %83 %82 %62\n%85 = OpBitcast %5 %76\n%86 = OpBitcast %5 %77\n%87 = OpBitcast %5 %78\n%88 = OpAccessChain %63 %25 %36 %84\nOpStore %88 %85\n%90 = OpIAdd %5 %84 %31\n%89 = OpAccessChain %63 %25 %36 %90\nOpStore %89 %86\n%92 = OpIAdd %5 %84 %39\n%91 = OpAccessChain %63 %25 %36 %92\nOpStore %91 %87\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-float4x4.ssbo.comp",
    "content": "#version 460\nlayout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nvoid main()\n{\n    vec4 _29 = uintBitsToFloat(_10._m0[gl_GlobalInvocationID.x * 4u]);\n    uvec4 _38 = _10._m0[(gl_GlobalInvocationID.x * 4u) + 1u];\n    vec4 _39 = uintBitsToFloat(_38);\n    uvec4 _48 = _10._m0[(gl_GlobalInvocationID.x * 4u) + 2u];\n    vec4 _49 = uintBitsToFloat(_48);\n    uvec4 _58 = _10._m0[(gl_GlobalInvocationID.x * 4u) + 3u];\n    vec4 _59 = uintBitsToFloat(_58);\n    _14._m0[gl_GlobalInvocationID.x * 4u] = uvec4(floatBitsToUint(_29.x), floatBitsToUint(_29.y), floatBitsToUint(_29.z), floatBitsToUint(_29.w));\n    _14._m0[(gl_GlobalInvocationID.x * 4u) + 1u] = uvec4(floatBitsToUint(_39.x), floatBitsToUint(_39.y), floatBitsToUint(_39.z), floatBitsToUint(_39.w));\n    _14._m0[(gl_GlobalInvocationID.x * 4u) + 2u] = uvec4(floatBitsToUint(_49.x), floatBitsToUint(_49.y), floatBitsToUint(_49.z), floatBitsToUint(_49.w));\n    _14._m0[(gl_GlobalInvocationID.x * 4u) + 3u] = uvec4(floatBitsToUint(_59.x), floatBitsToUint(_59.y), floatBitsToUint(_59.z), floatBitsToUint(_59.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 97\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %17\nOpExecutionMode %3 LocalSize 128 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %17 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeVector %5 3\n%16 = OpTypePointer Input %15\n%17 = OpVariable %16 Input\n%18 = OpTypePointer Input %5\n%20 = OpConstant %5 0\n%23 = OpConstant %5 4\n%24 = OpTypePointer StorageBuffer %6\n%27 = OpTypeFloat 32\n%28 = OpTypeVector %27 4\n%35 = OpConstant %5 1\n%45 = OpConstant %5 2\n%55 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %95\n%95 = OpLabel\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpIMul %5 %21 %23\n%25 = OpAccessChain %24 %10 %20 %22\n%26 = OpLoad %6 %25\n%29 = OpBitcast %28 %26\n%30 = OpCompositeExtract %27 %29 0\n%31 = OpCompositeExtract %27 %29 1\n%32 = OpCompositeExtract %27 %29 2\n%33 = OpCompositeExtract %27 %29 3\n%34 = OpIMul %5 %21 %23\n%36 = OpIAdd %5 %34 %35\n%37 = OpAccessChain %24 %10 %20 %36\n%38 = OpLoad %6 %37\n%39 = OpBitcast %28 %38\n%40 = OpCompositeExtract %27 %39 0\n%41 = OpCompositeExtract %27 %39 1\n%42 = OpCompositeExtract %27 %39 2\n%43 = OpCompositeExtract %27 %39 3\n%44 = OpIMul %5 %21 %23\n%46 = OpIAdd %5 %44 %45\n%47 = OpAccessChain %24 %10 %20 %46\n%48 = OpLoad %6 %47\n%49 = OpBitcast %28 %48\n%50 = OpCompositeExtract %27 %49 0\n%51 = OpCompositeExtract %27 %49 1\n%52 = OpCompositeExtract %27 %49 2\n%53 = OpCompositeExtract %27 %49 3\n%54 = OpIMul %5 %21 %23\n%56 = OpIAdd %5 %54 %55\n%57 = OpAccessChain %24 %10 %20 %56\n%58 = OpLoad %6 %57\n%59 = OpBitcast %28 %58\n%60 = OpCompositeExtract %27 %59 0\n%61 = OpCompositeExtract %27 %59 1\n%62 = OpCompositeExtract %27 %59 2\n%63 = OpCompositeExtract %27 %59 3\n%64 = OpIMul %5 %21 %23\n%65 = OpBitcast %5 %30\n%66 = OpBitcast %5 %31\n%67 = OpBitcast %5 %32\n%68 = OpBitcast %5 %33\n%69 = OpCompositeConstruct %6 %65 %66 %67 %68\n%70 = OpAccessChain %24 %14 %20 %64\nOpStore %70 %69\n%71 = OpIMul %5 %21 %23\n%72 = OpIAdd %5 %71 %35\n%73 = OpBitcast %5 %40\n%74 = OpBitcast %5 %41\n%75 = OpBitcast %5 %42\n%76 = OpBitcast %5 %43\n%77 = OpCompositeConstruct %6 %73 %74 %75 %76\n%78 = OpAccessChain %24 %14 %20 %72\nOpStore %78 %77\n%79 = OpIMul %5 %21 %23\n%80 = OpIAdd %5 %79 %45\n%81 = OpBitcast %5 %50\n%82 = OpBitcast %5 %51\n%83 = OpBitcast %5 %52\n%84 = OpBitcast %5 %53\n%85 = OpCompositeConstruct %6 %81 %82 %83 %84\n%86 = OpAccessChain %24 %14 %20 %80\nOpStore %86 %85\n%87 = OpIMul %5 %21 %23\n%88 = OpIAdd %5 %87 %55\n%89 = OpBitcast %5 %60\n%90 = OpBitcast %5 %61\n%91 = OpBitcast %5 %62\n%92 = OpBitcast %5 %63\n%93 = OpCompositeConstruct %6 %89 %90 %91 %92\n%94 = OpAccessChain %24 %14 %20 %88\nOpStore %94 %93\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-half2.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    u16vec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    u16vec2 _m0[];\n} _14;\n\nvoid main()\n{\n    f16vec2 _28 = uint16BitsToFloat16(_10._m0[gl_GlobalInvocationID.x]);\n    _14._m0[gl_GlobalInvocationID.x] = u16vec2(float16BitsToUint16(_28.x), float16BitsToUint16(_28.y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 4\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 4\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 16 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 32 0\n%16 = OpTypeVector %15 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %15\n%21 = OpConstant %15 0\n%23 = OpTypePointer StorageBuffer %6\n%26 = OpTypeFloat 16\n%27 = OpTypeVector %26 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %35\n%35 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %15 %20\n%24 = OpAccessChain %23 %10 %21 %22\n%25 = OpLoad %6 %24\n%28 = OpBitcast %27 %25\n%29 = OpCompositeExtract %26 %28 0\n%30 = OpCompositeExtract %26 %28 1\n%31 = OpBitcast %5 %29\n%32 = OpBitcast %5 %30\n%33 = OpCompositeConstruct %6 %31 %32\n%34 = OpAccessChain %23 %14 %21 %22\nOpStore %34 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-half2.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    u16vec2 _m0[];\n} _20[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _22_25\n{\n    u16vec2 _m0[];\n} _25[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _32 = registers._m4 + 1u;\n    uvec2 _40 = _13._m0[subgroupBroadcastFirst(_32)] >> uvec2(2u);\n    uvec2 _50 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(2u);\n    f16vec2 _69 = uint16BitsToFloat16(_20[registers._m4]._m0[(gl_GlobalInvocationID.x < _50.y) ? (gl_GlobalInvocationID.x + _50.x) : 1073741823u]);\n    _25[_32]._m0[(gl_GlobalInvocationID.x < _40.y) ? (gl_GlobalInvocationID.x + _40.x) : 1073741823u] = u16vec2(float16BitsToUint16(_69.x), float16BitsToUint16(_69.y));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 83\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability GroupNonUniformBallot\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %53\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %17 \"SSBO\"\nOpName %22 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 ArrayStride 4\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %20 DescriptorSet 4\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %21 ArrayStride 4\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %25 DescriptorSet 4\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %53 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeVector %14 2\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %15\n%22 = OpTypeStruct %21\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypePointer StorageBuffer %22\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 4\n%33 = OpConstant %5 1\n%35 = OpConstant %5 3\n%36 = OpTypePointer StorageBuffer %9\n%38 = OpConstant %5 0\n%41 = OpConstant %5 2\n%42 = OpConstantComposite %9 %41 %41\n%43 = OpTypePointer StorageBuffer %17\n%51 = OpTypeVector %5 3\n%52 = OpTypePointer Input %51\n%53 = OpVariable %52 Input\n%54 = OpTypePointer Input %5\n%60 = OpTypeBool\n%63 = OpConstant %5 1073741823\n%64 = OpTypePointer StorageBuffer %15\n%67 = OpTypeFloat 16\n%68 = OpTypeVector %67 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %81\n%81 = OpLabel\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%32 = OpIAdd %5 %31 %33\n%27 = OpAccessChain %26 %25 %32\n%34 = OpGroupNonUniformBroadcastFirst %5 %35 %32\n%37 = OpAccessChain %36 %13 %38 %34\n%39 = OpLoad %9 %37\n%40 = OpShiftRightLogical %9 %39 %42\n%45 = OpAccessChain %28 %8 %30\n%46 = OpLoad %5 %45\n%44 = OpAccessChain %43 %20 %46\n%47 = OpGroupNonUniformBroadcastFirst %5 %35 %46\n%48 = OpAccessChain %36 %13 %38 %47\n%49 = OpLoad %9 %48\n%50 = OpShiftRightLogical %9 %49 %42\n%55 = OpAccessChain %54 %53 %38\n%56 = OpLoad %5 %55\n%57 = OpCompositeExtract %5 %50 0\n%58 = OpCompositeExtract %5 %50 1\n%59 = OpIAdd %5 %56 %57\n%61 = OpULessThan %60 %56 %58\n%62 = OpSelect %5 %61 %59 %63\n%65 = OpAccessChain %64 %44 %38 %62\n%66 = OpLoad %15 %65\n%69 = OpBitcast %68 %66\n%70 = OpCompositeExtract %67 %69 0\n%71 = OpCompositeExtract %67 %69 1\n%72 = OpCompositeExtract %5 %40 0\n%73 = OpCompositeExtract %5 %40 1\n%74 = OpIAdd %5 %56 %72\n%75 = OpULessThan %60 %56 %73\n%76 = OpSelect %5 %75 %74 %63\n%77 = OpBitcast %14 %70\n%78 = OpBitcast %14 %71\n%79 = OpCompositeConstruct %15 %77 %78\n%80 = OpAccessChain %64 %27 %38 %76\nOpStore %80 %79\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-half3.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_scalar_block_layout : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, scalar) readonly buffer SSBO\n{\n    u16vec3 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, scalar) writeonly buffer _12_14\n{\n    u16vec3 _m0[];\n} _14;\n\nvoid main()\n{\n    f16vec3 _28 = uint16BitsToFloat16(_10._m0[gl_GlobalInvocationID.x]);\n    _14._m0[gl_GlobalInvocationID.x] = u16vec3(float16BitsToUint16(_28.x), float16BitsToUint16(_28.y), float16BitsToUint16(_28.z));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 6\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 6\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 16 0\n%6 = OpTypeVector %5 3\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 32 0\n%16 = OpTypeVector %15 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %15\n%21 = OpConstant %15 0\n%23 = OpTypePointer StorageBuffer %6\n%26 = OpTypeFloat 16\n%27 = OpTypeVector %26 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %15 %20\n%24 = OpAccessChain %23 %10 %21 %22\n%25 = OpLoad %6 %24\n%28 = OpBitcast %27 %25\n%29 = OpCompositeExtract %26 %28 0\n%30 = OpCompositeExtract %26 %28 1\n%31 = OpCompositeExtract %26 %28 2\n%32 = OpBitcast %5 %29\n%33 = OpBitcast %5 %30\n%34 = OpBitcast %5 %31\n%35 = OpCompositeConstruct %6 %32 %33 %34\n%36 = OpAccessChain %23 %14 %21 %22\nOpStore %36 %35\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-half3.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    uint16_t _m0[];\n} _19[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _21_24\n{\n    uint16_t _m0[];\n} _24[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _31 = registers._m4 + 1u;\n    uvec2 _39 = _13._m0[subgroupBroadcastFirst(_31)] >> uvec2(1u);\n    uvec2 _48 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(1u);\n    uint _55 = gl_GlobalInvocationID.x * 3u;\n    uint _61 = (_55 < _48.y) ? (_55 + _48.x) : 2147483644u;\n    uint16_t _65 = _19[registers._m4]._m0[_61];\n    uint16_t _68 = _19[registers._m4]._m0[_61 + 1u];\n    uint16_t _72 = _19[registers._m4]._m0[_61 + 2u];\n    f16vec3 _77 = uint16BitsToFloat16(u16vec3(_65, _68, _72));\n    uint _81 = gl_GlobalInvocationID.x * 3u;\n    uint _86 = (_81 < _39.y) ? (_81 + _39.x) : 2147483644u;\n    _24[_31]._m0[_86] = float16BitsToUint16(_77.x);\n    _24[_31]._m0[_86 + 1u] = float16BitsToUint16(_77.y);\n    _24[_31]._m0[_86 + 2u] = float16BitsToUint16(_77.z);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 97\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability GroupNonUniformBallot\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %51\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %15 ArrayStride 2\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 4\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %20 ArrayStride 2\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 4\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\nOpDecorate %51 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %14\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypePointer StorageBuffer %21\n%27 = OpTypePointer PushConstant %5\n%29 = OpConstant %5 4\n%32 = OpConstant %5 1\n%34 = OpConstant %5 3\n%35 = OpTypePointer StorageBuffer %9\n%37 = OpConstant %5 0\n%40 = OpConstantComposite %9 %32 %32\n%41 = OpTypePointer StorageBuffer %16\n%49 = OpTypeVector %5 3\n%50 = OpTypePointer Input %49\n%51 = OpVariable %50 Input\n%52 = OpTypePointer Input %5\n%59 = OpTypeBool\n%62 = OpConstant %5 2147483644\n%63 = OpTypePointer StorageBuffer %14\n%71 = OpConstant %5 2\n%73 = OpTypeVector %14 3\n%75 = OpTypeFloat 16\n%76 = OpTypeVector %75 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %95\n%95 = OpLabel\n%28 = OpAccessChain %27 %8 %29\n%30 = OpLoad %5 %28\n%31 = OpIAdd %5 %30 %32\n%26 = OpAccessChain %25 %24 %31\n%33 = OpGroupNonUniformBroadcastFirst %5 %34 %31\n%36 = OpAccessChain %35 %13 %37 %33\n%38 = OpLoad %9 %36\n%39 = OpShiftRightLogical %9 %38 %40\n%43 = OpAccessChain %27 %8 %29\n%44 = OpLoad %5 %43\n%42 = OpAccessChain %41 %19 %44\n%45 = OpGroupNonUniformBroadcastFirst %5 %34 %44\n%46 = OpAccessChain %35 %13 %37 %45\n%47 = OpLoad %9 %46\n%48 = OpShiftRightLogical %9 %47 %40\n%53 = OpAccessChain %52 %51 %37\n%54 = OpLoad %5 %53\n%55 = OpIMul %5 %54 %34\n%56 = OpCompositeExtract %5 %48 0\n%57 = OpCompositeExtract %5 %48 1\n%58 = OpIAdd %5 %55 %56\n%60 = OpULessThan %59 %55 %57\n%61 = OpSelect %5 %60 %58 %62\n%64 = OpAccessChain %63 %42 %37 %61\n%65 = OpLoad %14 %64\n%67 = OpIAdd %5 %61 %32\n%66 = OpAccessChain %63 %42 %37 %67\n%68 = OpLoad %14 %66\n%70 = OpIAdd %5 %61 %71\n%69 = OpAccessChain %63 %42 %37 %70\n%72 = OpLoad %14 %69\n%74 = OpCompositeConstruct %73 %65 %68 %72\n%77 = OpBitcast %76 %74\n%78 = OpCompositeExtract %75 %77 0\n%79 = OpCompositeExtract %75 %77 1\n%80 = OpCompositeExtract %75 %77 2\n%81 = OpIMul %5 %54 %34\n%82 = OpCompositeExtract %5 %39 0\n%83 = OpCompositeExtract %5 %39 1\n%84 = OpIAdd %5 %81 %82\n%85 = OpULessThan %59 %81 %83\n%86 = OpSelect %5 %85 %84 %62\n%87 = OpBitcast %14 %78\n%88 = OpBitcast %14 %79\n%89 = OpBitcast %14 %80\n%90 = OpAccessChain %63 %26 %37 %86\nOpStore %90 %87\n%92 = OpIAdd %5 %86 %32\n%91 = OpAccessChain %63 %26 %37 %92\nOpStore %91 %88\n%94 = OpIAdd %5 %86 %71\n%93 = OpAccessChain %63 %26 %37 %94\nOpStore %93 %89\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-half4.ssbo.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    u16vec4 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) writeonly buffer _12_14\n{\n    u16vec4 _m0[];\n} _14;\n\nvoid main()\n{\n    f16vec4 _28 = uint16BitsToFloat16(_10._m0[gl_GlobalInvocationID.x]);\n    _14._m0[gl_GlobalInvocationID.x] = u16vec4(float16BitsToUint16(_28.x), float16BitsToUint16(_28.y), float16BitsToUint16(_28.z), float16BitsToUint16(_28.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 41\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint GLCompute %3 \"main\" %18\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %12 \"SSBO\"\nOpDecorate %7 ArrayStride 8\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %10 DescriptorSet 0\nOpDecorate %10 Binding 0\nOpDecorate %10 NonWritable\nOpDecorate %11 ArrayStride 8\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonReadable\nOpDecorate %18 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 16 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypePointer StorageBuffer %8\n%10 = OpVariable %9 StorageBuffer\n%11 = OpTypeRuntimeArray %6\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeInt 32 0\n%16 = OpTypeVector %15 3\n%17 = OpTypePointer Input %16\n%18 = OpVariable %17 Input\n%19 = OpTypePointer Input %15\n%21 = OpConstant %15 0\n%23 = OpTypePointer StorageBuffer %6\n%26 = OpTypeFloat 16\n%27 = OpTypeVector %26 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %39\n%39 = OpLabel\n%20 = OpAccessChain %19 %18 %21\n%22 = OpLoad %15 %20\n%24 = OpAccessChain %23 %10 %21 %22\n%25 = OpLoad %6 %24\n%28 = OpBitcast %27 %25\n%29 = OpCompositeExtract %26 %28 0\n%30 = OpCompositeExtract %26 %28 1\n%31 = OpCompositeExtract %26 %28 2\n%32 = OpCompositeExtract %26 %28 3\n%33 = OpBitcast %5 %29\n%34 = OpBitcast %5 %30\n%35 = OpBitcast %5 %31\n%36 = OpBitcast %5 %32\n%37 = OpCompositeConstruct %6 %33 %34 %35 %36\n%38 = OpAccessChain %23 %14 %21 %22\nOpStore %38 %37\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vectorization/copy-half4.ssbo.ssbo-align.bindless.comp",
    "content": "#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 15, binding = 0, std430) restrict readonly buffer SSBO_Offsets\n{\n    uvec2 _m0[];\n} _13;\n\nlayout(set = 4, binding = 0, std430) readonly buffer SSBO\n{\n    u16vec4 _m0[];\n} _20[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _22_25\n{\n    u16vec4 _m0[];\n} _25[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _32 = registers._m4 + 1u;\n    uvec2 _40 = _13._m0[subgroupBroadcastFirst(_32)] >> uvec2(3u);\n    uvec2 _49 = _13._m0[subgroupBroadcastFirst(registers._m4)] >> uvec2(3u);\n    f16vec4 _68 = uint16BitsToFloat16(_20[registers._m4]._m0[(gl_GlobalInvocationID.x < _49.y) ? (gl_GlobalInvocationID.x + _49.x) : 536870911u]);\n    _25[_32]._m0[(gl_GlobalInvocationID.x < _40.y) ? (gl_GlobalInvocationID.x + _40.x) : 536870911u] = u16vec4(float16BitsToUint16(_68.x), float16BitsToUint16(_68.y), float16BitsToUint16(_68.z), float16BitsToUint16(_68.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 86\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability GroupNonUniformBallot\nOpCapability StorageBuffer16BitAccess\nOpCapability DenormPreserve\nOpCapability RuntimeDescriptorArray\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_float_controls\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 GLSL450\nOpEntryPoint GLCompute %3 \"main\" %52\nOpExecutionMode %3 LocalSize 2 1 1\nOpExecutionMode %3 DenormPreserve 16\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO_Offsets\"\nOpName %17 \"SSBO\"\nOpName %22 \"SSBO\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 8\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %13 DescriptorSet 15\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %16 ArrayStride 8\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %20 DescriptorSet 4\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %21 ArrayStride 8\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %25 DescriptorSet 4\nOpDecorate %25 Binding 0\nOpDecorate %25 NonReadable\nOpDecorate %52 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 2\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeInt 16 0\n%15 = OpTypeVector %14 4\n%16 = OpTypeRuntimeArray %15\n%17 = OpTypeStruct %16\n%18 = OpTypeRuntimeArray %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %15\n%22 = OpTypeStruct %21\n%23 = OpTypeRuntimeArray %22\n%24 = OpTypePointer StorageBuffer %23\n%25 = OpVariable %24 StorageBuffer\n%26 = OpTypePointer StorageBuffer %22\n%28 = OpTypePointer PushConstant %5\n%30 = OpConstant %5 4\n%33 = OpConstant %5 1\n%35 = OpConstant %5 3\n%36 = OpTypePointer StorageBuffer %9\n%38 = OpConstant %5 0\n%41 = OpConstantComposite %9 %35 %35\n%42 = OpTypePointer StorageBuffer %17\n%50 = OpTypeVector %5 3\n%51 = OpTypePointer Input %50\n%52 = OpVariable %51 Input\n%53 = OpTypePointer Input %5\n%59 = OpTypeBool\n%62 = OpConstant %5 536870911\n%63 = OpTypePointer StorageBuffer %15\n%66 = OpTypeFloat 16\n%67 = OpTypeVector %66 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %84\n%84 = OpLabel\n%29 = OpAccessChain %28 %8 %30\n%31 = OpLoad %5 %29\n%32 = OpIAdd %5 %31 %33\n%27 = OpAccessChain %26 %25 %32\n%34 = OpGroupNonUniformBroadcastFirst %5 %35 %32\n%37 = OpAccessChain %36 %13 %38 %34\n%39 = OpLoad %9 %37\n%40 = OpShiftRightLogical %9 %39 %41\n%44 = OpAccessChain %28 %8 %30\n%45 = OpLoad %5 %44\n%43 = OpAccessChain %42 %20 %45\n%46 = OpGroupNonUniformBroadcastFirst %5 %35 %45\n%47 = OpAccessChain %36 %13 %38 %46\n%48 = OpLoad %9 %47\n%49 = OpShiftRightLogical %9 %48 %41\n%54 = OpAccessChain %53 %52 %38\n%55 = OpLoad %5 %54\n%56 = OpCompositeExtract %5 %49 0\n%57 = OpCompositeExtract %5 %49 1\n%58 = OpIAdd %5 %55 %56\n%60 = OpULessThan %59 %55 %57\n%61 = OpSelect %5 %60 %58 %62\n%64 = OpAccessChain %63 %43 %38 %61\n%65 = OpLoad %15 %64\n%68 = OpBitcast %67 %65\n%69 = OpCompositeExtract %66 %68 0\n%70 = OpCompositeExtract %66 %68 1\n%71 = OpCompositeExtract %66 %68 2\n%72 = OpCompositeExtract %66 %68 3\n%73 = OpCompositeExtract %5 %40 0\n%74 = OpCompositeExtract %5 %40 1\n%75 = OpIAdd %5 %55 %73\n%76 = OpULessThan %59 %55 %74\n%77 = OpSelect %5 %76 %75 %62\n%78 = OpBitcast %14 %69\n%79 = OpBitcast %14 %70\n%80 = OpBitcast %14 %71\n%81 = OpBitcast %14 %72\n%82 = OpCompositeConstruct %15 %78 %79 %80 %81\n%83 = OpAccessChain %63 %27 %38 %77\nOpStore %83 %82\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/geom/basic.view-instancing.last-pre-raster.geom",
    "content": "#version 460\nlayout(triangles) in;\nlayout(max_vertices = 1, points) out;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 57\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15 %54\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 1\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpName %45 \"ViewInstancingOffsetsUBO\"\nOpMemberName %45 0 \"ViewID_Layer\"\nOpName %47 \"ViewInstancingOffsets\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\nOpDecorate %45 Block\nOpMemberDecorate %45 0 Offset 0\nOpDecorate %47 DescriptorSet 10\nOpDecorate %47 Binding 22\nOpDecorate %54 BuiltIn Layer\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%36 = OpTypePointer Output %5\n%45 = OpTypeStruct %7\n%46 = OpTypePointer Uniform %45\n%47 = OpVariable %46 Uniform\n%48 = OpTypePointer Uniform %7\n%52 = OpConstant %7 16\n%53 = OpTypePointer Output %7\n%54 = OpVariable %53 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %55\n%55 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %8\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %16 %12 %21 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %21 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %21 %24\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %21 %8\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %21\nOpStore %38 %22\n%39 = OpAccessChain %36 %14 %24\nOpStore %39 %25\n%40 = OpAccessChain %36 %14 %8\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %21\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %24\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %8\nOpStore %44 %35\n%49 = OpAccessChain %48 %47 %18\n%50 = OpLoad %7 %49\n%51 = OpBitFieldUExtract %7 %50 %52 %52\nOpStore %54 %51\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/geom/basic.view-instancing.last-pre-raster.view-instance-mask.geom",
    "content": "#version 460\nlayout(triangles) in;\nlayout(max_vertices = 1, points) out;\n\nlayout(set = 10, binding = 23, std140) uniform ViewInstanceMaskUBO\n{\n    uint Mask;\n} ViewInstanceMask;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    if (bitfieldExtract(ViewInstanceMask.Mask, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u))), int(1u)) == 0u)\n    {\n        return;\n    }\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15 %65\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 1\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpName %16 \"ViewInstanceMaskUBO\"\nOpMemberName %16 0 \"Mask\"\nOpName %18 \"ViewInstanceMask\"\nOpName %19 \"ViewInstancingOffsetsUBO\"\nOpMemberName %19 0 \"ViewID_Layer\"\nOpName %21 \"ViewInstancingOffsets\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\nOpDecorate %16 Block\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %18 DescriptorSet 10\nOpDecorate %18 Binding 23\nOpDecorate %19 Block\nOpMemberDecorate %19 0 Offset 0\nOpDecorate %21 DescriptorSet 10\nOpDecorate %21 Binding 22\nOpDecorate %65 BuiltIn Layer\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypeStruct %7\n%17 = OpTypePointer Uniform %16\n%18 = OpVariable %17 Uniform\n%19 = OpTypeStruct %7\n%20 = OpTypePointer Uniform %19\n%21 = OpVariable %20 Uniform\n%22 = OpTypePointer Uniform %7\n%24 = OpConstant %7 0\n%27 = OpConstant %7 16\n%31 = OpConstant %7 1\n%32 = OpTypeBool\n%34 = OpTypePointer Input %5\n%40 = OpConstant %7 2\n%52 = OpTypePointer Output %5\n%64 = OpTypePointer Output %7\n%65 = OpVariable %64 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %66\n%66 = OpLabel\n%23 = OpAccessChain %22 %21 %24\n%25 = OpLoad %7 %23\n%26 = OpBitFieldUExtract %7 %25 %24 %27\n%28 = OpAccessChain %22 %18 %24\n%29 = OpLoad %7 %28\n%30 = OpBitFieldUExtract %7 %29 %26 %31\n%33 = OpIEqual %32 %30 %24\nOpSelectionMerge %68 None\nOpBranchConditional %33 %67 %68\n%67 = OpLabel\nOpReturn\n%68 = OpLabel\n%35 = OpAccessChain %34 %11 %24 %24\n%36 = OpLoad %5 %35\n%37 = OpAccessChain %34 %11 %24 %31\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %34 %11 %24 %40\n%41 = OpLoad %5 %39\n%42 = OpAccessChain %34 %11 %24 %8\n%43 = OpLoad %5 %42\n%44 = OpAccessChain %34 %12 %31 %24\n%45 = OpLoad %5 %44\n%46 = OpAccessChain %34 %12 %31 %31\n%47 = OpLoad %5 %46\n%48 = OpAccessChain %34 %12 %31 %40\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %34 %12 %31 %8\n%51 = OpLoad %5 %50\n%53 = OpAccessChain %52 %14 %24\nOpStore %53 %36\n%54 = OpAccessChain %52 %14 %31\nOpStore %54 %38\n%55 = OpAccessChain %52 %14 %40\nOpStore %55 %41\n%56 = OpAccessChain %52 %14 %8\nOpStore %56 %43\n%57 = OpAccessChain %52 %15 %24\nOpStore %57 %45\n%58 = OpAccessChain %52 %15 %31\nOpStore %58 %47\n%59 = OpAccessChain %52 %15 %40\nOpStore %59 %49\n%60 = OpAccessChain %52 %15 %8\nOpStore %60 %51\n%61 = OpAccessChain %22 %21 %24\n%62 = OpLoad %7 %61\n%63 = OpBitFieldUExtract %7 %62 %27 %27\nOpStore %65 %63\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/geom/basic.view-instancing.view-instancing-multiview.last-pre-raster.geom",
    "content": "#version 460\n#extension GL_EXT_multiview : require\nlayout(triangles) in;\nlayout(max_vertices = 2, points) out;\n\nlayout(constant_id = 1000) const uint ViewIndexToViewInstanceMap = 0u;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    float _34 = float(bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u)));\n    float _35 = TEXCOORD[0u].x + _34;\n    float _36 = TEXCOORD[0u].y + _34;\n    float _37 = TEXCOORD[0u].z + _34;\n    float _38 = TEXCOORD[0u].w + _34;\n    TEXCOORD_1.x = _35;\n    TEXCOORD_1.y = _36;\n    TEXCOORD_1.z = _37;\n    TEXCOORD_1.w = _38;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n    TEXCOORD_1.x = _35;\n    TEXCOORD_1.y = _36;\n    TEXCOORD_1.z = _37;\n    TEXCOORD_1.w = _38;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n// MultiviewCompatible\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiView\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15 %18\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 2\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpName %16 \"ViewIndexToViewInstanceMap\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\nOpDecorate %16 SpecId 1000\nOpDecorate %18 BuiltIn ViewIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpSpecConstant %7 0\n%17 = OpTypePointer Input %7\n%18 = OpVariable %17 Input\n%21 = OpConstant %7 2\n%23 = OpTypePointer Input %5\n%25 = OpConstant %7 0\n%28 = OpConstant %7 1\n%47 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%19 = OpLoad %7 %18\n%20 = OpIMul %7 %19 %21\n%22 = OpBitFieldUExtract %7 %16 %20 %21\n%24 = OpAccessChain %23 %11 %25 %25\n%26 = OpLoad %5 %24\n%27 = OpAccessChain %23 %11 %25 %28\n%29 = OpLoad %5 %27\n%30 = OpAccessChain %23 %11 %25 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %23 %11 %25 %8\n%33 = OpLoad %5 %32\n%34 = OpConvertUToF %5 %22\n%35 = OpFAdd %5 %26 %34\n%36 = OpFAdd %5 %29 %34\n%37 = OpFAdd %5 %31 %34\n%38 = OpFAdd %5 %33 %34\n%39 = OpAccessChain %23 %12 %28 %25\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %23 %12 %28 %28\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %23 %12 %28 %21\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %23 %12 %28 %8\n%46 = OpLoad %5 %45\n%48 = OpAccessChain %47 %14 %25\nOpStore %48 %35\n%49 = OpAccessChain %47 %14 %28\nOpStore %49 %36\n%50 = OpAccessChain %47 %14 %21\nOpStore %50 %37\n%51 = OpAccessChain %47 %14 %8\nOpStore %51 %38\n%52 = OpAccessChain %47 %15 %25\nOpStore %52 %40\n%53 = OpAccessChain %47 %15 %28\nOpStore %53 %42\n%54 = OpAccessChain %47 %15 %21\nOpStore %54 %44\n%55 = OpAccessChain %47 %15 %8\nOpStore %55 %46\nOpEmitVertex\n%56 = OpAccessChain %47 %14 %25\nOpStore %56 %35\n%57 = OpAccessChain %47 %14 %28\nOpStore %57 %36\n%58 = OpAccessChain %47 %14 %21\nOpStore %58 %37\n%59 = OpAccessChain %47 %14 %8\nOpStore %59 %38\n%60 = OpAccessChain %47 %15 %25\nOpStore %60 %40\n%61 = OpAccessChain %47 %15 %28\nOpStore %61 %42\n%62 = OpAccessChain %47 %15 %21\nOpStore %62 %44\n%63 = OpAccessChain %47 %15 %8\nOpStore %63 %46\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/geom/basic.view-instancing.view-instancing-multiview.view-instancing-viewport-offset.last-pre-raster.geom",
    "content": "#version 460\n#extension GL_EXT_multiview : require\nlayout(triangles) in;\nlayout(max_vertices = 2, points) out;\n\nlayout(constant_id = 1000) const uint ViewIndexToViewInstanceMap = 0u;\nlayout(constant_id = 1001) const uint ViewIDToViewport = 0u;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    gl_ViewportIndex = int(bitfieldExtract(ViewIDToViewport, int(bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u)) * 8u), int(8u)));\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    gl_ViewportIndex = int(bitfieldExtract(ViewIDToViewport, int(bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u)) * 8u), int(8u)));\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n// MultiviewCompatible\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability MultiView\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15 %47 %56\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 2\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpName %45 \"ViewIndexToViewInstanceMap\"\nOpName %51 \"ViewIDToViewport\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\nOpDecorate %45 SpecId 1000\nOpDecorate %47 BuiltIn ViewIndex\nOpDecorate %51 SpecId 1001\nOpDecorate %56 BuiltIn ViewportIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%36 = OpTypePointer Output %5\n%45 = OpSpecConstant %7 0\n%46 = OpTypePointer Input %7\n%47 = OpVariable %46 Input\n%51 = OpSpecConstant %7 0\n%53 = OpConstant %7 8\n%55 = OpTypePointer Output %7\n%56 = OpVariable %55 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %70\n%70 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %8\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %16 %12 %21 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %21 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %21 %24\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %21 %8\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %21\nOpStore %38 %22\n%39 = OpAccessChain %36 %14 %24\nOpStore %39 %25\n%40 = OpAccessChain %36 %14 %8\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %21\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %24\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %8\nOpStore %44 %35\n%48 = OpLoad %7 %47\n%49 = OpIMul %7 %48 %24\n%50 = OpBitFieldUExtract %7 %45 %49 %24\n%52 = OpIMul %7 %50 %53\n%54 = OpBitFieldUExtract %7 %51 %52 %53\nOpStore %56 %54\nOpEmitVertex\n%57 = OpAccessChain %36 %14 %18\nOpStore %57 %19\n%58 = OpAccessChain %36 %14 %21\nOpStore %58 %22\n%59 = OpAccessChain %36 %14 %24\nOpStore %59 %25\n%60 = OpAccessChain %36 %14 %8\nOpStore %60 %27\n%61 = OpAccessChain %36 %15 %18\nOpStore %61 %29\n%62 = OpAccessChain %36 %15 %21\nOpStore %62 %31\n%63 = OpAccessChain %36 %15 %24\nOpStore %63 %33\n%64 = OpAccessChain %36 %15 %8\nOpStore %64 %35\n%65 = OpLoad %7 %47\n%66 = OpIMul %7 %65 %24\n%67 = OpBitFieldUExtract %7 %45 %66 %24\n%68 = OpIMul %7 %67 %53\n%69 = OpBitFieldUExtract %7 %51 %68 %53\nOpStore %56 %69\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/geom/basic.view-instancing.view-instancing-viewport-offset.last-pre-raster.geom",
    "content": "#version 460\nlayout(triangles) in;\nlayout(max_vertices = 2, points) out;\n\nlayout(constant_id = 1001) const uint ViewIDToViewport = 0u;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in vec4 TEXCOORD[3];\nlayout(location = 0) out vec4 TEXCOORD_1;\n\nvoid main()\n{\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    gl_ViewportIndex = int(bitfieldExtract(ViewIDToViewport, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)) * 8u), int(8u)));\n    EmitVertex();\n    TEXCOORD_1.x = TEXCOORD[0u].x;\n    TEXCOORD_1.y = TEXCOORD[0u].y;\n    TEXCOORD_1.z = TEXCOORD[0u].z;\n    TEXCOORD_1.w = TEXCOORD[0u].w;\n    gl_Position.x = gl_in[1u].gl_Position.x;\n    gl_Position.y = gl_in[1u].gl_Position.y;\n    gl_Position.z = gl_in[1u].gl_Position.z;\n    gl_Position.w = gl_in[1u].gl_Position.w;\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    gl_ViewportIndex = int(bitfieldExtract(ViewIDToViewport, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)) * 8u), int(8u)));\n    EmitVertex();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 81\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpMemoryModel Logical GLSL450\nOpEntryPoint Geometry %3 \"main\" %11 %12 %14 %15 %54 %62\nOpExecutionMode %3 Invocations 1\nOpExecutionMode %3 OutputVertices 2\nOpExecutionMode %3 Triangles\nOpExecutionMode %3 OutputPoints\nOpName %3 \"main\"\nOpName %11 \"TEXCOORD\"\nOpName %12 \"SV_Position\"\nOpName %14 \"TEXCOORD\"\nOpName %15 \"SV_Position\"\nOpName %45 \"ViewInstancingOffsetsUBO\"\nOpMemberName %45 0 \"ViewID_Layer\"\nOpName %47 \"ViewInstancingOffsets\"\nOpName %58 \"ViewIDToViewport\"\nOpDecorate %11 Location 0\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 Location 0\nOpDecorate %15 BuiltIn Position\nOpDecorate %45 Block\nOpMemberDecorate %45 0 Offset 0\nOpDecorate %47 DescriptorSet 10\nOpDecorate %47 Binding 22\nOpDecorate %54 BuiltIn Layer\nOpDecorate %58 SpecId 1001\nOpDecorate %62 BuiltIn ViewportIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 3\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpVariable %10 Input\n%13 = OpTypePointer Output %6\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%16 = OpTypePointer Input %5\n%18 = OpConstant %7 0\n%21 = OpConstant %7 1\n%24 = OpConstant %7 2\n%36 = OpTypePointer Output %5\n%45 = OpTypeStruct %7\n%46 = OpTypePointer Uniform %45\n%47 = OpVariable %46 Uniform\n%48 = OpTypePointer Uniform %7\n%52 = OpConstant %7 16\n%53 = OpTypePointer Output %7\n%54 = OpVariable %53 Output\n%58 = OpSpecConstant %7 0\n%60 = OpConstant %7 8\n%62 = OpVariable %53 Output\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %79\n%79 = OpLabel\n%17 = OpAccessChain %16 %11 %18 %18\n%19 = OpLoad %5 %17\n%20 = OpAccessChain %16 %11 %18 %21\n%22 = OpLoad %5 %20\n%23 = OpAccessChain %16 %11 %18 %24\n%25 = OpLoad %5 %23\n%26 = OpAccessChain %16 %11 %18 %8\n%27 = OpLoad %5 %26\n%28 = OpAccessChain %16 %12 %21 %18\n%29 = OpLoad %5 %28\n%30 = OpAccessChain %16 %12 %21 %21\n%31 = OpLoad %5 %30\n%32 = OpAccessChain %16 %12 %21 %24\n%33 = OpLoad %5 %32\n%34 = OpAccessChain %16 %12 %21 %8\n%35 = OpLoad %5 %34\n%37 = OpAccessChain %36 %14 %18\nOpStore %37 %19\n%38 = OpAccessChain %36 %14 %21\nOpStore %38 %22\n%39 = OpAccessChain %36 %14 %24\nOpStore %39 %25\n%40 = OpAccessChain %36 %14 %8\nOpStore %40 %27\n%41 = OpAccessChain %36 %15 %18\nOpStore %41 %29\n%42 = OpAccessChain %36 %15 %21\nOpStore %42 %31\n%43 = OpAccessChain %36 %15 %24\nOpStore %43 %33\n%44 = OpAccessChain %36 %15 %8\nOpStore %44 %35\n%49 = OpAccessChain %48 %47 %18\n%50 = OpLoad %7 %49\n%51 = OpBitFieldUExtract %7 %50 %52 %52\nOpStore %54 %51\n%55 = OpAccessChain %48 %47 %18\n%56 = OpLoad %7 %55\n%57 = OpBitFieldUExtract %7 %56 %18 %52\n%59 = OpIMul %7 %57 %60\n%61 = OpBitFieldUExtract %7 %58 %59 %60\nOpStore %62 %61\nOpEmitVertex\n%63 = OpAccessChain %36 %14 %18\nOpStore %63 %19\n%64 = OpAccessChain %36 %14 %21\nOpStore %64 %22\n%65 = OpAccessChain %36 %14 %24\nOpStore %65 %25\n%66 = OpAccessChain %36 %14 %8\nOpStore %66 %27\n%67 = OpAccessChain %36 %15 %18\nOpStore %67 %29\n%68 = OpAccessChain %36 %15 %21\nOpStore %68 %31\n%69 = OpAccessChain %36 %15 %24\nOpStore %69 %33\n%70 = OpAccessChain %36 %15 %8\nOpStore %70 %35\n%71 = OpAccessChain %48 %47 %18\n%72 = OpLoad %7 %71\n%73 = OpBitFieldUExtract %7 %72 %52 %52\nOpStore %54 %73\n%74 = OpAccessChain %48 %47 %18\n%75 = OpLoad %7 %74\n%76 = OpBitFieldUExtract %7 %75 %18 %52\n%77 = OpIMul %7 %76 %60\n%78 = OpBitFieldUExtract %7 %58 %77 %60\nOpStore %62 %78\nOpEmitVertex\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic-export-viewport-layer.view-instancing.last-pre-raster.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    uint _31 = bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u));\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    float _48 = float(gl_LocalInvocationIndex);\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _48;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _48;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _48;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _48;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _59 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_59, _59 + 1u, _59 + 2u);\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = int(_31 + bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_ViewportIndex = int(_31 + 1u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 80\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %18 %19 %23 %26 %34 %36\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %18 \"SV_RenderTargetArrayIndex\"\nOpName %19 \"SV_ViewportArrayIndex\"\nOpName %23 \"indices\"\nOpName %24 \"ViewInstancingOffsetsUBO\"\nOpMemberName %24 0 \"ViewID_Layer\"\nOpName %26 \"ViewInstancingOffsets\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %18 BuiltIn Layer\nOpDecorate %18 PerPrimitiveEXT\nOpDecorate %19 BuiltIn ViewportIndex\nOpDecorate %19 PerPrimitiveEXT\nOpDecorate %23 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %24 Block\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %26 DescriptorSet 10\nOpDecorate %26 Binding 22\nOpDecorate %34 BuiltIn LocalInvocationIndex\nOpDecorate %36 BuiltIn NumSubgroups\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeArray %7 %15\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpVariable %17 Output\n%20 = OpTypeVector %7 3\n%21 = OpTypeArray %20 %15\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpTypeStruct %7\n%25 = OpTypePointer Uniform %24\n%26 = OpVariable %25 Uniform\n%27 = OpTypePointer Uniform %7\n%29 = OpConstant %7 0\n%32 = OpConstant %7 16\n%33 = OpTypePointer Input %7\n%34 = OpVariable %33 Input\n%36 = OpVariable %33 Input\n%38 = OpTypeBool\n%40 = OpConstant %7 1\n%42 = OpConstant %7 3\n%49 = OpTypePointer Output %5\n%53 = OpConstant %7 2\n%63 = OpTypePointer Output %20\n%69 = OpTypePointer Output %7\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%28 = OpAccessChain %27 %26 %29\n%30 = OpLoad %7 %28\n%31 = OpBitFieldUExtract %7 %30 %29 %32\n%35 = OpLoad %7 %34\nOpSetMeshOutputsEXT %8 %15\n%37 = OpLoad %7 %36\n%39 = OpIEqual %38 %37 %40\n%41 = OpGroupNonUniformBroadcastFirst %7 %42 %8\n%43 = OpGroupNonUniformBroadcastFirst %7 %42 %15\n%44 = OpIEqual %38 %41 %29\n%45 = OpIEqual %38 %43 %29\n%46 = OpLogicalOr %38 %44 %45\n%47 = OpLogicalAnd %38 %39 %46\nOpSelectionMerge %77 None\nOpBranchConditional %47 %76 %77\n%76 = OpLabel\nOpReturn\n%77 = OpLabel\n%48 = OpConvertUToF %5 %35\n%50 = OpAccessChain %49 %11 %35 %29\nOpStore %50 %48\n%51 = OpAccessChain %49 %11 %35 %40\nOpStore %51 %48\n%52 = OpAccessChain %49 %11 %35 %53\nOpStore %52 %48\n%54 = OpAccessChain %49 %11 %35 %42\nOpStore %54 %48\n%55 = OpBitwiseXor %7 %35 %40\n%56 = OpConvertUToF %5 %55\n%57 = OpAccessChain %49 %14 %35\nOpStore %57 %56\n%58 = OpULessThan %38 %35 %15\nOpSelectionMerge %75 None\nOpBranchConditional %58 %74 %75\n%74 = OpLabel\n%59 = OpIMul %7 %35 %42\n%60 = OpIAdd %7 %59 %40\n%61 = OpIAdd %7 %59 %53\n%62 = OpCompositeConstruct %20 %59 %60 %61\n%64 = OpAccessChain %63 %23 %35\nOpStore %64 %62\n%66 = OpAccessChain %27 %26 %29\n%67 = OpLoad %7 %66\n%68 = OpBitFieldUExtract %7 %67 %32 %32\n%65 = OpIAdd %7 %31 %68\n%70 = OpAccessChain %69 %18 %35\nOpStore %70 %65\n%71 = OpIAdd %7 %31 %40\n%72 = OpAccessChain %69 %19 %35\nOpStore %72 %71\nOpBranch %75\n%75 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic-export-viewport-layer.view-instancing.last-pre-raster.view-instancing-viewport-offset.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(constant_id = 1001) const uint ViewIDToViewport = 0u;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    uint _31 = bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u));\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    float _48 = float(gl_LocalInvocationIndex);\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _48;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _48;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _48;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _48;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _59 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_59, _59 + 1u, _59 + 2u);\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = int(_31 + bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n        gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_ViewportIndex = int((_31 + 1u) + bitfieldExtract(ViewIDToViewport, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)) * 8u), int(8u)));\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %18 %19 %23 %26 %34 %36\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %18 \"SV_RenderTargetArrayIndex\"\nOpName %19 \"SV_ViewportArrayIndex\"\nOpName %23 \"indices\"\nOpName %24 \"ViewInstancingOffsetsUBO\"\nOpMemberName %24 0 \"ViewID_Layer\"\nOpName %26 \"ViewInstancingOffsets\"\nOpName %76 \"ViewIDToViewport\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %18 BuiltIn Layer\nOpDecorate %18 PerPrimitiveEXT\nOpDecorate %19 BuiltIn ViewportIndex\nOpDecorate %19 PerPrimitiveEXT\nOpDecorate %23 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %24 Block\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %26 DescriptorSet 10\nOpDecorate %26 Binding 22\nOpDecorate %34 BuiltIn LocalInvocationIndex\nOpDecorate %36 BuiltIn NumSubgroups\nOpDecorate %76 SpecId 1001\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeArray %7 %15\n%17 = OpTypePointer Output %16\n%18 = OpVariable %17 Output\n%19 = OpVariable %17 Output\n%20 = OpTypeVector %7 3\n%21 = OpTypeArray %20 %15\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%24 = OpTypeStruct %7\n%25 = OpTypePointer Uniform %24\n%26 = OpVariable %25 Uniform\n%27 = OpTypePointer Uniform %7\n%29 = OpConstant %7 0\n%32 = OpConstant %7 16\n%33 = OpTypePointer Input %7\n%34 = OpVariable %33 Input\n%36 = OpVariable %33 Input\n%38 = OpTypeBool\n%40 = OpConstant %7 1\n%42 = OpConstant %7 3\n%49 = OpTypePointer Output %5\n%53 = OpConstant %7 2\n%63 = OpTypePointer Output %20\n%69 = OpTypePointer Output %7\n%76 = OpSpecConstant %7 0\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %80\n%80 = OpLabel\n%28 = OpAccessChain %27 %26 %29\n%30 = OpLoad %7 %28\n%31 = OpBitFieldUExtract %7 %30 %29 %32\n%35 = OpLoad %7 %34\nOpSetMeshOutputsEXT %8 %15\n%37 = OpLoad %7 %36\n%39 = OpIEqual %38 %37 %40\n%41 = OpGroupNonUniformBroadcastFirst %7 %42 %8\n%43 = OpGroupNonUniformBroadcastFirst %7 %42 %15\n%44 = OpIEqual %38 %41 %29\n%45 = OpIEqual %38 %43 %29\n%46 = OpLogicalOr %38 %44 %45\n%47 = OpLogicalAnd %38 %39 %46\nOpSelectionMerge %84 None\nOpBranchConditional %47 %83 %84\n%83 = OpLabel\nOpReturn\n%84 = OpLabel\n%48 = OpConvertUToF %5 %35\n%50 = OpAccessChain %49 %11 %35 %29\nOpStore %50 %48\n%51 = OpAccessChain %49 %11 %35 %40\nOpStore %51 %48\n%52 = OpAccessChain %49 %11 %35 %53\nOpStore %52 %48\n%54 = OpAccessChain %49 %11 %35 %42\nOpStore %54 %48\n%55 = OpBitwiseXor %7 %35 %40\n%56 = OpConvertUToF %5 %55\n%57 = OpAccessChain %49 %14 %35\nOpStore %57 %56\n%58 = OpULessThan %38 %35 %15\nOpSelectionMerge %82 None\nOpBranchConditional %58 %81 %82\n%81 = OpLabel\n%59 = OpIMul %7 %35 %42\n%60 = OpIAdd %7 %59 %40\n%61 = OpIAdd %7 %59 %53\n%62 = OpCompositeConstruct %20 %59 %60 %61\n%64 = OpAccessChain %63 %23 %35\nOpStore %64 %62\n%66 = OpAccessChain %27 %26 %29\n%67 = OpLoad %7 %66\n%68 = OpBitFieldUExtract %7 %67 %32 %32\n%65 = OpIAdd %7 %31 %68\n%70 = OpAccessChain %69 %18 %35\nOpStore %70 %65\n%71 = OpIAdd %7 %31 %40\n%73 = OpAccessChain %27 %26 %29\n%74 = OpLoad %7 %73\n%75 = OpBitFieldUExtract %7 %74 %29 %32\n%77 = OpIMul %7 %75 %15\n%78 = OpBitFieldUExtract %7 %76 %77 %15\n%72 = OpIAdd %7 %71 %78\n%79 = OpAccessChain %69 %19 %35\nOpStore %79 %72\nOpBranch %82\n%82 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic-few-thread.view-instancing.last-pre-raster.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 1) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    uint _42 = bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u));\n    uint _48 = gl_LocalInvocationIndex + 0u;\n    if (_48 < 8u)\n    {\n        gl_MeshPrimitivesEXT[_48].gl_Layer = int(_42);\n    }\n    uint _52 = gl_LocalInvocationIndex + 6u;\n    if (_52 < 8u)\n    {\n        gl_MeshPrimitivesEXT[_52].gl_Layer = int(_42);\n    }\n    float _56 = float(gl_LocalInvocationIndex);\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _56;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _56;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _56;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _56;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _67 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_67, _67 + 1u, _67 + 2u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 84\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %19 %21 %23 %38 %46\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 1\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %19 \"indices\"\nOpName %36 \"ViewInstancingOffsetsUBO\"\nOpMemberName %36 0 \"ViewID_Layer\"\nOpName %38 \"ViewInstancingOffsets\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %19 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %21 BuiltIn LocalInvocationIndex\nOpDecorate %23 BuiltIn NumSubgroups\nOpDecorate %36 Block\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %38 DescriptorSet 10\nOpDecorate %38 Binding 22\nOpDecorate %46 BuiltIn Layer\nOpDecorate %46 PerPrimitiveEXT\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeVector %7 3\n%17 = OpTypeArray %16 %15\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%20 = OpTypePointer Input %7\n%21 = OpVariable %20 Input\n%23 = OpVariable %20 Input\n%25 = OpTypeBool\n%27 = OpConstant %7 1\n%29 = OpConstant %7 3\n%32 = OpConstant %7 0\n%36 = OpTypeStruct %7\n%37 = OpTypePointer Uniform %36\n%38 = OpVariable %37 Uniform\n%39 = OpTypePointer Uniform %7\n%43 = OpConstant %7 16\n%44 = OpTypeArray %7 %15\n%45 = OpTypePointer Output %44\n%46 = OpVariable %45 Output\n%50 = OpTypePointer Output %7\n%53 = OpConstant %7 6\n%57 = OpTypePointer Output %5\n%61 = OpConstant %7 2\n%71 = OpTypePointer Output %16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%22 = OpLoad %7 %21\nOpSetMeshOutputsEXT %8 %15\n%24 = OpLoad %7 %23\n%26 = OpIEqual %25 %24 %27\n%28 = OpGroupNonUniformBroadcastFirst %7 %29 %8\n%30 = OpGroupNonUniformBroadcastFirst %7 %29 %15\n%31 = OpIEqual %25 %28 %32\n%33 = OpIEqual %25 %30 %32\n%34 = OpLogicalOr %25 %31 %33\n%35 = OpLogicalAnd %25 %26 %34\nOpSelectionMerge %77 None\nOpBranchConditional %35 %76 %77\n%76 = OpLabel\nOpReturn\n%77 = OpLabel\n%40 = OpAccessChain %39 %38 %32\n%41 = OpLoad %7 %40\n%42 = OpBitFieldUExtract %7 %41 %43 %43\n%47 = OpLoad %7 %21\n%48 = OpIAdd %7 %47 %32\n%49 = OpULessThan %25 %48 %15\n%51 = OpAccessChain %50 %46 %48\nOpSelectionMerge %80 None\nOpBranchConditional %49 %79 %80\n%79 = OpLabel\nOpStore %51 %42\nOpBranch %80\n%80 = OpLabel\n%52 = OpIAdd %7 %47 %53\n%54 = OpULessThan %25 %52 %15\n%55 = OpAccessChain %50 %46 %52\nOpSelectionMerge %82 None\nOpBranchConditional %54 %81 %82\n%81 = OpLabel\nOpStore %55 %42\nOpBranch %82\n%82 = OpLabel\n%56 = OpConvertUToF %5 %22\n%58 = OpAccessChain %57 %11 %22 %32\nOpStore %58 %56\n%59 = OpAccessChain %57 %11 %22 %27\nOpStore %59 %56\n%60 = OpAccessChain %57 %11 %22 %61\nOpStore %60 %56\n%62 = OpAccessChain %57 %11 %22 %29\nOpStore %62 %56\n%63 = OpBitwiseXor %7 %22 %27\n%64 = OpConvertUToF %5 %63\n%65 = OpAccessChain %57 %14 %22\nOpStore %65 %64\n%66 = OpULessThan %25 %22 %15\nOpSelectionMerge %75 None\nOpBranchConditional %66 %74 %75\n%74 = OpLabel\n%67 = OpIMul %7 %22 %29\n%68 = OpIAdd %7 %67 %27\n%69 = OpIAdd %7 %67 %61\n%70 = OpCompositeConstruct %16 %67 %68 %69\n%72 = OpAccessChain %71 %19 %22\nOpStore %72 %70\nOpBranch %75\n%75 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic-many-thread.view-instancing.last-pre-raster.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 6) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    uint _48 = gl_LocalInvocationIndex + 0u;\n    if (_48 < 8u)\n    {\n        gl_MeshPrimitivesEXT[_48].gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    }\n    float _52 = float(gl_LocalInvocationIndex);\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _52;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _52;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _52;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _52;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _63 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_63, _63 + 1u, _63 + 2u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 78\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %19 %21 %23 %38 %46\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 6\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %19 \"indices\"\nOpName %36 \"ViewInstancingOffsetsUBO\"\nOpMemberName %36 0 \"ViewID_Layer\"\nOpName %38 \"ViewInstancingOffsets\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %19 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %21 BuiltIn LocalInvocationIndex\nOpDecorate %23 BuiltIn NumSubgroups\nOpDecorate %36 Block\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %38 DescriptorSet 10\nOpDecorate %38 Binding 22\nOpDecorate %46 BuiltIn Layer\nOpDecorate %46 PerPrimitiveEXT\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeVector %7 3\n%17 = OpTypeArray %16 %15\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%20 = OpTypePointer Input %7\n%21 = OpVariable %20 Input\n%23 = OpVariable %20 Input\n%25 = OpTypeBool\n%27 = OpConstant %7 1\n%29 = OpConstant %7 3\n%32 = OpConstant %7 0\n%36 = OpTypeStruct %7\n%37 = OpTypePointer Uniform %36\n%38 = OpVariable %37 Uniform\n%39 = OpTypePointer Uniform %7\n%43 = OpConstant %7 16\n%44 = OpTypeArray %7 %15\n%45 = OpTypePointer Output %44\n%46 = OpVariable %45 Output\n%50 = OpTypePointer Output %7\n%53 = OpTypePointer Output %5\n%57 = OpConstant %7 2\n%67 = OpTypePointer Output %16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %69\n%69 = OpLabel\n%22 = OpLoad %7 %21\nOpSetMeshOutputsEXT %8 %15\n%24 = OpLoad %7 %23\n%26 = OpIEqual %25 %24 %27\n%28 = OpGroupNonUniformBroadcastFirst %7 %29 %8\n%30 = OpGroupNonUniformBroadcastFirst %7 %29 %15\n%31 = OpIEqual %25 %28 %32\n%33 = OpIEqual %25 %30 %32\n%34 = OpLogicalOr %25 %31 %33\n%35 = OpLogicalAnd %25 %26 %34\nOpSelectionMerge %73 None\nOpBranchConditional %35 %72 %73\n%72 = OpLabel\nOpReturn\n%73 = OpLabel\n%40 = OpAccessChain %39 %38 %32\n%41 = OpLoad %7 %40\n%42 = OpBitFieldUExtract %7 %41 %43 %43\n%47 = OpLoad %7 %21\n%48 = OpIAdd %7 %47 %32\n%49 = OpULessThan %25 %48 %15\n%51 = OpAccessChain %50 %46 %48\nOpSelectionMerge %76 None\nOpBranchConditional %49 %75 %76\n%75 = OpLabel\nOpStore %51 %42\nOpBranch %76\n%76 = OpLabel\n%52 = OpConvertUToF %5 %22\n%54 = OpAccessChain %53 %11 %22 %32\nOpStore %54 %52\n%55 = OpAccessChain %53 %11 %22 %27\nOpStore %55 %52\n%56 = OpAccessChain %53 %11 %22 %57\nOpStore %56 %52\n%58 = OpAccessChain %53 %11 %22 %29\nOpStore %58 %52\n%59 = OpBitwiseXor %7 %22 %27\n%60 = OpConvertUToF %5 %59\n%61 = OpAccessChain %53 %14 %22\nOpStore %61 %60\n%62 = OpULessThan %25 %22 %15\nOpSelectionMerge %71 None\nOpBranchConditional %62 %70 %71\n%70 = OpLabel\n%63 = OpIMul %7 %22 %29\n%64 = OpIAdd %7 %63 %27\n%65 = OpIAdd %7 %63 %57\n%66 = OpCompositeConstruct %16 %63 %64 %65\n%68 = OpAccessChain %67 %19 %22\nOpStore %68 %66\nOpBranch %71\n%71 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic.view-instancing.last-pre-raster.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    uint _48 = gl_LocalInvocationIndex + 0u;\n    if (_48 < 8u)\n    {\n        gl_MeshPrimitivesEXT[_48].gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    }\n    float _52 = float(gl_LocalInvocationIndex);\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _52;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _52;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _52;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _52;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _63 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_63, _63 + 1u, _63 + 2u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 78\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %19 %21 %23 %38 %46\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %19 \"indices\"\nOpName %36 \"ViewInstancingOffsetsUBO\"\nOpMemberName %36 0 \"ViewID_Layer\"\nOpName %38 \"ViewInstancingOffsets\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %19 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %21 BuiltIn LocalInvocationIndex\nOpDecorate %23 BuiltIn NumSubgroups\nOpDecorate %36 Block\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %38 DescriptorSet 10\nOpDecorate %38 Binding 22\nOpDecorate %46 BuiltIn Layer\nOpDecorate %46 PerPrimitiveEXT\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeVector %7 3\n%17 = OpTypeArray %16 %15\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%20 = OpTypePointer Input %7\n%21 = OpVariable %20 Input\n%23 = OpVariable %20 Input\n%25 = OpTypeBool\n%27 = OpConstant %7 1\n%29 = OpConstant %7 3\n%32 = OpConstant %7 0\n%36 = OpTypeStruct %7\n%37 = OpTypePointer Uniform %36\n%38 = OpVariable %37 Uniform\n%39 = OpTypePointer Uniform %7\n%43 = OpConstant %7 16\n%44 = OpTypeArray %7 %15\n%45 = OpTypePointer Output %44\n%46 = OpVariable %45 Output\n%50 = OpTypePointer Output %7\n%53 = OpTypePointer Output %5\n%57 = OpConstant %7 2\n%67 = OpTypePointer Output %16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %69\n%69 = OpLabel\n%22 = OpLoad %7 %21\nOpSetMeshOutputsEXT %8 %15\n%24 = OpLoad %7 %23\n%26 = OpIEqual %25 %24 %27\n%28 = OpGroupNonUniformBroadcastFirst %7 %29 %8\n%30 = OpGroupNonUniformBroadcastFirst %7 %29 %15\n%31 = OpIEqual %25 %28 %32\n%33 = OpIEqual %25 %30 %32\n%34 = OpLogicalOr %25 %31 %33\n%35 = OpLogicalAnd %25 %26 %34\nOpSelectionMerge %73 None\nOpBranchConditional %35 %72 %73\n%72 = OpLabel\nOpReturn\n%73 = OpLabel\n%40 = OpAccessChain %39 %38 %32\n%41 = OpLoad %7 %40\n%42 = OpBitFieldUExtract %7 %41 %43 %43\n%47 = OpLoad %7 %21\n%48 = OpIAdd %7 %47 %32\n%49 = OpULessThan %25 %48 %15\n%51 = OpAccessChain %50 %46 %48\nOpSelectionMerge %76 None\nOpBranchConditional %49 %75 %76\n%75 = OpLabel\nOpStore %51 %42\nOpBranch %76\n%76 = OpLabel\n%52 = OpConvertUToF %5 %22\n%54 = OpAccessChain %53 %11 %22 %32\nOpStore %54 %52\n%55 = OpAccessChain %53 %11 %22 %27\nOpStore %55 %52\n%56 = OpAccessChain %53 %11 %22 %57\nOpStore %56 %52\n%58 = OpAccessChain %53 %11 %22 %29\nOpStore %58 %52\n%59 = OpBitwiseXor %7 %22 %27\n%60 = OpConvertUToF %5 %59\n%61 = OpAccessChain %53 %14 %22\nOpStore %61 %60\n%62 = OpULessThan %25 %22 %15\nOpSelectionMerge %71 None\nOpBranchConditional %62 %70 %71\n%70 = OpLabel\n%63 = OpIMul %7 %22 %29\n%64 = OpIAdd %7 %63 %27\n%65 = OpIAdd %7 %63 %57\n%66 = OpCompositeConstruct %16 %63 %64 %65\n%68 = OpAccessChain %67 %19 %22\nOpStore %68 %66\nOpBranch %71\n%71 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic.view-instancing.last-pre-raster.view-instance-mask.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(set = 10, binding = 23, std140) uniform ViewInstanceMaskUBO\n{\n    uint Mask;\n} ViewInstanceMask;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    if (bitfieldExtract(ViewInstanceMask.Mask, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u))), int(1u)) == 0u)\n    {\n        return;\n    }\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    uint _58 = gl_LocalInvocationIndex + 0u;\n    if (_58 < 8u)\n    {\n        gl_MeshPrimitivesEXT[_58].gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    }\n    float _62 = float(gl_LocalInvocationIndex);\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _62;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _62;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _62;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _62;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _73 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_73, _73 + 1u, _73 + 2u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %19 %22 %25 %39 %41 %56\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %19 \"indices\"\nOpName %20 \"ViewInstanceMaskUBO\"\nOpMemberName %20 0 \"Mask\"\nOpName %22 \"ViewInstanceMask\"\nOpName %23 \"ViewInstancingOffsetsUBO\"\nOpMemberName %23 0 \"ViewID_Layer\"\nOpName %25 \"ViewInstancingOffsets\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %19 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %20 Block\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %22 DescriptorSet 10\nOpDecorate %22 Binding 23\nOpDecorate %23 Block\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %25 DescriptorSet 10\nOpDecorate %25 Binding 22\nOpDecorate %39 BuiltIn LocalInvocationIndex\nOpDecorate %41 BuiltIn NumSubgroups\nOpDecorate %56 BuiltIn Layer\nOpDecorate %56 PerPrimitiveEXT\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeVector %7 3\n%17 = OpTypeArray %16 %15\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%20 = OpTypeStruct %7\n%21 = OpTypePointer Uniform %20\n%22 = OpVariable %21 Uniform\n%23 = OpTypeStruct %7\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypePointer Uniform %7\n%28 = OpConstant %7 0\n%31 = OpConstant %7 16\n%35 = OpConstant %7 1\n%36 = OpTypeBool\n%38 = OpTypePointer Input %7\n%39 = OpVariable %38 Input\n%41 = OpVariable %38 Input\n%45 = OpConstant %7 3\n%54 = OpTypeArray %7 %15\n%55 = OpTypePointer Output %54\n%56 = OpVariable %55 Output\n%60 = OpTypePointer Output %7\n%63 = OpTypePointer Output %5\n%67 = OpConstant %7 2\n%77 = OpTypePointer Output %16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %79\n%79 = OpLabel\n%27 = OpAccessChain %26 %25 %28\n%29 = OpLoad %7 %27\n%30 = OpBitFieldUExtract %7 %29 %28 %31\n%32 = OpAccessChain %26 %22 %28\n%33 = OpLoad %7 %32\n%34 = OpBitFieldUExtract %7 %33 %30 %35\n%37 = OpIEqual %36 %34 %28\nOpSelectionMerge %83 None\nOpBranchConditional %37 %82 %83\n%82 = OpLabel\nOpReturn\n%83 = OpLabel\n%40 = OpLoad %7 %39\nOpSetMeshOutputsEXT %8 %15\n%42 = OpLoad %7 %41\n%43 = OpIEqual %36 %42 %35\n%44 = OpGroupNonUniformBroadcastFirst %7 %45 %8\n%46 = OpGroupNonUniformBroadcastFirst %7 %45 %15\n%47 = OpIEqual %36 %44 %28\n%48 = OpIEqual %36 %46 %28\n%49 = OpLogicalOr %36 %47 %48\n%50 = OpLogicalAnd %36 %43 %49\nOpSelectionMerge %86 None\nOpBranchConditional %50 %85 %86\n%85 = OpLabel\nOpReturn\n%86 = OpLabel\n%51 = OpAccessChain %26 %25 %28\n%52 = OpLoad %7 %51\n%53 = OpBitFieldUExtract %7 %52 %31 %31\n%57 = OpLoad %7 %39\n%58 = OpIAdd %7 %57 %28\n%59 = OpULessThan %36 %58 %15\n%61 = OpAccessChain %60 %56 %58\nOpSelectionMerge %89 None\nOpBranchConditional %59 %88 %89\n%88 = OpLabel\nOpStore %61 %53\nOpBranch %89\n%89 = OpLabel\n%62 = OpConvertUToF %5 %40\n%64 = OpAccessChain %63 %11 %40 %28\nOpStore %64 %62\n%65 = OpAccessChain %63 %11 %40 %35\nOpStore %65 %62\n%66 = OpAccessChain %63 %11 %40 %67\nOpStore %66 %62\n%68 = OpAccessChain %63 %11 %40 %45\nOpStore %68 %62\n%69 = OpBitwiseXor %7 %40 %35\n%70 = OpConvertUToF %5 %69\n%71 = OpAccessChain %63 %14 %40\nOpStore %71 %70\n%72 = OpULessThan %36 %40 %15\nOpSelectionMerge %81 None\nOpBranchConditional %72 %80 %81\n%80 = OpLabel\n%73 = OpIMul %7 %40 %45\n%74 = OpIAdd %7 %73 %35\n%75 = OpIAdd %7 %73 %67\n%76 = OpCompositeConstruct %16 %73 %74 %75\n%78 = OpAccessChain %77 %19 %40\nOpStore %78 %76\nOpBranch %81\n%81 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic.view-instancing.last-pre-raster.view-instancing-viewport-offset.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(constant_id = 1001) const uint ViewIDToViewport = 0u;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    uint _48 = gl_LocalInvocationIndex + 0u;\n    if (_48 < 8u)\n    {\n        gl_MeshPrimitivesEXT[_48].gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    }\n    uint _60 = gl_LocalInvocationIndex + 0u;\n    if (_60 < 8u)\n    {\n        gl_MeshPrimitivesEXT[_60].gl_ViewportIndex = int(bitfieldExtract(ViewIDToViewport, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)) * 8u), int(8u)));\n    }\n    float _63 = float(gl_LocalInvocationIndex);\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _63;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _63;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _63;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _63;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _74 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_74, _74 + 1u, _74 + 2u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability ShaderViewportIndexLayerEXT\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %19 %21 %23 %38 %46 %58\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %19 \"indices\"\nOpName %36 \"ViewInstancingOffsetsUBO\"\nOpMemberName %36 0 \"ViewID_Layer\"\nOpName %38 \"ViewInstancingOffsets\"\nOpName %55 \"ViewIDToViewport\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %19 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %21 BuiltIn LocalInvocationIndex\nOpDecorate %23 BuiltIn NumSubgroups\nOpDecorate %36 Block\nOpMemberDecorate %36 0 Offset 0\nOpDecorate %38 DescriptorSet 10\nOpDecorate %38 Binding 22\nOpDecorate %46 BuiltIn Layer\nOpDecorate %46 PerPrimitiveEXT\nOpDecorate %55 SpecId 1001\nOpDecorate %58 BuiltIn ViewportIndex\nOpDecorate %58 PerPrimitiveEXT\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeVector %7 3\n%17 = OpTypeArray %16 %15\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%20 = OpTypePointer Input %7\n%21 = OpVariable %20 Input\n%23 = OpVariable %20 Input\n%25 = OpTypeBool\n%27 = OpConstant %7 1\n%29 = OpConstant %7 3\n%32 = OpConstant %7 0\n%36 = OpTypeStruct %7\n%37 = OpTypePointer Uniform %36\n%38 = OpVariable %37 Uniform\n%39 = OpTypePointer Uniform %7\n%43 = OpConstant %7 16\n%44 = OpTypeArray %7 %15\n%45 = OpTypePointer Output %44\n%46 = OpVariable %45 Output\n%50 = OpTypePointer Output %7\n%55 = OpSpecConstant %7 0\n%58 = OpVariable %45 Output\n%64 = OpTypePointer Output %5\n%68 = OpConstant %7 2\n%78 = OpTypePointer Output %16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %80\n%80 = OpLabel\n%22 = OpLoad %7 %21\nOpSetMeshOutputsEXT %8 %15\n%24 = OpLoad %7 %23\n%26 = OpIEqual %25 %24 %27\n%28 = OpGroupNonUniformBroadcastFirst %7 %29 %8\n%30 = OpGroupNonUniformBroadcastFirst %7 %29 %15\n%31 = OpIEqual %25 %28 %32\n%33 = OpIEqual %25 %30 %32\n%34 = OpLogicalOr %25 %31 %33\n%35 = OpLogicalAnd %25 %26 %34\nOpSelectionMerge %84 None\nOpBranchConditional %35 %83 %84\n%83 = OpLabel\nOpReturn\n%84 = OpLabel\n%40 = OpAccessChain %39 %38 %32\n%41 = OpLoad %7 %40\n%42 = OpBitFieldUExtract %7 %41 %43 %43\n%47 = OpLoad %7 %21\n%48 = OpIAdd %7 %47 %32\n%49 = OpULessThan %25 %48 %15\n%51 = OpAccessChain %50 %46 %48\nOpSelectionMerge %87 None\nOpBranchConditional %49 %86 %87\n%86 = OpLabel\nOpStore %51 %42\nOpBranch %87\n%87 = OpLabel\n%52 = OpAccessChain %39 %38 %32\n%53 = OpLoad %7 %52\n%54 = OpBitFieldUExtract %7 %53 %32 %43\n%56 = OpIMul %7 %54 %15\n%57 = OpBitFieldUExtract %7 %55 %56 %15\n%59 = OpLoad %7 %21\n%60 = OpIAdd %7 %59 %32\n%61 = OpULessThan %25 %60 %15\n%62 = OpAccessChain %50 %58 %60\nOpSelectionMerge %89 None\nOpBranchConditional %61 %88 %89\n%88 = OpLabel\nOpStore %62 %57\nOpBranch %89\n%89 = OpLabel\n%63 = OpConvertUToF %5 %22\n%65 = OpAccessChain %64 %11 %22 %32\nOpStore %65 %63\n%66 = OpAccessChain %64 %11 %22 %27\nOpStore %66 %63\n%67 = OpAccessChain %64 %11 %22 %68\nOpStore %67 %63\n%69 = OpAccessChain %64 %11 %22 %29\nOpStore %69 %63\n%70 = OpBitwiseXor %7 %22 %27\n%71 = OpConvertUToF %5 %70\n%72 = OpAccessChain %64 %14 %22\nOpStore %72 %71\n%73 = OpULessThan %25 %22 %15\nOpSelectionMerge %82 None\nOpBranchConditional %73 %81 %82\n%81 = OpLabel\n%74 = OpIMul %7 %22 %29\n%75 = OpIAdd %7 %74 %27\n%76 = OpIAdd %7 %74 %68\n%77 = OpCompositeConstruct %16 %74 %75 %76\n%79 = OpAccessChain %78 %19 %22\nOpStore %79 %77\nOpBranch %82\n%82 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/mesh/basic.view-instancing.mesh",
    "content": "#version 460\n#extension GL_EXT_mesh_shader : require\n#extension GL_KHR_shader_subgroup_basic : require\n#extension GL_KHR_shader_subgroup_ballot : require\nlayout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;\nlayout(max_vertices = 24, max_primitives = 8, triangles) out;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 1) out float B[24];\n\nvoid main()\n{\n    SetMeshOutputsEXT(24u, 8u);\n    if ((gl_NumSubgroups == 1u) && ((subgroupBroadcastFirst(24u) == 0u) || (subgroupBroadcastFirst(8u) == 0u)))\n    {\n        return;\n    }\n    float _45 = float(gl_LocalInvocationIndex + bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = _45;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = _45;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = _45;\n    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = _45;\n    B[gl_LocalInvocationIndex] = float(gl_LocalInvocationIndex ^ 1u);\n    if (gl_LocalInvocationIndex < 8u)\n    {\n        uint _56 = gl_LocalInvocationIndex * 3u;\n        gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(_56, _56 + 1u, _56 + 2u);\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.4\n; Generator: Unknown(30017); 21022\n; Bound: 69\n; Schema: 0\nOpCapability Shader\nOpCapability GroupNonUniform\nOpCapability GroupNonUniformBallot\nOpCapability MeshShadingEXT\nOpExtension \"SPV_EXT_mesh_shader\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint MeshEXT %3 \"main\" %11 %14 %19 %22 %30 %32\nOpExecutionMode %3 OutputVertices 24\nOpExecutionMode %3 OutputPrimitivesEXT 8\nOpExecutionMode %3 OutputTrianglesEXT\nOpExecutionMode %3 LocalSize 2 3 4\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpName %14 \"B\"\nOpName %19 \"indices\"\nOpName %20 \"ViewInstancingOffsetsUBO\"\nOpMemberName %20 0 \"ViewID_Layer\"\nOpName %22 \"ViewInstancingOffsets\"\nOpDecorate %11 BuiltIn Position\nOpDecorate %14 Location 1\nOpDecorate %19 BuiltIn PrimitiveTriangleIndicesEXT\nOpDecorate %20 Block\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %22 DescriptorSet 10\nOpDecorate %22 Binding 22\nOpDecorate %30 BuiltIn LocalInvocationIndex\nOpDecorate %32 BuiltIn NumSubgroups\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypeInt 32 0\n%8 = OpConstant %7 24\n%9 = OpTypeArray %6 %8\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypeArray %5 %8\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpConstant %7 8\n%16 = OpTypeVector %7 3\n%17 = OpTypeArray %16 %15\n%18 = OpTypePointer Output %17\n%19 = OpVariable %18 Output\n%20 = OpTypeStruct %7\n%21 = OpTypePointer Uniform %20\n%22 = OpVariable %21 Uniform\n%23 = OpTypePointer Uniform %7\n%25 = OpConstant %7 0\n%28 = OpConstant %7 16\n%29 = OpTypePointer Input %7\n%30 = OpVariable %29 Input\n%32 = OpVariable %29 Input\n%34 = OpTypeBool\n%36 = OpConstant %7 1\n%38 = OpConstant %7 3\n%46 = OpTypePointer Output %5\n%50 = OpConstant %7 2\n%60 = OpTypePointer Output %16\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %62\n%62 = OpLabel\n%24 = OpAccessChain %23 %22 %25\n%26 = OpLoad %7 %24\n%27 = OpBitFieldUExtract %7 %26 %25 %28\n%31 = OpLoad %7 %30\nOpSetMeshOutputsEXT %8 %15\n%33 = OpLoad %7 %32\n%35 = OpIEqual %34 %33 %36\n%37 = OpGroupNonUniformBroadcastFirst %7 %38 %8\n%39 = OpGroupNonUniformBroadcastFirst %7 %38 %15\n%40 = OpIEqual %34 %37 %25\n%41 = OpIEqual %34 %39 %25\n%42 = OpLogicalOr %34 %40 %41\n%43 = OpLogicalAnd %34 %35 %42\nOpSelectionMerge %66 None\nOpBranchConditional %43 %65 %66\n%65 = OpLabel\nOpReturn\n%66 = OpLabel\n%44 = OpIAdd %7 %31 %27\n%45 = OpConvertUToF %5 %44\n%47 = OpAccessChain %46 %11 %31 %25\nOpStore %47 %45\n%48 = OpAccessChain %46 %11 %31 %36\nOpStore %48 %45\n%49 = OpAccessChain %46 %11 %31 %50\nOpStore %49 %45\n%51 = OpAccessChain %46 %11 %31 %38\nOpStore %51 %45\n%52 = OpBitwiseXor %7 %31 %36\n%53 = OpConvertUToF %5 %52\n%54 = OpAccessChain %46 %14 %31\nOpStore %54 %53\n%55 = OpULessThan %34 %31 %15\nOpSelectionMerge %64 None\nOpBranchConditional %55 %63 %64\n%63 = OpLabel\n%56 = OpIMul %7 %31 %38\n%57 = OpIAdd %7 %56 %36\n%58 = OpIAdd %7 %56 %50\n%59 = OpCompositeConstruct %16 %56 %57 %58\n%61 = OpAccessChain %60 %19 %31\nOpStore %61 %59\nOpBranch %64\n%64 = OpLabel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tesc/basic.view-instancing.tesc",
    "content": "#version 460\nlayout(vertices = 4) out;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in float VSValue[];\nlayout(location = 0) out float HSValue[4];\nlayout(location = 1) out uint SV_RenderTargetArrayIndex[4];\nlayout(location = 1, component = 1) out uint SV_ViewportArrayIndex[4];\n\nvoid hull_main()\n{\n    uint _35 = bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u));\n    HSValue[gl_InvocationID] = float(gl_InvocationID + _35);\n    SV_RenderTargetArrayIndex[gl_InvocationID] = _35;\n    SV_ViewportArrayIndex[gl_InvocationID] = _35;\n}\n\nvoid patch_main()\n{\n    gl_TessLevelOuter[0u] = 1.0;\n    gl_TessLevelOuter[1u] = 1.0;\n    gl_TessLevelOuter[2u] = 1.0;\n    gl_TessLevelOuter[3u] = 1.0;\n    gl_TessLevelInner[0u] = 1.0;\n    gl_TessLevelInner[1u] = 1.0;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationControl %3 \"main\" %10 %14 %17 %18 %19 %23 %38\nOpExecutionMode %3 Quads\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCw\nOpExecutionMode %3 OutputVertices 4\nOpName %3 \"main\"\nOpName %10 \"VSValue\"\nOpName %14 \"HSValue\"\nOpName %17 \"SV_RenderTargetArrayIndex\"\nOpName %18 \"SV_ViewportArrayIndex\"\nOpName %19 \"SV_TessFactor\"\nOpName %23 \"SV_InsideTessFactor\"\nOpName %24 \"hull_main\"\nOpName %26 \"patch_main\"\nOpName %28 \"ViewInstancingOffsetsUBO\"\nOpMemberName %28 0 \"ViewID_Layer\"\nOpName %30 \"ViewInstancingOffsets\"\nOpDecorate %10 Location 0\nOpDecorate %14 Location 0\nOpDecorate %17 Location 1\nOpDecorate %18 Location 1\nOpDecorate %18 Component 1\nOpDecorate %19 BuiltIn TessLevelOuter\nOpDecorate %19 Patch\nOpDecorate %23 BuiltIn TessLevelInner\nOpDecorate %23 Patch\nOpDecorate %28 Block\nOpMemberDecorate %28 0 Offset 0\nOpDecorate %30 DescriptorSet 10\nOpDecorate %30 Binding 22\nOpDecorate %38 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 32\n%8 = OpTypeArray %5 %7\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpConstant %6 4\n%12 = OpTypeArray %5 %11\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpTypeArray %6 %11\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%18 = OpVariable %16 Output\n%19 = OpVariable %13 Output\n%20 = OpConstant %6 2\n%21 = OpTypeArray %5 %20\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%28 = OpTypeStruct %6\n%29 = OpTypePointer Uniform %28\n%30 = OpVariable %29 Uniform\n%31 = OpTypePointer Uniform %6\n%33 = OpConstant %6 0\n%36 = OpConstant %6 16\n%37 = OpTypePointer Input %6\n%38 = OpVariable %37 Input\n%42 = OpTypePointer Output %5\n%45 = OpTypePointer Output %6\n%51 = OpConstant %5 1\n%53 = OpConstant %6 1\n%56 = OpConstant %6 3\n%61 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %64\n%64 = OpLabel\n%59 = OpFunctionCall %1 %24\n%60 = OpLoad %6 %38\n%62 = OpIEqual %61 %60 %33\nOpControlBarrier %20 %11 %33\nOpSelectionMerge %66 None\nOpBranchConditional %62 %65 %66\n%65 = OpLabel\n%63 = OpFunctionCall %1 %26\nOpBranch %66\n%66 = OpLabel\nOpReturn\nOpFunctionEnd\n%24 = OpFunction %1 None %2\n%25 = OpLabel\nOpBranch %68\n%68 = OpLabel\n%32 = OpAccessChain %31 %30 %33\n%34 = OpLoad %6 %32\n%35 = OpBitFieldUExtract %6 %34 %33 %36\n%39 = OpLoad %6 %38\n%40 = OpIAdd %6 %39 %35\n%41 = OpConvertUToF %5 %40\n%44 = OpLoad %6 %38\n%43 = OpAccessChain %42 %14 %44\nOpStore %43 %41\n%47 = OpLoad %6 %38\n%46 = OpAccessChain %45 %17 %47\nOpStore %46 %35\n%49 = OpLoad %6 %38\n%48 = OpAccessChain %45 %18 %49\nOpStore %48 %35\nOpReturn\nOpFunctionEnd\n%26 = OpFunction %1 None %2\n%27 = OpLabel\nOpBranch %70\n%70 = OpLabel\n%50 = OpAccessChain %42 %19 %33\nOpStore %50 %51\n%52 = OpAccessChain %42 %19 %53\nOpStore %52 %51\n%54 = OpAccessChain %42 %19 %20\nOpStore %54 %51\n%55 = OpAccessChain %42 %19 %56\nOpStore %55 %51\n%57 = OpAccessChain %42 %23 %33\nOpStore %57 %51\n%58 = OpAccessChain %42 %23 %53\nOpStore %58 %51\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tesc/basic.view-instancing.view-instancing-multiview.tesc",
    "content": "#version 460\n#extension GL_EXT_multiview : require\nlayout(vertices = 4) out;\n\nlayout(constant_id = 1000) const uint ViewIndexToViewInstanceMap = 0u;\n\nlayout(location = 0) in float VSValue[];\nlayout(location = 0) out float HSValue[4];\nlayout(location = 1) out uint SV_RenderTargetArrayIndex[4];\nlayout(location = 1, component = 1) out uint SV_ViewportArrayIndex[4];\n\nvoid hull_main()\n{\n    uint _33 = bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u));\n    HSValue[gl_InvocationID] = float(gl_InvocationID + _33);\n    SV_RenderTargetArrayIndex[gl_InvocationID] = _33;\n    SV_ViewportArrayIndex[gl_InvocationID] = _33;\n}\n\nvoid patch_main()\n{\n    gl_TessLevelOuter[0u] = 1.0;\n    gl_TessLevelOuter[1u] = 1.0;\n    gl_TessLevelOuter[2u] = 1.0;\n    gl_TessLevelOuter[3u] = 1.0;\n    gl_TessLevelInner[0u] = 1.0;\n    gl_TessLevelInner[1u] = 1.0;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n// MultiviewCompatible\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 69\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpCapability MultiView\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationControl %3 \"main\" %10 %14 %17 %18 %19 %23 %30 %34\nOpExecutionMode %3 Quads\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCw\nOpExecutionMode %3 OutputVertices 4\nOpName %3 \"main\"\nOpName %10 \"VSValue\"\nOpName %14 \"HSValue\"\nOpName %17 \"SV_RenderTargetArrayIndex\"\nOpName %18 \"SV_ViewportArrayIndex\"\nOpName %19 \"SV_TessFactor\"\nOpName %23 \"SV_InsideTessFactor\"\nOpName %24 \"hull_main\"\nOpName %26 \"patch_main\"\nOpName %28 \"ViewIndexToViewInstanceMap\"\nOpDecorate %10 Location 0\nOpDecorate %14 Location 0\nOpDecorate %17 Location 1\nOpDecorate %18 Location 1\nOpDecorate %18 Component 1\nOpDecorate %19 BuiltIn TessLevelOuter\nOpDecorate %19 Patch\nOpDecorate %23 BuiltIn TessLevelInner\nOpDecorate %23 Patch\nOpDecorate %28 SpecId 1000\nOpDecorate %30 BuiltIn ViewIndex\nOpDecorate %34 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 32\n%8 = OpTypeArray %5 %7\n%9 = OpTypePointer Input %8\n%10 = OpVariable %9 Input\n%11 = OpConstant %6 4\n%12 = OpTypeArray %5 %11\n%13 = OpTypePointer Output %12\n%14 = OpVariable %13 Output\n%15 = OpTypeArray %6 %11\n%16 = OpTypePointer Output %15\n%17 = OpVariable %16 Output\n%18 = OpVariable %16 Output\n%19 = OpVariable %13 Output\n%20 = OpConstant %6 2\n%21 = OpTypeArray %5 %20\n%22 = OpTypePointer Output %21\n%23 = OpVariable %22 Output\n%28 = OpSpecConstant %6 0\n%29 = OpTypePointer Input %6\n%30 = OpVariable %29 Input\n%34 = OpVariable %29 Input\n%38 = OpTypePointer Output %5\n%41 = OpTypePointer Output %6\n%47 = OpConstant %6 0\n%48 = OpConstant %5 1\n%50 = OpConstant %6 1\n%53 = OpConstant %6 3\n%58 = OpTypeBool\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %61\n%61 = OpLabel\n%56 = OpFunctionCall %1 %24\n%57 = OpLoad %6 %34\n%59 = OpIEqual %58 %57 %47\nOpControlBarrier %20 %11 %47\nOpSelectionMerge %63 None\nOpBranchConditional %59 %62 %63\n%62 = OpLabel\n%60 = OpFunctionCall %1 %26\nOpBranch %63\n%63 = OpLabel\nOpReturn\nOpFunctionEnd\n%24 = OpFunction %1 None %2\n%25 = OpLabel\nOpBranch %65\n%65 = OpLabel\n%31 = OpLoad %6 %30\n%32 = OpIMul %6 %31 %20\n%33 = OpBitFieldUExtract %6 %28 %32 %20\n%35 = OpLoad %6 %34\n%36 = OpIAdd %6 %35 %33\n%37 = OpConvertUToF %5 %36\n%40 = OpLoad %6 %34\n%39 = OpAccessChain %38 %14 %40\nOpStore %39 %37\n%43 = OpLoad %6 %34\n%42 = OpAccessChain %41 %17 %43\nOpStore %42 %33\n%45 = OpLoad %6 %34\n%44 = OpAccessChain %41 %18 %45\nOpStore %44 %33\nOpReturn\nOpFunctionEnd\n%26 = OpFunction %1 None %2\n%27 = OpLabel\nOpBranch %67\n%67 = OpLabel\n%46 = OpAccessChain %38 %19 %47\nOpStore %46 %48\n%49 = OpAccessChain %38 %19 %50\nOpStore %49 %48\n%51 = OpAccessChain %38 %19 %20\nOpStore %51 %48\n%52 = OpAccessChain %38 %19 %53\nOpStore %52 %48\n%54 = OpAccessChain %38 %23 %47\nOpStore %54 %48\n%55 = OpAccessChain %38 %23 %50\nOpStore %55 %48\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain-export-layer-viewport.view-instancing.view-instancing-multiview.last-pre-raster.tese",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\nlayout(triangles) in;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    uint _30 = bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u));\n    float _64 = ((((A[2u][0u] + B[2u]) * gl_TessCoord.z) + float(_30)) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[0u][2u] + B[0u]) * gl_TessCoord.x);\n    gl_Position.x = _64;\n    gl_Position.y = _64;\n    gl_Position.z = _64;\n    gl_Position.w = _64;\n    gl_Layer = int(_30 + bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    gl_ViewportIndex = int(_30 + 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 77\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability Tessellation\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %18 %19 %20 %22 %34\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %18 \"SV_RenderTargetArrayIndex\"\nOpName %19 \"SV_ViewportArrayIndex\"\nOpName %20 \"C\"\nOpName %22 \"D\"\nOpName %23 \"ViewInstancingOffsetsUBO\"\nOpMemberName %23 0 \"ViewID_Layer\"\nOpName %25 \"ViewInstancingOffsets\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %18 BuiltIn Layer\nOpDecorate %19 BuiltIn ViewportIndex\nOpDecorate %20 Location 3\nOpDecorate %20 Patch\nOpDecorate %22 Location 3\nOpDecorate %22 Component 1\nOpDecorate %22 Patch\nOpDecorate %23 Block\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %25 DescriptorSet 10\nOpDecorate %25 Binding 22\nOpDecorate %34 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Output %6\n%18 = OpVariable %17 Output\n%19 = OpVariable %17 Output\n%20 = OpVariable %12 Input\n%21 = OpTypePointer Input %5\n%22 = OpVariable %21 Input\n%23 = OpTypeStruct %6\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypePointer Uniform %6\n%28 = OpConstant %6 0\n%31 = OpConstant %6 16\n%32 = OpTypeVector %5 3\n%33 = OpTypePointer Input %32\n%34 = OpVariable %33 Input\n%38 = OpConstant %6 1\n%41 = OpConstant %6 2\n%66 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%27 = OpAccessChain %26 %25 %28\n%29 = OpLoad %6 %27\n%30 = OpBitFieldUExtract %6 %29 %28 %31\n%35 = OpAccessChain %21 %34 %28\n%36 = OpLoad %5 %35\n%37 = OpAccessChain %21 %34 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %21 %34 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %21 %13 %28\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %21 %13 %38\n%46 = OpLoad %5 %45\n%47 = OpAccessChain %21 %13 %41\n%48 = OpLoad %5 %47\n%49 = OpConvertUToF %5 %30\n%50 = OpAccessChain %21 %11 %28 %41\n%51 = OpLoad %5 %50\n%52 = OpAccessChain %21 %11 %38 %38\n%53 = OpLoad %5 %52\n%54 = OpAccessChain %21 %11 %41 %28\n%55 = OpLoad %5 %54\n%56 = OpFAdd %5 %55 %48\n%57 = OpFMul %5 %56 %42\n%58 = OpFAdd %5 %53 %46\n%59 = OpFMul %5 %58 %39\n%60 = OpFAdd %5 %51 %44\n%61 = OpFMul %5 %60 %36\n%62 = OpFAdd %5 %57 %49\n%63 = OpFAdd %5 %62 %59\n%64 = OpFAdd %5 %63 %61\n%65 = OpIAdd %6 %30 %38\n%67 = OpAccessChain %66 %16 %28\nOpStore %67 %64\n%68 = OpAccessChain %66 %16 %38\nOpStore %68 %64\n%69 = OpAccessChain %66 %16 %41\nOpStore %69 %64\n%70 = OpAccessChain %66 %16 %7\nOpStore %70 %64\n%72 = OpAccessChain %26 %25 %28\n%73 = OpLoad %6 %72\n%74 = OpBitFieldUExtract %6 %73 %31 %31\n%71 = OpIAdd %6 %30 %74\nOpStore %18 %71\nOpStore %19 %65\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain-export-layer-viewport.view-instancing.view-instancing-multiview.tese",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\nlayout(triangles) in;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    uint _30 = bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u));\n    float _64 = ((((A[2u][0u] + B[2u]) * gl_TessCoord.z) + float(_30)) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[0u][2u] + B[0u]) * gl_TessCoord.x);\n    gl_Position.x = _64;\n    gl_Position.y = _64;\n    gl_Position.z = _64;\n    gl_Position.w = _64;\n    gl_Layer = int(_30);\n    gl_ViewportIndex = int(_30 + 1u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 73\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability Tessellation\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %18 %19 %20 %22 %34\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %18 \"SV_RenderTargetArrayIndex\"\nOpName %19 \"SV_ViewportArrayIndex\"\nOpName %20 \"C\"\nOpName %22 \"D\"\nOpName %23 \"ViewInstancingOffsetsUBO\"\nOpMemberName %23 0 \"ViewID_Layer\"\nOpName %25 \"ViewInstancingOffsets\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %18 BuiltIn Layer\nOpDecorate %19 BuiltIn ViewportIndex\nOpDecorate %20 Location 3\nOpDecorate %20 Patch\nOpDecorate %22 Location 3\nOpDecorate %22 Component 1\nOpDecorate %22 Patch\nOpDecorate %23 Block\nOpMemberDecorate %23 0 Offset 0\nOpDecorate %25 DescriptorSet 10\nOpDecorate %25 Binding 22\nOpDecorate %34 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpTypePointer Output %6\n%18 = OpVariable %17 Output\n%19 = OpVariable %17 Output\n%20 = OpVariable %12 Input\n%21 = OpTypePointer Input %5\n%22 = OpVariable %21 Input\n%23 = OpTypeStruct %6\n%24 = OpTypePointer Uniform %23\n%25 = OpVariable %24 Uniform\n%26 = OpTypePointer Uniform %6\n%28 = OpConstant %6 0\n%31 = OpConstant %6 16\n%32 = OpTypeVector %5 3\n%33 = OpTypePointer Input %32\n%34 = OpVariable %33 Input\n%38 = OpConstant %6 1\n%41 = OpConstant %6 2\n%66 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %71\n%71 = OpLabel\n%27 = OpAccessChain %26 %25 %28\n%29 = OpLoad %6 %27\n%30 = OpBitFieldUExtract %6 %29 %28 %31\n%35 = OpAccessChain %21 %34 %28\n%36 = OpLoad %5 %35\n%37 = OpAccessChain %21 %34 %38\n%39 = OpLoad %5 %37\n%40 = OpAccessChain %21 %34 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %21 %13 %28\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %21 %13 %38\n%46 = OpLoad %5 %45\n%47 = OpAccessChain %21 %13 %41\n%48 = OpLoad %5 %47\n%49 = OpConvertUToF %5 %30\n%50 = OpAccessChain %21 %11 %28 %41\n%51 = OpLoad %5 %50\n%52 = OpAccessChain %21 %11 %38 %38\n%53 = OpLoad %5 %52\n%54 = OpAccessChain %21 %11 %41 %28\n%55 = OpLoad %5 %54\n%56 = OpFAdd %5 %55 %48\n%57 = OpFMul %5 %56 %42\n%58 = OpFAdd %5 %53 %46\n%59 = OpFMul %5 %58 %39\n%60 = OpFAdd %5 %51 %44\n%61 = OpFMul %5 %60 %36\n%62 = OpFAdd %5 %57 %49\n%63 = OpFAdd %5 %62 %59\n%64 = OpFAdd %5 %63 %61\n%65 = OpIAdd %6 %30 %38\n%67 = OpAccessChain %66 %16 %28\nOpStore %67 %64\n%68 = OpAccessChain %66 %16 %38\nOpStore %68 %64\n%69 = OpAccessChain %66 %16 %41\nOpStore %69 %64\n%70 = OpAccessChain %66 %16 %7\nOpStore %70 %64\nOpStore %18 %30\nOpStore %19 %65\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain.view-instancing.last-pre-raster.tese",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\nlayout(triangles) in;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    gl_Position.x = ((((A[0u][2u] + B[0u]) * gl_TessCoord.x) + float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)))) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[2u][0u] + B[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 82\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability Tessellation\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %17 %19 %30 %37\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %17 \"C\"\nOpName %19 \"D\"\nOpName %20 \"ViewInstancingOffsetsUBO\"\nOpMemberName %20 0 \"ViewID_Layer\"\nOpName %22 \"ViewInstancingOffsets\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %17 Location 3\nOpDecorate %17 Patch\nOpDecorate %19 Location 3\nOpDecorate %19 Component 1\nOpDecorate %19 Patch\nOpDecorate %20 Block\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %22 DescriptorSet 10\nOpDecorate %22 Binding 22\nOpDecorate %30 BuiltIn Layer\nOpDecorate %37 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %12 Input\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%20 = OpTypeStruct %6\n%21 = OpTypePointer Uniform %20\n%22 = OpVariable %21 Uniform\n%23 = OpTypePointer Uniform %6\n%25 = OpConstant %6 0\n%28 = OpConstant %6 16\n%29 = OpTypePointer Output %6\n%30 = OpVariable %29 Output\n%35 = OpTypeVector %5 3\n%36 = OpTypePointer Input %35\n%37 = OpVariable %36 Input\n%41 = OpConstant %6 1\n%44 = OpConstant %6 2\n%75 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %80\n%80 = OpLabel\n%24 = OpAccessChain %23 %22 %25\n%26 = OpLoad %6 %24\n%27 = OpBitFieldUExtract %6 %26 %28 %28\nOpStore %30 %27\n%31 = OpLoad %5 %19\n%32 = OpAccessChain %23 %22 %25\n%33 = OpLoad %6 %32\n%34 = OpBitFieldUExtract %6 %33 %25 %28\n%38 = OpAccessChain %18 %37 %25\n%39 = OpLoad %5 %38\n%40 = OpAccessChain %18 %37 %41\n%42 = OpLoad %5 %40\n%43 = OpAccessChain %18 %37 %44\n%45 = OpLoad %5 %43\n%46 = OpAccessChain %18 %13 %25\n%47 = OpLoad %5 %46\n%48 = OpAccessChain %18 %13 %41\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %18 %13 %44\n%51 = OpLoad %5 %50\n%52 = OpConvertUToF %5 %34\n%53 = OpAccessChain %18 %11 %25 %44\n%54 = OpLoad %5 %53\n%55 = OpAccessChain %18 %11 %41 %41\n%56 = OpLoad %5 %55\n%57 = OpAccessChain %18 %11 %44 %25\n%58 = OpLoad %5 %57\n%59 = OpFAdd %5 %58 %51\n%60 = OpFMul %5 %59 %45\n%61 = OpFAdd %5 %56 %49\n%62 = OpFMul %5 %61 %42\n%63 = OpFAdd %5 %54 %47\n%64 = OpFMul %5 %63 %39\n%65 = OpFAdd %5 %64 %52\n%66 = OpFAdd %5 %65 %62\n%67 = OpFAdd %5 %66 %60\n%68 = OpAccessChain %18 %17 %25\n%69 = OpLoad %5 %68\n%70 = OpAccessChain %18 %17 %41\n%71 = OpLoad %5 %70\n%72 = OpFAdd %5 %71 %69\n%73 = OpAccessChain %18 %17 %44\n%74 = OpLoad %5 %73\n%76 = OpAccessChain %75 %16 %25\nOpStore %76 %67\n%77 = OpAccessChain %75 %16 %41\nOpStore %77 %72\n%78 = OpAccessChain %75 %16 %44\nOpStore %78 %74\n%79 = OpAccessChain %75 %16 %7\nOpStore %79 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain.view-instancing.tese",
    "content": "#version 460\nlayout(triangles) in;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Position.x = ((((A[0u][2u] + B[0u]) * gl_TessCoord.x) + float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)))) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[2u][0u] + B[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 77\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %17 %19 %32\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %17 \"C\"\nOpName %19 \"D\"\nOpName %21 \"ViewInstancingOffsetsUBO\"\nOpMemberName %21 0 \"ViewID_Layer\"\nOpName %23 \"ViewInstancingOffsets\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %17 Location 3\nOpDecorate %17 Patch\nOpDecorate %19 Location 3\nOpDecorate %19 Component 1\nOpDecorate %19 Patch\nOpDecorate %21 Block\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %23 DescriptorSet 10\nOpDecorate %23 Binding 22\nOpDecorate %32 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %12 Input\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%21 = OpTypeStruct %6\n%22 = OpTypePointer Uniform %21\n%23 = OpVariable %22 Uniform\n%24 = OpTypePointer Uniform %6\n%26 = OpConstant %6 0\n%29 = OpConstant %6 16\n%30 = OpTypeVector %5 3\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%36 = OpConstant %6 1\n%39 = OpConstant %6 2\n%70 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%20 = OpLoad %5 %19\n%25 = OpAccessChain %24 %23 %26\n%27 = OpLoad %6 %25\n%28 = OpBitFieldUExtract %6 %27 %26 %29\n%33 = OpAccessChain %18 %32 %26\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %18 %32 %36\n%37 = OpLoad %5 %35\n%38 = OpAccessChain %18 %32 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %18 %13 %26\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %18 %13 %36\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %18 %13 %39\n%46 = OpLoad %5 %45\n%47 = OpConvertUToF %5 %28\n%48 = OpAccessChain %18 %11 %26 %39\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %18 %11 %36 %36\n%51 = OpLoad %5 %50\n%52 = OpAccessChain %18 %11 %39 %26\n%53 = OpLoad %5 %52\n%54 = OpFAdd %5 %53 %46\n%55 = OpFMul %5 %54 %40\n%56 = OpFAdd %5 %51 %44\n%57 = OpFMul %5 %56 %37\n%58 = OpFAdd %5 %49 %42\n%59 = OpFMul %5 %58 %34\n%60 = OpFAdd %5 %59 %47\n%61 = OpFAdd %5 %60 %57\n%62 = OpFAdd %5 %61 %55\n%63 = OpAccessChain %18 %17 %26\n%64 = OpLoad %5 %63\n%65 = OpAccessChain %18 %17 %36\n%66 = OpLoad %5 %65\n%67 = OpFAdd %5 %66 %64\n%68 = OpAccessChain %18 %17 %39\n%69 = OpLoad %5 %68\n%71 = OpAccessChain %70 %16 %26\nOpStore %71 %62\n%72 = OpAccessChain %70 %16 %36\nOpStore %72 %67\n%73 = OpAccessChain %70 %16 %39\nOpStore %73 %69\n%74 = OpAccessChain %70 %16 %7\nOpStore %74 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain.view-instancing.view-instancing-multiview.last-pre-raster.tese",
    "content": "#version 460\n#extension GL_EXT_multiview : require\nlayout(triangles) in;\n\nlayout(constant_id = 1000) const uint ViewIndexToViewInstanceMap = 0u;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Position.x = ((((A[0u][2u] + B[0u]) * gl_TessCoord.x) + float(bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u)))) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[2u][0u] + B[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n// MultiviewCompatible\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 75\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpCapability MultiView\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %17 %19 %23 %30\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %17 \"C\"\nOpName %19 \"D\"\nOpName %21 \"ViewIndexToViewInstanceMap\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %17 Location 3\nOpDecorate %17 Patch\nOpDecorate %19 Location 3\nOpDecorate %19 Component 1\nOpDecorate %19 Patch\nOpDecorate %21 SpecId 1000\nOpDecorate %23 BuiltIn ViewIndex\nOpDecorate %30 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %12 Input\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%21 = OpSpecConstant %6 0\n%22 = OpTypePointer Input %6\n%23 = OpVariable %22 Input\n%26 = OpConstant %6 2\n%28 = OpTypeVector %5 3\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%32 = OpConstant %6 0\n%35 = OpConstant %6 1\n%68 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%20 = OpLoad %5 %19\n%24 = OpLoad %6 %23\n%25 = OpIMul %6 %24 %26\n%27 = OpBitFieldUExtract %6 %21 %25 %26\n%31 = OpAccessChain %18 %30 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %18 %30 %35\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %18 %30 %26\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %18 %13 %32\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %18 %13 %35\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %18 %13 %26\n%44 = OpLoad %5 %43\n%45 = OpConvertUToF %5 %27\n%46 = OpAccessChain %18 %11 %32 %26\n%47 = OpLoad %5 %46\n%48 = OpAccessChain %18 %11 %35 %35\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %18 %11 %26 %32\n%51 = OpLoad %5 %50\n%52 = OpFAdd %5 %51 %44\n%53 = OpFMul %5 %52 %38\n%54 = OpFAdd %5 %49 %42\n%55 = OpFMul %5 %54 %36\n%56 = OpFAdd %5 %47 %40\n%57 = OpFMul %5 %56 %33\n%58 = OpFAdd %5 %57 %45\n%59 = OpFAdd %5 %58 %55\n%60 = OpFAdd %5 %59 %53\n%61 = OpAccessChain %18 %17 %32\n%62 = OpLoad %5 %61\n%63 = OpAccessChain %18 %17 %35\n%64 = OpLoad %5 %63\n%65 = OpFAdd %5 %64 %62\n%66 = OpAccessChain %18 %17 %26\n%67 = OpLoad %5 %66\n%69 = OpAccessChain %68 %16 %32\nOpStore %69 %60\n%70 = OpAccessChain %68 %16 %35\nOpStore %70 %65\n%71 = OpAccessChain %68 %16 %26\nOpStore %71 %67\n%72 = OpAccessChain %68 %16 %7\nOpStore %72 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain.view-instancing.view-instancing-multiview.tese",
    "content": "#version 460\n#extension GL_EXT_multiview : require\nlayout(triangles) in;\n\nlayout(constant_id = 1000) const uint ViewIndexToViewInstanceMap = 0u;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Position.x = ((((A[0u][2u] + B[0u]) * gl_TessCoord.x) + float(bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u)))) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[2u][0u] + B[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n// MultiviewCompatible\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 75\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpCapability MultiView\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %17 %19 %23 %30\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %17 \"C\"\nOpName %19 \"D\"\nOpName %21 \"ViewIndexToViewInstanceMap\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %17 Location 3\nOpDecorate %17 Patch\nOpDecorate %19 Location 3\nOpDecorate %19 Component 1\nOpDecorate %19 Patch\nOpDecorate %21 SpecId 1000\nOpDecorate %23 BuiltIn ViewIndex\nOpDecorate %30 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %12 Input\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%21 = OpSpecConstant %6 0\n%22 = OpTypePointer Input %6\n%23 = OpVariable %22 Input\n%26 = OpConstant %6 2\n%28 = OpTypeVector %5 3\n%29 = OpTypePointer Input %28\n%30 = OpVariable %29 Input\n%32 = OpConstant %6 0\n%35 = OpConstant %6 1\n%68 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %73\n%73 = OpLabel\n%20 = OpLoad %5 %19\n%24 = OpLoad %6 %23\n%25 = OpIMul %6 %24 %26\n%27 = OpBitFieldUExtract %6 %21 %25 %26\n%31 = OpAccessChain %18 %30 %32\n%33 = OpLoad %5 %31\n%34 = OpAccessChain %18 %30 %35\n%36 = OpLoad %5 %34\n%37 = OpAccessChain %18 %30 %26\n%38 = OpLoad %5 %37\n%39 = OpAccessChain %18 %13 %32\n%40 = OpLoad %5 %39\n%41 = OpAccessChain %18 %13 %35\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %18 %13 %26\n%44 = OpLoad %5 %43\n%45 = OpConvertUToF %5 %27\n%46 = OpAccessChain %18 %11 %32 %26\n%47 = OpLoad %5 %46\n%48 = OpAccessChain %18 %11 %35 %35\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %18 %11 %26 %32\n%51 = OpLoad %5 %50\n%52 = OpFAdd %5 %51 %44\n%53 = OpFMul %5 %52 %38\n%54 = OpFAdd %5 %49 %42\n%55 = OpFMul %5 %54 %36\n%56 = OpFAdd %5 %47 %40\n%57 = OpFMul %5 %56 %33\n%58 = OpFAdd %5 %57 %45\n%59 = OpFAdd %5 %58 %55\n%60 = OpFAdd %5 %59 %53\n%61 = OpAccessChain %18 %17 %32\n%62 = OpLoad %5 %61\n%63 = OpAccessChain %18 %17 %35\n%64 = OpLoad %5 %63\n%65 = OpFAdd %5 %64 %62\n%66 = OpAccessChain %18 %17 %26\n%67 = OpLoad %5 %66\n%69 = OpAccessChain %68 %16 %32\nOpStore %69 %60\n%70 = OpAccessChain %68 %16 %35\nOpStore %70 %65\n%71 = OpAccessChain %68 %16 %26\nOpStore %71 %67\n%72 = OpAccessChain %68 %16 %7\nOpStore %72 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain.view-instancing.view-instancing-viewport-offset.last-pre-raster.tese",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\nlayout(triangles) in;\n\nlayout(constant_id = 1001) const uint ViewIDToViewport = 0u;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    gl_ViewportIndex = int(bitfieldExtract(ViewIDToViewport, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)) * 8u), int(8u)));\n    gl_Position.x = ((((A[0u][2u] + B[0u]) * gl_TessCoord.x) + float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)))) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[2u][0u] + B[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 90\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability Tessellation\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %17 %19 %30 %38 %45\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %17 \"C\"\nOpName %19 \"D\"\nOpName %20 \"ViewInstancingOffsetsUBO\"\nOpMemberName %20 0 \"ViewID_Layer\"\nOpName %22 \"ViewInstancingOffsets\"\nOpName %34 \"ViewIDToViewport\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %17 Location 3\nOpDecorate %17 Patch\nOpDecorate %19 Location 3\nOpDecorate %19 Component 1\nOpDecorate %19 Patch\nOpDecorate %20 Block\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %22 DescriptorSet 10\nOpDecorate %22 Binding 22\nOpDecorate %30 BuiltIn Layer\nOpDecorate %34 SpecId 1001\nOpDecorate %38 BuiltIn ViewportIndex\nOpDecorate %45 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %12 Input\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%20 = OpTypeStruct %6\n%21 = OpTypePointer Uniform %20\n%22 = OpVariable %21 Uniform\n%23 = OpTypePointer Uniform %6\n%25 = OpConstant %6 0\n%28 = OpConstant %6 16\n%29 = OpTypePointer Output %6\n%30 = OpVariable %29 Output\n%34 = OpSpecConstant %6 0\n%36 = OpConstant %6 8\n%38 = OpVariable %29 Output\n%43 = OpTypeVector %5 3\n%44 = OpTypePointer Input %43\n%45 = OpVariable %44 Input\n%49 = OpConstant %6 1\n%52 = OpConstant %6 2\n%83 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %88\n%88 = OpLabel\n%24 = OpAccessChain %23 %22 %25\n%26 = OpLoad %6 %24\n%27 = OpBitFieldUExtract %6 %26 %28 %28\nOpStore %30 %27\n%31 = OpAccessChain %23 %22 %25\n%32 = OpLoad %6 %31\n%33 = OpBitFieldUExtract %6 %32 %25 %28\n%35 = OpIMul %6 %33 %36\n%37 = OpBitFieldUExtract %6 %34 %35 %36\nOpStore %38 %37\n%39 = OpLoad %5 %19\n%40 = OpAccessChain %23 %22 %25\n%41 = OpLoad %6 %40\n%42 = OpBitFieldUExtract %6 %41 %25 %28\n%46 = OpAccessChain %18 %45 %25\n%47 = OpLoad %5 %46\n%48 = OpAccessChain %18 %45 %49\n%50 = OpLoad %5 %48\n%51 = OpAccessChain %18 %45 %52\n%53 = OpLoad %5 %51\n%54 = OpAccessChain %18 %13 %25\n%55 = OpLoad %5 %54\n%56 = OpAccessChain %18 %13 %49\n%57 = OpLoad %5 %56\n%58 = OpAccessChain %18 %13 %52\n%59 = OpLoad %5 %58\n%60 = OpConvertUToF %5 %42\n%61 = OpAccessChain %18 %11 %25 %52\n%62 = OpLoad %5 %61\n%63 = OpAccessChain %18 %11 %49 %49\n%64 = OpLoad %5 %63\n%65 = OpAccessChain %18 %11 %52 %25\n%66 = OpLoad %5 %65\n%67 = OpFAdd %5 %66 %59\n%68 = OpFMul %5 %67 %53\n%69 = OpFAdd %5 %64 %57\n%70 = OpFMul %5 %69 %50\n%71 = OpFAdd %5 %62 %55\n%72 = OpFMul %5 %71 %47\n%73 = OpFAdd %5 %72 %60\n%74 = OpFAdd %5 %73 %70\n%75 = OpFAdd %5 %74 %68\n%76 = OpAccessChain %18 %17 %25\n%77 = OpLoad %5 %76\n%78 = OpAccessChain %18 %17 %49\n%79 = OpLoad %5 %78\n%80 = OpFAdd %5 %79 %77\n%81 = OpAccessChain %18 %17 %52\n%82 = OpLoad %5 %81\n%84 = OpAccessChain %83 %16 %25\nOpStore %84 %75\n%85 = OpAccessChain %83 %16 %49\nOpStore %85 %80\n%86 = OpAccessChain %83 %16 %52\nOpStore %86 %82\n%87 = OpAccessChain %83 %16 %7\nOpStore %87 %39\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/tese/domain.view-instancing.view-instancing-viewport-offset.tese",
    "content": "#version 460\nlayout(triangles) in;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in float A[][3];\nlayout(location = 0, component = 1) in float B[];\nlayout(location = 3) patch in float C[3];\nlayout(location = 3, component = 1) patch in float D;\n\nvoid main()\n{\n    gl_Position.x = ((((A[0u][2u] + B[0u]) * gl_TessCoord.x) + float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)))) + ((A[1u][1u] + B[1u]) * gl_TessCoord.y)) + ((A[2u][0u] + B[2u]) * gl_TessCoord.z);\n    gl_Position.y = C[1u] + C[0u];\n    gl_Position.z = C[2u];\n    gl_Position.w = D;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 77\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpMemoryModel Logical GLSL450\nOpEntryPoint TessellationEvaluation %3 \"main\" %11 %13 %16 %17 %19 %32\nOpExecutionMode %3 Triangles\nOpName %3 \"main\"\nOpName %11 \"A\"\nOpName %13 \"B\"\nOpName %16 \"SV_Position\"\nOpName %17 \"C\"\nOpName %19 \"D\"\nOpName %21 \"ViewInstancingOffsetsUBO\"\nOpMemberName %21 0 \"ViewID_Layer\"\nOpName %23 \"ViewInstancingOffsets\"\nOpDecorate %11 Location 0\nOpDecorate %13 Location 0\nOpDecorate %13 Component 1\nOpDecorate %16 BuiltIn Position\nOpDecorate %17 Location 3\nOpDecorate %17 Patch\nOpDecorate %19 Location 3\nOpDecorate %19 Component 1\nOpDecorate %19 Patch\nOpDecorate %21 Block\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %23 DescriptorSet 10\nOpDecorate %23 Binding 22\nOpDecorate %32 BuiltIn TessCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeInt 32 0\n%7 = OpConstant %6 3\n%8 = OpTypeArray %5 %7\n%9 = OpTypeArray %8 %7\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%12 = OpTypePointer Input %8\n%13 = OpVariable %12 Input\n%14 = OpTypeVector %5 4\n%15 = OpTypePointer Output %14\n%16 = OpVariable %15 Output\n%17 = OpVariable %12 Input\n%18 = OpTypePointer Input %5\n%19 = OpVariable %18 Input\n%21 = OpTypeStruct %6\n%22 = OpTypePointer Uniform %21\n%23 = OpVariable %22 Uniform\n%24 = OpTypePointer Uniform %6\n%26 = OpConstant %6 0\n%29 = OpConstant %6 16\n%30 = OpTypeVector %5 3\n%31 = OpTypePointer Input %30\n%32 = OpVariable %31 Input\n%36 = OpConstant %6 1\n%39 = OpConstant %6 2\n%70 = OpTypePointer Output %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %75\n%75 = OpLabel\n%20 = OpLoad %5 %19\n%25 = OpAccessChain %24 %23 %26\n%27 = OpLoad %6 %25\n%28 = OpBitFieldUExtract %6 %27 %26 %29\n%33 = OpAccessChain %18 %32 %26\n%34 = OpLoad %5 %33\n%35 = OpAccessChain %18 %32 %36\n%37 = OpLoad %5 %35\n%38 = OpAccessChain %18 %32 %39\n%40 = OpLoad %5 %38\n%41 = OpAccessChain %18 %13 %26\n%42 = OpLoad %5 %41\n%43 = OpAccessChain %18 %13 %36\n%44 = OpLoad %5 %43\n%45 = OpAccessChain %18 %13 %39\n%46 = OpLoad %5 %45\n%47 = OpConvertUToF %5 %28\n%48 = OpAccessChain %18 %11 %26 %39\n%49 = OpLoad %5 %48\n%50 = OpAccessChain %18 %11 %36 %36\n%51 = OpLoad %5 %50\n%52 = OpAccessChain %18 %11 %39 %26\n%53 = OpLoad %5 %52\n%54 = OpFAdd %5 %53 %46\n%55 = OpFMul %5 %54 %40\n%56 = OpFAdd %5 %51 %44\n%57 = OpFMul %5 %56 %37\n%58 = OpFAdd %5 %49 %42\n%59 = OpFMul %5 %58 %34\n%60 = OpFAdd %5 %59 %47\n%61 = OpFAdd %5 %60 %57\n%62 = OpFAdd %5 %61 %55\n%63 = OpAccessChain %18 %17 %26\n%64 = OpLoad %5 %63\n%65 = OpAccessChain %18 %17 %36\n%66 = OpLoad %5 %65\n%67 = OpFAdd %5 %66 %64\n%68 = OpAccessChain %18 %17 %39\n%69 = OpLoad %5 %68\n%71 = OpAccessChain %70 %16 %26\nOpStore %71 %62\n%72 = OpAccessChain %70 %16 %36\nOpStore %72 %67\n%73 = OpAccessChain %70 %16 %39\nOpStore %73 %69\n%74 = OpAccessChain %70 %16 %7\nOpStore %74 %20\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.last-pre-raster.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\nlayout(location = 1) in uint VP;\n\nvoid main()\n{\n    float _27 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _27;\n    gl_Position.y = _27;\n    gl_Position.z = _27;\n    gl_Position.w = _27;\n    gl_Layer = int(LAYER + bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %8 %12 %14 %15\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %8 \"VP\"\nOpName %12 \"SV_Position\"\nOpName %14 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"SV_ViewportArrayIndex\"\nOpName %18 \"ViewInstancingOffsetsUBO\"\nOpMemberName %18 0 \"ViewID_Layer\"\nOpName %20 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %8 Location 1\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 BuiltIn Layer\nOpDecorate %15 BuiltIn ViewportIndex\nOpDecorate %18 Block\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %20 DescriptorSet 10\nOpDecorate %20 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Output %10\n%12 = OpVariable %11 Output\n%13 = OpTypePointer Output %5\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%18 = OpTypeStruct %5\n%19 = OpTypePointer Uniform %18\n%20 = OpVariable %19 Uniform\n%21 = OpTypePointer Uniform %5\n%23 = OpConstant %5 0\n%26 = OpConstant %5 16\n%28 = OpTypePointer Output %9\n%31 = OpConstant %5 1\n%33 = OpConstant %5 2\n%35 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %40\n%40 = OpLabel\n%16 = OpLoad %5 %8\n%17 = OpLoad %5 %7\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpBitFieldUExtract %5 %24 %23 %26\n%27 = OpConvertUToF %9 %25\n%29 = OpAccessChain %28 %12 %23\nOpStore %29 %27\n%30 = OpAccessChain %28 %12 %31\nOpStore %30 %27\n%32 = OpAccessChain %28 %12 %33\nOpStore %32 %27\n%34 = OpAccessChain %28 %12 %35\nOpStore %34 %27\n%37 = OpAccessChain %21 %20 %23\n%38 = OpLoad %5 %37\n%39 = OpBitFieldUExtract %5 %38 %26 %26\n%36 = OpIAdd %5 %17 %39\nOpStore %14 %36\nOpStore %15 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\nlayout(location = 1) in uint VP;\n\nvoid main()\n{\n    float _27 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _27;\n    gl_Position.y = _27;\n    gl_Position.z = _27;\n    gl_Position.w = _27;\n    gl_Layer = int(LAYER);\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %8 %12 %14 %15\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %8 \"VP\"\nOpName %12 \"SV_Position\"\nOpName %14 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"SV_ViewportArrayIndex\"\nOpName %18 \"ViewInstancingOffsetsUBO\"\nOpMemberName %18 0 \"ViewID_Layer\"\nOpName %20 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %8 Location 1\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 BuiltIn Layer\nOpDecorate %15 BuiltIn ViewportIndex\nOpDecorate %18 Block\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %20 DescriptorSet 10\nOpDecorate %20 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Output %10\n%12 = OpVariable %11 Output\n%13 = OpTypePointer Output %5\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%18 = OpTypeStruct %5\n%19 = OpTypePointer Uniform %18\n%20 = OpVariable %19 Uniform\n%21 = OpTypePointer Uniform %5\n%23 = OpConstant %5 0\n%26 = OpConstant %5 16\n%28 = OpTypePointer Output %9\n%31 = OpConstant %5 1\n%33 = OpConstant %5 2\n%35 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %36\n%36 = OpLabel\n%16 = OpLoad %5 %8\n%17 = OpLoad %5 %7\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpBitFieldUExtract %5 %24 %23 %26\n%27 = OpConvertUToF %9 %25\n%29 = OpAccessChain %28 %12 %23\nOpStore %29 %27\n%30 = OpAccessChain %28 %12 %31\nOpStore %30 %27\n%32 = OpAccessChain %28 %12 %33\nOpStore %32 %27\n%34 = OpAccessChain %28 %12 %35\nOpStore %34 %27\nOpStore %14 %17\nOpStore %15 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.view-instancing-multiview.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\nlayout(location = 1) in uint VP;\n\nvoid main()\n{\n    float _27 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _27;\n    gl_Position.y = _27;\n    gl_Position.z = _27;\n    gl_Position.w = _27;\n    gl_Layer = int(LAYER);\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %8 %12 %14 %15\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %8 \"VP\"\nOpName %12 \"SV_Position\"\nOpName %14 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"SV_ViewportArrayIndex\"\nOpName %18 \"ViewInstancingOffsetsUBO\"\nOpMemberName %18 0 \"ViewID_Layer\"\nOpName %20 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %8 Location 1\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 BuiltIn Layer\nOpDecorate %15 BuiltIn ViewportIndex\nOpDecorate %18 Block\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %20 DescriptorSet 10\nOpDecorate %20 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Output %10\n%12 = OpVariable %11 Output\n%13 = OpTypePointer Output %5\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%18 = OpTypeStruct %5\n%19 = OpTypePointer Uniform %18\n%20 = OpVariable %19 Uniform\n%21 = OpTypePointer Uniform %5\n%23 = OpConstant %5 0\n%26 = OpConstant %5 16\n%28 = OpTypePointer Output %9\n%31 = OpConstant %5 1\n%33 = OpConstant %5 2\n%35 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %36\n%36 = OpLabel\n%16 = OpLoad %5 %8\n%17 = OpLoad %5 %7\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpBitFieldUExtract %5 %24 %23 %26\n%27 = OpConvertUToF %9 %25\n%29 = OpAccessChain %28 %12 %23\nOpStore %29 %27\n%30 = OpAccessChain %28 %12 %31\nOpStore %30 %27\n%32 = OpAccessChain %28 %12 %33\nOpStore %32 %27\n%34 = OpAccessChain %28 %12 %35\nOpStore %34 %27\nOpStore %14 %17\nOpStore %15 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.view-instancing-viewport-offset.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\nlayout(location = 1) in uint VP;\n\nvoid main()\n{\n    float _27 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _27;\n    gl_Position.y = _27;\n    gl_Position.z = _27;\n    gl_Position.w = _27;\n    gl_Layer = int(LAYER);\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 38\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %8 %12 %14 %15\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %8 \"VP\"\nOpName %12 \"SV_Position\"\nOpName %14 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"SV_ViewportArrayIndex\"\nOpName %18 \"ViewInstancingOffsetsUBO\"\nOpMemberName %18 0 \"ViewID_Layer\"\nOpName %20 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %8 Location 1\nOpDecorate %12 BuiltIn Position\nOpDecorate %14 BuiltIn Layer\nOpDecorate %15 BuiltIn ViewportIndex\nOpDecorate %18 Block\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %20 DescriptorSet 10\nOpDecorate %20 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpVariable %6 Input\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Output %10\n%12 = OpVariable %11 Output\n%13 = OpTypePointer Output %5\n%14 = OpVariable %13 Output\n%15 = OpVariable %13 Output\n%18 = OpTypeStruct %5\n%19 = OpTypePointer Uniform %18\n%20 = OpVariable %19 Uniform\n%21 = OpTypePointer Uniform %5\n%23 = OpConstant %5 0\n%26 = OpConstant %5 16\n%28 = OpTypePointer Output %9\n%31 = OpConstant %5 1\n%33 = OpConstant %5 2\n%35 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %36\n%36 = OpLabel\n%16 = OpLoad %5 %8\n%17 = OpLoad %5 %7\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %5 %22\n%25 = OpBitFieldUExtract %5 %24 %23 %26\n%27 = OpConvertUToF %9 %25\n%29 = OpAccessChain %28 %12 %23\nOpStore %29 %27\n%30 = OpAccessChain %28 %12 %31\nOpStore %30 %27\n%32 = OpAccessChain %28 %12 %33\nOpStore %32 %27\n%34 = OpAccessChain %28 %12 %35\nOpStore %34 %27\nOpStore %14 %17\nOpStore %15 %16\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer.last-pre-raster.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\n\nvoid main()\n{\n    float _24 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _24;\n    gl_Position.y = _24;\n    gl_Position.z = _24;\n    gl_Position.w = _24;\n    gl_Layer = int(LAYER + bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"ViewInstancingOffsetsUBO\"\nOpMemberName %15 0 \"ViewID_Layer\"\nOpName %17 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn Layer\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %17 DescriptorSet 10\nOpDecorate %17 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpTypeStruct %5\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Uniform %5\n%20 = OpConstant %5 0\n%23 = OpConstant %5 16\n%25 = OpTypePointer Output %8\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%32 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%14 = OpLoad %5 %7\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpBitFieldUExtract %5 %21 %20 %23\n%24 = OpConvertUToF %8 %22\n%26 = OpAccessChain %25 %11 %20\nOpStore %26 %24\n%27 = OpAccessChain %25 %11 %28\nOpStore %27 %24\n%29 = OpAccessChain %25 %11 %30\nOpStore %29 %24\n%31 = OpAccessChain %25 %11 %32\nOpStore %31 %24\n%34 = OpAccessChain %18 %17 %20\n%35 = OpLoad %5 %34\n%36 = OpBitFieldUExtract %5 %35 %23 %23\n%33 = OpIAdd %5 %14 %36\nOpStore %13 %33\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\n\nvoid main()\n{\n    float _24 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _24;\n    gl_Position.y = _24;\n    gl_Position.z = _24;\n    gl_Position.w = _24;\n    gl_Layer = int(LAYER);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"ViewInstancingOffsetsUBO\"\nOpMemberName %15 0 \"ViewID_Layer\"\nOpName %17 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn Layer\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %17 DescriptorSet 10\nOpDecorate %17 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpTypeStruct %5\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Uniform %5\n%20 = OpConstant %5 0\n%23 = OpConstant %5 16\n%25 = OpTypePointer Output %8\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%32 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%14 = OpLoad %5 %7\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpBitFieldUExtract %5 %21 %20 %23\n%24 = OpConvertUToF %8 %22\n%26 = OpAccessChain %25 %11 %20\nOpStore %26 %24\n%27 = OpAccessChain %25 %11 %28\nOpStore %27 %24\n%29 = OpAccessChain %25 %11 %30\nOpStore %29 %24\n%31 = OpAccessChain %25 %11 %32\nOpStore %31 %24\nOpStore %13 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer.view-instancing-multiview.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\n\nvoid main()\n{\n    float _24 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _24;\n    gl_Position.y = _24;\n    gl_Position.z = _24;\n    gl_Position.w = _24;\n    gl_Layer = int(LAYER);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"ViewInstancingOffsetsUBO\"\nOpMemberName %15 0 \"ViewID_Layer\"\nOpName %17 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn Layer\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %17 DescriptorSet 10\nOpDecorate %17 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpTypeStruct %5\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Uniform %5\n%20 = OpConstant %5 0\n%23 = OpConstant %5 16\n%25 = OpTypePointer Output %8\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%32 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%14 = OpLoad %5 %7\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpBitFieldUExtract %5 %21 %20 %23\n%24 = OpConvertUToF %8 %22\n%26 = OpAccessChain %25 %11 %20\nOpStore %26 %24\n%27 = OpAccessChain %25 %11 %28\nOpStore %27 %24\n%29 = OpAccessChain %25 %11 %30\nOpStore %29 %24\n%31 = OpAccessChain %25 %11 %32\nOpStore %31 %24\nOpStore %13 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-layer.view-instancing-viewport-offset.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint LAYER;\n\nvoid main()\n{\n    float _24 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _24;\n    gl_Position.y = _24;\n    gl_Position.z = _24;\n    gl_Position.w = _24;\n    gl_Layer = int(LAYER);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"LAYER\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_RenderTargetArrayIndex\"\nOpName %15 \"ViewInstancingOffsetsUBO\"\nOpMemberName %15 0 \"ViewID_Layer\"\nOpName %17 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn Layer\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %17 DescriptorSet 10\nOpDecorate %17 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpTypeStruct %5\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Uniform %5\n%20 = OpConstant %5 0\n%23 = OpConstant %5 16\n%25 = OpTypePointer Output %8\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%32 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%14 = OpLoad %5 %7\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpBitFieldUExtract %5 %21 %20 %23\n%24 = OpConvertUToF %8 %22\n%26 = OpAccessChain %25 %11 %20\nOpStore %26 %24\n%27 = OpAccessChain %25 %11 %28\nOpStore %27 %24\n%29 = OpAccessChain %25 %11 %30\nOpStore %29 %24\n%31 = OpAccessChain %25 %11 %32\nOpStore %31 %24\nOpStore %13 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-viewport.last-pre-raster.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint VP;\n\nvoid main()\n{\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    float _28 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _28;\n    gl_Position.y = _28;\n    gl_Position.z = _28;\n    gl_Position.w = _28;\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13 %23\nOpName %3 \"main\"\nOpName %7 \"VP\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_ViewportArrayIndex\"\nOpName %14 \"ViewInstancingOffsetsUBO\"\nOpMemberName %14 0 \"ViewID_Layer\"\nOpName %16 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn ViewportIndex\nOpDecorate %14 Block\nOpMemberDecorate %14 0 Offset 0\nOpDecorate %16 DescriptorSet 10\nOpDecorate %16 Binding 22\nOpDecorate %23 BuiltIn Layer\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%14 = OpTypeStruct %5\n%15 = OpTypePointer Uniform %14\n%16 = OpVariable %15 Uniform\n%17 = OpTypePointer Uniform %5\n%19 = OpConstant %5 0\n%22 = OpConstant %5 16\n%23 = OpVariable %12 Output\n%29 = OpTypePointer Output %8\n%32 = OpConstant %5 1\n%34 = OpConstant %5 2\n%36 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %37\n%37 = OpLabel\n%18 = OpAccessChain %17 %16 %19\n%20 = OpLoad %5 %18\n%21 = OpBitFieldUExtract %5 %20 %22 %22\nOpStore %23 %21\n%24 = OpLoad %5 %7\n%25 = OpAccessChain %17 %16 %19\n%26 = OpLoad %5 %25\n%27 = OpBitFieldUExtract %5 %26 %19 %22\n%28 = OpConvertUToF %8 %27\n%30 = OpAccessChain %29 %11 %19\nOpStore %30 %28\n%31 = OpAccessChain %29 %11 %32\nOpStore %31 %28\n%33 = OpAccessChain %29 %11 %34\nOpStore %33 %28\n%35 = OpAccessChain %29 %11 %36\nOpStore %35 %28\nOpStore %13 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-viewport.vert",
    "content": "#version 460\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint VP;\n\nvoid main()\n{\n    float _24 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _24;\n    gl_Position.y = _24;\n    gl_Position.z = _24;\n    gl_Position.w = _24;\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"VP\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_ViewportArrayIndex\"\nOpName %15 \"ViewInstancingOffsetsUBO\"\nOpMemberName %15 0 \"ViewID_Layer\"\nOpName %17 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn ViewportIndex\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %17 DescriptorSet 10\nOpDecorate %17 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpTypeStruct %5\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Uniform %5\n%20 = OpConstant %5 0\n%23 = OpConstant %5 16\n%25 = OpTypePointer Output %8\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%32 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%14 = OpLoad %5 %7\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpBitFieldUExtract %5 %21 %20 %23\n%24 = OpConvertUToF %8 %22\n%26 = OpAccessChain %25 %11 %20\nOpStore %26 %24\n%27 = OpAccessChain %25 %11 %28\nOpStore %27 %24\n%29 = OpAccessChain %25 %11 %30\nOpStore %29 %24\n%31 = OpAccessChain %25 %11 %32\nOpStore %31 %24\nOpStore %13 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-viewport.view-instancing-multiview.vert",
    "content": "#version 460\n#extension GL_EXT_multiview : require\n\nlayout(constant_id = 1000) const uint ViewIndexToViewInstanceMap = 0u;\n\nlayout(location = 0) in uint VP;\n\nvoid main()\n{\n    float _21 = float(bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u)));\n    gl_Position.x = _21;\n    gl_Position.y = _21;\n    gl_Position.z = _21;\n    gl_Position.w = _21;\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// MultiviewCompatible\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\nOpCapability Shader\nOpCapability MultiViewport\nOpCapability MultiView\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13 %16\nOpName %3 \"main\"\nOpName %7 \"VP\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_ViewportArrayIndex\"\nOpName %15 \"ViewIndexToViewInstanceMap\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn ViewportIndex\nOpDecorate %15 SpecId 1000\nOpDecorate %16 BuiltIn ViewIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpSpecConstant %5 0\n%16 = OpVariable %6 Input\n%19 = OpConstant %5 2\n%22 = OpTypePointer Output %8\n%24 = OpConstant %5 0\n%26 = OpConstant %5 1\n%29 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %30\n%30 = OpLabel\n%14 = OpLoad %5 %7\n%17 = OpLoad %5 %16\n%18 = OpIMul %5 %17 %19\n%20 = OpBitFieldUExtract %5 %15 %18 %19\n%21 = OpConvertUToF %8 %20\n%23 = OpAccessChain %22 %11 %24\nOpStore %23 %21\n%25 = OpAccessChain %22 %11 %26\nOpStore %25 %21\n%27 = OpAccessChain %22 %11 %19\nOpStore %27 %21\n%28 = OpAccessChain %22 %11 %29\nOpStore %28 %21\nOpStore %13 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.export-viewport.view-instancing-viewport-offset.vert",
    "content": "#version 460\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nlayout(location = 0) in uint VP;\n\nvoid main()\n{\n    float _24 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _24;\n    gl_Position.y = _24;\n    gl_Position.z = _24;\n    gl_Position.w = _24;\n    gl_ViewportIndex = int(VP);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability MultiViewport\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %7 %11 %13\nOpName %3 \"main\"\nOpName %7 \"VP\"\nOpName %11 \"SV_Position\"\nOpName %13 \"SV_ViewportArrayIndex\"\nOpName %15 \"ViewInstancingOffsetsUBO\"\nOpMemberName %15 0 \"ViewID_Layer\"\nOpName %17 \"ViewInstancingOffsets\"\nOpDecorate %7 Location 0\nOpDecorate %11 BuiltIn Position\nOpDecorate %13 BuiltIn ViewportIndex\nOpDecorate %15 Block\nOpMemberDecorate %15 0 Offset 0\nOpDecorate %17 DescriptorSet 10\nOpDecorate %17 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypePointer Input %5\n%7 = OpVariable %6 Input\n%8 = OpTypeFloat 32\n%9 = OpTypeVector %8 4\n%10 = OpTypePointer Output %9\n%11 = OpVariable %10 Output\n%12 = OpTypePointer Output %5\n%13 = OpVariable %12 Output\n%15 = OpTypeStruct %5\n%16 = OpTypePointer Uniform %15\n%17 = OpVariable %16 Uniform\n%18 = OpTypePointer Uniform %5\n%20 = OpConstant %5 0\n%23 = OpConstant %5 16\n%25 = OpTypePointer Output %8\n%28 = OpConstant %5 1\n%30 = OpConstant %5 2\n%32 = OpConstant %5 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%14 = OpLoad %5 %7\n%19 = OpAccessChain %18 %17 %20\n%21 = OpLoad %5 %19\n%22 = OpBitFieldUExtract %5 %21 %20 %23\n%24 = OpConvertUToF %8 %22\n%26 = OpAccessChain %25 %11 %20\nOpStore %26 %24\n%27 = OpAccessChain %25 %11 %28\nOpStore %27 %24\n%29 = OpAccessChain %25 %11 %30\nOpStore %29 %24\n%31 = OpAccessChain %25 %11 %32\nOpStore %31 %24\nOpStore %13 %14\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.last-pre-raster.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nvoid main()\n{\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    float _24 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _24;\n    gl_Position.y = _24;\n    gl_Position.z = _24;\n    gl_Position.w = _24;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %20\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %10 \"ViewInstancingOffsetsUBO\"\nOpMemberName %10 0 \"ViewID_Layer\"\nOpName %12 \"ViewInstancingOffsets\"\nOpDecorate %8 BuiltIn Position\nOpDecorate %10 Block\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %12 DescriptorSet 10\nOpDecorate %12 Binding 22\nOpDecorate %20 BuiltIn Layer\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Uniform %9\n%15 = OpConstant %9 0\n%18 = OpConstant %9 16\n%19 = OpTypePointer Output %9\n%20 = OpVariable %19 Output\n%25 = OpTypePointer Output %5\n%28 = OpConstant %9 1\n%30 = OpConstant %9 2\n%32 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %33\n%33 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %9 %14\n%17 = OpBitFieldUExtract %9 %16 %18 %18\nOpStore %20 %17\n%21 = OpAccessChain %13 %12 %15\n%22 = OpLoad %9 %21\n%23 = OpBitFieldUExtract %9 %22 %15 %18\n%24 = OpConvertUToF %5 %23\n%26 = OpAccessChain %25 %8 %15\nOpStore %26 %24\n%27 = OpAccessChain %25 %8 %28\nOpStore %27 %24\n%29 = OpAccessChain %25 %8 %30\nOpStore %29 %24\n%31 = OpAccessChain %25 %8 %32\nOpStore %31 %24\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.vert",
    "content": "#version 460\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nvoid main()\n{\n    float _19 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _19;\n    gl_Position.y = _19;\n    gl_Position.z = _19;\n    gl_Position.w = _19;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %10 \"ViewInstancingOffsetsUBO\"\nOpMemberName %10 0 \"ViewID_Layer\"\nOpName %12 \"ViewInstancingOffsets\"\nOpDecorate %8 BuiltIn Position\nOpDecorate %10 Block\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %12 DescriptorSet 10\nOpDecorate %12 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Uniform %9\n%15 = OpConstant %9 0\n%18 = OpConstant %9 16\n%20 = OpTypePointer Output %5\n%23 = OpConstant %9 1\n%25 = OpConstant %9 2\n%27 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %9 %14\n%17 = OpBitFieldUExtract %9 %16 %15 %18\n%19 = OpConvertUToF %5 %17\n%21 = OpAccessChain %20 %8 %15\nOpStore %21 %19\n%22 = OpAccessChain %20 %8 %23\nOpStore %22 %19\n%24 = OpAccessChain %20 %8 %25\nOpStore %24 %19\n%26 = OpAccessChain %20 %8 %27\nOpStore %26 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.view-instance-mask.last-pre-raster.vert",
    "content": "#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nlayout(set = 10, binding = 23, std140) uniform ViewInstanceMaskUBO\n{\n    uint Mask;\n} ViewInstanceMask;\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nvoid main()\n{\n    gl_Position = vec4(-1.0);\n    if (bitfieldExtract(ViewInstanceMask.Mask, int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u))), int(1u)) == 0u)\n    {\n        return;\n    }\n    gl_Layer = int(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(16u), int(16u)));\n    float _38 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _38;\n    gl_Position.y = _38;\n    gl_Position.z = _38;\n    gl_Position.w = _38;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 51\n; Schema: 0\nOpCapability Shader\nOpCapability Geometry\nOpCapability ShaderViewportIndexLayerEXT\nOpExtension \"SPV_EXT_shader_viewport_index_layer\"\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %34\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %10 \"ViewInstanceMaskUBO\"\nOpMemberName %10 0 \"Mask\"\nOpName %12 \"ViewInstanceMask\"\nOpName %13 \"ViewInstancingOffsetsUBO\"\nOpMemberName %13 0 \"ViewID_Layer\"\nOpName %15 \"ViewInstancingOffsets\"\nOpDecorate %8 BuiltIn Position\nOpDecorate %10 Block\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %12 DescriptorSet 10\nOpDecorate %12 Binding 23\nOpDecorate %13 Block\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %15 DescriptorSet 10\nOpDecorate %15 Binding 22\nOpDecorate %34 BuiltIn Layer\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypeStruct %9\n%14 = OpTypePointer Uniform %13\n%15 = OpVariable %14 Uniform\n%16 = OpTypePointer Uniform %9\n%18 = OpConstant %9 0\n%21 = OpConstant %9 16\n%25 = OpConstant %9 1\n%26 = OpTypeBool\n%28 = OpConstant %5 -1\n%29 = OpConstantComposite %6 %28 %28 %28 %28\n%33 = OpTypePointer Output %9\n%34 = OpVariable %33 Output\n%39 = OpTypePointer Output %5\n%43 = OpConstant %9 2\n%45 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%17 = OpAccessChain %16 %15 %18\n%19 = OpLoad %9 %17\n%20 = OpBitFieldUExtract %9 %19 %18 %21\n%22 = OpAccessChain %16 %12 %18\n%23 = OpLoad %9 %22\n%24 = OpBitFieldUExtract %9 %23 %20 %25\n%27 = OpIEqual %26 %24 %18\nOpStore %8 %29\nOpSelectionMerge %48 None\nOpBranchConditional %27 %47 %48\n%47 = OpLabel\nOpReturn\n%48 = OpLabel\n%30 = OpAccessChain %16 %15 %18\n%31 = OpLoad %9 %30\n%32 = OpBitFieldUExtract %9 %31 %21 %21\nOpStore %34 %32\n%35 = OpAccessChain %16 %15 %18\n%36 = OpLoad %9 %35\n%37 = OpBitFieldUExtract %9 %36 %18 %21\n%38 = OpConvertUToF %5 %37\n%40 = OpAccessChain %39 %8 %18\nOpStore %40 %38\n%41 = OpAccessChain %39 %8 %25\nOpStore %41 %38\n%42 = OpAccessChain %39 %8 %43\nOpStore %42 %38\n%44 = OpAccessChain %39 %8 %45\nOpStore %44 %38\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.view-instance-mask.vert",
    "content": "#version 460\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nvoid main()\n{\n    float _19 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _19;\n    gl_Position.y = _19;\n    gl_Position.z = _19;\n    gl_Position.w = _19;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %10 \"ViewInstancingOffsetsUBO\"\nOpMemberName %10 0 \"ViewID_Layer\"\nOpName %12 \"ViewInstancingOffsets\"\nOpDecorate %8 BuiltIn Position\nOpDecorate %10 Block\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %12 DescriptorSet 10\nOpDecorate %12 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Uniform %9\n%15 = OpConstant %9 0\n%18 = OpConstant %9 16\n%20 = OpTypePointer Output %5\n%23 = OpConstant %9 1\n%25 = OpConstant %9 2\n%27 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %9 %14\n%17 = OpBitFieldUExtract %9 %16 %15 %18\n%19 = OpConvertUToF %5 %17\n%21 = OpAccessChain %20 %8 %15\nOpStore %21 %19\n%22 = OpAccessChain %20 %8 %23\nOpStore %22 %19\n%24 = OpAccessChain %20 %8 %25\nOpStore %24 %19\n%26 = OpAccessChain %20 %8 %27\nOpStore %26 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.view-instancing-multiview.vert",
    "content": "#version 460\n#extension GL_EXT_multiview : require\n\nlayout(constant_id = 1000) const uint ViewIndexToViewInstanceMap = 0u;\n\nvoid main()\n{\n    float _17 = float(bitfieldExtract(ViewIndexToViewInstanceMap, int(gl_ViewIndex * 2u), int(2u)));\n    gl_Position.x = _17;\n    gl_Position.y = _17;\n    gl_Position.z = _17;\n    gl_Position.w = _17;\n}\n\n\n#if 0\n// SPIR-V disassembly\n// MultiviewCompatible\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\nOpCapability Shader\nOpCapability MultiView\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8 %12\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %10 \"ViewIndexToViewInstanceMap\"\nOpDecorate %8 BuiltIn Position\nOpDecorate %10 SpecId 1000\nOpDecorate %12 BuiltIn ViewIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpSpecConstant %9 0\n%11 = OpTypePointer Input %9\n%12 = OpVariable %11 Input\n%15 = OpConstant %9 2\n%18 = OpTypePointer Output %5\n%20 = OpConstant %9 0\n%22 = OpConstant %9 1\n%25 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %26\n%26 = OpLabel\n%13 = OpLoad %9 %12\n%14 = OpIMul %9 %13 %15\n%16 = OpBitFieldUExtract %9 %10 %14 %15\n%17 = OpConvertUToF %5 %16\n%19 = OpAccessChain %18 %8 %20\nOpStore %19 %17\n%21 = OpAccessChain %18 %8 %22\nOpStore %21 %17\n%23 = OpAccessChain %18 %8 %15\nOpStore %23 %17\n%24 = OpAccessChain %18 %8 %25\nOpStore %24 %17\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/view-instancing/vert/basic.view-instancing.view-instancing-viewport-offset.vert",
    "content": "#version 460\n\nlayout(set = 10, binding = 22, std140) uniform ViewInstancingOffsetsUBO\n{\n    uint ViewID_Layer;\n} ViewInstancingOffsets;\n\nvoid main()\n{\n    float _19 = float(bitfieldExtract(ViewInstancingOffsets.ViewID_Layer, int(0u), int(16u)));\n    gl_Position.x = _19;\n    gl_Position.y = _19;\n    gl_Position.z = _19;\n    gl_Position.w = _19;\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.3\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\nOpCapability Shader\nOpMemoryModel Logical GLSL450\nOpEntryPoint Vertex %3 \"main\" %8\nOpName %3 \"main\"\nOpName %8 \"SV_Position\"\nOpName %10 \"ViewInstancingOffsetsUBO\"\nOpMemberName %10 0 \"ViewID_Layer\"\nOpName %12 \"ViewInstancingOffsets\"\nOpDecorate %8 BuiltIn Position\nOpDecorate %10 Block\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %12 DescriptorSet 10\nOpDecorate %12 Binding 22\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeVector %5 4\n%7 = OpTypePointer Output %6\n%8 = OpVariable %7 Output\n%9 = OpTypeInt 32 0\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpTypePointer Uniform %9\n%15 = OpConstant %9 0\n%18 = OpConstant %9 16\n%20 = OpTypePointer Output %5\n%23 = OpConstant %9 1\n%25 = OpConstant %9 2\n%27 = OpConstant %9 3\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %28\n%28 = OpLabel\n%14 = OpAccessChain %13 %12 %15\n%16 = OpLoad %9 %14\n%17 = OpBitFieldUExtract %9 %16 %15 %18\n%19 = OpConvertUToF %5 %17\n%21 = OpAccessChain %20 %8 %15\nOpStore %21 %19\n%22 = OpAccessChain %20 %8 %23\nOpStore %22 %19\n%24 = OpAccessChain %20 %8 %25\nOpStore %24 %19\n%26 = OpAccessChain %20 %8 %27\nOpStore %26 %19\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/coopmat.sm66.ssbo.vkmm.comp",
    "content": "#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require\n#extension GL_EXT_shader_8bit_storage : require\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_KHR_cooperative_matrix : require\n#extension GL_KHR_memory_scope_semantics : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint8_t _m0[];\n} _20;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _22_24\n{\n    uint8_t _m0[];\n} _24;\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _33)\n{\n    uint _41;\n    _41 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;\n    for (;;)\n    {\n        uint _42 = _41 + 1u;\n        coop_output[_41] = int16BitsToFloat16((int16_t(int8_t(_33[_41])) << 7s) & (-16385s));\n        if (_42 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))\n        {\n            _41 = _42;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\ncoopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _68)\n{\n    uint _76;\n    _76 = 0u;\n    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;\n    for (;;)\n    {\n        uint _77 = _76 + 1u;\n        coop_output[_76] = int16BitsToFloat16((int16_t(int8_t(_68[_76])) << 7s) & (-16385s));\n        if (_77 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))\n        {\n            _76 = _77;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return coop_output * float16_t(256.0);\n}\n\nvoid main()\n{\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _29;\n    coopMatLoad(_29, _20._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _60 = _29;\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _65;\n    coopMatLoad(_65, _20._m0, 256u, 16u, gl_CooperativeMatrixLayoutRowMajor);\n    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _89 = _65;\n    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _94;\n    coopMatLoad(_94, _20._m0, 512u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n    coopMatStore(coopMatMulAdd(CoopMatFP8toFP16(_60), CoopMatFP8toFP16_1(_89), _94, 0), _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);\n}\n\n\n#if 0\n// SPIR-V disassembly\n// WaveSize(32)\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 99\n; Schema: 0\nOpCapability Shader\nOpCapability Float16\nOpCapability Int16\nOpCapability Int8\nOpCapability StorageBuffer8BitAccess\nOpCapability DenormPreserve\nOpCapability VulkanMemoryModel\nOpCapability CooperativeMatrixKHR\nOpExtension \"SPV_KHR_8bit_storage\"\nOpExtension \"SPV_KHR_cooperative_matrix\"\nOpExtension \"SPV_KHR_float_controls\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %14 \"main\" %20 %24\nOpExecutionMode %14 LocalSize 32 1 1\nOpExecutionMode %14 DenormPreserve 16\nOpName %14 \"main\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %34 \"CoopMatFP8toFP16\"\nOpName %37 \"coop_output\"\nOpName %69 \"CoopMatFP8toFP16\"\nOpName %72 \"coop_output\"\nOpDecorate %17 ArrayStride 1\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 1\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 0\nOpDecorate %24 NonReadable\n%1 = OpTypeFloat 16\n%2 = OpTypeInt 32 0\n%3 = OpConstant %2 0\n%4 = OpConstant %2 16\n%6 = OpConstant %2 3\n%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3\n%7 = OpConstant %2 1\n%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7\n%9 = OpTypeFloat 32\n%10 = OpConstant %2 2\n%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10\n%12 = OpTypeVoid\n%13 = OpTypeFunction %12\n%16 = OpTypeInt 8 0\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %16\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%26 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %3\n%27 = OpTypePointer StorageBuffer %16\n%30 = OpTypeBool\n%31 = OpTypePointer Function %26\n%32 = OpTypeFunction %5 %31\n%36 = OpTypePointer Function %5\n%43 = OpTypePointer Function %16\n%46 = OpTypeInt 16 1\n%49 = OpConstant %46 7\n%51 = OpConstant %46 -16385\n%53 = OpTypePointer Function %1\n%58 = OpConstant %1 0x1p+8\n%62 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %7\n%64 = OpConstant %2 256\n%66 = OpTypePointer Function %62\n%67 = OpTypeFunction %8 %66\n%71 = OpTypePointer Function %8\n%92 = OpConstant %2 512\n%93 = OpConstant %2 64\n%14 = OpFunction %12 None %13\n%15 = OpLabel\n%60 = OpVariable %31 Function\n%89 = OpVariable %66 Function\nOpBranch %97\n%97 = OpLabel\n%28 = OpAccessChain %27 %20 %3 %3\n%29 = OpCooperativeMatrixLoadKHR %26 %28 %3 %4 NonPrivatePointer\nOpStore %60 %29\n%61 = OpFunctionCall %5 %34 %60\n%63 = OpAccessChain %27 %20 %3 %64\n%65 = OpCooperativeMatrixLoadKHR %62 %63 %3 %4 NonPrivatePointer\nOpStore %89 %65\n%90 = OpFunctionCall %8 %69 %89\n%91 = OpAccessChain %27 %20 %3 %92\n%94 = OpCooperativeMatrixLoadKHR %11 %91 %3 %93 NonPrivatePointer\n%95 = OpCooperativeMatrixMulAddKHR %11 %61 %90 %94\n%96 = OpAccessChain %27 %24 %3 %3\nOpCooperativeMatrixStoreKHR %96 %95 %3 %93 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n%34 = OpFunction %5 None %32\n%33 = OpFunctionParameter %31\n%35 = OpLabel\n%37 = OpVariable %36 Function\n%38 = OpCooperativeMatrixLengthKHR %2 %26\nOpBranch %39\n%39 = OpLabel\n%41 = OpPhi %2 %3 %35 %42 %39\n%42 = OpIAdd %2 %41 %7\n%44 = OpInBoundsAccessChain %43 %33 %41\n%45 = OpLoad %16 %44\n%47 = OpSConvert %46 %45\n%48 = OpShiftLeftLogical %46 %47 %49\n%50 = OpBitwiseAnd %46 %48 %51\n%52 = OpBitcast %1 %50\n%54 = OpInBoundsAccessChain %53 %37 %41\nOpStore %54 %52\n%55 = OpULessThan %30 %42 %38\nOpLoopMerge %40 %39 None\nOpBranchConditional %55 %39 %40\n%40 = OpLabel\n%56 = OpLoad %5 %37\n%57 = OpMatrixTimesScalar %5 %56 %58\nOpReturnValue %57\nOpFunctionEnd\n%69 = OpFunction %8 None %67\n%68 = OpFunctionParameter %66\n%70 = OpLabel\n%72 = OpVariable %71 Function\n%73 = OpCooperativeMatrixLengthKHR %2 %62\nOpBranch %74\n%74 = OpLabel\n%76 = OpPhi %2 %3 %70 %77 %74\n%77 = OpIAdd %2 %76 %7\n%78 = OpInBoundsAccessChain %43 %68 %76\n%79 = OpLoad %16 %78\n%80 = OpSConvert %46 %79\n%81 = OpShiftLeftLogical %46 %80 %49\n%82 = OpBitwiseAnd %46 %81 %51\n%83 = OpBitcast %1 %82\n%84 = OpInBoundsAccessChain %53 %72 %76\nOpStore %84 %83\n%85 = OpULessThan %30 %77 %73\nOpLoopMerge %75 %74 None\nOpBranchConditional %85 %74 %75\n%75 = OpLabel\n%86 = OpLoad %8 %72\n%87 = OpMatrixTimesScalar %8 %86 %58\nOpReturnValue %87\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/cross_group_sharing.vkmm.node.inline-ubo.comp",
    "content": "#version 460\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x_id = 0, local_size_y_id = 1, local_size_z_id = 2) in;\n\nlayout(buffer_reference) buffer NodeReadonlyU32Ptr;\nlayout(buffer_reference) buffer NodeReadonlyU32ArrayPtr;\nlayout(buffer_reference) buffer NodeReadonlyU64Ptr;\nlayout(buffer_reference) buffer _50;\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(constant_id = 4) const bool NodeEntryIndirectPayloadStride = false;\nlayout(constant_id = 3) const bool NodeIsProgramEntry = false;\nlayout(constant_id = 5) const bool DispatchGridIsUpperBound = true;\nlayout(constant_id = 6) const bool DispatchStaticPayload = false;\nlayout(constant_id = 7) const uint MaxBroadcastGridX = 1024u;\nconst uint GridXMinus1 = (MaxBroadcastGridX - 1u);\nlayout(constant_id = 8) const uint MaxBroadcastGridY = 1u;\nconst uint GridYMinus1 = (MaxBroadcastGridY - 1u);\nlayout(constant_id = 9) const uint MaxBroadcastGridZ = 1u;\nconst uint GridZMinus1 = (MaxBroadcastGridZ - 1u);\nconst uvec3 ThreadGroupSize = uvec3(gl_WorkGroupSize.x, gl_WorkGroupSize.y, gl_WorkGroupSize.z);\n\nstruct anon_data\n{\n    uint _m0;\n    uint _m1;\n};\n\nconst uint _174 = (MaxBroadcastGridX * MaxBroadcastGridY);\nconst uint _175 = (_174 * MaxBroadcastGridZ);\nconst uint _239 = (MaxBroadcastGridX * MaxBroadcastGridY);\nconst uint _240 = (_239 * MaxBroadcastGridZ);\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer NodeReadonlyU32Ptr\n{\n    uint value;\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer NodeReadonlyU32ArrayPtr\n{\n    uint offsets[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 8, std430) readonly buffer NodeReadonlyU64Ptr\n{\n    uint64_t value;\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) buffer _50\n{\n    anon_data data;\n};\n\nlayout(push_constant, std430) uniform NodeDispatchRegisters\n{\n    uint64_t PayloadLinearBDA;\n    NodeReadonlyU32Ptr NodeLinearOffsetBDA;\n    NodeReadonlyU32Ptr NodeEndNodesBDA;\n    uvec2 NodePayloadStrideOrOffsetsBDA;\n    uint64_t NodePayloadOutputBDA;\n    uint64_t NodePayloadOutputAtomicBDA;\n    uvec2 NodeLocalRootSignatureBDA;\n    uint NodePayloadOutputOffset;\n    uint NodeRemainingRecursionLevels;\n} NodeDispatch;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer RWBuf0;\n\nuint64_t NodeInputPayloadBDA;\nuint NodeInputStride;\nuvec3 WorkgroupID;\nuvec3 GlobalInvocationID;\nuint NodeCoalesceOffset;\nuint NodeCoalesceCount;\nshared bool FinishCrossGroupSharingBroadcast;\n\nbool FinishCrossGroupSharing(uint64_t CounterBDA)\n{\n    if (gl_LocalInvocationIndex == 0u)\n    {\n        uint _79 = atomicAdd(uintPointer(CounterBDA).value, uint(-1));\n        FinishCrossGroupSharingBroadcast = _79 == 1u;\n    }\n    barrier();\n    return FinishCrossGroupSharingBroadcast;\n}\n\nvoid node_main()\n{\n    uint64_t _53 = NodeInputPayloadBDA;\n    _50 _54 = _50(_53);\n    uint _59 = atomicAdd(_54.data._m1, 1u);\n    _54.data._m1 += 3u;\n    groupMemoryBarrier();\n    barrier();\n    uint64_t _84 = NodeInputPayloadBDA;\n    bool _87 = FinishCrossGroupSharing(_84 + 8ul);\n    if (_87)\n    {\n        uint _93 = imageAtomicAdd(RWBuf0, int(gl_LocalInvocationIndex), _54.data._m1);\n    }\n}\n\nvoid main()\n{\n    uint _108 = DispatchStaticPayload ? NodeDispatch.NodeLinearOffsetBDA.value : (((gl_WorkGroupID.y * 32768u) + gl_WorkGroupID.x) + NodeDispatch.NodeLinearOffsetBDA.value);\n    NodeInputPayloadBDA = NodeDispatch.PayloadLinearBDA;\n    if (NodeIsProgramEntry)\n    {\n        NodeInputStride = NodeDispatch.NodePayloadStrideOrOffsetsBDA.x;\n        if (NodeEntryIndirectPayloadStride)\n        {\n            NodeInputPayloadBDA = NodeReadonlyU64Ptr(NodeDispatch.PayloadLinearBDA).value;\n            NodeInputStride = NodeReadonlyU32Ptr(NodeDispatch.NodePayloadStrideOrOffsetsBDA).value;\n        }\n    }\n    if (DispatchGridIsUpperBound)\n    {\n        if (NodeIsProgramEntry)\n        {\n            NodeInputPayloadBDA += uint64_t(_108 * NodeInputStride);\n            uintPointer _137 = uintPointer(NodeInputPayloadBDA + 0ul);\n            uint _139 = _137.value - 1u;\n            uint _141 = uint(findMSB(_139)) + 1u;\n            uint _146 = (int(_139) < int(0u)) ? 0u : (_137.value << 0u);\n            for (uint amplification_index = gl_WorkGroupID.z; amplification_index < _146; amplification_index += gl_NumWorkGroups.z)\n            {\n                uvec3 _151 = uvec3(bitfieldExtract(amplification_index, int(0u), int(_141)), 0u, 0u);\n                WorkgroupID = _151;\n                GlobalInvocationID = (ThreadGroupSize * _151) + gl_LocalInvocationID;\n                if (all(lessThanEqual(_151, uvec3(_139, 0u, 0u))))\n                {\n                    node_main();\n                    barrier();\n                }\n            }\n        }\n        else\n        {\n            NodeInputPayloadBDA += uint64_t(NodeReadonlyU32ArrayPtr(NodeDispatch.NodePayloadStrideOrOffsetsBDA).offsets[_108]);\n            uintPointer _202 = uintPointer(NodeInputPayloadBDA + 0ul);\n            uint _204 = _202.value - 1u;\n            uint _206 = uint(findMSB(_204)) + 1u;\n            uint _211 = (int(_204) < int(0u)) ? 0u : (_202.value << 0u);\n            for (uint amplification_index_1 = gl_WorkGroupID.z; amplification_index_1 < _211; amplification_index_1 += gl_NumWorkGroups.z)\n            {\n                uvec3 _216 = uvec3(bitfieldExtract(amplification_index_1, int(0u), int(_206)), 0u, 0u);\n                WorkgroupID = _216;\n                GlobalInvocationID = (ThreadGroupSize * _216) + gl_LocalInvocationID;\n                if (all(lessThanEqual(_216, uvec3(_204, 0u, 0u))))\n                {\n                    node_main();\n                    barrier();\n                }\n            }\n        }\n    }\n    else\n    {\n        if (NodeIsProgramEntry)\n        {\n            NodeInputPayloadBDA += uint64_t(_108 * NodeInputStride);\n            if (DispatchStaticPayload)\n            {\n                WorkgroupID = gl_WorkGroupID;\n                GlobalInvocationID = gl_GlobalInvocationID;\n                node_main();\n            }\n            else\n            {\n                for (uint amplification_index_2 = gl_WorkGroupID.z; amplification_index_2 < _175; amplification_index_2 += gl_NumWorkGroups.z)\n                {\n                    uint _180 = amplification_index_2 / MaxBroadcastGridX;\n                    uvec3 _183 = uvec3(amplification_index_2 % MaxBroadcastGridX, _180 % MaxBroadcastGridY, _180 / MaxBroadcastGridY);\n                    WorkgroupID = _183;\n                    GlobalInvocationID = (ThreadGroupSize * _183) + gl_LocalInvocationID;\n                    node_main();\n                    barrier();\n                }\n            }\n        }\n        else\n        {\n            NodeInputPayloadBDA += uint64_t(NodeReadonlyU32ArrayPtr(NodeDispatch.NodePayloadStrideOrOffsetsBDA).offsets[_108]);\n            if (DispatchStaticPayload)\n            {\n                WorkgroupID = gl_WorkGroupID;\n                GlobalInvocationID = gl_GlobalInvocationID;\n                node_main();\n            }\n            else\n            {\n                for (uint amplification_index_3 = gl_WorkGroupID.z; amplification_index_3 < _240; amplification_index_3 += gl_NumWorkGroups.z)\n                {\n                    uint _245 = amplification_index_3 / MaxBroadcastGridX;\n                    uvec3 _248 = uvec3(amplification_index_3 % MaxBroadcastGridX, _245 % MaxBroadcastGridY, _245 / MaxBroadcastGridY);\n                    WorkgroupID = _248;\n                    GlobalInvocationID = (ThreadGroupSize * _248) + gl_LocalInvocationID;\n                    node_main();\n                    barrier();\n                }\n            }\n        }\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 300\n; Schema: 0\nOpCapability Shader\nOpCapability Int64\nOpCapability ImageBuffer\nOpCapability VulkanMemoryModel\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\n%133 = OpExtInstImport \"GLSL.std.450\"\nOpMemoryModel PhysicalStorageBuffer64 Vulkan\nOpEntryPoint GLCompute %3 \"main\" %9 %11 %14 %15 %23 %24 %25 %46 %73 %75 %95 %130 %153 %166\nOpExecutionModeId %3 LocalSizeId %40 %41 %42\nOpName %3 \"main\"\nOpName %9 \"NodeInputPayloadBDA\"\nOpName %11 \"NodeInputStride\"\nOpName %14 \"WorkgroupID\"\nOpName %15 \"GlobalInvocationID\"\nOpName %17 \"NodeReadonlyU32Ptr\"\nOpMemberName %17 0 \"value\"\nOpName %19 \"NodeReadonlyU32ArrayPtr\"\nOpMemberName %19 0 \"offsets\"\nOpName %21 \"NodeDispatchRegisters\"\nOpMemberName %21 0 \"PayloadLinearBDA\"\nOpMemberName %21 1 \"NodeLinearOffsetBDA\"\nOpMemberName %21 2 \"NodeEndNodesBDA\"\nOpMemberName %21 3 \"NodePayloadStrideOrOffsetsBDA\"\nOpMemberName %21 4 \"NodePayloadOutputBDA\"\nOpMemberName %21 5 \"NodePayloadOutputAtomicBDA\"\nOpMemberName %21 6 \"NodeLocalRootSignatureBDA\"\nOpMemberName %21 7 \"NodePayloadOutputOffset\"\nOpMemberName %21 8 \"NodeRemainingRecursionLevels\"\nOpName %23 \"NodeDispatch\"\nOpName %24 \"NodeCoalesceOffset\"\nOpName %25 \"NodeCoalesceCount\"\nOpName %26 \"NodeReadonlyU64Ptr\"\nOpMemberName %26 0 \"value\"\nOpName %29 \"NodeEntryIndirectPayloadStride\"\nOpName %30 \"NodeIsProgramEntry\"\nOpName %31 \"DispatchGridIsUpperBound\"\nOpName %32 \"DispatchStaticPayload\"\nOpName %33 \"MaxBroadcastGridX\"\nOpName %35 \"GridXMinus1\"\nOpName %36 \"MaxBroadcastGridY\"\nOpName %37 \"GridYMinus1\"\nOpName %38 \"MaxBroadcastGridZ\"\nOpName %39 \"GridZMinus1\"\nOpName %43 \"ThreadGroupSize\"\nOpName %46 \"RWBuf0\"\nOpName %47 \"node_main\"\nOpName %49 \"\"\nOpName %50 \"\"\nOpMemberName %50 0 \"data\"\nOpName %68 \"FinishCrossGroupSharing\"\nOpName %67 \"CounterBDA\"\nOpName %75 \"FinishCrossGroupSharingBroadcast\"\nOpName %147 \"amplification_index\"\nOpName %176 \"amplification_index\"\nOpName %212 \"amplification_index\"\nOpName %241 \"amplification_index\"\nOpDecorate %16 ArrayStride 4\nOpDecorate %17 Block\nOpMemberDecorate %17 0 Offset 0\nOpMemberDecorate %17 0 NonWritable\nOpDecorate %19 Block\nOpMemberDecorate %19 0 Offset 0\nOpMemberDecorate %19 0 NonWritable\nOpMemberDecorate %21 0 Offset 0\nOpMemberDecorate %21 1 Offset 8\nOpMemberDecorate %21 2 Offset 16\nOpMemberDecorate %21 3 Offset 24\nOpMemberDecorate %21 4 Offset 32\nOpMemberDecorate %21 5 Offset 40\nOpMemberDecorate %21 6 Offset 48\nOpMemberDecorate %21 7 Offset 56\nOpMemberDecorate %21 8 Offset 60\nOpDecorate %21 Block\nOpDecorate %23 RestrictPointer\nOpDecorate %26 Block\nOpMemberDecorate %26 0 Offset 0\nOpMemberDecorate %26 0 NonWritable\nOpDecorate %29 SpecId 4\nOpDecorate %30 SpecId 3\nOpDecorate %31 SpecId 5\nOpDecorate %32 SpecId 6\nOpDecorate %33 SpecId 7\nOpDecorate %36 SpecId 8\nOpDecorate %38 SpecId 9\nOpDecorate %40 SpecId 0\nOpDecorate %41 SpecId 1\nOpDecorate %42 SpecId 2\nOpDecorate %46 DescriptorSet 0\nOpDecorate %46 Binding 0\nOpMemberDecorate %49 0 Offset 0\nOpMemberDecorate %49 1 Offset 4\nOpDecorate %50 Block\nOpMemberDecorate %50 0 Offset 0\nOpDecorate %73 BuiltIn LocalInvocationIndex\nOpDecorate %95 BuiltIn WorkgroupId\nOpDecorate %130 BuiltIn NumWorkgroups\nOpDecorate %153 BuiltIn LocalInvocationId\nOpDecorate %166 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeInt 64 0\n%8 = OpTypePointer Private %7\n%9 = OpVariable %8 Private\n%10 = OpTypePointer Private %5\n%11 = OpVariable %10 Private\n%12 = OpTypeVector %5 3\n%13 = OpTypePointer Private %12\n%14 = OpVariable %13 Private\n%15 = OpVariable %13 Private\n%16 = OpTypeRuntimeArray %5\n%17 = OpTypeStruct %5\n%18 = OpTypePointer PhysicalStorageBuffer %17\n%19 = OpTypeStruct %16\n%20 = OpTypePointer PhysicalStorageBuffer %19\n%21 = OpTypeStruct %7 %18 %18 %6 %7 %7 %6 %5 %5\n%22 = OpTypePointer PushConstant %21\n%23 = OpVariable %22 PushConstant\n%24 = OpVariable %10 Private\n%25 = OpVariable %10 Private\n%26 = OpTypeStruct %7\n%27 = OpTypePointer PhysicalStorageBuffer %26\n%28 = OpTypeBool\n%29 = OpSpecConstantFalse %28\n%30 = OpSpecConstantFalse %28\n%31 = OpSpecConstantTrue %28\n%32 = OpSpecConstantFalse %28\n%33 = OpSpecConstant %5 1024\n%34 = OpConstant %5 1\n%35 = OpSpecConstantOp %5 ISub %33 %34\n%36 = OpSpecConstant %5 1\n%37 = OpSpecConstantOp %5 ISub %36 %34\n%38 = OpSpecConstant %5 1\n%39 = OpSpecConstantOp %5 ISub %38 %34\n%40 = OpSpecConstant %5 64\n%41 = OpSpecConstant %5 1\n%42 = OpSpecConstant %5 1\n%43 = OpSpecConstantComposite %12 %40 %41 %42\n%44 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%45 = OpTypePointer UniformConstant %44\n%46 = OpVariable %45 UniformConstant\n%49 = OpTypeStruct %5 %5\n%50 = OpTypeStruct %49\n%51 = OpTypePointer PhysicalStorageBuffer %50\n%52 = OpTypePointer PhysicalStorageBuffer %49\n%56 = OpConstant %5 0\n%57 = OpTypePointer PhysicalStorageBuffer %5\n%60 = OpConstant %5 2\n%62 = OpConstant %5 5\n%64 = OpConstant %5 3\n%65 = OpConstant %5 24648\n%66 = OpTypeFunction %28 %7\n%72 = OpTypePointer Input %5\n%73 = OpVariable %72 Input\n%74 = OpTypePointer Workgroup %28\n%75 = OpVariable %74 Workgroup\n%81 = OpConstant %5 24840\n%86 = OpConstant %7 8\n%91 = OpTypePointer Image %5\n%94 = OpTypePointer Input %12\n%95 = OpVariable %94 Input\n%100 = OpConstant %5 32768\n%102 = OpTypePointer PushConstant %18\n%109 = OpTypePointer PushConstant %7\n%112 = OpTypePointer PushConstant %6\n%117 = OpTypePointer PhysicalStorageBuffer %7\n%130 = OpVariable %94 Input\n%136 = OpConstant %7 0\n%153 = OpVariable %94 Input\n%156 = OpTypeVector %28 3\n%166 = OpVariable %94 Input\n%174 = OpSpecConstantOp %5 IMul %33 %36\n%175 = OpSpecConstantOp %5 IMul %174 %38\n%239 = OpSpecConstantOp %5 IMul %33 %36\n%240 = OpSpecConstantOp %5 IMul %239 %38\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %253\n%253 = OpLabel\n%96 = OpLoad %12 %95\n%97 = OpCompositeExtract %5 %96 0\n%98 = OpCompositeExtract %5 %96 1\n%99 = OpIMul %5 %98 %100\n%101 = OpIAdd %5 %99 %97\n%103 = OpAccessChain %102 %23 %34\n%104 = OpLoad %18 %103\n%105 = OpAccessChain %57 %104 %56\n%106 = OpLoad %5 %105 Aligned 4\n%107 = OpIAdd %5 %101 %106\n%108 = OpSelect %5 %32 %106 %107\n%110 = OpAccessChain %109 %23 %56\n%111 = OpLoad %7 %110\nOpStore %9 %111\nOpSelectionMerge %257 None\nOpBranchConditional %30 %254 %257\n%254 = OpLabel\n%113 = OpAccessChain %112 %23 %64\n%114 = OpLoad %6 %113\n%115 = OpCompositeExtract %5 %114 0\nOpStore %11 %115\nOpSelectionMerge %256 None\nOpBranchConditional %29 %255 %256\n%255 = OpLabel\n%116 = OpConvertUToPtr %27 %111\n%118 = OpAccessChain %117 %116 %56\n%119 = OpLoad %7 %118 Aligned 8\nOpStore %9 %119\n%120 = OpBitcast %18 %114\n%121 = OpAccessChain %57 %120 %56\n%122 = OpLoad %5 %121 Aligned 4\nOpStore %11 %122\nOpBranch %256\n%256 = OpLabel\nOpBranch %257\n%257 = OpLabel\nOpSelectionMerge %290 None\nOpBranchConditional %31 %278 %258\n%278 = OpLabel\nOpSelectionMerge %289 None\nOpBranchConditional %30 %286 %279\n%286 = OpLabel\n%123 = OpLoad %7 %9\n%124 = OpLoad %5 %11\n%125 = OpIMul %5 %108 %124\n%126 = OpUConvert %7 %125\n%127 = OpIAdd %7 %123 %126\nOpStore %9 %127\n%128 = OpLoad %12 %95\n%129 = OpCompositeExtract %5 %128 2\n%131 = OpLoad %12 %130\n%132 = OpCompositeExtract %5 %131 2\n%134 = OpLoad %7 %9\n%135 = OpIAdd %7 %134 %136\n%137 = OpBitcast %57 %135\n%138 = OpLoad %5 %137 Aligned 4\n%139 = OpISub %5 %138 %34\n%140 = OpExtInst %5 %133 FindUMsb %139\n%141 = OpIAdd %5 %140 %34\n%142 = OpIAdd %5 %141 %56\n%143 = OpShiftLeftLogical %5 %138 %56\n%144 = OpCompositeConstruct %12 %139 %56 %56\n%145 = OpSLessThan %28 %139 %56\n%146 = OpSelect %5 %145 %56 %143\nOpBranch %287\n%287 = OpLabel\n%147 = OpPhi %5 %129 %286 %148 %294\n%149 = OpULessThan %28 %147 %146\nOpLoopMerge %288 %294 None\nOpBranchConditional %149 %291 %288\n%291 = OpLabel\n%150 = OpBitFieldUExtract %5 %147 %56 %141\n%151 = OpCompositeConstruct %12 %150 %56 %56\nOpStore %14 %151\n%152 = OpLoad %12 %153\n%154 = OpIMul %12 %43 %151\n%155 = OpIAdd %12 %154 %152\nOpStore %15 %155\n%158 = OpCompositeConstruct %12 %139 %56 %56\n%157 = OpULessThanEqual %156 %151 %158\n%159 = OpAll %28 %157\nOpSelectionMerge %293 None\nOpBranchConditional %159 %292 %293\n%292 = OpLabel\n%160 = OpFunctionCall %1 %47\nOpControlBarrier %60 %60 %81\nOpBranch %293\n%293 = OpLabel\nOpBranch %294\n%294 = OpLabel\n%148 = OpIAdd %5 %147 %132\nOpBranch %287\n%288 = OpLabel\nOpBranch %289\n%279 = OpLabel\n%188 = OpLoad %7 %9\n%189 = OpAccessChain %112 %23 %64\n%190 = OpLoad %6 %189\n%191 = OpBitcast %20 %190\n%192 = OpInBoundsAccessChain %57 %191 %56 %108\n%193 = OpLoad %5 %192 Aligned 4\n%194 = OpUConvert %7 %193\n%195 = OpIAdd %7 %188 %194\nOpStore %9 %195\n%196 = OpLoad %12 %95\n%197 = OpCompositeExtract %5 %196 2\n%198 = OpLoad %12 %130\n%199 = OpCompositeExtract %5 %198 2\n%200 = OpLoad %7 %9\n%201 = OpIAdd %7 %200 %136\n%202 = OpBitcast %57 %201\n%203 = OpLoad %5 %202 Aligned 4\n%204 = OpISub %5 %203 %34\n%205 = OpExtInst %5 %133 FindUMsb %204\n%206 = OpIAdd %5 %205 %34\n%207 = OpIAdd %5 %206 %56\n%208 = OpShiftLeftLogical %5 %203 %56\n%209 = OpCompositeConstruct %12 %204 %56 %56\n%210 = OpSLessThan %28 %204 %56\n%211 = OpSelect %5 %210 %56 %208\nOpBranch %280\n%280 = OpLabel\n%212 = OpPhi %5 %197 %279 %213 %285\n%214 = OpULessThan %28 %212 %211\nOpLoopMerge %281 %285 None\nOpBranchConditional %214 %282 %281\n%282 = OpLabel\n%215 = OpBitFieldUExtract %5 %212 %56 %206\n%216 = OpCompositeConstruct %12 %215 %56 %56\nOpStore %14 %216\n%217 = OpLoad %12 %153\n%218 = OpIMul %12 %43 %216\n%219 = OpIAdd %12 %218 %217\nOpStore %15 %219\n%221 = OpCompositeConstruct %12 %204 %56 %56\n%220 = OpULessThanEqual %156 %216 %221\n%222 = OpAll %28 %220\nOpSelectionMerge %284 None\nOpBranchConditional %222 %283 %284\n%283 = OpLabel\n%223 = OpFunctionCall %1 %47\nOpControlBarrier %60 %60 %81\nOpBranch %284\n%284 = OpLabel\nOpBranch %285\n%285 = OpLabel\n%213 = OpIAdd %5 %212 %199\nOpBranch %280\n%281 = OpLabel\nOpBranch %289\n%289 = OpLabel\nOpBranch %290\n%258 = OpLabel\nOpSelectionMerge %277 None\nOpBranchConditional %30 %268 %259\n%268 = OpLabel\n%161 = OpLoad %7 %9\n%162 = OpLoad %5 %11\n%163 = OpIMul %5 %108 %162\n%164 = OpUConvert %7 %163\n%165 = OpIAdd %7 %161 %164\nOpStore %9 %165\nOpSelectionMerge %276 None\nOpBranchConditional %32 %275 %269\n%275 = OpLabel\n%167 = OpLoad %12 %95\n%168 = OpLoad %12 %166\nOpStore %14 %167\nOpStore %15 %168\n%169 = OpFunctionCall %1 %47\nOpBranch %276\n%269 = OpLabel\n%170 = OpLoad %12 %95\n%171 = OpCompositeExtract %5 %170 2\n%172 = OpLoad %12 %130\n%173 = OpCompositeExtract %5 %172 2\nOpBranch %270\n%270 = OpLabel\n%176 = OpPhi %5 %171 %269 %177 %274\n%178 = OpULessThan %28 %176 %175\nOpLoopMerge %271 %274 None\nOpBranchConditional %178 %272 %271\n%272 = OpLabel\n%179 = OpUMod %5 %176 %33\n%180 = OpUDiv %5 %176 %33\n%181 = OpUMod %5 %180 %36\n%182 = OpUDiv %5 %180 %36\n%183 = OpCompositeConstruct %12 %179 %181 %182\nOpStore %14 %183\n%184 = OpLoad %12 %153\n%185 = OpIMul %12 %43 %183\n%186 = OpIAdd %12 %185 %184\nOpStore %15 %186\n%187 = OpFunctionCall %1 %47\nOpControlBarrier %60 %60 %81\nOpBranch %273\n%273 = OpLabel\nOpBranch %274\n%274 = OpLabel\n%177 = OpIAdd %5 %176 %173\nOpBranch %270\n%271 = OpLabel\nOpBranch %276\n%276 = OpLabel\nOpBranch %277\n%259 = OpLabel\n%224 = OpLoad %7 %9\n%225 = OpAccessChain %112 %23 %64\n%226 = OpLoad %6 %225\n%227 = OpBitcast %20 %226\n%228 = OpInBoundsAccessChain %57 %227 %56 %108\n%229 = OpLoad %5 %228 Aligned 4\n%230 = OpUConvert %7 %229\n%231 = OpIAdd %7 %224 %230\nOpStore %9 %231\nOpSelectionMerge %267 None\nOpBranchConditional %32 %266 %260\n%266 = OpLabel\n%232 = OpLoad %12 %95\n%233 = OpLoad %12 %166\nOpStore %14 %232\nOpStore %15 %233\n%234 = OpFunctionCall %1 %47\nOpBranch %267\n%260 = OpLabel\n%235 = OpLoad %12 %95\n%236 = OpCompositeExtract %5 %235 2\n%237 = OpLoad %12 %130\n%238 = OpCompositeExtract %5 %237 2\nOpBranch %261\n%261 = OpLabel\n%241 = OpPhi %5 %236 %260 %242 %265\n%243 = OpULessThan %28 %241 %240\nOpLoopMerge %262 %265 None\nOpBranchConditional %243 %263 %262\n%263 = OpLabel\n%244 = OpUMod %5 %241 %33\n%245 = OpUDiv %5 %241 %33\n%246 = OpUMod %5 %245 %36\n%247 = OpUDiv %5 %245 %36\n%248 = OpCompositeConstruct %12 %244 %246 %247\nOpStore %14 %248\n%249 = OpLoad %12 %153\n%250 = OpIMul %12 %43 %248\n%251 = OpIAdd %12 %250 %249\nOpStore %15 %251\n%252 = OpFunctionCall %1 %47\nOpControlBarrier %60 %60 %81\nOpBranch %264\n%264 = OpLabel\nOpBranch %265\n%265 = OpLabel\n%242 = OpIAdd %5 %241 %238\nOpBranch %261\n%262 = OpLabel\nOpBranch %267\n%267 = OpLabel\nOpBranch %277\n%277 = OpLabel\nOpBranch %290\n%290 = OpLabel\nOpReturn\nOpFunctionEnd\n%47 = OpFunction %1 None %2\n%48 = OpLabel\nOpBranch %296\n%296 = OpLabel\n%53 = OpLoad %7 %9\n%54 = OpConvertUToPtr %51 %53\n%55 = OpAccessChain %52 %54 %56\n%58 = OpAccessChain %57 %55 %34\n%59 = OpAtomicIAdd %5 %58 %60 %56 %34\n%61 = OpLoad %5 %58 Aligned|MakePointerVisible|NonPrivatePointer 4 %62\n%63 = OpIAdd %5 %61 %64\nOpStore %58 %63 Aligned|MakePointerAvailable|NonPrivatePointer 4 %62\nOpControlBarrier %60 %60 %65\n%84 = OpLoad %7 %9\n%85 = OpIAdd %7 %84 %86\n%87 = OpFunctionCall %28 %68 %85\nOpSelectionMerge %298 None\nOpBranchConditional %87 %297 %298\n%297 = OpLabel\n%88 = OpLoad %5 %73\n%89 = OpLoad %5 %58 Aligned|MakePointerVisible|NonPrivatePointer 4 %62\n%90 = OpLoad %44 %46\n%92 = OpImageTexelPointer %91 %46 %88 %56\n%93 = OpAtomicIAdd %5 %92 %62 %56 %89\nOpBranch %298\n%298 = OpLabel\nOpReturn\nOpFunctionEnd\n%68 = OpFunction %28 None %66\n%67 = OpFunctionParameter %7\n%69 = OpLabel\n%76 = OpLoad %5 %73\n%77 = OpIEqual %28 %76 %56\nOpSelectionMerge %71 None\nOpBranchConditional %77 %70 %71\n%70 = OpLabel\n%78 = OpBitcast %57 %67\n%79 = OpAtomicIDecrement %5 %78 %62 %56\n%80 = OpIEqual %28 %79 %34\nOpStore %75 %80 NonPrivatePointer\nOpBranch %71\n%71 = OpLabel\nOpControlBarrier %60 %60 %81\n%82 = OpLoad %28 %75 NonPrivatePointer\nOpReturnValue %82\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/descriptor_qa.bindless.descriptor-qa.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_buffer_reference_uvec2 : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer uintPointer;\n\nlayout(buffer_reference, buffer_reference_align = 4) buffer uintPointer\n{\n    uint value;\n};\n\nlayout(set = 7, binding = 0, std430) readonly buffer AtomicCounters\n{\n    uvec2 counters[];\n} _33;\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _47[];\n\nlayout(set = 10, binding = 10, std430) buffer DescriptorHeapGlobalQAData\n{\n    uvec2 failed_shader_hash;\n    uint failed_offset;\n    uint failed_heap;\n    uint failed_cookie;\n    uint fault_atomic;\n    uint failed_instruction;\n    uint failed_descriptor_type_mask;\n    uint actual_descriptor_type_mask;\n    uint fault_type;\n    uint va_map_timestamp;\n    uint live_status_table[];\n} QAGlobalData;\n\nlayout(set = 10, binding = 11, scalar) readonly buffer DescriptorHeapQAData\n{\n    uint descriptor_count;\n    uint heap_index;\n    uvec3 cookies_descriptor_info[];\n} QAHeapData;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nlayout(set = 0, binding = 0) uniform texture2D _13[];\nlayout(set = 1, binding = 0) uniform samplerBuffer _17[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _21[];\nlayout(set = 1, binding = 0) uniform usamplerBuffer _24[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _28[];\nlayout(set = 4, binding = 0, r32ui) uniform writeonly uimageBuffer _36[];\nlayout(set = 3, binding = 0) uniform writeonly image2D _40[];\nlayout(set = 2, binding = 0) uniform sampler _51[];\n\nvoid descriptor_qa_report_fault(uint fault_type, uint heap_offset, uint cookie, uint heap_index, uint descriptor_type, uint actual_descriptor_type, uint instruction)\n{\n    uint _86 = atomicAdd(QAGlobalData.fault_atomic, 1u);\n    if (_86 == 0u)\n    {\n        QAGlobalData.failed_cookie = cookie;\n        QAGlobalData.failed_offset = heap_offset;\n        QAGlobalData.failed_heap = heap_index;\n        QAGlobalData.failed_descriptor_type_mask = descriptor_type;\n        QAGlobalData.actual_descriptor_type_mask = actual_descriptor_type;\n        QAGlobalData.failed_instruction = instruction;\n        QAGlobalData.failed_shader_hash = uvec2(3735928559u, 0u);\n        memoryBarrierBuffer();\n        QAGlobalData.fault_type = fault_type;\n    }\n}\n\nuint descriptor_qa_check(uint heap_offset, uint descriptor_type_mask, uint instruction)\n{\n    uint _119 = QAHeapData.descriptor_count;\n    uint _121 = QAHeapData.heap_index;\n    uint _124 = QAGlobalData.va_map_timestamp;\n    uvec3 _127 = QAHeapData.cookies_descriptor_info[heap_offset];\n    uint _136 = QAGlobalData.live_status_table[_127.x >> 5u];\n    uint _150 = ((uint(heap_offset >= _119) | (((_127.z & descriptor_type_mask) == descriptor_type_mask) ? 0u : 2u)) | (((_136 & (1u << (_127.x & 31u))) != 0u) ? 0u : 4u)) | ((_124 >= _127.y) ? 0u : 8u);\n    if (_150 != 0u)\n    {\n        descriptor_qa_report_fault(_150, heap_offset, _127.x, _121, descriptor_type_mask, _127.z, instruction);\n        return _119;\n    }\n    return heap_offset;\n}\n\nuint RobustPhysicalAtomicCounter(uvec2 _386, uint _387, uint _388)\n{\n    uint _401;\n    if (any(notEqual(_386, uvec2(0u))))\n    {\n        uint _399 = atomicAdd(uintPointer(_386).value, _387);\n        _401 = _399 + _388;\n    }\n    else\n    {\n        _401 = 0u;\n    }\n    return _401;\n}\n\nvoid main()\n{\n    float _161;\n    if (gl_GlobalInvocationID.x > 2u)\n    {\n        uint _68 = descriptor_qa_check(registers._m5, 4u, 1u);\n        _161 = _47[_68]._m0[0u].x;\n    }\n    else\n    {\n        _161 = 0.0;\n    }\n    float _174;\n    if (gl_GlobalInvocationID.x > 3u)\n    {\n        uint _169 = descriptor_qa_check(registers._m5 + (gl_GlobalInvocationID.x + 1u), 4u, 2u);\n        _174 = _47[_169]._m0[0u].x + _161;\n    }\n    else\n    {\n        _174 = _161;\n    }\n    float _195;\n    if (gl_GlobalInvocationID.x > 4u)\n    {\n        uint _180 = descriptor_qa_check(registers._m0, 1u, 3u);\n        _195 = textureLod(sampler2D(_13[_180], _51[registers._m2]), vec2(0.5), 0.0).x + _174;\n    }\n    else\n    {\n        _195 = _174;\n    }\n    float _209;\n    if (gl_GlobalInvocationID.x > 5u)\n    {\n        uint _203 = descriptor_qa_check(registers._m0 + ((gl_GlobalInvocationID.x & 1u) + 1u), 1u, 4u);\n        _209 = texelFetch(_13[_203], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), int(0u)).x + _195;\n    }\n    else\n    {\n        _209 = _195;\n    }\n    float _222;\n    if (gl_GlobalInvocationID.x > 6u)\n    {\n        uint _216 = descriptor_qa_check(registers._m1 + 3u, 16u, 5u);\n        _222 = texelFetch(_17[_216], int(gl_GlobalInvocationID.x)).x + _209;\n    }\n    else\n    {\n        _222 = _209;\n    }\n    float _235;\n    if (gl_GlobalInvocationID.x > 7u)\n    {\n        uint _230 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 4u), 16u, 6u);\n        _235 = texelFetch(_17[_230], int(gl_GlobalInvocationID.x)).x + _222;\n    }\n    else\n    {\n        _235 = _222;\n    }\n    float _249;\n    if (gl_GlobalInvocationID.x > 8u)\n    {\n        uint _242 = descriptor_qa_check(registers._m1 + 6u, 16u, 7u);\n        _249 = uintBitsToFloat(texelFetch(_21[_242], int(gl_GlobalInvocationID.x)).x) + _235;\n    }\n    else\n    {\n        _249 = _235;\n    }\n    float _263;\n    if (gl_GlobalInvocationID.x > 9u)\n    {\n        uint _257 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 7u), 16u, 8u);\n        _263 = uintBitsToFloat(texelFetch(_21[_257], int(gl_GlobalInvocationID.x)).x) + _249;\n    }\n    else\n    {\n        _263 = _249;\n    }\n    float _276;\n    if (gl_GlobalInvocationID.x > 10u)\n    {\n        uint _269 = descriptor_qa_check(registers._m1 + 9u, 16u, 9u);\n        _276 = uintBitsToFloat(texelFetch(_24[_269], int(gl_GlobalInvocationID.x)).x) + _263;\n    }\n    else\n    {\n        _276 = _263;\n    }\n    float _292;\n    if (gl_GlobalInvocationID.x > 11u)\n    {\n        uint _285 = descriptor_qa_check(registers._m1 + ((gl_GlobalInvocationID.x & 1u) + 10u), 16u, 10u);\n        _292 = uintBitsToFloat(texelFetch(_24[_285], int(gl_GlobalInvocationID.x >> 2u)).x) + _276;\n    }\n    else\n    {\n        _292 = _276;\n    }\n    if (gl_GlobalInvocationID.x > 1u)\n    {\n        uint _298 = descriptor_qa_check(registers._m4, 32u, 11u);\n        uint _304 = descriptor_qa_check(registers._m4, 256u, 12u);\n        imageStore(_28[_298], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 30u)\n    {\n        uint _318 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 1u), 32u, 13u);\n        imageStore(_28[_318], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 40u)\n    {\n        uint _329 = descriptor_qa_check(registers._m4 + 3u, 32u, 14u);\n        imageStore(_36[_329], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 50u)\n    {\n        uint _345 = descriptor_qa_check(registers._m4 + ((gl_GlobalInvocationID.x & 1u) + 4u), 32u, 15u);\n        imageStore(_36[_345], int(gl_GlobalInvocationID.x), uvec4(floatBitsToUint(_292)));\n    }\n    if (gl_GlobalInvocationID.x > 80u)\n    {\n        uint _356 = descriptor_qa_check(registers._m3 + 6u, 2u, 16u);\n        imageStore(_40[_356], ivec2(uvec2(gl_GlobalInvocationID.x, 0u)), vec4(_292));\n    }\n    if (gl_GlobalInvocationID.x > 90u)\n    {\n        uint _368 = descriptor_qa_check(registers._m3 + ((gl_GlobalInvocationID.x & 1u) + 7u), 2u, 17u);\n        imageStore(_40[_368], ivec2(uvec2(0u, gl_GlobalInvocationID.x)), vec4(_292));\n    }\n    uint _376 = descriptor_qa_check(registers._m4, 32u, 18u);\n    uint _382 = descriptor_qa_check(registers._m4, 256u, 19u);\n    uvec2 _384 = _33.counters[_382];\n    uint _403 = RobustPhysicalAtomicCounter(_384, 1u, 0u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 438\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability SampledBuffer\nOpCapability ImageBuffer\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability UniformTexelBufferArrayDynamicIndexing\nOpCapability StorageTexelBufferArrayDynamicIndexing\nOpCapability VulkanMemoryModel\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 Vulkan\nOpEntryPoint GLCompute %3 \"main\" %8 %13 %17 %21 %24 %28 %33 %36 %40 %47 %51 %54 %72 %111\nOpExecutionMode %3 LocalSize 1 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %31 \"AtomicCounters\"\nOpMemberName %31 0 \"counters\"\nOpName %44 \"BindlessCBV\"\nOpName %70 \"DescriptorHeapGlobalQAData\"\nOpMemberName %70 0 \"failed_shader_hash\"\nOpMemberName %70 1 \"failed_offset\"\nOpMemberName %70 2 \"failed_heap\"\nOpMemberName %70 3 \"failed_cookie\"\nOpMemberName %70 4 \"fault_atomic\"\nOpMemberName %70 5 \"failed_instruction\"\nOpMemberName %70 6 \"failed_descriptor_type_mask\"\nOpMemberName %70 7 \"actual_descriptor_type_mask\"\nOpMemberName %70 8 \"fault_type\"\nOpMemberName %70 9 \"va_map_timestamp\"\nOpMemberName %70 10 \"live_status_table\"\nOpName %72 \"QAGlobalData\"\nOpName %81 \"descriptor_qa_report_fault\"\nOpName %74 \"fault_type\"\nOpName %75 \"heap_offset\"\nOpName %76 \"cookie\"\nOpName %77 \"heap_index\"\nOpName %78 \"descriptor_type\"\nOpName %79 \"actual_descriptor_type\"\nOpName %80 \"instruction\"\nOpName %109 \"DescriptorHeapQAData\"\nOpMemberName %109 0 \"descriptor_count\"\nOpMemberName %109 1 \"heap_index\"\nOpMemberName %109 2 \"cookies_descriptor_info\"\nOpName %111 \"QAHeapData\"\nOpName %116 \"descriptor_qa_check\"\nOpName %113 \"heap_offset\"\nOpName %114 \"descriptor_type_mask\"\nOpName %115 \"instruction\"\nOpName %389 \"RobustPhysicalAtomicCounter\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %13 DescriptorSet 0\nOpDecorate %13 Binding 0\nOpDecorate %17 DescriptorSet 1\nOpDecorate %17 Binding 0\nOpDecorate %21 DescriptorSet 1\nOpDecorate %21 Binding 0\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %28 DescriptorSet 4\nOpDecorate %28 Binding 0\nOpDecorate %28 NonReadable\nOpDecorate %30 ArrayStride 8\nOpDecorate %31 Block\nOpMemberDecorate %31 0 Offset 0\nOpMemberDecorate %31 0 NonWritable\nOpDecorate %33 DescriptorSet 7\nOpDecorate %33 Binding 0\nOpDecorate %33 AliasedPointer\nOpDecorate %36 DescriptorSet 4\nOpDecorate %36 Binding 0\nOpDecorate %36 NonReadable\nOpDecorate %40 DescriptorSet 3\nOpDecorate %40 Binding 0\nOpDecorate %40 NonReadable\nOpDecorate %43 ArrayStride 16\nOpDecorate %44 Block\nOpMemberDecorate %44 0 Offset 0\nOpDecorate %47 DescriptorSet 5\nOpDecorate %47 Binding 0\nOpDecorate %51 DescriptorSet 2\nOpDecorate %51 Binding 0\nOpDecorate %54 BuiltIn GlobalInvocationId\nOpDecorate %69 ArrayStride 4\nOpMemberDecorate %70 0 Offset 0\nOpMemberDecorate %70 1 Offset 8\nOpMemberDecorate %70 2 Offset 12\nOpMemberDecorate %70 3 Offset 16\nOpMemberDecorate %70 4 Offset 20\nOpMemberDecorate %70 5 Offset 24\nOpMemberDecorate %70 6 Offset 28\nOpMemberDecorate %70 7 Offset 32\nOpMemberDecorate %70 8 Offset 36\nOpMemberDecorate %70 9 Offset 40\nOpMemberDecorate %70 10 Offset 44\nOpDecorate %70 Block\nOpDecorate %72 DescriptorSet 10\nOpDecorate %72 Binding 10\nOpDecorate %108 ArrayStride 12\nOpMemberDecorate %109 0 Offset 0\nOpMemberDecorate %109 1 Offset 4\nOpMemberDecorate %109 2 Offset 8\nOpDecorate %109 Block\nOpDecorate %111 DescriptorSet 10\nOpDecorate %111 Binding 11\nOpDecorate %111 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeImage %9 2D 0 0 0 1 Unknown\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer UniformConstant %11\n%13 = OpVariable %12 UniformConstant\n%14 = OpTypeImage %9 Buffer 0 0 0 1 Unknown\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypePointer UniformConstant %15\n%17 = OpVariable %16 UniformConstant\n%18 = OpTypeImage %5 Buffer 0 0 0 1 Unknown\n%19 = OpTypeRuntimeArray %18\n%20 = OpTypePointer UniformConstant %19\n%21 = OpVariable %20 UniformConstant\n%22 = OpTypeRuntimeArray %18\n%23 = OpTypePointer UniformConstant %22\n%24 = OpVariable %23 UniformConstant\n%25 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%26 = OpTypeRuntimeArray %25\n%27 = OpTypePointer UniformConstant %26\n%28 = OpVariable %27 UniformConstant\n%29 = OpTypeVector %5 2\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypeStruct %30\n%32 = OpTypePointer StorageBuffer %31\n%33 = OpVariable %32 StorageBuffer\n%34 = OpTypeRuntimeArray %25\n%35 = OpTypePointer UniformConstant %34\n%36 = OpVariable %35 UniformConstant\n%37 = OpTypeImage %9 2D 0 0 0 2 Unknown\n%38 = OpTypeRuntimeArray %37\n%39 = OpTypePointer UniformConstant %38\n%40 = OpVariable %39 UniformConstant\n%41 = OpTypeVector %9 4\n%42 = OpConstant %5 4096\n%43 = OpTypeArray %41 %42\n%44 = OpTypeStruct %43\n%45 = OpTypeRuntimeArray %44\n%46 = OpTypePointer Uniform %45\n%47 = OpVariable %46 Uniform\n%48 = OpTypeSampler\n%49 = OpTypeRuntimeArray %48\n%50 = OpTypePointer UniformConstant %49\n%51 = OpVariable %50 UniformConstant\n%52 = OpTypeVector %5 3\n%53 = OpTypePointer Input %52\n%54 = OpVariable %53 Input\n%55 = OpTypePointer Input %5\n%57 = OpConstant %5 0\n%59 = OpTypeBool\n%61 = OpConstant %5 2\n%62 = OpTypePointer Uniform %44\n%64 = OpTypePointer PushConstant %5\n%66 = OpConstant %5 5\n%69 = OpTypeRuntimeArray %5\n%70 = OpTypeStruct %29 %5 %5 %5 %5 %5 %5 %5 %5 %5 %69\n%71 = OpTypePointer StorageBuffer %70\n%72 = OpVariable %71 StorageBuffer\n%73 = OpTypeFunction %1 %5 %5 %5 %5 %5 %5 %5\n%83 = OpTypePointer StorageBuffer %5\n%85 = OpConstant %5 4\n%87 = OpConstant %5 1\n%92 = OpConstant %5 3\n%96 = OpConstant %5 6\n%98 = OpConstant %5 7\n%100 = OpConstant %5 3735928559\n%101 = OpConstantComposite %29 %100 %57\n%102 = OpTypePointer StorageBuffer %29\n%104 = OpConstant %5 72\n%106 = OpConstant %5 8\n%108 = OpTypeRuntimeArray %52\n%109 = OpTypeStruct %5 %5 %108\n%110 = OpTypePointer StorageBuffer %109\n%111 = OpVariable %110 StorageBuffer\n%112 = OpTypeFunction %5 %5 %5 %5\n%123 = OpConstant %5 9\n%125 = OpTypePointer StorageBuffer %52\n%133 = OpConstant %5 31\n%135 = OpConstant %5 10\n%157 = OpTypePointer Uniform %41\n%162 = OpConstant %9 0\n%176 = OpTypePointer UniformConstant %10\n%182 = OpTypePointer UniformConstant %48\n%187 = OpTypeSampledImage %10\n%189 = OpConstant %9 0.5\n%191 = OpTypeVector %9 2\n%211 = OpTypePointer UniformConstant %14\n%217 = OpConstant %5 16\n%237 = OpTypePointer UniformConstant %18\n%244 = OpTypeVector %5 4\n%278 = OpConstant %5 11\n%294 = OpTypePointer UniformConstant %25\n%299 = OpConstant %5 32\n%305 = OpConstant %5 256\n%306 = OpConstant %5 12\n%311 = OpConstant %5 30\n%319 = OpConstant %5 13\n%324 = OpConstant %5 40\n%330 = OpConstant %5 14\n%336 = OpConstant %5 50\n%346 = OpConstant %5 15\n%350 = OpConstant %5 80\n%351 = OpTypePointer UniformConstant %37\n%361 = OpConstant %5 90\n%369 = OpConstant %5 17\n%377 = OpConstant %5 18\n%383 = OpConstant %5 19\n%385 = OpTypeFunction %5 %29 %5 %5\n%393 = OpTypeVector %59 2\n%394 = OpConstantNull %29\n%397 = OpTypePointer PhysicalStorageBuffer %5\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %404\n%404 = OpLabel\n%56 = OpAccessChain %55 %54 %57\n%58 = OpLoad %5 %56\n%60 = OpUGreaterThan %59 %58 %61\nOpSelectionMerge %406 None\nOpBranchConditional %60 %405 %406\n%405 = OpLabel\n%65 = OpAccessChain %64 %8 %66\n%67 = OpLoad %5 %65\n%68 = OpFunctionCall %5 %116 %67 %85 %87\n%63 = OpAccessChain %62 %47 %68\n%158 = OpAccessChain %157 %63 %57 %57\n%159 = OpLoad %41 %158\n%160 = OpCompositeExtract %9 %159 0\nOpBranch %406\n%406 = OpLabel\n%161 = OpPhi %9 %162 %404 %160 %405\n%163 = OpUGreaterThan %59 %58 %92\nOpSelectionMerge %408 None\nOpBranchConditional %163 %407 %408\n%407 = OpLabel\n%164 = OpIAdd %5 %58 %87\n%166 = OpAccessChain %64 %8 %66\n%167 = OpLoad %5 %166\n%168 = OpIAdd %5 %167 %164\n%169 = OpFunctionCall %5 %116 %168 %85 %61\n%165 = OpAccessChain %62 %47 %169\n%170 = OpAccessChain %157 %165 %57 %57\n%171 = OpLoad %41 %170\n%172 = OpCompositeExtract %9 %171 0\n%173 = OpFAdd %9 %172 %161\nOpBranch %408\n%408 = OpLabel\n%174 = OpPhi %9 %161 %406 %173 %407\n%175 = OpUGreaterThan %59 %58 %85\nOpSelectionMerge %410 None\nOpBranchConditional %175 %409 %410\n%409 = OpLabel\n%178 = OpAccessChain %64 %8 %57\n%179 = OpLoad %5 %178\n%180 = OpFunctionCall %5 %116 %179 %87 %92\n%177 = OpAccessChain %176 %13 %180\n%181 = OpLoad %10 %177\n%184 = OpAccessChain %64 %8 %61\n%185 = OpLoad %5 %184\n%183 = OpAccessChain %182 %51 %185\n%186 = OpLoad %48 %183\n%188 = OpSampledImage %187 %181 %186\n%192 = OpCompositeConstruct %191 %189 %189\n%190 = OpImageSampleExplicitLod %41 %188 %192 Lod %162\n%193 = OpCompositeExtract %9 %190 0\n%194 = OpFAdd %9 %193 %174\nOpBranch %410\n%410 = OpLabel\n%195 = OpPhi %9 %174 %408 %194 %409\n%196 = OpUGreaterThan %59 %58 %66\nOpSelectionMerge %412 None\nOpBranchConditional %196 %411 %412\n%411 = OpLabel\n%197 = OpBitwiseAnd %5 %58 %87\n%198 = OpIAdd %5 %197 %87\n%200 = OpAccessChain %64 %8 %57\n%201 = OpLoad %5 %200\n%202 = OpIAdd %5 %201 %198\n%203 = OpFunctionCall %5 %116 %202 %87 %85\n%199 = OpAccessChain %176 %13 %203\n%204 = OpLoad %10 %199\n%206 = OpCompositeConstruct %29 %57 %58\n%205 = OpImageFetch %41 %204 %206 Lod %57\n%207 = OpCompositeExtract %9 %205 0\n%208 = OpFAdd %9 %207 %195\nOpBranch %412\n%412 = OpLabel\n%209 = OpPhi %9 %195 %410 %208 %411\n%210 = OpUGreaterThan %59 %58 %96\nOpSelectionMerge %414 None\nOpBranchConditional %210 %413 %414\n%413 = OpLabel\n%213 = OpAccessChain %64 %8 %87\n%214 = OpLoad %5 %213\n%215 = OpIAdd %5 %214 %92\n%216 = OpFunctionCall %5 %116 %215 %217 %66\n%212 = OpAccessChain %211 %17 %216\n%218 = OpLoad %14 %212\n%219 = OpImageFetch %41 %218 %58\n%220 = OpCompositeExtract %9 %219 0\n%221 = OpFAdd %9 %220 %209\nOpBranch %414\n%414 = OpLabel\n%222 = OpPhi %9 %209 %412 %221 %413\n%223 = OpUGreaterThan %59 %58 %98\nOpSelectionMerge %416 None\nOpBranchConditional %223 %415 %416\n%415 = OpLabel\n%224 = OpBitwiseAnd %5 %58 %87\n%225 = OpIAdd %5 %224 %85\n%227 = OpAccessChain %64 %8 %87\n%228 = OpLoad %5 %227\n%229 = OpIAdd %5 %228 %225\n%230 = OpFunctionCall %5 %116 %229 %217 %96\n%226 = OpAccessChain %211 %17 %230\n%231 = OpLoad %14 %226\n%232 = OpImageFetch %41 %231 %58\n%233 = OpCompositeExtract %9 %232 0\n%234 = OpFAdd %9 %233 %222\nOpBranch %416\n%416 = OpLabel\n%235 = OpPhi %9 %222 %414 %234 %415\n%236 = OpUGreaterThan %59 %58 %106\nOpSelectionMerge %418 None\nOpBranchConditional %236 %417 %418\n%417 = OpLabel\n%239 = OpAccessChain %64 %8 %87\n%240 = OpLoad %5 %239\n%241 = OpIAdd %5 %240 %96\n%242 = OpFunctionCall %5 %116 %241 %217 %98\n%238 = OpAccessChain %237 %21 %242\n%243 = OpLoad %18 %238\n%245 = OpImageFetch %244 %243 %58\n%246 = OpCompositeExtract %5 %245 0\n%247 = OpBitcast %9 %246\n%248 = OpFAdd %9 %247 %235\nOpBranch %418\n%418 = OpLabel\n%249 = OpPhi %9 %235 %416 %248 %417\n%250 = OpUGreaterThan %59 %58 %123\nOpSelectionMerge %420 None\nOpBranchConditional %250 %419 %420\n%419 = OpLabel\n%251 = OpBitwiseAnd %5 %58 %87\n%252 = OpIAdd %5 %251 %98\n%254 = OpAccessChain %64 %8 %87\n%255 = OpLoad %5 %254\n%256 = OpIAdd %5 %255 %252\n%257 = OpFunctionCall %5 %116 %256 %217 %106\n%253 = OpAccessChain %237 %21 %257\n%258 = OpLoad %18 %253\n%259 = OpImageFetch %244 %258 %58\n%260 = OpCompositeExtract %5 %259 0\n%261 = OpBitcast %9 %260\n%262 = OpFAdd %9 %261 %249\nOpBranch %420\n%420 = OpLabel\n%263 = OpPhi %9 %249 %418 %262 %419\n%264 = OpUGreaterThan %59 %58 %135\nOpSelectionMerge %422 None\nOpBranchConditional %264 %421 %422\n%421 = OpLabel\n%266 = OpAccessChain %64 %8 %87\n%267 = OpLoad %5 %266\n%268 = OpIAdd %5 %267 %123\n%269 = OpFunctionCall %5 %116 %268 %217 %123\n%265 = OpAccessChain %237 %24 %269\n%270 = OpLoad %18 %265\n%271 = OpShiftLeftLogical %5 %58 %61\n%272 = OpImageFetch %244 %270 %58\n%273 = OpCompositeExtract %5 %272 0\n%274 = OpBitcast %9 %273\n%275 = OpFAdd %9 %274 %263\nOpBranch %422\n%422 = OpLabel\n%276 = OpPhi %9 %263 %420 %275 %421\n%277 = OpUGreaterThan %59 %58 %278\nOpSelectionMerge %424 None\nOpBranchConditional %277 %423 %424\n%423 = OpLabel\n%279 = OpBitwiseAnd %5 %58 %87\n%280 = OpIAdd %5 %279 %135\n%282 = OpAccessChain %64 %8 %87\n%283 = OpLoad %5 %282\n%284 = OpIAdd %5 %283 %280\n%285 = OpFunctionCall %5 %116 %284 %217 %135\n%281 = OpAccessChain %237 %24 %285\n%286 = OpLoad %18 %281\n%287 = OpShiftRightLogical %5 %58 %61\n%288 = OpImageFetch %244 %286 %287\n%289 = OpCompositeExtract %5 %288 0\n%290 = OpBitcast %9 %289\n%291 = OpFAdd %9 %290 %276\nOpBranch %424\n%424 = OpLabel\n%292 = OpPhi %9 %276 %422 %291 %423\n%293 = OpUGreaterThan %59 %58 %87\nOpSelectionMerge %426 None\nOpBranchConditional %293 %425 %426\n%425 = OpLabel\n%296 = OpAccessChain %64 %8 %85\n%297 = OpLoad %5 %296\n%298 = OpFunctionCall %5 %116 %297 %299 %278\n%295 = OpAccessChain %294 %28 %298\n%300 = OpLoad %25 %295\n%302 = OpAccessChain %64 %8 %85\n%303 = OpLoad %5 %302\n%304 = OpFunctionCall %5 %116 %303 %305 %306\n%301 = OpAccessChain %102 %33 %57 %304\n%307 = OpLoad %29 %301\n%308 = OpBitcast %5 %292\n%309 = OpCompositeConstruct %244 %308 %308 %308 %308\nOpImageWrite %300 %58 %309 NonPrivateTexel\nOpBranch %426\n%426 = OpLabel\n%310 = OpUGreaterThan %59 %58 %311\nOpSelectionMerge %428 None\nOpBranchConditional %310 %427 %428\n%427 = OpLabel\n%312 = OpBitwiseAnd %5 %58 %87\n%313 = OpIAdd %5 %312 %87\n%315 = OpAccessChain %64 %8 %85\n%316 = OpLoad %5 %315\n%317 = OpIAdd %5 %316 %313\n%318 = OpFunctionCall %5 %116 %317 %299 %319\n%314 = OpAccessChain %294 %28 %318\n%320 = OpLoad %25 %314\n%321 = OpBitcast %5 %292\n%322 = OpCompositeConstruct %244 %321 %321 %321 %321\nOpImageWrite %320 %58 %322 NonPrivateTexel\nOpBranch %428\n%428 = OpLabel\n%323 = OpUGreaterThan %59 %58 %324\nOpSelectionMerge %430 None\nOpBranchConditional %323 %429 %430\n%429 = OpLabel\n%326 = OpAccessChain %64 %8 %85\n%327 = OpLoad %5 %326\n%328 = OpIAdd %5 %327 %92\n%329 = OpFunctionCall %5 %116 %328 %299 %330\n%325 = OpAccessChain %294 %36 %329\n%331 = OpLoad %25 %325\n%332 = OpBitcast %5 %292\n%333 = OpShiftLeftLogical %5 %58 %61\n%334 = OpCompositeConstruct %244 %332 %332 %332 %332\nOpImageWrite %331 %58 %334 NonPrivateTexel\nOpBranch %430\n%430 = OpLabel\n%335 = OpUGreaterThan %59 %58 %336\nOpSelectionMerge %432 None\nOpBranchConditional %335 %431 %432\n%431 = OpLabel\n%337 = OpBitwiseAnd %5 %58 %87\n%338 = OpBitcast %5 %292\n%339 = OpShiftLeftLogical %5 %58 %61\n%340 = OpIAdd %5 %337 %85\n%342 = OpAccessChain %64 %8 %85\n%343 = OpLoad %5 %342\n%344 = OpIAdd %5 %343 %340\n%345 = OpFunctionCall %5 %116 %344 %299 %346\n%341 = OpAccessChain %294 %36 %345\n%347 = OpLoad %25 %341\n%348 = OpCompositeConstruct %244 %338 %338 %338 %338\nOpImageWrite %347 %58 %348 NonPrivateTexel\nOpBranch %432\n%432 = OpLabel\n%349 = OpUGreaterThan %59 %58 %350\nOpSelectionMerge %434 None\nOpBranchConditional %349 %433 %434\n%433 = OpLabel\n%353 = OpAccessChain %64 %8 %92\n%354 = OpLoad %5 %353\n%355 = OpIAdd %5 %354 %96\n%356 = OpFunctionCall %5 %116 %355 %61 %217\n%352 = OpAccessChain %351 %40 %356\n%357 = OpLoad %37 %352\n%358 = OpCompositeConstruct %29 %58 %57\n%359 = OpCompositeConstruct %41 %292 %292 %292 %292\nOpImageWrite %357 %358 %359 NonPrivateTexel\nOpBranch %434\n%434 = OpLabel\n%360 = OpUGreaterThan %59 %58 %361\nOpSelectionMerge %436 None\nOpBranchConditional %360 %435 %436\n%435 = OpLabel\n%362 = OpBitwiseAnd %5 %58 %87\n%363 = OpIAdd %5 %362 %98\n%365 = OpAccessChain %64 %8 %92\n%366 = OpLoad %5 %365\n%367 = OpIAdd %5 %366 %363\n%368 = OpFunctionCall %5 %116 %367 %61 %369\n%364 = OpAccessChain %351 %40 %368\n%370 = OpLoad %37 %364\n%371 = OpCompositeConstruct %29 %57 %58\n%372 = OpCompositeConstruct %41 %292 %292 %292 %292\nOpImageWrite %370 %371 %372 NonPrivateTexel\nOpBranch %436\n%436 = OpLabel\n%374 = OpAccessChain %64 %8 %85\n%375 = OpLoad %5 %374\n%376 = OpFunctionCall %5 %116 %375 %299 %377\n%373 = OpAccessChain %294 %28 %376\n%378 = OpLoad %25 %373\n%380 = OpAccessChain %64 %8 %85\n%381 = OpLoad %5 %380\n%382 = OpFunctionCall %5 %116 %381 %305 %383\n%379 = OpAccessChain %102 %33 %57 %382\n%384 = OpLoad %29 %379\n%403 = OpFunctionCall %5 %389 %384 %87 %57\nOpReturn\nOpFunctionEnd\n%81 = OpFunction %1 None %73\n%74 = OpFunctionParameter %5\n%75 = OpFunctionParameter %5\n%76 = OpFunctionParameter %5\n%77 = OpFunctionParameter %5\n%78 = OpFunctionParameter %5\n%79 = OpFunctionParameter %5\n%80 = OpFunctionParameter %5\n%82 = OpLabel\n%84 = OpAccessChain %83 %72 %85\n%86 = OpAtomicIAdd %5 %84 %66 %57 %87\n%88 = OpIEqual %59 %86 %57\nOpSelectionMerge %90 None\nOpBranchConditional %88 %89 %90\n%89 = OpLabel\n%91 = OpAccessChain %83 %72 %92\nOpStore %91 %76 NonPrivatePointer\n%93 = OpAccessChain %83 %72 %87\nOpStore %93 %75 NonPrivatePointer\n%94 = OpAccessChain %83 %72 %61\nOpStore %94 %77 NonPrivatePointer\n%95 = OpAccessChain %83 %72 %96\nOpStore %95 %78 NonPrivatePointer\n%97 = OpAccessChain %83 %72 %98\nOpStore %97 %79 NonPrivatePointer\n%99 = OpAccessChain %83 %72 %66\nOpStore %99 %80 NonPrivatePointer\n%103 = OpAccessChain %102 %72 %57\nOpStore %103 %101 NonPrivatePointer\nOpMemoryBarrier %66 %104\n%105 = OpAccessChain %83 %72 %106\nOpStore %105 %74 NonPrivatePointer\nOpBranch %90\n%90 = OpLabel\nOpReturn\nOpFunctionEnd\n%116 = OpFunction %5 None %112\n%113 = OpFunctionParameter %5\n%114 = OpFunctionParameter %5\n%115 = OpFunctionParameter %5\n%117 = OpLabel\n%118 = OpAccessChain %83 %111 %57\n%119 = OpLoad %5 %118\n%120 = OpAccessChain %83 %111 %87\n%121 = OpLoad %5 %120\n%122 = OpAccessChain %83 %72 %123\n%124 = OpLoad %5 %122\n%126 = OpAccessChain %125 %111 %61 %113\n%127 = OpLoad %52 %126\n%128 = OpCompositeExtract %5 %127 0\n%129 = OpCompositeExtract %5 %127 1\n%130 = OpCompositeExtract %5 %127 2\n%131 = OpShiftRightLogical %5 %128 %66\n%132 = OpBitwiseAnd %5 %128 %133\n%134 = OpAccessChain %83 %72 %135 %131\n%136 = OpLoad %5 %134\n%137 = OpShiftLeftLogical %5 %87 %132\n%138 = OpBitwiseAnd %5 %136 %137\n%139 = OpINotEqual %59 %138 %57\n%140 = OpBitwiseAnd %5 %130 %114\n%141 = OpIEqual %59 %140 %114\n%142 = OpUGreaterThanEqual %59 %113 %119\n%143 = OpSelect %5 %142 %87 %57\n%144 = OpSelect %5 %141 %57 %61\n%145 = OpSelect %5 %139 %57 %85\n%146 = OpUGreaterThanEqual %59 %124 %129\n%147 = OpSelect %5 %146 %57 %106\n%148 = OpBitwiseOr %5 %143 %144\n%149 = OpBitwiseOr %5 %148 %145\n%150 = OpBitwiseOr %5 %149 %147\n%151 = OpINotEqual %59 %150 %57\nOpSelectionMerge %153 None\nOpBranchConditional %151 %152 %153\n%152 = OpLabel\n%154 = OpFunctionCall %1 %81 %150 %113 %128 %121 %114 %130 %115\nOpReturnValue %119\n%153 = OpLabel\nOpReturnValue %113\nOpFunctionEnd\n%389 = OpFunction %5 None %385\n%386 = OpFunctionParameter %29\n%387 = OpFunctionParameter %5\n%388 = OpFunctionParameter %5\n%390 = OpLabel\n%395 = OpINotEqual %393 %386 %394\n%396 = OpAny %59 %395\nOpSelectionMerge %392 None\nOpBranchConditional %396 %391 %392\n%391 = OpLabel\n%398 = OpBitcast %397 %386\n%399 = OpAtomicIAdd %5 %398 %66 %57 %387\n%400 = OpIAdd %5 %399 %388\nOpBranch %392\n%392 = OpLabel\n%401 = OpPhi %5 %57 %390 %400 %391\nOpReturnValue %401\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/groupshared.vkmm.comp",
    "content": "#version 460\nlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform writeonly uimageBuffer _8;\n\nshared uint _12[64];\n\nvoid main()\n{\n    _12[gl_LocalInvocationIndex] = gl_LocalInvocationIndex;\n    barrier();\n    imageStore(_8, int(gl_LocalInvocationIndex), uvec4(_12[gl_LocalInvocationIndex ^ 3u]));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability VulkanMemoryModel\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %8 %12 %15\nOpExecutionMode %3 LocalSize 64 1 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %8 NonReadable\nOpDecorate %15 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpConstant %5 64\n%10 = OpTypeArray %5 %9\n%11 = OpTypePointer Workgroup %10\n%12 = OpVariable %11 Workgroup\n%14 = OpTypePointer Input %5\n%15 = OpVariable %14 Input\n%17 = OpTypePointer Workgroup %5\n%19 = OpConstant %5 2\n%20 = OpConstant %5 24840\n%22 = OpConstant %5 3\n%25 = OpTypeVector %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %27\n%27 = OpLabel\n%13 = OpLoad %6 %8\n%16 = OpLoad %5 %15\n%18 = OpAccessChain %17 %12 %16\nOpStore %18 %16 NonPrivatePointer\nOpControlBarrier %19 %19 %20\n%21 = OpBitwiseXor %5 %16 %22\n%23 = OpAccessChain %17 %12 %21\n%24 = OpLoad %5 %23 NonPrivatePointer\n%26 = OpCompositeConstruct %25 %24 %24 %24 %24\nOpImageWrite %13 %16 %26 NonPrivateTexel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/hull.vkmm.tesc",
    "content": "#version 460\nlayout(vertices = 4) out;\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[1];\n} _12;\n\nlayout(location = 0) in float VSValue[];\nlayout(location = 0) out float HSValue[4];\nlayout(location = 1) patch out float PATCH;\n\nvoid hull_main()\n{\n    float _36[4];\n    _36[0u] = VSValue[0u];\n    _36[1u] = VSValue[1u];\n    _36[2u] = VSValue[2u];\n    _36[3u] = VSValue[3u];\n    uint _53 = uint(int(VSValue[0u]));\n    _36[_53] += 40.0;\n    HSValue[gl_InvocationID] = (((VSValue[0u] + float(gl_InvocationID)) + VSValue[1u]) + VSValue[2u]) + _36[3u];\n}\n\nvoid patch_main()\n{\n    float _66[4];\n    _66[0u] = VSValue[0u];\n    _66[1u] = VSValue[1u];\n    _66[2u] = VSValue[2u];\n    _66[3u] = VSValue[3u];\n    uint _79 = uint(int(VSValue[0u]));\n    _66[_79] += 40.0;\n    gl_TessLevelOuter[0u] = VSValue[0u];\n    gl_TessLevelOuter[1u] = VSValue[1u];\n    gl_TessLevelOuter[2u] = VSValue[2u];\n    gl_TessLevelOuter[3u] = HSValue[0u] + VSValue[0u];\n    gl_TessLevelInner[0u] = HSValue[0u];\n    gl_TessLevelInner[1u] = HSValue[1u];\n    PATCH = _12._m0[0u].x + _66[3u];\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 114\n; Schema: 0\nOpCapability Shader\nOpCapability Tessellation\nOpCapability VulkanMemoryModel\nOpMemoryModel Logical Vulkan\nOpEntryPoint TessellationControl %3 \"main\" %12 %16 %20 %21 %25 %27 %33\nOpExecutionMode %3 Quads\nOpExecutionMode %3 SpacingEqual\nOpExecutionMode %3 VertexOrderCw\nOpExecutionMode %3 OutputVertices 4\nOpName %3 \"main\"\nOpName %10 \"\"\nOpName %16 \"VSValue\"\nOpName %20 \"HSValue\"\nOpName %21 \"SV_TessFactor\"\nOpName %25 \"SV_InsideTessFactor\"\nOpName %27 \"PATCH\"\nOpName %28 \"hull_main\"\nOpName %30 \"patch_main\"\nOpDecorate %9 ArrayStride 16\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %16 Location 0\nOpDecorate %20 Location 0\nOpDecorate %21 BuiltIn TessLevelOuter\nOpDecorate %21 Patch\nOpDecorate %25 BuiltIn TessLevelInner\nOpDecorate %25 Patch\nOpDecorate %27 Location 1\nOpDecorate %27 Patch\nOpDecorate %33 BuiltIn InvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpConstant %5 1\n%7 = OpTypeFloat 32\n%8 = OpTypeVector %7 4\n%9 = OpTypeArray %8 %6\n%10 = OpTypeStruct %9\n%11 = OpTypePointer Uniform %10\n%12 = OpVariable %11 Uniform\n%13 = OpConstant %5 32\n%14 = OpTypeArray %7 %13\n%15 = OpTypePointer Input %14\n%16 = OpVariable %15 Input\n%17 = OpConstant %5 4\n%18 = OpTypeArray %7 %17\n%19 = OpTypePointer Output %18\n%20 = OpVariable %19 Output\n%21 = OpVariable %19 Output\n%22 = OpConstant %5 2\n%23 = OpTypeArray %7 %22\n%24 = OpTypePointer Output %23\n%25 = OpVariable %24 Output\n%26 = OpTypePointer Output %7\n%27 = OpVariable %26 Output\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%35 = OpTypePointer Function %18\n%37 = OpTypePointer Input %7\n%39 = OpConstant %5 0\n%41 = OpTypePointer Function %7\n%50 = OpConstant %5 3\n%57 = OpConstant %7 40\n%89 = OpTypePointer Uniform %8\n%102 = OpTypeBool\n%104 = OpConstant %5 4104\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %106\n%106 = OpLabel\n%100 = OpFunctionCall %1 %28\n%101 = OpLoad %5 %33\n%103 = OpIEqual %102 %101 %39\nOpControlBarrier %22 %22 %104\nOpSelectionMerge %108 None\nOpBranchConditional %103 %107 %108\n%107 = OpLabel\n%105 = OpFunctionCall %1 %30\nOpBranch %108\n%108 = OpLabel\nOpReturn\nOpFunctionEnd\n%28 = OpFunction %1 None %2\n%29 = OpLabel\n%36 = OpVariable %35 Function\nOpBranch %110\n%110 = OpLabel\n%34 = OpLoad %5 %33\n%38 = OpAccessChain %37 %16 %39\n%40 = OpLoad %7 %38\n%42 = OpAccessChain %41 %36 %39\nOpStore %42 %40\n%43 = OpAccessChain %37 %16 %6\n%44 = OpLoad %7 %43\n%45 = OpAccessChain %41 %36 %6\nOpStore %45 %44\n%46 = OpAccessChain %37 %16 %22\n%47 = OpLoad %7 %46\n%48 = OpAccessChain %41 %36 %22\nOpStore %48 %47\n%49 = OpAccessChain %37 %16 %50\n%51 = OpLoad %7 %49\n%52 = OpAccessChain %41 %36 %50\nOpStore %52 %51\n%53 = OpConvertFToS %5 %40\n%54 = OpAccessChain %41 %36 %53\n%55 = OpLoad %7 %54\n%56 = OpFAdd %7 %55 %57\nOpStore %54 %56\n%58 = OpLoad %7 %52\n%59 = OpConvertUToF %7 %34\n%60 = OpFAdd %7 %40 %59\n%61 = OpFAdd %7 %60 %44\n%62 = OpFAdd %7 %61 %47\n%63 = OpFAdd %7 %62 %58\n%65 = OpLoad %5 %33\n%64 = OpAccessChain %26 %20 %65\nOpStore %64 %63\nOpReturn\nOpFunctionEnd\n%30 = OpFunction %1 None %2\n%31 = OpLabel\n%66 = OpVariable %35 Function\nOpBranch %112\n%112 = OpLabel\n%67 = OpAccessChain %37 %16 %39\n%68 = OpLoad %7 %67\n%69 = OpAccessChain %41 %66 %39\nOpStore %69 %68\n%70 = OpAccessChain %37 %16 %6\n%71 = OpLoad %7 %70\n%72 = OpAccessChain %41 %66 %6\nOpStore %72 %71\n%73 = OpAccessChain %37 %16 %22\n%74 = OpLoad %7 %73\n%75 = OpAccessChain %41 %66 %22\nOpStore %75 %74\n%76 = OpAccessChain %37 %16 %50\n%77 = OpLoad %7 %76\n%78 = OpAccessChain %41 %66 %50\nOpStore %78 %77\n%79 = OpConvertFToS %5 %68\n%80 = OpAccessChain %41 %66 %79\n%81 = OpLoad %7 %80\n%82 = OpFAdd %7 %81 %57\nOpStore %80 %82\n%83 = OpAccessChain %26 %20 %39\n%84 = OpLoad %7 %83\n%85 = OpAccessChain %26 %20 %6\n%86 = OpLoad %7 %85\n%87 = OpFAdd %7 %84 %68\n%88 = OpLoad %7 %78\n%90 = OpAccessChain %89 %12 %39 %39\n%91 = OpLoad %8 %90\n%92 = OpCompositeExtract %7 %91 0\n%93 = OpFAdd %7 %92 %88\n%94 = OpAccessChain %26 %21 %39\nOpStore %94 %68\n%95 = OpAccessChain %26 %21 %6\nOpStore %95 %71\n%96 = OpAccessChain %26 %21 %22\nOpStore %96 %74\n%97 = OpAccessChain %26 %21 %50\nOpStore %97 %87\n%98 = OpAccessChain %26 %25 %39\nOpStore %98 %84\n%99 = OpAccessChain %26 %25 %6\nOpStore %99 %86\nOpStore %27 %93\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/image-load-store.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0, r32f) uniform image2D _11;\nlayout(set = 0, binding = 1, r32f) uniform image2D _12;\n\nvoid main()\n{\n    imageStore(_11, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), vec4(imageLoad(_11, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y))).x + 1.0));\n    imageStore(_12, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), vec4(imageLoad(_12, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y))).x + texelFetch(_8, ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), int(0u)).x));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability VulkanMemoryModel\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %8 %11 %12 %19\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 1\nOpDecorate %19 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeImage %5 2D 0 0 0 2 R32f\n%10 = OpTypePointer UniformConstant %9\n%11 = OpVariable %10 UniformConstant\n%12 = OpVariable %10 UniformConstant\n%16 = OpTypeInt 32 0\n%17 = OpTypeVector %16 3\n%18 = OpTypePointer Input %17\n%19 = OpVariable %18 Input\n%20 = OpTypePointer Input %16\n%22 = OpConstant %16 0\n%25 = OpConstant %16 1\n%27 = OpTypeVector %5 4\n%29 = OpTypeVector %16 2\n%31 = OpConstant %16 5\n%34 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %46\n%46 = OpLabel\n%13 = OpLoad %9 %12\n%14 = OpLoad %9 %11\n%15 = OpLoad %6 %8\n%21 = OpAccessChain %20 %19 %22\n%23 = OpLoad %16 %21\n%24 = OpAccessChain %20 %19 %25\n%26 = OpLoad %16 %24\n%30 = OpCompositeConstruct %29 %23 %26\n%28 = OpImageRead %27 %14 %30 MakeTexelVisible|NonPrivateTexel %31\n%32 = OpCompositeExtract %5 %28 0\n%33 = OpFAdd %5 %32 %34\n%35 = OpCompositeConstruct %29 %23 %26\n%36 = OpCompositeConstruct %27 %33 %33 %33 %33\nOpImageWrite %14 %35 %36 MakeTexelAvailable|NonPrivateTexel %31\n%38 = OpCompositeConstruct %29 %23 %26\n%37 = OpImageFetch %27 %15 %38 Lod %22\n%39 = OpCompositeExtract %5 %37 0\n%41 = OpCompositeConstruct %29 %23 %26\n%40 = OpImageRead %27 %13 %41 NonPrivateTexel\n%42 = OpCompositeExtract %5 %40 0\n%43 = OpFAdd %5 %42 %39\n%44 = OpCompositeConstruct %29 %23 %26\n%45 = OpCompositeConstruct %27 %43 %43 %43 %43\nOpImageWrite %13 %44 %45 NonPrivateTexel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/image-load-store.vkmm.sm66.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_samplerless_texture_functions : require\nlayout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, r32f) uniform image2D _9[];\nlayout(set = 0, binding = 0, r32f) uniform image2D _12[];\nlayout(set = 0, binding = 0) uniform texture2D _16[];\n\nvoid main()\n{\n    imageStore(_9[0u], ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), vec4(imageLoad(_9[0u], ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y))).x + 1.0));\n    imageStore(_12[1u], ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), vec4(imageLoad(_12[1u], ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y))).x + texelFetch(_16[2u], ivec2(uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y)), int(0u)).x));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 58\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability RuntimeDescriptorArray\nOpCapability VulkanMemoryModel\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %9 %12 %16 %20\nOpExecutionMode %3 LocalSize 8 8 1\nOpName %3 \"main\"\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %12 DescriptorSet 0\nOpDecorate %12 Binding 0\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %20 BuiltIn GlobalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypePointer UniformConstant %7\n%9 = OpVariable %8 UniformConstant\n%10 = OpTypeRuntimeArray %6\n%11 = OpTypePointer UniformConstant %10\n%12 = OpVariable %11 UniformConstant\n%13 = OpTypeImage %5 2D 0 0 0 1 Unknown\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer UniformConstant %14\n%16 = OpVariable %15 UniformConstant\n%17 = OpTypeInt 32 0\n%18 = OpTypeVector %17 3\n%19 = OpTypePointer Input %18\n%20 = OpVariable %19 Input\n%21 = OpTypePointer Input %17\n%23 = OpConstant %17 0\n%26 = OpConstant %17 1\n%28 = OpTypePointer UniformConstant %6\n%33 = OpTypePointer UniformConstant %13\n%35 = OpConstant %17 2\n%37 = OpTypeVector %5 4\n%39 = OpTypeVector %17 2\n%41 = OpConstant %17 5\n%44 = OpConstant %5 1\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %56\n%56 = OpLabel\n%22 = OpAccessChain %21 %20 %23\n%24 = OpLoad %17 %22\n%25 = OpAccessChain %21 %20 %26\n%27 = OpLoad %17 %25\n%29 = OpAccessChain %28 %9 %23\n%30 = OpLoad %6 %29\n%31 = OpAccessChain %28 %12 %26\n%32 = OpLoad %6 %31\n%34 = OpAccessChain %33 %16 %35\n%36 = OpLoad %13 %34\n%40 = OpCompositeConstruct %39 %24 %27\n%38 = OpImageRead %37 %30 %40 MakeTexelVisible|NonPrivateTexel %41\n%42 = OpCompositeExtract %5 %38 0\n%43 = OpFAdd %5 %42 %44\n%45 = OpCompositeConstruct %39 %24 %27\n%46 = OpCompositeConstruct %37 %43 %43 %43 %43\nOpImageWrite %30 %45 %46 MakeTexelAvailable|NonPrivateTexel %41\n%48 = OpCompositeConstruct %39 %24 %27\n%47 = OpImageFetch %37 %36 %48 Lod %23\n%49 = OpCompositeExtract %5 %47 0\n%51 = OpCompositeConstruct %39 %24 %27\n%50 = OpImageRead %37 %32 %51 NonPrivateTexel\n%52 = OpCompositeExtract %5 %50 0\n%53 = OpFAdd %5 %52 %49\n%54 = OpCompositeConstruct %39 %24 %27\n%55 = OpCompositeConstruct %37 %53 %53 %53 %53\nOpImageWrite %32 %54 %55 NonPrivateTexel\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent-promotion.bindless.ssbo.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _13[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _16_19\n{\n    uvec4 _m0[];\n} _19[];\n\nlayout(set = 4, binding = 0, std430) buffer _21_24\n{\n    uvec4 _m0[];\n} _24[];\n\nlayout(set = 4, binding = 0, std430) readonly buffer _26_29\n{\n    uvec4 _m0[];\n} _29[];\n\nlayout(set = 4, binding = 0, std430) writeonly buffer _31_34\n{\n    uvec4 _m0[];\n} _34[];\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _42[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    uint _65 = registers._m1 + 1u;\n    _24[registers._m4]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_42[registers._m5]._m0[0u]).x == 0u))\n    {\n        uint _107 = 0u;\n        uint _111;\n        uint _114;\n        bool _116;\n        for (;;)\n        {\n            _111 = (_107 << 8u) + gl_LocalInvocationIndex;\n            _114 = _13[registers._m1]._m0[_111];\n            groupMemoryBarrier();\n            barrier();\n            _116 = _114 < 256u;\n            if (_116)\n            {\n                vec4 _120 = uintBitsToFloat(_19[_65]._m0[_111]);\n                vec4 _127 = uintBitsToFloat(_24[registers._m4]._m0[_114]);\n                _24[registers._m4]._m0[_114] = uvec4(floatBitsToUint(_127.x + _120.x), floatBitsToUint(_127.y + _120.y), floatBitsToUint(_127.z + _120.z), floatBitsToUint(_127.w + _120.w));\n            }\n            uint _108 = _107 + 1u;\n            if (_108 < floatBitsToUint(_42[registers._m5]._m0[0u]).x)\n            {\n                _107 = _108;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _96 = uintBitsToFloat(_29[registers._m4 + 1u]._m0[gl_LocalInvocationIndex]);\n    _34[registers._m4 + 2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_96.x), floatBitsToUint(_96.y), floatBitsToUint(_96.z), floatBitsToUint(_96.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 157\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability VulkanMemoryModel\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 Vulkan\nOpEntryPoint GLCompute %3 \"main\" %8 %13 %19 %24 %29 %34 %42 %76\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %10 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %26 \"SSBO\"\nOpName %31 \"SSBO\"\nOpName %39 \"BindlessCBV\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %9 ArrayStride 4\nOpMemberDecorate %10 0 Offset 0\nOpDecorate %10 Block\nOpDecorate %13 DescriptorSet 1\nOpDecorate %13 Binding 0\nOpDecorate %13 NonWritable\nOpDecorate %13 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 16\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 4\nOpDecorate %24 Binding 0\nOpDecorate %25 ArrayStride 16\nOpMemberDecorate %26 0 Offset 0\nOpDecorate %26 Block\nOpDecorate %29 DescriptorSet 4\nOpDecorate %29 Binding 0\nOpDecorate %29 NonWritable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %34 DescriptorSet 4\nOpDecorate %34 Binding 0\nOpDecorate %34 NonReadable\nOpDecorate %38 ArrayStride 16\nOpDecorate %39 Block\nOpMemberDecorate %39 0 Offset 0\nOpDecorate %42 DescriptorSet 5\nOpDecorate %42 Binding 0\nOpDecorate %76 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeRuntimeArray %5\n%10 = OpTypeStruct %9\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypePointer StorageBuffer %11\n%13 = OpVariable %12 StorageBuffer\n%14 = OpTypeVector %5 4\n%15 = OpTypeRuntimeArray %14\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %14\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeRuntimeArray %14\n%26 = OpTypeStruct %25\n%27 = OpTypeRuntimeArray %26\n%28 = OpTypePointer StorageBuffer %27\n%29 = OpVariable %28 StorageBuffer\n%30 = OpTypeRuntimeArray %14\n%31 = OpTypeStruct %30\n%32 = OpTypeRuntimeArray %31\n%33 = OpTypePointer StorageBuffer %32\n%34 = OpVariable %33 StorageBuffer\n%35 = OpTypeFloat 32\n%36 = OpTypeVector %35 4\n%37 = OpConstant %5 4096\n%38 = OpTypeArray %36 %37\n%39 = OpTypeStruct %38\n%40 = OpTypeRuntimeArray %39\n%41 = OpTypePointer Uniform %40\n%42 = OpVariable %41 Uniform\n%43 = OpTypePointer StorageBuffer %31\n%45 = OpTypePointer PushConstant %5\n%47 = OpConstant %5 4\n%50 = OpConstant %5 2\n%51 = OpTypePointer StorageBuffer %26\n%56 = OpConstant %5 1\n%57 = OpTypePointer StorageBuffer %21\n%61 = OpTypePointer StorageBuffer %16\n%66 = OpTypePointer StorageBuffer %10\n%70 = OpTypePointer Uniform %39\n%73 = OpConstant %5 5\n%75 = OpTypePointer Input %5\n%76 = OpVariable %75 Input\n%78 = OpConstant %35 0\n%84 = OpTypePointer StorageBuffer %14\n%86 = OpConstant %5 0\n%87 = OpTypePointer Uniform %36\n%92 = OpTypeBool\n%110 = OpConstant %5 8\n%112 = OpTypePointer StorageBuffer %5\n%115 = OpConstant %5 26696\n%117 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %147\n%147 = OpLabel\n%46 = OpAccessChain %45 %8 %47\n%48 = OpLoad %5 %46\n%49 = OpIAdd %5 %48 %50\n%44 = OpAccessChain %43 %34 %49\n%53 = OpAccessChain %45 %8 %47\n%54 = OpLoad %5 %53\n%55 = OpIAdd %5 %54 %56\n%52 = OpAccessChain %51 %29 %55\n%59 = OpAccessChain %45 %8 %47\n%60 = OpLoad %5 %59\n%58 = OpAccessChain %57 %24 %60\n%63 = OpAccessChain %45 %8 %56\n%64 = OpLoad %5 %63\n%65 = OpIAdd %5 %64 %56\n%62 = OpAccessChain %61 %19 %65\n%68 = OpAccessChain %45 %8 %56\n%69 = OpLoad %5 %68\n%67 = OpAccessChain %66 %13 %69\n%72 = OpAccessChain %45 %8 %73\n%74 = OpLoad %5 %72\n%71 = OpAccessChain %70 %42 %74\n%77 = OpLoad %5 %76\n%79 = OpBitcast %5 %78\n%80 = OpBitcast %5 %78\n%81 = OpBitcast %5 %78\n%82 = OpBitcast %5 %78\n%83 = OpCompositeConstruct %14 %79 %80 %81 %82\n%85 = OpAccessChain %84 %58 %86 %77\nOpStore %85 %83 NonPrivatePointer\n%88 = OpAccessChain %87 %71 %86 %86\n%89 = OpLoad %36 %88\n%90 = OpBitcast %14 %89\n%91 = OpCompositeExtract %5 %90 0\n%93 = OpIEqual %92 %91 %86\nOpSelectionMerge %155 None\nOpBranchConditional %93 %155 %148\n%148 = OpLabel\nOpBranch %149\n%149 = OpLabel\n%107 = OpPhi %5 %86 %148 %108 %153\n%109 = OpShiftLeftLogical %5 %107 %110\n%111 = OpIAdd %5 %109 %77\n%113 = OpAccessChain %112 %67 %86 %111\n%114 = OpLoad %5 %113\nOpControlBarrier %50 %50 %115\n%116 = OpULessThan %92 %114 %117\nOpLoopMerge %154 %153 None\nOpBranch %150\n%150 = OpLabel\nOpSelectionMerge %152 None\nOpBranchConditional %116 %151 %152\n%151 = OpLabel\n%118 = OpAccessChain %84 %62 %86 %111\n%119 = OpLoad %14 %118\n%120 = OpBitcast %36 %119\n%121 = OpCompositeExtract %35 %120 0\n%122 = OpCompositeExtract %35 %120 1\n%123 = OpCompositeExtract %35 %120 2\n%124 = OpCompositeExtract %35 %120 3\n%125 = OpAccessChain %84 %58 %86 %114\n%126 = OpLoad %14 %125 NonPrivatePointer\n%127 = OpBitcast %36 %126\n%128 = OpCompositeExtract %35 %127 0\n%129 = OpCompositeExtract %35 %127 1\n%130 = OpCompositeExtract %35 %127 2\n%131 = OpCompositeExtract %35 %127 3\n%132 = OpFAdd %35 %128 %121\n%133 = OpFAdd %35 %129 %122\n%134 = OpFAdd %35 %130 %123\n%135 = OpFAdd %35 %131 %124\n%136 = OpBitcast %5 %132\n%137 = OpBitcast %5 %133\n%138 = OpBitcast %5 %134\n%139 = OpBitcast %5 %135\n%140 = OpCompositeConstruct %14 %136 %137 %138 %139\n%141 = OpAccessChain %84 %58 %86 %114\nOpStore %141 %140 NonPrivatePointer\nOpBranch %152\n%152 = OpLabel\nOpBranch %153\n%153 = OpLabel\n%108 = OpIAdd %5 %107 %56\n%142 = OpAccessChain %87 %71 %86 %86\n%143 = OpLoad %36 %142\n%144 = OpBitcast %14 %143\n%145 = OpCompositeExtract %5 %144 0\n%146 = OpULessThan %92 %108 %145\nOpBranchConditional %146 %149 %154\n%154 = OpLabel\nOpBranch %155\n%155 = OpLabel\n%94 = OpAccessChain %84 %52 %86 %77\n%95 = OpLoad %14 %94 NonPrivatePointer\n%96 = OpBitcast %36 %95\n%97 = OpCompositeExtract %35 %96 0\n%98 = OpCompositeExtract %35 %96 1\n%99 = OpCompositeExtract %35 %96 2\n%100 = OpCompositeExtract %35 %96 3\n%101 = OpBitcast %5 %97\n%102 = OpBitcast %5 %98\n%103 = OpBitcast %5 %99\n%104 = OpBitcast %5 %100\n%105 = OpCompositeConstruct %14 %101 %102 %103 %104\n%106 = OpAccessChain %84 %44 %86 %77\nOpStore %106 %105 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent-promotion.root-descriptor.ssbo.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4Array;\nlayout(buffer_reference) buffer PhysicalPointerUint4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerUintNonWriteArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) buffer PhysicalPointerFloat4Array\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint4NonWriteCBVArray\n{\n    uvec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerUintNonWriteArray\n{\n    uint value[];\n};\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    PhysicalPointerFloat4Array(registers._m2).value[gl_LocalInvocationIndex] = vec4(0.0);\n    if (!(PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x == 0u))\n    {\n        uint _70 = 0u;\n        uint _74;\n        uint _81;\n        bool _83;\n        for (;;)\n        {\n            _74 = (_70 << 8u) + gl_LocalInvocationIndex;\n            _81 = PhysicalPointerUintNonWriteArray(registers._m1).value[_74];\n            groupMemoryBarrier();\n            barrier();\n            _83 = _81 < 256u;\n            if (_83)\n            {\n                vec4 _87 = uintBitsToFloat(_14._m0[_74]);\n                PhysicalPointerFloat4Array _92 = PhysicalPointerFloat4Array(registers._m2);\n                PhysicalPointerFloat4Array(registers._m2).value[_81] = vec4(_92.value[_81].x + _87.x, _92.value[_81].y + _87.y, _92.value[_81].z + _87.z, _92.value[_81].w + _87.w);\n            }\n            uint _71 = _70 + 1u;\n            if (_71 < PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x)\n            {\n                _70 = _71;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    PhysicalPointerFloat4Array _56 = PhysicalPointerFloat4Array(registers._m3);\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_56.value[gl_LocalInvocationIndex].x), floatBitsToUint(_56.value[gl_LocalInvocationIndex].y), floatBitsToUint(_56.value[gl_LocalInvocationIndex].z), floatBitsToUint(_56.value[gl_LocalInvocationIndex].w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 121\n; Schema: 0\nOpCapability Shader\nOpCapability VulkanMemoryModel\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 Vulkan\nOpEntryPoint GLCompute %3 \"main\" %9 %14 %18 %33\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %38 \"PhysicalPointerFloat4Array\"\nOpMemberName %38 0 \"value\"\nOpName %47 \"PhysicalPointerUint4NonWriteCBVArray\"\nOpMemberName %47 0 \"value\"\nOpName %76 \"PhysicalPointerUintNonWriteArray\"\nOpMemberName %76 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 2\nOpDecorate %18 NonReadable\nOpDecorate %33 BuiltIn LocalInvocationIndex\nOpDecorate %37 ArrayStride 16\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpDecorate %46 ArrayStride 16\nOpMemberDecorate %47 0 Offset 0\nOpDecorate %47 Block\nOpMemberDecorate %47 0 NonWritable\nOpDecorate %75 ArrayStride 4\nOpMemberDecorate %76 0 Offset 0\nOpDecorate %76 Block\nOpMemberDecorate %76 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypePointer PushConstant %6\n%21 = OpConstant %5 3\n%24 = OpConstant %5 2\n%27 = OpConstant %5 1\n%30 = OpConstant %5 0\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%35 = OpTypeFloat 32\n%36 = OpTypeVector %35 4\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypeStruct %37\n%39 = OpTypePointer PhysicalStorageBuffer %38\n%41 = OpTypePointer PhysicalStorageBuffer %36\n%43 = OpConstant %35 0\n%45 = OpConstant %5 4096\n%46 = OpTypeArray %10 %45\n%47 = OpTypeStruct %46\n%48 = OpTypePointer PhysicalStorageBuffer %47\n%50 = OpTypePointer PhysicalStorageBuffer %10\n%54 = OpTypeBool\n%68 = OpTypePointer StorageBuffer %10\n%73 = OpConstant %5 8\n%75 = OpTypeRuntimeArray %5\n%76 = OpTypeStruct %75\n%77 = OpTypePointer PhysicalStorageBuffer %76\n%79 = OpTypePointer PhysicalStorageBuffer %5\n%82 = OpConstant %5 26696\n%84 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %111\n%111 = OpLabel\n%20 = OpAccessChain %19 %9 %21\n%22 = OpLoad %6 %20\n%23 = OpAccessChain %19 %9 %24\n%25 = OpLoad %6 %23\n%26 = OpAccessChain %19 %9 %27\n%28 = OpLoad %6 %26\n%29 = OpAccessChain %19 %9 %30\n%31 = OpLoad %6 %29\n%34 = OpLoad %5 %33\n%40 = OpBitcast %39 %25\n%42 = OpInBoundsAccessChain %41 %40 %30 %34\n%44 = OpCompositeConstruct %36 %43 %43 %43 %43\nOpStore %42 %44 Aligned|NonPrivatePointer 16\n%49 = OpBitcast %48 %31\n%51 = OpInBoundsAccessChain %50 %49 %30 %30\n%52 = OpLoad %10 %51 Aligned 16\n%53 = OpCompositeExtract %5 %52 0\n%55 = OpIEqual %54 %53 %30\nOpSelectionMerge %119 None\nOpBranchConditional %55 %119 %112\n%112 = OpLabel\nOpBranch %113\n%113 = OpLabel\n%70 = OpPhi %5 %30 %112 %71 %117\n%72 = OpShiftLeftLogical %5 %70 %73\n%74 = OpIAdd %5 %72 %34\n%78 = OpBitcast %77 %28\n%80 = OpInBoundsAccessChain %79 %78 %30 %74\n%81 = OpLoad %5 %80 Aligned 4\nOpControlBarrier %24 %24 %82\n%83 = OpULessThan %54 %81 %84\nOpLoopMerge %118 %117 None\nOpBranch %114\n%114 = OpLabel\nOpSelectionMerge %116 None\nOpBranchConditional %83 %115 %116\n%115 = OpLabel\n%85 = OpAccessChain %68 %14 %30 %74\n%86 = OpLoad %10 %85\n%87 = OpBitcast %36 %86\n%88 = OpCompositeExtract %35 %87 0\n%89 = OpCompositeExtract %35 %87 1\n%90 = OpCompositeExtract %35 %87 2\n%91 = OpCompositeExtract %35 %87 3\n%92 = OpBitcast %39 %25\n%93 = OpInBoundsAccessChain %41 %92 %30 %81\n%94 = OpLoad %36 %93 Aligned|NonPrivatePointer 16\n%95 = OpCompositeExtract %35 %94 0\n%96 = OpCompositeExtract %35 %94 1\n%97 = OpCompositeExtract %35 %94 2\n%98 = OpCompositeExtract %35 %94 3\n%99 = OpFAdd %35 %95 %88\n%100 = OpFAdd %35 %96 %89\n%101 = OpFAdd %35 %97 %90\n%102 = OpFAdd %35 %98 %91\n%103 = OpBitcast %39 %25\n%104 = OpInBoundsAccessChain %41 %103 %30 %81\n%105 = OpCompositeConstruct %36 %99 %100 %101 %102\nOpStore %104 %105 Aligned|NonPrivatePointer 16\nOpBranch %116\n%116 = OpLabel\nOpBranch %117\n%117 = OpLabel\n%71 = OpIAdd %5 %70 %27\n%106 = OpBitcast %48 %31\n%107 = OpInBoundsAccessChain %50 %106 %30 %30\n%108 = OpLoad %10 %107 Aligned 16\n%109 = OpCompositeExtract %5 %108 0\n%110 = OpULessThan %54 %71 %109\nOpBranchConditional %110 %113 %118\n%118 = OpLabel\nOpBranch %119\n%119 = OpLabel\n%56 = OpBitcast %39 %22\n%57 = OpInBoundsAccessChain %41 %56 %30 %34\n%58 = OpLoad %36 %57 Aligned|NonPrivatePointer 16\n%59 = OpCompositeExtract %35 %58 0\n%60 = OpCompositeExtract %35 %58 1\n%61 = OpCompositeExtract %35 %58 2\n%62 = OpCompositeExtract %35 %58 3\n%63 = OpBitcast %5 %59\n%64 = OpBitcast %5 %60\n%65 = OpBitcast %5 %61\n%66 = OpBitcast %5 %62\n%67 = OpCompositeConstruct %10 %63 %64 %65 %66\n%69 = OpAccessChain %68 %18 %30 %34\nOpStore %69 %67 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent-promotion.sm66.bindless.ssbo.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _14[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _16_19\n{\n    uint _m0[];\n} _19[];\n\nlayout(set = 1, binding = 0, std430) restrict readonly buffer _21_24\n{\n    uvec4 _m0[];\n} _24[];\n\nlayout(set = 5, binding = 0, std140) uniform BindlessCBV\n{\n    vec4 _m0[4096];\n} _32[];\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uint _m0;\n    uint _m1;\n    uint _m2;\n    uint _m3;\n    uint _m4;\n    uint _m5;\n    uint _m6;\n    uint _m7;\n} registers;\n\nvoid main()\n{\n    _14[0u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_32[registers._m5]._m0[0u]).x == 0u))\n    {\n        uint _77 = 0u;\n        uint _81;\n        uint _88;\n        bool _90;\n        for (;;)\n        {\n            _81 = (_77 << 8u) + gl_LocalInvocationIndex;\n            _88 = _19[registers._m1]._m0[_81];\n            groupMemoryBarrier();\n            barrier();\n            _90 = _88 < 256u;\n            if (_90)\n            {\n                vec4 _99 = uintBitsToFloat(_24[registers._m1 + 1u]._m0[_81]);\n                vec4 _106 = uintBitsToFloat(_14[0u]._m0[_88]);\n                _14[0u]._m0[_88] = uvec4(floatBitsToUint(_106.x + _99.x), floatBitsToUint(_106.y + _99.y), floatBitsToUint(_106.z + _99.z), floatBitsToUint(_106.w + _99.w));\n            }\n            uint _78 = _77 + 1u;\n            if (_78 < floatBitsToUint(_32[registers._m5]._m0[0u]).x)\n            {\n                _77 = _78;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _66 = uintBitsToFloat(_14[1u]._m0[gl_LocalInvocationIndex]);\n    _14[2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_66.x), floatBitsToUint(_66.y), floatBitsToUint(_66.z), floatBitsToUint(_66.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 136\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability VulkanMemoryModel\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 Vulkan\nOpEntryPoint GLCompute %3 \"main\" %8 %14 %19 %24 %32 %40\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %6 \"RootConstants\"\nOpName %8 \"registers\"\nOpName %11 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %21 \"SSBO\"\nOpName %29 \"BindlessCBV\"\nOpDecorate %6 Block\nOpMemberDecorate %6 0 Offset 0\nOpMemberDecorate %6 1 Offset 4\nOpMemberDecorate %6 2 Offset 8\nOpMemberDecorate %6 3 Offset 12\nOpMemberDecorate %6 4 Offset 16\nOpMemberDecorate %6 5 Offset 20\nOpMemberDecorate %6 6 Offset 24\nOpMemberDecorate %6 7 Offset 28\nOpDecorate %10 ArrayStride 16\nOpMemberDecorate %11 0 Offset 0\nOpDecorate %11 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 0\nOpDecorate %15 ArrayStride 4\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %19 DescriptorSet 1\nOpDecorate %19 Binding 0\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %20 ArrayStride 16\nOpMemberDecorate %21 0 Offset 0\nOpDecorate %21 Block\nOpDecorate %24 DescriptorSet 1\nOpDecorate %24 Binding 0\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %28 ArrayStride 16\nOpDecorate %29 Block\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %32 DescriptorSet 5\nOpDecorate %32 Binding 0\nOpDecorate %40 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeStruct %5 %5 %5 %5 %5 %5 %5 %5\n%7 = OpTypePointer PushConstant %6\n%8 = OpVariable %7 PushConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypeRuntimeArray %9\n%11 = OpTypeStruct %10\n%12 = OpTypeRuntimeArray %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %5\n%16 = OpTypeStruct %15\n%17 = OpTypeRuntimeArray %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpTypeRuntimeArray %9\n%21 = OpTypeStruct %20\n%22 = OpTypeRuntimeArray %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpTypeFloat 32\n%26 = OpTypeVector %25 4\n%27 = OpConstant %5 4096\n%28 = OpTypeArray %26 %27\n%29 = OpTypeStruct %28\n%30 = OpTypeRuntimeArray %29\n%31 = OpTypePointer Uniform %30\n%32 = OpVariable %31 Uniform\n%33 = OpTypePointer Uniform %29\n%35 = OpTypePointer PushConstant %5\n%37 = OpConstant %5 5\n%39 = OpTypePointer Input %5\n%40 = OpVariable %39 Input\n%42 = OpTypePointer StorageBuffer %11\n%44 = OpConstant %5 0\n%46 = OpConstant %5 1\n%48 = OpConstant %5 2\n%49 = OpConstant %25 0\n%55 = OpTypePointer StorageBuffer %9\n%57 = OpTypePointer Uniform %26\n%62 = OpTypeBool\n%80 = OpConstant %5 8\n%82 = OpTypePointer StorageBuffer %16\n%86 = OpTypePointer StorageBuffer %5\n%89 = OpConstant %5 26696\n%91 = OpConstant %5 256\n%92 = OpTypePointer StorageBuffer %21\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %126\n%126 = OpLabel\n%36 = OpAccessChain %35 %8 %37\n%38 = OpLoad %5 %36\n%34 = OpAccessChain %33 %32 %38\n%41 = OpLoad %5 %40\n%43 = OpAccessChain %42 %14 %44\n%45 = OpAccessChain %42 %14 %46\n%47 = OpAccessChain %42 %14 %48\n%50 = OpBitcast %5 %49\n%51 = OpBitcast %5 %49\n%52 = OpBitcast %5 %49\n%53 = OpBitcast %5 %49\n%54 = OpCompositeConstruct %9 %50 %51 %52 %53\n%56 = OpAccessChain %55 %43 %44 %41\nOpStore %56 %54 NonPrivatePointer\n%58 = OpAccessChain %57 %34 %44 %44\n%59 = OpLoad %26 %58\n%60 = OpBitcast %9 %59\n%61 = OpCompositeExtract %5 %60 0\n%63 = OpIEqual %62 %61 %44\nOpSelectionMerge %134 None\nOpBranchConditional %63 %134 %127\n%127 = OpLabel\nOpBranch %128\n%128 = OpLabel\n%77 = OpPhi %5 %44 %127 %78 %132\n%79 = OpShiftLeftLogical %5 %77 %80\n%81 = OpIAdd %5 %79 %41\n%84 = OpAccessChain %35 %8 %46\n%85 = OpLoad %5 %84\n%83 = OpAccessChain %82 %19 %85\n%87 = OpAccessChain %86 %83 %44 %81\n%88 = OpLoad %5 %87\nOpControlBarrier %48 %48 %89\n%90 = OpULessThan %62 %88 %91\nOpLoopMerge %133 %132 None\nOpBranch %129\n%129 = OpLabel\nOpSelectionMerge %131 None\nOpBranchConditional %90 %130 %131\n%130 = OpLabel\n%94 = OpAccessChain %35 %8 %46\n%95 = OpLoad %5 %94\n%96 = OpIAdd %5 %95 %46\n%93 = OpAccessChain %92 %24 %96\n%97 = OpAccessChain %55 %93 %44 %81\n%98 = OpLoad %9 %97\n%99 = OpBitcast %26 %98\n%100 = OpCompositeExtract %25 %99 0\n%101 = OpCompositeExtract %25 %99 1\n%102 = OpCompositeExtract %25 %99 2\n%103 = OpCompositeExtract %25 %99 3\n%104 = OpAccessChain %55 %43 %44 %88\n%105 = OpLoad %9 %104 NonPrivatePointer\n%106 = OpBitcast %26 %105\n%107 = OpCompositeExtract %25 %106 0\n%108 = OpCompositeExtract %25 %106 1\n%109 = OpCompositeExtract %25 %106 2\n%110 = OpCompositeExtract %25 %106 3\n%111 = OpFAdd %25 %107 %100\n%112 = OpFAdd %25 %108 %101\n%113 = OpFAdd %25 %109 %102\n%114 = OpFAdd %25 %110 %103\n%115 = OpBitcast %5 %111\n%116 = OpBitcast %5 %112\n%117 = OpBitcast %5 %113\n%118 = OpBitcast %5 %114\n%119 = OpCompositeConstruct %9 %115 %116 %117 %118\n%120 = OpAccessChain %55 %43 %44 %88\nOpStore %120 %119 NonPrivatePointer\nOpBranch %131\n%131 = OpLabel\nOpBranch %132\n%132 = OpLabel\n%78 = OpIAdd %5 %77 %46\n%121 = OpAccessChain %57 %34 %44 %44\n%122 = OpLoad %26 %121\n%123 = OpBitcast %9 %122\n%124 = OpCompositeExtract %5 %123 0\n%125 = OpULessThan %62 %78 %124\nOpBranchConditional %125 %128 %133\n%133 = OpLabel\nOpBranch %134\n%134 = OpLabel\n%64 = OpAccessChain %55 %45 %44 %41\n%65 = OpLoad %9 %64 NonPrivatePointer\n%66 = OpBitcast %26 %65\n%67 = OpCompositeExtract %25 %66 0\n%68 = OpCompositeExtract %25 %66 1\n%69 = OpCompositeExtract %25 %66 2\n%70 = OpCompositeExtract %25 %66 3\n%71 = OpBitcast %5 %67\n%72 = OpBitcast %5 %68\n%73 = OpBitcast %5 %69\n%74 = OpBitcast %5 %70\n%75 = OpCompositeConstruct %9 %71 %72 %73 %74\n%76 = OpAccessChain %55 %47 %44 %41\nOpStore %76 %75 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent-promotion.sm66.ssbo.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _11[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _13_15\n{\n    uint _m0[];\n} _15;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _17_19\n{\n    uvec4 _m0[];\n} _19;\n\nlayout(set = 0, binding = 0, std140) uniform _24_26\n{\n    vec4 _m0[1];\n} _26;\n\nvoid main()\n{\n    _11[0u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_26._m0[0u]).x == 0u))\n    {\n        uint _64 = 0u;\n        uint _68;\n        uint _71;\n        bool _73;\n        for (;;)\n        {\n            _68 = (_64 << 8u) + gl_LocalInvocationIndex;\n            _71 = _15._m0[_68];\n            groupMemoryBarrier();\n            barrier();\n            _73 = _71 < 256u;\n            if (_73)\n            {\n                vec4 _77 = uintBitsToFloat(_19._m0[_68]);\n                vec4 _84 = uintBitsToFloat(_11[0u]._m0[_71]);\n                _11[0u]._m0[_71] = uvec4(floatBitsToUint(_84.x + _77.x), floatBitsToUint(_84.y + _77.y), floatBitsToUint(_84.z + _77.z), floatBitsToUint(_84.w + _77.w));\n            }\n            uint _65 = _64 + 1u;\n            if (_65 < floatBitsToUint(_26._m0[0u]).x)\n            {\n                _64 = _65;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _53 = uintBitsToFloat(_11[1u]._m0[gl_LocalInvocationIndex]);\n    _11[2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_53.x), floatBitsToUint(_53.y), floatBitsToUint(_53.z), floatBitsToUint(_53.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 114\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability VulkanMemoryModel\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %11 %15 %19 %26 %28\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %17 \"SSBO\"\nOpName %24 \"\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %12 ArrayStride 4\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %15 DescriptorSet 0\nOpDecorate %15 Binding 0\nOpDecorate %15 NonWritable\nOpDecorate %15 Restrict\nOpDecorate %16 ArrayStride 16\nOpMemberDecorate %17 0 Offset 0\nOpDecorate %17 Block\nOpDecorate %19 DescriptorSet 0\nOpDecorate %19 Binding 1\nOpDecorate %19 NonWritable\nOpDecorate %19 Restrict\nOpDecorate %23 ArrayStride 16\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 0\nOpDecorate %28 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeRuntimeArray %5\n%13 = OpTypeStruct %12\n%14 = OpTypePointer StorageBuffer %13\n%15 = OpVariable %14 StorageBuffer\n%16 = OpTypeRuntimeArray %6\n%17 = OpTypeStruct %16\n%18 = OpTypePointer StorageBuffer %17\n%19 = OpVariable %18 StorageBuffer\n%20 = OpConstant %5 1\n%21 = OpTypeFloat 32\n%22 = OpTypeVector %21 4\n%23 = OpTypeArray %22 %20\n%24 = OpTypeStruct %23\n%25 = OpTypePointer Uniform %24\n%26 = OpVariable %25 Uniform\n%27 = OpTypePointer Input %5\n%28 = OpVariable %27 Input\n%30 = OpTypePointer StorageBuffer %8\n%32 = OpConstant %5 0\n%35 = OpConstant %5 2\n%36 = OpConstant %21 0\n%42 = OpTypePointer StorageBuffer %6\n%44 = OpTypePointer Uniform %22\n%49 = OpTypeBool\n%67 = OpConstant %5 8\n%69 = OpTypePointer StorageBuffer %5\n%72 = OpConstant %5 26696\n%74 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %104\n%104 = OpLabel\n%29 = OpLoad %5 %28\n%31 = OpAccessChain %30 %11 %32\n%33 = OpAccessChain %30 %11 %20\n%34 = OpAccessChain %30 %11 %35\n%37 = OpBitcast %5 %36\n%38 = OpBitcast %5 %36\n%39 = OpBitcast %5 %36\n%40 = OpBitcast %5 %36\n%41 = OpCompositeConstruct %6 %37 %38 %39 %40\n%43 = OpAccessChain %42 %31 %32 %29\nOpStore %43 %41 NonPrivatePointer\n%45 = OpAccessChain %44 %26 %32 %32\n%46 = OpLoad %22 %45\n%47 = OpBitcast %6 %46\n%48 = OpCompositeExtract %5 %47 0\n%50 = OpIEqual %49 %48 %32\nOpSelectionMerge %112 None\nOpBranchConditional %50 %112 %105\n%105 = OpLabel\nOpBranch %106\n%106 = OpLabel\n%64 = OpPhi %5 %32 %105 %65 %110\n%66 = OpShiftLeftLogical %5 %64 %67\n%68 = OpIAdd %5 %66 %29\n%70 = OpAccessChain %69 %15 %32 %68\n%71 = OpLoad %5 %70\nOpControlBarrier %35 %35 %72\n%73 = OpULessThan %49 %71 %74\nOpLoopMerge %111 %110 None\nOpBranch %107\n%107 = OpLabel\nOpSelectionMerge %109 None\nOpBranchConditional %73 %108 %109\n%108 = OpLabel\n%75 = OpAccessChain %42 %19 %32 %68\n%76 = OpLoad %6 %75\n%77 = OpBitcast %22 %76\n%78 = OpCompositeExtract %21 %77 0\n%79 = OpCompositeExtract %21 %77 1\n%80 = OpCompositeExtract %21 %77 2\n%81 = OpCompositeExtract %21 %77 3\n%82 = OpAccessChain %42 %31 %32 %71\n%83 = OpLoad %6 %82 NonPrivatePointer\n%84 = OpBitcast %22 %83\n%85 = OpCompositeExtract %21 %84 0\n%86 = OpCompositeExtract %21 %84 1\n%87 = OpCompositeExtract %21 %84 2\n%88 = OpCompositeExtract %21 %84 3\n%89 = OpFAdd %21 %85 %78\n%90 = OpFAdd %21 %86 %79\n%91 = OpFAdd %21 %87 %80\n%92 = OpFAdd %21 %88 %81\n%93 = OpBitcast %5 %89\n%94 = OpBitcast %5 %90\n%95 = OpBitcast %5 %91\n%96 = OpBitcast %5 %92\n%97 = OpCompositeConstruct %6 %93 %94 %95 %96\n%98 = OpAccessChain %42 %31 %32 %71\nOpStore %98 %97 NonPrivatePointer\nOpBranch %109\n%109 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%65 = OpIAdd %5 %64 %20\n%99 = OpAccessChain %44 %26 %32 %32\n%100 = OpLoad %22 %99\n%101 = OpBitcast %6 %100\n%102 = OpCompositeExtract %5 %101 0\n%103 = OpULessThan %49 %65 %102\nOpBranchConditional %103 %106 %111\n%111 = OpLabel\nOpBranch %112\n%112 = OpLabel\n%51 = OpAccessChain %42 %33 %32 %29\n%52 = OpLoad %6 %51 NonPrivatePointer\n%53 = OpBitcast %22 %52\n%54 = OpCompositeExtract %21 %53 0\n%55 = OpCompositeExtract %21 %53 1\n%56 = OpCompositeExtract %21 %53 2\n%57 = OpCompositeExtract %21 %53 3\n%58 = OpBitcast %5 %54\n%59 = OpBitcast %5 %55\n%60 = OpBitcast %5 %56\n%61 = OpBitcast %5 %57\n%62 = OpCompositeConstruct %6 %58 %59 %60 %61\n%63 = OpAccessChain %42 %34 %32 %29\nOpStore %63 %62 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent-promotion.ssbo.vkmm.comp",
    "content": "#version 460\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, std430) buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(set = 0, binding = 1, std430) readonly buffer _20_22\n{\n    uvec4 _m0[];\n} _22;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _24_26\n{\n    uvec4 _m0[];\n} _26;\n\nlayout(set = 0, binding = 0, std140) uniform _31_33\n{\n    vec4 _m0[1];\n} _33;\n\nvoid main()\n{\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_33._m0[0u]).x == 0u))\n    {\n        uint _66 = 0u;\n        uint _70;\n        uint _73;\n        bool _76;\n        for (;;)\n        {\n            _70 = (_66 << 8u) + gl_LocalInvocationIndex;\n            _73 = _9._m0[_70];\n            groupMemoryBarrier();\n            barrier();\n            _76 = _73 < 256u;\n            if (_76)\n            {\n                vec4 _80 = uintBitsToFloat(_14._m0[_70]);\n                vec4 _87 = uintBitsToFloat(_18._m0[_73]);\n                _18._m0[_73] = uvec4(floatBitsToUint(_87.x + _80.x), floatBitsToUint(_87.y + _80.y), floatBitsToUint(_87.z + _80.z), floatBitsToUint(_87.w + _80.w));\n            }\n            uint _67 = _66 + 1u;\n            if (_67 < floatBitsToUint(_33._m0[0u]).x)\n            {\n                _66 = _67;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _55 = uintBitsToFloat(_22._m0[gl_LocalInvocationIndex]);\n    _26._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_55.x), floatBitsToUint(_55.y), floatBitsToUint(_55.z), floatBitsToUint(_55.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 117\n; Schema: 0\nOpCapability Shader\nOpCapability VulkanMemoryModel\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %9 %14 %18 %22 %26 %33 %35\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %20 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %31 \"\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 1\nOpDecorate %22 NonWritable\nOpDecorate %23 ArrayStride 16\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 2\nOpDecorate %26 NonReadable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %35 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %10\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %10\n%24 = OpTypeStruct %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpConstant %5 1\n%28 = OpTypeFloat 32\n%29 = OpTypeVector %28 4\n%30 = OpTypeArray %29 %27\n%31 = OpTypeStruct %30\n%32 = OpTypePointer Uniform %31\n%33 = OpVariable %32 Uniform\n%34 = OpTypePointer Input %5\n%35 = OpVariable %34 Input\n%37 = OpConstant %28 0\n%43 = OpTypePointer StorageBuffer %10\n%45 = OpConstant %5 0\n%46 = OpTypePointer Uniform %29\n%51 = OpTypeBool\n%69 = OpConstant %5 8\n%71 = OpTypePointer StorageBuffer %5\n%74 = OpConstant %5 2\n%75 = OpConstant %5 26696\n%77 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %107\n%107 = OpLabel\n%36 = OpLoad %5 %35\n%38 = OpBitcast %5 %37\n%39 = OpBitcast %5 %37\n%40 = OpBitcast %5 %37\n%41 = OpBitcast %5 %37\n%42 = OpCompositeConstruct %10 %38 %39 %40 %41\n%44 = OpAccessChain %43 %18 %45 %36\nOpStore %44 %42 NonPrivatePointer\n%47 = OpAccessChain %46 %33 %45 %45\n%48 = OpLoad %29 %47\n%49 = OpBitcast %10 %48\n%50 = OpCompositeExtract %5 %49 0\n%52 = OpIEqual %51 %50 %45\nOpSelectionMerge %115 None\nOpBranchConditional %52 %115 %108\n%108 = OpLabel\nOpBranch %109\n%109 = OpLabel\n%66 = OpPhi %5 %45 %108 %67 %113\n%68 = OpShiftLeftLogical %5 %66 %69\n%70 = OpIAdd %5 %68 %36\n%72 = OpAccessChain %71 %9 %45 %70\n%73 = OpLoad %5 %72\nOpControlBarrier %74 %74 %75\n%76 = OpULessThan %51 %73 %77\nOpLoopMerge %114 %113 None\nOpBranch %110\n%110 = OpLabel\nOpSelectionMerge %112 None\nOpBranchConditional %76 %111 %112\n%111 = OpLabel\n%78 = OpAccessChain %43 %14 %45 %70\n%79 = OpLoad %10 %78\n%80 = OpBitcast %29 %79\n%81 = OpCompositeExtract %28 %80 0\n%82 = OpCompositeExtract %28 %80 1\n%83 = OpCompositeExtract %28 %80 2\n%84 = OpCompositeExtract %28 %80 3\n%85 = OpAccessChain %43 %18 %45 %73\n%86 = OpLoad %10 %85 NonPrivatePointer\n%87 = OpBitcast %29 %86\n%88 = OpCompositeExtract %28 %87 0\n%89 = OpCompositeExtract %28 %87 1\n%90 = OpCompositeExtract %28 %87 2\n%91 = OpCompositeExtract %28 %87 3\n%92 = OpFAdd %28 %88 %81\n%93 = OpFAdd %28 %89 %82\n%94 = OpFAdd %28 %90 %83\n%95 = OpFAdd %28 %91 %84\n%96 = OpBitcast %5 %92\n%97 = OpBitcast %5 %93\n%98 = OpBitcast %5 %94\n%99 = OpBitcast %5 %95\n%100 = OpCompositeConstruct %10 %96 %97 %98 %99\n%101 = OpAccessChain %43 %18 %45 %73\nOpStore %101 %100 NonPrivatePointer\nOpBranch %112\n%112 = OpLabel\nOpBranch %113\n%113 = OpLabel\n%67 = OpIAdd %5 %66 %27\n%102 = OpAccessChain %46 %33 %45 %45\n%103 = OpLoad %29 %102\n%104 = OpBitcast %10 %103\n%105 = OpCompositeExtract %5 %104 0\n%106 = OpULessThan %51 %67 %105\nOpBranchConditional %106 %109 %114\n%114 = OpLabel\nOpBranch %115\n%115 = OpLabel\n%53 = OpAccessChain %43 %22 %45 %36\n%54 = OpLoad %10 %53 NonPrivatePointer\n%55 = OpBitcast %29 %54\n%56 = OpCompositeExtract %28 %55 0\n%57 = OpCompositeExtract %28 %55 1\n%58 = OpCompositeExtract %28 %55 2\n%59 = OpCompositeExtract %28 %55 3\n%60 = OpBitcast %5 %56\n%61 = OpBitcast %5 %57\n%62 = OpBitcast %5 %58\n%63 = OpBitcast %5 %59\n%64 = OpCompositeConstruct %10 %60 %61 %62 %63\n%65 = OpAccessChain %43 %26 %45 %36\nOpStore %65 %64 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent.root-descriptor.ssbo.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_buffer_reference2 : require\n#extension GL_EXT_buffer_reference_uvec2 : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(buffer_reference) buffer PhysicalPointerFloat4CoherentArray;\nlayout(buffer_reference) buffer PhysicalPointerUint4NonWriteCBVArray;\nlayout(buffer_reference) buffer PhysicalPointerFloat4Array;\nlayout(buffer_reference) buffer PhysicalPointerUintNonWriteArray;\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) buffer PhysicalPointerFloat4CoherentArray\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint4NonWriteCBVArray\n{\n    uvec4 value[4096];\n};\n\nlayout(buffer_reference, buffer_reference_align = 16, std430) buffer PhysicalPointerFloat4Array\n{\n    vec4 value[];\n};\n\nlayout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerUintNonWriteArray\n{\n    uint value[];\n};\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(push_constant, std430) uniform RootConstants\n{\n    uvec2 _m0;\n    uvec2 _m1;\n    uvec2 _m2;\n    uvec2 _m3;\n} registers;\n\nvoid main()\n{\n    PhysicalPointerFloat4CoherentArray(registers._m2).value[gl_LocalInvocationIndex] = vec4(0.0);\n    if (!(PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x == 0u))\n    {\n        uint _74 = 0u;\n        uint _78;\n        uint _85;\n        bool _87;\n        for (;;)\n        {\n            _78 = (_74 << 8u) + gl_LocalInvocationIndex;\n            _85 = PhysicalPointerUintNonWriteArray(registers._m1).value[_78];\n            groupMemoryBarrier();\n            barrier();\n            _87 = _85 < 256u;\n            if (_87)\n            {\n                vec4 _91 = uintBitsToFloat(_14._m0[_78]);\n                PhysicalPointerFloat4CoherentArray _96 = PhysicalPointerFloat4CoherentArray(registers._m2);\n                PhysicalPointerFloat4CoherentArray(registers._m2).value[_85] = vec4(_96.value[_85].x + _91.x, _96.value[_85].y + _91.y, _96.value[_85].z + _91.z, _96.value[_85].w + _91.w);\n            }\n            uint _75 = _74 + 1u;\n            if (_75 < PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x)\n            {\n                _74 = _75;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    PhysicalPointerFloat4Array _60 = PhysicalPointerFloat4Array(registers._m3);\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_60.value[gl_LocalInvocationIndex].x), floatBitsToUint(_60.value[gl_LocalInvocationIndex].y), floatBitsToUint(_60.value[gl_LocalInvocationIndex].z), floatBitsToUint(_60.value[gl_LocalInvocationIndex].w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 125\n; Schema: 0\nOpCapability Shader\nOpCapability VulkanMemoryModel\nOpCapability PhysicalStorageBufferAddresses\nOpExtension \"SPV_KHR_physical_storage_buffer\"\nOpMemoryModel PhysicalStorageBuffer64 Vulkan\nOpEntryPoint GLCompute %3 \"main\" %9 %14 %18 %33\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"RootConstants\"\nOpName %9 \"registers\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %38 \"PhysicalPointerFloat4CoherentArray\"\nOpMemberName %38 0 \"value\"\nOpName %48 \"PhysicalPointerUint4NonWriteCBVArray\"\nOpMemberName %48 0 \"value\"\nOpName %58 \"PhysicalPointerFloat4Array\"\nOpMemberName %58 0 \"value\"\nOpName %80 \"PhysicalPointerUintNonWriteArray\"\nOpMemberName %80 0 \"value\"\nOpDecorate %7 Block\nOpMemberDecorate %7 0 Offset 0\nOpMemberDecorate %7 1 Offset 8\nOpMemberDecorate %7 2 Offset 16\nOpMemberDecorate %7 3 Offset 24\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 2\nOpDecorate %18 NonReadable\nOpDecorate %33 BuiltIn LocalInvocationIndex\nOpDecorate %37 ArrayStride 16\nOpMemberDecorate %38 0 Offset 0\nOpDecorate %38 Block\nOpDecorate %47 ArrayStride 16\nOpMemberDecorate %48 0 Offset 0\nOpDecorate %48 Block\nOpMemberDecorate %48 0 NonWritable\nOpDecorate %57 ArrayStride 16\nOpMemberDecorate %58 0 Offset 0\nOpDecorate %58 Block\nOpDecorate %79 ArrayStride 4\nOpMemberDecorate %80 0 Offset 0\nOpDecorate %80 Block\nOpMemberDecorate %80 0 NonWritable\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 2\n%7 = OpTypeStruct %6 %6 %6 %6\n%8 = OpTypePointer PushConstant %7\n%9 = OpVariable %8 PushConstant\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypePointer PushConstant %6\n%21 = OpConstant %5 3\n%24 = OpConstant %5 2\n%27 = OpConstant %5 1\n%30 = OpConstant %5 0\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%35 = OpTypeFloat 32\n%36 = OpTypeVector %35 4\n%37 = OpTypeRuntimeArray %36\n%38 = OpTypeStruct %37\n%39 = OpTypePointer PhysicalStorageBuffer %38\n%41 = OpTypePointer PhysicalStorageBuffer %36\n%43 = OpConstant %35 0\n%45 = OpConstant %5 5\n%46 = OpConstant %5 4096\n%47 = OpTypeArray %10 %46\n%48 = OpTypeStruct %47\n%49 = OpTypePointer PhysicalStorageBuffer %48\n%51 = OpTypePointer PhysicalStorageBuffer %10\n%55 = OpTypeBool\n%57 = OpTypeRuntimeArray %36\n%58 = OpTypeStruct %57\n%59 = OpTypePointer PhysicalStorageBuffer %58\n%72 = OpTypePointer StorageBuffer %10\n%77 = OpConstant %5 8\n%79 = OpTypeRuntimeArray %5\n%80 = OpTypeStruct %79\n%81 = OpTypePointer PhysicalStorageBuffer %80\n%83 = OpTypePointer PhysicalStorageBuffer %5\n%86 = OpConstant %5 26696\n%88 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %115\n%115 = OpLabel\n%20 = OpAccessChain %19 %9 %21\n%22 = OpLoad %6 %20\n%23 = OpAccessChain %19 %9 %24\n%25 = OpLoad %6 %23\n%26 = OpAccessChain %19 %9 %27\n%28 = OpLoad %6 %26\n%29 = OpAccessChain %19 %9 %30\n%31 = OpLoad %6 %29\n%34 = OpLoad %5 %33\n%40 = OpBitcast %39 %25\n%42 = OpInBoundsAccessChain %41 %40 %30 %34\n%44 = OpCompositeConstruct %36 %43 %43 %43 %43\nOpStore %42 %44 Aligned|MakePointerAvailable|NonPrivatePointer 16 %45\n%50 = OpBitcast %49 %31\n%52 = OpInBoundsAccessChain %51 %50 %30 %30\n%53 = OpLoad %10 %52 Aligned 16\n%54 = OpCompositeExtract %5 %53 0\n%56 = OpIEqual %55 %54 %30\nOpSelectionMerge %123 None\nOpBranchConditional %56 %123 %116\n%116 = OpLabel\nOpBranch %117\n%117 = OpLabel\n%74 = OpPhi %5 %30 %116 %75 %121\n%76 = OpShiftLeftLogical %5 %74 %77\n%78 = OpIAdd %5 %76 %34\n%82 = OpBitcast %81 %28\n%84 = OpInBoundsAccessChain %83 %82 %30 %78\n%85 = OpLoad %5 %84 Aligned 4\nOpControlBarrier %24 %24 %86\n%87 = OpULessThan %55 %85 %88\nOpLoopMerge %122 %121 None\nOpBranch %118\n%118 = OpLabel\nOpSelectionMerge %120 None\nOpBranchConditional %87 %119 %120\n%119 = OpLabel\n%89 = OpAccessChain %72 %14 %30 %78\n%90 = OpLoad %10 %89\n%91 = OpBitcast %36 %90\n%92 = OpCompositeExtract %35 %91 0\n%93 = OpCompositeExtract %35 %91 1\n%94 = OpCompositeExtract %35 %91 2\n%95 = OpCompositeExtract %35 %91 3\n%96 = OpBitcast %39 %25\n%97 = OpInBoundsAccessChain %41 %96 %30 %85\n%98 = OpLoad %36 %97 Aligned|MakePointerVisible|NonPrivatePointer 16 %45\n%99 = OpCompositeExtract %35 %98 0\n%100 = OpCompositeExtract %35 %98 1\n%101 = OpCompositeExtract %35 %98 2\n%102 = OpCompositeExtract %35 %98 3\n%103 = OpFAdd %35 %99 %92\n%104 = OpFAdd %35 %100 %93\n%105 = OpFAdd %35 %101 %94\n%106 = OpFAdd %35 %102 %95\n%107 = OpBitcast %39 %25\n%108 = OpInBoundsAccessChain %41 %107 %30 %85\n%109 = OpCompositeConstruct %36 %103 %104 %105 %106\nOpStore %108 %109 Aligned|MakePointerAvailable|NonPrivatePointer 16 %45\nOpBranch %120\n%120 = OpLabel\nOpBranch %121\n%121 = OpLabel\n%75 = OpIAdd %5 %74 %27\n%110 = OpBitcast %49 %31\n%111 = OpInBoundsAccessChain %51 %110 %30 %30\n%112 = OpLoad %10 %111 Aligned 16\n%113 = OpCompositeExtract %5 %112 0\n%114 = OpULessThan %55 %75 %113\nOpBranchConditional %114 %117 %122\n%122 = OpLabel\nOpBranch %123\n%123 = OpLabel\n%60 = OpBitcast %59 %22\n%61 = OpInBoundsAccessChain %41 %60 %30 %34\n%62 = OpLoad %36 %61 Aligned|NonPrivatePointer 16\n%63 = OpCompositeExtract %35 %62 0\n%64 = OpCompositeExtract %35 %62 1\n%65 = OpCompositeExtract %35 %62 2\n%66 = OpCompositeExtract %35 %62 3\n%67 = OpBitcast %5 %63\n%68 = OpBitcast %5 %64\n%69 = OpBitcast %5 %65\n%70 = OpBitcast %5 %66\n%71 = OpCompositeConstruct %10 %67 %68 %69 %70\n%73 = OpAccessChain %72 %18 %30 %34\nOpStore %73 %71 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent.sm66.ssbo.vkmm.comp",
    "content": "#version 460\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uvec4 _m0[];\n} _11[];\n\nlayout(set = 0, binding = 0, std430) buffer _13_16\n{\n    uvec4 _m0[];\n} _16[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _18_20\n{\n    uint _m0[];\n} _20;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _22_24\n{\n    uvec4 _m0[];\n} _24;\n\nlayout(set = 0, binding = 0, std140) uniform _29_31\n{\n    vec4 _m0[1];\n} _31;\n\nvoid main()\n{\n    _11[0u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_31._m0[0u]).x == 0u))\n    {\n        uint _71 = 0u;\n        uint _75;\n        uint _78;\n        bool _80;\n        for (;;)\n        {\n            _75 = (_71 << 8u) + gl_LocalInvocationIndex;\n            _78 = _20._m0[_75];\n            groupMemoryBarrier();\n            barrier();\n            _80 = _78 < 256u;\n            if (_80)\n            {\n                vec4 _84 = uintBitsToFloat(_24._m0[_75]);\n                vec4 _91 = uintBitsToFloat(_11[0u]._m0[_78]);\n                _11[0u]._m0[_78] = uvec4(floatBitsToUint(_91.x + _84.x), floatBitsToUint(_91.y + _84.y), floatBitsToUint(_91.z + _84.z), floatBitsToUint(_91.w + _84.w));\n            }\n            uint _72 = _71 + 1u;\n            if (_72 < floatBitsToUint(_31._m0[0u]).x)\n            {\n                _71 = _72;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _60 = uintBitsToFloat(_16[1u]._m0[gl_LocalInvocationIndex]);\n    _16[2u]._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_60.x), floatBitsToUint(_60.y), floatBitsToUint(_60.z), floatBitsToUint(_60.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 121\n; Schema: 0\nOpCapability Shader\nOpCapability RuntimeDescriptorArray\nOpCapability VulkanMemoryModel\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %11 %16 %20 %24 %31 %33\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %8 \"SSBO\"\nOpName %13 \"SSBO\"\nOpName %18 \"SSBO\"\nOpName %22 \"SSBO\"\nOpName %29 \"\"\nOpDecorate %7 ArrayStride 16\nOpMemberDecorate %8 0 Offset 0\nOpDecorate %8 Block\nOpDecorate %11 DescriptorSet 0\nOpDecorate %11 Binding 0\nOpDecorate %12 ArrayStride 16\nOpMemberDecorate %13 0 Offset 0\nOpDecorate %13 Block\nOpDecorate %16 DescriptorSet 0\nOpDecorate %16 Binding 0\nOpDecorate %17 ArrayStride 4\nOpMemberDecorate %18 0 Offset 0\nOpDecorate %18 Block\nOpDecorate %20 DescriptorSet 0\nOpDecorate %20 Binding 0\nOpDecorate %20 NonWritable\nOpDecorate %20 Restrict\nOpDecorate %21 ArrayStride 16\nOpMemberDecorate %22 0 Offset 0\nOpDecorate %22 Block\nOpDecorate %24 DescriptorSet 0\nOpDecorate %24 Binding 1\nOpDecorate %24 NonWritable\nOpDecorate %24 Restrict\nOpDecorate %28 ArrayStride 16\nOpMemberDecorate %29 0 Offset 0\nOpDecorate %29 Block\nOpDecorate %31 DescriptorSet 0\nOpDecorate %31 Binding 0\nOpDecorate %33 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeVector %5 4\n%7 = OpTypeRuntimeArray %6\n%8 = OpTypeStruct %7\n%9 = OpTypeRuntimeArray %8\n%10 = OpTypePointer StorageBuffer %9\n%11 = OpVariable %10 StorageBuffer\n%12 = OpTypeRuntimeArray %6\n%13 = OpTypeStruct %12\n%14 = OpTypeRuntimeArray %13\n%15 = OpTypePointer StorageBuffer %14\n%16 = OpVariable %15 StorageBuffer\n%17 = OpTypeRuntimeArray %5\n%18 = OpTypeStruct %17\n%19 = OpTypePointer StorageBuffer %18\n%20 = OpVariable %19 StorageBuffer\n%21 = OpTypeRuntimeArray %6\n%22 = OpTypeStruct %21\n%23 = OpTypePointer StorageBuffer %22\n%24 = OpVariable %23 StorageBuffer\n%25 = OpConstant %5 1\n%26 = OpTypeFloat 32\n%27 = OpTypeVector %26 4\n%28 = OpTypeArray %27 %25\n%29 = OpTypeStruct %28\n%30 = OpTypePointer Uniform %29\n%31 = OpVariable %30 Uniform\n%32 = OpTypePointer Input %5\n%33 = OpVariable %32 Input\n%35 = OpTypePointer StorageBuffer %8\n%37 = OpConstant %5 0\n%38 = OpTypePointer StorageBuffer %13\n%41 = OpConstant %5 2\n%42 = OpConstant %26 0\n%48 = OpTypePointer StorageBuffer %6\n%50 = OpConstant %5 5\n%51 = OpTypePointer Uniform %27\n%56 = OpTypeBool\n%74 = OpConstant %5 8\n%76 = OpTypePointer StorageBuffer %5\n%79 = OpConstant %5 26696\n%81 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %111\n%111 = OpLabel\n%34 = OpLoad %5 %33\n%36 = OpAccessChain %35 %11 %37\n%39 = OpAccessChain %38 %16 %25\n%40 = OpAccessChain %38 %16 %41\n%43 = OpBitcast %5 %42\n%44 = OpBitcast %5 %42\n%45 = OpBitcast %5 %42\n%46 = OpBitcast %5 %42\n%47 = OpCompositeConstruct %6 %43 %44 %45 %46\n%49 = OpAccessChain %48 %36 %37 %34\nOpStore %49 %47 MakePointerAvailable|NonPrivatePointer %50\n%52 = OpAccessChain %51 %31 %37 %37\n%53 = OpLoad %27 %52\n%54 = OpBitcast %6 %53\n%55 = OpCompositeExtract %5 %54 0\n%57 = OpIEqual %56 %55 %37\nOpSelectionMerge %119 None\nOpBranchConditional %57 %119 %112\n%112 = OpLabel\nOpBranch %113\n%113 = OpLabel\n%71 = OpPhi %5 %37 %112 %72 %117\n%73 = OpShiftLeftLogical %5 %71 %74\n%75 = OpIAdd %5 %73 %34\n%77 = OpAccessChain %76 %20 %37 %75\n%78 = OpLoad %5 %77\nOpControlBarrier %41 %41 %79\n%80 = OpULessThan %56 %78 %81\nOpLoopMerge %118 %117 None\nOpBranch %114\n%114 = OpLabel\nOpSelectionMerge %116 None\nOpBranchConditional %80 %115 %116\n%115 = OpLabel\n%82 = OpAccessChain %48 %24 %37 %75\n%83 = OpLoad %6 %82\n%84 = OpBitcast %27 %83\n%85 = OpCompositeExtract %26 %84 0\n%86 = OpCompositeExtract %26 %84 1\n%87 = OpCompositeExtract %26 %84 2\n%88 = OpCompositeExtract %26 %84 3\n%89 = OpAccessChain %48 %36 %37 %78\n%90 = OpLoad %6 %89 MakePointerVisible|NonPrivatePointer %50\n%91 = OpBitcast %27 %90\n%92 = OpCompositeExtract %26 %91 0\n%93 = OpCompositeExtract %26 %91 1\n%94 = OpCompositeExtract %26 %91 2\n%95 = OpCompositeExtract %26 %91 3\n%96 = OpFAdd %26 %92 %85\n%97 = OpFAdd %26 %93 %86\n%98 = OpFAdd %26 %94 %87\n%99 = OpFAdd %26 %95 %88\n%100 = OpBitcast %5 %96\n%101 = OpBitcast %5 %97\n%102 = OpBitcast %5 %98\n%103 = OpBitcast %5 %99\n%104 = OpCompositeConstruct %6 %100 %101 %102 %103\n%105 = OpAccessChain %48 %36 %37 %78\nOpStore %105 %104 MakePointerAvailable|NonPrivatePointer %50\nOpBranch %116\n%116 = OpLabel\nOpBranch %117\n%117 = OpLabel\n%72 = OpIAdd %5 %71 %25\n%106 = OpAccessChain %51 %31 %37 %37\n%107 = OpLoad %27 %106\n%108 = OpBitcast %6 %107\n%109 = OpCompositeExtract %5 %108 0\n%110 = OpULessThan %56 %72 %109\nOpBranchConditional %110 %113 %118\n%118 = OpLabel\nOpBranch %119\n%119 = OpLabel\n%58 = OpAccessChain %48 %39 %37 %34\n%59 = OpLoad %6 %58 NonPrivatePointer\n%60 = OpBitcast %27 %59\n%61 = OpCompositeExtract %26 %60 0\n%62 = OpCompositeExtract %26 %60 1\n%63 = OpCompositeExtract %26 %60 2\n%64 = OpCompositeExtract %26 %60 3\n%65 = OpBitcast %5 %61\n%66 = OpBitcast %5 %62\n%67 = OpBitcast %5 %63\n%68 = OpBitcast %5 %64\n%69 = OpCompositeConstruct %6 %65 %66 %67 %68\n%70 = OpAccessChain %48 %40 %37 %34\nOpStore %70 %69 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/memory-model/uav-coherent.ssbo.vkmm.comp",
    "content": "#version 460\nlayout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _12_14\n{\n    uvec4 _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, std430) buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nlayout(set = 0, binding = 1, std430) readonly buffer _20_22\n{\n    uvec4 _m0[];\n} _22;\n\nlayout(set = 0, binding = 2, std430) writeonly buffer _24_26\n{\n    uvec4 _m0[];\n} _26;\n\nlayout(set = 0, binding = 0, std140) uniform _31_33\n{\n    vec4 _m0[1];\n} _33;\n\nvoid main()\n{\n    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0), floatBitsToUint(0.0));\n    if (!(floatBitsToUint(_33._m0[0u]).x == 0u))\n    {\n        uint _67 = 0u;\n        uint _71;\n        uint _74;\n        bool _77;\n        for (;;)\n        {\n            _71 = (_67 << 8u) + gl_LocalInvocationIndex;\n            _74 = _9._m0[_71];\n            groupMemoryBarrier();\n            barrier();\n            _77 = _74 < 256u;\n            if (_77)\n            {\n                vec4 _81 = uintBitsToFloat(_14._m0[_71]);\n                vec4 _88 = uintBitsToFloat(_18._m0[_74]);\n                _18._m0[_74] = uvec4(floatBitsToUint(_88.x + _81.x), floatBitsToUint(_88.y + _81.y), floatBitsToUint(_88.z + _81.z), floatBitsToUint(_88.w + _81.w));\n            }\n            uint _68 = _67 + 1u;\n            if (_68 < floatBitsToUint(_33._m0[0u]).x)\n            {\n                _67 = _68;\n                continue;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    vec4 _56 = uintBitsToFloat(_22._m0[gl_LocalInvocationIndex]);\n    _26._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_56.x), floatBitsToUint(_56.y), floatBitsToUint(_56.z), floatBitsToUint(_56.w));\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 118\n; Schema: 0\nOpCapability Shader\nOpCapability VulkanMemoryModel\nOpMemoryModel Logical Vulkan\nOpEntryPoint GLCompute %3 \"main\" %9 %14 %18 %22 %26 %33 %35\nOpExecutionMode %3 LocalSize 256 1 1\nOpName %3 \"main\"\nOpName %7 \"SSBO\"\nOpName %12 \"SSBO\"\nOpName %16 \"SSBO\"\nOpName %20 \"SSBO\"\nOpName %24 \"SSBO\"\nOpName %31 \"\"\nOpDecorate %6 ArrayStride 4\nOpMemberDecorate %7 0 Offset 0\nOpDecorate %7 Block\nOpDecorate %9 DescriptorSet 0\nOpDecorate %9 Binding 0\nOpDecorate %9 NonWritable\nOpDecorate %9 Restrict\nOpDecorate %11 ArrayStride 16\nOpMemberDecorate %12 0 Offset 0\nOpDecorate %12 Block\nOpDecorate %14 DescriptorSet 0\nOpDecorate %14 Binding 1\nOpDecorate %14 NonWritable\nOpDecorate %14 Restrict\nOpDecorate %15 ArrayStride 16\nOpMemberDecorate %16 0 Offset 0\nOpDecorate %16 Block\nOpDecorate %18 DescriptorSet 0\nOpDecorate %18 Binding 0\nOpDecorate %19 ArrayStride 16\nOpMemberDecorate %20 0 Offset 0\nOpDecorate %20 Block\nOpDecorate %22 DescriptorSet 0\nOpDecorate %22 Binding 1\nOpDecorate %22 NonWritable\nOpDecorate %23 ArrayStride 16\nOpMemberDecorate %24 0 Offset 0\nOpDecorate %24 Block\nOpDecorate %26 DescriptorSet 0\nOpDecorate %26 Binding 2\nOpDecorate %26 NonReadable\nOpDecorate %30 ArrayStride 16\nOpMemberDecorate %31 0 Offset 0\nOpDecorate %31 Block\nOpDecorate %33 DescriptorSet 0\nOpDecorate %33 Binding 0\nOpDecorate %35 BuiltIn LocalInvocationIndex\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeRuntimeArray %5\n%7 = OpTypeStruct %6\n%8 = OpTypePointer StorageBuffer %7\n%9 = OpVariable %8 StorageBuffer\n%10 = OpTypeVector %5 4\n%11 = OpTypeRuntimeArray %10\n%12 = OpTypeStruct %11\n%13 = OpTypePointer StorageBuffer %12\n%14 = OpVariable %13 StorageBuffer\n%15 = OpTypeRuntimeArray %10\n%16 = OpTypeStruct %15\n%17 = OpTypePointer StorageBuffer %16\n%18 = OpVariable %17 StorageBuffer\n%19 = OpTypeRuntimeArray %10\n%20 = OpTypeStruct %19\n%21 = OpTypePointer StorageBuffer %20\n%22 = OpVariable %21 StorageBuffer\n%23 = OpTypeRuntimeArray %10\n%24 = OpTypeStruct %23\n%25 = OpTypePointer StorageBuffer %24\n%26 = OpVariable %25 StorageBuffer\n%27 = OpConstant %5 1\n%28 = OpTypeFloat 32\n%29 = OpTypeVector %28 4\n%30 = OpTypeArray %29 %27\n%31 = OpTypeStruct %30\n%32 = OpTypePointer Uniform %31\n%33 = OpVariable %32 Uniform\n%34 = OpTypePointer Input %5\n%35 = OpVariable %34 Input\n%37 = OpConstant %28 0\n%43 = OpTypePointer StorageBuffer %10\n%45 = OpConstant %5 0\n%46 = OpConstant %5 5\n%47 = OpTypePointer Uniform %29\n%52 = OpTypeBool\n%70 = OpConstant %5 8\n%72 = OpTypePointer StorageBuffer %5\n%75 = OpConstant %5 2\n%76 = OpConstant %5 26696\n%78 = OpConstant %5 256\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %108\n%108 = OpLabel\n%36 = OpLoad %5 %35\n%38 = OpBitcast %5 %37\n%39 = OpBitcast %5 %37\n%40 = OpBitcast %5 %37\n%41 = OpBitcast %5 %37\n%42 = OpCompositeConstruct %10 %38 %39 %40 %41\n%44 = OpAccessChain %43 %18 %45 %36\nOpStore %44 %42 MakePointerAvailable|NonPrivatePointer %46\n%48 = OpAccessChain %47 %33 %45 %45\n%49 = OpLoad %29 %48\n%50 = OpBitcast %10 %49\n%51 = OpCompositeExtract %5 %50 0\n%53 = OpIEqual %52 %51 %45\nOpSelectionMerge %116 None\nOpBranchConditional %53 %116 %109\n%109 = OpLabel\nOpBranch %110\n%110 = OpLabel\n%67 = OpPhi %5 %45 %109 %68 %114\n%69 = OpShiftLeftLogical %5 %67 %70\n%71 = OpIAdd %5 %69 %36\n%73 = OpAccessChain %72 %9 %45 %71\n%74 = OpLoad %5 %73\nOpControlBarrier %75 %75 %76\n%77 = OpULessThan %52 %74 %78\nOpLoopMerge %115 %114 None\nOpBranch %111\n%111 = OpLabel\nOpSelectionMerge %113 None\nOpBranchConditional %77 %112 %113\n%112 = OpLabel\n%79 = OpAccessChain %43 %14 %45 %71\n%80 = OpLoad %10 %79\n%81 = OpBitcast %29 %80\n%82 = OpCompositeExtract %28 %81 0\n%83 = OpCompositeExtract %28 %81 1\n%84 = OpCompositeExtract %28 %81 2\n%85 = OpCompositeExtract %28 %81 3\n%86 = OpAccessChain %43 %18 %45 %74\n%87 = OpLoad %10 %86 MakePointerVisible|NonPrivatePointer %46\n%88 = OpBitcast %29 %87\n%89 = OpCompositeExtract %28 %88 0\n%90 = OpCompositeExtract %28 %88 1\n%91 = OpCompositeExtract %28 %88 2\n%92 = OpCompositeExtract %28 %88 3\n%93 = OpFAdd %28 %89 %82\n%94 = OpFAdd %28 %90 %83\n%95 = OpFAdd %28 %91 %84\n%96 = OpFAdd %28 %92 %85\n%97 = OpBitcast %5 %93\n%98 = OpBitcast %5 %94\n%99 = OpBitcast %5 %95\n%100 = OpBitcast %5 %96\n%101 = OpCompositeConstruct %10 %97 %98 %99 %100\n%102 = OpAccessChain %43 %18 %45 %74\nOpStore %102 %101 MakePointerAvailable|NonPrivatePointer %46\nOpBranch %113\n%113 = OpLabel\nOpBranch %114\n%114 = OpLabel\n%68 = OpIAdd %5 %67 %27\n%103 = OpAccessChain %47 %33 %45 %45\n%104 = OpLoad %29 %103\n%105 = OpBitcast %10 %104\n%106 = OpCompositeExtract %5 %105 0\n%107 = OpULessThan %52 %68 %106\nOpBranchConditional %107 %110 %115\n%115 = OpLabel\nOpBranch %116\n%116 = OpLabel\n%54 = OpAccessChain %43 %22 %45 %36\n%55 = OpLoad %10 %54 NonPrivatePointer\n%56 = OpBitcast %29 %55\n%57 = OpCompositeExtract %28 %56 0\n%58 = OpCompositeExtract %28 %56 1\n%59 = OpCompositeExtract %28 %56 2\n%60 = OpCompositeExtract %28 %56 3\n%61 = OpBitcast %5 %57\n%62 = OpBitcast %5 %58\n%63 = OpBitcast %5 %59\n%64 = OpBitcast %5 %60\n%65 = OpCompositeConstruct %10 %61 %62 %63 %64\n%66 = OpAccessChain %43 %26 %45 %36\nOpStore %66 %65 NonPrivatePointer\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/report-hit.vkmm.rint",
    "content": "#version 460\n#extension GL_EXT_ray_tracing : require\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_KHR_shader_subgroup_basic : require\n\nstruct _6\n{\n    float _m0;\n};\n\nhitAttributeEXT _6 hit;\n\nvoid main()\n{\n    _6 _12;\n    _12._m0 = gl_RayTmaxEXT;\n    hit = _12;\n    bool _24 = reportIntersectionEXT(4.0, 100u);\n    _6 _11;\n    _11._m0 = gl_RayTminEXT;\n    hit = _11;\n    bool _29 = reportIntersectionEXT(3.0, 50u);\n    _6 _10;\n    _10._m0 = float(gl_SubgroupInvocationID);\n    hit = _10;\n    bool _38 = reportIntersectionEXT(2.0, 50u);\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\nOpCapability Shader\nOpCapability UniformBufferArrayDynamicIndexing\nOpCapability SampledImageArrayDynamicIndexing\nOpCapability StorageBufferArrayDynamicIndexing\nOpCapability StorageImageArrayDynamicIndexing\nOpCapability GroupNonUniform\nOpCapability RayTracingKHR\nOpCapability RuntimeDescriptorArray\nOpCapability UniformBufferArrayNonUniformIndexing\nOpCapability SampledImageArrayNonUniformIndexing\nOpCapability StorageBufferArrayNonUniformIndexing\nOpCapability StorageImageArrayNonUniformIndexing\nOpCapability VulkanMemoryModel\nOpExtension \"SPV_EXT_descriptor_indexing\"\nOpExtension \"SPV_KHR_ray_tracing\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint IntersectionKHR %3 \"main\" %8 %14 %16 %33\nOpName %3 \"main\"\nOpName %6 \"\"\nOpName %8 \"hit\"\nOpDecorate %14 BuiltIn RayTmaxKHR\nOpDecorate %16 BuiltIn RayTminKHR\nOpDecorate %33 BuiltIn SubgroupLocalInvocationId\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeStruct %5\n%7 = OpTypePointer HitAttributeKHR %6\n%8 = OpVariable %7 HitAttributeKHR\n%9 = OpTypePointer Function %6\n%13 = OpTypePointer Input %5\n%14 = OpVariable %13 Input\n%16 = OpVariable %13 Input\n%18 = OpTypePointer Function %5\n%20 = OpTypeInt 32 0\n%21 = OpConstant %20 0\n%23 = OpTypeBool\n%25 = OpConstant %5 4\n%26 = OpConstant %20 100\n%30 = OpConstant %5 3\n%31 = OpConstant %20 50\n%32 = OpTypePointer Input %20\n%33 = OpVariable %32 Input\n%39 = OpConstant %5 2\n%3 = OpFunction %1 None %2\n%4 = OpLabel\n%10 = OpVariable %9 Function\n%11 = OpVariable %9 Function\n%12 = OpVariable %9 Function\nOpBranch %40\n%40 = OpLabel\n%15 = OpLoad %5 %14 Volatile\n%17 = OpLoad %5 %16\n%19 = OpInBoundsAccessChain %18 %12 %21\nOpStore %19 %15\n%22 = OpLoad %6 %12\nOpStore %8 %22\n%24 = OpReportIntersectionKHR %23 %25 %26\n%27 = OpInBoundsAccessChain %18 %11 %21\nOpStore %27 %17\n%28 = OpLoad %6 %11\nOpStore %8 %28\n%29 = OpReportIntersectionKHR %23 %30 %31\n%34 = OpLoad %20 %33 Volatile\n%35 = OpConvertUToF %5 %34\n%36 = OpInBoundsAccessChain %18 %10 %21\nOpStore %36 %35\n%37 = OpLoad %6 %10\nOpStore %8 %37\n%38 = OpReportIntersectionKHR %23 %39 %31\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/rov-structured.vkmm.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nvoid main()\n{\n    uint _25 = (uint(gl_FragCoord.y) * 1000u) + uint(gl_FragCoord.x);\n    uint _26 = _25 * 4u;\n    SPIRV_Cross_beginInvocationInterlock();\n    uvec4 _29 = imageLoad(_8, int(_26));\n    uvec4 _32 = imageLoad(_8, int(_26 + 1u));\n    uvec4 _35 = imageLoad(_8, int(_26 + 2u));\n    uvec4 _39 = imageLoad(_8, int(_26 + 3u));\n    vec4 _44 = uintBitsToFloat(uvec4(_29.x, _32.x, _35.x, _39.x));\n    uint _57 = _25 * 4u;\n    imageStore(_8, int(_57), uvec4(floatBitsToUint(_44.x + 1.0)));\n    imageStore(_8, int(_57 + 1u), uvec4(floatBitsToUint(_44.y + 2.0)));\n    imageStore(_8, int(_57 + 2u), uvec4(floatBitsToUint(_44.z + 3.0)));\n    imageStore(_8, int(_57 + 3u), uvec4(floatBitsToUint(_44.w + 4.0)));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\nOpCapability Shader\nOpCapability ImageBuffer\nOpCapability VulkanMemoryModel\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint Fragment %3 \"main\" %8 %12\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %12 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %12 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeInt 32 0\n%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeFloat 32\n%10 = OpTypeVector %9 4\n%11 = OpTypePointer Input %10\n%12 = OpVariable %11 Input\n%14 = OpTypePointer Input %9\n%16 = OpConstant %5 0\n%19 = OpConstant %5 1\n%24 = OpConstant %5 1000\n%27 = OpConstant %5 4\n%28 = OpTypeVector %5 4\n%30 = OpConstant %5 5\n%37 = OpConstant %5 2\n%41 = OpConstant %5 3\n%50 = OpConstant %9 1\n%52 = OpConstant %9 2\n%54 = OpConstant %9 3\n%56 = OpConstant %9 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %69\n%69 = OpLabel\n%13 = OpLoad %6 %8\n%15 = OpAccessChain %14 %12 %16\n%17 = OpLoad %9 %15\n%18 = OpAccessChain %14 %12 %19\n%20 = OpLoad %9 %18\n%21 = OpConvertFToU %5 %17\n%22 = OpConvertFToU %5 %20\n%23 = OpIMul %5 %22 %24\n%25 = OpIAdd %5 %23 %21\n%26 = OpIMul %5 %25 %27\nOpBeginInvocationInterlockEXT\n%29 = OpImageRead %28 %13 %26 MakeTexelVisible|NonPrivateTexel %30\n%31 = OpCompositeExtract %5 %29 0\n%33 = OpIAdd %5 %26 %19\n%32 = OpImageRead %28 %13 %33 MakeTexelVisible|NonPrivateTexel %30\n%34 = OpCompositeExtract %5 %32 0\n%36 = OpIAdd %5 %26 %37\n%35 = OpImageRead %28 %13 %36 MakeTexelVisible|NonPrivateTexel %30\n%38 = OpCompositeExtract %5 %35 0\n%40 = OpIAdd %5 %26 %41\n%39 = OpImageRead %28 %13 %40 MakeTexelVisible|NonPrivateTexel %30\n%42 = OpCompositeExtract %5 %39 0\n%43 = OpCompositeConstruct %28 %31 %34 %38 %42\n%44 = OpBitcast %10 %43\n%45 = OpCompositeExtract %9 %44 0\n%46 = OpCompositeExtract %9 %44 1\n%47 = OpCompositeExtract %9 %44 2\n%48 = OpCompositeExtract %9 %44 3\n%49 = OpFAdd %9 %45 %50\n%51 = OpFAdd %9 %46 %52\n%53 = OpFAdd %9 %47 %54\n%55 = OpFAdd %9 %48 %56\n%57 = OpIMul %5 %25 %27\n%58 = OpBitcast %5 %49\n%59 = OpBitcast %5 %51\n%60 = OpBitcast %5 %53\n%61 = OpBitcast %5 %55\n%62 = OpCompositeConstruct %28 %58 %58 %58 %58\nOpImageWrite %13 %57 %62 MakeTexelAvailable|NonPrivateTexel %30\n%63 = OpCompositeConstruct %28 %59 %59 %59 %59\n%64 = OpIAdd %5 %57 %19\nOpImageWrite %13 %64 %63 MakeTexelAvailable|NonPrivateTexel %30\n%65 = OpCompositeConstruct %28 %60 %60 %60 %60\n%66 = OpIAdd %5 %57 %37\nOpImageWrite %13 %66 %65 MakeTexelAvailable|NonPrivateTexel %30\n%67 = OpCompositeConstruct %28 %61 %61 %61 %61\n%68 = OpIAdd %5 %57 %41\nOpImageWrite %13 %68 %67 MakeTexelAvailable|NonPrivateTexel %30\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference/shaders/vkmm/rov-tex2d.vkmm.frag",
    "content": "#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, r32f) uniform image2D _8;\n\nvoid main()\n{\n    uint _21 = uint(gl_FragCoord.x);\n    uint _22 = uint(gl_FragCoord.y);\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _23 = imageLoad(_8, ivec2(uvec2(_21, _22)));\n    imageStore(_8, ivec2(uvec2(_21, _22)), vec4(_23.x + 1.0, _23.y + 2.0, _23.z + 3.0, _23.w + 4.0));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n#if 0\n// SPIR-V disassembly\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\nOpCapability Shader\nOpCapability StorageImageWriteWithoutFormat\nOpCapability VulkanMemoryModel\nOpCapability FragmentShaderPixelInterlockEXT\nOpExtension \"SPV_EXT_fragment_shader_interlock\"\nOpMemoryModel Logical Vulkan\nOpEntryPoint Fragment %3 \"main\" %8 %11\nOpExecutionMode %3 OriginUpperLeft\nOpExecutionMode %3 EarlyFragmentTests\nOpExecutionMode %3 PixelInterlockOrderedEXT\nOpName %3 \"main\"\nOpName %11 \"SV_Position\"\nOpDecorate %8 DescriptorSet 0\nOpDecorate %8 Binding 0\nOpDecorate %11 BuiltIn FragCoord\n%1 = OpTypeVoid\n%2 = OpTypeFunction %1\n%5 = OpTypeFloat 32\n%6 = OpTypeImage %5 2D 0 0 0 2 R32f\n%7 = OpTypePointer UniformConstant %6\n%8 = OpVariable %7 UniformConstant\n%9 = OpTypeVector %5 4\n%10 = OpTypePointer Input %9\n%11 = OpVariable %10 Input\n%13 = OpTypePointer Input %5\n%15 = OpTypeInt 32 0\n%16 = OpConstant %15 0\n%19 = OpConstant %15 1\n%24 = OpTypeVector %15 2\n%26 = OpConstant %15 5\n%32 = OpConstant %5 1\n%34 = OpConstant %5 2\n%36 = OpConstant %5 3\n%38 = OpConstant %5 4\n%3 = OpFunction %1 None %2\n%4 = OpLabel\nOpBranch %41\n%41 = OpLabel\n%12 = OpLoad %6 %8\n%14 = OpAccessChain %13 %11 %16\n%17 = OpLoad %5 %14\n%18 = OpAccessChain %13 %11 %19\n%20 = OpLoad %5 %18\n%21 = OpConvertFToU %15 %17\n%22 = OpConvertFToU %15 %20\n%25 = OpCompositeConstruct %24 %21 %22\nOpBeginInvocationInterlockEXT\n%23 = OpImageRead %9 %12 %25 MakeTexelVisible|NonPrivateTexel %26\n%27 = OpCompositeExtract %5 %23 0\n%28 = OpCompositeExtract %5 %23 1\n%29 = OpCompositeExtract %5 %23 2\n%30 = OpCompositeExtract %5 %23 3\n%31 = OpFAdd %5 %27 %32\n%33 = OpFAdd %5 %28 %34\n%35 = OpFAdd %5 %29 %36\n%37 = OpFAdd %5 %30 %38\n%39 = OpCompositeConstruct %24 %21 %22\n%40 = OpCompositeConstruct %9 %31 %33 %35 %37\nOpImageWrite %12 %39 %40 MakeTexelAvailable|NonPrivateTexel %26\nOpEndInvocationInterlockEXT\nOpReturn\nOpFunctionEnd\n#endif\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_bool.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 69\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n       %bool = OpTypeBool\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %67\n\n         %67 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpINotEqual %bool %uint_0 %17\n         %21 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %22 =   OpLoad %uint %21\n         %23 =   OpINotEqual %bool %uint_0 %22\n         %24 =   OpLogicalAnd %bool %19 %23\n         %25 =   OpSelect %uint %24 %uint_1 %uint_0\n         %26 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %26 %25 NonPrivatePointer\n         %28 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %29 =   OpLoad %uint %28\n         %30 =   OpINotEqual %bool %uint_0 %29\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %33 =   OpLoad %uint %32\n         %34 =   OpINotEqual %bool %uint_0 %33\n         %35 =   OpLogicalOr %bool %30 %34\n         %36 =   OpSelect %uint %35 %uint_1 %uint_0\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %37 %36 NonPrivatePointer\n         %39 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %40 =   OpLoad %uint %39\n         %41 =   OpINotEqual %bool %uint_0 %40\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %44 =   OpLoad %uint %43\n         %45 =   OpINotEqual %bool %uint_0 %44\n         %46 =   OpLogicalEqual %bool %41 %45\n         %47 =   OpSelect %uint %46 %uint_1 %uint_0\n         %48 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %48 %47 NonPrivatePointer\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %51 =   OpLoad %uint %50\n         %52 =   OpINotEqual %bool %uint_0 %51\n         %54 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %55 =   OpLoad %uint %54\n         %56 =   OpINotEqual %bool %uint_0 %55\n         %57 =   OpLogicalNotEqual %bool %52 %56\n         %58 =   OpSelect %uint %57 %uint_1 %uint_0\n         %59 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %59 %58 NonPrivatePointer\n         %61 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %62 =   OpLoad %uint %61\n         %63 =   OpINotEqual %bool %uint_0 %62\n         %64 =   OpLogicalNot %bool %63\n         %65 =   OpSelect %uint %64 %uint_1 %uint_0\n         %66 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %66 %65 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_bool.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = uint((0u != _9._m0[0u]) && (0u != _9._m0[1u]));\n    _13._m0[1u] = uint((0u != _9._m0[2u]) || (0u != _9._m0[3u]));\n    _13._m0[2u] = uint((0u != _9._m0[4u]) == (0u != _9._m0[5u]));\n    _13._m0[3u] = uint((0u != _9._m0[6u]) != (0u != _9._m0[7u]));\n    _13._m0[4u] = uint(!(0u != _9._m0[8u]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_compare.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 16\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n       %half = OpTypeFloat 16\n     %uint_1 = OpConstant %uint 1\n       %bool = OpTypeBool\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %54\n\n         %54 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpFConvert %half %19\n         %23 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %24 =   OpLoad %uint %23\n         %25 =   OpBitcast %float %24\n         %26 =   OpFConvert %half %25\n         %28 =   OpFOrdEqual %bool %21 %26\n         %29 =   OpSelect %uint %28 %uint_1 %uint_0\n         %30 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %30 %29 NonPrivatePointer\n         %31 =   OpFUnordNotEqual %bool %21 %26\n         %32 =   OpSelect %uint %31 %uint_1 %uint_0\n         %33 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %33 %32 NonPrivatePointer\n         %34 =   OpFOrdLessThan %bool %21 %26\n         %35 =   OpSelect %uint %34 %uint_1 %uint_0\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %37 %35 NonPrivatePointer\n         %38 =   OpFOrdLessThanEqual %bool %21 %26\n         %39 =   OpSelect %uint %38 %uint_1 %uint_0\n         %41 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %41 %39 NonPrivatePointer\n         %42 =   OpFOrdGreaterThan %bool %21 %26\n         %43 =   OpSelect %uint %42 %uint_1 %uint_0\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %45 %43 NonPrivatePointer\n         %46 =   OpFOrdGreaterThanEqual %bool %21 %26\n         %47 =   OpSelect %uint %46 %uint_1 %uint_0\n         %49 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_5\n                 OpStore %49 %47 NonPrivatePointer\n         %50 =   OpIsNan %bool %21\n         %51 =   OpSelect %uint %50 %uint_1 %uint_0\n         %53 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_6\n                 OpStore %53 %51 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_compare.glsl",
    "content": "GLSL:\n#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    float16_t _21 = float16_t(uintBitsToFloat(_9._m0[0u]));\n    float16_t _26 = float16_t(uintBitsToFloat(_9._m0[1u]));\n    _13._m0[0u] = uint(_21 == _26);\n    _13._m0[1u] = uint(_21 != _26);\n    _13._m0[2u] = uint(_21 < _26);\n    _13._m0[3u] = uint(_21 <= _26);\n    _13._m0[4u] = uint(_21 > _26);\n    _13._m0[5u] = uint(_21 >= _26);\n    _13._m0[6u] = uint(isnan(_21));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_packing.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 16\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_1 = OpConstant %uint 1\n       %half = OpTypeFloat 16\n     %v2half = OpTypeVector %half 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %28\n\n         %28 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %20 =   OpLoad %uint %19\n         %23 =   OpBitcast %v2half %17\n         %24 =   OpBitcast %v2half %20\n         %25 =   OpFAdd %v2half %23 %24\n         %26 =   OpBitcast %uint %25\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %27 %26 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_packing.glsl",
    "content": "GLSL:\n#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = packFloat2x16(unpackFloat2x16(_9._m0[0u]) + unpackFloat2x16(_9._m0[1u]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_packing_legacy.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %21 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_1 = OpConstant %uint 1\n      %float = OpTypeFloat 32\n    %v2float = OpTypeVector %float 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %35\n\n         %35 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %20 =   OpLoad %uint %19\n         %24 =   OpExtInst %v2float %21 UnpackHalf2x16 %17\n         %25 =   OpExtInst %v2float %21 UnpackHalf2x16 %20\n         %26 =   OpCompositeExtract %float %25 0\n         %27 =   OpCompositeExtract %float %24 0\n         %28 =   OpFAdd %float %27 %26\n         %29 =   OpCompositeExtract %float %25 1\n         %30 =   OpCompositeExtract %float %24 1\n         %31 =   OpFAdd %float %30 %29\n         %32 =   OpCompositeConstruct %v2float %28 %31\n         %33 =   OpExtInst %uint %21 PackHalf2x16 %32\n         %34 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %34 %33 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_packing_legacy.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    vec2 _24 = unpackHalf2x16(_9._m0[0u]);\n    vec2 _25 = unpackHalf2x16(_9._m0[1u]);\n    _13._m0[0u] = packHalf2x16(vec2(_24.x + _25.x, _24.y + _25.y));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_scalar.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %22 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 16\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n       %half = OpTypeFloat 16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n%half_0x1p_0 = OpConstant %half 0x1p+0\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %93\n\n         %93 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpFConvert %half %19\n         %23 =   OpExtInst %half %22 Trunc %21\n         %24 =   OpExtInst %half %22 FAbs %23\n         %25 =   OpFNegate %half %24\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %28 =   OpLoad %uint %27\n         %29 =   OpBitcast %float %28\n         %30 =   OpFConvert %half %29\n         %31 =   OpFAdd %half %25 %30\n         %32 =   OpExtInst %half %22 RoundEven %31\n         %34 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %35 =   OpLoad %uint %34\n         %36 =   OpBitcast %float %35\n         %37 =   OpFConvert %half %36\n         %38 =   OpFSub %half %32 %37\n         %39 =   OpExtInst %half %22 Floor %38\n         %41 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %42 =   OpLoad %uint %41\n         %43 =   OpBitcast %float %42\n         %44 =   OpFConvert %half %43\n         %45 =   OpFMul %half %39 %44\n         %46 =   OpExtInst %half %22 Ceil %45\n         %48 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %49 =   OpLoad %uint %48\n         %50 =   OpBitcast %float %49\n         %51 =   OpFConvert %half %50\n         %53 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %54 =   OpLoad %uint %53\n         %55 =   OpBitcast %float %54\n         %56 =   OpFConvert %half %55\n         %57 =   OpExtInst %half %22 Fma %46 %51 %56\n         %59 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %60 =   OpLoad %uint %59\n         %61 =   OpBitcast %float %60\n         %62 =   OpFConvert %half %61\n         %63 =   OpFDiv %half %57 %62\n         %64 =   OpFDiv %half %half_0x1p_0 %63\n         %66 =   OpExtInst %half %22 Fract %64\n         %68 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %69 =   OpLoad %uint %68\n         %70 =   OpBitcast %float %69\n         %71 =   OpFConvert %half %70\n         %72 =   OpExtInst %half %22 NMin %66 %71\n         %74 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %75 =   OpLoad %uint %74\n         %76 =   OpBitcast %float %75\n         %77 =   OpFConvert %half %76\n         %78 =   OpExtInst %half %22 NMax %72 %77\n         %80 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %81 =   OpLoad %uint %80\n         %82 =   OpBitcast %float %81\n         %83 =   OpFConvert %half %82\n         %85 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %86 =   OpLoad %uint %85\n         %87 =   OpBitcast %float %86\n         %88 =   OpFConvert %half %87\n         %89 =   OpExtInst %half %22 NClamp %78 %83 %88\n         %90 =   OpFConvert %float %89\n         %91 =   OpBitcast %uint %90\n         %92 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %92 %91 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_scalar.glsl",
    "content": "GLSL:\n#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_spirv_intrinsics : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float16_t spvNMin(float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) f16vec2 spvNMin(f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) f16vec3 spvNMin(f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) f16vec4 spvNMin(f16vec4, f16vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) float16_t spvNMax(float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) f16vec2 spvNMax(f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) f16vec3 spvNMax(f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) f16vec4 spvNMax(f16vec4, f16vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);\n\nvoid main()\n{\n    _13._m0[0u] = floatBitsToUint(float(spvNClamp(spvNMax(spvNMin(fract(float16_t(1.0) / (fma(ceil(floor(roundEven((-abs(trunc(float16_t(uintBitsToFloat(_9._m0[0u]))))) + float16_t(uintBitsToFloat(_9._m0[1u]))) - float16_t(uintBitsToFloat(_9._m0[2u]))) * float16_t(uintBitsToFloat(_9._m0[3u]))), float16_t(uintBitsToFloat(_9._m0[4u])), float16_t(uintBitsToFloat(_9._m0[5u]))) / float16_t(uintBitsToFloat(_9._m0[6u])))), float16_t(uintBitsToFloat(_9._m0[7u]))), float16_t(uintBitsToFloat(_9._m0[8u]))), float16_t(uintBitsToFloat(_9._m0[9u])), float16_t(uintBitsToFloat(_9._m0[10u])))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_vector.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 168\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %29 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 16\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n       %half = OpTypeFloat 16\n     %uint_1 = OpConstant %uint 1\n     %v2half = OpTypeVector %half 2\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n%half_0x1p_0 = OpConstant %half 0x1p+0\n        %109 = OpConstantComposite %v2half %half_0x1p_0 %half_0x1p_0\n    %uint_14 = OpConstant %uint 14\n    %uint_15 = OpConstant %uint 15\n    %uint_16 = OpConstant %uint 16\n    %uint_17 = OpConstant %uint 17\n    %uint_18 = OpConstant %uint 18\n    %uint_19 = OpConstant %uint 19\n    %uint_20 = OpConstant %uint 20\n    %uint_21 = OpConstant %uint 21\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %166\n\n        %166 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpFConvert %half %19\n         %23 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %24 =   OpLoad %uint %23\n         %25 =   OpBitcast %float %24\n         %26 =   OpFConvert %half %25\n         %28 =   OpCompositeConstruct %v2half %21 %26\n         %30 =   OpExtInst %v2half %29 Trunc %28\n         %31 =   OpExtInst %v2half %29 FAbs %30\n         %32 =   OpFNegate %v2half %31\n         %34 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %35 =   OpLoad %uint %34\n         %36 =   OpBitcast %float %35\n         %37 =   OpFConvert %half %36\n         %39 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %40 =   OpLoad %uint %39\n         %41 =   OpBitcast %float %40\n         %42 =   OpFConvert %half %41\n         %43 =   OpCompositeConstruct %v2half %37 %42\n         %44 =   OpFAdd %v2half %32 %43\n         %45 =   OpExtInst %v2half %29 RoundEven %44\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %48 =   OpLoad %uint %47\n         %49 =   OpBitcast %float %48\n         %50 =   OpFConvert %half %49\n         %52 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %53 =   OpLoad %uint %52\n         %54 =   OpBitcast %float %53\n         %55 =   OpFConvert %half %54\n         %56 =   OpCompositeConstruct %v2half %50 %55\n         %57 =   OpFSub %v2half %45 %56\n         %58 =   OpExtInst %v2half %29 Floor %57\n         %60 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %61 =   OpLoad %uint %60\n         %62 =   OpBitcast %float %61\n         %63 =   OpFConvert %half %62\n         %65 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %66 =   OpLoad %uint %65\n         %67 =   OpBitcast %float %66\n         %68 =   OpFConvert %half %67\n         %69 =   OpCompositeConstruct %v2half %63 %68\n         %70 =   OpFMul %v2half %58 %69\n         %71 =   OpExtInst %v2half %29 Ceil %70\n         %73 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %74 =   OpLoad %uint %73\n         %75 =   OpBitcast %float %74\n         %76 =   OpFConvert %half %75\n         %78 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %79 =   OpLoad %uint %78\n         %80 =   OpBitcast %float %79\n         %81 =   OpFConvert %half %80\n         %82 =   OpCompositeConstruct %v2half %76 %81\n         %84 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %85 =   OpLoad %uint %84\n         %86 =   OpBitcast %float %85\n         %87 =   OpFConvert %half %86\n         %89 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_11\n         %90 =   OpLoad %uint %89\n         %91 =   OpBitcast %float %90\n         %92 =   OpFConvert %half %91\n         %93 =   OpCompositeConstruct %v2half %87 %92\n         %94 =   OpExtInst %v2half %29 Fma %71 %82 %93\n         %96 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_12\n         %97 =   OpLoad %uint %96\n         %98 =   OpBitcast %float %97\n         %99 =   OpFConvert %half %98\n        %101 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_13\n        %102 =   OpLoad %uint %101\n        %103 =   OpBitcast %float %102\n        %104 =   OpFConvert %half %103\n        %105 =   OpCompositeConstruct %v2half %99 %104\n        %106 =   OpFDiv %v2half %94 %105\n        %107 =   OpFDiv %v2half %109 %106\n        %110 =   OpExtInst %v2half %29 Fract %107\n        %112 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_14\n        %113 =   OpLoad %uint %112\n        %114 =   OpBitcast %float %113\n        %115 =   OpFConvert %half %114\n        %117 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_15\n        %118 =   OpLoad %uint %117\n        %119 =   OpBitcast %float %118\n        %120 =   OpFConvert %half %119\n        %121 =   OpCompositeConstruct %v2half %115 %120\n        %122 =   OpExtInst %v2half %29 NMin %110 %121\n        %124 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_16\n        %125 =   OpLoad %uint %124\n        %126 =   OpBitcast %float %125\n        %127 =   OpFConvert %half %126\n        %129 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_17\n        %130 =   OpLoad %uint %129\n        %131 =   OpBitcast %float %130\n        %132 =   OpFConvert %half %131\n        %133 =   OpCompositeConstruct %v2half %127 %132\n        %134 =   OpExtInst %v2half %29 NMax %122 %133\n        %136 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_18\n        %137 =   OpLoad %uint %136\n        %138 =   OpBitcast %float %137\n        %139 =   OpFConvert %half %138\n        %141 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_19\n        %142 =   OpLoad %uint %141\n        %143 =   OpBitcast %float %142\n        %144 =   OpFConvert %half %143\n        %145 =   OpCompositeConstruct %v2half %139 %144\n        %147 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_20\n        %148 =   OpLoad %uint %147\n        %149 =   OpBitcast %float %148\n        %150 =   OpFConvert %half %149\n        %152 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_21\n        %153 =   OpLoad %uint %152\n        %154 =   OpBitcast %float %153\n        %155 =   OpFConvert %half %154\n        %156 =   OpCompositeConstruct %v2half %150 %155\n        %157 =   OpExtInst %v2half %29 NClamp %134 %145 %156\n        %158 =   OpCompositeExtract %half %157 0\n        %159 =   OpFConvert %float %158\n        %160 =   OpBitcast %uint %159\n        %161 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %161 %160 NonPrivatePointer\n        %162 =   OpCompositeExtract %half %157 1\n        %163 =   OpFConvert %float %162\n        %164 =   OpBitcast %uint %163\n        %165 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %165 %164 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp16_vector.glsl",
    "content": "GLSL:\n#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n#extension GL_EXT_spirv_intrinsics : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float16_t spvNMin(float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) f16vec2 spvNMin(f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) f16vec3 spvNMin(f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) f16vec4 spvNMin(f16vec4, f16vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) float16_t spvNMax(float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) f16vec2 spvNMax(f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) f16vec3 spvNMax(f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) f16vec4 spvNMax(f16vec4, f16vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);\n\nvoid main()\n{\n    f16vec2 _107 = f16vec2(float16_t(1.0)) / (fma(ceil(floor(roundEven((-abs(trunc(f16vec2(float16_t(uintBitsToFloat(_9._m0[0u])), float16_t(uintBitsToFloat(_9._m0[1u])))))) + f16vec2(float16_t(uintBitsToFloat(_9._m0[2u])), float16_t(uintBitsToFloat(_9._m0[3u])))) - f16vec2(float16_t(uintBitsToFloat(_9._m0[4u])), float16_t(uintBitsToFloat(_9._m0[5u])))) * f16vec2(float16_t(uintBitsToFloat(_9._m0[6u])), float16_t(uintBitsToFloat(_9._m0[7u])))), f16vec2(float16_t(uintBitsToFloat(_9._m0[8u])), float16_t(uintBitsToFloat(_9._m0[9u]))), f16vec2(float16_t(uintBitsToFloat(_9._m0[10u])), float16_t(uintBitsToFloat(_9._m0[11u])))) / f16vec2(float16_t(uintBitsToFloat(_9._m0[12u])), float16_t(uintBitsToFloat(_9._m0[13u]))));\n    f16vec2 _157 = spvNClamp(spvNMax(spvNMin(fract(_107), f16vec2(float16_t(uintBitsToFloat(_9._m0[14u])), float16_t(uintBitsToFloat(_9._m0[15u])))), f16vec2(float16_t(uintBitsToFloat(_9._m0[16u])), float16_t(uintBitsToFloat(_9._m0[17u])))), f16vec2(float16_t(uintBitsToFloat(_9._m0[18u])), float16_t(uintBitsToFloat(_9._m0[19u]))), f16vec2(float16_t(uintBitsToFloat(_9._m0[20u])), float16_t(uintBitsToFloat(_9._m0[21u]))));\n    _13._m0[0u] = floatBitsToUint(float(_157.x));\n    _13._m0[1u] = floatBitsToUint(float(_157.y));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 82\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %20 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n    %float_1 = OpConstant %float 1\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %80\n\n         %80 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpExtInst %float %20 Trunc %19\n         %22 =   OpExtInst %float %20 FAbs %21\n         %23 =   OpFNegate %float %22\n         %25 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %26 =   OpLoad %uint %25\n         %27 =   OpBitcast %float %26\n         %28 =   OpFAdd %float %23 %27\n         %29 =   OpExtInst %float %20 RoundEven %28\n         %31 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %32 =   OpLoad %uint %31\n         %33 =   OpBitcast %float %32\n         %34 =   OpFSub %float %29 %33\n         %35 =   OpExtInst %float %20 Floor %34\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %38 =   OpLoad %uint %37\n         %39 =   OpBitcast %float %38\n         %40 =   OpFMul %float %35 %39\n         %41 =   OpExtInst %float %20 Ceil %40\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %44 =   OpLoad %uint %43\n         %45 =   OpBitcast %float %44\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %48 =   OpLoad %uint %47\n         %49 =   OpBitcast %float %48\n         %50 =   OpExtInst %float %20 Fma %41 %45 %49\n         %52 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %53 =   OpLoad %uint %52\n         %54 =   OpBitcast %float %53\n         %55 =   OpFDiv %float %50 %54\n         %56 =   OpFDiv %float %float_1 %55\n         %58 =   OpExtInst %float %20 Fract %56\n         %60 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %61 =   OpLoad %uint %60\n         %62 =   OpBitcast %float %61\n         %63 =   OpExtInst %float %20 NMin %58 %62\n         %65 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %66 =   OpLoad %uint %65\n         %67 =   OpBitcast %float %66\n         %68 =   OpExtInst %float %20 NMax %63 %67\n         %70 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %71 =   OpLoad %uint %70\n         %72 =   OpBitcast %float %71\n         %74 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %75 =   OpLoad %uint %74\n         %76 =   OpBitcast %float %75\n         %77 =   OpExtInst %float %20 NClamp %68 %72 %76\n         %78 =   OpBitcast %uint %77\n         %79 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %79 %78 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_spirv_intrinsics : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float spvNMin(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec2 spvNMin(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec3 spvNMin(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec4 spvNMin(vec4, vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) float spvNMax(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec2 spvNMax(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec3 spvNMax(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec4 spvNMax(vec4, vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float spvNClamp(float, float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec2 spvNClamp(vec2, vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec3 spvNClamp(vec3, vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec4 spvNClamp(vec4, vec4, vec4);\n\nvoid main()\n{\n    _13._m0[0u] = floatBitsToUint(spvNClamp(spvNMax(spvNMin(fract(1.0 / (fma(ceil(floor(roundEven((-abs(trunc(uintBitsToFloat(_9._m0[0u])))) + uintBitsToFloat(_9._m0[1u])) - uintBitsToFloat(_9._m0[2u])) * uintBitsToFloat(_9._m0[3u])), uintBitsToFloat(_9._m0[4u]), uintBitsToFloat(_9._m0[5u])) / uintBitsToFloat(_9._m0[6u]))), uintBitsToFloat(_9._m0[7u])), uintBitsToFloat(_9._m0[8u])), uintBitsToFloat(_9._m0[9u]), uintBitsToFloat(_9._m0[10u])));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32_compare.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 53\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n     %uint_1 = OpConstant %uint 1\n       %bool = OpTypeBool\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %51\n\n         %51 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %22 =   OpLoad %uint %21\n         %23 =   OpBitcast %float %22\n         %25 =   OpFOrdEqual %bool %19 %23\n         %26 =   OpSelect %uint %25 %uint_1 %uint_0\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %27 %26 NonPrivatePointer\n         %28 =   OpFUnordNotEqual %bool %19 %23\n         %29 =   OpSelect %uint %28 %uint_1 %uint_0\n         %30 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %30 %29 NonPrivatePointer\n         %31 =   OpFOrdLessThan %bool %19 %23\n         %32 =   OpSelect %uint %31 %uint_1 %uint_0\n         %34 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %34 %32 NonPrivatePointer\n         %35 =   OpFOrdLessThanEqual %bool %19 %23\n         %36 =   OpSelect %uint %35 %uint_1 %uint_0\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %38 %36 NonPrivatePointer\n         %39 =   OpFOrdGreaterThan %bool %19 %23\n         %40 =   OpSelect %uint %39 %uint_1 %uint_0\n         %42 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %42 %40 NonPrivatePointer\n         %43 =   OpFOrdGreaterThanEqual %bool %19 %23\n         %44 =   OpSelect %uint %43 %uint_1 %uint_0\n         %46 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_5\n                 OpStore %46 %44 NonPrivatePointer\n         %47 =   OpIsNan %bool %19\n         %48 =   OpSelect %uint %47 %uint_1 %uint_0\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_6\n                 OpStore %50 %48 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32_compare.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    float _19 = uintBitsToFloat(_9._m0[0u]);\n    float _23 = uintBitsToFloat(_9._m0[1u]);\n    _13._m0[0u] = uint(_19 == _23);\n    _13._m0[1u] = uint(_19 != _23);\n    _13._m0[2u] = uint(_19 < _23);\n    _13._m0[3u] = uint(_19 <= _23);\n    _13._m0[4u] = uint(_19 > _23);\n    _13._m0[5u] = uint(_19 >= _23);\n    _13._m0[6u] = uint(isnan(_19));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32_precise.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 82\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %20 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n               OpDecorate %28 NoContraction\n               OpDecorate %34 NoContraction\n               OpDecorate %40 NoContraction\n               OpDecorate %55 NoContraction\n               OpDecorate %56 NoContraction\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n    %float_1 = OpConstant %float 1\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %80\n\n         %80 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpExtInst %float %20 Trunc %19\n         %22 =   OpExtInst %float %20 FAbs %21\n         %23 =   OpFNegate %float %22\n         %25 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %26 =   OpLoad %uint %25\n         %27 =   OpBitcast %float %26\n         %28 =   OpFAdd %float %23 %27\n         %29 =   OpExtInst %float %20 RoundEven %28\n         %31 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %32 =   OpLoad %uint %31\n         %33 =   OpBitcast %float %32\n         %34 =   OpFSub %float %29 %33\n         %35 =   OpExtInst %float %20 Floor %34\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %38 =   OpLoad %uint %37\n         %39 =   OpBitcast %float %38\n         %40 =   OpFMul %float %35 %39\n         %41 =   OpExtInst %float %20 Ceil %40\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %44 =   OpLoad %uint %43\n         %45 =   OpBitcast %float %44\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %48 =   OpLoad %uint %47\n         %49 =   OpBitcast %float %48\n         %50 =   OpExtInst %float %20 Fma %41 %45 %49\n         %52 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %53 =   OpLoad %uint %52\n         %54 =   OpBitcast %float %53\n         %55 =   OpFDiv %float %50 %54\n         %56 =   OpFDiv %float %float_1 %55\n         %58 =   OpExtInst %float %20 Fract %56\n         %60 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %61 =   OpLoad %uint %60\n         %62 =   OpBitcast %float %61\n         %63 =   OpExtInst %float %20 NMin %58 %62\n         %65 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %66 =   OpLoad %uint %65\n         %67 =   OpBitcast %float %66\n         %68 =   OpExtInst %float %20 NMax %63 %67\n         %70 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %71 =   OpLoad %uint %70\n         %72 =   OpBitcast %float %71\n         %74 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %75 =   OpLoad %uint %74\n         %76 =   OpBitcast %float %75\n         %77 =   OpExtInst %float %20 NClamp %68 %72 %76\n         %78 =   OpBitcast %uint %77\n         %79 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %79 %78 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32_precise.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_spirv_intrinsics : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float spvNMin(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec2 spvNMin(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec3 spvNMin(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec4 spvNMin(vec4, vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) float spvNMax(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec2 spvNMax(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec3 spvNMax(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) vec4 spvNMax(vec4, vec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) float spvNClamp(float, float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec2 spvNClamp(vec2, vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec3 spvNClamp(vec3, vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) vec4 spvNClamp(vec4, vec4, vec4);\n\nvoid main()\n{\n    precise float _28 = (-abs(trunc(uintBitsToFloat(_9._m0[0u])))) + uintBitsToFloat(_9._m0[1u]);\n    precise float _34 = roundEven(_28) - uintBitsToFloat(_9._m0[2u]);\n    precise float _40 = floor(_34) * uintBitsToFloat(_9._m0[3u]);\n    precise float _55 = fma(ceil(_40), uintBitsToFloat(_9._m0[4u]), uintBitsToFloat(_9._m0[5u])) / uintBitsToFloat(_9._m0[6u]);\n    precise float _56 = 1.0 / _55;\n    _13._m0[0u] = floatBitsToUint(spvNClamp(spvNMax(spvNMin(fract(_56), uintBitsToFloat(_9._m0[7u])), uintBitsToFloat(_9._m0[8u])), uintBitsToFloat(_9._m0[9u]), uintBitsToFloat(_9._m0[10u])));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32_special.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %20 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n%float_2_4000001 = OpConstant %float 2.4000001\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %31\n\n         %31 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpExtInst %float %20 Log2 %19\n         %22 =   OpExtInst %float %20 Sin %21\n         %23 =   OpExtInst %float %20 Sqrt %22\n         %24 =   OpExtInst %float %20 Exp2 %23\n         %25 =   OpExtInst %float %20 InverseSqrt %24\n         %26 =   OpExtInst %float %20 Cos %25\n         %27 =   OpExtInst %float %20 Pow %26 %float_2_4000001\n         %29 =   OpBitcast %uint %27\n         %30 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %30 %29 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp32_special.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = floatBitsToUint(pow(cos(inversesqrt(exp2(sqrt(sin(log2(uintBitsToFloat(_9._m0[0u]))))))), 2.400000095367431640625));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp64.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 90\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float64\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %22 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 64\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n     %double = OpTypeFloat 64\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n   %double_1 = OpConstant %double 1\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %88\n\n         %88 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpFConvert %double %19\n         %23 =   OpExtInst %double %22 FAbs %21\n         %24 =   OpFNegate %double %23\n         %26 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %27 =   OpLoad %uint %26\n         %28 =   OpBitcast %float %27\n         %29 =   OpFConvert %double %28\n         %30 =   OpFAdd %double %24 %29\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %33 =   OpLoad %uint %32\n         %34 =   OpBitcast %float %33\n         %35 =   OpFConvert %double %34\n         %36 =   OpFSub %double %30 %35\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %39 =   OpLoad %uint %38\n         %40 =   OpBitcast %float %39\n         %41 =   OpFConvert %double %40\n         %42 =   OpFMul %double %36 %41\n         %44 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %45 =   OpLoad %uint %44\n         %46 =   OpBitcast %float %45\n         %47 =   OpFConvert %double %46\n         %49 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %50 =   OpLoad %uint %49\n         %51 =   OpBitcast %float %50\n         %52 =   OpFConvert %double %51\n         %53 =   OpExtInst %double %22 Fma %42 %47 %52\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %56 =   OpLoad %uint %55\n         %57 =   OpBitcast %float %56\n         %58 =   OpFConvert %double %57\n         %59 =   OpFDiv %double %53 %58\n         %60 =   OpFDiv %double %double_1 %59\n         %63 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %64 =   OpLoad %uint %63\n         %65 =   OpBitcast %float %64\n         %66 =   OpFConvert %double %65\n         %67 =   OpExtInst %double %22 NMin %60 %66\n         %69 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %70 =   OpLoad %uint %69\n         %71 =   OpBitcast %float %70\n         %72 =   OpFConvert %double %71\n         %73 =   OpExtInst %double %22 NMax %67 %72\n         %75 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %76 =   OpLoad %uint %75\n         %77 =   OpBitcast %float %76\n         %78 =   OpFConvert %double %77\n         %80 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %81 =   OpLoad %uint %80\n         %82 =   OpBitcast %float %81\n         %83 =   OpFConvert %double %82\n         %84 =   OpExtInst %double %22 NClamp %73 %78 %83\n         %85 =   OpFConvert %float %84\n         %86 =   OpBitcast %uint %85\n         %87 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %87 %86 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp64.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_spirv_intrinsics : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) double spvNMin(double, double);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) dvec2 spvNMin(dvec2, dvec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) dvec3 spvNMin(dvec3, dvec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) dvec4 spvNMin(dvec4, dvec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) double spvNMax(double, double);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) dvec2 spvNMax(dvec2, dvec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) dvec3 spvNMax(dvec3, dvec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 80) dvec4 spvNMax(dvec4, dvec4);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) double spvNClamp(double, double, double);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) dvec2 spvNClamp(dvec2, dvec2, dvec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) dvec3 spvNClamp(dvec3, dvec3, dvec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 81) dvec4 spvNClamp(dvec4, dvec4, dvec4);\n\nvoid main()\n{\n    _13._m0[0u] = floatBitsToUint(float(spvNClamp(spvNMax(spvNMin(1.0lf / (fma((((-abs(double(uintBitsToFloat(_9._m0[0u])))) + double(uintBitsToFloat(_9._m0[1u]))) - double(uintBitsToFloat(_9._m0[2u]))) * double(uintBitsToFloat(_9._m0[3u])), double(uintBitsToFloat(_9._m0[4u])), double(uintBitsToFloat(_9._m0[5u]))) / double(uintBitsToFloat(_9._m0[6u]))), double(uintBitsToFloat(_9._m0[7u]))), double(uintBitsToFloat(_9._m0[8u]))), double(uintBitsToFloat(_9._m0[9u])), double(uintBitsToFloat(_9._m0[10u])))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp64_compare.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float64\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 64\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n      %float = OpTypeFloat 32\n     %double = OpTypeFloat 64\n     %uint_1 = OpConstant %uint 1\n       %bool = OpTypeBool\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %54\n\n         %54 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpBitcast %float %17\n         %21 =   OpFConvert %double %19\n         %23 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %24 =   OpLoad %uint %23\n         %25 =   OpBitcast %float %24\n         %26 =   OpFConvert %double %25\n         %28 =   OpFOrdEqual %bool %21 %26\n         %29 =   OpSelect %uint %28 %uint_1 %uint_0\n         %30 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %30 %29 NonPrivatePointer\n         %31 =   OpFUnordNotEqual %bool %21 %26\n         %32 =   OpSelect %uint %31 %uint_1 %uint_0\n         %33 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %33 %32 NonPrivatePointer\n         %34 =   OpFOrdLessThan %bool %21 %26\n         %35 =   OpSelect %uint %34 %uint_1 %uint_0\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %37 %35 NonPrivatePointer\n         %38 =   OpFOrdLessThanEqual %bool %21 %26\n         %39 =   OpSelect %uint %38 %uint_1 %uint_0\n         %41 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %41 %39 NonPrivatePointer\n         %42 =   OpFOrdGreaterThan %bool %21 %26\n         %43 =   OpSelect %uint %42 %uint_1 %uint_0\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %45 %43 NonPrivatePointer\n         %46 =   OpFOrdGreaterThanEqual %bool %21 %26\n         %47 =   OpSelect %uint %46 %uint_1 %uint_0\n         %49 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_5\n                 OpStore %49 %47 NonPrivatePointer\n         %50 =   OpIsNan %bool %21\n         %51 =   OpSelect %uint %50 %uint_1 %uint_0\n         %53 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_6\n                 OpStore %53 %51 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp64_compare.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    double _21 = double(uintBitsToFloat(_9._m0[0u]));\n    double _26 = double(uintBitsToFloat(_9._m0[1u]));\n    _13._m0[0u] = uint(_21 == _26);\n    _13._m0[1u] = uint(_21 != _26);\n    _13._m0[2u] = uint(_21 < _26);\n    _13._m0[3u] = uint(_21 <= _26);\n    _13._m0[4u] = uint(_21 > _26);\n    _13._m0[5u] = uint(_21 >= _26);\n    _13._m0[6u] = uint(isnan(_21));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp64_packing.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float64\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %10 %14\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 64\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_v2uint ArrayStride 8\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Restrict\n               OpDecorate %_runtimearr_v2uint_0 ArrayStride 8\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %14 DescriptorSet 0\n               OpDecorate %14 Binding 0\n               OpDecorate %14 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint\n       %SSBO = OpTypeStruct %_runtimearr_v2uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n         %10 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_v2uint_0 = OpTypeRuntimeArray %v2uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_v2uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %14 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint\n     %uint_1 = OpConstant %uint 1\n     %double = OpTypeFloat 64\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %37\n\n         %37 = OpLabel\n         %17 =   OpAccessChain %_ptr_StorageBuffer_v2uint %10 %uint_0 %uint_0\n         %18 =   OpLoad %v2uint %17\n         %19 =   OpCompositeExtract %uint %18 0\n         %20 =   OpCompositeExtract %uint %18 1\n         %21 =   OpCompositeConstruct %v2uint %19 %20\n         %23 =   OpAccessChain %_ptr_StorageBuffer_v2uint %10 %uint_0 %uint_1\n         %24 =   OpLoad %v2uint %23\n         %25 =   OpCompositeExtract %uint %24 0\n         %26 =   OpCompositeExtract %uint %24 1\n         %27 =   OpCompositeConstruct %v2uint %25 %26\n         %29 =   OpBitcast %double %21\n         %30 =   OpBitcast %double %27\n         %31 =   OpFAdd %double %29 %30\n         %32 =   OpBitcast %v2uint %31\n         %33 =   OpCompositeExtract %uint %32 0\n         %34 =   OpCompositeExtract %uint %32 1\n         %35 =   OpCompositeConstruct %v2uint %33 %34\n         %36 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %uint_0\n                 OpStore %36 %35 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_fp64_packing.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _12_14\n{\n    uvec2 _m0[];\n} _14;\n\nvoid main()\n{\n    _14._m0[0u] = uvec2((uvec2(_10._m0[0u])) + (uvec2(_10._m0[1u])));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_int_extended.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 76\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %10 %14\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %WideArithResult \"WideArithResult\"\n               OpDecorate %_runtimearr_v2uint ArrayStride 8\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Restrict\n               OpDecorate %_runtimearr_v2uint_0 ArrayStride 8\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %14 DescriptorSet 0\n               OpDecorate %14 Binding 0\n               OpDecorate %14 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint\n       %SSBO = OpTypeStruct %_runtimearr_v2uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n         %10 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_v2uint_0 = OpTypeRuntimeArray %v2uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_v2uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %14 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint\n%WideArithResult = OpTypeStruct %uint %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %74\n\n         %74 = OpLabel\n         %17 =   OpAccessChain %_ptr_StorageBuffer_v2uint %10 %uint_0 %uint_0\n         %18 =   OpLoad %v2uint %17\n         %19 =   OpCompositeExtract %uint %18 0\n         %20 =   OpCompositeExtract %uint %18 1\n         %23 =   OpIAddCarry %WideArithResult %19 %20\n         %24 =   OpCompositeExtract %uint %23 0\n         %25 =   OpCompositeExtract %uint %23 1\n         %26 =   OpCompositeConstruct %v2uint %24 %25\n         %27 =   OpCompositeExtract %uint %26 0\n         %28 =   OpCompositeExtract %uint %26 1\n         %29 =   OpCompositeConstruct %v2uint %27 %28\n         %30 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %uint_0\n                 OpStore %30 %29 NonPrivatePointer\n         %32 =   OpAccessChain %_ptr_StorageBuffer_v2uint %10 %uint_0 %uint_1\n         %33 =   OpLoad %v2uint %32\n         %34 =   OpCompositeExtract %uint %33 0\n         %35 =   OpCompositeExtract %uint %33 1\n         %37 =   OpISubBorrow %WideArithResult %34 %35\n         %38 =   OpCompositeExtract %uint %37 0\n         %39 =   OpCompositeExtract %uint %37 1\n         %40 =   OpCompositeConstruct %v2uint %38 %39\n         %41 =   OpCompositeExtract %uint %40 0\n         %42 =   OpCompositeExtract %uint %40 1\n         %43 =   OpCompositeConstruct %v2uint %41 %42\n         %44 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %uint_1\n                 OpStore %44 %43 NonPrivatePointer\n         %46 =   OpAccessChain %_ptr_StorageBuffer_v2uint %10 %uint_0 %uint_2\n         %47 =   OpLoad %v2uint %46\n         %48 =   OpCompositeExtract %uint %47 0\n         %49 =   OpCompositeExtract %uint %47 1\n         %51 =   OpSMulExtended %WideArithResult %48 %49\n         %52 =   OpCompositeExtract %uint %51 0\n         %53 =   OpCompositeExtract %uint %51 1\n         %54 =   OpCompositeConstruct %v2uint %52 %53\n         %55 =   OpCompositeExtract %uint %54 0\n         %56 =   OpCompositeExtract %uint %54 1\n         %58 =   OpCompositeConstruct %v2uint %55 %56\n         %59 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %uint_2\n                 OpStore %59 %58 NonPrivatePointer\n         %61 =   OpAccessChain %_ptr_StorageBuffer_v2uint %10 %uint_0 %uint_3\n         %62 =   OpLoad %v2uint %61\n         %63 =   OpCompositeExtract %uint %62 0\n         %64 =   OpCompositeExtract %uint %62 1\n         %66 =   OpUMulExtended %WideArithResult %63 %64\n         %67 =   OpCompositeExtract %uint %66 0\n         %68 =   OpCompositeExtract %uint %66 1\n         %69 =   OpCompositeConstruct %v2uint %67 %68\n         %70 =   OpCompositeExtract %uint %69 0\n         %71 =   OpCompositeExtract %uint %69 1\n         %72 =   OpCompositeConstruct %v2uint %70 %71\n         %73 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %uint_3\n                 OpStore %73 %72 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_int_extended.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nstruct WideArithResult\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uvec2 _m0[];\n} _10;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _12_14\n{\n    uvec2 _m0[];\n} _14;\n\nvoid main()\n{\n    WideArithResult _23;\n    _23._m0 = uaddCarry(_10._m0[0u].x, _10._m0[0u].y, _23._m1);\n    _14._m0[0u] = uvec2(uvec2(_23._m0, _23._m1));\n    WideArithResult _37;\n    _37._m0 = usubBorrow(_10._m0[1u].x, _10._m0[1u].y, _37._m1);\n    _14._m0[1u] = uvec2(uvec2(_37._m0, _37._m1));\n    WideArithResult _51;\n    imulExtended(_10._m0[2u].x, _10._m0[2u].y, _51._m1, _51._m0);\n    _14._m0[2u] = uvec2(uvec2(_51._m0, _51._m1));\n    WideArithResult _66;\n    umulExtended(_10._m0[3u].x, _10._m0[3u].y, _66._m1, _66._m0);\n    _14._m0[3u] = uvec2(uvec2(_66._m0, _66._m1));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint16_compare.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 65\n; Schema: 0\n               OpCapability Shader\n               OpCapability Int16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %ushort = OpTypeInt 16 0\n     %uint_1 = OpConstant %uint 1\n       %bool = OpTypeBool\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %63\n\n         %63 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpUConvert %ushort %17\n         %21 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %22 =   OpLoad %uint %21\n         %23 =   OpUConvert %ushort %22\n         %25 =   OpIEqual %bool %19 %23\n         %26 =   OpSelect %uint %25 %uint_1 %uint_0\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %27 %26 NonPrivatePointer\n         %28 =   OpINotEqual %bool %19 %23\n         %29 =   OpSelect %uint %28 %uint_1 %uint_0\n         %30 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %30 %29 NonPrivatePointer\n         %31 =   OpSLessThan %bool %19 %23\n         %32 =   OpSelect %uint %31 %uint_1 %uint_0\n         %34 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %34 %32 NonPrivatePointer\n         %35 =   OpSLessThanEqual %bool %19 %23\n         %36 =   OpSelect %uint %35 %uint_1 %uint_0\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %38 %36 NonPrivatePointer\n         %39 =   OpSGreaterThan %bool %19 %23\n         %40 =   OpSelect %uint %39 %uint_1 %uint_0\n         %42 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %42 %40 NonPrivatePointer\n         %43 =   OpSGreaterThanEqual %bool %19 %23\n         %44 =   OpSelect %uint %43 %uint_1 %uint_0\n         %46 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_5\n                 OpStore %46 %44 NonPrivatePointer\n         %47 =   OpULessThan %bool %19 %23\n         %48 =   OpSelect %uint %47 %uint_1 %uint_0\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_6\n                 OpStore %50 %48 NonPrivatePointer\n         %51 =   OpULessThanEqual %bool %19 %23\n         %52 =   OpSelect %uint %51 %uint_1 %uint_0\n         %54 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_7\n                 OpStore %54 %52 NonPrivatePointer\n         %55 =   OpUGreaterThan %bool %19 %23\n         %56 =   OpSelect %uint %55 %uint_1 %uint_0\n         %58 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_8\n                 OpStore %58 %56 NonPrivatePointer\n         %59 =   OpUGreaterThanEqual %bool %19 %23\n         %60 =   OpSelect %uint %59 %uint_1 %uint_0\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_9\n                 OpStore %62 %60 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint16_compare.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    uint16_t _19 = uint16_t(_9._m0[0u]);\n    uint16_t _23 = uint16_t(_9._m0[1u]);\n    _13._m0[0u] = uint(_19 == _23);\n    _13._m0[1u] = uint(_19 != _23);\n    _13._m0[2u] = uint(int16_t(_19) < int16_t(_23));\n    _13._m0[3u] = uint(int16_t(_19) <= int16_t(_23));\n    _13._m0[4u] = uint(int16_t(_19) > int16_t(_23));\n    _13._m0[5u] = uint(int16_t(_19) >= int16_t(_23));\n    _13._m0[6u] = uint(_19 < _23);\n    _13._m0[7u] = uint(_19 <= _23);\n    _13._m0[8u] = uint(_19 > _23);\n    _13._m0[9u] = uint(_19 >= _23);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint16_scalar.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 92\n; Schema: 0\n               OpCapability Shader\n               OpCapability Int16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %47 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %ushort = OpTypeInt 16 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %90\n\n         %90 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpUConvert %ushort %17\n         %21 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %22 =   OpLoad %uint %21\n         %23 =   OpUConvert %ushort %22\n         %24 =   OpBitwiseAnd %ushort %19 %23\n         %26 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %27 =   OpLoad %uint %26\n         %28 =   OpUConvert %ushort %27\n         %29 =   OpBitwiseOr %ushort %24 %28\n         %31 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %32 =   OpLoad %uint %31\n         %33 =   OpUConvert %ushort %32\n         %34 =   OpBitwiseXor %ushort %29 %33\n         %35 =   OpNot %ushort %34\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %38 =   OpLoad %uint %37\n         %39 =   OpUConvert %ushort %38\n         %40 =   OpIAdd %ushort %35 %39\n         %42 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %43 =   OpLoad %uint %42\n         %44 =   OpUConvert %ushort %43\n         %45 =   OpISub %ushort %40 %44\n         %46 =   OpSNegate %ushort %45\n         %48 =   OpExtInst %ushort %47 SAbs %46\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %51 =   OpLoad %uint %50\n         %52 =   OpUConvert %ushort %51\n         %53 =   OpIMul %ushort %48 %52\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %56 =   OpLoad %uint %55\n         %57 =   OpUConvert %ushort %56\n         %58 =   OpShiftLeftLogical %ushort %53 %57\n         %60 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %61 =   OpLoad %uint %60\n         %62 =   OpUConvert %ushort %61\n         %63 =   OpShiftRightArithmetic %ushort %58 %62\n         %65 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %66 =   OpLoad %uint %65\n         %67 =   OpUConvert %ushort %66\n         %68 =   OpShiftRightLogical %ushort %63 %67\n         %70 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %71 =   OpLoad %uint %70\n         %72 =   OpUConvert %ushort %71\n         %73 =   OpExtInst %ushort %47 SMin %68 %72\n         %75 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_11\n         %76 =   OpLoad %uint %75\n         %77 =   OpUConvert %ushort %76\n         %78 =   OpExtInst %ushort %47 SMax %73 %77\n         %80 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_12\n         %81 =   OpLoad %uint %80\n         %82 =   OpUConvert %ushort %81\n         %84 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_13\n         %85 =   OpLoad %uint %84\n         %86 =   OpUConvert %ushort %85\n         %87 =   OpExtInst %ushort %47 SClamp %78 %82 %86\n         %88 =   OpSConvert %uint %87\n         %89 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %89 %88 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint16_scalar.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = uint(int16_t(uint16_t(clamp(int16_t(uint16_t(max(int16_t(uint16_t(min(int16_t(uint16_t(int16_t((uint16_t(abs(int16_t(-(((~(((uint16_t(_9._m0[0u]) & uint16_t(_9._m0[1u])) | uint16_t(_9._m0[2u])) ^ uint16_t(_9._m0[3u]))) + uint16_t(_9._m0[4u])) - uint16_t(_9._m0[5u]))))) * uint16_t(_9._m0[6u])) << uint16_t(_9._m0[7u])) >> int16_t(uint16_t(_9._m0[8u]))) >> uint16_t(_9._m0[9u])), int16_t(uint16_t(_9._m0[10u]))))), int16_t(uint16_t(_9._m0[11u]))))), int16_t(uint16_t(_9._m0[12u])), int16_t(uint16_t(_9._m0[13u]))))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint16_vector.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 93\n; Schema: 0\n               OpCapability Shader\n               OpCapability Int16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %48 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %ushort = OpTypeInt 16 0\n   %v2ushort = OpTypeVector %ushort 2\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %91\n\n         %91 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %20 =   OpBitcast %v2ushort %17\n         %22 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %23 =   OpLoad %uint %22\n         %24 =   OpBitcast %v2ushort %23\n         %25 =   OpBitwiseAnd %v2ushort %20 %24\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %28 =   OpLoad %uint %27\n         %29 =   OpBitcast %v2ushort %28\n         %30 =   OpBitwiseOr %v2ushort %25 %29\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %33 =   OpLoad %uint %32\n         %34 =   OpBitcast %v2ushort %33\n         %35 =   OpBitwiseXor %v2ushort %30 %34\n         %36 =   OpNot %v2ushort %35\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %39 =   OpLoad %uint %38\n         %40 =   OpBitcast %v2ushort %39\n         %41 =   OpIAdd %v2ushort %36 %40\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %44 =   OpLoad %uint %43\n         %45 =   OpBitcast %v2ushort %44\n         %46 =   OpISub %v2ushort %41 %45\n         %47 =   OpSNegate %v2ushort %46\n         %49 =   OpExtInst %v2ushort %48 SAbs %47\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %52 =   OpLoad %uint %51\n         %53 =   OpBitcast %v2ushort %52\n         %54 =   OpIMul %v2ushort %49 %53\n         %56 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %57 =   OpLoad %uint %56\n         %58 =   OpBitcast %v2ushort %57\n         %59 =   OpShiftLeftLogical %v2ushort %54 %58\n         %61 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %62 =   OpLoad %uint %61\n         %63 =   OpBitcast %v2ushort %62\n         %64 =   OpShiftRightArithmetic %v2ushort %59 %63\n         %66 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %67 =   OpLoad %uint %66\n         %68 =   OpBitcast %v2ushort %67\n         %69 =   OpShiftRightLogical %v2ushort %64 %68\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %72 =   OpLoad %uint %71\n         %73 =   OpBitcast %v2ushort %72\n         %74 =   OpExtInst %v2ushort %48 SMin %69 %73\n         %76 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_11\n         %77 =   OpLoad %uint %76\n         %78 =   OpBitcast %v2ushort %77\n         %79 =   OpExtInst %v2ushort %48 SMax %74 %78\n         %81 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_12\n         %82 =   OpLoad %uint %81\n         %83 =   OpBitcast %v2ushort %82\n         %85 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_13\n         %86 =   OpLoad %uint %85\n         %87 =   OpBitcast %v2ushort %86\n         %88 =   OpExtInst %v2ushort %48 SClamp %79 %83 %87\n         %89 =   OpBitcast %uint %88\n         %90 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %90 %89 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint16_vector.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = packUint2x16(u16vec2(clamp(i16vec2(u16vec2(max(i16vec2(u16vec2(min(i16vec2(u16vec2(i16vec2((u16vec2(abs(i16vec2(-(((~(((unpackUint2x16(_9._m0[0u]) & unpackUint2x16(_9._m0[1u])) | unpackUint2x16(_9._m0[2u])) ^ unpackUint2x16(_9._m0[3u]))) + unpackUint2x16(_9._m0[4u])) - unpackUint2x16(_9._m0[5u]))))) * unpackUint2x16(_9._m0[6u])) << unpackUint2x16(_9._m0[7u])) >> i16vec2(unpackUint2x16(_9._m0[8u]))) >> unpackUint2x16(_9._m0[9u])), i16vec2(unpackUint2x16(_9._m0[10u]))))), i16vec2(unpackUint2x16(_9._m0[11u]))))), i16vec2(unpackUint2x16(_9._m0[12u])), i16vec2(unpackUint2x16(_9._m0[13u])))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint32.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 97\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %40 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n    %uint_14 = OpConstant %uint 14\n    %uint_15 = OpConstant %uint 15\n    %uint_16 = OpConstant %uint 16\n    %uint_17 = OpConstant %uint 17\n    %uint_18 = OpConstant %uint 18\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %95\n\n         %95 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %20 =   OpLoad %uint %19\n         %21 =   OpBitwiseAnd %uint %17 %20\n         %23 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %24 =   OpLoad %uint %23\n         %25 =   OpBitwiseOr %uint %21 %24\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %28 =   OpLoad %uint %27\n         %29 =   OpBitwiseXor %uint %25 %28\n         %30 =   OpNot %uint %29\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %33 =   OpLoad %uint %32\n         %34 =   OpIAdd %uint %30 %33\n         %36 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %37 =   OpLoad %uint %36\n         %38 =   OpISub %uint %34 %37\n         %39 =   OpSNegate %uint %38\n         %41 =   OpExtInst %uint %40 SAbs %39\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %44 =   OpLoad %uint %43\n         %45 =   OpIMul %uint %41 %44\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %48 =   OpLoad %uint %47\n         %49 =   OpShiftLeftLogical %uint %45 %48\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %52 =   OpLoad %uint %51\n         %53 =   OpShiftRightArithmetic %uint %49 %52\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %56 =   OpLoad %uint %55\n         %57 =   OpShiftRightLogical %uint %53 %56\n         %59 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %60 =   OpLoad %uint %59\n         %61 =   OpExtInst %uint %40 SMin %57 %60\n         %63 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_11\n         %64 =   OpLoad %uint %63\n         %65 =   OpExtInst %uint %40 SMax %61 %64\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_12\n         %68 =   OpLoad %uint %67\n         %70 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_13\n         %71 =   OpLoad %uint %70\n         %72 =   OpExtInst %uint %40 SClamp %65 %68 %71\n         %74 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_14\n         %75 =   OpLoad %uint %74\n         %77 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_15\n         %78 =   OpLoad %uint %77\n         %80 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_16\n         %81 =   OpLoad %uint %80\n         %82 =   OpBitFieldInsert %uint %72 %75 %78 %81\n         %84 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_17\n         %85 =   OpLoad %uint %84\n         %87 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_18\n         %88 =   OpLoad %uint %87\n         %89 =   OpBitFieldSExtract %uint %82 %85 %88\n         %90 =   OpBitCount %uint %89\n         %91 =   OpBitReverse %uint %90\n         %92 =   OpExtInst %uint %40 FindILsb %91\n         %93 =   OpExtInst %uint %40 FindSMsb %92\n         %94 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %94 %93 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint32.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = uint(findMSB(int(uint(findLSB(bitfieldReverse(uint(bitCount(uint(bitfieldExtract(int(bitfieldInsert(uint(clamp(int(uint(max(int(uint(min(int(uint(int((uint(abs(int(-(((~(((_9._m0[0u] & _9._m0[1u]) | _9._m0[2u]) ^ _9._m0[3u])) + _9._m0[4u]) - _9._m0[5u])))) * _9._m0[6u]) << _9._m0[7u]) >> int(_9._m0[8u])) >> _9._m0[9u]), int(_9._m0[10u])))), int(_9._m0[11u])))), int(_9._m0[12u]), int(_9._m0[13u]))), _9._m0[14u], int(_9._m0[15u]), int(_9._m0[16u]))), int(_9._m0[17u]), int(_9._m0[18u])))))))))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint32_compare.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_1 = OpConstant %uint 1\n       %bool = OpTypeBool\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %60\n\n         %60 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %20 =   OpLoad %uint %19\n         %22 =   OpIEqual %bool %17 %20\n         %23 =   OpSelect %uint %22 %uint_1 %uint_0\n         %24 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %24 %23 NonPrivatePointer\n         %25 =   OpINotEqual %bool %17 %20\n         %26 =   OpSelect %uint %25 %uint_1 %uint_0\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %27 %26 NonPrivatePointer\n         %28 =   OpSLessThan %bool %17 %20\n         %29 =   OpSelect %uint %28 %uint_1 %uint_0\n         %31 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %31 %29 NonPrivatePointer\n         %32 =   OpSLessThanEqual %bool %17 %20\n         %33 =   OpSelect %uint %32 %uint_1 %uint_0\n         %35 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %35 %33 NonPrivatePointer\n         %36 =   OpSGreaterThan %bool %17 %20\n         %37 =   OpSelect %uint %36 %uint_1 %uint_0\n         %39 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %39 %37 NonPrivatePointer\n         %40 =   OpSGreaterThanEqual %bool %17 %20\n         %41 =   OpSelect %uint %40 %uint_1 %uint_0\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_5\n                 OpStore %43 %41 NonPrivatePointer\n         %44 =   OpULessThan %bool %17 %20\n         %45 =   OpSelect %uint %44 %uint_1 %uint_0\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_6\n                 OpStore %47 %45 NonPrivatePointer\n         %48 =   OpULessThanEqual %bool %17 %20\n         %49 =   OpSelect %uint %48 %uint_1 %uint_0\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_7\n                 OpStore %51 %49 NonPrivatePointer\n         %52 =   OpUGreaterThan %bool %17 %20\n         %53 =   OpSelect %uint %52 %uint_1 %uint_0\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_8\n                 OpStore %55 %53 NonPrivatePointer\n         %56 =   OpUGreaterThanEqual %bool %17 %20\n         %57 =   OpSelect %uint %56 %uint_1 %uint_0\n         %59 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_9\n                 OpStore %59 %57 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_sint32_compare.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = uint(_9._m0[0u] == _9._m0[1u]);\n    _13._m0[1u] = uint(_9._m0[0u] != _9._m0[1u]);\n    _13._m0[2u] = uint(int(_9._m0[0u]) < int(_9._m0[1u]));\n    _13._m0[3u] = uint(int(_9._m0[0u]) <= int(_9._m0[1u]));\n    _13._m0[4u] = uint(int(_9._m0[0u]) > int(_9._m0[1u]));\n    _13._m0[5u] = uint(int(_9._m0[0u]) >= int(_9._m0[1u]));\n    _13._m0[6u] = uint(_9._m0[0u] < _9._m0[1u]);\n    _13._m0[7u] = uint(_9._m0[0u] <= _9._m0[1u]);\n    _13._m0[8u] = uint(_9._m0[0u] > _9._m0[1u]);\n    _13._m0[9u] = uint(_9._m0[0u] >= _9._m0[1u]);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint16_compare.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 65\n; Schema: 0\n               OpCapability Shader\n               OpCapability Int16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %ushort = OpTypeInt 16 0\n     %uint_1 = OpConstant %uint 1\n       %bool = OpTypeBool\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %63\n\n         %63 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpUConvert %ushort %17\n         %21 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %22 =   OpLoad %uint %21\n         %23 =   OpUConvert %ushort %22\n         %25 =   OpIEqual %bool %19 %23\n         %26 =   OpSelect %uint %25 %uint_1 %uint_0\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %27 %26 NonPrivatePointer\n         %28 =   OpINotEqual %bool %19 %23\n         %29 =   OpSelect %uint %28 %uint_1 %uint_0\n         %30 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %30 %29 NonPrivatePointer\n         %31 =   OpSLessThan %bool %19 %23\n         %32 =   OpSelect %uint %31 %uint_1 %uint_0\n         %34 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %34 %32 NonPrivatePointer\n         %35 =   OpSLessThanEqual %bool %19 %23\n         %36 =   OpSelect %uint %35 %uint_1 %uint_0\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %38 %36 NonPrivatePointer\n         %39 =   OpSGreaterThan %bool %19 %23\n         %40 =   OpSelect %uint %39 %uint_1 %uint_0\n         %42 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %42 %40 NonPrivatePointer\n         %43 =   OpSGreaterThanEqual %bool %19 %23\n         %44 =   OpSelect %uint %43 %uint_1 %uint_0\n         %46 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_5\n                 OpStore %46 %44 NonPrivatePointer\n         %47 =   OpULessThan %bool %19 %23\n         %48 =   OpSelect %uint %47 %uint_1 %uint_0\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_6\n                 OpStore %50 %48 NonPrivatePointer\n         %51 =   OpULessThanEqual %bool %19 %23\n         %52 =   OpSelect %uint %51 %uint_1 %uint_0\n         %54 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_7\n                 OpStore %54 %52 NonPrivatePointer\n         %55 =   OpUGreaterThan %bool %19 %23\n         %56 =   OpSelect %uint %55 %uint_1 %uint_0\n         %58 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_8\n                 OpStore %58 %56 NonPrivatePointer\n         %59 =   OpUGreaterThanEqual %bool %19 %23\n         %60 =   OpSelect %uint %59 %uint_1 %uint_0\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_9\n                 OpStore %62 %60 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint16_compare.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    uint16_t _19 = uint16_t(_9._m0[0u]);\n    uint16_t _23 = uint16_t(_9._m0[1u]);\n    _13._m0[0u] = uint(_19 == _23);\n    _13._m0[1u] = uint(_19 != _23);\n    _13._m0[2u] = uint(int16_t(_19) < int16_t(_23));\n    _13._m0[3u] = uint(int16_t(_19) <= int16_t(_23));\n    _13._m0[4u] = uint(int16_t(_19) > int16_t(_23));\n    _13._m0[5u] = uint(int16_t(_19) >= int16_t(_23));\n    _13._m0[6u] = uint(_19 < _23);\n    _13._m0[7u] = uint(_19 <= _23);\n    _13._m0[8u] = uint(_19 > _23);\n    _13._m0[9u] = uint(_19 >= _23);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint16_scalar.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 102\n; Schema: 0\n               OpCapability Shader\n               OpCapability Int16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %47 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %ushort = OpTypeInt 16 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n    %uint_14 = OpConstant %uint 14\n    %uint_15 = OpConstant %uint 15\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %100\n\n        %100 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpUConvert %ushort %17\n         %21 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %22 =   OpLoad %uint %21\n         %23 =   OpUConvert %ushort %22\n         %24 =   OpBitwiseAnd %ushort %19 %23\n         %26 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %27 =   OpLoad %uint %26\n         %28 =   OpUConvert %ushort %27\n         %29 =   OpBitwiseOr %ushort %24 %28\n         %31 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %32 =   OpLoad %uint %31\n         %33 =   OpUConvert %ushort %32\n         %34 =   OpBitwiseXor %ushort %29 %33\n         %35 =   OpNot %ushort %34\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %38 =   OpLoad %uint %37\n         %39 =   OpUConvert %ushort %38\n         %40 =   OpIAdd %ushort %35 %39\n         %42 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %43 =   OpLoad %uint %42\n         %44 =   OpUConvert %ushort %43\n         %45 =   OpISub %ushort %40 %44\n         %46 =   OpSNegate %ushort %45\n         %48 =   OpExtInst %ushort %47 SAbs %46\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %51 =   OpLoad %uint %50\n         %52 =   OpUConvert %ushort %51\n         %53 =   OpIMul %ushort %48 %52\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %56 =   OpLoad %uint %55\n         %57 =   OpUConvert %ushort %56\n         %58 =   OpShiftLeftLogical %ushort %53 %57\n         %60 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %61 =   OpLoad %uint %60\n         %62 =   OpUConvert %ushort %61\n         %63 =   OpShiftRightArithmetic %ushort %58 %62\n         %65 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %66 =   OpLoad %uint %65\n         %67 =   OpUConvert %ushort %66\n         %68 =   OpShiftRightLogical %ushort %63 %67\n         %70 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %71 =   OpLoad %uint %70\n         %72 =   OpUConvert %ushort %71\n         %73 =   OpUDiv %ushort %68 %72\n         %75 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_11\n         %76 =   OpLoad %uint %75\n         %77 =   OpUConvert %ushort %76\n         %78 =   OpUMod %ushort %73 %77\n         %80 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_12\n         %81 =   OpLoad %uint %80\n         %82 =   OpUConvert %ushort %81\n         %83 =   OpExtInst %ushort %47 UMin %78 %82\n         %85 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_13\n         %86 =   OpLoad %uint %85\n         %87 =   OpUConvert %ushort %86\n         %88 =   OpExtInst %ushort %47 UMax %83 %87\n         %90 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_14\n         %91 =   OpLoad %uint %90\n         %92 =   OpUConvert %ushort %91\n         %94 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_15\n         %95 =   OpLoad %uint %94\n         %96 =   OpUConvert %ushort %95\n         %97 =   OpExtInst %ushort %47 UClamp %88 %92 %96\n         %98 =   OpUConvert %uint %97\n         %99 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %99 %98 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint16_scalar.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    uint _98 = uint(clamp(max(min((((uint16_t(int16_t((uint16_t(abs(int16_t(-(((~(((uint16_t(_9._m0[0u]) & uint16_t(_9._m0[1u])) | uint16_t(_9._m0[2u])) ^ uint16_t(_9._m0[3u]))) + uint16_t(_9._m0[4u])) - uint16_t(_9._m0[5u]))))) * uint16_t(_9._m0[6u])) << uint16_t(_9._m0[7u])) >> int16_t(uint16_t(_9._m0[8u]))) >> uint16_t(_9._m0[9u])) / uint16_t(_9._m0[10u])) % uint16_t(_9._m0[11u])), uint16_t(_9._m0[12u])), uint16_t(_9._m0[13u])), uint16_t(_9._m0[14u]), uint16_t(_9._m0[15u])));\n    _13._m0[0u] = _98;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint16_vector.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 103\n; Schema: 0\n               OpCapability Shader\n               OpCapability Int16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %48 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %ushort = OpTypeInt 16 0\n   %v2ushort = OpTypeVector %ushort 2\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n    %uint_14 = OpConstant %uint 14\n    %uint_15 = OpConstant %uint 15\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %101\n\n        %101 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %20 =   OpBitcast %v2ushort %17\n         %22 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %23 =   OpLoad %uint %22\n         %24 =   OpBitcast %v2ushort %23\n         %25 =   OpBitwiseAnd %v2ushort %20 %24\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %28 =   OpLoad %uint %27\n         %29 =   OpBitcast %v2ushort %28\n         %30 =   OpBitwiseOr %v2ushort %25 %29\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %33 =   OpLoad %uint %32\n         %34 =   OpBitcast %v2ushort %33\n         %35 =   OpBitwiseXor %v2ushort %30 %34\n         %36 =   OpNot %v2ushort %35\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %39 =   OpLoad %uint %38\n         %40 =   OpBitcast %v2ushort %39\n         %41 =   OpIAdd %v2ushort %36 %40\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %44 =   OpLoad %uint %43\n         %45 =   OpBitcast %v2ushort %44\n         %46 =   OpISub %v2ushort %41 %45\n         %47 =   OpSNegate %v2ushort %46\n         %49 =   OpExtInst %v2ushort %48 SAbs %47\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %52 =   OpLoad %uint %51\n         %53 =   OpBitcast %v2ushort %52\n         %54 =   OpIMul %v2ushort %49 %53\n         %56 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %57 =   OpLoad %uint %56\n         %58 =   OpBitcast %v2ushort %57\n         %59 =   OpShiftLeftLogical %v2ushort %54 %58\n         %61 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %62 =   OpLoad %uint %61\n         %63 =   OpBitcast %v2ushort %62\n         %64 =   OpShiftRightArithmetic %v2ushort %59 %63\n         %66 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %67 =   OpLoad %uint %66\n         %68 =   OpBitcast %v2ushort %67\n         %69 =   OpShiftRightLogical %v2ushort %64 %68\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %72 =   OpLoad %uint %71\n         %73 =   OpBitcast %v2ushort %72\n         %74 =   OpUDiv %v2ushort %69 %73\n         %76 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_11\n         %77 =   OpLoad %uint %76\n         %78 =   OpBitcast %v2ushort %77\n         %79 =   OpUMod %v2ushort %74 %78\n         %81 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_12\n         %82 =   OpLoad %uint %81\n         %83 =   OpBitcast %v2ushort %82\n         %84 =   OpExtInst %v2ushort %48 UMin %79 %83\n         %86 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_13\n         %87 =   OpLoad %uint %86\n         %88 =   OpBitcast %v2ushort %87\n         %89 =   OpExtInst %v2ushort %48 UMax %84 %88\n         %91 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_14\n         %92 =   OpLoad %uint %91\n         %93 =   OpBitcast %v2ushort %92\n         %95 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_15\n         %96 =   OpLoad %uint %95\n         %97 =   OpBitcast %v2ushort %96\n         %98 =   OpExtInst %v2ushort %48 UClamp %89 %93 %97\n         %99 =   OpBitcast %uint %98\n        %100 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %100 %99 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint16_vector.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    uint _99 = packUint2x16(clamp(max(min((((u16vec2(i16vec2((u16vec2(abs(i16vec2(-(((~(((unpackUint2x16(_9._m0[0u]) & unpackUint2x16(_9._m0[1u])) | unpackUint2x16(_9._m0[2u])) ^ unpackUint2x16(_9._m0[3u]))) + unpackUint2x16(_9._m0[4u])) - unpackUint2x16(_9._m0[5u]))))) * unpackUint2x16(_9._m0[6u])) << unpackUint2x16(_9._m0[7u])) >> i16vec2(unpackUint2x16(_9._m0[8u]))) >> unpackUint2x16(_9._m0[9u])) / unpackUint2x16(_9._m0[10u])) % unpackUint2x16(_9._m0[11u])), unpackUint2x16(_9._m0[12u])), unpackUint2x16(_9._m0[13u])), unpackUint2x16(_9._m0[14u]), unpackUint2x16(_9._m0[15u])));\n    _13._m0[0u] = _99;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint32.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 105\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %40 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n    %uint_14 = OpConstant %uint 14\n    %uint_15 = OpConstant %uint 15\n    %uint_16 = OpConstant %uint 16\n    %uint_17 = OpConstant %uint 17\n    %uint_18 = OpConstant %uint 18\n    %uint_19 = OpConstant %uint 19\n    %uint_20 = OpConstant %uint 20\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %103\n\n        %103 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %20 =   OpLoad %uint %19\n         %21 =   OpBitwiseAnd %uint %17 %20\n         %23 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_2\n         %24 =   OpLoad %uint %23\n         %25 =   OpBitwiseOr %uint %21 %24\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_3\n         %28 =   OpLoad %uint %27\n         %29 =   OpBitwiseXor %uint %25 %28\n         %30 =   OpNot %uint %29\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_4\n         %33 =   OpLoad %uint %32\n         %34 =   OpIAdd %uint %30 %33\n         %36 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_5\n         %37 =   OpLoad %uint %36\n         %38 =   OpISub %uint %34 %37\n         %39 =   OpSNegate %uint %38\n         %41 =   OpExtInst %uint %40 SAbs %39\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_6\n         %44 =   OpLoad %uint %43\n         %45 =   OpIMul %uint %41 %44\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %48 =   OpLoad %uint %47\n         %49 =   OpShiftLeftLogical %uint %45 %48\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_8\n         %52 =   OpLoad %uint %51\n         %53 =   OpShiftRightArithmetic %uint %49 %52\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_9\n         %56 =   OpLoad %uint %55\n         %57 =   OpShiftRightLogical %uint %53 %56\n         %59 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_10\n         %60 =   OpLoad %uint %59\n         %61 =   OpUDiv %uint %57 %60\n         %63 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_11\n         %64 =   OpLoad %uint %63\n         %65 =   OpUMod %uint %61 %64\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_12\n         %68 =   OpLoad %uint %67\n         %69 =   OpExtInst %uint %40 UMin %65 %68\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_13\n         %72 =   OpLoad %uint %71\n         %73 =   OpExtInst %uint %40 UMax %69 %72\n         %75 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_14\n         %76 =   OpLoad %uint %75\n         %78 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_15\n         %79 =   OpLoad %uint %78\n         %80 =   OpExtInst %uint %40 UClamp %73 %76 %79\n         %82 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_16\n         %83 =   OpLoad %uint %82\n         %85 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_17\n         %86 =   OpLoad %uint %85\n         %88 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_18\n         %89 =   OpLoad %uint %88\n         %90 =   OpBitFieldInsert %uint %80 %83 %86 %89\n         %92 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_19\n         %93 =   OpLoad %uint %92\n         %95 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_20\n         %96 =   OpLoad %uint %95\n         %97 =   OpBitFieldUExtract %uint %90 %93 %96\n         %98 =   OpBitCount %uint %97\n         %99 =   OpBitReverse %uint %98\n        %100 =   OpExtInst %uint %40 FindILsb %99\n        %101 =   OpExtInst %uint %40 FindUMsb %100\n        %102 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %102 %101 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint32.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = uint(findMSB(uint(findLSB(bitfieldReverse(uint(bitCount(bitfieldExtract(bitfieldInsert(clamp(max(min((((uint(int((uint(abs(int(-(((~(((_9._m0[0u] & _9._m0[1u]) | _9._m0[2u]) ^ _9._m0[3u])) + _9._m0[4u]) - _9._m0[5u])))) * _9._m0[6u]) << _9._m0[7u]) >> int(_9._m0[8u])) >> _9._m0[9u]) / _9._m0[10u]) % _9._m0[11u]), _9._m0[12u]), _9._m0[13u]), _9._m0[14u], _9._m0[15u]), _9._m0[16u], int(_9._m0[17u]), int(_9._m0[18u])), int(_9._m0[19u]), int(_9._m0[20u])))))))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint32_compare.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_1 = OpConstant %uint 1\n       %bool = OpTypeBool\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %60\n\n         %60 = OpLabel\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0\n         %17 =   OpLoad %uint %16\n         %19 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_1\n         %20 =   OpLoad %uint %19\n         %22 =   OpIEqual %bool %17 %20\n         %23 =   OpSelect %uint %22 %uint_1 %uint_0\n         %24 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_0\n                 OpStore %24 %23 NonPrivatePointer\n         %25 =   OpINotEqual %bool %17 %20\n         %26 =   OpSelect %uint %25 %uint_1 %uint_0\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_1\n                 OpStore %27 %26 NonPrivatePointer\n         %28 =   OpSLessThan %bool %17 %20\n         %29 =   OpSelect %uint %28 %uint_1 %uint_0\n         %31 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_2\n                 OpStore %31 %29 NonPrivatePointer\n         %32 =   OpSLessThanEqual %bool %17 %20\n         %33 =   OpSelect %uint %32 %uint_1 %uint_0\n         %35 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_3\n                 OpStore %35 %33 NonPrivatePointer\n         %36 =   OpSGreaterThan %bool %17 %20\n         %37 =   OpSelect %uint %36 %uint_1 %uint_0\n         %39 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_4\n                 OpStore %39 %37 NonPrivatePointer\n         %40 =   OpSGreaterThanEqual %bool %17 %20\n         %41 =   OpSelect %uint %40 %uint_1 %uint_0\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_5\n                 OpStore %43 %41 NonPrivatePointer\n         %44 =   OpULessThan %bool %17 %20\n         %45 =   OpSelect %uint %44 %uint_1 %uint_0\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_6\n                 OpStore %47 %45 NonPrivatePointer\n         %48 =   OpULessThanEqual %bool %17 %20\n         %49 =   OpSelect %uint %48 %uint_1 %uint_0\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_7\n                 OpStore %51 %49 NonPrivatePointer\n         %52 =   OpUGreaterThan %bool %17 %20\n         %53 =   OpSelect %uint %52 %uint_1 %uint_0\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_8\n                 OpStore %55 %53 NonPrivatePointer\n         %56 =   OpUGreaterThanEqual %bool %17 %20\n         %57 =   OpSelect %uint %56 %uint_1 %uint_0\n         %59 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %uint_9\n                 OpStore %59 %57 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_arithmetic_uint32_compare.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nvoid main()\n{\n    _13._m0[0u] = uint(_9._m0[0u] == _9._m0[1u]);\n    _13._m0[1u] = uint(_9._m0[0u] != _9._m0[1u]);\n    _13._m0[2u] = uint(int(_9._m0[0u]) < int(_9._m0[1u]));\n    _13._m0[3u] = uint(int(_9._m0[0u]) <= int(_9._m0[1u]));\n    _13._m0[4u] = uint(int(_9._m0[0u]) > int(_9._m0[1u]));\n    _13._m0[5u] = uint(int(_9._m0[0u]) >= int(_9._m0[1u]));\n    _13._m0[6u] = uint(_9._m0[0u] < _9._m0[1u]);\n    _13._m0[7u] = uint(_9._m0[0u] <= _9._m0[1u]);\n    _13._m0[8u] = uint(_9._m0[0u] > _9._m0[1u]);\n    _13._m0[9u] = uint(_9._m0[0u] >= _9._m0[1u]);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_if.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%_ptr_Input_float = OpTypePointer Input %float\n       %uint = OpTypeInt 32 0\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_0 = OpConstant %float 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %24\n\n         %24 = OpLabel\n         %12 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_2\n         %15 =   OpLoad %float %12\n         %16 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_3\n         %18 =   OpLoad %float %16\n         %20 =   OpFUnordNotEqual %bool %18 %float_0\n                 OpSelectionMerge %26 None\n                 OpBranchConditional %20 %25 %26\n\n         %25 =     OpLabel\n         %22 =       OpFDiv %float %15 %18\n                     OpBranch %26\n\n         %26 = OpLabel\n         %23 =   OpPhi %float %15 %24 %22 %25\n                 OpStore %SV_TARGET %23\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_if.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    float _23;\n    if (gl_FragCoord.w != 0.0)\n    {\n        _23 = gl_FragCoord.z / gl_FragCoord.w;\n    }\n    else\n    {\n        _23 = gl_FragCoord.z;\n    }\n    SV_TARGET = _23;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_if_else.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%_ptr_Input_float = OpTypePointer Input %float\n       %uint = OpTypeInt 32 0\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %24\n\n         %24 = OpLabel\n         %12 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_2\n         %15 =   OpLoad %float %12\n         %16 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_3\n         %18 =   OpLoad %float %16\n         %20 =   OpFOrdGreaterThan %bool %15 %18\n                 OpSelectionMerge %27 None\n                 OpBranchConditional %20 %26 %25\n\n         %26 =     OpLabel\n         %21 =       OpFDiv %float %15 %18\n                     OpBranch %27\n\n         %25 =     OpLabel\n         %22 =       OpFDiv %float %18 %15\n                     OpBranch %27\n\n         %27 = OpLabel\n         %23 =   OpPhi %float %21 %26 %22 %25\n                 OpStore %SV_TARGET %23\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_if_else.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    float _23;\n    if (gl_FragCoord.z > gl_FragCoord.w)\n    {\n        _23 = gl_FragCoord.z / gl_FragCoord.w;\n    }\n    else\n    {\n        _23 = gl_FragCoord.w / gl_FragCoord.z;\n    }\n    SV_TARGET = _23;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_loop_infinite.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%_ptr_Input_float = OpTypePointer Input %float\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n    %float_1 = OpConstant %float 1\n       %bool = OpTypeBool\n%float_10000 = OpConstant %float 10000\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %22\n\n         %22 = OpLabel\n         %12 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_0\n         %15 =   OpLoad %float %12\n                 OpBranch %23\n\n         %23 = OpLabel\n         %16 =   OpPhi %float %15 %22 %17 %26\n                 OpLoopMerge %28 %26 None\n                 OpBranch %24\n\n         %24 =     OpLabel\n         %17 =       OpFAdd %float %16 %float_1\n         %20 =       OpFOrdGreaterThanEqual %bool %17 %float_10000\n                     OpSelectionMerge %25 None\n                     OpBranchConditional %20 %27 %25\n\n         %27 =         OpLabel\n                         OpStore %SV_TARGET %17\n                         OpReturn\n\n         %25 =     OpLabel\n                     OpBranch %26\n\n         %26 =   OpLabel\n                   OpBranch %23\n\n         %28 = OpLabel\n                 OpUnreachable\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_loop_infinite.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    float _17;\n    float _16 = gl_FragCoord.x;\n    for (;;)\n    {\n        _17 = _16 + 1.0;\n        if (_17 >= 10000.0)\n        {\n            SV_TARGET = _17;\n            return;\n        }\n        _16 = _17;\n        continue;\n    }\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_loop_once.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 24\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%_ptr_Input_float = OpTypePointer Input %float\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n    %float_1 = OpConstant %float 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %18\n\n         %18 = OpLabel\n         %12 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_0\n         %15 =   OpLoad %float %12\n                 OpBranch %19\n\n         %19 = OpLabel\n                 OpLoopMerge %21 %22 None\n                 OpBranch %20\n\n         %20 =     OpLabel\n         %16 =       OpFAdd %float %15 %float_1\n                     OpBranch %21\n\n         %22 =   OpLabel\n                   OpBranch %19\n\n         %21 = OpLabel\n                 OpStore %SV_TARGET %16\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_loop_once.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    float _16;\n    for (;;)\n    {\n        _16 = gl_FragCoord.x + 1.0;\n        break;\n    }\n    SV_TARGET = _16;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_switch_complex.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %SEL %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %SEL \"SEL\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %SEL Flat\n               OpDecorate %SEL Location 1\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n        %int = OpTypeInt 32 1\n%_ptr_Input_int = OpTypePointer Input %int\n        %SEL = OpVariable %_ptr_Input_int Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n    %float_0 = OpConstant %float 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n   %float_n1 = OpConstant %float -1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %35\n\n         %35 = OpLabel\n         %14 =   OpLoad %int %SEL\n         %16 =   OpBitcast %uint %14\n                 OpSelectionMerge %40 None\n                 OpSwitch %16 %40 3 %39 7 %37 9 %38 17 %36\n\n         %39 =     OpLabel\n         %23 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_0\n         %19 =       OpLoad %float %23\n                     OpBranch %40\n\n         %37 =     OpLabel\n         %25 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_1\n         %27 =       OpLoad %float %25\n                     OpBranch %38\n\n         %38 =     OpLabel\n         %28 =       OpPhi %float %float_n1 %35 %27 %37\n         %30 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_2\n         %32 =       OpLoad %float %30\n         %20 =       OpFAdd %float %32 %28\n                     OpBranch %40\n\n         %36 =     OpLabel\n         %33 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_3\n         %21 =       OpLoad %float %33\n                     OpBranch %40\n\n         %40 = OpLabel\n         %17 =   OpPhi %float %float_0 %35 %19 %39 %20 %38 %21 %36\n                 OpStore %SV_TARGET %17\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_switch_complex.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 1) flat in int SEL;\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    uint _16 = uint(SEL);\n    float _17;\n    float _28;\n    if (_16 == 9)\n    {\n        _28 = -1.0;\n    }\n    switch (_16)\n    {\n        case 3u:\n        {\n            _17 = gl_FragCoord.x;\n            break;\n        }\n        case 7u:\n        {\n            _28 = gl_FragCoord.y;\n        }\n        case 9u:\n        {\n            _17 = gl_FragCoord.z + _28;\n            break;\n        }\n        case 17u:\n        {\n            _17 = gl_FragCoord.w;\n            break;\n        }\n        default:\n        {\n            _17 = 0.0;\n            break;\n        }\n    }\n    SV_TARGET = _17;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_switch_simple.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %SEL %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %SEL \"SEL\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %SEL Flat\n               OpDecorate %SEL Location 1\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n        %int = OpTypeInt 32 1\n%_ptr_Input_int = OpTypePointer Input %int\n        %SEL = OpVariable %_ptr_Input_int Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_3 = OpConstant %uint 3\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %30\n\n         %30 = OpLabel\n         %14 =   OpLoad %int %SEL\n         %16 =   OpBitcast %uint %14\n                 OpSelectionMerge %35 None\n                 OpSwitch %16 %34 3 %33 6 %32 7 %32 9 %31\n\n         %34 =     OpLabel\n         %18 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_3\n         %20 =       OpLoad %float %18\n                     OpStore %SV_TARGET %20\n                     OpBranch %35\n\n         %33 =     OpLabel\n         %21 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_0\n         %23 =       OpLoad %float %21\n                     OpStore %SV_TARGET %23\n                     OpBranch %35\n\n         %32 =     OpLabel\n         %24 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_1\n         %26 =       OpLoad %float %24\n                     OpStore %SV_TARGET %26\n                     OpBranch %35\n\n         %31 =     OpLabel\n         %27 =       OpAccessChain %_ptr_Input_float %SV_POSITION %uint_2\n         %29 =       OpLoad %float %27\n                     OpStore %SV_TARGET %29\n                     OpBranch %35\n\n         %35 = OpLabel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_cfg_switch_simple.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 1) flat in int SEL;\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    switch (uint(SEL))\n    {\n        case 3u:\n        {\n            SV_TARGET = gl_FragCoord.x;\n            break;\n        }\n        case 6u:\n        case 7u:\n        {\n            SV_TARGET = gl_FragCoord.y;\n            break;\n        }\n        case 9u:\n        {\n            SV_TARGET = gl_FragCoord.z;\n            break;\n        }\n        default:\n        {\n            SV_TARGET = gl_FragCoord.w;\n            break;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_f_to_f.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float16\n               OpCapability Float64\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %INPUT %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 16\n               OpExecutionMode %main SignedZeroInfNanPreserve 64\n               OpName %main \"main\"\n               OpName %INPUT \"INPUT\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %INPUT Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n%_ptr_Input_float = OpTypePointer Input %float\n      %INPUT = OpVariable %_ptr_Input_float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n       %half = OpTypeFloat 16\n     %double = OpTypeFloat 64\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %19\n\n         %19 = OpLabel\n         %10 =   OpLoad %float %INPUT\n         %12 =   OpFConvert %half %10\n         %14 =   OpFConvert %double %12\n         %15 =   OpFConvert %float %14\n         %16 =   OpFConvert %double %15\n         %17 =   OpFConvert %half %16\n         %18 =   OpFConvert %float %17\n                 OpStore %SV_TARGET %18\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_f_to_f.glsl",
    "content": "GLSL:\n#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) in float INPUT;\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = float(float16_t(double(float(double(float16_t(INPUT))))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_f_to_i.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float16\n               OpCapability Float64\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %INPUT %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 16\n               OpExecutionMode %main SignedZeroInfNanPreserve 64\n               OpName %main \"main\"\n               OpName %INPUT \"INPUT\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %INPUT Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n%_ptr_Input_float = OpTypePointer Input %float\n      %INPUT = OpVariable %_ptr_Input_float Input\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n        %int = OpTypeInt 32 1\n%_ptr_Output_int = OpTypePointer Output %int\n%SV_TARGET_1 = OpVariable %_ptr_Output_int Output\n     %double = OpTypeFloat 64\n       %half = OpTypeFloat 16\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %32\n\n         %32 = OpLabel\n         %14 =   OpLoad %float %INPUT\n         %15 =   OpConvertFToU %uint %14\n         %16 =   OpConvertFToS %uint %14\n         %18 =   OpFConvert %double %14\n         %19 =   OpConvertFToU %uint %18\n         %20 =   OpIAdd %uint %15 %19\n         %21 =   OpFConvert %double %14\n         %22 =   OpConvertFToS %uint %21\n         %23 =   OpIAdd %uint %16 %22\n         %25 =   OpFConvert %half %14\n         %26 =   OpConvertFToU %uint %25\n         %27 =   OpIAdd %uint %20 %26\n         %28 =   OpFConvert %half %14\n         %29 =   OpConvertFToS %uint %28\n         %30 =   OpIAdd %uint %23 %29\n                 OpStore %SV_TARGET %27\n         %31 =   OpBitcast %int %30\n                 OpStore %SV_TARGET_1 %31\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_f_to_i.glsl",
    "content": "GLSL:\n#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) in float INPUT;\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out int SV_TARGET_1;\n\nvoid main()\n{\n    SV_TARGET = (uint(INPUT) + uint(double(INPUT))) + uint(float16_t(INPUT));\n    SV_TARGET_1 = int((uint(int(INPUT)) + uint(int(double(INPUT)))) + uint(int(float16_t(INPUT))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_i_to_f.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\n               OpCapability Shader\n               OpCapability Float16\n               OpCapability Float64\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %UINPUT %SINPUT %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpExecutionMode %main SignedZeroInfNanPreserve 16\n               OpExecutionMode %main SignedZeroInfNanPreserve 64\n               OpName %main \"main\"\n               OpName %UINPUT \"UINPUT\"\n               OpName %SINPUT \"SINPUT\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %UINPUT Flat\n               OpDecorate %UINPUT Location 0\n               OpDecorate %SINPUT Flat\n               OpDecorate %SINPUT Location 0\n               OpDecorate %SINPUT Component 1\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %UINPUT = OpVariable %_ptr_Input_uint Input\n        %int = OpTypeInt 32 1\n%_ptr_Input_int = OpTypePointer Input %int\n     %SINPUT = OpVariable %_ptr_Input_int Input\n      %float = OpTypeFloat 32\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n       %half = OpTypeFloat 16\n     %double = OpTypeFloat 64\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %34\n\n         %34 = OpLabel\n         %15 =   OpLoad %uint %UINPUT\n         %16 =   OpLoad %int %SINPUT\n         %17 =   OpBitcast %uint %16\n         %18 =   OpConvertUToF %float %15\n         %19 =   OpConvertSToF %float %17\n         %21 =   OpConvertUToF %half %15\n         %22 =   OpFConvert %float %21\n         %23 =   OpFAdd %float %18 %22\n         %24 =   OpConvertSToF %half %17\n         %25 =   OpFConvert %float %24\n         %26 =   OpFAdd %float %19 %25\n         %28 =   OpConvertUToF %double %15\n         %29 =   OpFConvert %float %28\n         %30 =   OpFAdd %float %23 %29\n         %31 =   OpConvertSToF %double %17\n         %32 =   OpFConvert %float %31\n         %33 =   OpFAdd %float %26 %32\n                 OpStore %SV_TARGET %30\n                 OpStore %SV_TARGET_1 %33\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_i_to_f.glsl",
    "content": "GLSL:\n#version 460\n#if defined(GL_AMD_gpu_shader_half_float)\n#extension GL_AMD_gpu_shader_half_float : require\n#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)\n#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require\n#else\n#error No extension available for FP16.\n#endif\n#extension GL_EXT_shader_16bit_storage : require\n\nlayout(location = 0) flat in uint UINPUT;\nlayout(location = 0, component = 1) flat in int SINPUT;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    uint _17 = uint(SINPUT);\n    SV_TARGET = (float(UINPUT) + float(float16_t(UINPUT))) + float(double(UINPUT));\n    SV_TARGET_1 = (float(int(_17)) + float(float16_t(int(_17)))) + float(double(int(_17)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_i_to_i.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\n               OpCapability Shader\n               OpCapability Int64\n               OpCapability Int16\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %INPUT %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %INPUT \"INPUT\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %INPUT Flat\n               OpDecorate %INPUT Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %INPUT = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %ushort = OpTypeInt 16 0\n      %ulong = OpTypeInt 64 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %33\n\n         %33 = OpLabel\n         %10 =   OpLoad %uint %INPUT\n         %12 =   OpUConvert %ushort %10\n         %14 =   OpUConvert %ulong %12\n         %15 =   OpUConvert %uint %14\n         %16 =   OpUConvert %ulong %15\n         %17 =   OpUConvert %ushort %16\n         %18 =   OpUConvert %uint %17\n         %19 =   OpSConvert %ulong %18\n         %20 =   OpUConvert %ushort %19\n         %21 =   OpSConvert %ulong %20\n         %22 =   OpUConvert %uint %21\n         %23 =   OpUConvert %ushort %22\n         %24 =   OpSConvert %uint %23\n         %25 =   OpSConvert %ulong %24\n         %26 =   OpUConvert %uint %25\n         %27 =   OpUConvert %ushort %26\n         %28 =   OpUConvert %uint %27\n         %29 =   OpUConvert %ushort %28\n         %30 =   OpUConvert %ulong %29\n         %31 =   OpUConvert %ushort %30\n         %32 =   OpUConvert %uint %31\n                 OpStore %SV_TARGET %32\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_convert_i_to_i.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require\n#extension GL_EXT_shader_16bit_storage : require\n#if defined(GL_ARB_gpu_shader_int64)\n#extension GL_ARB_gpu_shader_int64 : require\n#else\n#error No extension available for 64-bit integers.\n#endif\n\nlayout(location = 0) flat in uint INPUT;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(uint16_t(uint64_t(uint16_t(uint(uint16_t(uint(uint64_t(int(uint(int16_t(uint16_t(uint(uint64_t(int16_t(uint16_t(uint64_t(int(uint(uint16_t(uint64_t(uint(uint64_t(uint16_t(INPUT))))))))))))))))))))))));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_cs_builtins.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %8 %9 %10 %SV_DispatchThreadId %SV_GroupId %SV_GroupThreadId %gl_LocalInvocationIndex\n               OpExecutionMode %main LocalSize 4 4 4\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_DispatchThreadId \"SV_DispatchThreadId\"\n               OpName %SV_GroupId \"SV_GroupId\"\n               OpName %SV_GroupThreadId \"SV_GroupThreadId\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 1\n               OpDecorate %9 NonReadable\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 2\n               OpDecorate %10 NonReadable\n               OpDecorate %SV_DispatchThreadId BuiltIn GlobalInvocationId\n               OpDecorate %SV_GroupId BuiltIn WorkgroupId\n               OpDecorate %SV_GroupThreadId BuiltIn LocalInvocationId\n               OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 3D 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n         %10 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n%SV_DispatchThreadId = OpVariable %_ptr_Input_v3uint Input\n %SV_GroupId = OpVariable %_ptr_Input_v3uint Input\n%SV_GroupThreadId = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n%gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input\n     %v4uint = OpTypeVector %uint 4\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %54\n\n         %54 = OpLabel\n         %16 =   OpLoad %6 %8\n         %17 =   OpLoad %6 %9\n         %18 =   OpLoad %6 %10\n         %21 =   OpLoad %uint %gl_LocalInvocationIndex\n         %24 =   OpAccessChain %_ptr_Input_uint %SV_DispatchThreadId %uint_0\n         %26 =   OpLoad %uint %24\n         %27 =   OpAccessChain %_ptr_Input_uint %SV_DispatchThreadId %uint_1\n         %29 =   OpLoad %uint %27\n         %30 =   OpAccessChain %_ptr_Input_uint %SV_DispatchThreadId %uint_2\n         %32 =   OpLoad %uint %30\n         %34 =   OpAccessChain %_ptr_Input_uint %SV_GroupId %uint_0\n         %35 =   OpLoad %uint %34\n         %36 =   OpAccessChain %_ptr_Input_uint %SV_GroupId %uint_1\n         %37 =   OpLoad %uint %36\n         %38 =   OpAccessChain %_ptr_Input_uint %SV_GroupId %uint_2\n         %39 =   OpLoad %uint %38\n         %41 =   OpAccessChain %_ptr_Input_uint %SV_GroupThreadId %uint_0\n         %42 =   OpLoad %uint %41\n         %43 =   OpAccessChain %_ptr_Input_uint %SV_GroupThreadId %uint_1\n         %44 =   OpLoad %uint %43\n         %45 =   OpAccessChain %_ptr_Input_uint %SV_GroupThreadId %uint_2\n         %46 =   OpLoad %uint %45\n         %48 =   OpCompositeConstruct %v3uint %26 %29 %32\n         %49 =   OpCompositeConstruct %v4uint %21 %21 %21 %21\n                 OpImageWrite %16 %48 %49 NonPrivateTexel\n         %50 =   OpCompositeConstruct %v3uint %35 %37 %39\n         %51 =   OpCompositeConstruct %v4uint %21 %21 %21 %21\n                 OpImageWrite %17 %50 %51 NonPrivateTexel\n         %52 =   OpCompositeConstruct %v3uint %42 %44 %46\n         %53 =   OpCompositeConstruct %v4uint %21 %21 %21 %21\n                 OpImageWrite %18 %52 %53 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_cs_builtins.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;\n\nlayout(set = 0, binding = 0) uniform writeonly uimage3D _8;\nlayout(set = 0, binding = 1) uniform writeonly uimage3D _9;\nlayout(set = 0, binding = 2) uniform writeonly uimage3D _10;\n\nvoid main()\n{\n    imageStore(_8, ivec3(uvec3(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, gl_GlobalInvocationID.z)), uvec4(gl_LocalInvocationIndex));\n    imageStore(_9, ivec3(uvec3(gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z)), uvec4(gl_LocalInvocationIndex));\n    imageStore(_10, ivec3(uvec3(gl_LocalInvocationID.x, gl_LocalInvocationID.y, gl_LocalInvocationID.z)), uvec4(gl_LocalInvocationIndex));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ds_isoline.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 192\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability Tessellation\n               OpCapability ClipDistance\n               OpCapability MultiViewport\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability ShaderViewportIndexLayerEXT\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_shader_viewport_index_layer\"\n               OpExtension \"SPV_KHR_float_controls\"\n        %102 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint TessellationEvaluation %main \"main\" %SV_DOMAINLOCATION %SV_POSITION %R_COLOR %G_COLOR %B_COLOR %TEXCOORD %SV_POSITION_0 %SV_RENDERTARGETARRAYINDEX %SV_VIEWPORTARRAYINDEX %COLOR %PRIMID %TEXCOORD_0 %TESS_INNER %TESS_OUTER %gl_ClipDistance %SV_INSIDETESSFACTOR %SV_TESSFACTOR %LAYER %VIEWPORT %INDEX %gl_PrimitiveID\n               OpExecutionMode %main Isolines\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_DOMAINLOCATION \"SV_DOMAINLOCATION\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %R_COLOR \"R_COLOR\"\n               OpName %G_COLOR \"G_COLOR\"\n               OpName %B_COLOR \"B_COLOR\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %SV_RENDERTARGETARRAYINDEX \"SV_RENDERTARGETARRAYINDEX\"\n               OpName %SV_VIEWPORTARRAYINDEX \"SV_VIEWPORTARRAYINDEX\"\n               OpName %COLOR \"COLOR\"\n               OpName %PRIMID \"PRIMID\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %TESS_INNER \"TESS_INNER\"\n               OpName %TESS_OUTER \"TESS_OUTER\"\n               OpName %SV_INSIDETESSFACTOR \"SV_INSIDETESSFACTOR\"\n               OpName %SV_TESSFACTOR \"SV_TESSFACTOR\"\n               OpName %LAYER \"LAYER\"\n               OpName %VIEWPORT \"VIEWPORT\"\n               OpName %INDEX \"INDEX\"\n               OpDecorate %SV_DOMAINLOCATION BuiltIn TessCoord\n               OpDecorate %SV_POSITION Location 0\n               OpDecorate %R_COLOR Location 1\n               OpDecorate %G_COLOR Location 1\n               OpDecorate %G_COLOR Component 1\n               OpDecorate %B_COLOR Location 1\n               OpDecorate %B_COLOR Component 2\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %SV_RENDERTARGETARRAYINDEX BuiltIn Layer\n               OpDecorate %SV_VIEWPORTARRAYINDEX BuiltIn ViewportIndex\n               OpDecorate %COLOR Location 6\n               OpDecorate %PRIMID Location 6\n               OpDecorate %PRIMID Component 3\n               OpDecorate %TEXCOORD_0 Location 7\n               OpDecorate %TESS_INNER Location 7\n               OpDecorate %TESS_INNER Component 2\n               OpDecorate %TESS_OUTER Location 8\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_INSIDETESSFACTOR BuiltIn TessLevelInner\n               OpDecorate %SV_INSIDETESSFACTOR Patch\n               OpDecorate %SV_TESSFACTOR BuiltIn TessLevelOuter\n               OpDecorate %SV_TESSFACTOR Patch\n               OpDecorate %LAYER Location 6\n               OpDecorate %LAYER Patch\n               OpDecorate %VIEWPORT Location 6\n               OpDecorate %VIEWPORT Component 1\n               OpDecorate %VIEWPORT Patch\n               OpDecorate %INDEX Location 6\n               OpDecorate %INDEX Component 2\n               OpDecorate %INDEX Patch\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n%SV_DOMAINLOCATION = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n    %uint_32 = OpConstant %uint 32\n%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32\n%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_32 Input\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32\n    %R_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %G_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %B_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_32 = OpTypeArray %v2float %uint_32\n%_ptr_Input__arr_v2float_uint_32 = OpTypePointer Input %_arr_v2float_uint_32\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_32 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n     %uint_8 = OpConstant %uint 8\n%_arr_float_uint_8 = OpTypeArray %float %uint_8\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_RENDERTARGETARRAYINDEX = OpVariable %_ptr_Output_uint Output\n%SV_VIEWPORTARRAYINDEX = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n      %COLOR = OpVariable %_ptr_Output_v3float Output\n     %PRIMID = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n %TESS_INNER = OpVariable %_ptr_Output_v2float Output\n %TESS_OUTER = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output__arr_float_uint_8 = OpTypePointer Output %_arr_float_uint_8\n%gl_ClipDistance = OpVariable %_ptr_Output__arr_float_uint_8 Output\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Input__arr_float_uint_2 = OpTypePointer Input %_arr_float_uint_2\n%SV_INSIDETESSFACTOR = OpVariable %_ptr_Input__arr_float_uint_2 Input\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n%_ptr_Input__arr_float_uint_4 = OpTypePointer Input %_arr_float_uint_4\n%SV_TESSFACTOR = OpVariable %_ptr_Input__arr_float_uint_4 Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %LAYER = OpVariable %_ptr_Input_uint Input\n   %VIEWPORT = OpVariable %_ptr_Input_uint Input\n      %INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %190\n\n        %190 = OpLabel\n         %53 =   OpAccessChain %_ptr_Input_float %SV_INSIDETESSFACTOR %uint_0\n         %55 =   OpLoad %float %53\n         %57 =   OpAccessChain %_ptr_Output_float %TESS_INNER %uint_0\n                 OpStore %57 %55\n         %58 =   OpAccessChain %_ptr_Input_float %SV_INSIDETESSFACTOR %uint_1\n         %60 =   OpLoad %float %58\n         %61 =   OpAccessChain %_ptr_Output_float %TESS_INNER %uint_1\n                 OpStore %61 %60\n         %62 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_0\n         %63 =   OpLoad %float %62\n         %64 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_0\n                 OpStore %64 %63\n         %65 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_1\n         %66 =   OpLoad %float %65\n         %67 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_1\n                 OpStore %67 %66\n         %68 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_2\n         %69 =   OpLoad %float %68\n         %70 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_2\n                 OpStore %70 %69\n         %71 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_3\n         %73 =   OpLoad %float %71\n         %74 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_3\n                 OpStore %74 %73\n         %75 =   OpLoad %uint %LAYER\n                 OpStore %SV_RENDERTARGETARRAYINDEX %75\n         %76 =   OpLoad %uint %VIEWPORT\n                 OpStore %SV_VIEWPORTARRAYINDEX %76\n         %78 =   OpLoad %uint %gl_PrimitiveID\n                 OpStore %PRIMID %78\n         %79 =   OpLoad %uint %INDEX\n         %80 =   OpAccessChain %_ptr_Input_float %SV_DOMAINLOCATION %uint_0\n         %81 =   OpLoad %float %80\n         %82 =   OpAccessChain %_ptr_Input_float %SV_DOMAINLOCATION %uint_1\n         %83 =   OpLoad %float %82\n         %86 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_0\n         %87 =   OpLoad %float %86\n         %88 =   OpBitwiseXor %uint %79 %uint_1\n         %90 =   OpAccessChain %_ptr_Input_float %SV_POSITION %88 %uint_0\n         %91 =   OpLoad %float %90\n         %92 =   OpBitwiseXor %uint %79 %uint_2\n         %94 =   OpAccessChain %_ptr_Input_float %SV_POSITION %92 %uint_0\n         %95 =   OpLoad %float %94\n         %96 =   OpBitwiseXor %uint %79 %uint_3\n         %98 =   OpAccessChain %_ptr_Input_float %SV_POSITION %96 %uint_0\n         %99 =   OpLoad %float %98\n        %100 =   OpFSub %float %91 %87\n        %101 =   OpFSub %float %99 %95\n        %103 =   OpExtInst %float %102 Fma %81 %100 %87\n        %104 =   OpExtInst %float %102 Fma %81 %101 %95\n        %105 =   OpFSub %float %104 %103\n        %106 =   OpExtInst %float %102 Fma %83 %105 %103\n        %108 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_1\n        %109 =   OpLoad %float %108\n        %110 =   OpBitwiseXor %uint %79 %uint_1\n        %112 =   OpAccessChain %_ptr_Input_float %SV_POSITION %110 %uint_1\n        %113 =   OpLoad %float %112\n        %114 =   OpBitwiseXor %uint %79 %uint_2\n        %116 =   OpAccessChain %_ptr_Input_float %SV_POSITION %114 %uint_1\n        %117 =   OpLoad %float %116\n        %118 =   OpBitwiseXor %uint %79 %uint_3\n        %120 =   OpAccessChain %_ptr_Input_float %SV_POSITION %118 %uint_1\n        %121 =   OpLoad %float %120\n        %122 =   OpFSub %float %113 %109\n        %123 =   OpFSub %float %121 %117\n        %124 =   OpExtInst %float %102 Fma %81 %122 %109\n        %125 =   OpExtInst %float %102 Fma %81 %123 %117\n        %126 =   OpFSub %float %125 %124\n        %127 =   OpExtInst %float %102 Fma %83 %126 %124\n        %129 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_2\n        %130 =   OpLoad %float %129\n        %131 =   OpBitwiseXor %uint %79 %uint_1\n        %133 =   OpAccessChain %_ptr_Input_float %SV_POSITION %131 %uint_2\n        %134 =   OpLoad %float %133\n        %135 =   OpBitwiseXor %uint %79 %uint_2\n        %137 =   OpAccessChain %_ptr_Input_float %SV_POSITION %135 %uint_2\n        %138 =   OpLoad %float %137\n        %139 =   OpBitwiseXor %uint %79 %uint_3\n        %141 =   OpAccessChain %_ptr_Input_float %SV_POSITION %139 %uint_2\n        %142 =   OpLoad %float %141\n        %143 =   OpFSub %float %134 %130\n        %144 =   OpFSub %float %142 %138\n        %145 =   OpExtInst %float %102 Fma %81 %143 %130\n        %146 =   OpExtInst %float %102 Fma %81 %144 %138\n        %147 =   OpFSub %float %146 %145\n        %148 =   OpExtInst %float %102 Fma %83 %147 %145\n        %150 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_3\n        %151 =   OpLoad %float %150\n        %152 =   OpBitwiseXor %uint %79 %uint_1\n        %154 =   OpAccessChain %_ptr_Input_float %SV_POSITION %152 %uint_3\n        %155 =   OpLoad %float %154\n        %156 =   OpBitwiseXor %uint %79 %uint_2\n        %158 =   OpAccessChain %_ptr_Input_float %SV_POSITION %156 %uint_3\n        %159 =   OpLoad %float %158\n        %160 =   OpBitwiseXor %uint %79 %uint_3\n        %162 =   OpAccessChain %_ptr_Input_float %SV_POSITION %160 %uint_3\n        %163 =   OpLoad %float %162\n        %164 =   OpFSub %float %155 %151\n        %165 =   OpFSub %float %163 %159\n        %166 =   OpExtInst %float %102 Fma %81 %164 %151\n        %167 =   OpExtInst %float %102 Fma %81 %165 %159\n        %168 =   OpFSub %float %167 %166\n        %169 =   OpExtInst %float %102 Fma %83 %168 %166\n        %170 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                 OpStore %170 %106\n        %171 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                 OpStore %171 %127\n        %172 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                 OpStore %172 %148\n        %173 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                 OpStore %173 %169\n        %174 =   OpAccessChain %_ptr_Input_float %R_COLOR %uint_0\n        %175 =   OpLoad %float %174\n        %176 =   OpAccessChain %_ptr_Output_float %COLOR %uint_0\n                 OpStore %176 %175\n        %177 =   OpAccessChain %_ptr_Input_float %G_COLOR %uint_1\n        %178 =   OpLoad %float %177\n        %179 =   OpAccessChain %_ptr_Output_float %COLOR %uint_1\n                 OpStore %179 %178\n        %180 =   OpAccessChain %_ptr_Input_float %B_COLOR %uint_2\n        %181 =   OpLoad %float %180\n        %182 =   OpAccessChain %_ptr_Output_float %COLOR %uint_2\n                 OpStore %182 %181\n        %183 =   OpAccessChain %_ptr_Input_float %TEXCOORD %79 %uint_0\n        %184 =   OpLoad %float %183\n        %185 =   OpAccessChain %_ptr_Input_float %TEXCOORD %79 %uint_1\n        %186 =   OpLoad %float %185\n        %188 =   OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                 OpStore %188 %184\n        %189 =   OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                 OpStore %189 %186\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ds_isoline.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\nlayout(isolines) in;\n\nlayout(location = 0) in vec4 SV_POSITION[];\nlayout(location = 1) in float R_COLOR[];\nlayout(location = 1, component = 1) in float G_COLOR[];\nlayout(location = 1, component = 2) in float B_COLOR[];\nlayout(location = 2) in vec2 TEXCOORD[];\nlayout(location = 6) out vec3 COLOR;\nlayout(location = 6, component = 3) out uint PRIMID;\nlayout(location = 7) out vec2 TEXCOORD_1;\nlayout(location = 7, component = 2) out vec2 TESS_INNER;\nlayout(location = 8) out vec4 TESS_OUTER;\nlayout(location = 6) patch in uint LAYER;\nlayout(location = 6, component = 1) patch in uint VIEWPORT;\nlayout(location = 6, component = 2) patch in uint INDEX;\n\nvoid main()\n{\n    TESS_INNER.x = gl_TessLevelInner[0u];\n    TESS_INNER.y = gl_TessLevelInner[1u];\n    TESS_OUTER.x = gl_TessLevelOuter[0u];\n    TESS_OUTER.y = gl_TessLevelOuter[1u];\n    TESS_OUTER.z = gl_TessLevelOuter[2u];\n    TESS_OUTER.w = gl_TessLevelOuter[3u];\n    gl_Layer = int(LAYER);\n    gl_ViewportIndex = int(VIEWPORT);\n    PRIMID = uint(gl_PrimitiveID);\n    uint _92 = INDEX ^ 2u;\n    float _103 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].x - SV_POSITION[INDEX].x, SV_POSITION[INDEX].x);\n    uint _114 = INDEX ^ 2u;\n    float _124 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].y - SV_POSITION[INDEX].y, SV_POSITION[INDEX].y);\n    uint _135 = INDEX ^ 2u;\n    float _145 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].z - SV_POSITION[INDEX].z, SV_POSITION[INDEX].z);\n    uint _156 = INDEX ^ 2u;\n    float _166 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].w - SV_POSITION[INDEX].w, SV_POSITION[INDEX].w);\n    gl_Position.x = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].x - SV_POSITION[_92].x, SV_POSITION[_92].x) - _103, _103);\n    gl_Position.y = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].y - SV_POSITION[_114].y, SV_POSITION[_114].y) - _124, _124);\n    gl_Position.z = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].z - SV_POSITION[_135].z, SV_POSITION[_135].z) - _145, _145);\n    gl_Position.w = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].w - SV_POSITION[_156].w, SV_POSITION[_156].w) - _166, _166);\n    COLOR.x = R_COLOR[0u];\n    COLOR.y = G_COLOR[1u];\n    COLOR.z = B_COLOR[2u];\n    TEXCOORD_1.x = TEXCOORD[INDEX].x;\n    TEXCOORD_1.y = TEXCOORD[INDEX].y;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ds_quad.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 192\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability Tessellation\n               OpCapability ClipDistance\n               OpCapability MultiViewport\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability ShaderViewportIndexLayerEXT\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_shader_viewport_index_layer\"\n               OpExtension \"SPV_KHR_float_controls\"\n        %102 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint TessellationEvaluation %main \"main\" %SV_DOMAINLOCATION %SV_POSITION %R_COLOR %G_COLOR %B_COLOR %TEXCOORD %SV_POSITION_0 %SV_RENDERTARGETARRAYINDEX %SV_VIEWPORTARRAYINDEX %COLOR %PRIMID %TEXCOORD_0 %TESS_INNER %TESS_OUTER %gl_ClipDistance %SV_INSIDETESSFACTOR %SV_TESSFACTOR %LAYER %VIEWPORT %INDEX %gl_PrimitiveID\n               OpExecutionMode %main Quads\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_DOMAINLOCATION \"SV_DOMAINLOCATION\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %R_COLOR \"R_COLOR\"\n               OpName %G_COLOR \"G_COLOR\"\n               OpName %B_COLOR \"B_COLOR\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %SV_RENDERTARGETARRAYINDEX \"SV_RENDERTARGETARRAYINDEX\"\n               OpName %SV_VIEWPORTARRAYINDEX \"SV_VIEWPORTARRAYINDEX\"\n               OpName %COLOR \"COLOR\"\n               OpName %PRIMID \"PRIMID\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %TESS_INNER \"TESS_INNER\"\n               OpName %TESS_OUTER \"TESS_OUTER\"\n               OpName %SV_INSIDETESSFACTOR \"SV_INSIDETESSFACTOR\"\n               OpName %SV_TESSFACTOR \"SV_TESSFACTOR\"\n               OpName %LAYER \"LAYER\"\n               OpName %VIEWPORT \"VIEWPORT\"\n               OpName %INDEX \"INDEX\"\n               OpDecorate %SV_DOMAINLOCATION BuiltIn TessCoord\n               OpDecorate %SV_POSITION Location 0\n               OpDecorate %R_COLOR Location 1\n               OpDecorate %G_COLOR Location 1\n               OpDecorate %G_COLOR Component 1\n               OpDecorate %B_COLOR Location 1\n               OpDecorate %B_COLOR Component 2\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %SV_RENDERTARGETARRAYINDEX BuiltIn Layer\n               OpDecorate %SV_VIEWPORTARRAYINDEX BuiltIn ViewportIndex\n               OpDecorate %COLOR Location 6\n               OpDecorate %PRIMID Location 6\n               OpDecorate %PRIMID Component 3\n               OpDecorate %TEXCOORD_0 Location 7\n               OpDecorate %TESS_INNER Location 7\n               OpDecorate %TESS_INNER Component 2\n               OpDecorate %TESS_OUTER Location 8\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_INSIDETESSFACTOR BuiltIn TessLevelInner\n               OpDecorate %SV_INSIDETESSFACTOR Patch\n               OpDecorate %SV_TESSFACTOR BuiltIn TessLevelOuter\n               OpDecorate %SV_TESSFACTOR Patch\n               OpDecorate %LAYER Location 6\n               OpDecorate %LAYER Patch\n               OpDecorate %VIEWPORT Location 6\n               OpDecorate %VIEWPORT Component 1\n               OpDecorate %VIEWPORT Patch\n               OpDecorate %INDEX Location 6\n               OpDecorate %INDEX Component 2\n               OpDecorate %INDEX Patch\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n%SV_DOMAINLOCATION = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n    %uint_32 = OpConstant %uint 32\n%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32\n%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_32 Input\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32\n    %R_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %G_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %B_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_32 = OpTypeArray %v2float %uint_32\n%_ptr_Input__arr_v2float_uint_32 = OpTypePointer Input %_arr_v2float_uint_32\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_32 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n     %uint_8 = OpConstant %uint 8\n%_arr_float_uint_8 = OpTypeArray %float %uint_8\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_RENDERTARGETARRAYINDEX = OpVariable %_ptr_Output_uint Output\n%SV_VIEWPORTARRAYINDEX = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n      %COLOR = OpVariable %_ptr_Output_v3float Output\n     %PRIMID = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n %TESS_INNER = OpVariable %_ptr_Output_v2float Output\n %TESS_OUTER = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output__arr_float_uint_8 = OpTypePointer Output %_arr_float_uint_8\n%gl_ClipDistance = OpVariable %_ptr_Output__arr_float_uint_8 Output\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Input__arr_float_uint_2 = OpTypePointer Input %_arr_float_uint_2\n%SV_INSIDETESSFACTOR = OpVariable %_ptr_Input__arr_float_uint_2 Input\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n%_ptr_Input__arr_float_uint_4 = OpTypePointer Input %_arr_float_uint_4\n%SV_TESSFACTOR = OpVariable %_ptr_Input__arr_float_uint_4 Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %LAYER = OpVariable %_ptr_Input_uint Input\n   %VIEWPORT = OpVariable %_ptr_Input_uint Input\n      %INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %190\n\n        %190 = OpLabel\n         %53 =   OpAccessChain %_ptr_Input_float %SV_INSIDETESSFACTOR %uint_0\n         %55 =   OpLoad %float %53\n         %57 =   OpAccessChain %_ptr_Output_float %TESS_INNER %uint_0\n                 OpStore %57 %55\n         %58 =   OpAccessChain %_ptr_Input_float %SV_INSIDETESSFACTOR %uint_1\n         %60 =   OpLoad %float %58\n         %61 =   OpAccessChain %_ptr_Output_float %TESS_INNER %uint_1\n                 OpStore %61 %60\n         %62 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_0\n         %63 =   OpLoad %float %62\n         %64 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_0\n                 OpStore %64 %63\n         %65 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_1\n         %66 =   OpLoad %float %65\n         %67 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_1\n                 OpStore %67 %66\n         %68 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_2\n         %69 =   OpLoad %float %68\n         %70 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_2\n                 OpStore %70 %69\n         %71 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_3\n         %73 =   OpLoad %float %71\n         %74 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_3\n                 OpStore %74 %73\n         %75 =   OpLoad %uint %LAYER\n                 OpStore %SV_RENDERTARGETARRAYINDEX %75\n         %76 =   OpLoad %uint %VIEWPORT\n                 OpStore %SV_VIEWPORTARRAYINDEX %76\n         %78 =   OpLoad %uint %gl_PrimitiveID\n                 OpStore %PRIMID %78\n         %79 =   OpLoad %uint %INDEX\n         %80 =   OpAccessChain %_ptr_Input_float %SV_DOMAINLOCATION %uint_0\n         %81 =   OpLoad %float %80\n         %82 =   OpAccessChain %_ptr_Input_float %SV_DOMAINLOCATION %uint_1\n         %83 =   OpLoad %float %82\n         %86 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_0\n         %87 =   OpLoad %float %86\n         %88 =   OpBitwiseXor %uint %79 %uint_1\n         %90 =   OpAccessChain %_ptr_Input_float %SV_POSITION %88 %uint_0\n         %91 =   OpLoad %float %90\n         %92 =   OpBitwiseXor %uint %79 %uint_2\n         %94 =   OpAccessChain %_ptr_Input_float %SV_POSITION %92 %uint_0\n         %95 =   OpLoad %float %94\n         %96 =   OpBitwiseXor %uint %79 %uint_3\n         %98 =   OpAccessChain %_ptr_Input_float %SV_POSITION %96 %uint_0\n         %99 =   OpLoad %float %98\n        %100 =   OpFSub %float %91 %87\n        %101 =   OpFSub %float %99 %95\n        %103 =   OpExtInst %float %102 Fma %81 %100 %87\n        %104 =   OpExtInst %float %102 Fma %81 %101 %95\n        %105 =   OpFSub %float %104 %103\n        %106 =   OpExtInst %float %102 Fma %83 %105 %103\n        %108 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_1\n        %109 =   OpLoad %float %108\n        %110 =   OpBitwiseXor %uint %79 %uint_1\n        %112 =   OpAccessChain %_ptr_Input_float %SV_POSITION %110 %uint_1\n        %113 =   OpLoad %float %112\n        %114 =   OpBitwiseXor %uint %79 %uint_2\n        %116 =   OpAccessChain %_ptr_Input_float %SV_POSITION %114 %uint_1\n        %117 =   OpLoad %float %116\n        %118 =   OpBitwiseXor %uint %79 %uint_3\n        %120 =   OpAccessChain %_ptr_Input_float %SV_POSITION %118 %uint_1\n        %121 =   OpLoad %float %120\n        %122 =   OpFSub %float %113 %109\n        %123 =   OpFSub %float %121 %117\n        %124 =   OpExtInst %float %102 Fma %81 %122 %109\n        %125 =   OpExtInst %float %102 Fma %81 %123 %117\n        %126 =   OpFSub %float %125 %124\n        %127 =   OpExtInst %float %102 Fma %83 %126 %124\n        %129 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_2\n        %130 =   OpLoad %float %129\n        %131 =   OpBitwiseXor %uint %79 %uint_1\n        %133 =   OpAccessChain %_ptr_Input_float %SV_POSITION %131 %uint_2\n        %134 =   OpLoad %float %133\n        %135 =   OpBitwiseXor %uint %79 %uint_2\n        %137 =   OpAccessChain %_ptr_Input_float %SV_POSITION %135 %uint_2\n        %138 =   OpLoad %float %137\n        %139 =   OpBitwiseXor %uint %79 %uint_3\n        %141 =   OpAccessChain %_ptr_Input_float %SV_POSITION %139 %uint_2\n        %142 =   OpLoad %float %141\n        %143 =   OpFSub %float %134 %130\n        %144 =   OpFSub %float %142 %138\n        %145 =   OpExtInst %float %102 Fma %81 %143 %130\n        %146 =   OpExtInst %float %102 Fma %81 %144 %138\n        %147 =   OpFSub %float %146 %145\n        %148 =   OpExtInst %float %102 Fma %83 %147 %145\n        %150 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_3\n        %151 =   OpLoad %float %150\n        %152 =   OpBitwiseXor %uint %79 %uint_1\n        %154 =   OpAccessChain %_ptr_Input_float %SV_POSITION %152 %uint_3\n        %155 =   OpLoad %float %154\n        %156 =   OpBitwiseXor %uint %79 %uint_2\n        %158 =   OpAccessChain %_ptr_Input_float %SV_POSITION %156 %uint_3\n        %159 =   OpLoad %float %158\n        %160 =   OpBitwiseXor %uint %79 %uint_3\n        %162 =   OpAccessChain %_ptr_Input_float %SV_POSITION %160 %uint_3\n        %163 =   OpLoad %float %162\n        %164 =   OpFSub %float %155 %151\n        %165 =   OpFSub %float %163 %159\n        %166 =   OpExtInst %float %102 Fma %81 %164 %151\n        %167 =   OpExtInst %float %102 Fma %81 %165 %159\n        %168 =   OpFSub %float %167 %166\n        %169 =   OpExtInst %float %102 Fma %83 %168 %166\n        %170 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                 OpStore %170 %106\n        %171 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                 OpStore %171 %127\n        %172 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                 OpStore %172 %148\n        %173 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                 OpStore %173 %169\n        %174 =   OpAccessChain %_ptr_Input_float %R_COLOR %uint_0\n        %175 =   OpLoad %float %174\n        %176 =   OpAccessChain %_ptr_Output_float %COLOR %uint_0\n                 OpStore %176 %175\n        %177 =   OpAccessChain %_ptr_Input_float %G_COLOR %uint_1\n        %178 =   OpLoad %float %177\n        %179 =   OpAccessChain %_ptr_Output_float %COLOR %uint_1\n                 OpStore %179 %178\n        %180 =   OpAccessChain %_ptr_Input_float %B_COLOR %uint_2\n        %181 =   OpLoad %float %180\n        %182 =   OpAccessChain %_ptr_Output_float %COLOR %uint_2\n                 OpStore %182 %181\n        %183 =   OpAccessChain %_ptr_Input_float %TEXCOORD %79 %uint_0\n        %184 =   OpLoad %float %183\n        %185 =   OpAccessChain %_ptr_Input_float %TEXCOORD %79 %uint_1\n        %186 =   OpLoad %float %185\n        %188 =   OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                 OpStore %188 %184\n        %189 =   OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                 OpStore %189 %186\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ds_quad.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\nlayout(quads) in;\n\nlayout(location = 0) in vec4 SV_POSITION[];\nlayout(location = 1) in float R_COLOR[];\nlayout(location = 1, component = 1) in float G_COLOR[];\nlayout(location = 1, component = 2) in float B_COLOR[];\nlayout(location = 2) in vec2 TEXCOORD[];\nlayout(location = 6) out vec3 COLOR;\nlayout(location = 6, component = 3) out uint PRIMID;\nlayout(location = 7) out vec2 TEXCOORD_1;\nlayout(location = 7, component = 2) out vec2 TESS_INNER;\nlayout(location = 8) out vec4 TESS_OUTER;\nlayout(location = 6) patch in uint LAYER;\nlayout(location = 6, component = 1) patch in uint VIEWPORT;\nlayout(location = 6, component = 2) patch in uint INDEX;\n\nvoid main()\n{\n    TESS_INNER.x = gl_TessLevelInner[0u];\n    TESS_INNER.y = gl_TessLevelInner[1u];\n    TESS_OUTER.x = gl_TessLevelOuter[0u];\n    TESS_OUTER.y = gl_TessLevelOuter[1u];\n    TESS_OUTER.z = gl_TessLevelOuter[2u];\n    TESS_OUTER.w = gl_TessLevelOuter[3u];\n    gl_Layer = int(LAYER);\n    gl_ViewportIndex = int(VIEWPORT);\n    PRIMID = uint(gl_PrimitiveID);\n    uint _92 = INDEX ^ 2u;\n    float _103 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].x - SV_POSITION[INDEX].x, SV_POSITION[INDEX].x);\n    uint _114 = INDEX ^ 2u;\n    float _124 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].y - SV_POSITION[INDEX].y, SV_POSITION[INDEX].y);\n    uint _135 = INDEX ^ 2u;\n    float _145 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].z - SV_POSITION[INDEX].z, SV_POSITION[INDEX].z);\n    uint _156 = INDEX ^ 2u;\n    float _166 = fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 1u].w - SV_POSITION[INDEX].w, SV_POSITION[INDEX].w);\n    gl_Position.x = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].x - SV_POSITION[_92].x, SV_POSITION[_92].x) - _103, _103);\n    gl_Position.y = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].y - SV_POSITION[_114].y, SV_POSITION[_114].y) - _124, _124);\n    gl_Position.z = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].z - SV_POSITION[_135].z, SV_POSITION[_135].z) - _145, _145);\n    gl_Position.w = fma(gl_TessCoord.y, fma(gl_TessCoord.x, SV_POSITION[INDEX ^ 3u].w - SV_POSITION[_156].w, SV_POSITION[_156].w) - _166, _166);\n    COLOR.x = R_COLOR[0u];\n    COLOR.y = G_COLOR[1u];\n    COLOR.z = B_COLOR[2u];\n    TEXCOORD_1.x = TEXCOORD[INDEX].x;\n    TEXCOORD_1.y = TEXCOORD[INDEX].y;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ds_triangle.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 160\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability Tessellation\n               OpCapability ClipDistance\n               OpCapability MultiViewport\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability ShaderViewportIndexLayerEXT\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_shader_viewport_index_layer\"\n               OpExtension \"SPV_KHR_float_controls\"\n        %107 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint TessellationEvaluation %main \"main\" %SV_DOMAINLOCATION %SV_POSITION %R_COLOR %G_COLOR %B_COLOR %TEXCOORD %SV_POSITION_0 %SV_RENDERTARGETARRAYINDEX %SV_VIEWPORTARRAYINDEX %COLOR %PRIMID %TEXCOORD_0 %TESS_INNER %TESS_OUTER %gl_ClipDistance %SV_INSIDETESSFACTOR %SV_TESSFACTOR %LAYER %VIEWPORT %INDEX %gl_PrimitiveID\n               OpExecutionMode %main Triangles\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_DOMAINLOCATION \"SV_DOMAINLOCATION\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %R_COLOR \"R_COLOR\"\n               OpName %G_COLOR \"G_COLOR\"\n               OpName %B_COLOR \"B_COLOR\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %SV_RENDERTARGETARRAYINDEX \"SV_RENDERTARGETARRAYINDEX\"\n               OpName %SV_VIEWPORTARRAYINDEX \"SV_VIEWPORTARRAYINDEX\"\n               OpName %COLOR \"COLOR\"\n               OpName %PRIMID \"PRIMID\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %TESS_INNER \"TESS_INNER\"\n               OpName %TESS_OUTER \"TESS_OUTER\"\n               OpName %SV_INSIDETESSFACTOR \"SV_INSIDETESSFACTOR\"\n               OpName %SV_TESSFACTOR \"SV_TESSFACTOR\"\n               OpName %LAYER \"LAYER\"\n               OpName %VIEWPORT \"VIEWPORT\"\n               OpName %INDEX \"INDEX\"\n               OpDecorate %SV_DOMAINLOCATION BuiltIn TessCoord\n               OpDecorate %SV_POSITION Location 0\n               OpDecorate %R_COLOR Location 1\n               OpDecorate %G_COLOR Location 1\n               OpDecorate %G_COLOR Component 1\n               OpDecorate %B_COLOR Location 1\n               OpDecorate %B_COLOR Component 2\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %SV_RENDERTARGETARRAYINDEX BuiltIn Layer\n               OpDecorate %SV_VIEWPORTARRAYINDEX BuiltIn ViewportIndex\n               OpDecorate %COLOR Location 6\n               OpDecorate %PRIMID Location 6\n               OpDecorate %PRIMID Component 3\n               OpDecorate %TEXCOORD_0 Location 7\n               OpDecorate %TESS_INNER Location 7\n               OpDecorate %TESS_INNER Component 2\n               OpDecorate %TESS_OUTER Location 8\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_INSIDETESSFACTOR BuiltIn TessLevelInner\n               OpDecorate %SV_INSIDETESSFACTOR Patch\n               OpDecorate %SV_TESSFACTOR BuiltIn TessLevelOuter\n               OpDecorate %SV_TESSFACTOR Patch\n               OpDecorate %LAYER Location 6\n               OpDecorate %LAYER Patch\n               OpDecorate %VIEWPORT Location 6\n               OpDecorate %VIEWPORT Component 1\n               OpDecorate %VIEWPORT Patch\n               OpDecorate %INDEX Location 6\n               OpDecorate %INDEX Component 2\n               OpDecorate %INDEX Patch\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n%SV_DOMAINLOCATION = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n    %uint_32 = OpConstant %uint 32\n%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32\n%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_32 Input\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32\n    %R_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %G_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %B_COLOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_32 = OpTypeArray %v2float %uint_32\n%_ptr_Input__arr_v2float_uint_32 = OpTypePointer Input %_arr_v2float_uint_32\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_32 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n     %uint_8 = OpConstant %uint 8\n%_arr_float_uint_8 = OpTypeArray %float %uint_8\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_RENDERTARGETARRAYINDEX = OpVariable %_ptr_Output_uint Output\n%SV_VIEWPORTARRAYINDEX = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n      %COLOR = OpVariable %_ptr_Output_v3float Output\n     %PRIMID = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n %TESS_INNER = OpVariable %_ptr_Output_v2float Output\n %TESS_OUTER = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output__arr_float_uint_8 = OpTypePointer Output %_arr_float_uint_8\n%gl_ClipDistance = OpVariable %_ptr_Output__arr_float_uint_8 Output\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Input__arr_float_uint_2 = OpTypePointer Input %_arr_float_uint_2\n%SV_INSIDETESSFACTOR = OpVariable %_ptr_Input__arr_float_uint_2 Input\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n%_ptr_Input__arr_float_uint_4 = OpTypePointer Input %_arr_float_uint_4\n%SV_TESSFACTOR = OpVariable %_ptr_Input__arr_float_uint_4 Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %LAYER = OpVariable %_ptr_Input_uint Input\n   %VIEWPORT = OpVariable %_ptr_Input_uint Input\n      %INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %158\n\n        %158 = OpLabel\n         %53 =   OpAccessChain %_ptr_Input_float %SV_INSIDETESSFACTOR %uint_0\n         %55 =   OpLoad %float %53\n         %57 =   OpAccessChain %_ptr_Output_float %TESS_INNER %uint_0\n                 OpStore %57 %55\n         %58 =   OpAccessChain %_ptr_Input_float %SV_INSIDETESSFACTOR %uint_1\n         %60 =   OpLoad %float %58\n         %61 =   OpAccessChain %_ptr_Output_float %TESS_INNER %uint_1\n                 OpStore %61 %60\n         %62 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_0\n         %63 =   OpLoad %float %62\n         %64 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_0\n                 OpStore %64 %63\n         %65 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_1\n         %66 =   OpLoad %float %65\n         %67 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_1\n                 OpStore %67 %66\n         %68 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_2\n         %69 =   OpLoad %float %68\n         %70 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_2\n                 OpStore %70 %69\n         %71 =   OpAccessChain %_ptr_Input_float %SV_TESSFACTOR %uint_3\n         %73 =   OpLoad %float %71\n         %74 =   OpAccessChain %_ptr_Output_float %TESS_OUTER %uint_3\n                 OpStore %74 %73\n         %75 =   OpLoad %uint %LAYER\n                 OpStore %SV_RENDERTARGETARRAYINDEX %75\n         %76 =   OpLoad %uint %VIEWPORT\n                 OpStore %SV_VIEWPORTARRAYINDEX %76\n         %78 =   OpLoad %uint %gl_PrimitiveID\n                 OpStore %PRIMID %78\n         %79 =   OpLoad %uint %INDEX\n         %80 =   OpAccessChain %_ptr_Input_float %SV_DOMAINLOCATION %uint_0\n         %81 =   OpLoad %float %80\n         %82 =   OpAccessChain %_ptr_Input_float %SV_DOMAINLOCATION %uint_1\n         %83 =   OpLoad %float %82\n         %84 =   OpAccessChain %_ptr_Input_float %SV_DOMAINLOCATION %uint_2\n         %85 =   OpLoad %float %84\n         %88 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_0\n         %89 =   OpLoad %float %88\n         %90 =   OpFMul %float %89 %81\n         %92 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_1\n         %93 =   OpLoad %float %92\n         %94 =   OpFMul %float %93 %81\n         %96 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_2\n         %97 =   OpLoad %float %96\n         %98 =   OpFMul %float %97 %81\n        %100 =   OpAccessChain %_ptr_Input_float %SV_POSITION %79 %uint_3\n        %101 =   OpLoad %float %100\n        %102 =   OpFMul %float %101 %81\n        %103 =   OpBitwiseXor %uint %79 %uint_1\n        %105 =   OpAccessChain %_ptr_Input_float %SV_POSITION %103 %uint_0\n        %106 =   OpLoad %float %105\n        %108 =   OpExtInst %float %107 Fma %106 %83 %90\n        %110 =   OpAccessChain %_ptr_Input_float %SV_POSITION %103 %uint_1\n        %111 =   OpLoad %float %110\n        %112 =   OpExtInst %float %107 Fma %111 %83 %94\n        %114 =   OpAccessChain %_ptr_Input_float %SV_POSITION %103 %uint_2\n        %115 =   OpLoad %float %114\n        %116 =   OpExtInst %float %107 Fma %115 %83 %98\n        %118 =   OpAccessChain %_ptr_Input_float %SV_POSITION %103 %uint_3\n        %119 =   OpLoad %float %118\n        %120 =   OpExtInst %float %107 Fma %119 %83 %102\n        %121 =   OpBitwiseXor %uint %79 %uint_2\n        %123 =   OpAccessChain %_ptr_Input_float %SV_POSITION %121 %uint_0\n        %124 =   OpLoad %float %123\n        %125 =   OpExtInst %float %107 Fma %124 %85 %108\n        %127 =   OpAccessChain %_ptr_Input_float %SV_POSITION %121 %uint_1\n        %128 =   OpLoad %float %127\n        %129 =   OpExtInst %float %107 Fma %128 %85 %112\n        %131 =   OpAccessChain %_ptr_Input_float %SV_POSITION %121 %uint_2\n        %132 =   OpLoad %float %131\n        %133 =   OpExtInst %float %107 Fma %132 %85 %116\n        %135 =   OpAccessChain %_ptr_Input_float %SV_POSITION %121 %uint_3\n        %136 =   OpLoad %float %135\n        %137 =   OpExtInst %float %107 Fma %136 %85 %120\n        %138 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                 OpStore %138 %125\n        %139 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                 OpStore %139 %129\n        %140 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                 OpStore %140 %133\n        %141 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                 OpStore %141 %137\n        %142 =   OpAccessChain %_ptr_Input_float %R_COLOR %uint_0\n        %143 =   OpLoad %float %142\n        %144 =   OpAccessChain %_ptr_Output_float %COLOR %uint_0\n                 OpStore %144 %143\n        %145 =   OpAccessChain %_ptr_Input_float %G_COLOR %uint_1\n        %146 =   OpLoad %float %145\n        %147 =   OpAccessChain %_ptr_Output_float %COLOR %uint_1\n                 OpStore %147 %146\n        %148 =   OpAccessChain %_ptr_Input_float %B_COLOR %uint_2\n        %149 =   OpLoad %float %148\n        %150 =   OpAccessChain %_ptr_Output_float %COLOR %uint_2\n                 OpStore %150 %149\n        %151 =   OpAccessChain %_ptr_Input_float %TEXCOORD %79 %uint_0\n        %152 =   OpLoad %float %151\n        %153 =   OpAccessChain %_ptr_Input_float %TEXCOORD %79 %uint_1\n        %154 =   OpLoad %float %153\n        %156 =   OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                 OpStore %156 %152\n        %157 =   OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                 OpStore %157 %154\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ds_triangle.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\nlayout(triangles) in;\n\nlayout(location = 0) in vec4 SV_POSITION[];\nlayout(location = 1) in float R_COLOR[];\nlayout(location = 1, component = 1) in float G_COLOR[];\nlayout(location = 1, component = 2) in float B_COLOR[];\nlayout(location = 2) in vec2 TEXCOORD[];\nlayout(location = 6) out vec3 COLOR;\nlayout(location = 6, component = 3) out uint PRIMID;\nlayout(location = 7) out vec2 TEXCOORD_1;\nlayout(location = 7, component = 2) out vec2 TESS_INNER;\nlayout(location = 8) out vec4 TESS_OUTER;\nlayout(location = 6) patch in uint LAYER;\nlayout(location = 6, component = 1) patch in uint VIEWPORT;\nlayout(location = 6, component = 2) patch in uint INDEX;\n\nvoid main()\n{\n    TESS_INNER.x = gl_TessLevelInner[0u];\n    TESS_INNER.y = gl_TessLevelInner[1u];\n    TESS_OUTER.x = gl_TessLevelOuter[0u];\n    TESS_OUTER.y = gl_TessLevelOuter[1u];\n    TESS_OUTER.z = gl_TessLevelOuter[2u];\n    TESS_OUTER.w = gl_TessLevelOuter[3u];\n    gl_Layer = int(LAYER);\n    gl_ViewportIndex = int(VIEWPORT);\n    PRIMID = uint(gl_PrimitiveID);\n    uint _103 = INDEX ^ 1u;\n    uint _121 = INDEX ^ 2u;\n    gl_Position.x = fma(SV_POSITION[_121].x, gl_TessCoord.z, fma(SV_POSITION[_103].x, gl_TessCoord.y, SV_POSITION[INDEX].x * gl_TessCoord.x));\n    gl_Position.y = fma(SV_POSITION[_121].y, gl_TessCoord.z, fma(SV_POSITION[_103].y, gl_TessCoord.y, SV_POSITION[INDEX].y * gl_TessCoord.x));\n    gl_Position.z = fma(SV_POSITION[_121].z, gl_TessCoord.z, fma(SV_POSITION[_103].z, gl_TessCoord.y, SV_POSITION[INDEX].z * gl_TessCoord.x));\n    gl_Position.w = fma(SV_POSITION[_121].w, gl_TessCoord.z, fma(SV_POSITION[_103].w, gl_TessCoord.y, SV_POSITION[INDEX].w * gl_TessCoord.x));\n    COLOR.x = R_COLOR[0u];\n    COLOR.y = G_COLOR[1u];\n    COLOR.z = B_COLOR[2u];\n    TEXCOORD_1.x = TEXCOORD[INDEX].x;\n    TEXCOORD_1.y = TEXCOORD[INDEX].y;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_line.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability ClipDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %SV_POSITION %TEXCOORD %NORMAL %gl_ClipDistance %SV_POSITION_0 %TEXCOORD_0 %NORMAL_0 %gl_ClipDistance_0\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 2\n               OpExecutionMode %main InputLines\n               OpExecutionMode %main OutputLineStrip\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %NORMAL Location 3\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %TEXCOORD_0 Location 2\n               OpDecorate %NORMAL_0 Location 3\n               OpDecorate %gl_ClipDistance_0 BuiltIn ClipDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n     %uint_2 = OpConstant %uint 2\n%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2\n%_ptr_Input__arr_v4float_uint_2 = OpTypePointer Input %_arr_v4float_uint_2\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_2 Input\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_2 = OpTypeArray %v2float %uint_2\n%_ptr_Input__arr_v2float_uint_2 = OpTypePointer Input %_arr_v2float_uint_2\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_2 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_2 = OpTypeArray %v3float %uint_2\n%_ptr_Input__arr_v3float_uint_2 = OpTypePointer Input %_arr_v3float_uint_2\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_2 Input\n%_arr__arr_float_uint_2_uint_2 = OpTypeArray %_arr_float_uint_2 %uint_2\n%_ptr_Input__arr__arr_float_uint_2_uint_2 = OpTypePointer Input %_arr__arr_float_uint_2_uint_2\n%gl_ClipDistance = OpVariable %_ptr_Input__arr__arr_float_uint_2_uint_2 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n   %NORMAL_0 = OpVariable %_ptr_Output_v3float Output\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%gl_ClipDistance_0 = OpVariable %_ptr_Output__arr_float_uint_2 Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n     %v2uint = OpTypeVector %uint 2\n       %bool = OpTypeBool\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %81\n\n         %81 = OpLabel\n                 OpBranch %82\n\n         %82 = OpLabel\n         %32 =   OpPhi %uint %uint_0 %81 %34 %84\n                 OpLoopMerge %85 %84 None\n                 OpBranch %83\n\n         %83 =     OpLabel\n         %36 =       OpAccessChain %_ptr_Input_float %SV_POSITION %32 %uint_0\n         %37 =       OpLoad %float %36\n         %38 =       OpAccessChain %_ptr_Input_float %SV_POSITION %32 %uint_1\n         %40 =       OpLoad %float %38\n         %41 =       OpAccessChain %_ptr_Input_float %SV_POSITION %32 %uint_2\n         %42 =       OpLoad %float %41\n         %43 =       OpAccessChain %_ptr_Input_float %SV_POSITION %32 %uint_3\n         %45 =       OpLoad %float %43\n         %48 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                     OpStore %48 %37\n         %49 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                     OpStore %49 %40\n         %50 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                     OpStore %50 %42\n         %51 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                     OpStore %51 %45\n         %52 =       OpAccessChain %_ptr_Input_float %NORMAL %32 %uint_0\n         %53 =       OpLoad %float %52\n         %54 =       OpAccessChain %_ptr_Input_float %NORMAL %32 %uint_1\n         %55 =       OpLoad %float %54\n         %56 =       OpAccessChain %_ptr_Input_float %NORMAL %32 %uint_2\n         %57 =       OpLoad %float %56\n         %59 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_0\n                     OpStore %59 %53\n         %60 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_1\n                     OpStore %60 %55\n         %61 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_2\n                     OpStore %61 %57\n         %64 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %32 %uint_0\n         %65 =       OpLoad %float %64\n         %66 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_0\n                     OpStore %66 %65\n         %68 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %32 %uint_1\n         %69 =       OpLoad %float %68\n         %70 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_1\n                     OpStore %70 %69\n         %72 =       OpAccessChain %_ptr_Input_float %TEXCOORD %32 %uint_0\n         %73 =       OpLoad %float %72\n         %74 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                     OpStore %74 %73\n         %76 =       OpAccessChain %_ptr_Input_float %TEXCOORD %32 %uint_1\n         %77 =       OpLoad %float %76\n         %78 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                     OpStore %78 %77\n                     OpEmitVertex\n                     OpBranch %84\n\n         %84 =   OpLabel\n         %34 =     OpIAdd %uint %32 %uint_1\n         %80 =     OpULessThan %bool %34 %uint_2\n                   OpBranchConditional %80 %82 %85\n\n         %85 = OpLabel\n                 OpEndPrimitive\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_line.glsl",
    "content": "GLSL:\n#version 460\nlayout(lines) in;\nlayout(max_vertices = 2, line_strip) out;\n\nout float gl_ClipDistance[2];\n\nlayout(location = 2) in vec2 TEXCOORD[2];\nlayout(location = 3) in vec3 NORMAL[2];\nlayout(location = 2) out vec2 TEXCOORD_1;\nlayout(location = 3) out vec3 NORMAL_1;\n\nvoid main()\n{\n    uint _32 = 0u;\n    for (;;)\n    {\n        gl_Position.x = gl_in[_32].gl_Position.x;\n        gl_Position.y = gl_in[_32].gl_Position.y;\n        gl_Position.z = gl_in[_32].gl_Position.z;\n        gl_Position.w = gl_in[_32].gl_Position.w;\n        NORMAL_1.x = NORMAL[_32].x;\n        NORMAL_1.y = NORMAL[_32].y;\n        NORMAL_1.z = NORMAL[_32].z;\n        gl_ClipDistance[0u] = gl_in[_32].gl_ClipDistance[0u];\n        gl_ClipDistance[1u] = gl_in[_32].gl_ClipDistance[1u];\n        TEXCOORD_1.x = TEXCOORD[_32].x;\n        TEXCOORD_1.y = TEXCOORD[_32].y;\n        EmitVertex();\n        uint _34 = _32 + 1u;\n        if (_34 < 2u)\n        {\n            _32 = _34;\n            continue;\n        }\n        else\n        {\n            break;\n        }\n    }\n    EndPrimitive();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_line_adj.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 88\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability ClipDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %SV_POSITION %TEXCOORD %NORMAL %gl_ClipDistance %SV_POSITION_0 %TEXCOORD_0 %NORMAL_0 %gl_ClipDistance_0\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 4\n               OpExecutionMode %main InputLinesAdjacency\n               OpExecutionMode %main OutputLineStrip\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %NORMAL Location 3\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %TEXCOORD_0 Location 2\n               OpDecorate %NORMAL_0 Location 3\n               OpDecorate %gl_ClipDistance_0 BuiltIn ClipDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4\n%_ptr_Input__arr_v4float_uint_4 = OpTypePointer Input %_arr_v4float_uint_4\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_4 Input\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_4 = OpTypeArray %v2float %uint_4\n%_ptr_Input__arr_v2float_uint_4 = OpTypePointer Input %_arr_v2float_uint_4\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_4 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_4 = OpTypeArray %v3float %uint_4\n%_ptr_Input__arr_v3float_uint_4 = OpTypePointer Input %_arr_v3float_uint_4\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_4 Input\n%_arr__arr_float_uint_2_uint_4 = OpTypeArray %_arr_float_uint_2 %uint_4\n%_ptr_Input__arr__arr_float_uint_2_uint_4 = OpTypePointer Input %_arr__arr_float_uint_2_uint_4\n%gl_ClipDistance = OpVariable %_ptr_Input__arr__arr_float_uint_2_uint_4 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n   %NORMAL_0 = OpVariable %_ptr_Output_v3float Output\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%gl_ClipDistance_0 = OpVariable %_ptr_Output__arr_float_uint_2 Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n     %v2uint = OpTypeVector %uint 2\n       %bool = OpTypeBool\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %82\n\n         %82 = OpLabel\n                 OpBranch %83\n\n         %83 = OpLabel\n         %33 =   OpPhi %uint %uint_0 %82 %35 %85\n                 OpLoopMerge %86 %85 None\n                 OpBranch %84\n\n         %84 =     OpLabel\n         %37 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_0\n         %38 =       OpLoad %float %37\n         %39 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_1\n         %41 =       OpLoad %float %39\n         %42 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_2\n         %43 =       OpLoad %float %42\n         %44 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_3\n         %46 =       OpLoad %float %44\n         %49 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                     OpStore %49 %38\n         %50 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                     OpStore %50 %41\n         %51 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                     OpStore %51 %43\n         %52 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                     OpStore %52 %46\n         %53 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_0\n         %54 =       OpLoad %float %53\n         %55 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_1\n         %56 =       OpLoad %float %55\n         %57 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_2\n         %58 =       OpLoad %float %57\n         %60 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_0\n                     OpStore %60 %54\n         %61 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_1\n                     OpStore %61 %56\n         %62 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_2\n                     OpStore %62 %58\n         %65 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_0\n         %66 =       OpLoad %float %65\n         %67 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_0\n                     OpStore %67 %66\n         %69 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_1\n         %70 =       OpLoad %float %69\n         %71 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_1\n                     OpStore %71 %70\n         %73 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_0\n         %74 =       OpLoad %float %73\n         %75 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                     OpStore %75 %74\n         %77 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_1\n         %78 =       OpLoad %float %77\n         %79 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                     OpStore %79 %78\n                     OpEmitVertex\n                     OpBranch %85\n\n         %85 =   OpLabel\n         %35 =     OpIAdd %uint %33 %uint_1\n         %81 =     OpULessThan %bool %35 %uint_4\n                   OpBranchConditional %81 %83 %86\n\n         %86 = OpLabel\n                 OpEndPrimitive\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_line_adj.glsl",
    "content": "GLSL:\n#version 460\nlayout(lines_adjacency) in;\nlayout(max_vertices = 4, line_strip) out;\n\nout float gl_ClipDistance[2];\n\nlayout(location = 2) in vec2 TEXCOORD[4];\nlayout(location = 3) in vec3 NORMAL[4];\nlayout(location = 2) out vec2 TEXCOORD_1;\nlayout(location = 3) out vec3 NORMAL_1;\n\nvoid main()\n{\n    uint _33 = 0u;\n    for (;;)\n    {\n        gl_Position.x = gl_in[_33].gl_Position.x;\n        gl_Position.y = gl_in[_33].gl_Position.y;\n        gl_Position.z = gl_in[_33].gl_Position.z;\n        gl_Position.w = gl_in[_33].gl_Position.w;\n        NORMAL_1.x = NORMAL[_33].x;\n        NORMAL_1.y = NORMAL[_33].y;\n        NORMAL_1.z = NORMAL[_33].z;\n        gl_ClipDistance[0u] = gl_in[_33].gl_ClipDistance[0u];\n        gl_ClipDistance[1u] = gl_in[_33].gl_ClipDistance[1u];\n        TEXCOORD_1.x = TEXCOORD[_33].x;\n        TEXCOORD_1.y = TEXCOORD[_33].y;\n        EmitVertex();\n        uint _35 = _33 + 1u;\n        if (_35 < 4u)\n        {\n            _33 = _35;\n            continue;\n        }\n        else\n        {\n            break;\n        }\n    }\n    EndPrimitive();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_point.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability ClipDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %SV_POSITION %TEXCOORD %NORMAL %gl_ClipDistance %SV_POSITION_0 %TEXCOORD_0 %NORMAL_0 %gl_ClipDistance_0\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 1\n               OpExecutionMode %main InputPoints\n               OpExecutionMode %main OutputPoints\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %NORMAL Location 3\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %TEXCOORD_0 Location 2\n               OpDecorate %NORMAL_0 Location 3\n               OpDecorate %gl_ClipDistance_0 BuiltIn ClipDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n     %uint_1 = OpConstant %uint 1\n%_arr_v4float_uint_1 = OpTypeArray %v4float %uint_1\n%_ptr_Input__arr_v4float_uint_1 = OpTypePointer Input %_arr_v4float_uint_1\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_1 Input\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_1 = OpTypeArray %v2float %uint_1\n%_ptr_Input__arr_v2float_uint_1 = OpTypePointer Input %_arr_v2float_uint_1\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_1 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_1 = OpTypeArray %v3float %uint_1\n%_ptr_Input__arr_v3float_uint_1 = OpTypePointer Input %_arr_v3float_uint_1\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_1 Input\n%_arr__arr_float_uint_2_uint_1 = OpTypeArray %_arr_float_uint_2 %uint_1\n%_ptr_Input__arr__arr_float_uint_2_uint_1 = OpTypePointer Input %_arr__arr_float_uint_2_uint_1\n%gl_ClipDistance = OpVariable %_ptr_Input__arr__arr_float_uint_2_uint_1 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n   %NORMAL_0 = OpVariable %_ptr_Output_v3float Output\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%gl_ClipDistance_0 = OpVariable %_ptr_Output__arr_float_uint_2 Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n     %v2uint = OpTypeVector %uint 2\n       %bool = OpTypeBool\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %81\n\n         %81 = OpLabel\n                 OpBranch %82\n\n         %82 = OpLabel\n         %33 =   OpPhi %uint %uint_0 %81 %35 %84\n                 OpLoopMerge %85 %84 None\n                 OpBranch %83\n\n         %83 =     OpLabel\n         %37 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_0\n         %38 =       OpLoad %float %37\n         %39 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_1\n         %40 =       OpLoad %float %39\n         %41 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_2\n         %42 =       OpLoad %float %41\n         %43 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_3\n         %45 =       OpLoad %float %43\n         %48 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                     OpStore %48 %38\n         %49 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                     OpStore %49 %40\n         %50 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                     OpStore %50 %42\n         %51 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                     OpStore %51 %45\n         %52 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_0\n         %53 =       OpLoad %float %52\n         %54 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_1\n         %55 =       OpLoad %float %54\n         %56 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_2\n         %57 =       OpLoad %float %56\n         %59 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_0\n                     OpStore %59 %53\n         %60 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_1\n                     OpStore %60 %55\n         %61 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_2\n                     OpStore %61 %57\n         %64 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_0\n         %65 =       OpLoad %float %64\n         %66 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_0\n                     OpStore %66 %65\n         %68 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_1\n         %69 =       OpLoad %float %68\n         %70 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_1\n                     OpStore %70 %69\n         %72 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_0\n         %73 =       OpLoad %float %72\n         %74 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                     OpStore %74 %73\n         %76 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_1\n         %77 =       OpLoad %float %76\n         %78 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                     OpStore %78 %77\n                     OpEmitVertex\n                     OpBranch %84\n\n         %84 =   OpLabel\n         %35 =     OpIAdd %uint %33 %uint_1\n         %80 =     OpULessThan %bool %35 %uint_1\n                   OpBranchConditional %80 %82 %85\n\n         %85 = OpLabel\n                 OpEndPrimitive\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_point.glsl",
    "content": "GLSL:\n#version 460\nlayout(points) in;\nlayout(max_vertices = 1, points) out;\n\nout float gl_ClipDistance[2];\n\nlayout(location = 2) in vec2 TEXCOORD[1];\nlayout(location = 3) in vec3 NORMAL[1];\nlayout(location = 2) out vec2 TEXCOORD_1;\nlayout(location = 3) out vec3 NORMAL_1;\n\nvoid main()\n{\n    uint _33 = 0u;\n    for (;;)\n    {\n        gl_Position.x = gl_in[_33].gl_Position.x;\n        gl_Position.y = gl_in[_33].gl_Position.y;\n        gl_Position.z = gl_in[_33].gl_Position.z;\n        gl_Position.w = gl_in[_33].gl_Position.w;\n        NORMAL_1.x = NORMAL[_33].x;\n        NORMAL_1.y = NORMAL[_33].y;\n        NORMAL_1.z = NORMAL[_33].z;\n        gl_ClipDistance[0u] = gl_in[_33].gl_ClipDistance[0u];\n        gl_ClipDistance[1u] = gl_in[_33].gl_ClipDistance[1u];\n        TEXCOORD_1.x = TEXCOORD[_33].x;\n        TEXCOORD_1.y = TEXCOORD[_33].y;\n        EmitVertex();\n        uint _35 = _33 + 1u;\n        if (_35 < 1u)\n        {\n            _33 = _35;\n            continue;\n        }\n        else\n        {\n            break;\n        }\n    }\n    EndPrimitive();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_triangle.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 87\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability ClipDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %SV_POSITION %TEXCOORD %NORMAL %gl_ClipDistance %SV_POSITION_0 %TEXCOORD_0 %NORMAL_0 %gl_ClipDistance_0\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 3\n               OpExecutionMode %main Triangles\n               OpExecutionMode %main OutputTriangleStrip\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %NORMAL Location 3\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %TEXCOORD_0 Location 2\n               OpDecorate %NORMAL_0 Location 3\n               OpDecorate %gl_ClipDistance_0 BuiltIn ClipDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n     %uint_3 = OpConstant %uint 3\n%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3\n%_ptr_Input__arr_v4float_uint_3 = OpTypePointer Input %_arr_v4float_uint_3\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_3 Input\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3\n%_ptr_Input__arr_v2float_uint_3 = OpTypePointer Input %_arr_v2float_uint_3\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_3 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_3 = OpTypeArray %v3float %uint_3\n%_ptr_Input__arr_v3float_uint_3 = OpTypePointer Input %_arr_v3float_uint_3\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_3 Input\n%_arr__arr_float_uint_2_uint_3 = OpTypeArray %_arr_float_uint_2 %uint_3\n%_ptr_Input__arr__arr_float_uint_2_uint_3 = OpTypePointer Input %_arr__arr_float_uint_2_uint_3\n%gl_ClipDistance = OpVariable %_ptr_Input__arr__arr_float_uint_2_uint_3 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n   %NORMAL_0 = OpVariable %_ptr_Output_v3float Output\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%gl_ClipDistance_0 = OpVariable %_ptr_Output__arr_float_uint_2 Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n%_ptr_Output_float = OpTypePointer Output %float\n     %v2uint = OpTypeVector %uint 2\n       %bool = OpTypeBool\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %81\n\n         %81 = OpLabel\n                 OpBranch %82\n\n         %82 = OpLabel\n         %33 =   OpPhi %uint %uint_0 %81 %35 %84\n                 OpLoopMerge %85 %84 None\n                 OpBranch %83\n\n         %83 =     OpLabel\n         %37 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_0\n         %38 =       OpLoad %float %37\n         %39 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_1\n         %41 =       OpLoad %float %39\n         %42 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_2\n         %43 =       OpLoad %float %42\n         %44 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_3\n         %45 =       OpLoad %float %44\n         %48 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                     OpStore %48 %38\n         %49 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                     OpStore %49 %41\n         %50 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                     OpStore %50 %43\n         %51 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                     OpStore %51 %45\n         %52 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_0\n         %53 =       OpLoad %float %52\n         %54 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_1\n         %55 =       OpLoad %float %54\n         %56 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_2\n         %57 =       OpLoad %float %56\n         %59 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_0\n                     OpStore %59 %53\n         %60 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_1\n                     OpStore %60 %55\n         %61 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_2\n                     OpStore %61 %57\n         %64 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_0\n         %65 =       OpLoad %float %64\n         %66 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_0\n                     OpStore %66 %65\n         %68 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_1\n         %69 =       OpLoad %float %68\n         %70 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_1\n                     OpStore %70 %69\n         %72 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_0\n         %73 =       OpLoad %float %72\n         %74 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                     OpStore %74 %73\n         %76 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_1\n         %77 =       OpLoad %float %76\n         %78 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                     OpStore %78 %77\n                     OpEmitVertex\n                     OpBranch %84\n\n         %84 =   OpLabel\n         %35 =     OpIAdd %uint %33 %uint_1\n         %80 =     OpULessThan %bool %35 %uint_3\n                   OpBranchConditional %80 %82 %85\n\n         %85 = OpLabel\n                 OpEndPrimitive\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_triangle.glsl",
    "content": "GLSL:\n#version 460\nlayout(triangles) in;\nlayout(max_vertices = 3, triangle_strip) out;\n\nout float gl_ClipDistance[2];\n\nlayout(location = 2) in vec2 TEXCOORD[3];\nlayout(location = 3) in vec3 NORMAL[3];\nlayout(location = 2) out vec2 TEXCOORD_1;\nlayout(location = 3) out vec3 NORMAL_1;\n\nvoid main()\n{\n    uint _33 = 0u;\n    for (;;)\n    {\n        gl_Position.x = gl_in[_33].gl_Position.x;\n        gl_Position.y = gl_in[_33].gl_Position.y;\n        gl_Position.z = gl_in[_33].gl_Position.z;\n        gl_Position.w = gl_in[_33].gl_Position.w;\n        NORMAL_1.x = NORMAL[_33].x;\n        NORMAL_1.y = NORMAL[_33].y;\n        NORMAL_1.z = NORMAL[_33].z;\n        gl_ClipDistance[0u] = gl_in[_33].gl_ClipDistance[0u];\n        gl_ClipDistance[1u] = gl_in[_33].gl_ClipDistance[1u];\n        TEXCOORD_1.x = TEXCOORD[_33].x;\n        TEXCOORD_1.y = TEXCOORD[_33].y;\n        EmitVertex();\n        uint _35 = _33 + 1u;\n        if (_35 < 3u)\n        {\n            _33 = _35;\n            continue;\n        }\n        else\n        {\n            break;\n        }\n    }\n    EndPrimitive();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_triangle_adj.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 88\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability ClipDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %SV_POSITION %TEXCOORD %NORMAL %gl_ClipDistance %SV_POSITION_0 %TEXCOORD_0 %NORMAL_0 %gl_ClipDistance_0\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 6\n               OpExecutionMode %main InputTrianglesAdjacency\n               OpExecutionMode %main OutputTriangleStrip\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %TEXCOORD_0 \"TEXCOORD\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %TEXCOORD Location 2\n               OpDecorate %NORMAL Location 3\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %SV_POSITION_0 BuiltIn Position\n               OpDecorate %TEXCOORD_0 Location 2\n               OpDecorate %NORMAL_0 Location 3\n               OpDecorate %gl_ClipDistance_0 BuiltIn ClipDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n     %uint_6 = OpConstant %uint 6\n%_arr_v4float_uint_6 = OpTypeArray %v4float %uint_6\n%_ptr_Input__arr_v4float_uint_6 = OpTypePointer Input %_arr_v4float_uint_6\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_6 Input\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n    %v2float = OpTypeVector %float 2\n%_arr_v2float_uint_6 = OpTypeArray %v2float %uint_6\n%_ptr_Input__arr_v2float_uint_6 = OpTypePointer Input %_arr_v2float_uint_6\n   %TEXCOORD = OpVariable %_ptr_Input__arr_v2float_uint_6 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_6 = OpTypeArray %v3float %uint_6\n%_ptr_Input__arr_v3float_uint_6 = OpTypePointer Input %_arr_v3float_uint_6\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_6 Input\n%_arr__arr_float_uint_2_uint_6 = OpTypeArray %_arr_float_uint_2 %uint_6\n%_ptr_Input__arr__arr_float_uint_2_uint_6 = OpTypePointer Input %_arr__arr_float_uint_2_uint_6\n%gl_ClipDistance = OpVariable %_ptr_Input__arr__arr_float_uint_2_uint_6 Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION_0 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_v2float = OpTypePointer Output %v2float\n %TEXCOORD_0 = OpVariable %_ptr_Output_v2float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n   %NORMAL_0 = OpVariable %_ptr_Output_v3float Output\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%gl_ClipDistance_0 = OpVariable %_ptr_Output__arr_float_uint_2 Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n     %v2uint = OpTypeVector %uint 2\n       %bool = OpTypeBool\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %82\n\n         %82 = OpLabel\n                 OpBranch %83\n\n         %83 = OpLabel\n         %33 =   OpPhi %uint %uint_0 %82 %35 %85\n                 OpLoopMerge %86 %85 None\n                 OpBranch %84\n\n         %84 =     OpLabel\n         %37 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_0\n         %38 =       OpLoad %float %37\n         %39 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_1\n         %41 =       OpLoad %float %39\n         %42 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_2\n         %43 =       OpLoad %float %42\n         %44 =       OpAccessChain %_ptr_Input_float %SV_POSITION %33 %uint_3\n         %46 =       OpLoad %float %44\n         %49 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0\n                     OpStore %49 %38\n         %50 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1\n                     OpStore %50 %41\n         %51 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2\n                     OpStore %51 %43\n         %52 =       OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_3\n                     OpStore %52 %46\n         %53 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_0\n         %54 =       OpLoad %float %53\n         %55 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_1\n         %56 =       OpLoad %float %55\n         %57 =       OpAccessChain %_ptr_Input_float %NORMAL %33 %uint_2\n         %58 =       OpLoad %float %57\n         %60 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_0\n                     OpStore %60 %54\n         %61 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_1\n                     OpStore %61 %56\n         %62 =       OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_2\n                     OpStore %62 %58\n         %65 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_0\n         %66 =       OpLoad %float %65\n         %67 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_0\n                     OpStore %67 %66\n         %69 =       OpAccessChain %_ptr_Input_float %gl_ClipDistance %33 %uint_1\n         %70 =       OpLoad %float %69\n         %71 =       OpAccessChain %_ptr_Output_float %gl_ClipDistance_0 %uint_1\n                     OpStore %71 %70\n         %73 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_0\n         %74 =       OpLoad %float %73\n         %75 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_0\n                     OpStore %75 %74\n         %77 =       OpAccessChain %_ptr_Input_float %TEXCOORD %33 %uint_1\n         %78 =       OpLoad %float %77\n         %79 =       OpAccessChain %_ptr_Output_float %TEXCOORD_0 %uint_1\n                     OpStore %79 %78\n                     OpEmitVertex\n                     OpBranch %85\n\n         %85 =   OpLabel\n         %35 =     OpIAdd %uint %33 %uint_1\n         %81 =     OpULessThan %bool %35 %uint_6\n                   OpBranchConditional %81 %83 %86\n\n         %86 = OpLabel\n                 OpEndPrimitive\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_basic_triangle_adj.glsl",
    "content": "GLSL:\n#version 460\nlayout(triangles_adjacency) in;\nlayout(max_vertices = 6, triangle_strip) out;\n\nout float gl_ClipDistance[2];\n\nlayout(location = 2) in vec2 TEXCOORD[6];\nlayout(location = 3) in vec3 NORMAL[6];\nlayout(location = 2) out vec2 TEXCOORD_1;\nlayout(location = 3) out vec3 NORMAL_1;\n\nvoid main()\n{\n    uint _33 = 0u;\n    for (;;)\n    {\n        gl_Position.x = gl_in[_33].gl_Position.x;\n        gl_Position.y = gl_in[_33].gl_Position.y;\n        gl_Position.z = gl_in[_33].gl_Position.z;\n        gl_Position.w = gl_in[_33].gl_Position.w;\n        NORMAL_1.x = NORMAL[_33].x;\n        NORMAL_1.y = NORMAL[_33].y;\n        NORMAL_1.z = NORMAL[_33].z;\n        gl_ClipDistance[0u] = gl_in[_33].gl_ClipDistance[0u];\n        gl_ClipDistance[1u] = gl_in[_33].gl_ClipDistance[1u];\n        TEXCOORD_1.x = TEXCOORD[_33].x;\n        TEXCOORD_1.y = TEXCOORD[_33].y;\n        EmitVertex();\n        uint _35 = _33 + 1u;\n        if (_35 < 6u)\n        {\n            _33 = _35;\n            continue;\n        }\n        else\n        {\n            break;\n        }\n    }\n    EndPrimitive();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_instanced.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability MultiViewport\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %SV_POSITION %SV_RenderTargetArrayIndex %SV_ViewportArrayIndex %SV_PrimitiveId %gl_InvocationID %gl_PrimitiveID\n               OpExecutionMode %main Invocations 12\n               OpExecutionMode %main OutputVertices 1\n               OpExecutionMode %main InputPoints\n               OpExecutionMode %main OutputPoints\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %SV_RenderTargetArrayIndex \"SV_RenderTargetArrayIndex\"\n               OpName %SV_ViewportArrayIndex \"SV_ViewportArrayIndex\"\n               OpName %SV_PrimitiveId \"SV_PrimitiveId\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %SV_RenderTargetArrayIndex BuiltIn Layer\n               OpDecorate %SV_ViewportArrayIndex BuiltIn ViewportIndex\n               OpDecorate %SV_PrimitiveId BuiltIn PrimitiveId\n               OpDecorate %gl_InvocationID BuiltIn InvocationId\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_RenderTargetArrayIndex = OpVariable %_ptr_Output_uint Output\n%SV_ViewportArrayIndex = OpVariable %_ptr_Output_uint Output\n%SV_PrimitiveId = OpVariable %_ptr_Output_uint Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n%gl_InvocationID = OpVariable %_ptr_Input_uint Input\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n    %uint_12 = OpConstant %uint 12\n     %uint_1 = OpConstant %uint 1\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_0 = OpConstant %uint 0\n    %float_1 = OpConstant %float 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %34\n\n         %34 = OpLabel\n         %16 =   OpLoad %uint %gl_InvocationID\n         %18 =   OpLoad %uint %gl_PrimitiveID\n         %19 =   OpIMul %uint %18 %uint_12\n         %21 =   OpIAdd %uint %16 %19\n                 OpStore %SV_PrimitiveId %21\n         %22 =   OpShiftRightLogical %uint %16 %uint_1\n                 OpStore %SV_RenderTargetArrayIndex %22\n         %24 =   OpBitwiseAnd %uint %16 %uint_1\n                 OpStore %SV_ViewportArrayIndex %24\n         %26 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_0\n                 OpStore %26 %float_1\n         %29 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_1\n                 OpStore %29 %float_1\n         %30 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_2\n                 OpStore %30 %float_1\n         %32 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_3\n                 OpStore %32 %float_1\n                 OpEmitVertex\n                 OpEndPrimitive\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_instanced.glsl",
    "content": "GLSL:\n#version 460\nlayout(invocations = 12, points) in;\nlayout(max_vertices = 1, points) out;\n\nvoid main()\n{\n    gl_PrimitiveID = int(gl_InvocationID + (uint(gl_PrimitiveIDIn) * 12u));\n    gl_Layer = int(gl_InvocationID >> 1u);\n    gl_ViewportIndex = int(gl_InvocationID & 1u);\n    gl_Position.x = 1.0;\n    gl_Position.y = 1.0;\n    gl_Position.z = 1.0;\n    gl_Position.w = 1.0;\n    EmitVertex();\n    EndPrimitive();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_multi_stream_xfb_raster_0.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability GeometryStreams\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %SV_POSITION %BUFFER_A_ATTR_1 %BUFFER_B_ATTR\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 1\n               OpExecutionMode %main InputPoints\n               OpExecutionMode %main OutputPoints\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %BUFFER_A_ATTR_1 \"BUFFER_A_ATTR_1\"\n               OpName %BUFFER_B_ATTR \"BUFFER_B_ATTR\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %BUFFER_A_ATTR_1 Location 1\n               OpDecorate %BUFFER_B_ATTR Stream 1\n               OpDecorate %BUFFER_B_ATTR Location 4\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n%BUFFER_A_ATTR_1 = OpVariable %_ptr_Output_uint Output\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Output_v2int = OpTypePointer Output %v2int\n%BUFFER_B_ATTR = OpVariable %_ptr_Output_v2int Output\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_0 = OpConstant %uint 0\n    %float_1 = OpConstant %float 1\n     %uint_1 = OpConstant %uint 1\n    %float_2 = OpConstant %float 2\n     %uint_2 = OpConstant %uint 2\n    %float_3 = OpConstant %float 3\n     %uint_3 = OpConstant %uint 3\n    %float_4 = OpConstant %float 4\n     %uint_4 = OpConstant %uint 4\n%_ptr_Output_int = OpTypePointer Output %int\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %37\n\n         %37 = OpLabel\n         %17 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_0\n                 OpStore %17 %float_1\n         %20 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_1\n                 OpStore %20 %float_2\n         %23 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_2\n                 OpStore %23 %float_3\n         %26 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_3\n                 OpStore %26 %float_4\n                 OpStore %BUFFER_A_ATTR_1 %uint_4\n                 OpEmitStreamVertex %uint_0\n                 OpEndStreamPrimitive %uint_0\n         %31 =   OpAccessChain %_ptr_Output_int %BUFFER_B_ATTR %uint_0\n         %33 =   OpBitcast %int %uint_5\n                 OpStore %31 %33\n         %34 =   OpAccessChain %_ptr_Output_int %BUFFER_B_ATTR %uint_1\n         %36 =   OpBitcast %int %uint_6\n                 OpStore %34 %36\n                 OpEmitStreamVertex %uint_1\n                 OpEndStreamPrimitive %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_multi_stream_xfb_raster_0.glsl",
    "content": "GLSL:\n#version 460\nlayout(points) in;\nlayout(max_vertices = 1, points) out;\n\nlayout(location = 1) out uint BUFFER_A_ATTR_1;\nlayout(location = 4, stream = 1) out ivec2 BUFFER_B_ATTR;\n\nvoid main()\n{\n    gl_Position.x = 1.0;\n    gl_Position.y = 2.0;\n    gl_Position.z = 3.0;\n    gl_Position.w = 4.0;\n    BUFFER_A_ATTR_1 = 4u;\n    EmitStreamVertex(int(0u));\n    EndStreamPrimitive(int(0u));\n    BUFFER_B_ATTR.x = int(5u);\n    BUFFER_B_ATTR.y = int(6u);\n    EmitStreamVertex(int(1u));\n    EndStreamPrimitive(int(1u));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_multi_stream_xfb_raster_1.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability GeometryStreams\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %BUFFER_A_ATTR %BUFFER_A_ATTR_1 %SV_POSITION\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 1\n               OpExecutionMode %main InputPoints\n               OpExecutionMode %main OutputPoints\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_A_ATTR \"BUFFER_A_ATTR\"\n               OpName %BUFFER_A_ATTR_1 \"BUFFER_A_ATTR_1\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpDecorate %BUFFER_A_ATTR Location 0\n               OpDecorate %BUFFER_A_ATTR_1 Location 1\n               OpDecorate %SV_POSITION Stream 1\n               OpDecorate %SV_POSITION BuiltIn Position\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Output_v2int = OpTypePointer Output %v2int\n%BUFFER_A_ATTR = OpVariable %_ptr_Output_v2int Output\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n%BUFFER_A_ATTR_1 = OpVariable %_ptr_Output_uint Output\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_int = OpTypePointer Output %int\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n    %float_4 = OpConstant %float 4\n    %float_5 = OpConstant %float 5\n    %float_6 = OpConstant %float 6\n    %float_7 = OpConstant %float 7\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %34\n\n         %34 = OpLabel\n         %17 =   OpAccessChain %_ptr_Output_int %BUFFER_A_ATTR %uint_0\n         %20 =   OpBitcast %int %uint_1\n                 OpStore %17 %20\n         %21 =   OpAccessChain %_ptr_Output_int %BUFFER_A_ATTR %uint_1\n         %23 =   OpBitcast %int %uint_2\n                 OpStore %21 %23\n                 OpStore %BUFFER_A_ATTR_1 %uint_3\n                 OpEmitStreamVertex %uint_0\n                 OpEndStreamPrimitive %uint_0\n         %26 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_0\n                 OpStore %26 %float_4\n         %28 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_1\n                 OpStore %28 %float_5\n         %30 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_2\n                 OpStore %30 %float_6\n         %32 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_3\n                 OpStore %32 %float_7\n                 OpEmitStreamVertex %uint_1\n                 OpEndStreamPrimitive %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_multi_stream_xfb_raster_1.glsl",
    "content": "GLSL:\n#version 460\nlayout(points) in;\nlayout(max_vertices = 1, points) out;\n\nlayout(location = 0) out ivec2 BUFFER_A_ATTR;\nlayout(location = 1) out uint BUFFER_A_ATTR_1;\n\nvoid main()\n{\n    BUFFER_A_ATTR.x = int(1u);\n    BUFFER_A_ATTR.y = int(2u);\n    BUFFER_A_ATTR_1 = 3u;\n    EmitStreamVertex(int(0u));\n    EndStreamPrimitive(int(0u));\n    gl_Position.x = 4.0;\n    gl_Position.y = 5.0;\n    gl_Position.z = 6.0;\n    gl_Position.w = 7.0;\n    EmitStreamVertex(int(1u));\n    EndStreamPrimitive(int(1u));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_xfb.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Geometry %main \"main\" %BUFFER_A_ATTR %BUFFER_A_ATTR_1 %BUFFER_B_ATTR\n               OpExecutionMode %main Invocations 1\n               OpExecutionMode %main OutputVertices 1\n               OpExecutionMode %main InputPoints\n               OpExecutionMode %main OutputPoints\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_A_ATTR \"BUFFER_A_ATTR\"\n               OpName %BUFFER_A_ATTR_1 \"BUFFER_A_ATTR_1\"\n               OpName %BUFFER_B_ATTR \"BUFFER_B_ATTR\"\n               OpDecorate %BUFFER_A_ATTR Location 0\n               OpDecorate %BUFFER_A_ATTR_1 Location 0\n               OpDecorate %BUFFER_A_ATTR_1 Component 3\n               OpDecorate %BUFFER_B_ATTR Location 1\n               OpDecorate %BUFFER_B_ATTR Component 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v3float = OpTypeVector %float 3\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n%BUFFER_A_ATTR = OpVariable %_ptr_Output_v3float Output\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n%BUFFER_A_ATTR_1 = OpVariable %_ptr_Output_uint Output\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Output_v2int = OpTypePointer Output %v2int\n%BUFFER_B_ATTR = OpVariable %_ptr_Output_v2int Output\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_0 = OpConstant %uint 0\n    %float_1 = OpConstant %float 1\n     %uint_1 = OpConstant %uint 1\n    %float_2 = OpConstant %float 2\n     %uint_2 = OpConstant %uint 2\n    %float_3 = OpConstant %float 3\n     %uint_4 = OpConstant %uint 4\n%_ptr_Output_int = OpTypePointer Output %int\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %34\n\n         %34 = OpLabel\n         %17 =   OpAccessChain %_ptr_Output_float %BUFFER_A_ATTR %uint_0\n                 OpStore %17 %float_1\n         %20 =   OpAccessChain %_ptr_Output_float %BUFFER_A_ATTR %uint_1\n                 OpStore %20 %float_2\n         %23 =   OpAccessChain %_ptr_Output_float %BUFFER_A_ATTR %uint_2\n                 OpStore %23 %float_3\n                 OpStore %BUFFER_A_ATTR_1 %uint_4\n                 OpEmitVertex\n                 OpEndPrimitive\n         %28 =   OpAccessChain %_ptr_Output_int %BUFFER_B_ATTR %uint_0\n         %30 =   OpBitcast %int %uint_5\n                 OpStore %28 %30\n         %31 =   OpAccessChain %_ptr_Output_int %BUFFER_B_ATTR %uint_1\n         %33 =   OpBitcast %int %uint_6\n                 OpStore %31 %33\n                 OpEmitVertex\n                 OpEndPrimitive\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_gs_xfb.glsl",
    "content": "GLSL:\n#version 460\nlayout(points) in;\nlayout(max_vertices = 1, points) out;\n\nlayout(location = 0) out vec3 BUFFER_A_ATTR;\nlayout(location = 0, component = 3) out uint BUFFER_A_ATTR_1;\nlayout(location = 1, component = 2) out ivec2 BUFFER_B_ATTR;\n\nvoid main()\n{\n    BUFFER_A_ATTR.x = 1.0;\n    BUFFER_A_ATTR.y = 2.0;\n    BUFFER_A_ATTR.z = 3.0;\n    BUFFER_A_ATTR_1 = 4u;\n    EmitVertex();\n    EndPrimitive();\n    BUFFER_B_ATTR.x = int(5u);\n    BUFFER_B_ATTR.y = int(6u);\n    EmitVertex();\n    EndPrimitive();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_line.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 137\n; Schema: 0\n               OpCapability Shader\n               OpCapability Tessellation\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %84 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint TessellationControl %main \"main\" %SV_POSITION %NORMAL %FACTOR %SV_POSITION_0 %NORMAL_0 %INSTANCE_ID %TANGENT %TANGENT_1 %SV_TESSFACTOR %SV_INSIDETESSFACTOR %gl_InvocationID %gl_PrimitiveID\n               OpExecutionMode %main Isolines\n               OpExecutionMode %main SpacingEqual\n               OpExecutionMode %main OutputVertices 4\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %FACTOR \"FACTOR\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpName %INSTANCE_ID \"INSTANCE_ID\"\n               OpName %TANGENT \"TANGENT\"\n               OpName %TANGENT_1 \"TANGENT_1\"\n               OpName %SV_TESSFACTOR \"SV_TESSFACTOR\"\n               OpName %SV_INSIDETESSFACTOR \"SV_INSIDETESSFACTOR\"\n               OpName %hull_main \"hull_main\"\n               OpName %patch_main \"patch_main\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %NORMAL Location 1\n               OpDecorate %FACTOR Location 1\n               OpDecorate %FACTOR Component 3\n               OpDecorate %SV_POSITION_0 Location 0\n               OpDecorate %NORMAL_0 Location 1\n               OpDecorate %INSTANCE_ID Location 4\n               OpDecorate %INSTANCE_ID Patch\n               OpDecorate %TANGENT Location 5\n               OpDecorate %TANGENT Patch\n               OpDecorate %TANGENT_1 Location 6\n               OpDecorate %TANGENT_1 Patch\n               OpDecorate %SV_TESSFACTOR BuiltIn TessLevelOuter\n               OpDecorate %SV_TESSFACTOR Patch\n               OpDecorate %SV_INSIDETESSFACTOR BuiltIn TessLevelInner\n               OpDecorate %SV_INSIDETESSFACTOR Patch\n               OpDecorate %gl_InvocationID BuiltIn InvocationId\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n    %uint_32 = OpConstant %uint 32\n%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32\n%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_32 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32\n%_ptr_Input__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_32 Input\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32\n     %FACTOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n     %uint_4 = OpConstant %uint 4\n%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4\n%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4\n%SV_POSITION_0 = OpVariable %_ptr_Output__arr_v4float_uint_4 Output\n%_arr_v3float_uint_4 = OpTypeArray %v3float %uint_4\n%_ptr_Output__arr_v3float_uint_4 = OpTypePointer Output %_arr_v3float_uint_4\n   %NORMAL_0 = OpVariable %_ptr_Output__arr_v3float_uint_4 Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%INSTANCE_ID = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n    %TANGENT = OpVariable %_ptr_Output_v3float Output\n  %TANGENT_1 = OpVariable %_ptr_Output_v3float Output\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4\n%SV_TESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_4 Output\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%SV_INSIDETESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_2 Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n%gl_InvocationID = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n   %float_64 = OpConstant %float 64\n       %bool = OpTypeBool\n  %uint_4104 = OpConstant %uint 4104\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %129\n\n        %129 = OpLabel\n        %123 =   OpFunctionCall %void %hull_main\n        %124 =   OpLoad %uint %gl_InvocationID\n        %126 =   OpIEqual %bool %124 %uint_0\n                 OpControlBarrier %uint_2 %uint_2 %uint_4104\n                 OpSelectionMerge %131 None\n                 OpBranchConditional %126 %130 %131\n\n        %130 =     OpLabel\n        %128 =       OpFunctionCall %void %patch_main\n                     OpBranch %131\n\n        %131 = OpLabel\n                 OpReturn\n               OpFunctionEnd\n  %hull_main = OpFunction %void None %2\n\n         %39 = OpLabel\n                 OpBranch %133\n\n        %133 = OpLabel\n         %44 =   OpLoad %uint %gl_InvocationID\n         %46 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_0\n         %48 =   OpLoad %float %46\n         %49 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_2\n         %53 =   OpLoad %float %52\n         %54 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_3\n         %56 =   OpLoad %float %54\n         %60 =   OpLoad %uint %gl_InvocationID\n         %59 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %60 %uint_0\n                 OpStore %59 %48\n         %62 =   OpLoad %uint %gl_InvocationID\n         %61 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %62 %uint_1\n                 OpStore %61 %51\n         %64 =   OpLoad %uint %gl_InvocationID\n         %63 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %64 %uint_2\n                 OpStore %63 %53\n         %66 =   OpLoad %uint %gl_InvocationID\n         %65 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %66 %uint_3\n                 OpStore %65 %56\n         %67 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_0\n         %68 =   OpLoad %float %67\n         %69 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_1\n         %70 =   OpLoad %float %69\n         %71 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_2\n         %72 =   OpLoad %float %71\n         %75 =   OpLoad %uint %gl_InvocationID\n         %74 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %75 %uint_0\n                 OpStore %74 %68\n         %77 =   OpLoad %uint %gl_InvocationID\n         %76 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %77 %uint_1\n                 OpStore %76 %70\n         %79 =   OpLoad %uint %gl_InvocationID\n         %78 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %79 %uint_2\n                 OpStore %78 %72\n                 OpReturn\n               OpFunctionEnd\n %patch_main = OpFunction %void None %2\n\n         %41 = OpLabel\n                 OpBranch %135\n\n        %135 = OpLabel\n         %81 =   OpLoad %uint %gl_PrimitiveID\n                 OpStore %INSTANCE_ID %81\n         %82 =   OpAccessChain %_ptr_Input_float %FACTOR %uint_0\n         %83 =   OpLoad %float %82\n         %85 =   OpExtInst %float %84 NMin %83 %float_64\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_0\n                 OpStore %87 %85\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_1\n                 OpStore %88 %85\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_2\n                 OpStore %89 %85\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_3\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_0\n                 OpStore %91 %85\n         %92 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_1\n                 OpStore %92 %85\n         %93 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_0\n         %94 =   OpLoad %float %93\n         %95 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_0\n         %96 =   OpLoad %float %95\n         %97 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_0\n         %98 =   OpLoad %float %97\n         %99 =   OpFSub %float %96 %94\n        %100 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_0\n                 OpStore %100 %99\n        %101 =   OpFSub %float %98 %94\n        %102 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_0\n                 OpStore %102 %101\n        %103 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_1\n        %104 =   OpLoad %float %103\n        %105 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_1\n        %106 =   OpLoad %float %105\n        %107 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_1\n        %108 =   OpLoad %float %107\n        %109 =   OpFSub %float %106 %104\n        %110 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_1\n                 OpStore %110 %109\n        %111 =   OpFSub %float %108 %104\n        %112 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_1\n                 OpStore %112 %111\n        %113 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_2\n        %114 =   OpLoad %float %113\n        %115 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_2\n        %116 =   OpLoad %float %115\n        %117 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_2\n        %118 =   OpLoad %float %117\n        %119 =   OpFSub %float %116 %114\n        %120 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_2\n                 OpStore %120 %119\n        %121 =   OpFSub %float %118 %114\n        %122 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_2\n                 OpStore %122 %121\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_line.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_spirv_intrinsics : require\nlayout(vertices = 4) out;\n\nlayout(location = 1) in vec3 NORMAL[];\nlayout(location = 1, component = 3) in float FACTOR[];\nlayout(location = 0) out vec4 SV_POSITION[4];\nlayout(location = 1) out vec3 NORMAL_1[4];\nlayout(location = 4) patch out uint INSTANCE_ID;\nlayout(location = 5) patch out vec3 TANGENT;\nlayout(location = 6) patch out vec3 TANGENT_1;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float spvNMin(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec2 spvNMin(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec3 spvNMin(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec4 spvNMin(vec4, vec4);\n\nvoid hull_main()\n{\n    SV_POSITION[gl_InvocationID].x = gl_in[gl_InvocationID].gl_Position.x;\n    SV_POSITION[gl_InvocationID].y = gl_in[gl_InvocationID].gl_Position.y;\n    SV_POSITION[gl_InvocationID].z = gl_in[gl_InvocationID].gl_Position.z;\n    SV_POSITION[gl_InvocationID].w = gl_in[gl_InvocationID].gl_Position.w;\n    NORMAL_1[gl_InvocationID].x = NORMAL[gl_InvocationID].x;\n    NORMAL_1[gl_InvocationID].y = NORMAL[gl_InvocationID].y;\n    NORMAL_1[gl_InvocationID].z = NORMAL[gl_InvocationID].z;\n}\n\nvoid patch_main()\n{\n    INSTANCE_ID = uint(gl_PrimitiveID);\n    float _85 = spvNMin(FACTOR[0u], 64.0);\n    gl_TessLevelOuter[0u] = _85;\n    gl_TessLevelOuter[1u] = _85;\n    gl_TessLevelOuter[2u] = _85;\n    gl_TessLevelOuter[3u] = _85;\n    gl_TessLevelInner[0u] = _85;\n    gl_TessLevelInner[1u] = _85;\n    TANGENT.x = SV_POSITION[1u].x - SV_POSITION[0u].x;\n    TANGENT_1.x = SV_POSITION[2u].x - SV_POSITION[0u].x;\n    TANGENT.y = SV_POSITION[1u].y - SV_POSITION[0u].y;\n    TANGENT_1.y = SV_POSITION[2u].y - SV_POSITION[0u].y;\n    TANGENT.z = SV_POSITION[1u].z - SV_POSITION[0u].z;\n    TANGENT_1.z = SV_POSITION[2u].z - SV_POSITION[0u].z;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_point.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 137\n; Schema: 0\n               OpCapability Shader\n               OpCapability Tessellation\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %84 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint TessellationControl %main \"main\" %SV_POSITION %NORMAL %FACTOR %SV_POSITION_0 %NORMAL_0 %INSTANCE_ID %TANGENT %TANGENT_1 %SV_TESSFACTOR %SV_INSIDETESSFACTOR %gl_InvocationID %gl_PrimitiveID\n               OpExecutionMode %main Triangles\n               OpExecutionMode %main SpacingEqual\n               OpExecutionMode %main PointMode\n               OpExecutionMode %main OutputVertices 4\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %FACTOR \"FACTOR\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpName %INSTANCE_ID \"INSTANCE_ID\"\n               OpName %TANGENT \"TANGENT\"\n               OpName %TANGENT_1 \"TANGENT_1\"\n               OpName %SV_TESSFACTOR \"SV_TESSFACTOR\"\n               OpName %SV_INSIDETESSFACTOR \"SV_INSIDETESSFACTOR\"\n               OpName %hull_main \"hull_main\"\n               OpName %patch_main \"patch_main\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %NORMAL Location 1\n               OpDecorate %FACTOR Location 1\n               OpDecorate %FACTOR Component 3\n               OpDecorate %SV_POSITION_0 Location 0\n               OpDecorate %NORMAL_0 Location 1\n               OpDecorate %INSTANCE_ID Location 4\n               OpDecorate %INSTANCE_ID Patch\n               OpDecorate %TANGENT Location 5\n               OpDecorate %TANGENT Patch\n               OpDecorate %TANGENT_1 Location 6\n               OpDecorate %TANGENT_1 Patch\n               OpDecorate %SV_TESSFACTOR BuiltIn TessLevelOuter\n               OpDecorate %SV_TESSFACTOR Patch\n               OpDecorate %SV_INSIDETESSFACTOR BuiltIn TessLevelInner\n               OpDecorate %SV_INSIDETESSFACTOR Patch\n               OpDecorate %gl_InvocationID BuiltIn InvocationId\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n    %uint_32 = OpConstant %uint 32\n%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32\n%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_32 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32\n%_ptr_Input__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_32 Input\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32\n     %FACTOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n     %uint_4 = OpConstant %uint 4\n%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4\n%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4\n%SV_POSITION_0 = OpVariable %_ptr_Output__arr_v4float_uint_4 Output\n%_arr_v3float_uint_4 = OpTypeArray %v3float %uint_4\n%_ptr_Output__arr_v3float_uint_4 = OpTypePointer Output %_arr_v3float_uint_4\n   %NORMAL_0 = OpVariable %_ptr_Output__arr_v3float_uint_4 Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%INSTANCE_ID = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n    %TANGENT = OpVariable %_ptr_Output_v3float Output\n  %TANGENT_1 = OpVariable %_ptr_Output_v3float Output\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4\n%SV_TESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_4 Output\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%SV_INSIDETESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_2 Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n%gl_InvocationID = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n   %float_64 = OpConstant %float 64\n       %bool = OpTypeBool\n  %uint_4104 = OpConstant %uint 4104\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %129\n\n        %129 = OpLabel\n        %123 =   OpFunctionCall %void %hull_main\n        %124 =   OpLoad %uint %gl_InvocationID\n        %126 =   OpIEqual %bool %124 %uint_0\n                 OpControlBarrier %uint_2 %uint_2 %uint_4104\n                 OpSelectionMerge %131 None\n                 OpBranchConditional %126 %130 %131\n\n        %130 =     OpLabel\n        %128 =       OpFunctionCall %void %patch_main\n                     OpBranch %131\n\n        %131 = OpLabel\n                 OpReturn\n               OpFunctionEnd\n  %hull_main = OpFunction %void None %2\n\n         %39 = OpLabel\n                 OpBranch %133\n\n        %133 = OpLabel\n         %44 =   OpLoad %uint %gl_InvocationID\n         %46 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_0\n         %48 =   OpLoad %float %46\n         %49 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_2\n         %53 =   OpLoad %float %52\n         %54 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_3\n         %56 =   OpLoad %float %54\n         %60 =   OpLoad %uint %gl_InvocationID\n         %59 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %60 %uint_0\n                 OpStore %59 %48\n         %62 =   OpLoad %uint %gl_InvocationID\n         %61 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %62 %uint_1\n                 OpStore %61 %51\n         %64 =   OpLoad %uint %gl_InvocationID\n         %63 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %64 %uint_2\n                 OpStore %63 %53\n         %66 =   OpLoad %uint %gl_InvocationID\n         %65 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %66 %uint_3\n                 OpStore %65 %56\n         %67 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_0\n         %68 =   OpLoad %float %67\n         %69 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_1\n         %70 =   OpLoad %float %69\n         %71 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_2\n         %72 =   OpLoad %float %71\n         %75 =   OpLoad %uint %gl_InvocationID\n         %74 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %75 %uint_0\n                 OpStore %74 %68\n         %77 =   OpLoad %uint %gl_InvocationID\n         %76 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %77 %uint_1\n                 OpStore %76 %70\n         %79 =   OpLoad %uint %gl_InvocationID\n         %78 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %79 %uint_2\n                 OpStore %78 %72\n                 OpReturn\n               OpFunctionEnd\n %patch_main = OpFunction %void None %2\n\n         %41 = OpLabel\n                 OpBranch %135\n\n        %135 = OpLabel\n         %81 =   OpLoad %uint %gl_PrimitiveID\n                 OpStore %INSTANCE_ID %81\n         %82 =   OpAccessChain %_ptr_Input_float %FACTOR %uint_0\n         %83 =   OpLoad %float %82\n         %85 =   OpExtInst %float %84 NMin %83 %float_64\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_0\n                 OpStore %87 %85\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_1\n                 OpStore %88 %85\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_2\n                 OpStore %89 %85\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_3\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_0\n                 OpStore %91 %85\n         %92 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_1\n                 OpStore %92 %85\n         %93 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_0\n         %94 =   OpLoad %float %93\n         %95 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_0\n         %96 =   OpLoad %float %95\n         %97 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_0\n         %98 =   OpLoad %float %97\n         %99 =   OpFSub %float %96 %94\n        %100 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_0\n                 OpStore %100 %99\n        %101 =   OpFSub %float %98 %94\n        %102 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_0\n                 OpStore %102 %101\n        %103 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_1\n        %104 =   OpLoad %float %103\n        %105 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_1\n        %106 =   OpLoad %float %105\n        %107 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_1\n        %108 =   OpLoad %float %107\n        %109 =   OpFSub %float %106 %104\n        %110 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_1\n                 OpStore %110 %109\n        %111 =   OpFSub %float %108 %104\n        %112 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_1\n                 OpStore %112 %111\n        %113 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_2\n        %114 =   OpLoad %float %113\n        %115 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_2\n        %116 =   OpLoad %float %115\n        %117 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_2\n        %118 =   OpLoad %float %117\n        %119 =   OpFSub %float %116 %114\n        %120 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_2\n                 OpStore %120 %119\n        %121 =   OpFSub %float %118 %114\n        %122 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_2\n                 OpStore %122 %121\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_point.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_spirv_intrinsics : require\nlayout(vertices = 4) out;\n\nlayout(location = 1) in vec3 NORMAL[];\nlayout(location = 1, component = 3) in float FACTOR[];\nlayout(location = 0) out vec4 SV_POSITION[4];\nlayout(location = 1) out vec3 NORMAL_1[4];\nlayout(location = 4) patch out uint INSTANCE_ID;\nlayout(location = 5) patch out vec3 TANGENT;\nlayout(location = 6) patch out vec3 TANGENT_1;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float spvNMin(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec2 spvNMin(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec3 spvNMin(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec4 spvNMin(vec4, vec4);\n\nvoid hull_main()\n{\n    SV_POSITION[gl_InvocationID].x = gl_in[gl_InvocationID].gl_Position.x;\n    SV_POSITION[gl_InvocationID].y = gl_in[gl_InvocationID].gl_Position.y;\n    SV_POSITION[gl_InvocationID].z = gl_in[gl_InvocationID].gl_Position.z;\n    SV_POSITION[gl_InvocationID].w = gl_in[gl_InvocationID].gl_Position.w;\n    NORMAL_1[gl_InvocationID].x = NORMAL[gl_InvocationID].x;\n    NORMAL_1[gl_InvocationID].y = NORMAL[gl_InvocationID].y;\n    NORMAL_1[gl_InvocationID].z = NORMAL[gl_InvocationID].z;\n}\n\nvoid patch_main()\n{\n    INSTANCE_ID = uint(gl_PrimitiveID);\n    float _85 = spvNMin(FACTOR[0u], 64.0);\n    gl_TessLevelOuter[0u] = _85;\n    gl_TessLevelOuter[1u] = _85;\n    gl_TessLevelOuter[2u] = _85;\n    gl_TessLevelOuter[3u] = _85;\n    gl_TessLevelInner[0u] = _85;\n    gl_TessLevelInner[1u] = _85;\n    TANGENT.x = SV_POSITION[1u].x - SV_POSITION[0u].x;\n    TANGENT_1.x = SV_POSITION[2u].x - SV_POSITION[0u].x;\n    TANGENT.y = SV_POSITION[1u].y - SV_POSITION[0u].y;\n    TANGENT_1.y = SV_POSITION[2u].y - SV_POSITION[0u].y;\n    TANGENT.z = SV_POSITION[1u].z - SV_POSITION[0u].z;\n    TANGENT_1.z = SV_POSITION[2u].z - SV_POSITION[0u].z;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_triangle_ccw.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 137\n; Schema: 0\n               OpCapability Shader\n               OpCapability Tessellation\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %84 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint TessellationControl %main \"main\" %SV_POSITION %NORMAL %FACTOR %SV_POSITION_0 %NORMAL_0 %INSTANCE_ID %TANGENT %TANGENT_1 %SV_TESSFACTOR %SV_INSIDETESSFACTOR %gl_InvocationID %gl_PrimitiveID\n               OpExecutionMode %main Triangles\n               OpExecutionMode %main SpacingFractionalOdd\n               OpExecutionMode %main VertexOrderCcw\n               OpExecutionMode %main OutputVertices 4\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %FACTOR \"FACTOR\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpName %INSTANCE_ID \"INSTANCE_ID\"\n               OpName %TANGENT \"TANGENT\"\n               OpName %TANGENT_1 \"TANGENT_1\"\n               OpName %SV_TESSFACTOR \"SV_TESSFACTOR\"\n               OpName %SV_INSIDETESSFACTOR \"SV_INSIDETESSFACTOR\"\n               OpName %hull_main \"hull_main\"\n               OpName %patch_main \"patch_main\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %NORMAL Location 1\n               OpDecorate %FACTOR Location 1\n               OpDecorate %FACTOR Component 3\n               OpDecorate %SV_POSITION_0 Location 0\n               OpDecorate %NORMAL_0 Location 1\n               OpDecorate %INSTANCE_ID Location 4\n               OpDecorate %INSTANCE_ID Patch\n               OpDecorate %TANGENT Location 5\n               OpDecorate %TANGENT Patch\n               OpDecorate %TANGENT_1 Location 6\n               OpDecorate %TANGENT_1 Patch\n               OpDecorate %SV_TESSFACTOR BuiltIn TessLevelOuter\n               OpDecorate %SV_TESSFACTOR Patch\n               OpDecorate %SV_INSIDETESSFACTOR BuiltIn TessLevelInner\n               OpDecorate %SV_INSIDETESSFACTOR Patch\n               OpDecorate %gl_InvocationID BuiltIn InvocationId\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n    %uint_32 = OpConstant %uint 32\n%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32\n%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_32 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32\n%_ptr_Input__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_32 Input\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32\n     %FACTOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n     %uint_4 = OpConstant %uint 4\n%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4\n%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4\n%SV_POSITION_0 = OpVariable %_ptr_Output__arr_v4float_uint_4 Output\n%_arr_v3float_uint_4 = OpTypeArray %v3float %uint_4\n%_ptr_Output__arr_v3float_uint_4 = OpTypePointer Output %_arr_v3float_uint_4\n   %NORMAL_0 = OpVariable %_ptr_Output__arr_v3float_uint_4 Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%INSTANCE_ID = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n    %TANGENT = OpVariable %_ptr_Output_v3float Output\n  %TANGENT_1 = OpVariable %_ptr_Output_v3float Output\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4\n%SV_TESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_4 Output\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%SV_INSIDETESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_2 Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n%gl_InvocationID = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n   %float_64 = OpConstant %float 64\n       %bool = OpTypeBool\n  %uint_4104 = OpConstant %uint 4104\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %129\n\n        %129 = OpLabel\n        %123 =   OpFunctionCall %void %hull_main\n        %124 =   OpLoad %uint %gl_InvocationID\n        %126 =   OpIEqual %bool %124 %uint_0\n                 OpControlBarrier %uint_2 %uint_2 %uint_4104\n                 OpSelectionMerge %131 None\n                 OpBranchConditional %126 %130 %131\n\n        %130 =     OpLabel\n        %128 =       OpFunctionCall %void %patch_main\n                     OpBranch %131\n\n        %131 = OpLabel\n                 OpReturn\n               OpFunctionEnd\n  %hull_main = OpFunction %void None %2\n\n         %39 = OpLabel\n                 OpBranch %133\n\n        %133 = OpLabel\n         %44 =   OpLoad %uint %gl_InvocationID\n         %46 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_0\n         %48 =   OpLoad %float %46\n         %49 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_2\n         %53 =   OpLoad %float %52\n         %54 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_3\n         %56 =   OpLoad %float %54\n         %60 =   OpLoad %uint %gl_InvocationID\n         %59 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %60 %uint_0\n                 OpStore %59 %48\n         %62 =   OpLoad %uint %gl_InvocationID\n         %61 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %62 %uint_1\n                 OpStore %61 %51\n         %64 =   OpLoad %uint %gl_InvocationID\n         %63 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %64 %uint_2\n                 OpStore %63 %53\n         %66 =   OpLoad %uint %gl_InvocationID\n         %65 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %66 %uint_3\n                 OpStore %65 %56\n         %67 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_0\n         %68 =   OpLoad %float %67\n         %69 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_1\n         %70 =   OpLoad %float %69\n         %71 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_2\n         %72 =   OpLoad %float %71\n         %75 =   OpLoad %uint %gl_InvocationID\n         %74 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %75 %uint_0\n                 OpStore %74 %68\n         %77 =   OpLoad %uint %gl_InvocationID\n         %76 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %77 %uint_1\n                 OpStore %76 %70\n         %79 =   OpLoad %uint %gl_InvocationID\n         %78 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %79 %uint_2\n                 OpStore %78 %72\n                 OpReturn\n               OpFunctionEnd\n %patch_main = OpFunction %void None %2\n\n         %41 = OpLabel\n                 OpBranch %135\n\n        %135 = OpLabel\n         %81 =   OpLoad %uint %gl_PrimitiveID\n                 OpStore %INSTANCE_ID %81\n         %82 =   OpAccessChain %_ptr_Input_float %FACTOR %uint_0\n         %83 =   OpLoad %float %82\n         %85 =   OpExtInst %float %84 NMin %83 %float_64\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_0\n                 OpStore %87 %85\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_1\n                 OpStore %88 %85\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_2\n                 OpStore %89 %85\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_3\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_0\n                 OpStore %91 %85\n         %92 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_1\n                 OpStore %92 %85\n         %93 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_0\n         %94 =   OpLoad %float %93\n         %95 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_0\n         %96 =   OpLoad %float %95\n         %97 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_0\n         %98 =   OpLoad %float %97\n         %99 =   OpFSub %float %96 %94\n        %100 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_0\n                 OpStore %100 %99\n        %101 =   OpFSub %float %98 %94\n        %102 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_0\n                 OpStore %102 %101\n        %103 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_1\n        %104 =   OpLoad %float %103\n        %105 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_1\n        %106 =   OpLoad %float %105\n        %107 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_1\n        %108 =   OpLoad %float %107\n        %109 =   OpFSub %float %106 %104\n        %110 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_1\n                 OpStore %110 %109\n        %111 =   OpFSub %float %108 %104\n        %112 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_1\n                 OpStore %112 %111\n        %113 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_2\n        %114 =   OpLoad %float %113\n        %115 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_2\n        %116 =   OpLoad %float %115\n        %117 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_2\n        %118 =   OpLoad %float %117\n        %119 =   OpFSub %float %116 %114\n        %120 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_2\n                 OpStore %120 %119\n        %121 =   OpFSub %float %118 %114\n        %122 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_2\n                 OpStore %122 %121\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_triangle_ccw.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_spirv_intrinsics : require\nlayout(vertices = 4) out;\n\nlayout(location = 1) in vec3 NORMAL[];\nlayout(location = 1, component = 3) in float FACTOR[];\nlayout(location = 0) out vec4 SV_POSITION[4];\nlayout(location = 1) out vec3 NORMAL_1[4];\nlayout(location = 4) patch out uint INSTANCE_ID;\nlayout(location = 5) patch out vec3 TANGENT;\nlayout(location = 6) patch out vec3 TANGENT_1;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float spvNMin(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec2 spvNMin(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec3 spvNMin(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec4 spvNMin(vec4, vec4);\n\nvoid hull_main()\n{\n    SV_POSITION[gl_InvocationID].x = gl_in[gl_InvocationID].gl_Position.x;\n    SV_POSITION[gl_InvocationID].y = gl_in[gl_InvocationID].gl_Position.y;\n    SV_POSITION[gl_InvocationID].z = gl_in[gl_InvocationID].gl_Position.z;\n    SV_POSITION[gl_InvocationID].w = gl_in[gl_InvocationID].gl_Position.w;\n    NORMAL_1[gl_InvocationID].x = NORMAL[gl_InvocationID].x;\n    NORMAL_1[gl_InvocationID].y = NORMAL[gl_InvocationID].y;\n    NORMAL_1[gl_InvocationID].z = NORMAL[gl_InvocationID].z;\n}\n\nvoid patch_main()\n{\n    INSTANCE_ID = uint(gl_PrimitiveID);\n    float _85 = spvNMin(FACTOR[0u], 64.0);\n    gl_TessLevelOuter[0u] = _85;\n    gl_TessLevelOuter[1u] = _85;\n    gl_TessLevelOuter[2u] = _85;\n    gl_TessLevelOuter[3u] = _85;\n    gl_TessLevelInner[0u] = _85;\n    gl_TessLevelInner[1u] = _85;\n    TANGENT.x = SV_POSITION[1u].x - SV_POSITION[0u].x;\n    TANGENT_1.x = SV_POSITION[2u].x - SV_POSITION[0u].x;\n    TANGENT.y = SV_POSITION[1u].y - SV_POSITION[0u].y;\n    TANGENT_1.y = SV_POSITION[2u].y - SV_POSITION[0u].y;\n    TANGENT.z = SV_POSITION[1u].z - SV_POSITION[0u].z;\n    TANGENT_1.z = SV_POSITION[2u].z - SV_POSITION[0u].z;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_triangle_cw.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 137\n; Schema: 0\n               OpCapability Shader\n               OpCapability Tessellation\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %84 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint TessellationControl %main \"main\" %SV_POSITION %NORMAL %FACTOR %SV_POSITION_0 %NORMAL_0 %INSTANCE_ID %TANGENT %TANGENT_1 %SV_TESSFACTOR %SV_INSIDETESSFACTOR %gl_InvocationID %gl_PrimitiveID\n               OpExecutionMode %main Triangles\n               OpExecutionMode %main SpacingFractionalEven\n               OpExecutionMode %main VertexOrderCw\n               OpExecutionMode %main OutputVertices 4\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %FACTOR \"FACTOR\"\n               OpName %SV_POSITION_0 \"SV_POSITION\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpName %INSTANCE_ID \"INSTANCE_ID\"\n               OpName %TANGENT \"TANGENT\"\n               OpName %TANGENT_1 \"TANGENT_1\"\n               OpName %SV_TESSFACTOR \"SV_TESSFACTOR\"\n               OpName %SV_INSIDETESSFACTOR \"SV_INSIDETESSFACTOR\"\n               OpName %hull_main \"hull_main\"\n               OpName %patch_main \"patch_main\"\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %NORMAL Location 1\n               OpDecorate %FACTOR Location 1\n               OpDecorate %FACTOR Component 3\n               OpDecorate %SV_POSITION_0 Location 0\n               OpDecorate %NORMAL_0 Location 1\n               OpDecorate %INSTANCE_ID Location 4\n               OpDecorate %INSTANCE_ID Patch\n               OpDecorate %TANGENT Location 5\n               OpDecorate %TANGENT Patch\n               OpDecorate %TANGENT_1 Location 6\n               OpDecorate %TANGENT_1 Patch\n               OpDecorate %SV_TESSFACTOR BuiltIn TessLevelOuter\n               OpDecorate %SV_TESSFACTOR Patch\n               OpDecorate %SV_INSIDETESSFACTOR BuiltIn TessLevelInner\n               OpDecorate %SV_INSIDETESSFACTOR Patch\n               OpDecorate %gl_InvocationID BuiltIn InvocationId\n               OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n       %uint = OpTypeInt 32 0\n    %uint_32 = OpConstant %uint 32\n%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32\n%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32\n%SV_POSITION = OpVariable %_ptr_Input__arr_v4float_uint_32 Input\n    %v3float = OpTypeVector %float 3\n%_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32\n%_ptr_Input__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32\n     %NORMAL = OpVariable %_ptr_Input__arr_v3float_uint_32 Input\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32\n     %FACTOR = OpVariable %_ptr_Input__arr_float_uint_32 Input\n     %uint_4 = OpConstant %uint 4\n%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4\n%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4\n%SV_POSITION_0 = OpVariable %_ptr_Output__arr_v4float_uint_4 Output\n%_arr_v3float_uint_4 = OpTypeArray %v3float %uint_4\n%_ptr_Output__arr_v3float_uint_4 = OpTypePointer Output %_arr_v3float_uint_4\n   %NORMAL_0 = OpVariable %_ptr_Output__arr_v3float_uint_4 Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%INSTANCE_ID = OpVariable %_ptr_Output_uint Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n    %TANGENT = OpVariable %_ptr_Output_v3float Output\n  %TANGENT_1 = OpVariable %_ptr_Output_v3float Output\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4\n%SV_TESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_4 Output\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%SV_INSIDETESSFACTOR = OpVariable %_ptr_Output__arr_float_uint_2 Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n%gl_InvocationID = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n%_ptr_Output_float = OpTypePointer Output %float\n%gl_PrimitiveID = OpVariable %_ptr_Input_uint Input\n   %float_64 = OpConstant %float 64\n       %bool = OpTypeBool\n  %uint_4104 = OpConstant %uint 4104\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %129\n\n        %129 = OpLabel\n        %123 =   OpFunctionCall %void %hull_main\n        %124 =   OpLoad %uint %gl_InvocationID\n        %126 =   OpIEqual %bool %124 %uint_0\n                 OpControlBarrier %uint_2 %uint_2 %uint_4104\n                 OpSelectionMerge %131 None\n                 OpBranchConditional %126 %130 %131\n\n        %130 =     OpLabel\n        %128 =       OpFunctionCall %void %patch_main\n                     OpBranch %131\n\n        %131 = OpLabel\n                 OpReturn\n               OpFunctionEnd\n  %hull_main = OpFunction %void None %2\n\n         %39 = OpLabel\n                 OpBranch %133\n\n        %133 = OpLabel\n         %44 =   OpLoad %uint %gl_InvocationID\n         %46 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_0\n         %48 =   OpLoad %float %46\n         %49 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_2\n         %53 =   OpLoad %float %52\n         %54 =   OpAccessChain %_ptr_Input_float %SV_POSITION %44 %uint_3\n         %56 =   OpLoad %float %54\n         %60 =   OpLoad %uint %gl_InvocationID\n         %59 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %60 %uint_0\n                 OpStore %59 %48\n         %62 =   OpLoad %uint %gl_InvocationID\n         %61 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %62 %uint_1\n                 OpStore %61 %51\n         %64 =   OpLoad %uint %gl_InvocationID\n         %63 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %64 %uint_2\n                 OpStore %63 %53\n         %66 =   OpLoad %uint %gl_InvocationID\n         %65 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %66 %uint_3\n                 OpStore %65 %56\n         %67 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_0\n         %68 =   OpLoad %float %67\n         %69 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_1\n         %70 =   OpLoad %float %69\n         %71 =   OpAccessChain %_ptr_Input_float %NORMAL %44 %uint_2\n         %72 =   OpLoad %float %71\n         %75 =   OpLoad %uint %gl_InvocationID\n         %74 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %75 %uint_0\n                 OpStore %74 %68\n         %77 =   OpLoad %uint %gl_InvocationID\n         %76 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %77 %uint_1\n                 OpStore %76 %70\n         %79 =   OpLoad %uint %gl_InvocationID\n         %78 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %79 %uint_2\n                 OpStore %78 %72\n                 OpReturn\n               OpFunctionEnd\n %patch_main = OpFunction %void None %2\n\n         %41 = OpLabel\n                 OpBranch %135\n\n        %135 = OpLabel\n         %81 =   OpLoad %uint %gl_PrimitiveID\n                 OpStore %INSTANCE_ID %81\n         %82 =   OpAccessChain %_ptr_Input_float %FACTOR %uint_0\n         %83 =   OpLoad %float %82\n         %85 =   OpExtInst %float %84 NMin %83 %float_64\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_0\n                 OpStore %87 %85\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_1\n                 OpStore %88 %85\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_2\n                 OpStore %89 %85\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TESSFACTOR %uint_3\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_0\n                 OpStore %91 %85\n         %92 =   OpAccessChain %_ptr_Output_float %SV_INSIDETESSFACTOR %uint_1\n                 OpStore %92 %85\n         %93 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_0\n         %94 =   OpLoad %float %93\n         %95 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_0\n         %96 =   OpLoad %float %95\n         %97 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_0\n         %98 =   OpLoad %float %97\n         %99 =   OpFSub %float %96 %94\n        %100 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_0\n                 OpStore %100 %99\n        %101 =   OpFSub %float %98 %94\n        %102 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_0\n                 OpStore %102 %101\n        %103 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_1\n        %104 =   OpLoad %float %103\n        %105 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_1\n        %106 =   OpLoad %float %105\n        %107 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_1\n        %108 =   OpLoad %float %107\n        %109 =   OpFSub %float %106 %104\n        %110 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_1\n                 OpStore %110 %109\n        %111 =   OpFSub %float %108 %104\n        %112 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_1\n                 OpStore %112 %111\n        %113 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_0 %uint_2\n        %114 =   OpLoad %float %113\n        %115 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_1 %uint_2\n        %116 =   OpLoad %float %115\n        %117 =   OpAccessChain %_ptr_Output_float %SV_POSITION_0 %uint_2 %uint_2\n        %118 =   OpLoad %float %117\n        %119 =   OpFSub %float %116 %114\n        %120 =   OpAccessChain %_ptr_Output_float %TANGENT %uint_2\n                 OpStore %120 %119\n        %121 =   OpFSub %float %118 %114\n        %122 =   OpAccessChain %_ptr_Output_float %TANGENT_1 %uint_2\n                 OpStore %122 %121\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_hs_triangle_cw.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_spirv_intrinsics : require\nlayout(vertices = 4) out;\n\nlayout(location = 1) in vec3 NORMAL[];\nlayout(location = 1, component = 3) in float FACTOR[];\nlayout(location = 0) out vec4 SV_POSITION[4];\nlayout(location = 1) out vec3 NORMAL_1[4];\nlayout(location = 4) patch out uint INSTANCE_ID;\nlayout(location = 5) patch out vec3 TANGENT;\nlayout(location = 6) patch out vec3 TANGENT_1;\n\nspirv_instruction(set = \"GLSL.std.450\", id = 79) float spvNMin(float, float);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec2 spvNMin(vec2, vec2);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec3 spvNMin(vec3, vec3);\nspirv_instruction(set = \"GLSL.std.450\", id = 79) vec4 spvNMin(vec4, vec4);\n\nvoid hull_main()\n{\n    SV_POSITION[gl_InvocationID].x = gl_in[gl_InvocationID].gl_Position.x;\n    SV_POSITION[gl_InvocationID].y = gl_in[gl_InvocationID].gl_Position.y;\n    SV_POSITION[gl_InvocationID].z = gl_in[gl_InvocationID].gl_Position.z;\n    SV_POSITION[gl_InvocationID].w = gl_in[gl_InvocationID].gl_Position.w;\n    NORMAL_1[gl_InvocationID].x = NORMAL[gl_InvocationID].x;\n    NORMAL_1[gl_InvocationID].y = NORMAL[gl_InvocationID].y;\n    NORMAL_1[gl_InvocationID].z = NORMAL[gl_InvocationID].z;\n}\n\nvoid patch_main()\n{\n    INSTANCE_ID = uint(gl_PrimitiveID);\n    float _85 = spvNMin(FACTOR[0u], 64.0);\n    gl_TessLevelOuter[0u] = _85;\n    gl_TessLevelOuter[1u] = _85;\n    gl_TessLevelOuter[2u] = _85;\n    gl_TessLevelOuter[3u] = _85;\n    gl_TessLevelInner[0u] = _85;\n    gl_TessLevelInner[1u] = _85;\n    TANGENT.x = SV_POSITION[1u].x - SV_POSITION[0u].x;\n    TANGENT_1.x = SV_POSITION[2u].x - SV_POSITION[0u].x;\n    TANGENT.y = SV_POSITION[1u].y - SV_POSITION[0u].y;\n    TANGENT_1.y = SV_POSITION[2u].y - SV_POSITION[0u].y;\n    TANGENT.z = SV_POSITION[1u].z - SV_POSITION[0u].z;\n    TANGENT_1.z = SV_POSITION[2u].z - SV_POSITION[0u].z;\n}\n\nvoid main()\n{\n    hull_main();\n    barrier();\n    if (gl_InvocationID == 0u)\n    {\n        patch_main();\n    }\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_builtins.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampleRateShading\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_ISFRONTFACE %SV_SAMPLEINDEX %SV_COVERAGE %gl_SampleMask\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_ISFRONTFACE \"SV_ISFRONTFACE\"\n               OpName %SV_SAMPLEINDEX \"SV_SAMPLEINDEX\"\n               OpName %SV_COVERAGE \"SV_COVERAGE\"\n               OpDecorate %SV_ISFRONTFACE BuiltIn FrontFacing\n               OpDecorate %SV_SAMPLEINDEX BuiltIn SampleId\n               OpDecorate %SV_SAMPLEINDEX Flat\n               OpDecorate %SV_COVERAGE BuiltIn SampleMask\n               OpDecorate %gl_SampleMask BuiltIn SampleMask\n               OpDecorate %gl_SampleMask Flat\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n       %bool = OpTypeBool\n%_ptr_Input_bool = OpTypePointer Input %bool\n%SV_ISFRONTFACE = OpVariable %_ptr_Input_bool Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_SAMPLEINDEX = OpVariable %_ptr_Input_uint Input\n     %uint_1 = OpConstant %uint 1\n%_arr_uint_uint_1 = OpTypeArray %uint %uint_1\n%_ptr_Output__arr_uint_uint_1 = OpTypePointer Output %_arr_uint_uint_1\n%SV_COVERAGE = OpVariable %_ptr_Output__arr_uint_uint_1 Output\n%_ptr_Input__arr_uint_uint_1 = OpTypePointer Input %_arr_uint_uint_1\n%gl_SampleMask = OpVariable %_ptr_Input__arr_uint_uint_1 Input\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %26\n\n         %26 = OpLabel\n         %17 =   OpAccessChain %_ptr_Input_uint %gl_SampleMask %uint_0\n         %19 =   OpLoad %uint %17\n         %20 =   OpLoad %uint %SV_SAMPLEINDEX\n         %21 =   OpBitFieldUExtract %uint %19 %uint_0 %20\n         %22 =   OpLoad %bool %SV_ISFRONTFACE\n         %23 =   OpSelect %uint %22 %21 %uint_0\n         %25 =   OpAccessChain %_ptr_Output_uint %SV_COVERAGE %uint_0\n                 OpStore %25 %23\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_builtins.glsl",
    "content": "GLSL:\n#version 460\n\nvoid main()\n{\n    gl_SampleMask[0u] = int(gl_FrontFacing ? bitfieldExtract(uint(gl_SampleMaskIn[0u]), int(0u), int(uint(gl_SampleID))) : 0u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %DELTA %SV_DEPTH\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main DepthReplacing\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %DELTA \"DELTA\"\n               OpName %SV_DEPTH \"SV_DEPTH\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %DELTA Location 1\n               OpDecorate %SV_DEPTH BuiltIn FragDepth\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_float = OpTypePointer Input %float\n      %DELTA = OpVariable %_ptr_Input_float Input\n%_ptr_Output_float = OpTypePointer Output %float\n   %SV_DEPTH = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %19\n\n         %19 = OpLabel\n         %13 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_2\n         %16 =   OpLoad %float %13\n         %17 =   OpLoad %float %DELTA\n         %18 =   OpFAdd %float %17 %16\n                 OpStore %SV_DEPTH %18\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 1) in float DELTA;\n\nvoid main()\n{\n    gl_FragDepth = DELTA + gl_FragCoord.z;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_depth_greater.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %DELTA %SV_DEPTH\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main DepthReplacing\n               OpExecutionMode %main DepthGreater\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %DELTA \"DELTA\"\n               OpName %SV_DEPTH \"SV_DEPTH\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %DELTA Location 1\n               OpDecorate %SV_DEPTH BuiltIn FragDepth\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_float = OpTypePointer Input %float\n      %DELTA = OpVariable %_ptr_Input_float Input\n%_ptr_Output_float = OpTypePointer Output %float\n   %SV_DEPTH = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %19\n\n         %19 = OpLabel\n         %13 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_2\n         %16 =   OpLoad %float %13\n         %17 =   OpLoad %float %DELTA\n         %18 =   OpFAdd %float %17 %16\n                 OpStore %SV_DEPTH %18\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_depth_greater.glsl",
    "content": "GLSL:\n#version 460\nlayout(depth_greater) out float gl_FragDepth;\n\nlayout(location = 1) in float DELTA;\n\nvoid main()\n{\n    gl_FragDepth = DELTA + gl_FragCoord.z;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_depth_less.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_POSITION %DELTA %SV_DEPTH\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main DepthReplacing\n               OpExecutionMode %main DepthLess\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %DELTA \"DELTA\"\n               OpName %SV_DEPTH \"SV_DEPTH\"\n               OpDecorate %SV_POSITION BuiltIn FragCoord\n               OpDecorate %DELTA Location 1\n               OpDecorate %SV_DEPTH BuiltIn FragDepth\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n%SV_POSITION = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_float = OpTypePointer Input %float\n      %DELTA = OpVariable %_ptr_Input_float Input\n%_ptr_Output_float = OpTypePointer Output %float\n   %SV_DEPTH = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %19\n\n         %19 = OpLabel\n         %13 =   OpAccessChain %_ptr_Input_float %SV_POSITION %uint_2\n         %16 =   OpLoad %float %13\n         %17 =   OpLoad %float %DELTA\n         %18 =   OpFAdd %float %17 %16\n                 OpStore %SV_DEPTH %18\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_depth_less.glsl",
    "content": "GLSL:\n#version 460\nlayout(depth_less) out float gl_FragDepth;\n\nlayout(location = 1) in float DELTA;\n\nvoid main()\n{\n    gl_FragDepth = DELTA + gl_FragCoord.z;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_stencil.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 13\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability StencilExportEXT\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_shader_stencil_export\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %STENCIL_REF %SV_STENCILREF\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main StencilRefReplacingEXT\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %STENCIL_REF \"STENCIL_REF\"\n               OpName %SV_STENCILREF \"SV_STENCILREF\"\n               OpDecorate %STENCIL_REF Flat\n               OpDecorate %STENCIL_REF Location 0\n               OpDecorate %SV_STENCILREF BuiltIn FragStencilRefEXT\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%STENCIL_REF = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_STENCILREF = OpVariable %_ptr_Output_uint Output\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %11\n\n         %11 = OpLabel\n         %10 =   OpLoad %uint %STENCIL_REF\n                 OpStore %SV_STENCILREF %10\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_export_stencil.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_shader_stencil_export : require\n\nlayout(location = 0) flat in uint STENCIL_REF;\n\nvoid main()\n{\n    gl_FragStencilRefARB = int(STENCIL_REF);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_fully_covered.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 17\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability FragmentFullyCoveredEXT\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_fragment_fully_covered\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_TARGET %10\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %10 BuiltIn FullyCoveredEXT\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n       %bool = OpTypeBool\n%_ptr_Input_bool = OpTypePointer Input %bool\n         %10 = OpVariable %_ptr_Input_bool Input\n    %float_1 = OpConstant %float 1\n    %float_0 = OpConstant %float 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %15\n\n         %15 = OpLabel\n         %11 =   OpLoad %bool %10\n         %12 =   OpSelect %float %11 %float_1 %float_0\n                 OpStore %SV_TARGET %12\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_fully_covered.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_NV_conservative_raster_underestimation : require\n\nlayout(location = 0) out float SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = float(gl_FragFullyCoveredNV);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_interpolate_centroid.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampleRateShading\n               OpCapability InterpolationFunction\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %17 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %IN_SCALAR %IN_VECTOR %IN_VECTOR_1 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %IN_SCALAR \"IN_SCALAR\"\n               OpName %IN_VECTOR \"IN_VECTOR\"\n               OpName %IN_VECTOR_1 \"IN_VECTOR_1\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %IN_SCALAR NoPerspective\n               OpDecorate %IN_SCALAR Location 0\n               OpDecorate %IN_VECTOR Location 1\n               OpDecorate %IN_VECTOR_1 Sample\n               OpDecorate %IN_VECTOR_1 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n%_ptr_Input_float = OpTypePointer Input %float\n  %IN_SCALAR = OpVariable %_ptr_Input_float Input\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n  %IN_VECTOR = OpVariable %_ptr_Input_v3float Input\n%IN_VECTOR_1 = OpVariable %_ptr_Input_v3float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n%SV_TARGET_1 = OpVariable %_ptr_Output_v3float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %35\n\n         %35 = OpLabel\n         %18 =   OpExtInst %float %17 InterpolateAtCentroid %IN_SCALAR\n                 OpStore %SV_TARGET %18\n         %19 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_0\n         %22 =   OpExtInst %float %17 InterpolateAtCentroid %19\n         %23 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_1\n         %25 =   OpExtInst %float %17 InterpolateAtCentroid %23\n         %26 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_2\n         %28 =   OpExtInst %float %17 InterpolateAtCentroid %26\n         %30 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %30 %22\n         %31 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %31 %25\n         %32 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %32 %28\n         %33 =   OpAccessChain %_ptr_Input_float %IN_VECTOR_1 %uint_1\n         %34 =   OpExtInst %float %17 InterpolateAtCentroid %33\n                 OpStore %SV_TARGET_2 %34\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_interpolate_centroid.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) noperspective in float IN_SCALAR;\nlayout(location = 1) in vec3 IN_VECTOR;\nlayout(location = 2) sample in vec3 IN_VECTOR_1;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out vec3 SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\n\nvoid main()\n{\n    SV_TARGET = interpolateAtCentroid(IN_SCALAR);\n    SV_TARGET_1.x = interpolateAtCentroid(IN_VECTOR.x);\n    SV_TARGET_1.y = interpolateAtCentroid(IN_VECTOR.y);\n    SV_TARGET_1.z = interpolateAtCentroid(IN_VECTOR.z);\n    SV_TARGET_2 = interpolateAtCentroid(IN_VECTOR_1.y);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_interpolate_offset.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\n               OpCapability Shader\n               OpCapability InterpolationFunction\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %28 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %OFFSET %IN_SCALAR %IN_VECTOR %IN_VECTOR_1 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %IN_SCALAR \"IN_SCALAR\"\n               OpName %IN_VECTOR \"IN_VECTOR\"\n               OpName %IN_VECTOR_1 \"IN_VECTOR_1\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %OFFSET Location 3\n               OpDecorate %IN_SCALAR NoPerspective\n               OpDecorate %IN_SCALAR Location 0\n               OpDecorate %IN_VECTOR Location 1\n               OpDecorate %IN_VECTOR_1 Centroid\n               OpDecorate %IN_VECTOR_1 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n     %OFFSET = OpVariable %_ptr_Input_v2float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %IN_SCALAR = OpVariable %_ptr_Input_float Input\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n  %IN_VECTOR = OpVariable %_ptr_Input_v3float Input\n%IN_VECTOR_1 = OpVariable %_ptr_Input_v3float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n%SV_TARGET_1 = OpVariable %_ptr_Output_v3float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %43\n\n         %43 = OpLabel\n         %20 =   OpAccessChain %_ptr_Input_float %OFFSET %uint_0\n         %23 =   OpLoad %float %20\n         %24 =   OpAccessChain %_ptr_Input_float %OFFSET %uint_1\n         %26 =   OpLoad %float %24\n         %27 =   OpCompositeConstruct %v2float %23 %26\n         %29 =   OpExtInst %float %28 InterpolateAtOffset %IN_SCALAR %27\n                 OpStore %SV_TARGET %29\n         %30 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_0\n         %31 =   OpExtInst %float %28 InterpolateAtOffset %30 %27\n         %32 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_1\n         %33 =   OpExtInst %float %28 InterpolateAtOffset %32 %27\n         %34 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_2\n         %36 =   OpExtInst %float %28 InterpolateAtOffset %34 %27\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %38 %31\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %39 %33\n         %40 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %40 %36\n         %41 =   OpAccessChain %_ptr_Input_float %IN_VECTOR_1 %uint_1\n         %42 =   OpExtInst %float %28 InterpolateAtOffset %41 %27\n                 OpStore %SV_TARGET_2 %42\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_interpolate_offset.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 3) in vec2 OFFSET;\nlayout(location = 0) noperspective in float IN_SCALAR;\nlayout(location = 1) in vec3 IN_VECTOR;\nlayout(location = 2) centroid in vec3 IN_VECTOR_1;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out vec3 SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\n\nvoid main()\n{\n    vec2 _27 = vec2(OFFSET.x, OFFSET.y);\n    SV_TARGET = interpolateAtOffset(IN_SCALAR, _27);\n    SV_TARGET_1.x = interpolateAtOffset(IN_VECTOR.x, _27);\n    SV_TARGET_1.y = interpolateAtOffset(IN_VECTOR.y, _27);\n    SV_TARGET_1.z = interpolateAtOffset(IN_VECTOR.z, _27);\n    SV_TARGET_2 = interpolateAtOffset(IN_VECTOR_1.y, _27);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_interpolate_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampleRateShading\n               OpCapability InterpolationFunction\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %21 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_SAMPLEINDEX %IN_SCALAR %IN_VECTOR %IN_VECTOR_1 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_SAMPLEINDEX \"SV_SAMPLEINDEX\"\n               OpName %IN_SCALAR \"IN_SCALAR\"\n               OpName %IN_VECTOR \"IN_VECTOR\"\n               OpName %IN_VECTOR_1 \"IN_VECTOR_1\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %SV_SAMPLEINDEX BuiltIn SampleId\n               OpDecorate %SV_SAMPLEINDEX Flat\n               OpDecorate %IN_SCALAR NoPerspective\n               OpDecorate %IN_SCALAR Location 0\n               OpDecorate %IN_VECTOR Location 1\n               OpDecorate %IN_VECTOR_1 Centroid\n               OpDecorate %IN_VECTOR_1 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_SAMPLEINDEX = OpVariable %_ptr_Input_uint Input\n      %float = OpTypeFloat 32\n%_ptr_Input_float = OpTypePointer Input %float\n  %IN_SCALAR = OpVariable %_ptr_Input_float Input\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n  %IN_VECTOR = OpVariable %_ptr_Input_v3float Input\n%IN_VECTOR_1 = OpVariable %_ptr_Input_v3float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n%SV_TARGET_1 = OpVariable %_ptr_Output_v3float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %20 =   OpLoad %uint %SV_SAMPLEINDEX\n         %22 =   OpExtInst %float %21 InterpolateAtSample %IN_SCALAR %20\n                 OpStore %SV_TARGET %22\n         %23 =   OpLoad %uint %SV_SAMPLEINDEX\n         %24 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_0\n         %26 =   OpExtInst %float %21 InterpolateAtSample %24 %23\n         %27 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_1\n         %29 =   OpExtInst %float %21 InterpolateAtSample %27 %23\n         %30 =   OpAccessChain %_ptr_Input_float %IN_VECTOR %uint_2\n         %32 =   OpExtInst %float %21 InterpolateAtSample %30 %23\n         %34 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %34 %26\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %35 %29\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %36 %32\n         %37 =   OpLoad %uint %SV_SAMPLEINDEX\n         %38 =   OpAccessChain %_ptr_Input_float %IN_VECTOR_1 %uint_1\n         %39 =   OpExtInst %float %21 InterpolateAtSample %38 %37\n                 OpStore %SV_TARGET_2 %39\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_ps_interpolate_sample.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) noperspective in float IN_SCALAR;\nlayout(location = 1) in vec3 IN_VECTOR;\nlayout(location = 2) centroid in vec3 IN_VECTOR_1;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out vec3 SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\n\nvoid main()\n{\n    SV_TARGET = interpolateAtSample(IN_SCALAR, uint(gl_SampleID));\n    SV_TARGET_1.x = interpolateAtSample(IN_VECTOR.x, uint(gl_SampleID));\n    SV_TARGET_1.y = interpolateAtSample(IN_VECTOR.y, uint(gl_SampleID));\n    SV_TARGET_1.z = interpolateAtSample(IN_VECTOR.z, uint(gl_SampleID));\n    SV_TARGET_2 = interpolateAtSample(IN_VECTOR_1.y, uint(gl_SampleID));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 74\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %POSITION %NORMAL %TANGENT %TANGENT_1 %COLOR_1 %SV_POSITION %NORMAL_0 %COLOR %TANGENT_0 %TANGENT_1_0\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %POSITION \"POSITION\"\n               OpName %NORMAL \"NORMAL\"\n               OpName %TANGENT \"TANGENT\"\n               OpName %TANGENT_1 \"TANGENT_1\"\n               OpName %COLOR_1 \"COLOR_1\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpName %NORMAL_0 \"NORMAL\"\n               OpName %COLOR \"COLOR\"\n               OpName %TANGENT_0 \"TANGENT\"\n               OpName %TANGENT_1_0 \"TANGENT_1\"\n               OpDecorate %POSITION Location 0\n               OpDecorate %NORMAL Location 1\n               OpDecorate %TANGENT Location 2\n               OpDecorate %TANGENT_1 Location 3\n               OpDecorate %COLOR_1 Location 4\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %NORMAL_0 Location 1\n               OpDecorate %COLOR Location 1\n               OpDecorate %COLOR Component 3\n               OpDecorate %TANGENT_0 Location 2\n               OpDecorate %TANGENT_1_0 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %POSITION = OpVariable %_ptr_Input_v3float Input\n     %NORMAL = OpVariable %_ptr_Input_v3float Input\n    %TANGENT = OpVariable %_ptr_Input_v3float Input\n  %TANGENT_1 = OpVariable %_ptr_Input_v3float Input\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n    %COLOR_1 = OpVariable %_ptr_Input_uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_v3float = OpTypePointer Output %v3float\n   %NORMAL_0 = OpVariable %_ptr_Output_v3float Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n      %COLOR = OpVariable %_ptr_Output_uint Output\n  %TANGENT_0 = OpVariable %_ptr_Output_v3float Output\n%TANGENT_1_0 = OpVariable %_ptr_Output_v3float Output\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_2 = OpConstant %uint 2\n     %uint_1 = OpConstant %uint 1\n     %uint_0 = OpConstant %uint 0\n    %float_1 = OpConstant %float 1\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %72\n\n         %72 = OpLabel\n         %25 =   OpAccessChain %_ptr_Input_float %POSITION %uint_2\n         %27 =   OpLoad %float %25\n         %28 =   OpAccessChain %_ptr_Input_float %POSITION %uint_1\n         %30 =   OpLoad %float %28\n         %31 =   OpAccessChain %_ptr_Input_float %POSITION %uint_0\n         %33 =   OpLoad %float %31\n         %37 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_0\n                 OpStore %37 %33\n         %38 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_1\n                 OpStore %38 %30\n         %39 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_2\n                 OpStore %39 %27\n         %40 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_3\n                 OpStore %40 %float_1\n         %42 =   OpAccessChain %_ptr_Input_float %NORMAL %uint_0\n         %43 =   OpLoad %float %42\n         %44 =   OpAccessChain %_ptr_Input_float %NORMAL %uint_1\n         %45 =   OpLoad %float %44\n         %46 =   OpAccessChain %_ptr_Input_float %NORMAL %uint_2\n         %47 =   OpLoad %float %46\n         %49 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_0\n                 OpStore %49 %43\n         %50 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_1\n                 OpStore %50 %45\n         %51 =   OpAccessChain %_ptr_Output_float %NORMAL_0 %uint_2\n                 OpStore %51 %47\n         %52 =   OpLoad %uint %COLOR_1\n                 OpStore %COLOR %52\n         %53 =   OpAccessChain %_ptr_Input_float %TANGENT %uint_0\n         %54 =   OpLoad %float %53\n         %55 =   OpAccessChain %_ptr_Input_float %TANGENT %uint_1\n         %56 =   OpLoad %float %55\n         %57 =   OpAccessChain %_ptr_Input_float %TANGENT %uint_2\n         %58 =   OpLoad %float %57\n         %60 =   OpAccessChain %_ptr_Output_float %TANGENT_0 %uint_0\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %TANGENT_0 %uint_1\n                 OpStore %61 %56\n         %62 =   OpAccessChain %_ptr_Output_float %TANGENT_0 %uint_2\n                 OpStore %62 %58\n         %63 =   OpAccessChain %_ptr_Input_float %TANGENT_1 %uint_0\n         %64 =   OpLoad %float %63\n         %65 =   OpAccessChain %_ptr_Output_float %TANGENT_1_0 %uint_0\n                 OpStore %65 %64\n         %66 =   OpAccessChain %_ptr_Input_float %TANGENT_1 %uint_1\n         %67 =   OpLoad %float %66\n         %68 =   OpAccessChain %_ptr_Output_float %TANGENT_1_0 %uint_1\n                 OpStore %68 %67\n         %69 =   OpAccessChain %_ptr_Input_float %TANGENT_1 %uint_2\n         %70 =   OpLoad %float %69\n         %71 =   OpAccessChain %_ptr_Output_float %TANGENT_1_0 %uint_2\n                 OpStore %71 %70\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) in vec3 POSITION;\nlayout(location = 1) in vec3 NORMAL;\nlayout(location = 2) in vec3 TANGENT;\nlayout(location = 3) in vec3 TANGENT_1;\nlayout(location = 4) in uint COLOR_1;\nlayout(location = 1) out vec3 NORMAL_1;\nlayout(location = 1, component = 3) out uint COLOR;\nlayout(location = 2) out vec3 TANGENT_2;\nlayout(location = 3) out vec3 TANGENT_1_1;\n\nvoid main()\n{\n    gl_Position.x = POSITION.x;\n    gl_Position.y = POSITION.y;\n    gl_Position.z = POSITION.z;\n    gl_Position.w = 1.0;\n    NORMAL_1.x = NORMAL.x;\n    NORMAL_1.y = NORMAL.y;\n    NORMAL_1.z = NORMAL.z;\n    COLOR = COLOR_1;\n    TANGENT_2.x = TANGENT.x;\n    TANGENT_2.y = TANGENT.y;\n    TANGENT_2.z = TANGENT.z;\n    TANGENT_1_1.x = TANGENT_1.x;\n    TANGENT_1_1.y = TANGENT_1.y;\n    TANGENT_1_1.z = TANGENT_1.z;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_clip_cull_dist.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\n               OpCapability Shader\n               OpCapability ClipDistance\n               OpCapability CullDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %gl_ClipDistance %gl_CullDistance\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n               OpDecorate %gl_CullDistance BuiltIn CullDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n       %uint = OpTypeInt 32 0\n     %uint_7 = OpConstant %uint 7\n%_arr_float_uint_7 = OpTypeArray %float %uint_7\n%_ptr_Output__arr_float_uint_7 = OpTypePointer Output %_arr_float_uint_7\n%gl_ClipDistance = OpVariable %_ptr_Output__arr_float_uint_7 Output\n     %uint_1 = OpConstant %uint 1\n%_arr_float_uint_1 = OpTypeArray %float %uint_1\n%_ptr_Output__arr_float_uint_1 = OpTypePointer Output %_arr_float_uint_1\n%gl_CullDistance = OpVariable %_ptr_Output__arr_float_uint_1 Output\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_0 = OpConstant %uint 0\n %float_n2_5 = OpConstant %float -2.5\n %float_n1_5 = OpConstant %float -1.5\n     %uint_2 = OpConstant %uint 2\n %float_n0_5 = OpConstant %float -0.5\n     %uint_3 = OpConstant %uint 3\n  %float_0_5 = OpConstant %float 0.5\n     %uint_4 = OpConstant %uint 4\n  %float_1_5 = OpConstant %float 1.5\n     %uint_5 = OpConstant %uint 5\n  %float_2_5 = OpConstant %float 2.5\n     %uint_6 = OpConstant %uint 6\n  %float_3_5 = OpConstant %float 3.5\n   %float_n2 = OpConstant %float -2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %38\n\n         %38 = OpLabel\n         %16 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_0\n                 OpStore %16 %float_n2_5\n         %19 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_1\n                 OpStore %19 %float_n1_5\n         %21 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_2\n                 OpStore %21 %float_n0_5\n         %24 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_3\n                 OpStore %24 %float_0_5\n         %27 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_4\n                 OpStore %27 %float_1_5\n         %30 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_5\n                 OpStore %30 %float_2_5\n         %33 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_6\n                 OpStore %33 %float_3_5\n         %36 =   OpAccessChain %_ptr_Output_float %gl_CullDistance %uint_0\n                 OpStore %36 %float_n2\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_clip_cull_dist.glsl",
    "content": "GLSL:\n#version 460\n\nout float gl_ClipDistance[7];\nout float gl_CullDistance[1];\n\nvoid main()\n{\n    gl_ClipDistance[0u] = -2.5;\n    gl_ClipDistance[1u] = -1.5;\n    gl_ClipDistance[2u] = -0.5;\n    gl_ClipDistance[3u] = 0.5;\n    gl_ClipDistance[4u] = 1.5;\n    gl_ClipDistance[5u] = 2.5;\n    gl_ClipDistance[6u] = 3.5;\n    gl_CullDistance[0u] = -2.0;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_clip_dist.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\n               OpCapability Shader\n               OpCapability ClipDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %gl_ClipDistance\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpDecorate %gl_ClipDistance BuiltIn ClipDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n       %uint = OpTypeInt 32 0\n     %uint_6 = OpConstant %uint 6\n%_arr_float_uint_6 = OpTypeArray %float %uint_6\n%_ptr_Output__arr_float_uint_6 = OpTypePointer Output %_arr_float_uint_6\n%gl_ClipDistance = OpVariable %_ptr_Output__arr_float_uint_6 Output\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_0 = OpConstant %uint 0\n %float_n2_5 = OpConstant %float -2.5\n     %uint_1 = OpConstant %uint 1\n %float_n1_5 = OpConstant %float -1.5\n     %uint_2 = OpConstant %uint 2\n %float_n0_5 = OpConstant %float -0.5\n     %uint_3 = OpConstant %uint 3\n  %float_0_5 = OpConstant %float 0.5\n     %uint_4 = OpConstant %uint 4\n  %float_1_5 = OpConstant %float 1.5\n     %uint_5 = OpConstant %uint 5\n  %float_2_5 = OpConstant %float 2.5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %30\n\n         %30 = OpLabel\n         %12 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_0\n                 OpStore %12 %float_n2_5\n         %15 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_1\n                 OpStore %15 %float_n1_5\n         %18 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_2\n                 OpStore %18 %float_n0_5\n         %21 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_3\n                 OpStore %21 %float_0_5\n         %24 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_4\n                 OpStore %24 %float_1_5\n         %27 =   OpAccessChain %_ptr_Output_float %gl_ClipDistance %uint_5\n                 OpStore %27 %float_2_5\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_clip_dist.glsl",
    "content": "GLSL:\n#version 460\n\nout float gl_ClipDistance[6];\n\nvoid main()\n{\n    gl_ClipDistance[0u] = -2.5;\n    gl_ClipDistance[1u] = -1.5;\n    gl_ClipDistance[2u] = -0.5;\n    gl_ClipDistance[3u] = 0.5;\n    gl_ClipDistance[4u] = 1.5;\n    gl_ClipDistance[5u] = 2.5;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_cull_dist.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 20\n; Schema: 0\n               OpCapability Shader\n               OpCapability CullDistance\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %gl_CullDistance\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpDecorate %gl_CullDistance BuiltIn CullDistance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n       %uint = OpTypeInt 32 0\n     %uint_2 = OpConstant %uint 2\n%_arr_float_uint_2 = OpTypeArray %float %uint_2\n%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2\n%gl_CullDistance = OpVariable %_ptr_Output__arr_float_uint_2 Output\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_0 = OpConstant %uint 0\n%float_0_699999988 = OpConstant %float 0.699999988\n     %uint_1 = OpConstant %uint 1\n%float_0_100000001 = OpConstant %float 0.100000001\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %18\n\n         %18 = OpLabel\n         %12 =   OpAccessChain %_ptr_Output_float %gl_CullDistance %uint_0\n                 OpStore %12 %float_0_699999988\n         %15 =   OpAccessChain %_ptr_Output_float %gl_CullDistance %uint_1\n                 OpStore %15 %float_0_100000001\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_cull_dist.glsl",
    "content": "GLSL:\n#version 460\n\nout float gl_CullDistance[2];\n\nvoid main()\n{\n    gl_CullDistance[0u] = 0.699999988079071044921875;\n    gl_CullDistance[1u] = 0.100000001490116119384765625;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_instance_id.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 16\n; Schema: 0\n               OpCapability Shader\n               OpCapability DrawParameters\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %SV_INSTANCEID %SHADER_OUT %gl_BaseInstance\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_INSTANCEID \"SV_INSTANCEID\"\n               OpName %SHADER_OUT \"SHADER_OUT\"\n               OpDecorate %SV_INSTANCEID BuiltIn InstanceIndex\n               OpDecorate %SHADER_OUT Location 0\n               OpDecorate %gl_BaseInstance BuiltIn BaseInstance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_INSTANCEID = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n %SHADER_OUT = OpVariable %_ptr_Output_uint Output\n%gl_BaseInstance = OpVariable %_ptr_Input_uint Input\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %14\n\n         %14 = OpLabel\n         %10 =   OpLoad %uint %SV_INSTANCEID\n         %12 =   OpLoad %uint %gl_BaseInstance\n         %13 =   OpISub %uint %10 %12\n                 OpStore %SHADER_OUT %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_instance_id.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out uint SHADER_OUT;\n\nvoid main()\n{\n    SHADER_OUT = uint(gl_InstanceIndex) - uint(gl_BaseInstance);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_layer.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 16\n; Schema: 0\n               OpCapability Shader\n               OpCapability Geometry\n               OpCapability DrawParameters\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability ShaderViewportIndexLayerEXT\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_shader_viewport_index_layer\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %SV_INSTANCEID %SV_RenderTargetArrayIndex %gl_BaseInstance\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_INSTANCEID \"SV_INSTANCEID\"\n               OpName %SV_RenderTargetArrayIndex \"SV_RenderTargetArrayIndex\"\n               OpDecorate %SV_INSTANCEID BuiltIn InstanceIndex\n               OpDecorate %SV_RenderTargetArrayIndex BuiltIn Layer\n               OpDecorate %gl_BaseInstance BuiltIn BaseInstance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_INSTANCEID = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_RenderTargetArrayIndex = OpVariable %_ptr_Output_uint Output\n%gl_BaseInstance = OpVariable %_ptr_Input_uint Input\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %14\n\n         %14 = OpLabel\n         %10 =   OpLoad %uint %SV_INSTANCEID\n         %12 =   OpLoad %uint %gl_BaseInstance\n         %13 =   OpISub %uint %10 %12\n                 OpStore %SV_RenderTargetArrayIndex %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_layer.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_shader_viewport_layer_array : require\n\nvoid main()\n{\n    gl_Layer = int(uint(gl_InstanceIndex) - uint(gl_BaseInstance));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_vertex_id.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 16\n; Schema: 0\n               OpCapability Shader\n               OpCapability DrawParameters\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %SV_VERTEXID %SHADER_OUT %11\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_VERTEXID \"SV_VERTEXID\"\n               OpName %SHADER_OUT \"SHADER_OUT\"\n               OpDecorate %SV_VERTEXID BuiltIn VertexIndex\n               OpDecorate %SHADER_OUT Location 0\n               OpDecorate %11 BuiltIn BaseVertex\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_VERTEXID = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n %SHADER_OUT = OpVariable %_ptr_Output_uint Output\n         %11 = OpVariable %_ptr_Input_uint Input\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %14\n\n         %14 = OpLabel\n         %10 =   OpLoad %uint %SV_VERTEXID\n         %12 =   OpLoad %uint %11\n         %13 =   OpISub %uint %10 %12\n                 OpStore %SHADER_OUT %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_vertex_id.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out uint SHADER_OUT;\n\nvoid main()\n{\n    SHADER_OUT = uint(gl_VertexIndex) - uint(gl_BaseVertex);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_viewport.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 16\n; Schema: 0\n               OpCapability Shader\n               OpCapability MultiViewport\n               OpCapability DrawParameters\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability ShaderViewportIndexLayerEXT\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_shader_viewport_index_layer\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %SV_INSTANCEID %SV_ViewportArrayIndex %gl_BaseInstance\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_INSTANCEID \"SV_INSTANCEID\"\n               OpName %SV_ViewportArrayIndex \"SV_ViewportArrayIndex\"\n               OpDecorate %SV_INSTANCEID BuiltIn InstanceIndex\n               OpDecorate %SV_ViewportArrayIndex BuiltIn ViewportIndex\n               OpDecorate %gl_BaseInstance BuiltIn BaseInstance\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_INSTANCEID = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_ViewportArrayIndex = OpVariable %_ptr_Output_uint Output\n%gl_BaseInstance = OpVariable %_ptr_Input_uint Input\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %14\n\n         %14 = OpLabel\n         %10 =   OpLoad %uint %SV_INSTANCEID\n         %12 =   OpLoad %uint %gl_BaseInstance\n         %13 =   OpISub %uint %10 %12\n                 OpStore %SV_ViewportArrayIndex %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_io_vs_viewport.glsl",
    "content": "GLSL:\n#version 460\n\nvoid main()\n{\n    gl_ViewportIndex = int(uint(gl_InstanceIndex) - uint(gl_BaseInstance));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_constant_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\n               OpCapability Shader\n               OpCapability DrawParameters\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %27 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Vertex %main \"main\" %SV_VERTEXID %SV_POSITION %22 %24\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_VERTEXID \"SV_VERTEXID\"\n               OpName %SV_POSITION \"SV_POSITION\"\n               OpDecorate %SV_VERTEXID BuiltIn VertexIndex\n               OpDecorate %SV_POSITION BuiltIn Position\n               OpDecorate %24 BuiltIn BaseVertex\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_VERTEXID = OpVariable %_ptr_Input_uint Input\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n%SV_POSITION = OpVariable %_ptr_Output_v4float Output\n     %uint_5 = OpConstant %uint 5\n%_arr_v4float_uint_5 = OpTypeArray %v4float %uint_5\n    %float_0 = OpConstant %float 0\n         %15 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0\n    %float_1 = OpConstant %float 1\n         %17 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_0\n         %18 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_0\n         %19 = OpConstantComposite %v4float %float_1 %float_1 %float_0 %float_0\n         %20 = OpConstantComposite %_arr_v4float_uint_5 %15 %17 %18 %19 %15\n%_ptr_Private__arr_v4float_uint_5 = OpTypePointer Private %_arr_v4float_uint_5\n         %22 = OpVariable %_ptr_Private__arr_v4float_uint_5 Private %20\n         %24 = OpVariable %_ptr_Input_uint Input\n     %uint_4 = OpConstant %uint 4\n%_ptr_Private_v4float = OpTypePointer Private %v4float\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %46\n\n         %46 = OpLabel\n         %23 =   OpLoad %uint %SV_VERTEXID\n         %25 =   OpLoad %uint %24\n         %26 =   OpISub %uint %23 %25\n         %28 =   OpExtInst %uint %27 UMin %26 %uint_4\n         %31 =   OpInBoundsAccessChain %_ptr_Private_v4float %22 %28\n         %32 =   OpLoad %v4float %31\n         %33 =   OpCompositeExtract %float %32 0\n         %35 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_0\n                 OpStore %35 %33\n         %37 =   OpCompositeExtract %float %32 1\n         %38 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_1\n                 OpStore %38 %37\n         %40 =   OpCompositeExtract %float %32 2\n         %41 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_2\n                 OpStore %41 %40\n         %43 =   OpCompositeExtract %float %32 3\n         %44 =   OpAccessChain %_ptr_Output_float %SV_POSITION %uint_3\n                 OpStore %44 %43\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_constant_load.glsl",
    "content": "GLSL:\n#version 460\n\nconst vec4 _20[5] = vec4[](vec4(0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(1.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 0.0, 0.0), vec4(0.0));\n\nvoid main()\n{\n    uint _28 = min((uint(gl_VertexIndex) - uint(gl_BaseVertex)), 4u);\n    gl_Position.x = _20[_28].x;\n    gl_Position.y = _20[_28].y;\n    gl_Position.z = _20[_28].z;\n    gl_Position.w = _20[_28].w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %_ \"\"\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n    %float_1 = OpConstant %float 1\n     %uint_1 = OpConstant %uint 1\n    %float_2 = OpConstant %float 2\n     %uint_2 = OpConstant %uint 2\n    %float_3 = OpConstant %float 3\n     %uint_3 = OpConstant %uint 3\n    %float_4 = OpConstant %float 4\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %26\n\n         %26 = OpLabel\n         %25 =   OpFunctionCall %void %_\n                 OpReturn\n               OpFunctionEnd\n          %_ = OpFunction %void None %2\n\n         %10 = OpLabel\n                 OpBranch %28\n\n         %28 = OpLabel\n         %12 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %12 %float_1\n         %16 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %16 %float_2\n         %19 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %19 %float_3\n         %22 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %22 %float_4\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid _9()\n{\n    SV_TARGET.x = 1.0;\n    SV_TARGET.y = 2.0;\n    SV_TARGET.z = 3.0;\n    SV_TARGET.w = 4.0;\n}\n\nvoid main()\n{\n    _9();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function_with_args.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %_ \"\"\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n          %9 = OpTypeFunction %void %float %float %float %float\n%_ptr_Output_float = OpTypePointer Output %float\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n    %float_1 = OpConstant %float 1\n    %float_2 = OpConstant %float 2\n    %float_3 = OpConstant %float 3\n    %float_4 = OpConstant %float 4\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %31\n\n         %31 = OpLabel\n         %26 =   OpFunctionCall %void %_ %float_1 %float_2 %float_3 %float_4\n                 OpReturn\n               OpFunctionEnd\n          %_ = OpFunction %void None %9\n         %10 = OpFunctionParameter %float\n         %11 = OpFunctionParameter %float\n         %12 = OpFunctionParameter %float\n         %13 = OpFunctionParameter %float\n\n         %15 = OpLabel\n                 OpBranch %33\n\n         %33 = OpLabel\n         %17 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %17 %10\n         %20 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %20 %11\n         %22 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %22 %12\n         %24 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %24 %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function_with_args.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid _14(float _10, float _11, float _12, float _13)\n{\n    SV_TARGET.x = _10;\n    SV_TARGET.y = _11;\n    SV_TARGET.z = _12;\n    SV_TARGET.w = _13;\n}\n\nvoid main()\n{\n    _14(1.0, 2.0, 3.0, 4.0);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function_with_return.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %_ \"\"\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n          %9 = OpTypeFunction %v4float %float %float %float %float\n%float_0_200000003 = OpConstant %float 0.200000003\n  %float_0_5 = OpConstant %float 0.5\n    %float_1 = OpConstant %float 1\n%float_0_800000012 = OpConstant %float 0.800000012\n%_ptr_Output_float = OpTypePointer Output %float\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %39\n\n         %39 = OpLabel\n         %20 =   OpFunctionCall %v4float %_ %float_0_200000003 %float_0_5 %float_1 %float_0_800000012\n         %25 =   OpCompositeExtract %float %20 0\n         %27 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %27 %25\n         %30 =   OpCompositeExtract %float %20 1\n         %31 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %31 %30\n         %33 =   OpCompositeExtract %float %20 2\n         %34 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %34 %33\n         %36 =   OpCompositeExtract %float %20 3\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %37 %36\n                 OpReturn\n               OpFunctionEnd\n          %_ = OpFunction %v4float None %9\n         %10 = OpFunctionParameter %float\n         %11 = OpFunctionParameter %float\n         %12 = OpFunctionParameter %float\n         %13 = OpFunctionParameter %float\n\n         %15 = OpLabel\n                 OpBranch %41\n\n         %41 = OpLabel\n         %16 =   OpFMul %float %10 %13\n         %17 =   OpFMul %float %11 %13\n         %18 =   OpFMul %float %12 %13\n         %19 =   OpCompositeConstruct %v4float %16 %17 %18 %13\n                 OpReturnValue %19\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function_with_return.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(location = 0) out vec4 SV_TARGET;\n\nvec4 _14(float _10, float _11, float _12, float _13)\n{\n    return vec4(_10 * _13, _11 * _13, _12 * _13, _13);\n}\n\nvoid main()\n{\n    vec4 _20 = _14(0.20000000298023223876953125, 0.5, 1.0, 0.800000011920928955078125);\n    SV_TARGET.x = _20.x;\n    SV_TARGET.y = _20.y;\n    SV_TARGET.z = _20.z;\n    SV_TARGET.w = _20.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function_with_undef.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 31\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n         %17 = OpExtInstImport \"GLSL.std.450\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %INPUT %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %INPUT \"INPUT\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %_ \"\"\n               OpDecorate %INPUT Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n%_ptr_Input_float = OpTypePointer Input %float\n      %INPUT = OpVariable %_ptr_Input_float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n         %10 = OpTypeFunction %float %float\n       %bool = OpTypeBool\n    %float_0 = OpConstant %float 0\n         %20 = OpUndef %float\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %25\n\n         %25 = OpLabel\n         %21 =   OpLoad %float %INPUT\n         %22 =   OpFOrdGreaterThanEqual %bool %21 %float_0\n         %23 =   OpFunctionCall %float %_ %21\n         %24 =   OpSelect %float %22 %23 %20\n                 OpStore %SV_TARGET %24\n                 OpReturn\n               OpFunctionEnd\n          %_ = OpFunction %float None %10\n         %11 = OpFunctionParameter %float\n\n         %13 = OpLabel\n                 OpBranch %27\n\n         %27 = OpLabel\n         %15 =   OpFOrdGreaterThanEqual %bool %11 %float_0\n                 OpSelectionMerge %29 None\n                 OpBranchConditional %15 %28 %29\n\n         %28 =     OpLabel\n         %18 =       OpExtInst %float %17 Sqrt %11\n                     OpBranch %29\n\n         %29 = OpLabel\n         %19 =   OpPhi %float %20 %27 %18 %28\n                 OpReturnValue %19\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_function_with_undef.glsl",
    "content": "GLSL:\n#version 460\n\nfloat _20;\n\nlayout(location = 0) in float INPUT;\nlayout(location = 0) out float SV_TARGET;\n\nfloat _12(float _11)\n{\n    float _19;\n    if (_11 >= 0.0)\n    {\n        _19 = sqrt(_11);\n    }\n    else\n    {\n        _19 = _20;\n    }\n    return _19;\n}\n\nvoid main()\n{\n    SV_TARGET = (INPUT >= 0.0) ? _12(INPUT) : _20;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_lds.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 68\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13 %SV_DispatchThreadID %21 %gl_LocalInvocationIndex\n               OpExecutionMode %main LocalSize 32 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %SV_DispatchThreadID \"SV_DispatchThreadID\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n               OpDecorate %SV_DispatchThreadID BuiltIn GlobalInvocationId\n               OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n%SV_DispatchThreadID = OpVariable %_ptr_Input_v3uint Input\n    %uint_32 = OpConstant %uint 32\n      %float = OpTypeFloat 32\n%_arr_float_uint_32 = OpTypeArray %float %uint_32\n%_ptr_Workgroup__arr_float_uint_32 = OpTypePointer Workgroup %_arr_float_uint_32\n         %21 = OpVariable %_ptr_Workgroup__arr_float_uint_32 Workgroup\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n%gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n%_ptr_Workgroup_float = OpTypePointer Workgroup %float\n    %uint_16 = OpConstant %uint 16\n     %uint_2 = OpConstant %uint 2\n %uint_24840 = OpConstant %uint 24840\n       %bool = OpTypeBool\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n         %50 =   OpUndef %float\n                 OpBranch %59\n\n         %59 = OpLabel\n         %23 =   OpAccessChain %_ptr_Input_uint %SV_DispatchThreadID %uint_0\n         %25 =   OpLoad %uint %23\n         %27 =   OpLoad %uint %gl_LocalInvocationIndex\n         %31 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %25\n         %32 =   OpLoad %uint %31\n         %33 =   OpBitcast %float %32\n         %35 =   OpInBoundsAccessChain %_ptr_Workgroup_float %21 %27\n                 OpStore %35 %33 NonPrivatePointer\n                 OpBranch %60\n\n         %60 = OpLabel\n         %36 =   OpPhi %uint %uint_16 %59 %38 %65\n                 OpLoopMerge %66 %61 None\n                 OpBranch %61\n\n         %61 =   OpLabel\n                   OpControlBarrier %uint_2 %uint_2 %uint_24840\n         %42 =     OpULessThan %bool %27 %36\n                   OpSelectionMerge %63 None\n                   OpBranchConditional %42 %62 %63\n\n         %62 =       OpLabel\n         %43 =         OpIAdd %uint %27 %36\n         %44 =         OpInBoundsAccessChain %_ptr_Workgroup_float %21 %43\n         %45 =         OpLoad %float %44 NonPrivatePointer\n         %46 =         OpInBoundsAccessChain %_ptr_Workgroup_float %21 %27\n         %47 =         OpLoad %float %46 NonPrivatePointer\n         %48 =         OpFAdd %float %47 %45\n                       OpBranch %63\n\n         %63 =   OpLabel\n         %49 =     OpPhi %float %50 %61 %48 %62\n                   OpControlBarrier %uint_2 %uint_2 %uint_24840\n                   OpSelectionMerge %65 None\n                   OpBranchConditional %42 %64 %65\n\n         %64 =       OpLabel\n         %51 =         OpInBoundsAccessChain %_ptr_Workgroup_float %21 %27\n                       OpStore %51 %49 NonPrivatePointer\n                       OpBranch %65\n\n         %65 =   OpLabel\n         %38 =     OpShiftRightLogical %uint %36 %uint_1\n         %53 =     OpINotEqual %bool %38 %uint_0\n                   OpBranchConditional %53 %60 %66\n\n         %66 = OpLabel\n                 OpControlBarrier %uint_2 %uint_2 %uint_24840\n         %54 =   OpInBoundsAccessChain %_ptr_Workgroup_float %21 %uint_0\n         %55 =   OpLoad %float %54 NonPrivatePointer\n         %57 =   OpBitcast %uint %55\n         %58 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %25\n                 OpStore %58 %57 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_lds.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nfloat _50;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nshared float _21[32];\n\nvoid main()\n{\n    _21[gl_LocalInvocationIndex] = uintBitsToFloat(_9._m0[gl_GlobalInvocationID.x]);\n    bool _42;\n    float _49;\n    uint _36 = 16u;\n    for (;;)\n    {\n        barrier();\n        _42 = gl_LocalInvocationIndex < _36;\n        if (_42)\n        {\n            _49 = _21[gl_LocalInvocationIndex] + _21[gl_LocalInvocationIndex + _36];\n        }\n        else\n        {\n            _49 = _50;\n        }\n        barrier();\n        if (_42)\n        {\n            _21[gl_LocalInvocationIndex] = _49;\n        }\n        uint _38 = _36 >> 1u;\n        if (_38 != 0u)\n        {\n            _36 = _38;\n            continue;\n        }\n        else\n        {\n            break;\n        }\n    }\n    barrier();\n    _13._m0[gl_GlobalInvocationID.x] = floatBitsToUint(_21[0u]);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_lds_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %13 %SV_DispatchThreadID %20\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %SV_DispatchThreadID \"SV_DispatchThreadID\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 1\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %_runtimearr_uint_0 ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %13 NonReadable\n               OpDecorate %SV_DispatchThreadID BuiltIn GlobalInvocationId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint_0 = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint_0\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %13 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n%SV_DispatchThreadID = OpVariable %_ptr_Input_v3uint Input\n     %uint_1 = OpConstant %uint 1\n%_arr_uint_uint_1 = OpTypeArray %uint %uint_1\n%_ptr_Workgroup__arr_uint_uint_1 = OpTypePointer Workgroup %_arr_uint_uint_1\n         %20 = OpVariable %_ptr_Workgroup__arr_uint_uint_1 Workgroup\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %38\n\n         %38 = OpLabel\n         %22 =   OpAccessChain %_ptr_Input_uint %SV_DispatchThreadID %uint_0\n         %24 =   OpLoad %uint %22\n         %28 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %24\n         %29 =   OpLoad %uint %28\n         %31 =   OpInBoundsAccessChain %_ptr_Workgroup_uint %20 %uint_0\n         %32 =   OpAtomicIAdd %uint %31 %uint_2 %uint_0 %29\n         %34 =   OpInBoundsAccessChain %_ptr_Workgroup_uint %20 %uint_0\n         %35 =   OpAtomicXor %uint %34 %uint_2 %uint_0 %29\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %13 %uint_0 %24\n                 OpStore %37 %35 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_lds_atomic.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _11_13\n{\n    uint _m0[];\n} _13;\n\nshared uint _20[1];\n\nvoid main()\n{\n    uint _32 = atomicAdd(_20[0u], _9._m0[gl_GlobalInvocationID.x]);\n    uint _35 = atomicXor(_20[0u], _9._m0[gl_GlobalInvocationID.x]);\n    _13._m0[gl_GlobalInvocationID.x] = _35;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_ps_demote.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 53\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpCapability DemoteToHelperInvocation\n               OpExtension \"SPV_EXT_demote_to_helper_invocation\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n   %TEXCOORD = OpVariable %_ptr_Input_v2float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_float = OpTypePointer Input %float\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n         %29 = OpTypeSampledImage %6\n    %float_0 = OpConstant %float 0\n       %bool = OpTypeBool\n%float_0_00499999989 = OpConstant %float 0.00499999989\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %49\n\n         %49 = OpLabel\n         %18 =   OpLoad %6 %8\n         %19 =   OpLoad %9 %11\n         %21 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %24 =   OpLoad %float %21\n         %25 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %27 =   OpLoad %float %25\n         %30 =   OpSampledImage %29 %18 %19\n         %33 =   OpCompositeConstruct %v2float %24 %27\n         %32 =   OpImageSampleImplicitLod %v4float %30 %33 None\n         %34 =   OpCompositeExtract %float %32 0\n         %35 =   OpCompositeExtract %float %32 1\n         %36 =   OpCompositeExtract %float %32 2\n         %37 =   OpCompositeExtract %float %32 3\n         %40 =   OpFOrdLessThan %bool %37 %float_0_00499999989\n                 OpSelectionMerge %51 None\n                 OpBranchConditional %40 %50 %51\n\n         %50 =     OpLabel\n                     OpDemoteToHelperInvocation\n                     OpBranch %51\n\n         %51 = OpLabel\n         %43 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %43 %34\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %44 %35\n         %45 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %45 %36\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %47 %37\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_ps_demote.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_demote_to_helper_invocation : require\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec2 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _32 = texture(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y));\n    float _37 = _32.w;\n    if (_37 < 0.004999999888241291046142578125)\n    {\n        demote;\n    }\n    SV_TARGET.x = _32.x;\n    SV_TARGET.y = _32.y;\n    SV_TARGET.z = _32.z;\n    SV_TARGET.w = _37;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_ps_early_z.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %INDEX\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main EarlyFragmentTests\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %INDEX \"INDEX\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %INDEX Flat\n               OpDecorate %INDEX Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %INDEX = OpVariable %_ptr_Input_uint Input\n     %uint_4 = OpConstant %uint 4\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_5 = OpConstant %uint 5\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %21\n\n         %21 = OpLabel\n         %12 =   OpLoad %uint %INDEX\n         %16 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %12\n         %18 =   OpAtomicOr %uint %16 %uint_5 %uint_0 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_ps_early_z.glsl",
    "content": "GLSL:\n#version 460\nlayout(early_fragment_tests) in;\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uint INDEX;\n\nvoid main()\n{\n    uint _18 = atomicOr(_9._m0[INDEX], 1u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_scratch.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 1498\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %10 %14 %18 %SV_DispatchThreadID %27 %31 %34\n               OpExecutionMode %main LocalSize 1 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %SSBO_1 \"SSBO\"\n               OpName %SV_DispatchThreadID \"SV_DispatchThreadID\"\n               OpDecorate %_runtimearr_v4uint ArrayStride 16\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Restrict\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %14 DescriptorSet 0\n               OpDecorate %14 Binding 1\n               OpDecorate %14 NonWritable\n               OpDecorate %14 Restrict\n               OpDecorate %_runtimearr_v4uint_0 ArrayStride 16\n               OpMemberDecorate %SSBO_1 0 Offset 0\n               OpDecorate %SSBO_1 Block\n               OpDecorate %18 DescriptorSet 0\n               OpDecorate %18 Binding 0\n               OpDecorate %18 NonReadable\n               OpDecorate %SV_DispatchThreadID BuiltIn GlobalInvocationId\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n     %v4uint = OpTypeVector %uint 4\n%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint\n       %SSBO = OpTypeStruct %_runtimearr_v4uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n         %10 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %14 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint\n     %SSBO_1 = OpTypeStruct %_runtimearr_v4uint_0\n%_ptr_StorageBuffer_SSBO_1 = OpTypePointer StorageBuffer %SSBO_1\n         %18 = OpVariable %_ptr_StorageBuffer_SSBO_1 StorageBuffer\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n%SV_DispatchThreadID = OpVariable %_ptr_Input_v3uint Input\n    %uint_16 = OpConstant %uint 16\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_arr_v4float_uint_16 = OpTypeArray %v4float %uint_16\n%_ptr_Private__arr_v4float_uint_16 = OpTypePointer Private %_arr_v4float_uint_16\n         %27 = OpVariable %_ptr_Private__arr_v4float_uint_16 Private\n     %uint_4 = OpConstant %uint 4\n%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4\n%_ptr_Private__arr_v4float_uint_4 = OpTypePointer Private %_arr_v4float_uint_4\n         %31 = OpVariable %_ptr_Private__arr_v4float_uint_4 Private\n%_arr_uint_uint_16 = OpTypeArray %uint %uint_16\n%_ptr_Private__arr_uint_uint_16 = OpTypePointer Private %_arr_uint_uint_16\n         %34 = OpVariable %_ptr_Private__arr_uint_uint_16 Private\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n%_ptr_Private_v4float = OpTypePointer Private %v4float\n    %float_1 = OpConstant %float 1\n    %float_2 = OpConstant %float 2\n    %float_3 = OpConstant %float 3\n    %float_4 = OpConstant %float 4\n         %45 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4\n%_ptr_Private_uint = OpTypePointer Private %uint\n%uint_4294967295 = OpConstant %uint 4294967295\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n%_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint\n     %uint_5 = OpConstant %uint 5\n     %uint_6 = OpConstant %uint 6\n     %uint_7 = OpConstant %uint 7\n     %uint_8 = OpConstant %uint 8\n     %uint_9 = OpConstant %uint 9\n    %uint_10 = OpConstant %uint 10\n    %uint_11 = OpConstant %uint 11\n    %uint_12 = OpConstant %uint 12\n    %uint_13 = OpConstant %uint 13\n    %uint_14 = OpConstant %uint 14\n    %uint_15 = OpConstant %uint 15\n     %v2uint = OpTypeVector %uint 2\n    %uint_64 = OpConstant %uint 64\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n%_ptr_Private_float = OpTypePointer Private %float\n    %uint_17 = OpConstant %uint 17\n    %uint_18 = OpConstant %uint 18\n    %uint_19 = OpConstant %uint 19\n    %uint_20 = OpConstant %uint 20\n    %uint_21 = OpConstant %uint 21\n    %uint_22 = OpConstant %uint 22\n    %uint_23 = OpConstant %uint 23\n    %uint_24 = OpConstant %uint 24\n    %uint_25 = OpConstant %uint 25\n    %uint_26 = OpConstant %uint 26\n    %uint_27 = OpConstant %uint 27\n    %uint_28 = OpConstant %uint 28\n    %uint_29 = OpConstant %uint 29\n    %uint_30 = OpConstant %uint 30\n    %uint_31 = OpConstant %uint 31\n    %uint_32 = OpConstant %uint 32\n    %uint_33 = OpConstant %uint 33\n    %uint_34 = OpConstant %uint 34\n    %uint_35 = OpConstant %uint 35\n    %uint_36 = OpConstant %uint 36\n    %uint_37 = OpConstant %uint 37\n    %uint_38 = OpConstant %uint 38\n    %uint_39 = OpConstant %uint 39\n    %uint_40 = OpConstant %uint 40\n    %uint_41 = OpConstant %uint 41\n    %uint_42 = OpConstant %uint 42\n    %uint_43 = OpConstant %uint 43\n    %uint_44 = OpConstant %uint 44\n    %uint_45 = OpConstant %uint 45\n    %uint_46 = OpConstant %uint 46\n    %uint_47 = OpConstant %uint 47\n    %uint_48 = OpConstant %uint 48\n    %uint_49 = OpConstant %uint 49\n    %uint_50 = OpConstant %uint 50\n    %uint_51 = OpConstant %uint 51\n    %uint_52 = OpConstant %uint 52\n    %uint_53 = OpConstant %uint 53\n    %uint_54 = OpConstant %uint 54\n    %uint_55 = OpConstant %uint 55\n    %uint_56 = OpConstant %uint 56\n    %uint_57 = OpConstant %uint 57\n    %uint_58 = OpConstant %uint 58\n    %uint_59 = OpConstant %uint 59\n    %uint_60 = OpConstant %uint 60\n    %uint_61 = OpConstant %uint 61\n    %uint_62 = OpConstant %uint 62\n    %uint_63 = OpConstant %uint 63\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %1496\n\n       %1496 = OpLabel\n         %36 =   OpAccessChain %_ptr_Input_uint %SV_DispatchThreadID %uint_0\n         %38 =   OpLoad %uint %36\n         %40 =   OpInBoundsAccessChain %_ptr_Private_v4float %31 %uint_0\n                 OpStore %40 %45\n         %47 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %uint_0\n                 OpStore %47 %uint_4294967295\n         %49 =   OpInBoundsAccessChain %_ptr_Private_v4float %31 %uint_1\n                 OpStore %49 %45\n         %51 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %uint_1\n                 OpStore %51 %uint_4294967295\n         %52 =   OpInBoundsAccessChain %_ptr_Private_v4float %31 %uint_2\n                 OpStore %52 %45\n         %54 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %uint_2\n                 OpStore %54 %uint_4294967295\n         %55 =   OpInBoundsAccessChain %_ptr_Private_v4float %31 %uint_3\n                 OpStore %55 %45\n         %57 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %uint_3\n                 OpStore %57 %uint_4294967295\n         %59 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_0\n         %60 =   OpLoad %v4uint %59\n         %61 =   OpBitcast %v4float %60\n         %62 =   OpCompositeExtract %float %61 0\n         %63 =   OpCompositeExtract %float %61 1\n         %64 =   OpCompositeExtract %float %61 2\n         %65 =   OpCompositeExtract %float %61 3\n         %66 =   OpCompositeConstruct %v4float %62 %63 %64 %65\n         %67 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_0\n                 OpStore %67 %66\n         %68 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_1\n         %69 =   OpLoad %v4uint %68\n         %70 =   OpBitcast %v4float %69\n         %71 =   OpCompositeExtract %float %70 0\n         %72 =   OpCompositeExtract %float %70 1\n         %73 =   OpCompositeExtract %float %70 2\n         %74 =   OpCompositeExtract %float %70 3\n         %75 =   OpCompositeConstruct %v4float %71 %72 %73 %74\n         %76 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_1\n                 OpStore %76 %75\n         %77 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_2\n         %78 =   OpLoad %v4uint %77\n         %79 =   OpBitcast %v4float %78\n         %80 =   OpCompositeExtract %float %79 0\n         %81 =   OpCompositeExtract %float %79 1\n         %82 =   OpCompositeExtract %float %79 2\n         %83 =   OpCompositeExtract %float %79 3\n         %84 =   OpCompositeConstruct %v4float %80 %81 %82 %83\n         %85 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_2\n                 OpStore %85 %84\n         %86 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_3\n         %87 =   OpLoad %v4uint %86\n         %88 =   OpBitcast %v4float %87\n         %89 =   OpCompositeExtract %float %88 0\n         %90 =   OpCompositeExtract %float %88 1\n         %91 =   OpCompositeExtract %float %88 2\n         %92 =   OpCompositeExtract %float %88 3\n         %93 =   OpCompositeConstruct %v4float %89 %90 %91 %92\n         %94 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_3\n                 OpStore %94 %93\n         %95 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_4\n         %96 =   OpLoad %v4uint %95\n         %97 =   OpBitcast %v4float %96\n         %98 =   OpCompositeExtract %float %97 0\n         %99 =   OpCompositeExtract %float %97 1\n        %100 =   OpCompositeExtract %float %97 2\n        %101 =   OpCompositeExtract %float %97 3\n        %102 =   OpCompositeConstruct %v4float %98 %99 %100 %101\n        %103 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_4\n                 OpStore %103 %102\n        %105 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_5\n        %106 =   OpLoad %v4uint %105\n        %107 =   OpBitcast %v4float %106\n        %108 =   OpCompositeExtract %float %107 0\n        %109 =   OpCompositeExtract %float %107 1\n        %110 =   OpCompositeExtract %float %107 2\n        %111 =   OpCompositeExtract %float %107 3\n        %112 =   OpCompositeConstruct %v4float %108 %109 %110 %111\n        %113 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_5\n                 OpStore %113 %112\n        %115 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_6\n        %116 =   OpLoad %v4uint %115\n        %117 =   OpBitcast %v4float %116\n        %118 =   OpCompositeExtract %float %117 0\n        %119 =   OpCompositeExtract %float %117 1\n        %120 =   OpCompositeExtract %float %117 2\n        %121 =   OpCompositeExtract %float %117 3\n        %122 =   OpCompositeConstruct %v4float %118 %119 %120 %121\n        %123 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_6\n                 OpStore %123 %122\n        %125 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_7\n        %126 =   OpLoad %v4uint %125\n        %127 =   OpBitcast %v4float %126\n        %128 =   OpCompositeExtract %float %127 0\n        %129 =   OpCompositeExtract %float %127 1\n        %130 =   OpCompositeExtract %float %127 2\n        %131 =   OpCompositeExtract %float %127 3\n        %132 =   OpCompositeConstruct %v4float %128 %129 %130 %131\n        %133 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_7\n                 OpStore %133 %132\n        %135 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_8\n        %136 =   OpLoad %v4uint %135\n        %137 =   OpBitcast %v4float %136\n        %138 =   OpCompositeExtract %float %137 0\n        %139 =   OpCompositeExtract %float %137 1\n        %140 =   OpCompositeExtract %float %137 2\n        %141 =   OpCompositeExtract %float %137 3\n        %142 =   OpCompositeConstruct %v4float %138 %139 %140 %141\n        %143 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_8\n                 OpStore %143 %142\n        %145 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_9\n        %146 =   OpLoad %v4uint %145\n        %147 =   OpBitcast %v4float %146\n        %148 =   OpCompositeExtract %float %147 0\n        %149 =   OpCompositeExtract %float %147 1\n        %150 =   OpCompositeExtract %float %147 2\n        %151 =   OpCompositeExtract %float %147 3\n        %152 =   OpCompositeConstruct %v4float %148 %149 %150 %151\n        %153 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_9\n                 OpStore %153 %152\n        %155 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_10\n        %156 =   OpLoad %v4uint %155\n        %157 =   OpBitcast %v4float %156\n        %158 =   OpCompositeExtract %float %157 0\n        %159 =   OpCompositeExtract %float %157 1\n        %160 =   OpCompositeExtract %float %157 2\n        %161 =   OpCompositeExtract %float %157 3\n        %162 =   OpCompositeConstruct %v4float %158 %159 %160 %161\n        %163 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_10\n                 OpStore %163 %162\n        %165 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_11\n        %166 =   OpLoad %v4uint %165\n        %167 =   OpBitcast %v4float %166\n        %168 =   OpCompositeExtract %float %167 0\n        %169 =   OpCompositeExtract %float %167 1\n        %170 =   OpCompositeExtract %float %167 2\n        %171 =   OpCompositeExtract %float %167 3\n        %172 =   OpCompositeConstruct %v4float %168 %169 %170 %171\n        %173 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_11\n                 OpStore %173 %172\n        %175 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_12\n        %176 =   OpLoad %v4uint %175\n        %177 =   OpBitcast %v4float %176\n        %178 =   OpCompositeExtract %float %177 0\n        %179 =   OpCompositeExtract %float %177 1\n        %180 =   OpCompositeExtract %float %177 2\n        %181 =   OpCompositeExtract %float %177 3\n        %182 =   OpCompositeConstruct %v4float %178 %179 %180 %181\n        %183 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_12\n                 OpStore %183 %182\n        %185 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_13\n        %186 =   OpLoad %v4uint %185\n        %187 =   OpBitcast %v4float %186\n        %188 =   OpCompositeExtract %float %187 0\n        %189 =   OpCompositeExtract %float %187 1\n        %190 =   OpCompositeExtract %float %187 2\n        %191 =   OpCompositeExtract %float %187 3\n        %192 =   OpCompositeConstruct %v4float %188 %189 %190 %191\n        %193 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_13\n                 OpStore %193 %192\n        %195 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_14\n        %196 =   OpLoad %v4uint %195\n        %197 =   OpBitcast %v4float %196\n        %198 =   OpCompositeExtract %float %197 0\n        %199 =   OpCompositeExtract %float %197 1\n        %200 =   OpCompositeExtract %float %197 2\n        %201 =   OpCompositeExtract %float %197 3\n        %202 =   OpCompositeConstruct %v4float %198 %199 %200 %201\n        %203 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_14\n                 OpStore %203 %202\n        %205 =   OpAccessChain %_ptr_StorageBuffer_v4uint %10 %uint_0 %uint_15\n        %206 =   OpLoad %v4uint %205\n        %207 =   OpBitcast %v4float %206\n        %208 =   OpCompositeExtract %float %207 0\n        %209 =   OpCompositeExtract %float %207 1\n        %210 =   OpCompositeExtract %float %207 2\n        %211 =   OpCompositeExtract %float %207 3\n        %212 =   OpCompositeConstruct %v4float %208 %209 %210 %211\n        %213 =   OpInBoundsAccessChain %_ptr_Private_v4float %27 %uint_15\n                 OpStore %213 %212\n        %216 =   OpIMul %uint %38 %uint_64\n        %219 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %216\n        %220 =   OpLoad %uint %219\n        %221 =   OpBitwiseAnd %uint %220 %uint_3\n        %224 =   OpInBoundsAccessChain %_ptr_Private_float %31 %221 %uint_0\n        %225 =   OpLoad %float %224\n        %227 =   OpInBoundsAccessChain %_ptr_Private_float %27 %220 %uint_0\n        %228 =   OpLoad %float %227\n        %229 =   OpFAdd %float %225 %228\n        %231 =   OpInBoundsAccessChain %_ptr_Private_float %31 %221 %uint_0\n                 OpStore %231 %229\n        %232 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %220\n        %233 =   OpLoad %uint %232\n        %234 =   OpIAdd %uint %233 %uint_1\n        %235 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %220\n                 OpStore %235 %234\n        %237 =   OpIMul %uint %38 %uint_64\n        %238 =   OpIAdd %uint %237 %uint_1\n        %239 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %238\n        %240 =   OpLoad %uint %239\n        %241 =   OpBitwiseAnd %uint %240 %uint_3\n        %243 =   OpInBoundsAccessChain %_ptr_Private_float %31 %241 %uint_0\n        %244 =   OpLoad %float %243\n        %246 =   OpInBoundsAccessChain %_ptr_Private_float %27 %240 %uint_1\n        %247 =   OpLoad %float %246\n        %248 =   OpFAdd %float %244 %247\n        %250 =   OpInBoundsAccessChain %_ptr_Private_float %31 %241 %uint_0\n                 OpStore %250 %248\n        %251 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %240\n        %252 =   OpLoad %uint %251\n        %253 =   OpIAdd %uint %252 %uint_1\n        %254 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %240\n                 OpStore %254 %253\n        %256 =   OpIMul %uint %38 %uint_64\n        %257 =   OpIAdd %uint %256 %uint_2\n        %258 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %257\n        %259 =   OpLoad %uint %258\n        %260 =   OpBitwiseAnd %uint %259 %uint_3\n        %262 =   OpInBoundsAccessChain %_ptr_Private_float %31 %260 %uint_0\n        %263 =   OpLoad %float %262\n        %265 =   OpInBoundsAccessChain %_ptr_Private_float %27 %259 %uint_2\n        %266 =   OpLoad %float %265\n        %267 =   OpFAdd %float %263 %266\n        %269 =   OpInBoundsAccessChain %_ptr_Private_float %31 %260 %uint_0\n                 OpStore %269 %267\n        %270 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %259\n        %271 =   OpLoad %uint %270\n        %272 =   OpIAdd %uint %271 %uint_1\n        %273 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %259\n                 OpStore %273 %272\n        %275 =   OpIMul %uint %38 %uint_64\n        %276 =   OpIAdd %uint %275 %uint_3\n        %277 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %276\n        %278 =   OpLoad %uint %277\n        %279 =   OpBitwiseAnd %uint %278 %uint_3\n        %281 =   OpInBoundsAccessChain %_ptr_Private_float %31 %279 %uint_0\n        %282 =   OpLoad %float %281\n        %284 =   OpInBoundsAccessChain %_ptr_Private_float %27 %278 %uint_3\n        %285 =   OpLoad %float %284\n        %286 =   OpFAdd %float %282 %285\n        %288 =   OpInBoundsAccessChain %_ptr_Private_float %31 %279 %uint_0\n                 OpStore %288 %286\n        %289 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %278\n        %290 =   OpLoad %uint %289\n        %291 =   OpIAdd %uint %290 %uint_1\n        %292 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %278\n                 OpStore %292 %291\n        %294 =   OpIMul %uint %38 %uint_64\n        %295 =   OpIAdd %uint %294 %uint_4\n        %296 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %295\n        %297 =   OpLoad %uint %296\n        %298 =   OpBitwiseAnd %uint %297 %uint_3\n        %300 =   OpInBoundsAccessChain %_ptr_Private_float %31 %298 %uint_1\n        %301 =   OpLoad %float %300\n        %303 =   OpInBoundsAccessChain %_ptr_Private_float %27 %297 %uint_0\n        %304 =   OpLoad %float %303\n        %305 =   OpFAdd %float %301 %304\n        %307 =   OpInBoundsAccessChain %_ptr_Private_float %31 %298 %uint_1\n                 OpStore %307 %305\n        %308 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %297\n        %309 =   OpLoad %uint %308\n        %310 =   OpIAdd %uint %309 %uint_1\n        %311 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %297\n                 OpStore %311 %310\n        %313 =   OpIMul %uint %38 %uint_64\n        %314 =   OpIAdd %uint %313 %uint_5\n        %315 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %314\n        %316 =   OpLoad %uint %315\n        %317 =   OpBitwiseAnd %uint %316 %uint_3\n        %319 =   OpInBoundsAccessChain %_ptr_Private_float %31 %317 %uint_1\n        %320 =   OpLoad %float %319\n        %322 =   OpInBoundsAccessChain %_ptr_Private_float %27 %316 %uint_1\n        %323 =   OpLoad %float %322\n        %324 =   OpFAdd %float %320 %323\n        %326 =   OpInBoundsAccessChain %_ptr_Private_float %31 %317 %uint_1\n                 OpStore %326 %324\n        %327 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %316\n        %328 =   OpLoad %uint %327\n        %329 =   OpIAdd %uint %328 %uint_1\n        %330 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %316\n                 OpStore %330 %329\n        %332 =   OpIMul %uint %38 %uint_64\n        %333 =   OpIAdd %uint %332 %uint_6\n        %334 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %333\n        %335 =   OpLoad %uint %334\n        %336 =   OpBitwiseAnd %uint %335 %uint_3\n        %338 =   OpInBoundsAccessChain %_ptr_Private_float %31 %336 %uint_1\n        %339 =   OpLoad %float %338\n        %341 =   OpInBoundsAccessChain %_ptr_Private_float %27 %335 %uint_2\n        %342 =   OpLoad %float %341\n        %343 =   OpFAdd %float %339 %342\n        %345 =   OpInBoundsAccessChain %_ptr_Private_float %31 %336 %uint_1\n                 OpStore %345 %343\n        %346 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %335\n        %347 =   OpLoad %uint %346\n        %348 =   OpIAdd %uint %347 %uint_1\n        %349 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %335\n                 OpStore %349 %348\n        %351 =   OpIMul %uint %38 %uint_64\n        %352 =   OpIAdd %uint %351 %uint_7\n        %353 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %352\n        %354 =   OpLoad %uint %353\n        %355 =   OpBitwiseAnd %uint %354 %uint_3\n        %357 =   OpInBoundsAccessChain %_ptr_Private_float %31 %355 %uint_1\n        %358 =   OpLoad %float %357\n        %360 =   OpInBoundsAccessChain %_ptr_Private_float %27 %354 %uint_3\n        %361 =   OpLoad %float %360\n        %362 =   OpFAdd %float %358 %361\n        %364 =   OpInBoundsAccessChain %_ptr_Private_float %31 %355 %uint_1\n                 OpStore %364 %362\n        %365 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %354\n        %366 =   OpLoad %uint %365\n        %367 =   OpIAdd %uint %366 %uint_1\n        %368 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %354\n                 OpStore %368 %367\n        %370 =   OpIMul %uint %38 %uint_64\n        %371 =   OpIAdd %uint %370 %uint_8\n        %372 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %371\n        %373 =   OpLoad %uint %372\n        %374 =   OpBitwiseAnd %uint %373 %uint_3\n        %376 =   OpInBoundsAccessChain %_ptr_Private_float %31 %374 %uint_2\n        %377 =   OpLoad %float %376\n        %379 =   OpInBoundsAccessChain %_ptr_Private_float %27 %373 %uint_0\n        %380 =   OpLoad %float %379\n        %381 =   OpFAdd %float %377 %380\n        %383 =   OpInBoundsAccessChain %_ptr_Private_float %31 %374 %uint_2\n                 OpStore %383 %381\n        %384 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %373\n        %385 =   OpLoad %uint %384\n        %386 =   OpIAdd %uint %385 %uint_1\n        %387 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %373\n                 OpStore %387 %386\n        %389 =   OpIMul %uint %38 %uint_64\n        %390 =   OpIAdd %uint %389 %uint_9\n        %391 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %390\n        %392 =   OpLoad %uint %391\n        %393 =   OpBitwiseAnd %uint %392 %uint_3\n        %395 =   OpInBoundsAccessChain %_ptr_Private_float %31 %393 %uint_2\n        %396 =   OpLoad %float %395\n        %398 =   OpInBoundsAccessChain %_ptr_Private_float %27 %392 %uint_1\n        %399 =   OpLoad %float %398\n        %400 =   OpFAdd %float %396 %399\n        %402 =   OpInBoundsAccessChain %_ptr_Private_float %31 %393 %uint_2\n                 OpStore %402 %400\n        %403 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %392\n        %404 =   OpLoad %uint %403\n        %405 =   OpIAdd %uint %404 %uint_1\n        %406 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %392\n                 OpStore %406 %405\n        %408 =   OpIMul %uint %38 %uint_64\n        %409 =   OpIAdd %uint %408 %uint_10\n        %410 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %409\n        %411 =   OpLoad %uint %410\n        %412 =   OpBitwiseAnd %uint %411 %uint_3\n        %414 =   OpInBoundsAccessChain %_ptr_Private_float %31 %412 %uint_2\n        %415 =   OpLoad %float %414\n        %417 =   OpInBoundsAccessChain %_ptr_Private_float %27 %411 %uint_2\n        %418 =   OpLoad %float %417\n        %419 =   OpFAdd %float %415 %418\n        %421 =   OpInBoundsAccessChain %_ptr_Private_float %31 %412 %uint_2\n                 OpStore %421 %419\n        %422 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %411\n        %423 =   OpLoad %uint %422\n        %424 =   OpIAdd %uint %423 %uint_1\n        %425 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %411\n                 OpStore %425 %424\n        %427 =   OpIMul %uint %38 %uint_64\n        %428 =   OpIAdd %uint %427 %uint_11\n        %429 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %428\n        %430 =   OpLoad %uint %429\n        %431 =   OpBitwiseAnd %uint %430 %uint_3\n        %433 =   OpInBoundsAccessChain %_ptr_Private_float %31 %431 %uint_2\n        %434 =   OpLoad %float %433\n        %436 =   OpInBoundsAccessChain %_ptr_Private_float %27 %430 %uint_3\n        %437 =   OpLoad %float %436\n        %438 =   OpFAdd %float %434 %437\n        %440 =   OpInBoundsAccessChain %_ptr_Private_float %31 %431 %uint_2\n                 OpStore %440 %438\n        %441 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %430\n        %442 =   OpLoad %uint %441\n        %443 =   OpIAdd %uint %442 %uint_1\n        %444 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %430\n                 OpStore %444 %443\n        %446 =   OpIMul %uint %38 %uint_64\n        %447 =   OpIAdd %uint %446 %uint_12\n        %448 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %447\n        %449 =   OpLoad %uint %448\n        %450 =   OpBitwiseAnd %uint %449 %uint_3\n        %452 =   OpInBoundsAccessChain %_ptr_Private_float %31 %450 %uint_3\n        %453 =   OpLoad %float %452\n        %455 =   OpInBoundsAccessChain %_ptr_Private_float %27 %449 %uint_0\n        %456 =   OpLoad %float %455\n        %457 =   OpFAdd %float %453 %456\n        %459 =   OpInBoundsAccessChain %_ptr_Private_float %31 %450 %uint_3\n                 OpStore %459 %457\n        %460 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %449\n        %461 =   OpLoad %uint %460\n        %462 =   OpIAdd %uint %461 %uint_1\n        %463 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %449\n                 OpStore %463 %462\n        %465 =   OpIMul %uint %38 %uint_64\n        %466 =   OpIAdd %uint %465 %uint_13\n        %467 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %466\n        %468 =   OpLoad %uint %467\n        %469 =   OpBitwiseAnd %uint %468 %uint_3\n        %471 =   OpInBoundsAccessChain %_ptr_Private_float %31 %469 %uint_3\n        %472 =   OpLoad %float %471\n        %474 =   OpInBoundsAccessChain %_ptr_Private_float %27 %468 %uint_1\n        %475 =   OpLoad %float %474\n        %476 =   OpFAdd %float %472 %475\n        %478 =   OpInBoundsAccessChain %_ptr_Private_float %31 %469 %uint_3\n                 OpStore %478 %476\n        %479 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %468\n        %480 =   OpLoad %uint %479\n        %481 =   OpIAdd %uint %480 %uint_1\n        %482 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %468\n                 OpStore %482 %481\n        %484 =   OpIMul %uint %38 %uint_64\n        %485 =   OpIAdd %uint %484 %uint_14\n        %486 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %485\n        %487 =   OpLoad %uint %486\n        %488 =   OpBitwiseAnd %uint %487 %uint_3\n        %490 =   OpInBoundsAccessChain %_ptr_Private_float %31 %488 %uint_3\n        %491 =   OpLoad %float %490\n        %493 =   OpInBoundsAccessChain %_ptr_Private_float %27 %487 %uint_2\n        %494 =   OpLoad %float %493\n        %495 =   OpFAdd %float %491 %494\n        %497 =   OpInBoundsAccessChain %_ptr_Private_float %31 %488 %uint_3\n                 OpStore %497 %495\n        %498 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %487\n        %499 =   OpLoad %uint %498\n        %500 =   OpIAdd %uint %499 %uint_1\n        %501 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %487\n                 OpStore %501 %500\n        %503 =   OpIMul %uint %38 %uint_64\n        %504 =   OpIAdd %uint %503 %uint_15\n        %505 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %504\n        %506 =   OpLoad %uint %505\n        %507 =   OpBitwiseAnd %uint %506 %uint_3\n        %509 =   OpInBoundsAccessChain %_ptr_Private_float %31 %507 %uint_3\n        %510 =   OpLoad %float %509\n        %512 =   OpInBoundsAccessChain %_ptr_Private_float %27 %506 %uint_3\n        %513 =   OpLoad %float %512\n        %514 =   OpFAdd %float %510 %513\n        %516 =   OpInBoundsAccessChain %_ptr_Private_float %31 %507 %uint_3\n                 OpStore %516 %514\n        %517 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %506\n        %518 =   OpLoad %uint %517\n        %519 =   OpIAdd %uint %518 %uint_1\n        %520 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %506\n                 OpStore %520 %519\n        %522 =   OpIMul %uint %38 %uint_64\n        %523 =   OpIAdd %uint %522 %uint_16\n        %524 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %523\n        %525 =   OpLoad %uint %524\n        %526 =   OpBitwiseAnd %uint %525 %uint_3\n        %528 =   OpInBoundsAccessChain %_ptr_Private_float %31 %526 %uint_0\n        %529 =   OpLoad %float %528\n        %531 =   OpInBoundsAccessChain %_ptr_Private_float %27 %525 %uint_0\n        %532 =   OpLoad %float %531\n        %533 =   OpFAdd %float %529 %532\n        %535 =   OpInBoundsAccessChain %_ptr_Private_float %31 %526 %uint_0\n                 OpStore %535 %533\n        %536 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %525\n        %537 =   OpLoad %uint %536\n        %538 =   OpIAdd %uint %537 %uint_1\n        %539 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %525\n                 OpStore %539 %538\n        %542 =   OpIMul %uint %38 %uint_64\n        %543 =   OpIAdd %uint %542 %uint_17\n        %544 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %543\n        %545 =   OpLoad %uint %544\n        %546 =   OpBitwiseAnd %uint %545 %uint_3\n        %548 =   OpInBoundsAccessChain %_ptr_Private_float %31 %546 %uint_0\n        %549 =   OpLoad %float %548\n        %551 =   OpInBoundsAccessChain %_ptr_Private_float %27 %545 %uint_1\n        %552 =   OpLoad %float %551\n        %553 =   OpFAdd %float %549 %552\n        %555 =   OpInBoundsAccessChain %_ptr_Private_float %31 %546 %uint_0\n                 OpStore %555 %553\n        %556 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %545\n        %557 =   OpLoad %uint %556\n        %558 =   OpIAdd %uint %557 %uint_1\n        %559 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %545\n                 OpStore %559 %558\n        %562 =   OpIMul %uint %38 %uint_64\n        %563 =   OpIAdd %uint %562 %uint_18\n        %564 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %563\n        %565 =   OpLoad %uint %564\n        %566 =   OpBitwiseAnd %uint %565 %uint_3\n        %568 =   OpInBoundsAccessChain %_ptr_Private_float %31 %566 %uint_0\n        %569 =   OpLoad %float %568\n        %571 =   OpInBoundsAccessChain %_ptr_Private_float %27 %565 %uint_2\n        %572 =   OpLoad %float %571\n        %573 =   OpFAdd %float %569 %572\n        %575 =   OpInBoundsAccessChain %_ptr_Private_float %31 %566 %uint_0\n                 OpStore %575 %573\n        %576 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %565\n        %577 =   OpLoad %uint %576\n        %578 =   OpIAdd %uint %577 %uint_1\n        %579 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %565\n                 OpStore %579 %578\n        %582 =   OpIMul %uint %38 %uint_64\n        %583 =   OpIAdd %uint %582 %uint_19\n        %584 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %583\n        %585 =   OpLoad %uint %584\n        %586 =   OpBitwiseAnd %uint %585 %uint_3\n        %588 =   OpInBoundsAccessChain %_ptr_Private_float %31 %586 %uint_0\n        %589 =   OpLoad %float %588\n        %591 =   OpInBoundsAccessChain %_ptr_Private_float %27 %585 %uint_3\n        %592 =   OpLoad %float %591\n        %593 =   OpFAdd %float %589 %592\n        %595 =   OpInBoundsAccessChain %_ptr_Private_float %31 %586 %uint_0\n                 OpStore %595 %593\n        %596 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %585\n        %597 =   OpLoad %uint %596\n        %598 =   OpIAdd %uint %597 %uint_1\n        %599 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %585\n                 OpStore %599 %598\n        %602 =   OpIMul %uint %38 %uint_64\n        %603 =   OpIAdd %uint %602 %uint_20\n        %604 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %603\n        %605 =   OpLoad %uint %604\n        %606 =   OpBitwiseAnd %uint %605 %uint_3\n        %608 =   OpInBoundsAccessChain %_ptr_Private_float %31 %606 %uint_1\n        %609 =   OpLoad %float %608\n        %611 =   OpInBoundsAccessChain %_ptr_Private_float %27 %605 %uint_0\n        %612 =   OpLoad %float %611\n        %613 =   OpFAdd %float %609 %612\n        %615 =   OpInBoundsAccessChain %_ptr_Private_float %31 %606 %uint_1\n                 OpStore %615 %613\n        %616 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %605\n        %617 =   OpLoad %uint %616\n        %618 =   OpIAdd %uint %617 %uint_1\n        %619 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %605\n                 OpStore %619 %618\n        %622 =   OpIMul %uint %38 %uint_64\n        %623 =   OpIAdd %uint %622 %uint_21\n        %624 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %623\n        %625 =   OpLoad %uint %624\n        %626 =   OpBitwiseAnd %uint %625 %uint_3\n        %628 =   OpInBoundsAccessChain %_ptr_Private_float %31 %626 %uint_1\n        %629 =   OpLoad %float %628\n        %631 =   OpInBoundsAccessChain %_ptr_Private_float %27 %625 %uint_1\n        %632 =   OpLoad %float %631\n        %633 =   OpFAdd %float %629 %632\n        %635 =   OpInBoundsAccessChain %_ptr_Private_float %31 %626 %uint_1\n                 OpStore %635 %633\n        %636 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %625\n        %637 =   OpLoad %uint %636\n        %638 =   OpIAdd %uint %637 %uint_1\n        %639 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %625\n                 OpStore %639 %638\n        %642 =   OpIMul %uint %38 %uint_64\n        %643 =   OpIAdd %uint %642 %uint_22\n        %644 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %643\n        %645 =   OpLoad %uint %644\n        %646 =   OpBitwiseAnd %uint %645 %uint_3\n        %648 =   OpInBoundsAccessChain %_ptr_Private_float %31 %646 %uint_1\n        %649 =   OpLoad %float %648\n        %651 =   OpInBoundsAccessChain %_ptr_Private_float %27 %645 %uint_2\n        %652 =   OpLoad %float %651\n        %653 =   OpFAdd %float %649 %652\n        %655 =   OpInBoundsAccessChain %_ptr_Private_float %31 %646 %uint_1\n                 OpStore %655 %653\n        %656 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %645\n        %657 =   OpLoad %uint %656\n        %658 =   OpIAdd %uint %657 %uint_1\n        %659 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %645\n                 OpStore %659 %658\n        %662 =   OpIMul %uint %38 %uint_64\n        %663 =   OpIAdd %uint %662 %uint_23\n        %664 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %663\n        %665 =   OpLoad %uint %664\n        %666 =   OpBitwiseAnd %uint %665 %uint_3\n        %668 =   OpInBoundsAccessChain %_ptr_Private_float %31 %666 %uint_1\n        %669 =   OpLoad %float %668\n        %671 =   OpInBoundsAccessChain %_ptr_Private_float %27 %665 %uint_3\n        %672 =   OpLoad %float %671\n        %673 =   OpFAdd %float %669 %672\n        %675 =   OpInBoundsAccessChain %_ptr_Private_float %31 %666 %uint_1\n                 OpStore %675 %673\n        %676 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %665\n        %677 =   OpLoad %uint %676\n        %678 =   OpIAdd %uint %677 %uint_1\n        %679 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %665\n                 OpStore %679 %678\n        %682 =   OpIMul %uint %38 %uint_64\n        %683 =   OpIAdd %uint %682 %uint_24\n        %684 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %683\n        %685 =   OpLoad %uint %684\n        %686 =   OpBitwiseAnd %uint %685 %uint_3\n        %688 =   OpInBoundsAccessChain %_ptr_Private_float %31 %686 %uint_2\n        %689 =   OpLoad %float %688\n        %691 =   OpInBoundsAccessChain %_ptr_Private_float %27 %685 %uint_0\n        %692 =   OpLoad %float %691\n        %693 =   OpFAdd %float %689 %692\n        %695 =   OpInBoundsAccessChain %_ptr_Private_float %31 %686 %uint_2\n                 OpStore %695 %693\n        %696 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %685\n        %697 =   OpLoad %uint %696\n        %698 =   OpIAdd %uint %697 %uint_1\n        %699 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %685\n                 OpStore %699 %698\n        %702 =   OpIMul %uint %38 %uint_64\n        %703 =   OpIAdd %uint %702 %uint_25\n        %704 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %703\n        %705 =   OpLoad %uint %704\n        %706 =   OpBitwiseAnd %uint %705 %uint_3\n        %708 =   OpInBoundsAccessChain %_ptr_Private_float %31 %706 %uint_2\n        %709 =   OpLoad %float %708\n        %711 =   OpInBoundsAccessChain %_ptr_Private_float %27 %705 %uint_1\n        %712 =   OpLoad %float %711\n        %713 =   OpFAdd %float %709 %712\n        %715 =   OpInBoundsAccessChain %_ptr_Private_float %31 %706 %uint_2\n                 OpStore %715 %713\n        %716 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %705\n        %717 =   OpLoad %uint %716\n        %718 =   OpIAdd %uint %717 %uint_1\n        %719 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %705\n                 OpStore %719 %718\n        %722 =   OpIMul %uint %38 %uint_64\n        %723 =   OpIAdd %uint %722 %uint_26\n        %724 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %723\n        %725 =   OpLoad %uint %724\n        %726 =   OpBitwiseAnd %uint %725 %uint_3\n        %728 =   OpInBoundsAccessChain %_ptr_Private_float %31 %726 %uint_2\n        %729 =   OpLoad %float %728\n        %731 =   OpInBoundsAccessChain %_ptr_Private_float %27 %725 %uint_2\n        %732 =   OpLoad %float %731\n        %733 =   OpFAdd %float %729 %732\n        %735 =   OpInBoundsAccessChain %_ptr_Private_float %31 %726 %uint_2\n                 OpStore %735 %733\n        %736 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %725\n        %737 =   OpLoad %uint %736\n        %738 =   OpIAdd %uint %737 %uint_1\n        %739 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %725\n                 OpStore %739 %738\n        %742 =   OpIMul %uint %38 %uint_64\n        %743 =   OpIAdd %uint %742 %uint_27\n        %744 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %743\n        %745 =   OpLoad %uint %744\n        %746 =   OpBitwiseAnd %uint %745 %uint_3\n        %748 =   OpInBoundsAccessChain %_ptr_Private_float %31 %746 %uint_2\n        %749 =   OpLoad %float %748\n        %751 =   OpInBoundsAccessChain %_ptr_Private_float %27 %745 %uint_3\n        %752 =   OpLoad %float %751\n        %753 =   OpFAdd %float %749 %752\n        %755 =   OpInBoundsAccessChain %_ptr_Private_float %31 %746 %uint_2\n                 OpStore %755 %753\n        %756 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %745\n        %757 =   OpLoad %uint %756\n        %758 =   OpIAdd %uint %757 %uint_1\n        %759 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %745\n                 OpStore %759 %758\n        %762 =   OpIMul %uint %38 %uint_64\n        %763 =   OpIAdd %uint %762 %uint_28\n        %764 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %763\n        %765 =   OpLoad %uint %764\n        %766 =   OpBitwiseAnd %uint %765 %uint_3\n        %768 =   OpInBoundsAccessChain %_ptr_Private_float %31 %766 %uint_3\n        %769 =   OpLoad %float %768\n        %771 =   OpInBoundsAccessChain %_ptr_Private_float %27 %765 %uint_0\n        %772 =   OpLoad %float %771\n        %773 =   OpFAdd %float %769 %772\n        %775 =   OpInBoundsAccessChain %_ptr_Private_float %31 %766 %uint_3\n                 OpStore %775 %773\n        %776 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %765\n        %777 =   OpLoad %uint %776\n        %778 =   OpIAdd %uint %777 %uint_1\n        %779 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %765\n                 OpStore %779 %778\n        %782 =   OpIMul %uint %38 %uint_64\n        %783 =   OpIAdd %uint %782 %uint_29\n        %784 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %783\n        %785 =   OpLoad %uint %784\n        %786 =   OpBitwiseAnd %uint %785 %uint_3\n        %788 =   OpInBoundsAccessChain %_ptr_Private_float %31 %786 %uint_3\n        %789 =   OpLoad %float %788\n        %791 =   OpInBoundsAccessChain %_ptr_Private_float %27 %785 %uint_1\n        %792 =   OpLoad %float %791\n        %793 =   OpFAdd %float %789 %792\n        %795 =   OpInBoundsAccessChain %_ptr_Private_float %31 %786 %uint_3\n                 OpStore %795 %793\n        %796 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %785\n        %797 =   OpLoad %uint %796\n        %798 =   OpIAdd %uint %797 %uint_1\n        %799 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %785\n                 OpStore %799 %798\n        %802 =   OpIMul %uint %38 %uint_64\n        %803 =   OpIAdd %uint %802 %uint_30\n        %804 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %803\n        %805 =   OpLoad %uint %804\n        %806 =   OpBitwiseAnd %uint %805 %uint_3\n        %808 =   OpInBoundsAccessChain %_ptr_Private_float %31 %806 %uint_3\n        %809 =   OpLoad %float %808\n        %811 =   OpInBoundsAccessChain %_ptr_Private_float %27 %805 %uint_2\n        %812 =   OpLoad %float %811\n        %813 =   OpFAdd %float %809 %812\n        %815 =   OpInBoundsAccessChain %_ptr_Private_float %31 %806 %uint_3\n                 OpStore %815 %813\n        %816 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %805\n        %817 =   OpLoad %uint %816\n        %818 =   OpIAdd %uint %817 %uint_1\n        %819 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %805\n                 OpStore %819 %818\n        %822 =   OpIMul %uint %38 %uint_64\n        %823 =   OpIAdd %uint %822 %uint_31\n        %824 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %823\n        %825 =   OpLoad %uint %824\n        %826 =   OpBitwiseAnd %uint %825 %uint_3\n        %828 =   OpInBoundsAccessChain %_ptr_Private_float %31 %826 %uint_3\n        %829 =   OpLoad %float %828\n        %831 =   OpInBoundsAccessChain %_ptr_Private_float %27 %825 %uint_3\n        %832 =   OpLoad %float %831\n        %833 =   OpFAdd %float %829 %832\n        %835 =   OpInBoundsAccessChain %_ptr_Private_float %31 %826 %uint_3\n                 OpStore %835 %833\n        %836 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %825\n        %837 =   OpLoad %uint %836\n        %838 =   OpIAdd %uint %837 %uint_1\n        %839 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %825\n                 OpStore %839 %838\n        %842 =   OpIMul %uint %38 %uint_64\n        %843 =   OpIAdd %uint %842 %uint_32\n        %844 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %843\n        %845 =   OpLoad %uint %844\n        %846 =   OpBitwiseAnd %uint %845 %uint_3\n        %848 =   OpInBoundsAccessChain %_ptr_Private_float %31 %846 %uint_0\n        %849 =   OpLoad %float %848\n        %851 =   OpInBoundsAccessChain %_ptr_Private_float %27 %845 %uint_0\n        %852 =   OpLoad %float %851\n        %853 =   OpFAdd %float %849 %852\n        %855 =   OpInBoundsAccessChain %_ptr_Private_float %31 %846 %uint_0\n                 OpStore %855 %853\n        %856 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %845\n        %857 =   OpLoad %uint %856\n        %858 =   OpIAdd %uint %857 %uint_1\n        %859 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %845\n                 OpStore %859 %858\n        %862 =   OpIMul %uint %38 %uint_64\n        %863 =   OpIAdd %uint %862 %uint_33\n        %864 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %863\n        %865 =   OpLoad %uint %864\n        %866 =   OpBitwiseAnd %uint %865 %uint_3\n        %868 =   OpInBoundsAccessChain %_ptr_Private_float %31 %866 %uint_0\n        %869 =   OpLoad %float %868\n        %871 =   OpInBoundsAccessChain %_ptr_Private_float %27 %865 %uint_1\n        %872 =   OpLoad %float %871\n        %873 =   OpFAdd %float %869 %872\n        %875 =   OpInBoundsAccessChain %_ptr_Private_float %31 %866 %uint_0\n                 OpStore %875 %873\n        %876 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %865\n        %877 =   OpLoad %uint %876\n        %878 =   OpIAdd %uint %877 %uint_1\n        %879 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %865\n                 OpStore %879 %878\n        %882 =   OpIMul %uint %38 %uint_64\n        %883 =   OpIAdd %uint %882 %uint_34\n        %884 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %883\n        %885 =   OpLoad %uint %884\n        %886 =   OpBitwiseAnd %uint %885 %uint_3\n        %888 =   OpInBoundsAccessChain %_ptr_Private_float %31 %886 %uint_0\n        %889 =   OpLoad %float %888\n        %891 =   OpInBoundsAccessChain %_ptr_Private_float %27 %885 %uint_2\n        %892 =   OpLoad %float %891\n        %893 =   OpFAdd %float %889 %892\n        %895 =   OpInBoundsAccessChain %_ptr_Private_float %31 %886 %uint_0\n                 OpStore %895 %893\n        %896 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %885\n        %897 =   OpLoad %uint %896\n        %898 =   OpIAdd %uint %897 %uint_1\n        %899 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %885\n                 OpStore %899 %898\n        %902 =   OpIMul %uint %38 %uint_64\n        %903 =   OpIAdd %uint %902 %uint_35\n        %904 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %903\n        %905 =   OpLoad %uint %904\n        %906 =   OpBitwiseAnd %uint %905 %uint_3\n        %908 =   OpInBoundsAccessChain %_ptr_Private_float %31 %906 %uint_0\n        %909 =   OpLoad %float %908\n        %911 =   OpInBoundsAccessChain %_ptr_Private_float %27 %905 %uint_3\n        %912 =   OpLoad %float %911\n        %913 =   OpFAdd %float %909 %912\n        %915 =   OpInBoundsAccessChain %_ptr_Private_float %31 %906 %uint_0\n                 OpStore %915 %913\n        %916 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %905\n        %917 =   OpLoad %uint %916\n        %918 =   OpIAdd %uint %917 %uint_1\n        %919 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %905\n                 OpStore %919 %918\n        %922 =   OpIMul %uint %38 %uint_64\n        %923 =   OpIAdd %uint %922 %uint_36\n        %924 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %923\n        %925 =   OpLoad %uint %924\n        %926 =   OpBitwiseAnd %uint %925 %uint_3\n        %928 =   OpInBoundsAccessChain %_ptr_Private_float %31 %926 %uint_1\n        %929 =   OpLoad %float %928\n        %931 =   OpInBoundsAccessChain %_ptr_Private_float %27 %925 %uint_0\n        %932 =   OpLoad %float %931\n        %933 =   OpFAdd %float %929 %932\n        %935 =   OpInBoundsAccessChain %_ptr_Private_float %31 %926 %uint_1\n                 OpStore %935 %933\n        %936 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %925\n        %937 =   OpLoad %uint %936\n        %938 =   OpIAdd %uint %937 %uint_1\n        %939 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %925\n                 OpStore %939 %938\n        %942 =   OpIMul %uint %38 %uint_64\n        %943 =   OpIAdd %uint %942 %uint_37\n        %944 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %943\n        %945 =   OpLoad %uint %944\n        %946 =   OpBitwiseAnd %uint %945 %uint_3\n        %948 =   OpInBoundsAccessChain %_ptr_Private_float %31 %946 %uint_1\n        %949 =   OpLoad %float %948\n        %951 =   OpInBoundsAccessChain %_ptr_Private_float %27 %945 %uint_1\n        %952 =   OpLoad %float %951\n        %953 =   OpFAdd %float %949 %952\n        %955 =   OpInBoundsAccessChain %_ptr_Private_float %31 %946 %uint_1\n                 OpStore %955 %953\n        %956 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %945\n        %957 =   OpLoad %uint %956\n        %958 =   OpIAdd %uint %957 %uint_1\n        %959 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %945\n                 OpStore %959 %958\n        %962 =   OpIMul %uint %38 %uint_64\n        %963 =   OpIAdd %uint %962 %uint_38\n        %964 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %963\n        %965 =   OpLoad %uint %964\n        %966 =   OpBitwiseAnd %uint %965 %uint_3\n        %968 =   OpInBoundsAccessChain %_ptr_Private_float %31 %966 %uint_1\n        %969 =   OpLoad %float %968\n        %971 =   OpInBoundsAccessChain %_ptr_Private_float %27 %965 %uint_2\n        %972 =   OpLoad %float %971\n        %973 =   OpFAdd %float %969 %972\n        %975 =   OpInBoundsAccessChain %_ptr_Private_float %31 %966 %uint_1\n                 OpStore %975 %973\n        %976 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %965\n        %977 =   OpLoad %uint %976\n        %978 =   OpIAdd %uint %977 %uint_1\n        %979 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %965\n                 OpStore %979 %978\n        %982 =   OpIMul %uint %38 %uint_64\n        %983 =   OpIAdd %uint %982 %uint_39\n        %984 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %983\n        %985 =   OpLoad %uint %984\n        %986 =   OpBitwiseAnd %uint %985 %uint_3\n        %988 =   OpInBoundsAccessChain %_ptr_Private_float %31 %986 %uint_1\n        %989 =   OpLoad %float %988\n        %991 =   OpInBoundsAccessChain %_ptr_Private_float %27 %985 %uint_3\n        %992 =   OpLoad %float %991\n        %993 =   OpFAdd %float %989 %992\n        %995 =   OpInBoundsAccessChain %_ptr_Private_float %31 %986 %uint_1\n                 OpStore %995 %993\n        %996 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %985\n        %997 =   OpLoad %uint %996\n        %998 =   OpIAdd %uint %997 %uint_1\n        %999 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %985\n                 OpStore %999 %998\n       %1002 =   OpIMul %uint %38 %uint_64\n       %1003 =   OpIAdd %uint %1002 %uint_40\n       %1004 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1003\n       %1005 =   OpLoad %uint %1004\n       %1006 =   OpBitwiseAnd %uint %1005 %uint_3\n       %1008 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1006 %uint_2\n       %1009 =   OpLoad %float %1008\n       %1011 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1005 %uint_0\n       %1012 =   OpLoad %float %1011\n       %1013 =   OpFAdd %float %1009 %1012\n       %1015 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1006 %uint_2\n                 OpStore %1015 %1013\n       %1016 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1005\n       %1017 =   OpLoad %uint %1016\n       %1018 =   OpIAdd %uint %1017 %uint_1\n       %1019 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1005\n                 OpStore %1019 %1018\n       %1022 =   OpIMul %uint %38 %uint_64\n       %1023 =   OpIAdd %uint %1022 %uint_41\n       %1024 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1023\n       %1025 =   OpLoad %uint %1024\n       %1026 =   OpBitwiseAnd %uint %1025 %uint_3\n       %1028 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1026 %uint_2\n       %1029 =   OpLoad %float %1028\n       %1031 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1025 %uint_1\n       %1032 =   OpLoad %float %1031\n       %1033 =   OpFAdd %float %1029 %1032\n       %1035 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1026 %uint_2\n                 OpStore %1035 %1033\n       %1036 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1025\n       %1037 =   OpLoad %uint %1036\n       %1038 =   OpIAdd %uint %1037 %uint_1\n       %1039 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1025\n                 OpStore %1039 %1038\n       %1042 =   OpIMul %uint %38 %uint_64\n       %1043 =   OpIAdd %uint %1042 %uint_42\n       %1044 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1043\n       %1045 =   OpLoad %uint %1044\n       %1046 =   OpBitwiseAnd %uint %1045 %uint_3\n       %1048 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1046 %uint_2\n       %1049 =   OpLoad %float %1048\n       %1051 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1045 %uint_2\n       %1052 =   OpLoad %float %1051\n       %1053 =   OpFAdd %float %1049 %1052\n       %1055 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1046 %uint_2\n                 OpStore %1055 %1053\n       %1056 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1045\n       %1057 =   OpLoad %uint %1056\n       %1058 =   OpIAdd %uint %1057 %uint_1\n       %1059 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1045\n                 OpStore %1059 %1058\n       %1062 =   OpIMul %uint %38 %uint_64\n       %1063 =   OpIAdd %uint %1062 %uint_43\n       %1064 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1063\n       %1065 =   OpLoad %uint %1064\n       %1066 =   OpBitwiseAnd %uint %1065 %uint_3\n       %1068 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1066 %uint_2\n       %1069 =   OpLoad %float %1068\n       %1071 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1065 %uint_3\n       %1072 =   OpLoad %float %1071\n       %1073 =   OpFAdd %float %1069 %1072\n       %1075 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1066 %uint_2\n                 OpStore %1075 %1073\n       %1076 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1065\n       %1077 =   OpLoad %uint %1076\n       %1078 =   OpIAdd %uint %1077 %uint_1\n       %1079 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1065\n                 OpStore %1079 %1078\n       %1082 =   OpIMul %uint %38 %uint_64\n       %1083 =   OpIAdd %uint %1082 %uint_44\n       %1084 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1083\n       %1085 =   OpLoad %uint %1084\n       %1086 =   OpBitwiseAnd %uint %1085 %uint_3\n       %1088 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1086 %uint_3\n       %1089 =   OpLoad %float %1088\n       %1091 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1085 %uint_0\n       %1092 =   OpLoad %float %1091\n       %1093 =   OpFAdd %float %1089 %1092\n       %1095 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1086 %uint_3\n                 OpStore %1095 %1093\n       %1096 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1085\n       %1097 =   OpLoad %uint %1096\n       %1098 =   OpIAdd %uint %1097 %uint_1\n       %1099 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1085\n                 OpStore %1099 %1098\n       %1102 =   OpIMul %uint %38 %uint_64\n       %1103 =   OpIAdd %uint %1102 %uint_45\n       %1104 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1103\n       %1105 =   OpLoad %uint %1104\n       %1106 =   OpBitwiseAnd %uint %1105 %uint_3\n       %1108 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1106 %uint_3\n       %1109 =   OpLoad %float %1108\n       %1111 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1105 %uint_1\n       %1112 =   OpLoad %float %1111\n       %1113 =   OpFAdd %float %1109 %1112\n       %1115 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1106 %uint_3\n                 OpStore %1115 %1113\n       %1116 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1105\n       %1117 =   OpLoad %uint %1116\n       %1118 =   OpIAdd %uint %1117 %uint_1\n       %1119 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1105\n                 OpStore %1119 %1118\n       %1122 =   OpIMul %uint %38 %uint_64\n       %1123 =   OpIAdd %uint %1122 %uint_46\n       %1124 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1123\n       %1125 =   OpLoad %uint %1124\n       %1126 =   OpBitwiseAnd %uint %1125 %uint_3\n       %1128 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1126 %uint_3\n       %1129 =   OpLoad %float %1128\n       %1131 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1125 %uint_2\n       %1132 =   OpLoad %float %1131\n       %1133 =   OpFAdd %float %1129 %1132\n       %1135 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1126 %uint_3\n                 OpStore %1135 %1133\n       %1136 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1125\n       %1137 =   OpLoad %uint %1136\n       %1138 =   OpIAdd %uint %1137 %uint_1\n       %1139 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1125\n                 OpStore %1139 %1138\n       %1142 =   OpIMul %uint %38 %uint_64\n       %1143 =   OpIAdd %uint %1142 %uint_47\n       %1144 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1143\n       %1145 =   OpLoad %uint %1144\n       %1146 =   OpBitwiseAnd %uint %1145 %uint_3\n       %1148 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1146 %uint_3\n       %1149 =   OpLoad %float %1148\n       %1151 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1145 %uint_3\n       %1152 =   OpLoad %float %1151\n       %1153 =   OpFAdd %float %1149 %1152\n       %1155 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1146 %uint_3\n                 OpStore %1155 %1153\n       %1156 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1145\n       %1157 =   OpLoad %uint %1156\n       %1158 =   OpIAdd %uint %1157 %uint_1\n       %1159 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1145\n                 OpStore %1159 %1158\n       %1162 =   OpIMul %uint %38 %uint_64\n       %1163 =   OpIAdd %uint %1162 %uint_48\n       %1164 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1163\n       %1165 =   OpLoad %uint %1164\n       %1166 =   OpBitwiseAnd %uint %1165 %uint_3\n       %1168 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1166 %uint_0\n       %1169 =   OpLoad %float %1168\n       %1171 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1165 %uint_0\n       %1172 =   OpLoad %float %1171\n       %1173 =   OpFAdd %float %1169 %1172\n       %1175 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1166 %uint_0\n                 OpStore %1175 %1173\n       %1176 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1165\n       %1177 =   OpLoad %uint %1176\n       %1178 =   OpIAdd %uint %1177 %uint_1\n       %1179 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1165\n                 OpStore %1179 %1178\n       %1182 =   OpIMul %uint %38 %uint_64\n       %1183 =   OpIAdd %uint %1182 %uint_49\n       %1184 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1183\n       %1185 =   OpLoad %uint %1184\n       %1186 =   OpBitwiseAnd %uint %1185 %uint_3\n       %1188 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1186 %uint_0\n       %1189 =   OpLoad %float %1188\n       %1191 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1185 %uint_1\n       %1192 =   OpLoad %float %1191\n       %1193 =   OpFAdd %float %1189 %1192\n       %1195 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1186 %uint_0\n                 OpStore %1195 %1193\n       %1196 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1185\n       %1197 =   OpLoad %uint %1196\n       %1198 =   OpIAdd %uint %1197 %uint_1\n       %1199 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1185\n                 OpStore %1199 %1198\n       %1202 =   OpIMul %uint %38 %uint_64\n       %1203 =   OpIAdd %uint %1202 %uint_50\n       %1204 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1203\n       %1205 =   OpLoad %uint %1204\n       %1206 =   OpBitwiseAnd %uint %1205 %uint_3\n       %1208 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1206 %uint_0\n       %1209 =   OpLoad %float %1208\n       %1211 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1205 %uint_2\n       %1212 =   OpLoad %float %1211\n       %1213 =   OpFAdd %float %1209 %1212\n       %1215 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1206 %uint_0\n                 OpStore %1215 %1213\n       %1216 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1205\n       %1217 =   OpLoad %uint %1216\n       %1218 =   OpIAdd %uint %1217 %uint_1\n       %1219 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1205\n                 OpStore %1219 %1218\n       %1222 =   OpIMul %uint %38 %uint_64\n       %1223 =   OpIAdd %uint %1222 %uint_51\n       %1224 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1223\n       %1225 =   OpLoad %uint %1224\n       %1226 =   OpBitwiseAnd %uint %1225 %uint_3\n       %1228 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1226 %uint_0\n       %1229 =   OpLoad %float %1228\n       %1231 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1225 %uint_3\n       %1232 =   OpLoad %float %1231\n       %1233 =   OpFAdd %float %1229 %1232\n       %1235 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1226 %uint_0\n                 OpStore %1235 %1233\n       %1236 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1225\n       %1237 =   OpLoad %uint %1236\n       %1238 =   OpIAdd %uint %1237 %uint_1\n       %1239 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1225\n                 OpStore %1239 %1238\n       %1242 =   OpIMul %uint %38 %uint_64\n       %1243 =   OpIAdd %uint %1242 %uint_52\n       %1244 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1243\n       %1245 =   OpLoad %uint %1244\n       %1246 =   OpBitwiseAnd %uint %1245 %uint_3\n       %1248 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1246 %uint_1\n       %1249 =   OpLoad %float %1248\n       %1251 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1245 %uint_0\n       %1252 =   OpLoad %float %1251\n       %1253 =   OpFAdd %float %1249 %1252\n       %1255 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1246 %uint_1\n                 OpStore %1255 %1253\n       %1256 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1245\n       %1257 =   OpLoad %uint %1256\n       %1258 =   OpIAdd %uint %1257 %uint_1\n       %1259 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1245\n                 OpStore %1259 %1258\n       %1262 =   OpIMul %uint %38 %uint_64\n       %1263 =   OpIAdd %uint %1262 %uint_53\n       %1264 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1263\n       %1265 =   OpLoad %uint %1264\n       %1266 =   OpBitwiseAnd %uint %1265 %uint_3\n       %1268 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1266 %uint_1\n       %1269 =   OpLoad %float %1268\n       %1271 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1265 %uint_1\n       %1272 =   OpLoad %float %1271\n       %1273 =   OpFAdd %float %1269 %1272\n       %1275 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1266 %uint_1\n                 OpStore %1275 %1273\n       %1276 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1265\n       %1277 =   OpLoad %uint %1276\n       %1278 =   OpIAdd %uint %1277 %uint_1\n       %1279 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1265\n                 OpStore %1279 %1278\n       %1282 =   OpIMul %uint %38 %uint_64\n       %1283 =   OpIAdd %uint %1282 %uint_54\n       %1284 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1283\n       %1285 =   OpLoad %uint %1284\n       %1286 =   OpBitwiseAnd %uint %1285 %uint_3\n       %1288 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1286 %uint_1\n       %1289 =   OpLoad %float %1288\n       %1291 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1285 %uint_2\n       %1292 =   OpLoad %float %1291\n       %1293 =   OpFAdd %float %1289 %1292\n       %1295 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1286 %uint_1\n                 OpStore %1295 %1293\n       %1296 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1285\n       %1297 =   OpLoad %uint %1296\n       %1298 =   OpIAdd %uint %1297 %uint_1\n       %1299 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1285\n                 OpStore %1299 %1298\n       %1302 =   OpIMul %uint %38 %uint_64\n       %1303 =   OpIAdd %uint %1302 %uint_55\n       %1304 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1303\n       %1305 =   OpLoad %uint %1304\n       %1306 =   OpBitwiseAnd %uint %1305 %uint_3\n       %1308 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1306 %uint_1\n       %1309 =   OpLoad %float %1308\n       %1311 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1305 %uint_3\n       %1312 =   OpLoad %float %1311\n       %1313 =   OpFAdd %float %1309 %1312\n       %1315 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1306 %uint_1\n                 OpStore %1315 %1313\n       %1316 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1305\n       %1317 =   OpLoad %uint %1316\n       %1318 =   OpIAdd %uint %1317 %uint_1\n       %1319 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1305\n                 OpStore %1319 %1318\n       %1322 =   OpIMul %uint %38 %uint_64\n       %1323 =   OpIAdd %uint %1322 %uint_56\n       %1324 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1323\n       %1325 =   OpLoad %uint %1324\n       %1326 =   OpBitwiseAnd %uint %1325 %uint_3\n       %1328 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1326 %uint_2\n       %1329 =   OpLoad %float %1328\n       %1331 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1325 %uint_0\n       %1332 =   OpLoad %float %1331\n       %1333 =   OpFAdd %float %1329 %1332\n       %1335 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1326 %uint_2\n                 OpStore %1335 %1333\n       %1336 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1325\n       %1337 =   OpLoad %uint %1336\n       %1338 =   OpIAdd %uint %1337 %uint_1\n       %1339 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1325\n                 OpStore %1339 %1338\n       %1342 =   OpIMul %uint %38 %uint_64\n       %1343 =   OpIAdd %uint %1342 %uint_57\n       %1344 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1343\n       %1345 =   OpLoad %uint %1344\n       %1346 =   OpBitwiseAnd %uint %1345 %uint_3\n       %1348 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1346 %uint_2\n       %1349 =   OpLoad %float %1348\n       %1351 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1345 %uint_1\n       %1352 =   OpLoad %float %1351\n       %1353 =   OpFAdd %float %1349 %1352\n       %1355 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1346 %uint_2\n                 OpStore %1355 %1353\n       %1356 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1345\n       %1357 =   OpLoad %uint %1356\n       %1358 =   OpIAdd %uint %1357 %uint_1\n       %1359 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1345\n                 OpStore %1359 %1358\n       %1362 =   OpIMul %uint %38 %uint_64\n       %1363 =   OpIAdd %uint %1362 %uint_58\n       %1364 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1363\n       %1365 =   OpLoad %uint %1364\n       %1366 =   OpBitwiseAnd %uint %1365 %uint_3\n       %1368 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1366 %uint_2\n       %1369 =   OpLoad %float %1368\n       %1371 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1365 %uint_2\n       %1372 =   OpLoad %float %1371\n       %1373 =   OpFAdd %float %1369 %1372\n       %1375 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1366 %uint_2\n                 OpStore %1375 %1373\n       %1376 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1365\n       %1377 =   OpLoad %uint %1376\n       %1378 =   OpIAdd %uint %1377 %uint_1\n       %1379 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1365\n                 OpStore %1379 %1378\n       %1382 =   OpIMul %uint %38 %uint_64\n       %1383 =   OpIAdd %uint %1382 %uint_59\n       %1384 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1383\n       %1385 =   OpLoad %uint %1384\n       %1386 =   OpBitwiseAnd %uint %1385 %uint_3\n       %1388 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1386 %uint_2\n       %1389 =   OpLoad %float %1388\n       %1391 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1385 %uint_3\n       %1392 =   OpLoad %float %1391\n       %1393 =   OpFAdd %float %1389 %1392\n       %1395 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1386 %uint_2\n                 OpStore %1395 %1393\n       %1396 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1385\n       %1397 =   OpLoad %uint %1396\n       %1398 =   OpIAdd %uint %1397 %uint_1\n       %1399 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1385\n                 OpStore %1399 %1398\n       %1402 =   OpIMul %uint %38 %uint_64\n       %1403 =   OpIAdd %uint %1402 %uint_60\n       %1404 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1403\n       %1405 =   OpLoad %uint %1404\n       %1406 =   OpBitwiseAnd %uint %1405 %uint_3\n       %1408 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1406 %uint_3\n       %1409 =   OpLoad %float %1408\n       %1411 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1405 %uint_0\n       %1412 =   OpLoad %float %1411\n       %1413 =   OpFAdd %float %1409 %1412\n       %1415 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1406 %uint_3\n                 OpStore %1415 %1413\n       %1416 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1405\n       %1417 =   OpLoad %uint %1416\n       %1418 =   OpIAdd %uint %1417 %uint_1\n       %1419 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1405\n                 OpStore %1419 %1418\n       %1422 =   OpIMul %uint %38 %uint_64\n       %1423 =   OpIAdd %uint %1422 %uint_61\n       %1424 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1423\n       %1425 =   OpLoad %uint %1424\n       %1426 =   OpBitwiseAnd %uint %1425 %uint_3\n       %1428 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1426 %uint_3\n       %1429 =   OpLoad %float %1428\n       %1431 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1425 %uint_1\n       %1432 =   OpLoad %float %1431\n       %1433 =   OpFAdd %float %1429 %1432\n       %1435 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1426 %uint_3\n                 OpStore %1435 %1433\n       %1436 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1425\n       %1437 =   OpLoad %uint %1436\n       %1438 =   OpIAdd %uint %1437 %uint_1\n       %1439 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1425\n                 OpStore %1439 %1438\n       %1442 =   OpIMul %uint %38 %uint_64\n       %1443 =   OpIAdd %uint %1442 %uint_62\n       %1444 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1443\n       %1445 =   OpLoad %uint %1444\n       %1446 =   OpBitwiseAnd %uint %1445 %uint_3\n       %1448 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1446 %uint_3\n       %1449 =   OpLoad %float %1448\n       %1451 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1445 %uint_2\n       %1452 =   OpLoad %float %1451\n       %1453 =   OpFAdd %float %1449 %1452\n       %1455 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1446 %uint_3\n                 OpStore %1455 %1453\n       %1456 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1445\n       %1457 =   OpLoad %uint %1456\n       %1458 =   OpIAdd %uint %1457 %uint_1\n       %1459 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1445\n                 OpStore %1459 %1458\n       %1462 =   OpIMul %uint %38 %uint_64\n       %1463 =   OpIAdd %uint %1462 %uint_63\n       %1464 =   OpAccessChain %_ptr_StorageBuffer_uint %14 %uint_0 %1463\n       %1465 =   OpLoad %uint %1464\n       %1466 =   OpBitwiseAnd %uint %1465 %uint_3\n       %1468 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1466 %uint_3\n       %1469 =   OpLoad %float %1468\n       %1471 =   OpInBoundsAccessChain %_ptr_Private_float %27 %1465 %uint_3\n       %1472 =   OpLoad %float %1471\n       %1473 =   OpFAdd %float %1469 %1472\n       %1475 =   OpInBoundsAccessChain %_ptr_Private_float %31 %1466 %uint_3\n                 OpStore %1475 %1473\n       %1476 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1465\n       %1477 =   OpLoad %uint %1476\n       %1478 =   OpIAdd %uint %1477 %uint_1\n       %1479 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %1465\n                 OpStore %1479 %1478\n       %1480 =   OpInBoundsAccessChain %_ptr_Private_uint %34 %uint_15\n       %1481 =   OpLoad %uint %1480\n       %1482 =   OpIAdd %uint %38 %1481\n       %1483 =   OpInBoundsAccessChain %_ptr_Private_v4float %31 %uint_3\n       %1484 =   OpLoad %v4float %1483\n       %1486 =   OpCompositeExtract %float %1484 0\n       %1487 =   OpCompositeExtract %float %1484 1\n       %1488 =   OpCompositeExtract %float %1484 2\n       %1489 =   OpCompositeExtract %float %1484 3\n       %1490 =   OpBitcast %uint %1486\n       %1491 =   OpBitcast %uint %1487\n       %1492 =   OpBitcast %uint %1488\n       %1493 =   OpBitcast %uint %1489\n       %1494 =   OpCompositeConstruct %v4uint %1490 %1491 %1492 %1493\n       %1495 =   OpAccessChain %_ptr_StorageBuffer_v4uint %18 %uint_0 %1482\n                 OpStore %1495 %1494 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_misc_scratch.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uvec4 _m0[];\n} _10;\n\nlayout(set = 0, binding = 1, std430) restrict readonly buffer _12_14\n{\n    uint _m0[];\n} _14;\n\nlayout(set = 0, binding = 0, std430) writeonly buffer _16_18\n{\n    uvec4 _m0[];\n} _18;\n\nvec4 _27[16];\nvec4 _31[4];\nuint _34[16];\n\nvoid main()\n{\n    _31[0u] = vec4(1.0, 2.0, 3.0, 4.0);\n    _34[0u] = 4294967295u;\n    _31[1u] = vec4(1.0, 2.0, 3.0, 4.0);\n    _34[1u] = 4294967295u;\n    _31[2u] = vec4(1.0, 2.0, 3.0, 4.0);\n    _34[2u] = 4294967295u;\n    _31[3u] = vec4(1.0, 2.0, 3.0, 4.0);\n    _34[3u] = 4294967295u;\n    _27[0u] = vec4(uintBitsToFloat(_10._m0[0u]));\n    _27[1u] = vec4(uintBitsToFloat(_10._m0[1u]));\n    _27[2u] = vec4(uintBitsToFloat(_10._m0[2u]));\n    _27[3u] = vec4(uintBitsToFloat(_10._m0[3u]));\n    _27[4u] = vec4(uintBitsToFloat(_10._m0[4u]));\n    _27[5u] = vec4(uintBitsToFloat(_10._m0[5u]));\n    _27[6u] = vec4(uintBitsToFloat(_10._m0[6u]));\n    _27[7u] = vec4(uintBitsToFloat(_10._m0[7u]));\n    _27[8u] = vec4(uintBitsToFloat(_10._m0[8u]));\n    _27[9u] = vec4(uintBitsToFloat(_10._m0[9u]));\n    _27[10u] = vec4(uintBitsToFloat(_10._m0[10u]));\n    _27[11u] = vec4(uintBitsToFloat(_10._m0[11u]));\n    _27[12u] = vec4(uintBitsToFloat(_10._m0[12u]));\n    _27[13u] = vec4(uintBitsToFloat(_10._m0[13u]));\n    _27[14u] = vec4(uintBitsToFloat(_10._m0[14u]));\n    _27[15u] = vec4(uintBitsToFloat(_10._m0[15u]));\n    uint _216 = gl_GlobalInvocationID.x * 64u;\n    uint _221 = _14._m0[_216] & 3u;\n    _31[_221].x += _27[_14._m0[_216]].x;\n    _34[_14._m0[_216]]++;\n    uint _238 = (gl_GlobalInvocationID.x * 64u) + 1u;\n    uint _241 = _14._m0[_238] & 3u;\n    _31[_241].x += _27[_14._m0[_238]].y;\n    _34[_14._m0[_238]]++;\n    uint _257 = (gl_GlobalInvocationID.x * 64u) + 2u;\n    uint _260 = _14._m0[_257] & 3u;\n    _31[_260].x += _27[_14._m0[_257]].z;\n    _34[_14._m0[_257]]++;\n    uint _276 = (gl_GlobalInvocationID.x * 64u) + 3u;\n    uint _279 = _14._m0[_276] & 3u;\n    _31[_279].x += _27[_14._m0[_276]].w;\n    _34[_14._m0[_276]]++;\n    uint _295 = (gl_GlobalInvocationID.x * 64u) + 4u;\n    uint _298 = _14._m0[_295] & 3u;\n    _31[_298].y += _27[_14._m0[_295]].x;\n    _34[_14._m0[_295]]++;\n    uint _314 = (gl_GlobalInvocationID.x * 64u) + 5u;\n    uint _317 = _14._m0[_314] & 3u;\n    _31[_317].y += _27[_14._m0[_314]].y;\n    _34[_14._m0[_314]]++;\n    uint _333 = (gl_GlobalInvocationID.x * 64u) + 6u;\n    uint _336 = _14._m0[_333] & 3u;\n    _31[_336].y += _27[_14._m0[_333]].z;\n    _34[_14._m0[_333]]++;\n    uint _352 = (gl_GlobalInvocationID.x * 64u) + 7u;\n    uint _355 = _14._m0[_352] & 3u;\n    _31[_355].y += _27[_14._m0[_352]].w;\n    _34[_14._m0[_352]]++;\n    uint _371 = (gl_GlobalInvocationID.x * 64u) + 8u;\n    uint _374 = _14._m0[_371] & 3u;\n    _31[_374].z += _27[_14._m0[_371]].x;\n    _34[_14._m0[_371]]++;\n    uint _390 = (gl_GlobalInvocationID.x * 64u) + 9u;\n    uint _393 = _14._m0[_390] & 3u;\n    _31[_393].z += _27[_14._m0[_390]].y;\n    _34[_14._m0[_390]]++;\n    uint _409 = (gl_GlobalInvocationID.x * 64u) + 10u;\n    uint _412 = _14._m0[_409] & 3u;\n    _31[_412].z += _27[_14._m0[_409]].z;\n    _34[_14._m0[_409]]++;\n    uint _428 = (gl_GlobalInvocationID.x * 64u) + 11u;\n    uint _431 = _14._m0[_428] & 3u;\n    _31[_431].z += _27[_14._m0[_428]].w;\n    _34[_14._m0[_428]]++;\n    uint _447 = (gl_GlobalInvocationID.x * 64u) + 12u;\n    uint _450 = _14._m0[_447] & 3u;\n    _31[_450].w += _27[_14._m0[_447]].x;\n    _34[_14._m0[_447]]++;\n    uint _466 = (gl_GlobalInvocationID.x * 64u) + 13u;\n    uint _469 = _14._m0[_466] & 3u;\n    _31[_469].w += _27[_14._m0[_466]].y;\n    _34[_14._m0[_466]]++;\n    uint _485 = (gl_GlobalInvocationID.x * 64u) + 14u;\n    uint _488 = _14._m0[_485] & 3u;\n    _31[_488].w += _27[_14._m0[_485]].z;\n    _34[_14._m0[_485]]++;\n    uint _504 = (gl_GlobalInvocationID.x * 64u) + 15u;\n    uint _507 = _14._m0[_504] & 3u;\n    _31[_507].w += _27[_14._m0[_504]].w;\n    _34[_14._m0[_504]]++;\n    uint _523 = (gl_GlobalInvocationID.x * 64u) + 16u;\n    uint _526 = _14._m0[_523] & 3u;\n    _31[_526].x += _27[_14._m0[_523]].x;\n    _34[_14._m0[_523]]++;\n    uint _543 = (gl_GlobalInvocationID.x * 64u) + 17u;\n    uint _546 = _14._m0[_543] & 3u;\n    _31[_546].x += _27[_14._m0[_543]].y;\n    _34[_14._m0[_543]]++;\n    uint _563 = (gl_GlobalInvocationID.x * 64u) + 18u;\n    uint _566 = _14._m0[_563] & 3u;\n    _31[_566].x += _27[_14._m0[_563]].z;\n    _34[_14._m0[_563]]++;\n    uint _583 = (gl_GlobalInvocationID.x * 64u) + 19u;\n    uint _586 = _14._m0[_583] & 3u;\n    _31[_586].x += _27[_14._m0[_583]].w;\n    _34[_14._m0[_583]]++;\n    uint _603 = (gl_GlobalInvocationID.x * 64u) + 20u;\n    uint _606 = _14._m0[_603] & 3u;\n    _31[_606].y += _27[_14._m0[_603]].x;\n    _34[_14._m0[_603]]++;\n    uint _623 = (gl_GlobalInvocationID.x * 64u) + 21u;\n    uint _626 = _14._m0[_623] & 3u;\n    _31[_626].y += _27[_14._m0[_623]].y;\n    _34[_14._m0[_623]]++;\n    uint _643 = (gl_GlobalInvocationID.x * 64u) + 22u;\n    uint _646 = _14._m0[_643] & 3u;\n    _31[_646].y += _27[_14._m0[_643]].z;\n    _34[_14._m0[_643]]++;\n    uint _663 = (gl_GlobalInvocationID.x * 64u) + 23u;\n    uint _666 = _14._m0[_663] & 3u;\n    _31[_666].y += _27[_14._m0[_663]].w;\n    _34[_14._m0[_663]]++;\n    uint _683 = (gl_GlobalInvocationID.x * 64u) + 24u;\n    uint _686 = _14._m0[_683] & 3u;\n    _31[_686].z += _27[_14._m0[_683]].x;\n    _34[_14._m0[_683]]++;\n    uint _703 = (gl_GlobalInvocationID.x * 64u) + 25u;\n    uint _706 = _14._m0[_703] & 3u;\n    _31[_706].z += _27[_14._m0[_703]].y;\n    _34[_14._m0[_703]]++;\n    uint _723 = (gl_GlobalInvocationID.x * 64u) + 26u;\n    uint _726 = _14._m0[_723] & 3u;\n    _31[_726].z += _27[_14._m0[_723]].z;\n    _34[_14._m0[_723]]++;\n    uint _743 = (gl_GlobalInvocationID.x * 64u) + 27u;\n    uint _746 = _14._m0[_743] & 3u;\n    _31[_746].z += _27[_14._m0[_743]].w;\n    _34[_14._m0[_743]]++;\n    uint _763 = (gl_GlobalInvocationID.x * 64u) + 28u;\n    uint _766 = _14._m0[_763] & 3u;\n    _31[_766].w += _27[_14._m0[_763]].x;\n    _34[_14._m0[_763]]++;\n    uint _783 = (gl_GlobalInvocationID.x * 64u) + 29u;\n    uint _786 = _14._m0[_783] & 3u;\n    _31[_786].w += _27[_14._m0[_783]].y;\n    _34[_14._m0[_783]]++;\n    uint _803 = (gl_GlobalInvocationID.x * 64u) + 30u;\n    uint _806 = _14._m0[_803] & 3u;\n    _31[_806].w += _27[_14._m0[_803]].z;\n    _34[_14._m0[_803]]++;\n    uint _823 = (gl_GlobalInvocationID.x * 64u) + 31u;\n    uint _826 = _14._m0[_823] & 3u;\n    _31[_826].w += _27[_14._m0[_823]].w;\n    _34[_14._m0[_823]]++;\n    uint _843 = (gl_GlobalInvocationID.x * 64u) + 32u;\n    uint _846 = _14._m0[_843] & 3u;\n    _31[_846].x += _27[_14._m0[_843]].x;\n    _34[_14._m0[_843]]++;\n    uint _863 = (gl_GlobalInvocationID.x * 64u) + 33u;\n    uint _866 = _14._m0[_863] & 3u;\n    _31[_866].x += _27[_14._m0[_863]].y;\n    _34[_14._m0[_863]]++;\n    uint _883 = (gl_GlobalInvocationID.x * 64u) + 34u;\n    uint _886 = _14._m0[_883] & 3u;\n    _31[_886].x += _27[_14._m0[_883]].z;\n    _34[_14._m0[_883]]++;\n    uint _903 = (gl_GlobalInvocationID.x * 64u) + 35u;\n    uint _906 = _14._m0[_903] & 3u;\n    _31[_906].x += _27[_14._m0[_903]].w;\n    _34[_14._m0[_903]]++;\n    uint _923 = (gl_GlobalInvocationID.x * 64u) + 36u;\n    uint _926 = _14._m0[_923] & 3u;\n    _31[_926].y += _27[_14._m0[_923]].x;\n    _34[_14._m0[_923]]++;\n    uint _943 = (gl_GlobalInvocationID.x * 64u) + 37u;\n    uint _946 = _14._m0[_943] & 3u;\n    _31[_946].y += _27[_14._m0[_943]].y;\n    _34[_14._m0[_943]]++;\n    uint _963 = (gl_GlobalInvocationID.x * 64u) + 38u;\n    uint _966 = _14._m0[_963] & 3u;\n    _31[_966].y += _27[_14._m0[_963]].z;\n    _34[_14._m0[_963]]++;\n    uint _983 = (gl_GlobalInvocationID.x * 64u) + 39u;\n    uint _986 = _14._m0[_983] & 3u;\n    _31[_986].y += _27[_14._m0[_983]].w;\n    _34[_14._m0[_983]]++;\n    uint _1003 = (gl_GlobalInvocationID.x * 64u) + 40u;\n    uint _1006 = _14._m0[_1003] & 3u;\n    _31[_1006].z += _27[_14._m0[_1003]].x;\n    _34[_14._m0[_1003]]++;\n    uint _1023 = (gl_GlobalInvocationID.x * 64u) + 41u;\n    uint _1026 = _14._m0[_1023] & 3u;\n    _31[_1026].z += _27[_14._m0[_1023]].y;\n    _34[_14._m0[_1023]]++;\n    uint _1043 = (gl_GlobalInvocationID.x * 64u) + 42u;\n    uint _1046 = _14._m0[_1043] & 3u;\n    _31[_1046].z += _27[_14._m0[_1043]].z;\n    _34[_14._m0[_1043]]++;\n    uint _1063 = (gl_GlobalInvocationID.x * 64u) + 43u;\n    uint _1066 = _14._m0[_1063] & 3u;\n    _31[_1066].z += _27[_14._m0[_1063]].w;\n    _34[_14._m0[_1063]]++;\n    uint _1083 = (gl_GlobalInvocationID.x * 64u) + 44u;\n    uint _1086 = _14._m0[_1083] & 3u;\n    _31[_1086].w += _27[_14._m0[_1083]].x;\n    _34[_14._m0[_1083]]++;\n    uint _1103 = (gl_GlobalInvocationID.x * 64u) + 45u;\n    uint _1106 = _14._m0[_1103] & 3u;\n    _31[_1106].w += _27[_14._m0[_1103]].y;\n    _34[_14._m0[_1103]]++;\n    uint _1123 = (gl_GlobalInvocationID.x * 64u) + 46u;\n    uint _1126 = _14._m0[_1123] & 3u;\n    _31[_1126].w += _27[_14._m0[_1123]].z;\n    _34[_14._m0[_1123]]++;\n    uint _1143 = (gl_GlobalInvocationID.x * 64u) + 47u;\n    uint _1146 = _14._m0[_1143] & 3u;\n    _31[_1146].w += _27[_14._m0[_1143]].w;\n    _34[_14._m0[_1143]]++;\n    uint _1163 = (gl_GlobalInvocationID.x * 64u) + 48u;\n    uint _1166 = _14._m0[_1163] & 3u;\n    _31[_1166].x += _27[_14._m0[_1163]].x;\n    _34[_14._m0[_1163]]++;\n    uint _1183 = (gl_GlobalInvocationID.x * 64u) + 49u;\n    uint _1186 = _14._m0[_1183] & 3u;\n    _31[_1186].x += _27[_14._m0[_1183]].y;\n    _34[_14._m0[_1183]]++;\n    uint _1203 = (gl_GlobalInvocationID.x * 64u) + 50u;\n    uint _1206 = _14._m0[_1203] & 3u;\n    _31[_1206].x += _27[_14._m0[_1203]].z;\n    _34[_14._m0[_1203]]++;\n    uint _1223 = (gl_GlobalInvocationID.x * 64u) + 51u;\n    uint _1226 = _14._m0[_1223] & 3u;\n    _31[_1226].x += _27[_14._m0[_1223]].w;\n    _34[_14._m0[_1223]]++;\n    uint _1243 = (gl_GlobalInvocationID.x * 64u) + 52u;\n    uint _1246 = _14._m0[_1243] & 3u;\n    _31[_1246].y += _27[_14._m0[_1243]].x;\n    _34[_14._m0[_1243]]++;\n    uint _1263 = (gl_GlobalInvocationID.x * 64u) + 53u;\n    uint _1266 = _14._m0[_1263] & 3u;\n    _31[_1266].y += _27[_14._m0[_1263]].y;\n    _34[_14._m0[_1263]]++;\n    uint _1283 = (gl_GlobalInvocationID.x * 64u) + 54u;\n    uint _1286 = _14._m0[_1283] & 3u;\n    _31[_1286].y += _27[_14._m0[_1283]].z;\n    _34[_14._m0[_1283]]++;\n    uint _1303 = (gl_GlobalInvocationID.x * 64u) + 55u;\n    uint _1306 = _14._m0[_1303] & 3u;\n    _31[_1306].y += _27[_14._m0[_1303]].w;\n    _34[_14._m0[_1303]]++;\n    uint _1323 = (gl_GlobalInvocationID.x * 64u) + 56u;\n    uint _1326 = _14._m0[_1323] & 3u;\n    _31[_1326].z += _27[_14._m0[_1323]].x;\n    _34[_14._m0[_1323]]++;\n    uint _1343 = (gl_GlobalInvocationID.x * 64u) + 57u;\n    uint _1346 = _14._m0[_1343] & 3u;\n    _31[_1346].z += _27[_14._m0[_1343]].y;\n    _34[_14._m0[_1343]]++;\n    uint _1363 = (gl_GlobalInvocationID.x * 64u) + 58u;\n    uint _1366 = _14._m0[_1363] & 3u;\n    _31[_1366].z += _27[_14._m0[_1363]].z;\n    _34[_14._m0[_1363]]++;\n    uint _1383 = (gl_GlobalInvocationID.x * 64u) + 59u;\n    uint _1386 = _14._m0[_1383] & 3u;\n    _31[_1386].z += _27[_14._m0[_1383]].w;\n    _34[_14._m0[_1383]]++;\n    uint _1403 = (gl_GlobalInvocationID.x * 64u) + 60u;\n    uint _1406 = _14._m0[_1403] & 3u;\n    _31[_1406].w += _27[_14._m0[_1403]].x;\n    _34[_14._m0[_1403]]++;\n    uint _1423 = (gl_GlobalInvocationID.x * 64u) + 61u;\n    uint _1426 = _14._m0[_1423] & 3u;\n    _31[_1426].w += _27[_14._m0[_1423]].y;\n    _34[_14._m0[_1423]]++;\n    uint _1443 = (gl_GlobalInvocationID.x * 64u) + 62u;\n    uint _1446 = _14._m0[_1443] & 3u;\n    _31[_1446].w += _27[_14._m0[_1443]].z;\n    _34[_14._m0[_1443]]++;\n    uint _1463 = (gl_GlobalInvocationID.x * 64u) + 63u;\n    uint _1466 = _14._m0[_1463] & 3u;\n    _31[_1466].w += _27[_14._m0[_1463]].w;\n    _34[_14._m0[_1463]]++;\n    _18._m0[gl_GlobalInvocationID.x + _34[15u]] = uvec4(floatBitsToUint(_31[3u].x), floatBitsToUint(_31[3u].y), floatBitsToUint(_31[3u].z), floatBitsToUint(_31[3u].w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_rov.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpCapability FragmentShaderPixelInterlockEXT\n               OpExtension \"SPV_EXT_fragment_shader_interlock\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %_\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main PixelInterlockOrderedEXT\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %_ BuiltIn FragCoord\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n          %_ = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_float = OpTypePointer Input %float\n       %uint = OpTypeInt 32 0\n     %uint_1 = OpConstant %uint 1\n     %uint_0 = OpConstant %uint 0\n     %v2uint = OpTypeVector %uint 2\n     %uint_5 = OpConstant %uint 5\n    %float_2 = OpConstant %float 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %42\n\n         %42 = OpLabel\n         %12 =   OpLoad %6 %8\n         %14 =   OpAccessChain %_ptr_Input_float %_ %uint_1\n         %17 =   OpLoad %float %14\n         %18 =   OpConvertFToS %uint %17\n         %19 =   OpAccessChain %_ptr_Input_float %_ %uint_0\n         %21 =   OpLoad %float %19\n         %22 =   OpConvertFToS %uint %21\n         %26 =   OpCompositeConstruct %v2uint %22 %18\n                 OpBeginInvocationInterlockEXT\n         %25 =   OpImageRead %v4float %12 %26 MakeTexelVisible|NonPrivateTexel %uint_5\n         %28 =   OpCompositeExtract %float %25 0\n         %29 =   OpCompositeExtract %float %25 1\n         %30 =   OpCompositeExtract %float %25 2\n         %31 =   OpCompositeExtract %float %25 3\n         %32 =   OpCompositeConstruct %v4float %28 %29 %30 %31\n         %33 =   OpFMul %float %28 %float_2\n         %35 =   OpCompositeInsert %v4float %33 %32 0\n         %36 =   OpCompositeExtract %float %35 0\n         %37 =   OpCompositeExtract %float %35 1\n         %38 =   OpCompositeExtract %float %35 2\n         %39 =   OpCompositeExtract %float %35 3\n         %40 =   OpCompositeConstruct %v2uint %22 %18\n         %41 =   OpCompositeConstruct %v4float %36 %37 %38 %39\n                 OpImageWrite %12 %40 %41 MakeTexelAvailable|NonPrivateTexel %uint_5\n                 OpEndInvocationInterlockEXT\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_rov.glsl",
    "content": "GLSL:\n#version 460\n#ifdef GL_ARB_fragment_shader_interlock\n#extension GL_ARB_fragment_shader_interlock : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginInvocationInterlockARB()\n#define SPIRV_Cross_endInvocationInterlock() endInvocationInterlockARB()\n#elif defined(GL_INTEL_fragment_shader_ordering)\n#extension GL_INTEL_fragment_shader_ordering : enable\n#define SPIRV_Cross_beginInvocationInterlock() beginFragmentShaderOrderingINTEL()\n#define SPIRV_Cross_endInvocationInterlock()\n#endif\n#if defined(GL_ARB_fragment_shader_interlock)\nlayout(pixel_interlock_ordered) in;\n#elif !defined(GL_INTEL_fragment_shader_ordering)\n#error Fragment Shader Interlock/Ordering extension missing!\n#endif\n\nlayout(set = 0, binding = 0, r32f) uniform image2D _8;\n\nvoid main()\n{\n    uint _18 = uint(int(gl_FragCoord.y));\n    uint _22 = uint(int(gl_FragCoord.x));\n    SPIRV_Cross_beginInvocationInterlock();\n    vec4 _25 = imageLoad(_8, ivec2(uvec2(_22, _18)));\n    float _28 = _25.x;\n    vec4 _32 = vec4(_28, _25.yzw);\n    _32.x = _28 * 2.0;\n    imageStore(_8, ivec2(uvec2(_22, _18)), vec4(_32));\n    SPIRV_Cross_endInvocationInterlock();\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_buffer_load_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 50\n; Schema: 0\n               OpCapability Shader\n               OpCapability SparseResidency\n               OpCapability SampledBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n %uint_12345 = OpConstant %uint 12345\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %v4float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n    %float_0 = OpConstant %float 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %48\n\n         %48 = OpLabel\n         %14 =   OpLoad %6 %8\n         %18 =   OpImageSparseFetch %SparseTexel %14 %uint_12345\n         %19 =   OpCompositeExtract %uint %18 0\n         %20 =   OpCompositeExtract %v4float %18 1\n         %21 =   OpCompositeExtract %float %20 0\n         %22 =   OpCompositeExtract %float %20 1\n         %23 =   OpCompositeExtract %float %20 2\n         %24 =   OpCompositeExtract %float %20 3\n         %26 =   OpCompositeConstruct %_ %21 %22 %23 %24 %19\n         %27 =   OpCompositeExtract %uint %26 4\n         %28 =   OpCompositeExtract %float %26 0\n         %29 =   OpCompositeExtract %float %26 1\n         %30 =   OpCompositeExtract %float %26 2\n         %31 =   OpCompositeExtract %float %26 3\n         %32 =   OpCompositeConstruct %v4float %28 %29 %30 %31\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %35 %28\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %37 %29\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %39 %30\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %41 %31\n         %44 =   OpImageSparseTexelsResident %bool %27\n         %45 =   OpSelect %float %44 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %45\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_buffer_load_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _25\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _33\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _8;\n\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    uint _50;\n    vec4 _51;\n    _50 = sparseTexelFetchARB(_8, int(12345u), _51);\n    SparseTexel _18 = SparseTexel(_50, _51);\n    vec4 _20 = _18._m1;\n    _25 _26 = _25(_20.x, _20.y, _20.z, _20.w, _18._m0);\n    float _28 = _26._m0;\n    float _29 = _26._m1;\n    float _30 = _26._m2;\n    float _31 = _26._m3;\n    SV_TARGET.x = _28;\n    SV_TARGET.y = _29;\n    SV_TARGET.z = _30;\n    SV_TARGET.w = _31;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_26._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 53\n; Schema: 0\n               OpCapability Shader\n               OpCapability Sampled1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %51\n\n         %51 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %21 =   OpLoad %uint %19\n         %26 =   OpCompositeConstruct %v2uint %21 %uint_2\n         %24 =   OpImageFetch %v4float %17 %26 Lod %uint_1\n         %27 =   OpCompositeExtract %float %24 0\n         %28 =   OpCompositeExtract %float %24 1\n         %29 =   OpCompositeExtract %float %24 2\n         %30 =   OpCompositeExtract %float %24 3\n         %33 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %33 %27\n         %34 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %34 %28\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %35 %29\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %36 %30\n         %41 =   OpCompositeConstruct %v2uint %21 %uint_2\n         %40 =   OpImageFetch %v4float %17 %41 Lod|ConstOffset %uint_1 %int_n1\n         %42 =   OpCompositeExtract %float %40 0\n         %43 =   OpCompositeExtract %float %40 1\n         %44 =   OpCompositeExtract %float %40 2\n         %45 =   OpCompositeExtract %float %40 3\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %47 %42\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %48 %43\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %49 %44\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %50 %45\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture1DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _24 = texelFetch(_8, ivec2(uvec2(TEXCOORD.x, 2u)), int(1u));\n    SV_TARGET.x = _24.x;\n    SV_TARGET.y = _24.y;\n    SV_TARGET.z = _24.z;\n    SV_TARGET.w = _24.w;\n    vec4 _40 = texelFetchOffset(_8, ivec2(uvec2(TEXCOORD.x, 2u)), int(1u), -1);\n    SV_TARGET_1.x = _40.x;\n    SV_TARGET_1.y = _40.y;\n    SV_TARGET_1.z = _40.z;\n    SV_TARGET_1.w = _40.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 25\n; Schema: 0\n               OpCapability Shader\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %v2uint = OpTypeVector %uint 2\n     %uint_0 = OpConstant %uint 0\n          %_ = OpTypeStruct %uint %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %23\n\n         %23 = OpLabel\n         %14 =   OpLoad %6 %8\n         %16 =   OpImageQuerySizeLod %v2uint %14 %uint_0\n         %18 =   OpCompositeExtract %uint %16 0\n         %19 =   OpCompositeExtract %uint %16 1\n                 OpStore %SV_TARGET %18\n                 OpStore %SV_TARGET_1 %19\n         %22 =   OpImageQueryLevels %uint %14\n                 OpStore %SV_TARGET_2 %22\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _20\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture1DArray _8;\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uvec2 _16 = uvec2(textureSize(_8, int(0u)));\n    SV_TARGET = _16.x;\n    SV_TARGET_1 = _16.y;\n    SV_TARGET_2 = uint(textureQueryLevels(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_array_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 145\n; Schema: 0\n               OpCapability Shader\n               OpCapability MinLod\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n         %38 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %143\n\n        %143 = OpLabel\n         %31 =   OpLoad %6 %8\n         %32 =   OpLoad %9 %11\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %36 =   OpLoad %float %33\n         %37 =   OpLoad %float %LAYER\n         %39 =   OpSampledImage %38 %31 %32\n         %41 =   OpImageQueryLod %v2float %39 %36\n         %42 =   OpCompositeExtract %float %41 0\n         %43 =   OpLoad %float %LOD_BIAS\n         %44 =   OpLoad %float %LOD_CLAMP\n         %47 =   OpCompositeConstruct %v2float %36 %37\n         %46 =   OpImageSampleImplicitLod %v4float %39 %47 None\n         %48 =   OpCompositeExtract %float %46 0\n         %49 =   OpCompositeExtract %float %46 1\n         %50 =   OpCompositeExtract %float %46 2\n         %51 =   OpCompositeExtract %float %46 3\n         %54 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %54 %48\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %55 %49\n         %57 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %57 %50\n         %59 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %59 %51\n         %64 =   OpCompositeConstruct %v2float %36 %37\n         %63 =   OpImageSampleImplicitLod %v4float %39 %64 ConstOffset %int_n1\n         %65 =   OpCompositeExtract %float %63 0\n         %66 =   OpCompositeExtract %float %63 1\n         %67 =   OpCompositeExtract %float %63 2\n         %68 =   OpCompositeExtract %float %63 3\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %70 %65\n         %71 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %71 %66\n         %72 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %72 %67\n         %73 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %73 %68\n         %75 =   OpCompositeConstruct %v2float %36 %37\n         %74 =   OpImageSampleExplicitLod %v4float %39 %75 Lod %42\n         %76 =   OpCompositeExtract %float %74 0\n         %77 =   OpCompositeExtract %float %74 1\n         %78 =   OpCompositeExtract %float %74 2\n         %79 =   OpCompositeExtract %float %74 3\n         %81 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %81 %76\n         %82 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %82 %77\n         %83 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %83 %78\n         %84 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %84 %79\n         %86 =   OpCompositeConstruct %v2float %36 %37\n         %85 =   OpImageSampleImplicitLod %v4float %39 %86 Bias %43\n         %87 =   OpCompositeExtract %float %85 0\n         %88 =   OpCompositeExtract %float %85 1\n         %89 =   OpCompositeExtract %float %85 2\n         %90 =   OpCompositeExtract %float %85 3\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %95 %90\n         %97 =   OpCompositeConstruct %v2float %36 %37\n         %96 =   OpImageSampleImplicitLod %v4float %39 %97 MinLod %44\n         %98 =   OpCompositeExtract %float %96 0\n         %99 =   OpCompositeExtract %float %96 1\n        %100 =   OpCompositeExtract %float %96 2\n        %101 =   OpCompositeExtract %float %96 3\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %103 %98\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %104 %99\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %105 %100\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %106 %101\n        %108 =   OpCompositeConstruct %v2float %36 %37\n        %107 =   OpImageSampleImplicitLod %v4float %39 %108 Bias|ConstOffset|MinLod %43 %int_n1 %44\n        %109 =   OpCompositeExtract %float %107 0\n        %110 =   OpCompositeExtract %float %107 1\n        %111 =   OpCompositeExtract %float %107 2\n        %112 =   OpCompositeExtract %float %107 3\n        %114 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %114 %109\n        %115 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %115 %110\n        %116 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %116 %111\n        %117 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %117 %112\n        %118 =   OpLoad %float %TEXCOORD_2\n        %119 =   OpDPdx %float %118\n        %120 =   OpDPdy %float %118\n        %122 =   OpCompositeConstruct %v2float %36 %37\n        %121 =   OpImageSampleExplicitLod %v4float %39 %122 Grad %119 %120\n        %123 =   OpCompositeExtract %float %121 0\n        %124 =   OpCompositeExtract %float %121 1\n        %125 =   OpCompositeExtract %float %121 2\n        %126 =   OpCompositeExtract %float %121 3\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %128 %123\n        %129 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %129 %124\n        %130 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %130 %125\n        %131 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %131 %126\n        %133 =   OpCompositeConstruct %v2float %36 %37\n        %132 =   OpImageSampleExplicitLod %v4float %39 %133 Grad|ConstOffset %119 %120 %int_n1\n        %134 =   OpCompositeExtract %float %132 0\n        %135 =   OpCompositeExtract %float %132 1\n        %136 =   OpCompositeExtract %float %132 2\n        %137 =   OpCompositeExtract %float %132 3\n        %139 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %139 %134\n        %140 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %140 %135\n        %141 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %141 %136\n        %142 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %142 %137\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_array_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0) uniform texture1DArray _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in float TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    vec4 _46 = texture(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER));\n    SV_TARGET.x = _46.x;\n    SV_TARGET.y = _46.y;\n    SV_TARGET.z = _46.z;\n    SV_TARGET.w = _46.w;\n    vec4 _63 = textureOffset(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER), -1);\n    SV_TARGET_1.x = _63.x;\n    SV_TARGET_1.y = _63.y;\n    SV_TARGET_1.z = _63.z;\n    SV_TARGET_1.w = _63.w;\n    vec4 _74 = textureLod(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER), textureQueryLod(sampler1DArray(_8, _11), TEXCOORD.x).x);\n    SV_TARGET_2.x = _74.x;\n    SV_TARGET_2.y = _74.y;\n    SV_TARGET_2.z = _74.z;\n    SV_TARGET_2.w = _74.w;\n    vec4 _85 = texture(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER), LOD_BIAS);\n    SV_TARGET_3.x = _85.x;\n    SV_TARGET_3.y = _85.y;\n    SV_TARGET_3.z = _85.z;\n    SV_TARGET_3.w = _85.w;\n    vec4 _96 = textureClampARB(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER), LOD_CLAMP);\n    SV_TARGET_4.x = _96.x;\n    SV_TARGET_4.y = _96.y;\n    SV_TARGET_4.z = _96.z;\n    SV_TARGET_4.w = _96.w;\n    vec4 _107 = textureOffsetClampARB(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER), -1, LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _107.x;\n    SV_TARGET_5.y = _107.y;\n    SV_TARGET_5.z = _107.z;\n    SV_TARGET_5.w = _107.w;\n    float _119 = dFdx(TEXCOORD_2);\n    float _120 = dFdy(TEXCOORD_2);\n    vec4 _121 = textureGrad(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER), _119, _120);\n    SV_TARGET_6.x = _121.x;\n    SV_TARGET_6.y = _121.y;\n    SV_TARGET_6.z = _121.z;\n    SV_TARGET_6.w = _121.w;\n    vec4 _132 = textureGradOffset(sampler1DArray(_8, _11), vec2(TEXCOORD.x, LAYER), _119, _120, -1);\n    SV_TARGET_7.x = _132.x;\n    SV_TARGET_7.y = _132.y;\n    SV_TARGET_7.z = _132.z;\n    SV_TARGET_7.w = _132.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 50\n; Schema: 0\n               OpCapability Shader\n               OpCapability Sampled1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %48\n\n         %48 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %21 =   OpLoad %uint %19\n         %23 =   OpImageFetch %v4float %17 %21 Lod %uint_1\n         %24 =   OpCompositeExtract %float %23 0\n         %25 =   OpCompositeExtract %float %23 1\n         %26 =   OpCompositeExtract %float %23 2\n         %27 =   OpCompositeExtract %float %23 3\n         %30 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %30 %24\n         %31 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %31 %25\n         %32 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %32 %26\n         %34 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %34 %27\n         %38 =   OpImageFetch %v4float %17 %21 Lod|ConstOffset %uint_1 %int_n1\n         %39 =   OpCompositeExtract %float %38 0\n         %40 =   OpCompositeExtract %float %38 1\n         %41 =   OpCompositeExtract %float %38 2\n         %42 =   OpCompositeExtract %float %38 3\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %44 %39\n         %45 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %45 %40\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %46 %41\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %47 %42\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture1D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _23 = texelFetch(_8, int(TEXCOORD.x), int(1u));\n    SV_TARGET.x = _23.x;\n    SV_TARGET.y = _23.y;\n    SV_TARGET.z = _23.z;\n    SV_TARGET.w = _23.w;\n    vec4 _38 = texelFetchOffset(_8, int(TEXCOORD.x), int(1u), -1);\n    SV_TARGET_1.x = _38.x;\n    SV_TARGET_1.y = _38.y;\n    SV_TARGET_1.z = _38.z;\n    SV_TARGET_1.w = _38.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\n               OpCapability Shader\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n          %_ = OpTypeStruct %uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %21\n\n         %21 = OpLabel\n         %14 =   OpLoad %6 %8\n         %15 =   OpImageQuerySizeLod %uint %14 %uint_0\n                 OpStore %SV_TARGET %15\n                 OpStore %SV_TARGET_1 %uint_1\n         %20 =   OpImageQueryLevels %uint %14\n                 OpStore %SV_TARGET_2 %20\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _17\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture1D _8;\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    SV_TARGET = uint(textureSize(_8, int(0u)));\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 136\n; Schema: 0\n               OpCapability Shader\n               OpCapability MinLod\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n         %37 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %134\n\n        %134 = OpLabel\n         %31 =   OpLoad %6 %8\n         %32 =   OpLoad %9 %11\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %36 =   OpLoad %float %33\n         %38 =   OpSampledImage %37 %31 %32\n         %40 =   OpImageQueryLod %v2float %38 %36\n         %41 =   OpCompositeExtract %float %40 0\n         %42 =   OpLoad %float %LOD_BIAS\n         %43 =   OpLoad %float %LOD_CLAMP\n         %45 =   OpImageSampleImplicitLod %v4float %38 %36 None\n         %46 =   OpCompositeExtract %float %45 0\n         %47 =   OpCompositeExtract %float %45 1\n         %48 =   OpCompositeExtract %float %45 2\n         %49 =   OpCompositeExtract %float %45 3\n         %52 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %52 %46\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %53 %47\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %55 %48\n         %57 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %57 %49\n         %61 =   OpImageSampleImplicitLod %v4float %38 %36 ConstOffset %int_n1\n         %62 =   OpCompositeExtract %float %61 0\n         %63 =   OpCompositeExtract %float %61 1\n         %64 =   OpCompositeExtract %float %61 2\n         %65 =   OpCompositeExtract %float %61 3\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %67 %62\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %68 %63\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %69 %64\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %70 %65\n         %71 =   OpImageSampleExplicitLod %v4float %38 %36 Lod %41\n         %72 =   OpCompositeExtract %float %71 0\n         %73 =   OpCompositeExtract %float %71 1\n         %74 =   OpCompositeExtract %float %71 2\n         %75 =   OpCompositeExtract %float %71 3\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %77 %72\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %78 %73\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %79 %74\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %80 %75\n         %81 =   OpImageSampleImplicitLod %v4float %38 %36 Bias %42\n         %82 =   OpCompositeExtract %float %81 0\n         %83 =   OpCompositeExtract %float %81 1\n         %84 =   OpCompositeExtract %float %81 2\n         %85 =   OpCompositeExtract %float %81 3\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %88 %83\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %89 %84\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %90 %85\n         %91 =   OpImageSampleImplicitLod %v4float %38 %36 MinLod %43\n         %92 =   OpCompositeExtract %float %91 0\n         %93 =   OpCompositeExtract %float %91 1\n         %94 =   OpCompositeExtract %float %91 2\n         %95 =   OpCompositeExtract %float %91 3\n         %97 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %97 %92\n         %98 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %98 %93\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %99 %94\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %100 %95\n        %101 =   OpImageSampleImplicitLod %v4float %38 %36 Bias|ConstOffset|MinLod %42 %int_n1 %43\n        %102 =   OpCompositeExtract %float %101 0\n        %103 =   OpCompositeExtract %float %101 1\n        %104 =   OpCompositeExtract %float %101 2\n        %105 =   OpCompositeExtract %float %101 3\n        %107 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %107 %102\n        %108 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %108 %103\n        %109 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %109 %104\n        %110 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %110 %105\n        %111 =   OpLoad %float %TEXCOORD_2\n        %112 =   OpDPdx %float %111\n        %113 =   OpDPdy %float %111\n        %114 =   OpImageSampleExplicitLod %v4float %38 %36 Grad %112 %113\n        %115 =   OpCompositeExtract %float %114 0\n        %116 =   OpCompositeExtract %float %114 1\n        %117 =   OpCompositeExtract %float %114 2\n        %118 =   OpCompositeExtract %float %114 3\n        %120 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %120 %115\n        %121 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %121 %116\n        %122 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %122 %117\n        %123 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %123 %118\n        %124 =   OpImageSampleExplicitLod %v4float %38 %36 Grad|ConstOffset %112 %113 %int_n1\n        %125 =   OpCompositeExtract %float %124 0\n        %126 =   OpCompositeExtract %float %124 1\n        %127 =   OpCompositeExtract %float %124 2\n        %128 =   OpCompositeExtract %float %124 3\n        %130 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %130 %125\n        %131 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %131 %126\n        %132 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %132 %127\n        %133 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %133 %128\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_1d_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0) uniform texture1D _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in float TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    vec4 _45 = texture(sampler1D(_8, _11), TEXCOORD.x);\n    SV_TARGET.x = _45.x;\n    SV_TARGET.y = _45.y;\n    SV_TARGET.z = _45.z;\n    SV_TARGET.w = _45.w;\n    vec4 _61 = textureOffset(sampler1D(_8, _11), TEXCOORD.x, -1);\n    SV_TARGET_1.x = _61.x;\n    SV_TARGET_1.y = _61.y;\n    SV_TARGET_1.z = _61.z;\n    SV_TARGET_1.w = _61.w;\n    vec4 _71 = textureLod(sampler1D(_8, _11), TEXCOORD.x, textureQueryLod(sampler1D(_8, _11), TEXCOORD.x).x);\n    SV_TARGET_2.x = _71.x;\n    SV_TARGET_2.y = _71.y;\n    SV_TARGET_2.z = _71.z;\n    SV_TARGET_2.w = _71.w;\n    vec4 _81 = texture(sampler1D(_8, _11), TEXCOORD.x, LOD_BIAS);\n    SV_TARGET_3.x = _81.x;\n    SV_TARGET_3.y = _81.y;\n    SV_TARGET_3.z = _81.z;\n    SV_TARGET_3.w = _81.w;\n    vec4 _91 = textureClampARB(sampler1D(_8, _11), TEXCOORD.x, LOD_CLAMP);\n    SV_TARGET_4.x = _91.x;\n    SV_TARGET_4.y = _91.y;\n    SV_TARGET_4.z = _91.z;\n    SV_TARGET_4.w = _91.w;\n    vec4 _101 = textureOffsetClampARB(sampler1D(_8, _11), TEXCOORD.x, -1, LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _101.x;\n    SV_TARGET_5.y = _101.y;\n    SV_TARGET_5.z = _101.z;\n    SV_TARGET_5.w = _101.w;\n    float _112 = dFdx(TEXCOORD_2);\n    float _113 = dFdy(TEXCOORD_2);\n    vec4 _114 = textureGrad(sampler1D(_8, _11), TEXCOORD.x, _112, _113);\n    SV_TARGET_6.x = _114.x;\n    SV_TARGET_6.y = _114.y;\n    SV_TARGET_6.z = _114.z;\n    SV_TARGET_6.w = _114.w;\n    vec4 _124 = textureGradOffset(sampler1D(_8, _11), TEXCOORD.x, _112, _113, -1);\n    SV_TARGET_7.x = _124.x;\n    SV_TARGET_7.y = _124.y;\n    SV_TARGET_7.z = _124.z;\n    SV_TARGET_7.w = _124.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 130\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %51 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %71 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %128\n\n        %128 = OpLabel\n         %30 =   OpLoad %6 %8\n         %31 =   OpLoad %9 %11\n         %32 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %35 =   OpLoad %float %32\n         %36 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %38 =   OpLoad %float %36\n         %41 =   OpLoad %float %LAYER\n         %43 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %44 =   OpLoad %int %43\n         %45 =   OpBitcast %uint %44\n         %46 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %47 =   OpLoad %int %46\n         %48 =   OpBitcast %uint %47\n         %52 =   OpSampledImage %51 %30 %31\n         %53 =   OpCompositeConstruct %v3float %35 %38 %41\n         %54 =   OpImageGather %v4float %52 %53 %uint_0\n         %55 =   OpCompositeExtract %float %54 0\n         %56 =   OpCompositeExtract %float %54 1\n         %57 =   OpCompositeExtract %float %54 2\n         %58 =   OpCompositeExtract %float %54 3\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %61 %55\n         %62 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %62 %56\n         %63 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %63 %57\n         %65 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %65 %58\n         %67 =   OpCompositeConstruct %v3float %35 %38 %41\n         %70 =   OpImageGather %v4float %52 %67 %uint_0 ConstOffset %71\n         %72 =   OpCompositeExtract %float %70 0\n         %73 =   OpCompositeExtract %float %70 1\n         %74 =   OpCompositeExtract %float %70 2\n         %75 =   OpCompositeExtract %float %70 3\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %77 %72\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %78 %73\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %79 %74\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %80 %75\n         %81 =   OpCompositeConstruct %v3float %35 %38 %41\n         %82 =   OpImageGather %v4float %52 %81 %uint_1\n         %83 =   OpCompositeExtract %float %82 0\n         %84 =   OpCompositeExtract %float %82 1\n         %85 =   OpCompositeExtract %float %82 2\n         %86 =   OpCompositeExtract %float %82 3\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %88 %83\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %89 %84\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %91 %86\n         %92 =   OpCompositeConstruct %v3float %35 %38 %41\n         %93 =   OpImageGather %v4float %52 %92 %uint_2\n         %94 =   OpCompositeExtract %float %93 0\n         %95 =   OpCompositeExtract %float %93 1\n         %96 =   OpCompositeExtract %float %93 2\n         %97 =   OpCompositeExtract %float %93 3\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %99 %94\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %100 %95\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %101 %96\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %102 %97\n        %103 =   OpCompositeConstruct %v3float %35 %38 %41\n        %104 =   OpImageGather %v4float %52 %103 %uint_3\n        %105 =   OpCompositeExtract %float %104 0\n        %106 =   OpCompositeExtract %float %104 1\n        %107 =   OpCompositeExtract %float %104 2\n        %108 =   OpCompositeExtract %float %104 3\n        %110 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %110 %105\n        %111 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %111 %106\n        %112 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %112 %107\n        %113 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %113 %108\n        %114 =   OpCompositeConstruct %v3float %35 %38 %41\n        %115 =   OpBitcast %int %45\n        %116 =   OpBitcast %int %48\n        %118 =   OpCompositeConstruct %v2int %115 %116\n        %117 =   OpImageGather %v4float %52 %114 %uint_0 Offset %118\n        %119 =   OpCompositeExtract %float %117 0\n        %120 =   OpCompositeExtract %float %117 1\n        %121 =   OpCompositeExtract %float %117 2\n        %122 =   OpCompositeExtract %float %117 3\n        %124 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %124 %119\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %125 %120\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %126 %121\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %127 %122\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_gather.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\n\nvoid main()\n{\n    vec4 _54 = textureGather(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER));\n    SV_TARGET.x = _54.x;\n    SV_TARGET.y = _54.y;\n    SV_TARGET.z = _54.z;\n    SV_TARGET.w = _54.w;\n    vec4 _70 = textureGatherOffset(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(-1, 0));\n    SV_TARGET_1.x = _70.x;\n    SV_TARGET_1.y = _70.y;\n    SV_TARGET_1.z = _70.z;\n    SV_TARGET_1.w = _70.w;\n    vec4 _82 = textureGather(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), int(1u));\n    SV_TARGET_2.x = _82.x;\n    SV_TARGET_2.y = _82.y;\n    SV_TARGET_2.z = _82.z;\n    SV_TARGET_2.w = _82.w;\n    vec4 _93 = textureGather(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), int(2u));\n    SV_TARGET_3.x = _93.x;\n    SV_TARGET_3.y = _93.y;\n    SV_TARGET_3.z = _93.z;\n    SV_TARGET_3.w = _93.w;\n    vec4 _104 = textureGather(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), int(3u));\n    SV_TARGET_4.x = _104.x;\n    SV_TARGET_4.y = _104.y;\n    SV_TARGET_4.z = _104.z;\n    SV_TARGET_4.w = _104.w;\n    vec4 _117 = textureGatherOffset(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_5.x = _117.x;\n    SV_TARGET_5.y = _117.y;\n    SV_TARGET_5.z = _117.z;\n    SV_TARGET_5.w = _117.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 96\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %49 = OpTypeImage %float 2D 1 1 0 1 Unknown\n         %50 = OpTypeSampledImage %49\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %70 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %94\n\n         %94 = OpLabel\n         %27 =   OpLoad %6 %8\n         %28 =   OpLoad %9 %11\n         %29 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %32 =   OpLoad %float %29\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %35 =   OpLoad %float %33\n         %38 =   OpLoad %float %DEPTH_REF\n         %39 =   OpLoad %float %LAYER\n         %41 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %42 =   OpLoad %int %41\n         %43 =   OpBitcast %uint %42\n         %44 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %45 =   OpLoad %int %44\n         %46 =   OpBitcast %uint %45\n         %51 =   OpSampledImage %50 %27 %28\n         %52 =   OpCompositeConstruct %v3float %32 %35 %39\n         %53 =   OpImageDrefGather %v4float %51 %52 %38\n         %54 =   OpCompositeExtract %float %53 0\n         %55 =   OpCompositeExtract %float %53 1\n         %56 =   OpCompositeExtract %float %53 2\n         %57 =   OpCompositeExtract %float %53 3\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %61 %55\n         %62 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %62 %56\n         %64 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %64 %57\n         %66 =   OpCompositeConstruct %v3float %32 %35 %39\n         %69 =   OpImageDrefGather %v4float %51 %66 %38 ConstOffset %70\n         %71 =   OpCompositeExtract %float %69 0\n         %72 =   OpCompositeExtract %float %69 1\n         %73 =   OpCompositeExtract %float %69 2\n         %74 =   OpCompositeExtract %float %69 3\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %76 %71\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %77 %72\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %78 %73\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %79 %74\n         %80 =   OpCompositeConstruct %v3float %32 %35 %39\n         %81 =   OpBitcast %int %43\n         %82 =   OpBitcast %int %46\n         %84 =   OpCompositeConstruct %v2int %81 %82\n         %83 =   OpImageDrefGather %v4float %51 %80 %38 Offset %84\n         %85 =   OpCompositeExtract %float %83 0\n         %86 =   OpCompositeExtract %float %83 1\n         %87 =   OpCompositeExtract %float %83 2\n         %88 =   OpCompositeExtract %float %83 3\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %93 %88\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\n\nvoid main()\n{\n    vec3 _52 = vec3(TEXCOORD.x, TEXCOORD.y, LAYER);\n    vec4 _53 = textureGather(sampler2DArrayShadow(_8, _11), _52, DEPTH_REF);\n    SV_TARGET.x = _53.x;\n    SV_TARGET.y = _53.y;\n    SV_TARGET.z = _53.z;\n    SV_TARGET.w = _53.w;\n    vec3 _66 = vec3(TEXCOORD.x, TEXCOORD.y, LAYER);\n    vec4 _69 = textureGatherOffset(sampler2DArrayShadow(_8, _11), _66, DEPTH_REF, ivec2(-1, 0));\n    SV_TARGET_1.x = _69.x;\n    SV_TARGET_1.y = _69.y;\n    SV_TARGET_1.z = _69.z;\n    SV_TARGET_1.w = _69.w;\n    vec3 _80 = vec3(TEXCOORD.x, TEXCOORD.y, LAYER);\n    vec4 _83 = textureGatherOffset(sampler2DArrayShadow(_8, _11), _80, DEPTH_REF, ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_2.x = _83.x;\n    SV_TARGET_2.y = _83.y;\n    SV_TARGET_2.z = _83.z;\n    SV_TARGET_2.w = _83.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %47 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %57\n\n         %57 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %24 =   OpLoad %uint %22\n         %29 =   OpCompositeConstruct %v3uint %21 %24 %uint_2\n         %28 =   OpImageFetch %v4float %17 %29 Lod %uint_1\n         %30 =   OpCompositeExtract %float %28 0\n         %31 =   OpCompositeExtract %float %28 1\n         %32 =   OpCompositeExtract %float %28 2\n         %33 =   OpCompositeExtract %float %28 3\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %36 %30\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %39 %33\n         %45 =   OpCompositeConstruct %v3uint %21 %24 %uint_2\n         %44 =   OpImageFetch %v4float %17 %45 Lod|ConstOffset %uint_1 %47\n         %48 =   OpCompositeExtract %float %44 0\n         %49 =   OpCompositeExtract %float %44 1\n         %50 =   OpCompositeExtract %float %44 2\n         %51 =   OpCompositeExtract %float %44 3\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %53 %48\n         %54 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %54 %49\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %55 %50\n         %56 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %56 %51\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _28 = texelFetch(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), int(1u));\n    SV_TARGET.x = _28.x;\n    SV_TARGET.y = _28.y;\n    SV_TARGET.z = _28.z;\n    SV_TARGET.w = _28.w;\n    vec4 _44 = texelFetchOffset(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), int(1u), ivec2(-1, 0));\n    SV_TARGET_1.x = _44.x;\n    SV_TARGET_1.y = _44.y;\n    SV_TARGET_1.z = _44.z;\n    SV_TARGET_1.w = _44.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %v3uint = OpTypeVector %uint 3\n     %uint_0 = OpConstant %uint 0\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %30\n\n         %30 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpImageQuerySizeLod %v3uint %16 %uint_0\n         %20 =   OpCompositeExtract %uint %18 0\n         %21 =   OpCompositeExtract %uint %18 1\n         %22 =   OpCompositeConstruct %v2uint %20 %21\n         %23 =   OpCompositeExtract %uint %18 2\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %26 %20\n         %27 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %27 %21\n                 OpStore %SV_TARGET_1 %23\n         %29 =   OpImageQueryLevels %uint %16\n                 OpStore %SV_TARGET_2 %29\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _24\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uvec3 _18 = uvec3(textureSize(_8, int(0u)));\n    uint _20 = _18.x;\n    SV_TARGET.x = _20;\n    SV_TARGET.y = _18.y;\n    SV_TARGET_1 = _18.z;\n    SV_TARGET_2 = uint(textureQueryLevels(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 164\n; Schema: 0\n               OpCapability Shader\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n         %44 = OpTypeSampledImage %6\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %72 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %162\n\n        %162 = OpLabel\n         %33 =   OpLoad %6 %8\n         %34 =   OpLoad %9 %11\n         %35 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %38 =   OpLoad %float %35\n         %39 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %41 =   OpLoad %float %39\n         %43 =   OpLoad %float %LAYER\n         %45 =   OpSampledImage %44 %33 %34\n         %47 =   OpCompositeConstruct %v2float %38 %41\n         %46 =   OpImageQueryLod %v2float %45 %47\n         %48 =   OpCompositeExtract %float %46 0\n         %49 =   OpLoad %float %LOD_BIAS\n         %50 =   OpLoad %float %LOD_CLAMP\n         %53 =   OpCompositeConstruct %v3float %38 %41 %43\n         %52 =   OpImageSampleImplicitLod %v4float %45 %53 None\n         %54 =   OpCompositeExtract %float %52 0\n         %55 =   OpCompositeExtract %float %52 1\n         %56 =   OpCompositeExtract %float %52 2\n         %57 =   OpCompositeExtract %float %52 3\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %61 %55\n         %62 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %62 %56\n         %64 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %64 %57\n         %70 =   OpCompositeConstruct %v3float %38 %41 %43\n         %69 =   OpImageSampleImplicitLod %v4float %45 %70 ConstOffset %72\n         %73 =   OpCompositeExtract %float %69 0\n         %74 =   OpCompositeExtract %float %69 1\n         %75 =   OpCompositeExtract %float %69 2\n         %76 =   OpCompositeExtract %float %69 3\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %78 %73\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %79 %74\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %80 %75\n         %81 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %81 %76\n         %83 =   OpCompositeConstruct %v3float %38 %41 %43\n         %82 =   OpImageSampleExplicitLod %v4float %45 %83 Lod %48\n         %84 =   OpCompositeExtract %float %82 0\n         %85 =   OpCompositeExtract %float %82 1\n         %86 =   OpCompositeExtract %float %82 2\n         %87 =   OpCompositeExtract %float %82 3\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %89 %84\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %92 %87\n         %94 =   OpCompositeConstruct %v3float %38 %41 %43\n         %93 =   OpImageSampleImplicitLod %v4float %45 %94 Bias %49\n         %95 =   OpCompositeExtract %float %93 0\n         %96 =   OpCompositeExtract %float %93 1\n         %97 =   OpCompositeExtract %float %93 2\n         %98 =   OpCompositeExtract %float %93 3\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %100 %95\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %101 %96\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %102 %97\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %103 %98\n        %105 =   OpCompositeConstruct %v3float %38 %41 %43\n        %104 =   OpImageSampleImplicitLod %v4float %45 %105 MinLod %50\n        %106 =   OpCompositeExtract %float %104 0\n        %107 =   OpCompositeExtract %float %104 1\n        %108 =   OpCompositeExtract %float %104 2\n        %109 =   OpCompositeExtract %float %104 3\n        %111 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %111 %106\n        %112 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %112 %107\n        %113 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %113 %108\n        %114 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %114 %109\n        %116 =   OpCompositeConstruct %v3float %38 %41 %43\n        %115 =   OpImageSampleImplicitLod %v4float %45 %116 Bias|ConstOffset|MinLod %49 %72 %50\n        %117 =   OpCompositeExtract %float %115 0\n        %118 =   OpCompositeExtract %float %115 1\n        %119 =   OpCompositeExtract %float %115 2\n        %120 =   OpCompositeExtract %float %115 3\n        %122 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %122 %117\n        %123 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %123 %118\n        %124 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %124 %119\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %125 %120\n        %126 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %127 =   OpLoad %float %126\n        %128 =   OpDPdx %float %127\n        %129 =   OpDPdy %float %127\n        %130 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %131 =   OpLoad %float %130\n        %132 =   OpDPdx %float %131\n        %133 =   OpDPdy %float %131\n        %137 =   OpCompositeConstruct %v3float %38 %41 %43\n        %138 =   OpCompositeConstruct %v2float %128 %132\n        %139 =   OpCompositeConstruct %v2float %129 %133\n        %136 =   OpImageSampleExplicitLod %v4float %45 %137 Grad %138 %139\n        %140 =   OpCompositeExtract %float %136 0\n        %141 =   OpCompositeExtract %float %136 1\n        %142 =   OpCompositeExtract %float %136 2\n        %143 =   OpCompositeExtract %float %136 3\n        %145 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %145 %140\n        %146 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %146 %141\n        %147 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %147 %142\n        %148 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %148 %143\n        %150 =   OpCompositeConstruct %v3float %38 %41 %43\n        %151 =   OpCompositeConstruct %v2float %128 %132\n        %152 =   OpCompositeConstruct %v2float %129 %133\n        %149 =   OpImageSampleExplicitLod %v4float %45 %150 Grad|ConstOffset %151 %152 %72\n        %153 =   OpCompositeExtract %float %149 0\n        %154 =   OpCompositeExtract %float %149 1\n        %155 =   OpCompositeExtract %float %149 2\n        %156 =   OpCompositeExtract %float %149 3\n        %158 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %158 %153\n        %159 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %159 %154\n        %160 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %160 %155\n        %161 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %161 %156\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    vec4 _52 = texture(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER));\n    SV_TARGET.x = _52.x;\n    SV_TARGET.y = _52.y;\n    SV_TARGET.z = _52.z;\n    SV_TARGET.w = _52.w;\n    vec4 _69 = textureOffset(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(-1, 0));\n    SV_TARGET_1.x = _69.x;\n    SV_TARGET_1.y = _69.y;\n    SV_TARGET_1.z = _69.z;\n    SV_TARGET_1.w = _69.w;\n    vec4 _82 = textureLod(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), textureQueryLod(sampler2DArray(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y)).x);\n    SV_TARGET_2.x = _82.x;\n    SV_TARGET_2.y = _82.y;\n    SV_TARGET_2.z = _82.z;\n    SV_TARGET_2.w = _82.w;\n    vec4 _93 = texture(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), LOD_BIAS);\n    SV_TARGET_3.x = _93.x;\n    SV_TARGET_3.y = _93.y;\n    SV_TARGET_3.z = _93.z;\n    SV_TARGET_3.w = _93.w;\n    vec4 _104 = textureClampARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), LOD_CLAMP);\n    SV_TARGET_4.x = _104.x;\n    SV_TARGET_4.y = _104.y;\n    SV_TARGET_4.z = _104.z;\n    SV_TARGET_4.w = _104.w;\n    vec4 _115 = textureOffsetClampARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(-1, 0), LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _115.x;\n    SV_TARGET_5.y = _115.y;\n    SV_TARGET_5.z = _115.z;\n    SV_TARGET_5.w = _115.w;\n    float _128 = dFdx(TEXCOORD_2.x);\n    float _129 = dFdy(TEXCOORD_2.x);\n    float _132 = dFdx(TEXCOORD_2.y);\n    float _133 = dFdy(TEXCOORD_2.y);\n    vec4 _136 = textureGrad(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), vec2(_128, _132), vec2(_129, _133));\n    SV_TARGET_6.x = _136.x;\n    SV_TARGET_6.y = _136.y;\n    SV_TARGET_6.z = _136.z;\n    SV_TARGET_6.w = _136.w;\n    vec4 _149 = textureGradOffset(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), vec2(_128, _132), vec2(_129, _133), ivec2(-1, 0));\n    SV_TARGET_7.x = _149.x;\n    SV_TARGET_7.y = _149.y;\n    SV_TARGET_7.z = _149.z;\n    SV_TARGET_7.w = _149.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 65\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n         %41 = OpTypeImage %float 2D 1 1 0 1 Unknown\n         %42 = OpTypeSampledImage %41\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %56 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %63\n\n         %63 = OpLabel\n         %27 =   OpLoad %6 %8\n         %28 =   OpLoad %9 %11\n         %29 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %32 =   OpLoad %float %29\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %35 =   OpLoad %float %33\n         %37 =   OpLoad %float %DEPTH_REF\n         %38 =   OpLoad %float %LAYER\n         %43 =   OpSampledImage %42 %27 %28\n         %46 =   OpCompositeConstruct %v3float %32 %35 %38\n         %45 =   OpImageSampleDrefImplicitLod %float %43 %46 %37 None\n         %48 =   OpCompositeConstruct %v4float %45 %45 %45 %45\n         %49 =   OpCompositeExtract %float %48 0\n                 OpStore %SV_TARGET %49\n         %54 =   OpCompositeConstruct %v3float %32 %35 %38\n         %53 =   OpImageSampleDrefImplicitLod %float %43 %54 %37 ConstOffset %56\n         %57 =   OpCompositeConstruct %v4float %53 %53 %53 %53\n         %58 =   OpCompositeExtract %float %57 0\n                 OpStore %SV_TARGET_1 %58\n         %60 =   OpCompositeConstruct %v3float %32 %35 %38\n         %59 =   OpImageSampleDrefExplicitLod %float %43 %60 %37 Lod %float_0\n         %61 =   OpCompositeConstruct %v4float %59 %59 %59 %59\n         %62 =   OpCompositeExtract %float %61 0\n                 OpStore %SV_TARGET_2 %62\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_array_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\n\nvoid main()\n{\n    SV_TARGET = vec4(texture(sampler2DArrayShadow(_8, _11), vec4(vec3(TEXCOORD.x, TEXCOORD.y, LAYER), DEPTH_REF))).x;\n    SV_TARGET_1 = vec4(textureOffset(sampler2DArrayShadow(_8, _11), vec4(vec3(TEXCOORD.x, TEXCOORD.y, LAYER), DEPTH_REF), ivec2(-1, 0))).x;\n    SV_TARGET_2 = vec4(textureGrad(sampler2DArrayShadow(_8, _11), vec4(vec3(TEXCOORD.x, TEXCOORD.y, LAYER), DEPTH_REF), vec2(0.0), vec2(0.0))).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 129\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %50 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %70 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %127\n\n        %127 = OpLabel\n         %30 =   OpLoad %6 %8\n         %31 =   OpLoad %9 %11\n         %32 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %35 =   OpLoad %float %32\n         %36 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %38 =   OpLoad %float %36\n         %42 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %43 =   OpLoad %int %42\n         %44 =   OpBitcast %uint %43\n         %45 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %46 =   OpLoad %int %45\n         %47 =   OpBitcast %uint %46\n         %51 =   OpSampledImage %50 %30 %31\n         %52 =   OpCompositeConstruct %v2float %35 %38\n         %53 =   OpImageGather %v4float %51 %52 %uint_0\n         %54 =   OpCompositeExtract %float %53 0\n         %55 =   OpCompositeExtract %float %53 1\n         %56 =   OpCompositeExtract %float %53 2\n         %57 =   OpCompositeExtract %float %53 3\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %61 %55\n         %62 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %62 %56\n         %64 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %64 %57\n         %66 =   OpCompositeConstruct %v2float %35 %38\n         %69 =   OpImageGather %v4float %51 %66 %uint_0 ConstOffset %70\n         %71 =   OpCompositeExtract %float %69 0\n         %72 =   OpCompositeExtract %float %69 1\n         %73 =   OpCompositeExtract %float %69 2\n         %74 =   OpCompositeExtract %float %69 3\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %76 %71\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %77 %72\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %78 %73\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %79 %74\n         %80 =   OpCompositeConstruct %v2float %35 %38\n         %81 =   OpImageGather %v4float %51 %80 %uint_1\n         %82 =   OpCompositeExtract %float %81 0\n         %83 =   OpCompositeExtract %float %81 1\n         %84 =   OpCompositeExtract %float %81 2\n         %85 =   OpCompositeExtract %float %81 3\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %88 %83\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %89 %84\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %90 %85\n         %91 =   OpCompositeConstruct %v2float %35 %38\n         %92 =   OpImageGather %v4float %51 %91 %uint_2\n         %93 =   OpCompositeExtract %float %92 0\n         %94 =   OpCompositeExtract %float %92 1\n         %95 =   OpCompositeExtract %float %92 2\n         %96 =   OpCompositeExtract %float %92 3\n         %98 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %98 %93\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %99 %94\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %100 %95\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %101 %96\n        %102 =   OpCompositeConstruct %v2float %35 %38\n        %103 =   OpImageGather %v4float %51 %102 %uint_3\n        %104 =   OpCompositeExtract %float %103 0\n        %105 =   OpCompositeExtract %float %103 1\n        %106 =   OpCompositeExtract %float %103 2\n        %107 =   OpCompositeExtract %float %103 3\n        %109 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %109 %104\n        %110 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %110 %105\n        %111 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %111 %106\n        %112 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %112 %107\n        %113 =   OpCompositeConstruct %v2float %35 %38\n        %114 =   OpBitcast %int %44\n        %115 =   OpBitcast %int %47\n        %117 =   OpCompositeConstruct %v2int %114 %115\n        %116 =   OpImageGather %v4float %51 %113 %uint_0 Offset %117\n        %118 =   OpCompositeExtract %float %116 0\n        %119 =   OpCompositeExtract %float %116 1\n        %120 =   OpCompositeExtract %float %116 2\n        %121 =   OpCompositeExtract %float %116 3\n        %123 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %123 %118\n        %124 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %124 %119\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %125 %120\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %126 %121\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_gather.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\n\nvoid main()\n{\n    vec4 _53 = textureGather(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y));\n    SV_TARGET.x = _53.x;\n    SV_TARGET.y = _53.y;\n    SV_TARGET.z = _53.z;\n    SV_TARGET.w = _53.w;\n    vec4 _69 = textureGatherOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(-1, 0));\n    SV_TARGET_1.x = _69.x;\n    SV_TARGET_1.y = _69.y;\n    SV_TARGET_1.z = _69.z;\n    SV_TARGET_1.w = _69.w;\n    vec4 _81 = textureGather(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), int(1u));\n    SV_TARGET_2.x = _81.x;\n    SV_TARGET_2.y = _81.y;\n    SV_TARGET_2.z = _81.z;\n    SV_TARGET_2.w = _81.w;\n    vec4 _92 = textureGather(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), int(2u));\n    SV_TARGET_3.x = _92.x;\n    SV_TARGET_3.y = _92.y;\n    SV_TARGET_3.z = _92.z;\n    SV_TARGET_3.w = _92.w;\n    vec4 _103 = textureGather(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), int(3u));\n    SV_TARGET_4.x = _103.x;\n    SV_TARGET_4.y = _103.y;\n    SV_TARGET_4.z = _103.z;\n    SV_TARGET_4.w = _103.w;\n    vec4 _116 = textureGatherOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_5.x = _116.x;\n    SV_TARGET_5.y = _116.y;\n    SV_TARGET_5.z = _116.z;\n    SV_TARGET_5.w = _116.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 95\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %48 = OpTypeImage %float 2D 1 0 0 1 Unknown\n         %49 = OpTypeSampledImage %48\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %69 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %93\n\n         %93 = OpLabel\n         %27 =   OpLoad %6 %8\n         %28 =   OpLoad %9 %11\n         %29 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %32 =   OpLoad %float %29\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %35 =   OpLoad %float %33\n         %38 =   OpLoad %float %DEPTH_REF\n         %40 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %41 =   OpLoad %int %40\n         %42 =   OpBitcast %uint %41\n         %43 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %44 =   OpLoad %int %43\n         %45 =   OpBitcast %uint %44\n         %50 =   OpSampledImage %49 %27 %28\n         %51 =   OpCompositeConstruct %v2float %32 %35\n         %52 =   OpImageDrefGather %v4float %50 %51 %38\n         %53 =   OpCompositeExtract %float %52 0\n         %54 =   OpCompositeExtract %float %52 1\n         %55 =   OpCompositeExtract %float %52 2\n         %56 =   OpCompositeExtract %float %52 3\n         %59 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %59 %53\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %61 %55\n         %63 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %63 %56\n         %65 =   OpCompositeConstruct %v2float %32 %35\n         %68 =   OpImageDrefGather %v4float %50 %65 %38 ConstOffset %69\n         %70 =   OpCompositeExtract %float %68 0\n         %71 =   OpCompositeExtract %float %68 1\n         %72 =   OpCompositeExtract %float %68 2\n         %73 =   OpCompositeExtract %float %68 3\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %75 %70\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %76 %71\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %77 %72\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %78 %73\n         %79 =   OpCompositeConstruct %v2float %32 %35\n         %80 =   OpBitcast %int %42\n         %81 =   OpBitcast %int %45\n         %83 =   OpCompositeConstruct %v2int %80 %81\n         %82 =   OpImageDrefGather %v4float %50 %79 %38 Offset %83\n         %84 =   OpCompositeExtract %float %82 0\n         %85 =   OpCompositeExtract %float %82 1\n         %86 =   OpCompositeExtract %float %82 2\n         %87 =   OpCompositeExtract %float %82 3\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %89 %84\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %92 %87\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\n\nvoid main()\n{\n    vec2 _51 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _52 = textureGather(sampler2DShadow(_8, _11), _51, DEPTH_REF);\n    SV_TARGET.x = _52.x;\n    SV_TARGET.y = _52.y;\n    SV_TARGET.z = _52.z;\n    SV_TARGET.w = _52.w;\n    vec2 _65 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _68 = textureGatherOffset(sampler2DShadow(_8, _11), _65, DEPTH_REF, ivec2(-1, 0));\n    SV_TARGET_1.x = _68.x;\n    SV_TARGET_1.y = _68.y;\n    SV_TARGET_1.z = _68.z;\n    SV_TARGET_1.w = _68.w;\n    vec2 _79 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _82 = textureGatherOffset(sampler2DShadow(_8, _11), _79, DEPTH_REF, ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_2.x = _82.x;\n    SV_TARGET_2.y = _82.y;\n    SV_TARGET_2.z = _82.z;\n    SV_TARGET_2.w = _82.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %47 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %57\n\n         %57 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %24 =   OpLoad %uint %22\n         %28 =   OpCompositeConstruct %v2uint %21 %24\n         %27 =   OpImageFetch %v4float %17 %28 Lod %uint_1\n         %29 =   OpCompositeExtract %float %27 0\n         %30 =   OpCompositeExtract %float %27 1\n         %31 =   OpCompositeExtract %float %27 2\n         %32 =   OpCompositeExtract %float %27 3\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %35 %29\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %36 %30\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %37 %31\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %39 %32\n         %45 =   OpCompositeConstruct %v2uint %21 %24\n         %44 =   OpImageFetch %v4float %17 %45 Lod|ConstOffset %uint_1 %47\n         %48 =   OpCompositeExtract %float %44 0\n         %49 =   OpCompositeExtract %float %44 1\n         %50 =   OpCompositeExtract %float %44 2\n         %51 =   OpCompositeExtract %float %44 3\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %53 %48\n         %54 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %54 %49\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %55 %50\n         %56 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %56 %51\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _27 = texelFetch(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(1u));\n    SV_TARGET.x = _27.x;\n    SV_TARGET.y = _27.y;\n    SV_TARGET.z = _27.z;\n    SV_TARGET.w = _27.w;\n    vec4 _44 = texelFetchOffset(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(1u), ivec2(-1, 0));\n    SV_TARGET_1.x = _44.x;\n    SV_TARGET_1.y = _44.y;\n    SV_TARGET_1.z = _44.z;\n    SV_TARGET_1.w = _44.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampleRateShading\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_SAMPLEINDEX %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_SAMPLEINDEX \"SV_SAMPLEINDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_SAMPLEINDEX BuiltIn SampleId\n               OpDecorate %SV_SAMPLEINDEX Flat\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 1 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_SAMPLEINDEX = OpVariable %_ptr_Input_uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %49 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %59\n\n         %59 = OpLabel\n         %19 =   OpLoad %6 %8\n         %20 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %22 =   OpLoad %uint %20\n         %23 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %25 =   OpLoad %uint %23\n         %28 =   OpLoad %uint %SV_SAMPLEINDEX\n         %31 =   OpCompositeConstruct %v3uint %22 %25 %uint_2\n         %30 =   OpImageFetch %v4float %19 %31 Sample %28\n         %32 =   OpCompositeExtract %float %30 0\n         %33 =   OpCompositeExtract %float %30 1\n         %34 =   OpCompositeExtract %float %30 2\n         %35 =   OpCompositeExtract %float %30 3\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %39 %33\n         %40 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %40 %34\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %41 %35\n         %47 =   OpCompositeConstruct %v3uint %22 %25 %uint_2\n         %46 =   OpImageFetch %v4float %19 %47 ConstOffset|Sample %49 %28\n         %50 =   OpCompositeExtract %float %46 0\n         %51 =   OpCompositeExtract %float %46 1\n         %52 =   OpCompositeExtract %float %46 2\n         %53 =   OpCompositeExtract %float %46 3\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %55 %50\n         %56 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %56 %51\n         %57 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %57 %52\n         %58 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %58 %53\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture2DMSArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _30 = texelFetch(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), int(uint(gl_SampleID)));\n    SV_TARGET.x = _30.x;\n    SV_TARGET.y = _30.y;\n    SV_TARGET.z = _30.z;\n    SV_TARGET.w = _30.w;\n    vec4 _46 = texelFetchOffset(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), ivec2(-1, 0), int(uint(gl_SampleID)));\n    SV_TARGET_1.x = _46.x;\n    SV_TARGET_1.y = _46.y;\n    SV_TARGET_1.z = _46.z;\n    SV_TARGET_1.w = _46.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 1 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n     %v3uint = OpTypeVector %uint 3\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %30\n\n         %30 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpImageQuerySize %v3uint %16\n         %19 =   OpCompositeExtract %uint %18 0\n         %20 =   OpCompositeExtract %uint %18 1\n         %21 =   OpCompositeConstruct %v2uint %19 %20\n         %22 =   OpCompositeExtract %uint %18 2\n         %25 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %25 %19\n         %27 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %27 %20\n                 OpStore %SV_TARGET_1 %22\n         %29 =   OpImageQuerySamples %uint %16\n                 OpStore %SV_TARGET_3 %29\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _23\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2DMSArray _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uvec3 _18 = uvec3(textureSize(_8));\n    uint _19 = _18.x;\n    SV_TARGET.x = _19;\n    SV_TARGET.y = _18.y;\n    SV_TARGET_1 = _18.z;\n    SV_TARGET_3 = uint(textureSamples(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampleRateShading\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_SAMPLEINDEX %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_SAMPLEINDEX \"SV_SAMPLEINDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_SAMPLEINDEX BuiltIn SampleId\n               OpDecorate %SV_SAMPLEINDEX Flat\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 1 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_SAMPLEINDEX = OpVariable %_ptr_Input_uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %49 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %59\n\n         %59 = OpLabel\n         %19 =   OpLoad %6 %8\n         %20 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %22 =   OpLoad %uint %20\n         %23 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %25 =   OpLoad %uint %23\n         %28 =   OpLoad %uint %SV_SAMPLEINDEX\n         %30 =   OpCompositeConstruct %v2uint %22 %25\n         %29 =   OpImageFetch %v4float %19 %30 Sample %28\n         %31 =   OpCompositeExtract %float %29 0\n         %32 =   OpCompositeExtract %float %29 1\n         %33 =   OpCompositeExtract %float %29 2\n         %34 =   OpCompositeExtract %float %29 3\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %39 %33\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %41 %34\n         %47 =   OpCompositeConstruct %v2uint %22 %25\n         %46 =   OpImageFetch %v4float %19 %47 ConstOffset|Sample %49 %28\n         %50 =   OpCompositeExtract %float %46 0\n         %51 =   OpCompositeExtract %float %46 1\n         %52 =   OpCompositeExtract %float %46 2\n         %53 =   OpCompositeExtract %float %46 3\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %55 %50\n         %56 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %56 %51\n         %57 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %57 %52\n         %58 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %58 %53\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture2DMS _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _29 = texelFetch(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(uint(gl_SampleID)));\n    SV_TARGET.x = _29.x;\n    SV_TARGET.y = _29.y;\n    SV_TARGET.z = _29.z;\n    SV_TARGET.w = _29.w;\n    vec4 _46 = texelFetchOffset(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), ivec2(-1, 0), int(uint(gl_SampleID)));\n    SV_TARGET_1.x = _46.x;\n    SV_TARGET_1.y = _46.y;\n    SV_TARGET_1.z = _46.z;\n    SV_TARGET_1.w = _46.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 1 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_0 = OpConstant %uint 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %28\n\n         %28 = OpLabel\n         %16 =   OpLoad %6 %8\n         %17 =   OpImageQuerySize %v2uint %16\n         %18 =   OpCompositeExtract %uint %17 0\n         %19 =   OpCompositeExtract %uint %17 1\n         %20 =   OpCompositeConstruct %v2uint %18 %19\n         %24 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %24 %18\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %26 %19\n                 OpStore %SV_TARGET_1 %uint_1\n         %27 =   OpImageQuerySamples %uint %16\n                 OpStore %SV_TARGET_3 %27\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_ms_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _21\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2DMS _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uvec2 _17 = uvec2(textureSize(_8));\n    uint _18 = _17.x;\n    SV_TARGET.x = _18;\n    SV_TARGET.y = _17.y;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_3 = uint(textureSamples(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %28\n\n         %28 = OpLabel\n         %16 =   OpLoad %6 %8\n         %17 =   OpImageQuerySizeLod %v2uint %16 %uint_0\n         %19 =   OpCompositeExtract %uint %17 0\n         %20 =   OpCompositeExtract %uint %17 1\n         %21 =   OpCompositeConstruct %v2uint %19 %20\n         %25 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %25 %19\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %26 %20\n                 OpStore %SV_TARGET_1 %uint_1\n         %27 =   OpImageQueryLevels %uint %16\n                 OpStore %SV_TARGET_2 %27\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _22\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uvec2 _17 = uvec2(textureSize(_8, int(0u)));\n    uint _19 = _17.x;\n    SV_TARGET.x = _19;\n    SV_TARGET.y = _17.y;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 163\n; Schema: 0\n               OpCapability Shader\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n         %43 = OpTypeSampledImage %6\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %71 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %161\n\n        %161 = OpLabel\n         %33 =   OpLoad %6 %8\n         %34 =   OpLoad %9 %11\n         %35 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %38 =   OpLoad %float %35\n         %39 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %41 =   OpLoad %float %39\n         %44 =   OpSampledImage %43 %33 %34\n         %46 =   OpCompositeConstruct %v2float %38 %41\n         %45 =   OpImageQueryLod %v2float %44 %46\n         %47 =   OpCompositeExtract %float %45 0\n         %48 =   OpLoad %float %LOD_BIAS\n         %49 =   OpLoad %float %LOD_CLAMP\n         %52 =   OpCompositeConstruct %v2float %38 %41\n         %51 =   OpImageSampleImplicitLod %v4float %44 %52 None\n         %53 =   OpCompositeExtract %float %51 0\n         %54 =   OpCompositeExtract %float %51 1\n         %55 =   OpCompositeExtract %float %51 2\n         %56 =   OpCompositeExtract %float %51 3\n         %59 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %59 %53\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %61 %55\n         %63 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %63 %56\n         %69 =   OpCompositeConstruct %v2float %38 %41\n         %68 =   OpImageSampleImplicitLod %v4float %44 %69 ConstOffset %71\n         %72 =   OpCompositeExtract %float %68 0\n         %73 =   OpCompositeExtract %float %68 1\n         %74 =   OpCompositeExtract %float %68 2\n         %75 =   OpCompositeExtract %float %68 3\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %77 %72\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %78 %73\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %79 %74\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %80 %75\n         %82 =   OpCompositeConstruct %v2float %38 %41\n         %81 =   OpImageSampleExplicitLod %v4float %44 %82 Lod %47\n         %83 =   OpCompositeExtract %float %81 0\n         %84 =   OpCompositeExtract %float %81 1\n         %85 =   OpCompositeExtract %float %81 2\n         %86 =   OpCompositeExtract %float %81 3\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %88 %83\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %89 %84\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %91 %86\n         %93 =   OpCompositeConstruct %v2float %38 %41\n         %92 =   OpImageSampleImplicitLod %v4float %44 %93 Bias %48\n         %94 =   OpCompositeExtract %float %92 0\n         %95 =   OpCompositeExtract %float %92 1\n         %96 =   OpCompositeExtract %float %92 2\n         %97 =   OpCompositeExtract %float %92 3\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %99 %94\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %100 %95\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %101 %96\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %102 %97\n        %104 =   OpCompositeConstruct %v2float %38 %41\n        %103 =   OpImageSampleImplicitLod %v4float %44 %104 MinLod %49\n        %105 =   OpCompositeExtract %float %103 0\n        %106 =   OpCompositeExtract %float %103 1\n        %107 =   OpCompositeExtract %float %103 2\n        %108 =   OpCompositeExtract %float %103 3\n        %110 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %110 %105\n        %111 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %111 %106\n        %112 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %112 %107\n        %113 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %113 %108\n        %115 =   OpCompositeConstruct %v2float %38 %41\n        %114 =   OpImageSampleImplicitLod %v4float %44 %115 Bias|ConstOffset|MinLod %48 %71 %49\n        %116 =   OpCompositeExtract %float %114 0\n        %117 =   OpCompositeExtract %float %114 1\n        %118 =   OpCompositeExtract %float %114 2\n        %119 =   OpCompositeExtract %float %114 3\n        %121 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %121 %116\n        %122 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %122 %117\n        %123 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %123 %118\n        %124 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %124 %119\n        %125 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %126 =   OpLoad %float %125\n        %127 =   OpDPdx %float %126\n        %128 =   OpDPdy %float %126\n        %129 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %130 =   OpLoad %float %129\n        %131 =   OpDPdx %float %130\n        %132 =   OpDPdy %float %130\n        %136 =   OpCompositeConstruct %v2float %38 %41\n        %137 =   OpCompositeConstruct %v2float %127 %131\n        %138 =   OpCompositeConstruct %v2float %128 %132\n        %135 =   OpImageSampleExplicitLod %v4float %44 %136 Grad %137 %138\n        %139 =   OpCompositeExtract %float %135 0\n        %140 =   OpCompositeExtract %float %135 1\n        %141 =   OpCompositeExtract %float %135 2\n        %142 =   OpCompositeExtract %float %135 3\n        %144 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %144 %139\n        %145 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %145 %140\n        %146 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %146 %141\n        %147 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %147 %142\n        %149 =   OpCompositeConstruct %v2float %38 %41\n        %150 =   OpCompositeConstruct %v2float %127 %131\n        %151 =   OpCompositeConstruct %v2float %128 %132\n        %148 =   OpImageSampleExplicitLod %v4float %44 %149 Grad|ConstOffset %150 %151 %71\n        %152 =   OpCompositeExtract %float %148 0\n        %153 =   OpCompositeExtract %float %148 1\n        %154 =   OpCompositeExtract %float %148 2\n        %155 =   OpCompositeExtract %float %148 3\n        %157 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %157 %152\n        %158 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %158 %153\n        %159 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %159 %154\n        %160 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %160 %155\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    vec4 _51 = texture(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y));\n    SV_TARGET.x = _51.x;\n    SV_TARGET.y = _51.y;\n    SV_TARGET.z = _51.z;\n    SV_TARGET.w = _51.w;\n    vec4 _68 = textureOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(-1, 0));\n    SV_TARGET_1.x = _68.x;\n    SV_TARGET_1.y = _68.y;\n    SV_TARGET_1.z = _68.z;\n    SV_TARGET_1.w = _68.w;\n    vec4 _81 = textureLod(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), textureQueryLod(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y)).x);\n    SV_TARGET_2.x = _81.x;\n    SV_TARGET_2.y = _81.y;\n    SV_TARGET_2.z = _81.z;\n    SV_TARGET_2.w = _81.w;\n    vec4 _92 = texture(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), LOD_BIAS);\n    SV_TARGET_3.x = _92.x;\n    SV_TARGET_3.y = _92.y;\n    SV_TARGET_3.z = _92.z;\n    SV_TARGET_3.w = _92.w;\n    vec4 _103 = textureClampARB(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), LOD_CLAMP);\n    SV_TARGET_4.x = _103.x;\n    SV_TARGET_4.y = _103.y;\n    SV_TARGET_4.z = _103.z;\n    SV_TARGET_4.w = _103.w;\n    vec4 _114 = textureOffsetClampARB(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(-1, 0), LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _114.x;\n    SV_TARGET_5.y = _114.y;\n    SV_TARGET_5.z = _114.z;\n    SV_TARGET_5.w = _114.w;\n    float _127 = dFdx(TEXCOORD_2.x);\n    float _128 = dFdy(TEXCOORD_2.x);\n    float _131 = dFdx(TEXCOORD_2.y);\n    float _132 = dFdy(TEXCOORD_2.y);\n    vec4 _135 = textureGrad(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), vec2(_127, _131), vec2(_128, _132));\n    SV_TARGET_6.x = _135.x;\n    SV_TARGET_6.y = _135.y;\n    SV_TARGET_6.z = _135.z;\n    SV_TARGET_6.w = _135.w;\n    vec4 _148 = textureGradOffset(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), vec2(_127, _131), vec2(_128, _132), ivec2(-1, 0));\n    SV_TARGET_7.x = _148.x;\n    SV_TARGET_7.y = _148.y;\n    SV_TARGET_7.z = _148.z;\n    SV_TARGET_7.w = _148.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n         %40 = OpTypeImage %float 2D 1 0 0 1 Unknown\n         %41 = OpTypeSampledImage %40\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %55 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %62\n\n         %62 = OpLabel\n         %27 =   OpLoad %6 %8\n         %28 =   OpLoad %9 %11\n         %29 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %32 =   OpLoad %float %29\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %35 =   OpLoad %float %33\n         %37 =   OpLoad %float %DEPTH_REF\n         %42 =   OpSampledImage %41 %27 %28\n         %45 =   OpCompositeConstruct %v2float %32 %35\n         %44 =   OpImageSampleDrefImplicitLod %float %42 %45 %37 None\n         %47 =   OpCompositeConstruct %v4float %44 %44 %44 %44\n         %48 =   OpCompositeExtract %float %47 0\n                 OpStore %SV_TARGET %48\n         %53 =   OpCompositeConstruct %v2float %32 %35\n         %52 =   OpImageSampleDrefImplicitLod %float %42 %53 %37 ConstOffset %55\n         %56 =   OpCompositeConstruct %v4float %52 %52 %52 %52\n         %57 =   OpCompositeExtract %float %56 0\n                 OpStore %SV_TARGET_1 %57\n         %59 =   OpCompositeConstruct %v2float %32 %35\n         %58 =   OpImageSampleDrefExplicitLod %float %42 %59 %37 Lod %float_0\n         %60 =   OpCompositeConstruct %v4float %58 %58 %58 %58\n         %61 =   OpCompositeExtract %float %60 0\n                 OpStore %SV_TARGET_2 %61\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_2d_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\n\nvoid main()\n{\n    SV_TARGET = vec4(texture(sampler2DShadow(_8, _11), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DEPTH_REF))).x;\n    SV_TARGET_1 = vec4(textureOffset(sampler2DShadow(_8, _11), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DEPTH_REF), ivec2(-1, 0))).x;\n    SV_TARGET_2 = vec4(textureLod(sampler2DShadow(_8, _11), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DEPTH_REF), 0.0)).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_3d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 61\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %int_1 = OpConstant %int 1\n      %v3int = OpTypeVector %int 3\n         %49 = OpConstantComposite %v3int %int_n1 %int_0 %int_1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %59\n\n         %59 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %24 =   OpLoad %uint %22\n         %25 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %27 =   OpLoad %uint %25\n         %30 =   OpCompositeConstruct %v3uint %21 %24 %27\n         %29 =   OpImageFetch %v4float %17 %30 Lod %uint_1\n         %31 =   OpCompositeExtract %float %29 0\n         %32 =   OpCompositeExtract %float %29 1\n         %33 =   OpCompositeExtract %float %29 2\n         %34 =   OpCompositeExtract %float %29 3\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %39 %33\n         %40 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %40 %34\n         %47 =   OpCompositeConstruct %v3uint %21 %24 %27\n         %46 =   OpImageFetch %v4float %17 %47 Lod|ConstOffset %uint_1 %49\n         %50 =   OpCompositeExtract %float %46 0\n         %51 =   OpCompositeExtract %float %46 1\n         %52 =   OpCompositeExtract %float %46 2\n         %53 =   OpCompositeExtract %float %46 3\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %55 %50\n         %56 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %56 %51\n         %57 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %57 %52\n         %58 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %58 %53\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_3d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0) uniform texture3D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _29 = texelFetch(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(1u));\n    SV_TARGET.x = _29.x;\n    SV_TARGET.y = _29.y;\n    SV_TARGET.z = _29.z;\n    SV_TARGET.w = _29.w;\n    vec4 _46 = texelFetchOffset(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(1u), ivec3(-1, 0, 1));\n    SV_TARGET_1.x = _46.x;\n    SV_TARGET_1.y = _46.y;\n    SV_TARGET_1.z = _46.z;\n    SV_TARGET_1.w = _46.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_3d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Output_v3uint = OpTypePointer Output %v3uint\n  %SV_TARGET = OpVariable %_ptr_Output_v3uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n          %_ = OpTypeStruct %v3uint %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %31\n\n         %31 = OpLabel\n         %16 =   OpLoad %6 %8\n         %17 =   OpImageQuerySizeLod %v3uint %16 %uint_0\n         %19 =   OpCompositeExtract %uint %17 0\n         %20 =   OpCompositeExtract %uint %17 1\n         %21 =   OpCompositeExtract %uint %17 2\n         %22 =   OpCompositeConstruct %v3uint %19 %20 %21\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %26 %19\n         %27 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %27 %20\n         %28 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_2\n                 OpStore %28 %21\n                 OpStore %SV_TARGET_1 %uint_1\n         %30 =   OpImageQueryLevels %uint %16\n                 OpStore %SV_TARGET_2 %30\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_3d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _23\n{\n    uvec3 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture3D _8;\n\nlayout(location = 0) out uvec3 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uvec3 _17 = uvec3(textureSize(_8, int(0u)));\n    uint _19 = _17.x;\n    SV_TARGET.x = _19;\n    SV_TARGET.y = _17.y;\n    SV_TARGET.z = _17.z;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_3d_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 169\n; Schema: 0\n               OpCapability Shader\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %44 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %int_1 = OpConstant %int 1\n      %v3int = OpTypeVector %int 3\n         %73 = OpConstantComposite %v3int %int_n1 %int_0 %int_1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %167\n\n        %167 = OpLabel\n         %31 =   OpLoad %6 %8\n         %32 =   OpLoad %9 %11\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %36 =   OpLoad %float %33\n         %37 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %39 =   OpLoad %float %37\n         %40 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %42 =   OpLoad %float %40\n         %45 =   OpSampledImage %44 %31 %32\n         %48 =   OpCompositeConstruct %v3float %36 %39 %42\n         %47 =   OpImageQueryLod %v2float %45 %48\n         %49 =   OpCompositeExtract %float %47 0\n         %50 =   OpLoad %float %LOD_BIAS\n         %51 =   OpLoad %float %LOD_CLAMP\n         %54 =   OpCompositeConstruct %v3float %36 %39 %42\n         %53 =   OpImageSampleImplicitLod %v4float %45 %54 None\n         %55 =   OpCompositeExtract %float %53 0\n         %56 =   OpCompositeExtract %float %53 1\n         %57 =   OpCompositeExtract %float %53 2\n         %58 =   OpCompositeExtract %float %53 3\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %61 %55\n         %62 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %62 %56\n         %63 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %63 %57\n         %64 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %64 %58\n         %71 =   OpCompositeConstruct %v3float %36 %39 %42\n         %70 =   OpImageSampleImplicitLod %v4float %45 %71 ConstOffset %73\n         %74 =   OpCompositeExtract %float %70 0\n         %75 =   OpCompositeExtract %float %70 1\n         %76 =   OpCompositeExtract %float %70 2\n         %77 =   OpCompositeExtract %float %70 3\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %79 %74\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %80 %75\n         %81 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %81 %76\n         %82 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %82 %77\n         %84 =   OpCompositeConstruct %v3float %36 %39 %42\n         %83 =   OpImageSampleExplicitLod %v4float %45 %84 Lod %49\n         %85 =   OpCompositeExtract %float %83 0\n         %86 =   OpCompositeExtract %float %83 1\n         %87 =   OpCompositeExtract %float %83 2\n         %88 =   OpCompositeExtract %float %83 3\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %93 %88\n         %95 =   OpCompositeConstruct %v3float %36 %39 %42\n         %94 =   OpImageSampleImplicitLod %v4float %45 %95 Bias %50\n         %96 =   OpCompositeExtract %float %94 0\n         %97 =   OpCompositeExtract %float %94 1\n         %98 =   OpCompositeExtract %float %94 2\n         %99 =   OpCompositeExtract %float %94 3\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %101 %96\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %102 %97\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %103 %98\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %104 %99\n        %106 =   OpCompositeConstruct %v3float %36 %39 %42\n        %105 =   OpImageSampleImplicitLod %v4float %45 %106 MinLod %51\n        %107 =   OpCompositeExtract %float %105 0\n        %108 =   OpCompositeExtract %float %105 1\n        %109 =   OpCompositeExtract %float %105 2\n        %110 =   OpCompositeExtract %float %105 3\n        %112 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %112 %107\n        %113 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %113 %108\n        %114 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %114 %109\n        %115 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %115 %110\n        %117 =   OpCompositeConstruct %v3float %36 %39 %42\n        %116 =   OpImageSampleImplicitLod %v4float %45 %117 Bias|ConstOffset|MinLod %50 %73 %51\n        %118 =   OpCompositeExtract %float %116 0\n        %119 =   OpCompositeExtract %float %116 1\n        %120 =   OpCompositeExtract %float %116 2\n        %121 =   OpCompositeExtract %float %116 3\n        %123 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %123 %118\n        %124 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %124 %119\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %125 %120\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %126 %121\n        %127 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %128 =   OpLoad %float %127\n        %129 =   OpDPdx %float %128\n        %130 =   OpDPdy %float %128\n        %131 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %132 =   OpLoad %float %131\n        %133 =   OpDPdx %float %132\n        %134 =   OpDPdy %float %132\n        %135 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_2\n        %136 =   OpLoad %float %135\n        %137 =   OpDPdx %float %136\n        %138 =   OpDPdy %float %136\n        %142 =   OpCompositeConstruct %v3float %36 %39 %42\n        %143 =   OpCompositeConstruct %v3float %129 %133 %137\n        %144 =   OpCompositeConstruct %v3float %130 %134 %138\n        %141 =   OpImageSampleExplicitLod %v4float %45 %142 Grad %143 %144\n        %145 =   OpCompositeExtract %float %141 0\n        %146 =   OpCompositeExtract %float %141 1\n        %147 =   OpCompositeExtract %float %141 2\n        %148 =   OpCompositeExtract %float %141 3\n        %150 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %150 %145\n        %151 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %151 %146\n        %152 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %152 %147\n        %153 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %153 %148\n        %155 =   OpCompositeConstruct %v3float %36 %39 %42\n        %156 =   OpCompositeConstruct %v3float %129 %133 %137\n        %157 =   OpCompositeConstruct %v3float %130 %134 %138\n        %154 =   OpImageSampleExplicitLod %v4float %45 %155 Grad|ConstOffset %156 %157 %73\n        %158 =   OpCompositeExtract %float %154 0\n        %159 =   OpCompositeExtract %float %154 1\n        %160 =   OpCompositeExtract %float %154 2\n        %161 =   OpCompositeExtract %float %154 3\n        %163 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %163 %158\n        %164 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %164 %159\n        %165 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %165 %160\n        %166 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %166 %161\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_3d_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0) uniform texture3D _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    vec4 _53 = texture(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    SV_TARGET.x = _53.x;\n    SV_TARGET.y = _53.y;\n    SV_TARGET.z = _53.z;\n    SV_TARGET.w = _53.w;\n    vec4 _70 = textureOffset(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec3(-1, 0, 1));\n    SV_TARGET_1.x = _70.x;\n    SV_TARGET_1.y = _70.y;\n    SV_TARGET_1.z = _70.z;\n    SV_TARGET_1.w = _70.w;\n    vec4 _83 = textureLod(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), textureQueryLod(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x);\n    SV_TARGET_2.x = _83.x;\n    SV_TARGET_2.y = _83.y;\n    SV_TARGET_2.z = _83.z;\n    SV_TARGET_2.w = _83.w;\n    vec4 _94 = texture(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_BIAS);\n    SV_TARGET_3.x = _94.x;\n    SV_TARGET_3.y = _94.y;\n    SV_TARGET_3.z = _94.z;\n    SV_TARGET_3.w = _94.w;\n    vec4 _105 = textureClampARB(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_CLAMP);\n    SV_TARGET_4.x = _105.x;\n    SV_TARGET_4.y = _105.y;\n    SV_TARGET_4.z = _105.z;\n    SV_TARGET_4.w = _105.w;\n    vec4 _116 = textureOffsetClampARB(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec3(-1, 0, 1), LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _116.x;\n    SV_TARGET_5.y = _116.y;\n    SV_TARGET_5.z = _116.z;\n    SV_TARGET_5.w = _116.w;\n    float _129 = dFdx(TEXCOORD_2.x);\n    float _130 = dFdy(TEXCOORD_2.x);\n    float _133 = dFdx(TEXCOORD_2.y);\n    float _134 = dFdy(TEXCOORD_2.y);\n    float _137 = dFdx(TEXCOORD_2.z);\n    float _138 = dFdy(TEXCOORD_2.z);\n    vec4 _141 = textureGrad(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(_129, _133, _137), vec3(_130, _134, _138));\n    SV_TARGET_6.x = _141.x;\n    SV_TARGET_6.y = _141.y;\n    SV_TARGET_6.z = _141.z;\n    SV_TARGET_6.w = _141.w;\n    vec4 _154 = textureGradOffset(sampler3D(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(_129, _133, _137), vec3(_130, _134, _138), ivec3(-1, 0, 1));\n    SV_TARGET_7.x = _154.x;\n    SV_TARGET_7.y = _154.y;\n    SV_TARGET_7.z = _154.z;\n    SV_TARGET_7.w = _154.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 92\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledCubeArray\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %42 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %90\n\n         %90 = OpLabel\n         %28 =   OpLoad %6 %8\n         %29 =   OpLoad %9 %11\n         %30 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %33 =   OpLoad %float %30\n         %34 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %36 =   OpLoad %float %34\n         %37 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %39 =   OpLoad %float %37\n         %41 =   OpLoad %float %LAYER\n         %43 =   OpSampledImage %42 %28 %29\n         %44 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %45 =   OpImageGather %v4float %43 %44 %uint_0\n         %46 =   OpCompositeExtract %float %45 0\n         %47 =   OpCompositeExtract %float %45 1\n         %48 =   OpCompositeExtract %float %45 2\n         %49 =   OpCompositeExtract %float %45 3\n         %52 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %52 %46\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %53 %47\n         %54 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %54 %48\n         %55 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %55 %49\n         %57 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %58 =   OpImageGather %v4float %43 %57 %uint_1\n         %59 =   OpCompositeExtract %float %58 0\n         %60 =   OpCompositeExtract %float %58 1\n         %61 =   OpCompositeExtract %float %58 2\n         %62 =   OpCompositeExtract %float %58 3\n         %64 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %64 %59\n         %65 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %65 %60\n         %66 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %66 %61\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %67 %62\n         %68 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %69 =   OpImageGather %v4float %43 %68 %uint_2\n         %70 =   OpCompositeExtract %float %69 0\n         %71 =   OpCompositeExtract %float %69 1\n         %72 =   OpCompositeExtract %float %69 2\n         %73 =   OpCompositeExtract %float %69 3\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %75 %70\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %76 %71\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %77 %72\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %78 %73\n         %79 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %80 =   OpImageGather %v4float %43 %79 %uint_3\n         %81 =   OpCompositeExtract %float %80 0\n         %82 =   OpCompositeExtract %float %80 1\n         %83 =   OpCompositeExtract %float %80 2\n         %84 =   OpCompositeExtract %float %80 3\n         %86 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %86 %81\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %88 %83\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %89 %84\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_gather.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\n\nvoid main()\n{\n    vec4 _45 = textureGather(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER));\n    SV_TARGET.x = _45.x;\n    SV_TARGET.y = _45.y;\n    SV_TARGET.z = _45.z;\n    SV_TARGET.w = _45.w;\n    vec4 _58 = textureGather(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), int(1u));\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    SV_TARGET_1.z = _58.z;\n    SV_TARGET_1.w = _58.w;\n    vec4 _69 = textureGather(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), int(2u));\n    SV_TARGET_2.x = _69.x;\n    SV_TARGET_2.y = _69.y;\n    SV_TARGET_2.z = _69.z;\n    SV_TARGET_2.w = _69.w;\n    vec4 _80 = textureGather(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), int(3u));\n    SV_TARGET_3.x = _80.x;\n    SV_TARGET_3.y = _80.y;\n    SV_TARGET_3.z = _80.z;\n    SV_TARGET_3.w = _80.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 58\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledCubeArray\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %40 = OpTypeImage %float Cube 1 1 0 1 Unknown\n         %41 = OpTypeSampledImage %40\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %56\n\n         %56 = OpLabel\n         %25 =   OpLoad %6 %8\n         %26 =   OpLoad %9 %11\n         %27 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %30 =   OpLoad %float %27\n         %31 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %33 =   OpLoad %float %31\n         %34 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %36 =   OpLoad %float %34\n         %38 =   OpLoad %float %DEPTH_REF\n         %39 =   OpLoad %float %LAYER\n         %42 =   OpSampledImage %41 %25 %26\n         %43 =   OpCompositeConstruct %v4float %30 %33 %36 %39\n         %44 =   OpImageDrefGather %v4float %42 %43 %38\n         %45 =   OpCompositeExtract %float %44 0\n         %46 =   OpCompositeExtract %float %44 1\n         %47 =   OpCompositeExtract %float %44 2\n         %48 =   OpCompositeExtract %float %44 3\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %51 %45\n         %52 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %52 %46\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %53 %47\n         %54 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %54 %48\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _43 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER);\n    vec4 _44 = textureGather(samplerCubeArrayShadow(_8, _11), _43, DEPTH_REF);\n    SV_TARGET.x = _44.x;\n    SV_TARGET.y = _44.y;\n    SV_TARGET.z = _44.z;\n    SV_TARGET.w = _44.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 32\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledCubeArray\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %v3uint = OpTypeVector %uint 3\n     %uint_0 = OpConstant %uint 0\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %30\n\n         %30 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpImageQuerySizeLod %v3uint %16 %uint_0\n         %20 =   OpCompositeExtract %uint %18 0\n         %21 =   OpCompositeExtract %uint %18 1\n         %22 =   OpCompositeConstruct %v2uint %20 %21\n         %23 =   OpCompositeExtract %uint %18 2\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %26 %20\n         %27 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %27 %21\n                 OpStore %SV_TARGET_1 %23\n         %29 =   OpImageQueryLevels %uint %16\n                 OpStore %SV_TARGET_2 %29\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _24\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uvec3 _18 = uvec3(textureSize(_8, int(0u)));\n    uint _20 = _18.x;\n    SV_TARGET.x = _20;\n    SV_TARGET.y = _18.y;\n    SV_TARGET_1 = _18.z;\n    SV_TARGET_2 = uint(textureQueryLevels(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 126\n; Schema: 0\n               OpCapability Shader\n               OpCapability MinLod\n               OpCapability SampledCubeArray\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %42 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %124\n\n        %124 = OpLabel\n         %28 =   OpLoad %6 %8\n         %29 =   OpLoad %9 %11\n         %30 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %33 =   OpLoad %float %30\n         %34 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %36 =   OpLoad %float %34\n         %37 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %39 =   OpLoad %float %37\n         %41 =   OpLoad %float %LAYER\n         %43 =   OpSampledImage %42 %28 %29\n         %46 =   OpCompositeConstruct %v3float %33 %36 %39\n         %45 =   OpImageQueryLod %v2float %43 %46\n         %47 =   OpCompositeExtract %float %45 0\n         %48 =   OpLoad %float %LOD_BIAS\n         %49 =   OpLoad %float %LOD_CLAMP\n         %52 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %51 =   OpImageSampleImplicitLod %v4float %43 %52 None\n         %53 =   OpCompositeExtract %float %51 0\n         %54 =   OpCompositeExtract %float %51 1\n         %55 =   OpCompositeExtract %float %51 2\n         %56 =   OpCompositeExtract %float %51 3\n         %59 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %59 %53\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %61 %55\n         %62 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %62 %56\n         %65 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %64 =   OpImageSampleExplicitLod %v4float %43 %65 Lod %47\n         %66 =   OpCompositeExtract %float %64 0\n         %67 =   OpCompositeExtract %float %64 1\n         %68 =   OpCompositeExtract %float %64 2\n         %69 =   OpCompositeExtract %float %64 3\n         %71 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %71 %66\n         %72 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %72 %67\n         %73 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %73 %68\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %74 %69\n         %76 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %75 =   OpImageSampleImplicitLod %v4float %43 %76 Bias %48\n         %77 =   OpCompositeExtract %float %75 0\n         %78 =   OpCompositeExtract %float %75 1\n         %79 =   OpCompositeExtract %float %75 2\n         %80 =   OpCompositeExtract %float %75 3\n         %82 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %82 %77\n         %83 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %83 %78\n         %84 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %84 %79\n         %85 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %85 %80\n         %87 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n         %86 =   OpImageSampleImplicitLod %v4float %43 %87 MinLod %49\n         %88 =   OpCompositeExtract %float %86 0\n         %89 =   OpCompositeExtract %float %86 1\n         %90 =   OpCompositeExtract %float %86 2\n         %91 =   OpCompositeExtract %float %86 3\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %95 %90\n         %96 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %96 %91\n         %97 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n         %98 =   OpLoad %float %97\n         %99 =   OpDPdx %float %98\n        %100 =   OpDPdy %float %98\n        %101 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %102 =   OpLoad %float %101\n        %103 =   OpDPdx %float %102\n        %104 =   OpDPdy %float %102\n        %105 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_2\n        %106 =   OpLoad %float %105\n        %107 =   OpDPdx %float %106\n        %108 =   OpDPdy %float %106\n        %112 =   OpCompositeConstruct %v4float %33 %36 %39 %41\n        %113 =   OpCompositeConstruct %v3float %99 %103 %107\n        %114 =   OpCompositeConstruct %v3float %100 %104 %108\n        %111 =   OpImageSampleExplicitLod %v4float %43 %112 Grad %113 %114\n        %115 =   OpCompositeExtract %float %111 0\n        %116 =   OpCompositeExtract %float %111 1\n        %117 =   OpCompositeExtract %float %111 2\n        %118 =   OpCompositeExtract %float %111 3\n        %120 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %120 %115\n        %121 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %121 %116\n        %122 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %122 %117\n        %123 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %123 %118\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\n\nvoid main()\n{\n    vec4 _51 = texture(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER));\n    SV_TARGET.x = _51.x;\n    SV_TARGET.y = _51.y;\n    SV_TARGET.z = _51.z;\n    SV_TARGET.w = _51.w;\n    vec4 _64 = textureLod(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), textureQueryLod(samplerCubeArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x);\n    SV_TARGET_1.x = _64.x;\n    SV_TARGET_1.y = _64.y;\n    SV_TARGET_1.z = _64.z;\n    SV_TARGET_1.w = _64.w;\n    vec4 _75 = texture(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), LOD_BIAS);\n    SV_TARGET_2.x = _75.x;\n    SV_TARGET_2.y = _75.y;\n    SV_TARGET_2.z = _75.z;\n    SV_TARGET_2.w = _75.w;\n    vec4 _86 = textureClampARB(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), LOD_CLAMP);\n    SV_TARGET_3.x = _86.x;\n    SV_TARGET_3.y = _86.y;\n    SV_TARGET_3.z = _86.z;\n    SV_TARGET_3.w = _86.w;\n    vec4 _111 = textureGrad(samplerCubeArray(_8, _11), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), vec3(dFdx(TEXCOORD_2.x), dFdx(TEXCOORD_2.y), dFdx(TEXCOORD_2.z)), vec3(dFdy(TEXCOORD_2.x), dFdy(TEXCOORD_2.y), dFdy(TEXCOORD_2.z)));\n    SV_TARGET_4.x = _111.x;\n    SV_TARGET_4.y = _111.y;\n    SV_TARGET_4.z = _111.z;\n    SV_TARGET_4.w = _111.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 56\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledCubeArray\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %41 = OpTypeImage %float Cube 1 1 0 1 Unknown\n         %42 = OpTypeSampledImage %41\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %54\n\n         %54 = OpLabel\n         %24 =   OpLoad %6 %8\n         %25 =   OpLoad %9 %11\n         %26 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %29 =   OpLoad %float %26\n         %30 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %32 =   OpLoad %float %30\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %35 =   OpLoad %float %33\n         %37 =   OpLoad %float %DEPTH_REF\n         %38 =   OpLoad %float %LAYER\n         %43 =   OpSampledImage %42 %24 %25\n         %47 =   OpCompositeConstruct %v4float %29 %32 %35 %38\n         %45 =   OpImageSampleDrefImplicitLod %float %43 %47 %37 None\n         %48 =   OpCompositeConstruct %v4float %45 %45 %45 %45\n         %49 =   OpCompositeExtract %float %48 0\n                 OpStore %SV_TARGET %49\n         %51 =   OpCompositeConstruct %v4float %29 %32 %35 %38\n         %50 =   OpImageSampleDrefExplicitLod %float %43 %51 %37 Lod %float_0\n         %52 =   OpCompositeConstruct %v4float %50 %50 %50 %50\n         %53 =   OpCompositeExtract %float %52 0\n                 OpStore %SV_TARGET_1 %53\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_array_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _47 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER);\n    SV_TARGET = vec4(texture(samplerCubeArrayShadow(_8, _11), _47, DEPTH_REF)).x;\n    vec4 _51 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER);\n    SV_TARGET_1 = vec4(textureGrad(samplerCubeArrayShadow(_8, _11), _51, DEPTH_REF, vec3(0.0), vec3(0.0))).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %41 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %89\n\n         %89 = OpLabel\n         %28 =   OpLoad %6 %8\n         %29 =   OpLoad %9 %11\n         %30 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %33 =   OpLoad %float %30\n         %34 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %36 =   OpLoad %float %34\n         %37 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %39 =   OpLoad %float %37\n         %42 =   OpSampledImage %41 %28 %29\n         %43 =   OpCompositeConstruct %v3float %33 %36 %39\n         %44 =   OpImageGather %v4float %42 %43 %uint_0\n         %45 =   OpCompositeExtract %float %44 0\n         %46 =   OpCompositeExtract %float %44 1\n         %47 =   OpCompositeExtract %float %44 2\n         %48 =   OpCompositeExtract %float %44 3\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %51 %45\n         %52 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %52 %46\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %53 %47\n         %54 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %54 %48\n         %56 =   OpCompositeConstruct %v3float %33 %36 %39\n         %57 =   OpImageGather %v4float %42 %56 %uint_1\n         %58 =   OpCompositeExtract %float %57 0\n         %59 =   OpCompositeExtract %float %57 1\n         %60 =   OpCompositeExtract %float %57 2\n         %61 =   OpCompositeExtract %float %57 3\n         %63 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %63 %58\n         %64 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %64 %59\n         %65 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %65 %60\n         %66 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %66 %61\n         %67 =   OpCompositeConstruct %v3float %33 %36 %39\n         %68 =   OpImageGather %v4float %42 %67 %uint_2\n         %69 =   OpCompositeExtract %float %68 0\n         %70 =   OpCompositeExtract %float %68 1\n         %71 =   OpCompositeExtract %float %68 2\n         %72 =   OpCompositeExtract %float %68 3\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %74 %69\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %75 %70\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %76 %71\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %77 %72\n         %78 =   OpCompositeConstruct %v3float %33 %36 %39\n         %79 =   OpImageGather %v4float %42 %78 %uint_3\n         %80 =   OpCompositeExtract %float %79 0\n         %81 =   OpCompositeExtract %float %79 1\n         %82 =   OpCompositeExtract %float %79 2\n         %83 =   OpCompositeExtract %float %79 3\n         %85 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %85 %80\n         %86 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %86 %81\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %88 %83\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_gather.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform textureCube _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\n\nvoid main()\n{\n    vec4 _44 = textureGather(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    SV_TARGET.x = _44.x;\n    SV_TARGET.y = _44.y;\n    SV_TARGET.z = _44.z;\n    SV_TARGET.w = _44.w;\n    vec4 _57 = textureGather(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(1u));\n    SV_TARGET_1.x = _57.x;\n    SV_TARGET_1.y = _57.y;\n    SV_TARGET_1.z = _57.z;\n    SV_TARGET_1.w = _57.w;\n    vec4 _68 = textureGather(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(2u));\n    SV_TARGET_2.x = _68.x;\n    SV_TARGET_2.y = _68.y;\n    SV_TARGET_2.z = _68.z;\n    SV_TARGET_2.w = _68.w;\n    vec4 _79 = textureGather(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(3u));\n    SV_TARGET_3.x = _79.x;\n    SV_TARGET_3.y = _79.y;\n    SV_TARGET_3.z = _79.z;\n    SV_TARGET_3.w = _79.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 57\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %39 = OpTypeImage %float Cube 1 0 0 1 Unknown\n         %40 = OpTypeSampledImage %39\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %55\n\n         %55 = OpLabel\n         %25 =   OpLoad %6 %8\n         %26 =   OpLoad %9 %11\n         %27 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %30 =   OpLoad %float %27\n         %31 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %33 =   OpLoad %float %31\n         %34 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %36 =   OpLoad %float %34\n         %38 =   OpLoad %float %DEPTH_REF\n         %41 =   OpSampledImage %40 %25 %26\n         %42 =   OpCompositeConstruct %v3float %30 %33 %36\n         %43 =   OpImageDrefGather %v4float %41 %42 %38\n         %44 =   OpCompositeExtract %float %43 0\n         %45 =   OpCompositeExtract %float %43 1\n         %46 =   OpCompositeExtract %float %43 2\n         %47 =   OpCompositeExtract %float %43 3\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %50 %44\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %51 %45\n         %52 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %52 %46\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %53 %47\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform textureCube _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec3 _42 = vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z);\n    vec4 _43 = textureGather(samplerCubeShadow(_8, _11), _42, DEPTH_REF);\n    SV_TARGET.x = _43.x;\n    SV_TARGET.y = _43.y;\n    SV_TARGET.z = _43.z;\n    SV_TARGET.w = _43.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %28\n\n         %28 = OpLabel\n         %16 =   OpLoad %6 %8\n         %17 =   OpImageQuerySizeLod %v2uint %16 %uint_0\n         %19 =   OpCompositeExtract %uint %17 0\n         %20 =   OpCompositeExtract %uint %17 1\n         %21 =   OpCompositeConstruct %v2uint %19 %20\n         %25 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %25 %19\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %26 %20\n                 OpStore %SV_TARGET_1 %uint_1\n         %27 =   OpImageQueryLevels %uint %16\n                 OpStore %SV_TARGET_2 %27\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _22\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform textureCube _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uvec2 _17 = uvec2(textureSize(_8, int(0u)));\n    uint _19 = _17.x;\n    SV_TARGET.x = _19;\n    SV_TARGET.y = _17.y;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 125\n; Schema: 0\n               OpCapability Shader\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %41 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %123\n\n        %123 = OpLabel\n         %28 =   OpLoad %6 %8\n         %29 =   OpLoad %9 %11\n         %30 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %33 =   OpLoad %float %30\n         %34 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %36 =   OpLoad %float %34\n         %37 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %39 =   OpLoad %float %37\n         %42 =   OpSampledImage %41 %28 %29\n         %45 =   OpCompositeConstruct %v3float %33 %36 %39\n         %44 =   OpImageQueryLod %v2float %42 %45\n         %46 =   OpCompositeExtract %float %44 0\n         %47 =   OpLoad %float %LOD_BIAS\n         %48 =   OpLoad %float %LOD_CLAMP\n         %51 =   OpCompositeConstruct %v3float %33 %36 %39\n         %50 =   OpImageSampleImplicitLod %v4float %42 %51 None\n         %52 =   OpCompositeExtract %float %50 0\n         %53 =   OpCompositeExtract %float %50 1\n         %54 =   OpCompositeExtract %float %50 2\n         %55 =   OpCompositeExtract %float %50 3\n         %58 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %58 %52\n         %59 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %59 %53\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %60 %54\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %61 %55\n         %64 =   OpCompositeConstruct %v3float %33 %36 %39\n         %63 =   OpImageSampleExplicitLod %v4float %42 %64 Lod %46\n         %65 =   OpCompositeExtract %float %63 0\n         %66 =   OpCompositeExtract %float %63 1\n         %67 =   OpCompositeExtract %float %63 2\n         %68 =   OpCompositeExtract %float %63 3\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %70 %65\n         %71 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %71 %66\n         %72 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %72 %67\n         %73 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %73 %68\n         %75 =   OpCompositeConstruct %v3float %33 %36 %39\n         %74 =   OpImageSampleImplicitLod %v4float %42 %75 Bias %47\n         %76 =   OpCompositeExtract %float %74 0\n         %77 =   OpCompositeExtract %float %74 1\n         %78 =   OpCompositeExtract %float %74 2\n         %79 =   OpCompositeExtract %float %74 3\n         %81 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %81 %76\n         %82 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %82 %77\n         %83 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %83 %78\n         %84 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %84 %79\n         %86 =   OpCompositeConstruct %v3float %33 %36 %39\n         %85 =   OpImageSampleImplicitLod %v4float %42 %86 MinLod %48\n         %87 =   OpCompositeExtract %float %85 0\n         %88 =   OpCompositeExtract %float %85 1\n         %89 =   OpCompositeExtract %float %85 2\n         %90 =   OpCompositeExtract %float %85 3\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %95 %90\n         %96 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n         %97 =   OpLoad %float %96\n         %98 =   OpDPdx %float %97\n         %99 =   OpDPdy %float %97\n        %100 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %101 =   OpLoad %float %100\n        %102 =   OpDPdx %float %101\n        %103 =   OpDPdy %float %101\n        %104 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_2\n        %105 =   OpLoad %float %104\n        %106 =   OpDPdx %float %105\n        %107 =   OpDPdy %float %105\n        %111 =   OpCompositeConstruct %v3float %33 %36 %39\n        %112 =   OpCompositeConstruct %v3float %98 %102 %106\n        %113 =   OpCompositeConstruct %v3float %99 %103 %107\n        %110 =   OpImageSampleExplicitLod %v4float %42 %111 Grad %112 %113\n        %114 =   OpCompositeExtract %float %110 0\n        %115 =   OpCompositeExtract %float %110 1\n        %116 =   OpCompositeExtract %float %110 2\n        %117 =   OpCompositeExtract %float %110 3\n        %119 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %119 %114\n        %120 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %120 %115\n        %121 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %121 %116\n        %122 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %122 %117\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0) uniform textureCube _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\n\nvoid main()\n{\n    vec4 _50 = texture(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    SV_TARGET.x = _50.x;\n    SV_TARGET.y = _50.y;\n    SV_TARGET.z = _50.z;\n    SV_TARGET.w = _50.w;\n    vec4 _63 = textureLod(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), textureQueryLod(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x);\n    SV_TARGET_1.x = _63.x;\n    SV_TARGET_1.y = _63.y;\n    SV_TARGET_1.z = _63.z;\n    SV_TARGET_1.w = _63.w;\n    vec4 _74 = texture(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_BIAS);\n    SV_TARGET_2.x = _74.x;\n    SV_TARGET_2.y = _74.y;\n    SV_TARGET_2.z = _74.z;\n    SV_TARGET_2.w = _74.w;\n    vec4 _85 = textureClampARB(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_CLAMP);\n    SV_TARGET_3.x = _85.x;\n    SV_TARGET_3.y = _85.y;\n    SV_TARGET_3.z = _85.z;\n    SV_TARGET_3.w = _85.w;\n    vec4 _110 = textureGrad(samplerCube(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(dFdx(TEXCOORD_2.x), dFdx(TEXCOORD_2.y), dFdx(TEXCOORD_2.z)), vec3(dFdy(TEXCOORD_2.x), dFdy(TEXCOORD_2.y), dFdy(TEXCOORD_2.z)));\n    SV_TARGET_4.x = _110.x;\n    SV_TARGET_4.y = _110.y;\n    SV_TARGET_4.z = _110.z;\n    SV_TARGET_4.w = _110.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %40 = OpTypeImage %float Cube 1 0 0 1 Unknown\n         %41 = OpTypeSampledImage %40\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %53\n\n         %53 = OpLabel\n         %24 =   OpLoad %6 %8\n         %25 =   OpLoad %9 %11\n         %26 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %29 =   OpLoad %float %26\n         %30 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %32 =   OpLoad %float %30\n         %33 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %35 =   OpLoad %float %33\n         %37 =   OpLoad %float %DEPTH_REF\n         %42 =   OpSampledImage %41 %24 %25\n         %45 =   OpCompositeConstruct %v3float %29 %32 %35\n         %44 =   OpImageSampleDrefImplicitLod %float %42 %45 %37 None\n         %47 =   OpCompositeConstruct %v4float %44 %44 %44 %44\n         %48 =   OpCompositeExtract %float %47 0\n                 OpStore %SV_TARGET %48\n         %50 =   OpCompositeConstruct %v3float %29 %32 %35\n         %49 =   OpImageSampleDrefExplicitLod %float %42 %50 %37 Lod %float_0\n         %51 =   OpCompositeConstruct %v4float %49 %49 %49 %49\n         %52 =   OpCompositeExtract %float %51 0\n                 OpStore %SV_TARGET_1 %52\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_cube_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform textureCube _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    SV_TARGET = vec4(texture(samplerCubeShadow(_8, _11), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DEPTH_REF))).x;\n    SV_TARGET_1 = vec4(textureGrad(samplerCubeShadow(_8, _11), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DEPTH_REF), vec3(0.0), vec3(0.0))).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_gather_depth_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 136\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SparseResidency\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %51 = OpTypeImage %float 2D 1 0 0 1 Unknown\n         %52 = OpTypeSampledImage %51\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %v4float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n    %float_0 = OpConstant %float 0\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %88 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %134\n\n        %134 = OpLabel\n         %30 =   OpLoad %6 %8\n         %31 =   OpLoad %9 %11\n         %32 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %35 =   OpLoad %float %32\n         %36 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %38 =   OpLoad %float %36\n         %41 =   OpLoad %float %DEPTH_REF\n         %43 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %44 =   OpLoad %int %43\n         %45 =   OpBitcast %uint %44\n         %46 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %47 =   OpLoad %int %46\n         %48 =   OpBitcast %uint %47\n         %53 =   OpSampledImage %52 %30 %31\n         %54 =   OpCompositeConstruct %v2float %35 %38\n         %56 =   OpImageSparseDrefGather %SparseTexel %53 %54 %41\n         %57 =   OpCompositeExtract %uint %56 0\n         %58 =   OpCompositeExtract %v4float %56 1\n         %59 =   OpCompositeExtract %float %58 0\n         %60 =   OpCompositeExtract %float %58 1\n         %61 =   OpCompositeExtract %float %58 2\n         %62 =   OpCompositeExtract %float %58 3\n         %64 =   OpCompositeConstruct %_ %59 %60 %61 %62 %57\n         %65 =   OpCompositeExtract %uint %64 4\n         %66 =   OpCompositeExtract %float %64 0\n         %67 =   OpCompositeExtract %float %64 1\n         %68 =   OpCompositeExtract %float %64 2\n         %69 =   OpCompositeExtract %float %64 3\n         %70 =   OpCompositeConstruct %v4float %66 %67 %68 %69\n         %73 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %73 %66\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %74 %67\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %75 %68\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %77 %69\n         %80 =   OpImageSparseTexelsResident %bool %65\n         %81 =   OpSelect %float %80 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %81\n         %84 =   OpCompositeConstruct %v2float %35 %38\n         %87 =   OpImageSparseDrefGather %SparseTexel %53 %84 %41 ConstOffset %88\n         %89 =   OpCompositeExtract %uint %87 0\n         %90 =   OpCompositeExtract %v4float %87 1\n         %91 =   OpCompositeExtract %float %90 0\n         %92 =   OpCompositeExtract %float %90 1\n         %93 =   OpCompositeExtract %float %90 2\n         %94 =   OpCompositeExtract %float %90 3\n         %95 =   OpCompositeConstruct %_ %91 %92 %93 %94 %89\n         %96 =   OpCompositeExtract %uint %95 4\n         %97 =   OpCompositeExtract %float %95 0\n         %98 =   OpCompositeExtract %float %95 1\n         %99 =   OpCompositeExtract %float %95 2\n        %100 =   OpCompositeExtract %float %95 3\n        %101 =   OpCompositeConstruct %v4float %97 %98 %99 %100\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %103 %97\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %104 %98\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %105 %99\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %106 %100\n        %107 =   OpImageSparseTexelsResident %bool %96\n        %108 =   OpSelect %float %107 %float_1 %float_0\n                 OpStore %SV_TARGET_3 %108\n        %109 =   OpCompositeConstruct %v2float %35 %38\n        %110 =   OpBitcast %int %45\n        %111 =   OpBitcast %int %48\n        %113 =   OpCompositeConstruct %v2int %110 %111\n        %112 =   OpImageSparseDrefGather %SparseTexel %53 %109 %41 Offset %113\n        %114 =   OpCompositeExtract %uint %112 0\n        %115 =   OpCompositeExtract %v4float %112 1\n        %116 =   OpCompositeExtract %float %115 0\n        %117 =   OpCompositeExtract %float %115 1\n        %118 =   OpCompositeExtract %float %115 2\n        %119 =   OpCompositeExtract %float %115 3\n        %120 =   OpCompositeConstruct %_ %116 %117 %118 %119 %114\n        %121 =   OpCompositeExtract %uint %120 4\n        %122 =   OpCompositeExtract %float %120 0\n        %123 =   OpCompositeExtract %float %120 1\n        %124 =   OpCompositeExtract %float %120 2\n        %125 =   OpCompositeExtract %float %120 3\n        %126 =   OpCompositeConstruct %v4float %122 %123 %124 %125\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %128 %122\n        %129 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %129 %123\n        %130 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %130 %124\n        %131 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %131 %125\n        %132 =   OpImageSparseTexelsResident %bool %121\n        %133 =   OpSelect %float %132 %float_1 %float_0\n                 OpStore %SV_TARGET_5 %133\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_gather_depth_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _63\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _71\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform samplerShadow _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out float SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out float SV_TARGET_5;\n\nvoid main()\n{\n    vec2 _54 = vec2(TEXCOORD.x, TEXCOORD.y);\n    uint _136;\n    vec4 _137;\n    _136 = sparseTextureGatherARB(sampler2DShadow(_8, _11), _54, DEPTH_REF, _137);\n    SparseTexel _56 = SparseTexel(_136, _137);\n    vec4 _58 = _56._m1;\n    _63 _64 = _63(_58.x, _58.y, _58.z, _58.w, _56._m0);\n    float _66 = _64._m0;\n    float _67 = _64._m1;\n    float _68 = _64._m2;\n    float _69 = _64._m3;\n    SV_TARGET.x = _66;\n    SV_TARGET.y = _67;\n    SV_TARGET.z = _68;\n    SV_TARGET.w = _69;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_64._m4)));\n    vec2 _84 = vec2(TEXCOORD.x, TEXCOORD.y);\n    uint _138;\n    vec4 _139;\n    _138 = sparseTextureGatherOffsetARB(sampler2DShadow(_8, _11), _84, DEPTH_REF, ivec2(-1, 0), _139);\n    SparseTexel _87 = SparseTexel(_138, _139);\n    vec4 _90 = _87._m1;\n    _63 _95 = _63(_90.x, _90.y, _90.z, _90.w, _87._m0);\n    float _97 = _95._m0;\n    float _98 = _95._m1;\n    float _99 = _95._m2;\n    float _100 = _95._m3;\n    SV_TARGET_2.x = _97;\n    SV_TARGET_2.y = _98;\n    SV_TARGET_2.z = _99;\n    SV_TARGET_2.w = _100;\n    SV_TARGET_3 = float(sparseTexelsResidentARB(int(_95._m4)));\n    vec2 _109 = vec2(TEXCOORD.x, TEXCOORD.y);\n    uint _140;\n    vec4 _141;\n    _140 = sparseTextureGatherOffsetARB(sampler2DShadow(_8, _11), _109, DEPTH_REF, ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))), _141);\n    SparseTexel _112 = SparseTexel(_140, _141);\n    vec4 _115 = _112._m1;\n    _63 _120 = _63(_115.x, _115.y, _115.z, _115.w, _112._m0);\n    float _122 = _120._m0;\n    float _123 = _120._m1;\n    float _124 = _120._m2;\n    float _125 = _120._m3;\n    SV_TARGET_4.x = _122;\n    SV_TARGET_4.y = _123;\n    SV_TARGET_4.z = _124;\n    SV_TARGET_4.w = _125;\n    SV_TARGET_5 = float(sparseTexelsResidentARB(int(_120._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_gather_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 134\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SparseResidency\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %50 = OpTypeSampledImage %6\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %v4float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n    %float_0 = OpConstant %float 0\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %86 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %132\n\n        %132 = OpLabel\n         %30 =   OpLoad %6 %8\n         %31 =   OpLoad %9 %11\n         %32 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %35 =   OpLoad %float %32\n         %36 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %38 =   OpLoad %float %36\n         %42 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %43 =   OpLoad %int %42\n         %44 =   OpBitcast %uint %43\n         %45 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %46 =   OpLoad %int %45\n         %47 =   OpBitcast %uint %46\n         %51 =   OpSampledImage %50 %30 %31\n         %52 =   OpCompositeConstruct %v2float %35 %38\n         %54 =   OpImageSparseGather %SparseTexel %51 %52 %uint_0\n         %55 =   OpCompositeExtract %uint %54 0\n         %56 =   OpCompositeExtract %v4float %54 1\n         %57 =   OpCompositeExtract %float %56 0\n         %58 =   OpCompositeExtract %float %56 1\n         %59 =   OpCompositeExtract %float %56 2\n         %60 =   OpCompositeExtract %float %56 3\n         %62 =   OpCompositeConstruct %_ %57 %58 %59 %60 %55\n         %63 =   OpCompositeExtract %uint %62 4\n         %64 =   OpCompositeExtract %float %62 0\n         %65 =   OpCompositeExtract %float %62 1\n         %66 =   OpCompositeExtract %float %62 2\n         %67 =   OpCompositeExtract %float %62 3\n         %68 =   OpCompositeConstruct %v4float %64 %65 %66 %67\n         %71 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %71 %64\n         %72 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %72 %65\n         %73 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %73 %66\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %75 %67\n         %78 =   OpImageSparseTexelsResident %bool %63\n         %79 =   OpSelect %float %78 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %79\n         %82 =   OpCompositeConstruct %v2float %35 %38\n         %85 =   OpImageSparseGather %SparseTexel %51 %82 %uint_0 ConstOffset %86\n         %87 =   OpCompositeExtract %uint %85 0\n         %88 =   OpCompositeExtract %v4float %85 1\n         %89 =   OpCompositeExtract %float %88 0\n         %90 =   OpCompositeExtract %float %88 1\n         %91 =   OpCompositeExtract %float %88 2\n         %92 =   OpCompositeExtract %float %88 3\n         %93 =   OpCompositeConstruct %_ %89 %90 %91 %92 %87\n         %94 =   OpCompositeExtract %uint %93 4\n         %95 =   OpCompositeExtract %float %93 0\n         %96 =   OpCompositeExtract %float %93 1\n         %97 =   OpCompositeExtract %float %93 2\n         %98 =   OpCompositeExtract %float %93 3\n         %99 =   OpCompositeConstruct %v4float %95 %96 %97 %98\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %101 %95\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %102 %96\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %103 %97\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %104 %98\n        %105 =   OpImageSparseTexelsResident %bool %94\n        %106 =   OpSelect %float %105 %float_1 %float_0\n                 OpStore %SV_TARGET_3 %106\n        %107 =   OpCompositeConstruct %v2float %35 %38\n        %108 =   OpBitcast %int %44\n        %109 =   OpBitcast %int %47\n        %111 =   OpCompositeConstruct %v2int %108 %109\n        %110 =   OpImageSparseGather %SparseTexel %51 %107 %uint_0 Offset %111\n        %112 =   OpCompositeExtract %uint %110 0\n        %113 =   OpCompositeExtract %v4float %110 1\n        %114 =   OpCompositeExtract %float %113 0\n        %115 =   OpCompositeExtract %float %113 1\n        %116 =   OpCompositeExtract %float %113 2\n        %117 =   OpCompositeExtract %float %113 3\n        %118 =   OpCompositeConstruct %_ %114 %115 %116 %117 %112\n        %119 =   OpCompositeExtract %uint %118 4\n        %120 =   OpCompositeExtract %float %118 0\n        %121 =   OpCompositeExtract %float %118 1\n        %122 =   OpCompositeExtract %float %118 2\n        %123 =   OpCompositeExtract %float %118 3\n        %124 =   OpCompositeConstruct %v4float %120 %121 %122 %123\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %126 %120\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %127 %121\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %128 %122\n        %129 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %129 %123\n        %130 =   OpImageSparseTexelsResident %bool %119\n        %131 =   OpSelect %float %130 %float_1 %float_0\n                 OpStore %SV_TARGET_5 %131\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_gather_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _61\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _69\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out float SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out float SV_TARGET_5;\n\nvoid main()\n{\n    uint _134;\n    vec4 _135;\n    _134 = sparseTextureGatherARB(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), _135);\n    SparseTexel _54 = SparseTexel(_134, _135);\n    vec4 _56 = _54._m1;\n    _61 _62 = _61(_56.x, _56.y, _56.z, _56.w, _54._m0);\n    float _64 = _62._m0;\n    float _65 = _62._m1;\n    float _66 = _62._m2;\n    float _67 = _62._m3;\n    SV_TARGET.x = _64;\n    SV_TARGET.y = _65;\n    SV_TARGET.z = _66;\n    SV_TARGET.w = _67;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_62._m4)));\n    uint _136;\n    vec4 _137;\n    _136 = sparseTextureGatherOffsetARB(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(-1, 0), _137);\n    SparseTexel _85 = SparseTexel(_136, _137);\n    vec4 _88 = _85._m1;\n    _61 _93 = _61(_88.x, _88.y, _88.z, _88.w, _85._m0);\n    float _95 = _93._m0;\n    float _96 = _93._m1;\n    float _97 = _93._m2;\n    float _98 = _93._m3;\n    SV_TARGET_2.x = _95;\n    SV_TARGET_2.y = _96;\n    SV_TARGET_2.z = _97;\n    SV_TARGET_2.w = _98;\n    SV_TARGET_3 = float(sparseTexelsResidentARB(int(_93._m4)));\n    uint _138;\n    vec4 _139;\n    _138 = sparseTextureGatherOffsetARB(sampler2D(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))), _139);\n    SparseTexel _110 = SparseTexel(_138, _139);\n    vec4 _113 = _110._m1;\n    _61 _118 = _61(_113.x, _113.y, _113.z, _113.w, _110._m0);\n    float _120 = _118._m0;\n    float _121 = _118._m1;\n    float _122 = _118._m2;\n    float _123 = _118._m3;\n    SV_TARGET_4.x = _120;\n    SV_TARGET_4.y = _121;\n    SV_TARGET_4.z = _122;\n    SV_TARGET_4.w = _123;\n    SV_TARGET_5 = float(sparseTexelsResidentARB(int(_118._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_load_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 89\n; Schema: 0\n               OpCapability Shader\n               OpCapability SparseResidency\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %v4float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n    %float_0 = OpConstant %float 0\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %66 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %87\n\n         %87 = OpLabel\n         %20 =   OpLoad %6 %8\n         %22 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %24 =   OpLoad %uint %22\n         %25 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %27 =   OpLoad %uint %25\n         %32 =   OpCompositeConstruct %v2uint %24 %27\n         %31 =   OpImageSparseFetch %SparseTexel %20 %32 Lod %uint_1\n         %33 =   OpCompositeExtract %uint %31 0\n         %34 =   OpCompositeExtract %v4float %31 1\n         %35 =   OpCompositeExtract %float %34 0\n         %36 =   OpCompositeExtract %float %34 1\n         %37 =   OpCompositeExtract %float %34 2\n         %38 =   OpCompositeExtract %float %34 3\n         %40 =   OpCompositeConstruct %_ %35 %36 %37 %38 %33\n         %41 =   OpCompositeExtract %uint %40 4\n         %42 =   OpCompositeExtract %float %40 0\n         %43 =   OpCompositeExtract %float %40 1\n         %44 =   OpCompositeExtract %float %40 2\n         %45 =   OpCompositeExtract %float %40 3\n         %46 =   OpCompositeConstruct %v4float %42 %43 %44 %45\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %49 %42\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %50 %43\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %51 %44\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %53 %45\n         %56 =   OpImageSparseTexelsResident %bool %41\n         %57 =   OpSelect %float %56 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %57\n         %64 =   OpCompositeConstruct %v2uint %24 %27\n         %63 =   OpImageSparseFetch %SparseTexel %20 %64 Lod|ConstOffset %uint_1 %66\n         %67 =   OpCompositeExtract %uint %63 0\n         %68 =   OpCompositeExtract %v4float %63 1\n         %69 =   OpCompositeExtract %float %68 0\n         %70 =   OpCompositeExtract %float %68 1\n         %71 =   OpCompositeExtract %float %68 2\n         %72 =   OpCompositeExtract %float %68 3\n         %73 =   OpCompositeConstruct %_ %69 %70 %71 %72 %67\n         %74 =   OpCompositeExtract %uint %73 4\n         %75 =   OpCompositeExtract %float %73 0\n         %76 =   OpCompositeExtract %float %73 1\n         %77 =   OpCompositeExtract %float %73 2\n         %78 =   OpCompositeExtract %float %73 3\n         %79 =   OpCompositeConstruct %v4float %75 %76 %77 %78\n         %81 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %81 %75\n         %82 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %82 %76\n         %83 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %83 %77\n         %84 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %84 %78\n         %85 =   OpImageSparseTexelsResident %bool %74\n         %86 =   OpSelect %float %85 %float_1 %float_0\n                 OpStore %SV_TARGET_3 %86\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_load_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _39\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _47\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out float SV_TARGET_3;\n\nvoid main()\n{\n    uint _89;\n    vec4 _90;\n    _89 = sparseTexelFetchARB(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(1u), _90);\n    SparseTexel _31 = SparseTexel(_89, _90);\n    vec4 _34 = _31._m1;\n    _39 _40 = _39(_34.x, _34.y, _34.z, _34.w, _31._m0);\n    float _42 = _40._m0;\n    float _43 = _40._m1;\n    float _44 = _40._m2;\n    float _45 = _40._m3;\n    SV_TARGET.x = _42;\n    SV_TARGET.y = _43;\n    SV_TARGET.z = _44;\n    SV_TARGET.w = _45;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_40._m4)));\n    uint _91;\n    vec4 _92;\n    _91 = sparseTexelFetchOffsetARB(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(1u), ivec2(-1, 0), _92);\n    SparseTexel _63 = SparseTexel(_91, _92);\n    vec4 _68 = _63._m1;\n    _39 _73 = _39(_68.x, _68.y, _68.z, _68.w, _63._m0);\n    float _75 = _73._m0;\n    float _76 = _73._m1;\n    float _77 = _73._m2;\n    float _78 = _73._m3;\n    SV_TARGET_2.x = _75;\n    SV_TARGET_2.y = _76;\n    SV_TARGET_2.z = _77;\n    SV_TARGET_2.w = _78;\n    SV_TARGET_3 = float(sparseTexelsResidentARB(int(_73._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_sample_depth_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 81\n; Schema: 0\n               OpCapability Shader\n               OpCapability SparseResidency\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n         %42 = OpTypeSampledImage %6\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %float\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %79\n\n         %79 = OpLabel\n         %28 =   OpLoad %6 %8\n         %29 =   OpLoad %9 %11\n         %30 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %33 =   OpLoad %float %30\n         %34 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %36 =   OpLoad %float %34\n         %39 =   OpLoad %float %LAYER\n         %43 =   OpSampledImage %42 %28 %29\n         %48 =   OpCompositeConstruct %v3float %33 %36 %39\n         %47 =   OpImageSparseSampleImplicitLod %SparseTexel %43 %48 None\n         %49 =   OpCompositeExtract %uint %47 0\n         %50 =   OpCompositeExtract %v4float %47 1\n         %51 =   OpCompositeExtract %float %50 0\n         %52 =   OpCompositeExtract %float %50 1\n         %53 =   OpCompositeExtract %float %50 2\n         %54 =   OpCompositeExtract %float %50 3\n         %56 =   OpCompositeConstruct %_ %51 %52 %53 %54 %49\n         %57 =   OpCompositeExtract %uint %56 4\n         %58 =   OpCompositeExtract %float %56 0\n                 OpStore %SV_TARGET %58\n         %62 =   OpImageSparseTexelsResident %bool %57\n         %63 =   OpSelect %float %62 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %63\n         %66 =   OpCompositeConstruct %v3float %33 %36 %39\n         %65 =   OpImageSparseSampleExplicitLod %SparseTexel %43 %66 Lod %float_0\n         %67 =   OpCompositeExtract %uint %65 0\n         %68 =   OpCompositeExtract %v4float %65 1\n         %69 =   OpCompositeExtract %float %68 0\n         %70 =   OpCompositeExtract %float %68 1\n         %71 =   OpCompositeExtract %float %68 2\n         %72 =   OpCompositeExtract %float %68 3\n         %73 =   OpCompositeConstruct %_ %69 %70 %71 %72 %67\n         %74 =   OpCompositeExtract %uint %73 4\n         %75 =   OpCompositeExtract %float %73 0\n                 OpStore %SV_TARGET_2 %75\n         %77 =   OpImageSparseTexelsResident %bool %74\n         %78 =   OpSelect %float %77 %float_1 %float_0\n                 OpStore %SV_TARGET_3 %78\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_sample_depth_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _55\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _59\n{\n    uint _m0;\n    float _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\nlayout(location = 3) out float SV_TARGET_3;\n\nvoid main()\n{\n    uint _81;\n    vec4 _82;\n    _81 = sparseTextureARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), _82);\n    SparseTexel _47 = SparseTexel(_81, _82);\n    vec4 _50 = _47._m1;\n    _55 _56 = _55(_50.x, _50.y, _50.z, _50.w, _47._m0);\n    SV_TARGET = _56._m0;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_56._m4)));\n    uint _83;\n    vec4 _84;\n    _83 = sparseTextureLodARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), 0.0, _84);\n    SparseTexel _65 = SparseTexel(_83, _84);\n    vec4 _68 = _65._m1;\n    _55 _73 = _55(_68.x, _68.y, _68.z, _68.w, _65._m0);\n    SV_TARGET_2 = _73._m0;\n    SV_TARGET_3 = float(sparseTexelsResidentARB(int(_73._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_sample_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 167\n; Schema: 0\n               OpCapability Shader\n               OpCapability SparseResidency\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %11 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %11 DescriptorSet 0\n               OpDecorate %11 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n          %9 = OpTypeSampler\n%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9\n         %11 = OpVariable %_ptr_UniformConstant_9 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n         %45 = OpTypeSampledImage %6\n    %float_0 = OpConstant %float 0\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %v4float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n        %110 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %165\n\n        %165 = OpLabel\n         %34 =   OpLoad %6 %8\n         %35 =   OpLoad %9 %11\n         %36 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %39 =   OpLoad %float %36\n         %40 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %42 =   OpLoad %float %40\n         %44 =   OpLoad %float %LAYER\n         %46 =   OpSampledImage %45 %34 %35\n         %48 =   OpCompositeConstruct %v2float %39 %42\n         %47 =   OpImageQueryLod %v2float %46 %48\n         %49 =   OpCompositeExtract %float %47 0\n         %50 =   OpLoad %float %LOD_BIAS\n         %51 =   OpLoad %float %LOD_CLAMP\n         %55 =   OpCompositeConstruct %v3float %39 %42 %44\n         %54 =   OpImageSparseSampleImplicitLod %SparseTexel %46 %55 None\n         %56 =   OpCompositeExtract %uint %54 0\n         %57 =   OpCompositeExtract %v4float %54 1\n         %58 =   OpCompositeExtract %float %57 0\n         %59 =   OpCompositeExtract %float %57 1\n         %60 =   OpCompositeExtract %float %57 2\n         %61 =   OpCompositeExtract %float %57 3\n         %63 =   OpCompositeConstruct %_ %58 %59 %60 %61 %56\n         %64 =   OpCompositeExtract %uint %63 4\n         %65 =   OpCompositeExtract %float %63 0\n         %66 =   OpCompositeExtract %float %63 1\n         %67 =   OpCompositeExtract %float %63 2\n         %68 =   OpCompositeExtract %float %63 3\n         %69 =   OpCompositeConstruct %v4float %65 %66 %67 %68\n         %72 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %72 %65\n         %73 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %73 %66\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %74 %67\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %76 %68\n         %79 =   OpImageSparseTexelsResident %bool %64\n         %80 =   OpSelect %float %79 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %80\n         %83 =   OpCompositeConstruct %v3float %39 %42 %44\n         %82 =   OpImageSparseSampleExplicitLod %SparseTexel %46 %83 Lod %49\n         %84 =   OpCompositeExtract %uint %82 0\n         %85 =   OpCompositeExtract %v4float %82 1\n         %86 =   OpCompositeExtract %float %85 0\n         %87 =   OpCompositeExtract %float %85 1\n         %88 =   OpCompositeExtract %float %85 2\n         %89 =   OpCompositeExtract %float %85 3\n         %90 =   OpCompositeConstruct %_ %86 %87 %88 %89 %84\n         %91 =   OpCompositeExtract %uint %90 4\n         %92 =   OpCompositeExtract %float %90 0\n         %93 =   OpCompositeExtract %float %90 1\n         %94 =   OpCompositeExtract %float %90 2\n         %95 =   OpCompositeExtract %float %90 3\n         %96 =   OpCompositeConstruct %v4float %92 %93 %94 %95\n         %98 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %98 %92\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %99 %93\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %100 %94\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %101 %95\n        %102 =   OpImageSparseTexelsResident %bool %91\n        %103 =   OpSelect %float %102 %float_1 %float_0\n                 OpStore %SV_TARGET_3 %103\n        %108 =   OpCompositeConstruct %v3float %39 %42 %44\n        %107 =   OpImageSparseSampleImplicitLod %SparseTexel %46 %108 Bias|ConstOffset|MinLod %50 %110 %51\n        %111 =   OpCompositeExtract %uint %107 0\n        %112 =   OpCompositeExtract %v4float %107 1\n        %113 =   OpCompositeExtract %float %112 0\n        %114 =   OpCompositeExtract %float %112 1\n        %115 =   OpCompositeExtract %float %112 2\n        %116 =   OpCompositeExtract %float %112 3\n        %117 =   OpCompositeConstruct %_ %113 %114 %115 %116 %111\n        %118 =   OpCompositeExtract %uint %117 4\n        %119 =   OpCompositeExtract %float %117 0\n        %120 =   OpCompositeExtract %float %117 1\n        %121 =   OpCompositeExtract %float %117 2\n        %122 =   OpCompositeExtract %float %117 3\n        %123 =   OpCompositeConstruct %v4float %119 %120 %121 %122\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %125 %119\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %126 %120\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %127 %121\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %128 %122\n        %129 =   OpImageSparseTexelsResident %bool %118\n        %130 =   OpSelect %float %129 %float_1 %float_0\n                 OpStore %SV_TARGET_5 %130\n        %131 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %132 =   OpLoad %float %131\n        %133 =   OpDPdx %float %132\n        %134 =   OpDPdy %float %132\n        %135 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %136 =   OpLoad %float %135\n        %137 =   OpDPdx %float %136\n        %138 =   OpDPdy %float %136\n        %142 =   OpCompositeConstruct %v3float %39 %42 %44\n        %143 =   OpCompositeConstruct %v2float %133 %137\n        %144 =   OpCompositeConstruct %v2float %134 %138\n        %141 =   OpImageSparseSampleExplicitLod %SparseTexel %46 %142 Grad %143 %144\n        %145 =   OpCompositeExtract %uint %141 0\n        %146 =   OpCompositeExtract %v4float %141 1\n        %147 =   OpCompositeExtract %float %146 0\n        %148 =   OpCompositeExtract %float %146 1\n        %149 =   OpCompositeExtract %float %146 2\n        %150 =   OpCompositeExtract %float %146 3\n        %151 =   OpCompositeConstruct %_ %147 %148 %149 %150 %145\n        %152 =   OpCompositeExtract %uint %151 4\n        %153 =   OpCompositeExtract %float %151 0\n        %154 =   OpCompositeExtract %float %151 1\n        %155 =   OpCompositeExtract %float %151 2\n        %156 =   OpCompositeExtract %float %151 3\n        %157 =   OpCompositeConstruct %v4float %153 %154 %155 %156\n        %159 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %159 %153\n        %160 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %160 %154\n        %161 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %161 %155\n        %162 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %162 %156\n        %163 =   OpImageSparseTexelsResident %bool %152\n        %164 =   OpSelect %float %163 %float_1 %float_0\n                 OpStore %SV_TARGET_7 %164\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_image_sample_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _62\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _70\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nlayout(set = 0, binding = 0) uniform texture2DArray _8;\nlayout(set = 0, binding = 0) uniform sampler _11;\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out float SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out float SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out float SV_TARGET_7;\n\nvoid main()\n{\n    uint _167;\n    vec4 _168;\n    _167 = sparseTextureARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), _168);\n    SparseTexel _54 = SparseTexel(_167, _168);\n    vec4 _57 = _54._m1;\n    _62 _63 = _62(_57.x, _57.y, _57.z, _57.w, _54._m0);\n    float _65 = _63._m0;\n    float _66 = _63._m1;\n    float _67 = _63._m2;\n    float _68 = _63._m3;\n    SV_TARGET.x = _65;\n    SV_TARGET.y = _66;\n    SV_TARGET.z = _67;\n    SV_TARGET.w = _68;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_63._m4)));\n    uint _169;\n    vec4 _170;\n    _169 = sparseTextureLodARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), textureQueryLod(sampler2DArray(_8, _11), vec2(TEXCOORD.x, TEXCOORD.y)).x, _170);\n    SparseTexel _82 = SparseTexel(_169, _170);\n    vec4 _85 = _82._m1;\n    _62 _90 = _62(_85.x, _85.y, _85.z, _85.w, _82._m0);\n    float _92 = _90._m0;\n    float _93 = _90._m1;\n    float _94 = _90._m2;\n    float _95 = _90._m3;\n    SV_TARGET_2.x = _92;\n    SV_TARGET_2.y = _93;\n    SV_TARGET_2.z = _94;\n    SV_TARGET_2.w = _95;\n    SV_TARGET_3 = float(sparseTexelsResidentARB(int(_90._m4)));\n    uint _171;\n    vec4 _172;\n    _171 = sparseTextureOffsetClampARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(-1, 0), LOD_CLAMP, _172, LOD_BIAS);\n    SparseTexel _107 = SparseTexel(_171, _172);\n    vec4 _112 = _107._m1;\n    _62 _117 = _62(_112.x, _112.y, _112.z, _112.w, _107._m0);\n    float _119 = _117._m0;\n    float _120 = _117._m1;\n    float _121 = _117._m2;\n    float _122 = _117._m3;\n    SV_TARGET_4.x = _119;\n    SV_TARGET_4.y = _120;\n    SV_TARGET_4.z = _121;\n    SV_TARGET_4.w = _122;\n    SV_TARGET_5 = float(sparseTexelsResidentARB(int(_117._m4)));\n    uint _173;\n    vec4 _174;\n    _173 = sparseTextureGradARB(sampler2DArray(_8, _11), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), vec2(dFdx(TEXCOORD_2.x), dFdx(TEXCOORD_2.y)), vec2(dFdy(TEXCOORD_2.x), dFdy(TEXCOORD_2.y)), _174);\n    SparseTexel _141 = SparseTexel(_173, _174);\n    vec4 _146 = _141._m1;\n    _62 _151 = _62(_146.x, _146.y, _146.z, _146.w, _141._m0);\n    float _153 = _151._m0;\n    float _154 = _151._m1;\n    float _155 = _151._m2;\n    float _156 = _151._m3;\n    SV_TARGET_6.x = _153;\n    SV_TARGET_6.y = _154;\n    SV_TARGET_6.z = _155;\n    SV_TARGET_6.w = _156;\n    SV_TARGET_7 = float(sparseTexelsResidentARB(int(_151._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 65\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability Sampled1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %27 NonUniform\n               OpDecorate %30 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %63\n\n         %63 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %30 =   OpLoad %6 %29\n         %32 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %33 =   OpLoad %uint %32\n         %38 =   OpCompositeConstruct %v2uint %33 %uint_2\n         %36 =   OpImageFetch %v4float %30 %38 Lod %uint_1\n         %39 =   OpCompositeExtract %float %36 0\n         %40 =   OpCompositeExtract %float %36 1\n         %41 =   OpCompositeExtract %float %36 2\n         %42 =   OpCompositeExtract %float %36 3\n         %45 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %45 %39\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %46 %40\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %47 %41\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %48 %42\n         %53 =   OpCompositeConstruct %v2uint %33 %uint_2\n         %52 =   OpImageFetch %v4float %30 %53 Lod|ConstOffset %uint_1 %int_n1\n         %54 =   OpCompositeExtract %float %52 0\n         %55 =   OpCompositeExtract %float %52 1\n         %56 =   OpCompositeExtract %float %52 2\n         %57 =   OpCompositeExtract %float %52 3\n         %59 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %59 %54\n         %60 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %60 %55\n         %61 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %61 %56\n         %62 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %62 %57\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture1DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    uint _27 = floatBitsToUint(_15._m0[0u]);\n    vec4 _36 = texelFetch(_9[nonuniformEXT(_27)], ivec2(uvec2(TEXCOORD.x, 2u)), int(1u));\n    SV_TARGET.x = _36.x;\n    SV_TARGET.y = _36.y;\n    SV_TARGET.z = _36.z;\n    SV_TARGET.w = _36.w;\n    vec4 _52 = texelFetchOffset(_9[nonuniformEXT(_27)], ivec2(uvec2(TEXCOORD.x, 2u)), int(1u), -1);\n    SV_TARGET_1.x = _52.x;\n    SV_TARGET_1.y = _52.y;\n    SV_TARGET_1.z = _52.z;\n    SV_TARGET_1.w = _52.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %24 NonUniform\n               OpDecorate %27 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %v2uint = OpTypeVector %uint 2\n        %__0 = OpTypeStruct %uint %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %35\n\n         %35 = OpLabel\n         %22 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %23 =   OpLoad %float %22\n         %24 =   OpBitcast %uint %23\n         %26 =   OpAccessChain %_ptr_UniformConstant_6 %9 %24\n         %27 =   OpLoad %6 %26\n         %29 =   OpImageQuerySizeLod %v2uint %27 %uint_0\n         %30 =   OpCompositeExtract %uint %29 0\n         %31 =   OpCompositeExtract %uint %29 1\n                 OpStore %SV_TARGET %30\n                 OpStore %SV_TARGET_1 %31\n         %34 =   OpImageQueryLevels %uint %27\n                 OpStore %SV_TARGET_2 %34\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _32\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture1DArray _9[];\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uint _24 = floatBitsToUint(_15._m0[0u]);\n    uvec2 _29 = uvec2(textureSize(_9[nonuniformEXT(_24)], int(0u)));\n    SV_TARGET = _29.x;\n    SV_TARGET_1 = _29.y;\n    SV_TARGET_2 = uint(textureQueryLevels(_9[nonuniformEXT(_24)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_array_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 160\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability MinLod\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n               OpDecorate %43 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %49 NonUniform\n               OpDecorate %54 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n         %53 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %158\n\n        %158 = OpLabel\n         %41 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %42 =   OpLoad %float %41\n         %43 =   OpBitcast %uint %42\n         %45 =   OpAccessChain %_ptr_UniformConstant_6 %9 %43\n         %46 =   OpLoad %6 %45\n         %48 =   OpAccessChain %_ptr_UniformConstant_16 %19 %43\n         %49 =   OpLoad %16 %48\n         %50 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %51 =   OpLoad %float %50\n         %52 =   OpLoad %float %LAYER\n         %54 =   OpSampledImage %53 %46 %49\n         %56 =   OpImageQueryLod %v2float %54 %51\n         %57 =   OpCompositeExtract %float %56 0\n         %58 =   OpLoad %float %LOD_BIAS\n         %59 =   OpLoad %float %LOD_CLAMP\n         %62 =   OpCompositeConstruct %v2float %51 %52\n         %61 =   OpImageSampleImplicitLod %v4float %54 %62 None\n         %63 =   OpCompositeExtract %float %61 0\n         %64 =   OpCompositeExtract %float %61 1\n         %65 =   OpCompositeExtract %float %61 2\n         %66 =   OpCompositeExtract %float %61 3\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %69 %63\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %70 %64\n         %72 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %72 %65\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %74 %66\n         %79 =   OpCompositeConstruct %v2float %51 %52\n         %78 =   OpImageSampleImplicitLod %v4float %54 %79 ConstOffset %int_n1\n         %80 =   OpCompositeExtract %float %78 0\n         %81 =   OpCompositeExtract %float %78 1\n         %82 =   OpCompositeExtract %float %78 2\n         %83 =   OpCompositeExtract %float %78 3\n         %85 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %85 %80\n         %86 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %86 %81\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %88 %83\n         %90 =   OpCompositeConstruct %v2float %51 %52\n         %89 =   OpImageSampleExplicitLod %v4float %54 %90 Lod %57\n         %91 =   OpCompositeExtract %float %89 0\n         %92 =   OpCompositeExtract %float %89 1\n         %93 =   OpCompositeExtract %float %89 2\n         %94 =   OpCompositeExtract %float %89 3\n         %96 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %96 %91\n         %97 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %97 %92\n         %98 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %98 %93\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %99 %94\n        %101 =   OpCompositeConstruct %v2float %51 %52\n        %100 =   OpImageSampleImplicitLod %v4float %54 %101 Bias %58\n        %102 =   OpCompositeExtract %float %100 0\n        %103 =   OpCompositeExtract %float %100 1\n        %104 =   OpCompositeExtract %float %100 2\n        %105 =   OpCompositeExtract %float %100 3\n        %107 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %107 %102\n        %108 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %108 %103\n        %109 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %109 %104\n        %110 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %110 %105\n        %112 =   OpCompositeConstruct %v2float %51 %52\n        %111 =   OpImageSampleImplicitLod %v4float %54 %112 MinLod %59\n        %113 =   OpCompositeExtract %float %111 0\n        %114 =   OpCompositeExtract %float %111 1\n        %115 =   OpCompositeExtract %float %111 2\n        %116 =   OpCompositeExtract %float %111 3\n        %118 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %118 %113\n        %119 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %119 %114\n        %120 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %120 %115\n        %121 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %121 %116\n        %123 =   OpCompositeConstruct %v2float %51 %52\n        %122 =   OpImageSampleImplicitLod %v4float %54 %123 Bias|ConstOffset|MinLod %58 %int_n1 %59\n        %124 =   OpCompositeExtract %float %122 0\n        %125 =   OpCompositeExtract %float %122 1\n        %126 =   OpCompositeExtract %float %122 2\n        %127 =   OpCompositeExtract %float %122 3\n        %129 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %129 %124\n        %130 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %130 %125\n        %131 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %131 %126\n        %132 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %132 %127\n        %133 =   OpLoad %float %TEXCOORD_2\n        %134 =   OpDPdx %float %133\n        %135 =   OpDPdy %float %133\n        %137 =   OpCompositeConstruct %v2float %51 %52\n        %136 =   OpImageSampleExplicitLod %v4float %54 %137 Grad %134 %135\n        %138 =   OpCompositeExtract %float %136 0\n        %139 =   OpCompositeExtract %float %136 1\n        %140 =   OpCompositeExtract %float %136 2\n        %141 =   OpCompositeExtract %float %136 3\n        %143 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %143 %138\n        %144 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %144 %139\n        %145 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %145 %140\n        %146 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %146 %141\n        %148 =   OpCompositeConstruct %v2float %51 %52\n        %147 =   OpImageSampleExplicitLod %v4float %54 %148 Grad|ConstOffset %134 %135 %int_n1\n        %149 =   OpCompositeExtract %float %147 0\n        %150 =   OpCompositeExtract %float %147 1\n        %151 =   OpCompositeExtract %float %147 2\n        %152 =   OpCompositeExtract %float %147 3\n        %154 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %154 %149\n        %155 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %155 %150\n        %156 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %156 %151\n        %157 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %157 %152\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_array_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture1DArray _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in float TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    uint _43 = floatBitsToUint(_15._m0[0u]);\n    vec4 _61 = texture(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER));\n    SV_TARGET.x = _61.x;\n    SV_TARGET.y = _61.y;\n    SV_TARGET.z = _61.z;\n    SV_TARGET.w = _61.w;\n    vec4 _78 = textureOffset(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER), -1);\n    SV_TARGET_1.x = _78.x;\n    SV_TARGET_1.y = _78.y;\n    SV_TARGET_1.z = _78.z;\n    SV_TARGET_1.w = _78.w;\n    vec4 _89 = textureLod(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER), textureQueryLod(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), TEXCOORD.x).x);\n    SV_TARGET_2.x = _89.x;\n    SV_TARGET_2.y = _89.y;\n    SV_TARGET_2.z = _89.z;\n    SV_TARGET_2.w = _89.w;\n    vec4 _100 = texture(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER), LOD_BIAS);\n    SV_TARGET_3.x = _100.x;\n    SV_TARGET_3.y = _100.y;\n    SV_TARGET_3.z = _100.z;\n    SV_TARGET_3.w = _100.w;\n    vec4 _111 = textureClampARB(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER), LOD_CLAMP);\n    SV_TARGET_4.x = _111.x;\n    SV_TARGET_4.y = _111.y;\n    SV_TARGET_4.z = _111.z;\n    SV_TARGET_4.w = _111.w;\n    vec4 _122 = textureOffsetClampARB(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER), -1, LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _122.x;\n    SV_TARGET_5.y = _122.y;\n    SV_TARGET_5.z = _122.z;\n    SV_TARGET_5.w = _122.w;\n    float _134 = dFdx(TEXCOORD_2);\n    float _135 = dFdy(TEXCOORD_2);\n    vec4 _136 = textureGrad(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER), _134, _135);\n    SV_TARGET_6.x = _136.x;\n    SV_TARGET_6.y = _136.y;\n    SV_TARGET_6.z = _136.z;\n    SV_TARGET_6.w = _136.w;\n    vec4 _147 = textureGradOffset(nonuniformEXT(sampler1DArray(_9[_43], _19[_43])), vec2(TEXCOORD.x, LAYER), _134, _135, -1);\n    SV_TARGET_7.x = _147.x;\n    SV_TARGET_7.y = _147.y;\n    SV_TARGET_7.z = _147.z;\n    SV_TARGET_7.w = _147.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 62\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability Sampled1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %27 NonUniform\n               OpDecorate %30 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %60\n\n         %60 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %30 =   OpLoad %6 %29\n         %32 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %33 =   OpLoad %uint %32\n         %35 =   OpImageFetch %v4float %30 %33 Lod %uint_1\n         %36 =   OpCompositeExtract %float %35 0\n         %37 =   OpCompositeExtract %float %35 1\n         %38 =   OpCompositeExtract %float %35 2\n         %39 =   OpCompositeExtract %float %35 3\n         %42 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %42 %36\n         %43 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %43 %37\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %44 %38\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %46 %39\n         %50 =   OpImageFetch %v4float %30 %33 Lod|ConstOffset %uint_1 %int_n1\n         %51 =   OpCompositeExtract %float %50 0\n         %52 =   OpCompositeExtract %float %50 1\n         %53 =   OpCompositeExtract %float %50 2\n         %54 =   OpCompositeExtract %float %50 3\n         %56 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %56 %51\n         %57 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %57 %52\n         %58 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %58 %53\n         %59 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %59 %54\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture1D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    uint _27 = floatBitsToUint(_15._m0[0u]);\n    vec4 _35 = texelFetch(_9[nonuniformEXT(_27)], int(TEXCOORD.x), int(1u));\n    SV_TARGET.x = _35.x;\n    SV_TARGET.y = _35.y;\n    SV_TARGET.z = _35.z;\n    SV_TARGET.w = _35.w;\n    vec4 _50 = texelFetchOffset(_9[nonuniformEXT(_27)], int(TEXCOORD.x), int(1u), -1);\n    SV_TARGET_1.x = _50.x;\n    SV_TARGET_1.y = _50.y;\n    SV_TARGET_1.z = _50.z;\n    SV_TARGET_1.w = _50.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %24 NonUniform\n               OpDecorate %27 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %33\n\n         %33 = OpLabel\n         %22 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %23 =   OpLoad %float %22\n         %24 =   OpBitcast %uint %23\n         %26 =   OpAccessChain %_ptr_UniformConstant_6 %9 %24\n         %27 =   OpLoad %6 %26\n         %28 =   OpImageQuerySizeLod %uint %27 %uint_0\n                 OpStore %SV_TARGET %28\n                 OpStore %SV_TARGET_1 %uint_1\n         %32 =   OpImageQueryLevels %uint %27\n                 OpStore %SV_TARGET_2 %32\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _29\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture1D _9[];\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uint _24 = floatBitsToUint(_15._m0[0u]);\n    SV_TARGET = uint(textureSize(_9[nonuniformEXT(_24)], int(0u)));\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_9[nonuniformEXT(_24)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 151\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability MinLod\n               OpCapability Sampled1D\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n               OpDecorate %43 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %49 NonUniform\n               OpDecorate %53 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n         %52 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %149\n\n        %149 = OpLabel\n         %41 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %42 =   OpLoad %float %41\n         %43 =   OpBitcast %uint %42\n         %45 =   OpAccessChain %_ptr_UniformConstant_6 %9 %43\n         %46 =   OpLoad %6 %45\n         %48 =   OpAccessChain %_ptr_UniformConstant_16 %19 %43\n         %49 =   OpLoad %16 %48\n         %50 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %51 =   OpLoad %float %50\n         %53 =   OpSampledImage %52 %46 %49\n         %55 =   OpImageQueryLod %v2float %53 %51\n         %56 =   OpCompositeExtract %float %55 0\n         %57 =   OpLoad %float %LOD_BIAS\n         %58 =   OpLoad %float %LOD_CLAMP\n         %60 =   OpImageSampleImplicitLod %v4float %53 %51 None\n         %61 =   OpCompositeExtract %float %60 0\n         %62 =   OpCompositeExtract %float %60 1\n         %63 =   OpCompositeExtract %float %60 2\n         %64 =   OpCompositeExtract %float %60 3\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %67 %61\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %68 %62\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %70 %63\n         %72 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %72 %64\n         %76 =   OpImageSampleImplicitLod %v4float %53 %51 ConstOffset %int_n1\n         %77 =   OpCompositeExtract %float %76 0\n         %78 =   OpCompositeExtract %float %76 1\n         %79 =   OpCompositeExtract %float %76 2\n         %80 =   OpCompositeExtract %float %76 3\n         %82 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %82 %77\n         %83 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %83 %78\n         %84 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %84 %79\n         %85 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %85 %80\n         %86 =   OpImageSampleExplicitLod %v4float %53 %51 Lod %56\n         %87 =   OpCompositeExtract %float %86 0\n         %88 =   OpCompositeExtract %float %86 1\n         %89 =   OpCompositeExtract %float %86 2\n         %90 =   OpCompositeExtract %float %86 3\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %95 %90\n         %96 =   OpImageSampleImplicitLod %v4float %53 %51 Bias %57\n         %97 =   OpCompositeExtract %float %96 0\n         %98 =   OpCompositeExtract %float %96 1\n         %99 =   OpCompositeExtract %float %96 2\n        %100 =   OpCompositeExtract %float %96 3\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %102 %97\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %103 %98\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %104 %99\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %105 %100\n        %106 =   OpImageSampleImplicitLod %v4float %53 %51 MinLod %58\n        %107 =   OpCompositeExtract %float %106 0\n        %108 =   OpCompositeExtract %float %106 1\n        %109 =   OpCompositeExtract %float %106 2\n        %110 =   OpCompositeExtract %float %106 3\n        %112 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %112 %107\n        %113 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %113 %108\n        %114 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %114 %109\n        %115 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %115 %110\n        %116 =   OpImageSampleImplicitLod %v4float %53 %51 Bias|ConstOffset|MinLod %57 %int_n1 %58\n        %117 =   OpCompositeExtract %float %116 0\n        %118 =   OpCompositeExtract %float %116 1\n        %119 =   OpCompositeExtract %float %116 2\n        %120 =   OpCompositeExtract %float %116 3\n        %122 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %122 %117\n        %123 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %123 %118\n        %124 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %124 %119\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %125 %120\n        %126 =   OpLoad %float %TEXCOORD_2\n        %127 =   OpDPdx %float %126\n        %128 =   OpDPdy %float %126\n        %129 =   OpImageSampleExplicitLod %v4float %53 %51 Grad %127 %128\n        %130 =   OpCompositeExtract %float %129 0\n        %131 =   OpCompositeExtract %float %129 1\n        %132 =   OpCompositeExtract %float %129 2\n        %133 =   OpCompositeExtract %float %129 3\n        %135 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %135 %130\n        %136 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %136 %131\n        %137 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %137 %132\n        %138 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %138 %133\n        %139 =   OpImageSampleExplicitLod %v4float %53 %51 Grad|ConstOffset %127 %128 %int_n1\n        %140 =   OpCompositeExtract %float %139 0\n        %141 =   OpCompositeExtract %float %139 1\n        %142 =   OpCompositeExtract %float %139 2\n        %143 =   OpCompositeExtract %float %139 3\n        %145 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %145 %140\n        %146 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %146 %141\n        %147 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %147 %142\n        %148 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %148 %143\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_1d_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture1D _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in float TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    uint _43 = floatBitsToUint(_15._m0[0u]);\n    vec4 _60 = texture(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x);\n    SV_TARGET.x = _60.x;\n    SV_TARGET.y = _60.y;\n    SV_TARGET.z = _60.z;\n    SV_TARGET.w = _60.w;\n    vec4 _76 = textureOffset(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x, -1);\n    SV_TARGET_1.x = _76.x;\n    SV_TARGET_1.y = _76.y;\n    SV_TARGET_1.z = _76.z;\n    SV_TARGET_1.w = _76.w;\n    vec4 _86 = textureLod(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x, textureQueryLod(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x).x);\n    SV_TARGET_2.x = _86.x;\n    SV_TARGET_2.y = _86.y;\n    SV_TARGET_2.z = _86.z;\n    SV_TARGET_2.w = _86.w;\n    vec4 _96 = texture(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x, LOD_BIAS);\n    SV_TARGET_3.x = _96.x;\n    SV_TARGET_3.y = _96.y;\n    SV_TARGET_3.z = _96.z;\n    SV_TARGET_3.w = _96.w;\n    vec4 _106 = textureClampARB(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x, LOD_CLAMP);\n    SV_TARGET_4.x = _106.x;\n    SV_TARGET_4.y = _106.y;\n    SV_TARGET_4.z = _106.z;\n    SV_TARGET_4.w = _106.w;\n    vec4 _116 = textureOffsetClampARB(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x, -1, LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _116.x;\n    SV_TARGET_5.y = _116.y;\n    SV_TARGET_5.z = _116.z;\n    SV_TARGET_5.w = _116.w;\n    float _127 = dFdx(TEXCOORD_2);\n    float _128 = dFdy(TEXCOORD_2);\n    vec4 _129 = textureGrad(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x, _127, _128);\n    SV_TARGET_6.x = _129.x;\n    SV_TARGET_6.y = _129.y;\n    SV_TARGET_6.z = _129.z;\n    SV_TARGET_6.w = _129.w;\n    vec4 _139 = textureGradOffset(nonuniformEXT(sampler1D(_9[_43], _19[_43])), TEXCOORD.x, _127, _128, -1);\n    SV_TARGET_7.x = _139.x;\n    SV_TARGET_7.y = _139.y;\n    SV_TARGET_7.z = _139.z;\n    SV_TARGET_7.w = _139.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 145\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %42 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %48 NonUniform\n               OpDecorate %67 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %66 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %86 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %143\n\n        %143 = OpLabel\n         %40 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %41 =   OpLoad %float %40\n         %42 =   OpBitcast %uint %41\n         %44 =   OpAccessChain %_ptr_UniformConstant_6 %9 %42\n         %45 =   OpLoad %6 %44\n         %47 =   OpAccessChain %_ptr_UniformConstant_16 %19 %42\n         %48 =   OpLoad %16 %47\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %50 =   OpLoad %float %49\n         %51 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %53 =   OpLoad %float %51\n         %56 =   OpLoad %float %LAYER\n         %58 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %59 =   OpLoad %int %58\n         %60 =   OpBitcast %uint %59\n         %61 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %62 =   OpLoad %int %61\n         %63 =   OpBitcast %uint %62\n         %67 =   OpSampledImage %66 %45 %48\n         %68 =   OpCompositeConstruct %v3float %50 %53 %56\n         %69 =   OpImageGather %v4float %67 %68 %uint_0\n         %70 =   OpCompositeExtract %float %69 0\n         %71 =   OpCompositeExtract %float %69 1\n         %72 =   OpCompositeExtract %float %69 2\n         %73 =   OpCompositeExtract %float %69 3\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %76 %70\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %77 %71\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %78 %72\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %80 %73\n         %82 =   OpCompositeConstruct %v3float %50 %53 %56\n         %85 =   OpImageGather %v4float %67 %82 %uint_0 ConstOffset %86\n         %87 =   OpCompositeExtract %float %85 0\n         %88 =   OpCompositeExtract %float %85 1\n         %89 =   OpCompositeExtract %float %85 2\n         %90 =   OpCompositeExtract %float %85 3\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %95 %90\n         %96 =   OpCompositeConstruct %v3float %50 %53 %56\n         %97 =   OpImageGather %v4float %67 %96 %uint_1\n         %98 =   OpCompositeExtract %float %97 0\n         %99 =   OpCompositeExtract %float %97 1\n        %100 =   OpCompositeExtract %float %97 2\n        %101 =   OpCompositeExtract %float %97 3\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %103 %98\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %104 %99\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %105 %100\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %106 %101\n        %107 =   OpCompositeConstruct %v3float %50 %53 %56\n        %108 =   OpImageGather %v4float %67 %107 %uint_2\n        %109 =   OpCompositeExtract %float %108 0\n        %110 =   OpCompositeExtract %float %108 1\n        %111 =   OpCompositeExtract %float %108 2\n        %112 =   OpCompositeExtract %float %108 3\n        %114 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %114 %109\n        %115 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %115 %110\n        %116 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %116 %111\n        %117 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %117 %112\n        %118 =   OpCompositeConstruct %v3float %50 %53 %56\n        %119 =   OpImageGather %v4float %67 %118 %uint_3\n        %120 =   OpCompositeExtract %float %119 0\n        %121 =   OpCompositeExtract %float %119 1\n        %122 =   OpCompositeExtract %float %119 2\n        %123 =   OpCompositeExtract %float %119 3\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %125 %120\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %126 %121\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %127 %122\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %128 %123\n        %129 =   OpCompositeConstruct %v3float %50 %53 %56\n        %130 =   OpBitcast %int %60\n        %131 =   OpBitcast %int %63\n        %133 =   OpCompositeConstruct %v2int %130 %131\n        %132 =   OpImageGather %v4float %67 %129 %uint_0 Offset %133\n        %134 =   OpCompositeExtract %float %132 0\n        %135 =   OpCompositeExtract %float %132 1\n        %136 =   OpCompositeExtract %float %132 2\n        %137 =   OpCompositeExtract %float %132 3\n        %139 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %139 %134\n        %140 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %140 %135\n        %141 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %141 %136\n        %142 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %142 %137\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_gather.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DArray _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\n\nvoid main()\n{\n    uint _42 = floatBitsToUint(_15._m0[0u]);\n    vec4 _69 = textureGather(nonuniformEXT(sampler2DArray(_9[_42], _19[_42])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER));\n    SV_TARGET.x = _69.x;\n    SV_TARGET.y = _69.y;\n    SV_TARGET.z = _69.z;\n    SV_TARGET.w = _69.w;\n    vec4 _85 = textureGatherOffset(nonuniformEXT(sampler2DArray(_9[_42], _19[_42])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(-1, 0));\n    SV_TARGET_1.x = _85.x;\n    SV_TARGET_1.y = _85.y;\n    SV_TARGET_1.z = _85.z;\n    SV_TARGET_1.w = _85.w;\n    vec4 _97 = textureGather(nonuniformEXT(sampler2DArray(_9[_42], _19[_42])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), int(1u));\n    SV_TARGET_2.x = _97.x;\n    SV_TARGET_2.y = _97.y;\n    SV_TARGET_2.z = _97.z;\n    SV_TARGET_2.w = _97.w;\n    vec4 _108 = textureGather(nonuniformEXT(sampler2DArray(_9[_42], _19[_42])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), int(2u));\n    SV_TARGET_3.x = _108.x;\n    SV_TARGET_3.y = _108.y;\n    SV_TARGET_3.z = _108.z;\n    SV_TARGET_3.w = _108.w;\n    vec4 _119 = textureGather(nonuniformEXT(sampler2DArray(_9[_42], _19[_42])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), int(3u));\n    SV_TARGET_4.x = _119.x;\n    SV_TARGET_4.y = _119.y;\n    SV_TARGET_4.z = _119.z;\n    SV_TARGET_4.w = _119.w;\n    vec4 _132 = textureGatherOffset(nonuniformEXT(sampler2DArray(_9[_42], _19[_42])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_5.x = _132.x;\n    SV_TARGET_5.y = _132.y;\n    SV_TARGET_5.z = _132.z;\n    SV_TARGET_5.w = _132.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 111\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %39 NonUniform\n               OpDecorate %42 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %66 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %64 = OpTypeImage %float 2D 1 1 0 1 Unknown\n         %65 = OpTypeSampledImage %64\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %85 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %109\n\n        %109 = OpLabel\n         %37 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %38 =   OpLoad %float %37\n         %39 =   OpBitcast %uint %38\n         %41 =   OpAccessChain %_ptr_UniformConstant_6 %9 %39\n         %42 =   OpLoad %6 %41\n         %44 =   OpAccessChain %_ptr_UniformConstant_16 %19 %39\n         %45 =   OpLoad %16 %44\n         %46 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %47 =   OpLoad %float %46\n         %48 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %50 =   OpLoad %float %48\n         %53 =   OpLoad %float %DEPTH_REF\n         %54 =   OpLoad %float %LAYER\n         %56 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %57 =   OpLoad %int %56\n         %58 =   OpBitcast %uint %57\n         %59 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %60 =   OpLoad %int %59\n         %61 =   OpBitcast %uint %60\n         %66 =   OpSampledImage %65 %42 %45\n         %67 =   OpCompositeConstruct %v3float %47 %50 %54\n         %68 =   OpImageDrefGather %v4float %66 %67 %53\n         %69 =   OpCompositeExtract %float %68 0\n         %70 =   OpCompositeExtract %float %68 1\n         %71 =   OpCompositeExtract %float %68 2\n         %72 =   OpCompositeExtract %float %68 3\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %75 %69\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %76 %70\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %77 %71\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %79 %72\n         %81 =   OpCompositeConstruct %v3float %47 %50 %54\n         %84 =   OpImageDrefGather %v4float %66 %81 %53 ConstOffset %85\n         %86 =   OpCompositeExtract %float %84 0\n         %87 =   OpCompositeExtract %float %84 1\n         %88 =   OpCompositeExtract %float %84 2\n         %89 =   OpCompositeExtract %float %84 3\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %94 %89\n         %95 =   OpCompositeConstruct %v3float %47 %50 %54\n         %96 =   OpBitcast %int %58\n         %97 =   OpBitcast %int %61\n         %99 =   OpCompositeConstruct %v2int %96 %97\n         %98 =   OpImageDrefGather %v4float %66 %95 %53 Offset %99\n        %100 =   OpCompositeExtract %float %98 0\n        %101 =   OpCompositeExtract %float %98 1\n        %102 =   OpCompositeExtract %float %98 2\n        %103 =   OpCompositeExtract %float %98 3\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %105 %100\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %106 %101\n        %107 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %107 %102\n        %108 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %108 %103\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DArray _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\n\nvoid main()\n{\n    uint _39 = floatBitsToUint(_15._m0[0u]);\n    vec3 _67 = vec3(TEXCOORD.x, TEXCOORD.y, LAYER);\n    vec4 _68 = textureGather(nonuniformEXT(sampler2DArrayShadow(_9[_39], _19[_39])), _67, DEPTH_REF);\n    SV_TARGET.x = _68.x;\n    SV_TARGET.y = _68.y;\n    SV_TARGET.z = _68.z;\n    SV_TARGET.w = _68.w;\n    vec3 _81 = vec3(TEXCOORD.x, TEXCOORD.y, LAYER);\n    vec4 _84 = textureGatherOffset(nonuniformEXT(sampler2DArrayShadow(_9[_39], _19[_39])), _81, DEPTH_REF, ivec2(-1, 0));\n    SV_TARGET_1.x = _84.x;\n    SV_TARGET_1.y = _84.y;\n    SV_TARGET_1.z = _84.z;\n    SV_TARGET_1.w = _84.w;\n    vec3 _95 = vec3(TEXCOORD.x, TEXCOORD.y, LAYER);\n    vec4 _98 = textureGatherOffset(nonuniformEXT(sampler2DArrayShadow(_9[_39], _19[_39])), _95, DEPTH_REF, ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_2.x = _98.x;\n    SV_TARGET_2.y = _98.y;\n    SV_TARGET_2.z = _98.z;\n    SV_TARGET_2.w = _98.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %27 NonUniform\n               OpDecorate %30 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %59 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %69\n\n         %69 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %30 =   OpLoad %6 %29\n         %32 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %33 =   OpLoad %uint %32\n         %34 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %36 =   OpLoad %uint %34\n         %41 =   OpCompositeConstruct %v3uint %33 %36 %uint_2\n         %40 =   OpImageFetch %v4float %30 %41 Lod %uint_1\n         %42 =   OpCompositeExtract %float %40 0\n         %43 =   OpCompositeExtract %float %40 1\n         %44 =   OpCompositeExtract %float %40 2\n         %45 =   OpCompositeExtract %float %40 3\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %48 %42\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %49 %43\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %50 %44\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %51 %45\n         %57 =   OpCompositeConstruct %v3uint %33 %36 %uint_2\n         %56 =   OpImageFetch %v4float %30 %57 Lod|ConstOffset %uint_1 %59\n         %60 =   OpCompositeExtract %float %56 0\n         %61 =   OpCompositeExtract %float %56 1\n         %62 =   OpCompositeExtract %float %56 2\n         %63 =   OpCompositeExtract %float %56 3\n         %65 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %65 %60\n         %66 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %66 %61\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %67 %62\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %68 %63\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    uint _27 = floatBitsToUint(_15._m0[0u]);\n    vec4 _40 = texelFetch(_9[nonuniformEXT(_27)], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), int(1u));\n    SV_TARGET.x = _40.x;\n    SV_TARGET.y = _40.y;\n    SV_TARGET.z = _40.z;\n    SV_TARGET.w = _40.w;\n    vec4 _56 = texelFetchOffset(_9[nonuniformEXT(_27)], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), int(1u), ivec2(-1, 0));\n    SV_TARGET_1.x = _56.x;\n    SV_TARGET_1.y = _56.y;\n    SV_TARGET_1.z = _56.z;\n    SV_TARGET_1.w = _56.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %v3uint = OpTypeVector %uint 3\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %42\n\n         %42 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpImageQuerySizeLod %v3uint %29 %uint_0\n         %32 =   OpCompositeExtract %uint %31 0\n         %33 =   OpCompositeExtract %uint %31 1\n         %34 =   OpCompositeConstruct %v2uint %32 %33\n         %35 =   OpCompositeExtract %uint %31 2\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %39 %33\n                 OpStore %SV_TARGET_1 %35\n         %41 =   OpImageQueryLevels %uint %29\n                 OpStore %SV_TARGET_2 %41\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _36\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DArray _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uint _26 = floatBitsToUint(_15._m0[0u]);\n    uvec3 _31 = uvec3(textureSize(_9[nonuniformEXT(_26)], int(0u)));\n    uint _32 = _31.x;\n    SV_TARGET.x = _32;\n    SV_TARGET.y = _31.y;\n    SV_TARGET_1 = _31.z;\n    SV_TARGET_2 = uint(textureQueryLevels(_9[nonuniformEXT(_26)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 179\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n               OpDecorate %45 NonUniform\n               OpDecorate %48 NonUniform\n               OpDecorate %51 NonUniform\n               OpDecorate %60 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n         %59 = OpTypeSampledImage %6\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %87 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %177\n\n        %177 = OpLabel\n         %43 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %44 =   OpLoad %float %43\n         %45 =   OpBitcast %uint %44\n         %47 =   OpAccessChain %_ptr_UniformConstant_6 %9 %45\n         %48 =   OpLoad %6 %47\n         %50 =   OpAccessChain %_ptr_UniformConstant_16 %19 %45\n         %51 =   OpLoad %16 %50\n         %52 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %53 =   OpLoad %float %52\n         %54 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %56 =   OpLoad %float %54\n         %58 =   OpLoad %float %LAYER\n         %60 =   OpSampledImage %59 %48 %51\n         %62 =   OpCompositeConstruct %v2float %53 %56\n         %61 =   OpImageQueryLod %v2float %60 %62\n         %63 =   OpCompositeExtract %float %61 0\n         %64 =   OpLoad %float %LOD_BIAS\n         %65 =   OpLoad %float %LOD_CLAMP\n         %68 =   OpCompositeConstruct %v3float %53 %56 %58\n         %67 =   OpImageSampleImplicitLod %v4float %60 %68 None\n         %69 =   OpCompositeExtract %float %67 0\n         %70 =   OpCompositeExtract %float %67 1\n         %71 =   OpCompositeExtract %float %67 2\n         %72 =   OpCompositeExtract %float %67 3\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %75 %69\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %76 %70\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %77 %71\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %79 %72\n         %85 =   OpCompositeConstruct %v3float %53 %56 %58\n         %84 =   OpImageSampleImplicitLod %v4float %60 %85 ConstOffset %87\n         %88 =   OpCompositeExtract %float %84 0\n         %89 =   OpCompositeExtract %float %84 1\n         %90 =   OpCompositeExtract %float %84 2\n         %91 =   OpCompositeExtract %float %84 3\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %95 %90\n         %96 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %96 %91\n         %98 =   OpCompositeConstruct %v3float %53 %56 %58\n         %97 =   OpImageSampleExplicitLod %v4float %60 %98 Lod %63\n         %99 =   OpCompositeExtract %float %97 0\n        %100 =   OpCompositeExtract %float %97 1\n        %101 =   OpCompositeExtract %float %97 2\n        %102 =   OpCompositeExtract %float %97 3\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %104 %99\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %105 %100\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %106 %101\n        %107 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %107 %102\n        %109 =   OpCompositeConstruct %v3float %53 %56 %58\n        %108 =   OpImageSampleImplicitLod %v4float %60 %109 Bias %64\n        %110 =   OpCompositeExtract %float %108 0\n        %111 =   OpCompositeExtract %float %108 1\n        %112 =   OpCompositeExtract %float %108 2\n        %113 =   OpCompositeExtract %float %108 3\n        %115 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %115 %110\n        %116 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %116 %111\n        %117 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %117 %112\n        %118 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %118 %113\n        %120 =   OpCompositeConstruct %v3float %53 %56 %58\n        %119 =   OpImageSampleImplicitLod %v4float %60 %120 MinLod %65\n        %121 =   OpCompositeExtract %float %119 0\n        %122 =   OpCompositeExtract %float %119 1\n        %123 =   OpCompositeExtract %float %119 2\n        %124 =   OpCompositeExtract %float %119 3\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %126 %121\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %127 %122\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %128 %123\n        %129 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %129 %124\n        %131 =   OpCompositeConstruct %v3float %53 %56 %58\n        %130 =   OpImageSampleImplicitLod %v4float %60 %131 Bias|ConstOffset|MinLod %64 %87 %65\n        %132 =   OpCompositeExtract %float %130 0\n        %133 =   OpCompositeExtract %float %130 1\n        %134 =   OpCompositeExtract %float %130 2\n        %135 =   OpCompositeExtract %float %130 3\n        %137 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %137 %132\n        %138 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %138 %133\n        %139 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %139 %134\n        %140 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %140 %135\n        %141 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %142 =   OpLoad %float %141\n        %143 =   OpDPdx %float %142\n        %144 =   OpDPdy %float %142\n        %145 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %146 =   OpLoad %float %145\n        %147 =   OpDPdx %float %146\n        %148 =   OpDPdy %float %146\n        %152 =   OpCompositeConstruct %v3float %53 %56 %58\n        %153 =   OpCompositeConstruct %v2float %143 %147\n        %154 =   OpCompositeConstruct %v2float %144 %148\n        %151 =   OpImageSampleExplicitLod %v4float %60 %152 Grad %153 %154\n        %155 =   OpCompositeExtract %float %151 0\n        %156 =   OpCompositeExtract %float %151 1\n        %157 =   OpCompositeExtract %float %151 2\n        %158 =   OpCompositeExtract %float %151 3\n        %160 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %160 %155\n        %161 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %161 %156\n        %162 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %162 %157\n        %163 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %163 %158\n        %165 =   OpCompositeConstruct %v3float %53 %56 %58\n        %166 =   OpCompositeConstruct %v2float %143 %147\n        %167 =   OpCompositeConstruct %v2float %144 %148\n        %164 =   OpImageSampleExplicitLod %v4float %60 %165 Grad|ConstOffset %166 %167 %87\n        %168 =   OpCompositeExtract %float %164 0\n        %169 =   OpCompositeExtract %float %164 1\n        %170 =   OpCompositeExtract %float %164 2\n        %171 =   OpCompositeExtract %float %164 3\n        %173 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %173 %168\n        %174 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %174 %169\n        %175 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %175 %170\n        %176 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %176 %171\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DArray _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    uint _45 = floatBitsToUint(_15._m0[0u]);\n    vec4 _67 = texture(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER));\n    SV_TARGET.x = _67.x;\n    SV_TARGET.y = _67.y;\n    SV_TARGET.z = _67.z;\n    SV_TARGET.w = _67.w;\n    vec4 _84 = textureOffset(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(-1, 0));\n    SV_TARGET_1.x = _84.x;\n    SV_TARGET_1.y = _84.y;\n    SV_TARGET_1.z = _84.z;\n    SV_TARGET_1.w = _84.w;\n    vec4 _97 = textureLod(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), textureQueryLod(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y)).x);\n    SV_TARGET_2.x = _97.x;\n    SV_TARGET_2.y = _97.y;\n    SV_TARGET_2.z = _97.z;\n    SV_TARGET_2.w = _97.w;\n    vec4 _108 = texture(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), LOD_BIAS);\n    SV_TARGET_3.x = _108.x;\n    SV_TARGET_3.y = _108.y;\n    SV_TARGET_3.z = _108.z;\n    SV_TARGET_3.w = _108.w;\n    vec4 _119 = textureClampARB(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), LOD_CLAMP);\n    SV_TARGET_4.x = _119.x;\n    SV_TARGET_4.y = _119.y;\n    SV_TARGET_4.z = _119.z;\n    SV_TARGET_4.w = _119.w;\n    vec4 _130 = textureOffsetClampARB(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), ivec2(-1, 0), LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _130.x;\n    SV_TARGET_5.y = _130.y;\n    SV_TARGET_5.z = _130.z;\n    SV_TARGET_5.w = _130.w;\n    float _143 = dFdx(TEXCOORD_2.x);\n    float _144 = dFdy(TEXCOORD_2.x);\n    float _147 = dFdx(TEXCOORD_2.y);\n    float _148 = dFdy(TEXCOORD_2.y);\n    vec4 _151 = textureGrad(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), vec2(_143, _147), vec2(_144, _148));\n    SV_TARGET_6.x = _151.x;\n    SV_TARGET_6.y = _151.y;\n    SV_TARGET_6.z = _151.z;\n    SV_TARGET_6.w = _151.w;\n    vec4 _164 = textureGradOffset(nonuniformEXT(sampler2DArray(_9[_45], _19[_45])), vec3(TEXCOORD.x, TEXCOORD.y, LAYER), vec2(_143, _147), vec2(_144, _148), ivec2(-1, 0));\n    SV_TARGET_7.x = _164.x;\n    SV_TARGET_7.y = _164.y;\n    SV_TARGET_7.z = _164.z;\n    SV_TARGET_7.w = _164.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 80\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %39 NonUniform\n               OpDecorate %42 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %58 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n         %56 = OpTypeImage %float 2D 1 1 0 1 Unknown\n         %57 = OpTypeSampledImage %56\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %71 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %78\n\n         %78 = OpLabel\n         %37 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %38 =   OpLoad %float %37\n         %39 =   OpBitcast %uint %38\n         %41 =   OpAccessChain %_ptr_UniformConstant_6 %9 %39\n         %42 =   OpLoad %6 %41\n         %44 =   OpAccessChain %_ptr_UniformConstant_16 %19 %39\n         %45 =   OpLoad %16 %44\n         %46 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %47 =   OpLoad %float %46\n         %48 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %50 =   OpLoad %float %48\n         %52 =   OpLoad %float %DEPTH_REF\n         %53 =   OpLoad %float %LAYER\n         %58 =   OpSampledImage %57 %42 %45\n         %61 =   OpCompositeConstruct %v3float %47 %50 %53\n         %60 =   OpImageSampleDrefImplicitLod %float %58 %61 %52 None\n         %63 =   OpCompositeConstruct %v4float %60 %60 %60 %60\n         %64 =   OpCompositeExtract %float %63 0\n                 OpStore %SV_TARGET %64\n         %69 =   OpCompositeConstruct %v3float %47 %50 %53\n         %68 =   OpImageSampleDrefImplicitLod %float %58 %69 %52 ConstOffset %71\n         %72 =   OpCompositeConstruct %v4float %68 %68 %68 %68\n         %73 =   OpCompositeExtract %float %72 0\n                 OpStore %SV_TARGET_1 %73\n         %75 =   OpCompositeConstruct %v3float %47 %50 %53\n         %74 =   OpImageSampleDrefExplicitLod %float %58 %75 %52 Lod %float_0\n         %76 =   OpCompositeConstruct %v4float %74 %74 %74 %74\n         %77 =   OpCompositeExtract %float %76 0\n                 OpStore %SV_TARGET_2 %77\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_array_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DArray _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\n\nvoid main()\n{\n    uint _39 = floatBitsToUint(_15._m0[0u]);\n    SV_TARGET = vec4(texture(nonuniformEXT(sampler2DArrayShadow(_9[_39], _19[_39])), vec4(vec3(TEXCOORD.x, TEXCOORD.y, LAYER), DEPTH_REF))).x;\n    SV_TARGET_1 = vec4(textureOffset(nonuniformEXT(sampler2DArrayShadow(_9[_39], _19[_39])), vec4(vec3(TEXCOORD.x, TEXCOORD.y, LAYER), DEPTH_REF), ivec2(-1, 0))).x;\n    SV_TARGET_2 = vec4(textureGrad(nonuniformEXT(sampler2DArrayShadow(_9[_39], _19[_39])), vec4(vec3(TEXCOORD.x, TEXCOORD.y, LAYER), DEPTH_REF), vec2(0.0), vec2(0.0))).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 144\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %42 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %48 NonUniform\n               OpDecorate %66 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %65 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %85 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %142\n\n        %142 = OpLabel\n         %40 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %41 =   OpLoad %float %40\n         %42 =   OpBitcast %uint %41\n         %44 =   OpAccessChain %_ptr_UniformConstant_6 %9 %42\n         %45 =   OpLoad %6 %44\n         %47 =   OpAccessChain %_ptr_UniformConstant_16 %19 %42\n         %48 =   OpLoad %16 %47\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %50 =   OpLoad %float %49\n         %51 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %53 =   OpLoad %float %51\n         %57 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %58 =   OpLoad %int %57\n         %59 =   OpBitcast %uint %58\n         %60 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %61 =   OpLoad %int %60\n         %62 =   OpBitcast %uint %61\n         %66 =   OpSampledImage %65 %45 %48\n         %67 =   OpCompositeConstruct %v2float %50 %53\n         %68 =   OpImageGather %v4float %66 %67 %uint_0\n         %69 =   OpCompositeExtract %float %68 0\n         %70 =   OpCompositeExtract %float %68 1\n         %71 =   OpCompositeExtract %float %68 2\n         %72 =   OpCompositeExtract %float %68 3\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %75 %69\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %76 %70\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %77 %71\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %79 %72\n         %81 =   OpCompositeConstruct %v2float %50 %53\n         %84 =   OpImageGather %v4float %66 %81 %uint_0 ConstOffset %85\n         %86 =   OpCompositeExtract %float %84 0\n         %87 =   OpCompositeExtract %float %84 1\n         %88 =   OpCompositeExtract %float %84 2\n         %89 =   OpCompositeExtract %float %84 3\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %94 %89\n         %95 =   OpCompositeConstruct %v2float %50 %53\n         %96 =   OpImageGather %v4float %66 %95 %uint_1\n         %97 =   OpCompositeExtract %float %96 0\n         %98 =   OpCompositeExtract %float %96 1\n         %99 =   OpCompositeExtract %float %96 2\n        %100 =   OpCompositeExtract %float %96 3\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %102 %97\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %103 %98\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %104 %99\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %105 %100\n        %106 =   OpCompositeConstruct %v2float %50 %53\n        %107 =   OpImageGather %v4float %66 %106 %uint_2\n        %108 =   OpCompositeExtract %float %107 0\n        %109 =   OpCompositeExtract %float %107 1\n        %110 =   OpCompositeExtract %float %107 2\n        %111 =   OpCompositeExtract %float %107 3\n        %113 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %113 %108\n        %114 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %114 %109\n        %115 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %115 %110\n        %116 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %116 %111\n        %117 =   OpCompositeConstruct %v2float %50 %53\n        %118 =   OpImageGather %v4float %66 %117 %uint_3\n        %119 =   OpCompositeExtract %float %118 0\n        %120 =   OpCompositeExtract %float %118 1\n        %121 =   OpCompositeExtract %float %118 2\n        %122 =   OpCompositeExtract %float %118 3\n        %124 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %124 %119\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %125 %120\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %126 %121\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %127 %122\n        %128 =   OpCompositeConstruct %v2float %50 %53\n        %129 =   OpBitcast %int %59\n        %130 =   OpBitcast %int %62\n        %132 =   OpCompositeConstruct %v2int %129 %130\n        %131 =   OpImageGather %v4float %66 %128 %uint_0 Offset %132\n        %133 =   OpCompositeExtract %float %131 0\n        %134 =   OpCompositeExtract %float %131 1\n        %135 =   OpCompositeExtract %float %131 2\n        %136 =   OpCompositeExtract %float %131 3\n        %138 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %138 %133\n        %139 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %139 %134\n        %140 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %140 %135\n        %141 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %141 %136\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_gather.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\n\nvoid main()\n{\n    uint _42 = floatBitsToUint(_15._m0[0u]);\n    vec4 _68 = textureGather(nonuniformEXT(sampler2D(_9[_42], _19[_42])), vec2(TEXCOORD.x, TEXCOORD.y));\n    SV_TARGET.x = _68.x;\n    SV_TARGET.y = _68.y;\n    SV_TARGET.z = _68.z;\n    SV_TARGET.w = _68.w;\n    vec4 _84 = textureGatherOffset(nonuniformEXT(sampler2D(_9[_42], _19[_42])), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(-1, 0));\n    SV_TARGET_1.x = _84.x;\n    SV_TARGET_1.y = _84.y;\n    SV_TARGET_1.z = _84.z;\n    SV_TARGET_1.w = _84.w;\n    vec4 _96 = textureGather(nonuniformEXT(sampler2D(_9[_42], _19[_42])), vec2(TEXCOORD.x, TEXCOORD.y), int(1u));\n    SV_TARGET_2.x = _96.x;\n    SV_TARGET_2.y = _96.y;\n    SV_TARGET_2.z = _96.z;\n    SV_TARGET_2.w = _96.w;\n    vec4 _107 = textureGather(nonuniformEXT(sampler2D(_9[_42], _19[_42])), vec2(TEXCOORD.x, TEXCOORD.y), int(2u));\n    SV_TARGET_3.x = _107.x;\n    SV_TARGET_3.y = _107.y;\n    SV_TARGET_3.z = _107.z;\n    SV_TARGET_3.w = _107.w;\n    vec4 _118 = textureGather(nonuniformEXT(sampler2D(_9[_42], _19[_42])), vec2(TEXCOORD.x, TEXCOORD.y), int(3u));\n    SV_TARGET_4.x = _118.x;\n    SV_TARGET_4.y = _118.y;\n    SV_TARGET_4.z = _118.z;\n    SV_TARGET_4.w = _118.w;\n    vec4 _131 = textureGatherOffset(nonuniformEXT(sampler2D(_9[_42], _19[_42])), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_5.x = _131.x;\n    SV_TARGET_5.y = _131.y;\n    SV_TARGET_5.z = _131.z;\n    SV_TARGET_5.w = _131.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 110\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageGatherExtended\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %39 NonUniform\n               OpDecorate %42 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %65 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v2int = OpTypeVector %int 2\n%_ptr_Input_v2int = OpTypePointer Input %v2int\n     %OFFSET = OpVariable %_ptr_Input_v2int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_int = OpTypePointer Input %int\n     %v2uint = OpTypeVector %uint 2\n         %63 = OpTypeImage %float 2D 1 0 0 1 Unknown\n         %64 = OpTypeSampledImage %63\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n         %84 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %108\n\n        %108 = OpLabel\n         %37 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %38 =   OpLoad %float %37\n         %39 =   OpBitcast %uint %38\n         %41 =   OpAccessChain %_ptr_UniformConstant_6 %9 %39\n         %42 =   OpLoad %6 %41\n         %44 =   OpAccessChain %_ptr_UniformConstant_16 %19 %39\n         %45 =   OpLoad %16 %44\n         %46 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %47 =   OpLoad %float %46\n         %48 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %50 =   OpLoad %float %48\n         %53 =   OpLoad %float %DEPTH_REF\n         %55 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_0\n         %56 =   OpLoad %int %55\n         %57 =   OpBitcast %uint %56\n         %58 =   OpAccessChain %_ptr_Input_int %OFFSET %uint_1\n         %59 =   OpLoad %int %58\n         %60 =   OpBitcast %uint %59\n         %65 =   OpSampledImage %64 %42 %45\n         %66 =   OpCompositeConstruct %v2float %47 %50\n         %67 =   OpImageDrefGather %v4float %65 %66 %53\n         %68 =   OpCompositeExtract %float %67 0\n         %69 =   OpCompositeExtract %float %67 1\n         %70 =   OpCompositeExtract %float %67 2\n         %71 =   OpCompositeExtract %float %67 3\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %74 %68\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %75 %69\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %76 %70\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %78 %71\n         %80 =   OpCompositeConstruct %v2float %47 %50\n         %83 =   OpImageDrefGather %v4float %65 %80 %53 ConstOffset %84\n         %85 =   OpCompositeExtract %float %83 0\n         %86 =   OpCompositeExtract %float %83 1\n         %87 =   OpCompositeExtract %float %83 2\n         %88 =   OpCompositeExtract %float %83 3\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %93 %88\n         %94 =   OpCompositeConstruct %v2float %47 %50\n         %95 =   OpBitcast %int %57\n         %96 =   OpBitcast %int %60\n         %98 =   OpCompositeConstruct %v2int %95 %96\n         %97 =   OpImageDrefGather %v4float %65 %94 %53 Offset %98\n         %99 =   OpCompositeExtract %float %97 0\n        %100 =   OpCompositeExtract %float %97 1\n        %101 =   OpCompositeExtract %float %97 2\n        %102 =   OpCompositeExtract %float %97 3\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %104 %99\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %105 %100\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %106 %101\n        %107 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %107 %102\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec2 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\n\nvoid main()\n{\n    uint _39 = floatBitsToUint(_15._m0[0u]);\n    vec2 _66 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _67 = textureGather(nonuniformEXT(sampler2DShadow(_9[_39], _19[_39])), _66, DEPTH_REF);\n    SV_TARGET.x = _67.x;\n    SV_TARGET.y = _67.y;\n    SV_TARGET.z = _67.z;\n    SV_TARGET.w = _67.w;\n    vec2 _80 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _83 = textureGatherOffset(nonuniformEXT(sampler2DShadow(_9[_39], _19[_39])), _80, DEPTH_REF, ivec2(-1, 0));\n    SV_TARGET_1.x = _83.x;\n    SV_TARGET_1.y = _83.y;\n    SV_TARGET_1.z = _83.z;\n    SV_TARGET_1.w = _83.w;\n    vec2 _94 = vec2(TEXCOORD.x, TEXCOORD.y);\n    vec4 _97 = textureGatherOffset(nonuniformEXT(sampler2DShadow(_9[_39], _19[_39])), _94, DEPTH_REF, ivec2(int(uint(OFFSET.x)), int(uint(OFFSET.y))));\n    SV_TARGET_2.x = _97.x;\n    SV_TARGET_2.y = _97.y;\n    SV_TARGET_2.z = _97.z;\n    SV_TARGET_2.w = _97.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %27 NonUniform\n               OpDecorate %30 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %59 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %69\n\n         %69 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %30 =   OpLoad %6 %29\n         %32 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %33 =   OpLoad %uint %32\n         %34 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %36 =   OpLoad %uint %34\n         %40 =   OpCompositeConstruct %v2uint %33 %36\n         %39 =   OpImageFetch %v4float %30 %40 Lod %uint_1\n         %41 =   OpCompositeExtract %float %39 0\n         %42 =   OpCompositeExtract %float %39 1\n         %43 =   OpCompositeExtract %float %39 2\n         %44 =   OpCompositeExtract %float %39 3\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %47 %41\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %48 %42\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %49 %43\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %51 %44\n         %57 =   OpCompositeConstruct %v2uint %33 %36\n         %56 =   OpImageFetch %v4float %30 %57 Lod|ConstOffset %uint_1 %59\n         %60 =   OpCompositeExtract %float %56 0\n         %61 =   OpCompositeExtract %float %56 1\n         %62 =   OpCompositeExtract %float %56 2\n         %63 =   OpCompositeExtract %float %56 3\n         %65 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %65 %60\n         %66 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %66 %61\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %67 %62\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %68 %63\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    uint _27 = floatBitsToUint(_15._m0[0u]);\n    vec4 _39 = texelFetch(_9[nonuniformEXT(_27)], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(1u));\n    SV_TARGET.x = _39.x;\n    SV_TARGET.y = _39.y;\n    SV_TARGET.z = _39.z;\n    SV_TARGET.w = _39.w;\n    vec4 _56 = texelFetchOffset(_9[nonuniformEXT(_27)], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(1u), ivec2(-1, 0));\n    SV_TARGET_1.x = _56.x;\n    SV_TARGET_1.y = _56.y;\n    SV_TARGET_1.z = _56.z;\n    SV_TARGET_1.w = _56.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 73\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SampleRateShading\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_SAMPLEINDEX %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_SAMPLEINDEX \"SV_SAMPLEINDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_SAMPLEINDEX BuiltIn SampleId\n               OpDecorate %SV_SAMPLEINDEX Flat\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %29 NonUniform\n               OpDecorate %32 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 1 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_SAMPLEINDEX = OpVariable %_ptr_Input_uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %61 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %71\n\n         %71 = OpLabel\n         %27 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %28 =   OpLoad %float %27\n         %29 =   OpBitcast %uint %28\n         %31 =   OpAccessChain %_ptr_UniformConstant_6 %9 %29\n         %32 =   OpLoad %6 %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %34 =   OpLoad %uint %33\n         %35 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %37 =   OpLoad %uint %35\n         %40 =   OpLoad %uint %SV_SAMPLEINDEX\n         %43 =   OpCompositeConstruct %v3uint %34 %37 %uint_2\n         %42 =   OpImageFetch %v4float %32 %43 Sample %40\n         %44 =   OpCompositeExtract %float %42 0\n         %45 =   OpCompositeExtract %float %42 1\n         %46 =   OpCompositeExtract %float %42 2\n         %47 =   OpCompositeExtract %float %42 3\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %50 %44\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %51 %45\n         %52 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %52 %46\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %53 %47\n         %59 =   OpCompositeConstruct %v3uint %34 %37 %uint_2\n         %58 =   OpImageFetch %v4float %32 %59 ConstOffset|Sample %61 %40\n         %62 =   OpCompositeExtract %float %58 0\n         %63 =   OpCompositeExtract %float %58 1\n         %64 =   OpCompositeExtract %float %58 2\n         %65 =   OpCompositeExtract %float %58 3\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %67 %62\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %68 %63\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %69 %64\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %70 %65\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DMSArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    uint _29 = floatBitsToUint(_15._m0[0u]);\n    vec4 _42 = texelFetch(_9[nonuniformEXT(_29)], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), int(uint(gl_SampleID)));\n    SV_TARGET.x = _42.x;\n    SV_TARGET.y = _42.y;\n    SV_TARGET.z = _42.z;\n    SV_TARGET.w = _42.w;\n    vec4 _58 = texelFetchOffset(_9[nonuniformEXT(_29)], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), ivec2(-1, 0), int(uint(gl_SampleID)));\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    SV_TARGET_1.z = _58.z;\n    SV_TARGET_1.w = _58.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 1 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %v3uint = OpTypeVector %uint 3\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %42\n\n         %42 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpImageQuerySize %v3uint %29\n         %32 =   OpCompositeExtract %uint %31 0\n         %33 =   OpCompositeExtract %uint %31 1\n         %34 =   OpCompositeConstruct %v2uint %32 %33\n         %35 =   OpCompositeExtract %uint %31 2\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %39 %33\n                 OpStore %SV_TARGET_1 %35\n         %41 =   OpImageQuerySamples %uint %29\n                 OpStore %SV_TARGET_3 %41\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _36\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DMSArray _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _26 = floatBitsToUint(_15._m0[0u]);\n    uvec3 _31 = uvec3(textureSize(_9[nonuniformEXT(_26)]));\n    uint _32 = _31.x;\n    SV_TARGET.x = _32;\n    SV_TARGET.y = _31.y;\n    SV_TARGET_1 = _31.z;\n    SV_TARGET_3 = uint(textureSamples(_9[nonuniformEXT(_26)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 73\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SampleRateShading\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_SAMPLEINDEX %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_SAMPLEINDEX \"SV_SAMPLEINDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_SAMPLEINDEX BuiltIn SampleId\n               OpDecorate %SV_SAMPLEINDEX Flat\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %29 NonUniform\n               OpDecorate %32 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 1 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n%SV_SAMPLEINDEX = OpVariable %_ptr_Input_uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %61 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %71\n\n         %71 = OpLabel\n         %27 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %28 =   OpLoad %float %27\n         %29 =   OpBitcast %uint %28\n         %31 =   OpAccessChain %_ptr_UniformConstant_6 %9 %29\n         %32 =   OpLoad %6 %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %34 =   OpLoad %uint %33\n         %35 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %37 =   OpLoad %uint %35\n         %40 =   OpLoad %uint %SV_SAMPLEINDEX\n         %42 =   OpCompositeConstruct %v2uint %34 %37\n         %41 =   OpImageFetch %v4float %32 %42 Sample %40\n         %43 =   OpCompositeExtract %float %41 0\n         %44 =   OpCompositeExtract %float %41 1\n         %45 =   OpCompositeExtract %float %41 2\n         %46 =   OpCompositeExtract %float %41 3\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %49 %43\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %50 %44\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %51 %45\n         %53 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %53 %46\n         %59 =   OpCompositeConstruct %v2uint %34 %37\n         %58 =   OpImageFetch %v4float %32 %59 ConstOffset|Sample %61 %40\n         %62 =   OpCompositeExtract %float %58 0\n         %63 =   OpCompositeExtract %float %58 1\n         %64 =   OpCompositeExtract %float %58 2\n         %65 =   OpCompositeExtract %float %58 3\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %67 %62\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %68 %63\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %69 %64\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %70 %65\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DMS _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    uint _29 = floatBitsToUint(_15._m0[0u]);\n    vec4 _41 = texelFetch(_9[nonuniformEXT(_29)], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), int(uint(gl_SampleID)));\n    SV_TARGET.x = _41.x;\n    SV_TARGET.y = _41.y;\n    SV_TARGET.z = _41.z;\n    SV_TARGET.w = _41.w;\n    vec4 _58 = texelFetchOffset(_9[nonuniformEXT(_29)], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), ivec2(-1, 0), int(uint(gl_SampleID)));\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    SV_TARGET_1.z = _58.z;\n    SV_TARGET_1.w = _58.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 1 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %30 =   OpImageQuerySize %v2uint %29\n         %31 =   OpCompositeExtract %uint %30 0\n         %32 =   OpCompositeExtract %uint %30 1\n         %33 =   OpCompositeConstruct %v2uint %31 %32\n         %37 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %38 %32\n                 OpStore %SV_TARGET_1 %uint_1\n         %39 =   OpImageQuerySamples %uint %29\n                 OpStore %SV_TARGET_3 %39\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_ms_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _34\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2DMS _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _26 = floatBitsToUint(_15._m0[0u]);\n    uvec2 _30 = uvec2(textureSize(_9[nonuniformEXT(_26)]));\n    uint _31 = _30.x;\n    SV_TARGET.x = _31;\n    SV_TARGET.y = _30.y;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_3 = uint(textureSamples(_9[nonuniformEXT(_26)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %30 =   OpImageQuerySizeLod %v2uint %29 %uint_0\n         %31 =   OpCompositeExtract %uint %30 0\n         %32 =   OpCompositeExtract %uint %30 1\n         %33 =   OpCompositeConstruct %v2uint %31 %32\n         %37 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %38 %32\n                 OpStore %SV_TARGET_1 %uint_1\n         %39 =   OpImageQueryLevels %uint %29\n                 OpStore %SV_TARGET_2 %39\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _34\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uint _26 = floatBitsToUint(_15._m0[0u]);\n    uvec2 _30 = uvec2(textureSize(_9[nonuniformEXT(_26)], int(0u)));\n    uint _31 = _30.x;\n    SV_TARGET.x = _31;\n    SV_TARGET.y = _30.y;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_9[nonuniformEXT(_26)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 178\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n               OpDecorate %45 NonUniform\n               OpDecorate %48 NonUniform\n               OpDecorate %51 NonUniform\n               OpDecorate %59 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n         %58 = OpTypeSampledImage %6\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %86 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %176\n\n        %176 = OpLabel\n         %43 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %44 =   OpLoad %float %43\n         %45 =   OpBitcast %uint %44\n         %47 =   OpAccessChain %_ptr_UniformConstant_6 %9 %45\n         %48 =   OpLoad %6 %47\n         %50 =   OpAccessChain %_ptr_UniformConstant_16 %19 %45\n         %51 =   OpLoad %16 %50\n         %52 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %53 =   OpLoad %float %52\n         %54 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %56 =   OpLoad %float %54\n         %59 =   OpSampledImage %58 %48 %51\n         %61 =   OpCompositeConstruct %v2float %53 %56\n         %60 =   OpImageQueryLod %v2float %59 %61\n         %62 =   OpCompositeExtract %float %60 0\n         %63 =   OpLoad %float %LOD_BIAS\n         %64 =   OpLoad %float %LOD_CLAMP\n         %67 =   OpCompositeConstruct %v2float %53 %56\n         %66 =   OpImageSampleImplicitLod %v4float %59 %67 None\n         %68 =   OpCompositeExtract %float %66 0\n         %69 =   OpCompositeExtract %float %66 1\n         %70 =   OpCompositeExtract %float %66 2\n         %71 =   OpCompositeExtract %float %66 3\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %74 %68\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %75 %69\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %76 %70\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %78 %71\n         %84 =   OpCompositeConstruct %v2float %53 %56\n         %83 =   OpImageSampleImplicitLod %v4float %59 %84 ConstOffset %86\n         %87 =   OpCompositeExtract %float %83 0\n         %88 =   OpCompositeExtract %float %83 1\n         %89 =   OpCompositeExtract %float %83 2\n         %90 =   OpCompositeExtract %float %83 3\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %93 %88\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %95 %90\n         %97 =   OpCompositeConstruct %v2float %53 %56\n         %96 =   OpImageSampleExplicitLod %v4float %59 %97 Lod %62\n         %98 =   OpCompositeExtract %float %96 0\n         %99 =   OpCompositeExtract %float %96 1\n        %100 =   OpCompositeExtract %float %96 2\n        %101 =   OpCompositeExtract %float %96 3\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %103 %98\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %104 %99\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %105 %100\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %106 %101\n        %108 =   OpCompositeConstruct %v2float %53 %56\n        %107 =   OpImageSampleImplicitLod %v4float %59 %108 Bias %63\n        %109 =   OpCompositeExtract %float %107 0\n        %110 =   OpCompositeExtract %float %107 1\n        %111 =   OpCompositeExtract %float %107 2\n        %112 =   OpCompositeExtract %float %107 3\n        %114 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %114 %109\n        %115 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %115 %110\n        %116 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %116 %111\n        %117 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %117 %112\n        %119 =   OpCompositeConstruct %v2float %53 %56\n        %118 =   OpImageSampleImplicitLod %v4float %59 %119 MinLod %64\n        %120 =   OpCompositeExtract %float %118 0\n        %121 =   OpCompositeExtract %float %118 1\n        %122 =   OpCompositeExtract %float %118 2\n        %123 =   OpCompositeExtract %float %118 3\n        %125 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %125 %120\n        %126 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %126 %121\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %127 %122\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %128 %123\n        %130 =   OpCompositeConstruct %v2float %53 %56\n        %129 =   OpImageSampleImplicitLod %v4float %59 %130 Bias|ConstOffset|MinLod %63 %86 %64\n        %131 =   OpCompositeExtract %float %129 0\n        %132 =   OpCompositeExtract %float %129 1\n        %133 =   OpCompositeExtract %float %129 2\n        %134 =   OpCompositeExtract %float %129 3\n        %136 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %136 %131\n        %137 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %137 %132\n        %138 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %138 %133\n        %139 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %139 %134\n        %140 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %141 =   OpLoad %float %140\n        %142 =   OpDPdx %float %141\n        %143 =   OpDPdy %float %141\n        %144 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %145 =   OpLoad %float %144\n        %146 =   OpDPdx %float %145\n        %147 =   OpDPdy %float %145\n        %151 =   OpCompositeConstruct %v2float %53 %56\n        %152 =   OpCompositeConstruct %v2float %142 %146\n        %153 =   OpCompositeConstruct %v2float %143 %147\n        %150 =   OpImageSampleExplicitLod %v4float %59 %151 Grad %152 %153\n        %154 =   OpCompositeExtract %float %150 0\n        %155 =   OpCompositeExtract %float %150 1\n        %156 =   OpCompositeExtract %float %150 2\n        %157 =   OpCompositeExtract %float %150 3\n        %159 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %159 %154\n        %160 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %160 %155\n        %161 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %161 %156\n        %162 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %162 %157\n        %164 =   OpCompositeConstruct %v2float %53 %56\n        %165 =   OpCompositeConstruct %v2float %142 %146\n        %166 =   OpCompositeConstruct %v2float %143 %147\n        %163 =   OpImageSampleExplicitLod %v4float %59 %164 Grad|ConstOffset %165 %166 %86\n        %167 =   OpCompositeExtract %float %163 0\n        %168 =   OpCompositeExtract %float %163 1\n        %169 =   OpCompositeExtract %float %163 2\n        %170 =   OpCompositeExtract %float %163 3\n        %172 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %172 %167\n        %173 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %173 %168\n        %174 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %174 %169\n        %175 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %175 %170\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    uint _45 = floatBitsToUint(_15._m0[0u]);\n    vec4 _66 = texture(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y));\n    SV_TARGET.x = _66.x;\n    SV_TARGET.y = _66.y;\n    SV_TARGET.z = _66.z;\n    SV_TARGET.w = _66.w;\n    vec4 _83 = textureOffset(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(-1, 0));\n    SV_TARGET_1.x = _83.x;\n    SV_TARGET_1.y = _83.y;\n    SV_TARGET_1.z = _83.z;\n    SV_TARGET_1.w = _83.w;\n    vec4 _96 = textureLod(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y), textureQueryLod(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y)).x);\n    SV_TARGET_2.x = _96.x;\n    SV_TARGET_2.y = _96.y;\n    SV_TARGET_2.z = _96.z;\n    SV_TARGET_2.w = _96.w;\n    vec4 _107 = texture(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y), LOD_BIAS);\n    SV_TARGET_3.x = _107.x;\n    SV_TARGET_3.y = _107.y;\n    SV_TARGET_3.z = _107.z;\n    SV_TARGET_3.w = _107.w;\n    vec4 _118 = textureClampARB(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y), LOD_CLAMP);\n    SV_TARGET_4.x = _118.x;\n    SV_TARGET_4.y = _118.y;\n    SV_TARGET_4.z = _118.z;\n    SV_TARGET_4.w = _118.w;\n    vec4 _129 = textureOffsetClampARB(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y), ivec2(-1, 0), LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _129.x;\n    SV_TARGET_5.y = _129.y;\n    SV_TARGET_5.z = _129.z;\n    SV_TARGET_5.w = _129.w;\n    float _142 = dFdx(TEXCOORD_2.x);\n    float _143 = dFdy(TEXCOORD_2.x);\n    float _146 = dFdx(TEXCOORD_2.y);\n    float _147 = dFdy(TEXCOORD_2.y);\n    vec4 _150 = textureGrad(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y), vec2(_142, _146), vec2(_143, _147));\n    SV_TARGET_6.x = _150.x;\n    SV_TARGET_6.y = _150.y;\n    SV_TARGET_6.z = _150.z;\n    SV_TARGET_6.w = _150.w;\n    vec4 _163 = textureGradOffset(nonuniformEXT(sampler2D(_9[_45], _19[_45])), vec2(TEXCOORD.x, TEXCOORD.y), vec2(_142, _146), vec2(_143, _147), ivec2(-1, 0));\n    SV_TARGET_7.x = _163.x;\n    SV_TARGET_7.y = _163.y;\n    SV_TARGET_7.z = _163.z;\n    SV_TARGET_7.w = _163.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 79\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %39 NonUniform\n               OpDecorate %42 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %57 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n    %v2float = OpTypeVector %float 2\n%_ptr_Input_v2float = OpTypePointer Input %v2float\n %TEXCOORD_2 = OpVariable %_ptr_Input_v2float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n         %55 = OpTypeImage %float 2D 1 0 0 1 Unknown\n         %56 = OpTypeSampledImage %55\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %v2int = OpTypeVector %int 2\n         %70 = OpConstantComposite %v2int %int_n1 %int_0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %77\n\n         %77 = OpLabel\n         %37 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %38 =   OpLoad %float %37\n         %39 =   OpBitcast %uint %38\n         %41 =   OpAccessChain %_ptr_UniformConstant_6 %9 %39\n         %42 =   OpLoad %6 %41\n         %44 =   OpAccessChain %_ptr_UniformConstant_16 %19 %39\n         %45 =   OpLoad %16 %44\n         %46 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %47 =   OpLoad %float %46\n         %48 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %50 =   OpLoad %float %48\n         %52 =   OpLoad %float %DEPTH_REF\n         %57 =   OpSampledImage %56 %42 %45\n         %60 =   OpCompositeConstruct %v2float %47 %50\n         %59 =   OpImageSampleDrefImplicitLod %float %57 %60 %52 None\n         %62 =   OpCompositeConstruct %v4float %59 %59 %59 %59\n         %63 =   OpCompositeExtract %float %62 0\n                 OpStore %SV_TARGET %63\n         %68 =   OpCompositeConstruct %v2float %47 %50\n         %67 =   OpImageSampleDrefImplicitLod %float %57 %68 %52 ConstOffset %70\n         %71 =   OpCompositeConstruct %v4float %67 %67 %67 %67\n         %72 =   OpCompositeExtract %float %71 0\n                 OpStore %SV_TARGET_1 %72\n         %74 =   OpCompositeConstruct %v2float %47 %50\n         %73 =   OpImageSampleDrefExplicitLod %float %57 %74 %52 Lod %float_0\n         %75 =   OpCompositeConstruct %v4float %73 %73 %73 %73\n         %76 =   OpCompositeExtract %float %75 0\n                 OpStore %SV_TARGET_2 %76\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_2d_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture2D _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec2 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\nlayout(location = 2) out float SV_TARGET_2;\n\nvoid main()\n{\n    uint _39 = floatBitsToUint(_15._m0[0u]);\n    SV_TARGET = vec4(texture(nonuniformEXT(sampler2DShadow(_9[_39], _19[_39])), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DEPTH_REF))).x;\n    SV_TARGET_1 = vec4(textureOffset(nonuniformEXT(sampler2DShadow(_9[_39], _19[_39])), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DEPTH_REF), ivec2(-1, 0))).x;\n    SV_TARGET_2 = vec4(textureLod(nonuniformEXT(sampler2DShadow(_9[_39], _19[_39])), vec3(vec2(TEXCOORD.x, TEXCOORD.y), DEPTH_REF), 0.0)).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_3d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 73\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %27 NonUniform\n               OpDecorate %30 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %int_1 = OpConstant %int 1\n      %v3int = OpTypeVector %int 3\n         %61 = OpConstantComposite %v3int %int_n1 %int_0 %int_1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %71\n\n         %71 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %30 =   OpLoad %6 %29\n         %32 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %33 =   OpLoad %uint %32\n         %34 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %36 =   OpLoad %uint %34\n         %37 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %39 =   OpLoad %uint %37\n         %42 =   OpCompositeConstruct %v3uint %33 %36 %39\n         %41 =   OpImageFetch %v4float %30 %42 Lod %uint_1\n         %43 =   OpCompositeExtract %float %41 0\n         %44 =   OpCompositeExtract %float %41 1\n         %45 =   OpCompositeExtract %float %41 2\n         %46 =   OpCompositeExtract %float %41 3\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %49 %43\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %50 %44\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %51 %45\n         %52 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %52 %46\n         %59 =   OpCompositeConstruct %v3uint %33 %36 %39\n         %58 =   OpImageFetch %v4float %30 %59 Lod|ConstOffset %uint_1 %61\n         %62 =   OpCompositeExtract %float %58 0\n         %63 =   OpCompositeExtract %float %58 1\n         %64 =   OpCompositeExtract %float %58 2\n         %65 =   OpCompositeExtract %float %58 3\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %67 %62\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %68 %63\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %69 %64\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %70 %65\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_3d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture3D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    uint _27 = floatBitsToUint(_15._m0[0u]);\n    vec4 _41 = texelFetch(_9[nonuniformEXT(_27)], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(1u));\n    SV_TARGET.x = _41.x;\n    SV_TARGET.y = _41.y;\n    SV_TARGET.z = _41.z;\n    SV_TARGET.w = _41.w;\n    vec4 _58 = texelFetchOffset(_9[nonuniformEXT(_27)], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), int(1u), ivec3(-1, 0, 1));\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    SV_TARGET_1.z = _58.z;\n    SV_TARGET_1.w = _58.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_3d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 45\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Output_v3uint = OpTypePointer Output %v3uint\n  %SV_TARGET = OpVariable %_ptr_Output_v3uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %v3uint %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %43\n\n         %43 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %30 =   OpImageQuerySizeLod %v3uint %29 %uint_0\n         %31 =   OpCompositeExtract %uint %30 0\n         %32 =   OpCompositeExtract %uint %30 1\n         %33 =   OpCompositeExtract %uint %30 2\n         %34 =   OpCompositeConstruct %v3uint %31 %32 %33\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %38 %31\n         %39 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %39 %32\n         %40 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_2\n                 OpStore %40 %33\n                 OpStore %SV_TARGET_1 %uint_1\n         %42 =   OpImageQueryLevels %uint %29\n                 OpStore %SV_TARGET_2 %42\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_3d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _35\n{\n    uvec3 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture3D _9[];\n\nlayout(location = 0) out uvec3 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uint _26 = floatBitsToUint(_15._m0[0u]);\n    uvec3 _30 = uvec3(textureSize(_9[nonuniformEXT(_26)], int(0u)));\n    uint _31 = _30.x;\n    SV_TARGET.x = _31;\n    SV_TARGET.y = _30.y;\n    SV_TARGET.z = _30.z;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_9[nonuniformEXT(_26)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_3d_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 184\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4 %SV_TARGET_5 %SV_TARGET_6 %SV_TARGET_7\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpName %SV_TARGET_5 \"SV_TARGET_5\"\n               OpName %SV_TARGET_6 \"SV_TARGET_6\"\n               OpName %SV_TARGET_7 \"SV_TARGET_7\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %SV_TARGET_5 Location 5\n               OpDecorate %SV_TARGET_6 Location 6\n               OpDecorate %SV_TARGET_7 Location 7\n               OpDecorate %43 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %49 NonUniform\n               OpDecorate %60 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_5 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_6 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_7 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %59 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n        %int = OpTypeInt 32 1\n     %int_n1 = OpConstant %int -1\n      %int_0 = OpConstant %int 0\n      %int_1 = OpConstant %int 1\n      %v3int = OpTypeVector %int 3\n         %88 = OpConstantComposite %v3int %int_n1 %int_0 %int_1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %182\n\n        %182 = OpLabel\n         %41 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %42 =   OpLoad %float %41\n         %43 =   OpBitcast %uint %42\n         %45 =   OpAccessChain %_ptr_UniformConstant_6 %9 %43\n         %46 =   OpLoad %6 %45\n         %48 =   OpAccessChain %_ptr_UniformConstant_16 %19 %43\n         %49 =   OpLoad %16 %48\n         %50 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %51 =   OpLoad %float %50\n         %52 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %54 =   OpLoad %float %52\n         %55 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %57 =   OpLoad %float %55\n         %60 =   OpSampledImage %59 %46 %49\n         %63 =   OpCompositeConstruct %v3float %51 %54 %57\n         %62 =   OpImageQueryLod %v2float %60 %63\n         %64 =   OpCompositeExtract %float %62 0\n         %65 =   OpLoad %float %LOD_BIAS\n         %66 =   OpLoad %float %LOD_CLAMP\n         %69 =   OpCompositeConstruct %v3float %51 %54 %57\n         %68 =   OpImageSampleImplicitLod %v4float %60 %69 None\n         %70 =   OpCompositeExtract %float %68 0\n         %71 =   OpCompositeExtract %float %68 1\n         %72 =   OpCompositeExtract %float %68 2\n         %73 =   OpCompositeExtract %float %68 3\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %76 %70\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %77 %71\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %78 %72\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %79 %73\n         %86 =   OpCompositeConstruct %v3float %51 %54 %57\n         %85 =   OpImageSampleImplicitLod %v4float %60 %86 ConstOffset %88\n         %89 =   OpCompositeExtract %float %85 0\n         %90 =   OpCompositeExtract %float %85 1\n         %91 =   OpCompositeExtract %float %85 2\n         %92 =   OpCompositeExtract %float %85 3\n         %94 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %94 %89\n         %95 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %95 %90\n         %96 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %96 %91\n         %97 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %97 %92\n         %99 =   OpCompositeConstruct %v3float %51 %54 %57\n         %98 =   OpImageSampleExplicitLod %v4float %60 %99 Lod %64\n        %100 =   OpCompositeExtract %float %98 0\n        %101 =   OpCompositeExtract %float %98 1\n        %102 =   OpCompositeExtract %float %98 2\n        %103 =   OpCompositeExtract %float %98 3\n        %105 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %105 %100\n        %106 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %106 %101\n        %107 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %107 %102\n        %108 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %108 %103\n        %110 =   OpCompositeConstruct %v3float %51 %54 %57\n        %109 =   OpImageSampleImplicitLod %v4float %60 %110 Bias %65\n        %111 =   OpCompositeExtract %float %109 0\n        %112 =   OpCompositeExtract %float %109 1\n        %113 =   OpCompositeExtract %float %109 2\n        %114 =   OpCompositeExtract %float %109 3\n        %116 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %116 %111\n        %117 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %117 %112\n        %118 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %118 %113\n        %119 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %119 %114\n        %121 =   OpCompositeConstruct %v3float %51 %54 %57\n        %120 =   OpImageSampleImplicitLod %v4float %60 %121 MinLod %66\n        %122 =   OpCompositeExtract %float %120 0\n        %123 =   OpCompositeExtract %float %120 1\n        %124 =   OpCompositeExtract %float %120 2\n        %125 =   OpCompositeExtract %float %120 3\n        %127 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %127 %122\n        %128 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %128 %123\n        %129 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %129 %124\n        %130 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %130 %125\n        %132 =   OpCompositeConstruct %v3float %51 %54 %57\n        %131 =   OpImageSampleImplicitLod %v4float %60 %132 Bias|ConstOffset|MinLod %65 %88 %66\n        %133 =   OpCompositeExtract %float %131 0\n        %134 =   OpCompositeExtract %float %131 1\n        %135 =   OpCompositeExtract %float %131 2\n        %136 =   OpCompositeExtract %float %131 3\n        %138 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_0\n                 OpStore %138 %133\n        %139 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_1\n                 OpStore %139 %134\n        %140 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_2\n                 OpStore %140 %135\n        %141 =   OpAccessChain %_ptr_Output_float %SV_TARGET_5 %uint_3\n                 OpStore %141 %136\n        %142 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %143 =   OpLoad %float %142\n        %144 =   OpDPdx %float %143\n        %145 =   OpDPdy %float %143\n        %146 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %147 =   OpLoad %float %146\n        %148 =   OpDPdx %float %147\n        %149 =   OpDPdy %float %147\n        %150 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_2\n        %151 =   OpLoad %float %150\n        %152 =   OpDPdx %float %151\n        %153 =   OpDPdy %float %151\n        %157 =   OpCompositeConstruct %v3float %51 %54 %57\n        %158 =   OpCompositeConstruct %v3float %144 %148 %152\n        %159 =   OpCompositeConstruct %v3float %145 %149 %153\n        %156 =   OpImageSampleExplicitLod %v4float %60 %157 Grad %158 %159\n        %160 =   OpCompositeExtract %float %156 0\n        %161 =   OpCompositeExtract %float %156 1\n        %162 =   OpCompositeExtract %float %156 2\n        %163 =   OpCompositeExtract %float %156 3\n        %165 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_0\n                 OpStore %165 %160\n        %166 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_1\n                 OpStore %166 %161\n        %167 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_2\n                 OpStore %167 %162\n        %168 =   OpAccessChain %_ptr_Output_float %SV_TARGET_6 %uint_3\n                 OpStore %168 %163\n        %170 =   OpCompositeConstruct %v3float %51 %54 %57\n        %171 =   OpCompositeConstruct %v3float %144 %148 %152\n        %172 =   OpCompositeConstruct %v3float %145 %149 %153\n        %169 =   OpImageSampleExplicitLod %v4float %60 %170 Grad|ConstOffset %171 %172 %88\n        %173 =   OpCompositeExtract %float %169 0\n        %174 =   OpCompositeExtract %float %169 1\n        %175 =   OpCompositeExtract %float %169 2\n        %176 =   OpCompositeExtract %float %169 3\n        %178 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_0\n                 OpStore %178 %173\n        %179 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_1\n                 OpStore %179 %174\n        %180 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_2\n                 OpStore %180 %175\n        %181 =   OpAccessChain %_ptr_Output_float %SV_TARGET_7 %uint_3\n                 OpStore %181 %176\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_3d_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform texture3D _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\nlayout(location = 5) out vec4 SV_TARGET_5;\nlayout(location = 6) out vec4 SV_TARGET_6;\nlayout(location = 7) out vec4 SV_TARGET_7;\n\nvoid main()\n{\n    uint _43 = floatBitsToUint(_15._m0[0u]);\n    vec4 _68 = texture(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    SV_TARGET.x = _68.x;\n    SV_TARGET.y = _68.y;\n    SV_TARGET.z = _68.z;\n    SV_TARGET.w = _68.w;\n    vec4 _85 = textureOffset(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec3(-1, 0, 1));\n    SV_TARGET_1.x = _85.x;\n    SV_TARGET_1.y = _85.y;\n    SV_TARGET_1.z = _85.z;\n    SV_TARGET_1.w = _85.w;\n    vec4 _98 = textureLod(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), textureQueryLod(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x);\n    SV_TARGET_2.x = _98.x;\n    SV_TARGET_2.y = _98.y;\n    SV_TARGET_2.z = _98.z;\n    SV_TARGET_2.w = _98.w;\n    vec4 _109 = texture(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_BIAS);\n    SV_TARGET_3.x = _109.x;\n    SV_TARGET_3.y = _109.y;\n    SV_TARGET_3.z = _109.z;\n    SV_TARGET_3.w = _109.w;\n    vec4 _120 = textureClampARB(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_CLAMP);\n    SV_TARGET_4.x = _120.x;\n    SV_TARGET_4.y = _120.y;\n    SV_TARGET_4.z = _120.z;\n    SV_TARGET_4.w = _120.w;\n    vec4 _131 = textureOffsetClampARB(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), ivec3(-1, 0, 1), LOD_CLAMP, LOD_BIAS);\n    SV_TARGET_5.x = _131.x;\n    SV_TARGET_5.y = _131.y;\n    SV_TARGET_5.z = _131.z;\n    SV_TARGET_5.w = _131.w;\n    float _144 = dFdx(TEXCOORD_2.x);\n    float _145 = dFdy(TEXCOORD_2.x);\n    float _148 = dFdx(TEXCOORD_2.y);\n    float _149 = dFdy(TEXCOORD_2.y);\n    float _152 = dFdx(TEXCOORD_2.z);\n    float _153 = dFdy(TEXCOORD_2.z);\n    vec4 _156 = textureGrad(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(_144, _148, _152), vec3(_145, _149, _153));\n    SV_TARGET_6.x = _156.x;\n    SV_TARGET_6.y = _156.y;\n    SV_TARGET_6.z = _156.z;\n    SV_TARGET_6.w = _156.w;\n    vec4 _169 = textureGradOffset(nonuniformEXT(sampler3D(_9[_43], _19[_43])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(_144, _148, _152), vec3(_145, _149, _153), ivec3(-1, 0, 1));\n    SV_TARGET_7.x = _169.x;\n    SV_TARGET_7.y = _169.y;\n    SV_TARGET_7.z = _169.z;\n    SV_TARGET_7.w = _169.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 107\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SampledCubeArray\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %40 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %58 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %57 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %105\n\n        %105 = OpLabel\n         %38 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %39 =   OpLoad %float %38\n         %40 =   OpBitcast %uint %39\n         %42 =   OpAccessChain %_ptr_UniformConstant_6 %9 %40\n         %43 =   OpLoad %6 %42\n         %45 =   OpAccessChain %_ptr_UniformConstant_16 %19 %40\n         %46 =   OpLoad %16 %45\n         %47 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %48 =   OpLoad %float %47\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %54 =   OpLoad %float %52\n         %56 =   OpLoad %float %LAYER\n         %58 =   OpSampledImage %57 %43 %46\n         %59 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n         %60 =   OpImageGather %v4float %58 %59 %uint_0\n         %61 =   OpCompositeExtract %float %60 0\n         %62 =   OpCompositeExtract %float %60 1\n         %63 =   OpCompositeExtract %float %60 2\n         %64 =   OpCompositeExtract %float %60 3\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %67 %61\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %68 %62\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %69 %63\n         %70 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %70 %64\n         %72 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n         %73 =   OpImageGather %v4float %58 %72 %uint_1\n         %74 =   OpCompositeExtract %float %73 0\n         %75 =   OpCompositeExtract %float %73 1\n         %76 =   OpCompositeExtract %float %73 2\n         %77 =   OpCompositeExtract %float %73 3\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %79 %74\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %80 %75\n         %81 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %81 %76\n         %82 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %82 %77\n         %83 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n         %84 =   OpImageGather %v4float %58 %83 %uint_2\n         %85 =   OpCompositeExtract %float %84 0\n         %86 =   OpCompositeExtract %float %84 1\n         %87 =   OpCompositeExtract %float %84 2\n         %88 =   OpCompositeExtract %float %84 3\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %92 %87\n         %93 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %93 %88\n         %94 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n         %95 =   OpImageGather %v4float %58 %94 %uint_3\n         %96 =   OpCompositeExtract %float %95 0\n         %97 =   OpCompositeExtract %float %95 1\n         %98 =   OpCompositeExtract %float %95 2\n         %99 =   OpCompositeExtract %float %95 3\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %101 %96\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %102 %97\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %103 %98\n        %104 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %104 %99\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_gather.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\n\nvoid main()\n{\n    uint _40 = floatBitsToUint(_15._m0[0u]);\n    vec4 _60 = textureGather(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER));\n    SV_TARGET.x = _60.x;\n    SV_TARGET.y = _60.y;\n    SV_TARGET.z = _60.z;\n    SV_TARGET.w = _60.w;\n    vec4 _73 = textureGather(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), int(1u));\n    SV_TARGET_1.x = _73.x;\n    SV_TARGET_1.y = _73.y;\n    SV_TARGET_1.z = _73.z;\n    SV_TARGET_1.w = _73.w;\n    vec4 _84 = textureGather(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), int(2u));\n    SV_TARGET_2.x = _84.x;\n    SV_TARGET_2.y = _84.y;\n    SV_TARGET_2.z = _84.z;\n    SV_TARGET_2.w = _84.w;\n    vec4 _95 = textureGather(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), int(3u));\n    SV_TARGET_3.x = _95.x;\n    SV_TARGET_3.y = _95.y;\n    SV_TARGET_3.z = _95.z;\n    SV_TARGET_3.w = _95.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 73\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SampledCubeArray\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %37 NonUniform\n               OpDecorate %40 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %57 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %55 = OpTypeImage %float Cube 1 1 0 1 Unknown\n         %56 = OpTypeSampledImage %55\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %71\n\n         %71 = OpLabel\n         %35 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %36 =   OpLoad %float %35\n         %37 =   OpBitcast %uint %36\n         %39 =   OpAccessChain %_ptr_UniformConstant_6 %9 %37\n         %40 =   OpLoad %6 %39\n         %42 =   OpAccessChain %_ptr_UniformConstant_16 %19 %37\n         %43 =   OpLoad %16 %42\n         %44 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %45 =   OpLoad %float %44\n         %46 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %48 =   OpLoad %float %46\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %51 =   OpLoad %float %49\n         %53 =   OpLoad %float %DEPTH_REF\n         %54 =   OpLoad %float %LAYER\n         %57 =   OpSampledImage %56 %40 %43\n         %58 =   OpCompositeConstruct %v4float %45 %48 %51 %54\n         %59 =   OpImageDrefGather %v4float %57 %58 %53\n         %60 =   OpCompositeExtract %float %59 0\n         %61 =   OpCompositeExtract %float %59 1\n         %62 =   OpCompositeExtract %float %59 2\n         %63 =   OpCompositeExtract %float %59 3\n         %66 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %66 %60\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %67 %61\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %68 %62\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %69 %63\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    uint _37 = floatBitsToUint(_15._m0[0u]);\n    vec4 _58 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER);\n    vec4 _59 = textureGather(nonuniformEXT(samplerCubeArrayShadow(_9[_37], _19[_37])), _58, DEPTH_REF);\n    SV_TARGET.x = _59.x;\n    SV_TARGET.y = _59.y;\n    SV_TARGET.z = _59.z;\n    SV_TARGET.w = _59.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 44\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SampledCubeArray\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %v3uint = OpTypeVector %uint 3\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %42\n\n         %42 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpImageQuerySizeLod %v3uint %29 %uint_0\n         %32 =   OpCompositeExtract %uint %31 0\n         %33 =   OpCompositeExtract %uint %31 1\n         %34 =   OpCompositeConstruct %v2uint %32 %33\n         %35 =   OpCompositeExtract %uint %31 2\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %39 %33\n                 OpStore %SV_TARGET_1 %35\n         %41 =   OpImageQueryLevels %uint %29\n                 OpStore %SV_TARGET_2 %41\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _36\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uint _26 = floatBitsToUint(_15._m0[0u]);\n    uvec3 _31 = uvec3(textureSize(_9[nonuniformEXT(_26)], int(0u)));\n    uint _32 = _31.x;\n    SV_TARGET.x = _32;\n    SV_TARGET.y = _31.y;\n    SV_TARGET_1 = _31.z;\n    SV_TARGET_2 = uint(textureQueryLevels(_9[nonuniformEXT(_26)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 141\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability MinLod\n               OpCapability SampledCubeArray\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %40 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %58 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %57 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %139\n\n        %139 = OpLabel\n         %38 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %39 =   OpLoad %float %38\n         %40 =   OpBitcast %uint %39\n         %42 =   OpAccessChain %_ptr_UniformConstant_6 %9 %40\n         %43 =   OpLoad %6 %42\n         %45 =   OpAccessChain %_ptr_UniformConstant_16 %19 %40\n         %46 =   OpLoad %16 %45\n         %47 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %48 =   OpLoad %float %47\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %54 =   OpLoad %float %52\n         %56 =   OpLoad %float %LAYER\n         %58 =   OpSampledImage %57 %43 %46\n         %61 =   OpCompositeConstruct %v3float %48 %51 %54\n         %60 =   OpImageQueryLod %v2float %58 %61\n         %62 =   OpCompositeExtract %float %60 0\n         %63 =   OpLoad %float %LOD_BIAS\n         %64 =   OpLoad %float %LOD_CLAMP\n         %67 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n         %66 =   OpImageSampleImplicitLod %v4float %58 %67 None\n         %68 =   OpCompositeExtract %float %66 0\n         %69 =   OpCompositeExtract %float %66 1\n         %70 =   OpCompositeExtract %float %66 2\n         %71 =   OpCompositeExtract %float %66 3\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %74 %68\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %75 %69\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %76 %70\n         %77 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %77 %71\n         %80 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n         %79 =   OpImageSampleExplicitLod %v4float %58 %80 Lod %62\n         %81 =   OpCompositeExtract %float %79 0\n         %82 =   OpCompositeExtract %float %79 1\n         %83 =   OpCompositeExtract %float %79 2\n         %84 =   OpCompositeExtract %float %79 3\n         %86 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %86 %81\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %88 %83\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %89 %84\n         %91 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n         %90 =   OpImageSampleImplicitLod %v4float %58 %91 Bias %63\n         %92 =   OpCompositeExtract %float %90 0\n         %93 =   OpCompositeExtract %float %90 1\n         %94 =   OpCompositeExtract %float %90 2\n         %95 =   OpCompositeExtract %float %90 3\n         %97 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %97 %92\n         %98 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %98 %93\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %99 %94\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %100 %95\n        %102 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n        %101 =   OpImageSampleImplicitLod %v4float %58 %102 MinLod %64\n        %103 =   OpCompositeExtract %float %101 0\n        %104 =   OpCompositeExtract %float %101 1\n        %105 =   OpCompositeExtract %float %101 2\n        %106 =   OpCompositeExtract %float %101 3\n        %108 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %108 %103\n        %109 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %109 %104\n        %110 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %110 %105\n        %111 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %111 %106\n        %112 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %113 =   OpLoad %float %112\n        %114 =   OpDPdx %float %113\n        %115 =   OpDPdy %float %113\n        %116 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %117 =   OpLoad %float %116\n        %118 =   OpDPdx %float %117\n        %119 =   OpDPdy %float %117\n        %120 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_2\n        %121 =   OpLoad %float %120\n        %122 =   OpDPdx %float %121\n        %123 =   OpDPdy %float %121\n        %127 =   OpCompositeConstruct %v4float %48 %51 %54 %56\n        %128 =   OpCompositeConstruct %v3float %114 %118 %122\n        %129 =   OpCompositeConstruct %v3float %115 %119 %123\n        %126 =   OpImageSampleExplicitLod %v4float %58 %127 Grad %128 %129\n        %130 =   OpCompositeExtract %float %126 0\n        %131 =   OpCompositeExtract %float %126 1\n        %132 =   OpCompositeExtract %float %126 2\n        %133 =   OpCompositeExtract %float %126 3\n        %135 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %135 %130\n        %136 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %136 %131\n        %137 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %137 %132\n        %138 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %138 %133\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\n\nvoid main()\n{\n    uint _40 = floatBitsToUint(_15._m0[0u]);\n    vec4 _66 = texture(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER));\n    SV_TARGET.x = _66.x;\n    SV_TARGET.y = _66.y;\n    SV_TARGET.z = _66.z;\n    SV_TARGET.w = _66.w;\n    vec4 _79 = textureLod(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), textureQueryLod(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x);\n    SV_TARGET_1.x = _79.x;\n    SV_TARGET_1.y = _79.y;\n    SV_TARGET_1.z = _79.z;\n    SV_TARGET_1.w = _79.w;\n    vec4 _90 = texture(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), LOD_BIAS);\n    SV_TARGET_2.x = _90.x;\n    SV_TARGET_2.y = _90.y;\n    SV_TARGET_2.z = _90.z;\n    SV_TARGET_2.w = _90.w;\n    vec4 _101 = textureClampARB(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), LOD_CLAMP);\n    SV_TARGET_3.x = _101.x;\n    SV_TARGET_3.y = _101.y;\n    SV_TARGET_3.z = _101.z;\n    SV_TARGET_3.w = _101.w;\n    vec4 _126 = textureGrad(nonuniformEXT(samplerCubeArray(_9[_40], _19[_40])), vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER), vec3(dFdx(TEXCOORD_2.x), dFdx(TEXCOORD_2.y), dFdx(TEXCOORD_2.z)), vec3(dFdy(TEXCOORD_2.x), dFdy(TEXCOORD_2.y), dFdy(TEXCOORD_2.z)));\n    SV_TARGET_4.x = _126.x;\n    SV_TARGET_4.y = _126.y;\n    SV_TARGET_4.z = _126.z;\n    SV_TARGET_4.w = _126.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 71\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SampledCubeArray\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %36 NonUniform\n               OpDecorate %39 NonUniform\n               OpDecorate %42 NonUniform\n               OpDecorate %58 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 1 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %56 = OpTypeImage %float Cube 1 1 0 1 Unknown\n         %57 = OpTypeSampledImage %56\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %69\n\n         %69 = OpLabel\n         %34 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %35 =   OpLoad %float %34\n         %36 =   OpBitcast %uint %35\n         %38 =   OpAccessChain %_ptr_UniformConstant_6 %9 %36\n         %39 =   OpLoad %6 %38\n         %41 =   OpAccessChain %_ptr_UniformConstant_16 %19 %36\n         %42 =   OpLoad %16 %41\n         %43 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %44 =   OpLoad %float %43\n         %45 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %47 =   OpLoad %float %45\n         %48 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %50 =   OpLoad %float %48\n         %52 =   OpLoad %float %DEPTH_REF\n         %53 =   OpLoad %float %LAYER\n         %58 =   OpSampledImage %57 %39 %42\n         %62 =   OpCompositeConstruct %v4float %44 %47 %50 %53\n         %60 =   OpImageSampleDrefImplicitLod %float %58 %62 %52 None\n         %63 =   OpCompositeConstruct %v4float %60 %60 %60 %60\n         %64 =   OpCompositeExtract %float %63 0\n                 OpStore %SV_TARGET %64\n         %66 =   OpCompositeConstruct %v4float %44 %47 %50 %53\n         %65 =   OpImageSampleDrefExplicitLod %float %58 %66 %52 Lod %float_0\n         %67 =   OpCompositeConstruct %v4float %65 %65 %65 %65\n         %68 =   OpCompositeExtract %float %67 0\n                 OpStore %SV_TARGET_1 %68\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_array_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCubeArray _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    uint _36 = floatBitsToUint(_15._m0[0u]);\n    vec4 _62 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER);\n    SV_TARGET = vec4(texture(nonuniformEXT(samplerCubeArrayShadow(_9[_36], _19[_36])), _62, DEPTH_REF)).x;\n    vec4 _66 = vec4(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z, LAYER);\n    SV_TARGET_1 = vec4(textureGrad(nonuniformEXT(samplerCubeArrayShadow(_9[_36], _19[_36])), _66, DEPTH_REF, vec3(0.0), vec3(0.0))).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_gather.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 106\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %40 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %57 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %56 = OpTypeSampledImage %6\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %104\n\n        %104 = OpLabel\n         %38 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %39 =   OpLoad %float %38\n         %40 =   OpBitcast %uint %39\n         %42 =   OpAccessChain %_ptr_UniformConstant_6 %9 %40\n         %43 =   OpLoad %6 %42\n         %45 =   OpAccessChain %_ptr_UniformConstant_16 %19 %40\n         %46 =   OpLoad %16 %45\n         %47 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %48 =   OpLoad %float %47\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %54 =   OpLoad %float %52\n         %57 =   OpSampledImage %56 %43 %46\n         %58 =   OpCompositeConstruct %v3float %48 %51 %54\n         %59 =   OpImageGather %v4float %57 %58 %uint_0\n         %60 =   OpCompositeExtract %float %59 0\n         %61 =   OpCompositeExtract %float %59 1\n         %62 =   OpCompositeExtract %float %59 2\n         %63 =   OpCompositeExtract %float %59 3\n         %66 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %66 %60\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %67 %61\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %68 %62\n         %69 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %69 %63\n         %71 =   OpCompositeConstruct %v3float %48 %51 %54\n         %72 =   OpImageGather %v4float %57 %71 %uint_1\n         %73 =   OpCompositeExtract %float %72 0\n         %74 =   OpCompositeExtract %float %72 1\n         %75 =   OpCompositeExtract %float %72 2\n         %76 =   OpCompositeExtract %float %72 3\n         %78 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %78 %73\n         %79 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %79 %74\n         %80 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %80 %75\n         %81 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %81 %76\n         %82 =   OpCompositeConstruct %v3float %48 %51 %54\n         %83 =   OpImageGather %v4float %57 %82 %uint_2\n         %84 =   OpCompositeExtract %float %83 0\n         %85 =   OpCompositeExtract %float %83 1\n         %86 =   OpCompositeExtract %float %83 2\n         %87 =   OpCompositeExtract %float %83 3\n         %89 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %89 %84\n         %90 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %90 %85\n         %91 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %91 %86\n         %92 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %92 %87\n         %93 =   OpCompositeConstruct %v3float %48 %51 %54\n         %94 =   OpImageGather %v4float %57 %93 %uint_3\n         %95 =   OpCompositeExtract %float %94 0\n         %96 =   OpCompositeExtract %float %94 1\n         %97 =   OpCompositeExtract %float %94 2\n         %98 =   OpCompositeExtract %float %94 3\n        %100 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %100 %95\n        %101 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %101 %96\n        %102 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %102 %97\n        %103 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %103 %98\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_gather.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCube _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\n\nvoid main()\n{\n    uint _40 = floatBitsToUint(_15._m0[0u]);\n    vec4 _59 = textureGather(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    SV_TARGET.x = _59.x;\n    SV_TARGET.y = _59.y;\n    SV_TARGET.z = _59.z;\n    SV_TARGET.w = _59.w;\n    vec4 _72 = textureGather(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(1u));\n    SV_TARGET_1.x = _72.x;\n    SV_TARGET_1.y = _72.y;\n    SV_TARGET_1.z = _72.z;\n    SV_TARGET_1.w = _72.w;\n    vec4 _83 = textureGather(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(2u));\n    SV_TARGET_2.x = _83.x;\n    SV_TARGET_2.y = _83.y;\n    SV_TARGET_2.z = _83.z;\n    SV_TARGET_2.w = _83.w;\n    vec4 _94 = textureGather(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), int(3u));\n    SV_TARGET_3.x = _94.x;\n    SV_TARGET_3.y = _94.y;\n    SV_TARGET_3.z = _94.z;\n    SV_TARGET_3.w = _94.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_gather_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 72\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LAYER %OFFSET %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LAYER \"LAYER\"\n               OpName %OFFSET \"OFFSET\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 1\n               OpDecorate %OFFSET Flat\n               OpDecorate %OFFSET Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %37 NonUniform\n               OpDecorate %40 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %56 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n        %int = OpTypeInt 32 1\n      %v3int = OpTypeVector %int 3\n%_ptr_Input_v3int = OpTypePointer Input %v3int\n     %OFFSET = OpVariable %_ptr_Input_v3int Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %54 = OpTypeImage %float Cube 1 0 0 1 Unknown\n         %55 = OpTypeSampledImage %54\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %70\n\n         %70 = OpLabel\n         %35 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %36 =   OpLoad %float %35\n         %37 =   OpBitcast %uint %36\n         %39 =   OpAccessChain %_ptr_UniformConstant_6 %9 %37\n         %40 =   OpLoad %6 %39\n         %42 =   OpAccessChain %_ptr_UniformConstant_16 %19 %37\n         %43 =   OpLoad %16 %42\n         %44 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %45 =   OpLoad %float %44\n         %46 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %48 =   OpLoad %float %46\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %51 =   OpLoad %float %49\n         %53 =   OpLoad %float %DEPTH_REF\n         %56 =   OpSampledImage %55 %40 %43\n         %57 =   OpCompositeConstruct %v3float %45 %48 %51\n         %58 =   OpImageDrefGather %v4float %56 %57 %53\n         %59 =   OpCompositeExtract %float %58 0\n         %60 =   OpCompositeExtract %float %58 1\n         %61 =   OpCompositeExtract %float %58 2\n         %62 =   OpCompositeExtract %float %58 3\n         %65 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %65 %59\n         %66 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %66 %60\n         %67 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %67 %61\n         %68 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %68 %62\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_gather_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCube _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LAYER;\nlayout(location = 2) flat in ivec3 OFFSET;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    uint _37 = floatBitsToUint(_15._m0[0u]);\n    vec3 _57 = vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z);\n    vec4 _58 = textureGather(nonuniformEXT(samplerCubeShadow(_9[_37], _19[_37])), _57, DEPTH_REF);\n    SV_TARGET.x = _58.x;\n    SV_TARGET.y = _58.y;\n    SV_TARGET.z = _58.z;\n    SV_TARGET.w = _58.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %30 =   OpImageQuerySizeLod %v2uint %29 %uint_0\n         %31 =   OpCompositeExtract %uint %30 0\n         %32 =   OpCompositeExtract %uint %30 1\n         %33 =   OpCompositeConstruct %v2uint %31 %32\n         %37 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %38 %32\n                 OpStore %SV_TARGET_1 %uint_1\n         %39 =   OpImageQueryLevels %uint %29\n                 OpStore %SV_TARGET_2 %39\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_EXT_samplerless_texture_functions : require\n\nstruct _34\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCube _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\nlayout(location = 2) out uint SV_TARGET_2;\n\nvoid main()\n{\n    uint _26 = floatBitsToUint(_15._m0[0u]);\n    uvec2 _30 = uvec2(textureSize(_9[nonuniformEXT(_26)], int(0u)));\n    uint _31 = _30.x;\n    SV_TARGET.x = _31;\n    SV_TARGET.y = _30.y;\n    SV_TARGET_1 = 1u;\n    SV_TARGET_2 = uint(textureQueryLevels(_9[nonuniformEXT(_26)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_sample.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 140\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability MinLod\n               OpCapability ImageQuery\n               OpCapability DerivativeControl\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3 %SV_TARGET_4\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpName %SV_TARGET_4 \"SV_TARGET_4\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %SV_TARGET_4 Location 4\n               OpDecorate %40 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %57 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_3 = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_4 = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %56 = OpTypeSampledImage %6\n    %v2float = OpTypeVector %float 2\n    %float_0 = OpConstant %float 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %138\n\n        %138 = OpLabel\n         %38 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %39 =   OpLoad %float %38\n         %40 =   OpBitcast %uint %39\n         %42 =   OpAccessChain %_ptr_UniformConstant_6 %9 %40\n         %43 =   OpLoad %6 %42\n         %45 =   OpAccessChain %_ptr_UniformConstant_16 %19 %40\n         %46 =   OpLoad %16 %45\n         %47 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %48 =   OpLoad %float %47\n         %49 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %51 =   OpLoad %float %49\n         %52 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %54 =   OpLoad %float %52\n         %57 =   OpSampledImage %56 %43 %46\n         %60 =   OpCompositeConstruct %v3float %48 %51 %54\n         %59 =   OpImageQueryLod %v2float %57 %60\n         %61 =   OpCompositeExtract %float %59 0\n         %62 =   OpLoad %float %LOD_BIAS\n         %63 =   OpLoad %float %LOD_CLAMP\n         %66 =   OpCompositeConstruct %v3float %48 %51 %54\n         %65 =   OpImageSampleImplicitLod %v4float %57 %66 None\n         %67 =   OpCompositeExtract %float %65 0\n         %68 =   OpCompositeExtract %float %65 1\n         %69 =   OpCompositeExtract %float %65 2\n         %70 =   OpCompositeExtract %float %65 3\n         %73 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %73 %67\n         %74 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %74 %68\n         %75 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %75 %69\n         %76 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %76 %70\n         %79 =   OpCompositeConstruct %v3float %48 %51 %54\n         %78 =   OpImageSampleExplicitLod %v4float %57 %79 Lod %61\n         %80 =   OpCompositeExtract %float %78 0\n         %81 =   OpCompositeExtract %float %78 1\n         %82 =   OpCompositeExtract %float %78 2\n         %83 =   OpCompositeExtract %float %78 3\n         %85 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %85 %80\n         %86 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %86 %81\n         %87 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %88 %83\n         %90 =   OpCompositeConstruct %v3float %48 %51 %54\n         %89 =   OpImageSampleImplicitLod %v4float %57 %90 Bias %62\n         %91 =   OpCompositeExtract %float %89 0\n         %92 =   OpCompositeExtract %float %89 1\n         %93 =   OpCompositeExtract %float %89 2\n         %94 =   OpCompositeExtract %float %89 3\n         %96 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_0\n                 OpStore %96 %91\n         %97 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_1\n                 OpStore %97 %92\n         %98 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_2\n                 OpStore %98 %93\n         %99 =   OpAccessChain %_ptr_Output_float %SV_TARGET_2 %uint_3\n                 OpStore %99 %94\n        %101 =   OpCompositeConstruct %v3float %48 %51 %54\n        %100 =   OpImageSampleImplicitLod %v4float %57 %101 MinLod %63\n        %102 =   OpCompositeExtract %float %100 0\n        %103 =   OpCompositeExtract %float %100 1\n        %104 =   OpCompositeExtract %float %100 2\n        %105 =   OpCompositeExtract %float %100 3\n        %107 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_0\n                 OpStore %107 %102\n        %108 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_1\n                 OpStore %108 %103\n        %109 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_2\n                 OpStore %109 %104\n        %110 =   OpAccessChain %_ptr_Output_float %SV_TARGET_3 %uint_3\n                 OpStore %110 %105\n        %111 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_0\n        %112 =   OpLoad %float %111\n        %113 =   OpDPdx %float %112\n        %114 =   OpDPdy %float %112\n        %115 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_1\n        %116 =   OpLoad %float %115\n        %117 =   OpDPdx %float %116\n        %118 =   OpDPdy %float %116\n        %119 =   OpAccessChain %_ptr_Input_float %TEXCOORD_2 %uint_2\n        %120 =   OpLoad %float %119\n        %121 =   OpDPdx %float %120\n        %122 =   OpDPdy %float %120\n        %126 =   OpCompositeConstruct %v3float %48 %51 %54\n        %127 =   OpCompositeConstruct %v3float %113 %117 %121\n        %128 =   OpCompositeConstruct %v3float %114 %118 %122\n        %125 =   OpImageSampleExplicitLod %v4float %57 %126 Grad %127 %128\n        %129 =   OpCompositeExtract %float %125 0\n        %130 =   OpCompositeExtract %float %125 1\n        %131 =   OpCompositeExtract %float %125 2\n        %132 =   OpCompositeExtract %float %125 3\n        %134 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_0\n                 OpStore %134 %129\n        %135 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_1\n                 OpStore %135 %130\n        %136 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_2\n                 OpStore %136 %131\n        %137 =   OpAccessChain %_ptr_Output_float %SV_TARGET_4 %uint_3\n                 OpStore %137 %132\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_sample.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n#extension GL_ARB_sparse_texture_clamp : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCube _9[];\nlayout(set = 0, binding = 0) uniform sampler _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\nlayout(location = 2) out vec4 SV_TARGET_2;\nlayout(location = 3) out vec4 SV_TARGET_3;\nlayout(location = 4) out vec4 SV_TARGET_4;\n\nvoid main()\n{\n    uint _40 = floatBitsToUint(_15._m0[0u]);\n    vec4 _65 = texture(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z));\n    SV_TARGET.x = _65.x;\n    SV_TARGET.y = _65.y;\n    SV_TARGET.z = _65.z;\n    SV_TARGET.w = _65.w;\n    vec4 _78 = textureLod(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), textureQueryLod(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)).x);\n    SV_TARGET_1.x = _78.x;\n    SV_TARGET_1.y = _78.y;\n    SV_TARGET_1.z = _78.z;\n    SV_TARGET_1.w = _78.w;\n    vec4 _89 = texture(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_BIAS);\n    SV_TARGET_2.x = _89.x;\n    SV_TARGET_2.y = _89.y;\n    SV_TARGET_2.z = _89.z;\n    SV_TARGET_2.w = _89.w;\n    vec4 _100 = textureClampARB(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), LOD_CLAMP);\n    SV_TARGET_3.x = _100.x;\n    SV_TARGET_3.y = _100.y;\n    SV_TARGET_3.z = _100.z;\n    SV_TARGET_3.w = _100.w;\n    vec4 _125 = textureGrad(nonuniformEXT(samplerCube(_9[_40], _19[_40])), vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), vec3(dFdx(TEXCOORD_2.x), dFdx(TEXCOORD_2.y), dFdx(TEXCOORD_2.z)), vec3(dFdy(TEXCOORD_2.x), dFdy(TEXCOORD_2.y), dFdy(TEXCOORD_2.z)));\n    SV_TARGET_4.x = _125.x;\n    SV_TARGET_4.y = _125.y;\n    SV_TARGET_4.z = _125.z;\n    SV_TARGET_4.w = _125.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_sample_depth.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 70\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability SampledImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %19 %TEXCOORD %DEPTH_REF %LOD_BIAS %LOD_CLAMP %LAYER %TEXCOORD_2 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %DEPTH_REF \"DEPTH_REF\"\n               OpName %LOD_BIAS \"LOD_BIAS\"\n               OpName %LOD_CLAMP \"LOD_CLAMP\"\n               OpName %LAYER \"LAYER\"\n               OpName %TEXCOORD_2 \"TEXCOORD_2\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %DEPTH_REF Location 1\n               OpDecorate %LOD_BIAS Location 1\n               OpDecorate %LOD_BIAS Component 1\n               OpDecorate %LOD_CLAMP Location 1\n               OpDecorate %LOD_CLAMP Component 2\n               OpDecorate %LAYER Location 1\n               OpDecorate %LAYER Component 3\n               OpDecorate %TEXCOORD_2 Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %36 NonUniform\n               OpDecorate %39 NonUniform\n               OpDecorate %42 NonUniform\n               OpDecorate %57 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Cube 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n         %16 = OpTypeSampler\n%_runtimearr_16 = OpTypeRuntimeArray %16\n%_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16\n         %19 = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant\n    %v3float = OpTypeVector %float 3\n%_ptr_Input_v3float = OpTypePointer Input %v3float\n   %TEXCOORD = OpVariable %_ptr_Input_v3float Input\n%_ptr_Input_float = OpTypePointer Input %float\n  %DEPTH_REF = OpVariable %_ptr_Input_float Input\n   %LOD_BIAS = OpVariable %_ptr_Input_float Input\n  %LOD_CLAMP = OpVariable %_ptr_Input_float Input\n      %LAYER = OpVariable %_ptr_Input_float Input\n %TEXCOORD_2 = OpVariable %_ptr_Input_v3float Input\n%_ptr_Output_float = OpTypePointer Output %float\n  %SV_TARGET = OpVariable %_ptr_Output_float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n         %55 = OpTypeImage %float Cube 1 0 0 1 Unknown\n         %56 = OpTypeSampledImage %55\n    %float_0 = OpConstant %float 0\n    %v4float = OpTypeVector %float 4\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %68\n\n         %68 = OpLabel\n         %34 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %35 =   OpLoad %float %34\n         %36 =   OpBitcast %uint %35\n         %38 =   OpAccessChain %_ptr_UniformConstant_6 %9 %36\n         %39 =   OpLoad %6 %38\n         %41 =   OpAccessChain %_ptr_UniformConstant_16 %19 %36\n         %42 =   OpLoad %16 %41\n         %43 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_0\n         %44 =   OpLoad %float %43\n         %45 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_1\n         %47 =   OpLoad %float %45\n         %48 =   OpAccessChain %_ptr_Input_float %TEXCOORD %uint_2\n         %50 =   OpLoad %float %48\n         %52 =   OpLoad %float %DEPTH_REF\n         %57 =   OpSampledImage %56 %39 %42\n         %60 =   OpCompositeConstruct %v3float %44 %47 %50\n         %59 =   OpImageSampleDrefImplicitLod %float %57 %60 %52 None\n         %62 =   OpCompositeConstruct %v4float %59 %59 %59 %59\n         %63 =   OpCompositeExtract %float %62 0\n                 OpStore %SV_TARGET %63\n         %65 =   OpCompositeConstruct %v3float %44 %47 %50\n         %64 =   OpImageSampleDrefExplicitLod %float %57 %65 %52 Lod %float_0\n         %66 =   OpCompositeConstruct %v4float %64 %64 %64 %64\n         %67 =   OpCompositeExtract %float %66 0\n                 OpStore %SV_TARGET_1 %67\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_srv_indexed_image_cube_sample_depth.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform textureCube _9[];\nlayout(set = 0, binding = 0) uniform samplerShadow _19[];\n\nlayout(location = 0) in vec3 TEXCOORD;\nlayout(location = 1) in float DEPTH_REF;\nlayout(location = 1, component = 1) in float LOD_BIAS;\nlayout(location = 1, component = 2) in float LOD_CLAMP;\nlayout(location = 1, component = 3) in float LAYER;\nlayout(location = 2) in vec3 TEXCOORD_2;\nlayout(location = 0) out float SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    uint _36 = floatBitsToUint(_15._m0[0u]);\n    SV_TARGET = vec4(texture(nonuniformEXT(samplerCubeShadow(_9[_36], _19[_36])), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DEPTH_REF))).x;\n    SV_TARGET_1 = vec4(textureGrad(nonuniformEXT(samplerCubeShadow(_9[_36], _19[_36])), vec4(vec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z), DEPTH_REF), vec3(0.0), vec3(0.0))).x;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_buffer_load_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 50\n; Schema: 0\n               OpCapability Shader\n               OpCapability SparseResidency\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n       %uint = OpTypeInt 32 0\n %uint_12345 = OpConstant %uint 12345\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %v4float\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n    %float_0 = OpConstant %float 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %48\n\n         %48 = OpLabel\n         %14 =   OpLoad %6 %8\n         %18 =   OpImageSparseRead %SparseTexel %14 %uint_12345 NonPrivateTexel\n         %19 =   OpCompositeExtract %uint %18 0\n         %20 =   OpCompositeExtract %v4float %18 1\n         %21 =   OpCompositeExtract %float %20 0\n         %22 =   OpCompositeExtract %float %20 1\n         %23 =   OpCompositeExtract %float %20 2\n         %24 =   OpCompositeExtract %float %20 3\n         %26 =   OpCompositeConstruct %_ %21 %22 %23 %24 %19\n         %27 =   OpCompositeExtract %uint %26 4\n         %28 =   OpCompositeExtract %float %26 0\n         %29 =   OpCompositeExtract %float %26 1\n         %30 =   OpCompositeExtract %float %26 2\n         %31 =   OpCompositeExtract %float %26 3\n         %32 =   OpCompositeConstruct %v4float %28 %29 %30 %31\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %35 %28\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %37 %29\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %39 %30\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %41 %31\n         %44 =   OpImageSparseTexelsResident %bool %27\n         %45 =   OpSelect %float %44 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %45\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_buffer_load_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _25\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _33\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _8;\n\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    uint _50;\n    vec4 _51;\n    _50 = sparseImageLoadARB(_8, int(12345u), _51);\n    SparseTexel _18 = SparseTexel(_50, _51);\n    vec4 _20 = _18._m1;\n    _25 _26 = _25(_20.x, _20.y, _20.z, _20.w, _18._m0);\n    float _28 = _26._m0;\n    float _29 = _26._m1;\n    float _30 = _26._m2;\n    float _31 = _26._m3;\n    SV_TARGET.x = _28;\n    SV_TARGET.y = _29;\n    SV_TARGET.z = _30;\n    SV_TARGET.w = _31;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_26._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_counter.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %9 %12\n               OpExecutionMode %main LocalSize 32 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %12 DescriptorSet 0\n               OpDecorate %12 Binding 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n         %10 = OpTypeImage %uint Buffer 0 0 0 2 R32ui\n%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n         %12 = OpVariable %_ptr_UniformConstant_10 UniformConstant\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_5 = OpConstant %uint 5\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %19\n\n         %19 = OpLabel\n         %14 =   OpImageTexelPointer %_ptr_Image_uint %12 %uint_0 %uint_0\n         %16 =   OpAtomicIAdd %uint %14 %uint_5 %uint_0 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_counter.glsl",
    "content": "GLSL:\n#version 460\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _12;\n\nvoid main()\n{\n    uint _16 = imageAtomicAdd(_12, int(0u), 1u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_counter_indexed.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageTexelBufferArrayDynamicIndexing\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint GLCompute %main \"main\" %10 %14 %SV_GROUPID\n               OpExecutionMode %main LocalSize 32 1 1\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SV_GROUPID \"SV_GROUPID\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonReadable\n               OpDecorate %10 NonWritable\n               OpDecorate %14 DescriptorSet 0\n               OpDecorate %14 Binding 0\n               OpDecorate %SV_GROUPID BuiltIn WorkgroupId\n               OpDecorate %21 NonUniform\n               OpDecorate %27 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n         %11 = OpTypeImage %uint Buffer 0 0 0 2 R32ui\n%_runtimearr_11 = OpTypeRuntimeArray %11\n%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n         %14 = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n %SV_GROUPID = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %31\n\n         %31 = OpLabel\n         %19 =   OpAccessChain %_ptr_Input_uint %SV_GROUPID %uint_0\n         %21 =   OpLoad %uint %19\n         %25 =   OpAccessChain %_ptr_UniformConstant_11 %14 %21\n         %27 =   OpImageTexelPointer %_ptr_Image_uint %25 %uint_0 %uint_0\n         %28 =   OpAtomicIAdd %uint %27 %uint_5 %uint_0 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_counter_indexed.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\nlayout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;\n\nlayout(set = 0, binding = 0, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _14[];\n\nvoid main()\n{\n    uint _28 = imageAtomicAdd(_14[nonuniformEXT(gl_WorkGroupID.x)], int(0u), 1u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 1D 0 1 0 2 R32ui\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n     %uint_2 = OpConstant %uint 2\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %28\n\n         %28 = OpLabel\n         %17 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %19 =   OpLoad %uint %17\n         %20 =   OpLoad %uint %VALUE\n         %23 =   OpCompositeConstruct %v2uint %19 %uint_2\n         %25 =   OpImageTexelPointer %_ptr_Image_uint %8 %23 %uint_0\n         %26 =   OpAtomicIAdd %uint %25 %uint_5 %uint_0 %20\n                 OpStore %SV_TARGET %26\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _26 = imageAtomicAdd(_8, ivec2(uvec2(TEXCOORD.x, 2u)), VALUE);\n    SV_TARGET = _26;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_2 = OpConstant %uint 2\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %37\n\n         %37 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %24 =   OpCompositeConstruct %v2uint %20 %uint_2\n         %22 =   OpImageRead %v4float %16 %24 NonPrivateTexel\n         %25 =   OpCompositeExtract %float %22 0\n         %26 =   OpCompositeExtract %float %22 1\n         %27 =   OpCompositeExtract %float %22 2\n         %28 =   OpCompositeExtract %float %22 3\n         %31 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %31 %25\n         %32 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %32 %26\n         %34 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %34 %27\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %35 %28\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image1DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _22 = imageLoad(_8, ivec2(uvec2(TEXCOORD.x, 2u)));\n    SV_TARGET.x = _22.x;\n    SV_TARGET.y = _22.y;\n    SV_TARGET.z = _22.z;\n    SV_TARGET.w = _22.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %8 NonWritable\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n     %v2uint = OpTypeVector %uint 2\n          %_ = OpTypeStruct %uint %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %20\n\n         %20 = OpLabel\n         %13 =   OpLoad %6 %8\n         %15 =   OpImageQuerySize %v2uint %13\n         %16 =   OpCompositeExtract %uint %15 0\n         %17 =   OpCompositeExtract %uint %15 1\n                 OpStore %SV_TARGET %16\n                 OpStore %SV_TARGET_1 %17\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_query.glsl",
    "content": "GLSL:\n#version 460\n\nstruct _18\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image1DArray _8;\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec2 _15 = uvec2(imageSize(_8));\n    SV_TARGET = _15.x;\n    SV_TARGET_1 = _15.y;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %v2uint = OpTypeVector %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %37\n\n         %37 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %22 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %23 =   OpLoad %float %22\n         %24 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %26 =   OpLoad %float %24\n         %27 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %29 =   OpLoad %float %27\n         %30 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %32 =   OpLoad %float %30\n         %35 =   OpCompositeConstruct %v2uint %20 %uint_2\n         %36 =   OpCompositeConstruct %v4float %23 %26 %29 %32\n                 OpImageWrite %16 %35 %36 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_array_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly image1DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_8, ivec2(uvec2(TEXCOORD.x, 2u)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 27\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 1D 0 0 0 2 R32ui\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %25\n\n         %25 = OpLabel\n         %17 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %19 =   OpLoad %uint %17\n         %20 =   OpLoad %uint %VALUE\n         %22 =   OpImageTexelPointer %_ptr_Image_uint %8 %19 %uint_0\n         %23 =   OpAtomicIAdd %uint %22 %uint_5 %uint_0 %20\n                 OpStore %SV_TARGET %23\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _23 = imageAtomicAdd(_8, int(TEXCOORD.x), VALUE);\n    SV_TARGET = _23;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %35\n\n         %35 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpImageRead %v4float %16 %20 NonPrivateTexel\n         %22 =   OpCompositeExtract %float %21 0\n         %23 =   OpCompositeExtract %float %21 1\n         %24 =   OpCompositeExtract %float %21 2\n         %25 =   OpCompositeExtract %float %21 3\n         %28 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %28 %22\n         %29 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %29 %23\n         %31 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %31 %24\n         %33 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %33 %25\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image1D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _21 = imageLoad(_8, int(TEXCOORD.x));\n    SV_TARGET.x = _21.x;\n    SV_TARGET.y = _21.y;\n    SV_TARGET.z = _21.z;\n    SV_TARGET.w = _21.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 20\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %8 NonWritable\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n          %_ = OpTypeStruct %uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %18\n\n         %18 = OpLabel\n         %13 =   OpLoad %6 %8\n         %14 =   OpImageQuerySize %uint %13\n                 OpStore %SV_TARGET %14\n                 OpStore %SV_TARGET_1 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_query.glsl",
    "content": "GLSL:\n#version 460\n\nstruct _15\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image1D _8;\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    SV_TARGET = uint(imageSize(_8));\n    SV_TARGET_1 = 1u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 37\n; Schema: 0\n               OpCapability Shader\n               OpCapability Image1D\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %35\n\n         %35 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %22 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %23 =   OpLoad %float %22\n         %24 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %26 =   OpLoad %float %24\n         %27 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %29 =   OpLoad %float %27\n         %30 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %32 =   OpLoad %float %30\n         %34 =   OpCompositeConstruct %v4float %23 %26 %29 %32\n                 OpImageWrite %16 %20 %34 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_1d_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly image1D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_8, int(TEXCOORD.x), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 2D 0 1 0 2 R32ui\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %32\n\n         %32 = OpLabel\n         %17 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %19 =   OpLoad %uint %17\n         %20 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %22 =   OpLoad %uint %20\n         %25 =   OpLoad %uint %VALUE\n         %27 =   OpCompositeConstruct %v3uint %19 %22 %uint_2\n         %29 =   OpImageTexelPointer %_ptr_Image_uint %8 %27 %uint_0\n         %30 =   OpAtomicIAdd %uint %29 %uint_5 %uint_0 %25\n                 OpStore %SV_TARGET %30\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage2DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _30 = imageAtomicAdd(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), VALUE);\n    SV_TARGET = _30;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %23 =   OpLoad %uint %21\n         %28 =   OpCompositeConstruct %v3uint %20 %23 %uint_2\n         %27 =   OpImageRead %v4float %16 %28 NonPrivateTexel\n         %29 =   OpCompositeExtract %float %27 0\n         %30 =   OpCompositeExtract %float %27 1\n         %31 =   OpCompositeExtract %float %27 2\n         %32 =   OpCompositeExtract %float %27 3\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %35 %29\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %36 %30\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %38 %32\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _27 = imageLoad(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)));\n    SV_TARGET.x = _27.x;\n    SV_TARGET.y = _27.y;\n    SV_TARGET.z = _27.z;\n    SV_TARGET.w = _27.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 30\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %8 NonWritable\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n     %v3uint = OpTypeVector %uint 3\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %28\n\n         %28 = OpLabel\n         %15 =   OpLoad %6 %8\n         %17 =   OpImageQuerySize %v3uint %15\n         %18 =   OpCompositeExtract %uint %17 0\n         %19 =   OpCompositeExtract %uint %17 1\n         %20 =   OpCompositeConstruct %v2uint %18 %19\n         %21 =   OpCompositeExtract %uint %17 2\n         %24 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %24 %18\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %26 %19\n                 OpStore %SV_TARGET_1 %21\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_query.glsl",
    "content": "GLSL:\n#version 460\n\nstruct _22\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image2DArray _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec3 _17 = uvec3(imageSize(_8));\n    uint _18 = _17.x;\n    SV_TARGET.x = _18;\n    SV_TARGET.y = _17.y;\n    SV_TARGET_1 = _17.z;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %23 =   OpLoad %uint %21\n         %27 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %28 =   OpLoad %float %27\n         %29 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %30 =   OpLoad %float %29\n         %31 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %33 =   OpLoad %float %31\n         %34 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %36 =   OpLoad %float %34\n         %38 =   OpCompositeConstruct %v3uint %20 %23 %uint_2\n         %39 =   OpCompositeConstruct %v4float %28 %30 %33 %36\n                 OpImageWrite %16 %38 %39 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_array_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly image2DArray _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %31\n\n         %31 = OpLabel\n         %17 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %19 =   OpLoad %uint %17\n         %20 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %22 =   OpLoad %uint %20\n         %25 =   OpLoad %uint %VALUE\n         %26 =   OpCompositeConstruct %v2uint %19 %22\n         %28 =   OpImageTexelPointer %_ptr_Image_uint %8 %26 %uint_0\n         %29 =   OpAtomicIAdd %uint %28 %uint_5 %uint_0 %25\n                 OpStore %SV_TARGET %29\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage2D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _29 = imageAtomicAdd(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), VALUE);\n    SV_TARGET = _29;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %23 =   OpLoad %uint %21\n         %27 =   OpCompositeConstruct %v2uint %20 %23\n         %26 =   OpImageRead %v4float %16 %27 NonPrivateTexel\n         %28 =   OpCompositeExtract %float %26 0\n         %29 =   OpCompositeExtract %float %26 1\n         %30 =   OpCompositeExtract %float %26 2\n         %31 =   OpCompositeExtract %float %26 3\n         %34 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %34 %28\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %35 %29\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %36 %30\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %38 %31\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _26 = imageLoad(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)));\n    SV_TARGET.x = _26.x;\n    SV_TARGET.y = _26.y;\n    SV_TARGET.z = _26.z;\n    SV_TARGET.w = _26.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_load_precise.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %23 =   OpLoad %uint %21\n         %27 =   OpCompositeConstruct %v2uint %20 %23\n         %26 =   OpImageRead %v4float %16 %27 NonPrivateTexel\n         %28 =   OpCompositeExtract %float %26 0\n         %29 =   OpCompositeExtract %float %26 1\n         %30 =   OpCompositeExtract %float %26 2\n         %31 =   OpCompositeExtract %float %26 3\n         %34 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %34 %28\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %35 %29\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %36 %30\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %38 %31\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_load_precise.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _26 = imageLoad(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)));\n    SV_TARGET.x = _26.x;\n    SV_TARGET.y = _26.y;\n    SV_TARGET.z = _26.z;\n    SV_TARGET.w = _26.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 28\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %8 NonWritable\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n          %_ = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_0 = OpConstant %uint 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %26\n\n         %26 = OpLabel\n         %15 =   OpLoad %6 %8\n         %16 =   OpImageQuerySize %v2uint %15\n         %17 =   OpCompositeExtract %uint %16 0\n         %18 =   OpCompositeExtract %uint %16 1\n         %19 =   OpCompositeConstruct %v2uint %17 %18\n         %23 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %23 %17\n         %25 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %25 %18\n                 OpStore %SV_TARGET_1 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_query.glsl",
    "content": "GLSL:\n#version 460\n\nstruct _20\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image2D _8;\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec2 _16 = uvec2(imageSize(_8));\n    uint _17 = _16.x;\n    SV_TARGET.x = _17;\n    SV_TARGET.y = _16.y;\n    SV_TARGET_1 = 1u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %23 =   OpLoad %uint %21\n         %27 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %28 =   OpLoad %float %27\n         %29 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %30 =   OpLoad %float %29\n         %31 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %33 =   OpLoad %float %31\n         %34 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %36 =   OpLoad %float %34\n         %38 =   OpCompositeConstruct %v2uint %20 %23\n         %39 =   OpCompositeConstruct %v4float %28 %30 %33 %36\n                 OpImageWrite %16 %38 %39 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_2d_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly image2D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 3D 0 0 0 2 R32ui\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %33\n\n         %33 = OpLabel\n         %17 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %19 =   OpLoad %uint %17\n         %20 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %22 =   OpLoad %uint %20\n         %23 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %25 =   OpLoad %uint %23\n         %27 =   OpLoad %uint %VALUE\n         %28 =   OpCompositeConstruct %v3uint %19 %22 %25\n         %30 =   OpImageTexelPointer %_ptr_Image_uint %8 %28 %uint_0\n         %31 =   OpAtomicIAdd %uint %30 %uint_5 %uint_0 %27\n                 OpStore %SV_TARGET %31\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage3D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _31 = imageAtomicAdd(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), VALUE);\n    SV_TARGET = _31;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %41\n\n         %41 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %23 =   OpLoad %uint %21\n         %24 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %26 =   OpLoad %uint %24\n         %29 =   OpCompositeConstruct %v3uint %20 %23 %26\n         %28 =   OpImageRead %v4float %16 %29 NonPrivateTexel\n         %30 =   OpCompositeExtract %float %28 0\n         %31 =   OpCompositeExtract %float %28 1\n         %32 =   OpCompositeExtract %float %28 2\n         %33 =   OpCompositeExtract %float %28 3\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %36 %30\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %38 %32\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %39 %33\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image3D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _28 = imageLoad(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)));\n    SV_TARGET.x = _28.x;\n    SV_TARGET.y = _28.y;\n    SV_TARGET.z = _28.z;\n    SV_TARGET.w = _28.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 31\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %_ \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %8 NonWritable\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Output_v3uint = OpTypePointer Output %v3uint\n  %SV_TARGET = OpVariable %_ptr_Output_v3uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n          %_ = OpTypeStruct %v3uint %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_0 = OpConstant %uint 0\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %29\n\n         %29 = OpLabel\n         %15 =   OpLoad %6 %8\n         %16 =   OpImageQuerySize %v3uint %15\n         %17 =   OpCompositeExtract %uint %16 0\n         %18 =   OpCompositeExtract %uint %16 1\n         %19 =   OpCompositeExtract %uint %16 2\n         %20 =   OpCompositeConstruct %v3uint %17 %18 %19\n         %24 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %24 %17\n         %26 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %26 %18\n         %27 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_2\n                 OpStore %27 %19\n                 OpStore %SV_TARGET_1 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_query.glsl",
    "content": "GLSL:\n#version 460\n\nstruct _21\n{\n    uvec3 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image3D _8;\n\nlayout(location = 0) out uvec3 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec3 _16 = uvec3(imageSize(_8));\n    uint _17 = _16.x;\n    SV_TARGET.x = _17;\n    SV_TARGET.y = _16.y;\n    SV_TARGET.z = _16.z;\n    SV_TARGET_1 = 1u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %41\n\n         %41 = OpLabel\n         %16 =   OpLoad %6 %8\n         %18 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %20 =   OpLoad %uint %18\n         %21 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %23 =   OpLoad %uint %21\n         %24 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %26 =   OpLoad %uint %24\n         %29 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %30 =   OpLoad %float %29\n         %31 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %32 =   OpLoad %float %31\n         %33 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %34 =   OpLoad %float %33\n         %35 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %37 =   OpLoad %float %35\n         %39 =   OpCompositeConstruct %v3uint %20 %23 %26\n         %40 =   OpCompositeConstruct %v4float %30 %32 %34 %37\n                 OpImageWrite %16 %39 %40 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_3d_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly image3D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_8, ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_load_sparse_feedback.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 60\n; Schema: 0\n               OpCapability Shader\n               OpCapability SparseResidency\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %TEXCOORD %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SparseTexel \"SparseTexel\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Output_float = OpTypePointer Output %float\n%SV_TARGET_1 = OpVariable %_ptr_Output_float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%SparseTexel = OpTypeStruct %uint %v4float\n          %_ = OpTypeStruct %float %float %float %float %uint\n        %__0 = OpTypeStruct %uint %v4float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %bool = OpTypeBool\n    %float_1 = OpConstant %float 1\n    %float_0 = OpConstant %float 0\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %58\n\n         %58 = OpLabel\n         %18 =   OpLoad %6 %8\n         %20 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %22 =   OpLoad %uint %20\n         %23 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %25 =   OpLoad %uint %23\n         %30 =   OpCompositeConstruct %v2uint %22 %25\n         %29 =   OpImageSparseRead %SparseTexel %18 %30 NonPrivateTexel\n         %31 =   OpCompositeExtract %uint %29 0\n         %32 =   OpCompositeExtract %v4float %29 1\n         %33 =   OpCompositeExtract %float %32 0\n         %34 =   OpCompositeExtract %float %32 1\n         %35 =   OpCompositeExtract %float %32 2\n         %36 =   OpCompositeExtract %float %32 3\n         %38 =   OpCompositeConstruct %_ %33 %34 %35 %36 %31\n         %39 =   OpCompositeExtract %uint %38 4\n         %40 =   OpCompositeExtract %float %38 0\n         %41 =   OpCompositeExtract %float %38 1\n         %42 =   OpCompositeExtract %float %38 2\n         %43 =   OpCompositeExtract %float %38 3\n         %44 =   OpCompositeConstruct %v4float %40 %41 %42 %43\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %47 %40\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %48 %41\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %49 %42\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %51 %43\n         %54 =   OpImageSparseTexelsResident %bool %39\n         %55 =   OpSelect %float %54 %float_1 %float_0\n                 OpStore %SV_TARGET_1 %55\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_image_load_sparse_feedback.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_ARB_sparse_texture2 : require\n\nstruct SparseTexel\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nstruct _37\n{\n    float _m0;\n    float _m1;\n    float _m2;\n    float _m3;\n    uint _m4;\n};\n\nstruct _45\n{\n    uint _m0;\n    vec4 _m1;\n};\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _8;\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out float SV_TARGET_1;\n\nvoid main()\n{\n    uint _60;\n    vec4 _61;\n    _60 = sparseImageLoadARB(_8, ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), _61);\n    SparseTexel _29 = SparseTexel(_60, _61);\n    vec4 _32 = _29._m1;\n    _37 _38 = _37(_32.x, _32.y, _32.z, _32.w, _29._m0);\n    float _40 = _38._m0;\n    float _41 = _38._m1;\n    float _42 = _38._m2;\n    float _43 = _38._m3;\n    SV_TARGET.x = _40;\n    SV_TARGET.y = _41;\n    SV_TARGET.z = _42;\n    SV_TARGET.w = _43;\n    SV_TARGET_1 = float(sparseTexelsResidentARB(int(_38._m4)));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %27 NonUniform\n               OpDecorate %38 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 1D 0 1 0 2 R32ui\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n     %uint_4 = OpConstant %uint 4\n      %float = OpTypeFloat 32\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_2 = OpConstant %uint 2\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %41\n\n         %41 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpLoad %uint %VALUE\n         %36 =   OpCompositeConstruct %v2uint %32 %uint_2\n         %38 =   OpImageTexelPointer %_ptr_Image_uint %29 %36 %uint_0\n         %39 =   OpAtomicIAdd %uint %38 %uint_5 %uint_0 %33\n                 OpStore %SV_TARGET %39\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _39 = imageAtomicAdd(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec2(uvec2(TEXCOORD.x, 2u)), VALUE);\n    SV_TARGET = _39;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 51\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 2 R32f\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_2 = OpConstant %uint 2\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %49\n\n         %49 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %36 =   OpCompositeConstruct %v2uint %32 %uint_2\n         %34 =   OpImageRead %v4float %29 %36 NonPrivateTexel\n         %37 =   OpCompositeExtract %float %34 0\n         %38 =   OpCompositeExtract %float %34 1\n         %39 =   OpCompositeExtract %float %34 2\n         %40 =   OpCompositeExtract %float %34 3\n         %43 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %43 %37\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %44 %38\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %46 %39\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %47 %40\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image1DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _34 = imageLoad(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec2(uvec2(TEXCOORD.x, 2u)));\n    SV_TARGET.x = _34.x;\n    SV_TARGET.y = _34.y;\n    SV_TARGET.z = _34.z;\n    SV_TARGET.w = _34.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 35\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %23 NonUniform\n               OpDecorate %26 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %v2uint = OpTypeVector %uint 2\n        %__0 = OpTypeStruct %uint %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %33\n\n         %33 = OpLabel\n         %21 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %22 =   OpLoad %float %21\n         %23 =   OpBitcast %uint %22\n         %25 =   OpAccessChain %_ptr_UniformConstant_6 %9 %23\n         %26 =   OpLoad %6 %25\n         %28 =   OpImageQuerySize %v2uint %26\n         %29 =   OpCompositeExtract %uint %28 0\n         %30 =   OpCompositeExtract %uint %28 1\n                 OpStore %SV_TARGET %29\n                 OpStore %SV_TARGET_1 %30\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nstruct _31\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image1DArray _9[];\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec2 _28 = uvec2(imageSize(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))]));\n    SV_TARGET = _28.x;\n    SV_TARGET_1 = _28.y;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 51\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 1 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n     %v2uint = OpTypeVector %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %49\n\n         %49 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %34 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %35 =   OpLoad %float %34\n         %36 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %38 =   OpLoad %float %36\n         %39 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %41 =   OpLoad %float %39\n         %42 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %44 =   OpLoad %float %42\n         %47 =   OpCompositeConstruct %v2uint %32 %uint_2\n         %48 =   OpCompositeConstruct %v4float %35 %38 %41 %44\n                 OpImageWrite %29 %47 %48 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_array_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform writeonly image1DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec2(uvec2(TEXCOORD.x, 2u)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %27 NonUniform\n               OpDecorate %35 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 1D 0 0 0 2 R32ui\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n     %uint_4 = OpConstant %uint 4\n      %float = OpTypeFloat 32\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %38\n\n         %38 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpLoad %uint %VALUE\n         %35 =   OpImageTexelPointer %_ptr_Image_uint %29 %32 %uint_0\n         %36 =   OpAtomicIAdd %uint %35 %uint_5 %uint_0 %33\n                 OpStore %SV_TARGET %36\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage1D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _36 = imageAtomicAdd(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], int(TEXCOORD.x), VALUE);\n    SV_TARGET = _36;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 2 R32f\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %47\n\n         %47 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpImageRead %v4float %29 %32 NonPrivateTexel\n         %34 =   OpCompositeExtract %float %33 0\n         %35 =   OpCompositeExtract %float %33 1\n         %36 =   OpCompositeExtract %float %33 2\n         %37 =   OpCompositeExtract %float %33 3\n         %40 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %40 %34\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %41 %35\n         %43 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %43 %36\n         %45 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %45 %37\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image1D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _33 = imageLoad(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], int(TEXCOORD.x));\n    SV_TARGET.x = _33.x;\n    SV_TARGET.y = _33.y;\n    SV_TARGET.z = _33.z;\n    SV_TARGET.w = _33.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %23 NonUniform\n               OpDecorate %26 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %31\n\n         %31 = OpLabel\n         %21 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %22 =   OpLoad %float %21\n         %23 =   OpBitcast %uint %22\n         %25 =   OpAccessChain %_ptr_UniformConstant_6 %9 %23\n         %26 =   OpLoad %6 %25\n         %27 =   OpImageQuerySize %uint %26\n                 OpStore %SV_TARGET %27\n                 OpStore %SV_TARGET_1 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nstruct _28\n{\n    uint _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image1D _9[];\n\nlayout(location = 0) out uint SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    SV_TARGET = uint(imageSize(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))]));\n    SV_TARGET_1 = 1u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability Image1D\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 1D 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %47\n\n         %47 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %34 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %35 =   OpLoad %float %34\n         %36 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %38 =   OpLoad %float %36\n         %39 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %41 =   OpLoad %float %39\n         %42 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %44 =   OpLoad %float %42\n         %46 =   OpCompositeConstruct %v4float %35 %38 %41 %44\n                 OpImageWrite %29 %32 %46 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_1d_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform writeonly image1D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], int(TEXCOORD.x), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %27 NonUniform\n               OpDecorate %42 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 2D 0 1 0 2 R32ui\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n     %uint_4 = OpConstant %uint 4\n      %float = OpTypeFloat 32\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %45\n\n         %45 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %38 =   OpLoad %uint %VALUE\n         %40 =   OpCompositeConstruct %v3uint %32 %35 %uint_2\n         %42 =   OpImageTexelPointer %_ptr_Image_uint %29 %40 %uint_0\n         %43 =   OpAtomicIAdd %uint %42 %uint_5 %uint_0 %38\n                 OpStore %SV_TARGET %43\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage2DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _43 = imageAtomicAdd(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), VALUE);\n    SV_TARGET = _43;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 2 R32f\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %52\n\n         %52 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %40 =   OpCompositeConstruct %v3uint %32 %35 %uint_2\n         %39 =   OpImageRead %v4float %29 %40 NonPrivateTexel\n         %41 =   OpCompositeExtract %float %39 0\n         %42 =   OpCompositeExtract %float %39 1\n         %43 =   OpCompositeExtract %float %39 2\n         %44 =   OpCompositeExtract %float %39 3\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %47 %41\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %48 %42\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %49 %43\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %50 %44\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _39 = imageLoad(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)));\n    SV_TARGET.x = _39.x;\n    SV_TARGET.y = _39.y;\n    SV_TARGET.z = _39.z;\n    SV_TARGET.w = _39.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 42\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %25 NonUniform\n               OpDecorate %28 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %v3uint = OpTypeVector %uint 3\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %40\n\n         %40 = OpLabel\n         %23 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %24 =   OpLoad %float %23\n         %25 =   OpBitcast %uint %24\n         %27 =   OpAccessChain %_ptr_UniformConstant_6 %9 %25\n         %28 =   OpLoad %6 %27\n         %30 =   OpImageQuerySize %v3uint %28\n         %31 =   OpCompositeExtract %uint %30 0\n         %32 =   OpCompositeExtract %uint %30 1\n         %33 =   OpCompositeConstruct %v2uint %31 %32\n         %34 =   OpCompositeExtract %uint %30 2\n         %37 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %37 %31\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %38 %32\n                 OpStore %SV_TARGET_1 %34\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nstruct _35\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image2DArray _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec3 _30 = uvec3(imageSize(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))]));\n    uint _31 = _30.x;\n    SV_TARGET.x = _31;\n    SV_TARGET.y = _30.y;\n    SV_TARGET_1 = _30.z;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 1 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %52\n\n         %52 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %39 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %40 =   OpLoad %float %39\n         %41 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %42 =   OpLoad %float %41\n         %43 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %45 =   OpLoad %float %43\n         %46 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %48 =   OpLoad %float %46\n         %50 =   OpCompositeConstruct %v3uint %32 %35 %uint_2\n         %51 =   OpCompositeConstruct %v4float %40 %42 %45 %48\n                 OpImageWrite %29 %50 %51 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_array_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform writeonly image2DArray _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, 2u)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %27 NonUniform\n               OpDecorate %41 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n     %uint_4 = OpConstant %uint 4\n      %float = OpTypeFloat 32\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %44\n\n         %44 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %38 =   OpLoad %uint %VALUE\n         %39 =   OpCompositeConstruct %v2uint %32 %35\n         %41 =   OpImageTexelPointer %_ptr_Image_uint %29 %39 %uint_0\n         %42 =   OpAtomicIAdd %uint %41 %uint_5 %uint_0 %38\n                 OpStore %SV_TARGET %42\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage2D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _42 = imageAtomicAdd(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), VALUE);\n    SV_TARGET = _42;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 R32f\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %52\n\n         %52 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %39 =   OpCompositeConstruct %v2uint %32 %35\n         %38 =   OpImageRead %v4float %29 %39 NonPrivateTexel\n         %40 =   OpCompositeExtract %float %38 0\n         %41 =   OpCompositeExtract %float %38 1\n         %42 =   OpCompositeExtract %float %38 2\n         %43 =   OpCompositeExtract %float %38 3\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %46 %40\n         %47 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %47 %41\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %48 %42\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %50 %43\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image2D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _38 = imageLoad(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)));\n    SV_TARGET.x = _38.x;\n    SV_TARGET.y = _38.y;\n    SV_TARGET.z = _38.z;\n    SV_TARGET.w = _38.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 40\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %25 NonUniform\n               OpDecorate %28 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %v2uint %uint\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %38\n\n         %38 = OpLabel\n         %23 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %24 =   OpLoad %float %23\n         %25 =   OpBitcast %uint %24\n         %27 =   OpAccessChain %_ptr_UniformConstant_6 %9 %25\n         %28 =   OpLoad %6 %27\n         %29 =   OpImageQuerySize %v2uint %28\n         %30 =   OpCompositeExtract %uint %29 0\n         %31 =   OpCompositeExtract %uint %29 1\n         %32 =   OpCompositeConstruct %v2uint %30 %31\n         %36 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %36 %30\n         %37 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %37 %31\n                 OpStore %SV_TARGET_1 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nstruct _33\n{\n    uvec2 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image2D _9[];\n\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec2 _29 = uvec2(imageSize(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))]));\n    uint _30 = _29.x;\n    SV_TARGET.x = _30;\n    SV_TARGET.y = _29.y;\n    SV_TARGET_1 = 1u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 2D 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %52\n\n         %52 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %39 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %40 =   OpLoad %float %39\n         %41 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %42 =   OpLoad %float %41\n         %43 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %45 =   OpLoad %float %43\n         %46 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %48 =   OpLoad %float %46\n         %50 =   OpCompositeConstruct %v2uint %32 %35\n         %51 =   OpCompositeConstruct %v4float %40 %42 %45 %48\n                 OpImageWrite %29 %50 %51 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_2d_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform writeonly image2D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec2(uvec2(TEXCOORD.x, TEXCOORD.y)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %VALUE %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %VALUE \"VALUE\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %VALUE Flat\n               OpDecorate %VALUE Location 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %27 NonUniform\n               OpDecorate %43 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint 3D 0 0 0 2 R32ui\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n     %uint_4 = OpConstant %uint 4\n      %float = OpTypeFloat 32\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %VALUE = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %46\n\n         %46 = OpLabel\n         %25 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %26 =   OpLoad %float %25\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_UniformConstant_6 %9 %27\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %36 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %38 =   OpLoad %uint %36\n         %40 =   OpLoad %uint %VALUE\n         %41 =   OpCompositeConstruct %v3uint %32 %35 %38\n         %43 =   OpImageTexelPointer %_ptr_Image_uint %29 %41 %uint_0\n         %44 =   OpAtomicIAdd %uint %43 %uint_5 %uint_0 %40\n                 OpStore %SV_TARGET %44\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32ui) uniform uimage3D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) flat in uint VALUE;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    uint _44 = imageAtomicAdd(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), VALUE);\n    SV_TARGET = _44;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 2 R32f\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %53\n\n         %53 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %36 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %38 =   OpLoad %uint %36\n         %41 =   OpCompositeConstruct %v3uint %32 %35 %38\n         %40 =   OpImageRead %v4float %29 %41 NonPrivateTexel\n         %42 =   OpCompositeExtract %float %40 0\n         %43 =   OpCompositeExtract %float %40 1\n         %44 =   OpCompositeExtract %float %40 2\n         %45 =   OpCompositeExtract %float %40 3\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %48 %42\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %49 %43\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %50 %44\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %51 %45\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0, r32f) uniform readonly image3D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    vec4 _40 = imageLoad(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)));\n    SV_TARGET.x = _40.x;\n    SV_TARGET.y = _40.y;\n    SV_TARGET.z = _40.z;\n    SV_TARGET.w = _40.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 43\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %__0 \"\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %25 NonUniform\n               OpDecorate %28 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Output_v3uint = OpTypePointer Output %v3uint\n  %SV_TARGET = OpVariable %_ptr_Output_v3uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_1 = OpVariable %_ptr_Output_uint Output\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n        %__0 = OpTypeStruct %v3uint %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %41\n\n         %41 = OpLabel\n         %23 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %24 =   OpLoad %float %23\n         %25 =   OpBitcast %uint %24\n         %27 =   OpAccessChain %_ptr_UniformConstant_6 %9 %25\n         %28 =   OpLoad %6 %27\n         %29 =   OpImageQuerySize %v3uint %28\n         %30 =   OpCompositeExtract %uint %29 0\n         %31 =   OpCompositeExtract %uint %29 1\n         %32 =   OpCompositeExtract %uint %29 2\n         %33 =   OpCompositeConstruct %v3uint %30 %31 %32\n         %37 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %37 %30\n         %38 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %38 %31\n         %39 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_2\n                 OpStore %39 %32\n                 OpStore %SV_TARGET_1 %uint_1\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nstruct _34\n{\n    uvec3 _m0;\n    uint _m1;\n};\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform readonly writeonly image3D _9[];\n\nlayout(location = 0) out uvec3 SV_TARGET;\nlayout(location = 1) out uint SV_TARGET_1;\n\nvoid main()\n{\n    uvec3 _29 = uvec3(imageSize(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))]));\n    uint _30 = _29.x;\n    SV_TARGET.x = _30;\n    SV_TARGET.y = _29.y;\n    SV_TARGET.z = _29.z;\n    SV_TARGET_1 = 1u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 55\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageImageArrayDynamicIndexing\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageImageArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %15 %TEXCOORD %COLOR\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %TEXCOORD \"TEXCOORD\"\n               OpName %COLOR \"COLOR\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %15 DescriptorSet 0\n               OpDecorate %15 Binding 0\n               OpDecorate %TEXCOORD Flat\n               OpDecorate %TEXCOORD Location 0\n               OpDecorate %COLOR NoPerspective\n               OpDecorate %COLOR Location 2\n               OpDecorate %26 NonUniform\n               OpDecorate %29 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float 3D 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %15 = OpVariable %_ptr_Uniform__ Uniform\n     %v3uint = OpTypeVector %uint 3\n%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n   %TEXCOORD = OpVariable %_ptr_Input_v3uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Input_v4float = OpTypePointer Input %v4float\n      %COLOR = OpVariable %_ptr_Input_v4float Input\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n%_ptr_Input_float = OpTypePointer Input %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %53\n\n         %53 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %15 %uint_0 %uint_0\n         %25 =   OpLoad %float %24\n         %26 =   OpBitcast %uint %25\n         %28 =   OpAccessChain %_ptr_UniformConstant_6 %9 %26\n         %29 =   OpLoad %6 %28\n         %31 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_0\n         %32 =   OpLoad %uint %31\n         %33 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_1\n         %35 =   OpLoad %uint %33\n         %36 =   OpAccessChain %_ptr_Input_uint %TEXCOORD %uint_2\n         %38 =   OpLoad %uint %36\n         %41 =   OpAccessChain %_ptr_Input_float %COLOR %uint_0\n         %42 =   OpLoad %float %41\n         %43 =   OpAccessChain %_ptr_Input_float %COLOR %uint_1\n         %44 =   OpLoad %float %43\n         %45 =   OpAccessChain %_ptr_Input_float %COLOR %uint_2\n         %46 =   OpLoad %float %45\n         %47 =   OpAccessChain %_ptr_Input_float %COLOR %uint_3\n         %49 =   OpLoad %float %47\n         %51 =   OpCompositeConstruct %v3uint %32 %35 %38\n         %52 =   OpCompositeConstruct %v4float %42 %44 %46 %49\n                 OpImageWrite %29 %51 %52 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resource_uav_indexed_image_3d_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 0, binding = 0, scalar) uniform _13_15\n{\n    float _m0[4];\n} _15;\n\nlayout(set = 0, binding = 0) uniform writeonly image3D _9[];\n\nlayout(location = 0) flat in uvec3 TEXCOORD;\nlayout(location = 2) noperspective in vec4 COLOR;\n\nvoid main()\n{\n    imageStore(_9[nonuniformEXT(floatBitsToUint(_15._m0[0u]))], ivec3(uvec3(TEXCOORD.x, TEXCOORD.y, TEXCOORD.z)), vec4(COLOR.x, COLOR.y, COLOR.z, COLOR.w));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 33\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %12 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_arr_v4float_uint_8 ArrayStride 16\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %12 DescriptorSet 0\n               OpDecorate %12 Binding 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n     %uint_8 = OpConstant %uint 8\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8\n          %_ = OpTypeStruct %_arr_v4float_uint_8\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %12 = OpVariable %_ptr_Uniform__ Uniform\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_2 = OpConstant %uint 2\n%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %31\n\n         %31 = OpLabel\n         %17 =   OpAccessChain %_ptr_Uniform_v4float %12 %uint_0 %uint_2\n         %19 =   OpLoad %v4float %17\n         %20 =   OpCompositeExtract %float %19 0\n         %22 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %22 %20\n         %23 =   OpCompositeExtract %float %19 1\n         %24 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %24 %23\n         %26 =   OpCompositeExtract %float %19 2\n         %27 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %27 %26\n         %28 =   OpCompositeExtract %float %19 3\n         %29 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %29 %28\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[8];\n} _12;\n\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET.x = _12._m0[2u].x;\n    SV_TARGET.y = _12._m0[2u].y;\n    SV_TARGET.z = _12._m0[2u].z;\n    SV_TARGET.w = _12._m0[2u].w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv_dynamic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 36\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %12 %INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %INDEX \"INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_arr_v4float_uint_4096 ArrayStride 16\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %12 DescriptorSet 0\n               OpDecorate %12 Binding 0\n               OpDecorate %INDEX Flat\n               OpDecorate %INDEX Location 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n  %uint_4096 = OpConstant %uint 4096\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_arr_v4float_uint_4096 = OpTypeArray %v4float %uint_4096\n          %_ = OpTypeStruct %_arr_v4float_uint_4096\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %12 = OpVariable %_ptr_Uniform__ Uniform\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %34\n\n         %34 = OpLabel\n         %17 =   OpLoad %uint %INDEX\n         %19 =   OpAccessChain %_ptr_Uniform_v4float %12 %uint_0 %17\n         %21 =   OpLoad %v4float %19\n         %22 =   OpCompositeExtract %float %21 0\n         %24 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %24 %22\n         %25 =   OpCompositeExtract %float %21 1\n         %26 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %26 %25\n         %28 =   OpCompositeExtract %float %21 2\n         %29 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %29 %28\n         %31 =   OpCompositeExtract %float %21 3\n         %32 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %32 %31\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv_dynamic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std140) uniform _10_12\n{\n    vec4 _m0[4096];\n} _12;\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET.x = _12._m0[INDEX].x;\n    SV_TARGET.y = _12._m0[INDEX].y;\n    SV_TARGET.z = _12._m0[INDEX].z;\n    SV_TARGET.w = _12._m0[INDEX].w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv_indexed.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 46\n; Schema: 0\n               OpCapability Shader\n               OpCapability UniformBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %11 %19 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %__0 \"\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_arr_float_uint_4 ArrayStride 4\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %11 DescriptorSet 1\n               OpDecorate %11 Binding 0\n               OpDecorate %_arr_v4float_uint_8 ArrayStride 16\n               OpMemberDecorate %__0 0 Offset 0\n               OpDecorate %__0 Block\n               OpDecorate %19 DescriptorSet 0\n               OpDecorate %19 Binding 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n     %uint_4 = OpConstant %uint 4\n      %float = OpTypeFloat 32\n%_arr_float_uint_4 = OpTypeArray %float %uint_4\n          %_ = OpTypeStruct %_arr_float_uint_4\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n         %11 = OpVariable %_ptr_Uniform__ Uniform\n     %uint_8 = OpConstant %uint 8\n    %v4float = OpTypeVector %float 4\n%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8\n        %__0 = OpTypeStruct %_arr_v4float_uint_8\n   %uint_256 = OpConstant %uint 256\n%_arr___0_uint_256 = OpTypeArray %__0 %uint_256\n%_ptr_Uniform__arr___0_uint_256 = OpTypePointer Uniform %_arr___0_uint_256\n         %19 = OpVariable %_ptr_Uniform__arr___0_uint_256 Uniform\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n     %uint_1 = OpConstant %uint 1\n%_ptr_Uniform_float = OpTypePointer Uniform %float\n     %uint_0 = OpConstant %uint 0\n%_ptr_Uniform___0 = OpTypePointer Uniform %__0\n     %uint_2 = OpConstant %uint 2\n%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %44\n\n         %44 = OpLabel\n         %24 =   OpAccessChain %_ptr_Uniform_float %11 %uint_0 %uint_1\n         %26 =   OpLoad %float %24\n         %27 =   OpBitcast %uint %26\n         %29 =   OpAccessChain %_ptr_Uniform___0 %19 %27\n         %32 =   OpAccessChain %_ptr_Uniform_v4float %29 %uint_0 %uint_2\n         %33 =   OpLoad %v4float %32\n         %34 =   OpCompositeExtract %float %33 0\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %36 %34\n         %37 =   OpCompositeExtract %float %33 1\n         %38 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %38 %37\n         %39 =   OpCompositeExtract %float %33 2\n         %40 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %40 %39\n         %41 =   OpCompositeExtract %float %33 3\n         %42 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %42 %41\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv_indexed.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_scalar_block_layout : require\n\nlayout(set = 1, binding = 0, scalar) uniform _9_11\n{\n    float _m0[4];\n} _11;\n\nlayout(set = 0, binding = 0, std140) uniform _15_19\n{\n    vec4 _m0[8];\n} _19[256];\n\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    uint _27 = floatBitsToUint(_11._m0[1u]);\n    SV_TARGET.x = _19[_27]._m0[2u].x;\n    SV_TARGET.y = _19[_27]._m0[2u].y;\n    SV_TARGET.z = _19[_27]._m0[2u].z;\n    SV_TARGET.w = _19[_27]._m0[2u].w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv_indexed_nonuniform.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 39\n; Schema: 0\n               OpCapability Shader\n               OpCapability UniformBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability UniformBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %13 %INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %_ \"\"\n               OpName %INDEX \"INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_arr_v4float_uint_8 ArrayStride 16\n               OpMemberDecorate %_ 0 Offset 0\n               OpDecorate %_ Block\n               OpDecorate %13 DescriptorSet 0\n               OpDecorate %13 Binding 0\n               OpDecorate %INDEX Flat\n               OpDecorate %INDEX Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %18 NonUniform\n               OpDecorate %20 NonUniform\n               OpDecorate %23 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n     %uint_8 = OpConstant %uint 8\n      %float = OpTypeFloat 32\n    %v4float = OpTypeVector %float 4\n%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8\n          %_ = OpTypeStruct %_arr_v4float_uint_8\n%_runtimearr__ = OpTypeRuntimeArray %_\n%_ptr_Uniform__runtimearr__ = OpTypePointer Uniform %_runtimearr__\n         %13 = OpVariable %_ptr_Uniform__runtimearr__ Uniform\n%_ptr_Input_uint = OpTypePointer Input %uint\n      %INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%_ptr_Uniform__ = OpTypePointer Uniform %_\n     %uint_2 = OpConstant %uint 2\n%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n     %uint_0 = OpConstant %uint 0\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %37\n\n         %37 = OpLabel\n         %18 =   OpLoad %uint %INDEX\n         %20 =   OpAccessChain %_ptr_Uniform__ %13 %18\n         %23 =   OpAccessChain %_ptr_Uniform_v4float %20 %uint_0 %uint_2\n         %25 =   OpLoad %v4float %23\n         %26 =   OpCompositeExtract %float %25 0\n         %28 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %28 %26\n         %29 =   OpCompositeExtract %float %25 1\n         %30 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %30 %29\n         %32 =   OpCompositeExtract %float %25 2\n         %33 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %33 %32\n         %34 =   OpCompositeExtract %float %25 3\n         %35 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %35 %34\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_cbv_indexed_nonuniform.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std140) uniform _10_13\n{\n    vec4 _m0[8];\n} _13[];\n\nlayout(location = 0) flat in uint INDEX;\nlayout(location = 0) out vec4 SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET.x = _13[nonuniformEXT(INDEX)]._m0[2u].x;\n    SV_TARGET.y = _13[nonuniformEXT(INDEX)]._m0[2u].y;\n    SV_TARGET.z = _13[nonuniformEXT(INDEX)]._m0[2u].z;\n    SV_TARGET.w = _13[nonuniformEXT(INDEX)]._m0[2u].w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_raw_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %14 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %_runtimearr_v2uint ArrayStride 8\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %14 DescriptorSet 0\n               OpDecorate %14 Binding 0\n               OpDecorate %14 NonWritable\n               OpDecorate %14 Restrict\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_v2uint\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %14 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n     %uint_1 = OpConstant %uint 1\n%_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint\n     %uint_7 = OpConstant %uint 7\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %64\n\n         %64 = OpLabel\n         %23 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %25 =   OpLoad %uint %23\n         %26 =   OpIMul %uint %25 %uint_4\n         %30 =   OpIMul %uint %uint_16 %25\n         %34 =   OpIMul %uint %25 %uint_2\n         %35 =   OpIAdd %uint %34 %uint_1\n         %38 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %35\n         %39 =   OpLoad %v2uint %38\n         %40 =   OpCompositeExtract %uint %39 0\n         %41 =   OpCompositeExtract %uint %39 1\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %46 =   OpLoad %uint %45\n         %48 =   OpIAdd %uint %uint_7 %uint_1\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %48\n         %49 =   OpLoad %uint %47\n         %50 =   OpCompositeConstruct %v2uint %46 %49\n         %51 =   OpCompositeExtract %uint %50 0\n         %52 =   OpCompositeExtract %uint %50 1\n         %54 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %54 %40\n         %55 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %55 %41\n         %56 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %56 %51\n         %57 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %57 %52\n         %58 =   OpIMul %uint %uint_16 %25\n         %60 =   OpIMul %uint %25 %uint_4\n         %61 =   OpIAdd %uint %60 %uint_2\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %61\n         %63 =   OpLoad %uint %62\n                 OpStore %SV_TARGET_3 %63\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_raw_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _12_14\n{\n    uvec2 _m0[];\n} _14;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _35 = (BUFFER_ADDRESS.x * 2u) + 1u;\n    uint _48 = 7u + 1u;\n    uvec2 _50 = uvec2(_9._m0[7u], _9._m0[_48]);\n    SV_TARGET.x = _14._m0[_35].x;\n    SV_TARGET.y = _14._m0[_35].y;\n    SV_TARGET_1.x = _50.x;\n    SV_TARGET_1.y = _50.y;\n    SV_TARGET_3 = _9._m0[(BUFFER_ADDRESS.x * 4u) + 2u];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_raw_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %13\n\n         %13 = OpLabel\n         %12 =   OpArrayLength %uint %9 0\n                 OpStore %SV_TARGET %12\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_raw_query.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_9._m0.length());\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_structured_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n     %v4uint = OpTypeVector %uint 4\n%_ptr_Output_v4uint = OpTypePointer Output %v4uint\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_7 = OpConstant %uint 7\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n   %uint_143 = OpConstant %uint 143\n   %uint_331 = OpConstant %uint 331\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %89\n\n         %89 = OpLabel\n         %22 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %24 =   OpLoad %uint %22\n         %25 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %27 =   OpLoad %uint %25\n         %34 =   OpIMul %uint %24 %uint_20\n         %36 =   OpIAdd %uint %34 %27\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %36\n         %39 =   OpLoad %uint %38\n         %41 =   OpIAdd %uint %36 %uint_1\n         %40 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %41\n         %42 =   OpLoad %uint %40\n         %43 =   OpCompositeConstruct %v2uint %39 %42\n         %44 =   OpCompositeExtract %uint %43 0\n         %45 =   OpCompositeExtract %uint %43 1\n         %48 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_143\n         %49 =   OpLoad %uint %48\n         %51 =   OpIAdd %uint %uint_143 %uint_1\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %51\n         %52 =   OpLoad %uint %50\n         %53 =   OpCompositeConstruct %v2uint %49 %52\n         %54 =   OpCompositeExtract %uint %53 0\n         %55 =   OpCompositeExtract %uint %53 1\n         %57 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %57 %44\n         %58 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %58 %45\n         %59 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %59 %54\n         %60 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %60 %55\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_331\n         %63 =   OpLoad %uint %62\n         %65 =   OpIAdd %uint %uint_331 %uint_1\n         %64 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %65\n         %66 =   OpLoad %uint %64\n         %68 =   OpIAdd %uint %uint_331 %uint_2\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %68\n         %70 =   OpLoad %uint %67\n         %72 =   OpIAdd %uint %uint_331 %uint_3\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %72\n         %73 =   OpLoad %uint %71\n         %74 =   OpCompositeConstruct %v4uint %63 %66 %70 %73\n         %75 =   OpCompositeExtract %uint %74 0\n         %76 =   OpCompositeExtract %uint %74 1\n         %77 =   OpCompositeExtract %uint %74 2\n         %78 =   OpCompositeExtract %uint %74 3\n         %80 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_0\n                 OpStore %80 %75\n         %81 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_1\n                 OpStore %81 %76\n         %82 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_2\n                 OpStore %82 %77\n         %83 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_3\n                 OpStore %83 %78\n         %85 =   OpIMul %uint %24 %uint_20\n         %86 =   OpIAdd %uint %85 %27\n         %87 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %86\n         %88 =   OpLoad %uint %87\n                 OpStore %SV_TARGET_3 %88\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_structured_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 2) out uvec4 SV_TARGET_2;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _36 = (BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y;\n    uvec2 _43 = uvec2(_9._m0[_36], _9._m0[_36 + 1u]);\n    uint _51 = 143u + 1u;\n    uvec2 _53 = uvec2(_9._m0[143u], _9._m0[_51]);\n    SV_TARGET.x = _43.x;\n    SV_TARGET.y = _43.y;\n    SV_TARGET_1.x = _53.x;\n    SV_TARGET_1.y = _53.y;\n    uint _65 = 331u + 1u;\n    uint _68 = 331u + 2u;\n    uint _72 = 331u + 3u;\n    uvec4 _74 = uvec4(_9._m0[331u], _9._m0[_65], _9._m0[_68], _9._m0[_72]);\n    SV_TARGET_2.x = _74.x;\n    SV_TARGET_2.y = _74.y;\n    SV_TARGET_2.z = _74.z;\n    SV_TARGET_2.w = _74.w;\n    SV_TARGET_3 = _9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_structured_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 17\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Restrict\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n    %uint_20 = OpConstant %uint 20\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %15\n\n         %15 = OpLabel\n         %12 =   OpArrayLength %uint %9 0\n         %13 =   OpUDiv %uint %12 %uint_20\n                 OpStore %SV_TARGET %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_structured_query.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_9._m0.length()) / 20u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_typed_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_7 = OpConstant %uint 7\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %47\n\n         %47 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpImageFetch %v4float %17 %21\n         %23 =   OpCompositeExtract %float %22 0\n         %24 =   OpCompositeExtract %float %22 1\n         %25 =   OpCompositeExtract %float %22 2\n         %26 =   OpCompositeExtract %float %22 3\n         %29 =   OpImageFetch %v4float %17 %uint_7\n         %30 =   OpCompositeExtract %float %29 0\n         %31 =   OpCompositeExtract %float %29 1\n         %32 =   OpCompositeExtract %float %29 2\n         %33 =   OpCompositeExtract %float %29 3\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %36 %23\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %37 %24\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %39 %25\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %41 %26\n         %43 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %43 %30\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %44 %31\n         %45 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %45 %32\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %46 %33\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_typed_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _8;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _22 = texelFetch(_8, int(BUFFER_ADDRESS.x));\n    vec4 _29 = texelFetch(_8, int(7u));\n    SV_TARGET.x = _22.x;\n    SV_TARGET.y = _22.y;\n    SV_TARGET.z = _22.z;\n    SV_TARGET.w = _22.w;\n    SV_TARGET_1.x = _29.x;\n    SV_TARGET_1.y = _29.y;\n    SV_TARGET_1.z = _29.z;\n    SV_TARGET_1.w = _29.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_typed_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 16\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledBuffer\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %14\n\n         %14 = OpLabel\n         %12 =   OpLoad %6 %8\n         %13 =   OpImageQuerySize %uint %12\n                 OpStore %SV_TARGET %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_buffer_typed_query.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _8;\n\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(textureSize(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_raw_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 74\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %16 %BUFFER_INDEX %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %_runtimearr_v2uint ArrayStride 8\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Restrict\n               OpDecorate %16 DescriptorSet 0\n               OpDecorate %16 Binding 0\n               OpDecorate %16 NonWritable\n               OpDecorate %16 Restrict\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %26 NonUniform\n               OpDecorate %28 NonUniform\n               OpDecorate %30 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %53 NonUniform\n               OpDecorate %55 NonUniform\n               OpDecorate %70 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_v2uint\n%_runtimearr_SSBO_0 = OpTypeRuntimeArray %SSBO_0\n%_ptr_StorageBuffer__runtimearr_SSBO_0 = OpTypePointer StorageBuffer %_runtimearr_SSBO_0\n         %16 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO_0 StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n     %uint_1 = OpConstant %uint 1\n%_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint\n     %uint_7 = OpConstant %uint 7\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %72\n\n         %72 = OpLabel\n         %26 =   OpLoad %uint %BUFFER_INDEX\n         %28 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %26\n         %30 =   OpAccessChain %_ptr_StorageBuffer_SSBO_0 %16 %26\n         %31 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %33 =   OpLoad %uint %31\n         %34 =   OpIMul %uint %33 %uint_4\n         %38 =   OpIMul %uint %uint_16 %33\n         %42 =   OpIMul %uint %33 %uint_2\n         %43 =   OpIAdd %uint %42 %uint_1\n         %46 =   OpAccessChain %_ptr_StorageBuffer_v2uint %30 %uint_0 %43\n         %47 =   OpLoad %v2uint %46\n         %48 =   OpCompositeExtract %uint %47 0\n         %49 =   OpCompositeExtract %uint %47 1\n         %53 =   OpAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 %uint_7\n         %54 =   OpLoad %uint %53\n         %56 =   OpIAdd %uint %uint_7 %uint_1\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 %56\n         %57 =   OpLoad %uint %55\n         %58 =   OpCompositeConstruct %v2uint %54 %57\n         %59 =   OpCompositeExtract %uint %58 0\n         %60 =   OpCompositeExtract %uint %58 1\n         %62 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %62 %48\n         %63 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %63 %49\n         %64 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %64 %59\n         %65 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %65 %60\n         %66 =   OpIMul %uint %uint_16 %33\n         %68 =   OpIMul %uint %33 %uint_4\n         %69 =   OpIAdd %uint %68 %uint_2\n         %70 =   OpAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 %69\n         %71 =   OpLoad %uint %70\n                 OpStore %SV_TARGET_3 %71\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_raw_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer _13_16\n{\n    uvec2 _m0[];\n} _16[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _43 = (BUFFER_ADDRESS.x * 2u) + 1u;\n    uint _56 = 7u + 1u;\n    uvec2 _58 = uvec2(_10[nonuniformEXT(BUFFER_INDEX)]._m0[7u], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_56]);\n    SV_TARGET.x = _16[nonuniformEXT(BUFFER_INDEX)]._m0[_43].x;\n    SV_TARGET.y = _16[nonuniformEXT(BUFFER_INDEX)]._m0[_43].y;\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    SV_TARGET_3 = _10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_raw_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Restrict\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %15 NonUniform\n               OpDecorate %17 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %19\n\n         %19 = OpLabel\n         %15 =   OpLoad %uint %BUFFER_INDEX\n         %17 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %15\n         %18 =   OpArrayLength %uint %17 0\n                 OpStore %SV_TARGET %18\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_raw_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_10[nonuniformEXT(BUFFER_INDEX)]._m0.length());\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_structured_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 96\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Restrict\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %24 NonUniform\n               OpDecorate %26 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %53 NonUniform\n               OpDecorate %55 NonUniform\n               OpDecorate %67 NonUniform\n               OpDecorate %69 NonUniform\n               OpDecorate %72 NonUniform\n               OpDecorate %76 NonUniform\n               OpDecorate %92 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n     %v4uint = OpTypeVector %uint 4\n%_ptr_Output_v4uint = OpTypePointer Output %v4uint\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_7 = OpConstant %uint 7\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n   %uint_143 = OpConstant %uint 143\n   %uint_331 = OpConstant %uint 331\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %94\n\n         %94 = OpLabel\n         %24 =   OpLoad %uint %BUFFER_INDEX\n         %26 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %24\n         %27 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %29 =   OpLoad %uint %27\n         %30 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %32 =   OpLoad %uint %30\n         %39 =   OpIMul %uint %29 %uint_20\n         %41 =   OpIAdd %uint %39 %32\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %41\n         %44 =   OpLoad %uint %43\n         %46 =   OpIAdd %uint %41 %uint_1\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %46\n         %47 =   OpLoad %uint %45\n         %48 =   OpCompositeConstruct %v2uint %44 %47\n         %49 =   OpCompositeExtract %uint %48 0\n         %50 =   OpCompositeExtract %uint %48 1\n         %53 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %uint_143\n         %54 =   OpLoad %uint %53\n         %56 =   OpIAdd %uint %uint_143 %uint_1\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %56\n         %57 =   OpLoad %uint %55\n         %58 =   OpCompositeConstruct %v2uint %54 %57\n         %59 =   OpCompositeExtract %uint %58 0\n         %60 =   OpCompositeExtract %uint %58 1\n         %62 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %62 %49\n         %63 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %63 %50\n         %64 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %64 %59\n         %65 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %65 %60\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %uint_331\n         %68 =   OpLoad %uint %67\n         %70 =   OpIAdd %uint %uint_331 %uint_1\n         %69 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %70\n         %71 =   OpLoad %uint %69\n         %73 =   OpIAdd %uint %uint_331 %uint_2\n         %72 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %73\n         %75 =   OpLoad %uint %72\n         %77 =   OpIAdd %uint %uint_331 %uint_3\n         %76 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %77\n         %78 =   OpLoad %uint %76\n         %79 =   OpCompositeConstruct %v4uint %68 %71 %75 %78\n         %80 =   OpCompositeExtract %uint %79 0\n         %81 =   OpCompositeExtract %uint %79 1\n         %82 =   OpCompositeExtract %uint %79 2\n         %83 =   OpCompositeExtract %uint %79 3\n         %85 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_0\n                 OpStore %85 %80\n         %86 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_1\n                 OpStore %86 %81\n         %87 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_2\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_3\n                 OpStore %88 %83\n         %90 =   OpIMul %uint %29 %uint_20\n         %91 =   OpIAdd %uint %90 %32\n         %92 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %91\n         %93 =   OpLoad %uint %92\n                 OpStore %SV_TARGET_3 %93\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_structured_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 2) out uvec4 SV_TARGET_2;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _41 = (BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y;\n    uvec2 _48 = uvec2(_10[nonuniformEXT(BUFFER_INDEX)]._m0[_41], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_41 + 1u]);\n    uint _56 = 143u + 1u;\n    uvec2 _58 = uvec2(_10[nonuniformEXT(BUFFER_INDEX)]._m0[143u], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_56]);\n    SV_TARGET.x = _48.x;\n    SV_TARGET.y = _48.y;\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    uint _70 = 331u + 1u;\n    uint _73 = 331u + 2u;\n    uint _77 = 331u + 3u;\n    uvec4 _79 = uvec4(_10[nonuniformEXT(BUFFER_INDEX)]._m0[331u], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_70], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_73], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_77]);\n    SV_TARGET_2.x = _79.x;\n    SV_TARGET_2.y = _79.y;\n    SV_TARGET_2.z = _79.z;\n    SV_TARGET_2.w = _79.w;\n    SV_TARGET_3 = _10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_structured_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Restrict\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %15 NonUniform\n               OpDecorate %17 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n    %uint_20 = OpConstant %uint 20\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %21\n\n         %21 = OpLabel\n         %15 =   OpLoad %uint %BUFFER_INDEX\n         %17 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %15\n         %18 =   OpArrayLength %uint %17 0\n         %19 =   OpUDiv %uint %18 %uint_20\n                 OpStore %SV_TARGET %19\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_structured_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) restrict readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_10[nonuniformEXT(BUFFER_INDEX)]._m0.length()) / 20u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_typed_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability UniformTexelBufferArrayDynamicIndexing\n               OpCapability UniformTexelBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_INDEX %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %20 NonUniform\n               OpDecorate %23 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_0 = OpConstant %uint 0\n     %uint_7 = OpConstant %uint 7\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %52\n\n         %52 = OpLabel\n         %20 =   OpLoad %uint %BUFFER_INDEX\n         %22 =   OpAccessChain %_ptr_UniformConstant_6 %9 %20\n         %23 =   OpLoad %6 %22\n         %24 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %26 =   OpLoad %uint %24\n         %27 =   OpImageFetch %v4float %23 %26\n         %28 =   OpCompositeExtract %float %27 0\n         %29 =   OpCompositeExtract %float %27 1\n         %30 =   OpCompositeExtract %float %27 2\n         %31 =   OpCompositeExtract %float %27 3\n         %34 =   OpImageFetch %v4float %23 %uint_7\n         %35 =   OpCompositeExtract %float %34 0\n         %36 =   OpCompositeExtract %float %34 1\n         %37 =   OpCompositeExtract %float %34 2\n         %38 =   OpCompositeExtract %float %34 3\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %41 %28\n         %42 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %42 %29\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %44 %30\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %46 %31\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %48 %35\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %49 %36\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %50 %37\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %51 %38\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_typed_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _9[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _27 = texelFetch(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x));\n    vec4 _34 = texelFetch(_9[nonuniformEXT(BUFFER_INDEX)], int(7u));\n    SV_TARGET.x = _27.x;\n    SV_TARGET.y = _27.y;\n    SV_TARGET.z = _27.z;\n    SV_TARGET.w = _27.w;\n    SV_TARGET_1.x = _34.x;\n    SV_TARGET_1.y = _34.y;\n    SV_TARGET_1.z = _34.z;\n    SV_TARGET_1.w = _34.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_typed_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\n               OpCapability Shader\n               OpCapability SampledBuffer\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability UniformTexelBufferArrayDynamicIndexing\n               OpCapability UniformTexelBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %15 NonUniform\n               OpDecorate %18 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %20\n\n         %20 = OpLabel\n         %15 =   OpLoad %uint %BUFFER_INDEX\n         %17 =   OpAccessChain %_ptr_UniformConstant_6 %9 %15\n         %18 =   OpLoad %6 %17\n         %19 =   OpImageQuerySize %uint %18\n                 OpStore %SV_TARGET %19\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_srv_indexed_buffer_typed_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform samplerBuffer _9[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(textureSize(_9[nonuniformEXT(BUFFER_INDEX)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 132\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_5 = OpConstant %uint 5\n    %uint_10 = OpConstant %uint 10\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %130\n\n        %130 = OpLabel\n         %14 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %16 =   OpLoad %uint %14\n         %17 =   OpIMul %uint %16 %uint_4\n         %21 =   OpIMul %uint %uint_16 %16\n         %25 =   OpIMul %uint %16 %uint_4\n         %26 =   OpIAdd %uint %25 %uint_2\n         %28 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %26\n         %29 =   OpAtomicLoad %uint %28 %uint_5 %uint_0\n         %31 =   OpIAdd %uint %29 %uint_10\n         %33 =   OpIMul %uint %uint_16 %16\n         %35 =   OpIMul %uint %16 %uint_4\n         %36 =   OpIAdd %uint %35 %uint_2\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %36\n         %38 =   OpAtomicExchange %uint %37 %uint_5 %uint_0 %31\n         %40 =   OpIMul %uint %uint_16 %16\n         %42 =   OpIMul %uint %16 %uint_4\n         %43 =   OpIAdd %uint %42 %uint_2\n         %44 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %43\n         %45 =   OpAtomicCompareExchange %uint %44 %uint_5 %uint_0 %uint_0 %38 %uint_10\n         %46 =   OpIMul %uint %uint_16 %16\n         %48 =   OpIMul %uint %16 %uint_4\n         %49 =   OpIAdd %uint %48 %uint_2\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %49\n         %51 =   OpAtomicIAdd %uint %50 %uint_5 %uint_0 %45\n         %52 =   OpIMul %uint %uint_16 %16\n         %54 =   OpIMul %uint %16 %uint_4\n         %55 =   OpIAdd %uint %54 %uint_2\n         %56 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %55\n         %57 =   OpAtomicISub %uint %56 %uint_5 %uint_0 %51\n         %58 =   OpIMul %uint %uint_16 %16\n         %60 =   OpIMul %uint %16 %uint_4\n         %61 =   OpIAdd %uint %60 %uint_2\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %61\n         %63 =   OpAtomicSMin %uint %62 %uint_5 %uint_0 %57\n         %64 =   OpIMul %uint %uint_16 %16\n         %66 =   OpIMul %uint %16 %uint_4\n         %67 =   OpIAdd %uint %66 %uint_2\n         %68 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %67\n         %69 =   OpAtomicSMax %uint %68 %uint_5 %uint_0 %63\n         %70 =   OpIMul %uint %uint_16 %16\n         %72 =   OpIMul %uint %16 %uint_4\n         %73 =   OpIAdd %uint %72 %uint_2\n         %74 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %73\n         %75 =   OpAtomicUMin %uint %74 %uint_5 %uint_0 %69\n         %76 =   OpIMul %uint %uint_16 %16\n         %78 =   OpIMul %uint %16 %uint_4\n         %79 =   OpIAdd %uint %78 %uint_2\n         %80 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %79\n         %81 =   OpAtomicUMax %uint %80 %uint_5 %uint_0 %75\n         %82 =   OpIMul %uint %uint_16 %16\n         %84 =   OpIMul %uint %16 %uint_4\n         %85 =   OpIAdd %uint %84 %uint_2\n         %86 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %85\n         %87 =   OpAtomicAnd %uint %86 %uint_5 %uint_0 %81\n         %88 =   OpIMul %uint %uint_16 %16\n         %90 =   OpIMul %uint %16 %uint_4\n         %91 =   OpIAdd %uint %90 %uint_2\n         %92 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %91\n         %93 =   OpAtomicOr %uint %92 %uint_5 %uint_0 %87\n         %94 =   OpIMul %uint %uint_16 %16\n         %96 =   OpIMul %uint %16 %uint_4\n         %97 =   OpIAdd %uint %96 %uint_2\n         %98 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %97\n         %99 =   OpAtomicXor %uint %98 %uint_5 %uint_0 %93\n        %100 =   OpIMul %uint %uint_16 %16\n        %102 =   OpIMul %uint %16 %uint_4\n        %103 =   OpIAdd %uint %102 %uint_2\n        %104 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %103\n        %105 =   OpAtomicIAdd %uint %104 %uint_5 %uint_0 %uint_1\n        %107 =   OpIMul %uint %uint_16 %16\n        %109 =   OpIMul %uint %16 %uint_4\n        %110 =   OpIAdd %uint %109 %uint_2\n        %111 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %110\n        %112 =   OpAtomicISub %uint %111 %uint_5 %uint_0 %uint_1\n        %113 =   OpIMul %uint %uint_16 %16\n        %115 =   OpIMul %uint %16 %uint_4\n        %116 =   OpIAdd %uint %115 %uint_2\n        %117 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %116\n                 OpAtomicStore %117 %uint_5 %uint_0 %112\n        %118 =   OpIMul %uint %uint_16 %16\n        %120 =   OpIMul %uint %16 %uint_4\n        %121 =   OpIAdd %uint %120 %uint_2\n        %122 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %121\n        %123 =   OpAtomicIAdd %uint %122 %uint_5 %uint_0 %uint_1\n        %124 =   OpIMul %uint %uint_16 %16\n        %126 =   OpIMul %uint %16 %uint_4\n        %127 =   OpIAdd %uint %126 %uint_2\n        %128 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %127\n        %129 =   OpAtomicISub %uint %128 %uint_5 %uint_0 %uint_2\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _29 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 0u);\n    uint _38 = atomicExchange(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _29 + 10u);\n    uint _45 = atomicCompSwap(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 10u, _38);\n    uint _51 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _45);\n    uint _57 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], -_51);\n    uint _63 = atomicMin(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _57);\n    uint _69 = atomicMax(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _63);\n    uint _75 = atomicMin(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _69);\n    uint _81 = atomicMax(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _75);\n    uint _87 = atomicAnd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _81);\n    uint _93 = atomicOr(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _87);\n    uint _99 = atomicXor(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _93);\n    uint _105 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 1u);\n    uint _112 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], -1u);\n    atomicExchange(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _112);\n    uint _123 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 1u);\n    uint _129 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 4u) + 2u], -2u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %14 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %_runtimearr_v2uint ArrayStride 8\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Aliased\n               OpDecorate %14 DescriptorSet 0\n               OpDecorate %14 Binding 0\n               OpDecorate %14 NonWritable\n               OpDecorate %14 Aliased\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_v2uint\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %14 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n     %uint_1 = OpConstant %uint 1\n%_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint\n     %uint_7 = OpConstant %uint 7\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %64\n\n         %64 = OpLabel\n         %23 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %25 =   OpLoad %uint %23\n         %26 =   OpIMul %uint %25 %uint_4\n         %30 =   OpIMul %uint %uint_16 %25\n         %34 =   OpIMul %uint %25 %uint_2\n         %35 =   OpIAdd %uint %34 %uint_1\n         %38 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %35\n         %39 =   OpLoad %v2uint %38 NonPrivatePointer\n         %40 =   OpCompositeExtract %uint %39 0\n         %41 =   OpCompositeExtract %uint %39 1\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %46 =   OpLoad %uint %45 NonPrivatePointer\n         %48 =   OpIAdd %uint %uint_7 %uint_1\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %48\n         %49 =   OpLoad %uint %47 NonPrivatePointer\n         %50 =   OpCompositeConstruct %v2uint %46 %49\n         %51 =   OpCompositeExtract %uint %50 0\n         %52 =   OpCompositeExtract %uint %50 1\n         %54 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %54 %40\n         %55 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %55 %41\n         %56 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %56 %51\n         %57 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %57 %52\n         %58 =   OpIMul %uint %uint_16 %25\n         %60 =   OpIMul %uint %25 %uint_4\n         %61 =   OpIAdd %uint %60 %uint_2\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %61\n         %63 =   OpLoad %uint %62 NonPrivatePointer\n                 OpStore %SV_TARGET_3 %63\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _12_14\n{\n    uvec2 _m0[];\n} _14;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _35 = (BUFFER_ADDRESS.x * 2u) + 1u;\n    uint _48 = 7u + 1u;\n    uvec2 _50 = uvec2(_9._m0[7u], _9._m0[_48]);\n    SV_TARGET.x = _14._m0[_35].x;\n    SV_TARGET.y = _14._m0[_35].y;\n    SV_TARGET_1.x = _50.x;\n    SV_TARGET_1.y = _50.y;\n    SV_TARGET_3 = _9._m0[(BUFFER_ADDRESS.x * 4u) + 2u];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_load_precise.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 66\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %14 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %_runtimearr_v2uint ArrayStride 8\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %9 Aliased\n               OpDecorate %14 DescriptorSet 0\n               OpDecorate %14 Binding 0\n               OpDecorate %14 NonWritable\n               OpDecorate %14 Aliased\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_v2uint\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n         %14 = OpVariable %_ptr_StorageBuffer_SSBO_0 StorageBuffer\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n     %uint_1 = OpConstant %uint 1\n%_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint\n     %uint_7 = OpConstant %uint 7\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %64\n\n         %64 = OpLabel\n         %23 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %25 =   OpLoad %uint %23\n         %26 =   OpIMul %uint %25 %uint_4\n         %30 =   OpIMul %uint %uint_16 %25\n         %34 =   OpIMul %uint %25 %uint_2\n         %35 =   OpIAdd %uint %34 %uint_1\n         %38 =   OpAccessChain %_ptr_StorageBuffer_v2uint %14 %uint_0 %35\n         %39 =   OpLoad %v2uint %38 NonPrivatePointer\n         %40 =   OpCompositeExtract %uint %39 0\n         %41 =   OpCompositeExtract %uint %39 1\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n         %46 =   OpLoad %uint %45 NonPrivatePointer\n         %48 =   OpIAdd %uint %uint_7 %uint_1\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %48\n         %49 =   OpLoad %uint %47 NonPrivatePointer\n         %50 =   OpCompositeConstruct %v2uint %46 %49\n         %51 =   OpCompositeExtract %uint %50 0\n         %52 =   OpCompositeExtract %uint %50 1\n         %54 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %54 %40\n         %55 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %55 %41\n         %56 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %56 %51\n         %57 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %57 %52\n         %58 =   OpIMul %uint %uint_16 %25\n         %60 =   OpIMul %uint %25 %uint_4\n         %61 =   OpIAdd %uint %60 %uint_2\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %61\n         %63 =   OpLoad %uint %62 NonPrivatePointer\n                 OpStore %SV_TARGET_3 %63\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_load_precise.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(set = 0, binding = 0, std430) readonly buffer _12_14\n{\n    uvec2 _m0[];\n} _14;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _35 = (BUFFER_ADDRESS.x * 2u) + 1u;\n    uint _48 = 7u + 1u;\n    uvec2 _50 = uvec2(_9._m0[7u], _9._m0[_48]);\n    SV_TARGET.x = _14._m0[_35].x;\n    SV_TARGET.y = _14._m0[_35].y;\n    SV_TARGET_1.x = _50.x;\n    SV_TARGET_1.y = _50.y;\n    SV_TARGET_3 = _9._m0[(BUFFER_ADDRESS.x * 4u) + 2u];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 15\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %13\n\n         %13 = OpLabel\n         %12 =   OpArrayLength %uint %9 0\n                 OpStore %SV_TARGET %12\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_query.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_9._m0.length());\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 47\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n     %v3uint = OpTypeVector %uint 3\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_7 = OpConstant %uint 7\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %45\n\n         %45 = OpLabel\n         %14 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %16 =   OpLoad %uint %14\n         %17 =   OpIMul %uint %16 %uint_4\n         %25 =   OpIMul %uint %uint_16 %16\n         %29 =   OpIMul %uint %16 %uint_4\n         %30 =   OpIAdd %uint %29 %uint_2\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %30\n                 OpStore %32 %uint_1 NonPrivatePointer\n         %34 =   OpIAdd %uint %30 %uint_1\n         %33 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %34\n                 OpStore %33 %uint_2 NonPrivatePointer\n         %36 =   OpIAdd %uint %30 %uint_2\n         %35 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %36\n                 OpStore %35 %uint_3 NonPrivatePointer\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n                 OpStore %38 %uint_1 NonPrivatePointer\n         %40 =   OpIAdd %uint %uint_7 %uint_1\n         %39 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %40\n                 OpStore %39 %uint_2 NonPrivatePointer\n         %42 =   OpIAdd %uint %uint_7 %uint_2\n         %41 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %42\n                 OpStore %41 %uint_3 NonPrivatePointer\n         %44 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_7\n                 OpStore %44 %uint_6 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_raw_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _30 = (BUFFER_ADDRESS.x * 4u) + 2u;\n    _9._m0[_30] = 1u;\n    _9._m0[_30 + 1u] = 2u;\n    _9._m0[_30 + 2u] = 3u;\n    _9._m0[7u] = 1u;\n    uint _40 = 7u + 1u;\n    _9._m0[_40] = 2u;\n    uint _42 = 7u + 2u;\n    _9._m0[_42] = 3u;\n    _9._m0[7u] = 6u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 115\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_5 = OpConstant %uint 5\n    %uint_10 = OpConstant %uint 10\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %113\n\n        %113 = OpLabel\n         %14 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %16 =   OpLoad %uint %14\n         %17 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %19 =   OpLoad %uint %17\n         %23 =   OpIMul %uint %16 %uint_20\n         %25 =   OpIAdd %uint %23 %19\n         %27 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %25\n         %28 =   OpAtomicLoad %uint %27 %uint_5 %uint_0\n         %30 =   OpIAdd %uint %28 %uint_10\n         %33 =   OpIMul %uint %16 %uint_20\n         %34 =   OpIAdd %uint %33 %19\n         %35 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %34\n         %36 =   OpAtomicExchange %uint %35 %uint_5 %uint_0 %30\n         %39 =   OpIMul %uint %16 %uint_20\n         %40 =   OpIAdd %uint %39 %19\n         %41 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %40\n         %42 =   OpAtomicCompareExchange %uint %41 %uint_5 %uint_0 %uint_0 %36 %uint_10\n         %44 =   OpIMul %uint %16 %uint_20\n         %45 =   OpIAdd %uint %44 %19\n         %46 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %45\n         %47 =   OpAtomicIAdd %uint %46 %uint_5 %uint_0 %42\n         %49 =   OpIMul %uint %16 %uint_20\n         %50 =   OpIAdd %uint %49 %19\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %50\n         %52 =   OpAtomicISub %uint %51 %uint_5 %uint_0 %47\n         %54 =   OpIMul %uint %16 %uint_20\n         %55 =   OpIAdd %uint %54 %19\n         %56 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %55\n         %57 =   OpAtomicSMin %uint %56 %uint_5 %uint_0 %52\n         %59 =   OpIMul %uint %16 %uint_20\n         %60 =   OpIAdd %uint %59 %19\n         %61 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %60\n         %62 =   OpAtomicSMax %uint %61 %uint_5 %uint_0 %57\n         %64 =   OpIMul %uint %16 %uint_20\n         %65 =   OpIAdd %uint %64 %19\n         %66 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %65\n         %67 =   OpAtomicUMin %uint %66 %uint_5 %uint_0 %62\n         %69 =   OpIMul %uint %16 %uint_20\n         %70 =   OpIAdd %uint %69 %19\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %70\n         %72 =   OpAtomicUMax %uint %71 %uint_5 %uint_0 %67\n         %74 =   OpIMul %uint %16 %uint_20\n         %75 =   OpIAdd %uint %74 %19\n         %76 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %75\n         %77 =   OpAtomicAnd %uint %76 %uint_5 %uint_0 %72\n         %79 =   OpIMul %uint %16 %uint_20\n         %80 =   OpIAdd %uint %79 %19\n         %81 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %80\n         %82 =   OpAtomicOr %uint %81 %uint_5 %uint_0 %77\n         %84 =   OpIMul %uint %16 %uint_20\n         %85 =   OpIAdd %uint %84 %19\n         %86 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %85\n         %87 =   OpAtomicXor %uint %86 %uint_5 %uint_0 %82\n         %89 =   OpIMul %uint %16 %uint_20\n         %90 =   OpIAdd %uint %89 %19\n         %91 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %90\n         %92 =   OpAtomicIAdd %uint %91 %uint_5 %uint_0 %uint_1\n         %94 =   OpIMul %uint %16 %uint_20\n         %95 =   OpIAdd %uint %94 %19\n         %96 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %95\n         %97 =   OpAtomicISub %uint %96 %uint_5 %uint_0 %uint_1\n         %99 =   OpIMul %uint %16 %uint_20\n        %100 =   OpIAdd %uint %99 %19\n        %101 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %100\n                 OpAtomicStore %101 %uint_5 %uint_0 %97\n        %103 =   OpIMul %uint %16 %uint_20\n        %104 =   OpIAdd %uint %103 %19\n        %105 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %104\n        %106 =   OpAtomicIAdd %uint %105 %uint_5 %uint_0 %uint_1\n        %108 =   OpIMul %uint %16 %uint_20\n        %109 =   OpIAdd %uint %108 %19\n        %110 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %109\n        %111 =   OpAtomicISub %uint %110 %uint_5 %uint_0 %uint_2\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _28 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 0u);\n    uint _36 = atomicExchange(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _28 + 10u);\n    uint _42 = atomicCompSwap(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 10u, _36);\n    uint _47 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _42);\n    uint _52 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], -_47);\n    uint _57 = atomicMin(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _52);\n    uint _62 = atomicMax(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _57);\n    uint _67 = atomicMin(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _62);\n    uint _72 = atomicMax(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _67);\n    uint _77 = atomicAnd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _72);\n    uint _82 = atomicOr(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _77);\n    uint _87 = atomicXor(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _82);\n    uint _92 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 1u);\n    uint _97 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], -1u);\n    atomicExchange(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _97);\n    uint _106 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 1u);\n    uint _111 = atomicAdd(_9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], -2u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n     %v4uint = OpTypeVector %uint 4\n%_ptr_Output_v4uint = OpTypePointer Output %v4uint\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_7 = OpConstant %uint 7\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n   %uint_143 = OpConstant %uint 143\n   %uint_331 = OpConstant %uint 331\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %89\n\n         %89 = OpLabel\n         %22 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %24 =   OpLoad %uint %22\n         %25 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %27 =   OpLoad %uint %25\n         %34 =   OpIMul %uint %24 %uint_20\n         %36 =   OpIAdd %uint %34 %27\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %36\n         %39 =   OpLoad %uint %38 NonPrivatePointer\n         %41 =   OpIAdd %uint %36 %uint_1\n         %40 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %41\n         %42 =   OpLoad %uint %40 NonPrivatePointer\n         %43 =   OpCompositeConstruct %v2uint %39 %42\n         %44 =   OpCompositeExtract %uint %43 0\n         %45 =   OpCompositeExtract %uint %43 1\n         %48 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_143\n         %49 =   OpLoad %uint %48 NonPrivatePointer\n         %51 =   OpIAdd %uint %uint_143 %uint_1\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %51\n         %52 =   OpLoad %uint %50 NonPrivatePointer\n         %53 =   OpCompositeConstruct %v2uint %49 %52\n         %54 =   OpCompositeExtract %uint %53 0\n         %55 =   OpCompositeExtract %uint %53 1\n         %57 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %57 %44\n         %58 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %58 %45\n         %59 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %59 %54\n         %60 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %60 %55\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_331\n         %63 =   OpLoad %uint %62 NonPrivatePointer\n         %65 =   OpIAdd %uint %uint_331 %uint_1\n         %64 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %65\n         %66 =   OpLoad %uint %64 NonPrivatePointer\n         %68 =   OpIAdd %uint %uint_331 %uint_2\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %68\n         %70 =   OpLoad %uint %67 NonPrivatePointer\n         %72 =   OpIAdd %uint %uint_331 %uint_3\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %72\n         %73 =   OpLoad %uint %71 NonPrivatePointer\n         %74 =   OpCompositeConstruct %v4uint %63 %66 %70 %73\n         %75 =   OpCompositeExtract %uint %74 0\n         %76 =   OpCompositeExtract %uint %74 1\n         %77 =   OpCompositeExtract %uint %74 2\n         %78 =   OpCompositeExtract %uint %74 3\n         %80 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_0\n                 OpStore %80 %75\n         %81 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_1\n                 OpStore %81 %76\n         %82 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_2\n                 OpStore %82 %77\n         %83 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_3\n                 OpStore %83 %78\n         %85 =   OpIMul %uint %24 %uint_20\n         %86 =   OpIAdd %uint %85 %27\n         %87 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %86\n         %88 =   OpLoad %uint %87 NonPrivatePointer\n                 OpStore %SV_TARGET_3 %88\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 2) out uvec4 SV_TARGET_2;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _36 = (BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y;\n    uvec2 _43 = uvec2(_9._m0[_36], _9._m0[_36 + 1u]);\n    uint _51 = 143u + 1u;\n    uvec2 _53 = uvec2(_9._m0[143u], _9._m0[_51]);\n    SV_TARGET.x = _43.x;\n    SV_TARGET.y = _43.y;\n    SV_TARGET_1.x = _53.x;\n    SV_TARGET_1.y = _53.y;\n    uint _65 = 331u + 1u;\n    uint _68 = 331u + 2u;\n    uint _72 = 331u + 3u;\n    uvec4 _74 = uvec4(_9._m0[331u], _9._m0[_65], _9._m0[_68], _9._m0[_72]);\n    SV_TARGET_2.x = _74.x;\n    SV_TARGET_2.y = _74.y;\n    SV_TARGET_2.z = _74.z;\n    SV_TARGET_2.w = _74.w;\n    SV_TARGET_3 = _9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_load_precise.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 91\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n     %v4uint = OpTypeVector %uint 4\n%_ptr_Output_v4uint = OpTypePointer Output %v4uint\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_7 = OpConstant %uint 7\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n   %uint_143 = OpConstant %uint 143\n   %uint_331 = OpConstant %uint 331\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %89\n\n         %89 = OpLabel\n         %22 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %24 =   OpLoad %uint %22\n         %25 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %27 =   OpLoad %uint %25\n         %34 =   OpIMul %uint %24 %uint_20\n         %36 =   OpIAdd %uint %34 %27\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %36\n         %39 =   OpLoad %uint %38 NonPrivatePointer\n         %41 =   OpIAdd %uint %36 %uint_1\n         %40 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %41\n         %42 =   OpLoad %uint %40 NonPrivatePointer\n         %43 =   OpCompositeConstruct %v2uint %39 %42\n         %44 =   OpCompositeExtract %uint %43 0\n         %45 =   OpCompositeExtract %uint %43 1\n         %48 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_143\n         %49 =   OpLoad %uint %48 NonPrivatePointer\n         %51 =   OpIAdd %uint %uint_143 %uint_1\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %51\n         %52 =   OpLoad %uint %50 NonPrivatePointer\n         %53 =   OpCompositeConstruct %v2uint %49 %52\n         %54 =   OpCompositeExtract %uint %53 0\n         %55 =   OpCompositeExtract %uint %53 1\n         %57 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %57 %44\n         %58 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %58 %45\n         %59 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %59 %54\n         %60 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %60 %55\n         %62 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_331\n         %63 =   OpLoad %uint %62 NonPrivatePointer\n         %65 =   OpIAdd %uint %uint_331 %uint_1\n         %64 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %65\n         %66 =   OpLoad %uint %64 NonPrivatePointer\n         %68 =   OpIAdd %uint %uint_331 %uint_2\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %68\n         %70 =   OpLoad %uint %67 NonPrivatePointer\n         %72 =   OpIAdd %uint %uint_331 %uint_3\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %72\n         %73 =   OpLoad %uint %71 NonPrivatePointer\n         %74 =   OpCompositeConstruct %v4uint %63 %66 %70 %73\n         %75 =   OpCompositeExtract %uint %74 0\n         %76 =   OpCompositeExtract %uint %74 1\n         %77 =   OpCompositeExtract %uint %74 2\n         %78 =   OpCompositeExtract %uint %74 3\n         %80 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_0\n                 OpStore %80 %75\n         %81 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_1\n                 OpStore %81 %76\n         %82 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_2\n                 OpStore %82 %77\n         %83 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_3\n                 OpStore %83 %78\n         %85 =   OpIMul %uint %24 %uint_20\n         %86 =   OpIAdd %uint %85 %27\n         %87 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %86\n         %88 =   OpLoad %uint %87 NonPrivatePointer\n                 OpStore %SV_TARGET_3 %88\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_load_precise.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 2) out uvec4 SV_TARGET_2;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _36 = (BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y;\n    uvec2 _43 = uvec2(_9._m0[_36], _9._m0[_36 + 1u]);\n    uint _51 = 143u + 1u;\n    uvec2 _53 = uvec2(_9._m0[143u], _9._m0[_51]);\n    SV_TARGET.x = _43.x;\n    SV_TARGET.y = _43.y;\n    SV_TARGET_1.x = _53.x;\n    SV_TARGET_1.y = _53.y;\n    uint _65 = 331u + 1u;\n    uint _68 = 331u + 2u;\n    uint _72 = 331u + 3u;\n    uvec4 _74 = uvec4(_9._m0[331u], _9._m0[_65], _9._m0[_68], _9._m0[_72]);\n    SV_TARGET_2.x = _74.x;\n    SV_TARGET_2.y = _74.y;\n    SV_TARGET_2.z = _74.z;\n    SV_TARGET_2.w = _74.w;\n    SV_TARGET_3 = _9._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 17\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n    %uint_20 = OpConstant %uint 20\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %15\n\n         %15 = OpLabel\n         %12 =   OpArrayLength %uint %9 0\n         %13 =   OpUDiv %uint %12 %uint_20\n                 OpStore %SV_TARGET %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_query.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_9._m0.length()) / 20u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 48\n; Schema: 0\n               OpCapability Shader\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n          %9 = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_7 = OpConstant %uint 7\n     %uint_3 = OpConstant %uint 3\n     %v3uint = OpTypeVector %uint 3\n     %uint_2 = OpConstant %uint 2\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n   %uint_143 = OpConstant %uint 143\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %46\n\n         %46 = OpLabel\n         %14 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %16 =   OpLoad %uint %14\n         %17 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %19 =   OpLoad %uint %17\n         %29 =   OpIMul %uint %16 %uint_20\n         %31 =   OpIAdd %uint %29 %19\n         %33 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %31\n                 OpStore %33 %uint_1 NonPrivatePointer\n         %35 =   OpIAdd %uint %31 %uint_1\n         %34 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %35\n                 OpStore %34 %uint_2 NonPrivatePointer\n         %37 =   OpIAdd %uint %31 %uint_2\n         %36 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %37\n                 OpStore %36 %uint_3 NonPrivatePointer\n         %39 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_143\n                 OpStore %39 %uint_1 NonPrivatePointer\n         %41 =   OpIAdd %uint %uint_143 %uint_1\n         %40 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %41\n                 OpStore %40 %uint_2 NonPrivatePointer\n         %43 =   OpIAdd %uint %uint_143 %uint_2\n         %42 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %43\n                 OpStore %42 %uint_3 NonPrivatePointer\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_143\n                 OpStore %45 %uint_6 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_structured_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _9;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _31 = (BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y;\n    _9._m0[_31] = 1u;\n    _9._m0[_31 + 1u] = 2u;\n    _9._m0[_31 + 2u] = 3u;\n    _9._m0[143u] = 1u;\n    uint _41 = 143u + 1u;\n    _9._m0[_41] = 2u;\n    uint _43 = 143u + 2u;\n    _9._m0[_43] = 3u;\n    _9._m0[143u] = 6u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 59\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n    %uint_10 = OpConstant %uint 10\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %57\n\n         %57 = OpLabel\n         %14 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %16 =   OpLoad %uint %14\n         %18 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %19 =   OpAtomicLoad %uint %18 %uint_5 %uint_0\n         %21 =   OpIAdd %uint %19 %uint_10\n         %23 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %24 =   OpAtomicExchange %uint %23 %uint_5 %uint_0 %21\n         %26 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %27 =   OpAtomicCompareExchange %uint %26 %uint_5 %uint_0 %uint_0 %24 %uint_10\n         %28 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %29 =   OpAtomicIAdd %uint %28 %uint_5 %uint_0 %27\n         %30 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %31 =   OpAtomicISub %uint %30 %uint_5 %uint_0 %29\n         %32 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %33 =   OpAtomicSMin %uint %32 %uint_5 %uint_0 %31\n         %34 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %35 =   OpAtomicSMax %uint %34 %uint_5 %uint_0 %33\n         %36 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %37 =   OpAtomicUMin %uint %36 %uint_5 %uint_0 %35\n         %38 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %39 =   OpAtomicUMax %uint %38 %uint_5 %uint_0 %37\n         %40 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %41 =   OpAtomicAnd %uint %40 %uint_5 %uint_0 %39\n         %42 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %43 =   OpAtomicOr %uint %42 %uint_5 %uint_0 %41\n         %44 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %45 =   OpAtomicXor %uint %44 %uint_5 %uint_0 %43\n         %46 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %47 =   OpAtomicIAdd %uint %46 %uint_5 %uint_0 %uint_1\n         %49 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %50 =   OpAtomicISub %uint %49 %uint_5 %uint_0 %uint_1\n         %51 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n                 OpAtomicStore %51 %uint_5 %uint_0 %50\n         %52 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %53 =   OpAtomicIAdd %uint %52 %uint_5 %uint_0 %uint_1\n         %54 =   OpImageTexelPointer %_ptr_Image_uint %8 %16 %uint_0\n         %55 =   OpAtomicISub %uint %54 %uint_5 %uint_0 %uint_2\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_atomic.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _19 = imageAtomicAdd(_8, int(BUFFER_ADDRESS.x), 0u);\n    uint _24 = imageAtomicExchange(_8, int(BUFFER_ADDRESS.x), _19 + 10u);\n    uint _27 = imageAtomicCompSwap(_8, int(BUFFER_ADDRESS.x), 10u, _24);\n    uint _29 = imageAtomicAdd(_8, int(BUFFER_ADDRESS.x), _27);\n    uint _31 = imageAtomicAdd(_8, int(BUFFER_ADDRESS.x), -_29);\n    uint _33 = imageAtomicMin(_8, int(BUFFER_ADDRESS.x), _31);\n    uint _35 = imageAtomicMax(_8, int(BUFFER_ADDRESS.x), _33);\n    uint _37 = imageAtomicMin(_8, int(BUFFER_ADDRESS.x), _35);\n    uint _39 = imageAtomicMax(_8, int(BUFFER_ADDRESS.x), _37);\n    uint _41 = imageAtomicAnd(_8, int(BUFFER_ADDRESS.x), _39);\n    uint _43 = imageAtomicOr(_8, int(BUFFER_ADDRESS.x), _41);\n    uint _45 = imageAtomicXor(_8, int(BUFFER_ADDRESS.x), _43);\n    uint _47 = imageAtomicAdd(_8, int(BUFFER_ADDRESS.x), 1u);\n    uint _50 = imageAtomicAdd(_8, int(BUFFER_ADDRESS.x), -1u);\n    imageAtomicExchange(_8, int(BUFFER_ADDRESS.x), _50);\n    uint _53 = imageAtomicAdd(_8, int(BUFFER_ADDRESS.x), 1u);\n    uint _55 = imageAtomicAdd(_8, int(BUFFER_ADDRESS.x), -2u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_7 = OpConstant %uint 7\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %47\n\n         %47 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpImageRead %v4float %17 %21 NonPrivateTexel\n         %23 =   OpCompositeExtract %float %22 0\n         %24 =   OpCompositeExtract %float %22 1\n         %25 =   OpCompositeExtract %float %22 2\n         %26 =   OpCompositeExtract %float %22 3\n         %29 =   OpImageRead %v4float %17 %uint_7 NonPrivateTexel\n         %30 =   OpCompositeExtract %float %29 0\n         %31 =   OpCompositeExtract %float %29 1\n         %32 =   OpCompositeExtract %float %29 2\n         %33 =   OpCompositeExtract %float %29 3\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %36 %23\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %37 %24\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %39 %25\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %41 %26\n         %43 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %43 %30\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %44 %31\n         %45 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %45 %32\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %46 %33\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_load.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _8;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _22 = imageLoad(_8, int(BUFFER_ADDRESS.x));\n    vec4 _29 = imageLoad(_8, int(7u));\n    SV_TARGET.x = _22.x;\n    SV_TARGET.y = _22.y;\n    SV_TARGET.z = _22.z;\n    SV_TARGET.w = _22.w;\n    SV_TARGET_1.x = _29.x;\n    SV_TARGET_1.y = _29.y;\n    SV_TARGET_1.z = _29.z;\n    SV_TARGET_1.w = _29.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_load_precise.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 49\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonWritable\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 R32f\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n     %uint_7 = OpConstant %uint 7\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %47\n\n         %47 = OpLabel\n         %17 =   OpLoad %6 %8\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpImageRead %v4float %17 %21 NonPrivateTexel\n         %23 =   OpCompositeExtract %float %22 0\n         %24 =   OpCompositeExtract %float %22 1\n         %25 =   OpCompositeExtract %float %22 2\n         %26 =   OpCompositeExtract %float %22 3\n         %29 =   OpImageRead %v4float %17 %uint_7 NonPrivateTexel\n         %30 =   OpCompositeExtract %float %29 0\n         %31 =   OpCompositeExtract %float %29 1\n         %32 =   OpCompositeExtract %float %29 2\n         %33 =   OpCompositeExtract %float %29 3\n         %36 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %36 %23\n         %37 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %37 %24\n         %39 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %39 %25\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %41 %26\n         %43 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %43 %30\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %44 %31\n         %45 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %45 %32\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %46 %33\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_load_precise.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _8;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _22 = imageLoad(_8, int(BUFFER_ADDRESS.x));\n    vec4 _29 = imageLoad(_8, int(7u));\n    SV_TARGET.x = _22.x;\n    SV_TARGET.y = _22.y;\n    SV_TARGET.z = _22.z;\n    SV_TARGET.w = _22.w;\n    SV_TARGET_1.x = _29.x;\n    SV_TARGET_1.y = _29.y;\n    SV_TARGET_1.z = _29.z;\n    SV_TARGET_1.w = _29.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 16\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %8 NonWritable\n               OpDecorate %SV_TARGET Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %14\n\n         %14 = OpLabel\n         %12 =   OpLoad %6 %8\n         %13 =   OpImageQuerySize %uint %12\n                 OpStore %SV_TARGET %13\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_query.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform readonly writeonly imageBuffer _8;\n\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(imageSize(_8));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 29\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %8 %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %8 DescriptorSet 0\n               OpDecorate %8 Binding 0\n               OpDecorate %8 NonReadable\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 Unknown\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n          %8 = OpVariable %_ptr_UniformConstant_6 UniformConstant\n       %uint = OpTypeInt 32 0\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Input_uint = OpTypePointer Input %uint\n     %uint_0 = OpConstant %uint 0\n    %v4float = OpTypeVector %float 4\n    %float_1 = OpConstant %float 1\n    %float_2 = OpConstant %float 2\n    %float_3 = OpConstant %float 3\n    %float_4 = OpConstant %float 4\n     %uint_7 = OpConstant %uint 7\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %27\n\n         %27 = OpLabel\n         %13 =   OpLoad %6 %8\n         %15 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %17 =   OpLoad %uint %15\n         %24 =   OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4\n                 OpImageWrite %13 %17 %24 NonPrivateTexel\n         %26 =   OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4\n                 OpImageWrite %13 %uint_7 %26 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_buffer_typed_store.glsl",
    "content": "GLSL:\n#version 460\n\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _8;\n\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    imageStore(_8, int(BUFFER_ADDRESS.x), vec4(1.0, 2.0, 3.0, 4.0));\n    imageStore(_8, int(7u), vec4(1.0, 2.0, 3.0, 4.0));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 137\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %16 NonUniform\n               OpDecorate %18 NonUniform\n               OpDecorate %33 NonUniform\n               OpDecorate %42 NonUniform\n               OpDecorate %49 NonUniform\n               OpDecorate %55 NonUniform\n               OpDecorate %61 NonUniform\n               OpDecorate %67 NonUniform\n               OpDecorate %73 NonUniform\n               OpDecorate %79 NonUniform\n               OpDecorate %85 NonUniform\n               OpDecorate %91 NonUniform\n               OpDecorate %97 NonUniform\n               OpDecorate %103 NonUniform\n               OpDecorate %109 NonUniform\n               OpDecorate %116 NonUniform\n               OpDecorate %122 NonUniform\n               OpDecorate %127 NonUniform\n               OpDecorate %133 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_5 = OpConstant %uint 5\n    %uint_10 = OpConstant %uint 10\n     %uint_1 = OpConstant %uint 1\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %135\n\n        %135 = OpLabel\n         %16 =   OpLoad %uint %BUFFER_INDEX\n         %18 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %16\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpIMul %uint %21 %uint_4\n         %26 =   OpIMul %uint %uint_16 %21\n         %30 =   OpIMul %uint %21 %uint_4\n         %31 =   OpIAdd %uint %30 %uint_2\n         %33 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %31\n         %34 =   OpAtomicLoad %uint %33 %uint_5 %uint_0\n         %36 =   OpIAdd %uint %34 %uint_10\n         %38 =   OpIMul %uint %uint_16 %21\n         %40 =   OpIMul %uint %21 %uint_4\n         %41 =   OpIAdd %uint %40 %uint_2\n         %42 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %41\n         %43 =   OpAtomicExchange %uint %42 %uint_5 %uint_0 %36\n         %45 =   OpIMul %uint %uint_16 %21\n         %47 =   OpIMul %uint %21 %uint_4\n         %48 =   OpIAdd %uint %47 %uint_2\n         %49 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %48\n         %50 =   OpAtomicCompareExchange %uint %49 %uint_5 %uint_0 %uint_0 %43 %uint_10\n         %51 =   OpIMul %uint %uint_16 %21\n         %53 =   OpIMul %uint %21 %uint_4\n         %54 =   OpIAdd %uint %53 %uint_2\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %54\n         %56 =   OpAtomicIAdd %uint %55 %uint_5 %uint_0 %50\n         %57 =   OpIMul %uint %uint_16 %21\n         %59 =   OpIMul %uint %21 %uint_4\n         %60 =   OpIAdd %uint %59 %uint_2\n         %61 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %60\n         %62 =   OpAtomicISub %uint %61 %uint_5 %uint_0 %56\n         %63 =   OpIMul %uint %uint_16 %21\n         %65 =   OpIMul %uint %21 %uint_4\n         %66 =   OpIAdd %uint %65 %uint_2\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %66\n         %68 =   OpAtomicSMin %uint %67 %uint_5 %uint_0 %62\n         %69 =   OpIMul %uint %uint_16 %21\n         %71 =   OpIMul %uint %21 %uint_4\n         %72 =   OpIAdd %uint %71 %uint_2\n         %73 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %72\n         %74 =   OpAtomicSMax %uint %73 %uint_5 %uint_0 %68\n         %75 =   OpIMul %uint %uint_16 %21\n         %77 =   OpIMul %uint %21 %uint_4\n         %78 =   OpIAdd %uint %77 %uint_2\n         %79 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %78\n         %80 =   OpAtomicUMin %uint %79 %uint_5 %uint_0 %74\n         %81 =   OpIMul %uint %uint_16 %21\n         %83 =   OpIMul %uint %21 %uint_4\n         %84 =   OpIAdd %uint %83 %uint_2\n         %85 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %84\n         %86 =   OpAtomicUMax %uint %85 %uint_5 %uint_0 %80\n         %87 =   OpIMul %uint %uint_16 %21\n         %89 =   OpIMul %uint %21 %uint_4\n         %90 =   OpIAdd %uint %89 %uint_2\n         %91 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %90\n         %92 =   OpAtomicAnd %uint %91 %uint_5 %uint_0 %86\n         %93 =   OpIMul %uint %uint_16 %21\n         %95 =   OpIMul %uint %21 %uint_4\n         %96 =   OpIAdd %uint %95 %uint_2\n         %97 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %96\n         %98 =   OpAtomicOr %uint %97 %uint_5 %uint_0 %92\n         %99 =   OpIMul %uint %uint_16 %21\n        %101 =   OpIMul %uint %21 %uint_4\n        %102 =   OpIAdd %uint %101 %uint_2\n        %103 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %102\n        %104 =   OpAtomicXor %uint %103 %uint_5 %uint_0 %98\n        %105 =   OpIMul %uint %uint_16 %21\n        %107 =   OpIMul %uint %21 %uint_4\n        %108 =   OpIAdd %uint %107 %uint_2\n        %109 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %108\n        %110 =   OpAtomicIAdd %uint %109 %uint_5 %uint_0 %uint_1\n        %112 =   OpIMul %uint %uint_16 %21\n        %114 =   OpIMul %uint %21 %uint_4\n        %115 =   OpIAdd %uint %114 %uint_2\n        %116 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %115\n        %117 =   OpAtomicISub %uint %116 %uint_5 %uint_0 %uint_1\n        %118 =   OpIMul %uint %uint_16 %21\n        %120 =   OpIMul %uint %21 %uint_4\n        %121 =   OpIAdd %uint %120 %uint_2\n        %122 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %121\n                 OpAtomicStore %122 %uint_5 %uint_0 %117\n        %123 =   OpIMul %uint %uint_16 %21\n        %125 =   OpIMul %uint %21 %uint_4\n        %126 =   OpIAdd %uint %125 %uint_2\n        %127 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %126\n        %128 =   OpAtomicIAdd %uint %127 %uint_5 %uint_0 %uint_1\n        %129 =   OpIMul %uint %uint_16 %21\n        %131 =   OpIMul %uint %21 %uint_4\n        %132 =   OpIAdd %uint %131 %uint_2\n        %133 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %132\n        %134 =   OpAtomicISub %uint %133 %uint_5 %uint_0 %uint_2\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _34 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 0u);\n    uint _43 = atomicExchange(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _34 + 10u);\n    uint _50 = atomicCompSwap(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 10u, _43);\n    uint _56 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _50);\n    uint _62 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], -_56);\n    uint _68 = atomicMin(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _62);\n    uint _74 = atomicMax(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _68);\n    uint _80 = atomicMin(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _74);\n    uint _86 = atomicMax(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _80);\n    uint _92 = atomicAnd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _86);\n    uint _98 = atomicOr(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _92);\n    uint _104 = atomicXor(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _98);\n    uint _110 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 1u);\n    uint _117 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], -1u);\n    atomicExchange(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], _117);\n    uint _128 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], 1u);\n    uint _134 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u], -2u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 74\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %16 %BUFFER_INDEX %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %SSBO_0 \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %_runtimearr_v2uint ArrayStride 8\n               OpMemberDecorate %SSBO_0 0 Offset 0\n               OpDecorate %SSBO_0 Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %10 Aliased\n               OpDecorate %16 DescriptorSet 0\n               OpDecorate %16 Binding 0\n               OpDecorate %16 NonWritable\n               OpDecorate %16 Aliased\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %26 NonUniform\n               OpDecorate %28 NonUniform\n               OpDecorate %30 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %53 NonUniform\n               OpDecorate %55 NonUniform\n               OpDecorate %70 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n     %v2uint = OpTypeVector %uint 2\n%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint\n     %SSBO_0 = OpTypeStruct %_runtimearr_v2uint\n%_runtimearr_SSBO_0 = OpTypeRuntimeArray %SSBO_0\n%_ptr_StorageBuffer__runtimearr_SSBO_0 = OpTypePointer StorageBuffer %_runtimearr_SSBO_0\n         %16 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO_0 StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n%_ptr_StorageBuffer_SSBO_0 = OpTypePointer StorageBuffer %SSBO_0\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n     %uint_1 = OpConstant %uint 1\n%_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint\n     %uint_7 = OpConstant %uint 7\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %72\n\n         %72 = OpLabel\n         %26 =   OpLoad %uint %BUFFER_INDEX\n         %28 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %26\n         %30 =   OpAccessChain %_ptr_StorageBuffer_SSBO_0 %16 %26\n         %31 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %33 =   OpLoad %uint %31\n         %34 =   OpIMul %uint %33 %uint_4\n         %38 =   OpIMul %uint %uint_16 %33\n         %42 =   OpIMul %uint %33 %uint_2\n         %43 =   OpIAdd %uint %42 %uint_1\n         %46 =   OpAccessChain %_ptr_StorageBuffer_v2uint %30 %uint_0 %43\n         %47 =   OpLoad %v2uint %46 NonPrivatePointer\n         %48 =   OpCompositeExtract %uint %47 0\n         %49 =   OpCompositeExtract %uint %47 1\n         %53 =   OpAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 %uint_7\n         %54 =   OpLoad %uint %53 NonPrivatePointer\n         %56 =   OpIAdd %uint %uint_7 %uint_1\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 %56\n         %57 =   OpLoad %uint %55 NonPrivatePointer\n         %58 =   OpCompositeConstruct %v2uint %54 %57\n         %59 =   OpCompositeExtract %uint %58 0\n         %60 =   OpCompositeExtract %uint %58 1\n         %62 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %62 %48\n         %63 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %63 %49\n         %64 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %64 %59\n         %65 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %65 %60\n         %66 =   OpIMul %uint %uint_16 %33\n         %68 =   OpIMul %uint %33 %uint_4\n         %69 =   OpIAdd %uint %68 %uint_2\n         %70 =   OpAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 %69\n         %71 =   OpLoad %uint %70 NonPrivatePointer\n                 OpStore %SV_TARGET_3 %71\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(set = 0, binding = 0, std430) readonly buffer _13_16\n{\n    uvec2 _m0[];\n} _16[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _43 = (BUFFER_ADDRESS.x * 2u) + 1u;\n    uint _56 = 7u + 1u;\n    uvec2 _58 = uvec2(_10[nonuniformEXT(BUFFER_INDEX)]._m0[7u], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_56]);\n    SV_TARGET.x = _16[nonuniformEXT(BUFFER_INDEX)]._m0[_43].x;\n    SV_TARGET.y = _16[nonuniformEXT(BUFFER_INDEX)]._m0[_43].y;\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    SV_TARGET_3 = _10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 4u) + 2u];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 21\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonReadable\n               OpDecorate %10 NonWritable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %15 NonUniform\n               OpDecorate %17 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %19\n\n         %19 = OpLabel\n         %15 =   OpLoad %uint %BUFFER_INDEX\n         %17 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %15\n         %18 =   OpArrayLength %uint %17 0\n                 OpStore %SV_TARGET %18\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_10[nonuniformEXT(BUFFER_INDEX)]._m0.length());\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 52\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonReadable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %16 NonUniform\n               OpDecorate %18 NonUniform\n               OpDecorate %37 NonUniform\n               OpDecorate %38 NonUniform\n               OpDecorate %40 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %44 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %49 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n     %uint_0 = OpConstant %uint 0\n     %uint_4 = OpConstant %uint 4\n     %uint_2 = OpConstant %uint 2\n     %v3uint = OpTypeVector %uint 3\n     %uint_1 = OpConstant %uint 1\n     %uint_3 = OpConstant %uint 3\n    %uint_16 = OpConstant %uint 16\n     %uint_8 = OpConstant %uint 8\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_7 = OpConstant %uint 7\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %50\n\n         %50 = OpLabel\n         %16 =   OpLoad %uint %BUFFER_INDEX\n         %18 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %16\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpIMul %uint %21 %uint_4\n         %30 =   OpIMul %uint %uint_16 %21\n         %34 =   OpIMul %uint %21 %uint_4\n         %35 =   OpIAdd %uint %34 %uint_2\n         %37 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %35\n                 OpStore %37 %uint_1 NonPrivatePointer\n         %39 =   OpIAdd %uint %35 %uint_1\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %39\n                 OpStore %38 %uint_2 NonPrivatePointer\n         %41 =   OpIAdd %uint %35 %uint_2\n         %40 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %41\n                 OpStore %40 %uint_3 NonPrivatePointer\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %uint_7\n                 OpStore %43 %uint_1 NonPrivatePointer\n         %45 =   OpIAdd %uint %uint_7 %uint_1\n         %44 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %45\n                 OpStore %44 %uint_2 NonPrivatePointer\n         %47 =   OpIAdd %uint %uint_7 %uint_2\n         %46 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %47\n                 OpStore %46 %uint_3 NonPrivatePointer\n         %49 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %uint_7\n                 OpStore %49 %uint_6 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_raw_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _35 = (BUFFER_ADDRESS.x * 4u) + 2u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_35] = 1u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_35 + 1u] = 2u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_35 + 2u] = 3u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[7u] = 1u;\n    uint _45 = 7u + 1u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_45] = 2u;\n    uint _47 = 7u + 2u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_47] = 3u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[7u] = 6u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 120\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %16 NonUniform\n               OpDecorate %18 NonUniform\n               OpDecorate %32 NonUniform\n               OpDecorate %40 NonUniform\n               OpDecorate %46 NonUniform\n               OpDecorate %51 NonUniform\n               OpDecorate %56 NonUniform\n               OpDecorate %61 NonUniform\n               OpDecorate %66 NonUniform\n               OpDecorate %71 NonUniform\n               OpDecorate %76 NonUniform\n               OpDecorate %81 NonUniform\n               OpDecorate %86 NonUniform\n               OpDecorate %91 NonUniform\n               OpDecorate %96 NonUniform\n               OpDecorate %101 NonUniform\n               OpDecorate %106 NonUniform\n               OpDecorate %110 NonUniform\n               OpDecorate %115 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n     %uint_5 = OpConstant %uint 5\n    %uint_10 = OpConstant %uint 10\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %118\n\n        %118 = OpLabel\n         %16 =   OpLoad %uint %BUFFER_INDEX\n         %18 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %16\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %24 =   OpLoad %uint %22\n         %28 =   OpIMul %uint %21 %uint_20\n         %30 =   OpIAdd %uint %28 %24\n         %32 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %30\n         %33 =   OpAtomicLoad %uint %32 %uint_5 %uint_0\n         %35 =   OpIAdd %uint %33 %uint_10\n         %38 =   OpIMul %uint %21 %uint_20\n         %39 =   OpIAdd %uint %38 %24\n         %40 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %39\n         %41 =   OpAtomicExchange %uint %40 %uint_5 %uint_0 %35\n         %44 =   OpIMul %uint %21 %uint_20\n         %45 =   OpIAdd %uint %44 %24\n         %46 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %45\n         %47 =   OpAtomicCompareExchange %uint %46 %uint_5 %uint_0 %uint_0 %41 %uint_10\n         %49 =   OpIMul %uint %21 %uint_20\n         %50 =   OpIAdd %uint %49 %24\n         %51 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %50\n         %52 =   OpAtomicIAdd %uint %51 %uint_5 %uint_0 %47\n         %54 =   OpIMul %uint %21 %uint_20\n         %55 =   OpIAdd %uint %54 %24\n         %56 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %55\n         %57 =   OpAtomicISub %uint %56 %uint_5 %uint_0 %52\n         %59 =   OpIMul %uint %21 %uint_20\n         %60 =   OpIAdd %uint %59 %24\n         %61 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %60\n         %62 =   OpAtomicSMin %uint %61 %uint_5 %uint_0 %57\n         %64 =   OpIMul %uint %21 %uint_20\n         %65 =   OpIAdd %uint %64 %24\n         %66 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %65\n         %67 =   OpAtomicSMax %uint %66 %uint_5 %uint_0 %62\n         %69 =   OpIMul %uint %21 %uint_20\n         %70 =   OpIAdd %uint %69 %24\n         %71 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %70\n         %72 =   OpAtomicUMin %uint %71 %uint_5 %uint_0 %67\n         %74 =   OpIMul %uint %21 %uint_20\n         %75 =   OpIAdd %uint %74 %24\n         %76 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %75\n         %77 =   OpAtomicUMax %uint %76 %uint_5 %uint_0 %72\n         %79 =   OpIMul %uint %21 %uint_20\n         %80 =   OpIAdd %uint %79 %24\n         %81 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %80\n         %82 =   OpAtomicAnd %uint %81 %uint_5 %uint_0 %77\n         %84 =   OpIMul %uint %21 %uint_20\n         %85 =   OpIAdd %uint %84 %24\n         %86 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %85\n         %87 =   OpAtomicOr %uint %86 %uint_5 %uint_0 %82\n         %89 =   OpIMul %uint %21 %uint_20\n         %90 =   OpIAdd %uint %89 %24\n         %91 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %90\n         %92 =   OpAtomicXor %uint %91 %uint_5 %uint_0 %87\n         %94 =   OpIMul %uint %21 %uint_20\n         %95 =   OpIAdd %uint %94 %24\n         %96 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %95\n         %97 =   OpAtomicIAdd %uint %96 %uint_5 %uint_0 %uint_1\n         %99 =   OpIMul %uint %21 %uint_20\n        %100 =   OpIAdd %uint %99 %24\n        %101 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %100\n        %102 =   OpAtomicISub %uint %101 %uint_5 %uint_0 %uint_1\n        %104 =   OpIMul %uint %21 %uint_20\n        %105 =   OpIAdd %uint %104 %24\n        %106 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %105\n                 OpAtomicStore %106 %uint_5 %uint_0 %102\n        %108 =   OpIMul %uint %21 %uint_20\n        %109 =   OpIAdd %uint %108 %24\n        %110 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %109\n        %111 =   OpAtomicIAdd %uint %110 %uint_5 %uint_0 %uint_1\n        %113 =   OpIMul %uint %21 %uint_20\n        %114 =   OpIAdd %uint %113 %24\n        %115 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %114\n        %116 =   OpAtomicISub %uint %115 %uint_5 %uint_0 %uint_2\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _33 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 0u);\n    uint _41 = atomicExchange(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _33 + 10u);\n    uint _47 = atomicCompSwap(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 10u, _41);\n    uint _52 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _47);\n    uint _57 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], -_52);\n    uint _62 = atomicMin(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _57);\n    uint _67 = atomicMax(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _62);\n    uint _72 = atomicMin(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _67);\n    uint _77 = atomicMax(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _72);\n    uint _82 = atomicAnd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _77);\n    uint _87 = atomicOr(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _82);\n    uint _92 = atomicXor(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _87);\n    uint _97 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 1u);\n    uint _102 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], -1u);\n    atomicExchange(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], _102);\n    uint _111 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], 1u);\n    uint _116 = atomicAdd(_10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y], -2u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 96\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1 %SV_TARGET_2 %SV_TARGET_3\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpName %SV_TARGET_2 \"SV_TARGET_2\"\n               OpName %SV_TARGET_3 \"SV_TARGET_3\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonWritable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %SV_TARGET_2 Location 2\n               OpDecorate %SV_TARGET_3 Location 3\n               OpDecorate %24 NonUniform\n               OpDecorate %26 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %53 NonUniform\n               OpDecorate %55 NonUniform\n               OpDecorate %67 NonUniform\n               OpDecorate %69 NonUniform\n               OpDecorate %72 NonUniform\n               OpDecorate %76 NonUniform\n               OpDecorate %92 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_Output_v2uint = OpTypePointer Output %v2uint\n  %SV_TARGET = OpVariable %_ptr_Output_v2uint Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v2uint Output\n     %v4uint = OpTypeVector %uint 4\n%_ptr_Output_v4uint = OpTypePointer Output %v4uint\n%SV_TARGET_2 = OpVariable %_ptr_Output_v4uint Output\n%_ptr_Output_uint = OpTypePointer Output %uint\n%SV_TARGET_3 = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_7 = OpConstant %uint 7\n     %uint_3 = OpConstant %uint 3\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n   %uint_143 = OpConstant %uint 143\n   %uint_331 = OpConstant %uint 331\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %94\n\n         %94 = OpLabel\n         %24 =   OpLoad %uint %BUFFER_INDEX\n         %26 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %24\n         %27 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %29 =   OpLoad %uint %27\n         %30 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %32 =   OpLoad %uint %30\n         %39 =   OpIMul %uint %29 %uint_20\n         %41 =   OpIAdd %uint %39 %32\n         %43 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %41\n         %44 =   OpLoad %uint %43 NonPrivatePointer\n         %46 =   OpIAdd %uint %41 %uint_1\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %46\n         %47 =   OpLoad %uint %45 NonPrivatePointer\n         %48 =   OpCompositeConstruct %v2uint %44 %47\n         %49 =   OpCompositeExtract %uint %48 0\n         %50 =   OpCompositeExtract %uint %48 1\n         %53 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %uint_143\n         %54 =   OpLoad %uint %53 NonPrivatePointer\n         %56 =   OpIAdd %uint %uint_143 %uint_1\n         %55 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %56\n         %57 =   OpLoad %uint %55 NonPrivatePointer\n         %58 =   OpCompositeConstruct %v2uint %54 %57\n         %59 =   OpCompositeExtract %uint %58 0\n         %60 =   OpCompositeExtract %uint %58 1\n         %62 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_0\n                 OpStore %62 %49\n         %63 =   OpAccessChain %_ptr_Output_uint %SV_TARGET %uint_1\n                 OpStore %63 %50\n         %64 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_0\n                 OpStore %64 %59\n         %65 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_1 %uint_1\n                 OpStore %65 %60\n         %67 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %uint_331\n         %68 =   OpLoad %uint %67 NonPrivatePointer\n         %70 =   OpIAdd %uint %uint_331 %uint_1\n         %69 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %70\n         %71 =   OpLoad %uint %69 NonPrivatePointer\n         %73 =   OpIAdd %uint %uint_331 %uint_2\n         %72 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %73\n         %75 =   OpLoad %uint %72 NonPrivatePointer\n         %77 =   OpIAdd %uint %uint_331 %uint_3\n         %76 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %77\n         %78 =   OpLoad %uint %76 NonPrivatePointer\n         %79 =   OpCompositeConstruct %v4uint %68 %71 %75 %78\n         %80 =   OpCompositeExtract %uint %79 0\n         %81 =   OpCompositeExtract %uint %79 1\n         %82 =   OpCompositeExtract %uint %79 2\n         %83 =   OpCompositeExtract %uint %79 3\n         %85 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_0\n                 OpStore %85 %80\n         %86 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_1\n                 OpStore %86 %81\n         %87 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_2\n                 OpStore %87 %82\n         %88 =   OpAccessChain %_ptr_Output_uint %SV_TARGET_2 %uint_3\n                 OpStore %88 %83\n         %90 =   OpIMul %uint %29 %uint_20\n         %91 =   OpIAdd %uint %90 %32\n         %92 =   OpAccessChain %_ptr_StorageBuffer_uint %26 %uint_0 %91\n         %93 =   OpLoad %uint %92 NonPrivatePointer\n                 OpStore %SV_TARGET_3 %93\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out uvec2 SV_TARGET;\nlayout(location = 1) out uvec2 SV_TARGET_1;\nlayout(location = 2) out uvec4 SV_TARGET_2;\nlayout(location = 3) out uint SV_TARGET_3;\n\nvoid main()\n{\n    uint _41 = (BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y;\n    uvec2 _48 = uvec2(_10[nonuniformEXT(BUFFER_INDEX)]._m0[_41], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_41 + 1u]);\n    uint _56 = 143u + 1u;\n    uvec2 _58 = uvec2(_10[nonuniformEXT(BUFFER_INDEX)]._m0[143u], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_56]);\n    SV_TARGET.x = _48.x;\n    SV_TARGET.y = _48.y;\n    SV_TARGET_1.x = _58.x;\n    SV_TARGET_1.y = _58.y;\n    uint _70 = 331u + 1u;\n    uint _73 = 331u + 2u;\n    uint _77 = 331u + 3u;\n    uvec4 _79 = uvec4(_10[nonuniformEXT(BUFFER_INDEX)]._m0[331u], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_70], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_73], _10[nonuniformEXT(BUFFER_INDEX)]._m0[_77]);\n    SV_TARGET_2.x = _79.x;\n    SV_TARGET_2.y = _79.y;\n    SV_TARGET_2.z = _79.z;\n    SV_TARGET_2.w = _79.w;\n    SV_TARGET_3 = _10[nonuniformEXT(BUFFER_INDEX)]._m0[(BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y];\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 23\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonReadable\n               OpDecorate %10 NonWritable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %15 NonUniform\n               OpDecorate %17 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n    %uint_20 = OpConstant %uint 20\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %21\n\n         %21 = OpLabel\n         %15 =   OpLoad %uint %BUFFER_INDEX\n         %17 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %15\n         %18 =   OpArrayLength %uint %17 0\n         %19 =   OpUDiv %uint %18 %uint_20\n                 OpStore %SV_TARGET %19\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) writeonly readonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(_10[nonuniformEXT(BUFFER_INDEX)]._m0.length()) / 20u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 53\n; Schema: 0\n               OpCapability Shader\n               OpCapability StorageBufferArrayDynamicIndexing\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %10 %BUFFER_INDEX %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %SSBO \"SSBO\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %_runtimearr_uint ArrayStride 4\n               OpMemberDecorate %SSBO 0 Offset 0\n               OpDecorate %SSBO Block\n               OpDecorate %10 DescriptorSet 0\n               OpDecorate %10 Binding 0\n               OpDecorate %10 NonReadable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %16 NonUniform\n               OpDecorate %18 NonUniform\n               OpDecorate %38 NonUniform\n               OpDecorate %39 NonUniform\n               OpDecorate %41 NonUniform\n               OpDecorate %44 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %47 NonUniform\n               OpDecorate %50 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n%_runtimearr_uint = OpTypeRuntimeArray %uint\n       %SSBO = OpTypeStruct %_runtimearr_uint\n%_runtimearr_SSBO = OpTypeRuntimeArray %SSBO\n%_ptr_StorageBuffer__runtimearr_SSBO = OpTypePointer StorageBuffer %_runtimearr_SSBO\n         %10 = OpVariable %_ptr_StorageBuffer__runtimearr_SSBO StorageBuffer\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO\n     %uint_0 = OpConstant %uint 0\n     %uint_1 = OpConstant %uint 1\n     %uint_7 = OpConstant %uint 7\n     %uint_3 = OpConstant %uint 3\n     %v3uint = OpTypeVector %uint 3\n     %uint_2 = OpConstant %uint 2\n     %uint_4 = OpConstant %uint 4\n    %uint_20 = OpConstant %uint 20\n%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n   %uint_143 = OpConstant %uint 143\n     %uint_6 = OpConstant %uint 6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %51\n\n         %51 = OpLabel\n         %16 =   OpLoad %uint %BUFFER_INDEX\n         %18 =   OpAccessChain %_ptr_StorageBuffer_SSBO %10 %16\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %22 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_1\n         %24 =   OpLoad %uint %22\n         %34 =   OpIMul %uint %21 %uint_20\n         %36 =   OpIAdd %uint %34 %24\n         %38 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %36\n                 OpStore %38 %uint_1 NonPrivatePointer\n         %40 =   OpIAdd %uint %36 %uint_1\n         %39 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %40\n                 OpStore %39 %uint_2 NonPrivatePointer\n         %42 =   OpIAdd %uint %36 %uint_2\n         %41 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %42\n                 OpStore %41 %uint_3 NonPrivatePointer\n         %44 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %uint_143\n                 OpStore %44 %uint_1 NonPrivatePointer\n         %46 =   OpIAdd %uint %uint_143 %uint_1\n         %45 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %46\n                 OpStore %45 %uint_2 NonPrivatePointer\n         %48 =   OpIAdd %uint %uint_143 %uint_2\n         %47 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %48\n                 OpStore %47 %uint_3 NonPrivatePointer\n         %50 =   OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_0 %uint_143\n                 OpStore %50 %uint_6 NonPrivatePointer\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_structured_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, std430) writeonly buffer SSBO\n{\n    uint _m0[];\n} _10[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _36 = (BUFFER_ADDRESS.x * 20u) + BUFFER_ADDRESS.y;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_36] = 1u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_36 + 1u] = 2u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_36 + 2u] = 3u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[143u] = 1u;\n    uint _46 = 143u + 1u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_46] = 2u;\n    uint _48 = 143u + 2u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[_48] = 3u;\n    _10[nonuniformEXT(BUFFER_INDEX)]._m0[143u] = 6u;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_atomic.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 64\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageTexelBufferArrayDynamicIndexing\n               OpCapability StorageTexelBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_INDEX %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %15 NonUniform\n               OpDecorate %23 NonUniform\n               OpDecorate %28 NonUniform\n               OpDecorate %31 NonUniform\n               OpDecorate %33 NonUniform\n               OpDecorate %35 NonUniform\n               OpDecorate %37 NonUniform\n               OpDecorate %39 NonUniform\n               OpDecorate %41 NonUniform\n               OpDecorate %43 NonUniform\n               OpDecorate %45 NonUniform\n               OpDecorate %47 NonUniform\n               OpDecorate %49 NonUniform\n               OpDecorate %51 NonUniform\n               OpDecorate %54 NonUniform\n               OpDecorate %56 NonUniform\n               OpDecorate %57 NonUniform\n               OpDecorate %59 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n       %uint = OpTypeInt 32 0\n          %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_0 = OpConstant %uint 0\n%_ptr_Image_uint = OpTypePointer Image %uint\n     %uint_5 = OpConstant %uint 5\n    %uint_10 = OpConstant %uint 10\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %62\n\n         %62 = OpLabel\n         %15 =   OpLoad %uint %BUFFER_INDEX\n         %17 =   OpAccessChain %_ptr_UniformConstant_6 %9 %15\n         %19 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %21 =   OpLoad %uint %19\n         %23 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %24 =   OpAtomicLoad %uint %23 %uint_5 %uint_0\n         %26 =   OpIAdd %uint %24 %uint_10\n         %28 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %29 =   OpAtomicExchange %uint %28 %uint_5 %uint_0 %26\n         %31 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %32 =   OpAtomicCompareExchange %uint %31 %uint_5 %uint_0 %uint_0 %29 %uint_10\n         %33 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %34 =   OpAtomicIAdd %uint %33 %uint_5 %uint_0 %32\n         %35 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %36 =   OpAtomicISub %uint %35 %uint_5 %uint_0 %34\n         %37 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %38 =   OpAtomicSMin %uint %37 %uint_5 %uint_0 %36\n         %39 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %40 =   OpAtomicSMax %uint %39 %uint_5 %uint_0 %38\n         %41 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %42 =   OpAtomicUMin %uint %41 %uint_5 %uint_0 %40\n         %43 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %44 =   OpAtomicUMax %uint %43 %uint_5 %uint_0 %42\n         %45 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %46 =   OpAtomicAnd %uint %45 %uint_5 %uint_0 %44\n         %47 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %48 =   OpAtomicOr %uint %47 %uint_5 %uint_0 %46\n         %49 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %50 =   OpAtomicXor %uint %49 %uint_5 %uint_0 %48\n         %51 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %52 =   OpAtomicIAdd %uint %51 %uint_5 %uint_0 %uint_1\n         %54 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %55 =   OpAtomicISub %uint %54 %uint_5 %uint_0 %uint_1\n         %56 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n                 OpAtomicStore %56 %uint_5 %uint_0 %55\n         %57 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %58 =   OpAtomicIAdd %uint %57 %uint_5 %uint_0 %uint_1\n         %59 =   OpImageTexelPointer %_ptr_Image_uint %17 %21 %uint_0\n         %60 =   OpAtomicISub %uint %59 %uint_5 %uint_0 %uint_2\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_atomic.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32ui) uniform uimageBuffer _9[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    uint _24 = imageAtomicAdd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), 0u);\n    uint _29 = imageAtomicExchange(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _24 + 10u);\n    uint _32 = imageAtomicCompSwap(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), 10u, _29);\n    uint _34 = imageAtomicAdd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _32);\n    uint _36 = imageAtomicAdd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), -_34);\n    uint _38 = imageAtomicMin(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _36);\n    uint _40 = imageAtomicMax(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _38);\n    uint _42 = imageAtomicMin(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _40);\n    uint _44 = imageAtomicMax(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _42);\n    uint _46 = imageAtomicAnd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _44);\n    uint _48 = imageAtomicOr(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _46);\n    uint _50 = imageAtomicXor(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _48);\n    uint _52 = imageAtomicAdd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), 1u);\n    uint _55 = imageAtomicAdd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), -1u);\n    imageAtomicExchange(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), _55);\n    uint _58 = imageAtomicAdd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), 1u);\n    uint _60 = imageAtomicAdd(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), -2u);\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_load.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 54\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageTexelBufferArrayDynamicIndexing\n               OpCapability StorageTexelBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_INDEX %BUFFER_ADDRESS %SV_TARGET %SV_TARGET_1\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpName %SV_TARGET_1 \"SV_TARGET_1\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonWritable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %SV_TARGET_1 Location 1\n               OpDecorate %20 NonUniform\n               OpDecorate %23 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 R32f\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n    %v4float = OpTypeVector %float 4\n%_ptr_Output_v4float = OpTypePointer Output %v4float\n  %SV_TARGET = OpVariable %_ptr_Output_v4float Output\n%SV_TARGET_1 = OpVariable %_ptr_Output_v4float Output\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_0 = OpConstant %uint 0\n     %uint_7 = OpConstant %uint 7\n%_ptr_Output_float = OpTypePointer Output %float\n     %uint_1 = OpConstant %uint 1\n     %uint_2 = OpConstant %uint 2\n     %uint_3 = OpConstant %uint 3\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %52\n\n         %52 = OpLabel\n         %20 =   OpLoad %uint %BUFFER_INDEX\n         %22 =   OpAccessChain %_ptr_UniformConstant_6 %9 %20\n         %23 =   OpLoad %6 %22\n         %24 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %26 =   OpLoad %uint %24\n         %27 =   OpImageRead %v4float %23 %26 NonPrivateTexel\n         %28 =   OpCompositeExtract %float %27 0\n         %29 =   OpCompositeExtract %float %27 1\n         %30 =   OpCompositeExtract %float %27 2\n         %31 =   OpCompositeExtract %float %27 3\n         %34 =   OpImageRead %v4float %23 %uint_7 NonPrivateTexel\n         %35 =   OpCompositeExtract %float %34 0\n         %36 =   OpCompositeExtract %float %34 1\n         %37 =   OpCompositeExtract %float %34 2\n         %38 =   OpCompositeExtract %float %34 3\n         %41 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_0\n                 OpStore %41 %28\n         %42 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_1\n                 OpStore %42 %29\n         %44 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_2\n                 OpStore %44 %30\n         %46 =   OpAccessChain %_ptr_Output_float %SV_TARGET %uint_3\n                 OpStore %46 %31\n         %48 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_0\n                 OpStore %48 %35\n         %49 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_1\n                 OpStore %49 %36\n         %50 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_2\n                 OpStore %50 %37\n         %51 =   OpAccessChain %_ptr_Output_float %SV_TARGET_1 %uint_3\n                 OpStore %51 %38\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_load.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0, r32f) uniform readonly imageBuffer _9[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\nlayout(location = 0) out vec4 SV_TARGET;\nlayout(location = 1) out vec4 SV_TARGET_1;\n\nvoid main()\n{\n    vec4 _27 = imageLoad(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x));\n    vec4 _34 = imageLoad(_9[nonuniformEXT(BUFFER_INDEX)], int(7u));\n    SV_TARGET.x = _27.x;\n    SV_TARGET.y = _27.y;\n    SV_TARGET.z = _27.z;\n    SV_TARGET.w = _27.w;\n    SV_TARGET_1.x = _34.x;\n    SV_TARGET_1.y = _34.y;\n    SV_TARGET_1.z = _34.z;\n    SV_TARGET_1.w = _34.w;\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_query.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 22\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability ImageQuery\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageTexelBufferArrayDynamicIndexing\n               OpCapability StorageTexelBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_INDEX %SV_TARGET\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %SV_TARGET \"SV_TARGET\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %9 NonWritable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %SV_TARGET Location 0\n               OpDecorate %15 NonUniform\n               OpDecorate %18 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n%_ptr_Output_uint = OpTypePointer Output %uint\n  %SV_TARGET = OpVariable %_ptr_Output_uint Output\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %20\n\n         %20 = OpLabel\n         %15 =   OpLoad %uint %BUFFER_INDEX\n         %17 =   OpAccessChain %_ptr_UniformConstant_6 %9 %15\n         %18 =   OpLoad %6 %17\n         %19 =   OpImageQuerySize %uint %18\n                 OpStore %SV_TARGET %19\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_query.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform readonly writeonly imageBuffer _9[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) out uint SV_TARGET;\n\nvoid main()\n{\n    SV_TARGET = uint(imageSize(_9[nonuniformEXT(BUFFER_INDEX)]));\n}\n\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_store.asm",
    "content": "SPIR-V:\n; SPIR-V\n; Version: 1.6\n; Generator: Unknown(30017); 21022\n; Bound: 34\n; Schema: 0\n               OpCapability Shader\n               OpCapability ImageBuffer\n               OpCapability StorageImageWriteWithoutFormat\n               OpCapability SignedZeroInfNanPreserve\n               OpCapability RuntimeDescriptorArray\n               OpCapability StorageTexelBufferArrayDynamicIndexing\n               OpCapability StorageTexelBufferArrayNonUniformIndexing\n               OpCapability VulkanMemoryModel\n               OpExtension \"SPV_EXT_descriptor_indexing\"\n               OpExtension \"SPV_KHR_float_controls\"\n               OpMemoryModel Logical Vulkan\n               OpEntryPoint Fragment %main \"main\" %9 %BUFFER_INDEX %BUFFER_ADDRESS\n               OpExecutionMode %main OriginUpperLeft\n               OpExecutionMode %main SignedZeroInfNanPreserve 32\n               OpName %main \"main\"\n               OpName %BUFFER_INDEX \"BUFFER_INDEX\"\n               OpName %BUFFER_ADDRESS \"BUFFER_ADDRESS\"\n               OpDecorate %9 DescriptorSet 0\n               OpDecorate %9 Binding 0\n               OpDecorate %9 NonReadable\n               OpDecorate %BUFFER_INDEX Flat\n               OpDecorate %BUFFER_INDEX Location 0\n               OpDecorate %BUFFER_INDEX Component 2\n               OpDecorate %BUFFER_ADDRESS Flat\n               OpDecorate %BUFFER_ADDRESS Location 0\n               OpDecorate %16 NonUniform\n               OpDecorate %19 NonUniform\n       %void = OpTypeVoid\n          %2 = OpTypeFunction %void\n      %float = OpTypeFloat 32\n          %6 = OpTypeImage %float Buffer 0 0 0 2 Unknown\n%_runtimearr_6 = OpTypeRuntimeArray %6\n%_ptr_UniformConstant__runtimearr_6 = OpTypePointer UniformConstant %_runtimearr_6\n          %9 = OpVariable %_ptr_UniformConstant__runtimearr_6 UniformConstant\n       %uint = OpTypeInt 32 0\n%_ptr_Input_uint = OpTypePointer Input %uint\n%BUFFER_INDEX = OpVariable %_ptr_Input_uint Input\n     %v2uint = OpTypeVector %uint 2\n%_ptr_Input_v2uint = OpTypePointer Input %v2uint\n%BUFFER_ADDRESS = OpVariable %_ptr_Input_v2uint Input\n%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6\n     %uint_0 = OpConstant %uint 0\n    %v4float = OpTypeVector %float 4\n    %float_1 = OpConstant %float 1\n    %float_2 = OpConstant %float 2\n    %float_3 = OpConstant %float 3\n    %float_4 = OpConstant %float 4\n     %uint_7 = OpConstant %uint 7\n       %main = OpFunction %void None %2\n\n          %4 = OpLabel\n                 OpBranch %32\n\n         %32 = OpLabel\n         %16 =   OpLoad %uint %BUFFER_INDEX\n         %18 =   OpAccessChain %_ptr_UniformConstant_6 %9 %16\n         %19 =   OpLoad %6 %18\n         %20 =   OpAccessChain %_ptr_Input_uint %BUFFER_ADDRESS %uint_0\n         %22 =   OpLoad %uint %20\n         %29 =   OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4\n                 OpImageWrite %19 %22 %29 NonPrivateTexel\n         %31 =   OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4\n                 OpImageWrite %19 %uint_7 %31 NonPrivateTexel\n                 OpReturn\n               OpFunctionEnd\n\n"
  },
  {
    "path": "reference-dxbc/test_resources_uav_indexed_buffer_typed_store.glsl",
    "content": "GLSL:\n#version 460\n#extension GL_EXT_nonuniform_qualifier : require\n\nlayout(set = 0, binding = 0) uniform writeonly imageBuffer _9[];\n\nlayout(location = 0, component = 2) flat in uint BUFFER_INDEX;\nlayout(location = 0) flat in uvec2 BUFFER_ADDRESS;\n\nvoid main()\n{\n    imageStore(_9[nonuniformEXT(BUFFER_INDEX)], int(BUFFER_ADDRESS.x), vec4(1.0, 2.0, 3.0, 4.0));\n    imageStore(_9[nonuniformEXT(BUFFER_INDEX)], int(7u), vec4(1.0, 2.0, 3.0, 4.0));\n}\n\n\n"
  },
  {
    "path": "roundtrip_shaders.py",
    "content": "#!/usr/bin/env python3\n\n# Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n#\n# SPDX-License-Identifier: MIT\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n# \n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n# \n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n# Helper utility for vkd3d-proton where we roundtrip\n# VKD3D_SHADER_DUMP_PATH -> VKD3D_SHADER_OVERRIDE folders.\n\nimport sys\nimport os\nimport os.path\nimport subprocess\nimport multiprocessing\nimport argparse\n\ndef convert_spirv(in_path, out_path, args, stage):\n    out_file = out_path + '.' + stage\n    if args.preserve and os.path.exists(out_file):\n        return\n\n    spirv_cross_cmd = [args.spirv_cross, '--version', '460', '--vulkan-semantics', '--output', out_file, in_path, '--stage', stage, '--relax-nan-checks']\n    try:\n        subprocess.check_call(spirv_cross_cmd, stderr = subprocess.DEVNULL)\n    except subprocess.CalledProcessError as e:\n        if e.returncode > 0:\n            # Ignore this. We kinda expect it.\n            return\n        raise\n\ndef convert_shaders(args):\n    files = os.listdir(args.input)\n    files = [ f for f in files if os.path.splitext(f)[1] == '.spv' ]\n\n    pool = multiprocessing.Pool(multiprocessing.cpu_count())\n    results = []\n\n    for f in files:\n        in_path = os.path.join(args.input, f)\n        out_path = os.path.join(args.output, os.path.splitext(f)[0])\n        # Try to emit all stages. Kinda hacky.\n        # Should maybe add --deduce-extension or something to SPIRV-Cross CLI, but w/e.\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'vert')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'frag')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'tesc')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'tese')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'geom')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'comp')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'rgen')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'rint')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'rahit')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'rchit')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'rmiss')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'rcall')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'mesh')))\n        results.append(pool.apply_async(convert_spirv, args = (in_path, out_path, args, 'task')))\n\n    for res in results:\n        res.get()\n    pool.close()\n    pool.join()\n\ndef main():\n    parser = argparse.ArgumentParser(description = 'Script for roundtripping shaders through SPIRV-Cross.')\n    parser.add_argument('--input',\n            help = 'Folder containing shader files to convert.')\n    parser.add_argument('--spirv-cross',\n            default = 'spirv-cross',\n            help = 'Explicit path to SPIRV-Cross')\n    parser.add_argument('--preserve',\n            action = 'store_true',\n            help = 'Do not overwrite files which already exist')\n    parser.add_argument('--output',\n            help = 'Path where shaders are output')\n\n    args = parser.parse_args()\n    if not args.input:\n        sys.stderr.write('Need input shader folder.\\n')\n        sys.exit(1)\n    if not args.output:\n        sys.stderr.write('Need output shader folder.\\n')\n        sys.exit(1)\n\n    convert_shaders(args)\n    print('Complete!')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "scratch_pool.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef DXIL_SPV_SCRATCH_POOL_H_\n#define DXIL_SPV_SCRATCH_POOL_H_\n\n#include \"thread_local_allocator.hpp\"\n\nnamespace dxil_spv\n{\ntemplate <typename T>\nclass ScratchPool\n{\npublic:\n\tScratchPool()\n\t{\n\t\tstatic_assert(std::is_trivially_destructible<T>::value, \"T must be trivially destructible.\");\n\t}\n\n\ttemplate <typename... P>\n\tT *allocate(P &&... p)\n\t{\n\t\tT *t = allocate_raw();\n\t\treturn new (t) T(std::forward<P>(p)...);\n\t}\n\n\tT *allocate_raw()\n\t{\n\t\tif (current.offset < current.size)\n\t\t\treturn &current.base[current.offset++];\n\n\t\tBlock new_block = {};\n\t\tnew_block.size = next_allocate_size;\n\t\tnew_block.base = static_cast<T *>(allocate_in_thread(sizeof(T) * next_allocate_size));\n\t\tif (!new_block.base)\n\t\t{\n\t\t\t// If we fail to allocate this little memory, we are hosed anyways.\n\t\t\tstd::terminate();\n\t\t}\n\n\t\tblocks.emplace_back(new_block.base);\n\t\tnext_allocate_size *= 2;\n\n\t\tcurrent = new_block;\n\t\tcurrent.offset = 1;\n\t\treturn current.base;\n\t}\n\nprivate:\n\tstruct MallocDeleter\n\t{\n\t\tvoid operator()(void *ptr) noexcept\n\t\t{\n\t\t\tfree_in_thread(ptr);\n\t\t}\n\t};\n\n\tstruct Block\n\t{\n\t\tT *base;\n\t\tsize_t offset;\n\t\tsize_t size;\n\t};\n\tBlock current = {};\n\tsize_t next_allocate_size = 64;\n\tVector<std::unique_ptr<T, MallocDeleter>> blocks;\n};\n} // namespace dxil_spv\n\n#endif\n"
  },
  {
    "path": "shaders/ags/ags.ssbo.comp",
    "content": "RWByteAddressBuffer Buf;\nRWTexture1D<uint2> Img1D;\nRWTexture2D<uint2> Img2D;\nRWTexture3D<uint2> Img3D;\nRWStructuredBuffer<uint2> Out;\n\n#include \"ags_shader_intrinsics_dx12.inc\"\n\n[numthreads(8, 8, 1)]\nvoid main(uint3 thr : SV_DispatchThreadID)\n{\n\tOut[thr.x] = AmdExtD3DShaderIntrinsics_AtomicMaxU64(Buf, 8 * thr.x, uint2(40, 50));\n\tOut[thr.x] += AmdExtD3DShaderIntrinsics_AtomicMinU64(Img1D, thr.x, uint2(60, 70));\n\tOut[thr.x] += AmdExtD3DShaderIntrinsics_AtomicXorU64(Img2D, thr.xy, uint2(80, 90));\n\tOut[thr.x] += AmdExtD3DShaderIntrinsics_AtomicAddU64(Img3D, thr, uint2(100, 110));\n\tOut[thr.x].x += AmdExtD3DShaderIntrinsics_ReadfirstlaneU(thr.x * 16);\n\tOut[thr.x].x += AmdExtD3DShaderIntrinsics_ReadfirstlaneF(thr.y * 16);\n\tOut[thr.x].y += AmdExtD3DShaderIntrinsics_ReadlaneU(thr.z * 16, 7);\n\tOut[thr.x].y += AmdExtD3DShaderIntrinsics_ReadlaneF(thr.x * 16, 9);\n\tOut[thr.x] += AmdExtD3DShaderIntrinsics_LaneId();\n}\n"
  },
  {
    "path": "shaders/ags/ags_shader_intrinsics_dx12.inc",
    "content": "//\n// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n\n/**\n***********************************************************************************************************************\n* @file  ags_shader_intrinsics_dx12.hlsl\n* @brief\n*    AMD D3D Shader Intrinsics HLSL include file.\n*    This include file contains the Shader Intrinsics definitions used in shader code by the application.\n* @note\n*    This does not work with immediate values or values that the compiler determines can produces denorms\n*\n***********************************************************************************************************************\n*/\n\n#ifndef _AMDEXTD3DSHADERINTRINICS_HLSL\n#define _AMDEXTD3DSHADERINTRINICS_HLSL\n\n// Default AMD shader intrinsics designated SpaceId.\n#define AmdExtD3DShaderIntrinsicsSpaceId space2147420894\n\n// Dummy UAV used to access shader intrinsics. Applications need to add a root signature entry for this resource in\n// order to use shader extensions. Applications may specify an alternate UAV binding by defining AMD_EXT_SHADER_INTRINSIC_UAV_OVERRIDE.\n#ifdef AMD_EXT_SHADER_INTRINSIC_UAV_OVERRIDE\nRWByteAddressBuffer AmdExtD3DShaderIntrinsicsUAV : register(AMD_EXT_SHADER_INTRINSIC_UAV_OVERRIDE);\n#else\nRWByteAddressBuffer AmdExtD3DShaderIntrinsicsUAV : register(u0, AmdExtD3DShaderIntrinsicsSpaceId);\n#endif\n\n/**\n***********************************************************************************************************************\n*   Definitions to construct the intrinsic instruction composed of an opcode and optional immediate data.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsics_MagicCodeShift   28\n#define AmdExtD3DShaderIntrinsics_MagicCodeMask    0xf\n#define AmdExtD3DShaderIntrinsics_OpcodePhaseShift 24\n#define AmdExtD3DShaderIntrinsics_OpcodePhaseMask  0x3\n#define AmdExtD3DShaderIntrinsics_DataShift        8\n#define AmdExtD3DShaderIntrinsics_DataMask         0xffff\n#define AmdExtD3DShaderIntrinsics_OpcodeShift      0\n#define AmdExtD3DShaderIntrinsics_OpcodeMask       0xff\n\n#define AmdExtD3DShaderIntrinsics_MagicCode        0x5\n\n\n/**\n***********************************************************************************************************************\n*   Intrinsic opcodes.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsOpcode_Readfirstlane           0x01\n#define AmdExtD3DShaderIntrinsicsOpcode_Readlane                0x02\n#define AmdExtD3DShaderIntrinsicsOpcode_LaneId                  0x03\n#define AmdExtD3DShaderIntrinsicsOpcode_Swizzle                 0x04\n#define AmdExtD3DShaderIntrinsicsOpcode_Ballot                  0x05\n#define AmdExtD3DShaderIntrinsicsOpcode_MBCnt                   0x06\n#define AmdExtD3DShaderIntrinsicsOpcode_Min3U                   0x07\n#define AmdExtD3DShaderIntrinsicsOpcode_Min3F                   0x08\n#define AmdExtD3DShaderIntrinsicsOpcode_Med3U                   0x09\n#define AmdExtD3DShaderIntrinsicsOpcode_Med3F                   0x0a\n#define AmdExtD3DShaderIntrinsicsOpcode_Max3U                   0x0b\n#define AmdExtD3DShaderIntrinsicsOpcode_Max3F                   0x0c\n#define AmdExtD3DShaderIntrinsicsOpcode_BaryCoord               0x0d\n#define AmdExtD3DShaderIntrinsicsOpcode_VtxParam                0x0e\n#define AmdExtD3DShaderIntrinsicsOpcode_Reserved1               0x0f\n#define AmdExtD3DShaderIntrinsicsOpcode_Reserved2               0x10\n#define AmdExtD3DShaderIntrinsicsOpcode_Reserved3               0x11\n#define AmdExtD3DShaderIntrinsicsOpcode_WaveReduce              0x12\n#define AmdExtD3DShaderIntrinsicsOpcode_WaveScan                0x13\n#define AmdExtD3DShaderIntrinsicsOpcode_LoadDwAtAddr            0x14\n#define AmdExtD3DShaderIntrinsicsOpcode_DrawIndex               0x17\n#define AmdExtD3DShaderIntrinsicsOpcode_AtomicU64               0x18\n#define AmdExtD3DShaderIntrinsicsOpcode_GetWaveSize             0x19\n#define AmdExtD3DShaderIntrinsicsOpcode_BaseInstance            0x1a\n#define AmdExtD3DShaderIntrinsicsOpcode_BaseVertex              0x1b\n#define AmdExtD3DShaderIntrinsicsOpcode_FloatConversion         0x1c\n#define AmdExtD3DShaderIntrinsicsOpcode_ReadlaneAt              0x1d\n#define AmdExtD3DShaderIntrinsicsOpcode_ShaderClock             0x1f\n#define AmdExtD3DShaderIntrinsicsOpcode_ShaderRealtimeClock     0x20\n\n\n/**\n***********************************************************************************************************************\n*   Intrinsic opcode phases.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsOpcodePhase_0    0x0\n#define AmdExtD3DShaderIntrinsicsOpcodePhase_1    0x1\n#define AmdExtD3DShaderIntrinsicsOpcodePhase_2    0x2\n#define AmdExtD3DShaderIntrinsicsOpcodePhase_3    0x3\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsWaveOp defines for supported operations. Can be used as the parameter for the\n*   AmdExtD3DShaderIntrinsicsOpcode_WaveOp intrinsic.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsWaveOp_AddF 0x01\n#define AmdExtD3DShaderIntrinsicsWaveOp_AddI 0x02\n#define AmdExtD3DShaderIntrinsicsWaveOp_AddU 0x03\n#define AmdExtD3DShaderIntrinsicsWaveOp_MulF 0x04\n#define AmdExtD3DShaderIntrinsicsWaveOp_MulI 0x05\n#define AmdExtD3DShaderIntrinsicsWaveOp_MulU 0x06\n#define AmdExtD3DShaderIntrinsicsWaveOp_MinF 0x07\n#define AmdExtD3DShaderIntrinsicsWaveOp_MinI 0x08\n#define AmdExtD3DShaderIntrinsicsWaveOp_MinU 0x09\n#define AmdExtD3DShaderIntrinsicsWaveOp_MaxF 0x0a\n#define AmdExtD3DShaderIntrinsicsWaveOp_MaxI 0x0b\n#define AmdExtD3DShaderIntrinsicsWaveOp_MaxU 0x0c\n#define AmdExtD3DShaderIntrinsicsWaveOp_And  0x0d    // Reduction only\n#define AmdExtD3DShaderIntrinsicsWaveOp_Or   0x0e    // Reduction only\n#define AmdExtD3DShaderIntrinsicsWaveOp_Xor  0x0f    // Reduction only\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsWaveOp masks and shifts for opcode and flags\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift 0\n#define AmdExtD3DShaderIntrinsicsWaveOp_OpcodeMask  0xff\n#define AmdExtD3DShaderIntrinsicsWaveOp_FlagShift   8\n#define AmdExtD3DShaderIntrinsicsWaveOp_FlagMask    0xff\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsWaveOp flags for use with AmdExtD3DShaderIntrinsicsOpcode_WaveScan.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsWaveOp_Inclusive   0x01\n#define AmdExtD3DShaderIntrinsicsWaveOp_Exclusive   0x02\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsSwizzle defines for common swizzles.  Can be used as the operation parameter for the\n*   AmdExtD3DShaderIntrinsics_Swizzle intrinsic.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsSwizzle_SwapX1      0x041f\n#define AmdExtD3DShaderIntrinsicsSwizzle_SwapX2      0x081f\n#define AmdExtD3DShaderIntrinsicsSwizzle_SwapX4      0x101f\n#define AmdExtD3DShaderIntrinsicsSwizzle_SwapX8      0x201f\n#define AmdExtD3DShaderIntrinsicsSwizzle_SwapX16     0x401f\n#define AmdExtD3DShaderIntrinsicsSwizzle_ReverseX2   0x041f\n#define AmdExtD3DShaderIntrinsicsSwizzle_ReverseX4   0x0c1f\n#define AmdExtD3DShaderIntrinsicsSwizzle_ReverseX8   0x1c1f\n#define AmdExtD3DShaderIntrinsicsSwizzle_ReverseX16  0x3c1f\n#define AmdExtD3DShaderIntrinsicsSwizzle_ReverseX32  0x7c1f\n#define AmdExtD3DShaderIntrinsicsSwizzle_BCastX2     0x003e\n#define AmdExtD3DShaderIntrinsicsSwizzle_BCastX4     0x003c\n#define AmdExtD3DShaderIntrinsicsSwizzle_BCastX8     0x0038\n#define AmdExtD3DShaderIntrinsicsSwizzle_BCastX16    0x0030\n#define AmdExtD3DShaderIntrinsicsSwizzle_BCastX32    0x0020\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsBarycentric defines for barycentric interpolation mode.  To be used with\n*   AmdExtD3DShaderIntrinsicsOpcode_IjBarycentricCoords to specify the interpolation mode.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsBarycentric_LinearCenter    0x1\n#define AmdExtD3DShaderIntrinsicsBarycentric_LinearCentroid  0x2\n#define AmdExtD3DShaderIntrinsicsBarycentric_LinearSample    0x3\n#define AmdExtD3DShaderIntrinsicsBarycentric_PerspCenter     0x4\n#define AmdExtD3DShaderIntrinsicsBarycentric_PerspCentroid   0x5\n#define AmdExtD3DShaderIntrinsicsBarycentric_PerspSample     0x6\n#define AmdExtD3DShaderIntrinsicsBarycentric_PerspPullModel  0x7\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsBarycentric defines for specifying vertex and parameter indices.  To be used as inputs to\n*   the AmdExtD3DShaderIntrinsicsOpcode_VertexParameter function\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsBarycentric_Vertex0        0x0\n#define AmdExtD3DShaderIntrinsicsBarycentric_Vertex1        0x1\n#define AmdExtD3DShaderIntrinsicsBarycentric_Vertex2        0x2\n\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param0         0x00\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param1         0x01\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param2         0x02\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param3         0x03\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param4         0x04\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param5         0x05\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param6         0x06\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param7         0x07\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param8         0x08\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param9         0x09\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param10        0x0a\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param11        0x0b\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param12        0x0c\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param13        0x0d\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param14        0x0e\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param15        0x0f\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param16        0x10\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param17        0x11\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param18        0x12\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param19        0x13\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param20        0x14\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param21        0x15\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param22        0x16\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param23        0x17\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param24        0x18\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param25        0x19\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param26        0x1a\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param27        0x1b\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param28        0x1c\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param29        0x1d\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param30        0x1e\n#define AmdExtD3DShaderIntrinsicsBarycentric_Param31        0x1f\n\n#define AmdExtD3DShaderIntrinsicsBarycentric_ComponentX     0x0\n#define AmdExtD3DShaderIntrinsicsBarycentric_ComponentY     0x1\n#define AmdExtD3DShaderIntrinsicsBarycentric_ComponentZ     0x2\n#define AmdExtD3DShaderIntrinsicsBarycentric_ComponentW     0x3\n\n#define AmdExtD3DShaderIntrinsicsBarycentric_ParamShift     0\n#define AmdExtD3DShaderIntrinsicsBarycentric_ParamMask      0x1f\n#define AmdExtD3DShaderIntrinsicsBarycentric_VtxShift       0x5\n#define AmdExtD3DShaderIntrinsicsBarycentric_VtxMask        0x3\n#define AmdExtD3DShaderIntrinsicsBarycentric_ComponentShift 0x7\n#define AmdExtD3DShaderIntrinsicsBarycentric_ComponentMask  0x3\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsAtomic defines for supported operations. Can be used as the parameter for the\n*   AmdExtD3DShaderIntrinsicsOpcode_AtomicU64 intrinsic.\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsAtomicOp_MinU64     0x01\n#define AmdExtD3DShaderIntrinsicsAtomicOp_MaxU64     0x02\n#define AmdExtD3DShaderIntrinsicsAtomicOp_AndU64     0x03\n#define AmdExtD3DShaderIntrinsicsAtomicOp_OrU64      0x04\n#define AmdExtD3DShaderIntrinsicsAtomicOp_XorU64     0x05\n#define AmdExtD3DShaderIntrinsicsAtomicOp_AddU64     0x06\n#define AmdExtD3DShaderIntrinsicsAtomicOp_XchgU64    0x07\n#define AmdExtD3DShaderIntrinsicsAtomicOp_CmpXchgU64 0x08\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsicsFloatConversion defines for supported rounding modes from float to float16 conversions.\n*   To be used as an input AmdExtD3DShaderIntrinsicsOpcode_FloatConversion instruction\n***********************************************************************************************************************\n*/\n#define AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16Near    0x01\n#define AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16NegInf  0x02\n#define AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16PlusInf 0x03\n\n\n/**\n***********************************************************************************************************************\n*   MakeAmdShaderIntrinsicsInstruction\n*\n*   Creates instruction from supplied opcode and immediate data.\n*   NOTE: This is an internal function and should not be called by the source HLSL shader directly.\n*\n***********************************************************************************************************************\n*/\nuint MakeAmdShaderIntrinsicsInstruction(uint opcode, uint opcodePhase, uint immediateData)\n{\n    return ((AmdExtD3DShaderIntrinsics_MagicCode << AmdExtD3DShaderIntrinsics_MagicCodeShift) |\n            (immediateData << AmdExtD3DShaderIntrinsics_DataShift) |\n            (opcodePhase << AmdExtD3DShaderIntrinsics_OpcodePhaseShift) |\n            (opcode << AmdExtD3DShaderIntrinsics_OpcodeShift));\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ReadfirstlaneF\n*\n*   Returns the value of float src for the first active lane of the wavefront.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_ReadfirstlaneF(float src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Readfirstlane, 0, 0);\n\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src), 0, retVal);\n    return asfloat(retVal);\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ReadfirstlaneU\n*\n*   Returns the value of unsigned integer src for the first active lane of the wavefront.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_ReadfirstlaneU(uint src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Readfirstlane, 0, 0);\n\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src, 0, retVal);\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Readlane\n*\n*   Returns the value of float src for the lane within the wavefront specified by laneId.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_ReadlaneF(float src, uint laneId)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Readlane, 0, laneId);\n\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src), 0, retVal);\n    return asfloat(retVal);\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ReadlaneU\n*\n*   Returns the value of unsigned integer src for the lane within the wavefront specified by laneId.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_ReadlaneU(uint src, uint laneId)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Readlane, 0, laneId);\n\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src, 0, retVal);\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_LaneId\n*\n*   Returns the current lane id for the thread within the wavefront.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_LaneId()\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_LaneId, 0, 0);\n\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal);\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_GetWaveSize\n*\n*   Returns the wave size for the current shader, including active, inactive and helper lanes.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_GetWaveSize()\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_GetWaveSize, 0, 0);\n\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal);\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Swizzle\n*\n*   Generic instruction to shuffle the float src value among different lanes as specified by the operation.\n*   Note that the operation parameter must be an immediately specified value not a value from a variable.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_SwizzleF(float src, uint operation)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Swizzle, 0, operation);\n\n    uint retVal;\n    //InterlockedCompareExchange(AmdExtD3DShaderIntrinsicsUAV[instruction], asuint(src), 0, retVal);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src), 0, retVal);\n    return asfloat(retVal);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_SwizzleU\n*\n*   Generic instruction to shuffle the unsigned integer src value among different lanes as specified by the operation.\n*   Note that the operation parameter must be an immediately specified value not a value from a variable.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_SwizzleU(uint src, uint operation)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Swizzle, 0, operation);\n\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src, 0, retVal);\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Ballot\n*\n*   Given an input predicate returns a bit mask indicating for which lanes the predicate is true.\n*   Inactive or non-existent lanes will always return 0.  The number of existent lanes is the wavefront size.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_Ballot(bool predicate)\n{\n    uint instruction;\n\n    uint retVal1;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Ballot,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0, 0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, predicate, 0, retVal1);\n\n    uint retVal2;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Ballot,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_1, 0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, predicate, 0, retVal2);\n\n    return uint2(retVal1, retVal2);\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_BallotAny\n*\n*   Convenience routine that uses Ballot and returns true if for any of the active lanes the predicate is true.\n*\n***********************************************************************************************************************\n*/\nbool AmdExtD3DShaderIntrinsics_BallotAny(bool predicate)\n{\n    uint2 retVal = AmdExtD3DShaderIntrinsics_Ballot(predicate);\n\n    return ((retVal.x | retVal.y) != 0 ? true : false);\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_BallotAll\n*\n*   Convenience routine that uses Ballot and returns true if for all of the active lanes the predicate is true.\n*\n***********************************************************************************************************************\n*/\nbool AmdExtD3DShaderIntrinsics_BallotAll(bool predicate)\n{\n    uint2 ballot = AmdExtD3DShaderIntrinsics_Ballot(predicate);\n\n    uint2 execMask = AmdExtD3DShaderIntrinsics_Ballot(true);\n\n    return ((ballot.x == execMask.x) && (ballot.y == execMask.y));\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_MBCnt\n*\n*   Returns the masked bit count of the source register for this thread within all the active threads within a\n*   wavefront.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_MBCnt(uint2 src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_MBCnt, 0, 0);\n\n    uint retVal;\n\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.x, src.y, retVal);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Min3F\n*\n*   Returns the minimum value of the three floating point source arguments.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_Min3F(float src0, float src1, float src2)\n{\n    uint minimum;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Min3F,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, asuint(src0), asuint(src1), minimum);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Min3F,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, asuint(src2), minimum, minimum);\n\n    return asfloat(minimum);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Min3U\n*\n*   Returns the minimum value of the three unsigned integer source arguments.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_Min3U(uint src0, uint src1, uint src2)\n{\n    uint minimum;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Min3U,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, src0, src1, minimum);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Min3U,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, src2, minimum, minimum);\n\n    return minimum;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Med3F\n*\n*   Returns the median value of the three floating point source arguments.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_Med3F(float src0, float src1, float src2)\n{\n    uint median;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Med3F,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, asuint(src0), asuint(src1), median);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Med3F,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, asuint(src2), median, median);\n\n    return asfloat(median);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Med3U\n*\n*   Returns the median value of the three unsigned integer source arguments.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_Med3U(uint src0, uint src1, uint src2)\n{\n    uint median;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Med3U,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, src0, src1, median);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Med3U,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, src2, median, median);\n\n    return median;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Max3F\n*\n*   Returns the maximum value of the three floating point source arguments.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_Max3F(float src0, float src1, float src2)\n{\n    uint maximum;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Max3F,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, asuint(src0), asuint(src1), maximum);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Max3F,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, asuint(src2), maximum, maximum);\n\n    return asfloat(maximum);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_Max3U\n*\n*   Returns the maximum value of the three unsigned integer source arguments.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_Max3U(uint src0, uint src1, uint src2)\n{\n    uint maximum;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Max3U,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, src0, src1, maximum);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_Max3U,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, src2, maximum, maximum);\n\n    return maximum;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_IjBarycentricCoords\n*\n*   Returns the (i, j) barycentric coordinate pair for this shader invocation with the specified interpolation mode at\n*   the specified pixel location.  Should not be used for \"pull-model\" interpolation, PullModelBarycentricCoords should\n*   be used instead\n*\n*   Can only be used in pixel shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_IjBarycentricCoords(uint interpMode)\n{\n    uint2 retVal;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_BaryCoord,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           interpMode);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, 0, 0, retVal.x);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_BaryCoord,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           interpMode);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, retVal.x, 0, retVal.y);\n\n    return float2(asfloat(retVal.x), asfloat(retVal.y));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_PullModelBarycentricCoords\n*\n*   Returns the (1/W,1/I,1/J) coordinates at the pixel center which can be used for custom interpolation at any\n*   location in the pixel.\n*\n*   Can only be used in pixel shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_PullModelBarycentricCoords()\n{\n    uint3 retVal;\n\n    uint instruction1 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_BaryCoord,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                           AmdExtD3DShaderIntrinsicsBarycentric_PerspPullModel);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction1, 0, 0, retVal.x);\n\n    uint instruction2 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_BaryCoord,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                           AmdExtD3DShaderIntrinsicsBarycentric_PerspPullModel);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction2, retVal.x, 0, retVal.y);\n\n    uint instruction3 = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_BaryCoord,\n                                                           AmdExtD3DShaderIntrinsicsOpcodePhase_2,\n                                                           AmdExtD3DShaderIntrinsicsBarycentric_PerspPullModel);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction3, retVal.y, 0, retVal.z);\n\n    return float3(asfloat(retVal.x), asfloat(retVal.y), asfloat(retVal.z));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_VertexParameter\n*\n*   Returns the triangle's parameter information at the specified triangle vertex.\n*   The vertex and parameter indices must specified as immediate values.\n*\n*   Only available in pixel shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_VertexParameter(uint vertexIdx, uint parameterIdx)\n{\n    uint4 retVal;\n    uint4 instruction;\n\n    instruction.x = MakeAmdShaderIntrinsicsInstruction(\n             AmdExtD3DShaderIntrinsicsOpcode_VtxParam,\n             AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n           ((vertexIdx << AmdExtD3DShaderIntrinsicsBarycentric_VtxShift) |\n            (parameterIdx << AmdExtD3DShaderIntrinsicsBarycentric_ParamShift) |\n            (AmdExtD3DShaderIntrinsicsBarycentric_ComponentX << AmdExtD3DShaderIntrinsicsBarycentric_ComponentShift)));\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction.x, 0, 0, retVal.x);\n\n    instruction.y = MakeAmdShaderIntrinsicsInstruction(\n             AmdExtD3DShaderIntrinsicsOpcode_VtxParam,\n             AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n           ((vertexIdx << AmdExtD3DShaderIntrinsicsBarycentric_VtxShift) |\n            (parameterIdx << AmdExtD3DShaderIntrinsicsBarycentric_ParamShift) |\n            (AmdExtD3DShaderIntrinsicsBarycentric_ComponentY << AmdExtD3DShaderIntrinsicsBarycentric_ComponentShift)));\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction.y, 0, 0, retVal.y);\n\n    instruction.z = MakeAmdShaderIntrinsicsInstruction(\n             AmdExtD3DShaderIntrinsicsOpcode_VtxParam,\n             AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n           ((vertexIdx << AmdExtD3DShaderIntrinsicsBarycentric_VtxShift) |\n            (parameterIdx << AmdExtD3DShaderIntrinsicsBarycentric_ParamShift) |\n            (AmdExtD3DShaderIntrinsicsBarycentric_ComponentZ << AmdExtD3DShaderIntrinsicsBarycentric_ComponentShift)));\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction.z, 0, 0, retVal.z);\n\n    instruction.w = MakeAmdShaderIntrinsicsInstruction(\n             AmdExtD3DShaderIntrinsicsOpcode_VtxParam,\n             AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n           ((vertexIdx << AmdExtD3DShaderIntrinsicsBarycentric_VtxShift) |\n            (parameterIdx << AmdExtD3DShaderIntrinsicsBarycentric_ParamShift) |\n            (AmdExtD3DShaderIntrinsicsBarycentric_ComponentW << AmdExtD3DShaderIntrinsicsBarycentric_ComponentShift)));\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction.w, 0, 0, retVal.w);\n\n    return float4(asfloat(retVal.x), asfloat(retVal.y), asfloat(retVal.z), asfloat(retVal.w));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_VertexParameterComponent\n*\n*   Returns the triangle's parameter information at the specified triangle vertex and component.\n*   The vertex, parameter and component indices must be specified as immediate values.\n*\n*   Only available in pixel shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_VertexParameterComponent(uint vertexIdx, uint parameterIdx, uint componentIdx)\n{\n    uint retVal;\n    uint instruction =\n        MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_VtxParam,\n                                           AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                          ((vertexIdx << AmdExtD3DShaderIntrinsicsBarycentric_VtxShift) |\n                                           (parameterIdx << AmdExtD3DShaderIntrinsicsBarycentric_ParamShift) |\n                                           (componentIdx << AmdExtD3DShaderIntrinsicsBarycentric_ComponentShift)));\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal);\n\n    return asfloat(retVal);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce\n*\n*   Performs reduction operation on wavefront (thread group) data.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : float\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, float src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src), 0, retVal);\n\n    return asfloat(retVal);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : float2\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, float2 src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n\n    uint2 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.x), 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.y), 0, retVal.y);\n\n    return float2(asfloat(retVal.x), asfloat(retVal.y));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : float3\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, float3 src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n\n    uint3 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.x), 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.y), 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.z), 0, retVal.z);\n\n    return float3(asfloat(retVal.x), asfloat(retVal.y), asfloat(retVal.z));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : float4\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, float4 src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n\n    uint4 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.x), 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.y), 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.z), 0, retVal.z);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.w), 0, retVal.w);\n\n    return float4(asfloat(retVal.x), asfloat(retVal.y), asfloat(retVal.z), asfloat(retVal.w));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : int\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, int src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n\n    int retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src, 0, retVal);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : int2\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, int2 src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n\n    int2 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.x, 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.y, 0, retVal.y);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : int3\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, int3 src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n\n    int3 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.x, 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.y, 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.z, 0, retVal.z);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveReduce : int4\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveReduce(uint waveOp, int4 src)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveReduce,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift));\n\n    int4 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.x, 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.y, 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.z, 0, retVal.z);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.w, 0, retVal.w);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan\n*\n*   Performs scan operation on wavefront (thread group) data.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : float\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, float src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags  << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n    uint retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src), 0, retVal);\n\n    return asfloat(retVal);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : float2\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, float2 src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n\n    uint2 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.x), 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.y), 0, retVal.y);\n\n    return float2(asfloat(retVal.x), asfloat(retVal.y));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : float3\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, float3 src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n\n    uint3 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.x), 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.y), 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.z), 0, retVal.z);\n\n    return float3(asfloat(retVal.x), asfloat(retVal.y), asfloat(retVal.z));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : float4\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, float4 src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n\n    uint4 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.x), 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.y), 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.z), 0, retVal.z);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src.w), 0, retVal.w);\n\n    return float4(asfloat(retVal.x), asfloat(retVal.y), asfloat(retVal.z), asfloat(retVal.w));\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : int\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, int src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n\n    int retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src, 0, retVal);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : int2\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, int2 src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n\n    int2 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.x, 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.y, 0, retVal.y);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : int3\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, int3 src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n\n    int3 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.x, 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.y, 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.z, 0, retVal.z);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveScan : int4\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveScan(uint waveOp, uint flags, int4 src)\n{\n    const uint waveScanOp = (waveOp << AmdExtD3DShaderIntrinsicsWaveOp_OpcodeShift) |\n                            (flags << AmdExtD3DShaderIntrinsicsWaveOp_FlagShift);\n\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_WaveScan,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          waveScanOp);\n\n    int4 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.x, 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.y, 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.z, 0, retVal.z);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src.w, 0, retVal.w);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_LoadDwordAtAddr\n*\n*   Loads a DWORD from GPU memory from a given 64-bit GPU VA and 32-bit offset.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_LoadDwordAtAddr\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_LoadDwordAtAddr(uint gpuVaLoBits, uint gpuVaHiBits, uint offset)\n{\n    uint retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_LoadDwAtAddr,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, gpuVaLoBits, gpuVaHiBits, retVal);\n\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_LoadDwAtAddr,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                     0);\n\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, offset, 0, retVal);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_LoadDwordAtAddrx2\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_LoadDwordAtAddrx2(uint gpuVaLoBits, uint gpuVaHiBits, uint offset)\n{\n    uint2 retVal;\n\n    retVal.x = AmdExtD3DShaderIntrinsics_LoadDwordAtAddr(gpuVaLoBits, gpuVaHiBits, offset);\n    retVal.y = AmdExtD3DShaderIntrinsics_LoadDwordAtAddr(gpuVaLoBits, gpuVaHiBits, offset + 0x4);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_LoadDwordAtAddrx4\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_LoadDwordAtAddrx4(uint gpuVaLoBits, uint gpuVaHiBits, uint offset)\n{\n    uint4 retVal;\n\n    retVal.x = AmdExtD3DShaderIntrinsics_LoadDwordAtAddr(gpuVaLoBits, gpuVaHiBits, offset);\n    retVal.y = AmdExtD3DShaderIntrinsics_LoadDwordAtAddr(gpuVaLoBits, gpuVaHiBits, offset + 0x4);\n    retVal.z = AmdExtD3DShaderIntrinsics_LoadDwordAtAddr(gpuVaLoBits, gpuVaHiBits, offset + 0x8);\n    retVal.w = AmdExtD3DShaderIntrinsics_LoadDwordAtAddr(gpuVaLoBits, gpuVaHiBits, offset + 0xC);\n\n    return retVal;\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_GetDrawIndex\n*\n*   Returns the 0-based draw index in an indirect draw. Always returns 0 for direct draws.\n*\n*   Available in vertex shader stage only.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_GetDrawIndex()\n{\n    uint retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_DrawIndex,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_GetBaseInstance\n*\n*   Returns the StartInstanceLocation parameter passed to direct or indirect drawing commands.\n*\n*   Available in vertex shader stage only.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_GetBaseInstance()\n{\n    uint retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_BaseInstance,\n        AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n        0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_GetBaseVertex\n*\n*   For non-indexed draw commands, returns the StartVertexLocation parameter. For indexed draw commands, returns the\n*   BaseVertexLocation parameter.\n*\n*   Available in vertex shader stage only.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_GetBaseVertex()\n{\n    uint retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_BaseVertex,\n        AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n        0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal);\n\n    return retVal;\n}\n\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ReadlaneAt : uint\n*\n*   Returns the value of the source for the given lane index within the specified wave.  The lane index\n*   can be non-uniform across the wave.\n*\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_ReadlaneAt(uint src, uint laneId)\n{\n    uint retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_ReadlaneAt,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, src, laneId, retVal);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ReadlaneAt : int\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_ReadlaneAt(int src, uint laneId)\n{\n    uint retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_ReadlaneAt,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src), laneId, retVal);\n\n    return asint(retVal);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ReadlaneAt : float\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_ReadlaneAt(float src, uint laneId)\n{\n    uint retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_ReadlaneAt,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(src), laneId, retVal);\n\n    return asfloat(retVal);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ConvertF32toF16\n*\n*   Converts 32bit floating point numbers into 16bit floating point number using a specified rounding mode\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ConvertF32toF16 - helper to convert f32 to f16 number\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_ConvertF32toF16(in uint convOp, in float3 val)\n{\n    uint instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_FloatConversion,\n                                                          AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                          convOp);\n\n    uint3 retVal;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(val.x), 0, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(val.y), 0, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, asuint(val.z), 0, retVal.z);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ConvertF32toF16Near - convert f32 to f16 number using nearest rounding mode\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_ConvertF32toF16Near(in float3 inVec)\n{\n    return AmdExtD3DShaderIntrinsics_ConvertF32toF16(AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16Near, inVec);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ConvertF32toF16Near - convert f32 to f16 number using -inf rounding mode\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_ConvertF32toF16NegInf(in float3 inVec)\n{\n    return AmdExtD3DShaderIntrinsics_ConvertF32toF16(AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16NegInf, inVec);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ConvertF32toF16Near - convert f32 to f16 number using +inf rounding mode\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_ConvertF32toF16PosInf(in float3 inVec)\n{\n    return AmdExtD3DShaderIntrinsics_ConvertF32toF16(AmdExtD3DShaderIntrinsicsFloatConversionOp_FToF16PlusInf, inVec);\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ShaderClock\n*\n*   Returns the current value of the timestamp clock. The value monotonically increments and will wrap after it\n*   exceeds the maximum representable value. The units are not defined and need not be constant, and the value\n*   is not guaranteed to be dynamically uniform across a single draw or dispatch.\n*\n*   The function serves as a code motion barrier. Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ShaderClock\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_ShaderClock()\n{\n    uint2 retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_ShaderClock,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal.x);\n\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_ShaderClock,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal.y);\n\n    return retVal;\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ShaderRealtimeClock\n*\n*   Returns a value representing the real-time clock that is globally coherent by all invocations on the GPU.\n*   The units are not defined and the value will wrap after exceeding the maximum representable value.\n*\n*   The function serves as a code motion barrier. Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_ShaderRealtimeClock\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_ShaderRealtimeClock()\n{\n    uint2 retVal;\n\n    uint instruction;\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_ShaderRealtimeClock,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_0,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal.x);\n\n    instruction = MakeAmdShaderIntrinsicsInstruction(AmdExtD3DShaderIntrinsicsOpcode_ShaderRealtimeClock,\n                                                     AmdExtD3DShaderIntrinsicsOpcodePhase_1,\n                                                     0);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instruction, 0, 0, retVal.y);\n\n    return retVal;\n}\n\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_MakeAtomicInstructions\n*\n*   Creates uint4 with x/y/z/w components containing phase 0/1/2/3 for atomic instructions.\n*   NOTE: This is an internal function and should not be called by the source HLSL shader directly.\n*\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(uint op)\n{\n    uint4 instructions;\n    instructions.x = MakeAmdShaderIntrinsicsInstruction(\n        AmdExtD3DShaderIntrinsicsOpcode_AtomicU64, AmdExtD3DShaderIntrinsicsOpcodePhase_0, op);\n    instructions.y = MakeAmdShaderIntrinsicsInstruction(\n        AmdExtD3DShaderIntrinsicsOpcode_AtomicU64, AmdExtD3DShaderIntrinsicsOpcodePhase_1, op);\n    instructions.z = MakeAmdShaderIntrinsicsInstruction(\n        AmdExtD3DShaderIntrinsicsOpcode_AtomicU64, AmdExtD3DShaderIntrinsicsOpcodePhase_2, op);\n    instructions.w = MakeAmdShaderIntrinsicsInstruction(\n        AmdExtD3DShaderIntrinsicsOpcode_AtomicU64, AmdExtD3DShaderIntrinsicsOpcodePhase_3, op);\n    return instructions;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicOp\n*\n*   Creates intrinstic instructions for the specified atomic op.\n*   NOTE: These are internal functions and should not be called by the source HLSL shader directly.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(RWByteAddressBuffer uav, uint3 address, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x, address.y, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z, value.x,   retVal.y);\n    uav.Store(retVal.x, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,   retVal.y,  retVal.y);\n\n    return retVal;\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(RWTexture1D<uint2> uav, uint3 address, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x, address.y, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z, value.x,   retVal.y);\n    uav[retVal.x] = retVal.y;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,   retVal.y,  retVal.y);\n\n    return retVal;\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(RWTexture2D<uint2> uav, uint3 address, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x, address.y, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z, value.x,   retVal.y);\n    uav[uint2(retVal.x, retVal.x)] = retVal.y;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,   retVal.y,  retVal.y);\n\n    return retVal;\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(RWTexture3D<uint2> uav, uint3 address, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x, address.y, retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z, value.x,   retVal.y);\n    uav[uint3(retVal.x, retVal.x, retVal.x)] = retVal.y;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,   retVal.y,  retVal.y);\n\n    return retVal;\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(\n    RWByteAddressBuffer uav, uint3 address, uint2 compare_value, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x,       address.y,       retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z,       value.x,         retVal.y);\n    uav.Store(retVal.x, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,         compare_value.x, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.w, compare_value.y, retVal.y,        retVal.y);\n\n    return retVal;\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(\n    RWTexture1D<uint2> uav, uint3 address, uint2 compare_value, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x,       address.y,       retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z,       value.x,         retVal.y);\n    uav[retVal.x] = retVal.y;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,         compare_value.x, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.w, compare_value.y, retVal.y,        retVal.y);\n\n    return retVal;\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(\n    RWTexture2D<uint2> uav, uint3 address, uint2 compare_value, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x,       address.y,       retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z,       value.x,         retVal.y);\n    uav[uint2(retVal.x, retVal.x)] = retVal.y;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,         compare_value.x, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.w, compare_value.y, retVal.y,        retVal.y);\n\n    return retVal;\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOp(\n    RWTexture3D<uint2> uav, uint3 address, uint2 compare_value, uint2 value, uint op)\n{\n    uint2 retVal;\n\n    const uint4 instructions = AmdExtD3DShaderIntrinsics_MakeAtomicInstructions(op);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.x, address.x,       address.y,       retVal.x);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.y, address.z,       value.x,         retVal.y);\n    uav[uint3(retVal.x, retVal.x, retVal.x)] = retVal.y;\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.z, value.y,         compare_value.x, retVal.y);\n    AmdExtD3DShaderIntrinsicsUAV.InterlockedCompareExchange(instructions.w, compare_value.y, retVal.y,        retVal.y);\n\n    return retVal;\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicMinU64\n*\n*   Performs 64-bit atomic minimum of value with the UAV at address, returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicMinU64(RWByteAddressBuffer uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MinU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicMinU64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MinU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicMinU64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MinU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicMinU64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MinU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), value, op);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicMaxU64\n*\n*   Performs 64-bit atomic maximum of value with the UAV at address, returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicMaxU64(RWByteAddressBuffer uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MaxU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicMaxU64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MaxU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicMaxU64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MaxU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicMaxU64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_MaxU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), value, op);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicAndU64\n*\n*   Performs 64-bit atomic AND of value with the UAV at address, returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicAndU64(RWByteAddressBuffer uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AndU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicAndU64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AndU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicAndU64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AndU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicAndU64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AndU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), value, op);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicOrU64\n*\n*   Performs 64-bit atomic OR of value with the UAV at address, returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicOrU64(RWByteAddressBuffer uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_OrU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOrU64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_OrU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOrU64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_OrU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicOrU64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_OrU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), value, op);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicXorU64\n*\n*   Performs 64-bit atomic XOR of value with the UAV at address, returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicXorU64(RWByteAddressBuffer uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XorU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicXorU64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XorU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicXorU64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XorU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicXorU64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XorU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), value, op);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicAddU64\n*\n*   Performs 64-bit atomic add of value with the UAV at address, returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicAddU64(RWByteAddressBuffer uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AddU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicAddU64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AddU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicAddU64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AddU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicAddU64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_AddU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), value, op);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicXchgU64\n*\n*   Performs 64-bit atomic exchange of value with the UAV at address, returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicXchgU64(RWByteAddressBuffer uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicXchgU64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicXchgU64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicXchgU64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_XchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), value, op);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_AtomicCmpXchgU64\n*\n*   Performs 64-bit atomic compare of comparison value with UAV at address, stores value if values match,\n*   returns the original value.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_AtomicCmpXchgU64(\n    RWByteAddressBuffer uav, uint address, uint2 compare_value, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_CmpXchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), compare_value, value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicCmpXchgU64(\n    RWTexture1D<uint2> uav, uint address, uint2 compare_value, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_CmpXchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address, 0, 0), compare_value, value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicCmpXchgU64(\n    RWTexture2D<uint2> uav, uint2 address, uint2 compare_value, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_CmpXchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, 0), compare_value, value, op);\n}\n\nuint2 AmdExtD3DShaderIntrinsics_AtomicCmpXchgU64(\n    RWTexture3D<uint2> uav, uint3 address, uint2 compare_value, uint2 value)\n{\n    const uint op = AmdExtD3DShaderIntrinsicsAtomicOp_CmpXchgU64;\n    return AmdExtD3DShaderIntrinsics_AtomicOp(uav, uint3(address.x, address.y, address.z), compare_value, value, op);\n}\n\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum\n*\n*   Performs reduction operation across a wave and returns the result of the reduction (sum of all threads in a wave)\n*   to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WaveActiveSum(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WaveActiveSum(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WaveActiveSum(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WaveActiveSum(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveActiveSum(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveActiveSum(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveActiveSum(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveActiveSum(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WaveActiveSum(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WaveActiveSum(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WaveActiveSum(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveSum<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WaveActiveSum(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_AddU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct\n*\n*   Performs reduction operation across a wave and returns the result of the reduction (product of all threads in a\n*   wave) to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WaveActiveProduct(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WaveActiveProduct(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WaveActiveProduct(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WaveActiveProduct(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveActiveProduct(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveActiveProduct(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveActiveProduct(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveActiveProduct(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WaveActiveProduct(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WaveActiveProduct(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WaveActiveProduct(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveProduct<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WaveActiveProduct(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MulU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin\n*\n*   Performs reduction operation across a wave and returns the result of the reduction (minimum of all threads in a\n*   wave) to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WaveActiveMin(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WaveActiveMin(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WaveActiveMin(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WaveActiveMin(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveActiveMin(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveActiveMin(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveActiveMin(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveActiveMin(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WaveActiveMin(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WaveActiveMin(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WaveActiveMin(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMin<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WaveActiveMin(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MinU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax\n*\n*   Performs reduction operation across a wave and returns the result of the reduction (maximum of all threads in a\n*   wave) to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WaveActiveMax(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WaveActiveMax(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WaveActiveMax(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WaveActiveMax(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxF, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveActiveMax(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveActiveMax(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveActiveMax(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveActiveMax(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxI, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WaveActiveMax(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WaveActiveMax(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WaveActiveMax(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveMax<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WaveActiveMax(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_MaxU, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd\n*\n*   Performs reduction operation across a wave and returns the result of the reduction (Bitwise AND of all threads in a\n*   wave) to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitAnd<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WaveActiveBitAnd(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_And, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr\n*\n*   Performs reduction operation across a wave and returns the result of the reduction (Bitwise OR of all threads in a\n*   wave) to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveActiveBitOr(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveActiveBitOr(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveActiveBitOr(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveActiveBitOr(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WaveActiveBitOr(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WaveActiveBitOr(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WaveActiveBitOr(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitOr<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WaveActiveBitOr(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Or, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor\n*\n*   Performs reduction operation across a wave and returns the result of the reduction (Bitwise XOR of all threads in a\n*   wave) to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WaveActiveBitXor(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WaveActiveBitXor(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WaveActiveBitXor(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WaveActiveBitXor(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WaveActiveBitXor(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WaveActiveBitXor(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WaveActiveBitXor(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WaveActiveBitXor<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WaveActiveBitXor(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveReduce(AmdExtD3DShaderIntrinsicsWaveOp_Xor, src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum\n*\n*   Performs a prefix (exclusive) scan operation across a wave and returns the resulting sum to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePrefixSum(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePrefixSum(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePrefixSum(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePrefixSum(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePrefixSum(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePrefixSum(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePrefixSum(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePrefixSum(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePrefixSum(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePrefixSum(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePrefixSum(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixSum<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePrefixSum(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct\n*\n*   Performs a prefix scan operation across a wave and returns the resulting product to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePrefixProduct(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePrefixProduct(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePrefixProduct(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePrefixProduct(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePrefixProduct(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePrefixProduct(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePrefixProduct(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePrefixProduct(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePrefixProduct(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePrefixProduct(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePrefixProduct(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixProduct<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePrefixProduct(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin\n*\n*   Performs a prefix scan operation across a wave and returns the resulting minimum value to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePrefixMin(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePrefixMin(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePrefixMin(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePrefixMin(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePrefixMin(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePrefixMin(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePrefixMin(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePrefixMin(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePrefixMin(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePrefixMin(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePrefixMin(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMin<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePrefixMin(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax\n*\n*   Performs a prefix scan operation across a wave and returns the resulting maximum value to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePrefixMax(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePrefixMax(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePrefixMax(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePrefixMax(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePrefixMax(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePrefixMax(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePrefixMax(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePrefixMax(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePrefixMax(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePrefixMax(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePrefixMax(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePrefixMax<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePrefixMax(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Exclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum\n*\n*   Performs a Postfix (Inclusive) scan operation across a wave and returns the resulting sum to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePostfixSum(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePostfixSum(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePostfixSum(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePostfixSum(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePostfixSum(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePostfixSum(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePostfixSum(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePostfixSum(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePostfixSum(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePostfixSum(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePostfixSum(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixSum<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePostfixSum(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_AddU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct\n*\n*   Performs a Postfix scan operation across a wave and returns the resulting product to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePostfixProduct(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePostfixProduct(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePostfixProduct(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePostfixProduct(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePostfixProduct(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePostfixProduct(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePostfixProduct(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePostfixProduct(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePostfixProduct(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePostfixProduct(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePostfixProduct(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixProduct<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePostfixProduct(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MulU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin\n*\n*   Performs a Postfix scan operation across a wave and returns the resulting minimum value to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePostfixMin(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePostfixMin(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePostfixMin(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePostfixMin(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePostfixMin(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePostfixMin(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePostfixMin(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePostfixMin(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePostfixMin(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePostfixMin(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePostfixMin(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMin<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePostfixMin(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MinU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax\n*\n*   Performs a Postfix scan operation across a wave and returns the resulting maximum value to all participating lanes.\n*\n*   Available in all shader stages.\n*\n***********************************************************************************************************************\n*/\nfloat AmdExtD3DShaderIntrinsics_WavePostfixMax(float src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<float2>\n***********************************************************************************************************************\n*/\nfloat2 AmdExtD3DShaderIntrinsics_WavePostfixMax(float2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<float3>\n***********************************************************************************************************************\n*/\nfloat3 AmdExtD3DShaderIntrinsics_WavePostfixMax(float3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<float4>\n***********************************************************************************************************************\n*/\nfloat4 AmdExtD3DShaderIntrinsics_WavePostfixMax(float4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxF,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<int>\n***********************************************************************************************************************\n*/\nint AmdExtD3DShaderIntrinsics_WavePostfixMax(int src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<int2>\n***********************************************************************************************************************\n*/\nint2 AmdExtD3DShaderIntrinsics_WavePostfixMax(int2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<int3>\n***********************************************************************************************************************\n*/\nint3 AmdExtD3DShaderIntrinsics_WavePostfixMax(int3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<int4>\n***********************************************************************************************************************\n*/\nint4 AmdExtD3DShaderIntrinsics_WavePostfixMax(int4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxI,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<uint>\n***********************************************************************************************************************\n*/\nuint AmdExtD3DShaderIntrinsics_WavePostfixMax(uint src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<uint2>\n***********************************************************************************************************************\n*/\nuint2 AmdExtD3DShaderIntrinsics_WavePostfixMax(uint2 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<uint3>\n***********************************************************************************************************************\n*/\nuint3 AmdExtD3DShaderIntrinsics_WavePostfixMax(uint3 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n/**\n***********************************************************************************************************************\n*   AmdExtD3DShaderIntrinsics_WavePostfixMax<uint4>\n***********************************************************************************************************************\n*/\nuint4 AmdExtD3DShaderIntrinsics_WavePostfixMax(uint4 src)\n{\n    return AmdExtD3DShaderIntrinsics_WaveScan(AmdExtD3DShaderIntrinsicsWaveOp_MaxU,\n                                              AmdExtD3DShaderIntrinsicsWaveOp_Inclusive,\n                                              src);\n}\n\n#if defined (AGS_RAY_HIT_TOKEN)\n\n//=====================================================================================================================\nstruct AmdExtRtHitToken\n{\n    uint dword[2];\n};\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsRT structure when included in a Ray Tracing payload will indicate to the driver\n*    that the dwords are already supplied in AmdExtRtHitTokenIn and only requires a call to intersect\n*    ray, bypassing the traversal of the acceleration structure.\n***********************************************************************************************************************\n*/\nstruct AmdExtRtHitTokenIn : AmdExtRtHitToken { };\n\n/**\n***********************************************************************************************************************\n* @brief\n*    AmdExtD3DShaderIntrinsicsRT structure when included in a Ray Tracing payload will indicate to the driver\n*    that the dwords must be patched into the payload after traversal.  The application can store this\n*    data in a buffer which can then be used for hit group sorting so shading divergence can be avoided.\n***********************************************************************************************************************\n*/\nstruct AmdExtRtHitTokenOut : AmdExtRtHitToken { };\n\n/**\n***********************************************************************************************************************\n* @brief\n*    Group shared memory reserved for temprary storage of hit tokens. Not intended to touched by the app shader.\n*    Application shader must only use the extension functions defined below to access the hit tokens\n*\n***********************************************************************************************************************\n*/\ngroupshared AmdExtRtHitToken AmdHitToken;\n\n/**\n***********************************************************************************************************************\n* @brief\n*    Accessor function to obtain the hit tokens from the last call to TraceRays(). The data returned by this\n*    function only guarantees valid values for the last call to TraceRays() prior to calling this function.\n*\n***********************************************************************************************************************\n*/\nuint2 AmdGetLastHitToken()\n{\n    return uint2(AmdHitToken.dword[0], AmdHitToken.dword[1]);\n}\n\n/**\n***********************************************************************************************************************\n* @brief\n*    This function initialises hit tokens for subsequent TraceRays() call. Note, any TraceRay() that intends to use\n*    these hit tokens must include this function call in the same basic block. Applications can use a convenience macro\n*    defined below to enforce that.\n*\n***********************************************************************************************************************\n*/\nvoid AmdSetHitToken(uint2 token)\n{\n    AmdHitToken.dword[0] = token.x;\n    AmdHitToken.dword[1] = token.y;\n}\n\n/**\n***********************************************************************************************************************\n* @brief\n*    Convenience macro for calling TraceRays that uses the hit token\n*\n***********************************************************************************************************************\n*/\n#define AmdTraceRay(accelStruct,                    \\\n                    rayFlags,                       \\\n                    instanceInclusionMask,          \\\n                    rayContributionToHitGroupIndex, \\\n                    geometryMultiplier,             \\\n                    missShaderIndex,                \\\n                    ray,                            \\\n                    payload,                        \\\n                    token)                          \\\nAmdSetHitToken(token);                              \\\nTraceRay(accelStruct,                               \\\n         rayFlags,                                  \\\n         instanceInclusionMask,                     \\\n         rayContributionToHitGroupIndex,            \\\n         geometryMultiplier,                        \\\n         missShaderIndex,                           \\\n         ray,                                       \\\n         payload);                                  \\\n\n#endif // AGS_RAY_HIT_TOKEN\n\n#endif // _AMDEXTD3DSHADERINTRINICS_HLSL\n"
  },
  {
    "path": "shaders/ags/cs_constexpr_wmma_gep.sm66.full-wmma.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\nstatic WMMA_Matrix as[5];\nstatic WMMA_Matrix bs[5];\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\tas[0] = WMMA_Load(TypeA, Inputs, 0, 64);\n\tbs[0] = WMMA_Load(TypeB, Inputs, 1024, 64);\n\tas[1] = WMMA_Load(TypeA, Inputs, 32, 64);\n\tbs[1] = WMMA_Load(TypeB, Inputs, 1024 + 32, 64);\n\n\t[loop]\n\tfor (int i = 2; i < 5; i++)\n\t{\n\t\tas[i] = WMMA_Load(TypeA, Inputs, 32 * i, 64);\n\t\tbs[i] = WMMA_Load(TypeB, Inputs, 1024 + 32 * i, 64);\n\t}\n\n\tWMMA_Matrix c = WMMA_MatrixFill(TypeC, 0);\n\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[0], bs[0], c);\n\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[1], bs[1], c);\n\t[loop]\n\tfor (int i = 2; i < 5; i++)\n\t\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[i], bs[i], c);\n\tWMMA_Store(TypeC, Outputs, 0, 64, c);\n}\n"
  },
  {
    "path": "shaders/ags/cs_constexpr_wmma_gep.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\nstatic WMMA_Matrix as[5];\nstatic WMMA_Matrix bs[5];\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\tas[0] = WMMA_Load(TypeA, Inputs, 0, 64);\n\tbs[0] = WMMA_Load(TypeB, Inputs, 1024, 64);\n\tas[1] = WMMA_Load(TypeA, Inputs, 32, 64);\n\tbs[1] = WMMA_Load(TypeB, Inputs, 1024 + 32, 64);\n\n\t[loop]\n\tfor (int i = 2; i < 5; i++)\n\t{\n\t\tas[i] = WMMA_Load(TypeA, Inputs, 32 * i, 64);\n\t\tbs[i] = WMMA_Load(TypeB, Inputs, 1024 + 32 * i, 64);\n\t}\n\n\tWMMA_Matrix c = WMMA_MatrixFill(TypeC, 0);\n\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[0], bs[0], c);\n\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[1], bs[1], c);\n\t[loop]\n\tfor (int i = 2; i < 5; i++)\n\t\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[i], bs[i], c);\n\tWMMA_Store(TypeC, Outputs, 0, 64, c);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_alloca.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tWMMA_Matrix as[2];\n\tWMMA_Matrix bs[2];\n\tWMMA_Matrix cs[2];\n\tWMMA_Matrix ds[2];\n\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\t[loop]\n\tfor (int i = 0; i < 2; i++)\n\t{\n\t\tas[i] = WMMA_Load(TypeA, Inputs, 32 * i, 64);\n\t\tbs[i] = WMMA_Load(TypeB, Inputs, 1024 + 32 * i, 64);\n\t}\n\n\t// Test case where we have static write addressing.\n\t[unroll]\n\tfor (int i = 0; i < 2; i++)\n\t{\n\t\tcs[1 - i] = WMMA_Load(TypeA, Inputs, 32 - 32 * i, 64);\n\t\tds[1 - i] = WMMA_Load(TypeB, Inputs, 1024 + 32 - 32 * i, 64);\n\t}\n\n\tWMMA_Matrix c = WMMA_MatrixFill(TypeC, 0);\n\n\t[loop]\n\tfor (int i = 0; i < 2; i++)\n\t\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, as[i], bs[i], c);\n\n\t[loop]\n\tfor (int i = 0; i < 2; i++)\n\t\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, cs[i], ds[i], c);\n\n\tWMMA_Store(TypeC, Outputs, 0, 64, c);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_copy_transpose_fp16.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t// Transpose layout is ignored on arith ops it seems.\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC32 = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeB8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\n\t// Tests if we can just YOLO convert to different types.\n\t// It seems to work ...\n\tWMMA_Matrix m = WMMA_Load(TypeC, Inputs, 0, 32);\n\tWMMA_Matrix a = WMMA_Convert(TypeC, TypeA, m);\n\tWMMA_Matrix b = WMMA_Convert(TypeC, TypeB, m);\n\tWMMA_Matrix c = WMMA_Convert(TypeC, TypeC32, m);\n\tm = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, a, b, c);\n\tWMMA_Store(TypeC32, Outputs, 0, 64, m);\n\n\t// Possible to transpose and do format conversions ... >_<\n\t// Ran into these in the wild.\n\tm = WMMA_Convert(TypeC32, TypeB8, m);\n\tWMMA_Store(TypeB8, Outputs, 1024, 16, m);\n\n\tm = WMMA_Convert(TypeB8, TypeC32, m);\n\tWMMA_Store(TypeC32, Outputs, 2048, 64, m);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_copy_transpose_fp16.sm66.ssbo.full-wmma.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t// Transpose layout is ignored on arith ops it seems.\n\tWMMA_Type TypeC32 = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeB8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\n\tWMMA_Matrix m = WMMA_Load(TypeC32, Inputs, 0, 64);\n\tm = WMMA_ConvertSaturate(TypeC32, TypeB8, m);\n\tWMMA_Store(TypeB8, Outputs, 1024, 16, m);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_extract_insert.sm66.ssbo.full-wmma.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tWMMA_Type TypeA8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Matrix m = WMMA_Load(TypeA8, Inputs, 0, 16);\n\tuint len = WMMA_MatrixLength(TypeA8);\n\n\t// 8-bit matrices are tightly packed ;_;\n\tfor (uint i = 0; i < len; i++)\n\t{\n\t\tuint elem = WMMA_MatrixElementExtract(TypeA8, m, i);\n\t\tOutputs.Store(256 + 4 * (thr * len + i), elem);\n\t\telem ^= 0xff00ff;\n\t\tm = WMMA_MatrixElementFill(TypeA8, m, i, elem);\n\t}\n\n\tWMMA_Store(TypeA8, Outputs, 0, 16, m);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 32, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_at.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 32, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_bt.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 32, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_ct.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 32, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_f16_quant_f16_ot.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 32, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_f16_quant_fp8.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC8, C);\n\n\tWMMA_Store(TypeC8, Outputs, 0, 16, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_fp8.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 16);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 256, 16);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 512, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, A, B, C);\n\tWMMA_Store(TypeC, Outputs, 0, 64, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_fp8.sm66.ssbo.full-wmma.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 16);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 256, 16);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 512, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, A, B, C);\n\tWMMA_Store(TypeC, Outputs, 0, 64, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f16.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 16);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 256, 16);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 512, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 32, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f16_strided.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 64, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f16_strided_transpose.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 32);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 512, 32);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 1024, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, A, B, C);\n\tC = WMMA_Convert(TypeC, TypeC16, C);\n\n\tWMMA_Store(TypeC16, Outputs, 0, 64, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_f32_16x16x16_fp8_quant_f32.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 16);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 256, 16);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 512, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, A, B, C);\n\tWMMA_Store(TypeC, Outputs, 0, 64, C);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_fp16_fp8_conversions.sm66.ssbo.full-wmma.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type Type8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type Type16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix pm = WMMA_MatrixFill(Type16, gid.x);\n\tWMMA_Matrix nm = WMMA_MatrixFill(Type16, gid.x | 0x8000);\n\tpm = WMMA_Convert(Type16, Type8, pm);\n\tnm = WMMA_Convert(Type16, Type8, nm);\n\tuint extracted0 = WMMA_MatrixElementExtract(Type8, pm, 0);\n\tuint extracted1 = WMMA_MatrixElementExtract(Type8, nm, 0);\n\n\tif (thr == 0)\n\t\tOutputs.Store2(8 * gid, uint2(extracted0, extracted1));\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_fp32_fp16_conversions.sm66.ssbo.full-wmma.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type Type16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type Type32 = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix pm = WMMA_MatrixFill(Type32, gid.x);\n\tpm = WMMA_Convert(Type32, Type16, pm);\n\tuint extracted0 = WMMA_MatrixElementExtract(Type16, pm, 0);\n\n\tif (thr == 0)\n\t\tOutputs.Store(gid, extracted0);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_fp32_fp8_conversions.sm66.ssbo.nv-coopmat2.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type Type8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type Type32 = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Matrix pm = WMMA_MatrixFill(Type32, gid.x);\n\tpm = WMMA_ConvertSaturate(Type32, Type8, pm);\n\tWMMA_Store(Type8, Outputs, 0, 16, pm);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_fp8_fp32_conversions.sm66.ssbo.full-wmma.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type Type8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type Type16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type Type16C = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type Type32 = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix m = WMMA_MatrixFill(Type8, gid);\n\tm = WMMA_Convert(Type8, Type16, m);\n\n\tWMMA_StoreLDS(Type16, 0, 32, m);\n\tGroupMemoryBarrierWithGroupSync();\n\tm = WMMA_LoadLDS(Type16C, 0, 32);\n\tm = WMMA_Convert(Type16C, Type32, m);\n\n\tuint extracted = WMMA_MatrixElementExtract(Type32, m, 0);\n\tif (thr == 0)\n\t\tOutputs.Store(4 * gid, extracted);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_lds_transpose.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tWMMA_Type TypeA16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeA16T = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeB16 = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC32 = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix m = WMMA_Load(TypeA16, Inputs, 0, 32);\n\tWMMA_StoreLDS(TypeA16, 0, 32, m);\n\tGroupMemoryBarrierWithGroupSync();\n\tWMMA_Matrix a = WMMA_LoadLDS(TypeA16T, 0, 32);\n\tWMMA_Matrix b = WMMA_LoadLDS(TypeB16, 0, 32);\n\tWMMA_Matrix c = WMMA_MatrixFill(TypeC32, 0);\n\tm = WMMA_MatMulAcc(WMMA_F32_16X16X16_F16, a, b, c);\n\n\tWMMA_Store(TypeC32, Outputs, 0, 64, m);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_matrix_length.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main()\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeA8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB8 = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\n\tWMMA_Type TypeAT = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_A, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeBT = WMMA_MakeType(WaveMatrixDataFormat_F16, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeCT = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeA8T = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeB8T = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\n\tuint size[10];\n\tsize[0] = WMMA_MatrixLength(TypeA);\n\tsize[1] = WMMA_MatrixLength(TypeB);\n\tsize[2] = WMMA_MatrixLength(TypeC);\n\tsize[3] = WMMA_MatrixLength(TypeA8);\n\tsize[4] = WMMA_MatrixLength(TypeB8);\n\tsize[5] = WMMA_MatrixLength(TypeAT);\n\tsize[6] = WMMA_MatrixLength(TypeBT);\n\tsize[7] = WMMA_MatrixLength(TypeCT);\n\tsize[8] = WMMA_MatrixLength(TypeA8T);\n\tsize[9] = WMMA_MatrixLength(TypeB8T);\n\n\tfor (int i = 0; i < 10; i++)\n\t\tOutputs.Store(4 * i, size[i]);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_store_phi.full-wmma.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\ncbuffer Cbuf { uint selector; };\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tWMMA_Matrix as[2];\n\tWMMA_Matrix bs[2];\n\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\t[loop]\n\tfor (int i = 0; i < 2; i++)\n\t{\n\t\tas[i] = WMMA_Load(TypeA, Inputs, 32 * i, 64);\n\n\t\tWMMA_Matrix t;\n\n\t\t[branch]\n\t\tif (selector == 1)\n\t\t\tt = WMMA_Load(TypeB, Inputs, 1024 + 32 * i, 64);\n\t\telse\n\t\t\tt = WMMA_MatrixFill(TypeB, 0);\n\n\t\tbs[i] = t;\n\t}\n\n\tWMMA_Matrix c = WMMA_MatrixFill(TypeC, 0);\n\t[loop]\n\tfor (int i = 0; i < 2; i++)\n\t\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[i], bs[i], c);\n\tWMMA_Store(TypeC, Outputs, 0, 64, c);\n}\n"
  },
  {
    "path": "shaders/ags/cs_wmma_store_phi.sm66.ssbo.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\ncbuffer Cbuf { uint selector; };\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tWMMA_Matrix as[2];\n\tWMMA_Matrix bs[2];\n\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, true);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, true);\n\n\t[loop]\n\tfor (int i = 0; i < 2; i++)\n\t{\n\t\tas[i] = WMMA_Load(TypeA, Inputs, 32 * i, 64);\n\n\t\tWMMA_Matrix t;\n\n\t\t[branch]\n\t\tif (selector == 1)\n\t\t\tt = WMMA_Load(TypeB, Inputs, 1024 + 32 * i, 64);\n\t\telse\n\t\t\tt = WMMA_MatrixFill(TypeB, 0);\n\n\t\tbs[i] = t;\n\t}\n\n\tWMMA_Matrix c = WMMA_MatrixFill(TypeC, 0);\n\t[loop]\n\tfor (int i = 0; i < 2; i++)\n\t\tc = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, as[i], bs[i], c);\n\tWMMA_Store(TypeC, Outputs, 0, 64, c);\n}\n"
  },
  {
    "path": "shaders/ags/wmma_ags.h",
    "content": "#pragma once\n\nstatic const uint MagicCodeShift   = 28;\nstatic const uint MagicCodeMask    = 0xf;\nstatic const uint OpcodePhaseShift = 24;\nstatic const uint OpcodePhaseMask  = 0x3;\nstatic const uint DataShift        = 8;\nstatic const uint DataMask         = 0xffff;\nstatic const uint OpcodeShift      = 0;\nstatic const uint OpcodeMask       = 0xff;\n\nstatic const uint MagicCode = 0x5;\n\nstatic const uint WaveMatrixMulAcc            = 0x28;\nstatic const uint WaveMatrixUavLoad           = 0x29;\nstatic const uint WaveMatrixUavStore          = 0x2a;\nstatic const uint WaveMatrixGlobalLoad        = 0x2b;\nstatic const uint WaveMatrixGlobalStore       = 0x2c;\nstatic const uint WaveMatrixLdsLoad           = 0x2d;\nstatic const uint WaveMatrixLdsStore          = 0x2e;\nstatic const uint WaveMatrixElementFill       = 0x2f;\nstatic const uint WaveMatrixElementExtract    = 0x30;\nstatic const uint WaveMatrixLength            = 0x31;\nstatic const uint WaveMatrixCopy              = 0x32;\nstatic const uint WaveMatrixFill              = 0x33;\nstatic const uint Float8Conversion            = 0x36;\n\nenum WaveMatrixOpDataFormat\n{\n    WaveMatrixDataFormat_I4   = 0x0,\n    WaveMatrixDataFormat_U4   = 0x1,\n    WaveMatrixDataFormat_I8   = 0x2,\n    WaveMatrixDataFormat_U8   = 0x3,\n    WaveMatrixDataFormat_F16  = 0x4,\n    WaveMatrixDataFormat_BF16 = 0x5,\n    WaveMatrixDataFormat_F32  = 0x6,\n    WaveMatrixDataFormat_I32  = 0x7,\n    WaveMatrixDataFormat_U32  = 0x8,\n    WaveMatrixDataFormat_BF8  = 0x9,\n    WaveMatrixDataFormat_FP8  = 0xa,\n};\n\nenum WaveMatrixOpMatrixType\n{\n    WaveMatrixType_A            = 0x0,\n    WaveMatrixType_B            = 0x1,\n    WaveMatrixType_Accumulator  = 0x2,\n};\n\nenum WaveMatrixOpMatrixShape\n{\n    WaveMatrixShape_16X16 = 0x0,\n    WaveMatrixShape_32X16 = 0x1,\n    WaveMatrixShape_16X32 = 0x2,\n    WaveMatrixShape_64X16 = 0x3,\n};\n\nenum WaveMatrixOpcode\n{\n    WMMA_BF16_16X16X16_BF16     = 0x0,\n    WMMA_F16_16X16X16_F16       = 0x1,\n    WMMA_F32_16X16X16_BF16      = 0x2,\n    WMMA_F32_16X16X16_BF8_BF8   = 0x3,\n    WMMA_F32_16X16X16_BF8_FP8   = 0x4,\n    WMMA_F32_16X16X16_F16       = 0x5,\n    WMMA_F32_16X16X16_FP8_BF8   = 0x6,\n    WMMA_F32_16X16X16_FP8_FP8   = 0x7,\n    WMMA_I32_16X16X16_I4        = 0x8,\n    WMMA_I32_16X16X16_U4        = 0x9,\n    WMMA_I32_16X16X16_IU4       = 0xa,\n    WMMA_I32_16X16X16_UI4       = 0xb,\n    WMMA_I32_16X16X16_I8        = 0xc,\n    WMMA_I32_16X16X16_U8        = 0xd,\n    WMMA_I32_16X16X16_IU8       = 0xe,\n    WMMA_I32_16X16X16_UI8       = 0xf,\n    WMMA_I32_16X16X32_I4        = 0x10,\n    WMMA_I32_16X16X32_U4        = 0x11,\n    WMMA_I32_16X16X32_IU4       = 0x12,\n    WMMA_I32_16X16X32_UI4       = 0x13,\n    SWMMA_BF16_16X16X32_BF16    = 0x14,\n    SWMMA_F16_16X16X32_F16      = 0x15,\n    SWMMA_F32_16X16X32_BF16     = 0x16,\n    SWMMA_F32_16X16X32_BF8_BF8  = 0x17,\n    SWMMA_F32_16X16X32_BF8_FP8  = 0x18,\n    SWMMA_F32_16X16X32_F16      = 0x19,\n    SWMMA_F32_16X16X32_FP8_BF8  = 0x1a,\n    SWMMA_F32_16X16X32_FP8_FP8  = 0x1b,\n    SWMMA_I32_16X16X32_I4       = 0x1c,\n    SWMMA_I32_16X16X32_U4       = 0x1d,\n    SWMMA_I32_16X16X32_IU4      = 0x1e,\n    SWMMA_I32_16X16X32_UI4      = 0x1f,\n    SWMMA_I32_16X16X32_I8       = 0x20,\n    SWMMA_I32_16X16X32_U8       = 0x21,\n    SWMMA_I32_16X16X32_IU8      = 0x22,\n    SWMMA_I32_16X16X32_UI8      = 0x23,\n    SWMMA_I32_16X16X64_I4       = 0x24,\n    SWMMA_I32_16X16X64_U4       = 0x25,\n    SWMMA_I32_16X16X64_IU4      = 0x26,\n    SWMMA_I32_16X16X64_UI4      = 0x27,\n};\n\nenum WaveMatrixRegType\n{\n    WaveMatrixRegType_RetVal_Reg          = 0x0,\n    WaveMatrixRegType_A_TempReg           = 0x1,\n    WaveMatrixRegType_B_TempReg           = 0x2,\n    WaveMatrixRegType_Accumulator_TempReg = 0x3,\n};\n\nenum MatrixElementWiseOp\n{\n    MatrixElementWiseOp_Add   = 0x1,\n    MatrixElementWiseOp_Sub   = 0x2,\n    MatrixElementWiseOp_Mul   = 0x3,\n    MatrixElementWiseOp_Div   = 0x4,\n    MatrixElementWiseOp_Times = 0x5,\n};\n\nenum SparsityIndexMem\n{\n    SparsityIndexMem_UavBuffer    = 0x0,\n    SparsityIndexMem_GroupShared  = 0x1,\n    SparsityIndexMem_GlobalBuffer = 0x2,\n};\n\nstatic const uint WaveMatrixOpcode_OpsShift  = 0;\nstatic const uint WaveMatrixOpcode_OpsMask   = 0x7f;\nstatic const uint WaveMatrixOpcode_FlagShift = 15;\nstatic const uint WaveMatrixOpcode_FlagMask  = 0x1;\n\nstatic const uint WaveMatrixInOut_ChannelShift        = 0;\nstatic const uint WaveMatrixInOut_ChannelMask         = 0xf;\nstatic const uint WaveMatrixInOut_SecondRegFlagShift  = 4;\nstatic const uint WaveMatrixInOut_SecondRegFlagMask   = 0xf;\nstatic const uint WaveMatrixInOut_MatRegTypeFlagShift = 8;\nstatic const uint WaveMatrixInOut_MatRegTypeFlagMask  = 0xff;\n\nstatic const uint WaveMatrixModifier_DataFormatFlagShift = 0;\nstatic const uint WaveMatrixModifier_DataFormatFlagMask  = 0xf;\nstatic const uint WaveMatrixModifier_MatrixTypeFlagShift = 4;\nstatic const uint WaveMatrixModifier_MatrixTypeFlagMask  = 0x7;\nstatic const uint WaveMatrixModifier_LayoutFlagShift     = 7;\nstatic const uint WaveMatrixModifier_LayoutFlagMask      = 0x1;\nstatic const uint WaveMatrixModifier_ShapeShift          = 8;\nstatic const uint WaveMatrixModifier_ShapeMask           = 0x7;\nstatic const uint WaveMatrixModifier_MatrixTileShift     = 11;\nstatic const uint WaveMatrixModifier_MatrixTileMask      = 0x1;\nstatic const uint WaveMatrixModifier_IndexMemTypeShift   = 14;\nstatic const uint WaveMatrixModifier_IndexMemTypeMask    = 0x3;\n\n// For wave32 and FP32, we need up to 8 values to store a 16x16 matrix.\nstruct WMMA_Matrix\n{\n\tuint v[8];\n};\n\nuint Code(uint opcode, uint opcodePhase, uint immediateData)\n{\n    return (MagicCode << MagicCodeShift) |\n           ((immediateData & DataMask) << DataShift) |\n           ((opcodePhase & OpcodePhaseMask) << OpcodePhaseShift) |\n           ((opcode & OpcodeMask) << OpcodeShift);\n}\n\nuint AGSMagic(uint code, uint arg0, uint arg1)\n{\n\tuint ret;\n\tMAGIC.InterlockedCompareExchange(code, arg0, arg1, ret);\n\treturn ret;\n}\n\nuint AGSMagic(uint opcode, uint phase, uint imm, uint arg0, uint arg1)\n{\n\treturn AGSMagic(Code(opcode, phase, imm), arg0, arg1);\n}\n\nuint MatrixIO(uint channel, uint reg, uint type)\n{\n\treturn (channel << WaveMatrixInOut_ChannelShift) |\n\t\t(reg << WaveMatrixInOut_SecondRegFlagShift) |\n\t\t(type << WaveMatrixInOut_MatRegTypeFlagShift);\n}\n\nWMMA_Matrix WMMA_MatMulAcc(WaveMatrixOpcode op, WMMA_Matrix A, WMMA_Matrix B, WMMA_Matrix C)\n{\n\t// A matrix\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 0, WaveMatrixRegType_A_TempReg), A.v[0], A.v[1]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 0, WaveMatrixRegType_A_TempReg), A.v[2], A.v[3]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 1, WaveMatrixRegType_A_TempReg), A.v[4], A.v[5]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 1, WaveMatrixRegType_A_TempReg), A.v[6], A.v[7]);\n\n\t// B matrix\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 0, WaveMatrixRegType_B_TempReg), B.v[0], B.v[1]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 0, WaveMatrixRegType_B_TempReg), B.v[2], B.v[3]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 1, WaveMatrixRegType_B_TempReg), B.v[4], B.v[5]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 1, WaveMatrixRegType_B_TempReg), B.v[6], B.v[7]);\n\n\t// C matrix\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 0, WaveMatrixRegType_Accumulator_TempReg), C.v[0], C.v[1]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 0, WaveMatrixRegType_Accumulator_TempReg), C.v[2], C.v[3]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 1, WaveMatrixRegType_Accumulator_TempReg), C.v[4], C.v[5]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 1, WaveMatrixRegType_Accumulator_TempReg), C.v[6], C.v[7]);\n\n\t// Configure type\n\tAGSMagic(WaveMatrixMulAcc, 1, int(op) << int(WaveMatrixOpcode_OpsShift), 0, 0);\n\n\t// Read output\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nstruct WMMA_Type\n{\n\tuint code;\n};\n\nWMMA_Type WMMA_MakeType(WaveMatrixOpDataFormat fmt, WaveMatrixOpMatrixType mtype, WaveMatrixOpMatrixShape shape, bool transposed)\n{\n\tWMMA_Type type;\n\ttype.code = (int(fmt) << WaveMatrixModifier_DataFormatFlagShift) |\n\t\t(int(mtype) << WaveMatrixModifier_MatrixTypeFlagShift) |\n\t\t(int(shape) << WaveMatrixModifier_ShapeShift) |\n\t\t(transposed << WaveMatrixModifier_LayoutFlagShift);\n\treturn type;\n}\n\nWMMA_Matrix WMMA_Load(WMMA_Type type, ByteAddressBuffer BAB, uint offset, uint stride)\n{\n\tuint doorbell = AGSMagic(WaveMatrixUavLoad, 0, 0, offset, stride);\n\tuint hook = BAB.Load(doorbell);\n\tAGSMagic(WaveMatrixUavLoad, 1, type.code, hook, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nWMMA_Matrix WMMA_Load(WMMA_Type type, RWByteAddressBuffer BAB, uint offset, uint stride)\n{\n\tuint doorbell = AGSMagic(WaveMatrixUavLoad, 0, 0, offset, stride);\n\tuint hook = BAB.Load(doorbell);\n\tAGSMagic(WaveMatrixUavLoad, 1, type.code, hook, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nvoid WMMA_Store(WMMA_Type type, RWByteAddressBuffer BAB, uint offset, uint stride, WMMA_Matrix m)\n{\n\tuint doorbell = AGSMagic(WaveMatrixUavStore, 0, 0, offset, stride);\n\tuint hook = BAB.Load(doorbell);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixUavStore, 2, type.code, hook, 0);\n}\n\ngroupshared uint LDS[512];\n\nWMMA_Matrix WMMA_LoadLDS(WMMA_Type type, uint offset, uint stride)\n{\n\tuint hook;\n\tuint doorbell = AGSMagic(WaveMatrixLdsLoad, 0, 0, offset, stride);\n\tInterlockedAdd(LDS[doorbell], 0, hook);\n\tAGSMagic(WaveMatrixLdsLoad, 1, type.code, hook, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nvoid WMMA_StoreLDS(WMMA_Type type, uint offset, uint stride, WMMA_Matrix m)\n{\n\tuint doorbell = AGSMagic(WaveMatrixLdsStore, 0, 0, offset, stride);\n\tuint hook;\n\tInterlockedAdd(LDS[doorbell], 0, hook);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixLdsStore, 2, type.code, hook, 0);\n}\n\nWMMA_Matrix WMMA_Convert(WMMA_Type intype, WMMA_Type outtype, WMMA_Matrix m)\n{\n\tAGSMagic(WaveMatrixCopy, 0, 0, 0, 0);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(0, 0, 0), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(1, 0, 0), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(0, 1, 0), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(1, 1, 0), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixCopy, 1, intype.code, outtype.code, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nWMMA_Matrix WMMA_ConvertSaturate(WMMA_Type intype, WMMA_Type outtype, WMMA_Matrix m)\n{\n\tAGSMagic(WaveMatrixCopy, 0, 0, 0, 0);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(0, 0, 0), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(1, 0, 0), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(0, 1, 0), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(1, 1, 0), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixCopy, 1, intype.code, outtype.code, 1);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nuint WMMA_MatrixLength(WMMA_Type type)\n{\n\treturn AGSMagic(WaveMatrixLength, 0, type.code, 0, 0);\n}\n\nuint WMMA_MatrixElementExtract(WMMA_Type type, WMMA_Matrix m, uint elem)\n{\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\treturn AGSMagic(WaveMatrixElementExtract, 1, type.code, elem, 0); \n}\n\nWMMA_Matrix WMMA_MatrixElementFill(WMMA_Type type, WMMA_Matrix m, uint index, uint data)\n{\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixElementFill, 1, type.code, index, data);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nWMMA_Matrix WMMA_MatrixFill(WMMA_Type type, uint value)\n{\n\tAGSMagic(WaveMatrixFill, 0, type.code, value, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixFill, 1, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixFill, 1, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixFill, 1, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixFill, 1, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixFill, 1, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixFill, 1, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixFill, 1, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixFill, 1, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\n"
  },
  {
    "path": "shaders/alloca-opts/bad-stride.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\tbs[0] = foo.b[0];\n\tbs[1] = foo.b[1];\n\tbs[2] = foo.b[3];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/double-array-load.frag",
    "content": "struct Foo\n{\n\tdouble4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tdouble4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * float4(bs[a % 6]);\n}\n"
  },
  {
    "path": "shaders/alloca-opts/float4-array-load.bindless.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/float4-array-load.bindless.root-constants.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/float4-array-load.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/float4-array-load.root-constant.frag",
    "content": "struct Foo\n{\n\tfloat4 b0;\n\tfloat4 b1;\n\tfloat4 b2;\n};\n\ncbuffer Buf : register(b0)\n{\n\tFoo foo;\n};\n\ncbuffer BufForward : register(b3)\n{\n\tFoo foo2;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[3];\n\tfloat4 cs[3];\n\n\tbs[0] = foo.b0;\n\tbs[1] = foo.b1;\n\tbs[2] = foo.b2;\n\n\tcs[0] = foo2.b0;\n\tcs[1] = foo2.b1;\n\tcs[2] = foo2.b2;\n\n\treturn p * bs[a % 3] + cs[a % 3];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/float4-array-load.root-descriptor.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/float4-array-load.root-descriptor.root-constants.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/load-different.frag",
    "content": "struct Foo\n{\n\tfloat a, b, c, d;\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\ncbuffer Buf2\n{\n\tFoo foo2;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat same[4];\n\tfloat diff[4];\n\n\tsame[0] = foo.a;\n\tsame[1] = foo.b;\n\tsame[2] = foo.c;\n\tsame[3] = foo.d;\n\n\tdiff[0] = foo.a;\n\tdiff[1] = foo.b;\n\tdiff[2] = foo2.c;\n\tdiff[3] = foo2.d;\n\n\treturn p * same[a % 4] * diff[a % 4];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/local-root-constants.local-root-signature.rgen",
    "content": "struct Foo\n{\n\tfloat b0, b1, b2, b3;\n};\n\ncbuffer Buf : register(b0, space15)\n{\n\tFoo foo;\n};\n\ncbuffer Buf : register(b2, space15)\n{\n\tFoo foo2;\n};\n\nRWTexture2D<float> RWIMG : register(u0);\n\n[shader(\"raygeneration\")]\nvoid main()\n{\n\tfloat bs[4];\n\tfloat cs[4];\n\n\tbs[0] = foo.b0;\n\tbs[1] = foo.b1;\n\tbs[2] = foo.b2;\n\tbs[3] = foo.b3;\n\n\tcs[0] = foo2.b0;\n\tcs[1] = foo2.b1;\n\tcs[2] = foo2.b2;\n\tcs[3] = foo2.b3;\n\n\tuint2 id = DispatchRaysIndex().xy;\n\n\tRWIMG[id] = bs[id.x % 4] * cs[id.y % 4];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/matrix-load.frag",
    "content": "struct Foo\n{\n\tfloat4x4 a[6];\n};\n\ncbuffer Buf\n{\n\tfloat4 a;\n\tfloat4 b;\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4x4 as[3];\n\t[unroll]\n\tfor (int i = 0; i < 3; i++)\n\t\tas[i] = foo.a[i];\n\n\treturn as[a % 3][2] * p;\n}\n"
  },
  {
    "path": "shaders/alloca-opts/missing-first.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 1; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/missing-last-element.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 5; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/out-of-order-load.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\n\tbs[0] = foo.b[0];\n\tbs[5] = foo.b[5];\n\tbs[3] = foo.b[3];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/alloca-opts/store-after-load.frag",
    "content": "struct Foo\n{\n\tfloat4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nfloat4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tfloat4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 3; i++)\n\t\tbs[i] = foo.b[i];\n\n\tfloat4 result = bs[a % 3];\n\n\tfor (int i = 3; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6] + result;\n}\n"
  },
  {
    "path": "shaders/alloca-opts/uint4-array-load.frag",
    "content": "struct Foo\n{\n\tuint4 b[6];\n};\n\ncbuffer Buf\n{\n\tFoo foo;\n};\n\nuint4 main(uint a : A, float4 p : P) : SV_Target\n{\n\tuint4 bs[6];\n\t[unroll]\n\tfor (int i = 0; i < 6; i++)\n\t\tbs[i] = foo.b[i];\n\n\treturn p * bs[a % 6];\n}\n"
  },
  {
    "path": "shaders/auto-barrier/complex-loop.auto-group-shared-barrier.comp",
    "content": "RWStructuredBuffer<uint> Output;\ngroupshared uint A;\ngroupshared uint B[32];\n\n\t[numthreads(32, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t[loop]\n\tfor (int i = 0; i < 4; i++)\n\t{\n\t\t// Store\n\t\tA = 10;\n\t\tB[thr] = 40;\n\t\t// Load\n\t\tOutput[thr] = B[thr ^ 31];\n\t\tOutput[thr] = B[thr ^ 15];\n\n\t\t[loop]\n\t\tfor (int j = 0; j < 4; j++)\n\t\t{\n\t\t\t// Atomics\n\t\t\tuint o;\n\t\t\tInterlockedAdd(B[thr], 1, o);\n\t\t\tInterlockedOr(B[thr], o, o);\n\t\t\tInterlockedXor(B[thr], o, o);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "shaders/auto-barrier/inner-to-inner.auto-group-shared-barrier.comp",
    "content": "RWStructuredBuffer<uint> Output;\nRWStructuredBuffer<uint> Output2;\ngroupshared uint A[32];\n\n[numthreads(32, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t[branch]\n\tif (thr < 16)\n\t{\n\t\t// Store\n\t\tA[thr] = Output[1024 + thr];\n\t}\n\telse\n\t{\n\t\t// Store\n\t\tA[thr ^ 1] = Output2[1024 + thr];\n\t}\n\n\t[branch]\n\tif (thr < 16)\n\t{\n\t\t[branch]\n\t\tif (Output[thr] == 50)\n\t\t{\n\t\t\t// Load\n\t\t\tOutput[thr] = A[thr ^ 31];\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "shaders/auto-barrier/inner-to-outer.auto-group-shared-barrier.comp",
    "content": "RWStructuredBuffer<uint> Output;\ngroupshared uint A;\n\n[numthreads(32, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t[branch]\n\tif (thr < 16)\n\t{\n\t\t[branch]\n\t\tif (Output[thr] == 50)\n\t\t{\n\t\t\t// Store\n\t\t\tA = 50;\n\t\t}\n\t}\n\t// Load\n\tOutput[thr] = A;\n}\n"
  },
  {
    "path": "shaders/auto-barrier/outer-to-inner.auto-group-shared-barrier.comp",
    "content": "RWStructuredBuffer<uint> Output;\ngroupshared uint A[32];\n\n[numthreads(32, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t// Store\n\tA[thr] = Output[1024 + thr];\n\n\t[branch]\n\tif (thr < 16)\n\t{\n\t\t[branch]\n\t\tif (Output[thr] == 50)\n\t\t{\n\t\t\t// Load\n\t\t\tOutput[thr] = A[thr ^ 31];\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "shaders/auto-barrier/single-block-loop.auto-group-shared-barrier.comp",
    "content": "RWStructuredBuffer<uint> Output;\ngroupshared uint A;\ngroupshared uint B[32];\n\n[numthreads(32, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t[loop]\n\tfor (int i = 0; i < 4; i++)\n\t{\n\t\t// Store\n\t\tA = 10;\n\t\tB[thr] = 40;\n\t\t// Load\n\t\tOutput[thr] = B[thr ^ 31];\n\t\tOutput[thr] = B[thr ^ 15];\n\t\t// Atomics\n\t\tuint o;\n\t\tInterlockedAdd(B[thr], 1, o);\n\t\tInterlockedOr(B[thr], 1, o);\n\t\tInterlockedXor(B[thr], 1, o);\n\t}\n}\n"
  },
  {
    "path": "shaders/auto-barrier/single-block.auto-group-shared-barrier.comp",
    "content": "RWStructuredBuffer<uint> Output;\ngroupshared uint A;\ngroupshared uint B[32];\n\n[numthreads(32, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\t// Store\n\tA = 10;\n\tB[thr] = 40;\n\t// Load\n\tOutput[thr] = B[thr ^ 31];\n\tOutput[thr] = B[thr ^ 15];\n\t// Atomics\n\tuint o;\n\tInterlockedAdd(B[thr], 1, o);\n\tInterlockedOr(B[thr], 1, o);\n\tInterlockedXor(B[thr], 1, o);\n}\n"
  },
  {
    "path": "shaders/control-flow/branch-return-2.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n// Test two layers of complicated inlining.\n\nuint func2(uint3 index)\n{\n\tuint result = 0;\n\t[branch]\n\tif (index.x == 10)\n\t{\n\t\t[branch]\n\t\tif (index.z == 40)\n\t\t\treturn index.x * index.y;\n\t\tresult += index.x;\n\t}\n\telse if (index.y == 20)\n\t{\n\t\t[branch]\n\t\tif (index.z == 50)\n\t\t\treturn index.x * (index.y + 4);\n\t\tresult += index.z;\n\t}\n\n\tresult += index.x;\n\treturn result;\n}\n\nuint func(uint3 index)\n{\n\tuint result = 0;\n\t[branch]\n\tif (index.x == 10)\n\t{\n\t\t[branch]\n\t\tif (index.z == 40)\n\t\t\treturn index.x * index.y;\n\t\tresult += func2(index);\n\t}\n\telse if (index.y == 20)\n\t{\n\t\t[branch]\n\t\tif (index.z == 50)\n\t\t\treturn index.x * (index.y + 4);\n\t\tresult += func2(index + 10);\n\t}\n\n\tresult += index.x;\n\n\treturn result;\n}\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = func(index);\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/branch-return.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nuint func(uint3 index)\n{\n\tuint result = 0;\n\t[branch]\n\tif (index.x == 10)\n\t{\n\t\t[branch]\n\t\tif (index.z == 40)\n\t\t\treturn index.x * index.y;\n\t\tresult += index.y;\n\t}\n\telse if (index.y == 20)\n\t{\n\t\t[branch]\n\t\tif (index.z == 50)\n\t\t\treturn index.x * (index.y + 4);\n\t\tresult += index.z;\n\t}\n\n\tresult += index.x;\n\n\treturn result;\n}\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = func(index);\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/branch.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\t// Single branch\n\t[branch]\n\tif (index.x == 10)\n\t\tresult = 40;\n\telse\n\t\tresult = 50;\n\n\t// 2-level branch\n\t[branch]\n\tif (index.x == 20)\n\t{\n\t\t[branch]\n\t\tif (index.y == 30)\n\t\t\tresult += 20;\n\t\telse\n\t\t\tresult *= result;\n\t}\n\telse\n\t{\n\t\t[branch]\n\t\tif (index.y == 40)\n\t\t\tresult += 70;\n\t\telse\n\t\t\tresult *= 10;\n\t}\n\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/conditional-break-into-if-else-if-ladder-2.comp",
    "content": "RWStructuredBuffer<uint> RW : register(u0);\n\nuint run_foo(uint3 id)\n{\n\t[branch]\n\tif (id.x & 1)\n\t{\n\t\t[branch]\n\t\tif (id.x & 2)\n\t\t\treturn 60;\n\n\t\t[branch]\n\t\tif (id.x & 4)\n\t\t{\n\t\t\treturn 30;\n\t\t}\n\t\telse if (id.x & 8)\n\t\t{\n\t\t\treturn 40;\n\t\t}\n\t\telse if (id.x & 16)\n\t\t{\n\t\t\treturn 50;\n\t\t}\n\t}\n\treturn 0;\n}\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 id : SV_DispatchThreadID)\n{\n\tuint foo = run_foo(id);\n\tRW[0] = foo;\n}\n"
  },
  {
    "path": "shaders/control-flow/conditional-break-into-if-else-if-ladder.comp",
    "content": "RWStructuredBuffer<uint> RW : register(u0);\n\nuint run_foo(uint3 id)\n{\n\t[branch]\n\tif (id.x & 1)\n\t{\n\t\t[branch]\n\t\tif (id.x & 2)\n\t\t{\n\t\t\tRW[2] = 20;\n\t\t\treturn 60;\n\t\t}\n\n\t\t[branch]\n\t\tif (id.x & 4)\n\t\t{\n\t\t\treturn 30;\n\t\t}\n\t\telse if (id.x & 8)\n\t\t{\n\t\t\treturn 40;\n\t\t}\n\t\telse if (id.x & 16)\n\t\t{\n\t\t\treturn 50;\n\t\t}\n\t}\n\treturn 0;\n}\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 id : SV_DispatchThreadID)\n{\n\tuint foo = run_foo(id);\n\tRW[0] = foo;\n}\n"
  },
  {
    "path": "shaders/control-flow/dual-inner-loop-early-return.comp",
    "content": "uint func(uint3 dispatch)\n{\n\t[loop]\n\tfor (int i = 0; i < 10; i++)\n\t{\n\t\t[loop]\n\t\tfor (int j = 0; j < 20; j++)\n\t\t{\n\t\t\t[branch]\n\t\t\tif (dispatch.y < 10)\n\t\t\t\treturn 50;\n\n\t\t\t[branch]\n\t\t\tif (dispatch.z < 10)\n\t\t\t\treturn 70;\n\t\t\tdispatch.y++;\n\t\t}\n\n\t\tdispatch.x++;\n\t}\n\n\treturn 80;\n}\n\nRWStructuredBuffer<uint> buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 dispatch : SV_DispatchThreadID)\n{\n\tbuf[dispatch.x] = func(dispatch);\n}\n"
  },
  {
    "path": "shaders/control-flow/if-else-if-into-continue.comp",
    "content": "RWStructuredBuffer<uint> RW : register(u0);\n\n[numthreads(1,1,1)]\nvoid main(uint3 d : SV_DispatchThreadID)\n{\n\t[loop]\n\tfor (uint i = 0; i < d.x; i++)\n\t{\n\t\t[branch]\n\t\tif (d.z < 10)\n\t\t\tRW[d.y] = 20;\n\t\telse if (d.y < 5)\n\t\t\tRW[d.z] = 40;\n\n\t\td += 1;\n\t}\n}\n"
  },
  {
    "path": "shaders/control-flow/inner-loop-early-return.comp",
    "content": "uint func(uint3 dispatch)\n{\n\t[loop]\n\tfor (int i = 0; i < 10; i++)\n\t{\n\t\t[loop]\n\t\tfor (int j = 0; j < 20; j++)\n\t\t{\n\t\t\t[branch]\n\t\t\tif (dispatch.z < 10)\n\t\t\t\treturn 70;\n\t\t\tdispatch.y++;\n\t\t}\n\n\t\tdispatch.x++;\n\t}\n\n\treturn 80;\n}\n\nRWStructuredBuffer<uint> buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 dispatch : SV_DispatchThreadID)\n{\n\tbuf[dispatch.x] = func(dispatch);\n}\n"
  },
  {
    "path": "shaders/control-flow/interleaved-unrolled-loop-breaks.comp",
    "content": "RWStructuredBuffer<uint> RW : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint id : SV_DispatchThreadID)\n{\n\tuint v;\n\tuint w = 1;\n\tuint dummy = 0;\n\n\t[unroll]\n\tfor (int i = 0; i < 4; i++)\n\t{\n\t\tInterlockedAdd(RW[0], w, v); w = v;\n\n\t\t[branch]\n\t\tif (w & 13)\n\t\t{\n\t\t\tInterlockedAdd(RW[0], w, v); w = v;\n\t\t\tdummy = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\t[branch]\n\t\tif (w & 1)\n\t\t{\n\t\t\t[branch]\n\t\t\tif (w & 4)\n\t\t\t\tInterlockedOr(RW[0], w, v); w = v;\n\t\t\tdummy = 2;\n\t\t\tbreak;\n\t\t}\n\n\t\t[branch]\n\t\tif (w & 2)\n\t\t{\n\t\t\tInterlockedOr(RW[0], w, v); w = v;\n\t\t\tdummy = 3;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tInterlockedAdd(RW[0], w, v); w = v;\n\tInterlockedAdd(RW[0], dummy, v);\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-break-2.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\t// Simple loop with a break.\n\t[loop]\n\tfor (uint i = 0; i < index.z; i++)\n\t{\n\t\tuint val = Buf.Load(4 * i);\n\t\tif (val == 30)\n\t\t{\n\t\t\t// Do some work before breaking.\n\t\t\tresult += Buf.Load(100);\n\t\t\tbreak;\n\t\t}\n\t\tresult += val;\n\t}\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-break.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\t// Simple loop with a break.\n\t[loop]\n\tfor (uint i = 0; i < index.z; i++)\n\t{\n\t\tuint val = Buf.Load(4 * i);\n\t\tif (val == 30)\n\t\t\tbreak;\n\t\tresult += val;\n\t}\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-continue-2.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\tuint i = 0;\n\n\twhile (i < index.x)\n\t{\n\t\t[branch]\n\t\tif (Buf.Load(4 * i) == 40)\n\t\t{\n\t\t\t[branch]\n\t\t\tif (i == 10)\n\t\t\t{\n\t\t\t\ti += index.y;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tresult += Buf.Load(16 * i);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tresult += Buf.Load(12 * i);\n\t\t}\n\t\tresult += Buf.Load(8 * i);\n\t\ti++;\n\t}\n\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-continue-3.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\tuint i = 0;\n\n\twhile (i < index.x)\n\t{\n\t\t[branch]\n\t\tif (Buf.Load(4 * i) == 40)\n\t\t{\n\t\t\t[branch]\n\t\t\tif (i == 10)\n\t\t\t{\n\t\t\t\tBuf.Store(256 * i, i);\n\t\t\t\ti *= index.y;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tresult += Buf.Load(16 * i);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tresult += Buf.Load(12 * i);\n\t\t}\n\t\tresult += Buf.Load(8 * i);\n\t\ti++;\n\t}\n\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-continue.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\tfor (uint i = 0; i < index.x; i++)\n\t{\n\t\t[branch]\n\t\tif (Buf.Load(4 * i) == 40)\n\t\t{\n\t\t\t[branch]\n\t\t\tif (i == 10)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tresult += Buf.Load(16 * i);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tresult += Buf.Load(12 * i);\n\t\t}\n\t\tresult += Buf.Load(8 * i);\n\t}\n\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-inside-infinite-loop-2.frag",
    "content": "StructuredBuffer<uint> RO : register(t0);\nRWStructuredBuffer<uint> RW : register(u0);\n\nvoid inc(inout uint v)\n{\n\tuint ov;\n\tInterlockedAdd(RW[0], v, v);\n\tv = ov;\n}\n\nfloat4 inner_main(uint4 v)\n{\n\tfor (;;)\n\t{\n\t\tinc(v.x);\n\t\tfor (int i = 0; i < v.y; i++)\n\t\t{\n\t\t\tif (v.x & 3)\n\t\t\t\treturn float4(v);\n\t\t\tif (v.x & 7)\n\t\t\t\tbreak;\n\t\t\tinc(v.x);\n\t\t}\n\t\tinc(v.x);\n\t\tv.x++;\n\t}\n\treturn float4(v);\n}\n\nfloat4 main(uint4 v : V) : SV_Target\n{\n\tfloat4 ov;\n\t[branch]\n\tif (v.x < 10)\n\t{\n\t\tov = inner_main(v);\n\t}\n\telse\n\t{\n\t\tov = inner_main(~v);\n\t\t//ov = 0.0.xxxx;\n\t}\n\treturn ov;\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-inside-infinite-loop.frag",
    "content": "StructuredBuffer<uint> RO : register(t0);\nRWStructuredBuffer<uint> RW : register(u0);\n\nvoid inc(inout uint v)\n{\n\tuint ov;\n\tInterlockedAdd(RW[0], v, v);\n\tv = ov;\n}\n\nfloat4 inner_main(uint4 v)\n{\n\tfor (;;)\n\t{\n\t\tinc(v.x);\n\t\tfor (int i = 0; i < v.y; i++)\n\t\t{\n\t\t\tif (v.x & 3)\n\t\t\t\treturn float4(v);\n\t\t\tif (v.x & 7)\n\t\t\t\tbreak;\n\t\t\tinc(v.x);\n\t\t}\n\t\tinc(v.x);\n\t\tv.x++;\n\t}\n\treturn float4(v);\n}\n\nfloat4 main(uint4 v : V) : SV_Target\n{\n\tfloat4 ov;\n\t[branch]\n\tif (v.x < 10)\n\t{\n\t\tov = inner_main(v);\n\t}\n\telse\n\t{\n\t\t//ov = inner_main(~v);\n\t\tov = 0.0.xxxx;\n\t}\n\treturn ov;\n}\n"
  },
  {
    "path": "shaders/control-flow/loop-return.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nuint func(uint3 index)\n{\n\tuint result = 0;\n\tfor (uint i = 0; i < index.x; i++)\n\t{\n\t\tfor (uint j = 0; j < index.y; j++)\n\t\t{\n\t\t\tif (Buf.Load(4 * (i ^ j)) == 100)\n\t\t\t{\n\t\t\t\tresult += Buf.Load(128);\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tresult += Buf.Load(4 * (i * j));\n\t\t}\n\t}\n\n\treturn result;\n}\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result;\n\t[branch]\n\tif (index.x < 100)\n\t\tresult = func(index);\n\telse\n\t\tresult = func(index.zyx);\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/loop.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\t// Simple loop\n\t[loop]\n\tfor (uint i = 0; i < index.z; i++)\n\t\tresult += Buf.Load(4 * i);\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/nested-loop-break-2.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\t// Two level loop, with one break.\n\t[loop]\n\tfor (uint j = 0; j < index.y; j++)\n\t{\n\t\t[loop]\n\t\tfor (uint k = 0; k < index.z; k++)\n\t\t{\n\t\t\tif (Buf.Load(k * 128) == 10)\n\t\t\t{\n\t\t\t\tresult += Buf.Load(8);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tresult += Buf.Load(4 * (j ^ k));\n\t\t}\n\t}\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/nested-loop-break.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\t// Three level loop, with two breaks.\n\t[loop]\n\tfor (uint i = 0; i < index.x; i++)\n\t{\n\t\t[loop]\n\t\tfor (uint j = 0; j < index.y; j++)\n\t\t{\n\t\t\tif (Buf.Load(j * 128) == 10)\n\t\t\t{\n\t\t\t\tresult += Buf.Load(4);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t[loop]\n\t\t\tfor (uint k = 0; k < index.z; k++)\n\t\t\t{\n\t\t\t\tif (Buf.Load(k * 128) == 10)\n\t\t\t\t{\n\t\t\t\t\tresult += Buf.Load(8);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tresult += Buf.Load(4 * (i ^ j ^ k));\n\t\t\t}\n\t\t}\n\t}\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/nested-loop.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint result = 0;\n\n\t// Three level loop.\n\t[loop]\n\tfor (uint i = 0; i < index.x; i++)\n\t{\n\t\t[loop]\n\t\tfor (uint j = 0; j < index.y; j++)\n\t\t{\n\t\t\t[loop]\n\t\t\tfor (uint k = 0; k < index.z; k++)\n\t\t\t{\n\t\t\t\tresult += Buf.Load(4 * (i ^ j ^ k));\n\t\t\t}\n\t\t}\n\t}\n\tBuf.Store(0, result);\n}\n"
  },
  {
    "path": "shaders/control-flow/selection-merge-split-post-domination.frag",
    "content": "float4 main(float4 v : V) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\t[branch]\n\tif (v.x > 0.0)\n\t{\n\t\tres.x = 10.0;\n\t}\n\n\t[branch]\n\tif (v.y > 0.0)\n\t{\n\t\tres.y = 20.0;\n\t\t[branch]\n\t\tif (v.x > 1.0)\n\t\t\tres.y = 10.0;\n\n\t\t[branch]\n\t\tif (v.z > 0.0)\n\t\t{\n\t\t\tres.w = 20.0;\n\t\t}\n\t}\n\n\tres += 10.0;\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/control-flow/switch-continue.frag",
    "content": "float main(int4 i : I) : SV_Target\n{\n\t[loop]\n\tfor (;;)\n\t{\n\t\tswitch (i.x)\n\t\t{\n\t\t\tcase 5:\n\t\t\t\ti.x++;\n\t\t\t\ti = i.yzwx;\n\t\t\t\tcontinue;\n\n\t\t\tcase 7:\n\t\t\t\ti.x += 10;\n\t\t\t\ti = i.yzwx;\n\t\t\t\tcontinue;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\ti = i.yzwx;\n\t\tbreak;\n\t}\n\n\treturn float(i.x + i.y);\n}\n"
  },
  {
    "path": "shaders/control-flow/switch-merge-into-other-merge.comp",
    "content": "RWStructuredBuffer<uint> RW : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 thr : SV_DispatchThreadID)\n{\n\tuint ret = 0;\n\t[loop]\n\tfor (uint i = 0; i < thr.y; i++)\n\t{\n\t\t[branch]\n\t\tif (RW[100] > 20)\n\t\t{\n\t\t\tret = (ret * 3 + 4);\n\t\t\tRW[50] += ret * 80;\n\t\t}\n\n\t\t[branch]\n\t\tswitch (thr.x)\n\t\t{\n\t\tcase 0:\n\t\t\tRW[0] += ret;\n\t\t\tbreak;\n\n\t\tcase 1:\n\t\t\tRW[40] += 2 * ret;\n\t\t\tbreak;\n\n\t\tcase 5:\n\t\t\tRW[60] += 3 * ret;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tRW[100] += 4 * ret;\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\t}\n\tRW[1] = ret;\n}\n"
  },
  {
    "path": "shaders/control-flow/switch-shared-header-with-loop.comp",
    "content": "RWStructuredBuffer<uint> RW : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 thr : SV_DispatchThreadID)\n{\n\tuint ret = 0;\n\t[loop]\n\tfor (uint i = 0; i < thr.y; i++)\n\t{\n\t\t[branch]\n\t\tswitch (thr.x)\n\t\t{\n\t\tcase 0:\n\t\t\tRW[0] += ret;\n\t\t\tbreak;\n\n\t\tcase 1:\n\t\t\tRW[40] += 2 * ret;\n\t\t\tbreak;\n\n\t\tcase 5:\n\t\t\tRW[60] += 3 * ret;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tRW[100] += 4 * ret;\n\t\t\tbreak;\n\t\t}\n\t}\n\tRW[1] = ret;\n}\n"
  },
  {
    "path": "shaders/control-flow/wave-size-dependent-loop-unroll.comp",
    "content": "RWStructuredBuffer<float4> U : register(u0);\n\ngroupshared float4 foo[64];\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint count = 256 / WaveGetLaneCount();\n\tuint i;\n\n\t[unroll]\n\tfor (i = 0; i < count; i++)\n\t\tfoo[i] = float4(0, 1, 2, 3) + float(i) * 4.0;\n\n\tGroupMemoryBarrierWithGroupSync();\n\n\tfor (i = 0; i < count; i++)\n\t\tU[thr] = foo[i];\n\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/acceleration-structure.bindless.descriptor-qa.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS_Plain : register(t3, space0);\nRaytracingAccelerationStructure AS[] : register(t100, space1);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tp.color = float4(1, 2, 3, 4);\n\tTraceRay(AS[10], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Plain, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS[NonUniformResourceIndex(int(p.color.w))], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n}\n\n"
  },
  {
    "path": "shaders/descriptor_qa/acceleration-structure.bindless.descriptor-qa.sm66.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS_Plain : register(t3, space0);\nRaytracingAccelerationStructure AS[] : register(t100, space1);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tp.color = float4(1, 2, 3, 4);\n\tTraceRay(AS[10], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Plain, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS[NonUniformResourceIndex(int(p.color.w))], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n}\n\n"
  },
  {
    "path": "shaders/descriptor_qa/acceleration-structure.bindless.ssbo-rtas.local-root-signature.descriptor-qa.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS_Plain : register(t3, space1);\nRaytracingAccelerationStructure AS[] : register(t100, space1);\nRaytracingAccelerationStructure AS_Local[] : register(t3, space15);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tp.color = float4(1, 2, 3, 4);\n\tTraceRay(AS[10], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Plain, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS[NonUniformResourceIndex(int(p.color.w))], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Local[200], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n}\n\n"
  },
  {
    "path": "shaders/descriptor_qa/descriptor_qa.bindless.cbv-as-ssbo.descriptor-qa.comp",
    "content": "struct C { float v; };\nConstantBuffer<C> c : register(b0, space0);\nConstantBuffer<C> carr[2] : register(b1, space0);\n\nTexture2D<float> tex : register(t0, space0);\nTexture2D<float> texarr[2] : register(t1, space0);\nBuffer<float> typedbuf : register(t3, space0);\nBuffer<float> typedbufarr[2] : register(t4, space0);\nStructuredBuffer<float> buf : register(t6, space0);\nStructuredBuffer<float> bufarr[2] : register(t7, space0);\nByteAddressBuffer rawbuf : register(t9, space0);\nByteAddressBuffer rawbufarr[2] : register(t10, space0);\n\nRWStructuredBuffer<float> rwbuf : register(u0, space0);\nRWStructuredBuffer<float> rwbufarr[2] : register(u1, space0);\nRWByteAddressBuffer rwrawbuf : register(u3, space0);\nRWByteAddressBuffer rwrawbufarr[2] : register(u4, space0);\nRWTexture2D<float> rwtex : register(u6, space0);\nRWTexture2D<float> rwtexarr[2] : register(u7, space0);\nRWBuffer<float> rwtypedbuf : register(u9, space0);\nRWBuffer<float> rwtypedbufarr[2] : register(u10, space0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tfloat value = 0.0;\n\tif (index > 2)\n\t\tvalue += c.v;\n\tif (index > 3)\n\t\tvalue += carr[index].v;\n\tif (index > 4)\n\t\tvalue += tex[int2(index, 0)];\n\tif (index > 5)\n\t\tvalue += texarr[index & 1][int2(0, index)];\n\tif (index > 6)\n\t\tvalue += typedbuf[index];\n\tif (index > 7)\n\t\tvalue += typedbufarr[index & 1][index];\n\tif (index > 8)\n\t\tvalue += buf[index];\n\tif (index > 9)\n\t\tvalue += bufarr[index & 1][index];\n\tif (index > 10)\n\t\tvalue += asfloat(rawbuf.Load(4 * index));\n\tif (index > 11)\n\t\tvalue += asfloat(rawbufarr[index & 1].Load(index));\n\n\tif (index > 1)\n\t\trwbuf[index] = value;\n\tif (index > 30)\n\t\trwbufarr[index & 1][index] = value;\n\tif (index > 40)\n\t\trwrawbuf.Store(4 * index, asuint(value));\n\tif (index > 50)\n\t\trwrawbufarr[index & 1].Store(4 * index, asuint(value));\n\tif (index > 80)\n\t\trwtex[int2(index, 0)] = value;\n\tif (index > 90)\n\t\trwtexarr[index & 1][int2(0, index)] = value;\n\n\trwbuf.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/descriptor_qa.bindless.descriptor-qa.comp",
    "content": "struct C { float v; };\nConstantBuffer<C> c : register(b0, space0);\nConstantBuffer<C> carr[2] : register(b1, space0);\n\nTexture2D<float> tex : register(t0, space0);\nTexture2D<float> texarr[2] : register(t1, space0);\nBuffer<float> typedbuf : register(t3, space0);\nBuffer<float> typedbufarr[2] : register(t4, space0);\nStructuredBuffer<float> buf : register(t6, space0);\nStructuredBuffer<float> bufarr[2] : register(t7, space0);\nByteAddressBuffer rawbuf : register(t9, space0);\nByteAddressBuffer rawbufarr[2] : register(t10, space0);\n\nRWStructuredBuffer<float> rwbuf : register(u0, space0);\nRWStructuredBuffer<float> rwbufarr[2] : register(u1, space0);\nRWByteAddressBuffer rwrawbuf : register(u3, space0);\nRWByteAddressBuffer rwrawbufarr[2] : register(u4, space0);\nRWTexture2D<float> rwtex : register(u6, space0);\nRWTexture2D<float> rwtexarr[2] : register(u7, space0);\nRWBuffer<float> rwtypedbuf : register(u9, space0);\nRWBuffer<float> rwtypedbufarr[2] : register(u10, space0);\n\nSamplerState samp : register(s0, space0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tfloat value = 0.0;\n\tif (index > 2)\n\t\tvalue += c.v;\n\tif (index > 3)\n\t\tvalue += carr[index].v;\n\tif (index > 4)\n\t\tvalue += tex.SampleLevel(samp, float2(0.5, 0.5), 0.0);\n\tif (index > 5)\n\t\tvalue += texarr[index & 1][int2(0, index)];\n\tif (index > 6)\n\t\tvalue += typedbuf[index];\n\tif (index > 7)\n\t\tvalue += typedbufarr[index & 1][index];\n\tif (index > 8)\n\t\tvalue += buf[index];\n\tif (index > 9)\n\t\tvalue += bufarr[index & 1][index];\n\tif (index > 10)\n\t\tvalue += asfloat(rawbuf.Load(4 * index));\n\tif (index > 11)\n\t\tvalue += asfloat(rawbufarr[index & 1].Load(index));\n\n\tif (index > 1)\n\t\trwbuf[index] = value;\n\tif (index > 30)\n\t\trwbufarr[index & 1][index] = value;\n\tif (index > 40)\n\t\trwrawbuf.Store(4 * index, asuint(value));\n\tif (index > 50)\n\t\trwrawbufarr[index & 1].Store(4 * index, asuint(value));\n\tif (index > 80)\n\t\trwtex[int2(index, 0)] = value;\n\tif (index > 90)\n\t\trwtexarr[index & 1][int2(0, index)] = value;\n\n\trwbuf.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/descriptor_qa.bindless.descriptor-qa.sm66.comp",
    "content": "struct C { float v; };\nConstantBuffer<C> c : register(b0, space0);\nConstantBuffer<C> carr[2] : register(b1, space0);\n\nTexture2D<float> tex : register(t0, space0);\nTexture2D<float> texarr[2] : register(t1, space0);\nBuffer<float> typedbuf : register(t3, space0);\nBuffer<float> typedbufarr[2] : register(t4, space0);\nStructuredBuffer<float> buf : register(t6, space0);\nStructuredBuffer<float> bufarr[2] : register(t7, space0);\nByteAddressBuffer rawbuf : register(t9, space0);\nByteAddressBuffer rawbufarr[2] : register(t10, space0);\n\nRWStructuredBuffer<float> rwbuf : register(u0, space0);\nRWStructuredBuffer<float> rwbufarr[2] : register(u1, space0);\nRWByteAddressBuffer rwrawbuf : register(u3, space0);\nRWByteAddressBuffer rwrawbufarr[2] : register(u4, space0);\nRWTexture2D<float> rwtex : register(u6, space0);\nRWTexture2D<float> rwtexarr[2] : register(u7, space0);\nRWBuffer<float> rwtypedbuf : register(u9, space0);\nRWBuffer<float> rwtypedbufarr[2] : register(u10, space0);\n\nSamplerState samp : register(s0, space0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tfloat value = 0.0;\n\tif ((index & 3423432) > 2)\n\t\tvalue += c.v;\n\tif ((index & 234234) > 3)\n\t\tvalue += carr[index].v;\n\tif ((index & 236234) > 4)\n\t\tvalue += tex.SampleLevel(samp, float2(0.5, 0.5), 0.0);\n\tif ((index & 34234) > 5)\n\t\tvalue += texarr[index & 1][int2(0, index)];\n\tif ((index & 234) > 6)\n\t\tvalue += typedbuf[index];\n\tif ((index & 22) > 7)\n\t\tvalue += typedbufarr[index & 1][index];\n\tif ((index & 9234234) > 8)\n\t\tvalue += buf[index];\n\tif ((index & 2342342) > 9)\n\t\tvalue += bufarr[index & 1][index];\n\tif ((index & 234234324) > 10)\n\t\tvalue += asfloat(rawbuf.Load(4 * index));\n\tif ((index & 234234233) > 11)\n\t\tvalue += asfloat(rawbufarr[index & 1].Load(index));\n\n\tif ((index & 234884) > 1)\n\t\trwbuf[index] = value;\n\tif ((index & 9999) > 30)\n\t\trwbufarr[index & 1][index] = value;\n\tif ((index & 8888) > 40)\n\t\trwrawbuf.Store(4 * index, asuint(value));\n\tif ((index & 7777) > 50)\n\t\trwrawbufarr[index & 1].Store(4 * index, asuint(value));\n\tif ((index & 5555) > 80)\n\t\trwtex[int2(index, 0)] = value;\n\tif ((index & 34234) > 90)\n\t\trwtexarr[index & 1][int2(0, index)] = value;\n\n\trwbuf.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/descriptor_qa.bindless.ssbo.descriptor-qa.comp",
    "content": "struct C { float v; };\nConstantBuffer<C> c : register(b0, space0);\nConstantBuffer<C> carr[2] : register(b1, space0);\n\nTexture2D<float> tex : register(t0, space0);\nTexture2D<float> texarr[2] : register(t1, space0);\nBuffer<float> typedbuf : register(t3, space0);\nBuffer<float> typedbufarr[2] : register(t4, space0);\nStructuredBuffer<float> buf : register(t6, space0);\nStructuredBuffer<float> bufarr[2] : register(t7, space0);\nByteAddressBuffer rawbuf : register(t9, space0);\nByteAddressBuffer rawbufarr[2] : register(t10, space0);\n\nRWStructuredBuffer<float> rwbuf : register(u0, space0);\nRWStructuredBuffer<float> rwbufarr[2] : register(u1, space0);\nRWByteAddressBuffer rwrawbuf : register(u3, space0);\nRWByteAddressBuffer rwrawbufarr[2] : register(u4, space0);\nRWTexture2D<float> rwtex : register(u6, space0);\nRWTexture2D<float> rwtexarr[2] : register(u7, space0);\nRWBuffer<float> rwtypedbuf : register(u9, space0);\nRWBuffer<float> rwtypedbufarr[2] : register(u10, space0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tfloat value = 0.0;\n\tif (index > 2)\n\t\tvalue += c.v;\n\tif (index > 3)\n\t\tvalue += carr[index].v;\n\tif (index > 4)\n\t\tvalue += tex[int2(index, 0)];\n\tif (index > 5)\n\t\tvalue += texarr[index & 1][int2(0, index)];\n\tif (index > 6)\n\t\tvalue += typedbuf[index];\n\tif (index > 7)\n\t\tvalue += typedbufarr[index & 1][index];\n\tif (index > 8)\n\t\tvalue += buf[index];\n\tif (index > 9)\n\t\tvalue += bufarr[index & 1][index];\n\tif (index > 10)\n\t\tvalue += asfloat(rawbuf.Load(4 * index));\n\tif (index > 11)\n\t\tvalue += asfloat(rawbufarr[index & 1].Load(index));\n\n\tif (index > 1)\n\t\trwbuf[index] = value;\n\tif (index > 30)\n\t\trwbufarr[index & 1][index] = value;\n\tif (index > 40)\n\t\trwrawbuf.Store(4 * index, asuint(value));\n\tif (index > 50)\n\t\trwrawbufarr[index & 1].Store(4 * index, asuint(value));\n\tif (index > 80)\n\t\trwtex[int2(index, 0)] = value;\n\tif (index > 90)\n\t\trwtexarr[index & 1][int2(0, index)] = value;\n\n\trwbuf.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/early-2.bindless.descriptor-qa.frag",
    "content": "Texture2D<float4> T : register(t0);\nSamplerState S : register(s0);\n\nfloat4 main(float2 uv : UV) : SV_Target\n{\n\tif (uv.x < 0.0)\n\t\tdiscard;\n\treturn T.Sample(S, uv);\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/early-3.bindless.descriptor-qa.frag",
    "content": "Texture2D<float4> T : register(t0);\nSamplerState S : register(s0);\n\nstruct Out { float4 col : SV_Target; float d : SV_Depth; };\n\nOut main(float2 uv : UV)\n{\n\tOut o;\n\to.col = T.Sample(S, uv);\n\to.d = 0.5;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/early-4.bindless.descriptor-qa.frag",
    "content": "Texture2D<float4> T : register(t0);\nSamplerState S : register(s0);\n\nstruct Out { float4 col : SV_Target; uint d : SV_Coverage; };\n\nOut main(float2 uv : UV)\n{\n\tOut o;\n\to.col = T.Sample(S, uv);\n\to.d = 3;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/early-5.bindless.descriptor-qa.frag",
    "content": "Texture2D<float4> T : register(t0);\nSamplerState S : register(s0);\nRWTexture2D<float4> U : register(u0);\n\nfloat4 main(float2 uv : UV) : SV_Target\n{\n\tif (uv.x < 0.0)\n\t\tU[int2(uv)] = 2.0.xxxx;\n\treturn T.Sample(S, uv);\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/early-heap.descriptor-qa.sm66.frag",
    "content": "float4 main(uint index : INDEX, float2 uv : UV) : SV_Target\n{\n\tTexture2D<float4> T = ResourceDescriptorHeap[index];\n\treturn T.Load(int3(uv, 0));\n}\n"
  },
  {
    "path": "shaders/descriptor_qa/early.bindless.descriptor-qa.frag",
    "content": "Texture2D<float4> T : register(t0);\nSamplerState S : register(s0);\n\nfloat4 main(float2 uv : UV) : SV_Target\n{\n\treturn T.Sample(S, uv);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/accept-hit-and-end-search-ignore-hit.rany",
    "content": "struct Payload\n{\n\tfloat p;\n};\n\nstruct Hit\n{\n\tfloat2 attr;\n};\n\n[shader(\"anyhit\")]\nvoid RayAny(inout Payload payload, in Hit attr)\n{\n\tif (attr.attr.x > 10.0)\n\t{\n\t\tpayload.p = 10.0;\n\t\tAcceptHitAndEndSearch();\n\t}\n\telse\n\t{\n\t\tIgnoreHit();\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/acos.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn acos(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/asin.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn asin(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atan.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn atan(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atomic-bin-op.bindless.root-constant.frag",
    "content": "RWTexture2D<uint> RWTex2D[] : register(u2);\n\nuint main(nointerpolation uint index : INDEX, nointerpolation uint3 coord : TEXCOORD) : SV_Target\n{\n\tuint output;\n\tuint res = 0;\n\tInterlockedAdd(RWTex2D[NonUniformResourceIndex(index)][coord.xy], 3, output);\n\tres += output;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atomic-bin-op.frag",
    "content": "RWTexture1D<uint> RWTex1D : register(u0);\nRWTexture1DArray<uint> RWTex1DArray : register(u1);\nRWTexture2D<uint> RWTex2D : register(u2);\nRWTexture2DArray<uint> RWTex2DArray : register(u3);\nRWTexture3D<uint> RWTex3D : register(u4);\nRWBuffer<uint> RWBuf : register(u5);\n\nRWTexture1D<int> RWTex1DSigned : register(u0, space1);\nRWTexture2D<int> RWTex2DSigned : register(u2, space1);\n\nstruct Composite\n{\n\tint a, b, c, d;\n};\n\nRWStructuredBuffer<Composite> RWStructured : register(u6);\nRWByteAddressBuffer Raw : register(u7);\n\nuint main(nointerpolation uint3 coord : TEXCOORD) : SV_Target\n{\n\tuint res = 0;\n\tuint output;\n\tint output_signed;\n\n\tInterlockedAdd(RWTex1D[coord.x], 1, output);\n\tres += output;\n\n\tInterlockedAnd(RWTex1DArray[coord.xy], 2, output);\n\tres += output;\n\n\tInterlockedExchange(RWTex2D[coord.xy], 3, output);\n\tres += output;\n\n\tInterlockedMax(RWTex2DArray[coord.xyz], 4, output);\n\tres += output;\n\n\tInterlockedMin(RWTex3D[coord.xyz], 5, output);\n\tres += output;\n\n\tInterlockedOr(RWBuf[coord.x], 6, output);\n\tres += output;\n\n\tInterlockedXor(RWBuf[coord.x], 7, output);\n\tres += output;\n\n\tInterlockedMin(RWTex1DSigned[coord.x], 8, output_signed);\n\tres += output_signed;\n\n\tInterlockedMax(RWTex2DSigned[coord.xy], 9, output_signed);\n\tres += output_signed;\n\n\tInterlockedAdd(RWStructured[coord.x].c, 10, output_signed);\n\tres += output_signed;\n\n\tRaw.InterlockedMax(coord.x * 4, 12, output_signed);\n\tres += output_signed;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atomic-bin-op.root-descriptor.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint res;\n\tBuf.InterlockedAdd(thr * 16, 1, res);\n\tBuf.InterlockedAdd(thr * 16 + 4, 2, res);\n\tBuf.InterlockedAdd(thr * 16 + 2, 3, res);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atomic-bin-op.ssbo.frag",
    "content": "RWTexture1D<uint> RWTex1D : register(u0);\nRWTexture1DArray<uint> RWTex1DArray : register(u1);\nRWTexture2D<uint> RWTex2D : register(u2);\nRWTexture2DArray<uint> RWTex2DArray : register(u3);\nRWTexture3D<uint> RWTex3D : register(u4);\nRWBuffer<uint> RWBuf : register(u5);\n\nRWTexture1D<int> RWTex1DSigned : register(u0, space1);\nRWTexture2D<int> RWTex2DSigned : register(u2, space1);\n\nstruct Composite\n{\n\tint a, b, c, d;\n};\n\nRWStructuredBuffer<Composite> RWStructured : register(u6);\nRWByteAddressBuffer Raw : register(u7);\n\nuint main(nointerpolation uint3 coord : TEXCOORD) : SV_Target\n{\n\tuint res = 0;\n\tuint output;\n\tint output_signed;\n\n\tInterlockedAdd(RWTex1D[coord.x], 1, output);\n\tres += output;\n\n\tInterlockedAnd(RWTex1DArray[coord.xy], 2, output);\n\tres += output;\n\n\tInterlockedExchange(RWTex2D[coord.xy], 3, output);\n\tres += output;\n\n\tInterlockedMax(RWTex2DArray[coord.xyz], 4, output);\n\tres += output;\n\n\tInterlockedMin(RWTex3D[coord.xyz], 5, output);\n\tres += output;\n\n\tInterlockedOr(RWBuf[coord.x], 6, output);\n\tres += output;\n\n\tInterlockedXor(RWBuf[coord.x], 7, output);\n\tres += output;\n\n\tInterlockedMin(RWTex1DSigned[coord.x], 8, output_signed);\n\tres += output_signed;\n\n\tInterlockedMax(RWTex2DSigned[coord.xy], 9, output_signed);\n\tres += output_signed;\n\n\tInterlockedAdd(RWStructured[coord.x].c, 10, output_signed);\n\tres += output_signed;\n\n\tRaw.InterlockedMax(coord.x * 4, 12, output_signed);\n\tres += output_signed;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atomic-compare-exchange.frag",
    "content": "RWTexture1D<uint> RWTex1D : register(u0);\nRWTexture1DArray<uint> RWTex1DArray : register(u1);\nRWTexture2D<uint> RWTex2D : register(u2);\nRWTexture2DArray<uint> RWTex2DArray : register(u3);\nRWTexture3D<uint> RWTex3D : register(u4);\nRWBuffer<uint> RWBuf : register(u5);\n\nRWTexture1D<int> RWTex1DSigned : register(u0, space1);\nRWTexture2D<int> RWTex2DSigned : register(u2, space1);\n\nstruct Composite\n{\n\tint a, b, c, d;\n};\n\nRWStructuredBuffer<Composite> RWStructured : register(u6);\nRWByteAddressBuffer Raw : register(u7);\n\nuint main(nointerpolation uint3 coord : TEXCOORD) : SV_Target\n{\n\tuint res = 0;\n\tuint compare_value = 20;\n\tuint value = 30;\n\tuint output;\n\n\tInterlockedCompareExchange(RWTex1D[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex1DArray[coord.xy], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex2D[coord.xy], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex2DArray[coord.xyz], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex3D[coord.xyz], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWBuf[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWBuf[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex1DSigned[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex2DSigned[coord.xy], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWStructured[coord.x].c, compare_value, value, output);\n\tres += output;\n\n\tRaw.InterlockedCompareExchange(coord.x * 4, compare_value, value, output);\n\tres += output;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atomic-compare-exchange.root-descriptor.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint res;\n\tBuf.InterlockedCompareExchange(thr * 4, 1, 2, res);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/atomic-compare-exchange.ssbo.frag",
    "content": "RWTexture1D<uint> RWTex1D : register(u0);\nRWTexture1DArray<uint> RWTex1DArray : register(u1);\nRWTexture2D<uint> RWTex2D : register(u2);\nRWTexture2DArray<uint> RWTex2DArray : register(u3);\nRWTexture3D<uint> RWTex3D : register(u4);\nRWBuffer<uint> RWBuf : register(u5);\n\nRWTexture1D<int> RWTex1DSigned : register(u0, space1);\nRWTexture2D<int> RWTex2DSigned : register(u2, space1);\n\nstruct Composite\n{\n\tint a, b, c, d;\n};\n\nRWStructuredBuffer<Composite> RWStructured : register(u6);\nRWByteAddressBuffer Raw : register(u7);\n\nuint main(nointerpolation uint3 coord : TEXCOORD) : SV_Target\n{\n\tuint res = 0;\n\tuint compare_value = 20;\n\tuint value = 30;\n\tuint output;\n\n\tInterlockedCompareExchange(RWTex1D[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex1DArray[coord.xy], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex2D[coord.xy], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex2DArray[coord.xyz], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex3D[coord.xyz], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWBuf[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWBuf[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex1DSigned[coord.x], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWTex2DSigned[coord.xy], compare_value, value, output);\n\tres += output;\n\n\tInterlockedCompareExchange(RWStructured[coord.x].c, compare_value, value, output);\n\tres += output;\n\n\tRaw.InterlockedCompareExchange(coord.x * 4, compare_value, value, output);\n\tres += output;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/attributes.denorm-ftz.comp",
    "content": "StructuredBuffer<float> A;\nRWStructuredBuffer<float> B;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tB[thr] = 2.0 * A[thr];\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/attributes.denorm-preserve.comp",
    "content": "StructuredBuffer<float> A;\nRWStructuredBuffer<float> B;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tB[thr] = 2.0 * A[thr];\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/barrier.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(7, 8, 9)]\nvoid main()\n{\n\tBuf.Store(0, 5u);\n\tGroupMemoryBarrier();\n\tBuf.Store(0, 10u);\n\tAllMemoryBarrier();\n\tBuf.Store(0, 15u);\n\tGroupMemoryBarrierWithGroupSync();\n\tBuf.Store(0, 20u);\n\tAllMemoryBarrierWithGroupSync();\n\tBuf.Store(0, 30u);\n\tDeviceMemoryBarrier();\n\tBuf.Store(0, 40u);\n\tDeviceMemoryBarrierWithGroupSync();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/barycentrics-2.frag",
    "content": "float main(\n\t\tnointerpolation float attrib0 : ATTRIB,\n\t\tnointerpolation float attrib1 : ATTRIB1,\n\t\tnointerpolation float attrib2 : ATTRIB2,\n\t\tsample float3 bary : SV_Barycentrics,\n\t\tcentroid float foo : FOO) : SV_Target\n{\n\tfloat result = 0.0;\n\tresult += GetAttributeAtVertex(attrib0, 0) * bary.x;\n\tresult += GetAttributeAtVertex(attrib1, 1) * bary.y;\n\tresult += GetAttributeAtVertex(attrib2, 2) * bary.z;\n\tresult += foo;\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/barycentrics.frag",
    "content": "float4 main(\n\t\tnointerpolation float4 attrib : ATTRIB, nointerpolation float4 attrib2[2] : ATTRIB2,\n\t\tfloat3 bary : SV_Barycentrics, centroid noperspective float3 bary2 : SV_Barycentrics1, nointerpolation uint index : INDEX) : SV_Target\n{\n\tfloat4 result = float4(bary.xy, bary2.yx);\n\tresult += GetAttributeAtVertex(attrib, 0) * bary.x;\n\tresult += GetAttributeAtVertex(attrib, 1) * bary.y;\n\tresult += GetAttributeAtVertex(attrib2[index], 0) * bary.z;\n\tresult += GetAttributeAtVertex(attrib2[0], 1) * bary2.x;\n\tresult += GetAttributeAtVertex(attrib2[0], 2) * bary2.y;\n\tresult += GetAttributeAtVertex(attrib2[1], 0) * bary2.x;\n\tresult += GetAttributeAtVertex(attrib2[1], 1) * bary2.y;\n\tresult += attrib;\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/bfrev.frag",
    "content": "uint main(uint a : A) : SV_Target\n{\n\treturn reversebits(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/bitcount-bitrev-sizes.ssbo.comp",
    "content": "RWStructuredBuffer<uint64_t> A;\nRWStructuredBuffer<uint16_t> B;\n\n[numthreads(1, 1, 1)]\nvoid main()\n{\n\tA[0] = reversebits(A[0]);\n\tB[0] = reversebits(B[0]);\n\tA[1] = countbits(A[1]);\n\tB[1] = uint16_t(countbits(B[1]));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-load-feedback.frag",
    "content": "ByteAddressBuffer RawBuf : register(t1);\nRWByteAddressBuffer RWRawBuf : register(u1);\n\nStructuredBuffer<float2> StructuredBuf : register(t2);\nRWStructuredBuffer<float2> RWStructuredBuf : register(u2);\n\nstruct Composite\n{\n\tfloat3 a;\n\tfloat3 b;\n};\n\nStructuredBuffer<Composite> StructuredBufComposite : register(t3);\nRWStructuredBuffer<Composite> RWStructuredBufComposite : register(u3);\n\nfloat2 main(nointerpolation uint index : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tuint feedback;\n\n\tres += asfloat(RawBuf.Load2(index * 8, feedback));\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += asfloat(RWRawBuf.Load2(index * 8, feedback));\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += StructuredBuf.Load(index, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += RWStructuredBuf.Load(index, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-load-signed-feedback.frag",
    "content": "Buffer<int2> TypedBuf : register(t0);\nRWBuffer<int2> RWTypedBuf : register(u0);\n\nint2 main(nointerpolation uint index : TEXCOORD) : SV_Target\n{\n\tint2 res = int2(0, 0);\n\tuint feedback;\n\tres += TypedBuf.Load(index, feedback).xy;\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += RWTypedBuf.Load(index, feedback).xy;\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-load-signed.frag",
    "content": "Buffer<int2> TypedBuf : register(t0);\nRWBuffer<int2> RWTypedBuf : register(u0);\n\nint2 main(nointerpolation uint index : TEXCOORD) : SV_Target\n{\n\tint2 res = int2(0, 0);\n\tres += TypedBuf.Load(index).xy;\n\tres += RWTypedBuf.Load(index).xy;\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-load.frag",
    "content": "Buffer<float2> TypedBuf : register(t0);\nRWBuffer<float2> RWTypedBuf : register(u0);\n\nByteAddressBuffer RawBuf : register(t1);\nRWByteAddressBuffer RWRawBuf : register(u1);\n\nStructuredBuffer<float2> StructuredBuf : register(t2);\nRWStructuredBuffer<float2> RWStructuredBuf : register(u2);\n\nstruct Composite\n{\n\tfloat3 a;\n\tfloat3 b;\n};\n\nStructuredBuffer<Composite> StructuredBufComposite : register(t3);\nRWStructuredBuffer<Composite> RWStructuredBufComposite : register(u3);\n\nfloat2 main(nointerpolation uint index : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += TypedBuf.Load(index).xy;\n\tres += RWTypedBuf.Load(index).xy;\n\tres += asfloat(RawBuf.Load2(index * 8));\n\tres += asfloat(RWRawBuf.Load2(index * 8));\n\tres += StructuredBuf[index];\n\tres += RWStructuredBuf[index];\n\tres += StructuredBufComposite[index].a.yz;\n\tres += RWStructuredBufComposite[index].b.yz;\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-load.ssbo.frag",
    "content": "Buffer<float2> TypedBuf : register(t0);\nRWBuffer<float2> RWTypedBuf : register(u0);\n\nByteAddressBuffer RawBuf : register(t1);\nRWByteAddressBuffer RWRawBuf : register(u1);\n\nStructuredBuffer<float2> StructuredBuf : register(t2);\nRWStructuredBuffer<float2> RWStructuredBuf : register(u2);\n\nstruct Composite\n{\n\tfloat3 a;\n\tfloat3 b;\n};\n\nStructuredBuffer<Composite> StructuredBufComposite : register(t3);\nRWStructuredBuffer<Composite> RWStructuredBufComposite : register(u3);\n\nfloat2 main(nointerpolation uint index : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += TypedBuf.Load(index).xy;\n\tres += RWTypedBuf.Load(index).xy;\n\tres += asfloat(RawBuf.Load2(index * 8));\n\tres += asfloat(RWRawBuf.Load2(index * 8));\n\tres += StructuredBuf[index];\n\tres += RWStructuredBuf[index];\n\tres += StructuredBufComposite[index].a.yz;\n\tres += RWStructuredBufComposite[index].b.yz;\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-store-signed.frag",
    "content": "RWBuffer<int2> RWBuf : register(u0);\n\nvoid main(nointerpolation uint index : INDEX, nointerpolation int2 data : DATA)\n{\n\tRWBuf[index] = data;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-store.frag",
    "content": "RWBuffer<float2> RWBuf : register(u0);\nRWByteAddressBuffer RWRawBuf : register(u1);\nRWStructuredBuffer<float2> RWStructuredBuf : register(u2);\n\nstruct Composite\n{\n\tfloat3 a;\n\tfloat2 b;\n};\nRWStructuredBuffer<Composite> RWStructuredBufComposite : register(u3);\n\nvoid main(nointerpolation uint index : INDEX, nointerpolation float2 data : DATA)\n{\n\tRWBuf[index] = data;\n\tRWRawBuf.Store2(8 * index, asuint(data));\n\tRWStructuredBuf[index] = data;\n\tRWStructuredBufComposite[index].b = data;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-store.ssbo.frag",
    "content": "RWBuffer<float2> RWBuf : register(u0);\nRWByteAddressBuffer RWRawBuf : register(u1);\nRWStructuredBuffer<float2> RWStructuredBuf : register(u2);\n\nstruct Composite\n{\n\tfloat3 a;\n\tfloat2 b;\n};\nRWStructuredBuffer<Composite> RWStructuredBufComposite : register(u3);\n\nvoid main(nointerpolation uint index : INDEX, nointerpolation float2 data : DATA)\n{\n\tRWBuf[index] = data;\n\tRWRawBuf.Store2(8 * index, asuint(data));\n\tRWStructuredBuf[index] = data;\n\tRWStructuredBufComposite[index].b = data;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/buffer-update-counter.frag",
    "content": "RWStructuredBuffer<float2> RWStructuredBuf : register(u0);\nRWStructuredBuffer<float2> RWStructuredBuf2 : register(u1);\n\nuint main() : SV_Target\n{\n\tuint v = RWStructuredBuf.IncrementCounter();\n\tv += RWStructuredBuf2.DecrementCounter();\n\treturn v;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/calculate-lod.frag",
    "content": "Texture1D<float> Tex1D : register(t0);\nTexture1DArray<float> Tex1DArray : register(t1);\nTexture2D<float> Tex2D : register(t2);\nTexture2DArray<float> Tex2DArray : register(t3);\nTexture3D<float> Tex3D : register(t4);\nTextureCube<float> TexCube : register(t5);\nTextureCubeArray<float> TexCubeArray : register(t6);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float3 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres.x += Tex1D.CalculateLevelOfDetail(Samp, UV.x);\n\tres.x += Tex1DArray.CalculateLevelOfDetail(Samp, UV.x);\n\tres.x += Tex2D.CalculateLevelOfDetail(Samp, UV.xy);\n\tres.x += Tex2DArray.CalculateLevelOfDetail(Samp, UV.xy);\n\tres.x += Tex3D.CalculateLevelOfDetail(Samp, UV.xyz);\n\tres.x += TexCube.CalculateLevelOfDetail(Samp, UV.xyz);\n\tres.x += TexCubeArray.CalculateLevelOfDetail(Samp, UV.xyz);\n\n\tres.y += Tex1D.CalculateLevelOfDetailUnclamped(Samp, UV.x);\n\tres.y += Tex1DArray.CalculateLevelOfDetailUnclamped(Samp, UV.x);\n\tres.y += Tex2D.CalculateLevelOfDetailUnclamped(Samp, UV.xy);\n\tres.y += Tex2DArray.CalculateLevelOfDetailUnclamped(Samp, UV.xy);\n\tres.y += Tex3D.CalculateLevelOfDetailUnclamped(Samp, UV.xyz);\n\tres.y += TexCube.CalculateLevelOfDetailUnclamped(Samp, UV.xyz);\n\tres.y += TexCubeArray.CalculateLevelOfDetailUnclamped(Samp, UV.xyz);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/call-shader.rgen",
    "content": "struct Payload0\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat4 color;\n};\n\nstruct Payload2\n{\n\tfloat4 color;\n};\n\nstruct Payload3\n{\n\tfloat4 color;\n};\n\nRWTexture2D<float4> IMG : register(u0);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tPayload0 p0;\n\tPayload1 p1;\n\tPayload2 p2;\n\tPayload3 p3;\n\tCallShader(0, p0);\n\tCallShader(1, p1);\n\tCallShader(2, p2);\n\tCallShader(3, p3);\n\n\tIMG[DispatchRaysIndex().xy] = p0.color + p1.color + p2.color + p3.color;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/clip.demote-to-helper.frag",
    "content": "void main(float2 UV : TEXCOORD)\n{\n\tclip(UV.x - 10.0);\n\tclip(UV.y - 20.0);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/clip.frag",
    "content": "void main(float2 UV : TEXCOORD)\n{\n\tclip(UV.x - 10.0);\n\tclip(UV.y - 20.0);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/compute-shader-derivatives-cube-array.noderivs.sm66.ssbo.comp",
    "content": "Texture2D<float> T2D;\nTexture2DArray<float> T2DArr;\nTextureCube<float> TCube;\nTextureCubeArray<float> TCubeArr;\nTexture3D<float> T3D;\n\nRWStructuredBuffer<float> O;\n\nSamplerState S;\nSamplerComparisonState SComp;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat4 uv = float4(0.1, 0.2, 0.3, 0.4) * float(thr);\n\tO[thr] += TCubeArr.CalculateLevelOfDetail(S, uv.xyz);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/compute-shader-derivatives-cube.noderivs.sm66.ssbo.comp",
    "content": "Texture2D<float> T2D;\nTexture2DArray<float> T2DArr;\nTextureCube<float> TCube;\nTextureCubeArray<float> TCubeArr;\nTexture3D<float> T3D;\n\nRWStructuredBuffer<float> O;\n\nSamplerState S;\nSamplerComparisonState SComp;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat4 uv = float4(0.1, 0.2, 0.3, 0.4) * float(thr);\n\tO[thr] += TCube.CalculateLevelOfDetail(S, uv.xyz);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/compute-shader-derivatives-single-thread.sm66.ssbo.comp",
    "content": "Texture2D<float> T2D;\nTexture2DArray<float> T2DArr;\nTextureCube<float> TCube;\nTextureCubeArray<float> TCubeArr;\nTexture3D<float> T3D;\n\nRWStructuredBuffer<float> O;\n\nSamplerState S;\nSamplerComparisonState SComp;\n\n// DXC is robust against this, even if it is non-sensical.\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat4 uv = float4(0.1, 0.2, 0.3, 0.4) * float(thr);\n\n\tO[thr] += T2D.Sample(S, uv.xy);\n\tO[thr] += T2DArr.Sample(S, uv.xyz);\n\tO[thr] += TCube.Sample(S, uv.xyz);\n\tO[thr] += TCubeArr.Sample(S, uv);\n\tO[thr] += T3D.Sample(S, uv.xyz);\n\n\t// Delimiter to make things a bit easier to read.\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.SampleBias(S, uv.xy, uv.w);\n\tO[thr] += T2DArr.SampleBias(S, uv.xyz, uv.w);\n\tO[thr] += TCube.SampleBias(S, uv.xyz, uv.w);\n\tO[thr] += TCubeArr.SampleBias(S, uv, uv.w);\n\tO[thr] += T3D.SampleBias(S, uv.xyz, uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.SampleCmp(SComp, uv.xy, uv.w);\n\tO[thr] += T2DArr.SampleCmp(SComp, uv.xyz, uv.w);\n\tO[thr] += TCube.SampleCmp(SComp, uv.xyz, uv.w);\n\tO[thr] += TCubeArr.SampleCmp(SComp, uv, uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += ddx(uv.w);\n\tO[thr] += ddy(uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += ddx_coarse(uv.w);\n\tO[thr] += ddy_coarse(uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += ddx_fine(uv.w);\n\tO[thr] += ddy_fine(uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.CalculateLevelOfDetail(S, uv.xy);\n\tO[thr] += T2DArr.CalculateLevelOfDetail(S, uv.xy);\n\t// Cube derivatives in separate test\n\tO[thr] += T3D.CalculateLevelOfDetail(S, uv.xyz);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.CalculateLevelOfDetailUnclamped(S, uv.xy);\n\tO[thr] += T2DArr.CalculateLevelOfDetailUnclamped(S, uv.xy);\n\tO[thr] += T3D.CalculateLevelOfDetailUnclamped(S, uv.xyz);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/compute-shader-derivatives.noderivs.sm66.ssbo.comp",
    "content": "Texture2D<float> T2D;\nTexture2DArray<float> T2DArr;\nTextureCube<float> TCube;\nTextureCubeArray<float> TCubeArr;\nTexture3D<float> T3D;\n\nRWStructuredBuffer<float> O;\n\nSamplerState S;\nSamplerComparisonState SComp;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat4 uv = float4(0.1, 0.2, 0.3, 0.4) * float(thr);\n\n\tO[thr] += T2D.Sample(S, uv.xy);\n\tO[thr] += T2DArr.Sample(S, uv.xyz);\n\tO[thr] += TCube.Sample(S, uv.xyz);\n\tO[thr] += TCubeArr.Sample(S, uv);\n\tO[thr] += T3D.Sample(S, uv.xyz);\n\n\t// Delimiter to make things a bit easier to read.\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.SampleBias(S, uv.xy, uv.w);\n\tO[thr] += T2DArr.SampleBias(S, uv.xyz, uv.w);\n\tO[thr] += TCube.SampleBias(S, uv.xyz, uv.w);\n\tO[thr] += TCubeArr.SampleBias(S, uv, uv.w);\n\tO[thr] += T3D.SampleBias(S, uv.xyz, uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.SampleCmp(SComp, uv.xy, uv.w);\n\tO[thr] += T2DArr.SampleCmp(SComp, uv.xyz, uv.w);\n\tO[thr] += TCube.SampleCmp(SComp, uv.xyz, uv.w);\n\tO[thr] += TCubeArr.SampleCmp(SComp, uv, uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += ddx(uv.w);\n\tO[thr] += ddy(uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += ddx_coarse(uv.w);\n\tO[thr] += ddy_coarse(uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += ddx_fine(uv.w);\n\tO[thr] += ddy_fine(uv.w);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.CalculateLevelOfDetail(S, uv.xy);\n\tO[thr] += T2DArr.CalculateLevelOfDetail(S, uv.xy);\n\t// Cube derivatives in separate test\n\tO[thr] += T3D.CalculateLevelOfDetail(S, uv.xyz);\n\n\tDeviceMemoryBarrierWithGroupSync();\n\n\tO[thr] += T2D.CalculateLevelOfDetailUnclamped(S, uv.xy);\n\tO[thr] += T2DArr.CalculateLevelOfDetailUnclamped(S, uv.xy);\n\tO[thr] += T3D.CalculateLevelOfDetailUnclamped(S, uv.xyz);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/cos.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn cos(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/countbits.frag",
    "content": "uint main(uint a : A) : SV_Target\n{\n\treturn countbits(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/coverage.frag",
    "content": "uint main(uint index : SV_Coverage) : SV_Target\n{\n\treturn index;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/derivative.frag",
    "content": "float4 main(float2 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 r = 0.0.xxxx;\n\tr.xy += ddx_coarse(UV);\n\tr.zw += ddy_coarse(UV);\n\tr.xy += ddx_fine(UV);\n\tr.zw += ddy_fine(UV);\n\n\thalf2 UV_h = half2(UV);\n\tr.xy += float2(ddx_coarse(UV_h));\n\tr.zw += float2(ddy_coarse(UV_h));\n\tr.xy += float2(ddx_fine(UV_h));\n\tr.zw += float2(ddy_fine(UV_h));\n\n\tdouble2 UV_d = double2(UV);\n\tr.xy += double2(ddx_coarse(UV_d));\n\tr.zw += double2(ddy_coarse(UV_d));\n\tr.xy += double2(ddx_fine(UV_d));\n\tr.zw += double2(ddy_fine(UV_d));\n\n\treturn r;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/derivative.sm60.frag",
    "content": "float4 main(float2 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 r = 0.0.xxxx;\n\tr.xy += ddx_coarse(UV);\n\tr.zw += ddy_coarse(UV);\n\tr.xy += ddx_fine(UV);\n\tr.zw += ddy_fine(UV);\n\n\tmin16float2 UV_h = min16float2(UV);\n\tr.xy += float2(ddx_coarse(UV_h));\n\tr.zw += float2(ddy_coarse(UV_h));\n\tr.xy += float2(ddx_fine(UV_h));\n\tr.zw += float2(ddy_fine(UV_h));\n\n\treturn r;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/derivative.sm60.native-fp16.frag",
    "content": "float4 main(float2 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 r = 0.0.xxxx;\n\tr.xy += ddx_coarse(UV);\n\tr.zw += ddy_coarse(UV);\n\tr.xy += ddx_fine(UV);\n\tr.zw += ddy_fine(UV);\n\n\tmin16float2 UV_h = min16float2(UV);\n\tr.xy += float2(ddx_coarse(UV_h));\n\tr.zw += float2(ddy_coarse(UV_h));\n\tr.xy += float2(ddx_fine(UV_h));\n\tr.zw += float2(ddy_fine(UV_h));\n\n\treturn r;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/derivatives.sm66.comp",
    "content": "RWTexture3D<float4> RW;\nSamplerState S;\nTexture3D<float4> TEX;\n\n[numthreads(4, 4, 4)]\nvoid main(uint3 thr : SV_DispatchThreadID, uint3 gthr : SV_GroupThreadID)\n{\n\tfloat3 uvw = (float3(thr) + 0.5) / 64.0;\n\tfloat4 result = TEX.Sample(S, uvw);\n\tRW[thr] = result;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/discard.demote-to-helper.frag",
    "content": "void main(float2 UV : TEXCOORD)\n{\n\tif (UV.x > 10.0)\n\t\tdiscard;\n\telse if (UV.y > 20.0)\n\t\tdiscard;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/discard.frag",
    "content": "void main(float2 UV : TEXCOORD)\n{\n\tif (UV.x > 10.0)\n\t\tdiscard;\n\telse if (UV.y > 20.0)\n\t\tdiscard;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/dispatch-rays-dimensions.rgen",
    "content": "RWTexture2D<uint3> UTex : register(u0);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tUTex[DispatchRaysDimensions().xy] = uint3(1, 2, 3);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/dispatch-rays-index.rgen",
    "content": "RWTexture2D<uint3> UTex : register(u0);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tUTex[DispatchRaysIndex().xy] = uint3(1, 2, 3);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/dot2.frag",
    "content": "float main(float2 a : A, float2 b : B) : SV_Target\n{\n\treturn dot(a, b);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/dot3.frag",
    "content": "float main(float3 a : A, float3 b : B) : SV_Target\n{\n\treturn dot(a, b);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/dot4.frag",
    "content": "float main(float4 a : A, float4 b : B) : SV_Target\n{\n\treturn dot(a, b);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/eval-centroid.frag",
    "content": "float2 main(float2 UV[2] : TEXCOORD, float uv0 : UV0, float uv1[2] : UV1, uint a : A, uint b : B) : SV_Target\n{\n\tfloat2 res0 = EvaluateAttributeCentroid(UV[a]);\n\tfloat2 res1 = EvaluateAttributeCentroid(UV[b]);\n\treturn res0 + res1 + EvaluateAttributeCentroid(uv0) + EvaluateAttributeCentroid(uv1[a]);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/eval-sample-index.frag",
    "content": "float2 main(float2 UV : TEXCOORD, nointerpolation int sample : SAMPLE) : SV_Target\n{\n\tfloat2 res = EvaluateAttributeAtSample(UV, 1);\n\tres += EvaluateAttributeAtSample(UV, sample);\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/eval-snapped.frag",
    "content": "float2 main(float2 UV : TEXCOORD, nointerpolation int2 code : CODE) : SV_Target\n{\n\tfloat2 res = EvaluateAttributeSnapped(UV, int2(-7, 4));\n\tres += EvaluateAttributeSnapped(UV, code);\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/exp.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn exp2(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/f16-to-f32.frag",
    "content": "float main(nointerpolation uint a : A) : SV_Target\n{\n\treturn f16tof32(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/f32-to-f16.frag",
    "content": "uint main(nointerpolation float a : A) : SV_Target\n{\n\treturn f32tof16(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/fabs.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn abs(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbithi-16.sm62.frag",
    "content": "uint main(uint16_t a : A) : SV_Target\n{\n\treturn firstbithigh(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbithi-64.frag",
    "content": "uint main(uint a : A, uint b : B) : SV_Target\n{\n\tuint64_t c = a | (uint64_t(b) << 32);\n\treturn firstbithigh(c);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbithi.frag",
    "content": "uint main(uint a : A) : SV_Target\n{\n\treturn firstbithigh(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbitlo-16.sm62.frag",
    "content": "uint main(uint16_t a : A) : SV_Target\n{\n\treturn firstbitlow(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbitlo-64.frag",
    "content": "uint main(uint a : A, uint b : B) : SV_Target\n{\n\tuint64_t c = a | (uint64_t(b) << 32);\n\treturn firstbitlow(c);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbitlo.frag",
    "content": "uint main(uint a : A) : SV_Target\n{\n\treturn firstbitlow(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbitshi-16.sm62.frag",
    "content": "int main(int16_t a : A) : SV_Target\n{\n\treturn firstbithigh(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbitshi-64.frag",
    "content": "int main(uint a : A, uint b : B) : SV_Target\n{\n\tint64_t c = int64_t((uint64_t(b) << 32) | a);\n\treturn firstbithigh(c);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/firstbitshi.frag",
    "content": "int main(int a : A) : SV_Target\n{\n\treturn firstbithigh(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/flattened_thread_id_in_group.comp",
    "content": "RWStructuredBuffer<float> RWBuf : register(u0);\n\n[numthreads(2, 2, 2)]\nvoid main(uint ThreadID : SV_GroupIndex)\n{\n\tRWBuf[ThreadID] = 10.0;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/fma.frag",
    "content": "float main(float3 a : A) : SV_Target\n{\n\tdouble3 d = a;\n\treturn float(fma(d.x, d.y, d.z));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/fmad-precise.frag",
    "content": "float main(float3 a : A) : SV_Target\n{\n\tprecise float res = mad(a.x, a.y, a.z);\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/fmad.frag",
    "content": "float main(float3 a : A) : SV_Target\n{\n\treturn mad(a.x, a.y, a.z);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/fmax.frag",
    "content": "float main(float2 a : A) : SV_Target\n{\n\treturn max(a.x, a.y);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/fmin.frag",
    "content": "float main(float2 a : A) : SV_Target\n{\n\treturn min(a.x, a.y);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/frc.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn frac(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/get-dimensions-w-only.frag",
    "content": "Texture1D<float4> Tex1D : register(t0);\nTexture1DArray<float4> Tex1DArray : register(t1);\nTexture2D<float4> Tex2D : register(t2);\nTexture2DArray<float4> Tex2DArray : register(t3);\nTexture2DMS<float4> Tex2DMS : register(t4);\nTexture2DMSArray<float4> Tex2DMSArray : register(t5);\nTexture3D<float4> Tex3D : register(t6);\nTextureCube<float4> TexCube : register(t7);\nTextureCubeArray<float4> TexCubeArray : register(t8);\nBuffer<float4> Buf : register(t9);\n\nRWTexture1D<float4> RWTex1D : register(u0);\nRWTexture1DArray<float4> RWTex1DArray : register(u1);\nRWTexture2D<float4> RWTex2D : register(u2);\nRWTexture2DArray<float4> RWTex2DArray : register(u3);\nRWTexture3D<float4> RWTex3D : register(u6);\nRWBuffer<float4> RWBuf : register(u9);\n\nStructuredBuffer<float4> StructBuf : register(t10);\nRWStructuredBuffer<float4> RWStructBuf : register(u10);\n\nByteAddressBuffer RawBuf : register(t11);\nRWByteAddressBuffer RWRawBuf : register(u11);\n\nuint main(nointerpolation uint level : LEVEL) : SV_Target\n{\n\tuint res = 0;\n\n\tuint width, height, depth, layers, levels, samples;\n\n\tTex1D.GetDimensions(level, width, levels);\n\tres += levels;\n\n\tTex1DArray.GetDimensions(level, width, layers, levels);\n\tres += levels;\n\n\tTex2D.GetDimensions(level, width, height, levels);\n\tres += levels;\n\n\tTex2DArray.GetDimensions(level, width, height, layers, levels);\n\tres += levels;\n\n\tTex2DMS.GetDimensions(width, height, samples);\n\tres += samples;\n\n\tTex2DMSArray.GetDimensions(width, height, layers, samples);\n\tres += samples;\n\n\tTex3D.GetDimensions(level, width, height, depth, levels);\n\tres += levels;\n\n\tTexCube.GetDimensions(level, width, height, levels);\n\tres += levels;\n\n\tTexCubeArray.GetDimensions(level, width, height, layers, levels);\n\tres += levels;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/get-dimensions-xyz-only.frag",
    "content": "Texture1D<float4> Tex1D : register(t0);\nTexture1DArray<float4> Tex1DArray : register(t1);\nTexture2D<float4> Tex2D : register(t2);\nTexture2DArray<float4> Tex2DArray : register(t3);\nTexture2DMS<float4> Tex2DMS : register(t4);\nTexture2DMSArray<float4> Tex2DMSArray : register(t5);\nTexture3D<float4> Tex3D : register(t6);\nTextureCube<float4> TexCube : register(t7);\nTextureCubeArray<float4> TexCubeArray : register(t8);\nBuffer<float4> Buf : register(t9);\n\nRWTexture1D<float4> RWTex1D : register(u0);\nRWTexture1DArray<float4> RWTex1DArray : register(u1);\nRWTexture2D<float4> RWTex2D : register(u2);\nRWTexture2DArray<float4> RWTex2DArray : register(u3);\nRWTexture3D<float4> RWTex3D : register(u6);\nRWBuffer<float4> RWBuf : register(u9);\n\nStructuredBuffer<float4> StructBuf : register(t10);\nRWStructuredBuffer<float4> RWStructBuf : register(u10);\n\nByteAddressBuffer RawBuf : register(t11);\nRWByteAddressBuffer RWRawBuf : register(u11);\n\nuint main(nointerpolation uint level : LEVEL) : SV_Target\n{\n\tuint res = 0;\n\n\tuint width, height, depth, layers, levels, samples;\n\n\tTex1D.GetDimensions(level, width, levels);\n\tres += width;\n\n\tTex1DArray.GetDimensions(level, width, layers, levels);\n\tres += width + layers;\n\n\tTex2D.GetDimensions(level, width, height, levels);\n\tres += width + height;\n\n\tTex2DArray.GetDimensions(level, width, height, layers, levels);\n\tres += width + height + layers;\n\n\tTex2DMS.GetDimensions(width, height, samples);\n\tres += width + height;\n\n\tTex2DMSArray.GetDimensions(width, height, layers, samples);\n\tres += width + height + layers;\n\n\tTex3D.GetDimensions(level, width, height, depth, levels);\n\tres += width + height + depth;\n\n\tTexCube.GetDimensions(level, width, height, levels);\n\tres += width + height;\n\n\tTexCubeArray.GetDimensions(level, width, height, layers, levels);\n\tres += width + height + layers;\n\n\tBuf.GetDimensions(width);\n\tres += width * width;\n\n\tRWTex1D.GetDimensions(width);\n\tres += width * width;\n\n\tRWTex1DArray.GetDimensions(width, layers);\n\tres += width + layers;\n\n\tRWTex2D.GetDimensions(width, height);\n\tres += width + height;\n\n\tRWTex2DArray.GetDimensions(width, height, layers);\n\tres += width + height + layers;\n\n\tRWTex3D.GetDimensions(width, height, depth);\n\tres += width + height + depth;\n\n\tRWBuf.GetDimensions(width);\n\tres += width * width;\n\n\tStructBuf.GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRWStructBuf.GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRawBuf.GetDimensions(width);\n\tres += width * width;\n\tRWRawBuf.GetDimensions(width);\n\tres += width * width;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/get-dimensions.bindless.root-constant.frag",
    "content": "Texture2D<float4> Tex2D[] : register(t0, space0);\nBuffer<float4> Buf[] : register(t0, space1);\nRWTexture2D<float4> RWTex2D[] : register(u0, space2);\nRWBuffer<float4> RWBuf[] : register(u0, space3);\n\nStructuredBuffer<float4> StructBuf[] : register(t0, space4);\nRWStructuredBuffer<float4> RWStructBuf[] : register(u0, space5);\n\nByteAddressBuffer RawBuf[] : register(t0, space6);\nRWByteAddressBuffer RWRawBuf[] : register(u0, space7);\n\nuint main(nointerpolation uint level : LEVEL, nointerpolation uint index : INDEX) : SV_Target\n{\n\tuint res = 0;\n\tuint width, height, depth, layers, levels;\n\n\tTex2D[NonUniformResourceIndex(index)].GetDimensions(level, width, height, levels);\n\tres += width + height + levels;\n\n\tBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\n\tRWTex2D[NonUniformResourceIndex(index)].GetDimensions(width, height);\n\tres += width + height;\n\n\tRWBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\n\tStructBuf[NonUniformResourceIndex(index)].GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRWStructBuf[NonUniformResourceIndex(index)].GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRawBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\tRWRawBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/get-dimensions.bindless.root-constant.ssbo.frag",
    "content": "Texture2D<float4> Tex2D[] : register(t0, space0);\nBuffer<float4> Buf[] : register(t0, space1);\nRWTexture2D<float4> RWTex2D[] : register(u0, space2);\nRWBuffer<float4> RWBuf[] : register(u0, space3);\n\nStructuredBuffer<float4> StructBuf[] : register(t0, space4);\nRWStructuredBuffer<float4> RWStructBuf[] : register(u0, space5);\n\nByteAddressBuffer RawBuf[] : register(t0, space6);\nRWByteAddressBuffer RWRawBuf[] : register(u0, space7);\n\nuint main(nointerpolation uint level : LEVEL, nointerpolation uint index : INDEX) : SV_Target\n{\n\tuint res = 0;\n\tuint width, height, depth, layers, levels;\n\n\tTex2D[NonUniformResourceIndex(index)].GetDimensions(level, width, height, levels);\n\tres += width + height + levels;\n\n\tBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\n\tRWTex2D[NonUniformResourceIndex(index)].GetDimensions(width, height);\n\tres += width + height;\n\n\tRWBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\n\tStructBuf[NonUniformResourceIndex(index)].GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRWStructBuf[NonUniformResourceIndex(index)].GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRawBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\tRWRawBuf[NonUniformResourceIndex(index)].GetDimensions(width);\n\tres += width * width;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/get-dimensions.frag",
    "content": "Texture1D<float4> Tex1D : register(t0);\nTexture1DArray<float4> Tex1DArray : register(t1);\nTexture2D<float4> Tex2D : register(t2);\nTexture2DArray<float4> Tex2DArray : register(t3);\nTexture2DMS<float4> Tex2DMS : register(t4);\nTexture2DMSArray<float4> Tex2DMSArray : register(t5);\nTexture3D<float4> Tex3D : register(t6);\nTextureCube<float4> TexCube : register(t7);\nTextureCubeArray<float4> TexCubeArray : register(t8);\nBuffer<float4> Buf : register(t9);\n\nRWTexture1D<float4> RWTex1D : register(u0);\nRWTexture1DArray<float4> RWTex1DArray : register(u1);\nRWTexture2D<float4> RWTex2D : register(u2);\nRWTexture2DArray<float4> RWTex2DArray : register(u3);\nRWTexture3D<float4> RWTex3D : register(u6);\nRWBuffer<float4> RWBuf : register(u9);\n\nStructuredBuffer<float4> StructBuf : register(t10);\nRWStructuredBuffer<float4> RWStructBuf : register(u10);\n\nByteAddressBuffer RawBuf : register(t11);\nRWByteAddressBuffer RWRawBuf : register(u11);\n\nuint main(nointerpolation uint level : LEVEL) : SV_Target\n{\n\tuint res = 0;\n\n\tuint width, height, depth, layers, levels, samples;\n\n\tTex1D.GetDimensions(level, width, levels);\n\tres += width + levels;\n\n\tTex1DArray.GetDimensions(level, width, layers, levels);\n\tres += width + layers + levels;\n\n\tTex2D.GetDimensions(level, width, height, levels);\n\tres += width + height + levels;\n\n\tTex2DArray.GetDimensions(level, width, height, layers, levels);\n\tres += width + height + layers + levels;\n\n\tTex2DMS.GetDimensions(width, height, samples);\n\tres += width + height + samples;\n\n\tTex2DMSArray.GetDimensions(width, height, layers, samples);\n\tres += width + height + layers + samples;\n\n\tTex3D.GetDimensions(level, width, height, depth, levels);\n\tres += width + height + depth + levels;\n\n\tTexCube.GetDimensions(level, width, height, levels);\n\tres += width + height + levels;\n\n\tTexCubeArray.GetDimensions(level, width, height, layers, levels);\n\tres += width + height + layers + levels;\n\n\tBuf.GetDimensions(width);\n\tres += width * width;\n\n\tRWTex1D.GetDimensions(width);\n\tres += width * width;\n\n\tRWTex1DArray.GetDimensions(width, layers);\n\tres += width + layers;\n\n\tRWTex2D.GetDimensions(width, height);\n\tres += width + height;\n\n\tRWTex2DArray.GetDimensions(width, height, layers);\n\tres += width + height + layers;\n\n\tRWTex3D.GetDimensions(width, height, depth);\n\tres += width + height + depth;\n\n\tRWBuf.GetDimensions(width);\n\tres += width * width;\n\n\tStructBuf.GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRWStructBuf.GetDimensions(width, depth);\n\tres += width * width + depth;\n\n\tRawBuf.GetDimensions(width);\n\tres += width * width;\n\tRWRawBuf.GetDimensions(width);\n\tres += width * width;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/get-dimensions.ssbo.frag",
    "content": "RWStructuredBuffer<float4> RWStructBuf : register(u10);\nRWByteAddressBuffer RWRawBuf : register(u11);\n\nuint main(nointerpolation uint level : LEVEL) : SV_Target\n{\n\tuint res = 0;\n\n\tuint width, height, depth, layers, levels, samples;\n\n\tRWStructBuf.GetDimensions(width, depth);\n\tres += width * width + depth;\n\tRWRawBuf.GetDimensions(width);\n\tres += width * width;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/group_id.comp",
    "content": "RWStructuredBuffer<float> RWBuf : register(u0);\n\n[numthreads(2, 2, 2)]\nvoid main(uint3 ThreadID : SV_GroupID)\n{\n\tRWBuf[ThreadID.x] = 10.0;\n\tRWBuf[ThreadID.y] = 20.0;\n\tRWBuf[ThreadID.z] = 30.0;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/hcos.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn cosh(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/hsin.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn sinh(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/htan.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn tanh(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/imad.frag",
    "content": "int main(nointerpolation int3 a : A) : SV_Target\n{\n\treturn mad(a.x, a.y, a.z);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/imax.frag",
    "content": "int main(nointerpolation int2 a : A) : SV_Target\n{\n\treturn max(a.x, a.y);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/imin.frag",
    "content": "int main(nointerpolation int2 a : A) : SV_Target\n{\n\treturn min(a.x, a.y);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/instance-id.vert",
    "content": "float4 main(uint ID : SV_InstanceID) : SV_Position\n{\n\tfloat res = float(ID);\n\treturn res.xxxx;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/is-helper-lane-2.demote-to-helper.sm66.frag",
    "content": "float4 main(float2 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\tif (!IsHelperLane())\n\t\tres = WavePrefixSum(float4(UV, UV * UV));\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/is-helper-lane-2.sm66.frag",
    "content": "float4 main(float2 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\tif (!IsHelperLane())\n\t\tres = WavePrefixSum(float4(UV, UV * UV));\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/is-helper-lane.demote-to-helper.sm66.frag",
    "content": "float4 main(float2 UV : TEXCOORD) : SV_Target\n{\n\tif (UV.x > 10.0)\n\t\tdiscard;\n\telse if (UV.y > 20.0)\n\t\tdiscard;\n\n\tfloat4 res = 0.0.xxxx;\n\tif (!IsHelperLane())\n\t\tres = WavePrefixSum(float4(UV, UV * UV));\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/is-helper-lane.sm66.frag",
    "content": "float4 main(float2 UV : TEXCOORD) : SV_Target\n{\n\tif (UV.x > 10.0)\n\t\tdiscard;\n\telse if (UV.y > 20.0)\n\t\tdiscard;\n\n\tfloat4 res = 0.0.xxxx;\n\tif (!IsHelperLane())\n\t\tres = WavePrefixSum(float4(UV, UV * UV));\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/isfinite.frag",
    "content": "float main(float3 a : A) : SV_Target\n{\n\treturn isfinite(a.x) ? a.y : a.z;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/isinf.frag",
    "content": "float main(float3 a : A) : SV_Target\n{\n\treturn isinf(a.x) ? a.y : a.z;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/isnan.frag",
    "content": "float main(float3 a : A) : SV_Target\n{\n\treturn isnan(a.x) ? a.y : a.z;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/log.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn log2(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/make-double.frag",
    "content": "float main(nointerpolation uint2 values : VALUE) : SV_Target\n{\n\treturn float(asdouble(values.x, values.y));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/msaa-uav.sm67.comp",
    "content": "RWTexture2DMS<float, 4> FirstLayer : register(u0);\nRWTexture2DMSArray<float, 4> Layers : register(u1);\nRWStructuredBuffer<float4> Outputs : register(u2);\n\nfloat compute_reference_value(uint3 coord, uint sample)\n{\n\treturn float(coord.z * 64 + coord.y * 16 + coord.x * 4 + sample);\n}\n\n[numthreads(4, 4, 4)]\nvoid main(uint3 id : SV_DispatchThreadID)\n{\n\t// Read and write to different coordinates so we're sure we're going through the descriptors.\n\tuint3 write_coord = id ^ uint3(1, 2, 3);\n\tif (write_coord.z == 0)\n\t{\n\t\tFirstLayer[write_coord.xy] = compute_reference_value(write_coord, 0);\n\t\tfor (int i = 1; i < 4; i++)\n\t\t\tFirstLayer.sample[i][write_coord.xy] = compute_reference_value(write_coord, i);\n\t}\n\telse\n\t{\n\t\tLayers[write_coord] = compute_reference_value(write_coord, 0);\n\t\tfor (int i = 1; i < 4; i++)\n\t\t\tLayers.sample[i][write_coord] = compute_reference_value(write_coord, i);\n\t}\n\n\t// globallycoherent is not needed since it's within same threadgroup.\n\tDeviceMemoryBarrierWithGroupSync();\n\n\t// Test all new commands.\n\tfloat4 samples;\n\tif (id.z == 0)\n\t{\n\t\tsamples[0] = FirstLayer[id.xy];\n\t\t// Make sure the sample indexing works both in a constant and dynamic context.\n\t\t[unroll]\n\t\t\tfor (int i = 1; i < 4; i++)\n\t\t\t\tsamples[i] = FirstLayer.sample[i][id.xy];\n\t}\n\telse\n\t{\n\t\tsamples[0] = Layers[id];\n\t\t[loop]\n\t\t\tfor (int i = 1; i < 4; i++)\n\t\t\t\tsamples[i] = Layers.sample[i][id];\n\t}\n\n\tOutputs[id.z * 16 + id.y * 4 + id.x] = samples;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/msad.comp",
    "content": "    StructuredBuffer<uint4> Inputs;\n    RWStructuredBuffer<uint4> Outputs;\n\n    [numthreads(1, 1, 1)]\n    void main(uint thr : SV_DispatchThreadID)\n    {\n            Outputs[thr] = msad4(Inputs[thr].x, Inputs[thr].yz, Inputs[thr].wwww);\n    }\n"
  },
  {
    "path": "shaders/dxil-builtin/object-ray-direction.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = ObjectRayDirection();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/object-ray-origin.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = ObjectRayOrigin();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/object-to-world-3x4.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = mul(ObjectToWorld3x4(), float4(payload.orig, 1.0));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/object-to-world-4x3.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = mul(float4(payload.orig, 1.0), ObjectToWorld4x3());\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/pack-unpack.ssbo.sm66.comp",
    "content": "StructuredBuffer<uint> RO : register(t0);\nRWStructuredBuffer<uint4> RW : register(u0);\nRWStructuredBuffer<uint16_t4> RW16 : register(u1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint8_t4_packed p = RO[thr];\n\n\t{\n\t\tuint4 p4 = unpack_u8u32(p);\n\t\tRW[thr] = p4;\n\t}\n\n\t{\n\t\tuint16_t4 p4 = unpack_u8u16(p);\n\t\tRW16[thr] = p4;\n\t}\n\n\t{\n\t\tint4 p4 = unpack_s8s32(p);\n\t\tRW[thr] = p4;\n\t}\n\n\t{\n\t\tint16_t4 p4 = unpack_s8s16(p);\n\t\tRW16[thr] = p4;\n\t}\n\n\t{\n\t\tuint4 u32s = RW[thr + 100000];\n\t\tuint p0 = pack_u8(u32s);\n\t\tuint p1 = pack_s8(int4(u32s));\n\t\tuint p2 = pack_clamp_u8(int4(u32s));\n\t\tuint p3 = pack_clamp_s8(int4(u32s));\n\t\tRW[thr + 1000] = uint4(p0, p1, p2, p3);\n\t}\n\n\t{\n\t\tuint16_t4 u16s = RW16[thr + 100000];\n\t\tuint p0 = pack_u8(u16s);\n\t\tuint p1 = pack_s8(int16_t4(u16s));\n\t\tuint p2 = pack_clamp_u8(int16_t4(u16s));\n\t\tuint p3 = pack_clamp_s8(int16_t4(u16s));\n\t\tRW16[thr + 1000] = uint16_t4(p0, p1, p2, p3);\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-all-any.sm67.comp",
    "content": "RWStructuredBuffer<uint> A : register(u0);\nRWStructuredBuffer<uint> B : register(u1);\n\n[numthreads(8, 8, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tbool any_result = QuadAny(bool(A[index]));\n\tbool all_result = QuadAll(bool(A[index]));\n\tB[2 * index] = uint(any_result);\n\tB[2 * index + 1] = uint(all_result);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-all-any.sm67.quad-maximal-reconvergence.noglsl.comp",
    "content": "RWStructuredBuffer<uint> A : register(u0);\nRWStructuredBuffer<uint> B : register(u1);\n\n[numthreads(8, 8, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tbool any_result = QuadAny(bool(A[index]));\n\tbool all_result = QuadAll(bool(A[index]));\n\tB[2 * index] = uint(any_result);\n\tB[2 * index + 1] = uint(all_result);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-read-at-2d.comp",
    "content": "RWByteAddressBuffer A : register(u0);\nRWByteAddressBuffer B : register(u1);\n\n[numthreads(8, 8, 1)]\nvoid main(uint index : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tindex += gid * 64;\n\n\tuint value = A.Load(index * 4);\n\tuint2 r;\n\tr.x = QuadReadLaneAt(value, 1);\n\tr.y = QuadReadLaneAt(value, value & 3);\n\tB.Store2(index * 8, r);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-read-at-2d.sm66.comp",
    "content": "RWByteAddressBuffer A : register(u0);\nRWByteAddressBuffer B : register(u1);\n\n[numthreads(8, 4, 2)]\nvoid main(uint index : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tindex += gid * 64;\n\n\tuint value = A.Load(index * 4);\n\tuint2 r;\n\tr.x = QuadReadLaneAt(value, 1);\n\tr.y = QuadReadLaneAt(value, value & 3);\n\tB.Store2(index * 8, r);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-read-at.comp",
    "content": "RWByteAddressBuffer A : register(u0);\nRWByteAddressBuffer B : register(u1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint value = A.Load(index * 4);\n\tuint2 r;\n\tr.x = QuadReadLaneAt(value, 1);\n\tr.y = QuadReadLaneAt(value, value & 3);\n\tB.Store2(index * 8, r);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-read-at.frag",
    "content": "float2 main(float v : V, nointerpolation uint index : INDEX) : SV_Target\n{\n\tfloat2 res;\n\tres.x = QuadReadLaneAt(v, 2);\n\tres.y = QuadReadLaneAt(v, index);\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-swap.comp",
    "content": "RWByteAddressBuffer A : register(u0);\nRWByteAddressBuffer B : register(u1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint value = A.Load(index * 4);\n\tuint4 r;\n\tr.x = value;\n\tr.y = QuadReadAcrossX(value);\n\tr.z = QuadReadAcrossY(value);\n\tr.w = QuadReadAcrossDiagonal(value);\n\tB.Store4(index * 16, r);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/quad-swap.frag",
    "content": "float4 main(float a : A) : SV_Target\n{\n\tfloat4 r;\n\tr.x = a;\n\tr.y = QuadReadAcrossX(a);\n\tr.z = QuadReadAcrossY(a);\n\tr.w = QuadReadAcrossDiagonal(a);\n\treturn r;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/raw-gather-offset-sparse.sm67.ssbo.comp",
    "content": "Texture2D<uint16_t> D16 : register(t0);\nTexture2D<uint> D32 : register(t1);\nTexture2D<uint64_t> D64 : register(t2);\nSamplerState S : register(s0);\nRWByteAddressBuffer U : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint id : SV_DispatchThreadID)\n{\n\tuint3 status;\n\tuint16_t4 d16 = D16.GatherRaw(S, 0.5.xx, int2(-3, -2), status.x);\n\tuint4 d32 = D32.GatherRaw(S, 0.5.xx, int2(d16.xy), status.y);\n\tuint64_t4 d64 = D64.GatherRaw(S, 0.5.xx, int2(-3, -2), status.z);\n\n\tU.Store<uint4>(0, uint4(d16));\n\tU.Store<uint4>(16, d32);\n\tU.Store<uint64_t4>(32, d64);\n\tU.Store<uint3>(64, status);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/raw-gather-offset.sm67.ssbo.comp",
    "content": "Texture2D<uint16_t> D16 : register(t0);\nTexture2D<uint> D32 : register(t1);\nTexture2D<uint64_t> D64 : register(t2);\nSamplerState S : register(s0);\nRWByteAddressBuffer U : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint id : SV_DispatchThreadID)\n{\n\tuint16_t4 d16 = D16.GatherRaw(S, 0.5.xx, int2(1, 2));\n\t// Dynamic offset is allowed for gather as-is in Vulkan.\n\tuint4 d32 = D32.GatherRaw(S, 0.5.xx, int2(d16.xy));\n\tuint64_t4 d64 = D64.GatherRaw(S, 0.5.xx, int2(4, 5));\n\n\tU.Store<uint4>(0, uint4(d16));\n\tU.Store<uint4>(16, d32);\n\tU.Store<uint64_t4>(32, d64);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/raw-gather-sparse.sm67.ssbo.comp",
    "content": "Texture2D<uint16_t> D16 : register(t0);\nTexture2D<uint> D32 : register(t1);\nTexture2D<uint64_t> D64 : register(t2);\nSamplerState S : register(s0);\nRWByteAddressBuffer U : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint id : SV_DispatchThreadID)\n{\n\tuint3 status;\n\tuint16_t4 d16 = D16.GatherRaw(S, 0.5.xx, int2(0, 0), status.x);\n\tuint4 d32 = D32.GatherRaw(S, 0.5.xx, int2(0, 0), status.y);\n\tuint64_t4 d64 = D64.GatherRaw(S, 0.5.xx, int2(0, 0), status.z);\n\n\tU.Store<uint4>(0, uint4(d16));\n\tU.Store<uint4>(16, d32);\n\tU.Store<uint64_t4>(32, d64);\n\tU.Store<uint3>(64, status);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/raw-gather.sm67.ssbo.comp",
    "content": "Texture2D<uint16_t> D16 : register(t0);\nTexture2D<uint> D32 : register(t1);\nTexture2D<uint64_t> D64 : register(t2);\nSamplerState S : register(s0);\nRWByteAddressBuffer U : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint id : SV_DispatchThreadID)\n{\n\tuint16_t4 d16 = D16.GatherRaw(S, 0.5.xx);\n\tuint4 d32 = D32.GatherRaw(S, 0.5.xx);\n\tuint64_t4 d64 = D64.GatherRaw(S, 0.5.xx);\n\n\tU.Store<uint4>(0, uint4(d16));\n\tU.Store<uint4>(16, d32);\n\tU.Store<uint64_t4>(32, d64);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-query-phi-multi.invalid.sm66.comp",
    "content": "cbuffer Bindings : register(b0)\n{\n    uint tlasSrv;\n\tuint test;\n};\n\n[numthreads(8, 8, 1)]\nvoid main(uint2 dispatchThreadId : SV_DispatchThreadID)\n{\n    float2 pixelCenter = dispatchThreadId + 0.5f;\n    float3 wsPos = float3(pixelCenter, -1);\n    RayDesc ray;\n    ray.Origin = wsPos;\n    ray.TMin = 0.1;\n    ray.TMax = 1000.0;\n    ray.Direction = float3(0, 0, 1);\n\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> a;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> b;\n\n\tbool alphaTest = test != 0;\n\n\t[branch]\n    if (!alphaTest)\n\t\tq = a;\n\telse\n\t\tq = b;\n\n    RaytracingAccelerationStructure tlas = ResourceDescriptorHeap[tlasSrv];\n    q.TraceRayInline(tlas, 0, 0xff, ray);\n    b.TraceRayInline(tlas, 0, 0xff, ray);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-query-phi-simple.sm66.comp",
    "content": "cbuffer Bindings : register(b0)\n{\n    uint tlasSrv;\n\tuint test;\n};\n\n[numthreads(8, 8, 1)]\nvoid main(uint2 dispatchThreadId : SV_DispatchThreadID)\n{\n    float2 pixelCenter = dispatchThreadId + 0.5f;\n    float3 wsPos = float3(pixelCenter, -1);\n    RayDesc ray;\n    ray.Origin = wsPos;\n    ray.TMin = 0.1;\n    ray.TMax = 1000.0;\n    ray.Direction = float3(0, 0, 1);\n\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> a;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> b;\n\n\tbool alphaTest = test != 0;\n\n\t[branch]\n    if (!alphaTest)\n\t\tq = a;\n\telse\n\t\tq = b;\n\n    RaytracingAccelerationStructure tlas = ResourceDescriptorHeap[tlasSrv];\n    q.TraceRayInline(tlas, 0, 0xff, ray);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-query-select-multi.invalid.sm66.comp",
    "content": "cbuffer Bindings : register(b0)\n{\n    uint tlasSrv;\n\tuint test;\n};\n\n[numthreads(8, 8, 1)]\nvoid main(uint2 dispatchThreadId : SV_DispatchThreadID)\n{\n    float2 pixelCenter = dispatchThreadId + 0.5f;\n    float3 wsPos = float3(pixelCenter, -1);\n    RayDesc ray;\n    ray.Origin = wsPos;\n    ray.TMin = 0.1;\n    ray.TMax = 1000.0;\n    ray.Direction = float3(0, 0, 1);\n\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> a;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> b;\n\n\tbool alphaTest = test != 0;\n\n    if (!alphaTest)\n\t\tq = a;\n\telse\n\t\tq = b;\n\n    RaytracingAccelerationStructure tlas = ResourceDescriptorHeap[tlasSrv];\n    q.TraceRayInline(tlas, 0, 0xff, ray);\n    b.TraceRayInline(tlas, 0, 0xff, ray);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-query-select-simple.sm66.comp",
    "content": "cbuffer Bindings : register(b0)\n{\n    uint tlasSrv;\n\tuint test;\n};\n\n[numthreads(8, 8, 1)]\nvoid main(uint2 dispatchThreadId : SV_DispatchThreadID)\n{\n    float2 pixelCenter = dispatchThreadId + 0.5f;\n    float3 wsPos = float3(pixelCenter, -1);\n    RayDesc ray;\n    ray.Origin = wsPos;\n    ray.TMin = 0.1;\n    ray.TMax = 1000.0;\n    ray.Direction = float3(0, 0, 1);\n\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> a;\n\tRayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> b;\n\n\tbool alphaTest = test != 0;\n\n    if (!alphaTest)\n\t\tq = a;\n\telse\n\t\tq = b;\n\n    RaytracingAccelerationStructure tlas = ResourceDescriptorHeap[tlasSrv];\n    q.TraceRayInline(tlas, 0, 0xff, ray);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-query-store-multi.invalid.sm66.comp",
    "content": "cbuffer Bindings : register(b0)\n{\n    uint tlasSrv;\n\tuint test;\n};\n\n[numthreads(8, 8, 1)]\nvoid main(uint2 dispatchThreadId : SV_DispatchThreadID)\n{\n    float2 pixelCenter = dispatchThreadId + 0.5f;\n    float3 wsPos = float3(pixelCenter, -1);\n    RayDesc ray;\n    ray.Origin = wsPos;\n    ray.TMin = 0.1;\n    ray.TMax = 1000.0;\n    ray.Direction = float3(0, 0, 1);\n\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> a;\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> qa[4];\n\n    RayQuery<RAY_FLAG_FORCE_OPAQUE> b;\n    RayQuery<RAY_FLAG_FORCE_OPAQUE> qb[4];\n\n\ta = qa[test ^ 1];\n\tb = qb[test ^ 2];\n    RaytracingAccelerationStructure tlas = ResourceDescriptorHeap[tlasSrv];\n    a.TraceRayInline(tlas, 0, 0xff, ray);\n    b.TraceRayInline(tlas, 0, 0xff, ray);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-query-store-simple.sm66.comp",
    "content": "cbuffer Bindings : register(b0)\n{\n    uint tlasSrv;\n\tuint test;\n};\n\n[numthreads(8, 8, 1)]\nvoid main(uint2 dispatchThreadId : SV_DispatchThreadID)\n{\n    float2 pixelCenter = dispatchThreadId + 0.5f;\n    float3 wsPos = float3(pixelCenter, -1);\n    RayDesc ray;\n    ray.Origin = wsPos;\n    ray.TMin = 0.1;\n    ray.TMax = 1000.0;\n    ray.Direction = float3(0, 0, 1);\n\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> a;\n    RayQuery<RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q[4];\n\n\tbool alphaTest = test != 0;\n\ta = q[test];\n    RaytracingAccelerationStructure tlas = ResourceDescriptorHeap[tlasSrv];\n    a.TraceRayInline(tlas, 0, 0xff, ray);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-query.comp",
    "content": "RaytracingAccelerationStructure RTAS : register(t0);\nRWStructuredBuffer<uint> RWUint : register(u1);\nRWStructuredBuffer<float> RWFloat : register(u2);\nRWStructuredBuffer<float4> RWFloat4 : register(u3);\nRWStructuredBuffer<float3> RWFloat3 : register(u4);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tRayQuery<RAY_FLAG_CULL_NON_OPAQUE> q;\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.TMin = 4;\n\tray.Direction = float3(5, 6, 7);\n\tray.TMax = 8;\n\tq.TraceRayInline(RTAS, RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, 0xaa, ray);\n\n\tuint a = 0;\n\tuint b = 0;\n\tuint c = 0;\n\n\twhile (q.Proceed())\n\t{\n\t\tRWUint[64 * thr + 0] = q.CandidateInstanceIndex();\n\t\tRWUint[64 * thr + 1] = q.CandidateInstanceID();\n\t\tRWUint[64 * thr + 2] = q.CandidateGeometryIndex();\n\t\tRWUint[64 * thr + 3] = q.CandidatePrimitiveIndex();\n\t\tRWFloat[64 * thr + 4] = q.CandidateObjectRayOrigin().x;\n\t\tRWFloat[64 * thr + 5] = q.CandidateObjectRayDirection().y;\n\t\tRWUint[64 * thr + 16] = q.CandidateInstanceContributionToHitGroupIndex();\n\n\t\tfloat4 row0 = q.CandidateWorldToObject3x4()[0];\n\t\tfloat4 row1 = q.CandidateObjectToWorld3x4()[0];\n\t\tRWFloat4[4 * thr + 0] = row0;\n\t\tRWFloat4[4 * thr + 1] = row1;\n\n\t\tfloat3 row2 = q.CandidateWorldToObject4x3()[0];\n\t\tfloat3 row3 = q.CandidateObjectToWorld4x3()[0];\n\t\tRWFloat3[4 * thr + 0] = row2;\n\t\tRWFloat3[4 * thr + 1] = row3;\n\n\t\tif (q.CandidateType() == CANDIDATE_NON_OPAQUE_TRIANGLE)\n\t\t{\n\t\t\ta++;\n\t\t\tRWFloat[64 * thr + 6] = q.CandidateTriangleRayT();\n\t\t\tRWFloat[64 * thr + 7] = q.CandidateTriangleBarycentrics().y;\n\t\t\tRWUint[64 * thr + 8] = q.CandidateTriangleFrontFace() ? 100 : 10;\n\t\t\tq.CommitNonOpaqueTriangleHit();\n\t\t}\n\t\telse if (q.CandidateType() == CANDIDATE_PROCEDURAL_PRIMITIVE)\n\t\t{\n\t\t\tif (q.CandidateProceduralPrimitiveNonOpaque())\n\t\t\t\tb++;\n\t\t\telse\n\t\t\t\tc++;\n\t\t\tq.CommitProceduralPrimitiveHit(0.5);\n\t\t}\n\n\t\tif (a == 4)\n\t\t\tq.Abort();\n\t}\n\n\tRWUint[64 * thr + 9] = q.RayFlags();\n\tRWFloat[64 * thr + 10] = q.WorldRayOrigin().x;\n\tRWFloat[64 * thr + 11] = q.WorldRayDirection().y;\n\tRWFloat[64 * thr + 12] = q.RayTMin();\n\n\tif (q.CommittedStatus())\n\t{\n\t\tRWUint[64 * thr + 32] = q.CommittedInstanceIndex();\n\t\tRWUint[64 * thr + 33] = q.CommittedInstanceID();\n\t\tRWUint[64 * thr + 34] = q.CommittedGeometryIndex();\n\t\tRWUint[64 * thr + 35] = q.CommittedPrimitiveIndex();\n\t\tRWFloat[64 * thr + 36] = q.CommittedObjectRayOrigin().x;\n\t\tRWFloat[64 * thr + 37] = q.CommittedObjectRayDirection().y;\n\t\tRWUint[64 * thr + 38] = q.CommittedInstanceContributionToHitGroupIndex();\n\n\t\tfloat4 row0 = q.CommittedWorldToObject3x4()[0];\n\t\tfloat4 row1 = q.CommittedObjectToWorld3x4()[0];\n\t\tRWFloat4[4 * thr + 39] = row0;\n\t\tRWFloat4[4 * thr + 40] = row1;\n\n\t\tfloat3 row2 = q.CommittedWorldToObject4x3()[0];\n\t\tfloat3 row3 = q.CommittedObjectToWorld4x3()[0];\n\t\tRWFloat3[4 * thr + 41] = row2;\n\t\tRWFloat3[4 * thr + 42] = row3;\n\t\tRWFloat[64 * thr + 43] = q.CommittedRayT();\n\t}\n\n\tif (q.CommittedStatus() == COMMITTED_TRIANGLE_HIT)\n\t{\n\t\tRWUint[64 * thr + 13] = a;\n\t\tRWFloat[64 * thr + 44] = q.CommittedTriangleBarycentrics().y;\n\t\tRWUint[64 * thr + 45] = q.CommittedTriangleFrontFace() ? 100 : 10;\n\t}\n\telse if (q.CommittedStatus() == COMMITTED_PROCEDURAL_PRIMITIVE_HIT)\n\t{\n\t\tRWUint[64 * thr + 14] = b;\n\t}\n\telse\n\t{\n\t\tRWUint[64 * thr + 15] = c;\n\t}\n}\n\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-t-current.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = RayTCurrent();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/ray-t-min.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = RayTMin();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/render-target-sample-count.frag",
    "content": "float4 main() : SV_Target\n{\n\treturn GetRenderTargetSampleCount();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/render-target-sample-position.frag",
    "content": "float2 main(uint index : SV_SampleIndex) : SV_Target\n{\n\treturn GetRenderTargetSamplePosition(index);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/report-hit.rint",
    "content": "struct Payload\n{\n\tfloat p;\n};\n\n[shader(\"intersection\")]\nvoid RayIntersect()\n{\n\tPayload p;\n\tPayload p2;\n\tp.p = RayTCurrent();\n\tp2.p = RayTMin();\n\n\tReportHit(4.0, 100, p);\n\tReportHit(3.0, 50, p2);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/round-ne.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn round(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/round-ni.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn floor(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/round-pi.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn ceil(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/round-z.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn trunc(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/rsqrt.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn rsqrt(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/rt-geometry-index.rany",
    "content": "struct Payload\n{\n\tuint index;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.index = GeometryIndex();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/rt-hit-kind.rany",
    "content": "struct Payload\n{\n\tuint index;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.index = HitKind();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/rt-instance-id.rany",
    "content": "struct Payload\n{\n\tuint index;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.index = InstanceID();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/rt-instance-index.rany",
    "content": "struct Payload\n{\n\tuint index;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.index = InstanceIndex();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/rt-primitive-index.rany",
    "content": "struct Payload\n{\n\tuint index;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.index = PrimitiveIndex();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/rt-ray-flags.rany",
    "content": "struct Payload\n{\n\tuint index;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.index = RayFlags();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-bias-feedback.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tuint feedback;\n\n\t// Sample without bias.\n\tres += Tex1D.SampleBias(Samp, UV.x, 0.0, 0, 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += Tex1DArray.SampleBias(Samp, UV.xy, 0.0, 0, 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += Tex2D.SampleBias(Samp, UV.xy, 0.0, int2(0, 0), 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += Tex2DArray.SampleBias(Samp, UV.xyz, 0.0, int2(0, 0), 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += Tex3D.SampleBias(Samp, UV.xyz, 0.0, int3(0, 0, 0), 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += TexCube.SampleBias(Samp, UV.xyz, 0.0, 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += TexCubeArray.SampleBias(Samp, UV, 0.0, 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-bias-offset.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleBias(Samp, UV.x, UV.w, 1);\n\tres += Tex1DArray.SampleBias(Samp, UV.xy, UV.w, 2);\n\tres += Tex2D.SampleBias(Samp, UV.xy, UV.w, int2(2, 3));\n\tres += Tex2DArray.SampleBias(Samp, UV.xyz, UV.w, int2(-1, -3));\n\tres += Tex3D.SampleBias(Samp, UV.xyz, UV.w, int3(-4, -5, 3));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-bias.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleBias(Samp, UV.x, UV.w);\n\tres += Tex1DArray.SampleBias(Samp, UV.xy, UV.w);\n\tres += Tex2D.SampleBias(Samp, UV.xy, UV.w);\n\tres += Tex2DArray.SampleBias(Samp, UV.xyz, UV.w);\n\tres += Tex3D.SampleBias(Samp, UV.xyz, UV.w);\n\tres += TexCube.SampleBias(Samp, UV.xyz, UV.w);\n\tres += TexCubeArray.SampleBias(Samp, UV, UV.w);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-bias-feedback.frag",
    "content": "Texture1D<float> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTextureCube<float> TexCube : register(t5, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat main(float4 UV : TEXCOORD, float Dref : DREF) : SV_Target\n{\n\tfloat res = 0.0;\n\tuint feedback;\n\n\t// Sample without bias.\n\tres += Tex1D.SampleCmpBias(Samp, UV.x, Dref, 0.0, 0, 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += Tex1DArray.SampleCmpBias(Samp, UV.xy, Dref, 0.0, 0, 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += Tex2D.SampleCmpBias(Samp, UV.xy, Dref, 0.0, int2(0, 0), 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += Tex2DArray.SampleCmpBias(Samp, UV.xyz, Dref, 0.0, int2(0, 0), 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\tres += TexCube.SampleCmpBias(Samp, UV.xyz, Dref, 0.0, 1.5, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1.0 : 0.0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-bias-offset.frag",
    "content": "Texture1D<float> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTextureCube<float> TexCube : register(t5, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat main(float4 UV : TEXCOORD, float Dref : DREF) : SV_Target\n{\n\tfloat res = 0.0;\n\n\tres += Tex1D.SampleCmpBias(Samp, UV.x, Dref, UV.w, 1);\n\tres += Tex1DArray.SampleCmpBias(Samp, UV.xy, Dref, UV.w, 2);\n\tres += Tex2D.SampleCmpBias(Samp, UV.xy, Dref, UV.w, int2(2, 3));\n\tres += Tex2DArray.SampleCmpBias(Samp, UV.xyz, Dref, UV.w, int2(-1, -3));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-bias.frag",
    "content": "Texture1D<float> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTextureCube<float> TexCube : register(t5, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat main(float4 UV : TEXCOORD, float Dref : DREF) : SV_Target\n{\n\tfloat res = 0.0;\n\n\tres += Tex1D.SampleCmpBias(Samp, UV.x, Dref, UV.w);\n\tres += Tex1DArray.SampleCmpBias(Samp, UV.xy, Dref, UV.w);\n\tres += Tex2D.SampleCmpBias(Samp, UV.xy, Dref, UV.w);\n\tres += Tex2DArray.SampleCmpBias(Samp, UV.xyz, Dref, UV.w);\n\tres += TexCube.SampleCmpBias(Samp, UV.xyz, Dref, UV.w);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-feedback.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tuint feedback;\n\n\tres += Tex1D.SampleCmp(Samp, UV.x, UV.w, 1, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex1DArray.SampleCmp(Samp, UV.xy, UV.w, 2, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2D.SampleCmp(Samp, UV.xy, UV.w, int2(1, 2), 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.SampleCmp(Samp, UV.xyz, UV.w, int2(1, 2), 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += TexCube.SampleCmp(Samp, UV.xyz, UV.w, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += TexCubeArray.SampleCmp(Samp, UV, UV.w, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-grad-offset-feedback.frag",
    "content": "Texture1D<float> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTextureCube<float> TexCube : register(t5, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat main(float4 UV : TEXCOORD, float Dref : DREF) : SV_Target\n{\n\tfloat res = 0.0;\n\tuint feedback;\n\n\tres += Tex1D.SampleCmpGrad(Samp, UV.x, Dref, UV.z, UV.w, 1, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex1DArray.SampleCmpGrad(Samp, UV.xy, Dref, UV.z, UV.w, 2, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2D.SampleCmpGrad(Samp, UV.xy, Dref, UV.zz, UV.ww, int2(-3, -4), 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.SampleCmpGrad(Samp, UV.xyz, Dref, UV.zz, UV.ww, int2(4, -5), 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-grad-offset.frag",
    "content": "Texture1D<float> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTextureCube<float> TexCube : register(t5, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat main(float4 UV : TEXCOORD, float Dref : DREF) : SV_Target\n{\n\tfloat res = 0.0;\n\n\tres += Tex1D.SampleCmpGrad(Samp, UV.x, Dref, UV.z, UV.w, 1);\n\tres += Tex1DArray.SampleCmpGrad(Samp, UV.xy, Dref, UV.z, UV.w, 2);\n\tres += Tex2D.SampleCmpGrad(Samp, UV.xy, Dref, UV.zz, UV.ww, int2(-3, -4));\n\tres += Tex2DArray.SampleCmpGrad(Samp, UV.xyz, Dref, UV.zz, UV.ww, int2(4, -5));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-grad.frag",
    "content": "Texture1D<float> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTextureCube<float> TexCube : register(t5, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat main(float4 UV : TEXCOORD, float Dref : DREF) : SV_Target\n{\n\tfloat res = 0.0;\n\n\tres += Tex1D.SampleCmpGrad(Samp, UV.x, Dref, UV.z, UV.w);\n\tres += Tex1DArray.SampleCmpGrad(Samp, UV.xy, Dref, UV.z, UV.w);\n\tres += Tex2D.SampleCmpGrad(Samp, UV.xy, Dref, UV.zz, UV.ww);\n\tres += Tex2DArray.SampleCmpGrad(Samp, UV.xyz, Dref, UV.zz, UV.ww);\n\tres += TexCube.SampleCmpGrad(Samp, UV.xyz, Dref, UV.zzz, UV.www);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-level.sm67.noglsl.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\t// Some of these cannot be expressed in GLSL directly, so use noglsl.\n\tres += Tex1D.SampleCmpLevel(Samp, UV.x, UV.w, 0.25);\n\tres += Tex1DArray.SampleCmpLevel(Samp, UV.xy, UV.w, 0.5);\n\tres += Tex2D.SampleCmpLevel(Samp, UV.xy, UV.w, 1.0);\n\tres += Tex2DArray.SampleCmpLevel(Samp, UV.xyz, UV.w, 2.0);\n\tres += TexCube.SampleCmpLevel(Samp, UV.xyz, UV.w, 3.0);\n\tres += TexCubeArray.SampleCmpLevel(Samp, UV, UV.w, 4.0);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-levelzero.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleCmpLevelZero(Samp, UV.x, UV.w);\n\tres += Tex1DArray.SampleCmpLevelZero(Samp, UV.xy, UV.w);\n\tres += Tex2D.SampleCmpLevelZero(Samp, UV.xy, UV.w);\n\tres += Tex2DArray.SampleCmpLevelZero(Samp, UV.xyz, UV.w);\n\tres += TexCube.SampleCmpLevelZero(Samp, UV.xyz, UV.w);\n\tres += TexCubeArray.SampleCmpLevelZero(Samp, UV, UV.w);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-offset-levelzero-feedback.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tuint feedback;\n\n\tres += Tex1D.SampleCmpLevelZero(Samp, UV.x, UV.w, 1, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex1DArray.SampleCmpLevelZero(Samp, UV.xy, UV.w, 2, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2D.SampleCmpLevelZero(Samp, UV.xy, UV.w, int2(-3, -2), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.SampleCmpLevelZero(Samp, UV.xyz, UV.w, int2(4, 5), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-offset-levelzero.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleCmpLevelZero(Samp, UV.x, UV.w, 1);\n\tres += Tex1DArray.SampleCmpLevelZero(Samp, UV.xy, UV.w, 2);\n\tres += Tex2D.SampleCmpLevelZero(Samp, UV.xy, UV.w, int2(-3, -2));\n\tres += Tex2DArray.SampleCmpLevelZero(Samp, UV.xyz, UV.w, int2(4, 5));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp-offset.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleCmp(Samp, UV.x, UV.w, 1);\n\tres += Tex1DArray.SampleCmp(Samp, UV.xy, UV.w, 2);\n\tres += Tex2D.SampleCmp(Samp, UV.xy, UV.w, int2(-3, -2));\n\tres += Tex2DArray.SampleCmp(Samp, UV.xyz, UV.w, int2(4, 5));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-cmp.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerComparisonState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleCmp(Samp, UV.x, UV.w);\n\tres += Tex1DArray.SampleCmp(Samp, UV.xy, UV.w);\n\tres += Tex2D.SampleCmp(Samp, UV.xy, UV.w);\n\tres += Tex2DArray.SampleCmp(Samp, UV.xyz, UV.w);\n\tres += TexCube.SampleCmp(Samp, UV.xyz, UV.w);\n\tres += TexCubeArray.SampleCmp(Samp, UV, UV.w);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-grad-offset-dynamic.noglsl.invalid.sm67.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\ncbuffer Offsets : register(b0)\n{\n\tint off;\n\tint2 off2;\n\tint3 off3;\n};\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleGrad(Samp, UV.x, UV.z, UV.w, off);\n\tres += Tex1DArray.SampleGrad(Samp, UV.xy, UV.z, UV.y, off);\n\tres += Tex2D.SampleGrad(Samp, UV.xy, UV.zz, UV.ww, off2);\n\tres += Tex2DArray.SampleGrad(Samp, UV.xyz, UV.zz, UV.ww, off2);\n\tres += Tex3D.SampleGrad(Samp, UV.xyz, UV.zzz, UV.www, off3);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-grad-offset-feedback.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tuint feedback;\n\n\tres += Tex1D.SampleGrad(Samp, UV.x, UV.z, UV.w, 1, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex1DArray.SampleGrad(Samp, UV.xy, UV.z, UV.y, 2, 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2D.SampleGrad(Samp, UV.xy, UV.zz, UV.ww, int2(-3, -4), 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.SampleGrad(Samp, UV.xyz, UV.zz, UV.ww, int2(4, -5), 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex3D.SampleGrad(Samp, UV.xyz, UV.zzz, UV.www, int3(5, 6, 7), 0.0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-grad-offset.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleGrad(Samp, UV.x, UV.z, UV.w, 1);\n\tres += Tex1DArray.SampleGrad(Samp, UV.xy, UV.z, UV.y, 2);\n\tres += Tex2D.SampleGrad(Samp, UV.xy, UV.zz, UV.ww, int2(-3, -4));\n\tres += Tex2DArray.SampleGrad(Samp, UV.xyz, UV.zz, UV.ww, int2(4, -5));\n\tres += Tex3D.SampleGrad(Samp, UV.xyz, UV.zzz, UV.www, int3(5, 6, 7));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-grad.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleGrad(Samp, UV.x, UV.z, UV.w);\n\tres += Tex1DArray.SampleGrad(Samp, UV.xy, UV.z, UV.y);\n\tres += Tex2D.SampleGrad(Samp, UV.xy, UV.zz, UV.ww);\n\tres += Tex2DArray.SampleGrad(Samp, UV.xyz, UV.zz, UV.ww);\n\tres += Tex3D.SampleGrad(Samp, UV.xyz, UV.zzz, UV.www);\n\tres += TexCube.SampleGrad(Samp, UV.xyz, UV.zzz, UV.www);\n\tres += TexCubeArray.SampleGrad(Samp, UV, UV.zzz, UV.www);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-id.frag",
    "content": "uint main(uint index : SV_SampleIndex) : SV_Target\n{\n\treturn index;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-level-offset-feedback.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tuint feedback;\n\n\tres += Tex1D.SampleLevel(Samp, UV.x, UV.w, 1, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex1DArray.SampleLevel(Samp, UV.xy, UV.w, 2, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2D.SampleLevel(Samp, UV.xy, UV.w, float2(2, 3), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.SampleLevel(Samp, UV.xyz, UV.w, float2(-1, -3), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex3D.SampleLevel(Samp, UV.xyz, UV.w, float3(-4, -5, 3), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-level-offset.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleLevel(Samp, UV.x, UV.w, 1);\n\tres += Tex1DArray.SampleLevel(Samp, UV.xy, UV.w, 2);\n\tres += Tex2D.SampleLevel(Samp, UV.xy, UV.w, int2(2, 3));\n\tres += Tex2DArray.SampleLevel(Samp, UV.xyz, UV.w, int2(-1, -3));\n\tres += Tex3D.SampleLevel(Samp, UV.xyz, UV.w, int3(-4, -5, 3));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-level.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\tres += Tex1D.SampleLevel(Samp, UV.x, UV.w);\n\tres += Tex1DArray.SampleLevel(Samp, UV.xy, UV.w);\n\tres += Tex2D.SampleLevel(Samp, UV.xy, UV.w);\n\tres += Tex2DArray.SampleLevel(Samp, UV.xyz, UV.w);\n\tres += Tex3D.SampleLevel(Samp, UV.xyz, UV.w);\n\tres += TexCube.SampleLevel(Samp, UV.xyz, UV.w);\n\tres += TexCubeArray.SampleLevel(Samp, UV, UV.w);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-offset-dynamic.noglsl.invalid.sm67.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\ncbuffer Offsets : register(b0)\n{\n\tint off;\n\tint2 off2;\n\tint3 off3;\n};\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\t// Sample without bias.\n\tres += Tex1D.Sample(Samp, UV.x, off);\n\tres += Tex1DArray.Sample(Samp, UV.xy, off);\n\tres += Tex2D.Sample(Samp, UV.xy, off2);\n\tres += Tex2DArray.Sample(Samp, UV.xyz, off2);\n\tres += Tex3D.Sample(Samp, UV.xyz, off3);\n\n\t// TextureCube does not support offset.\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample-offset.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\t// Sample without bias.\n\tres += Tex1D.Sample(Samp, UV.x, 1);\n\tres += Tex1DArray.Sample(Samp, UV.xy, 2);\n\tres += Tex2D.Sample(Samp, UV.xy, int2(3, 4));\n\tres += Tex2DArray.Sample(Samp, UV.xyz, int2(5, 6));\n\tres += Tex3D.Sample(Samp, UV.xyz, int3(7, 6, 5));\n\n\t// TextureCube does not support offset.\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sample.frag",
    "content": "Texture1D<float2> Tex1D : register(t0, space1);\nTexture1DArray<float> Tex1DArray : register(t1, space1);\nTexture2D<float2> Tex2D : register(t2, space1);\nTexture2DArray<float> Tex2DArray : register(t3, space1);\nTexture3D<float2> Tex3D : register(t4, space1);\nTextureCube<float2> TexCube : register(t5, space1);\nTextureCubeArray<float> TexCubeArray : register(t6, space1);\n\nSamplerState Samp : register(s0);\n\nfloat2 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\n\t// Sample without bias.\n\tres += Tex1D.Sample(Samp, UV.x);\n\tres += Tex1DArray.Sample(Samp, UV.xy);\n\tres += Tex2D.Sample(Samp, UV.xy);\n\tres += Tex2DArray.Sample(Samp, UV.xyz);\n\tres += Tex3D.Sample(Samp, UV.xyz);\n\tres += TexCube.Sample(Samp, UV.xyz);\n\tres += TexCubeArray.Sample(Samp, UV);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/saturate.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn saturate(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sin.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn sin(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sm64-packed-arithmetic.ssbo.comp",
    "content": "StructuredBuffer<uint> A;\nStructuredBuffer<uint> B;\nRWStructuredBuffer<uint> C;\n\nStructuredBuffer<half2> D;\nStructuredBuffer<half2> E;\nRWStructuredBuffer<float> F;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tC[thr] = dot4add_u8packed(A[thr], B[thr], C[thr]);\n\tC[thr] = dot4add_i8packed(A[thr], B[thr], C[thr]);\n\tF[thr] = dot2add(half(2.0) * D[thr], half(3.0) * E[thr], F[thr]);\n\tprecise float intermediate = dot2add(half(4.0) * D[thr], half(5.0) * E[thr], F[thr]);\n\tF[thr] = intermediate;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sm64-packed-arithmetic.ssbo.i8dot.noglsl.comp",
    "content": "StructuredBuffer<uint> A;\nStructuredBuffer<uint> B;\nRWStructuredBuffer<uint> C;\n\nStructuredBuffer<half2> D;\nStructuredBuffer<half2> E;\nRWStructuredBuffer<float> F;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tC[thr] = dot4add_u8packed(A[thr], B[thr], C[thr]);\n\tC[thr] = dot4add_i8packed(A[thr], B[thr], C[thr]);\n\tF[thr] = dot2add(half(2.0) * D[thr], half(3.0) * E[thr], F[thr]);\n\tprecise float intermediate = dot2add(half(4.0) * D[thr], half(5.0) * E[thr], F[thr]);\n\tF[thr] = intermediate;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sm64-packed-arithmetic.ssbo.mixed-float-dot-product.noglsl.comp",
    "content": "StructuredBuffer<uint> A;\nStructuredBuffer<uint> B;\nRWStructuredBuffer<uint> C;\n\nStructuredBuffer<half2> D;\nStructuredBuffer<half2> E;\nRWStructuredBuffer<float> F;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tC[thr] = dot4add_u8packed(A[thr], B[thr], C[thr]);\n\tC[thr] = dot4add_i8packed(A[thr], B[thr], C[thr]);\n\tF[thr] = dot2add(half(2.0) * D[thr], half(3.0) * E[thr], F[thr]);\n\tprecise float intermediate = dot2add(half(4.0) * D[thr], half(5.0) * E[thr], F[thr]);\n\tF[thr] = intermediate;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/split-double.frag",
    "content": "uint2 main(float a : A) : SV_Target\n{\n\tuint oa, ob;\n\tasuint(double(a), oa, ob);\n\treturn uint2(oa, ob);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/sqrt.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn sqrt(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/tan.frag",
    "content": "float main(float a : A) : SV_Target\n{\n\treturn tan(a);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather-4offset.frag",
    "content": "Texture2D<float4> Tex2D : register(t3);\n\nSamplerState Samp : register(s1);\n\nfloat4 main(float4 UV : TEXCOORD, nointerpolation int2 off : OFF, int2 off2 : OFF2) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\n\tres += Tex2D.GatherRed(Samp, UV.xy, off, off + off2, off - off2, off2);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather-cmp-offset-feedback.frag",
    "content": "Texture2D<float4> Tex2D : register(t3);\nTexture2DArray<float4> Tex2DArray : register(t4);\n\nSamplerComparisonState Samp : register(s1);\n\nfloat4 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\tuint feedback;\n\n\tres += Tex2D.GatherCmp(Samp, UV.xy, UV.z, int2(-3, -4), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.GatherCmp(Samp, UV.xyz, UV.w, int2(-4, -5), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather-cmp-offset.frag",
    "content": "Texture2D<float4> Tex2D : register(t3);\nTexture2DArray<float4> Tex2DArray : register(t4);\n\nSamplerComparisonState Samp : register(s1);\n\nfloat4 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\n\tres += Tex2D.GatherCmp(Samp, UV.xy, UV.z, int2(-3, -4));\n\tres += Tex2DArray.GatherCmp(Samp, UV.xyz, UV.w, int2(-4, -5));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather-cmp.frag",
    "content": "Texture2D<float4> Tex2D : register(t3);\nTexture2DArray<float4> Tex2DArray : register(t4);\nTextureCube<float4> TexCube : register(t6);\nTextureCubeArray<float4> TexCubeArray : register(t7);\n\nSamplerComparisonState Samp : register(s1);\n\nfloat4 main(float4 UV : TEXCOORD, nointerpolation int2 off : OFF) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\n\tres += Tex2D.GatherCmp(Samp, UV.xy, UV.z);\n\tres += Tex2DArray.GatherCmp(Samp, UV.xyz, UV.w);\n\tres += TexCube.GatherCmp(Samp, UV.xyz, UV.w);\n\tres += TexCubeArray.GatherCmp(Samp, UV, UV.w);\n\n\tres += Tex2D.GatherCmp(Samp, UV.xy, UV.z, off);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather-offset.frag",
    "content": "Texture2D<float4> Tex2D : register(t3);\nTexture2DArray<float4> Tex2DArray : register(t4);\n\nSamplerState Samp : register(s1);\n\nfloat4 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\n\tres += Tex2D.Gather(Samp, UV.xy, int2(1, 2));\n\tres += Tex2DArray.GatherGreen(Samp, UV.xyz, int2(-2, -3));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather-signed-feedback.frag",
    "content": "Texture2D<int4> Tex2D : register(t3);\nTexture2DArray<int4> Tex2DArray : register(t4);\nTextureCube<int4> TexCube : register(t6);\nTextureCubeArray<int4> TexCubeArray : register(t7);\n\nSamplerState Samp : register(s1);\n\nint4 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tint4 res = int4(0, 0, 0, 0);\n\tuint feedback;\n\n\tres += Tex2D.Gather(Samp, UV.xy, int2(0, 1), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.GatherGreen(Samp, UV.xyz, int2(0, 1), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += TexCube.GatherBlue(Samp, UV.xyz, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += TexCubeArray.GatherAlpha(Samp, UV, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather-signed.frag",
    "content": "Texture2D<int4> Tex2D : register(t3);\nTexture2DArray<int4> Tex2DArray : register(t4);\nTextureCube<int4> TexCube : register(t6);\nTextureCubeArray<int4> TexCubeArray : register(t7);\n\nSamplerState Samp : register(s1);\n\nint4 main(float4 UV : TEXCOORD) : SV_Target\n{\n\tint4 res = int4(0, 0, 0, 0);\n\n\tres += Tex2D.Gather(Samp, UV.xy);\n\tres += Tex2DArray.GatherGreen(Samp, UV.xyz);\n\tres += TexCube.GatherBlue(Samp, UV.xyz);\n\tres += TexCubeArray.GatherAlpha(Samp, UV);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-gather.frag",
    "content": "Texture2D<float4> Tex2D : register(t3);\nTexture2DArray<float4> Tex2DArray : register(t4);\nTextureCube<float4> TexCube : register(t6);\nTextureCubeArray<float4> TexCubeArray : register(t7);\n\nSamplerState Samp : register(s1);\n\nfloat4 main(float4 UV : TEXCOORD, nointerpolation int2 off : OFF) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\n\tres += Tex2D.Gather(Samp, UV.xy);\n\tres += Tex2DArray.GatherGreen(Samp, UV.xyz);\n\tres += TexCube.GatherBlue(Samp, UV.xyz);\n\tres += TexCubeArray.GatherAlpha(Samp, UV);\n\n\tres += Tex2D.Gather(Samp, UV.xy, off);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-load-feedback.frag",
    "content": "Texture1D<float2> Tex1D : register(t1);\nTexture1DArray<float2> Tex1DArray : register(t2);\nTexture2D<float2> Tex2D : register(t3);\nTexture2DArray<float2> Tex2DArray : register(t4);\nTexture3D<float2> Tex3D : register(t5);\n\nTexture2DMS<float2> Tex2DMS : register(t6);\nTexture2DMSArray<float2> Tex2DMSArray : register(t7);\n\nRWTexture1D<float2> RWTex1D : register(u1);\nRWTexture1DArray<float2> RWTex1DArray : register(u2);\nRWTexture2D<float2> RWTex2D : register(u3);\nRWTexture2DArray<float2> RWTex2DArray : register(u4);\nRWTexture3D<float2> RWTex3D : register(u5);\n\nfloat2 main(nointerpolation uint4 coord : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tuint feedback;\n\n\tres += Tex1D.Load(coord.xy, 0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex1DArray.Load(coord.xyz, 0, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2D.Load(coord.xyz, int2(0, 0), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DArray.Load(coord.xyzw, int2(0, 0), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex3D.Load(coord.xyzw, int3(0, 0, 0), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\tres += Tex2DMS.Load(coord.xy, coord.z, int2(0, 0), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += Tex2DMSArray.Load(coord.xyz, coord.w, int2(0, 0), feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\tres += RWTex1D.Load(coord.x, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += RWTex1DArray.Load(coord.xy, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += RWTex2D.Load(coord.xy, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += RWTex2DArray.Load(coord.xyz, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\tres += RWTex3D.Load(coord.xyz, feedback);\n\tres += CheckAccessFullyMapped(feedback) ? 1 : 0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-load-offset-dynamic.sm67.frag",
    "content": "Texture1D<float2> Tex1D : register(t1);\nTexture1DArray<float2> Tex1DArray : register(t2);\nTexture2D<float2> Tex2D : register(t3);\nTexture2DArray<float2> Tex2DArray : register(t4);\nTexture3D<float2> Tex3D : register(t5);\n\nTexture2DMS<float2> Tex2DMS : register(t6);\nTexture2DMSArray<float2> Tex2DMSArray : register(t7);\n\ncbuffer Offsets : register(b0)\n{\n\tint off;\n\tint2 off2;\n\tint3 off3;\n};\n\nfloat2 main(nointerpolation uint4 coord : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tres += Tex1D.Load(coord.xy, off);\n\tres += Tex1DArray.Load(coord.xyz, off);\n\tres += Tex2D.Load(coord.xyz, off2);\n\tres += Tex2DArray.Load(coord.xyzw, off2);\n\tres += Tex3D.Load(coord.xyzw, off3);\n\n\tres += Tex2DMS.Load(coord.xy, coord.z, off2);\n\tres += Tex2DMSArray.Load(coord.xyz, coord.w, off2);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-load-offset.frag",
    "content": "Texture1D<float2> Tex1D : register(t1);\nTexture1DArray<float2> Tex1DArray : register(t2);\nTexture2D<float2> Tex2D : register(t3);\nTexture2DArray<float2> Tex2DArray : register(t4);\nTexture3D<float2> Tex3D : register(t5);\n\nTexture2DMS<float2> Tex2DMS : register(t6);\nTexture2DMSArray<float2> Tex2DMSArray : register(t7);\n\nfloat2 main(nointerpolation uint4 coord : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tres += Tex1D.Load(coord.xy, 1);\n\tres += Tex1DArray.Load(coord.xyz, 2);\n\tres += Tex2D.Load(coord.xyz, int2(3, 4));\n\tres += Tex2DArray.Load(coord.xyzw, int2(-4, -3));\n\tres += Tex3D.Load(coord.xyzw, int3(-4, 2, 3));\n\n\tres += Tex2DMS.Load(coord.xy, coord.z, int2(2, 3));\n\tres += Tex2DMSArray.Load(coord.xyz, coord.w, int2(4, 5));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-load-signed.frag",
    "content": "Texture1D<int2> Tex1D : register(t1);\nTexture1DArray<int2> Tex1DArray : register(t2);\nTexture2D<int2> Tex2D : register(t3);\nTexture2DArray<int2> Tex2DArray : register(t4);\nTexture3D<int2> Tex3D : register(t5);\n\nTexture2DMS<int2> Tex2DMS : register(t6);\nTexture2DMSArray<int2> Tex2DMSArray : register(t7);\n\nRWTexture1D<int2> RWTex1D : register(u1);\nRWTexture1DArray<int2> RWTex1DArray : register(u2);\nRWTexture2D<int2> RWTex2D : register(u3);\nRWTexture2DArray<int2> RWTex2DArray : register(u4);\nRWTexture3D<int2> RWTex3D : register(u5);\n\nint2 main(nointerpolation uint4 coord : TEXCOORD) : SV_Target\n{\n\tint2 res = int2(0, 0);\n\tres += Tex1D.Load(coord.xy);\n\tres += Tex1DArray.Load(coord.xyz);\n\tres += Tex2D.Load(coord.xyz);\n\tres += Tex2DArray.Load(coord.xyzw);\n\tres += Tex3D.Load(coord.xyzw);\n\n\tres += Tex2DMS.Load(coord.xy, coord.z);\n\tres += Tex2DMSArray.Load(coord.xyz, coord.w);\n\n\tres += RWTex1D.Load(coord.x);\n\tres += RWTex1DArray.Load(coord.xy);\n\tres += RWTex2D.Load(coord.xy);\n\tres += RWTex2DArray.Load(coord.xyz);\n\tres += RWTex3D.Load(coord.xyz);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-load.frag",
    "content": "Texture1D<float2> Tex1D : register(t1);\nTexture1DArray<float2> Tex1DArray : register(t2);\nTexture2D<float2> Tex2D : register(t3);\nTexture2DArray<float2> Tex2DArray : register(t4);\nTexture3D<float2> Tex3D : register(t5);\n\nTexture2DMS<float2> Tex2DMS : register(t6);\nTexture2DMSArray<float2> Tex2DMSArray : register(t7);\n\nRWTexture1D<float2> RWTex1D : register(u1);\nRWTexture1DArray<float2> RWTex1DArray : register(u2);\nRWTexture2D<float2> RWTex2D : register(u3);\nRWTexture2DArray<float2> RWTex2DArray : register(u4);\nRWTexture3D<float2> RWTex3D : register(u5);\n\nfloat2 main(nointerpolation uint4 coord : TEXCOORD) : SV_Target\n{\n\tfloat2 res = 0.0.xx;\n\tres += Tex1D.Load(coord.xy);\n\tres += Tex1DArray.Load(coord.xyz);\n\tres += Tex2D.Load(coord.xyz);\n\tres += Tex2DArray.Load(coord.xyzw);\n\tres += Tex3D.Load(coord.xyzw);\n\n\tres += Tex2DMS.Load(coord.xy, coord.z);\n\tres += Tex2DMSArray.Load(coord.xyz, coord.w);\n\n\tres += RWTex1D.Load(coord.x);\n\tres += RWTex1DArray.Load(coord.xy);\n\tres += RWTex2D.Load(coord.xy);\n\tres += RWTex2DArray.Load(coord.xyz);\n\tres += RWTex3D.Load(coord.xyz);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-store-signed.frag",
    "content": "RWTexture1D<int2> RWTex1D : register(u1);\ngloballycoherent RWTexture1DArray<int2> RWTex1DArray : register(u2);\nRWTexture2D<int2> RWTex2D : register(u3);\ngloballycoherent RWTexture2DArray<int2> RWTex2DArray : register(u4);\nRWTexture3D<int2> RWTex3D : register(u5);\n\nvoid main(float3 uv : TEXCOORD)\n{\n\tRWTex1D[int(uv.x)] = int2(1, 2);\n\tRWTex1DArray[int2(uv.xy)] = int2(3, 4);\n\tRWTex2D[int2(uv.xy)] = int2(5, 6);\n\tRWTex2DArray[int3(uv.xyz)] = int2(7, 8);\n\tRWTex3D[int3(uv.xyz)] = int2(9, -9);\n}\n\n"
  },
  {
    "path": "shaders/dxil-builtin/texture-store.frag",
    "content": "RWTexture1D<float2> RWTex1D : register(u1);\ngloballycoherent RWTexture1DArray<float2> RWTex1DArray : register(u2);\nRWTexture2D<float2> RWTex2D : register(u3);\ngloballycoherent RWTexture2DArray<float2> RWTex2DArray : register(u4);\nRWTexture3D<float2> RWTex3D : register(u5);\n\nvoid main(float3 uv : TEXCOORD)\n{\n\tRWTex1D[int(uv.x)] = float2(1, 2);\n\tRWTex1DArray[int2(uv.xy)] = float2(3, 4);\n\tRWTex2D[int2(uv.xy)] = float2(5, 6);\n\tRWTex2DArray[int3(uv.xyz)] = float2(7, 8);\n\tRWTex3D[int3(uv.xyz)] = float2(9, -9);\n}\n\n"
  },
  {
    "path": "shaders/dxil-builtin/texture2dms-sample-position.frag",
    "content": "uint index;\nTexture2DMS<float4> t;\n\nfloat4 main() : SV_Target\n{\n\treturn float4(t.GetSamplePosition(index), 0, 0);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/thread_id.comp",
    "content": "RWStructuredBuffer<float> RWBuf : register(u0);\n\n[numthreads(2, 2, 2)]\nvoid main(uint3 ThreadID : SV_DispatchThreadID)\n{\n\tRWBuf[ThreadID.x] = 10.0;\n\tRWBuf[ThreadID.y] = 20.0;\n\tRWBuf[ThreadID.z] = 30.0;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/thread_id_in_group.comp",
    "content": "RWStructuredBuffer<float> RWBuf : register(u0);\n\n[numthreads(2, 2, 2)]\nvoid main(uint3 ThreadID : SV_GroupThreadID)\n{\n\tRWBuf[ThreadID.x] = 10.0;\n\tRWBuf[ThreadID.y] = 20.0;\n\tRWBuf[ThreadID.z] = 30.0;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/trace-ray-flags-2.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS : register(t0);\nRWTexture2D<float4> IMG : register(u0);\n\ncbuffer Flags : register(b0)\n{\n\tuint flags;\n};\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(4, 5, 6);\n\tray.TMin = 7.0;\n\tray.TMax = 8.0;\n\n\tPayload payload0;\n\tTraceRay(AS, flags, 0, 1, 2, 3, ray, payload0);\n\n\tIMG[int2(0, 0)] = payload0.color;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/trace-ray-flags.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS : register(t0);\nRWTexture2D<float4> IMG : register(u0);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(4, 5, 6);\n\tray.TMin = 7.0;\n\tray.TMax = 8.0;\n\n\tPayload payload0;\n\tTraceRay(AS, 17 | 0x100, 0, 1, 2, 3, ray, payload0);\n\n\tIMG[int2(0, 0)] = payload0.color;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/trace-ray.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS : register(t0);\nRWTexture2D<float4> IMG : register(u0);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(4, 5, 6);\n\tray.TMin = 7.0;\n\tray.TMax = 8.0;\n\n\tPayload payload0;\n\tTraceRay(AS, 17, 0, 1, 2, 3, ray, payload0);\n\n\tIMG[int2(0, 0)] = payload0.color;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/umad.frag",
    "content": "uint main(nointerpolation uint3 a : A) : SV_Target\n{\n\treturn mad(a.x, a.y, a.z);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/umax.frag",
    "content": "uint main(nointerpolation uint2 a : A) : SV_Target\n{\n\treturn max(a.x, a.y);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/umin.frag",
    "content": "uint main(nointerpolation uint2 a : A) : SV_Target\n{\n\treturn min(a.x, a.y);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/vertex-id.vert",
    "content": "float4 main(uint ID : SV_VertexID) : SV_Position\n{\n\tfloat res = float(ID);\n\treturn res.xxxx;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-all-true.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tbool all_true = WaveActiveAllTrue(index < 100);\n\tif (all_true)\n\t\tBuf.Store(index * 4, 1);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-all-true.frag",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\n\tbool all_true = WaveActiveAllTrue(index < 100);\n\tif (all_true)\n\t\tBuf.Store(index * 4, 1);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-any-true.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tbool any_true = WaveActiveAnyTrue(index < 100);\n\tif (any_true)\n\t\tBuf.Store(index * 4, 1);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-any-true.frag",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\n\tbool any_true = WaveActiveAnyTrue(index < 100);\n\tif (any_true)\n\t\tBuf.Store(index * 4, 1);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-ballot-discard.demote-to-helper.frag",
    "content": "uint4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\tif (index == 40)\n\t\tdiscard;\n\tuint4 ballot = WaveActiveBallot(index < 100);\n\treturn ballot;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-ballot-discard.frag",
    "content": "uint4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\tif (index == 40)\n\t\tdiscard;\n\tuint4 ballot = WaveActiveBallot(index < 100);\n\treturn ballot;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-ballot.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint4 ballot = WaveActiveBallot(index < 100);\n\tBuf.Store4(index * 16, ballot);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-ballot.demote-to-helper.frag",
    "content": "uint4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\tuint4 ballot = WaveActiveBallot(index < 100);\n\treturn ballot;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-ballot.frag",
    "content": "uint4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\tuint4 ballot = WaveActiveBallot(index < 100);\n\treturn ballot;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-count-bits.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint value = WaveActiveCountBits(index < 100);\n\tBuf.Store(index * 4, value);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-active-count-bits.frag",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\n\tuint value = WaveActiveCountBits(index < 100);\n\tBuf.Store(index * 4, value);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-all-equal.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tbool all_equal = WaveActiveAllEqual(index);\n\tif (all_equal)\n\t\tBuf.Store(index * 4, 1);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-all-equal.frag",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\tbool all_equal = WaveActiveAllEqual(index);\n\tif (all_equal)\n\t\tBuf.Store(index * 4, 1);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-get-lane-count.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main()\n{\n\tBuf.Store(0, WaveGetLaneCount());\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-get-lane-index.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main()\n{\n\tBuf.Store(0, WaveGetLaneIndex());\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-is-first-lane.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main()\n{\n\tif (WaveIsFirstLane())\n\t\tBuf.Store(0, 1);\n\telse\n\t\tBuf.Store(0, 0);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-is-first-lane.frag",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nvoid main(uint thr : THR)\n{\n\tif (thr == 40)\n\t\tdiscard;\n\n\tif (WaveIsFirstLane())\n\t\tBuf.Store(0, 1);\n\telse\n\t\tBuf.Store(0, 0);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-match.comp",
    "content": "StructuredBuffer<uint> RO;\nRWStructuredBuffer<uint4> RW;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] =\n\t\tWaveMatch(RO[thr]) |\n\t\tWaveMatch(asfloat(RO[thr])) |\n\t\tWaveMatch(bool(RO[thr] != 20));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-match.frag",
    "content": "StructuredBuffer<uint> RO;\nRWStructuredBuffer<uint4> RW;\n\nvoid main(uint thr : THR)\n{\n\tif (thr == 40)\n\t\tdiscard;\n\tRW[thr] =\n\t\tWaveMatch(RO[thr]) |\n\t\tWaveMatch(asfloat(RO[thr])) |\n\t\tWaveMatch(bool(RO[thr] != 20));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-match.partitioned.noglsl.comp",
    "content": "StructuredBuffer<uint> RO;\nRWStructuredBuffer<uint4> RW;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] =\n\t\tWaveMatch(RO[thr]) |\n\t\tWaveMatch(asfloat(RO[thr])) |\n\t\tWaveMatch(bool(RO[thr] != 20));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-match.partitioned.noglsl.frag",
    "content": "StructuredBuffer<uint> RO;\nRWStructuredBuffer<uint4> RW;\n\nvoid main(uint thr : THR)\n{\n\tRW[thr] =\n\t\tWaveMatch(RO[thr]) |\n\t\tWaveMatch(asfloat(RO[thr])) |\n\t\tWaveMatch(bool(RO[thr] != 20));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-multi-prefix-count-bits.comp",
    "content": "StructuredBuffer<uint> RO;\nStructuredBuffer<uint4> ROMask;\nRWStructuredBuffer<uint> RW;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = WaveMultiPrefixCountBits(RO[thr] != 10, ROMask[thr]);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-multi-prefix-count-bits.frag",
    "content": "StructuredBuffer<uint> RO;\nStructuredBuffer<uint4> ROMask;\nRWStructuredBuffer<uint> RW;\n\nvoid main(uint thr : THR)\n{\n\tif (thr == 40)\n\t\tdiscard;\n\tRW[thr] = WaveMultiPrefixCountBits(RO[thr] != 10, ROMask[thr]);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-multi-prefix-op.comp",
    "content": "StructuredBuffer<uint> RO;\nStructuredBuffer<uint4> ROMask;\nRWStructuredBuffer<uint> RW;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[7 * thr + 0] = WaveMultiPrefixSum(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 1] = WaveMultiPrefixSum(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 2] = WaveMultiPrefixProduct(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 3] = WaveMultiPrefixProduct(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 4] = WaveMultiPrefixBitOr(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 5] = WaveMultiPrefixBitAnd(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 6] = WaveMultiPrefixBitXor(asfloat(RO[thr]), ROMask[thr]);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-multi-prefix-op.frag",
    "content": "StructuredBuffer<uint> RO;\nStructuredBuffer<uint4> ROMask;\nRWStructuredBuffer<uint> RW;\n\nvoid main(uint thr : THR)\n{\n\tRW[7 * thr + 0] = WaveMultiPrefixSum(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 1] = WaveMultiPrefixSum(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 2] = WaveMultiPrefixProduct(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 3] = WaveMultiPrefixProduct(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 4] = WaveMultiPrefixBitOr(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 5] = WaveMultiPrefixBitAnd(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 6] = WaveMultiPrefixBitXor(asfloat(RO[thr]), ROMask[thr]);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-multi-prefix-op.partitioned.noglsl.comp",
    "content": "StructuredBuffer<uint> RO;\nStructuredBuffer<uint4> ROMask;\nRWStructuredBuffer<uint> RW;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[7 * thr + 0] = WaveMultiPrefixSum(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 1] = WaveMultiPrefixSum(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 2] = WaveMultiPrefixProduct(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 3] = WaveMultiPrefixProduct(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 4] = WaveMultiPrefixBitOr(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 5] = WaveMultiPrefixBitAnd(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 6] = WaveMultiPrefixBitXor(asfloat(RO[thr]), ROMask[thr]);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-multi-prefix-op.partitioned.noglsl.frag",
    "content": "StructuredBuffer<uint> RO;\nStructuredBuffer<uint4> ROMask;\nRWStructuredBuffer<uint> RW;\n\nvoid main(uint thr : THR)\n{\n\tRW[7 * thr + 0] = WaveMultiPrefixSum(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 1] = WaveMultiPrefixSum(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 2] = WaveMultiPrefixProduct(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 3] = WaveMultiPrefixProduct(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 4] = WaveMultiPrefixBitOr(RO[thr], ROMask[thr]);\n\tRW[7 * thr + 5] = WaveMultiPrefixBitAnd(asfloat(RO[thr]), ROMask[thr]);\n\tRW[7 * thr + 6] = WaveMultiPrefixBitXor(asfloat(RO[thr]), ROMask[thr]);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-prefix.comp",
    "content": "RWByteAddressBuffer BufU : register(u0);\nRWByteAddressBuffer BufI : register(u1);\nRWByteAddressBuffer BufF : register(u2);\n\nstatic const uint STRIDE = 8;\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint value;\n\n\tvalue = WavePrefixCountBits(index < 100);\n\tBufU.Store(index * STRIDE, value);\n\n\t// uint\n\t{\n\t\tvalue = WavePrefixSum(index);\n\t\tBufU.Store(index * STRIDE, value);\n\t\tvalue = WavePrefixProduct(index);\n\t\tBufU.Store(index * STRIDE + 4, value);\n\t}\n\n\t// int\n\t{\n\t\tint iindex = index;\n\t\tvalue = WavePrefixSum(iindex);\n\t\tBufI.Store(index * STRIDE, value);\n\t\tvalue = WavePrefixProduct(iindex);\n\t\tBufI.Store(index * STRIDE + 4, value);\n\t}\n\n\t// float\n\t{\n\t\tfloat findex = index;\n\t\tvalue = WavePrefixSum(findex);\n\t\tBufF.Store(index * STRIDE, value);\n\t\tvalue = WavePrefixProduct(findex);\n\t\tBufF.Store(index * STRIDE + 4, value);\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-prefix.frag",
    "content": "RWByteAddressBuffer BufU : register(u0);\nRWByteAddressBuffer BufI : register(u1);\nRWByteAddressBuffer BufF : register(u2);\n\nstatic const uint STRIDE = 8;\n\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\tuint value;\n\n\tvalue = WavePrefixCountBits(index < 100);\n\tBufU.Store(index * STRIDE, value);\n\n\t// uint\n\t{\n\t\tvalue = WavePrefixSum(index);\n\t\tBufU.Store(index * STRIDE, value);\n\t\tvalue = WavePrefixProduct(index);\n\t\tBufU.Store(index * STRIDE + 4, value);\n\t}\n\n\t// int\n\t{\n\t\tint iindex = index;\n\t\tvalue = WavePrefixSum(iindex);\n\t\tBufI.Store(index * STRIDE, value);\n\t\tvalue = WavePrefixProduct(iindex);\n\t\tBufI.Store(index * STRIDE + 4, value);\n\t}\n\n\t// float\n\t{\n\t\tfloat findex = index;\n\t\tvalue = WavePrefixSum(findex);\n\t\tBufF.Store(index * STRIDE, value);\n\t\tvalue = WavePrefixProduct(findex);\n\t\tBufF.Store(index * STRIDE + 4, value);\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-read-lane-at-optimizations.comp",
    "content": "RWStructuredBuffer<float> F : register(u0);\n\nuint get_quad_shuffle_add(uint index)\n{\n\treturn (WaveGetLaneIndex() & ~3) + index;\n}\n\nuint get_quad_shuffle_or(uint index)\n{\n\treturn (WaveGetLaneIndex() & ~3) | index;\n}\n\n[numthreads(64, 1, 1)]\nvoid main(uint2 thr : SV_DispatchThreadID)\n{\n\tfloat v = F[thr.x];\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_add(0));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_add(1));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_add(2));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_add(3));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_add(4));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_or(0));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_or(1));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_or(2));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_or(3));\n\tF[thr.x] += WaveReadLaneAt(v, get_quad_shuffle_or(4));\n\tF[thr.x] += WaveReadLaneAt(v, WaveGetLaneIndex() & ~3);\n\tF[thr.x] += WaveReadLaneAt(v, WaveGetLaneIndex() | 3);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-read-lane-at.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint3 first_value = WaveReadLaneAt(index, index.x & (WaveGetLaneCount() - 1));\n\tfirst_value += WaveReadLaneAt(index, 11);\n\tfirst_value += WaveReadLaneAt(index, WaveGetLaneIndex() ^ 1);\n\tfirst_value += WaveReadLaneAt(index, WaveGetLaneIndex() ^ 2);\n\tfirst_value += WaveReadLaneAt(index, WaveGetLaneIndex() ^ 3);\n\tfirst_value += WaveReadLaneAt(index, WaveGetLaneIndex() ^ 4);\n\tfirst_value += WaveReadLaneAt(index, WaveGetLaneIndex() ^ 8);\n\tfirst_value += WaveReadLaneAt(index, 16 ^ WaveGetLaneIndex());\n\tfirst_value += WaveReadLaneAt(index, 32 ^ WaveGetLaneIndex());\n\n\tBuf.Store3(index.x * 12, first_value);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-read-lane-first.comp",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint3 index : SV_DispatchThreadID)\n{\n\tuint3 first_value = WaveReadLaneFirst(index);\n\tBuf.Store3(index.x * 12, first_value);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-read-lane-first.frag",
    "content": "RWByteAddressBuffer Buf : register(u0);\n\nvoid main(uint3 index : INDEX)\n{\n\tif (index.x == 40)\n\t\tdiscard;\n\tuint3 first_value = WaveReadLaneFirst(index);\n\tBuf.Store3(index.x * 12, first_value);\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-reduce-helpers.sm67.frag",
    "content": "RWByteAddressBuffer BufU : register(u0);\nRWByteAddressBuffer BufI : register(u1);\nRWByteAddressBuffer BufF : register(u2);\n\nstatic const uint STRIDE = 28;\n\n[WaveOpsIncludeHelperLanes]\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\tuint value;\n\n\t// uint\n\t{\n\t\tvalue = WaveActiveSum(index);\n\t\tBufU.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(index);\n\t\tBufU.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(index);\n\t\tBufU.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(index);\n\t\tBufU.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(index);\n\t\tBufU.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(index);\n\t\tBufU.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(index);\n\t\tBufU.Store(index * STRIDE + 24, value);\n\t}\n\n\t// int\n\t{\n\t\tint iindex = index;\n\t\tvalue = WaveActiveSum(iindex);\n\t\tBufI.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(iindex);\n\t\tBufI.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(iindex);\n\t\tBufI.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(iindex);\n\t\tBufI.Store(index * STRIDE + 24, value);\n\t}\n\n\t// float\n\t{\n\t\tfloat findex = index;\n\t\tvalue = WaveActiveSum(findex);\n\t\tBufF.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(findex);\n\t\tBufF.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveMin(findex);\n\t\tBufF.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(findex);\n\t\tBufF.Store(index * STRIDE + 24, value);\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-reduce-helpers.sm67.quad-maximal-reconvergence.frag",
    "content": "RWByteAddressBuffer BufU : register(u0);\nRWByteAddressBuffer BufI : register(u1);\nRWByteAddressBuffer BufF : register(u2);\n\nstatic const uint STRIDE = 28;\n\n[WaveOpsIncludeHelperLanes]\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\tuint value;\n\n\t// uint\n\t{\n\t\tvalue = WaveActiveSum(index);\n\t\tBufU.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(index);\n\t\tBufU.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(index);\n\t\tBufU.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(index);\n\t\tBufU.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(index);\n\t\tBufU.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(index);\n\t\tBufU.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(index);\n\t\tBufU.Store(index * STRIDE + 24, value);\n\t}\n\n\t// int\n\t{\n\t\tint iindex = index;\n\t\tvalue = WaveActiveSum(iindex);\n\t\tBufI.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(iindex);\n\t\tBufI.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(iindex);\n\t\tBufI.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(iindex);\n\t\tBufI.Store(index * STRIDE + 24, value);\n\t}\n\n\t// float\n\t{\n\t\tfloat findex = index;\n\t\tvalue = WaveActiveSum(findex);\n\t\tBufF.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(findex);\n\t\tBufF.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveMin(findex);\n\t\tBufF.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(findex);\n\t\tBufF.Store(index * STRIDE + 24, value);\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-reduce.comp",
    "content": "RWByteAddressBuffer BufU : register(u0);\nRWByteAddressBuffer BufI : register(u1);\nRWByteAddressBuffer BufF : register(u2);\n\nstatic const uint STRIDE = 28;\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint value;\n\n\t// uint\n\t{\n\t\tvalue = WaveActiveSum(index);\n\t\tBufU.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(index);\n\t\tBufU.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(index);\n\t\tBufU.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(index);\n\t\tBufU.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(index);\n\t\tBufU.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(index);\n\t\tBufU.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(index);\n\t\tBufU.Store(index * STRIDE + 24, value);\n\t}\n\n\t// int\n\t{\n\t\tint iindex = index;\n\t\tvalue = WaveActiveSum(iindex);\n\t\tBufI.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(iindex);\n\t\tBufI.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(iindex);\n\t\tBufI.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(iindex);\n\t\tBufI.Store(index * STRIDE + 24, value);\n\t}\n\n\t// float\n\t{\n\t\tfloat findex = index;\n\t\tvalue = WaveActiveSum(findex);\n\t\tBufF.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(findex);\n\t\tBufF.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveMin(findex);\n\t\tBufF.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(findex);\n\t\tBufF.Store(index * STRIDE + 24, value);\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-reduce.frag",
    "content": "RWByteAddressBuffer BufU : register(u0);\nRWByteAddressBuffer BufI : register(u1);\nRWByteAddressBuffer BufF : register(u2);\n\nstatic const uint STRIDE = 28;\n\nvoid main(uint index : INDEX)\n{\n\tif (index == 40)\n\t\tdiscard;\n\tuint value;\n\n\t// uint\n\t{\n\t\tvalue = WaveActiveSum(index);\n\t\tBufU.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(index);\n\t\tBufU.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(index);\n\t\tBufU.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(index);\n\t\tBufU.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(index);\n\t\tBufU.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(index);\n\t\tBufU.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(index);\n\t\tBufU.Store(index * STRIDE + 24, value);\n\t}\n\n\t// int\n\t{\n\t\tint iindex = index;\n\t\tvalue = WaveActiveSum(iindex);\n\t\tBufI.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(iindex);\n\t\tBufI.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveBitAnd(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 8, value);\n\t\tvalue = WaveActiveBitOr(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 12, value);\n\t\tvalue = WaveActiveBitXor(uint(iindex));\n\t\tBufI.Store(index * STRIDE + 16, value);\n\t\tvalue = WaveActiveMin(iindex);\n\t\tBufI.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(iindex);\n\t\tBufI.Store(index * STRIDE + 24, value);\n\t}\n\n\t// float\n\t{\n\t\tfloat findex = index;\n\t\tvalue = WaveActiveSum(findex);\n\t\tBufF.Store(index * STRIDE, value);\n\t\tvalue = WaveActiveProduct(findex);\n\t\tBufF.Store(index * STRIDE + 4, value);\n\t\tvalue = WaveActiveMin(findex);\n\t\tBufF.Store(index * STRIDE + 20, value);\n\t\tvalue = WaveActiveMax(findex);\n\t\tBufF.Store(index * STRIDE + 24, value);\n\t}\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/wave-size.sm66.comp",
    "content": "RWStructuredBuffer<float> RW : register(u0);\n\n[WaveSize(128)]\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = 10.0;\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/world-ray-direction.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = WorldRayDirection();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/world-ray-origin.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = WorldRayOrigin();\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/world-to-object-3x4.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = mul(WorldToObject3x4(), float4(payload.orig, 1.0));\n}\n"
  },
  {
    "path": "shaders/dxil-builtin/world-to-object-4x3.rany",
    "content": "struct Payload\n{\n\tfloat3 orig;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.orig = mul(float4(payload.orig, 1.0), WorldToObject4x3());\n}\n"
  },
  {
    "path": "shaders/fp16/saturate.frag",
    "content": "half4 main(half4 v : V) : SV_Target\n{\n\treturn saturate(v);\n}\n"
  },
  {
    "path": "shaders/fp16/saturate.sm60.frag",
    "content": "min16float4 main(min16float4 v : V) : SV_Target\n{\n\treturn saturate(v);\n}\n"
  },
  {
    "path": "shaders/fp16/saturate.sm60.native-fp16.frag",
    "content": "min16float4 main(min16float4 v : V) : SV_Target\n{\n\treturn saturate(v);\n}\n"
  },
  {
    "path": "shaders/heap-robustness/misc.bindless.heap-raw-va-cbv.sm66.ssbo.comp",
    "content": "Texture2D<float4> Tex[] : register(t0, space0);\nSamplerState S[] : register(s0, space0);\nRWTexture2D<float4> RWTex[] : register(u0, space0);\nRWBuffer<float4> RWBuf[] : register(u0, space1);\nRWStructuredBuffer<float4> RWStruct[] : register(u0, space2);\n\nstruct C { float4 v; };\nConstantBuffer<C> Cbufs[] : register(b0, space0);\n\nRWStructuredBuffer<float4> Blah : register(u100, space3);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBlah[thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWTex[NonUniformResourceIndex(thr)][int2(thr, 0)] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWBuf[NonUniformResourceIndex(thr)][thr] = Cbufs[NonUniformResourceIndex(thr)].v;\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)][thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)].IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n\n\tTexture2D<float4> HeapTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr)];\n\tSamplerState HeapS = SamplerDescriptorHeap[NonUniformResourceIndex(thr + 100)];\n\tRWTexture2D<float4> HeapRWTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 200)];\n\tRWBuffer<float4> HeapRWBuf = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 300)];\n\tRWStructuredBuffer<float4> HeapRWStruct = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 400)];\n\tConstantBuffer<C> HeapCbufs = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 500)];\n\n\tBlah[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWTex[int2(thr, 0)] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWBuf[thr] = HeapCbufs.v;\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct.IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n}\n"
  },
  {
    "path": "shaders/heap-robustness/misc.bindless.heap-robustness.heap-robustness-cbv.sm66.ssbo.comp",
    "content": "Texture2D<float4> Tex[] : register(t0, space0);\nSamplerState S[] : register(s0, space0);\nRWTexture2D<float4> RWTex[] : register(u0, space0);\nRWBuffer<float4> RWBuf[] : register(u0, space1);\nRWStructuredBuffer<float4> RWStruct[] : register(u0, space2);\n\nstruct C { float4 v; };\nConstantBuffer<C> Cbufs[] : register(b0, space0);\n\nRWStructuredBuffer<float4> Blah : register(u100, space3);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBlah[thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWTex[NonUniformResourceIndex(thr)][int2(thr, 0)] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWBuf[NonUniformResourceIndex(thr)][thr] = Cbufs[NonUniformResourceIndex(thr)].v;\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)][thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)].IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n\n\tTexture2D<float4> HeapTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr)];\n\tSamplerState HeapS = SamplerDescriptorHeap[NonUniformResourceIndex(thr + 100)];\n\tRWTexture2D<float4> HeapRWTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 200)];\n\tRWBuffer<float4> HeapRWBuf = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 300)];\n\tRWStructuredBuffer<float4> HeapRWStruct = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 400)];\n\tConstantBuffer<C> HeapCbufs = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 500)];\n\n\tBlah[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWTex[int2(thr, 0)] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWBuf[thr] = HeapCbufs.v;\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct.IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n}\n"
  },
  {
    "path": "shaders/heap-robustness/misc.bindless.heap-robustness.sm66.ssbo.comp",
    "content": "Texture2D<float4> Tex[] : register(t0, space0);\nSamplerState S[] : register(s0, space0);\nRWTexture2D<float4> RWTex[] : register(u0, space0);\nRWBuffer<float4> RWBuf[] : register(u0, space1);\nRWStructuredBuffer<float4> RWStruct[] : register(u0, space2);\n\nstruct C { float4 v; };\nConstantBuffer<C> Cbufs[] : register(b0, space0);\n\nRWStructuredBuffer<float4> Blah : register(u100, space3);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBlah[thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWTex[NonUniformResourceIndex(thr)][int2(thr, 0)] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWBuf[NonUniformResourceIndex(thr)][thr] = Cbufs[NonUniformResourceIndex(thr)].v;\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)][thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)].IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n\n\tTexture2D<float4> HeapTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr)];\n\tSamplerState HeapS = SamplerDescriptorHeap[NonUniformResourceIndex(thr + 100)];\n\tRWTexture2D<float4> HeapRWTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 200)];\n\tRWBuffer<float4> HeapRWBuf = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 300)];\n\tRWStructuredBuffer<float4> HeapRWStruct = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 400)];\n\tConstantBuffer<C> HeapCbufs = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 500)];\n\n\tBlah[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWTex[int2(thr, 0)] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWBuf[thr] = HeapCbufs.v;\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct.IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n}\n"
  },
  {
    "path": "shaders/heap-robustness/misc.bindless.sm66.ssbo.comp",
    "content": "Texture2D<float4> Tex[] : register(t0, space0);\nSamplerState S[] : register(s0, space0);\nRWTexture2D<float4> RWTex[] : register(u0, space0);\nRWBuffer<float4> RWBuf[] : register(u0, space1);\nRWStructuredBuffer<float4> RWStruct[] : register(u0, space2);\n\nstruct C { float4 v; };\nConstantBuffer<C> Cbufs[] : register(b0, space0);\n\nRWStructuredBuffer<float4> Blah : register(u100, space3);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBlah[thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWTex[NonUniformResourceIndex(thr)][int2(thr, 0)] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWBuf[NonUniformResourceIndex(thr)][thr] = Cbufs[NonUniformResourceIndex(thr)].v;\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)][thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)].IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n\n\tTexture2D<float4> HeapTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr)];\n\tSamplerState HeapS = SamplerDescriptorHeap[NonUniformResourceIndex(thr + 100)];\n\tRWTexture2D<float4> HeapRWTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 200)];\n\tRWBuffer<float4> HeapRWBuf = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 300)];\n\tRWStructuredBuffer<float4> HeapRWStruct = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 400)];\n\tConstantBuffer<C> HeapCbufs = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 500)];\n\n\tBlah[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWTex[int2(thr, 0)] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWBuf[thr] = HeapCbufs.v;\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct.IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n}\n"
  },
  {
    "path": "shaders/heap-robustness/misc.heap-robustness.bindless.heap-robustness-cbv.heap-raw-va-cbv.sm66.ssbo.comp",
    "content": "Texture2D<float4> Tex[] : register(t0, space0);\nSamplerState S[] : register(s0, space0);\nRWTexture2D<float4> RWTex[] : register(u0, space0);\nRWBuffer<float4> RWBuf[] : register(u0, space1);\nRWStructuredBuffer<float4> RWStruct[] : register(u0, space2);\n\nstruct C { float4 v; };\nConstantBuffer<C> Cbufs[] : register(b0, space0);\n\nRWStructuredBuffer<float4> Blah : register(u100, space3);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBlah[thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWTex[NonUniformResourceIndex(thr)][int2(thr, 0)] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWBuf[NonUniformResourceIndex(thr)][thr] = Cbufs[NonUniformResourceIndex(thr)].v;\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)][thr] = Tex[NonUniformResourceIndex(thr)].SampleLevel(S[NonUniformResourceIndex(thr)], 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tRWStruct[NonUniformResourceIndex(thr)].IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n\n\tTexture2D<float4> HeapTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr)];\n\tSamplerState HeapS = SamplerDescriptorHeap[NonUniformResourceIndex(thr + 100)];\n\tRWTexture2D<float4> HeapRWTex = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 200)];\n\tRWBuffer<float4> HeapRWBuf = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 300)];\n\tRWStructuredBuffer<float4> HeapRWStruct = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 400)];\n\tConstantBuffer<C> HeapCbufs = ResourceDescriptorHeap[NonUniformResourceIndex(thr + 500)];\n\n\tBlah[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWTex[int2(thr, 0)] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWBuf[thr] = HeapCbufs.v;\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct[thr] = HeapTex.SampleLevel(HeapS, 0.5.xx, 0.0);\n\tGroupMemoryBarrierWithGroupSync();\n\tHeapRWStruct.IncrementCounter();\n\tGroupMemoryBarrierWithGroupSync();\n}\n"
  },
  {
    "path": "shaders/instrumentation/atomics-raw.bindless.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<uint> R;\nRWByteAddressBuffer BAB;\nRWBuffer<uint> T;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint o;\n\tBAB.InterlockedAdd(4 * thr, 1, o);\n\tBAB.InterlockedCompareExchange(4 * thr, 5, 6, o);\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/atomics-raw.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<uint> R;\nRWByteAddressBuffer BAB;\nRWBuffer<uint> T;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint o;\n\tBAB.InterlockedAdd(4 * thr, 1, o);\n\tBAB.InterlockedCompareExchange(4 * thr, 5, 6, o);\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/atomics-structured-counter.bindless.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<uint> R;\nRWByteAddressBuffer BAB;\nRWBuffer<uint> T;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint o;\n\tInterlockedAdd(R[thr], 1, o);\n\tInterlockedCompareExchange(R[thr], 1, 2, o);\n\tR.IncrementCounter(); // Should block validation for the UAV for now.\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/atomics-structured.bindless.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<uint> R;\nRWByteAddressBuffer BAB;\nRWBuffer<uint> T;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint o;\n\tInterlockedAdd(R[thr], 1, o);\n\tInterlockedCompareExchange(R[thr], 1, 2, o);\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/atomics-structured.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<uint> R;\nRWByteAddressBuffer BAB;\nRWBuffer<uint> T;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint o;\n\tInterlockedAdd(R[thr], 1, o);\n\tInterlockedCompareExchange(R[thr], 1, 2, o);\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/atomics-typed.bindless.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<uint> R;\nRWByteAddressBuffer BAB;\nRWBuffer<uint> T;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint o;\n\tInterlockedAdd(T[thr], 1, o);\n\tInterlockedCompareExchange(T[thr], 1, 2, o);\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/cbv.bindless.bda-instrumentation.comp",
    "content": "RWStructuredBuffer<float> R;\n\nstruct Foo { float3 vs[64]; };\nConstantBuffer<Foo> C[] : register(b0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = C[thr].vs[thr / 16];\n\tR[thr] += 40.0 + loaded.x + loaded.z;\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/cbv.root-descriptor.bda-instrumentation.comp",
    "content": "RWStructuredBuffer<float> R;\n\nstruct Foo { float3 vs[64]; };\nConstantBuffer<Foo> C : register(b0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = C.vs[thr / 16];\n\tR[thr] += 40.0 + loaded.x + loaded.z;\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/raw.bindless.bda-instrumentation.ssbo.comp",
    "content": "RWByteAddressBuffer R;\nByteAddressBuffer RO;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = RO.Load<float3>(12 * thr);\n\tR.Store<float>(4 * thr, R.Load<float>(4 * thr) + 40.0 + loaded.x + loaded.z);\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/raw.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "RWByteAddressBuffer R;\nByteAddressBuffer RO;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = RO.Load<float3>(8 * thr);\n\tR.Store<float>(4 * thr, R.Load<float>(4 * thr) + 40.0 + loaded.x + loaded.z);\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/structured.bindless.bda-instrumentation.comp",
    "content": "RWStructuredBuffer<float> R;\nStructuredBuffer<float3> RO;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = RO[thr];\n\tR[thr] += 40.0 + loaded.x + loaded.z;\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/structured.bindless.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<float> R;\nStructuredBuffer<float3> RO;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = RO[thr];\n\tR[thr] += 40.0 + loaded.x + loaded.z;\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/structured.root-descriptor.bda-instrumentation.ssbo.comp",
    "content": "RWStructuredBuffer<float> R;\nStructuredBuffer<float3> RO;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = RO[thr];\n\tR[thr] += 40.0 + loaded.x + loaded.z;\n}\n\n"
  },
  {
    "path": "shaders/instrumentation/typed.bindless.bda-instrumentation.comp",
    "content": "RWBuffer<float> R;\nBuffer<float3> RO;\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat3 loaded = RO[thr];\n\tR[thr] += 40.0 + loaded.x + loaded.z;\n}\n\n"
  },
  {
    "path": "shaders/llvm-builtin/alloca-robustness-cases.extended-robustness.vert",
    "content": "static const float LUT[4] = { 1, 2, 3, 4 };\nstatic float NonLUT[4] = { 5, 6, 7, 8 };\n\nfloat4 main(uint vid : SV_VertexID, uint iid : SV_InstanceID, uint4 a : A) : SV_Position\n{\n\tfloat arr[4] = (float[4])0;\n\n\tarr[a.x] = vid;\n\tNonLUT[a.y] = iid;\n\n\tfor (uint i = 0; i < a.w; i++, arr[i] += 50)\n\t{\n\t\tNonLUT[i ^ 2] += 60;\n\t}\n\n\treturn float4(LUT[a.z], NonLUT[a.w], arr[a.x], 1.0); \n}\n\n"
  },
  {
    "path": "shaders/llvm-builtin/alloca.frag",
    "content": "uint main(nointerpolation uint index : TEXCOORD) : SV_Target\n{\n\tuint array[4] = { 1, 2, 3, 4 };\n\tarray[index & 3] = index;\n\treturn array[0] + array[1] + array[2] + array[3];\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/atomic-bin-op.comp",
    "content": "groupshared uint array[64];\ngroupshared int array_signed[64];\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint res = 0;\n\tuint output;\n\tint output_signed;\n\n\tInterlockedAdd(array[index], 1, output);\n\tres += output;\n\n\tInterlockedAnd(array[index], 2, output);\n\tres += output;\n\n\tInterlockedExchange(array[index], 3, output);\n\tres += output;\n\n\tInterlockedMax(array[index], 4, output);\n\tres += output;\n\n\tInterlockedMin(array[index], 5, output);\n\tres += output;\n\n\tInterlockedOr(array[index], 6, output);\n\tres += output;\n\n\tInterlockedXor(array[index], 7, output);\n\tres += output;\n\n\tInterlockedMin(array_signed[index], 8, output_signed);\n\tres += output_signed;\n\n\tInterlockedMax(array_signed[index], 9, output_signed);\n\tres += output_signed;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/atomic-compare-exchange.comp",
    "content": "groupshared uint data[64];\n\nRWByteAddressBuffer Buf : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tuint res = 0;\n\tuint compare_value = 20;\n\tuint value = 30;\n\tuint output;\n\n\tInterlockedCompareExchange(data[index], compare_value, value, output);\n\tres += output;\n\tBuf.Store(index * 4, res);\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/atomic-compare-exchange.sm66.ssbo.comp",
    "content": "groupshared uint data[64];\ngroupshared uint64_t data64[64];\n\nRWByteAddressBuffer Buf : register(u0);\nRWByteAddressBuffer Buf64 : register(u1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\t{\n\t\tuint res = 0;\n\t\tuint compare_value = 20;\n\t\tuint value = 30;\n\t\tuint output;\n\n\t\tInterlockedCompareExchange(data[index], compare_value, value, output);\n\t\tres += output;\n\t\tInterlockedCompareExchange(data[index], compare_value, value, output);\n\t\tBuf.Store(index * 4, res);\n\t}\n\n\t{\n\t\tuint64_t res = 0;\n\t\tuint64_t compare_value = 20;\n\t\tuint64_t value = 30;\n\t\tuint64_t output;\n\n\t\tInterlockedCompareExchange(data64[index], compare_value, value, output);\n\t\tres += output;\n\t\tInterlockedCompareExchange(data64[index], compare_value, value, output);\n\t\tBuf64.Store<uint64_t>(index * 8, res);\n\t}\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/bool-to-fp.frag",
    "content": "float main(bool v : V) : SV_Target\n{\n\treturn float(v);\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/constant-expression-cast.comp",
    "content": "groupshared int foo[4];\nRWStructuredBuffer<float> RW : register(u0);\n\n[numthreads(4, 1, 1)]\nvoid main()\n{\n    RW[0] = ((float[4])(foo))[2];\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/constant-expression-gep.comp",
    "content": "groupshared uint foo[4];\nRWStructuredBuffer<uint> RW : register(u0);\n\n[numthreads(4, 1, 1)]\nvoid main(uint3 thr : SV_DispatchThreadID)\n{\n\tfoo[0] = thr.x;\n\tfoo[1] = thr.y;\n\tfoo[2] = thr.z;\n\tfoo[3] = 10;\n\n\tuint v;\n\tGroupMemoryBarrierWithGroupSync();\n\tInterlockedAdd(foo[3], 10, v);\n\tInterlockedCompareExchange(foo[2], 10, v, v);\n\t\n\tRW[thr.x] = foo[thr.y & 3];\n\tRW[thr.z] = foo[1] + v;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fadd.frag",
    "content": "float4 main(float4 a : A, float4 b : B) : SV_Target\n{\n\treturn a + b;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fast-mul-div-pair.comp",
    "content": "RWStructuredBuffer<float> Results : register(u0);\nStructuredBuffer<float> Inputs : register(t0);\n\n[numthreads(1, 1, 1)]\nvoid main()\n{\n\tfloat a = Inputs[0];\n\tfloat b = Inputs[1];\n\n\tResults[0] = (Inputs[2] * b) / b; // Should opt\n\tResults[1] = (b * Inputs[3]) / b; // Should opt\n\tResults[2] = b / (Inputs[4] * b); // Should not opt\n\tResults[3] = b / (b * Inputs[5]); // Should not opt\n\n\tResults[4] = (Inputs[6] / b) * b; // Should opt\n\tResults[5] = b * (Inputs[7] / b); // Should opt\n\tResults[6] = (b / Inputs[8]) * b; // Should not opt\n\tResults[7] = b * (b / Inputs[9]); // Should not opt\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fcmp_eq.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn a.x == a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fcmp_ge.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn a.x >= a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fcmp_gt.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn a.x > a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fcmp_le.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn a.x <= a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fcmp_lt.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn a.x < a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fcmp_ne.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn a.x != a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fdiv.frag",
    "content": "float4 main(float4 a : A, float4 b : B) : SV_Target\n{\n\treturn a / b;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fmul.frag",
    "content": "float4 main(float4 a : A, float4 b : B) : SV_Target\n{\n\treturn a * b;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/frem.frag",
    "content": "float4 main(float4 a : A, float4 b : B) : SV_Target\n{\n\treturn a % b;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/fsub.frag",
    "content": "float4 main(float4 a : A, float4 b : B) : SV_Target\n{\n\treturn a - b;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/glitched-integer-width.comp",
    "content": "cbuffer buffer1 : register (b0) \n{ \n    uint cbSwitch;\n}; \n\nstruct struct1 \n{ \n    float4 value1; \n}; \n\ncbuffer buffer2 : register (b1) \n{ \n    struct1 g_struct1; \n} \n\nRWTexture2DArray<float3> out1 : register(u0); \n\n[numthreads(8, 8, 1)] \nvoid main() \n{ \n    const float3 variable1 = float3(1.0f, 1.0f, 1.0f);\n    \n    bool variable3 = true; \n    switch (cbSwitch) \n    { \n\tcase 1:\n\tcase 2:\n\tcase 3:\n\tcase 7:\n\tcase 10:\n\tcase 11:\n        variable3 = false; \n        break; \n    } \n    \n    if (variable3) \n    {\n        out1[variable1] = float3(0, 0, 0);\n    } \n    else\n    {\n        out1[variable1] = float3(1, 1, 1);\n    }\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/groupshared.comp",
    "content": "struct Foo\n{\n\tfloat2 a[2];\n\tfloat2 b;\n};\n\ngroupshared Foo foos[64];\n\nRWStructuredBuffer<float2> outputs : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint ThreadID : SV_GroupIndex)\n{\n\tfoos[ThreadID].a[0] = float2(ThreadID, ThreadID + 1);\n\tfoos[ThreadID].a[1] = float2(ThreadID + 1, ThreadID + 2);\n\tfoos[ThreadID].b = float2(ThreadID + 2, ThreadID + 3);\n\tGroupMemoryBarrierWithGroupSync();\n\n\toutputs[ThreadID] = foos[ThreadID ^ 1].a[0] * foos[ThreadID ^ 2].a[1] * foos[ThreadID ^ 4].b;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_eq.frag",
    "content": "uint main(nointerpolation uint4 a : A) : SV_Target\n{\n\treturn a.x == a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_ne.frag",
    "content": "uint main(nointerpolation uint4 a : A) : SV_Target\n{\n\treturn a.x != a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_sge.frag",
    "content": "int main(nointerpolation int4 a : A) : SV_Target\n{\n\treturn a.x >= a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_sgt.frag",
    "content": "int main(nointerpolation int4 a : A) : SV_Target\n{\n\treturn a.x > a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_sle.frag",
    "content": "int main(nointerpolation int4 a : A) : SV_Target\n{\n\treturn a.x <= a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_slt.frag",
    "content": "int main(nointerpolation int4 a : A) : SV_Target\n{\n\treturn a.x < a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_uge.frag",
    "content": "uint main(nointerpolation uint4 a : A) : SV_Target\n{\n\treturn a.x >= a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_ugt.frag",
    "content": "uint main(nointerpolation uint4 a : A) : SV_Target\n{\n\treturn a.x > a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_ule.frag",
    "content": "uint main(nointerpolation uint4 a : A) : SV_Target\n{\n\treturn a.x <= a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/icmp_ult.frag",
    "content": "uint main(nointerpolation uint4 a : A) : SV_Target\n{\n\treturn a.x < a.y ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/logical-and.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn isnan(a.x) && isnan(a.y) ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/logical-equal.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn isnan(a.x) == isnan(a.y) ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/logical-not-equal.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn isnan(a.x) != isnan(a.y) ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/logical-or.frag",
    "content": "float main(float4 a : A) : SV_Target\n{\n\treturn isnan(a.x) || isnan(a.y) ? a.z : a.w;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/lut.frag",
    "content": "static const int2 values[8] = {\n\tint2(1, -1),\n\tint2(2, -2),\n\tint2(3, -3),\n\tint2(5, -5),\n\tint2(7, -7),\n\tint2(11, -11),\n\tint2(13, -13),\n\tint2(17, -17)\n};\n\nuint2 main(nointerpolation uint index : TEXCOORD) : SV_Target\n{\n\treturn values[index];\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/min16-phi.sm60.comp",
    "content": "RWStructuredBuffer<min16float4> B;\nTexture2D<min16float4> T0;\nTexture2D<min16float4> T1;\nTexture2D<min16float4> T2;\n\n[numthreads(64, 1, 1)]\nvoid main(uint3 thr : SV_DispatchThreadID)\n{\n\tmin16float4 v;\n\tif (thr.x < 20)\n\t\tv = T0.Load(int3(thr));\n\telse if (thr.y < 40)\n\t\tv = T1.Load(int3(thr));\n\telse\n\t\tv = T2.Load(int3(thr));\n\n\tB[thr.x] = v;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/precise_math.frag",
    "content": "precise float main(float a : A, float b : B, float c : C) : SV_Target\n{\n\tprecise float tmp;\n\ttmp = a * b + c;\n\ttmp += a;\n\ttmp -= b;\n\ttmp *= c;\n\treturn tmp;\n}\n"
  },
  {
    "path": "shaders/llvm-builtin/zext-bool.frag",
    "content": "uint main(uint v : V) : SV_Target\n{\n\tbool b = v != 40;\n\treturn uint(b);\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent-promotion.bindless.ssbo.comp",
    "content": "RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent-promotion.root-descriptor.ssbo.comp",
    "content": "RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent-promotion.sm66.bindless.ssbo.comp",
    "content": "StructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\tRWStructuredBuffer<float4> RW = ResourceDescriptorHeap[0];\n\tRWStructuredBuffer<float4> RW_RDONLY = ResourceDescriptorHeap[1];\n\tRWStructuredBuffer<float4> RW_WRONLY = ResourceDescriptorHeap[2];\n\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent-promotion.sm66.ssbo.comp",
    "content": "StructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\tRWStructuredBuffer<float4> RW = ResourceDescriptorHeap[0];\n\tRWStructuredBuffer<float4> RW_RDONLY = ResourceDescriptorHeap[1];\n\tRWStructuredBuffer<float4> RW_WRONLY = ResourceDescriptorHeap[2];\n\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent-promotion.ssbo.comp",
    "content": "RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent.root-descriptor.ssbo.comp",
    "content": "globallycoherent RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent.sm66.ssbo.comp",
    "content": "StructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\tgloballycoherent RWStructuredBuffer<float4> RW = ResourceDescriptorHeap[0];\n\tRWStructuredBuffer<float4> RW_RDONLY = ResourceDescriptorHeap[1];\n\tRWStructuredBuffer<float4> RW_WRONLY = ResourceDescriptorHeap[2];\n\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/memory-model/uav-coherent.ssbo.comp",
    "content": "globallycoherent RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/nvapi/bringup.nvapi.ssbo.rgen",
    "content": "#define NV_SHADER_EXTN_SLOT u127\n#define NV_SHADER_EXTN_REGISTER_SPACE space0\n#include \"nvHLSLExtns.h\"\n\nRWStructuredBuffer<uint> Blah : register(u0);\n\nRWByteAddressBuffer BAB : register(u1);\nRWTexture1D<float2> RWTex : register(u2);\n\n[shader(\"raygeneration\")]\nvoid main()\n{\n\tuint thr = DispatchRaysIndex().x;\n\tBlah[thr] = NvShfl(thr, 9);\n\n\t// Test UAV reference shenanigans.\n\tBlah[100] = NvInterlockedAddFp16x2(BAB, 64, 9);\n\tBlah[101] = NvInterlockedAddFp16x2(RWTex, thr, 10);\n}\n\n"
  },
  {
    "path": "shaders/nvapi/get-special-global-timer.nvapi.ssbo.rgen",
    "content": "#define NV_SHADER_EXTN_SLOT u127\n#define NV_SHADER_EXTN_REGISTER_SPACE space0\n#include \"nvHLSLExtns.h\"\n\nRWStructuredBuffer<uint> Buf : register(u0);\n\n[shader(\"raygeneration\")]\nvoid main()\n{\n\tBuf[0] = NvGetSpecial(NV_SPECIALOP_GLOBAL_TIMER_LO);\n\tBuf[1] = NvGetSpecial(NV_SPECIALOP_GLOBAL_TIMER_HI);\n}\n"
  },
  {
    "path": "shaders/nvapi/hit-object.local-root-signature.noglsl.nvapi.ssbo.rgen",
    "content": "#define NV_SHADER_EXTN_SLOT u127\n#define NV_SHADER_EXTN_REGISTER_SPACE space0\n#include \"nvHLSLExtns.h\"\n\nstruct Payload\n{\n\tuint index;\n};\n\nRaytracingAccelerationStructure AS : register(t0);\nRWStructuredBuffer<float> RWFloat : register(u1);\nRWStructuredBuffer<uint> RWUint : register(u2);\n\n[shader(\"raygeneration\")]\nvoid main()\n{\n\tBuiltInTriangleIntersectionAttributes attributes;\n\tNvHitObject hitobject;\n\tPayload payload;\n\tRayDesc ray;\n\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(4, 5, 6);\n\tray.TMin = 7.0;\n\tray.TMax = 8.0;\n\n\thitobject = NvMakeNop();\n\thitobject = NvMakeMiss(0, ray);\n\thitobject = NvMakeHit(AS, 0, 1, 2, 3, 4, 5, ray, attributes);\n\thitobject = NvMakeHitWithRecordIndex(4, AS, 0, 1, 2, 3, ray, attributes);\n\thitobject = NvTraceRayHitObject(AS, 17, 0, 1, 2, 3, ray, payload);\n\n\tRWUint[0] = payload.index;\n\n\tNvReorderThread(1, 2);\n\tNvReorderThread(hitobject);\n\n\tNvInvokeHitObject(AS, hitobject, payload);\n\n\tRWUint[1] = payload.index;\n\n\tRWUint[2] = hitobject.IsNop() ? 1 : 0;\n\tRWUint[3] = hitobject.IsMiss() ? 1 : 0;\n\tRWUint[4] = hitobject.IsHit() ? 1 : 0;\n\n\tRWUint[5] = hitobject.GetClusterID();\n\n\tRWUint[6] = hitobject.GetInstanceID();\n\tRWUint[7] = hitobject.GetInstanceIndex();\n\tRWUint[8] = hitobject.GetPrimitiveIndex();\n\tRWUint[9] = hitobject.GetGeometryIndex();\n\tRWUint[10] = hitobject.GetHitKind();\n\tRWUint[11] = hitobject.GetShaderTableIndex();\n\n\tRWUint[12] = hitobject.LoadLocalRootTableConstant(32);\n\n\tray = hitobject.GetRayDesc();\n\n\tRWFloat[0] = ray.TMin;\n\tRWFloat[1] = ray.TMax;\n\tRWFloat[2] = ray.Origin.x;\n\tRWFloat[3] = ray.Origin.y;\n\tRWFloat[4] = ray.Origin.z;\n\tRWFloat[5] = ray.Direction.x;\n\tRWFloat[6] = ray.Direction.y;\n\tRWFloat[7] = ray.Direction.z;\n\n\tattributes = hitobject.GetAttributes<BuiltInTriangleIntersectionAttributes>();\n\n\tRWFloat[8] = attributes.barycentrics.x;\n\tRWFloat[9] = attributes.barycentrics.y;\n}\n"
  },
  {
    "path": "shaders/nvapi/nvHLSLExtns.h",
    "content": "/*********************************************************************************************************\\\n|*                                                                                                        *|\n|* SPDX-FileCopyrightText: Copyright (c) 2019-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.  *|\n|* SPDX-License-Identifier: MIT                                                                           *|\n|*                                                                                                        *|\n|* Permission is hereby granted, free of charge, to any person obtaining a                                *|\n|* copy of this software and associated documentation files (the \"Software\"),                             *|\n|* to deal in the Software without restriction, including without limitation                              *|\n|* the rights to use, copy, modify, merge, publish, distribute, sublicense,                               *|\n|* and/or sell copies of the Software, and to permit persons to whom the                                  *|\n|* Software is furnished to do so, subject to the following conditions:                                   *|\n|*                                                                                                        *|\n|* The above copyright notice and this permission notice shall be included in                             *|\n|* all copies or substantial portions of the Software.                                                    *|\n|*                                                                                                        *|\n|* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                             *|\n|* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                               *|\n|* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL                               *|\n|* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                             *|\n|* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING                                *|\n|* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER                                    *|\n|* DEALINGS IN THE SOFTWARE.                                                                              *|\n|*                                                                                                        *|\n|*                                                                                                        *|\n\\*********************************************************************************************************/\n\n////////////////////////// NVIDIA SHADER EXTENSIONS /////////////////\n\n// this file is to be #included in the app HLSL shader code to make\n// use of nvidia shader extensions\n\n\n#include \"nvHLSLExtnsInternal.h\"\n\n//----------------------------------------------------------------------------//\n//------------------------- Warp Shuffle Functions ---------------------------//\n//----------------------------------------------------------------------------//\n\n// all functions have variants with width parameter which permits sub-division \n// of the warp into segments - for example to exchange data between 4 groups of \n// 8 lanes in a SIMD manner. If width is less than warpSize then each subsection \n// of the warp behaves as a separate entity with a starting logical lane ID of 0. \n// A thread may only exchange data with others in its own subsection. Width must \n// have a value which is a power of 2 so that the warp can be subdivided equally; \n// results are undefined if width is not a power of 2, or is a number greater \n// than warpSize.\n\n//\n// simple variant of SHFL instruction\n// returns val from the specified lane\n// optional width parameter must be a power of two and width <= 32\n// \nint NvShfl(int val, uint srcLane, int width = NV_WARP_SIZE)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  val;                             // variable to be shuffled\n    g_NvidiaExt[index].src0u.y  =  srcLane;                         // source lane\n    g_NvidiaExt[index].src0u.z  =  __NvGetShflMaskFromWidth(width);\n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_SHFL;\n    \n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    return g_NvidiaExt.IncrementCounter();\n}\n\nint2 NvShfl(int2 val, uint srcLane, int width = NV_WARP_SIZE)\n{\n    int x = NvShfl(val.x, srcLane, width);\n    int y = NvShfl(val.y, srcLane, width);\n    return int2(x, y);\n}\n\nint4 NvShfl(int4 val, uint srcLane, int width = NV_WARP_SIZE)\n{\n    int x = NvShfl(val.x, srcLane, width);\n    int y = NvShfl(val.y, srcLane, width);\n    int z = NvShfl(val.z, srcLane, width);\n    int w = NvShfl(val.w, srcLane, width);\n    return int4(x, y, z, w);\n}\n\n//\n// Copy from a lane with lower ID relative to caller\n//\nint NvShflUp(int val, uint delta, int width = NV_WARP_SIZE)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  val;                        // variable to be shuffled\n    g_NvidiaExt[index].src0u.y  =  delta;                      // relative lane offset\n    g_NvidiaExt[index].src0u.z  =  (NV_WARP_SIZE - width) << 8;   // minIndex = maxIndex for shfl_up (src2[4:0] is expected to be 0)\n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_SHFL_UP;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n//\n// Copy from a lane with higher ID relative to caller\n//\nint NvShflDown(int val, uint delta, int width = NV_WARP_SIZE)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  val;           // variable to be shuffled\n    g_NvidiaExt[index].src0u.y  =  delta;         // relative lane offset\n    g_NvidiaExt[index].src0u.z  =  __NvGetShflMaskFromWidth(width);\n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_SHFL_DOWN;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n//\n// Copy from a lane based on bitwise XOR of own lane ID\n//\nint NvShflXor(int val, uint laneMask, int width = NV_WARP_SIZE)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  val;           // variable to be shuffled\n    g_NvidiaExt[index].src0u.y  =  laneMask;      // laneMask to be XOR'ed with current laneId to get the source lane id\n    g_NvidiaExt[index].src0u.z  =  __NvGetShflMaskFromWidth(width); \n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_SHFL_XOR;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n\n//----------------------------------------------------------------------------//\n//----------------------------- Warp Vote Functions---------------------------//\n//----------------------------------------------------------------------------//\n\n// returns 0xFFFFFFFF if the predicate is true for any thread in the warp, returns 0 otherwise\nuint NvAny(int predicate)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  predicate;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_VOTE_ANY;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n// returns 0xFFFFFFFF if the predicate is true for ALL threads in the warp, returns 0 otherwise\nuint NvAll(int predicate)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  predicate;\n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_VOTE_ALL;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n// returns a mask of all threads in the warp with bits set for threads that have predicate true\nuint NvBallot(int predicate)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  predicate;\n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_VOTE_BALLOT;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n\n//----------------------------------------------------------------------------//\n//----------------------------- Utility Functions ----------------------------//\n//----------------------------------------------------------------------------//\n\n// returns the lane index of the current thread (thread index in warp)\nint NvGetLaneId()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_GET_LANE_ID;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n// returns value of special register - specify subopcode from any of NV_SPECIALOP_* specified in nvShaderExtnEnums.h - other opcodes undefined behavior\nuint NvGetSpecial(uint subOpCode)\n{\n    return __NvGetSpecial(subOpCode);\n}\n\n//----------------------------------------------------------------------------//\n//----------------------------- FP16 Atmoic Functions-------------------------//\n//----------------------------------------------------------------------------//\n\n// The functions below performs atomic operations on two consecutive fp16 \n// values in the given raw UAV. \n// The uint paramater 'fp16x2Val' is treated as two fp16 values byteAddress must be multiple of 4\n// The returned value are the two fp16 values packed into a single uint\n\nuint NvInterlockedAddFp16x2(RWByteAddressBuffer uav, uint byteAddress, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, byteAddress, fp16x2Val, NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWByteAddressBuffer uav, uint byteAddress, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, byteAddress, fp16x2Val, NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWByteAddressBuffer uav, uint byteAddress, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, byteAddress, fp16x2Val, NV_EXTN_ATOM_MAX);\n}\n\n\n// versions of the above functions taking two fp32 values (internally converted to fp16 values)\nuint NvInterlockedAddFp16x2(RWByteAddressBuffer uav, uint byteAddress, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, byteAddress, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWByteAddressBuffer uav, uint byteAddress, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, byteAddress, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWByteAddressBuffer uav, uint byteAddress, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, byteAddress, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MAX);\n}\n\n\n//----------------------------------------------------------------------------//\n\n// The functions below perform atomic operation on a R16G16_FLOAT UAV at the given address\n// the uint paramater 'fp16x2Val' is treated as two fp16 values\n// the returned value are the two fp16 values (.x and .y components) packed into a single uint\n// Warning: Behaviour of these set of functions is undefined if the UAV is not \n// of R16G16_FLOAT format (might result in app crash or TDR)\n\nuint NvInterlockedAddFp16x2(RWTexture1D<float2> uav, uint address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWTexture1D<float2> uav, uint address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWTexture1D<float2> uav, uint address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MAX);\n}\n\nuint NvInterlockedAddFp16x2(RWTexture2D<float2> uav, uint2 address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWTexture2D<float2> uav, uint2 address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWTexture2D<float2> uav, uint2 address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MAX);\n}\n\nuint NvInterlockedAddFp16x2(RWTexture3D<float2> uav, uint3 address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWTexture3D<float2> uav, uint3 address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWTexture3D<float2> uav, uint3 address, uint fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MAX);\n}\n\n\n// versions taking two fp32 values (internally converted to fp16)\nuint NvInterlockedAddFp16x2(RWTexture1D<float2> uav, uint address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWTexture1D<float2> uav, uint address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWTexture1D<float2> uav, uint address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MAX);\n}\n\nuint NvInterlockedAddFp16x2(RWTexture2D<float2> uav, uint2 address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWTexture2D<float2> uav, uint2 address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWTexture2D<float2> uav, uint2 address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MAX);\n}\n\nuint NvInterlockedAddFp16x2(RWTexture3D<float2> uav, uint3 address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_ADD);\n}\n\nuint NvInterlockedMinFp16x2(RWTexture3D<float2> uav, uint3 address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MIN);\n}\n\nuint NvInterlockedMaxFp16x2(RWTexture3D<float2> uav, uint3 address, float2 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x2Tofp16x2(val), NV_EXTN_ATOM_MAX);\n}\n\n\n//----------------------------------------------------------------------------//\n\n// The functions below perform Atomic operation on a R16G16B16A16_FLOAT UAV at the given address\n// the uint2 paramater 'fp16x2Val' is treated as four fp16 values \n// i.e, fp16x2Val.x = uav.xy and fp16x2Val.y = uav.yz\n// The returned value are the four fp16 values (.xyzw components) packed into uint2\n// Warning: Behaviour of these set of functions is undefined if the UAV is not \n// of R16G16B16A16_FLOAT format (might result in app crash or TDR)\n\nuint2 NvInterlockedAddFp16x4(RWTexture1D<float4> uav, uint address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMinFp16x4(RWTexture1D<float4> uav, uint address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedMaxFp16x4(RWTexture1D<float4> uav, uint address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedAddFp16x4(RWTexture2D<float4> uav, uint2 address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMinFp16x4(RWTexture2D<float4> uav, uint2 address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedMaxFp16x4(RWTexture2D<float4> uav, uint2 address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedAddFp16x4(RWTexture3D<float4> uav, uint3 address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMinFp16x4(RWTexture3D<float4> uav, uint3 address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedMaxFp16x4(RWTexture3D<float4> uav, uint3 address, uint2 fp16x2Val)\n{\n    return __NvAtomicOpFP16x2(uav, address, fp16x2Val, NV_EXTN_ATOM_MAX);\n}\n\n// versions taking four fp32 values (internally converted to fp16)\nuint2 NvInterlockedAddFp16x4(RWTexture1D<float4> uav, uint address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMinFp16x4(RWTexture1D<float4> uav, uint address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedMaxFp16x4(RWTexture1D<float4> uav, uint address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedAddFp16x4(RWTexture2D<float4> uav, uint2 address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMinFp16x4(RWTexture2D<float4> uav, uint2 address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedMaxFp16x4(RWTexture2D<float4> uav, uint2 address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedAddFp16x4(RWTexture3D<float4> uav, uint3 address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMinFp16x4(RWTexture3D<float4> uav, uint3 address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedMaxFp16x4(RWTexture3D<float4> uav, uint3 address, float4 val)\n{\n    return __NvAtomicOpFP16x2(uav, address, __fp32x4Tofp16x4(val), NV_EXTN_ATOM_MAX);\n}\n\n\n//----------------------------------------------------------------------------//\n//----------------------------- FP32 Atmoic Functions-------------------------//\n//----------------------------------------------------------------------------//\n\n// The functions below performs atomic add on the given UAV treating the value as float\n// byteAddress must be multiple of 4\n// The returned value is the value present in memory location before the atomic add\n\nfloat NvInterlockedAddFp32(RWByteAddressBuffer uav, uint byteAddress, float val)\n{\n    return __NvAtomicAddFP32(uav, byteAddress, val);\n}\n\n//----------------------------------------------------------------------------//\n\n// The functions below perform atomic add on a R32_FLOAT UAV at the given address\n// the returned value is the value before performing the atomic add\n// Warning: Behaviour of these set of functions is undefined if the UAV is not \n// of R32_FLOAT format (might result in app crash or TDR)\n\nfloat NvInterlockedAddFp32(RWTexture1D<float> uav, uint address, float val)\n{\n    return __NvAtomicAddFP32(uav, address, val);\n}\n\nfloat NvInterlockedAddFp32(RWTexture2D<float> uav, uint2 address, float val)\n{\n    return __NvAtomicAddFP32(uav, address, val);\n}\n\nfloat NvInterlockedAddFp32(RWTexture3D<float> uav, uint3 address, float val)\n{\n    return __NvAtomicAddFP32(uav, address, val);\n}\n\n\n//----------------------------------------------------------------------------//\n//--------------------------- UINT64 Atmoic Functions-------------------------//\n//----------------------------------------------------------------------------//\n\n// The functions below performs atomic operation on the given UAV treating the value as uint64\n// byteAddress must be multiple of 8\n// The returned value is the value present in memory location before the atomic operation\n// uint2 vector type is used to represent a single uint64 value with the x component containing the low 32 bits and y component the high 32 bits.\n\nuint2 NvInterlockedAddUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, byteAddress, value, NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMaxUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, byteAddress, value, NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedMinUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, byteAddress, value, NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedAndUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, byteAddress, value, NV_EXTN_ATOM_AND);\n}\n\nuint2 NvInterlockedOrUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, byteAddress, value, NV_EXTN_ATOM_OR);\n}\n\nuint2 NvInterlockedXorUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, byteAddress, value, NV_EXTN_ATOM_XOR);\n}\n\nuint2 NvInterlockedCompareExchangeUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 compare_value, uint2 value)\n{\n    return __NvAtomicCompareExchangeUINT64(uav, byteAddress, compare_value, value);\n}\n\nuint2 NvInterlockedExchangeUint64(RWByteAddressBuffer uav, uint byteAddress, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, byteAddress, value, NV_EXTN_ATOM_SWAP);\n}\n\n//----------------------------------------------------------------------------//\n\n// The functions below perform atomic operation on a R32G32_UINT UAV at the given address treating the value as uint64\n// the returned value is the value before performing the atomic operation\n// uint2 vector type is used to represent a single uint64 value with the x component containing the low 32 bits and y component the high 32 bits.\n// Warning: Behaviour of these set of functions is undefined if the UAV is not of R32G32_UINT format (might result in app crash or TDR)\n\nuint2 NvInterlockedAddUint64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMaxUint64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedMinUint64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedAndUint64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_AND);\n}\n\nuint2 NvInterlockedOrUint64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_OR);\n}\n\nuint2 NvInterlockedXorUint64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_XOR);\n}\n\nuint2 NvInterlockedCompareExchangeUint64(RWTexture1D<uint2> uav, uint address, uint2 compare_value, uint2 value)\n{\n    return __NvAtomicCompareExchangeUINT64(uav, address, compare_value, value);\n}\n\nuint2 NvInterlockedExchangeUint64(RWTexture1D<uint2> uav, uint address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_SWAP);\n}\n\nuint2 NvInterlockedAddUint64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMaxUint64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedMinUint64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedAndUint64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_AND);\n}\n\nuint2 NvInterlockedOrUint64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_OR);\n}\n\nuint2 NvInterlockedXorUint64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_XOR);\n}\n\nuint2 NvInterlockedCompareExchangeUint64(RWTexture2D<uint2> uav, uint2 address, uint2 compare_value, uint2 value)\n{\n    return __NvAtomicCompareExchangeUINT64(uav, address, compare_value, value);\n}\n\nuint2 NvInterlockedExchangeUint64(RWTexture2D<uint2> uav, uint2 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_SWAP);\n}\n\nuint2 NvInterlockedAddUint64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_ADD);\n}\n\nuint2 NvInterlockedMaxUint64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_MAX);\n}\n\nuint2 NvInterlockedMinUint64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_MIN);\n}\n\nuint2 NvInterlockedAndUint64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_AND);\n}\n\nuint2 NvInterlockedOrUint64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_OR);\n}\n\nuint2 NvInterlockedXorUint64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_XOR);\n}\n\nuint2 NvInterlockedCompareExchangeUint64(RWTexture3D<uint2> uav, uint3 address, uint2 compare_value, uint2 value)\n{\n    return __NvAtomicCompareExchangeUINT64(uav, address, compare_value, value);\n}\n\nuint2 NvInterlockedExchangeUint64(RWTexture3D<uint2> uav, uint3 address, uint2 value)\n{\n    return __NvAtomicOpUINT64(uav, address, value, NV_EXTN_ATOM_SWAP);\n}\n\n//----------------------------------------------------------------------------//\n//--------------------------- VPRS functions ---------------------------------//\n//----------------------------------------------------------------------------//\n\n// Returns the shading rate and the number of per-pixel shading passes for current VPRS pixel\nuint3 NvGetShadingRate()\n{\n    uint3 shadingRate = (uint3)0;\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_GET_SHADING_RATE;\n    g_NvidiaExt[index].numOutputsForIncCounter = 3;\n    shadingRate.x = g_NvidiaExt.IncrementCounter();\n    shadingRate.y = g_NvidiaExt.IncrementCounter();\n    shadingRate.z = g_NvidiaExt.IncrementCounter();\n    return shadingRate;\n}\n\nfloat NvEvaluateAttributeAtSampleForVPRS(float attrib, uint sampleIndex, int2 pixelOffset)\n{\n    float value = (float)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.x    = asuint(attrib.x);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 1;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nfloat2 NvEvaluateAttributeAtSampleForVPRS(float2 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    float2 value = (float2)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xy   = asuint(attrib.xy);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 2;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    value.y = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nfloat3 NvEvaluateAttributeAtSampleForVPRS(float3 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    float3 value = (float3)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xyz  = asuint(attrib.xyz);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 3;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    value.y = asfloat(g_NvidiaExt.IncrementCounter());\n    value.z = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nfloat4 NvEvaluateAttributeAtSampleForVPRS(float4 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    float4 value = (float4)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xyzw = asuint(attrib.xyzw);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 4;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    value.y = asfloat(g_NvidiaExt.IncrementCounter());\n    value.z = asfloat(g_NvidiaExt.IncrementCounter());\n    value.w = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint NvEvaluateAttributeAtSampleForVPRS(int attrib, uint sampleIndex, int2 pixelOffset)\n{\n    int value = (int)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.x    = asuint(attrib.x);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 1;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint2 NvEvaluateAttributeAtSampleForVPRS(int2 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    int2 value = (int2)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xy   = asuint(attrib.xy);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 2;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    value.y = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint3 NvEvaluateAttributeAtSampleForVPRS(int3 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    int3 value = (int3)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xyz  = asuint(attrib.xyz);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 3;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    value.y = asint(g_NvidiaExt.IncrementCounter());\n    value.z = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint4 NvEvaluateAttributeAtSampleForVPRS(int4 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    int4 value = (int4)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xyzw = asuint(attrib.xyzw);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 4;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    value.y = asint(g_NvidiaExt.IncrementCounter());\n    value.z = asint(g_NvidiaExt.IncrementCounter());\n    value.w = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint NvEvaluateAttributeAtSampleForVPRS(uint attrib, uint sampleIndex, int2 pixelOffset)\n{\n    uint value = (uint)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.x    = asuint(attrib.x);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 1;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint2 NvEvaluateAttributeAtSampleForVPRS(uint2 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    uint2 value = (uint2)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xy   = asuint(attrib.xy);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 2;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    value.y = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint3 NvEvaluateAttributeAtSampleForVPRS(uint3 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    uint3 value = (uint3)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xyz  = asuint(attrib.xyz);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 3;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    value.y = asuint(g_NvidiaExt.IncrementCounter());\n    value.z = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint4 NvEvaluateAttributeAtSampleForVPRS(uint4 attrib, uint sampleIndex, int2 pixelOffset)\n{\n    uint4 value = (uint4)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE;\n    g_NvidiaExt[ext].src0u.xyzw = asuint(attrib.xyzw);\n    g_NvidiaExt[ext].src1u.x    = sampleIndex;\n    g_NvidiaExt[ext].src2u.xy   = pixelOffset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 4;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    value.y = asuint(g_NvidiaExt.IncrementCounter());\n    value.z = asuint(g_NvidiaExt.IncrementCounter());\n    value.w = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\n\nfloat NvEvaluateAttributeSnappedForVPRS(float attrib, uint2 offset)\n{\n    float value = (float)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.x    = asuint(attrib.x);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 1;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nfloat2 NvEvaluateAttributeSnappedForVPRS(float2 attrib, uint2 offset)\n{\n    float2 value = (float2)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xy   = asuint(attrib.xy);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 2;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    value.y = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nfloat3 NvEvaluateAttributeSnappedForVPRS(float3 attrib, uint2 offset)\n{\n    float3 value = (float3)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xyz  = asuint(attrib.xyz);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 3;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    value.y = asfloat(g_NvidiaExt.IncrementCounter());\n    value.z = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nfloat4 NvEvaluateAttributeSnappedForVPRS(float4 attrib, uint2 offset)\n{\n    float4 value = (float4)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xyzw = asuint(attrib.xyzw);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 4;\n    value.x = asfloat(g_NvidiaExt.IncrementCounter());\n    value.y = asfloat(g_NvidiaExt.IncrementCounter());\n    value.z = asfloat(g_NvidiaExt.IncrementCounter());\n    value.w = asfloat(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint NvEvaluateAttributeSnappedForVPRS(int attrib, uint2 offset)\n{\n    int value = (int)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.x    = asuint(attrib.x);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 1;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint2 NvEvaluateAttributeSnappedForVPRS(int2 attrib, uint2 offset)\n{\n    int2 value = (int2)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xy   = asuint(attrib.xy);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 2;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    value.y = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint3 NvEvaluateAttributeSnappedForVPRS(int3 attrib, uint2 offset)\n{\n    int3 value = (int3)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xyz  = asuint(attrib.xyz);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 3;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    value.y = asint(g_NvidiaExt.IncrementCounter());\n    value.z = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nint4 NvEvaluateAttributeSnappedForVPRS(int4 attrib, uint2 offset)\n{\n    int4 value = (int4)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xyzw = asuint(attrib.xyzw);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 4;\n    value.x = asint(g_NvidiaExt.IncrementCounter());\n    value.y = asint(g_NvidiaExt.IncrementCounter());\n    value.z = asint(g_NvidiaExt.IncrementCounter());\n    value.w = asint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint NvEvaluateAttributeSnappedForVPRS(uint attrib, uint2 offset)\n{\n    uint value = (uint)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.x    = asuint(attrib.x);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 1;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint2 NvEvaluateAttributeSnappedForVPRS(uint2 attrib, uint2 offset)\n{\n    uint2 value = (uint2)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xy   = asuint(attrib.xy);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 2;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    value.y = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint3 NvEvaluateAttributeSnappedForVPRS(uint3 attrib, uint2 offset)\n{\n    uint3 value = (uint3)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xyz  = asuint(attrib.xyz);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 3;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    value.y = asuint(g_NvidiaExt.IncrementCounter());\n    value.z = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\nuint4 NvEvaluateAttributeSnappedForVPRS(uint4 attrib, uint2 offset)\n{\n    uint4 value = (uint4)0;\n    uint ext = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[ext].opcode     = NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED;\n    g_NvidiaExt[ext].src0u.xyzw = asuint(attrib.xyzw);\n    g_NvidiaExt[ext].src1u.xy   = offset;\n    g_NvidiaExt[ext].numOutputsForIncCounter = 4;\n    value.x = asuint(g_NvidiaExt.IncrementCounter());\n    value.y = asuint(g_NvidiaExt.IncrementCounter());\n    value.z = asuint(g_NvidiaExt.IncrementCounter());\n    value.w = asuint(g_NvidiaExt.IncrementCounter());\n    return value;\n}\n\n// MATCH instruction variants \nuint NvWaveMatch(uint value)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = value;\n    g_NvidiaExt[index].src1u.x = 1;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_MATCH_ANY;\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    return g_NvidiaExt.IncrementCounter();\n}\n\nuint NvWaveMatch(uint2 value)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy = value.xy;\n    g_NvidiaExt[index].src1u.x = 2;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_MATCH_ANY;\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    return g_NvidiaExt.IncrementCounter();\n}\n\nuint NvWaveMatch(uint4 value)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u = value;\n    g_NvidiaExt[index].src1u.x = 4;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_MATCH_ANY;\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    return g_NvidiaExt.IncrementCounter();\n}\n\nuint NvWaveMatch(float value)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = asuint(value);\n    g_NvidiaExt[index].src1u.x = 1;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_MATCH_ANY;\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    return g_NvidiaExt.IncrementCounter();\n}\n\nuint NvWaveMatch(float2 value)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy = asuint(value);\n    g_NvidiaExt[index].src1u.x = 2;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_MATCH_ANY;\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    return g_NvidiaExt.IncrementCounter();\n}\n\nuint NvWaveMatch(float4 value)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u = asuint(value);\n    g_NvidiaExt[index].src1u.x = 4;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_MATCH_ANY;\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    return g_NvidiaExt.IncrementCounter();\n}\n\n\n//----------------------------------------------------------------------------//\n//------------------------------ Footprint functions -------------------------//\n//----------------------------------------------------------------------------//\n// texSpace and smpSpace must be immediates, texIndex and smpIndex can be variable\n// offset must be immediate\n// the required components of location and offset fields can be filled depending on the dimension/type of the texture\n// texType should be one of 2D or 3D as defined in nvShaderExtnEnums.h and and should be an immediate literal\n// if the above restrictions are not met, the behaviour of this instruction is undefined\n\nuint4 NvFootprintFine(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprint(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, offset);\n}\n\nuint4 NvFootprintCoarse(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprint(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, offset);\n}\n\n\n\nuint4 NvFootprintFineBias(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float bias, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprintBias(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, bias, offset);\n}\n\nuint4 NvFootprintCoarseBias(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float bias, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprintBias(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, bias, offset);\n}\n\n\n\nuint4 NvFootprintFineLevel(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float lodLevel, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprintLevel(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, lodLevel, offset);\n}\n\nuint4 NvFootprintCoarseLevel(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float lodLevel, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprintLevel(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, lodLevel, offset);\n}\n\n\n\nuint4 NvFootprintFineGrad(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float3 ddx, float3 ddy, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprintGrad(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, ddx, ddy, offset);\n}\n\nuint4 NvFootprintCoarseGrad(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float3 ddx, float3 ddy, int3 offset = int3(0, 0, 0))\n{\n    return __NvFootprintGrad(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, ddx, ddy, offset);\n}\n\nuint NvFootprintExtractLOD(uint4 blob)\n{\n    return ((blob.w & 0xF000) >> 12);\n}\n\nuint NvFootprintExtractReturnGran(uint4 blob)\n{\n    return ((blob.z & 0xF000000) >> 24);\n}\n\nuint2 NvFootprintExtractAnchorTileLoc2D(uint4 blob)\n{\n    uint2 loc;\n    loc.x = (blob.w & 0xFFF);\n    loc.y = (blob.z & 0xFFF);\n    return loc;\n}\n\nuint3 NvFootprintExtractAnchorTileLoc3D(uint4 blob)\n{\n    uint3 loc;\n    loc.x = (blob.w & 0xFFF);\n    loc.y = ((blob.w & 0xFFF0000) >> 16);\n    loc.z = (blob.z & 0x1FFF);\n    return loc;\n}\n\nuint2 NvFootprintExtractOffset2D(uint4 blob)\n{\n    uint2 loc;\n    loc.x = ((blob.z & 0x070000) >> 16);\n    loc.y = ((blob.z & 0x380000) >> 19);\n    return loc;\n}\n\nuint3 NvFootprintExtractOffset3D(uint4 blob)\n{\n    uint3 loc;\n    loc.x = ((blob.z & 0x030000) >> 16);\n    loc.y = ((blob.z & 0x0C0000) >> 18);\n    loc.z = ((blob.z & 0x300000) >> 20);\n    return loc;\n}\n\nuint2 NvFootprintExtractBitmask(uint4 blob)\n{\n    return blob.xy;\n}\n\n\n// Variant of Footprint extensions which returns isSingleLod (out parameter) \n// isSingleLod = true -> This footprint request touched the texels from only single LOD.\nuint4 NvFootprintFine(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprint(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\nuint4 NvFootprintCoarse(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprint(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\n\n\nuint4 NvFootprintFineBias(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float bias, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprintBias(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, bias, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\nuint4 NvFootprintCoarseBias(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float bias, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprintBias(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, bias, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\n\n\nuint4 NvFootprintFineLevel(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float lodLevel, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprintLevel(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, lodLevel, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\nuint4 NvFootprintCoarseLevel(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float lodLevel, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprintLevel(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, lodLevel, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\n\n\nuint4 NvFootprintFineGrad(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float3 ddx, float3 ddy, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprintGrad(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_FINE, gran, ddx, ddy, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\nuint4 NvFootprintCoarseGrad(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint gran, float3 ddx, float3 ddy, out uint isSingleLod, int3 offset = int3(0, 0, 0))\n{\n    uint4 res = __NvFootprintGrad(texSpace, texIndex, smpSpace, smpIndex, texType, location, NV_EXTN_FOOTPRINT_MODE_COARSE, gran, ddx, ddy, offset);\n    isSingleLod = __NvGetSpecial(NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED);\n    return res;\n}\n\n\nuint NvActiveThreads()\n{\n    return NvBallot(1);\n}\n\n\n//----------------------------------------------------------------------------//\n//------------------------------ WaveMultiPrefix functions -------------------//\n//----------------------------------------------------------------------------//\n\n// Following are the WaveMultiPrefix functions for different operations (Add, Bitand, BitOr, BitXOr) for different datatypes (uint, uint2, uint4) \n// This is a set of functions which implement multi-prefix operations among the set of active lanes in the current wave (WARP). \n// A multi-prefix operation comprises a set of prefix operations, executed in parallel within subsets of lanes identified with the provided bitmasks. \n// These bitmasks represent partitioning of the set of active lanes in the current wave into N groups (where N is the number of unique masks across all lanes in the wave). \n// N prefix operations are then performed each within its corresponding group. \n// The groups are assumed to be non-intersecting (that is, a given lane can be a member of one and only one group), \n// and bitmasks in all lanes belonging to the same group are required to be the same.\n// There are 2 type of functions - Exclusive and Inclusive prefix operations.\n// e.g. For NvWaveMultiPrefixInclusiveAdd(val, mask) operation - For each of the groups (for which mask input is same) following is the expected output : \n// i^th thread in a group has value = sum(values of threads 0 to i)\n// For Exclusive version of same opeartion - \n// i^th thread in a group has value = sum(values of threads 0 to i-1)  and 0th thread in a the Group has value 0 \n\n// Extensions for Add \nuint NvWaveMultiPrefixInclusiveAdd(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        // As remainingThreads only has threads in group with smaller thread ids than its own thread-id nextLane can never be 31 for any thread in the group except the smallest one\n        // For smallest thread in the group, remainingThreads is 0 -->  nextLane is ~0 (i.e. considering last 5 bits its 31)\n        // So passing maskClampValue=30 to __NvShflGeneric, it will return laneValid=false for the smallest thread in the group. So update val and nextLane based on laneValid.\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val + temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint NvWaveMultiPrefixExclusiveAdd(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : 0;\n    return NvWaveMultiPrefixInclusiveAdd(val, mask);\n}\n\nuint2 NvWaveMultiPrefixInclusiveAdd(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val + temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint2 NvWaveMultiPrefixExclusiveAdd(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint2(0, 0);\n    return NvWaveMultiPrefixInclusiveAdd(val, mask);\n}\n\nuint4 NvWaveMultiPrefixInclusiveAdd(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val + temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint4 NvWaveMultiPrefixExclusiveAdd(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint4(0, 0, 0, 0);\n    return NvWaveMultiPrefixInclusiveAdd(val, mask);\n}\n\n// MultiPrefix extensions for Bitand\nuint NvWaveMultiPrefixInclusiveAnd(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val & temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint NvWaveMultiPrefixExclusiveAnd(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : ~0;\n    return NvWaveMultiPrefixInclusiveAnd(val, mask);\n}\n\nuint2 NvWaveMultiPrefixInclusiveAnd(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val & temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint2 NvWaveMultiPrefixExclusiveAnd(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint2(~0, ~0);\n    return NvWaveMultiPrefixInclusiveAnd(val, mask);\n}\n\n\nuint4 NvWaveMultiPrefixInclusiveAnd(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val & temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint4 NvWaveMultiPrefixExclusiveAnd(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint4(~0, ~0, ~0, ~0);\n    return NvWaveMultiPrefixInclusiveAnd(val, mask);\n}\n\n\n// MultiPrefix extensions for BitOr\nuint NvWaveMultiPrefixInclusiveOr(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val | temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint NvWaveMultiPrefixExclusiveOr(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : 0;\n    return NvWaveMultiPrefixInclusiveOr(val, mask);\n}\n\nuint2 NvWaveMultiPrefixInclusiveOr(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val | temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint2 NvWaveMultiPrefixExclusiveOr(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint2(0, 0);\n    return NvWaveMultiPrefixInclusiveOr(val, mask);\n}\n\n\nuint4 NvWaveMultiPrefixInclusiveOr(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val | temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint4 NvWaveMultiPrefixExclusiveOr(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint4(0, 0, 0, 0);\n    return NvWaveMultiPrefixInclusiveOr(val, mask);\n}\n\n\n// MultiPrefix extensions for BitXOr\nuint NvWaveMultiPrefixInclusiveXOr(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val ^ temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint NvWaveMultiPrefixExclusiveXOr(uint val, uint mask)\n{\n    uint temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : 0;\n    return NvWaveMultiPrefixInclusiveXOr(val, mask);\n}\n\nuint2 NvWaveMultiPrefixInclusiveXOr(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val ^ temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint2 NvWaveMultiPrefixExclusiveXOr(uint2 val, uint mask)\n{\n    uint2 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint2(0, 0);\n    return NvWaveMultiPrefixInclusiveXOr(val, mask);\n}\n\n\nuint4 NvWaveMultiPrefixInclusiveXOr(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint nextLane = firstbithigh(remainingThreads);\n    for (uint i = 0; i < NV_WARP_SIZE_LOG2; i++)\n    {\n        temp = NvShfl(val, nextLane);\n        uint laneValid;\n        uint newLane = asuint(__NvShflGeneric(nextLane, nextLane, 30, laneValid));\n        if (laneValid) // if nextLane's nextLane is valid\n        {\n            val = val ^ temp;\n            nextLane = newLane;\n        }\n    }\n    return val;\n}\n\nuint4 NvWaveMultiPrefixExclusiveXOr(uint4 val, uint mask)\n{\n    uint4 temp;\n    uint a = NvActiveThreads();\n    uint remainingThreads = a & __NvGetSpecial(NV_SPECIALOP_THREADLTMASK) & mask;\n    uint lane = firstbithigh(remainingThreads);\n    temp = NvShfl(val, lane);\n    val = remainingThreads != 0 ? temp : uint4(0, 0, 0, 0);\n    return NvWaveMultiPrefixInclusiveXOr(val, mask);\n}\n\n\n//----------------------------------------------------------------------------//\n//------------------------- DXR Micro-map Extension --------------------------//\n//----------------------------------------------------------------------------//\n\nfloat3x3 NvRtTriangleObjectPositions()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_TRIANGLE_OBJECT_POSITIONS;\n\n    float3x3 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat3x3 NvRtMicroTriangleObjectPositions()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_MICRO_TRIANGLE_OBJECT_POSITIONS;\n\n    float3x3 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat3x2 NvRtMicroTriangleBarycentrics()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_MICRO_TRIANGLE_BARYCENTRICS;\n\n    float3x2 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nbool NvRtIsMicroTriangleHit()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_IS_MICRO_TRIANGLE_HIT;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\nbool NvRtIsBackFacing()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_IS_BACK_FACING;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\n#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 5)\n\nfloat3 NvRtMicroVertexObjectPosition(RaytracingAccelerationStructure AccelerationStructure, uint InstanceIndex, uint GeometryIndex, uint PrimitiveIndex, uint2 UV)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_MICRO_VERTEX_OBJECT_POSITION;\n    g_NvidiaExt[index].src0u.x = InstanceIndex;\n    g_NvidiaExt[index].src0u.y = GeometryIndex;\n    g_NvidiaExt[index].src0u.z = PrimitiveIndex;\n    g_NvidiaExt[index].src0u.w = UV.x;\n    g_NvidiaExt[index].src1u.x = UV.y;\n    uint handle = g_NvidiaExt.IncrementCounter();\n    float3 ret;\n    ret.x = asfloat(g_NvidiaExt.IncrementCounter());\n    ret.y = asfloat(g_NvidiaExt.IncrementCounter());\n    ret.z = asfloat(g_NvidiaExt.IncrementCounter());\n\n    RayQuery<0> rq;\n    rq.TraceRayInline(AccelerationStructure, 0, handle, (RayDesc)0);\n\n    return ret;\n}\n\nfloat2 NvRtMicroVertexBarycentrics(RaytracingAccelerationStructure AccelerationStructure, uint InstanceIndex, uint GeometryIndex, uint PrimitiveIndex, uint2 UV)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_MICRO_VERTEX_BARYCENTRICS;\n    g_NvidiaExt[index].src0u.x = InstanceIndex;\n    g_NvidiaExt[index].src0u.y = GeometryIndex;\n    g_NvidiaExt[index].src0u.z = PrimitiveIndex;\n    g_NvidiaExt[index].src0u.w = UV.x;\n    g_NvidiaExt[index].src1u.x = UV.y;\n    uint handle = g_NvidiaExt.IncrementCounter();\n    float2 ret;\n    ret.x = asfloat(g_NvidiaExt.IncrementCounter());\n    ret.y = asfloat(g_NvidiaExt.IncrementCounter());\n\n    RayQuery<0> rq;\n    rq.TraceRayInline(AccelerationStructure, 0, handle, (RayDesc)0);\n\n    return ret;\n}\n\n#endif\n\n//----------------------------------------------------------------------------//\n//--------------------- DXR Cluster Geometry Extension -----------------------//\n//----------------------------------------------------------------------------//\n\n#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 3)\n\nuint NvRtGetClusterID()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_GET_CLUSTER_ID;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n#endif\n\n#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 5)\n\n#define NvRtGetCandidateClusterID(rq) __NvRtGetCandidateClusterID(rq.RayFlags())\n\n#define NvRtGetCommittedClusterID(rq) __NvRtGetCommittedClusterID(rq.RayFlags())\n\n#define NvRtCandidateTriangleObjectPositions(rq) __NvRtCandidateTriangleObjectPositions(rq.RayFlags())\n\n#define NvRtCommittedTriangleObjectPositions(rq) __NvRtCommittedTriangleObjectPositions(rq.RayFlags())\n\n#endif\n\n//----------------------------------------------------------------------------//\n//--------------------- DXR Linear Swept Sphere Extension --------------------//\n//----------------------------------------------------------------------------//\n\n#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 3)\n\nfloat4 NvRtSphereObjectPositionAndRadius()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_SPHERE_OBJECT_POSITION_AND_RADIUS;\n\n    float4 ret;\n    ret[0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[3] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat2x4 NvRtLssObjectPositionsAndRadii()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_LSS_OBJECT_POSITIONS_AND_RADII;\n\n    float2x4 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][3] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][3] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nbool NvRtIsSphereHit()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_IS_SPHERE_HIT;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\nbool NvRtIsLssHit()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_IS_LSS_HIT;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\n#endif\n\n#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 5)\n\n#define NvRtCandidateIsNonOpaqueSphere(rq) __NvRtCandidateIsNonOpaqueSphere(rq.RayFlags())\n\n#define NvRtCandidateIsNonOpaqueLss(rq) __NvRtCandidateIsNonOpaqueLss(rq.RayFlags())\n\n#define NvRtCandidateLssHitParameter(rq) __NvRtCandidateLssHitParameter(rq.RayFlags())\n\n#define NvRtCandidateSphereObjectPositionAndRadius(rq) __NvRtCandidateSphereObjectPositionAndRadius(rq.RayFlags())\n\n#define NvRtCandidateLssObjectPositionsAndRadii(rq) __NvRtCandidateLssObjectPositionsAndRadii(rq.RayFlags())\n\n#define NvRtCandidateBuiltinPrimitiveRayT(rq) __NvRtCandidateBuiltinPrimitiveRayT(rq.RayFlags())\n\n#define NvRtCommittedIsSphere(rq) __NvRtCommittedIsSphere(rq.RayFlags())\n\n#define NvRtCommittedIsLss(rq) __NvRtCommittedIsLss(rq.RayFlags())\n\n#define NvRtCommittedLssHitParameter(rq) __NvRtCommittedLssHitParameter(rq.RayFlags())\n\n#define NvRtCommittedSphereObjectPositionAndRadius(rq) __NvRtCommittedSphereObjectPositionAndRadius(rq.RayFlags())\n\n#define NvRtCommittedLssObjectPositionsAndRadii(rq) __NvRtCommittedLssObjectPositionsAndRadii(rq.RayFlags())\n\n#define NvRtCommitNonOpaqueBuiltinPrimitiveHit(rq) __NvRtCommitNonOpaqueBuiltinPrimitiveHit(rq.RayFlags())\n\n#endif\n\n//----------------------------------------------------------------------------//\n//------------------------- DXR HitObject Extension --------------------------//\n//----------------------------------------------------------------------------//\n\n// Support for templates in HLSL requires HLSL 2021+. When using dxc,\n// use the -HV 2021 command line argument to enable these versions.\n#if defined(__HLSL_VERSION) && (__HLSL_VERSION >= 2021) && !defined(NV_HITOBJECT_USE_MACRO_API)\n\nstruct NvHitObject {\n    uint _handle;\n\n    bool IsMiss()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_MISS;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    bool IsHit()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_HIT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    bool IsNop()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_NOP;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    uint GetInstanceID()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_ID;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetInstanceIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetPrimitiveIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_PRIMITIVE_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetGeometryIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_GEOMETRY_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetHitKind()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_HIT_KIND;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    RayDesc GetRayDesc()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_RAY_DESC;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        uint tmin = g_NvidiaExt.IncrementCounter();\n        uint tmax = g_NvidiaExt.IncrementCounter();\n        uint rayOrgX = g_NvidiaExt.IncrementCounter();\n        uint rayOrgY = g_NvidiaExt.IncrementCounter();\n        uint rayOrgZ = g_NvidiaExt.IncrementCounter();\n        uint rayDirX = g_NvidiaExt.IncrementCounter();\n        uint rayDirY = g_NvidiaExt.IncrementCounter();\n        uint rayDirZ = g_NvidiaExt.IncrementCounter();\n\n        RayDesc ray;\n        ray.TMin = asfloat(tmin);\n        ray.TMax = asfloat(tmax);\n        ray.Origin.x = asfloat(rayOrgX);\n        ray.Origin.y = asfloat(rayOrgY);\n        ray.Origin.z = asfloat(rayOrgZ);\n        ray.Direction.x = asfloat(rayDirX);\n        ray.Direction.y = asfloat(rayDirY);\n        ray.Direction.z = asfloat(rayDirZ);\n\n        return ray;\n    }\n\n    template <typename T>\n    T GetAttributes()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint callHandle = g_NvidiaExt.IncrementCounter();\n\n        T attrs;\n        CallShader(callHandle, attrs);\n        return attrs;\n    }\n\n    uint GetShaderTableIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_SHADER_TABLE_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint LoadLocalRootTableConstant(uint RootConstantOffsetInBytes)\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_LOAD_LOCAL_ROOT_TABLE_CONSTANT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        g_NvidiaExt[index].src0u.y = RootConstantOffsetInBytes;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    float4 GetSphereObjectPositionAndRadius()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_SPHERE_OBJECT_POSITION_AND_RADIUS;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        float4 ret;\n        ret[0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[3] = asfloat(g_NvidiaExt.IncrementCounter());\n        return ret;\n    }\n\n    float2x4 GetLssObjectPositionsAndRadii()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_LSS_OBJECT_POSITIONS_AND_RADII;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        float2x4 ret;\n        ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][3] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][3] = asfloat(g_NvidiaExt.IncrementCounter());\n        return ret;\n    }\n\n    bool IsSphereHit()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_SPHERE_HIT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    bool IsLssHit()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_LSS_HIT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    uint GetClusterID()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_CLUSTER_ID;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    float3x3 GetTriangleObjectPositions()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_TRIANGLE_OBJECT_POSITIONS;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        float3x3 ret;\n        ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        return ret;\n    }\n};\n\ntemplate<typename T>\nNvHitObject NvTraceRayHitObject(\n    RaytracingAccelerationStructure AccelerationStructure,\n    uint RayFlags,\n    uint InstanceInclusionMask,\n    uint RayContributionToHitGroupIndex,\n    uint MultiplierForGeometryContributionToHitGroupIndex,\n    uint MissShaderIndex,\n    RayDesc Ray,\n    inout T Payload)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_TRACE_RAY;\n    g_NvidiaExt[index].numOutputsForIncCounter = 2;\n    g_NvidiaExt[index].src0u.x = MissShaderIndex;\n    uint hitHandle = g_NvidiaExt.IncrementCounter();\n    uint traceHandle = g_NvidiaExt.IncrementCounter();\n\n    TraceRay(AccelerationStructure, RayFlags, InstanceInclusionMask, RayContributionToHitGroupIndex, MultiplierForGeometryContributionToHitGroupIndex, traceHandle, Ray, Payload);\n\n    NvHitObject hitObj;\n    hitObj._handle = hitHandle;\n    return hitObj;\n}\n\ntemplate <typename T>\nNvHitObject NvMakeHit(\n    RaytracingAccelerationStructure AccelerationStructure,\n    uint InstanceIndex,\n    uint GeometryIndex,\n    uint PrimitiveIndex,\n    uint HitKind,\n    uint RayContributionToHitGroupIndex,\n    uint MultiplierForGeometryContributionToHitGroupIndex,\n    RayDesc Ray,\n    T Attributes)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_HIT;\n    g_NvidiaExt[index].numOutputsForIncCounter = 2;\n    g_NvidiaExt[index].src0u.x = InstanceIndex;\n    g_NvidiaExt[index].src0u.y = GeometryIndex;\n    g_NvidiaExt[index].src0u.z = PrimitiveIndex;\n    g_NvidiaExt[index].src0u.w = HitKind;\n    g_NvidiaExt[index].src1u.x = RayContributionToHitGroupIndex;\n    g_NvidiaExt[index].src1u.y = MultiplierForGeometryContributionToHitGroupIndex;\n    uint hitHandle = g_NvidiaExt.IncrementCounter();\n    uint traceHandle = g_NvidiaExt.IncrementCounter();\n\n    struct AttrWrapper { T Attrs; };\n    AttrWrapper wrapper;\n    wrapper.Attrs = Attributes;\n    CallShader(traceHandle, wrapper);\n\n    struct DummyPayload { int a; };\n    DummyPayload payload;\n    TraceRay(AccelerationStructure, 0, 0, 0, 0, traceHandle, Ray, payload);\n\n    NvHitObject hitObj;\n    hitObj._handle = hitHandle;\n    return hitObj;\n}\n\ntemplate <typename T>\nNvHitObject NvMakeHitWithRecordIndex(\n    uint HitGroupRecordIndex,\n    RaytracingAccelerationStructure AccelerationStructure,\n    uint InstanceIndex,\n    uint GeometryIndex,\n    uint PrimitiveIndex,\n    uint HitKind,\n    RayDesc Ray,\n    T Attributes)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX;\n    g_NvidiaExt[index].numOutputsForIncCounter = 2;\n    g_NvidiaExt[index].src0u.x = InstanceIndex;\n    g_NvidiaExt[index].src0u.y = GeometryIndex;\n    g_NvidiaExt[index].src0u.z = PrimitiveIndex;\n    g_NvidiaExt[index].src0u.w = HitKind;\n    g_NvidiaExt[index].src1u.x = HitGroupRecordIndex;\n    uint hitHandle = g_NvidiaExt.IncrementCounter();\n    uint traceHandle = g_NvidiaExt.IncrementCounter();\n\n    struct AttrWrapper { T Attrs; };\n    AttrWrapper wrapper;\n    wrapper.Attrs = Attributes;\n    CallShader(traceHandle, wrapper);\n\n    struct DummyPayload { int a; };\n    DummyPayload payload;\n    TraceRay(AccelerationStructure, 0, 0, 0, 0, traceHandle, Ray, payload);\n\n    NvHitObject hitObj;\n    hitObj._handle = hitHandle;\n    return hitObj;\n}\n\nNvHitObject NvMakeMiss(\n    uint MissShaderIndex,\n    RayDesc Ray)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_MISS;\n    g_NvidiaExt[index].src0u.x = MissShaderIndex;\n    g_NvidiaExt[index].src0u.y = asuint(Ray.TMin);\n    g_NvidiaExt[index].src0u.z = asuint(Ray.TMax);\n    g_NvidiaExt[index].src1u.x = asuint(Ray.Origin.x);\n    g_NvidiaExt[index].src1u.y = asuint(Ray.Origin.y);\n    g_NvidiaExt[index].src1u.z = asuint(Ray.Origin.z);\n    g_NvidiaExt[index].src2u.x = asuint(Ray.Direction.x);\n    g_NvidiaExt[index].src2u.y = asuint(Ray.Direction.y);\n    g_NvidiaExt[index].src2u.z = asuint(Ray.Direction.z);\n    uint hitHandle = g_NvidiaExt.IncrementCounter();\n\n    NvHitObject hitObj;\n    hitObj._handle = hitHandle;\n    return hitObj;\n}\n\nNvHitObject NvMakeNop()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_NOP;\n    uint hitHandle = g_NvidiaExt.IncrementCounter();\n\n    NvHitObject hitObj;\n    hitObj._handle = hitHandle;\n    return hitObj;\n}\n\nvoid NvReorderThread(uint CoherenceHint, uint NumCoherenceHintBits)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_REORDER_THREAD;\n    g_NvidiaExt[index].src0u.x = 0;\n    g_NvidiaExt[index].src0u.y = 0;\n    g_NvidiaExt[index].src0u.z = CoherenceHint;\n    g_NvidiaExt[index].src0u.w = NumCoherenceHintBits;\n    g_NvidiaExt.IncrementCounter();\n}\n\nvoid NvReorderThread(NvHitObject HitObj, uint CoherenceHint, uint NumCoherenceHintBits)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_REORDER_THREAD;\n    g_NvidiaExt[index].src0u.x = 1;\n    g_NvidiaExt[index].src0u.y = HitObj._handle;\n    g_NvidiaExt[index].src0u.z = CoherenceHint;\n    g_NvidiaExt[index].src0u.w = NumCoherenceHintBits;\n    g_NvidiaExt.IncrementCounter();\n}\n\nvoid NvReorderThread(NvHitObject HitObj)\n{\n    NvReorderThread(HitObj, 0, 0);\n}\n\ntemplate<typename T>\nvoid NvInvokeHitObject(\n    RaytracingAccelerationStructure AccelerationStructure,\n    NvHitObject HitObj,\n    inout T Payload)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_INVOKE;\n    g_NvidiaExt[index].src0u.x = HitObj._handle;\n    uint handle = g_NvidiaExt.IncrementCounter();\n\n    TraceRay(AccelerationStructure, 0, 0, 0, 0, handle, (RayDesc)0, Payload);\n}\n\n// Macro-based version of the HitObject API. Use this when HLSL 2021 is not available.\n// Enable by specifying #define NV_HITOBJECT_USE_MACRO_API before including this header.\n#elif defined(NV_HITOBJECT_USE_MACRO_API)\n\nstruct NvHitObject {\n    uint _handle;\n\n    bool IsMiss()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_MISS;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    bool IsHit()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_HIT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    bool IsNop()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_NOP;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    uint GetInstanceID()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_ID;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetInstanceIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetPrimitiveIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_PRIMITIVE_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetGeometryIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_GEOMETRY_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint GetHitKind()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_HIT_KIND;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    RayDesc GetRayDesc()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_RAY_DESC;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        uint tmin = g_NvidiaExt.IncrementCounter();\n        uint tmax = g_NvidiaExt.IncrementCounter();\n        uint rayOrgX = g_NvidiaExt.IncrementCounter();\n        uint rayOrgY = g_NvidiaExt.IncrementCounter();\n        uint rayOrgZ = g_NvidiaExt.IncrementCounter();\n        uint rayDirX = g_NvidiaExt.IncrementCounter();\n        uint rayDirY = g_NvidiaExt.IncrementCounter();\n        uint rayDirZ = g_NvidiaExt.IncrementCounter();\n\n        RayDesc ray;\n        ray.TMin = asfloat(tmin);\n        ray.TMax = asfloat(tmax);\n        ray.Origin.x = asfloat(rayOrgX);\n        ray.Origin.y = asfloat(rayOrgY);\n        ray.Origin.z = asfloat(rayOrgZ);\n        ray.Direction.x = asfloat(rayDirX);\n        ray.Direction.y = asfloat(rayDirY);\n        ray.Direction.z = asfloat(rayDirZ);\n\n        return ray;\n    }    \n\n    uint GetShaderTableIndex()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_SHADER_TABLE_INDEX;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    uint LoadLocalRootTableConstant(uint RootConstantOffsetInBytes)\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_LOAD_LOCAL_ROOT_TABLE_CONSTANT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        g_NvidiaExt[index].src0u.y = RootConstantOffsetInBytes;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    float4 GetSphereObjectPositionAndRadius()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_SPHERE_OBJECT_POSITION_AND_RADIUS;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        float4 ret;\n        ret[0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[3] = asfloat(g_NvidiaExt.IncrementCounter());\n        return ret;\n    }\n\n    float2x4 GetLssObjectPositionsAndRadii()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_LSS_OBJECT_POSITIONS_AND_RADII;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        float2x4 ret;\n        ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][3] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][3] = asfloat(g_NvidiaExt.IncrementCounter());\n        return ret;\n    }\n\n    bool IsSphereHit()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_SPHERE_HIT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    bool IsLssHit()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_IS_LSS_HIT;\n        g_NvidiaExt[index].src0u.x = _handle;\n        uint ret = g_NvidiaExt.IncrementCounter();\n        return ret != 0;\n    }\n\n    uint GetClusterID()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_CLUSTER_ID;\n        g_NvidiaExt[index].src0u.x = _handle;\n        return g_NvidiaExt.IncrementCounter();\n    }\n\n    float3x3 GetTriangleObjectPositions()\n    {\n        uint index = g_NvidiaExt.IncrementCounter();\n        g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_TRIANGLE_OBJECT_POSITIONS;\n        g_NvidiaExt[index].src0u.x = _handle;\n\n        float3x3 ret;\n        ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2][0] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2][1] = asfloat(g_NvidiaExt.IncrementCounter());\n        ret[2][2] = asfloat(g_NvidiaExt.IncrementCounter());\n        return ret;\n    }\n};\n\n#define NvTraceRayHitObject(AccelerationStructure,RayFlags,InstanceInclusionMask,RayContributionToHitGroupIndex,MultiplierForGeometryContributionToHitGroupIndex,MissShaderIndex,Ray,Payload,ResultHitObj) \\\ndo { \\\n    uint _rayFlags = RayFlags; \\\n    uint _instanceInclusionMask = InstanceInclusionMask; \\\n    uint _rayContributionToHitGroupIndex = RayContributionToHitGroupIndex; \\\n    uint _multiplierForGeometryContributionToHitGroupIndex = MultiplierForGeometryContributionToHitGroupIndex; \\\n    uint _missShaderIndex = MissShaderIndex; \\\n    RayDesc _ray = Ray; \\\n    uint _index = g_NvidiaExt.IncrementCounter(); \\\n    g_NvidiaExt[_index].opcode = NV_EXTN_OP_HIT_OBJECT_TRACE_RAY; \\\n    g_NvidiaExt[_index].numOutputsForIncCounter = 2; \\\n    g_NvidiaExt[_index].src0u.x = _missShaderIndex; \\\n    uint _hitHandle = g_NvidiaExt.IncrementCounter(); \\\n    uint _traceHandle = g_NvidiaExt.IncrementCounter(); \\\n    TraceRay(AccelerationStructure, _rayFlags, _instanceInclusionMask, _rayContributionToHitGroupIndex, _multiplierForGeometryContributionToHitGroupIndex, _traceHandle, _ray, Payload); \\\n    ResultHitObj._handle = _hitHandle; \\\n} while(0)\n\nstruct NvHitObjectMacroDummyPayloadType { int a; };\n\n#define NvMakeHit(AccelerationStructure,InstanceIndex,GeometryIndex,PrimitiveIndex,HitKind,RayContributionToHitGroupIndex,MultiplierForGeometryContributionToHitGroupIndex,Ray,Attributes,ResultHitObj) \\\ndo { \\\n    uint _instanceIndex = InstanceIndex; \\\n    uint _geometryIndex = GeometryIndex; \\\n    uint _primitiveIndex = PrimitiveIndex; \\\n    uint _hitKind = HitKind; \\\n    uint _rayContributionToHitGroupIndex = RayContributionToHitGroupIndex; \\\n    uint _multiplierForGeometryContributionToHitGroupIndex = MultiplierForGeometryContributionToHitGroupIndex; \\\n    RayDesc _ray = Ray; \\\n    uint _index = g_NvidiaExt.IncrementCounter(); \\\n    g_NvidiaExt[_index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_HIT; \\\n    g_NvidiaExt[_index].numOutputsForIncCounter = 2; \\\n    g_NvidiaExt[_index].src0u.x = _instanceIndex; \\\n    g_NvidiaExt[_index].src0u.y = _geometryIndex; \\\n    g_NvidiaExt[_index].src0u.z = _primitiveIndex; \\\n    g_NvidiaExt[_index].src0u.w = _hitKind; \\\n    g_NvidiaExt[_index].src1u.x = _rayContributionToHitGroupIndex; \\\n    g_NvidiaExt[_index].src1u.y = _multiplierForGeometryContributionToHitGroupIndex; \\\n    uint _hitHandle = g_NvidiaExt.IncrementCounter(); \\\n    uint _traceHandle = g_NvidiaExt.IncrementCounter(); \\\n    CallShader(_traceHandle, Attributes); \\\n    NvHitObjectMacroDummyPayloadType _payload; \\\n    TraceRay(AccelerationStructure, 0, 0, 0, 0, _traceHandle, _ray, _payload); \\\n    ResultHitObj._handle = _hitHandle; \\\n} while(0)\n\n#define NvMakeHitWithRecordIndex(HitGroupRecordIndex,AccelerationStructure,InstanceIndex,GeometryIndex,PrimitiveIndex,HitKind,Ray,Attributes,ResultHitObj) \\\ndo { \\\n    uint _hitGroupRecordIndex = HitGroupRecordIndex; \\\n    uint _instanceIndex = InstanceIndex; \\\n    uint _geometryIndex = GeometryIndex; \\\n    uint _primitiveIndex = PrimitiveIndex; \\\n    uint _hitKind = HitKind; \\\n    RayDesc _ray = Ray; \\\n    uint _index = g_NvidiaExt.IncrementCounter(); \\\n    g_NvidiaExt[_index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX; \\\n    g_NvidiaExt[_index].numOutputsForIncCounter = 2; \\\n    g_NvidiaExt[_index].src0u.x = _instanceIndex; \\\n    g_NvidiaExt[_index].src0u.y = _geometryIndex; \\\n    g_NvidiaExt[_index].src0u.z = _primitiveIndex; \\\n    g_NvidiaExt[_index].src0u.w = _hitKind; \\\n    g_NvidiaExt[_index].src1u.x = _hitGroupRecordIndex; \\\n    uint _hitHandle = g_NvidiaExt.IncrementCounter(); \\\n    uint _traceHandle = g_NvidiaExt.IncrementCounter(); \\\n    CallShader(_traceHandle, Attributes); \\\n    NvHitObjectMacroDummyPayloadType _payload; \\\n    TraceRay(AccelerationStructure, 0, 0, 0, 0, _traceHandle, _ray, _payload); \\\n    ResultHitObj._handle = _hitHandle; \\\n} while(0)\n\nNvHitObject NvMakeMiss(\n    uint MissShaderIndex,\n    RayDesc Ray)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_MISS;\n    g_NvidiaExt[index].src0u.x = MissShaderIndex;\n    g_NvidiaExt[index].src0u.y = asuint(Ray.TMin);\n    g_NvidiaExt[index].src0u.z = asuint(Ray.TMax);\n    g_NvidiaExt[index].src1u.x = asuint(Ray.Origin.x);\n    g_NvidiaExt[index].src1u.y = asuint(Ray.Origin.y);\n    g_NvidiaExt[index].src1u.z = asuint(Ray.Origin.z);\n    g_NvidiaExt[index].src2u.x = asuint(Ray.Direction.x);\n    g_NvidiaExt[index].src2u.y = asuint(Ray.Direction.y);\n    g_NvidiaExt[index].src2u.z = asuint(Ray.Direction.z);\n    uint hitHandle = g_NvidiaExt.IncrementCounter();\n\n    NvHitObject hitObj;\n    hitObj._handle = hitHandle;\n    return hitObj;\n}\n\nNvHitObject NvMakeNop()\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_MAKE_NOP;\n    uint hitHandle = g_NvidiaExt.IncrementCounter();\n\n    NvHitObject hitObj;\n    hitObj._handle = hitHandle;\n    return hitObj;\n}\n\n#define NvGetAttributesFromHitObject(HitObj,ResultAttributes) \\\ndo { \\\n    uint _index = g_NvidiaExt.IncrementCounter(); \\\n    g_NvidiaExt[_index].opcode = NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES; \\\n    g_NvidiaExt[_index].src0u.x = HitObj._handle; \\\n    uint _callHandle = g_NvidiaExt.IncrementCounter(); \\\n    CallShader(_callHandle, ResultAttributes); \\\n} while(0)\n\nvoid NvReorderThread(uint CoherenceHint, uint NumCoherenceHintBits)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_REORDER_THREAD;\n    g_NvidiaExt[index].src0u.x = 0;\n    g_NvidiaExt[index].src0u.y = 0;\n    g_NvidiaExt[index].src0u.z = CoherenceHint;\n    g_NvidiaExt[index].src0u.w = NumCoherenceHintBits;\n    g_NvidiaExt.IncrementCounter();\n}\n\nvoid NvReorderThread(NvHitObject HitObj, uint CoherenceHint, uint NumCoherenceHintBits)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_HIT_OBJECT_REORDER_THREAD;\n    g_NvidiaExt[index].src0u.x = 1;\n    g_NvidiaExt[index].src0u.y = HitObj._handle;\n    g_NvidiaExt[index].src0u.z = CoherenceHint;\n    g_NvidiaExt[index].src0u.w = NumCoherenceHintBits;\n    g_NvidiaExt.IncrementCounter();\n}\n\nvoid NvReorderThread(NvHitObject HitObj)\n{\n    NvReorderThread(HitObj, 0, 0);\n}\n\n#define NvInvokeHitObject(AccelerationStructure,HitObj,Payload) \\\ndo { \\\n    uint _index = g_NvidiaExt.IncrementCounter(); \\\n    g_NvidiaExt[_index].opcode = NV_EXTN_OP_HIT_OBJECT_INVOKE; \\\n    g_NvidiaExt[_index].src0u.x = HitObj._handle; \\\n    uint _handle = g_NvidiaExt.IncrementCounter(); \\\n    TraceRay(AccelerationStructure, 0, 0, 0, 0, _handle, (RayDesc)0, Payload); \\\n} while(0)\n\n#endif\n"
  },
  {
    "path": "shaders/nvapi/nvHLSLExtnsInternal.h",
    "content": "/*********************************************************************************************************\\\n|*                                                                                                        *|\n|* SPDX-FileCopyrightText: Copyright (c) 2019-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.  *|\n|* SPDX-License-Identifier: MIT                                                                           *|\n|*                                                                                                        *|\n|* Permission is hereby granted, free of charge, to any person obtaining a                                *|\n|* copy of this software and associated documentation files (the \"Software\"),                             *|\n|* to deal in the Software without restriction, including without limitation                              *|\n|* the rights to use, copy, modify, merge, publish, distribute, sublicense,                               *|\n|* and/or sell copies of the Software, and to permit persons to whom the                                  *|\n|* Software is furnished to do so, subject to the following conditions:                                   *|\n|*                                                                                                        *|\n|* The above copyright notice and this permission notice shall be included in                             *|\n|* all copies or substantial portions of the Software.                                                    *|\n|*                                                                                                        *|\n|* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                             *|\n|* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                               *|\n|* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL                               *|\n|* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                             *|\n|* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING                                *|\n|* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER                                    *|\n|* DEALINGS IN THE SOFTWARE.                                                                              *|\n|*                                                                                                        *|\n|*                                                                                                        *|\n\\*********************************************************************************************************/\n////////////////////////// NVIDIA SHADER EXTENSIONS /////////////////\n// internal functions\n// Functions in this file are not expected to be called by apps directly\n\n#include \"nvShaderExtnEnums.h\"\n\nstruct NvShaderExtnStruct\n{\n    uint   opcode;                  // opcode\n    uint   rid;                     // resource ID\n    uint   sid;                     // sampler ID\n            \n    uint4  dst1u;                   // destination operand 1 (for instructions that need extra destination operands)\n    uint4  src3u;                   // source operand 3\n    uint4  src4u;                   // source operand 4\n    uint4  src5u;                   // source operand 5\n            \n    uint4  src0u;                   // uint source operand  0\n    uint4  src1u;                   // uint source operand  0\n    uint4  src2u;                   // uint source operand  0\n    uint4  dst0u;                   // uint destination operand\n            \n    uint   markUavRef;              // the next store to UAV is fake and is used only to identify the uav slot\n    uint   numOutputsForIncCounter; // Used for output to IncrementCounter \n    float  padding1[27];            // struct size: 256 bytes\n};\n\n// RW structured buffer for Nvidia shader extensions\n\n// Application needs to define NV_SHADER_EXTN_SLOT as a unused slot, which should be \n// set using NvAPI_D3D11_SetNvShaderExtnSlot() call before creating the first shader that\n// uses nvidia shader extensions. E.g before including this file in shader define it as:\n// #define NV_SHADER_EXTN_SLOT u7\n\n// For SM5.1, application needs to define NV_SHADER_EXTN_REGISTER_SPACE as register space\n// E.g. before including this file in shader define it as:\n// #define NV_SHADER_EXTN_REGISTER_SPACE space2\n\n// Note that other operations to this UAV will be ignored so application\n// should bind a null resource\n\n#ifdef NV_SHADER_EXTN_REGISTER_SPACE\nRWStructuredBuffer<NvShaderExtnStruct> g_NvidiaExt : register( NV_SHADER_EXTN_SLOT, NV_SHADER_EXTN_REGISTER_SPACE );\n#else\nRWStructuredBuffer<NvShaderExtnStruct> g_NvidiaExt : register( NV_SHADER_EXTN_SLOT );\n#endif\n\n//----------------------------------------------------------------------------//\n// the exposed SHFL instructions accept a mask parameter in src2\n// To compute lane mask from width of segment:\n// minLaneID : currentLaneId & src2[12:8]\n// maxLaneID : minLaneId | (src2[4:0] & ~src2[12:8])\n// where [minLaneId, maxLaneId] defines the segment where currentLaneId belongs\n// we always set src2[4:0] to 11111 (0x1F), and set src2[12:8] as (32 - width)\nint __NvGetShflMaskFromWidth(uint width)\n{\n    return ((NV_WARP_SIZE - width) << 8) | 0x1F;\n}\n\n//----------------------------------------------------------------------------//\n\nvoid __NvReferenceUAVForOp(RWByteAddressBuffer uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav.Store(index, 0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<float2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = float2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<float2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = float2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<float2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = float2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<float4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = float4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<float4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = float4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<float4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = float4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<float> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = 0.0f;\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<float> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = 0.0f;\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<float> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = 0.0f;\n}\n\n\nvoid __NvReferenceUAVForOp(RWTexture1D<uint2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = uint2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<uint2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = uint2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<uint2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = uint2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<uint4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = uint4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<uint4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = uint4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<uint4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = uint4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<uint> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = 0;\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<uint> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = 0;\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<uint> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = 0;\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<int2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = int2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<int2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = int2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<int2> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = int2(0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<int4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = int4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<int4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = int4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<int4> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = int4(0,0,0,0);\n}\n\nvoid __NvReferenceUAVForOp(RWTexture1D<int> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[index] = 0;\n}\n\nvoid __NvReferenceUAVForOp(RWTexture2D<int> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint2(index,index)] = 0;\n}\n\nvoid __NvReferenceUAVForOp(RWTexture3D<int> uav)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].markUavRef = 1;\n    uav[uint3(index,index,index)] = 0;\n}\n\n//----------------------------------------------------------------------------//\n// ATOMIC op sub-opcodes\n#define NV_EXTN_ATOM_AND                            0\n#define NV_EXTN_ATOM_OR                             1\n#define NV_EXTN_ATOM_XOR                            2\n\n#define NV_EXTN_ATOM_ADD                            3\n#define NV_EXTN_ATOM_MAX                            6\n#define NV_EXTN_ATOM_MIN                            7\n\n#define NV_EXTN_ATOM_SWAP                           8\n#define NV_EXTN_ATOM_CAS                            9\n\n//----------------------------------------------------------------------------//\n\n// performs Atomic operation on two consecutive fp16 values in the given UAV\n// the uint paramater 'fp16x2Val' is treated as two fp16 values\n// the passed sub-opcode 'op' should be an immediate constant\n// byteAddress must be multiple of 4\n// the returned value are the two fp16 values packed into a single uint\nuint __NvAtomicOpFP16x2(RWByteAddressBuffer uav, uint byteAddress, uint fp16x2Val, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = byteAddress;\n    g_NvidiaExt[index].src1u.x = fp16x2Val;\n    g_NvidiaExt[index].src2u.x = atomicOpType;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_FP16_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.x;    \n}\n\n//----------------------------------------------------------------------------//\n\n// performs Atomic operation on a R16G16_FLOAT UAV at the given address\n// the uint paramater 'fp16x2Val' is treated as two fp16 values\n// the passed sub-opcode 'op' should be an immediate constant\n// the returned value are the two fp16 values (.x and .y components) packed into a single uint\n// Warning: Behaviour of these set of functions is undefined if the UAV is not \n// of R16G16_FLOAT format (might result in app crash or TDR)\n\nuint __NvAtomicOpFP16x2(RWTexture1D<float2> uav, uint address, uint fp16x2Val, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x    = address;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.x;    \n}\n\nuint __NvAtomicOpFP16x2(RWTexture2D<float2> uav, uint2 address, uint fp16x2Val, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy   = address;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.x;    \n}\n\nuint __NvAtomicOpFP16x2(RWTexture3D<float2> uav, uint3 address, uint fp16x2Val, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xyz  = address;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.x;    \n}\n\n//----------------------------------------------------------------------------//\n\n// performs Atomic operation on a R16G16B16A16_FLOAT UAV at the given address\n// the uint2 paramater 'fp16x2Val' is treated as four fp16 values \n// i.e, fp16x2Val.x = uav.xy and fp16x2Val.y = uav.yz\n// the passed sub-opcode 'op' should be an immediate constant\n// the returned value are the four fp16 values (.xyzw components) packed into uint2\n// Warning: Behaviour of these set of functions is undefined if the UAV is not \n// of R16G16B16A16_FLOAT format (might result in app crash or TDR)\n\nuint2 __NvAtomicOpFP16x2(RWTexture1D<float4> uav, uint address, uint2 fp16x2Val, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n\n    // break it down into two fp16x2 atomic ops\n    uint2 retVal;\n\n    // first op has x-coordinate = x * 2\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x    = address * 2;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val.x;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n    retVal.x = g_NvidiaExt[index].dst0u.x;\n\n    // second op has x-coordinate = x * 2 + 1\n    index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x    = address * 2 + 1;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val.y;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n    retVal.y = g_NvidiaExt[index].dst0u.x;\n\n    return retVal;\n}\n\nuint2 __NvAtomicOpFP16x2(RWTexture2D<float4> uav, uint2 address, uint2 fp16x2Val, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n\n    // break it down into two fp16x2 atomic ops\n    uint2 retVal;\n\n    // first op has x-coordinate = x * 2\n    uint2 addressTemp = uint2(address.x * 2, address.y);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy   = addressTemp;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val.x;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n    retVal.x = g_NvidiaExt[index].dst0u.x;\n\n    // second op has x-coordinate = x * 2 + 1\n    addressTemp.x++;\n    index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy   = addressTemp;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val.y;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n    retVal.y = g_NvidiaExt[index].dst0u.x;\n\n    return retVal;\n}\n\nuint2 __NvAtomicOpFP16x2(RWTexture3D<float4> uav, uint3 address, uint2 fp16x2Val, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n\n    // break it down into two fp16x2 atomic ops\n    uint2 retVal;\n\n    // first op has x-coordinate = x * 2\n    uint3 addressTemp = uint3(address.x * 2, address.y, address.z);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xyz  = addressTemp;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val.x;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n    retVal.x = g_NvidiaExt[index].dst0u.x;\n\n    // second op has x-coordinate = x * 2 + 1\n    addressTemp.x++;\n    index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xyz  = addressTemp;\n    g_NvidiaExt[index].src1u.x    = fp16x2Val.y;\n    g_NvidiaExt[index].src2u.x    = atomicOpType;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP16_ATOMIC;\n    retVal.y = g_NvidiaExt[index].dst0u.x;\n\n    return retVal;\n}\n\nuint __fp32x2Tofp16x2(float2 val)\n{\n    return (f32tof16(val.y)<<16) | f32tof16(val.x) ;\n}\n\nuint2 __fp32x4Tofp16x4(float4 val)\n{\n    return uint2( (f32tof16(val.y)<<16) | f32tof16(val.x), (f32tof16(val.w)<<16) | f32tof16(val.z) ) ;\n}\n\n//----------------------------------------------------------------------------//\n\n// FP32 Atomic functions\n// performs Atomic operation treating the uav as float (fp32) values\n// the passed sub-opcode 'op' should be an immediate constant\n// byteAddress must be multiple of 4\nfloat __NvAtomicAddFP32(RWByteAddressBuffer uav, uint byteAddress, float val)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = byteAddress;\n    g_NvidiaExt[index].src1u.x = asuint(val);   // passing as uint to make it more convinient for the driver to translate\n    g_NvidiaExt[index].src2u.x = NV_EXTN_ATOM_ADD;\n    g_NvidiaExt[index].opcode  = NV_EXTN_OP_FP32_ATOMIC;\n\n    return asfloat(g_NvidiaExt[index].dst0u.x);\n}\n\nfloat __NvAtomicAddFP32(RWTexture1D<float> uav, uint address, float val)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x    = address;\n    g_NvidiaExt[index].src1u.x    = asuint(val);\n    g_NvidiaExt[index].src2u.x    = NV_EXTN_ATOM_ADD;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP32_ATOMIC;\n\n    return asfloat(g_NvidiaExt[index].dst0u.x);\n}\n\nfloat __NvAtomicAddFP32(RWTexture2D<float> uav, uint2 address, float val)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy   = address;\n    g_NvidiaExt[index].src1u.x    = asuint(val);\n    g_NvidiaExt[index].src2u.x    = NV_EXTN_ATOM_ADD;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP32_ATOMIC;\n\n    return asfloat(g_NvidiaExt[index].dst0u.x);\n}\n\nfloat __NvAtomicAddFP32(RWTexture3D<float> uav, uint3 address, float val)\n{\n    __NvReferenceUAVForOp(uav);\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xyz  = address;\n    g_NvidiaExt[index].src1u.x    = asuint(val);\n    g_NvidiaExt[index].src2u.x    = NV_EXTN_ATOM_ADD;\n    g_NvidiaExt[index].opcode     = NV_EXTN_OP_FP32_ATOMIC;\n\n    return asfloat(g_NvidiaExt[index].dst0u.x);\n}\n\n//----------------------------------------------------------------------------//\n\n// UINT64 Atmoic Functions\n// The functions below performs atomic operation on the given UAV treating the value as uint64\n// byteAddress must be multiple of 8\n// The returned value is the value present in memory location before the atomic operation\n// uint2 vector type is used to represent a single uint64 value with the x component containing the low 32 bits and y component the high 32 bits.\n\nuint2 __NvAtomicCompareExchangeUINT64(RWByteAddressBuffer uav, uint byteAddress, uint2 compareValue, uint2 value)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  = byteAddress;\n    g_NvidiaExt[index].src1u.xy = compareValue;\n    g_NvidiaExt[index].src1u.zw = value;\n    g_NvidiaExt[index].src2u.x  = NV_EXTN_ATOM_CAS;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\nuint2 __NvAtomicOpUINT64(RWByteAddressBuffer uav, uint byteAddress, uint2 value, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  = byteAddress;\n    g_NvidiaExt[index].src1u.xy = value;\n    g_NvidiaExt[index].src2u.x  = atomicOpType;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\nuint2 __NvAtomicCompareExchangeUINT64(RWTexture1D<uint2> uav, uint address, uint2 compareValue, uint2 value)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  = address;\n    g_NvidiaExt[index].src1u.xy = compareValue;\n    g_NvidiaExt[index].src1u.zw = value;\n    g_NvidiaExt[index].src2u.x  = NV_EXTN_ATOM_CAS;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\nuint2 __NvAtomicOpUINT64(RWTexture1D<uint2> uav, uint address, uint2 value, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  = address;\n    g_NvidiaExt[index].src1u.xy = value;\n    g_NvidiaExt[index].src2u.x  = atomicOpType;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\nuint2 __NvAtomicCompareExchangeUINT64(RWTexture2D<uint2> uav, uint2 address, uint2 compareValue, uint2 value)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy  = address;\n    g_NvidiaExt[index].src1u.xy = compareValue;\n    g_NvidiaExt[index].src1u.zw = value;\n    g_NvidiaExt[index].src2u.x  = NV_EXTN_ATOM_CAS;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\nuint2 __NvAtomicOpUINT64(RWTexture2D<uint2> uav, uint2 address, uint2 value, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xy  = address;\n    g_NvidiaExt[index].src1u.xy = value;\n    g_NvidiaExt[index].src2u.x  = atomicOpType;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\nuint2 __NvAtomicCompareExchangeUINT64(RWTexture3D<uint2> uav, uint3 address, uint2 compareValue, uint2 value)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xyz  = address;\n    g_NvidiaExt[index].src1u.xy = compareValue;\n    g_NvidiaExt[index].src1u.zw = value;\n    g_NvidiaExt[index].src2u.x  = NV_EXTN_ATOM_CAS;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\nuint2 __NvAtomicOpUINT64(RWTexture3D<uint2> uav, uint3 address, uint2 value, uint atomicOpType)\n{\n    __NvReferenceUAVForOp(uav);\n\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.xyz  = address;\n    g_NvidiaExt[index].src1u.xy = value;\n    g_NvidiaExt[index].src2u.x  = atomicOpType;\n    g_NvidiaExt[index].opcode   = NV_EXTN_OP_UINT64_ATOMIC;\n\n    return g_NvidiaExt[index].dst0u.xy;\n}\n\n\nuint4 __NvFootprint(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint footprintmode, uint gran, int3 offset = int3(0, 0, 0))\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = texIndex;\n    g_NvidiaExt[index].src0u.y  = smpIndex;\n    g_NvidiaExt[index].src1u.xyz = asuint(location);\n    g_NvidiaExt[index].src1u.w = gran;\n    g_NvidiaExt[index].src3u.x = texSpace;\n    g_NvidiaExt[index].src3u.y = smpSpace;\n    g_NvidiaExt[index].src3u.z = texType;\n    g_NvidiaExt[index].src3u.w = footprintmode;\n    g_NvidiaExt[index].src4u.xyz = asuint(offset);\n\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_FOOTPRINT;\n    g_NvidiaExt[index].numOutputsForIncCounter = 4;\n\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    uint4 op;\n    op.x = g_NvidiaExt.IncrementCounter();\n    op.y = g_NvidiaExt.IncrementCounter();\n    op.z = g_NvidiaExt.IncrementCounter();\n    op.w = g_NvidiaExt.IncrementCounter();\n    return op;\n}\n\nuint4 __NvFootprintBias(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint footprintmode, uint gran, float bias, int3 offset = int3(0, 0, 0))\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = texIndex;\n    g_NvidiaExt[index].src0u.y  = smpIndex;\n    g_NvidiaExt[index].src1u.xyz = asuint(location);\n    g_NvidiaExt[index].src1u.w = gran;\n    g_NvidiaExt[index].src2u.x = asuint(bias);\n    g_NvidiaExt[index].src3u.x = texSpace;\n    g_NvidiaExt[index].src3u.y = smpSpace;\n    g_NvidiaExt[index].src3u.z = texType;\n    g_NvidiaExt[index].src3u.w = footprintmode;\n    g_NvidiaExt[index].src4u.xyz = asuint(offset);\n\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_FOOTPRINT_BIAS;\n    g_NvidiaExt[index].numOutputsForIncCounter = 4;\n\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    uint4 op;\n    op.x = g_NvidiaExt.IncrementCounter();\n    op.y = g_NvidiaExt.IncrementCounter();\n    op.z = g_NvidiaExt.IncrementCounter();\n    op.w = g_NvidiaExt.IncrementCounter();\n    return op;\n}\n\nuint4 __NvFootprintLevel(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint footprintmode, uint gran, float lodLevel, int3 offset = int3(0, 0, 0))\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = texIndex;\n    g_NvidiaExt[index].src0u.y  = smpIndex;\n    g_NvidiaExt[index].src1u.xyz = asuint(location);\n    g_NvidiaExt[index].src1u.w = gran;\n    g_NvidiaExt[index].src2u.x = asuint(lodLevel);\n    g_NvidiaExt[index].src3u.x = texSpace;\n    g_NvidiaExt[index].src3u.y = smpSpace;\n    g_NvidiaExt[index].src3u.z = texType;\n    g_NvidiaExt[index].src3u.w = footprintmode;\n    g_NvidiaExt[index].src4u.xyz = asuint(offset);\n\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_FOOTPRINT_LEVEL;\n    g_NvidiaExt[index].numOutputsForIncCounter = 4;\n\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    uint4 op;\n    op.x = g_NvidiaExt.IncrementCounter();\n    op.y = g_NvidiaExt.IncrementCounter();\n    op.z = g_NvidiaExt.IncrementCounter();\n    op.w = g_NvidiaExt.IncrementCounter();\n    return op;\n}\n\nuint4 __NvFootprintGrad(uint texSpace, uint texIndex, uint smpSpace, uint smpIndex, uint texType, float3 location, uint footprintmode, uint gran, float3 ddx, float3 ddy, int3 offset = int3(0, 0, 0))\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x = texIndex;\n    g_NvidiaExt[index].src0u.y  = smpIndex;\n    g_NvidiaExt[index].src1u.xyz = asuint(location);\n    g_NvidiaExt[index].src1u.w = gran;\n    g_NvidiaExt[index].src2u.xyz = asuint(ddx);\n    g_NvidiaExt[index].src5u.xyz = asuint(ddy);\n    g_NvidiaExt[index].src3u.x = texSpace;\n    g_NvidiaExt[index].src3u.y = smpSpace;\n    g_NvidiaExt[index].src3u.z = texType;\n    g_NvidiaExt[index].src3u.w = footprintmode;\n    g_NvidiaExt[index].src4u.xyz = asuint(offset);\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_FOOTPRINT_GRAD;\n    g_NvidiaExt[index].numOutputsForIncCounter = 4;\n\n    // result is returned as the return value of IncrementCounter on fake UAV slot\n    uint4 op;\n    op.x = g_NvidiaExt.IncrementCounter();\n    op.y = g_NvidiaExt.IncrementCounter();\n    op.z = g_NvidiaExt.IncrementCounter();\n    op.w = g_NvidiaExt.IncrementCounter();\n    return op;\n}\n\n// returns value of special register - specify subopcode from any of NV_SPECIALOP_* specified in nvShaderExtnEnums.h - other opcodes undefined behavior\nuint __NvGetSpecial(uint subOpCode)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_GET_SPECIAL;\n    g_NvidiaExt[index].src0u.x = subOpCode;\n    return g_NvidiaExt.IncrementCounter();\n}\n\n// predicate is returned in laneValid indicating if srcLane is in range and val from specified lane is returned.\nint __NvShflGeneric(int val, uint srcLane, uint maskClampVal, out uint laneValid)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].src0u.x  =  val;                             // variable to be shuffled\n    g_NvidiaExt[index].src0u.y  =  srcLane;                         // source lane\n    g_NvidiaExt[index].src0u.z  =  maskClampVal;\n    g_NvidiaExt[index].opcode   =  NV_EXTN_OP_SHFL_GENERIC;\n    g_NvidiaExt[index].numOutputsForIncCounter = 2;\n\n    laneValid = asuint(g_NvidiaExt.IncrementCounter());\n    return g_NvidiaExt.IncrementCounter();\n}\n\n//----------------------------------------------------------------------------//\n\n// DXR RayQuery functions\n\n#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 5)\n\nuint __NvRtGetCandidateClusterID(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_GET_CANDIDATE_CLUSTER_ID;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    return g_NvidiaExt.IncrementCounter();\n}\n\nuint __NvRtGetCommittedClusterID(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_GET_COMMITTED_CLUSTER_ID;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    return g_NvidiaExt.IncrementCounter();\n}\n\nfloat3x3 __NvRtCandidateTriangleObjectPositions(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_CANDIDATE_TRIANGLE_OBJECT_POSITIONS;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n\n    float3x3 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat3x3 __NvRtCommittedTriangleObjectPositions(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_COMMITTED_TRIANGLE_OBJECT_POSITIONS;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n\n    float3x3 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nbool __NvRtCandidateIsNonOpaqueSphere(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_CANDIDATE_IS_NONOPAQUE_SPHERE;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\nbool __NvRtCandidateIsNonOpaqueLss(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_CANDIDATE_IS_NONOPAQUE_LSS;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\nfloat __NvRtCandidateLssHitParameter(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_CANDIDATE_LSS_HIT_PARAMETER;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    float ret = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat4 __NvRtCandidateSphereObjectPositionAndRadius(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_CANDIDATE_SPHERE_OBJECT_POSITION_AND_RADIUS;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n\n    float4 ret;\n    ret[0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[3] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat2x4 __NvRtCandidateLssObjectPositionsAndRadii(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_CANDIDATE_LSS_OBJECT_POSITIONS_AND_RADII;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n\n    float2x4 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][3] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][3] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat __NvRtCandidateBuiltinPrimitiveRayT(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_CANDIDATE_BUILTIN_PRIMITIVE_RAY_T;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    float ret = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nbool __NvRtCommittedIsSphere(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_COMMITTED_IS_SPHERE;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\nbool __NvRtCommittedIsLss(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_COMMITTED_IS_LSS;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    uint ret = g_NvidiaExt.IncrementCounter();\n    return ret != 0;\n}\n\nfloat __NvRtCommittedLssHitParameter(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_COMMITTED_LSS_HIT_PARAMETER;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    float ret = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat4 __NvRtCommittedSphereObjectPositionAndRadius(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_COMMITTED_SPHERE_OBJECT_POSITION_AND_RADIUS;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n\n    float4 ret;\n    ret[0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[3] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nfloat2x4 __NvRtCommittedLssObjectPositionsAndRadii(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_COMMITTED_LSS_OBJECT_POSITIONS_AND_RADII;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n\n    float2x4 ret;\n    ret[0][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[0][3] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][0] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][1] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][2] = asfloat(g_NvidiaExt.IncrementCounter());\n    ret[1][3] = asfloat(g_NvidiaExt.IncrementCounter());\n    return ret;\n}\n\nvoid __NvRtCommitNonOpaqueBuiltinPrimitiveHit(uint rqFlags)\n{\n    uint index = g_NvidiaExt.IncrementCounter();\n    g_NvidiaExt[index].opcode = NV_EXTN_OP_RT_COMMIT_NONOPAQUE_BUILTIN_PRIMITIVE_HIT;\n    g_NvidiaExt[index].src0u.x = rqFlags;\n    uint handle = g_NvidiaExt.IncrementCounter();\n}\n\n#endif\n"
  },
  {
    "path": "shaders/nvapi/nvShaderExtnEnums.h",
    "content": "/*********************************************************************************************************\\\n|*                                                                                                        *|\n|* SPDX-FileCopyrightText: Copyright (c) 2019-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.  *|\n|* SPDX-License-Identifier: MIT                                                                           *|\n|*                                                                                                        *|\n|* Permission is hereby granted, free of charge, to any person obtaining a                                *|\n|* copy of this software and associated documentation files (the \"Software\"),                             *|\n|* to deal in the Software without restriction, including without limitation                              *|\n|* the rights to use, copy, modify, merge, publish, distribute, sublicense,                               *|\n|* and/or sell copies of the Software, and to permit persons to whom the                                  *|\n|* Software is furnished to do so, subject to the following conditions:                                   *|\n|*                                                                                                        *|\n|* The above copyright notice and this permission notice shall be included in                             *|\n|* all copies or substantial portions of the Software.                                                    *|\n|*                                                                                                        *|\n|* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                             *|\n|* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                               *|\n|* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL                               *|\n|* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                             *|\n|* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING                                *|\n|* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER                                    *|\n|* DEALINGS IN THE SOFTWARE.                                                                              *|\n|*                                                                                                        *|\n|*                                                                                                        *|\n\\*********************************************************************************************************/\n\n////////////////////////////////////////////////////////////////////////////////\n////////////////////////// NVIDIA SHADER EXTENSIONS ////////////////////////////\n////////////////////////////////////////////////////////////////////////////////\n\n// This file can be included both from HLSL shader code as well as C++ code.\n// The app should call NvAPI_D3D11_IsNvShaderExtnOpCodeSupported() / NvAPI_D3D12_IsNvShaderExtnOpCodeSupported()\n// to check for support for every nv shader extension opcode it plans to use\n\n\n\n//----------------------------------------------------------------------------//\n//---------------------------- NV Shader Extn Version  -----------------------//\n//----------------------------------------------------------------------------//\n#define NV_SHADER_EXTN_VERSION                              1\n\n//----------------------------------------------------------------------------//\n//---------------------------- Misc constants --------------------------------//\n//----------------------------------------------------------------------------//\n#define NV_WARP_SIZE                                       32\n#define NV_WARP_SIZE_LOG2                                   5\n\n//----------------------------------------------------------------------------//\n//---------------------------- opCode constants ------------------------------//\n//----------------------------------------------------------------------------//\n\n\n#define NV_EXTN_OP_SHFL                                     1\n#define NV_EXTN_OP_SHFL_UP                                  2\n#define NV_EXTN_OP_SHFL_DOWN                                3\n#define NV_EXTN_OP_SHFL_XOR                                 4\n\n#define NV_EXTN_OP_VOTE_ALL                                 5\n#define NV_EXTN_OP_VOTE_ANY                                 6\n#define NV_EXTN_OP_VOTE_BALLOT                              7\n\n#define NV_EXTN_OP_GET_LANE_ID                              8\n#define NV_EXTN_OP_FP16_ATOMIC                             12\n#define NV_EXTN_OP_FP32_ATOMIC                             13\n\n#define NV_EXTN_OP_GET_SPECIAL                             19\n\n#define NV_EXTN_OP_UINT64_ATOMIC                           20\n\n#define NV_EXTN_OP_MATCH_ANY                               21 \n\n// FOOTPRINT - For Sample and SampleBias\n#define NV_EXTN_OP_FOOTPRINT                               28\n#define NV_EXTN_OP_FOOTPRINT_BIAS                          29\n\n#define NV_EXTN_OP_GET_SHADING_RATE                        30\n\n// FOOTPRINT - For SampleLevel and SampleGrad\n#define NV_EXTN_OP_FOOTPRINT_LEVEL                         31\n#define NV_EXTN_OP_FOOTPRINT_GRAD                          32\n\n// SHFL Generic\n#define NV_EXTN_OP_SHFL_GENERIC                            33\n\n#define NV_EXTN_OP_VPRS_EVAL_ATTRIB_AT_SAMPLE              51\n#define NV_EXTN_OP_VPRS_EVAL_ATTRIB_SNAPPED                52\n\n// HitObject API\n#define NV_EXTN_OP_HIT_OBJECT_TRACE_RAY                    67\n#define NV_EXTN_OP_HIT_OBJECT_MAKE_HIT                     68\n#define NV_EXTN_OP_HIT_OBJECT_MAKE_HIT_WITH_RECORD_INDEX   69\n#define NV_EXTN_OP_HIT_OBJECT_MAKE_MISS                    70\n#define NV_EXTN_OP_HIT_OBJECT_REORDER_THREAD               71\n#define NV_EXTN_OP_HIT_OBJECT_INVOKE                       72\n#define NV_EXTN_OP_HIT_OBJECT_IS_MISS                      73\n#define NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_ID              74\n#define NV_EXTN_OP_HIT_OBJECT_GET_INSTANCE_INDEX           75\n#define NV_EXTN_OP_HIT_OBJECT_GET_PRIMITIVE_INDEX          76\n#define NV_EXTN_OP_HIT_OBJECT_GET_GEOMETRY_INDEX           77\n#define NV_EXTN_OP_HIT_OBJECT_GET_HIT_KIND                 78\n#define NV_EXTN_OP_HIT_OBJECT_GET_RAY_DESC                 79\n#define NV_EXTN_OP_HIT_OBJECT_GET_ATTRIBUTES               80\n#define NV_EXTN_OP_HIT_OBJECT_GET_SHADER_TABLE_INDEX       81\n#define NV_EXTN_OP_HIT_OBJECT_LOAD_LOCAL_ROOT_TABLE_CONSTANT  82\n#define NV_EXTN_OP_HIT_OBJECT_IS_HIT                       83\n#define NV_EXTN_OP_HIT_OBJECT_IS_NOP                       84\n#define NV_EXTN_OP_HIT_OBJECT_MAKE_NOP                     85\n\n// Micro-map API\n#define NV_EXTN_OP_RT_TRIANGLE_OBJECT_POSITIONS            86\n#define NV_EXTN_OP_RT_MICRO_TRIANGLE_OBJECT_POSITIONS      87\n#define NV_EXTN_OP_RT_MICRO_TRIANGLE_BARYCENTRICS          88\n#define NV_EXTN_OP_RT_IS_MICRO_TRIANGLE_HIT                89\n#define NV_EXTN_OP_RT_IS_BACK_FACING                       90\n#define NV_EXTN_OP_RT_MICRO_VERTEX_OBJECT_POSITION         91\n#define NV_EXTN_OP_RT_MICRO_VERTEX_BARYCENTRICS            92\n\n// Megageometry API\n#define NV_EXTN_OP_RT_GET_CLUSTER_ID                        93\n#define NV_EXTN_OP_RT_GET_CANDIDATE_CLUSTER_ID              94\n#define NV_EXTN_OP_RT_GET_COMMITTED_CLUSTER_ID              95\n#define NV_EXTN_OP_HIT_OBJECT_GET_CLUSTER_ID                96\n#define NV_EXTN_OP_RT_CANDIDATE_TRIANGLE_OBJECT_POSITIONS   97\n#define NV_EXTN_OP_RT_COMMITTED_TRIANGLE_OBJECT_POSITIONS   98\n#define NV_EXTN_OP_HIT_OBJECT_GET_TRIANGLE_OBJECT_POSITIONS 99\n\n// Linear Swept Sphere API\n#define NV_EXTN_OP_RT_SPHERE_OBJECT_POSITION_AND_RADIUS             100\n#define NV_EXTN_OP_RT_CANDIDATE_SPHERE_OBJECT_POSITION_AND_RADIUS   101\n#define NV_EXTN_OP_RT_COMMITTED_SPHERE_OBJECT_POSITION_AND_RADIUS   102\n#define NV_EXTN_OP_HIT_OBJECT_GET_SPHERE_OBJECT_POSITION_AND_RADIUS 103\n#define NV_EXTN_OP_RT_LSS_OBJECT_POSITIONS_AND_RADII                104\n#define NV_EXTN_OP_RT_CANDIDATE_LSS_OBJECT_POSITIONS_AND_RADII      105\n#define NV_EXTN_OP_RT_COMMITTED_LSS_OBJECT_POSITIONS_AND_RADII      106\n#define NV_EXTN_OP_HIT_OBJECT_GET_LSS_OBJECT_POSITIONS_AND_RADII    107\n#define NV_EXTN_OP_RT_IS_SPHERE_HIT                                 108\n#define NV_EXTN_OP_RT_CANDIDATE_IS_NONOPAQUE_SPHERE                 109\n#define NV_EXTN_OP_RT_COMMITTED_IS_SPHERE                           110\n#define NV_EXTN_OP_HIT_OBJECT_IS_SPHERE_HIT                         111\n#define NV_EXTN_OP_RT_IS_LSS_HIT                                    112\n#define NV_EXTN_OP_RT_CANDIDATE_IS_NONOPAQUE_LSS                    113\n#define NV_EXTN_OP_RT_COMMITTED_IS_LSS                              114\n#define NV_EXTN_OP_HIT_OBJECT_IS_LSS_HIT                            115\n#define NV_EXTN_OP_RT_CANDIDATE_LSS_HIT_PARAMETER                   116\n#define NV_EXTN_OP_RT_COMMITTED_LSS_HIT_PARAMETER                   117\n#define NV_EXTN_OP_RT_CANDIDATE_BUILTIN_PRIMITIVE_RAY_T             118\n#define NV_EXTN_OP_RT_COMMIT_NONOPAQUE_BUILTIN_PRIMITIVE_HIT        119\n//----------------------------------------------------------------------------//\n//-------------------- GET_SPECIAL subOpCode constants -----------------------//\n//----------------------------------------------------------------------------//\n#define NV_SPECIALOP_THREADLTMASK                           4\n#define NV_SPECIALOP_FOOTPRINT_SINGLELOD_PRED               5\n#define NV_SPECIALOP_GLOBAL_TIMER_LO                        9\n#define NV_SPECIALOP_GLOBAL_TIMER_HI                       10\n\n//----------------------------------------------------------------------------//\n//----------------------------- Texture Types  -------------------------------//\n//----------------------------------------------------------------------------//\n#define NV_EXTN_TEXTURE_1D                                  2\n#define NV_EXTN_TEXTURE_1D_ARRAY                            3\n#define NV_EXTN_TEXTURE_2D                                  4\n#define NV_EXTN_TEXTURE_2D_ARRAY                            5\n#define NV_EXTN_TEXTURE_3D                                  6\n#define NV_EXTN_TEXTURE_CUBE                                7\n#define NV_EXTN_TEXTURE_CUBE_ARRAY                          8\n\n\n//---------------------------------------------------------------------------//\n//----------------FOOTPRINT Enums for NvFootprint* extns---------------------//\n//---------------------------------------------------------------------------//\n#define NV_EXTN_FOOTPRINT_MODE_FINE                         0\n#define NV_EXTN_FOOTPRINT_MODE_COARSE                       1\n\n//----------------------------------------------------------------------------//\n//--------------------------- Cluster Constants  -----------------------------//\n//----------------------------------------------------------------------------//\n\n#define NV_EXTN_CLUSTER_ID_INVALID                 0xffffffff\n\n"
  },
  {
    "path": "shaders/nvapi/ray-query-cluster-id.nvapi.comp",
    "content": "#define NV_SHADER_EXTN_SLOT u127\n#define NV_SHADER_EXTN_REGISTER_SPACE space0\n#include \"nvHLSLExtns.h\"\n\nRaytracingAccelerationStructure RTAS : register(t0);\nRWStructuredBuffer<uint> RWUint : register(u1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tRayQuery<RAY_FLAG_CULL_NON_OPAQUE> q;\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.TMin = 4;\n\tray.Direction = float3(5, 6, 7);\n\tray.TMax = 8;\n\tq.TraceRayInline(RTAS, RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, 0xaa, ray);\n\n\twhile (q.Proceed())\n\t{\n\t\tRWUint[2 * thr + 0] = NvRtGetCandidateClusterID(q);\n\t\tq.Abort();\n\t}\n\n\tif (q.CommittedStatus())\n\t{\n\t\tRWUint[2 * thr + 1] = NvRtGetCommittedClusterID(q);\n\t}\n}\n\n"
  },
  {
    "path": "shaders/nvapi/rt-cluster-id.nvapi.rany",
    "content": "#define NV_SHADER_EXTN_SLOT u127\n#define NV_SHADER_EXTN_REGISTER_SPACE space0\n#include \"nvHLSLExtns.h\"\n\nstruct Payload\n{\n\tuint index;\n};\n\n[shader(\"anyhit\")]\nvoid RayHit(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.index = NvRtGetClusterID();\n}\n"
  },
  {
    "path": "shaders/nvapi/shuffle.nvapi.ssbo.comp",
    "content": "#define NV_SHADER_EXTN_SLOT u127\n#define NV_SHADER_EXTN_REGISTER_SPACE space0\n#include \"nvHLSLExtns.h\"\n\nRWStructuredBuffer<uint> Blah;\n\nRWByteAddressBuffer BAB;\nRWTexture1D<float2> RWTex;\n\n[numthreads(32, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBlah[thr] = NvShfl(thr, 9);\n\n\t// Test UAV reference shenanigans.\n\tBlah[100] = NvInterlockedAddFp16x2(BAB, 64, 9);\n\tBlah[101] = NvInterlockedAddFp16x2(RWTex, thr, 10);\n}\n\n"
  },
  {
    "path": "shaders/opts/fp16-fp32-fp16-1.ssbo.comp",
    "content": "RWStructuredBuffer<uint> RWBuf;\nRWStructuredBuffer<float16_t> RWBuf2;\nRWStructuredBuffer<uint> RWBuf3;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tfloat f32_1 = f16tof32(RWBuf[thr] & 0xffff);\n\tfloat f32_2 = f16tof32(RWBuf[thr] >> 16);\n\n\tRWBuf2[2 * thr + 0] = float16_t(f32_1);\n\tRWBuf2[2 * thr + 1] = float16_t(f32_2);\n\n\tfloat2 a = float2(f32_1, f32_2);\n\tRWBuf3[2 * thr + 0] = f32tof16(a.x);\n\tRWBuf3[2 * thr + 1] = f32tof16(a.y);\n\n\tmin16float2 b = min16float2(f32_1, f32_2);\n\tRWBuf3[2 * thr + 1024 + 0] = f32tof16(b.x);\n\tRWBuf3[2 * thr + 1024 + 1] = f32tof16(b.y);\n}\n"
  },
  {
    "path": "shaders/opts/sabs.frag",
    "content": "int4 main(int4 a : A) : SV_Target\n{\n\treturn abs(a);\n}\n"
  },
  {
    "path": "shaders/opts/sneg.frag",
    "content": "int4 main(int4 a : A) : SV_Target\n{\n\treturn -a;\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first-heap.sm66.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\tConstantBuffer<Foo> Ctmp = ResourceDescriptorHeap[0];\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ctmp.value[0]), o); // Should not opt. Ignore opts for global heap.\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.bindless.local-root-signature.rmiss",
    "content": "struct CBVData { float4 v; float4 w; };\n\nConstantBuffer<CBVData> SBTCBV : register(b3, space15);\nConstantBuffer<CBVData> SBTRootConstant : register(b0, space15);\n\nstruct Payload\n{\n\tfloat4 color;\n\tint index;\n};\n\n[shader(\"miss\")]\nvoid RayMiss(inout Payload payload)\n{\n\t// None of these should optimize, unsafe.\n\tpayload.color += WaveReadLaneFirst(SBTRootConstant.v);\n\tpayload.color += WaveReadLaneFirst(SBTCBV.v);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.no-legacy-cbuf-layout.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.no-legacy-cbuf-layout.sm60.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.sm60.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.sm66.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.ssbo.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint2> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\nByteAddressBuffer TB : register(t4);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1].x), o); // Should opt\n\tInterlockedAdd(U[0], WaveReadLaneFirst(TB.Load(0)), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr].y), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[1][thr & 1]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(TB.Load(thr * 4)), o); // Should not opt\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.ssbo.rgen",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint2> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\nByteAddressBuffer TB : register(t4);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[shader(\"raygeneration\")]\nvoid main()\n{\n\tuint thr = DispatchRaysIndex().x;\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1].x), o); // Should opt\n\tInterlockedAdd(U[0], WaveReadLaneFirst(TB.Load(0)), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr].y), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[1][thr & 1]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(TB.Load(thr * 4)), o); // Should not opt\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.ssbo.sm60.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.ssbo.sm66.comp",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint gid : SV_GroupID)\n{\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// WorkGroupID\n\tInterlockedAdd(U[0], WaveReadLaneFirst(gid), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(thr), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/opts/wave-read-lane-first.ssbo.sm66.rgen",
    "content": "RWStructuredBuffer<uint> U : register(u0);\nStructuredBuffer<uint2> T : register(t0);\nStructuredBuffer<uint> Ts[2] : register(t1);\nBuffer<float> B : register(t3);\nByteAddressBuffer TB : register(t4);\n\nstruct Foo { uint value[1024]; };\nConstantBuffer<Foo> C : register(b0);\nConstantBuffer<Foo> Cs[2] : register(b1);\n\n[shader(\"raygeneration\")]\nvoid main()\n{\n\tuint thr = DispatchRaysIndex().x;\n\tuint o;\n\n\t// CBV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(C.value[1]), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(C.value[thr]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Cs[0].value[thr]), o); // Should not opt\n\n\t// SRV loads.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(T[1].x), o); // Should opt\n\tInterlockedAdd(U[0], WaveReadLaneFirst(TB.Load(0)), o); // Should opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[thr].y), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(T[1][thr & 1]), o); // Should not opt\n\tInterlockedAdd(U[1], WaveReadLaneFirst(Ts[0][1]), o); // Should not opt (but could if we care)\n\tInterlockedAdd(U[1], WaveReadLaneFirst(TB.Load(thr * 4)), o); // Should not opt\n\n\t// UAV loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(U[2]), o); // Should not opt\n\n\t// Typed loads.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(B[0]), o); // Should not opt\n\n\t// Wave ops which are considered wave uniform.\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveReadLaneFirst(C.value[1])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveSum(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBitOr(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllEqual(C.value[thr])), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveBallot(C.value[thr] != 0).x), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAnyTrue(C.value[thr] != 0)), o);\n\tInterlockedAdd(U[0], WaveReadLaneFirst(WaveActiveAllTrue(C.value[thr] != 0)), o);\n\n\t// Wave ops that should not optimize.\n\tInterlockedAdd(U[1], WaveReadLaneFirst(WavePrefixSum(C.value[thr])), o);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-double1.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB.Store<double>(8 * thr, BAB.Load<double>(8 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-double2.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB[2] : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB[0].Store<double2>(8 * thr, BAB[0].Load<double2>(8 * thr) + 4.0);\n\tBAB[1].Store<double2>(16 * thr, BAB[1].Load<double2>(16 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-double3.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB[4] : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB[0].Store<double3>(8 * thr, BAB[0].Load<double3>(8 * thr) + 4.0);\n\tBAB[1].Store<double3>(16 * thr, BAB[1].Load<double3>(16 * thr) + 4.0);\n\tBAB[2].Store<double3>(24 * thr, BAB[2].Load<double3>(24 * thr) + 4.0);\n\tBAB[3].Store<double3>(32 * thr, BAB[3].Load<double3>(32 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-double4.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB[5] : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB[0].Store<double4>(8 * thr, BAB[0].Load<double4>(8 * thr) + 4.0);\n\tBAB[1].Store<double4>(16 * thr, BAB[1].Load<double4>(16 * thr) + 4.0);\n\tBAB[2].Store<double4>(24 * thr, BAB[2].Load<double4>(24 * thr) + 4.0);\n\tBAB[3].Store<double4>(32 * thr, BAB[3].Load<double4>(32 * thr) + 4.0);\n\tBAB[4].Store<double4>(40 * thr, BAB[4].Load<double4>(40 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-float1.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB.Store<float>(4 * thr, BAB.Load<float>(4 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-float2.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB[2] : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB[0].Store<float2>(4 * thr, BAB[0].Load<float2>(4 * thr) + 4.0);\n\tBAB[1].Store<float2>(8 * thr, BAB[1].Load<float2>(8 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-float3.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB[4] : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB[0].Store<float3>(4 * thr, BAB[0].Load<float3>(4 * thr) + 4.0);\n\tBAB[1].Store<float3>(8 * thr, BAB[1].Load<float3>(8 * thr) + 4.0);\n\tBAB[2].Store<float3>(12 * thr, BAB[2].Load<float3>(12 * thr) + 4.0);\n\tBAB[3].Store<float3>(16 * thr, BAB[3].Load<float3>(16 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-float4.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB[5] : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB[0].Store<float4>(4 * thr, BAB[0].Load<float4>(4 * thr) + 4.0);\n\tBAB[1].Store<float4>(8 * thr, BAB[1].Load<float4>(8 * thr) + 4.0);\n\tBAB[2].Store<float4>(12 * thr, BAB[2].Load<float4>(12 * thr) + 4.0);\n\tBAB[3].Store<float4>(16 * thr, BAB[3].Load<float4>(16 * thr) + 4.0);\n\tBAB[4].Store<float4>(20 * thr, BAB[4].Load<float4>(20 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/bab-float4x4.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWByteAddressBuffer BAB[2] : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tBAB[0].Store<float4x4>(64 * thr, BAB[0].Load<float4x4>(64 * thr) + 4.0);\n\tBAB[1].Store<float4x4>(80 * thr, BAB[1].Load<float4x4>(80 * thr) + 4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-float1.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<float> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4.0;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-float2.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<float2> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4.0;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-float3.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<float3> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4.0;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-float4.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<float4> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4.0;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-float4x4.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<float4x4> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4.0;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-half1.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<half> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += half(4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-min16float1.raw-access-chains.noglsl.ssbo.sm60.comp",
    "content": "RWStructuredBuffer<min16float> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += min16float(4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-min16float1.raw-access-chains.noglsl.ssbo.sm60.native-fp16.comp",
    "content": "RWStructuredBuffer<min16float> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += min16float(4.0);\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-min16uint1.raw-access-chains.noglsl.ssbo.sm60.comp",
    "content": "RWStructuredBuffer<min16uint> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += min16uint(4);\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-min16uint1.raw-access-chains.noglsl.ssbo.sm60.native-fp16.comp",
    "content": "RWStructuredBuffer<min16uint> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += min16uint(4);\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-uint1.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<uint> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-uint2.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<uint2> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-uint3.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<uint3> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4;\n}\n"
  },
  {
    "path": "shaders/raw-access/structured-uint4.raw-access-chains.noglsl.ssbo.comp",
    "content": "RWStructuredBuffer<uint4> F1 : register(u0);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tF1[thr] += 4;\n}\n"
  },
  {
    "path": "shaders/resources/acceleration-structure.bindless.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS_Plain : register(t3, space0);\nRaytracingAccelerationStructure AS[] : register(t100, space1);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tp.color = float4(1, 2, 3, 4);\n\tTraceRay(AS[10], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Plain, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS[NonUniformResourceIndex(int(p.color.w))], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n}\n\n"
  },
  {
    "path": "shaders/resources/acceleration-structure.bindless.ssbo-rtas.local-root-signature.raw-va-stride-offset.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS_Plain : register(t3, space1);\nRaytracingAccelerationStructure AS[] : register(t100, space1);\nRaytracingAccelerationStructure AS_Local[] : register(t3, space15);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tp.color = float4(1, 2, 3, 4);\n\tTraceRay(AS[10], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Plain, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS[NonUniformResourceIndex(int(p.color.w))], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Local[200], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n}\n\n"
  },
  {
    "path": "shaders/resources/acceleration-structure.bindless.ssbo-rtas.local-root-signature.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS_Plain : register(t3, space1);\nRaytracingAccelerationStructure AS[] : register(t100, space1);\nRaytracingAccelerationStructure AS_Local[] : register(t3, space15);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tp.color = float4(1, 2, 3, 4);\n\tTraceRay(AS[10], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Plain, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS[NonUniformResourceIndex(int(p.color.w))], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Local[200], RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n}\n\n"
  },
  {
    "path": "shaders/resources/acceleration-structure.local-root-signature.root-descriptor.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS_Local : register(t1, space15);\nRaytracingAccelerationStructure AS_RootDesc : register(t0, space0);\nRaytracingAccelerationStructure AS_Plain : register(t1, space0);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tp.color = float4(1, 2, 3, 4);\n\tTraceRay(AS_Local, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_RootDesc, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS_Plain, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n}\n\n"
  },
  {
    "path": "shaders/resources/basic.input-attachment.frag",
    "content": "Texture2D<float4> Input : register(t0, space1000);\nTexture2D<int4> InputInt : register(t1, space1000);\nTexture2D<uint4> InputUint : register(t2, space1000);\nTexture2D<float> InputDepth : register(t3, space1001);\nTexture2D<uint> InputStencil : register(t4, space1001);\nTexture2DMS<float4> InputMS : register(t5, space1000);\nTexture2DMS<float> InputDepthMS : register(t6, space1001);\n\nfloat4 main(float4 pos : SV_Position, uint samp : SV_SampleIndex) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\n\tres += Input.Load(int3(pos.xy, 0));\n\tres += float4(InputInt.Load(int3(pos.xy, 0)));\n\tres += float4(InputUint.Load(int3(pos.xy, 0)));\n\tres += InputDepth.Load(int3(pos.xy, 0));\n\tres += float(InputStencil.Load(int3(pos.xy, 0)));\n\n\tres += InputMS.Load(int2(pos.xy), samp);\n\tres += InputDepthMS.Load(int2(pos.xy), samp);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/buffer-16bit.ssbo.bindless.comp",
    "content": "RWStructuredBuffer<half> HalfBuf : register(u0);\nRWStructuredBuffer<uint16_t2> Half2Buf : register(u1);\nRWStructuredBuffer<half3> Half3Buf : register(u2);\nRWStructuredBuffer<uint16_t4> Half4Buf : register(u3);\n\nRWByteAddressBuffer RWBuf : register(u4);\nRWByteAddressBuffer RWBuf2 : register(u5);\nRWByteAddressBuffer RWBuf3 : register(u6);\n\nRWByteAddressBuffer RWBuf4[] : register(u0, space1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tHalfBuf[thr] += half(1.0);\n\tHalf2Buf[thr] += uint16_t(2);\n\tHalf3Buf[thr] += half(3.0);\n\tHalf4Buf[thr] += uint16_t(4.0);\n\n\tfloat4 result = 0.0.xxxx;\n\n\tresult += RWBuf.Load<half>(2 * thr);\n\tresult += RWBuf.Load<half2>(4 * thr).xxyy;\n\tresult += RWBuf.Load<half3>(6 * thr).xyzx;\n\tresult += RWBuf.Load<half4>(8 * thr);\n\n\tresult += RWBuf.Load<uint16_t>(2 * thr);\n\tresult += RWBuf.Load<uint16_t2>(4 * thr).xxyy;\n\tresult += RWBuf.Load<uint16_t3>(6 * thr).xyzx;\n\tresult += RWBuf.Load<uint16_t4>(8 * thr);\n\n\tRWBuf2.Store<half>(2 * thr, half(1.0));\n\tRWBuf2.Store<half2>(4 * thr, half2(2.0, 4.0));\n\tRWBuf2.Store<half3>(6 * thr, half3(4.0, 5.0, 6.0));\n\tRWBuf2.Store<half4>(8 * thr, half4(7.0, 8.0, 9.0, 10.0));\n\n\tRWBuf3.Store<uint16_t>(2 * thr, uint16_t(1));\n\tRWBuf3.Store<uint16_t2>(4 * thr, uint16_t2(2, 4));\n\tRWBuf3.Store<uint16_t3>(6 * thr, uint16_t3(4, 5, 6));\n\tRWBuf3.Store<uint16_t4>(8 * thr, uint16_t4(7, 8, 9, 10));\n\n\tresult += RWBuf.Load<float>(4 * thr);\n\tresult += RWBuf4[NonUniformResourceIndex(thr)].Load<half>(4 * thr);\n\tRWBuf4[NonUniformResourceIndex(thr)].Store<half2>(8 * thr, half2(result.xy));\n\n\tuint count, stride;\n\tHalfBuf.GetDimensions(count, stride);\n\tresult.x += count;\n\tresult.y += stride;\n\n\tHalf4Buf.GetDimensions(count, stride);\n\tresult.z += count;\n\tresult.w += stride;\n\n\tRWBuf2.GetDimensions(count);\n\tresult.x += count;\n\n\tRWBuf.Store4(16 * thr, result);\n\n}\n"
  },
  {
    "path": "shaders/resources/buffer-16bit.ssbo.bindless.ssbo-align.comp",
    "content": "RWStructuredBuffer<half> HalfBuf : register(u0);\nRWStructuredBuffer<uint16_t2> Half2Buf : register(u1);\nRWStructuredBuffer<half3> Half3Buf : register(u2);\nRWStructuredBuffer<uint16_t4> Half4Buf : register(u3);\n\nRWByteAddressBuffer RWBuf : register(u4);\nRWByteAddressBuffer RWBuf2 : register(u5);\nRWByteAddressBuffer RWBuf3 : register(u6);\n\nRWByteAddressBuffer RWBuf4[] : register(u0, space1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tHalfBuf[thr] += half(1.0);\n\tHalf2Buf[thr] += uint16_t(2);\n\tHalf3Buf[thr] += half(3.0);\n\tHalf4Buf[thr] += uint16_t(4.0);\n\n\tfloat4 result = 0.0.xxxx;\n\n\tresult += RWBuf.Load<half>(2 * thr);\n\tresult += RWBuf.Load<half2>(4 * thr).xxyy;\n\tresult += RWBuf.Load<half3>(6 * thr).xyzx;\n\tresult += RWBuf.Load<half4>(8 * thr);\n\n\tresult += RWBuf.Load<uint16_t>(2 * thr);\n\tresult += RWBuf.Load<uint16_t2>(4 * thr).xxyy;\n\tresult += RWBuf.Load<uint16_t3>(6 * thr).xyzx;\n\tresult += RWBuf.Load<uint16_t4>(8 * thr);\n\n\tRWBuf2.Store<half>(2 * thr, half(1.0));\n\tRWBuf2.Store<half2>(4 * thr, half2(2.0, 4.0));\n\tRWBuf2.Store<half3>(6 * thr, half3(4.0, 5.0, 6.0));\n\tRWBuf2.Store<half4>(8 * thr, half4(7.0, 8.0, 9.0, 10.0));\n\n\tRWBuf3.Store<uint16_t>(2 * thr, uint16_t(1));\n\tRWBuf3.Store<uint16_t2>(4 * thr, uint16_t2(2, 4));\n\tRWBuf3.Store<uint16_t3>(6 * thr, uint16_t3(4, 5, 6));\n\tRWBuf3.Store<uint16_t4>(8 * thr, uint16_t4(7, 8, 9, 10));\n\n\tresult += RWBuf.Load<float>(4 * thr);\n\tresult += RWBuf4[NonUniformResourceIndex(thr)].Load<half>(4 * thr);\n\tRWBuf4[NonUniformResourceIndex(thr)].Store<half2>(8 * thr, half2(result.xy));\n\n\tuint count, stride;\n\tHalfBuf.GetDimensions(count, stride);\n\tresult.x += count;\n\tresult.y += stride;\n\n\tHalf4Buf.GetDimensions(count, stride);\n\tresult.z += count;\n\tresult.w += stride;\n\n\tRWBuf2.GetDimensions(count);\n\tresult.x += count;\n\n\tRWBuf.Store4(16 * thr, result);\n\n}\n"
  },
  {
    "path": "shaders/resources/buffer-16bit.ssbo.comp",
    "content": "RWStructuredBuffer<half> HalfBuf : register(u0);\nRWStructuredBuffer<uint16_t2> Half2Buf : register(u1);\nRWStructuredBuffer<half3> Half3Buf : register(u2);\nRWStructuredBuffer<uint16_t4> Half4Buf : register(u3);\n\nRWByteAddressBuffer RWBuf : register(u4);\nRWByteAddressBuffer RWBuf2 : register(u5);\nRWByteAddressBuffer RWBuf3 : register(u6);\n\nRWByteAddressBuffer RWBuf4[] : register(u0, space1);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tHalfBuf[thr] += half(1.0);\n\tHalf2Buf[thr] += uint16_t(2);\n\tHalf3Buf[thr] += half(3.0);\n\tHalf4Buf[thr] += uint16_t(4.0);\n\n\tfloat4 result = 0.0.xxxx;\n\n\tresult += RWBuf.Load<half>(2 * thr);\n\tresult += RWBuf.Load<half2>(4 * thr).xxyy;\n\tresult += RWBuf.Load<half3>(6 * thr).xyzx;\n\tresult += RWBuf.Load<half4>(8 * thr);\n\n\tresult += RWBuf.Load<uint16_t>(2 * thr);\n\tresult += RWBuf.Load<uint16_t2>(4 * thr).xxyy;\n\tresult += RWBuf.Load<uint16_t3>(6 * thr).xyzx;\n\tresult += RWBuf.Load<uint16_t4>(8 * thr);\n\n\tRWBuf2.Store<half>(2 * thr, half(1.0));\n\tRWBuf2.Store<half2>(4 * thr, half2(2.0, 4.0));\n\tRWBuf2.Store<half3>(6 * thr, half3(4.0, 5.0, 6.0));\n\tRWBuf2.Store<half4>(8 * thr, half4(7.0, 8.0, 9.0, 10.0));\n\n\tRWBuf3.Store<uint16_t>(2 * thr, uint16_t(1));\n\tRWBuf3.Store<uint16_t2>(4 * thr, uint16_t2(2, 4));\n\tRWBuf3.Store<uint16_t3>(6 * thr, uint16_t3(4, 5, 6));\n\tRWBuf3.Store<uint16_t4>(8 * thr, uint16_t4(7, 8, 9, 10));\n\n\tresult += RWBuf.Load<float>(4 * thr);\n\tresult += RWBuf4[NonUniformResourceIndex(thr)].Load<half>(4 * thr);\n\tRWBuf4[NonUniformResourceIndex(thr)].Store<half2>(8 * thr, half2(result.xy));\n\n\tuint count, stride;\n\tHalfBuf.GetDimensions(count, stride);\n\tresult.x += count;\n\tresult.y += stride;\n\n\tHalf4Buf.GetDimensions(count, stride);\n\tresult.z += count;\n\tresult.w += stride;\n\n\tRWBuf2.GetDimensions(count);\n\tresult.x += count;\n\n\tRWBuf.Store4(16 * thr, result);\n\n}\n"
  },
  {
    "path": "shaders/resources/buffer-64bit.ssbo.bindless.ssbo-align.comp",
    "content": "RWStructuredBuffer<uint64_t3> RW : register(u0);\nStructuredBuffer<uint64_t3> RO : register(t0);\n\nRWByteAddressBuffer RWBAB : register(u1);\nByteAddressBuffer BAB : register(t1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint64_t3 v0 = RO[2 * thr + 0];\n\tuint64_t3 v1 = RO[2 * thr + 1];\n\tRW[8 * thr + 0] = v0 + v1;\n\tRW[8 * thr + 1] = v0 - v1;\n\tRW[8 * thr + 2] = v0 * v1;\n\tRW[8 * thr + 3] = v0 / v1;\n\tRW[8 * thr + 4] = v0 << v1;\n\tRW[8 * thr + 5] = v0 >> v1;\n\tRW[8 * thr + 6] = int64_t3(v0) >> v1;\n\tRW[8 * thr + 7] = v0 & v1;\n\n\tv0.xy = BAB.Load<uint64_t2>(24 * thr);\n\tRWBAB.Store<uint64_t3>(8 * thr, v0);\n}\n"
  },
  {
    "path": "shaders/resources/buffer-64bit.ssbo.comp",
    "content": "RWStructuredBuffer<uint64_t3> RW : register(u0);\nStructuredBuffer<uint64_t3> RO : register(t0);\n\nRWByteAddressBuffer RWBAB : register(u1);\nByteAddressBuffer BAB : register(t1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint64_t3 v0 = RO[2 * thr + 0];\n\tuint64_t3 v1 = RO[2 * thr + 1];\n\tRW[8 * thr + 0] = v0 + v1;\n\tRW[8 * thr + 1] = v0 - v1;\n\tRW[8 * thr + 2] = v0 * v1;\n\tRW[8 * thr + 3] = v0 / v1;\n\tRW[8 * thr + 4] = v0 << v1;\n\tRW[8 * thr + 5] = v0 >> v1;\n\tRW[8 * thr + 6] = int64_t3(v0) >> v1;\n\tRW[8 * thr + 7] = v0 & v1;\n\n\tv0.xy = BAB.Load<uint64_t2>(24 * thr);\n\tRWBAB.Store<uint64_t3>(8 * thr, v0);\n}\n"
  },
  {
    "path": "shaders/resources/buffer-alignment-fixup.bindless.root-constant.offset-layout.typed-buffer-offset.comp",
    "content": "RWStructuredBuffer<float2> RWStr : register(u0);\nRWByteAddressBuffer RWBuf : register(u1);\nStructuredBuffer<float2> RStr : register(t0);\nByteAddressBuffer RBuf : register(t1);\n\nRWStructuredBuffer<float2> RWStrs[] : register(u0, space1);\nRWByteAddressBuffer RWBufs[] : register(u1, space2);\nStructuredBuffer<float2> RStrs[] : register(t2, space3);\nByteAddressBuffer RBufs[] : register(t3, space4);\n\nRWStructuredBuffer<uint2> RWStrUint2 : register(u0, space5);\n\nRWBuffer<uint4> RWTyped : register(u0, space6);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thread : SV_DispatchThreadID, uint wg : SV_GroupID)\n{\n\tRWStr[thread] = RStr[thread];\n\tRWBuf.Store4(thread * 16, RBuf.Load4(thread * 16));\n\n\tRWStr[thread] = RStr[thread];\n\tRWBuf.Store4(thread * 16, RBuf.Load4(thread * 16));\n\n\tRWStrs[wg][thread] = RStrs[wg][thread];\n\tRWStrs[NonUniformResourceIndex(thread)][thread] = RStrs[NonUniformResourceIndex(thread)][thread];\n\n\tRWBufs[wg].Store4(16 * thread, RBufs[wg].Load4(16 * thread));\n\tRWBufs[NonUniformResourceIndex(thread)].Store4(16 * thread, RBufs[NonUniformResourceIndex(thread)].Load4(16 * thread));\n\n\tuint val;\n\tInterlockedAdd(RWStrUint2[thread].y, 1, val);\n\n\tuint count, stride;\n\tRWStr.GetDimensions(count, stride);\n\tInterlockedAdd(RWStrUint2[thread].x, count);\n\n\tRWTyped[thread] = uint4(0, 1, 2, 3) + 4 * thread;\n}\n"
  },
  {
    "path": "shaders/resources/buffer-alignment-fixup.ssbo.ssbo-align.bindless.root-constant.comp",
    "content": "RWStructuredBuffer<float2> RWStr : register(u0);\nRWByteAddressBuffer RWBuf : register(u1);\nStructuredBuffer<float2> RStr : register(t0);\nByteAddressBuffer RBuf : register(t1);\n\nRWStructuredBuffer<float2> RWStrs[] : register(u0, space1);\nRWByteAddressBuffer RWBufs[] : register(u1, space2);\nStructuredBuffer<float2> RStrs[] : register(t2, space3);\nByteAddressBuffer RBufs[] : register(t3, space4);\n\nRWStructuredBuffer<uint2> RWStrUint2 : register(u0, space5);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thread : SV_DispatchThreadID, uint wg : SV_GroupID)\n{\n\tRWStr[thread] = RStr[thread];\n\tRWBuf.Store4(thread * 16, RBuf.Load4(thread * 16));\n\n\tRWStr[thread] = RStr[thread];\n\tRWBuf.Store4(thread * 16, RBuf.Load4(thread * 16));\n\n\tRWStrs[wg][thread] = RStrs[wg][thread];\n\tRWStrs[NonUniformResourceIndex(thread)][thread] = RStrs[NonUniformResourceIndex(thread)][thread];\n\n\tRWBufs[wg].Store4(16 * thread, RBufs[wg].Load4(16 * thread));\n\tRWBufs[NonUniformResourceIndex(thread)].Store4(16 * thread, RBufs[NonUniformResourceIndex(thread)].Load4(16 * thread));\n\n\tuint val;\n\tInterlockedAdd(RWStrUint2[thread].y, 1, val);\n\n\tuint count, stride;\n\tRWStr.GetDimensions(count, stride);\n\tInterlockedAdd(RWStrUint2[thread].x, count);\n}\n"
  },
  {
    "path": "shaders/resources/buffer-alignment-fixup.ssbo.ssbo-align.bindless.root-constant.offset-layout.typed-buffer-offset.comp",
    "content": "RWStructuredBuffer<float2> RWStr : register(u0);\nRWByteAddressBuffer RWBuf : register(u1);\nStructuredBuffer<float2> RStr : register(t0);\nByteAddressBuffer RBuf : register(t1);\n\nRWStructuredBuffer<float2> RWStrs[] : register(u0, space1);\nRWByteAddressBuffer RWBufs[] : register(u1, space2);\nStructuredBuffer<float2> RStrs[] : register(t2, space3);\nByteAddressBuffer RBufs[] : register(t3, space4);\n\nRWStructuredBuffer<uint2> RWStrUint2 : register(u0, space5);\n\nRWBuffer<uint4> RWTyped : register(u0, space6);\n\n[numthreads(64, 1, 1)]\nvoid main(uint thread : SV_DispatchThreadID, uint wg : SV_GroupID)\n{\n\tRWStr[thread] = RStr[thread];\n\tRWBuf.Store4(thread * 16, RBuf.Load4(thread * 16));\n\n\tRWStr[thread] = RStr[thread];\n\tRWBuf.Store4(thread * 16, RBuf.Load4(thread * 16));\n\n\tRWStrs[wg][thread] = RStrs[wg][thread];\n\tRWStrs[NonUniformResourceIndex(thread)][thread] = RStrs[NonUniformResourceIndex(thread)][thread];\n\n\tRWBufs[wg].Store4(16 * thread, RBufs[wg].Load4(16 * thread));\n\tRWBufs[NonUniformResourceIndex(thread)].Store4(16 * thread, RBufs[NonUniformResourceIndex(thread)].Load4(16 * thread));\n\n\tuint val;\n\tInterlockedAdd(RWStrUint2[thread].y, 1, val);\n\n\tuint count, stride;\n\tRWStr.GetDimensions(count, stride);\n\tInterlockedAdd(RWStrUint2[thread].x, count);\n\n\tRWTyped[thread] = uint4(0, 1, 2, 3) + 4 * thread;\n}\n"
  },
  {
    "path": "shaders/resources/cbuf.root-constant.min16float.sm60.frag",
    "content": "cbuffer Foo\n{\n\tmin16float4 a;\n\tmin16float4 b;\n};\n\nmin16float4 main(min16float4 c : C) : SV_Target\n{\n\treturn a + b + c;\n}\n"
  },
  {
    "path": "shaders/resources/cbuf.root-constant.min16float.sm60.native-fp16.frag",
    "content": "cbuffer Foo\n{\n\tmin16float4 a;\n\tmin16float4 b;\n};\n\nmin16float4 main(min16float4 c : C) : SV_Target\n{\n\treturn a + b + c;\n}\n"
  },
  {
    "path": "shaders/resources/cbuf.root-constant.min16int.sm60.frag",
    "content": "cbuffer Foo\n{\n\tmin16int4 a;\n\tmin16int4 b;\n};\n\nmin16int4 main(min16float4 c : C) : SV_Target\n{\n\treturn a + b + min16int4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbuf.root-constant.min16int.sm60.native-fp16.frag",
    "content": "cbuffer Foo\n{\n\tmin16int4 a;\n\tmin16int4 b;\n};\n\nmin16int4 main(min16float4 c : C) : SV_Target\n{\n\treturn a + b + min16int4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv-array-nonuniform.frag",
    "content": "struct Foo\n{\n\tfloat4 a[4];\n};\n\n// !!! DXC does not emit NonUniformResourceIndex here.\n\nConstantBuffer<Foo> Buf[] : register(b0, space0);\nConstantBuffer<Foo> Buf2[100] : register(b0, space1);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Buf[NonUniformResourceIndex(index)].a[index & 3] + Buf2[NonUniformResourceIndex(index ^ 1)].a[index & 1];\n}\n"
  },
  {
    "path": "shaders/resources/cbv-array.frag",
    "content": "struct Foo\n{\n\tfloat4 a[4];\n};\n\nConstantBuffer<Foo> Buf[] : register(b0, space0);\nConstantBuffer<Foo> Buf2[100] : register(b0, space1);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Buf[index].a[index & 3] + Buf2[index ^ 1].a[index & 1];\n}\n"
  },
  {
    "path": "shaders/resources/cbv-dynamic.no-legacy-cbuf-layout.local-root-signature.rmiss",
    "content": "cbuffer A : register(b0, space15)\n{\n\tfloat a[2];\n\tuint b;\n\tint c;\n};\n\ncbuffer B : register(b1, space15)\n{\n\tfloat2 a2[2];\n\tuint b2;\n\tint c2;\n};\n\nstruct Payload\n{\n\tfloat4 f;\n\tint4 i;\n};\n\n[shader(\"miss\")]\nvoid main(inout Payload payload)\n{\n\tpayload.f = float4(a[payload.i.x], b, c, 1.0);\n\tpayload.i = int4(a2[payload.i.y], b2, c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv-indexing.frag",
    "content": "struct Foo { float4 v; };\nConstantBuffer<Foo> CBV[3] : register(b5);\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn CBV[0].v + CBV[2].v + CBV[v].v;\n}\n\n"
  },
  {
    "path": "shaders/resources/cbv-indexing.sm66.frag",
    "content": "struct Foo { float4 v; };\nConstantBuffer<Foo> CBV[3] : register(b5);\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn CBV[0].v + CBV[2].v + CBV[v].v;\n}\n\n"
  },
  {
    "path": "shaders/resources/cbv-legacy-fp16-fp64.frag",
    "content": "struct Half8 { min16float4 lo; min16float4 hi; };\n\ncbuffer Cbuf\n{\n\tfloat4 a;\n\tHalf8 b;\n\tint64_t4 c;\n};\n\nfloat4 main() : SV_Target\n{\n\tHalf8 half8 = b;\n\treturn a + float4(half8.lo) + float4(half8.hi) + float4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv-legacy-fp16-fp64.root-descriptor.frag",
    "content": "struct Half8 { min16float4 lo; min16float4 hi; };\n\ncbuffer Cbuf\n{\n\tfloat4 a;\n\tHalf8 b;\n\tint64_t4 c;\n};\n\nfloat4 main() : SV_Target\n{\n\tHalf8 half8 = b;\n\treturn a + float4(half8.lo) + float4(half8.hi) + float4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv-legacy-fp16-fp64.root-descriptor.sm60.frag",
    "content": "struct Half8 { min16float4 lo; min16float4 hi; };\n\ncbuffer Cbuf\n{\n\tfloat4 a;\n\tHalf8 b;\n\tint64_t4 c;\n};\n\nfloat4 main() : SV_Target\n{\n\tHalf8 half8 = b;\n\treturn a + float4(half8.lo) + float4(half8.hi) + float4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv-legacy-fp16-fp64.root-descriptor.sm60.native-fp16.frag",
    "content": "struct Half8 { min16float4 lo; min16float4 hi; };\n\ncbuffer Cbuf\n{\n\tfloat4 a;\n\tHalf8 b;\n\tint64_t4 c;\n};\n\nfloat4 main() : SV_Target\n{\n\tHalf8 half8 = b;\n\treturn a + float4(half8.lo) + float4(half8.hi) + float4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv-legacy-fp16-fp64.sm60.frag",
    "content": "struct Half8 { min16float4 lo; min16float4 hi; };\n\ncbuffer Cbuf\n{\n\tfloat4 a;\n\tHalf8 b;\n\tint64_t4 c;\n};\n\nfloat4 main() : SV_Target\n{\n\tHalf8 half8 = b;\n\treturn a + float4(half8.lo) + float4(half8.hi) + float4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv-legacy-fp16-fp64.sm60.native-fp16.frag",
    "content": "struct Half8 { min16float4 lo; min16float4 hi; };\n\ncbuffer Cbuf\n{\n\tfloat4 a;\n\tHalf8 b;\n\tint64_t4 c;\n};\n\nfloat4 main() : SV_Target\n{\n\tHalf8 half8 = b;\n\treturn a + float4(half8.lo) + float4(half8.hi) + float4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv.bindless.root-constant.cbv-as-ssbo.frag",
    "content": "struct Foo\n{\n\tfloat4 v;\n};\n\nConstantBuffer<Foo> uFoo : register(b3);\nConstantBuffer<Foo> uFooArray[64] : register(b4);\nConstantBuffer<Foo> uFooBindless[] : register(b100);\n\ncbuffer Root : register(b0)\n{\n\tuint index;\n};\n\nfloat4 main(nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tfloat4 result = uFoo.v;\n\tresult += uFooArray[1].v;\n\tresult += uFooArray[index].v;\n\t// DXC is buggy and does not emit NonUniformResourceIndex correctly in the DXIL.\n\tresult += uFooBindless[NonUniformResourceIndex(dynamic_index)].v;\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/cbv.bindless.root-constant.frag",
    "content": "struct Foo\n{\n\tfloat4 v;\n};\n\nConstantBuffer<Foo> uFoo : register(b3);\nConstantBuffer<Foo> uFooArray[64] : register(b4);\nConstantBuffer<Foo> uFooBindless[] : register(b100);\n\ncbuffer Root : register(b0)\n{\n\tuint index;\n};\n\nfloat4 main(nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tfloat4 result = uFoo.v;\n\tresult += uFooArray[1].v;\n\tresult += uFooArray[index].v;\n\t// DXC is buggy and does not emit NonUniformResourceIndex correctly in the DXIL.\n\tresult += uFooBindless[NonUniformResourceIndex(dynamic_index)].v;\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/cbv.frag",
    "content": "cbuffer A : register(b1, space2)\n{\n\tfloat a;\n\tuint b;\n\tint c;\n};\n\ncbuffer B : register(b2, space2)\n{\n\tfloat a2;\n\tuint b2;\n\tint c2;\n};\n\nfloat main() : SV_Target\n{\n\treturn (a + a2) + (b + b2) + (c + c2);\n}\n"
  },
  {
    "path": "shaders/resources/cbv.no-legacy-cbuf-layout.bindless.frag",
    "content": "cbuffer Cbuf\n{\n\tfloat4 a;\n\thalf4 b;\n\tint64_t4 c;\n};\n\ncbuffer Cbuf1 : register(b1)\n{\n\tfloat4 d;\n};\n\ncbuffer Cbuf2 : register(b2)\n{\n\tdouble4 e;\n};\n\nfloat4 main() : SV_Target\n{\n\treturn a + float4(b) + float4(c) + d + float4(e);\n}\n"
  },
  {
    "path": "shaders/resources/cbv.no-legacy-cbuf-layout.index-divider.frag",
    "content": "cbuffer Cbuf\n{\n\tfloat a[64];\n\tfloat2 b[64];\n\tfloat3 c[64];\n\tfloat4 d[64];\n};\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn a[index].xxxx + b[index].xyxy + c[index].xyzx + d[index];\n}\n"
  },
  {
    "path": "shaders/resources/cbv.no-legacy-cbuf-layout.local-root-signature.rmiss",
    "content": "cbuffer A : register(b0, space15)\n{\n\tfloat a;\n\tuint b;\n\tint c;\n};\n\ncbuffer B : register(b1, space15)\n{\n\tfloat2 a2;\n\tuint b2;\n\tint c2;\n};\n\nstruct Payload\n{\n\tfloat4 f;\n\tint4 i;\n};\n\n[shader(\"miss\")]\nvoid main(inout Payload payload)\n{\n\tpayload.f = float4(a, b, c, 1.0);\n\tpayload.i = int4(a2, b2, c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv.no-legacy-cbuf-layout.native-fp16.sm60.frag",
    "content": "struct Half8 { min16float4 lo; min16float4 hi; };\n\ncbuffer Cbuf\n{\n\tfloat4 a;\n\tHalf8 b;\n\tint64_t4 c;\n};\n\nfloat4 main() : SV_Target\n{\n\tHalf8 half8 = b;\n\treturn a + float4(half8.lo) + float4(half8.hi) + float4(c);\n}\n"
  },
  {
    "path": "shaders/resources/cbv.no-legacy-cbuf-layout.root-constant.frag",
    "content": "cbuffer A : register(b0, space0)\n{\n\tfloat a;\n\tuint b;\n\tint c;\n};\n\ncbuffer B : register(b0, space1)\n{\n\tfloat2 a2;\n\tuint b2;\n\tint c2;\n};\n\nfloat2 main() : SV_Target\n{\n\treturn (a + a2) + (b + b2) + (c + c2);\n}\n"
  },
  {
    "path": "shaders/resources/cbv.root-constant.frag",
    "content": "cbuffer A : register(b0, space0)\n{\n\tfloat a;\n\tuint b;\n\tint c;\n};\n\ncbuffer B : register(b2, space2)\n{\n\tfloat a2;\n\tuint b2;\n\tint c2;\n};\n\nfloat main() : SV_Target\n{\n\treturn (a + a2) + (b + b2) + (c + c2);\n}\n"
  },
  {
    "path": "shaders/resources/cbv.root-descriptor.no-legacy-cbuf-layout.frag",
    "content": "cbuffer Buf : register(b0)\n{\n\tfloat4 a;\n\thalf4 c;\n\tint64_t4 b;\n};\n\nfloat4 main() : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\tres += a;\n\tres += float4(b);\n\tres += float4(c);\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/combined-image-sampler-reuse.frag",
    "content": "Texture2D<float4> Tex : register(t0);\nSamplerState Samp : register(s0, space1);\n\nfloat4 main(float2 uv : UV) : SV_Target\n{\n\tfloat4 res = Tex.Sample(Samp, uv);\n\tres += Tex.Sample(Samp, uv + 0.1);\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/dynamic-root-constant.root-constant.bindless.root-descriptor.comp",
    "content": "cbuffer cbuf : register(b0, space1)\n{\n\tfloat4 v[4];\n};\n\nRWStructuredBuffer<float4> RW0 : register(u0);\nRWStructuredBuffer<float4> RW1 : register(u2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint gid : SV_DispatchThreadID, uint thr : SV_GroupID)\n{\n\tRW0[gid] = v[2 * thr + 1];\n\tRW1[gid] = v[3];\n}\n"
  },
  {
    "path": "shaders/resources/min16-alloca-groupshared.sm60.comp",
    "content": "groupshared min16float bar[64];\ngroupshared min16float4 bar4[64];\n\nRWStructuredBuffer<min16float4> O;\nstatic min16float4 Vec;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint l : SV_GroupIndex)\n{\n\tVec = min16float4(0, 0, 0, 0);\n\tbar[l] = min16float(l);\n\tbar4[l] = min16float(l) + min16float4(1, 2, 3, 4);\n\tGroupMemoryBarrierWithGroupSync();\n\tVec[l & 3] = bar[l ^ 5];\n\tVec[(l + 1) & 3] = bar[l ^ 4];\n\tO[thr] = bar[l ^ 1] + bar4[l ^ 3] + Vec;\n}\n"
  },
  {
    "path": "shaders/resources/min16float-ssbo-dxr.ssbo.rgen",
    "content": "RaytracingAccelerationStructure AS : register(t0);\nRWStructuredBuffer<min16float> BUF : register(u0);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tBUF[DispatchRaysIndex().x] = min16float(20.0);\n}\n"
  },
  {
    "path": "shaders/resources/raw-buffer-addressing.comp",
    "content": "RWByteAddressBuffer RWBuf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint id : SV_DispatchThreadID)\n{\n\t// Should not be folded.\n\tRWBuf.Store(1 * id, 1.0);\n\tRWBuf.Store(2 * id, 2.0);\n\tRWBuf.Store(3 * id, 3.0);\n\n\t// Should be folded.\n\tRWBuf.Store(4 * id, 4.0);\n\tRWBuf.Store(8 * id, 5.0);\n\tRWBuf.Store(12 * id, 6.0);\n\tRWBuf.Store(id << 2, 7.0);\n\tRWBuf.Store(id << 3, 8.0);\n\tRWBuf.Store(id << 4, 9.0);\n\n\t// Should not be folded.\n\tRWBuf.Store(12 * id + 1, 10.0);\n\tRWBuf.Store(12 * id + 2, 11.0);\n\tRWBuf.Store(12 * id + 3, 12.0);\n\n\t// Should be folded.\n\tRWBuf.Store(12 * id + 4, 13.0);\n\tRWBuf.Store(12 * id + 8, 14.0);\n\tRWBuf.Store(12 * id - 4, 15.0);\n\tRWBuf.Store(12 * id - 8, 16.0);\n\n\t// Should not be folded.\n\tRWBuf.Store(id + 4, 17.0);\n\tRWBuf.Store(id + 8, 18.0);\n\tRWBuf.Store(id - 4, 19.0);\n\tRWBuf.Store(id - 8, 20.0);\n\n\tRWBuf.Store(id + 5, 17.0);\n\tRWBuf.Store(id + 9, 18.0);\n\tRWBuf.Store(id - 5, 19.0);\n\tRWBuf.Store(id - 9, 20.0);\n}\n"
  },
  {
    "path": "shaders/resources/raw-buffer-addressing.ssbo.comp",
    "content": "RWByteAddressBuffer RWBuf : register(u0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint id : SV_DispatchThreadID)\n{\n\t// Should not be folded.\n\tRWBuf.Store(1 * id, 1.0);\n\tRWBuf.Store(2 * id, 2.0);\n\tRWBuf.Store(3 * id, 3.0);\n\n\t// Should be folded.\n\tRWBuf.Store(4 * id, 4.0);\n\tRWBuf.Store(8 * id, 5.0);\n\tRWBuf.Store(12 * id, 6.0);\n\tRWBuf.Store(id << 2, 7.0);\n\tRWBuf.Store(id << 3, 8.0);\n\tRWBuf.Store(id << 4, 9.0);\n\n\t// Should not be folded.\n\tRWBuf.Store(12 * id + 1, 10.0);\n\tRWBuf.Store(12 * id + 2, 11.0);\n\tRWBuf.Store(12 * id + 3, 12.0);\n\n\t// Should be folded.\n\tRWBuf.Store(12 * id + 4, 13.0);\n\tRWBuf.Store(12 * id + 8, 14.0);\n\tRWBuf.Store(12 * id - 4, 15.0);\n\tRWBuf.Store(12 * id - 8, 16.0);\n\n\t// Should not be folded.\n\tRWBuf.Store(id + 4, 17.0);\n\tRWBuf.Store(id + 8, 18.0);\n\tRWBuf.Store(id - 4, 19.0);\n\tRWBuf.Store(id - 8, 20.0);\n\n\tRWBuf.Store(id + 5, 17.0);\n\tRWBuf.Store(id + 9, 18.0);\n\tRWBuf.Store(id - 5, 19.0);\n\tRWBuf.Store(id - 9, 20.0);\n}\n"
  },
  {
    "path": "shaders/resources/root-bda.root-descriptor.comp",
    "content": "globallycoherent RWStructuredBuffer<float4> RWBuf : register(u0);\nStructuredBuffer<float4> Buf : register(t0);\n\nRWByteAddressBuffer RW : register(u1);\n\ncbuffer CBV : register(b0)\n{\n\tfloat4 v[16];\n};\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWBuf[thr] = Buf[thr] + v[thr];\n\n\tRW.Store<half>(2 * thr, half(1.0));\n\tRW.Store<half2>(4 * thr, half2(1.0, 2.0));\n\tRW.Store<half3>(6 * thr, half3(1.0, 2.0, 3.0));\n\tRW.Store<half4>(8 * thr, half4(1.0, 2.0, 3.0, 4.0));\n\tRW.Store<uint2>(8 * thr, uint2(4, 5));\n}\n"
  },
  {
    "path": "shaders/resources/root-bda.root-descriptor.sm60.comp",
    "content": "globallycoherent RWStructuredBuffer<float4> RWBuf : register(u0);\nStructuredBuffer<float4> Buf : register(t0);\n\ncbuffer CBV : register(b0)\n{\n\tfloat4 v[16];\n};\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWBuf[thr] = Buf[thr] + v[thr];\n}\n"
  },
  {
    "path": "shaders/resources/root-constant-with-bda.root-descriptor.root-constant.comp",
    "content": "globallycoherent RWStructuredBuffer<float4> RWBuf : register(u0);\nStructuredBuffer<float4> Buf : register(t0);\n\nRWByteAddressBuffer RW : register(u1);\n\ncbuffer CBV : register(b0, space1)\n{\n\tfloat4 v;\n\tfloat4 v1;\n\tfloat4 v2;\n};\n\n[numthreads(1, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWBuf[thr] = Buf[thr] + v.x + v1.y + v2.z;\n}\n"
  },
  {
    "path": "shaders/resources/rt-resources.bindless.local-root-signature.rmiss",
    "content": "Texture2D<float4> Tex[2] : register(t0);\nTexture2D<float4> TexUnsized[] : register(t0, space1);\n\nTexture2D<float4> TexSBT[] : register(t10, space15);\nRWTexture2D<float4> UAVTexSBT[] : register(u10, space15);\n\nstruct CBVData { float4 v; float4 w; };\n\nConstantBuffer<CBVData> SBTCBV : register(b3, space15);\nConstantBuffer<CBVData> SBTCBVs[] : register(b4, space15);\n\nConstantBuffer<CBVData> SBTRootConstant : register(b0, space15);\nConstantBuffer<CBVData> SBTRootDescriptor : register(b2, space15);\n\nSamplerState Samp : register(s3, space15);\nSamplerState Samps[] : register(s4, space15);\n\nStructuredBuffer<float4> StrBuf : register(t1, space15);\nByteAddressBuffer BABuf : register(t2, space15);\n\nRWStructuredBuffer<float> RWStrBuf : register(u1, space15);\nRWByteAddressBuffer RWBABuf : register(u2, space15);\n\nstruct Payload\n{\n\tfloat4 color;\n\tint index;\n};\n\n[shader(\"miss\")]\nvoid RayMiss(inout Payload payload)\n{\n\tpayload.color = Tex[payload.index & 1].Load(int3(0, 0, 0));\n\tpayload.color += TexUnsized[payload.index].Load(int3(0, 0, 0));\n\tpayload.color += TexSBT[payload.index].Load(int3(0, 0, 0));\n\tpayload.color += UAVTexSBT[payload.index].Load(int2(0, 0));\n\tpayload.color += SBTCBV.v;\n\tpayload.color += SBTCBVs[payload.index].v;\n\tpayload.color += SBTRootConstant.v;\n\tpayload.color += SBTRootConstant.w;\n\tpayload.color += SBTRootDescriptor.w;\n\n\tpayload.color += Tex[payload.index & 1].SampleLevel(Samp, 0.5.xx, 0.0);\n\tpayload.color += TexUnsized[payload.index].SampleLevel(Samps[payload.index ^ 1], 0.5.xx, 0.0);\n\tpayload.color += StrBuf[payload.index];\n\tpayload.color += asfloat(BABuf.Load(4 * payload.index)).xxxx;\n\tpayload.color += asfloat(BABuf.Load2(8 * payload.index)).xyxy;\n\tpayload.color += asfloat(BABuf.Load3(12 * payload.index)).xyzz;\n\tpayload.color += asfloat(BABuf.Load4(16 * payload.index));\n\n\tpayload.color += RWStrBuf[payload.index];\n\tpayload.color += asfloat(RWBABuf.Load(4 * payload.index));\n\n\tRWStrBuf[payload.index] = payload.color.x;\n\tRWBABuf.Store(4 * payload.index, payload.color.y);\n}\n"
  },
  {
    "path": "shaders/resources/rt-resources.bindless.rmiss",
    "content": "Texture2D<float4> Tex[2] : register(t0);\nTexture2D<float4> TexUnsized[] : register(t0, space1);\n\nTexture2D<float4> TexSBT[] : register(t10, space15);\n\nstruct Payload\n{\n\tfloat4 color;\n\tint index;\n};\n\n[shader(\"miss\")]\nvoid RayMiss(inout Payload payload)\n{\n\tpayload.color = Tex[payload.index & 1].Load(int3(0, 0, 0));\n\tpayload.color += TexUnsized[payload.index].Load(int3(0, 0, 0));\n\tpayload.color += TexSBT[payload.index].Load(int3(0, 0, 0));\n}\n"
  },
  {
    "path": "shaders/resources/rt-resources.rmiss",
    "content": "Texture2D<float4> Tex[2] : register(t0);\nTexture2D<float4> TexUnsized[] : register(t0, space1);\n\nstruct Payload\n{\n\tfloat4 color;\n\tint index;\n};\n\n[shader(\"miss\")]\nvoid RayMiss(inout Payload payload)\n{\n\tpayload.color = Tex[payload.index & 1].Load(int3(0, 0, 0));\n\tpayload.color += TexUnsized[payload.index].Load(int3(0, 0, 0));\n}\n"
  },
  {
    "path": "shaders/resources/sampler-array.frag",
    "content": "Texture2D<float4> Tex : register(t0, space0);\nSamplerState Samp[] : register(s0, space0);\nSamplerState Samp2[100] : register(s0, space1);\n\nfloat4 main() : SV_Target\n{\n\treturn\n\t\tTex.Sample(Samp[2], 0.5.xx) +\n\t\tTex.Sample(Samp2[3], 0.5.xx);\n}\n"
  },
  {
    "path": "shaders/resources/sampler-indexing.frag",
    "content": "SamplerState S[3] : register(s5);\nTexture2D T;\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn T.Sample(S[0], 0.5.xx) + T.Sample(S[2], 0.5.xx) + T.Sample(S[v], 0.5.xx);\n}\n\n"
  },
  {
    "path": "shaders/resources/sampler-indexing.sm66.frag",
    "content": "SamplerState S[3] : register(s5);\nTexture2D T;\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn T.Sample(S[0], 0.5.xx) + T.Sample(S[2], 0.5.xx) + T.Sample(S[v], 0.5.xx);\n}\n\n"
  },
  {
    "path": "shaders/resources/sampler.bindless.root-constant.frag",
    "content": "SamplerState Samp : register(s3);\nSamplerState SampArray[64] : register(s4);\nSamplerState SampBindless[] : register(s100);\n\nTexture2D<float4> Tex : register(t0);\n\ncbuffer BUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat4 main(float2 uv : UV, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tfloat4 result = Tex.Sample(Samp, uv);\n\tresult += Tex.Sample(SampArray[1], uv);\n\tresult += Tex.Sample(SampArray[index], uv);\n\tresult += Tex.Sample(SampBindless[NonUniformResourceIndex(dynamic_index)], uv);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/atomics-64bit-groupshared.ssbo.sm66.comp",
    "content": "groupshared int64_t v[4];\nRWByteAddressBuffer RWBAB : register(u0);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tif (thr < 4)\n\t{\n\t\tv[thr] = 0;\n\t}\n\n\tGroupMemoryBarrierWithGroupSync();\n\n\tuint thr64 = thr;\n\tuint wrapped = thr & 3;\n\n\tInterlockedAdd(v[wrapped], thr64);\n\tInterlockedAnd(v[wrapped], thr64);\n\tInterlockedOr(v[wrapped], thr64);\n\tInterlockedXor(v[wrapped], thr64);\n\tInterlockedMin(v[wrapped], thr64);\n\tInterlockedMax(v[wrapped], thr64);\n\tInterlockedMin(v[wrapped], thr64);\n\tInterlockedMax(v[wrapped], thr64);\n\n\tuint64_t out_value;\n\tInterlockedExchange(v[wrapped], thr64, out_value);\n\tInterlockedCompareStore(v[wrapped], 10, out_value);\n\tInterlockedCompareExchange(v[wrapped], 20, thr64, out_value);\n\n\tInterlockedAdd(v[wrapped], thr64);\n\tInterlockedAdd(v[wrapped], thr64);\n\n\tGroupMemoryBarrierWithGroupSync();\n\n\tif (thr < 4)\n\t\tRWBAB.Store<uint64_t>(8 * thr, v[thr]);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/atomics-64bit.root-descriptor.sm66.comp",
    "content": "RWStructuredBuffer<uint64_t> RW : register(u0);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint64_t thr64 = thr;\n\n\tInterlockedAdd(RW[0], thr64);\n\tInterlockedAnd(RW[1], thr64);\n\tInterlockedOr(RW[2], thr64);\n\tInterlockedXor(RW[3], thr64);\n\tInterlockedMin(RW[4], thr64);\n\tInterlockedMax(RW[5], thr64);\n\n\tuint64_t out_value;\n\tInterlockedExchange(RW[6], thr64, out_value);\n\tInterlockedCompareStore(RW[7], 10, out_value);\n\tInterlockedCompareExchange(RW[8], 20, thr64, out_value);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/atomics-64bit.ssbo.sm66.comp",
    "content": "[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWStructuredBuffer<uint64_t> RW = ResourceDescriptorHeap[0];\n\tRWStructuredBuffer<int64_t> RWSign = ResourceDescriptorHeap[1];\n\tRWByteAddressBuffer RWBAB = ResourceDescriptorHeap[2];\n\n\tuint64_t thr64 = thr;\n\n\tInterlockedAdd(RW[0], thr64);\n\tInterlockedAnd(RW[1], thr64);\n\tInterlockedOr(RW[2], thr64);\n\tInterlockedXor(RW[3], thr64);\n\tInterlockedMin(RW[4], thr64);\n\tInterlockedMax(RW[5], thr64);\n\tInterlockedMin(RWSign[6], thr64);\n\tInterlockedMax(RWSign[7], thr64);\n\n\tuint64_t out_value;\n\tInterlockedExchange(RW[8], thr64, out_value);\n\tInterlockedCompareStore(RW[9], 10, out_value);\n\tInterlockedCompareExchange(RW[10], 20, thr64, out_value);\n\n\tRWBAB.InterlockedAdd64(0, thr64);\n\tRWBAB.InterlockedAnd64(8, thr64);\n\tRWBAB.InterlockedOr64(16, thr64);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/atomics-component-alias.sm66.comp",
    "content": "Buffer<uint64_t> RO;\nRWBuffer<uint64_t> RW;\n\nTexture2D<uint64_t> ROTex;\nRWTexture2D<uint64_t> RWTex;\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n\tInterlockedAdd(RW[thr + 1], RW[thr + 10]);\n\n\tRWTex[int2(thr, thr)] = ROTex[int2(thr, thr)];\n\tInterlockedAdd(RWTex[int2(thr + 1, thr + 2)], RWTex[int2(thr + 3, thr + 4)]);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/atomics-typed-64bit-heap.sm66.comp",
    "content": "[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWBuffer<uint64_t> RW = ResourceDescriptorHeap[0];\n\tRWBuffer<int64_t> RWSign = ResourceDescriptorHeap[1];\n\tRWTexture2D<uint64_t> TexRW = ResourceDescriptorHeap[2];\n\tRWTexture2D<int64_t> TexRWSign = ResourceDescriptorHeap[3];\n\n\tuint64_t thr64 = thr;\n\n\tInterlockedAdd(RW[0], thr64);\n\tInterlockedAnd(RWSign[1], thr64);\n\tInterlockedOr(RW[2], thr64);\n\tInterlockedXor(RWSign[3], thr64);\n\tInterlockedMin(RW[4], thr64);\n\tInterlockedMax(RW[5], thr64);\n\tInterlockedMin(RWSign[6], thr64);\n\tInterlockedMax(RWSign[7], thr64);\n\n\tuint64_t out_value;\n\tInterlockedExchange(RWSign[8], thr64, out_value);\n\tInterlockedCompareStore(RW[9], 10, out_value);\n\tInterlockedCompareExchange(RWSign[10], 20, thr64, out_value);\n\n\tInterlockedAdd(TexRW[int2(1, 2)], thr64);\n\tInterlockedAdd(TexRWSign[int2(3, 4)], thr64);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/atomics-typed-64bit.bindless.sm66.comp",
    "content": "RWBuffer<uint64_t> RW : register(u0);\nRWBuffer<int64_t> RWSign : register(u1);\nRWTexture2D<uint64_t> TexRW : register(u2);\nRWTexture2D<int64_t> TexRWSign : register(u3);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint64_t thr64 = thr;\n\n\tInterlockedAdd(RW[0], thr64);\n\tInterlockedAnd(RWSign[1], thr64);\n\tInterlockedOr(RW[2], thr64);\n\tInterlockedXor(RWSign[3], thr64);\n\tInterlockedMin(RW[4], thr64);\n\tInterlockedMax(RW[5], thr64);\n\tInterlockedMin(RWSign[6], thr64);\n\tInterlockedMax(RWSign[7], thr64);\n\n\tuint64_t out_value;\n\tInterlockedExchange(RWSign[8], thr64, out_value);\n\tInterlockedCompareStore(RW[9], 10, out_value);\n\tInterlockedCompareExchange(RWSign[10], 20, thr64, out_value);\n\n\tInterlockedAdd(TexRW[int2(1, 2)], thr64);\n\tInterlockedAdd(TexRWSign[int2(3, 4)], thr64);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/atomics-typed-64bit.sm66.comp",
    "content": "RWBuffer<uint64_t> RW : register(u0);\nRWBuffer<int64_t> RWSign : register(u1);\nRWTexture2D<uint64_t> TexRW : register(u2);\nRWTexture2D<int64_t> TexRWSign : register(u3);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tuint64_t thr64 = thr;\n\n\tInterlockedAdd(RW[0], thr64);\n\tInterlockedAnd(RWSign[1], thr64);\n\tInterlockedOr(RW[2], thr64);\n\tInterlockedXor(RWSign[3], thr64);\n\tInterlockedMin(RW[4], thr64);\n\tInterlockedMax(RW[5], thr64);\n\tInterlockedMin(RWSign[6], thr64);\n\tInterlockedMax(RWSign[7], thr64);\n\n\tuint64_t out_value;\n\tInterlockedExchange(RWSign[8], thr64, out_value);\n\tInterlockedCompareStore(RW[9], 10, out_value);\n\tInterlockedCompareExchange(RWSign[10], 20, thr64, out_value);\n\n\tInterlockedAdd(TexRW[int2(1, 2)], thr64);\n\tInterlockedAdd(TexRWSign[int2(3, 4)], thr64);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/binding-range-selection.bindless.sm66.comp",
    "content": "struct C { float v; };\nConstantBuffer<C> c : register(b0, space0);\nConstantBuffer<C> carr[2] : register(b1, space0);\n\nTexture2D<float> tex : register(t0, space0);\nTexture2D<float> texarr[2] : register(t1, space0);\nBuffer<float> typedbuf : register(t3, space0);\nBuffer<float> typedbufarr[2] : register(t4, space0);\nStructuredBuffer<float> buf : register(t6, space0);\nStructuredBuffer<float> bufarr[2] : register(t7, space0);\nByteAddressBuffer rawbuf : register(t9, space0);\nByteAddressBuffer rawbufarr[2] : register(t10, space0);\n\nRWStructuredBuffer<float> rwbuf : register(u0, space0);\nRWStructuredBuffer<float> rwbufarr[2] : register(u1, space0);\nRWByteAddressBuffer rwrawbuf : register(u3, space0);\nRWByteAddressBuffer rwrawbufarr[2] : register(u4, space0);\nRWTexture2D<float> rwtex : register(u6, space0);\nRWTexture2D<float> rwtexarr[2] : register(u7, space0);\nRWBuffer<float> rwtypedbuf : register(u9, space0);\nRWBuffer<float> rwtypedbufarr[2] : register(u10, space0);\n\nSamplerState samp : register(s0, space0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tfloat value = 0.0;\n\tif (index > 80)\n\t\trwtex[int2(index, 0)] = value;\n\tif (index > 90)\n\t\trwtexarr[index & 1][int2(0, index)] = value;\n\n\trwbuf.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/sm66/binding-range-selection.sm66.comp",
    "content": "struct C { float v; };\nConstantBuffer<C> c : register(b0, space0);\nConstantBuffer<C> carr[2] : register(b1, space0);\n\nTexture2D<float> tex : register(t0, space0);\nTexture2D<float> texarr[2] : register(t1, space0);\nBuffer<float> typedbuf : register(t3, space0);\nBuffer<float> typedbufarr[2] : register(t4, space0);\nStructuredBuffer<float> buf : register(t6, space0);\nStructuredBuffer<float> bufarr[2] : register(t7, space0);\nByteAddressBuffer rawbuf : register(t9, space0);\nByteAddressBuffer rawbufarr[2] : register(t10, space0);\n\nRWStructuredBuffer<float> rwbuf : register(u0, space0);\nRWStructuredBuffer<float> rwbufarr[2] : register(u1, space0);\nRWByteAddressBuffer rwrawbuf : register(u3, space0);\nRWByteAddressBuffer rwrawbufarr[2] : register(u4, space0);\nRWTexture2D<float> rwtex : register(u6, space0);\nRWTexture2D<float> rwtexarr[2] : register(u7, space0);\nRWBuffer<float> rwtypedbuf : register(u9, space0);\nRWBuffer<float> rwtypedbufarr[2] : register(u10, space0);\n\nSamplerState samp : register(s0, space0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tfloat value = 0.0;\n\tif (index > 80)\n\t\trwtex[int2(index, 0)] = value;\n\tif (index > 90)\n\t\trwtexarr[index & 1][int2(0, index)] = value;\n\n\trwbuf.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/sm66/buffer-64bit-double.ssbo.sm66.comp",
    "content": "[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWStructuredBuffer<double3> RW = ResourceDescriptorHeap[0];\n\tStructuredBuffer<double3> RO = ResourceDescriptorHeap[1];\n\tRWByteAddressBuffer RWBAB = ResourceDescriptorHeap[2];\n\tByteAddressBuffer BAB = ResourceDescriptorHeap[3];\n\n\tdouble3 v0 = RO[2 * thr + 0];\n\tdouble3 v1 = RO[2 * thr + 1];\n\tRW[4 * thr + 0] = v0 + v1;\n\tRW[4 * thr + 1] = v0 - v1;\n\tRW[4 * thr + 2] = v0 * v1;\n\tRW[4 * thr + 3] = v0 / v1;\n\n\tv0.xy = BAB.Load<double2>(24 * thr);\n\tRWBAB.Store<double3>(8 * thr, v0);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/buffer-64bit.ssbo.sm66.comp",
    "content": "[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWStructuredBuffer<uint64_t3> RW = ResourceDescriptorHeap[0];\n\tStructuredBuffer<uint64_t3> RO = ResourceDescriptorHeap[1];\n\tRWByteAddressBuffer RWBAB = ResourceDescriptorHeap[2];\n\tByteAddressBuffer BAB = ResourceDescriptorHeap[3];\n\n\tuint64_t3 v0 = RO[2 * thr + 0];\n\tuint64_t3 v1 = RO[2 * thr + 1];\n\tRW[8 * thr + 0] = v0 + v1;\n\tRW[8 * thr + 1] = v0 - v1;\n\tRW[8 * thr + 2] = v0 * v1;\n\tRW[8 * thr + 3] = v0 / v1;\n\tRW[8 * thr + 4] = v0 << v1;\n\tRW[8 * thr + 5] = v0 >> v1;\n\tRW[8 * thr + 6] = int64_t3(v0) >> v1;\n\tRW[8 * thr + 7] = v0 & v1;\n\n\tv0.xy = BAB.Load<uint64_t2>(24 * thr);\n\tRWBAB.Store<uint64_t3>(8 * thr, v0);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/buffer-64bit.ssbo.ssbo-align.sm66.comp",
    "content": "[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRWStructuredBuffer<uint64_t3> RW = ResourceDescriptorHeap[0];\n\tStructuredBuffer<uint64_t3> RO = ResourceDescriptorHeap[1];\n\tRWByteAddressBuffer RWBAB = ResourceDescriptorHeap[2];\n\tByteAddressBuffer BAB = ResourceDescriptorHeap[3];\n\n\tuint64_t3 v0 = RO[2 * thr + 0];\n\tuint64_t3 v1 = RO[2 * thr + 1];\n\tRW[8 * thr + 0] = v0 + v1;\n\tRW[8 * thr + 1] = v0 - v1;\n\tRW[8 * thr + 2] = v0 * v1;\n\tRW[8 * thr + 3] = v0 / v1;\n\tRW[8 * thr + 4] = v0 << v1;\n\tRW[8 * thr + 5] = v0 >> v1;\n\tRW[8 * thr + 6] = int64_t3(v0) >> v1;\n\tRW[8 * thr + 7] = v0 & v1;\n\n\tv0.xy = BAB.Load<uint64_t2>(24 * thr);\n\tRWBAB.Store<uint64_t3>(8 * thr, v0);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/cbuffer-heap.sm66.frag",
    "content": "struct Foo { int4 v; };\n\nfloat4 main(uint index : INDEX, float3 uv : UV) : SV_Target\n{\n\tTexture3D<float4> tex = ResourceDescriptorHeap[index + 1];\n\tConstantBuffer<Foo> cbuf = ResourceDescriptorHeap[index + 2];\n\treturn tex.Load(cbuf.v);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/cbv.no-legacy-cbuf-layout.bindless.sm66.frag",
    "content": "cbuffer Cbuf\n{\n\tfloat4 a;\n\thalf4 b;\n\tint64_t4 c;\n};\n\ncbuffer Cbuf1 : register(b1)\n{\n\tfloat4 d;\n};\n\ncbuffer Cbuf2 : register(b2)\n{\n\tdouble4 e;\n};\n\nfloat4 main() : SV_Target\n{\n\treturn a + float4(b) + float4(c) + d + float4(e);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/cbv.no-legacy-cbuf-layout.sm66.frag",
    "content": "cbuffer Cbuf\n{\n\tfloat4 a;\n\thalf4 b;\n\tint64_t4 c;\n};\n\ncbuffer Cbuf1 : register(b1)\n{\n\tfloat4 d;\n};\n\ncbuffer Cbuf2 : register(b2)\n{\n\tdouble4 e;\n};\n\nfloat4 main() : SV_Target\n{\n\treturn a + float4(b) + float4(c) + d + float4(e);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raw-buffer-heap.sm66.frag",
    "content": "float3 main(uint index : INDEX, int3 uv : UV) : SV_Target\n{\n\tByteAddressBuffer RO = ResourceDescriptorHeap[index];\n\tgloballycoherent RWByteAddressBuffer WR = ResourceDescriptorHeap[index + 1];\n\n\tfloat3 res = asfloat(RO.Load3(uv.x));\n\tWR.Store3(uv.y, asuint(res));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raw-buffer-heap.ssbo.sm66.frag",
    "content": "float3 main(uint index : INDEX, int3 uv : UV) : SV_Target\n{\n\tByteAddressBuffer RO = ResourceDescriptorHeap[index];\n\tgloballycoherent RWByteAddressBuffer WR = ResourceDescriptorHeap[index + 1];\n\n\tfloat3 res = asfloat(RO.Load3(uv.x));\n\tWR.Store3(uv.y, asuint(res));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raw-buffer-heap.typed-buffer-offset.sm66.frag",
    "content": "float3 main(uint index : INDEX, int3 uv : UV) : SV_Target\n{\n\tByteAddressBuffer RO = ResourceDescriptorHeap[index];\n\tgloballycoherent RWByteAddressBuffer WR = ResourceDescriptorHeap[index + 1];\n\n\tfloat3 res = asfloat(RO.Load3(uv.x));\n\tWR.Store3(uv.y, asuint(res));\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raw-buffers-binding.ssbo.bindless.sm66.frag",
    "content": "StructuredBuffer<float> RO1 : register(t0);\nStructuredBuffer<half2> RO2 : register(t1);\n\nRWStructuredBuffer<float> RW1 : register(u2);\nRWStructuredBuffer<half2> RW2 : register(u3);\n\nByteAddressBuffer BAB1 : register(t4);\nRWByteAddressBuffer BAB2 : register(u5);\n\nfloat4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.yz += float2(RO2[uv.y]);\n\tres.z += RW1[uv.z];\n\tres.wx += float2(RW2[uv.w]);\n\n\tres += BAB1.Load<half4>(8);\n\tres += BAB1.Load<float4>(16);\n\tres += BAB2.Load<half4>(8);\n\tBAB2.Store<float4>(16, res);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raw-buffers-binding.ssbo.bindless.ssbo-align.sm66.frag",
    "content": "StructuredBuffer<float> RO1 : register(t0);\nStructuredBuffer<half2> RO2 : register(t1);\n\nRWStructuredBuffer<float> RW1 : register(u2);\nRWStructuredBuffer<half2> RW2 : register(u3);\n\nByteAddressBuffer BAB1 : register(t4);\nRWByteAddressBuffer BAB2 : register(u5);\n\nfloat4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.yz += float2(RO2[uv.y]);\n\tres.z += RW1[uv.z];\n\tres.wx += float2(RW2[uv.w]);\n\n\tres += BAB1.Load<half4>(8);\n\tres += BAB1.Load<float4>(16);\n\tres += BAB2.Load<half4>(8);\n\tBAB2.Store<float4>(16, res);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raygen-heap.sm66.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tRaytracingAccelerationStructure AS = ResourceDescriptorHeap[0];\n\tRWTexture2D<float4> IMG = ResourceDescriptorHeap[1];\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raygen-heap.ssbo-rtas.raw-va-stride-offset.sm66.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tRaytracingAccelerationStructure AS = ResourceDescriptorHeap[0];\n\tRWTexture2D<float4> IMG = ResourceDescriptorHeap[1];\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raygen-heap.ssbo-rtas.sm66.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tRaytracingAccelerationStructure AS = ResourceDescriptorHeap[0];\n\tRWTexture2D<float4> IMG = ResourceDescriptorHeap[1];\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raygen.sm66.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\nRaytracingAccelerationStructure AS : register(t30, space40);\nRWTexture2D<float4> IMG : register(u10, space20);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raygen.ssbo-rtas.bindless.raw-va-stride-offset.sm66.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\nRaytracingAccelerationStructure AS : register(t30, space40);\nRWTexture2D<float4> IMG : register(u10, space20);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/raygen.ssbo-rtas.bindless.sm66.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\nRaytracingAccelerationStructure AS : register(t30, space40);\nRWTexture2D<float4> IMG : register(u10, space20);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/rw-typed-binding.sm66.frag",
    "content": "RWTexture2D<float> RO[] : register(u0, space0);\nRWBuffer<uint> WR[] : register(u0, space1);\ngloballycoherent RWTexture2D<int> RW[] : register(u0, space2);\ngloballycoherent RWTexture1D<uint> ATOM[] : register(u0, space3);\n\nfloat3 main(uint index : INDEX, int3 uv : UV) : SV_Target\n{\n\tfloat3 res;\n\n\tres.x = RO[index].Load(uv.xy);\n\tWR[index][uv.x] = uv.y;\n\tres.y = float(RW[index].Load(uv.yz));\n\tRW[index][uv.yz] = uv.x;\n\n\tuint o;\n\tInterlockedAdd(ATOM[index][uv.x], uv.y, o);\n\tres.z = float(o);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/rw-typed-heap.sm66.frag",
    "content": "float3 main(uint index : INDEX, int3 uv : UV) : SV_Target\n{\n\tRWTexture2D<float> RO = ResourceDescriptorHeap[index];\n\tRWBuffer<uint> WR = ResourceDescriptorHeap[index + 1];\n\tgloballycoherent RWTexture2D<int> RW = ResourceDescriptorHeap[index + 2];\n\tgloballycoherent RWTexture1D<uint> ATOM = ResourceDescriptorHeap[index + 3];\n\n\tfloat3 res;\n\n\tres.x = RO.Load(uv.xy);\n\tWR[uv.x] = uv.y;\n\tres.y = float(RW.Load(uv.yz));\n\tRW[uv.yz] = uv.x;\n\n\tuint o;\n\tInterlockedAdd(ATOM[uv.x], uv.y, o);\n\tres.z = float(o);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/sampled-types-binding.sm66.frag",
    "content": "Texture2D<float4> tex[] : register(t4, space0);\nBuffer<float4> buf[1000] : register(t5, space1);\nTexture1D<float4> tex1d : register(t6, space2);\n\nfloat4 main(uint index : INDEX, float2 uv : UV) : SV_Target\n{\n\treturn tex[NonUniformResourceIndex(index)].Load(int3(uv, 0)) +\n\t\tbuf[NonUniformResourceIndex(index + 1)][int(uv.x)] +\n\t\ttex1d.Load(int2(uv));\n}\n"
  },
  {
    "path": "shaders/resources/sm66/sampled-types.sm66.frag",
    "content": "float4 main(uint index : INDEX, float2 uv : UV) : SV_Target\n{\n\tTexture2D<half4> tex = ResourceDescriptorHeap[NonUniformResourceIndex(index)];\n\tBuffer<unorm float4> buf = ResourceDescriptorHeap[NonUniformResourceIndex(index + 1)];\n\tTexture1D<float4> tex1d = ResourceDescriptorHeap[NonUniformResourceIndex(index + 2)];\n\treturn float4(tex.Load(int3(uv, 0))) + buf[int(uv.x)] + tex1d.Load(int(uv.y));\n}\n"
  },
  {
    "path": "shaders/resources/sm66/sampler-binding.sm66.frag",
    "content": "Texture3D<float4> tex[] : register(t1);\nSamplerState samp[] : register(s4);\n\nfloat4 main(uint index : INDEX, float3 uv : UV) : SV_Target\n{\n\treturn tex[index].Sample(samp[index], uv);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/sampler-heap.sm66.frag",
    "content": "float4 main(uint index : INDEX, float3 uv : UV) : SV_Target\n{\n\tTexture3D<float4> tex = ResourceDescriptorHeap[index + 1];\n\tSamplerState samp = SamplerDescriptorHeap[index + 2];\n\treturn tex.Sample(samp, uv);\n}\n"
  },
  {
    "path": "shaders/resources/sm66/structured-16bit-heap.ssbo.sm66.frag",
    "content": "float4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tStructuredBuffer<float> RO1 = ResourceDescriptorHeap[index + 0];\n\tStructuredBuffer<half2> RO2 = ResourceDescriptorHeap[index + 1];\n\n\tRWStructuredBuffer<float> RW1 = ResourceDescriptorHeap[index + 4];\n\tRWStructuredBuffer<half2> RW2 = ResourceDescriptorHeap[index + 5];\n\n\tByteAddressBuffer BAB1 = ResourceDescriptorHeap[index + 8];\n\tRWByteAddressBuffer BAB2 = ResourceDescriptorHeap[index + 9];\n\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.yz += float2(RO2[uv.y]);\n\tres.z += RW1[uv.z];\n\tres.wx += float2(RW2[uv.w]);\n\n\tres += BAB1.Load<half4>(8);\n\tres += BAB1.Load<float4>(16);\n\tres += BAB2.Load<half4>(8);\n\tBAB2.Store<float4>(16, res);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/structured-16bit-heap.ssbo.ssbo-align.sm66.frag",
    "content": "float4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tStructuredBuffer<float> RO1 = ResourceDescriptorHeap[index + 0];\n\tStructuredBuffer<half2> RO2 = ResourceDescriptorHeap[index + 1];\n\n\tRWStructuredBuffer<float> RW1 = ResourceDescriptorHeap[index + 4];\n\tRWStructuredBuffer<half2> RW2 = ResourceDescriptorHeap[index + 5];\n\n\tByteAddressBuffer BAB1 = ResourceDescriptorHeap[index + 8];\n\tRWByteAddressBuffer BAB2 = ResourceDescriptorHeap[index + 9];\n\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.yz += float2(RO2[uv.y]);\n\tres.z += RW1[uv.z];\n\tres.wx += float2(RW2[uv.w]);\n\n\tres += BAB1.Load<half4>(8);\n\tres += BAB1.Load<float4>(16);\n\tres += BAB2.Load<half4>(8);\n\tBAB2.Store<float4>(16, res);\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/structured-buffer-heap.sm66.frag",
    "content": "float4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tStructuredBuffer<float > RO1 = ResourceDescriptorHeap[index + 0];\n\tStructuredBuffer<float2> RO2 = ResourceDescriptorHeap[index + 1];\n\tStructuredBuffer<float3> RO3 = ResourceDescriptorHeap[index + 2];\n\tStructuredBuffer<float4> RO4 = ResourceDescriptorHeap[index + 3];\n\n\tRWStructuredBuffer<float > RW1 = ResourceDescriptorHeap[index + 4];\n\tRWStructuredBuffer<float2> RW2 = ResourceDescriptorHeap[index + 5];\n\tRWStructuredBuffer<float3> RW3 = ResourceDescriptorHeap[index + 6];\n\tRWStructuredBuffer<float4> RW4 = ResourceDescriptorHeap[index + 7];\n\n\tgloballycoherent RWStructuredBuffer<float > RWC1 = ResourceDescriptorHeap[index + 8];\n\tgloballycoherent RWStructuredBuffer<float2> RWC2 = ResourceDescriptorHeap[index + 9];\n\tgloballycoherent RWStructuredBuffer<float3> RWC3 = ResourceDescriptorHeap[index + 10];\n\tgloballycoherent RWStructuredBuffer<float4> RWC4 = ResourceDescriptorHeap[index + 11];\n\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.xy += RO2[uv.y];\n\tres.xyz += RO3[uv.z];\n\tres += RO4[uv.w];\n\n\tres.x += RW1[uv.x];\n\tres.xy += RW2[uv.y];\n\tres.xyz += RW3[uv.z];\n\tres += RW4[uv.w];\n\n\tres.x += RWC1[uv.x];\n\tres.xy += RWC2[uv.y];\n\tres.xyz += RWC3[uv.z];\n\tres += RWC4[uv.w];\n\n\tRW2[uv.x] = 20.0;\n\tRWC3[uv.y] = 30.0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/structured-buffer-heap.ssbo.sm66.frag",
    "content": "float4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tStructuredBuffer<float > RO1 = ResourceDescriptorHeap[index + 0];\n\tStructuredBuffer<float2> RO2 = ResourceDescriptorHeap[index + 1];\n\tStructuredBuffer<float3> RO3 = ResourceDescriptorHeap[index + 2];\n\tStructuredBuffer<float4> RO4 = ResourceDescriptorHeap[index + 3];\n\n\tRWStructuredBuffer<float > RW1 = ResourceDescriptorHeap[index + 4];\n\tRWStructuredBuffer<float2> RW2 = ResourceDescriptorHeap[index + 5];\n\tRWStructuredBuffer<float3> RW3 = ResourceDescriptorHeap[index + 6];\n\tRWStructuredBuffer<float4> RW4 = ResourceDescriptorHeap[index + 7];\n\n\tgloballycoherent RWStructuredBuffer<float > RWC1 = ResourceDescriptorHeap[index + 8];\n\tgloballycoherent RWStructuredBuffer<float2> RWC2 = ResourceDescriptorHeap[index + 9];\n\tgloballycoherent RWStructuredBuffer<float3> RWC3 = ResourceDescriptorHeap[index + 10];\n\tgloballycoherent RWStructuredBuffer<float4> RWC4 = ResourceDescriptorHeap[index + 11];\n\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.xy += RO2[uv.y];\n\tres.xyz += RO3[uv.z];\n\tres += RO4[uv.w];\n\n\tres.x += RW1[uv.x];\n\tres.xy += RW2[uv.y];\n\tres.xyz += RW3[uv.z];\n\tres += RW4[uv.w];\n\n\tres.x += RWC1[uv.x];\n\tres.xy += RWC2[uv.y];\n\tres.xyz += RWC3[uv.z];\n\tres += RWC4[uv.w];\n\n\tRW2[uv.x] = 20.0;\n\tRWC3[uv.y] = 30.0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/structured-buffer-heap.ssbo.ssbo-align.sm66.frag",
    "content": "float4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tStructuredBuffer<float > RO1 = ResourceDescriptorHeap[index + 0];\n\tStructuredBuffer<float2> RO2 = ResourceDescriptorHeap[index + 1];\n\tStructuredBuffer<float3> RO3 = ResourceDescriptorHeap[index + 2];\n\tStructuredBuffer<float4> RO4 = ResourceDescriptorHeap[index + 3];\n\n\tRWStructuredBuffer<float > RW1 = ResourceDescriptorHeap[index + 4];\n\tRWStructuredBuffer<float2> RW2 = ResourceDescriptorHeap[index + 5];\n\tRWStructuredBuffer<float3> RW3 = ResourceDescriptorHeap[index + 6];\n\tRWStructuredBuffer<float4> RW4 = ResourceDescriptorHeap[index + 7];\n\n\tgloballycoherent RWStructuredBuffer<float > RWC1 = ResourceDescriptorHeap[index + 8];\n\tgloballycoherent RWStructuredBuffer<float2> RWC2 = ResourceDescriptorHeap[index + 9];\n\tgloballycoherent RWStructuredBuffer<float3> RWC3 = ResourceDescriptorHeap[index + 10];\n\tgloballycoherent RWStructuredBuffer<float4> RWC4 = ResourceDescriptorHeap[index + 11];\n\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.xy += RO2[uv.y];\n\tres.xyz += RO3[uv.z];\n\tres += RO4[uv.w];\n\n\tres.x += RW1[uv.x];\n\tres.xy += RW2[uv.y];\n\tres.xyz += RW3[uv.z];\n\tres += RW4[uv.w];\n\n\tres.x += RWC1[uv.x];\n\tres.xy += RWC2[uv.y];\n\tres.xyz += RWC3[uv.z];\n\tres += RWC4[uv.w];\n\n\tRW2[uv.x] = 20.0;\n\tRWC3[uv.y] = 30.0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/sm66/structured-buffer-heap.typed-buffer-offset.sm66.frag",
    "content": "float4 main(uint index : INDEX, int4 uv : UV) : SV_Target\n{\n\tStructuredBuffer<float > RO1 = ResourceDescriptorHeap[index + 0];\n\tStructuredBuffer<float2> RO2 = ResourceDescriptorHeap[index + 1];\n\tStructuredBuffer<float3> RO3 = ResourceDescriptorHeap[index + 2];\n\tStructuredBuffer<float4> RO4 = ResourceDescriptorHeap[index + 3];\n\n\tRWStructuredBuffer<float > RW1 = ResourceDescriptorHeap[index + 4];\n\tRWStructuredBuffer<float2> RW2 = ResourceDescriptorHeap[index + 5];\n\tRWStructuredBuffer<float3> RW3 = ResourceDescriptorHeap[index + 6];\n\tRWStructuredBuffer<float4> RW4 = ResourceDescriptorHeap[index + 7];\n\n\tgloballycoherent RWStructuredBuffer<float > RWC1 = ResourceDescriptorHeap[index + 8];\n\tgloballycoherent RWStructuredBuffer<float2> RWC2 = ResourceDescriptorHeap[index + 9];\n\tgloballycoherent RWStructuredBuffer<float3> RWC3 = ResourceDescriptorHeap[index + 10];\n\tgloballycoherent RWStructuredBuffer<float4> RWC4 = ResourceDescriptorHeap[index + 11];\n\n\tfloat4 res = 0.0.xxxx;\n\tres.x += RO1[uv.x];\n\tres.xy += RO2[uv.y];\n\tres.xyz += RO3[uv.z];\n\tres += RO4[uv.w];\n\n\tres.x += RW1[uv.x];\n\tres.xy += RW2[uv.y];\n\tres.xyz += RW3[uv.z];\n\tres += RW4[uv.w];\n\n\tres.x += RWC1[uv.x];\n\tres.xy += RWC2[uv.y];\n\tres.xyz += RWC3[uv.z];\n\tres += RWC4[uv.w];\n\n\tRW2[uv.x] = 20.0;\n\tRWC3[uv.y] = 30.0;\n\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-raw-buffer-nonuniform.frag",
    "content": "ByteAddressBuffer Tex[] : register(t0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn asfloat(Tex[NonUniformResourceIndex(index)].Load4(16 * index));\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-raw-buffer.frag",
    "content": "ByteAddressBuffer Tex[] : register(t0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn asfloat(Tex[index].Load4(16 * index));\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-structured-buffer-nonuniform.frag",
    "content": "StructuredBuffer<float4> Tex[] : register(t0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[NonUniformResourceIndex(index)][index];\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-structured-buffer.frag",
    "content": "StructuredBuffer<float4> Tex[] : register(t0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[index][index];\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-texture-nonuniform.frag",
    "content": "Texture2D<float4> Tex[] : register(t0, space0);\nTexture2D<float4> Tex2[100] : register(t0, space1);\nSamplerState Samp : register(s0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn\n\t\tTex[NonUniformResourceIndex(index)].Sample(Samp, 0.5.xx) +\n\t\tTex2[NonUniformResourceIndex(index ^ 1)].Sample(Samp, 0.5.xx);\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-texture.frag",
    "content": "Texture2D<float4> Tex[] : register(t0, space0);\nTexture2D<float4> Tex2[100] : register(t0, space1);\nSamplerState Samp : register(s0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn\n\t\tTex[index].Sample(Samp, 0.5.xx) +\n\t\tTex2[index ^ 1].Sample(Samp, 0.5.xx);\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-typed-buffer-nonuniform.frag",
    "content": "Buffer<float4> Tex[] : register(t0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn\n\t\tTex[NonUniformResourceIndex(index)].Load(index);\n}\n"
  },
  {
    "path": "shaders/resources/srv-array-typed-buffer.frag",
    "content": "Buffer<float4> Tex[] : register(t0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[index].Load(index);\n}\n"
  },
  {
    "path": "shaders/resources/srv-indexing.frag",
    "content": "Texture2D<float4> T[3] : register(t5);\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn T[0].Load(int3(0, 0, 0)) + T[2].Load(int3(0, 0, 0)) + T[v].Load(int3(0, 0, 0));\n}\n\n"
  },
  {
    "path": "shaders/resources/srv-indexing.sm66.frag",
    "content": "Texture2D<float4> T[3] : register(t5);\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn T[0].Load(int3(0, 0, 0)) + T[2].Load(int3(0, 0, 0)) + T[v].Load(int3(0, 0, 0));\n}\n\n"
  },
  {
    "path": "shaders/resources/srv-raw-buffer.bindless.root-constant.frag",
    "content": "ByteAddressBuffer uBuffer : register(t3);\nByteAddressBuffer uBufferArray[64] : register(t4);\nByteAddressBuffer uBufferBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nuint2 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x) * 8;\n\tuint2 result = uBuffer.Load2(offset);\n\tresult += uBufferArray[index].Load2(offset);\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load2(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-raw-buffer.bindless.root-constant.ssbo.frag",
    "content": "ByteAddressBuffer uBuffer : register(t3);\nByteAddressBuffer uBufferArray[64] : register(t4);\nByteAddressBuffer uBufferBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nuint2 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x) * 8;\n\tuint2 result = uBuffer.Load2(offset);\n\tresult += uBufferArray[index].Load2(offset);\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load2(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-raw-buffer.ssbo.frag",
    "content": "ByteAddressBuffer uBuffer : register(t3);\nByteAddressBuffer uBufferArray[64] : register(t4);\nByteAddressBuffer uBufferBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nuint2 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x) * 8;\n\tuint2 result = uBuffer.Load2(offset);\n\tresult += uBufferArray[index].Load2(offset);\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load2(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-structured-buffer.bindless.root-constant.frag",
    "content": "StructuredBuffer<float> uBuffer : register(t3);\nStructuredBuffer<float2> uBufferArray[64] : register(t4);\nStructuredBuffer<float3> uBufferBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat3 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x);\n\tfloat3 result = uBuffer.Load(offset);\n\tresult += uBufferArray[index].Load(offset).xyx;\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-structured-buffer.bindless.root-constant.ssbo.frag",
    "content": "StructuredBuffer<float> uBuffer : register(t3);\nStructuredBuffer<float2> uBufferArray[64] : register(t4);\nStructuredBuffer<float3> uBufferBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat3 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x);\n\tfloat3 result = uBuffer.Load(offset);\n\tresult += uBufferArray[index].Load(offset).xyx;\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-structured-buffer.ssbo.frag",
    "content": "StructuredBuffer<float> uBuffer : register(t3);\nStructuredBuffer<float2> uBufferArray[64] : register(t4);\nStructuredBuffer<float3> uBufferBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat3 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x);\n\tfloat3 result = uBuffer.Load(offset);\n\tresult += uBufferArray[index].Load(offset).xyx;\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-texture.bindless.root-constant.frag",
    "content": "Texture2D<float4> uTex : register(t3);\nTexture2D<float4> uTexArray[64] : register(t4);\nTexture2D<float4> uTexBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat4 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint3 coord = int3(pos.xy, 0);\n\tfloat4 result = uTex.Load(coord);\n\tresult += uTexArray[index].Load(coord);\n\tresult += uTexBindless[NonUniformResourceIndex(dynamic_index)].Load(coord);\n\tresult += uTexBindless[1].Load(coord);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-texture.bindless.root-constant.inline-ubo.frag",
    "content": "Texture2D<float4> uTex : register(t3);\nTexture2D<float4> uTexArray[64] : register(t4);\nTexture2D<float4> uTexBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat4 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint3 coord = int3(pos.xy, 0);\n\tfloat4 result = uTex.Load(coord);\n\tresult += uTexArray[index].Load(coord);\n\tresult += uTexBindless[NonUniformResourceIndex(dynamic_index)].Load(coord);\n\tresult += uTexBindless[1].Load(coord);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-typed-buffer.bindless.root-constant.frag",
    "content": "Buffer<float4> uBuffer : register(t3);\nBuffer<uint4> uBufferArray[64] : register(t4);\nBuffer<int4> uBufferBindless[] : register(t100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat4 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x);\n\tfloat4 result = uBuffer.Load(offset);\n\tresult += uBufferArray[index].Load(offset);\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/srv-uav-raw.typed-buffer-offset.comp",
    "content": "RWStructuredBuffer<float4> RWBuf : register(u0);\nStructuredBuffer<float4> Buf : register(t1);\nRWByteAddressBuffer RWAtomic : register(u2);\n\nRWStructuredBuffer<float4> RWBufs[] : register(u0, space1);\nStructuredBuffer<float4> Bufs[] : register(t0, space2);\nRWByteAddressBuffer RWAtomics[] : register(u0, space3);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 thr : SV_DispatchThreadID)\n{\n\tRWBuf[thr.x + 1024] = RWBuf[thr.x + 4];\n\tRWBuf[thr.x + 2048] = Buf[thr.x + 2];\n\n\tuint val;\n\tRWAtomic.InterlockedAdd(4 * thr.x, 40, val);\n\n\tRWAtomic.InterlockedCompareExchange(4 * thr.y, 40, 50, val);\n\n\tuint count;\n\tRWBuf.GetDimensions(val, count);\n\tRWBuf[0] = val;\n\n\tBuf.GetDimensions(val, count);\n\tRWBuf[1] = val;\n\n\tRWBufs[NonUniformResourceIndex(thr.z)][thr.x + 1024] = RWBufs[NonUniformResourceIndex(thr.z)][thr.x + 4];\n\tRWBufs[NonUniformResourceIndex(thr.z)][thr.x + 2048] = Bufs[NonUniformResourceIndex(thr.z)][thr.x + 4];\n\tRWAtomics[NonUniformResourceIndex(thr.z)].InterlockedAdd(4 * thr.y, 40, val);\n\tRWAtomics[NonUniformResourceIndex(thr.z)].InterlockedCompareExchange(4 * thr.y, 40, 70, val);\n\tRWBufs[NonUniformResourceIndex(thr.z)].GetDimensions(val, count);\n\tRWBuf[2] = val;\n\tBufs[NonUniformResourceIndex(thr.z)].GetDimensions(val, count);\n\tRWBuf[3] = val;\n}\n"
  },
  {
    "path": "shaders/resources/srv-uav.typed-buffer-offset.comp",
    "content": "RWBuffer<float4> RWBuf : register(u0);\nBuffer<float4> Buf : register(t1);\nRWBuffer<uint> RWAtomic : register(u2);\n\nRWBuffer<float4> RWBufs[] : register(u0, space1);\nBuffer<float4> Bufs[] : register(t0, space2);\nRWBuffer<uint> RWAtomics[] : register(u0, space3);\n\n[numthreads(1, 1, 1)]\nvoid main(uint3 thr : SV_DispatchThreadID)\n{\n\tRWBuf[thr.x + 1024] = RWBuf[thr.x + 4];\n\tRWBuf[thr.x + 2048] = Buf[thr.x + 2];\n\n\tuint val;\n\tInterlockedAdd(RWAtomic[thr.x], 40, val);\n\n\tInterlockedCompareExchange(RWAtomic[thr.y], 40, 50, val);\n\n\tRWBuf.GetDimensions(val);\n\tRWBuf[0] = val;\n\n\tBuf.GetDimensions(val);\n\tRWBuf[1] = val;\n\n\n\tRWBufs[NonUniformResourceIndex(thr.z)][thr.x + 1024] = RWBufs[NonUniformResourceIndex(thr.z)][thr.x + 4];\n\tRWBufs[NonUniformResourceIndex(thr.z)][thr.x + 2048] = Bufs[NonUniformResourceIndex(thr.z)][thr.x + 4];\n\tInterlockedAdd(RWAtomics[NonUniformResourceIndex(thr.z)][thr.y], 40, val);\n\tInterlockedCompareExchange(RWAtomics[NonUniformResourceIndex(thr.z)][thr.y], 40, 70, val);\n\tRWBufs[NonUniformResourceIndex(thr.z)].GetDimensions(val);\n\tRWBuf[2] = val;\n\tBufs[NonUniformResourceIndex(thr.z)].GetDimensions(val);\n\tRWBuf[3] = val;\n}\n"
  },
  {
    "path": "shaders/resources/ssbo-minprecision.sm60.native-fp16.frag",
    "content": "StructuredBuffer<min16float> B;\nRWStructuredBuffer<min16float> C;\n\nStructuredBuffer<min16int> Bint;\nRWStructuredBuffer<min16int> Cint;\n\nint main(min16int a : A) : SV_Target\n{\n\tC[a] = B[a] + B[a + 1];\n\tCint[a] = Bint[a] + Bint[a + 1];\n\treturn 10;\n}\n"
  },
  {
    "path": "shaders/resources/ssbo-minprecision.sm60.ssbo.frag",
    "content": "StructuredBuffer<min16float> B;\nRWStructuredBuffer<min16float> C;\n\nint main(min16int a : A) : SV_Target\n{\n\tC[a] = B[a] + B[a + 1];\n\treturn 10;\n}\n"
  },
  {
    "path": "shaders/resources/ssbo-minprecision.sm60.ssbo.native-fp16.frag",
    "content": "StructuredBuffer<min16float> B;\nRWStructuredBuffer<min16float> C;\n\nStructuredBuffer<min16int> Bint;\nRWStructuredBuffer<min16int> Cint;\n\nint main(min16int a : A) : SV_Target\n{\n\tC[a] = B[a] + B[a + 1];\n\tCint[a] = Bint[a] + Bint[a + 1];\n\treturn 10;\n}\n"
  },
  {
    "path": "shaders/resources/ssbo-minprecision.sm60.ssbo.native-fp16.root-descriptor.frag",
    "content": "StructuredBuffer<min16float> B;\nRWStructuredBuffer<min16float> C;\n\nStructuredBuffer<min16int> Bint;\nRWStructuredBuffer<min16int> Cint;\n\nint main(min16int a : A) : SV_Target\n{\n\tC[a] = B[a] + B[a + 1];\n\tCint[a] = Bint[a] + Bint[a + 1];\n\treturn 10;\n}\n"
  },
  {
    "path": "shaders/resources/ssbo-minprecision.sm60.ssbo.root-descriptor.frag",
    "content": "StructuredBuffer<min16float> B;\nRWStructuredBuffer<min16float> C;\n\nint main(min16int a : A) : SV_Target\n{\n\tC[a] = B[a] + B[a + 1];\n\treturn 10;\n}\n"
  },
  {
    "path": "shaders/resources/subobject-parsing.rgen",
    "content": "RaytracingShaderConfig sconf = { 80, 60 };\nRaytracingPipelineConfig pconf0 = { 4 };\nRaytracingPipelineConfig1 pconf1 = { 5, RAYTRACING_PIPELINE_FLAG_SKIP_TRIANGLES };\n// DXC specifies the typo :V\nStateObjectConfig soc = { STATE_OBJECT_FLAGS_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITONS };\nTriangleHitGroup tri_hg = { \"a\", \"b\" };\nTriangleHitGroup tri_hg2 = { \"\", \"b\" };\nProceduralPrimitiveHitGroup aabb_hg = { \"c\", \"d\", \"e\" };\nSubobjectToExportsAssociation assoc1 = { \"A\", \"foo;bar;meow;nyaa;frog\" };\nSubobjectToExportsAssociation assoc2 = { \"B\", \"meep;frog\" };\n\n[shader(\"raygeneration\")]\nvoid main()\n{\n}\n"
  },
  {
    "path": "shaders/resources/typed-resources-16bit-sparse.frag",
    "content": "Texture2D<half4> Tex : register(t0);\nTexture2D<int16_t4> TexI16 : register(t1);\nTexture2D<uint16_t4> TexU16 : register(t2);\nSamplerState S : register(s0);\nSamplerComparisonState SComp : register(s1);\n\nBuffer<half4> Buf : register(t3);\nBuffer<int16_t4> BufI16 : register(t4);\nBuffer<uint16_t4> BufU16 : register(t5);\n\nstruct FOut\n{\n\thalf4 f16 : SV_Target0;\n\tint16_t4 i16 : SV_Target1;\n\tuint16_t4 u16 : SV_Target2;\n\tuint codes : SV_Target3;\n};\n\nFOut main(float2 uv : UV)\n{\n\tuint code;\n\n\tFOut fout;\n\tfout.codes = 0;\n\tfout.f16 = Tex.Sample(S, uv, int2(0, 0), 0.0, code); fout.codes |= code;\n\tfout.i16 = TexI16.Load(int3(1, 2, 3), int2(0, 0), code); fout.codes |= code;\n\tfout.u16 = TexU16.Load(int3(4, 5, 6), int2(0, 0), code); fout.codes |= code;\n\n\tfout.f16 += Tex.GatherRed(S, uv, int2(0, 0), code); fout.codes |= code;\n\tfout.i16 += TexI16.GatherGreen(S, uv, int2(0, 0), code); fout.codes |= code;\n\tfout.u16 += TexU16.GatherBlue(S, uv, int2(0, 0), code); fout.codes |= code;\n\n\tfout.f16 += Tex.SampleCmp(SComp, uv, 0.5, int2(0, 0), 0.0, code).x; fout.codes |= code;\n\tfout.f16 += Tex.SampleCmpLevelZero(SComp, uv, 0.5, int2(0, 0), code).x; fout.codes |= code;\n\tfout.f16 += Tex.GatherCmp(SComp, uv, 0.5, int2(0, 0), code); fout.codes |= code;\n\n\tfout.f16 += Tex.SampleLevel(S, uv, 0.0, int2(0, 0), code); fout.codes |= code;\n\tfout.f16 += Tex.SampleGrad(S, uv, float2(0.2, 0.3), float2(0.4, 0.5), int2(0, 0), 0.0, code); fout.codes |= code;\n\tfout.f16 += Tex.SampleBias(S, uv, 0.5, int2(0, 0), 0.0, code); fout.codes |= code;\n\n\tfout.f16 += Buf.Load(int(uv.x), code); fout.codes |= code;\n\tfout.i16 += BufI16.Load(int(uv.x), code); fout.codes |= code;\n\tfout.u16 += BufU16.Load(int(uv.x), code); fout.codes |= code;\n\n\treturn fout;\n}\n"
  },
  {
    "path": "shaders/resources/typed-resources-16bit.bindless.frag",
    "content": "Texture2D<half4> Tex : register(t0);\nTexture2D<int16_t4> TexI16 : register(t1);\nTexture2D<uint16_t4> TexU16 : register(t2);\nSamplerState S : register(s0);\nSamplerComparisonState SComp : register(s1);\n\nRWTexture2D<half4> RWTex : register(u0);\nRWTexture2D<int16_t4> RWTexI16 : register(u1);\nRWTexture2D<uint16_t4> RWTexU16 : register(u2);\n\nBuffer<half4> Buf : register(t3);\nBuffer<int16_t4> BufI16 : register(t4);\nBuffer<uint16_t4> BufU16 : register(t5);\n\nRWBuffer<half4> RWBuf : register(u3);\nRWBuffer<int16_t4> RWBufI16 : register(u4);\nRWBuffer<uint16_t4> RWBufU16 : register(u5);\n\nstruct FOut\n{\n\thalf4 f16 : SV_Target0;\n\tint16_t4 i16 : SV_Target1;\n\tuint16_t4 u16 : SV_Target2;\n};\n\nFOut main(float2 uv : UV)\n{\n\tRWTex[int2(uv)] = half4(uv.xyxy);\n\tRWTexI16[int2(uv)] = int16_t4(uv.xyxy);\n\tRWTexU16[int2(uv)] = uint16_t4(uv.xyxy);\n\n\tRWBuf[int(uv.x)] = half(8.0);\n\tRWBufI16[int(uv.x)] = int16_t(-20);\n\tRWBufU16[int(uv.x)] = uint16_t(80);\n\n\tFOut fout;\n\tfout.f16 = Tex.Sample(S, uv);\n\tfout.i16 = TexI16.Load(int3(1, 2, 3));\n\tfout.u16 = TexU16.Load(int3(4, 5, 6));\n\n\tfout.f16 += Tex.GatherRed(S, uv);\n\tfout.i16 += TexI16.GatherGreen(S, uv);\n\tfout.u16 += TexU16.GatherBlue(S, uv);\n\n\tfout.f16 += Tex.SampleCmp(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.SampleCmpLevelZero(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.GatherCmp(SComp, uv, 0.5);\n\n\tfout.f16 += Tex.SampleLevel(S, uv, 0.0);\n\tfout.f16 += Tex.SampleGrad(S, uv, float2(0.2, 0.3), float2(0.4, 0.5));\n\tfout.f16 += Tex.SampleBias(S, uv, 0.5);\n\n\tfout.f16 += Buf[int(uv.x)];\n\tfout.i16 += BufI16[int(uv.x)];\n\tfout.u16 += BufU16[int(uv.x)];\n\n\treturn fout;\n}\n"
  },
  {
    "path": "shaders/resources/typed-resources-16bit.frag",
    "content": "Texture2D<half4> Tex : register(t0);\nTexture2D<int16_t4> TexI16 : register(t1);\nTexture2D<uint16_t4> TexU16 : register(t2);\nSamplerState S : register(s0);\nSamplerComparisonState SComp : register(s1);\n\nRWTexture2D<half4> RWTex : register(u0);\nRWTexture2D<int16_t4> RWTexI16 : register(u1);\nRWTexture2D<uint16_t4> RWTexU16 : register(u2);\n\nBuffer<half4> Buf : register(t3);\nBuffer<int16_t4> BufI16 : register(t4);\nBuffer<uint16_t4> BufU16 : register(t5);\n\nRWBuffer<half4> RWBuf : register(u3);\nRWBuffer<int16_t4> RWBufI16 : register(u4);\nRWBuffer<uint16_t4> RWBufU16 : register(u5);\n\nstruct FOut\n{\n\thalf4 f16 : SV_Target0;\n\tint16_t4 i16 : SV_Target1;\n\tuint16_t4 u16 : SV_Target2;\n};\n\nFOut main(float2 uv : UV)\n{\n\tRWTex[int2(uv)] = half4(uv.xyxy);\n\tRWTexI16[int2(uv)] = int16_t4(uv.xyxy);\n\tRWTexU16[int2(uv)] = uint16_t4(uv.xyxy);\n\n\tRWBuf[int(uv.x)] = half(8.0);\n\tRWBufI16[int(uv.x)] = int16_t(-20);\n\tRWBufU16[int(uv.x)] = uint16_t(80);\n\n\tFOut fout;\n\tfout.f16 = Tex.Sample(S, uv);\n\tfout.i16 = TexI16.Load(int3(1, 2, 3));\n\tfout.u16 = TexU16.Load(int3(4, 5, 6));\n\n\tfout.f16 += Tex.GatherRed(S, uv);\n\tfout.i16 += TexI16.GatherGreen(S, uv);\n\tfout.u16 += TexU16.GatherBlue(S, uv);\n\n\tfout.f16 += Tex.SampleCmp(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.SampleCmpLevelZero(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.GatherCmp(SComp, uv, 0.5);\n\n\tfout.f16 += Tex.SampleLevel(S, uv, 0.0);\n\tfout.f16 += Tex.SampleGrad(S, uv, float2(0.2, 0.3), float2(0.4, 0.5));\n\tfout.f16 += Tex.SampleBias(S, uv, 0.5);\n\n\tfout.f16 += Buf[int(uv.x)];\n\tfout.i16 += BufI16[int(uv.x)];\n\tfout.u16 += BufU16[int(uv.x)];\n\n\treturn fout;\n}\n"
  },
  {
    "path": "shaders/resources/typed-resources-16bit.sm60.bindless.frag",
    "content": "Texture2D<min16float4> Tex : register(t0);\nTexture2D<min16int4> TexI16 : register(t1);\nTexture2D<min16uint4> TexU16 : register(t2);\nSamplerState S : register(s0);\nSamplerComparisonState SComp : register(s1);\n\nRWTexture2D<min16float4> RWTex : register(u0);\nRWTexture2D<min16int4> RWTexI16 : register(u1);\nRWTexture2D<min16uint4> RWTexU16 : register(u2);\n\nBuffer<min16float4> Buf : register(t3);\nBuffer<min16int4> BufI16 : register(t4);\nBuffer<min16uint4> BufU16 : register(t5);\n\nRWBuffer<min16float4> RWBuf : register(u3);\nRWBuffer<min16int4> RWBufI16 : register(u4);\nRWBuffer<min16uint4> RWBufU16 : register(u5);\n\nstruct FOut\n{\n\tmin16float4 f16 : SV_Target0;\n\tmin16int4 i16 : SV_Target1;\n\tmin16uint4 u16 : SV_Target2;\n};\n\nFOut main(float2 uv : UV)\n{\n\tRWTex[int2(uv)] = min16float4(uv.xyxy);\n\tRWTexI16[int2(uv)] = min16int4(uv.xyxy);\n\tRWTexU16[int2(uv)] = min16uint4(uv.xyxy);\n\n\tRWBuf[int(uv.x)] = half(8.0);\n\tRWBufI16[int(uv.x)] = min16int(-20);\n\tRWBufU16[int(uv.x)] = min16uint(80);\n\n\tFOut fout;\n\tfout.f16 = Tex.Sample(S, uv);\n\tfout.i16 = TexI16.Load(int3(1, 2, 3));\n\tfout.u16 = TexU16.Load(int3(4, 5, 6));\n\n\tfout.f16 += Tex.GatherRed(S, uv);\n\tfout.i16 += TexI16.GatherGreen(S, uv);\n\tfout.u16 += TexU16.GatherBlue(S, uv);\n\n\tfout.f16 += Tex.SampleCmp(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.SampleCmpLevelZero(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.GatherCmp(SComp, uv, 0.5);\n\n\tfout.f16 += Tex.SampleLevel(S, uv, 0.0);\n\tfout.f16 += Tex.SampleGrad(S, uv, float2(0.2, 0.3), float2(0.4, 0.5));\n\tfout.f16 += Tex.SampleBias(S, uv, 0.5);\n\n\tfout.f16 += Buf[int(uv.x)];\n\tfout.i16 += BufI16[int(uv.x)];\n\tfout.u16 += BufU16[int(uv.x)];\n\n\treturn fout;\n}\n"
  },
  {
    "path": "shaders/resources/typed-resources-16bit.sm60.frag",
    "content": "Texture2D<min16float4> Tex : register(t0);\nTexture2D<min16int4> TexI16 : register(t1);\nTexture2D<min16uint4> TexU16 : register(t2);\nSamplerState S : register(s0);\nSamplerComparisonState SComp : register(s1);\n\nRWTexture2D<min16float4> RWTex : register(u0);\nRWTexture2D<min16int4> RWTexI16 : register(u1);\nRWTexture2D<min16uint4> RWTexU16 : register(u2);\n\nBuffer<min16float4> Buf : register(t3);\nBuffer<min16int4> BufI16 : register(t4);\nBuffer<min16uint4> BufU16 : register(t5);\n\nRWBuffer<min16float4> RWBuf : register(u3);\nRWBuffer<min16int4> RWBufI16 : register(u4);\nRWBuffer<min16uint4> RWBufU16 : register(u5);\n\nstruct FOut\n{\n\tmin16float4 f16 : SV_Target0;\n\tmin16int4 i16 : SV_Target1;\n\tmin16uint4 u16 : SV_Target2;\n};\n\nFOut main(float2 uv : UV)\n{\n\tRWTex[int2(uv)] = min16float4(uv.xyxy);\n\tRWTexI16[int2(uv)] = min16int4(uv.xyxy);\n\tRWTexU16[int2(uv)] = min16uint4(uv.xyxy);\n\n\tRWBuf[int(uv.x)] = half(8.0);\n\tRWBufI16[int(uv.x)] = min16int(-20);\n\tRWBufU16[int(uv.x)] = min16uint(80);\n\n\tFOut fout;\n\tfout.f16 = Tex.Sample(S, uv);\n\tfout.i16 = TexI16.Load(int3(1, 2, 3));\n\tfout.u16 = TexU16.Load(int3(4, 5, 6));\n\n\tfout.f16 += Tex.GatherRed(S, uv);\n\tfout.i16 += TexI16.GatherGreen(S, uv);\n\tfout.u16 += TexU16.GatherBlue(S, uv);\n\n\tfout.f16 += Tex.SampleCmp(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.SampleCmpLevelZero(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.GatherCmp(SComp, uv, 0.5);\n\n\tfout.f16 += Tex.SampleLevel(S, uv, 0.0);\n\tfout.f16 += Tex.SampleGrad(S, uv, float2(0.2, 0.3), float2(0.4, 0.5));\n\tfout.f16 += Tex.SampleBias(S, uv, 0.5);\n\n\tfout.f16 += Buf[int(uv.x)];\n\tfout.i16 += BufI16[int(uv.x)];\n\tfout.u16 += BufU16[int(uv.x)];\n\n\treturn fout;\n}\n"
  },
  {
    "path": "shaders/resources/typed-resources-16bit.sm60.native-fp16.bindless.frag",
    "content": "Texture2D<min16float4> Tex : register(t0);\nTexture2D<min16int4> TexI16 : register(t1);\nTexture2D<min16uint4> TexU16 : register(t2);\nSamplerState S : register(s0);\nSamplerComparisonState SComp : register(s1);\n\nRWTexture2D<min16float4> RWTex : register(u0);\nRWTexture2D<min16int4> RWTexI16 : register(u1);\nRWTexture2D<min16uint4> RWTexU16 : register(u2);\n\nBuffer<min16float4> Buf : register(t3);\nBuffer<min16int4> BufI16 : register(t4);\nBuffer<min16uint4> BufU16 : register(t5);\n\nRWBuffer<min16float4> RWBuf : register(u3);\nRWBuffer<min16int4> RWBufI16 : register(u4);\nRWBuffer<min16uint4> RWBufU16 : register(u5);\n\nstruct FOut\n{\n\tmin16float4 f16 : SV_Target0;\n\tmin16int4 i16 : SV_Target1;\n\tmin16uint4 u16 : SV_Target2;\n};\n\nFOut main(float2 uv : UV)\n{\n\tRWTex[int2(uv)] = min16float4(uv.xyxy);\n\tRWTexI16[int2(uv)] = min16int4(uv.xyxy);\n\tRWTexU16[int2(uv)] = min16uint4(uv.xyxy);\n\n\tRWBuf[int(uv.x)] = half(8.0);\n\tRWBufI16[int(uv.x)] = min16int(-20);\n\tRWBufU16[int(uv.x)] = min16uint(80);\n\n\tFOut fout;\n\tfout.f16 = Tex.Sample(S, uv);\n\tfout.i16 = TexI16.Load(int3(1, 2, 3));\n\tfout.u16 = TexU16.Load(int3(4, 5, 6));\n\n\tfout.f16 += Tex.GatherRed(S, uv);\n\tfout.i16 += TexI16.GatherGreen(S, uv);\n\tfout.u16 += TexU16.GatherBlue(S, uv);\n\n\tfout.f16 += Tex.SampleCmp(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.SampleCmpLevelZero(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.GatherCmp(SComp, uv, 0.5);\n\n\tfout.f16 += Tex.SampleLevel(S, uv, 0.0);\n\tfout.f16 += Tex.SampleGrad(S, uv, float2(0.2, 0.3), float2(0.4, 0.5));\n\tfout.f16 += Tex.SampleBias(S, uv, 0.5);\n\n\tfout.f16 += Buf[int(uv.x)];\n\tfout.i16 += BufI16[int(uv.x)];\n\tfout.u16 += BufU16[int(uv.x)];\n\n\treturn fout;\n}\n"
  },
  {
    "path": "shaders/resources/typed-resources-16bit.sm60.native-fp16.frag",
    "content": "Texture2D<min16float4> Tex : register(t0);\nTexture2D<min16int4> TexI16 : register(t1);\nTexture2D<min16uint4> TexU16 : register(t2);\nSamplerState S : register(s0);\nSamplerComparisonState SComp : register(s1);\n\nRWTexture2D<min16float4> RWTex : register(u0);\nRWTexture2D<min16int4> RWTexI16 : register(u1);\nRWTexture2D<min16uint4> RWTexU16 : register(u2);\n\nBuffer<min16float4> Buf : register(t3);\nBuffer<min16int4> BufI16 : register(t4);\nBuffer<min16uint4> BufU16 : register(t5);\n\nRWBuffer<min16float4> RWBuf : register(u3);\nRWBuffer<min16int4> RWBufI16 : register(u4);\nRWBuffer<min16uint4> RWBufU16 : register(u5);\n\nstruct FOut\n{\n\tmin16float4 f16 : SV_Target0;\n\tmin16int4 i16 : SV_Target1;\n\tmin16uint4 u16 : SV_Target2;\n};\n\nFOut main(float2 uv : UV)\n{\n\tRWTex[int2(uv)] = min16float4(uv.xyxy);\n\tRWTexI16[int2(uv)] = min16int4(uv.xyxy);\n\tRWTexU16[int2(uv)] = min16uint4(uv.xyxy);\n\n\tRWBuf[int(uv.x)] = half(8.0);\n\tRWBufI16[int(uv.x)] = min16int(-20);\n\tRWBufU16[int(uv.x)] = min16uint(80);\n\n\tFOut fout;\n\tfout.f16 = Tex.Sample(S, uv);\n\tfout.i16 = TexI16.Load(int3(1, 2, 3));\n\tfout.u16 = TexU16.Load(int3(4, 5, 6));\n\n\tfout.f16 += Tex.GatherRed(S, uv);\n\tfout.i16 += TexI16.GatherGreen(S, uv);\n\tfout.u16 += TexU16.GatherBlue(S, uv);\n\n\tfout.f16 += Tex.SampleCmp(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.SampleCmpLevelZero(SComp, uv, 0.5).x;\n\tfout.f16 += Tex.GatherCmp(SComp, uv, 0.5);\n\n\tfout.f16 += Tex.SampleLevel(S, uv, 0.0);\n\tfout.f16 += Tex.SampleGrad(S, uv, float2(0.2, 0.3), float2(0.4, 0.5));\n\tfout.f16 += Tex.SampleBias(S, uv, 0.5);\n\n\tfout.f16 += Buf[int(uv.x)];\n\tfout.i16 += BufI16[int(uv.x)];\n\tfout.u16 += BufU16[int(uv.x)];\n\n\treturn fout;\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-raw-buffer-nonuniform.frag",
    "content": "RWByteAddressBuffer Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn asfloat(Tex[NonUniformResourceIndex(index)].Load4(16 * index));\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-raw-buffer.frag",
    "content": "RWByteAddressBuffer Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn asfloat(Tex[index].Load4(16 * index));\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-structured-buffer-nonuniform.frag",
    "content": "RWStructuredBuffer<float4> Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[NonUniformResourceIndex(index)][index];\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-structured-buffer-nonuniform.ssbo.bindless.root-constant.frag",
    "content": "RWStructuredBuffer<float4> Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[NonUniformResourceIndex(index)][index];\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-structured-buffer-nonuniform.ssbo.frag",
    "content": "RWStructuredBuffer<float4> Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[NonUniformResourceIndex(index)][index];\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-structured-buffer.frag",
    "content": "RWStructuredBuffer<float4> Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[index][index];\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-texture-nonuniform.frag",
    "content": "RWTexture2D<float4> Tex[] : register(u0, space0);\nRWTexture2D<float4> Tex2[100] : register(u0, space1);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn\n\t\tTex[NonUniformResourceIndex(index)].Load(int2(0, 0)) +\n\t\tTex2[NonUniformResourceIndex(index ^ 1)].Load(int2(0, 0));\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-texture.frag",
    "content": "RWTexture2D<float4> Tex[] : register(u0, space0);\nRWTexture2D<float4> Tex2[100] : register(u0, space1);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn\n\t\tTex[index].Load(int2(0, 0)) +\n\t\tTex2[index ^ 1].Load(int2(0, 0));\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-typed-buffer-nonuniform.frag",
    "content": "RWBuffer<float4> Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn\n\t\tTex[NonUniformResourceIndex(index)].Load(index);\n}\n"
  },
  {
    "path": "shaders/resources/uav-array-typed-buffer.frag",
    "content": "RWBuffer<float4> Tex[] : register(u0, space0);\n\nfloat4 main(nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn Tex[index].Load(index);\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter-array.ssbo.frag",
    "content": "RWStructuredBuffer<uint> Blah[5] : register(u10);\n\nuint main(uint i : I) : SV_Target\n{\n\treturn Blah[NonUniformResourceIndex(i)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter-array.ssbo.sm66.frag",
    "content": "RWStructuredBuffer<uint> Blah[5] : register(u10);\n\nuint main(uint i : I) : SV_Target\n{\n\treturn Blah[NonUniformResourceIndex(i)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter-array.ssbo.sm66.uav-counter-ssbo.frag",
    "content": "RWStructuredBuffer<uint> Blah[5] : register(u10);\n\nuint main(uint i : I) : SV_Target\n{\n\treturn Blah[NonUniformResourceIndex(i)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter-array.ssbo.uav-counter-ssbo.frag",
    "content": "RWStructuredBuffer<uint> Blah[5] : register(u10);\n\nuint main(uint i : I) : SV_Target\n{\n\treturn Blah[NonUniformResourceIndex(i)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter-heap.sm66.bindless.ssbo.frag",
    "content": "float4 main(uint i : I) : SV_Target\n{\n\tRWStructuredBuffer<float4> A = ResourceDescriptorHeap[14];\n\tuint v = A.IncrementCounter();\n\treturn A[v];\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter-heap.sm66.uav-counter-ssbo.bindless.ssbo.frag",
    "content": "float4 main(uint i : I) : SV_Target\n{\n\tRWStructuredBuffer<float4> A = ResourceDescriptorHeap[14];\n\tuint v = A.IncrementCounter();\n\treturn A[v];\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter-heap.sm66.uav-counter-texel-buffer.bindless.ssbo.frag",
    "content": "float4 main(uint i : I) : SV_Target\n{\n\tRWStructuredBuffer<float4> A = ResourceDescriptorHeap[14];\n\tuint v = A.IncrementCounter();\n\treturn A[v];\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.bindless.nobda.root-constant.comp",
    "content": "RWStructuredBuffer<float> Bufs[] : register(u2, space1);\nRWStructuredBuffer<float> Bufs2[] : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs[NonUniformResourceIndex(index)].IncrementCounter();\n\tBufs2[NonUniformResourceIndex(index ^ 1)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.bindless.nobda.root-constant.raw-va-stride-offset.comp",
    "content": "RWStructuredBuffer<float> Bufs[] : register(u2, space1);\nRWStructuredBuffer<float> Bufs2[] : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs[NonUniformResourceIndex(index)].IncrementCounter();\n\tBufs2[NonUniformResourceIndex(index ^ 1)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.bindless.root-constant.comp",
    "content": "RWStructuredBuffer<float> Bufs[] : register(u2, space1);\nRWStructuredBuffer<float> Bufs2[] : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs[NonUniformResourceIndex(index)].IncrementCounter();\n\tBufs2[NonUniformResourceIndex(index ^ 1)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.bindless.root-constant.raw-va-stride-offset.comp",
    "content": "RWStructuredBuffer<float> Bufs[] : register(u2, space1);\nRWStructuredBuffer<float> Bufs2[] : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs[NonUniformResourceIndex(index)].IncrementCounter();\n\tBufs2[NonUniformResourceIndex(index ^ 1)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.bindless.root-constant.raw-va-stride-offset.heap-raw-va-cbv.comp",
    "content": "RWStructuredBuffer<float> Bufs[] : register(u2, space1);\nRWStructuredBuffer<float> Bufs2[] : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs[NonUniformResourceIndex(index)].IncrementCounter();\n\tBufs2[NonUniformResourceIndex(index ^ 1)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.bindless.root-constant.uav-counter-ssbo.comp",
    "content": "RWStructuredBuffer<float> Bufs[] : register(u2, space1);\nRWStructuredBuffer<float> Bufs2[] : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs[NonUniformResourceIndex(index)].IncrementCounter();\n\tBufs2[NonUniformResourceIndex(index ^ 1)].IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.ssbo.comp",
    "content": "RWStructuredBuffer<float> Bufs : register(u2, space1);\nRWStructuredBuffer<float> Bufs2 : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs.IncrementCounter();\n\tBufs2.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.ssbo.raw-va-stride-offset.comp",
    "content": "RWStructuredBuffer<float> Bufs : register(u2, space1);\nRWStructuredBuffer<float> Bufs2 : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs.IncrementCounter();\n\tBufs2.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-counter.ssbo.uav-counter-ssbo.comp",
    "content": "RWStructuredBuffer<float> Bufs : register(u2, space1);\nRWStructuredBuffer<float> Bufs2 : register(u2, space2);\n\n[numthreads(64, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tBufs.IncrementCounter();\n\tBufs2.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/resources/uav-indexing.frag",
    "content": "RWTexture2D<float4> T[3] : register(u5);\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn T[0].Load(int2(0, 0)) + T[2].Load(int2(0, 0)) + T[v].Load(int2(0, 0));\n}\n\n"
  },
  {
    "path": "shaders/resources/uav-indexing.sm66.frag",
    "content": "RWTexture2D<float4> T[3] : register(u5);\nfloat4 main(uint v : V) : SV_Target\n{\n\treturn T[0].Load(int2(0, 0)) + T[2].Load(int2(0, 0)) + T[v].Load(int2(0, 0));\n}\n\n"
  },
  {
    "path": "shaders/resources/uav-raw-buffer.bindless.root-constant.frag",
    "content": "RWByteAddressBuffer uBuffer : register(u3);\nRWByteAddressBuffer uBufferArray[64] : register(u4);\nRWByteAddressBuffer uBufferBindless[] : register(u100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nuint2 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x) * 8;\n\tuint2 result = uBuffer.Load2(offset);\n\tresult += uBufferArray[index].Load2(offset);\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load2(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/uav-raw-buffer.ssbo.frag",
    "content": "RWByteAddressBuffer uBuffer : register(u3);\nRWByteAddressBuffer uBufferArray[64] : register(u4);\nRWByteAddressBuffer uBufferBindless[] : register(u100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nuint2 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x) * 8;\n\tuint2 result = uBuffer.Load2(offset);\n\tresult += uBufferArray[index].Load2(offset);\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load2(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/uav-structured-buffer.bindless.root-constant.frag",
    "content": "RWStructuredBuffer<float> uBuffer : register(u3);\nRWStructuredBuffer<float2> uBufferArray[64] : register(u4);\nRWStructuredBuffer<float3> uBufferBindless[] : register(u100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat3 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x);\n\tfloat3 result = uBuffer.Load(offset);\n\tresult += uBufferArray[index].Load(offset).xyx;\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/uav-typed-buffer.bindless.root-constant.frag",
    "content": "RWBuffer<float4> uBuffer : register(u3);\nRWBuffer<uint4> uBufferArray[64] : register(u4);\nRWBuffer<int4> uBufferBindless[] : register(u100);\n\ncbuffer CBUFFER : register(b0)\n{\n\tuint index;\n};\n\nfloat4 main(float4 pos : SV_Position, nointerpolation uint dynamic_index : INDEX) : SV_Target\n{\n\tint offset = int(pos.x);\n\tfloat4 result = uBuffer.Load(offset);\n\tresult += uBufferArray[index].Load(offset);\n\tresult += uBufferBindless[NonUniformResourceIndex(dynamic_index)].Load(offset);\n\treturn result;\n}\n"
  },
  {
    "path": "shaders/resources/uav-typed.typed-uav-without-format.comp",
    "content": "RWTexture2D<float4> Img : register(u0);\nRWBuffer<float4> Buf : register(u1);\nRWBuffer<uint> BufAtomic : register(u2);\n\n[numthreads(1, 1, 1)]\nvoid main(uint2 thr : SV_DispatchThreadID)\n{\n\tfloat4 v = Img[thr];\n\tv += 2.0;\n\tImg[thr] = v;\n\n\tv = Buf[thr.x];\n\tv += 3.0;\n\tBuf[thr.x] = v;\n\n\tInterlockedAdd(BufAtomic[thr.y], 10u);\n}\n"
  },
  {
    "path": "shaders/rov/rov-bab.bindless.frag",
    "content": "RasterizerOrderedByteAddressBuffer RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\tRW.Store4(offset, RW.Load4(offset) + uint4(1, 2, 3, 4));\n}\n"
  },
  {
    "path": "shaders/rov/rov-bab.frag",
    "content": "RasterizerOrderedByteAddressBuffer RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\tRW.Store4(offset, RW.Load4(offset) + uint4(1, 2, 3, 4));\n}\n"
  },
  {
    "path": "shaders/rov/rov-bab.ssbo.bindless.frag",
    "content": "RasterizerOrderedByteAddressBuffer RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\tRW.Store4(offset, RW.Load4(offset) + uint4(1, 2, 3, 4));\n}\n"
  },
  {
    "path": "shaders/rov/rov-bab.ssbo.frag",
    "content": "RasterizerOrderedByteAddressBuffer RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\tRW.Store4(offset, RW.Load4(offset) + uint4(1, 2, 3, 4));\n}\n"
  },
  {
    "path": "shaders/rov/rov-bab.ssbo.root-descriptor.frag",
    "content": "RasterizerOrderedByteAddressBuffer RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\tRW.Store4(offset, RW.Load4(offset) + uint4(1, 2, 3, 4));\n}\n"
  },
  {
    "path": "shaders/rov/rov-branch-early-return.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW0 : register(u0);\nRasterizerOrderedTexture2D<float4> RW1 : register(u1);\nRWTexture2D<float4> RW2 : register(u2);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\n\tRW2[coord] += float4(1, 2, 3, 4);\n\n\t[branch]\n\tif (pos.x < 10.0)\n\t{\n\t\tRW0[coord] += float4(1, 2, 3, 4);\n\t\tif (RW2[coord].z > 100.0)\n\t\t\treturn;\n\t}\n\telse\n\t\tRW1[coord] += float4(1, 2, 3, 4);\n\n\tRW2[coord ^ 1] += float4(1, 2, 3, 4);\n}\n\n"
  },
  {
    "path": "shaders/rov/rov-branch.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW0 : register(u0);\nRasterizerOrderedTexture2D<float4> RW1 : register(u1);\nRWTexture2D<float4> RW2 : register(u2);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\n\tRW2[coord] += float4(1, 2, 3, 4);\n\n\t[branch]\n\tif (pos.x < 10.0)\n\t\tRW0[coord] += float4(1, 2, 3, 4);\n\telse\n\t\tRW1[coord] += float4(1, 2, 3, 4);\n}\n"
  },
  {
    "path": "shaders/rov/rov-buffer.frag",
    "content": "RasterizerOrderedBuffer<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-inloop-2.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW0 : register(u0);\nRasterizerOrderedTexture2D<float4> RW1 : register(u1);\nRWTexture2D<float4> RW2 : register(u2);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\n\tRW2[coord] += float4(1, 2, 3, 4);\n\n\t[loop]\n\tfor (uint i = 0; i < uint(pos.z); i++)\n\t\tRW0[coord] += float4(1, 2, 3, 4);\n}\n"
  },
  {
    "path": "shaders/rov/rov-inloop.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW0 : register(u0);\nRasterizerOrderedTexture2D<float4> RW1 : register(u1);\nRWTexture2D<float4> RW2 : register(u2);\n\n[earlydepthstencil]\nfloat main(float4 pos : SV_Position) : SV_Target\n{\n\tuint2 coord = uint2(pos.xy);\n\t// Make sure OpVariable move works for fallback.\n\tfloat V[8];\n\tuint i;\n\tfor (i = 0; i < 8; i++)\n\t\tV[i] = float(i);\n\n\tRW2[coord] += float4(1, 2, 3, 4);\n\n\t[loop]\n\tfor (i = 0; i < 4; i++)\n\t{\n\t\tRW0[coord] += float4(1, 2, 3, 4);\n\t\tV[i] = RW0[coord].y;\n\t}\n\n\treturn V[uint(pos.w * 7.0)];\n}\n"
  },
  {
    "path": "shaders/rov/rov-per-sample.sm66.frag",
    "content": "[earlydepthstencil]\nvoid main(float4 pos : SV_Position, uint id : SV_SampleIndex)\n{\n\tuint3 coord = uint3(pos.xyz);\n\tcoord += id;\n\n\tRasterizerOrderedByteAddressBuffer RW0 = ResourceDescriptorHeap[0];\n\n\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\tRW0.Store4(offset, RW0.Load4(offset) + uint4(1, 2, 3, 4));\n\n\tRasterizerOrderedStructuredBuffer<float4> RW1 = ResourceDescriptorHeap[1];\n\tRW1[coord.y * 1000 + coord.x] += float4(1, 2, 3, 4);\n\n\tRasterizerOrderedBuffer<float4> RW2 = ResourceDescriptorHeap[2];\n\tRW2[coord.y * 1000 + coord.x] += float4(1, 2, 3, 4);\n\n\tRasterizerOrderedTexture1D<float4> RW3 = ResourceDescriptorHeap[3];\n\tRW3[coord.y * 1000 + coord.x] += float4(1, 2, 3, 4);\n\n\tRasterizerOrderedTexture2D<float4> RW4 = ResourceDescriptorHeap[4];\n\tRW4[coord.xy] += float4(1, 2, 3, 4);\n}\n"
  },
  {
    "path": "shaders/rov/rov-postloop.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW0 : register(u0);\nRasterizerOrderedTexture2D<float4> RW1 : register(u1);\nRWTexture2D<float4> RW2 : register(u2);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\n\t[loop]\n\tfor (uint i = 0; i < 4; i++)\n\t\tRW2[coord] += float4(1, 2, 3, 4);\n\n\tRW0[coord] += float4(1, 2, 3, 4);\n}\n"
  },
  {
    "path": "shaders/rov/rov-structured.bindless.frag",
    "content": "RasterizerOrderedStructuredBuffer<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-structured.frag",
    "content": "RasterizerOrderedStructuredBuffer<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-structured.ssbo.bindless.frag",
    "content": "RasterizerOrderedStructuredBuffer<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-structured.ssbo.frag",
    "content": "RasterizerOrderedStructuredBuffer<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-structured.ssbo.root-descriptor.frag",
    "content": "RasterizerOrderedStructuredBuffer<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex1d.bindless.frag",
    "content": "RasterizerOrderedTexture1D<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex1d.frag",
    "content": "RasterizerOrderedTexture1D<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex1darray.bindless.frag",
    "content": "RasterizerOrderedTexture1DArray<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex1darray.frag",
    "content": "RasterizerOrderedTexture1DArray<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex2d.bindless.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex2d.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex2darray.bindless.frag",
    "content": "RasterizerOrderedTexture2DArray<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint3 coord = uint3(pos.xyz);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex2darray.frag",
    "content": "RasterizerOrderedTexture2DArray<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint3 coord = uint3(pos.xyz);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex3d.bindless.frag",
    "content": "RasterizerOrderedTexture3D<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint3 coord = uint3(pos.xyz);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-tex3d.frag",
    "content": "RasterizerOrderedTexture3D<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint3 coord = uint3(pos.xyz);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/rov/rov-undef.frag",
    "content": "RasterizerOrderedByteAddressBuffer RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tbool v = pos.x > 1000.0;\n\tbool v2 = pos.x > 1100.0;\n\n\tuint2 coord;\n\n\t[branch]\n\tif (v)\n\t{\n\t\tcoord = uint2(pos.xy);\n\t\tcoord = RW.Load2(0);\n\t\tRW.Store(0, 50);\n\t}\n\n\t[branch]\n\tif (v2)\n\t{\n\t\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\t\tRW.Store4(offset, RW.Load4(offset) + uint4(1, 2, 3, 4));\n\t}\n}\n"
  },
  {
    "path": "shaders/rov/rov.sm66.frag",
    "content": "[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint3 coord = uint3(pos.xyz);\n\tRasterizerOrderedByteAddressBuffer RW0 = ResourceDescriptorHeap[0];\n\n\tuint offset = 16 * (coord.y * 1000 + coord.x);\n\tRW0.Store4(offset, RW0.Load4(offset) + uint4(1, 2, 3, 4));\n\n\tRasterizerOrderedStructuredBuffer<float4> RW1 = ResourceDescriptorHeap[1];\n\tRW1[coord.y * 1000 + coord.x] += float4(1, 2, 3, 4);\n\n\tRasterizerOrderedBuffer<float4> RW2 = ResourceDescriptorHeap[2];\n\tRW2[coord.y * 1000 + coord.x] += float4(1, 2, 3, 4);\n\n\tRasterizerOrderedTexture1D<float4> RW3 = ResourceDescriptorHeap[3];\n\tRW3[coord.y * 1000 + coord.x] += float4(1, 2, 3, 4);\n\n\tRasterizerOrderedTexture2D<float4> RW4 = ResourceDescriptorHeap[4];\n\tRW4[coord.xy] += float4(1, 2, 3, 4);\n}\n"
  },
  {
    "path": "shaders/sampler-feedback/sampler-feedback.frag",
    "content": "// We ignore the kind of sampler feedback used, so don't bother testing it exhaustively.\nFeedbackTexture2D<SAMPLER_FEEDBACK_MIP_REGION_USED> F0 : register(u0);\nFeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP> F1 : register(u1);\nFeedbackTexture2D<SAMPLER_FEEDBACK_MIP_REGION_USED> F2[] : register(u0, space1);\nFeedbackTexture2DArray<SAMPLER_FEEDBACK_MIP_REGION_USED> F3[] : register(u0, space2);\n\nTexture2D<float4> T : register(t0);\nTexture2DArray<float4> TArray : register(t1);\nTexture2D<float4> Ts[] : register(t0, space1);\nTexture2DArray<float4> TArrays[] : register(t0, space2);\n\n// Comparison samplers don't work. Not a huge deal since we can estimate footprint with non-comparison samplers just fine. :')\nSamplerState S : register(s0);\nSamplerState Ss[] : register(s0, space1);\n\nvoid main(float4 pos : SV_Position, float2 grad_x : GRADX, float2 grad_y : GRADY, float mipclamp : CLAMP, uint idx : IDX)\n{\n\t// Test all HLSL calls available.\n\tF0.WriteSamplerFeedback(T, S, pos.xy);\n\t// Undocumented, with clamp\n\tF0.WriteSamplerFeedback(T, S, pos.xy, mipclamp);\n\tF0.WriteSamplerFeedbackLevel(T, S, pos.xy, pos.z);\n\tF0.WriteSamplerFeedbackGrad(T, S, pos.xy, grad_x, grad_y);\n\t// Undocumented, with clamp\n\tF0.WriteSamplerFeedbackGrad(T, S, pos.xy, grad_x, grad_y, mipclamp);\n\tF0.WriteSamplerFeedbackBias(T, S, pos.xy, pos.z);\n\t// Undocumented, with clamp\n\tF0.WriteSamplerFeedbackBias(T, S, pos.xy, pos.z, mipclamp);\n\n\t// Test array versions.\n\tF1.WriteSamplerFeedback(TArray, S, pos.xyz);\n\t// Undocumented, with clamp\n\tF1.WriteSamplerFeedback(TArray, S, pos.xyz, mipclamp);\n\tF1.WriteSamplerFeedbackLevel(TArray, S, pos.xyz, pos.w);\n\tF1.WriteSamplerFeedbackGrad(TArray, S, pos.xyz, grad_x, grad_y);\n\t// Undocumented, with clamp\n\tF1.WriteSamplerFeedbackGrad(TArray, S, pos.xyz, grad_x, grad_y, mipclamp);\n\tF1.WriteSamplerFeedbackBias(TArray, S, pos.xyz, pos.z);\n\t// Undocumented, with clamp\n\tF1.WriteSamplerFeedbackBias(TArray, S, pos.xyz, pos.w, mipclamp);\n\n\t// Test indexing\n\tF2[idx].WriteSamplerFeedback(Ts[idx], Ss[idx], pos.xy);\n\tF3[idx].WriteSamplerFeedback(TArrays[idx], Ss[idx], pos.xyz);\n\n\t// Test non-uniform indexing\n\tF2[NonUniformResourceIndex(idx)].WriteSamplerFeedback(Ts[NonUniformResourceIndex(idx)], Ss[NonUniformResourceIndex(idx)], pos.xy);\n\tF3[NonUniformResourceIndex(idx)].WriteSamplerFeedback(TArrays[NonUniformResourceIndex(idx)], Ss[NonUniformResourceIndex(idx)], pos.xyz);\n}\n\n"
  },
  {
    "path": "shaders/sampler-feedback/sampler-feedback.sm66.frag",
    "content": "// We ignore the kind of sampler feedback used, so don't bother testing it exhaustively.\nFeedbackTexture2D<SAMPLER_FEEDBACK_MIP_REGION_USED> F0 : register(u0);\nFeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP> F1 : register(u1);\nFeedbackTexture2D<SAMPLER_FEEDBACK_MIP_REGION_USED> F2[] : register(u0, space1);\nFeedbackTexture2DArray<SAMPLER_FEEDBACK_MIP_REGION_USED> F3[] : register(u0, space2);\n\nTexture2D<float4> T : register(t0);\nTexture2DArray<float4> TArray : register(t1);\nTexture2D<float4> Ts[] : register(t0, space1);\nTexture2DArray<float4> TArrays[] : register(t0, space2);\n\n// Comparison samplers don't work. Not a huge deal since we can estimate footprint with non-comparison samplers just fine. :')\nSamplerState S : register(s0);\nSamplerState Ss[] : register(s0, space1);\n\nvoid main(float4 pos : SV_Position, float2 grad_x : GRADX, float2 grad_y : GRADY, float mipclamp : CLAMP, uint idx : IDX)\n{\n\t// Test all HLSL calls available.\n\tF0.WriteSamplerFeedback(T, S, pos.xy);\n\t// Undocumented, with clamp\n\tF0.WriteSamplerFeedback(T, S, pos.xy, mipclamp);\n\tF0.WriteSamplerFeedbackLevel(T, S, pos.xy, pos.z);\n\tF0.WriteSamplerFeedbackGrad(T, S, pos.xy, grad_x, grad_y);\n\t// Undocumented, with clamp\n\tF0.WriteSamplerFeedbackGrad(T, S, pos.xy, grad_x, grad_y, mipclamp);\n\tF0.WriteSamplerFeedbackBias(T, S, pos.xy, pos.z);\n\t// Undocumented, with clamp\n\tF0.WriteSamplerFeedbackBias(T, S, pos.xy, pos.z, mipclamp);\n\n\t// Test array versions.\n\tF1.WriteSamplerFeedback(TArray, S, pos.xyz);\n\t// Undocumented, with clamp\n\tF1.WriteSamplerFeedback(TArray, S, pos.xyz, mipclamp);\n\tF1.WriteSamplerFeedbackLevel(TArray, S, pos.xyz, pos.w);\n\tF1.WriteSamplerFeedbackGrad(TArray, S, pos.xyz, grad_x, grad_y);\n\t// Undocumented, with clamp\n\tF1.WriteSamplerFeedbackGrad(TArray, S, pos.xyz, grad_x, grad_y, mipclamp);\n\tF1.WriteSamplerFeedbackBias(TArray, S, pos.xyz, pos.z);\n\t// Undocumented, with clamp\n\tF1.WriteSamplerFeedbackBias(TArray, S, pos.xyz, pos.w, mipclamp);\n\n\t// Test indexing\n\tF2[idx].WriteSamplerFeedback(Ts[idx], Ss[idx], pos.xy);\n\tF3[idx].WriteSamplerFeedback(TArrays[idx], Ss[idx], pos.xyz);\n\n\t// Test non-uniform indexing\n\tF2[NonUniformResourceIndex(idx)].WriteSamplerFeedback(Ts[NonUniformResourceIndex(idx)], Ss[NonUniformResourceIndex(idx)], pos.xy);\n\tF3[NonUniformResourceIndex(idx)].WriteSamplerFeedback(TArrays[NonUniformResourceIndex(idx)], Ss[NonUniformResourceIndex(idx)], pos.xyz);\n\n\t// Test heap.\n\tFeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP> FHeap = ResourceDescriptorHeap[idx];\n\tFHeap.WriteSamplerFeedback(T, S, pos.xy);\n\tFeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP> FHeapNRUI = ResourceDescriptorHeap[NonUniformResourceIndex(idx)];\n\tFHeapNRUI.WriteSamplerFeedback(T, S, pos.xy);\n}\n\n"
  },
  {
    "path": "shaders/semantics/clip-cull-distance.vert",
    "content": "struct VSOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat4 clip : SV_ClipDistance;\n\tfloat4 cull : SV_CullDistance;\n};\n\nVSOut main(float4 pos : POS, float4 clip : CLIP, float4 cull : CULL)\n{\n\tVSOut vs;\n\tvs.pos = pos;\n\tvs.clip = clip;\n\tvs.cull = cull;\n\treturn vs;\n}\n"
  },
  {
    "path": "shaders/semantics/clip-cull.frag",
    "content": "struct PSIn\n{\n\tfloat2 clip0 : SV_ClipDistance0;\n\tfloat clip1 : SV_ClipDistance1;\n\tfloat clip2 : SV_ClipDistance2;\n\tfloat2 cull0 : SV_CullDistance0;\n\tfloat cull1 : SV_CullDistance1;\n};\n\nfloat4 main(PSIn pin) : SV_Target\n{\n\tfloat4 res = float4(pin.clip0, pin.clip1, pin.clip2);\n\tres += pin.cull0.xyxy;\n\tres += pin.cull1;\n\treturn res;\n}\n"
  },
  {
    "path": "shaders/semantics/clip-distance-cols.frag",
    "content": "struct VSOut\n{\n\tfloat2 clip : SV_ClipDistance;\n};\n\nfloat4 main(VSOut vin) : SV_Target\n{\n\treturn vin.clip.xyyx;\n}\n"
  },
  {
    "path": "shaders/semantics/clip-distance-cols.vert",
    "content": "struct VSOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat2 clip : SV_ClipDistance;\n};\n\nVSOut main(float4 pos : POS, float2 clip : CLIP)\n{\n\tVSOut vs;\n\tvs.pos = pos;\n\tvs.clip[0] = clip.x;\n\tvs.clip[1] = clip.y;\n\treturn vs;\n}\n"
  },
  {
    "path": "shaders/semantics/clip-distance-flatten.frag",
    "content": "struct VSOut\n{\n\tfloat2 clip[2] : SV_ClipDistance;\n};\n\nfloat4 main(VSOut vin) : SV_Target\n{\n\treturn float4(vin.clip[0], vin.clip[1]);\n}\n"
  },
  {
    "path": "shaders/semantics/clip-distance-flatten.vert",
    "content": "struct VSOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat2 clip[2] : SV_ClipDistance;\n};\n\nVSOut main(float4 pos : POS, float2 clip : CLIP)\n{\n\tVSOut vs;\n\tvs.pos = pos;\n\tvs.clip[0] = clip;\n\tvs.clip[1] = clip + 1.0;\n\treturn vs;\n}\n\n"
  },
  {
    "path": "shaders/semantics/clip-distance-rows.frag",
    "content": "struct VSOut\n{\n\tfloat clip[2] : SV_ClipDistance;\n};\n\nfloat4 main(VSOut vin) : SV_Target\n{\n\treturn float4(vin.clip[0].xx, vin.clip[1].xx);\n}\n"
  },
  {
    "path": "shaders/semantics/clip-distance-rows.vert",
    "content": "struct VSOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat clip[2] : SV_ClipDistance;\n};\n\nVSOut main(float4 pos : POS, float clip : CLIP)\n{\n\tVSOut vs;\n\tvs.pos = pos;\n\tvs.clip[0] = clip;\n\tvs.clip[1] = clip + 1.0;\n\treturn vs;\n}\n"
  },
  {
    "path": "shaders/semantics/clip-distance-single.vert",
    "content": "struct VSOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat clip : SV_ClipDistance;\n};\n\nVSOut main(float4 pos : POS, float clip : CLIP)\n{\n\tVSOut vs;\n\tvs.pos = pos;\n\tvs.clip = clip.x;\n\treturn vs;\n}\n"
  },
  {
    "path": "shaders/semantics/coverage.frag",
    "content": "struct PSOut\n{\n\tfloat4 color : SV_Target;\n\tuint coverage : SV_Coverage;\n};\n\nPSOut main(uint coverage : SV_Coverage)\n{\n\tPSOut pout;\n\tpout.color = 1.0.xxxx;\n\tpout.coverage = coverage & 3;\n\treturn pout;\n}\n"
  },
  {
    "path": "shaders/semantics/depth-greater-equal.frag",
    "content": "float main(float d : D) : SV_DepthGreaterEqual\n{\n\treturn d;\n}\n"
  },
  {
    "path": "shaders/semantics/depth-less-equal.frag",
    "content": "float main(float d : D) : SV_DepthLessEqual\n{\n\treturn d;\n}\n"
  },
  {
    "path": "shaders/semantics/depth.frag",
    "content": "float main(float d : D) : SV_Depth\n{\n\treturn d;\n}\n"
  },
  {
    "path": "shaders/semantics/early-depth-stencil.frag",
    "content": "[earlydepthstencil]\nfloat4 main() : SV_Target\n{\n\treturn 1.0.xxxx;\n}\n"
  },
  {
    "path": "shaders/semantics/inner-coverage.noglsl.frag",
    "content": "float main(uint cov : SV_InnerCoverage) : SV_Target\n{\n\tif (cov == 0)\n\t\tdiscard;\n\treturn 1.0;\n}\n"
  },
  {
    "path": "shaders/semantics/is-front-face.frag",
    "content": "float main(bool front : SV_IsFrontFace) : SV_Target\n{\n\treturn front ? 1.0 : 0.0;\n}\n"
  },
  {
    "path": "shaders/semantics/position.frag",
    "content": "float main(float4 pos : SV_Position, nointerpolation uint index : INDEX) : SV_Target\n{\n\treturn pos[index];\n}\n"
  },
  {
    "path": "shaders/semantics/primitive-id.frag",
    "content": "uint main(uint prim : SV_PrimitiveID) : SV_Target\n{\n\treturn prim;\n}\n"
  },
  {
    "path": "shaders/semantics/primitive-id.geom",
    "content": "struct Output\n{\n\tfloat4 a : SV_Position;\n\tuint prim : SV_PrimitiveID;\n};\n\nstruct Inputs\n{\n\tfloat4 a : A;\n};\n\n[maxvertexcount(1)]\nvoid main(point Inputs points[1], inout PointStream<Output> o, uint prim : SV_PrimitiveID)\n{\n\tOutput res;\n\tres.a = points[0].a;\n\tres.prim = prim + 1;\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/semantics/render-target-array-index.frag",
    "content": "uint main(uint layer : SV_RenderTargetArrayIndex) : SV_Target\n{\n\treturn layer;\n}\n"
  },
  {
    "path": "shaders/semantics/render-target-array-index.geom",
    "content": "struct Output\n{\n\tfloat4 a : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n};\n\nstruct Inputs\n{\n\tfloat4 a : A;\n\tfloat4 b : B;\n};\n\n[maxvertexcount(2)]\nvoid main(point Inputs points[1], inout PointStream<Output> o)\n{\n\tOutput res;\n\tres.a = points[0].a;\n\tres.layer = 0;\n\to.Append(res);\n\tres.a = points[0].b;\n\tres.layer = 1;\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/semantics/sample-rate-pos.frag",
    "content": "float4 main(sample float4 pos : SV_Position) : SV_Target\n{\n\treturn pos;\n}\n"
  },
  {
    "path": "shaders/semantics/stencil-ref.frag",
    "content": "struct Out\n{\n\tfloat4 v : SV_Target0;\n\tuint s : SV_StencilRef;\n};\n\nOut main(float v : V)\n{\n\tOut o;\n\to.v = v.xxxx;\n\to.s = uint(v);\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/semantics/sv-shading-rate.noglsl.frag",
    "content": "uint main(uint rate : SV_ShadingRate) : SV_Target\n{\n\treturn rate;\n}\n"
  },
  {
    "path": "shaders/semantics/sv-shading-rate.noglsl.vert",
    "content": "struct Outs\n{\n\tfloat4 pos : SV_Position;\n\tuint rate : SV_ShadingRate;\n};\n\nOuts main()\n{\n\tOuts o;\n\to.pos = 1.0.xxxx;\n\to.rate = 0xa;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/semantics/view-id.frag",
    "content": "float4 main(float4 pos : POSITION, uint view : SV_ViewID) : SV_Target\n{\n\treturn pos + float(view);\n}\n"
  },
  {
    "path": "shaders/semantics/view-id.vert",
    "content": "float4 main(float4 pos : POSITION, uint view : SV_ViewID) : SV_Position\n{\n\treturn pos + float(view);\n}\n"
  },
  {
    "path": "shaders/semantics/viewport-array-index.frag",
    "content": "uint main(uint layer : SV_ViewportArrayIndex) : SV_Target\n{\n\treturn layer;\n}\n"
  },
  {
    "path": "shaders/semantics/viewport-array-index.geom",
    "content": "struct Output\n{\n\tfloat4 a : SV_Position;\n\tuint layer : SV_ViewportArrayIndex;\n};\n\nstruct Inputs\n{\n\tfloat4 a : A;\n\tfloat4 b : B;\n};\n\n[maxvertexcount(2)]\nvoid main(point Inputs points[1], inout PointStream<Output> o)\n{\n\tOutput res;\n\tres.a = points[0].a;\n\tres.layer = 0;\n\to.Append(res);\n\tres.a = points[0].b;\n\tres.layer = 1;\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/boolean-io.vert",
    "content": "struct Foo\n{\n\tfloat4 pos : SV_Position;\n\tbool v : V;\n};\n\nFoo main(bool a : A)\n{\n\tFoo foo;\n\tfoo.pos = 1.0.xxxx;\n\tfoo.v = true;\n\treturn foo;\n}\n"
  },
  {
    "path": "shaders/stages/callable-chain.rcall",
    "content": "struct Payload\n{\n\tfloat p;\n};\n\n[shader(\"callable\")]\nvoid main(inout Payload p)\n{\n\tCallShader(0, p);\n}\n"
  },
  {
    "path": "shaders/stages/callable.rcall",
    "content": "struct Payload\n{\n\tfloat p;\n};\n\n[shader(\"callable\")]\nvoid RayCallable(inout Payload p)\n{\n\tp.p = 1.0;\n}\n"
  },
  {
    "path": "shaders/stages/closesthit.rclosest",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\n[shader(\"closesthit\")]\nvoid RayClosest(inout Payload payload, BuiltInTriangleIntersectionAttributes attr)\n{\n\tpayload.color = attr.barycentrics.xyxy;\n}\n"
  },
  {
    "path": "shaders/stages/domain-clip-cull.tese",
    "content": "struct Foo\n{\n\tfloat3 a : SV_CullDistance;\n\tfloat b : SV_ClipDistance;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\nstruct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat clip : SV_ClipDistance;\n};\n\n[domain(\"tri\")]\nVOut main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation)\n{\n\tVOut vout;\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z;\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\tvout.pos = float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n\tvout.clip = 5.0;\n\treturn vout;\n}\n"
  },
  {
    "path": "shaders/stages/domain-patch-input-integer-io.tese",
    "content": "struct Foo\n{\n\tfloat a : A;\n};\n\nstruct Patch\n{\n\tint b : B;\n\tuint c : C;\n\tint4 bv : BV;\n\tuint4 cv : CV;\n\tint bvs[2] : BVS;\n\tuint cvs[2] : CVS;\n\tint4 bvss[2] : BVSS;\n\tuint4 cvss[2] : CVSS;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation) : SV_Position\n{\n\treturn float4(op[0].a, float(p.b), float(p.c), 1.0) +\n\t\tfloat4(p.bv) +\n\t\tfloat4(p.cv) +\n\t\tfloat(p.bvs[0]) +\n\t\tfloat(p.cvs[1]) +\n\t\tfloat4(p.bvss[0]) +\n\t\tfloat4(p.cvss[1]);\n}\n"
  },
  {
    "path": "shaders/stages/domain.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation) : SV_Position\n{\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z;\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\treturn float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n}\n"
  },
  {
    "path": "shaders/stages/extra_output.dual-source-blending.frag",
    "content": "float4 c0;\nfloat4 c1;\nfloat4 c2;\n\nvoid main(out float4 o0 : SV_Target0, out float4 o1 : SV_Target1, out float4 o2 : SV_Target2)\n{\n\to0 = c0;\n\to1 = c1;\n\to2 = c2;\n}\n"
  },
  {
    "path": "shaders/stages/extra_output_reordered.dual-source-blending.frag",
    "content": "float4 c0;\nfloat4 c1;\nfloat4 c2;\n\nvoid main(out float4 o2 : SV_Target2, out float4 o0 : SV_Target0, out float4 o1 : SV_Target1)\n{\n\to0 = c0;\n\to1 = c1;\n\to2 = c2;\n}\n"
  },
  {
    "path": "shaders/stages/geometry-clip-cull.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : SV_ClipDistance;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : SV_ClipDistance;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(6)]\nvoid main(triangle Inputs input[3], inout TriangleStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n\tres.a = input[1].a;\n\tres.pos.x += 0.01;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\to.RestartStrip();\n\n\to.Append(res);\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-input-line.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(6)]\nvoid main(line Inputs input[2], inout TriangleStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\to.RestartStrip();\n\n\to.Append(res);\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-input-lineadj.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(6)]\nvoid main(lineadj Inputs input[4], inout TriangleStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[3].pos;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\to.RestartStrip();\n\n\to.Append(res);\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-input-point.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(6)]\nvoid main(point Inputs input[1], inout TriangleStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[0].pos;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\to.RestartStrip();\n\n\to.Append(res);\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-input-triangle.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(6)]\nvoid main(triangle Inputs input[3], inout TriangleStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\to.RestartStrip();\n\n\to.Append(res);\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-input-triangleadj.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(6)]\nvoid main(triangleadj Inputs input[6], inout TriangleStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[5].pos;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\to.RestartStrip();\n\n\to.Append(res);\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-instancing.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(6)]\n[instance(2)]\nvoid main(triangle Inputs input[3], inout TriangleStream<Outputs> o, uint InstanceID : SV_GSInstanceID)\n{\n\tOutputs res;\n\tres.a = input[InstanceID].a;\n\tres.pos = input[InstanceID ^ 1].pos;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\tres.pos.x += 0.01;\n\to.Append(res);\n\to.RestartStrip();\n\n\to.Append(res);\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-output-line.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(2)]\nvoid main(triangle Inputs input[3], inout LineStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n\tres.pos += 0.01;\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-output-point.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(1)]\nvoid main(triangle Inputs input[3], inout PointStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/stages/geometry-streams.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs0\n{\n\tfloat4 a : A;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs1\n{\n\tfloat4 b : B;\n\tfloat4 d[2] : D;\n};\n\nstruct Outputs2\n{\n\tfloat4 c : C;\n\tfloat4 e : E;\n};\n\n[maxvertexcount(3)]\nvoid main(point Inputs input[1], inout PointStream<Outputs0> o0, inout PointStream<Outputs1> o1, inout PointStream<Outputs2> o2)\n{\n\tOutputs0 res0;\n\tres0.a = input[0].a;\n\tres0.pos = input[0].pos;\n\to0.Append(res0);\n\n\tOutputs1 res1;\n\tres1.b = input[0].a + 1.0;\n\tres1.d[0] = 1.0.xxxx;\n\tres1.d[1] = 3.0.xxxx;\n\to1.Append(res1);\n\n\tOutputs2 res2;\n\tres2.c = input[0].a + 2.0;\n\tres2.e = res2.c + 1.0;\n\to2.Append(res2);\n}\n"
  },
  {
    "path": "shaders/stages/hull-arrays.tesc",
    "content": "struct VSControlPoint\n{\n\tfloat value[3] : VSValue;\n};\n\nstruct HSControlPoint\n{\n\tfloat value[3] : HSValue;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[3] : SV_TessFactor;\n\tfloat inner[1] : SV_InsideTessFactor;\n\tfloat patch[2] : PATCH;\n};\n\n[domain(\"tri\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_ccw\")]\n[outputcontrolpoints(2)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<VSControlPoint, 5> ip)\n{\n\tHSControlPoint cp;\n\tcp.value[0] = ip[0].value[0] + ip[1].value[1] + ip[2].value[2];\n\tcp.value[1] = cp.value[0] + 1.0;\n\tcp.value[2] = cp.value[0] + 2.0;\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 2> op, InputPatch<VSControlPoint, 5> ip)\n{\n\tPatchConstant pc;\n\tpc.inner[0] = op[0].value[1] + op[1].value[2];\n\tpc.outer[0] = ip[0].value[2];\n\tpc.outer[1] = ip[1].value[1];\n\tpc.outer[2] = ip[2].value[0];\n\tpc.patch[0] = ip[3].value[2];\n\tpc.patch[1] = ip[4].value[1];\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/stages/hull-clip-cull.tesc",
    "content": "struct VSControlPoint\n{\n\tfloat2 clip_value : SV_ClipDistance;\n\tfloat cull_value[2] : SV_CullDistance;\n};\n\nstruct HSControlPoint\n{\n\tfloat2 value : HSValue;\n\tfloat2 clip_value : SV_ClipDistance;\n\tfloat cull_value[2] : SV_CullDistance;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[4] : SV_TessFactor;\n\tfloat inner[2] : SV_InsideTessFactor;\n};\n\n[domain(\"quad\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_cw\")]\n[outputcontrolpoints(4)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<VSControlPoint, 4> ip, uint control : SV_OutputControlPointID)\n{\n\tHSControlPoint cp;\n\tcp.value = ip[control].clip_value + ip[control].cull_value[0] + ip[control].cull_value[1];\n\tcp.clip_value = float2(1, 2);\n\tcp.cull_value[0] = 3.0;\n\tcp.cull_value[1] = 4.0;\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 4> op, InputPatch<VSControlPoint, 4> ip)\n{\n\tPatchConstant pc = (PatchConstant)0;\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/stages/hull-patch-output-integer-io.tesc",
    "content": "struct Foo\n{\n\tint a : A;\n\tuint b : B;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[3] : SV_TessFactor;\n\tfloat inner[1] : SV_InsideTessFactor;\n\tint b : B;\n\tuint c : C;\n\tint4 bv : BV;\n\tuint4 cv : CV;\n\tint bvs[2] : BVS;\n\tuint cvs[2] : CVS;\n\tint4 bvss[2] : BVSS;\n\tuint4 cvss[2] : CVSS;\n};\n\nstruct HSControlPoint\n{\n\tfloat a : A;\n};\n\n[domain(\"tri\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_ccw\")]\n[outputcontrolpoints(3)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<Foo, 2> ip)\n{\n\tHSControlPoint cp;\n\tcp.a = float(ip[0].a) + float(ip[1].b);\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 3> op, InputPatch<Foo, 2> ip)\n{\n\tPatchConstant pc;\n\tpc.inner[0] = op[0].a + op[1].a;\n\tpc.outer[0] = float(ip[0].a);\n\tpc.outer[1] = float(ip[1].b);\n\tpc.outer[2] = 4.0;\n\n\tpc.b = 10;\n\tpc.c = 20;\n\tpc.bv = int4(1, 2, 3, 4);\n\tpc.cv = uint4(5, 6, 7, 8);\n\tpc.bvs[0] = 50;\n\tpc.bvs[1] = 60;\n\tpc.cvs[0] = 70;\n\tpc.cvs[1] = 80;\n\tpc.bvss[0] = int4(50, 60, 70, 80);\n\tpc.bvss[1] = int4(51, 52, 53, 54);\n\tpc.cvss[0] = int4(70, 71, 72, 73);\n\tpc.cvss[1] = uint4(80, 81, 82, 83);\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/stages/hull-single-cp.tesc",
    "content": "struct VSControlPoint\n{\n\tfloat value : VSValue;\n};\n\nstruct HSControlPoint\n{\n\tfloat value : HSValue;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[3] : SV_TessFactor;\n\tfloat inner[1] : SV_InsideTessFactor;\n\tfloat patch : PATCH;\n};\n\n[domain(\"tri\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_ccw\")]\n[outputcontrolpoints(1)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<VSControlPoint, 5> ip)\n{\n\tHSControlPoint cp;\n\tcp.value = ip[0].value + ip[1].value + ip[2].value;\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 1> op, InputPatch<VSControlPoint, 5> ip)\n{\n\tPatchConstant pc;\n\tpc.inner[0] = op[0].value;\n\tpc.outer[0] = ip[0].value;\n\tpc.outer[1] = ip[1].value;\n\tpc.outer[2] = ip[2].value;\n\tpc.patch = ip[3].value;\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/stages/hull.tesc",
    "content": "struct VSControlPoint\n{\n\tfloat value : VSValue;\n};\n\nstruct HSControlPoint\n{\n\tfloat value : HSValue;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[4] : SV_TessFactor;\n\tfloat inner[2] : SV_InsideTessFactor;\n\tfloat patch : PATCH;\n};\n\ncbuffer Cbuf : register(b0)\n{\n\tfloat global_constant;\n};\n\n[domain(\"quad\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_cw\")]\n[outputcontrolpoints(4)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<VSControlPoint, 5> ip, uint control : SV_OutputControlPointID)\n{\n\t// Test that alloca gets directly appropriately.\n\tfloat4 v;\n\tv.x = ip[0].value;\n\tv.y = ip[1].value;\n\tv.z = ip[2].value;\n\tv.w = ip[3].value;\n\tv[int(ip[0].value)] += 40.0;\n\n\tHSControlPoint cp;\n\tcp.value = ip[0].value + ip[1].value + ip[2].value + v[3] + float(control);\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 4> op, InputPatch<VSControlPoint, 5> ip)\n{\n\t// Test that alloca gets directly appropriately.\n\tfloat4 v;\n\tv.x = ip[0].value;\n\tv.y = ip[1].value;\n\tv.z = ip[2].value;\n\tv.w = ip[3].value;\n\tv[int(ip[0].value)] += 40.0;\n\n\tPatchConstant pc;\n\tpc.inner[0] = op[0].value;\n\tpc.inner[1] = op[1].value;\n\tpc.outer[0] = ip[0].value;\n\tpc.outer[1] = ip[1].value;\n\tpc.outer[2] = ip[2].value;\n\tpc.outer[3] = ip[0].value + op[0].value;\n\tpc.patch = v[3] + global_constant;\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/stages/mesh-basic-line.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat4 b : B;\n};\n\nstruct PrimOut\n{\n\tbool cull : SV_CullPrimitive;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint primid : SV_PrimitiveID;\n\tfloat4 c : C;\n};\n\ngroupshared float foo[64];\n\nstruct Payload\n{\n\tfloat p;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"line\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tin payload Payload p,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint2 ind[8],\n\t\tout primitives PrimOut prim[8])\n{\n\tfoo[tid] = float(tid);\n\tGroupMemoryBarrierWithGroupSync();\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = foo[tid].xxxx;\n\tvout[tid].b = foo[tid ^ 1].xxxx + p.p;\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint2(0, 1);\n\t\tprim[tid].cull = bool(tid & 1);\n\t\tprim[tid].primid = tid;\n\t\tprim[tid].layer = tid;\n\t\tprim[tid].c = foo[tid ^ 2].xxxx;\n\t}\n}\n"
  },
  {
    "path": "shaders/stages/mesh-basic.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat4 b : B;\n};\n\nstruct PrimOut\n{\n\tbool cull : SV_CullPrimitive;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint primid : SV_PrimitiveID;\n\tfloat4 c : C;\n};\n\ngroupshared float foo[64];\n\nstruct Payload\n{\n\tfloat p;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tin payload Payload p,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8],\n\t\tout primitives PrimOut prim[8])\n{\n\tfoo[tid] = float(tid);\n\tGroupMemoryBarrierWithGroupSync();\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = foo[tid].xxxx;\n\tvout[tid].b = foo[tid ^ 1].xxxx + p.p;\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t\tprim[tid].cull = bool(tid & 1);\n\t\tprim[tid].primid = tid;\n\t\tprim[tid].layer = tid;\n\t\tprim[tid].c = foo[tid ^ 2].xxxx;\n\t}\n}\n"
  },
  {
    "path": "shaders/stages/mesh-clip-cull.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat4 clip : SV_ClipDistance;\n\tfloat4 cull : SV_CullDistance;\n};\n\nstruct Payload\n{\n\tfloat4 pos[24];\n\tfloat4 clip[24];\n\tfloat4 cull[24];\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tin payload Payload p,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8])\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = p.pos[tid];\n\tvout[tid].clip = p.clip[tid];\n\tvout[tid].cull = p.cull[tid];\n\tif (tid < 8)\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n}\n"
  },
  {
    "path": "shaders/stages/raygen-complex-storage-class.rgen",
    "content": "struct Inner\n{\n\tfloat4 color;\n};\n\nstruct Payload\n{\n\tInner a;\n\tInner b;\n};\n\nRaytracingAccelerationStructure AS : register(t30, space40);\nRWTexture2D<float4> IMG : register(u10, space20);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload p;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p);\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p.a);\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, p.b);\n\n\tCallShader(0, p);\n\tCallShader(0, p.a);\n\tCallShader(0, p.b);\n\n\tIMG[int2(0, 0)] = p.a.color + p.b.color;\n}\n"
  },
  {
    "path": "shaders/stages/raygen-skip-inactive-resources.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\nRaytracingAccelerationStructure AS : register(t30, space40);\nRWTexture2D<float4> IMG : register(u10, space20);\n\nSamplerState S : register(s0);\nTexture2D<float4> T : register(t0);\n\n[shader(\"miss\")]\nvoid RayMiss(inout Payload payload)\n{\n\tpayload.color = T.SampleLevel(S, 0.5.xx, 0.0);\n}\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/stages/raygen.rgen",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nstruct Payload1\n{\n\tfloat color;\n};\n\nRaytracingAccelerationStructure AS : register(t30, space40);\nRWTexture2D<float4> IMG : register(u10, space20);\n\n[shader(\"raygeneration\")]\nvoid RayGen()\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\n\tPayload payload0;\n\tPayload1 payload1;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload0);\n\tTraceRay(AS, RAY_FLAG_NONE, 1, 0, 0, 0, ray, payload1);\n\n\tIMG[int2(0, 0)] = payload0.color + payload1.color;\n}\n"
  },
  {
    "path": "shaders/stages/raymiss-chain.rmiss",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\nRaytracingAccelerationStructure AS : register(t0);\n\n[shader(\"miss\")]\nvoid RayMiss(inout Payload payload)\n{\n\tRayDesc ray;\n\tray.Origin = float3(1, 2, 3);\n\tray.Direction = float3(0, 0, 1);\n\tray.TMin = 1.0;\n\tray.TMax = 4.0;\n\tTraceRay(AS, RAY_FLAG_NONE, 0, 0, 0, 0, ray, payload);\n}\n\n"
  },
  {
    "path": "shaders/stages/raymiss.rmiss",
    "content": "struct Payload\n{\n\tfloat4 color;\n};\n\n[shader(\"miss\")]\nvoid RayMiss(inout Payload payload)\n{\n\tpayload.color = float4(1.0, 2.0, 3.0, 4.0);\n}\n\n"
  },
  {
    "path": "shaders/stages/simple.dual-source-blending.frag",
    "content": "float4 c0;\nfloat4 c1;\n\nvoid main(out float4 o0 : SV_Target0, out float4 o1 : SV_Target1)\n{\n\to0 = c0;\n\to1 = c1;\n}\n"
  },
  {
    "path": "shaders/stages/simple.invariant.vert",
    "content": "float4 main(float4 a : A, float4 b : B, float4 c : C) : SV_Position\n{\n\treturn mad(a, b, c);\n}\n"
  },
  {
    "path": "shaders/stages/stage-input-output.16bit-io.frag",
    "content": "struct StageIn\n{\n\thalf2 a : A;\n\tint16_t2 b : B;\n\tuint16_t c : C;\n};\n\nstruct StageOut\n{\n\thalf2 a : SV_Target0;\n\tint16_t2 b : SV_Target1;\n\tuint16_t c : SV_Target2;\n};\n\nStageOut main(StageIn inputs)\n{\n\tStageOut outputs;\n\toutputs.a = inputs.a * half(8.0);\n\toutputs.b = inputs.b * int16_t(-8);\n\toutputs.c = inputs.c * uint16_t(4);\n\treturn outputs;\n}\n"
  },
  {
    "path": "shaders/stages/stage-input-output.frag",
    "content": "struct StageIn\n{\n\thalf2 a : A;\n\tint16_t2 b : B;\n\tuint16_t c : C;\n};\n\nstruct StageOut\n{\n\thalf2 a : SV_Target0;\n\tint16_t2 b : SV_Target1;\n\tuint16_t c : SV_Target2;\n};\n\nStageOut main(StageIn inputs)\n{\n\tStageOut outputs;\n\toutputs.a = inputs.a * half(8.0);\n\toutputs.b = inputs.b * int16_t(-8);\n\toutputs.c = inputs.c * uint16_t(4);\n\treturn outputs;\n}\n"
  },
  {
    "path": "shaders/stages/stream-out.stream-out.vert",
    "content": "struct VSOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat4 s0 : StreamOut0;\n\tfloat4 s1 : StreamOut1;\n};\n\nVSOut main()\n{\n\tVSOut vout;\n\tvout.pos = 2.0.xxxx;\n\tvout.s0 = 4.0.xxxx;\n\tvout.s1 = 6.0.xxxx;\n\treturn vout;\n}\n"
  },
  {
    "path": "shaders/stages/swizzle.rt-swizzle.frag",
    "content": "struct PixelOut\n{\n\tfloat4 a : SV_Target0;\n\tfloat4 b : SV_Target1;\n};\n\nPixelOut main(float4 v : TEXCOORD)\n{\n\tPixelOut pout;\n\tpout.a = v;\n\tpout.b = v;\n\treturn pout;\n}\n"
  },
  {
    "path": "shaders/stages/task-basic.task",
    "content": "struct Payload\n{\n\tfloat4 p[64];\n};\n\ngroupshared Payload p;\n\n[numthreads(64, 1, 1)]\nvoid main(uint tid : SV_GroupIndex)\n{\n\tp.p[tid] = float(tid).xxxx;\n\tDispatchMesh(2, 3, 4, p);\n}\n"
  },
  {
    "path": "shaders/stages/vertex-array-input.vert",
    "content": "struct VSIn\n{\n\tfloat4 v4[4] : ATTR0;\n\tfloat v1[4] : ATTR4;\n};\n\nfloat4 main(VSIn v) : SV_Position\n{\n\treturn (v.v4[0] + v.v4[3]) + (v.v1[1] + v.v1[2]);\n};\n"
  },
  {
    "path": "shaders/stages/vertex-array-output.vert",
    "content": "struct VSOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat4 v4[4] : ATTR0;\n\tfloat v1[4] : ATTR4;\n};\n\nVSOut main(float4 v : POSITION)\n{\n\tVSOut vout;\n\tvout.pos = v;\n\tvout.v4[0] = v;\n\tvout.v4[1] = v + 1.0;\n\tvout.v4[2] = v + 2.0;\n\tvout.v4[3] = v + 3.0;\n\tvout.v1[0] = v.x;\n\tvout.v1[1] = v.y;\n\tvout.v1[2] = v.z;\n\tvout.v1[3] = v.w;\n\treturn vout;\n}\n"
  },
  {
    "path": "shaders/stages/vertex-input-remapping.vert",
    "content": "float4 main(float4 a : ATTR2, float b : ATTR4) : SV_Position\n{\n\treturn a + b;\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-byte-address.ssbo.comp",
    "content": "RWByteAddressBuffer RO : register(u0);\nRWByteAddressBuffer RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint lid : SV_GroupIndex)\n{\n\tuint addr = 96 * (thr + lid) + 96;\n\tRW.Store<double4>(addr, RO.Load<double4>(addr));\n\tRW.Store<double3>(addr, RO.Load<double3>(addr));\n\tRW.Store<double2>(addr, RO.Load<double2>(addr));\n\tRW.Store<double>(addr, RO.Load<double>(addr));\n\n\tRW.Store<float4>(addr, RO.Load<float4>(addr));\n\tRW.Store<float3>(addr, RO.Load<float3>(addr));\n\tRW.Store<float2>(addr, RO.Load<float2>(addr));\n\tRW.Store<float>(addr, RO.Load<float>(addr));\n\n\tRW.Store<half4>(addr, RO.Load<half4>(addr));\n\tRW.Store<half3>(addr, RO.Load<half3>(addr));\n\tRW.Store<half2>(addr, RO.Load<half2>(addr));\n\tRW.Store<half>(addr, RO.Load<half>(addr));\n\n\taddr = 96 * 2;\n\tRW.Store<double4>(addr, RO.Load<double4>(addr));\n\tRW.Store<float4>(addr, RO.Load<float4>(addr));\n\tRW.Store<half4>(addr, RO.Load<half4>(addr));\n\n\taddr = 96 * 2 * thr;\n\tRW.Store<double4>(addr, RO.Load<double4>(addr));\n\tRW.Store<float4>(addr, RO.Load<float4>(addr));\n\tRW.Store<half4>(addr, RO.Load<half4>(addr));\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-composite-2.ssbo.comp",
    "content": "RWStructuredBuffer<float4[4]> RO : register(u0);\nRWStructuredBuffer<float4[4]> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID, uint lid : SV_GroupIndex)\n{\n\tRW[thr][lid + 0] = RO[thr][lid + 1];\n\tRW[thr][lid + 1] = RO[thr][lid];\n\tRW[thr][2 * lid + 1] = RO[thr][3 * lid - 1];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-composite.ssbo.comp",
    "content": "struct Foo\n{\n\tfloat3 a;\n\tfloat3 b;\n};\nRWStructuredBuffer<Foo> RO : register(u0);\nRWStructuredBuffer<Foo> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr].a = RO[thr].a;\n\tRW[thr].b = RO[thr].b;\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-composite.ssbo.ssbo-align.bindless.comp",
    "content": "struct Foo\n{\n\tfloat3 a;\n\tfloat3 b;\n};\nRWStructuredBuffer<Foo> RO : register(u0);\nRWStructuredBuffer<Foo> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr].a = RO[thr].a;\n\tRW[thr].b = RO[thr].b;\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-double2.ssbo.comp",
    "content": "RWStructuredBuffer<double2> RO : register(u0);\nRWStructuredBuffer<double2> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-double2.ssbo.ssbo-align.bindless.comp",
    "content": "RWStructuredBuffer<double2> RO : register(u0);\nRWStructuredBuffer<double2> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-double3.ssbo.comp",
    "content": "RWStructuredBuffer<double3> RO : register(u0);\nRWStructuredBuffer<double3> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-double3.ssbo.ssbo-align.bindless.comp",
    "content": "RWStructuredBuffer<double3> RO : register(u0);\nRWStructuredBuffer<double3> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-double4.ssbo.comp",
    "content": "RWStructuredBuffer<double4> RO : register(u0);\nRWStructuredBuffer<double4> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-float2.ssbo.comp",
    "content": "RWStructuredBuffer<float2> RO : register(u0);\nRWStructuredBuffer<float2> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-float2.ssbo.ssbo-align.bindless.comp",
    "content": "RWStructuredBuffer<float2> RO : register(u0);\nRWStructuredBuffer<float2> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-float2x2.ssbo.comp",
    "content": "RWStructuredBuffer<float2x2> RO : register(u0);\nRWStructuredBuffer<float2x2> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-float3.ssbo.comp",
    "content": "RWStructuredBuffer<float3> RO : register(u0);\nRWStructuredBuffer<float3> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-float3.ssbo.ssbo-align.bindless.comp",
    "content": "RWStructuredBuffer<float3> RO : register(u0);\nRWStructuredBuffer<float3> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-float4x4.ssbo.comp",
    "content": "RWStructuredBuffer<float4x4> RO : register(u0);\nRWStructuredBuffer<float4x4> RW : register(u1);\n\n[numthreads(128, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-half2.ssbo.comp",
    "content": "RWStructuredBuffer<half2> RO : register(u0);\nRWStructuredBuffer<half2> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-half2.ssbo.ssbo-align.bindless.comp",
    "content": "RWStructuredBuffer<half2> RO : register(u0);\nRWStructuredBuffer<half2> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-half3.ssbo.comp",
    "content": "RWStructuredBuffer<half3> RO : register(u0);\nRWStructuredBuffer<half3> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-half3.ssbo.ssbo-align.bindless.comp",
    "content": "RWStructuredBuffer<half3> RO : register(u0);\nRWStructuredBuffer<half3> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-half4.ssbo.comp",
    "content": "RWStructuredBuffer<half4> RO : register(u0);\nRWStructuredBuffer<half4> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/vectorization/copy-half4.ssbo.ssbo-align.bindless.comp",
    "content": "RWStructuredBuffer<half4> RO : register(u0);\nRWStructuredBuffer<half4> RW : register(u1);\n\n[numthreads(2, 1, 1)]\nvoid main(uint thr : SV_DispatchThreadID)\n{\n\tRW[thr] = RO[thr];\n}\n"
  },
  {
    "path": "shaders/view-instancing/geom/basic.view-instancing.last-pre-raster.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(1)]\nvoid main(triangle Inputs input[3], inout PointStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/view-instancing/geom/basic.view-instancing.last-pre-raster.view-instance-mask.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(1)]\nvoid main(triangle Inputs input[3], inout PointStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/view-instancing/geom/basic.view-instancing.view-instancing-multiview.last-pre-raster.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(2)]\nvoid main(triangle Inputs input[3], inout PointStream<Outputs> o, uint vid : SV_ViewID)\n{\n\tOutputs res;\n\tres.a = input[0].a + float(vid);\n\tres.pos = input[1].pos;\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/view-instancing/geom/basic.view-instancing.view-instancing-multiview.view-instancing-viewport-offset.last-pre-raster.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(2)]\nvoid main(triangle Inputs input[3], inout PointStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/view-instancing/geom/basic.view-instancing.view-instancing-viewport-offset.last-pre-raster.geom",
    "content": "struct Inputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\nstruct Outputs\n{\n\tfloat4 a : TEXCOORD;\n\tfloat4 pos : SV_Position;\n};\n\n[maxvertexcount(2)]\nvoid main(triangle Inputs input[3], inout PointStream<Outputs> o)\n{\n\tOutputs res;\n\tres.a = input[0].a;\n\tres.pos = input[1].pos;\n\to.Append(res);\n\to.Append(res);\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic-export-viewport-layer.view-instancing.last-pre-raster.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\nstruct PrimOut\n{\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8], out primitives PrimOut prims[8], uint vid : SV_ViewID)\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t\tprims[tid].layer = vid;\n\t\tprims[tid].vp = vid + 1;\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic-export-viewport-layer.view-instancing.last-pre-raster.view-instancing-viewport-offset.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\nstruct PrimOut\n{\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8], out primitives PrimOut prims[8], uint vid : SV_ViewID)\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t\tprims[tid].layer = vid;\n\t\tprims[tid].vp = vid + 1;\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic-few-thread.view-instancing.last-pre-raster.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\n[numthreads(2, 3, 1)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8])\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic-many-thread.view-instancing.last-pre-raster.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\n[numthreads(2, 3, 6)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8])\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic.view-instancing.last-pre-raster.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8])\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic.view-instancing.last-pre-raster.view-instance-mask.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8])\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic.view-instancing.last-pre-raster.view-instancing-viewport-offset.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8])\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/mesh/basic.view-instancing.mesh",
    "content": "struct VOut\n{\n\tfloat4 pos : SV_Position;\n\tfloat b : B;\n};\n\n[numthreads(2, 3, 4)]\n[outputtopology(\"triangle\")]\nvoid main(uint tid : SV_GroupIndex,\n\t\tout vertices VOut vout[24],\n\t\tout indices uint3 ind[8], uint vid : SV_ViewID)\n{\n\tSetMeshOutputCounts(24, 8);\n\tvout[tid].pos = float(tid + vid).xxxx;\n\tvout[tid].b = float(tid ^ 1);\n\n\tif (tid < 8)\n\t{\n\t\tind[tid] = 3 * tid + uint3(0, 1, 2);\n\t}\n}\n"
  },
  {
    "path": "shaders/view-instancing/tesc/basic.view-instancing.tesc",
    "content": "struct VSControlPoint\n{\n\tfloat value : VSValue;\n};\n\nstruct HSControlPoint\n{\n\tfloat value : HSValue;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[4] : SV_TessFactor;\n\tfloat inner[2] : SV_InsideTessFactor;\n};\n\n[domain(\"quad\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_cw\")]\n[outputcontrolpoints(4)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<VSControlPoint, 1> ip, uint control : SV_OutputControlPointID, uint vid : SV_ViewID)\n{\n\tHSControlPoint cp;\n\tcp.value = float(control + vid);\n\tcp.layer = vid;\n\tcp.vp = vid;\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 4> op, InputPatch<VSControlPoint, 1> ip)\n{\n\tPatchConstant pc;\n\tpc.inner[0] = 1.0;\n\tpc.inner[1] = 1.0;\n\tpc.outer[0] = 1.0;\n\tpc.outer[1] = 1.0;\n\tpc.outer[2] = 1.0;\n\tpc.outer[3] = 1.0;\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/view-instancing/tesc/basic.view-instancing.view-instancing-multiview.tesc",
    "content": "struct VSControlPoint\n{\n\tfloat value : VSValue;\n};\n\nstruct HSControlPoint\n{\n\tfloat value : HSValue;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[4] : SV_TessFactor;\n\tfloat inner[2] : SV_InsideTessFactor;\n};\n\n[domain(\"quad\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_cw\")]\n[outputcontrolpoints(4)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<VSControlPoint, 1> ip, uint control : SV_OutputControlPointID, uint vid : SV_ViewID)\n{\n\tHSControlPoint cp;\n\tcp.value = float(control + vid);\n\tcp.layer = vid;\n\tcp.vp = vid;\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 4> op, InputPatch<VSControlPoint, 1> ip)\n{\n\tPatchConstant pc;\n\tpc.inner[0] = 1.0;\n\tpc.inner[1] = 1.0;\n\tpc.outer[0] = 1.0;\n\tpc.outer[1] = 1.0;\n\tpc.outer[2] = 1.0;\n\tpc.outer[3] = 1.0;\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain-export-layer-viewport.view-instancing.view-instancing-multiview.last-pre-raster.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\nstruct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\n[domain(\"tri\")]\nOutput main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\to.pos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\to.layer = vid;\n\to.vp = vid + 1;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain-export-layer-viewport.view-instancing.view-instancing-multiview.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\nstruct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\n[domain(\"tri\")]\nOutput main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\to.pos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\to.layer = vid;\n\to.vp = vid + 1;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain.view-instancing.last-pre-raster.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID) : SV_Position\n{\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\treturn float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain.view-instancing.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID) : SV_Position\n{\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\treturn float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain.view-instancing.view-instancing-multiview.last-pre-raster.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID) : SV_Position\n{\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\treturn float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain.view-instancing.view-instancing-multiview.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID) : SV_Position\n{\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\treturn float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain.view-instancing.view-instancing-viewport-offset.last-pre-raster.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID) : SV_Position\n{\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\treturn float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n}\n"
  },
  {
    "path": "shaders/view-instancing/tese/domain.view-instancing.view-instancing-viewport-offset.tese",
    "content": "struct Foo\n{\n\tfloat a[3] : A;\n\tfloat b : B;\n};\n\nstruct Patch\n{\n\tfloat c[3] : C;\n\tfloat d : D;\n};\n\n[domain(\"tri\")]\nfloat4 main(OutputPatch<Foo, 3> op, Patch p, float3 Coord : SV_DomainLocation, uint vid : SV_ViewID) : SV_Position\n{\n\tfloat pos = op[0].b * Coord.x + op[1].b * Coord.y + op[2].b * Coord.z + float(vid);\n\tpos += op[0].a[2] * Coord.x + op[1].a[1] * Coord.y + op[2].a[0] * Coord.z;\n\treturn float4(pos, p.c[0] + p.c[1], p.c[2], p.d);\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.last-pre-raster.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.view-instancing-multiview.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer-viewport.view-instancing-viewport-offset.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer.last-pre-raster.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer.view-instancing-multiview.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-layer.view-instancing-viewport-offset.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint layer : SV_RenderTargetArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint layer : LAYER)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.layer = layer;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-viewport.last-pre-raster.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-viewport.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-viewport.view-instancing-multiview.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.export-viewport.view-instancing-viewport-offset.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n\tuint vp : SV_ViewportArrayIndex;\n};\n\nOutput main(uint vid : SV_ViewID, uint vp : VP)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\to.vp = vp;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.last-pre-raster.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n};\n\nOutput main(uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n};\n\nOutput main(uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.view-instance-mask.last-pre-raster.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n};\n\nOutput main(uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.view-instance-mask.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n};\n\nOutput main(uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.view-instancing-multiview.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n};\n\nOutput main(uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/view-instancing/vert/basic.view-instancing.view-instancing-viewport-offset.vert",
    "content": "struct Output\n{\n\tfloat4 pos : SV_Position;\n};\n\nOutput main(uint vid : SV_ViewID)\n{\n\tOutput o;\n\to.pos = float(vid).xxxx;\n\treturn o;\n}\n"
  },
  {
    "path": "shaders/vkmm/coopmat.sm66.ssbo.vkmm.comp",
    "content": "RWByteAddressBuffer Outputs : register(u0);\nByteAddressBuffer Inputs : register(t0);\nRWByteAddressBuffer MAGIC : register(u0, space2147420894);\n\n#include \"wmma_ags.h\"\n\n[numthreads(32, 1, 1)]\n[WaveSize(32)]\nvoid main(uint thr : SV_GroupIndex, uint gid : SV_GroupID)\n{\n\tWMMA_Type TypeA = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_A, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeB = WMMA_MakeType(WaveMatrixDataFormat_FP8, WaveMatrixType_B, WaveMatrixShape_16X16, false);\n\tWMMA_Type TypeC = WMMA_MakeType(WaveMatrixDataFormat_F32, WaveMatrixType_Accumulator, WaveMatrixShape_16X16, false);\n\n\tWMMA_Matrix A = WMMA_Load(TypeA, Inputs, 0, 16);\n\tWMMA_Matrix B = WMMA_Load(TypeB, Inputs, 256, 16);\n\tWMMA_Matrix C = WMMA_Load(TypeC, Inputs, 512, 64);\n\n\tC = WMMA_MatMulAcc(WMMA_F32_16X16X16_FP8_FP8, A, B, C);\n\tWMMA_Store(TypeC, Outputs, 0, 64, C);\n}\n"
  },
  {
    "path": "shaders/vkmm/cross_group_sharing.vkmm.node.inline-ubo.comp",
    "content": "RWStructuredBuffer<uint> RWBuf0 : register(u0);\n\nstruct [NodeTrackRWInputSharing] SharedPayload\n{\n\tuint grid : SV_DispatchGrid;\n\tuint num_atomics;\n};\n\n[Shader(\"node\")]\n[NodeLaunch(\"broadcasting\")]\n[NumThreads(64, 1, 1)]\n[NodeMaxDispatchGrid(1024, 1, 1)]\n[NodeID(\"Broadcast\", 0)]\nvoid main(globallycoherent RWDispatchNodeInputRecord<SharedPayload> payload, uint thr : SV_GroupIndex)\n{\n\tuint o;\n\tInterlockedAdd(payload.Get().num_atomics, 1, o);\n\tpayload.Get().num_atomics += 3;\n\tBarrier(payload, GROUP_SYNC | GROUP_SCOPE | DEVICE_SCOPE);\n\t// Spec seems to imply we need to have a barrier outselves. WARP fails if we don't.\n\tif (payload.FinishedCrossGroupSharing())\n\t{\n\t\tInterlockedAdd(RWBuf0[thr], payload.Get().num_atomics, o);\n\t}\n}\n\n"
  },
  {
    "path": "shaders/vkmm/descriptor_qa.bindless.descriptor-qa.vkmm.comp",
    "content": "struct C { float v; };\nConstantBuffer<C> c : register(b0, space0);\nConstantBuffer<C> carr[2] : register(b1, space0);\n\nTexture2D<float> tex : register(t0, space0);\nTexture2D<float> texarr[2] : register(t1, space0);\nBuffer<float> typedbuf : register(t3, space0);\nBuffer<float> typedbufarr[2] : register(t4, space0);\nStructuredBuffer<float> buf : register(t6, space0);\nStructuredBuffer<float> bufarr[2] : register(t7, space0);\nByteAddressBuffer rawbuf : register(t9, space0);\nByteAddressBuffer rawbufarr[2] : register(t10, space0);\n\nRWStructuredBuffer<float> rwbuf : register(u0, space0);\nRWStructuredBuffer<float> rwbufarr[2] : register(u1, space0);\nRWByteAddressBuffer rwrawbuf : register(u3, space0);\nRWByteAddressBuffer rwrawbufarr[2] : register(u4, space0);\nRWTexture2D<float> rwtex : register(u6, space0);\nRWTexture2D<float> rwtexarr[2] : register(u7, space0);\nRWBuffer<float> rwtypedbuf : register(u9, space0);\nRWBuffer<float> rwtypedbufarr[2] : register(u10, space0);\n\nSamplerState samp : register(s0, space0);\n\n[numthreads(1, 1, 1)]\nvoid main(uint index : SV_DispatchThreadID)\n{\n\tfloat value = 0.0;\n\tif (index > 2)\n\t\tvalue += c.v;\n\tif (index > 3)\n\t\tvalue += carr[index].v;\n\tif (index > 4)\n\t\tvalue += tex.SampleLevel(samp, float2(0.5, 0.5), 0.0);\n\tif (index > 5)\n\t\tvalue += texarr[index & 1][int2(0, index)];\n\tif (index > 6)\n\t\tvalue += typedbuf[index];\n\tif (index > 7)\n\t\tvalue += typedbufarr[index & 1][index];\n\tif (index > 8)\n\t\tvalue += buf[index];\n\tif (index > 9)\n\t\tvalue += bufarr[index & 1][index];\n\tif (index > 10)\n\t\tvalue += asfloat(rawbuf.Load(4 * index));\n\tif (index > 11)\n\t\tvalue += asfloat(rawbufarr[index & 1].Load(index));\n\n\tif (index > 1)\n\t\trwbuf[index] = value;\n\tif (index > 30)\n\t\trwbufarr[index & 1][index] = value;\n\tif (index > 40)\n\t\trwrawbuf.Store(4 * index, asuint(value));\n\tif (index > 50)\n\t\trwrawbufarr[index & 1].Store(4 * index, asuint(value));\n\tif (index > 80)\n\t\trwtex[int2(index, 0)] = value;\n\tif (index > 90)\n\t\trwtexarr[index & 1][int2(0, index)] = value;\n\n\trwbuf.IncrementCounter();\n}\n"
  },
  {
    "path": "shaders/vkmm/groupshared.vkmm.comp",
    "content": "groupshared uint blah[64];\nRWStructuredBuffer<uint> B;\n\n[numthreads(64, 1, 1)]\nvoid main(uint thr : SV_GroupIndex)\n{\n\tblah[thr] = thr;\n\tGroupMemoryBarrierWithGroupSync();\n\tB[thr] = blah[thr ^ 3];\n}\n"
  },
  {
    "path": "shaders/vkmm/hull.vkmm.tesc",
    "content": "struct VSControlPoint\n{\n\tfloat value : VSValue;\n};\n\nstruct HSControlPoint\n{\n\tfloat value : HSValue;\n};\n\nstruct PatchConstant\n{\n\tfloat outer[4] : SV_TessFactor;\n\tfloat inner[2] : SV_InsideTessFactor;\n\tfloat patch : PATCH;\n};\n\ncbuffer Cbuf : register(b0)\n{\n\tfloat global_constant;\n};\n\n[domain(\"quad\")]\n[partitioning(\"integer\")]\n[outputtopology(\"triangle_cw\")]\n[outputcontrolpoints(4)]\n[patchconstantfunc(\"main_patch\")]\nHSControlPoint main(InputPatch<VSControlPoint, 5> ip, uint control : SV_OutputControlPointID)\n{\n\t// Test that alloca gets directly appropriately.\n\tfloat4 v;\n\tv.x = ip[0].value;\n\tv.y = ip[1].value;\n\tv.z = ip[2].value;\n\tv.w = ip[3].value;\n\tv[int(ip[0].value)] += 40.0;\n\n\tHSControlPoint cp;\n\tcp.value = ip[0].value + ip[1].value + ip[2].value + v[3] + float(control);\n\treturn cp;\n}\n\nPatchConstant main_patch(OutputPatch<HSControlPoint, 4> op, InputPatch<VSControlPoint, 5> ip)\n{\n\t// Test that alloca gets directly appropriately.\n\tfloat4 v;\n\tv.x = ip[0].value;\n\tv.y = ip[1].value;\n\tv.z = ip[2].value;\n\tv.w = ip[3].value;\n\tv[int(ip[0].value)] += 40.0;\n\n\tPatchConstant pc;\n\tpc.inner[0] = op[0].value;\n\tpc.inner[1] = op[1].value;\n\tpc.outer[0] = ip[0].value;\n\tpc.outer[1] = ip[1].value;\n\tpc.outer[2] = ip[2].value;\n\tpc.outer[3] = ip[0].value + op[0].value;\n\tpc.patch = v[3] + global_constant;\n\treturn pc;\n}\n"
  },
  {
    "path": "shaders/vkmm/image-load-store.vkmm.comp",
    "content": "globallycoherent RWTexture2D<float> RWImgCoherent : register(u0);\nRWTexture2D<float> RWImg : register(u1);\nTexture2D<float> Img : register(t0);\n\n[numthreads(8, 8, 1)]\nvoid main(uint2 thr : SV_DispatchThreadID)\n{\n\tRWImgCoherent[thr] += 1.0;\n\tRWImg[thr] += Img.Load(int3(thr, 0));\n}\n"
  },
  {
    "path": "shaders/vkmm/image-load-store.vkmm.sm66.comp",
    "content": "[numthreads(8, 8, 1)]\nvoid main(uint2 thr : SV_DispatchThreadID)\n{\n\tgloballycoherent RWTexture2D<float> RWImgCoherent = ResourceDescriptorHeap[0];\n\tRWTexture2D<float> RWImg  = ResourceDescriptorHeap[1];\n\tTexture2D<float> Img = ResourceDescriptorHeap[2];\n\n\tRWImgCoherent[thr] += 1.0;\n\tRWImg[thr] += Img.Load(int3(thr, 0));\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent-promotion.bindless.ssbo.vkmm.comp",
    "content": "RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent-promotion.root-descriptor.ssbo.vkmm.comp",
    "content": "RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent-promotion.sm66.bindless.ssbo.vkmm.comp",
    "content": "StructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\tRWStructuredBuffer<float4> RW = ResourceDescriptorHeap[0];\n\tRWStructuredBuffer<float4> RW_RDONLY = ResourceDescriptorHeap[1];\n\tRWStructuredBuffer<float4> RW_WRONLY = ResourceDescriptorHeap[2];\n\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent-promotion.sm66.ssbo.vkmm.comp",
    "content": "StructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\tRWStructuredBuffer<float4> RW = ResourceDescriptorHeap[0];\n\tRWStructuredBuffer<float4> RW_RDONLY = ResourceDescriptorHeap[1];\n\tRWStructuredBuffer<float4> RW_WRONLY = ResourceDescriptorHeap[2];\n\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent-promotion.ssbo.vkmm.comp",
    "content": "RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent.root-descriptor.ssbo.vkmm.comp",
    "content": "globallycoherent RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent.sm66.ssbo.vkmm.comp",
    "content": "StructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\tgloballycoherent RWStructuredBuffer<float4> RW = ResourceDescriptorHeap[0];\n\tRWStructuredBuffer<float4> RW_RDONLY = ResourceDescriptorHeap[1];\n\tRWStructuredBuffer<float4> RW_WRONLY = ResourceDescriptorHeap[2];\n\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/memory-model/uav-coherent.ssbo.vkmm.comp",
    "content": "globallycoherent RWStructuredBuffer<float4> RW : register(u0);\nRWStructuredBuffer<float4> RW_RDONLY : register(u1);\nRWStructuredBuffer<float4> RW_WRONLY : register(u2);\nStructuredBuffer<uint> WorkList : register(t0);\nStructuredBuffer<float4> RO : register(t1);\n\ncbuffer Constants : register(b0) { uint count; };\n\n[numthreads(256, 1, 1)]\nvoid main(uint id : SV_GroupIndex)\n{\n\t// Prime the L0 caches.\n\tRW[id] = 0.0.xxxx;\n\n\tfor (uint iter = 0; iter < count; iter++)\n\t{\n\t\tuint increment_offset = WorkList[256 * iter + id];\n\t\t// globallycoherent is not needed when sharing data between threads in the same group.\n\t\tDeviceMemoryBarrierWithGroupSync();\n\n\t\t// If caches are incoherent here in the workgroup, this will break hard.\n\t\tif (increment_offset < 256)\n\t\t\tRW[increment_offset] += RO[256 * iter + id];\n\t}\n\n\tRW_WRONLY[id] = RW_RDONLY[id];\n}\n"
  },
  {
    "path": "shaders/vkmm/report-hit.vkmm.rint",
    "content": "struct Payload\n{\n\tfloat p;\n};\n\n[shader(\"intersection\")]\nvoid RayIntersect()\n{\n\tPayload p;\n\tPayload p2;\n\tp.p = RayTCurrent();\n\tp2.p = RayTMin();\n\n\tReportHit(4.0, 100, p);\n\tReportHit(3.0, 50, p2);\n\n\tp2.p = WaveGetLaneIndex();\n\tReportHit(2.0, 50, p2);\n}\n"
  },
  {
    "path": "shaders/vkmm/rov-structured.vkmm.frag",
    "content": "RasterizerOrderedStructuredBuffer<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord.y * 1000 + coord.x] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/vkmm/rov-tex2d.vkmm.frag",
    "content": "RasterizerOrderedTexture2D<float4> RW : register(u0);\n\n[earlydepthstencil]\nvoid main(float4 pos : SV_Position)\n{\n\tuint2 coord = uint2(pos.xy);\n\tRW[coord] += float4(1.0, 2.0, 3.0, 4.0);\n}\n"
  },
  {
    "path": "shaders/vkmm/wmma_ags.h",
    "content": "#pragma once\n\nstatic const uint MagicCodeShift   = 28;\nstatic const uint MagicCodeMask    = 0xf;\nstatic const uint OpcodePhaseShift = 24;\nstatic const uint OpcodePhaseMask  = 0x3;\nstatic const uint DataShift        = 8;\nstatic const uint DataMask         = 0xffff;\nstatic const uint OpcodeShift      = 0;\nstatic const uint OpcodeMask       = 0xff;\n\nstatic const uint MagicCode = 0x5;\n\nstatic const uint WaveMatrixMulAcc            = 0x28;\nstatic const uint WaveMatrixUavLoad           = 0x29;\nstatic const uint WaveMatrixUavStore          = 0x2a;\nstatic const uint WaveMatrixGlobalLoad        = 0x2b;\nstatic const uint WaveMatrixGlobalStore       = 0x2c;\nstatic const uint WaveMatrixLdsLoad           = 0x2d;\nstatic const uint WaveMatrixLdsStore          = 0x2e;\nstatic const uint WaveMatrixElementFill       = 0x2f;\nstatic const uint WaveMatrixElementExtract    = 0x30;\nstatic const uint WaveMatrixLength            = 0x31;\nstatic const uint WaveMatrixCopy              = 0x32;\nstatic const uint WaveMatrixFill              = 0x33;\nstatic const uint Float8Conversion            = 0x36;\n\nenum WaveMatrixOpDataFormat\n{\n    WaveMatrixDataFormat_I4   = 0x0,\n    WaveMatrixDataFormat_U4   = 0x1,\n    WaveMatrixDataFormat_I8   = 0x2,\n    WaveMatrixDataFormat_U8   = 0x3,\n    WaveMatrixDataFormat_F16  = 0x4,\n    WaveMatrixDataFormat_BF16 = 0x5,\n    WaveMatrixDataFormat_F32  = 0x6,\n    WaveMatrixDataFormat_I32  = 0x7,\n    WaveMatrixDataFormat_U32  = 0x8,\n    WaveMatrixDataFormat_BF8  = 0x9,\n    WaveMatrixDataFormat_FP8  = 0xa,\n};\n\nenum WaveMatrixOpMatrixType\n{\n    WaveMatrixType_A            = 0x0,\n    WaveMatrixType_B            = 0x1,\n    WaveMatrixType_Accumulator  = 0x2,\n};\n\nenum WaveMatrixOpMatrixShape\n{\n    WaveMatrixShape_16X16 = 0x0,\n    WaveMatrixShape_32X16 = 0x1,\n    WaveMatrixShape_16X32 = 0x2,\n    WaveMatrixShape_64X16 = 0x3,\n};\n\nenum WaveMatrixOpcode\n{\n    WMMA_BF16_16X16X16_BF16     = 0x0,\n    WMMA_F16_16X16X16_F16       = 0x1,\n    WMMA_F32_16X16X16_BF16      = 0x2,\n    WMMA_F32_16X16X16_BF8_BF8   = 0x3,\n    WMMA_F32_16X16X16_BF8_FP8   = 0x4,\n    WMMA_F32_16X16X16_F16       = 0x5,\n    WMMA_F32_16X16X16_FP8_BF8   = 0x6,\n    WMMA_F32_16X16X16_FP8_FP8   = 0x7,\n    WMMA_I32_16X16X16_I4        = 0x8,\n    WMMA_I32_16X16X16_U4        = 0x9,\n    WMMA_I32_16X16X16_IU4       = 0xa,\n    WMMA_I32_16X16X16_UI4       = 0xb,\n    WMMA_I32_16X16X16_I8        = 0xc,\n    WMMA_I32_16X16X16_U8        = 0xd,\n    WMMA_I32_16X16X16_IU8       = 0xe,\n    WMMA_I32_16X16X16_UI8       = 0xf,\n    WMMA_I32_16X16X32_I4        = 0x10,\n    WMMA_I32_16X16X32_U4        = 0x11,\n    WMMA_I32_16X16X32_IU4       = 0x12,\n    WMMA_I32_16X16X32_UI4       = 0x13,\n    SWMMA_BF16_16X16X32_BF16    = 0x14,\n    SWMMA_F16_16X16X32_F16      = 0x15,\n    SWMMA_F32_16X16X32_BF16     = 0x16,\n    SWMMA_F32_16X16X32_BF8_BF8  = 0x17,\n    SWMMA_F32_16X16X32_BF8_FP8  = 0x18,\n    SWMMA_F32_16X16X32_F16      = 0x19,\n    SWMMA_F32_16X16X32_FP8_BF8  = 0x1a,\n    SWMMA_F32_16X16X32_FP8_FP8  = 0x1b,\n    SWMMA_I32_16X16X32_I4       = 0x1c,\n    SWMMA_I32_16X16X32_U4       = 0x1d,\n    SWMMA_I32_16X16X32_IU4      = 0x1e,\n    SWMMA_I32_16X16X32_UI4      = 0x1f,\n    SWMMA_I32_16X16X32_I8       = 0x20,\n    SWMMA_I32_16X16X32_U8       = 0x21,\n    SWMMA_I32_16X16X32_IU8      = 0x22,\n    SWMMA_I32_16X16X32_UI8      = 0x23,\n    SWMMA_I32_16X16X64_I4       = 0x24,\n    SWMMA_I32_16X16X64_U4       = 0x25,\n    SWMMA_I32_16X16X64_IU4      = 0x26,\n    SWMMA_I32_16X16X64_UI4      = 0x27,\n};\n\nenum WaveMatrixRegType\n{\n    WaveMatrixRegType_RetVal_Reg          = 0x0,\n    WaveMatrixRegType_A_TempReg           = 0x1,\n    WaveMatrixRegType_B_TempReg           = 0x2,\n    WaveMatrixRegType_Accumulator_TempReg = 0x3,\n};\n\nenum MatrixElementWiseOp\n{\n    MatrixElementWiseOp_Add   = 0x1,\n    MatrixElementWiseOp_Sub   = 0x2,\n    MatrixElementWiseOp_Mul   = 0x3,\n    MatrixElementWiseOp_Div   = 0x4,\n    MatrixElementWiseOp_Times = 0x5,\n};\n\nenum SparsityIndexMem\n{\n    SparsityIndexMem_UavBuffer    = 0x0,\n    SparsityIndexMem_GroupShared  = 0x1,\n    SparsityIndexMem_GlobalBuffer = 0x2,\n};\n\nstatic const uint WaveMatrixOpcode_OpsShift  = 0;\nstatic const uint WaveMatrixOpcode_OpsMask   = 0x7f;\nstatic const uint WaveMatrixOpcode_FlagShift = 15;\nstatic const uint WaveMatrixOpcode_FlagMask  = 0x1;\n\nstatic const uint WaveMatrixInOut_ChannelShift        = 0;\nstatic const uint WaveMatrixInOut_ChannelMask         = 0xf;\nstatic const uint WaveMatrixInOut_SecondRegFlagShift  = 4;\nstatic const uint WaveMatrixInOut_SecondRegFlagMask   = 0xf;\nstatic const uint WaveMatrixInOut_MatRegTypeFlagShift = 8;\nstatic const uint WaveMatrixInOut_MatRegTypeFlagMask  = 0xff;\n\nstatic const uint WaveMatrixModifier_DataFormatFlagShift = 0;\nstatic const uint WaveMatrixModifier_DataFormatFlagMask  = 0xf;\nstatic const uint WaveMatrixModifier_MatrixTypeFlagShift = 4;\nstatic const uint WaveMatrixModifier_MatrixTypeFlagMask  = 0x7;\nstatic const uint WaveMatrixModifier_LayoutFlagShift     = 7;\nstatic const uint WaveMatrixModifier_LayoutFlagMask      = 0x1;\nstatic const uint WaveMatrixModifier_ShapeShift          = 8;\nstatic const uint WaveMatrixModifier_ShapeMask           = 0x7;\nstatic const uint WaveMatrixModifier_MatrixTileShift     = 11;\nstatic const uint WaveMatrixModifier_MatrixTileMask      = 0x1;\nstatic const uint WaveMatrixModifier_IndexMemTypeShift   = 14;\nstatic const uint WaveMatrixModifier_IndexMemTypeMask    = 0x3;\n\n// For wave32 and FP32, we need up to 8 values to store a 16x16 matrix.\nstruct WMMA_Matrix\n{\n\tuint v[8];\n};\n\nuint Code(uint opcode, uint opcodePhase, uint immediateData)\n{\n    return (MagicCode << MagicCodeShift) |\n           ((immediateData & DataMask) << DataShift) |\n           ((opcodePhase & OpcodePhaseMask) << OpcodePhaseShift) |\n           ((opcode & OpcodeMask) << OpcodeShift);\n}\n\nuint AGSMagic(uint code, uint arg0, uint arg1)\n{\n\tuint ret;\n\tMAGIC.InterlockedCompareExchange(code, arg0, arg1, ret);\n\treturn ret;\n}\n\nuint AGSMagic(uint opcode, uint phase, uint imm, uint arg0, uint arg1)\n{\n\treturn AGSMagic(Code(opcode, phase, imm), arg0, arg1);\n}\n\nuint MatrixIO(uint channel, uint reg, uint type)\n{\n\treturn (channel << WaveMatrixInOut_ChannelShift) |\n\t\t(reg << WaveMatrixInOut_SecondRegFlagShift) |\n\t\t(type << WaveMatrixInOut_MatRegTypeFlagShift);\n}\n\nWMMA_Matrix WMMA_MatMulAcc(WaveMatrixOpcode op, WMMA_Matrix A, WMMA_Matrix B, WMMA_Matrix C)\n{\n\t// A matrix\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 0, WaveMatrixRegType_A_TempReg), A.v[0], A.v[1]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 0, WaveMatrixRegType_A_TempReg), A.v[2], A.v[3]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 1, WaveMatrixRegType_A_TempReg), A.v[4], A.v[5]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 1, WaveMatrixRegType_A_TempReg), A.v[6], A.v[7]);\n\n\t// B matrix\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 0, WaveMatrixRegType_B_TempReg), B.v[0], B.v[1]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 0, WaveMatrixRegType_B_TempReg), B.v[2], B.v[3]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 1, WaveMatrixRegType_B_TempReg), B.v[4], B.v[5]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 1, WaveMatrixRegType_B_TempReg), B.v[6], B.v[7]);\n\n\t// C matrix\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 0, WaveMatrixRegType_Accumulator_TempReg), C.v[0], C.v[1]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 0, WaveMatrixRegType_Accumulator_TempReg), C.v[2], C.v[3]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(0, 1, WaveMatrixRegType_Accumulator_TempReg), C.v[4], C.v[5]);\n\tAGSMagic(WaveMatrixMulAcc, 0, MatrixIO(1, 1, WaveMatrixRegType_Accumulator_TempReg), C.v[6], C.v[7]);\n\n\t// Configure type\n\tAGSMagic(WaveMatrixMulAcc, 1, int(op) << int(WaveMatrixOpcode_OpsShift), 0, 0);\n\n\t// Read output\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixMulAcc, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nstruct WMMA_Type\n{\n\tuint code;\n};\n\nWMMA_Type WMMA_MakeType(WaveMatrixOpDataFormat fmt, WaveMatrixOpMatrixType mtype, WaveMatrixOpMatrixShape shape, bool transposed)\n{\n\tWMMA_Type type;\n\ttype.code = (int(fmt) << WaveMatrixModifier_DataFormatFlagShift) |\n\t\t(int(mtype) << WaveMatrixModifier_MatrixTypeFlagShift) |\n\t\t(int(shape) << WaveMatrixModifier_ShapeShift) |\n\t\t(transposed << WaveMatrixModifier_LayoutFlagShift);\n\treturn type;\n}\n\nWMMA_Matrix WMMA_Load(WMMA_Type type, ByteAddressBuffer BAB, uint offset, uint stride)\n{\n\tuint doorbell = AGSMagic(WaveMatrixUavLoad, 0, 0, offset, stride);\n\tuint hook = BAB.Load(doorbell);\n\tAGSMagic(WaveMatrixUavLoad, 1, type.code, hook, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nWMMA_Matrix WMMA_Load(WMMA_Type type, RWByteAddressBuffer BAB, uint offset, uint stride)\n{\n\tuint doorbell = AGSMagic(WaveMatrixUavLoad, 0, 0, offset, stride);\n\tuint hook = BAB.Load(doorbell);\n\tAGSMagic(WaveMatrixUavLoad, 1, type.code, hook, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixUavLoad, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nvoid WMMA_Store(WMMA_Type type, RWByteAddressBuffer BAB, uint offset, uint stride, WMMA_Matrix m)\n{\n\tuint doorbell = AGSMagic(WaveMatrixUavStore, 0, 0, offset, stride);\n\tuint hook = BAB.Load(doorbell);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixUavStore, 1, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixUavStore, 2, type.code, hook, 0);\n}\n\ngroupshared uint LDS[512];\n\nWMMA_Matrix WMMA_LoadLDS(WMMA_Type type, uint offset, uint stride)\n{\n\tuint hook;\n\tuint doorbell = AGSMagic(WaveMatrixLdsLoad, 0, 0, offset, stride);\n\tInterlockedAdd(LDS[doorbell], 0, hook);\n\tAGSMagic(WaveMatrixLdsLoad, 1, type.code, hook, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixLdsLoad, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nvoid WMMA_StoreLDS(WMMA_Type type, uint offset, uint stride, WMMA_Matrix m)\n{\n\tuint doorbell = AGSMagic(WaveMatrixLdsStore, 0, 0, offset, stride);\n\tuint hook;\n\tInterlockedAdd(LDS[doorbell], 0, hook);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixLdsStore, 1, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixLdsStore, 2, type.code, hook, 0);\n}\n\nWMMA_Matrix WMMA_Convert(WMMA_Type intype, WMMA_Type outtype, WMMA_Matrix m)\n{\n\tAGSMagic(WaveMatrixCopy, 0, 0, 0, 0);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(0, 0, 0), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(1, 0, 0), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(0, 1, 0), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixCopy, 0, MatrixIO(1, 1, 0), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixCopy, 1, intype.code, outtype.code, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixCopy, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nuint WMMA_MatrixLength(WMMA_Type type)\n{\n\treturn AGSMagic(WaveMatrixLength, 0, type.code, 0, 0);\n}\n\nuint WMMA_MatrixElementExtract(WMMA_Type type, WMMA_Matrix m, uint elem)\n{\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixElementExtract, 0, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\treturn AGSMagic(WaveMatrixElementExtract, 1, type.code, elem, 0); \n}\n\nWMMA_Matrix WMMA_MatrixElementFill(WMMA_Type type, WMMA_Matrix m, uint index, uint data)\n{\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), m.v[0], m.v[1]);\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), m.v[2], m.v[3]);\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), m.v[4], m.v[5]);\n\tAGSMagic(WaveMatrixElementFill, 0, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), m.v[6], m.v[7]);\n\tAGSMagic(WaveMatrixElementFill, 1, type.code, index, data);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixElementFill, 2, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\nWMMA_Matrix WMMA_MatrixFill(WMMA_Type type, uint value)\n{\n\tAGSMagic(WaveMatrixFill, 0, type.code, value, 0);\n\tWMMA_Matrix ret;\n\tret.v[0] = AGSMagic(WaveMatrixFill, 1, MatrixIO(0, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[1] = AGSMagic(WaveMatrixFill, 1, MatrixIO(1, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[2] = AGSMagic(WaveMatrixFill, 1, MatrixIO(2, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[3] = AGSMagic(WaveMatrixFill, 1, MatrixIO(3, 0, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[4] = AGSMagic(WaveMatrixFill, 1, MatrixIO(0, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[5] = AGSMagic(WaveMatrixFill, 1, MatrixIO(1, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[6] = AGSMagic(WaveMatrixFill, 1, MatrixIO(2, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\tret.v[7] = AGSMagic(WaveMatrixFill, 1, MatrixIO(3, 1, WaveMatrixRegType_RetVal_Reg), 0, 0);\n\treturn ret;\n}\n\n"
  },
  {
    "path": "show_graph.py",
    "content": "#!/usr/bin/env python3\n\nfrom graphviz import Source\nimport sys\n\ndef main():\n    s = Source.from_file(sys.argv[1])\n    s.view()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "spirv_module.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"spirv_module.hpp\"\n#include \"descriptor_qa.hpp\"\n#include \"spirv_module_instrumentation.hpp\"\n#include \"SpvBuilder.h\"\n#include \"node.hpp\"\n#include \"scratch_pool.hpp\"\n#include \"logging.hpp\"\n#include \"GLSL.std.450.h\"\n#include <limits>\n\nnamespace dxil_spv\n{\nconstexpr uint32_t GENERATOR = 1967215134;\nstruct SPIRVModule::Impl : BlockEmissionInterface\n{\n\texplicit Impl(SPIRVModule &module)\n\t    : self(module), builder(GENERATOR, &build_logger)\n\t{\n\t}\n\n\tSPIRVModule &self;\n\n\tspv::SpvBuildLogger build_logger;\n\tspv::Builder builder;\n\tspv::Function *entry_function = nullptr;\n\tspv::Function *active_function = nullptr;\n\tspv::Instruction *entry_point = nullptr;\n\n\tvoid emit_entry_point(spv::ExecutionModel model, const char *name, bool physical_storage,\n\t                      spv::MemoryModel memory_model);\n\tbool finalize_spirv(Vector<uint32_t> &spirv);\n\n\tvoid register_block(CFGNode *node) override;\n\tvoid emit_basic_block(CFGNode *node) override;\n\tvoid emit_entry_point_function_body(CFGStructurizer &structurizer);\n\tvoid emit_leaf_function_body(spv::Function *func, CFGStructurizer &structurizer);\n\tstatic spv::Block *get_spv_block(CFGNode *node);\n\n\tvoid enable_shader_discard(bool supports_demote);\n\tvoid build_discard_call_early();\n\tvoid build_discard_call_early_cond(spv::Id cond);\n\tvoid build_demote_call_cond(spv::Id cond);\n\tvoid build_discard_call_exit();\n\tspv::Id build_descriptor_qa_check(SPIRVModule &module);\n\tspv::Id build_wave_match(SPIRVModule &module, spv::Id type_id);\n\tspv::Id build_wave_is_first_lane_masked(SPIRVModule &module);\n\tspv::Id build_wave_active_all_equal_masked(SPIRVModule &module, spv::Id type_id);\n\tspv::Id build_wave_read_first_lane_masked(SPIRVModule &module, spv::Id type_id);\n\tspv::Id build_wave_multi_prefix_count_bits(SPIRVModule &module);\n\tspv::Id build_wave_multi_prefix_op(SPIRVModule &module, spv::Op opcode, spv::Id type_id);\n\tspv::Id build_robust_physical_cbv_load(SPIRVModule &module, spv::Id type_id, spv::Id ptr_type_id, unsigned alignment);\n\tspv::Id build_robust_atomic_counter_op(SPIRVModule &module);\n\tspv::Id build_quad_all(SPIRVModule &module);\n\tspv::Id build_quad_any(SPIRVModule &module);\n\tspv::Id build_quad_vote(SPIRVModule &module, HelperCall call);\n\tspv::Id build_image_atomic_r64_compact(SPIRVModule &module, bool array, bool non_uniform);\n\tspv::Id build_finish_cross_group_sharing(SPIRVModule &module);\n\tspv::Id build_allocate_node_records(SPIRVModule &module, bool per_thread);\n\tspv::Id build_increment_node_count(SPIRVModule &module, bool per_thread);\n\tspv::Id build_allocate_node_records_waterfall(SPIRVModule &module);\n\tspv::Id build_node_coalesce_payload_offset(SPIRVModule &module, const spv::Id *ids, uint32_t id_count);\n\tspv::Id build_coop_mat_fp8_to_fp16(SPIRVModule &module, const spv::Id *ids, uint32_t id_count);\n\tspv::Id build_coop_mat_fp16_to_fp8(SPIRVModule &module, const spv::Id *ids, uint32_t id_count);\n\tspv::Id build_coop_mat_saturate_fp8(SPIRVModule &module, spv::Id type_id);\n\tspv::Id build_coop_mat_transfer(SPIRVModule &module, const spv::Id *ids, uint32_t id_count);\n\tspv::Id build_coop_mat_saturation_fixup(SPIRVModule &module, spv::Id type_id);\n\tspv::Id build_is_quad_uniform_control_flow(SPIRVModule &module);\n\tspv::Id build_validate_bda_load_store(SPIRVModule &module);\n\tspv::Id build_allocate_invocation_id(SPIRVModule &module);\n\tspv::Function *discard_function = nullptr;\n\tspv::Function *discard_function_cond = nullptr;\n\tspv::Function *demote_function_cond = nullptr;\n\tspv::Id discard_state_var_id = 0;\n\tspv::ExecutionModel execution_model = spv::ExecutionModelMax;\n\n\tspv::Id create_variable(spv::StorageClass storage, spv::Id type, const char *name);\n\tspv::Id create_variable_with_initializer(spv::StorageClass storage, spv::Id type,\n\t                                         spv::Id initializer, const char *name);\n\tvoid register_active_variable(spv::StorageClass storage, spv::Id id);\n\n\tstruct\n\t{\n\t\tbool supports_demote = false;\n\t} caps;\n\n\tspv::Id get_builtin_shader_input(spv::BuiltIn builtin);\n\tspv::Id get_builtin_shader_output(spv::BuiltIn builtin);\n\tbool has_builtin_shader_input(spv::BuiltIn builtin) const;\n\tbool has_builtin_shader_output(spv::BuiltIn builtin) const;\n\tvoid register_builtin_shader_input(spv::Id id, spv::BuiltIn builtin);\n\tbool query_builtin_shader_input(spv::Id id, spv::BuiltIn *builtin) const;\n\tvoid register_builtin_shader_output(spv::Id id, spv::BuiltIn builtin);\n\tbool query_builtin_shader_output(spv::Id id, spv::BuiltIn *builtin) const;\n\tUnorderedMap<spv::BuiltIn, spv::Id> builtins_input;\n\tUnorderedMap<spv::Id, spv::BuiltIn> id_to_builtin_input;\n\tUnorderedMap<spv::BuiltIn, spv::Id> builtins_output;\n\tUnorderedMap<spv::Id, spv::BuiltIn> id_to_builtin_output;\n\n\tspv::Id get_type_for_builtin(spv::BuiltIn builtin, bool &requires_flat_decoration);\n\tScratchPool<Operation> operation_pool;\n\n\tbool spirv_requires_14() const;\n\tbool builtin_requires_volatile(spv::BuiltIn builtin) const;\n\tbool execution_model_is_ray_tracing() const;\n\tbool mark_error = false;\n\n\tspv::Id get_helper_call_id(SPIRVModule &module, HelperCall call, spv::Id type_id);\n\tspv::Id get_helper_call_id(SPIRVModule &module, HelperCall call, const spv::Id *aux_ids, uint32_t aux_id_count);\n\tspv::Id descriptor_qa_helper_call_id = 0;\n\tspv::Id wave_multi_prefix_count_bits_id = 0;\n\tspv::Id robust_atomic_counter_call_id = 0;\n\tspv::Id quad_all_call_id = 0;\n\tspv::Id quad_any_call_id = 0;\n\tspv::Id wave_is_first_lane_masked_id = 0;\n\tVector<std::pair<spv::Id, spv::Id>> wave_match_call_ids;\n\tVector<std::pair<spv::Id, spv::Id>> wave_active_all_equal_masked_ids;\n\tVector<std::pair<spv::Id, spv::Id>> wave_read_first_lane_masked_ids;\n\tspv::Id image_r64_atomic_call_id = 0;\n\tspv::Id image_r64_array_atomic_call_id = 0;\n\tspv::Id image_r64_atomic_non_uniform_call_id = 0;\n\tspv::Id image_r64_array_atomic_non_uniform_call_id = 0;\n\tspv::Id finish_cross_group_sharing_call_id = 0;\n\tspv::Id allocate_thread_node_records_call_id = 0;\n\tspv::Id allocate_group_node_records_call_id = 0;\n\tspv::Id increment_thread_node_count_call_id = 0;\n\tspv::Id increment_group_node_count_call_id = 0;\n\tspv::Id allocate_thread_node_records_waterfall_call_id = 0;\n\tspv::Id node_coalesce_payload_offset_call_id = 0;\n\tspv::Id is_quad_uniform_call_id = 0;\n\tspv::Id validate_bda_load_store_call_id = 0;\n\tspv::Id allocate_invocation_id_call_id = 0;\n\n\tstruct MultiPrefixOp\n\t{\n\t\tspv::Op opcode;\n\t\tspv::Id type_id;\n\t\tspv::Id func_id;\n\t};\n\tVector<MultiPrefixOp> wave_multi_prefix_call_ids;\n\n\tstruct CBVOp\n\t{\n\t\tspv::Id type_id;\n\t\tspv::Id ptr_type_id;\n\t\tunsigned alignment;\n\t\tspv::Id func_id;\n\t};\n\tVector<CBVOp> physical_cbv_call_ids;\n\n\tstruct CoopMatConvOp\n\t{\n\t\tspv::Id input_type;\n\t\tspv::Id output_type;\n\t\tspv::Id func_id;\n\t\tHelperCall call;\n\t};\n\tVector<CoopMatConvOp> coop_mat_conv_ids;\n\n\tDescriptorQAInfo descriptor_qa_info;\n\n\tuint32_t override_spirv_version = 0;\n\tbool helper_lanes_participate_in_wave_ops = true;\n\n\tvoid add_instruction(spv::Block *bb, std::unique_ptr<spv::Instruction> inst);\n\tvoid add_instrumented_instruction(spv::Op op, spv::Block *bb, spv::Id id);\n\tInstructionInstrumentationState instruction_instrumentation;\n};\n\nspv::Id SPIRVModule::Impl::get_type_for_builtin(spv::BuiltIn builtin, bool &requires_flat)\n{\n\trequires_flat = false;\n\tswitch (builtin)\n\t{\n\tcase spv::BuiltInSampleMask:\n\t\trequires_flat = true;\n\t\treturn builder.makeArrayType(builder.makeUintType(32), builder.makeUintConstant(1), 0);\n\n\tcase spv::BuiltInTessCoord:\n\t\treturn builder.makeVectorType(builder.makeFloatType(32), 3);\n\n\tcase spv::BuiltInLocalInvocationIndex:\n\tcase spv::BuiltInDrawIndex:\n\tcase spv::BuiltInSampleId:\n\tcase spv::BuiltInVertexIndex:\n\tcase spv::BuiltInInstanceIndex:\n\tcase spv::BuiltInBaseVertex:\n\tcase spv::BuiltInBaseInstance:\n\tcase spv::BuiltInInvocationId:\n\tcase spv::BuiltInPrimitiveId:\n\tcase spv::BuiltInShadingRateKHR:\n\tcase spv::BuiltInPrimitiveShadingRateKHR:\n\tcase spv::BuiltInViewIndex:\n\tcase spv::BuiltInPatchVertices:\n\t\trequires_flat = true;\n\t\treturn builder.makeUintType(32);\n\n\tcase spv::BuiltInSubgroupSize:\n\tcase spv::BuiltInNumSubgroups:\n\tcase spv::BuiltInSubgroupLocalInvocationId:\n\tcase spv::BuiltInSubgroupId:\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\t\trequires_flat = true;\n\t\treturn builder.makeUintType(32);\n\n\tcase spv::BuiltInGlobalInvocationId:\n\tcase spv::BuiltInLocalInvocationId:\n\tcase spv::BuiltInWorkgroupId:\n\tcase spv::BuiltInLaunchIdKHR:\n\tcase spv::BuiltInLaunchSizeKHR:\n\tcase spv::BuiltInNumWorkgroups:\n\t\treturn builder.makeVectorType(builder.makeUintType(32), 3);\n\n\tcase spv::BuiltInObjectRayOriginKHR:\n\tcase spv::BuiltInWorldRayOriginKHR:\n\tcase spv::BuiltInObjectRayDirectionKHR:\n\tcase spv::BuiltInWorldRayDirectionKHR:\n\t\treturn builder.makeVectorType(builder.makeFloatType(32), 3);\n\n\tcase spv::BuiltInRayTminKHR:\n\tcase spv::BuiltInRayTmaxKHR:\n\t\treturn builder.makeFloatType(32);\n\n\tcase spv::BuiltInWorldToObjectKHR:\n\tcase spv::BuiltInObjectToWorldKHR:\n\t\treturn builder.makeMatrixType(builder.makeFloatType(32), 4, 3);\n\n\tcase spv::BuiltInInstanceCustomIndexKHR:\n\tcase spv::BuiltInInstanceId:\n\tcase spv::BuiltInRayGeometryIndexKHR:\n\tcase spv::BuiltInIncomingRayFlagsKHR:\n\tcase spv::BuiltInHitKindKHR:\n\t\trequires_flat = true;\n\t\treturn builder.makeUintType(32);\n\n\tcase spv::BuiltInHelperInvocation:\n\tcase spv::BuiltInFullyCoveredEXT:\n\t\treturn builder.makeBoolType();\n\n\tcase spv::BuiltInClusterIDNV:\n\t\treturn builder.makeUintType(32);\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nvoid SPIRVModule::Impl::register_builtin_shader_input(spv::Id id, spv::BuiltIn builtin)\n{\n\tbuiltins_input[builtin] = id;\n\tid_to_builtin_input[id] = builtin;\n}\n\nvoid SPIRVModule::Impl::register_builtin_shader_output(spv::Id id, spv::BuiltIn builtin)\n{\n\tbuiltins_output[builtin] = id;\n\tid_to_builtin_output[id] = builtin;\n}\n\nbool SPIRVModule::Impl::query_builtin_shader_input(spv::Id id, spv::BuiltIn *builtin) const\n{\n\tauto itr = id_to_builtin_input.find(id);\n\tif (itr != id_to_builtin_input.end())\n\t{\n\t\t*builtin = itr->second;\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nbool SPIRVModule::Impl::query_builtin_shader_output(spv::Id id, spv::BuiltIn *builtin) const\n{\n\tauto itr = id_to_builtin_output.find(id);\n\tif (itr != id_to_builtin_output.end())\n\t{\n\t\t*builtin = itr->second;\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nbool SPIRVModule::Impl::builtin_requires_volatile(spv::BuiltIn builtin) const\n{\n\tif (!execution_model_is_ray_tracing())\n\t\treturn false;\n\n\tswitch (builtin)\n\t{\n\tcase spv::BuiltInSubgroupId:\n\tcase spv::BuiltInSubgroupLocalInvocationId:\n\tcase spv::BuiltInSubgroupEqMask:\n\tcase spv::BuiltInSubgroupLtMask:\n\tcase spv::BuiltInSubgroupLeMask:\n\tcase spv::BuiltInSubgroupGtMask:\n\tcase spv::BuiltInSubgroupGeMask:\n\t\treturn true;\n\n\tcase spv::BuiltInRayTmaxKHR:\n\t\treturn execution_model == spv::ExecutionModelIntersectionKHR;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool SPIRVModule::Impl::has_builtin_shader_input(spv::BuiltIn builtin) const\n{\n\treturn builtins_input.count(builtin) != 0;\n}\n\nbool SPIRVModule::Impl::has_builtin_shader_output(spv::BuiltIn builtin) const\n{\n\treturn builtins_output.count(builtin) != 0;\n}\n\nspv::Id SPIRVModule::Impl::get_builtin_shader_input(spv::BuiltIn builtin)\n{\n\tauto itr = builtins_input.find(builtin);\n\tif (itr != builtins_input.end())\n\t\treturn itr->second;\n\n\tbool requires_flat = false;\n\tspv::Id var_id = create_variable(spv::StorageClassInput, get_type_for_builtin(builtin, requires_flat), nullptr);\n\tbuilder.addDecoration(var_id, spv::DecorationBuiltIn, builtin);\n\tif (builtin_requires_volatile(builtin) && !builder.hasCapability(spv::CapabilityVulkanMemoryModel))\n\t\tbuilder.addDecoration(var_id, spv::DecorationVolatile);\n\n\t// VUID-StandaloneSpirv-Flat-04744\n\tif (requires_flat && execution_model == spv::ExecutionModelFragment)\n\t\tbuilder.addDecoration(var_id, spv::DecorationFlat);\n\tregister_builtin_shader_input(var_id, builtin);\n\treturn var_id;\n}\n\nspv::Id SPIRVModule::Impl::get_builtin_shader_output(spv::BuiltIn builtin)\n{\n\tauto itr = builtins_output.find(builtin);\n\tif (itr != builtins_output.end())\n\t\treturn itr->second;\n\telse\n\t\treturn 0;\n}\n\nspv::Block *SPIRVModule::Impl::get_spv_block(CFGNode *node)\n{\n\tassert(node->userdata);\n\treturn static_cast<spv::Block *>(node->userdata);\n}\n\nvoid SPIRVModule::Impl::emit_entry_point(spv::ExecutionModel model,\n                                         const char *name, bool physical_storage,\n                                         spv::MemoryModel memory_model)\n{\n\texecution_model = model;\n\tbuilder.addCapability(spv::Capability::CapabilityShader);\n\n\tif (memory_model == spv::MemoryModelVulkan)\n\t\tbuilder.addCapability(spv::CapabilityVulkanMemoryModel);\n\n\tif (physical_storage)\n\t{\n\t\tbuilder.setMemoryModel(spv::AddressingModel::AddressingModelPhysicalStorageBuffer64, memory_model);\n\t\tbuilder.addCapability(spv::CapabilityPhysicalStorageBufferAddresses);\n\t\tbuilder.addExtension(\"SPV_KHR_physical_storage_buffer\");\n\t}\n\telse\n\t\tbuilder.setMemoryModel(spv::AddressingModel::AddressingModelLogical, memory_model);\n\n\tentry_function = builder.makeEntryPoint(\"main\");\n\tentry_point = builder.addEntryPoint(model, entry_function, name);\n\tif (model == spv::ExecutionModel::ExecutionModelFragment)\n\t\tbuilder.addExecutionMode(entry_function, spv::ExecutionModeOriginUpperLeft);\n\n\tif (instruction_instrumentation.info.enabled)\n\t{\n\t\tbuilder.addExtension(\"SPV_KHR_float_controls\");\n\t\tbuilder.addCapability(spv::CapabilitySignedZeroInfNanPreserve);\n\n\t\tif (instruction_instrumentation.info.fp16)\n\t\t{\n\t\t\tbuilder.addCapability(spv::CapabilityFloat16);\n\t\t\tbuilder.addExecutionMode(entry_function, spv::ExecutionModeSignedZeroInfNanPreserve, 16);\n\t\t}\n\n\t\tif (instruction_instrumentation.info.fp32)\n\t\t\tbuilder.addExecutionMode(entry_function, spv::ExecutionModeSignedZeroInfNanPreserve, 32);\n\n\t\tif (instruction_instrumentation.info.fp64)\n\t\t\tbuilder.addExecutionMode(entry_function, spv::ExecutionModeSignedZeroInfNanPreserve, 64);\n\t}\n}\n\nvoid SPIRVModule::Impl::enable_shader_discard(bool supports_demote)\n{\n\tcaps.supports_demote = supports_demote;\n\tif (!discard_state_var_id && !caps.supports_demote)\n\t{\n\t\tauto *current_build_point = builder.getBuildPoint();\n\t\tdiscard_state_var_id =\n\t\t    create_variable(spv::StorageClassPrivate, builder.makeBoolType(), \"discard_state\");\n\t\tbuilder.setBuildPoint(entry_function->getEntryBlock());\n\t\tbuilder.createStore(builder.makeBoolConstant(false), discard_state_var_id);\n\t\tbuilder.setBuildPoint(current_build_point);\n\t}\n}\n\nvoid SPIRVModule::Impl::build_discard_call_early()\n{\n\tbuilder.createStore(builder.makeBoolConstant(true), discard_state_var_id);\n}\n\nvoid SPIRVModule::Impl::build_demote_call_cond(spv::Id cond)\n{\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tif (!demote_function_cond)\n\t{\n\t\tspv::Block *entry = nullptr;\n\t\tdemote_function_cond =\n\t\t\tbuilder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(), \"demote_cond\",\n\t\t                              { builder.makeBoolType() }, {}, &entry);\n\n\t\tauto *true_block = new spv::Block(builder.getUniqueId(), *demote_function_cond);\n\t\tauto *false_block = new spv::Block(builder.getUniqueId(), *demote_function_cond);\n\t\tbuilder.setBuildPoint(entry);\n\t\tbuilder.createSelectionMerge(false_block, 0);\n\t\tbuilder.createConditionalBranch(demote_function_cond->getParamId(0), true_block, false_block);\n\t\tadd_instruction(true_block, std::make_unique<spv::Instruction>(spv::OpDemoteToHelperInvocationEXT));\n\t\tbuilder.setBuildPoint(true_block);\n\t\tbuilder.createBranch(false_block);\n\t\tbuilder.setBuildPoint(false_block);\n\t\tbuilder.makeReturn(false);\n\t}\n\n\tbuilder.setBuildPoint(current_build_point);\n\tbuilder.createFunctionCall(demote_function_cond, { cond });\n}\n\nvoid SPIRVModule::Impl::build_discard_call_early_cond(spv::Id cond)\n{\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tif (!discard_function_cond)\n\t{\n\t\tspv::Block *entry = nullptr;\n\t\tdiscard_function_cond =\n\t\t\tbuilder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(), \"discard_cond\",\n\t\t\t                          { builder.makeBoolType() }, {}, &entry);\n\n\t\tauto *true_block = new spv::Block(builder.getUniqueId(), *discard_function_cond);\n\t\tauto *false_block = new spv::Block(builder.getUniqueId(), *discard_function_cond);\n\t\tbuilder.setBuildPoint(entry);\n\t\tbuilder.createSelectionMerge(false_block, 0);\n\t\tbuilder.createConditionalBranch(discard_function_cond->getParamId(0), true_block, false_block);\n\t\tbuilder.setBuildPoint(true_block);\n\t\tbuilder.createStore(builder.makeBoolConstant(true), discard_state_var_id);\n\t\tbuilder.createBranch(false_block);\n\t\tbuilder.setBuildPoint(false_block);\n\t\tbuilder.makeReturn(false);\n\t}\n\n\tbuilder.setBuildPoint(current_build_point);\n\tbuilder.createFunctionCall(discard_function_cond, { cond });\n}\n\nvoid SPIRVModule::Impl::build_discard_call_exit()\n{\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tif (!discard_function)\n\t{\n\t\tspv::Block *entry = nullptr;\n\t\tdiscard_function =\n\t\t    builder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(), \"discard_exit\", {}, {}, &entry);\n\n\t\tauto *true_block = new spv::Block(builder.getUniqueId(), *discard_function);\n\t\tauto *false_block = new spv::Block(builder.getUniqueId(), *discard_function);\n\n\t\tbuilder.setBuildPoint(entry);\n\t\tspv::Id loaded_state = builder.createLoad(discard_state_var_id);\n\t\tbuilder.createSelectionMerge(false_block, 0);\n\t\tbuilder.createConditionalBranch(loaded_state, true_block, false_block);\n\t\tadd_instruction(true_block, std::make_unique<spv::Instruction>(spv::OpKill));\n\t\tbuilder.setBuildPoint(false_block);\n\t\tbuilder.makeReturn(false);\n\t}\n\n\tbuilder.setBuildPoint(current_build_point);\n\tbuilder.createFunctionCall(discard_function, {});\n}\n\nspv::Id SPIRVModule::Impl::build_descriptor_qa_check(SPIRVModule &module)\n{\n\tif (!descriptor_qa_helper_call_id)\n\t\tdescriptor_qa_helper_call_id = build_descriptor_qa_check_function(module);\n\treturn descriptor_qa_helper_call_id;\n}\n\nspv::Id SPIRVModule::Impl::build_validate_bda_load_store(SPIRVModule &module)\n{\n\tif (!validate_bda_load_store_call_id)\n\t{\n\t\tvalidate_bda_load_store_call_id = build_validate_bda_load_store_function(\n\t\t\tmodule,\n\t\t\tinstruction_instrumentation.info.control_desc_set,\n\t\t\tinstruction_instrumentation.info.control_binding);\n\t}\n\n\treturn validate_bda_load_store_call_id;\n}\n\nspv::Id SPIRVModule::Impl::build_allocate_invocation_id(SPIRVModule &module)\n{\n\tif (!allocate_invocation_id_call_id)\n\t{\n\t\tallocate_invocation_id_call_id = build_allocate_invocation_id_function(\n\t\t    module,\n\t\t    instruction_instrumentation.info.control_desc_set,\n\t\t    instruction_instrumentation.info.control_binding);\n\t}\n\n\treturn allocate_invocation_id_call_id;\n}\n\nstatic const char *opcode_to_multi_prefix_name(spv::Op opcode)\n{\n\tswitch (opcode)\n\t{\n\tcase spv::OpGroupNonUniformFAdd:\n\tcase spv::OpGroupNonUniformIAdd:\n\t\treturn \"WaveMultiPrefixSum\";\n\n\tcase spv::OpGroupNonUniformFMul:\n\tcase spv::OpGroupNonUniformIMul:\n\t\treturn \"WaveMultiPrefixProduct\";\n\n\tcase spv::OpGroupNonUniformBitwiseAnd:\n\t\treturn \"WaveMultiPrefixBitAnd\";\n\tcase spv::OpGroupNonUniformBitwiseOr:\n\t\treturn \"WaveMultiPrefixBitOr\";\n\tcase spv::OpGroupNonUniformBitwiseXor:\n\t\treturn \"WaveMultiPrefixBitXor\";\n\n\tdefault:\n\t\treturn \"\";\n\t}\n}\n\nspv::Id SPIRVModule::Impl::build_wave_multi_prefix_op(SPIRVModule &module, spv::Op opcode, spv::Id type_id)\n{\n\tfor (auto &call : wave_multi_prefix_call_ids)\n\t\tif (call.opcode == opcode && call.type_id == type_id)\n\t\t\treturn call.func_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec4_type = builder.makeVectorType(uint_type, 4);\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id bvec4_type = builder.makeVectorType(bool_type, 4);\n\n\tVector<spv::Id> types = { type_id, uvec4_type };\n\tif (!helper_lanes_participate_in_wave_ops)\n\t\ttypes.push_back(bool_type);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, type_id,\n\t                                       opcode_to_multi_prefix_name(opcode),\n\t                                       types, {}, &entry);\n\tspv::Id value_id = func->getParamId(0);\n\tspv::Id mask_id = func->getParamId(1);\n\tspv::Id undef_value = builder.createUndefined(type_id);\n\n\tspv::Block *outer_entry = nullptr;\n\tspv::Block *return_block = nullptr;\n\tauto *header_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *prefix_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *continue_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tbuilder.setBuildPoint(entry);\n\n\tif (!helper_lanes_participate_in_wave_ops)\n\t{\n\t\treturn_block = new spv::Block(builder.getUniqueId(), *func);\n\t\tauto *inner_entry_block = new spv::Block(builder.getUniqueId(), *func);\n\n\t\tbuilder.createSelectionMerge(return_block, 0);\n\t\tbuilder.createConditionalBranch(func->getParamId(2), return_block, inner_entry_block);\n\t\touter_entry = entry;\n\t\tentry = inner_entry_block;\n\t\tbuilder.setBuildPoint(entry);\n\t}\n\n\t{\n\t\tauto ballot_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBallot);\n\t\tballot_op->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tballot_op->addIdOperand(builder.makeBoolConstant(true));\n\t\tauto mask_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpBitwiseAnd);\n\t\tmask_op->addIdOperand(ballot_op->getResultId());\n\t\tmask_op->addIdOperand(mask_id);\n\t\tmask_id = mask_op->getResultId();\n\t\tadd_instruction(entry, std::move(ballot_op));\n\t\tadd_instruction(entry, std::move(mask_op));\n\t\tbuilder.createBranch(header_block);\n\t}\n\n\tbuilder.setBuildPoint(header_block);\n\t{\n\t\tbuilder.createLoopMerge(merge_block, body_block, 0);\n\t\tbuilder.createBranch(body_block);\n\t}\n\n\tbuilder.setBuildPoint(body_block);\n\tspv::Id compare_reduce_id;\n\t{\n\t\tauto broadcast_first = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBroadcastFirst);\n\t\tbroadcast_first->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tbroadcast_first->addIdOperand(mask_id);\n\n\t\tauto compare = std::make_unique<spv::Instruction>(builder.getUniqueId(), bvec4_type, spv::OpIEqual);\n\t\tcompare->addIdOperand(mask_id);\n\t\tcompare->addIdOperand(broadcast_first->getResultId());\n\n\t\tauto compare_reduce = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpAll);\n\t\tcompare_reduce->addIdOperand(compare->getResultId());\n\t\tcompare_reduce_id = compare_reduce->getResultId();\n\n\t\tadd_instruction(body_block, std::move(broadcast_first));\n\t\tadd_instruction(body_block, std::move(compare));\n\t\tadd_instruction(body_block, std::move(compare_reduce));\n\t\tbuilder.createSelectionMerge(continue_block, 0);\n\t\tbuilder.createConditionalBranch(compare_reduce_id, prefix_block, continue_block);\n\t}\n\n\tspv::Id result_id;\n\tbuilder.setBuildPoint(prefix_block);\n\t{\n\t\tauto prefix_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), type_id, opcode);\n\t\tprefix_op->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tprefix_op->addImmediateOperand(spv::GroupOperationExclusiveScan);\n\t\tprefix_op->addIdOperand(value_id);\n\t\tresult_id = prefix_op->getResultId();\n\t\tadd_instruction(prefix_block, std::move(prefix_op));\n\t\tbuilder.createBranch(continue_block);\n\t}\n\n\tbuilder.setBuildPoint(continue_block);\n\t{\n\t\tauto phi = std::make_unique<spv::Instruction>(builder.getUniqueId(), type_id, spv::OpPhi);\n\t\tphi->addIdOperand(result_id);\n\t\tphi->addIdOperand(prefix_block->getId());\n\t\tphi->addIdOperand(undef_value);\n\t\tphi->addIdOperand(body_block->getId());\n\t\tresult_id = phi->getResultId();\n\t\tadd_instruction(continue_block, std::move(phi));\n\t\tbuilder.createConditionalBranch(compare_reduce_id, merge_block, header_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\n\tif (return_block)\n\t{\n\t\tbuilder.createBranch(return_block);\n\t\tbuilder.setBuildPoint(return_block);\n\n\t\tauto phi = std::make_unique<spv::Instruction>(builder.getUniqueId(), type_id, spv::OpPhi);\n\t\tphi->addIdOperand(result_id);\n\t\tphi->addIdOperand(merge_block->getId());\n\t\tphi->addIdOperand(undef_value);\n\t\tphi->addIdOperand(outer_entry->getId());\n\t\tresult_id = phi->getResultId();\n\t\tadd_instruction(return_block, std::move(phi));\n\t}\n\n\tbuilder.makeReturn(false, result_id);\n\n\tbuilder.setBuildPoint(current_build_point);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformArithmetic);\n\twave_multi_prefix_call_ids.push_back({ opcode, type_id, func->getId() });\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_wave_multi_prefix_count_bits(SPIRVModule &module)\n{\n\tif (wave_multi_prefix_count_bits_id)\n\t\treturn wave_multi_prefix_count_bits_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec4_type = builder.makeVectorType(uint_type, 4);\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id bvec4_type = builder.makeVectorType(bool_type, 4);\n\n\tspv::Block *entry = nullptr;\n\tVector<spv::Id> types = { bool_type, uvec4_type };\n\tif (!helper_lanes_participate_in_wave_ops)\n\t\ttypes.push_back(bool_type);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, uint_type,\n\t                                       \"WaveMultiPrefixCountBits\",\n\t                                       types, {}, &entry);\n\tspv::Id value_id = func->getParamId(0);\n\tspv::Id mask_id = func->getParamId(1);\n\tauto *header_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tspv::Block *outer_entry = nullptr;\n\tspv::Block *return_block = nullptr;\n\tspv::Id undef_id = 0;\n\n\tbuilder.setBuildPoint(entry);\n\n\tif (!helper_lanes_participate_in_wave_ops)\n\t{\n\t\treturn_block = new spv::Block(builder.getUniqueId(), *func);\n\t\tauto *inner_entry_block = new spv::Block(builder.getUniqueId(), *func);\n\t\tundef_id = builder.createUndefined(uint_type);\n\t\tbuilder.createSelectionMerge(return_block, 0);\n\t\tbuilder.createConditionalBranch(func->getParamId(2), return_block, inner_entry_block);\n\t\touter_entry = entry;\n\t\tentry = inner_entry_block;\n\t\tbuilder.setBuildPoint(entry);\n\t}\n\n\t{\n\t\tauto ballot_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBallot);\n\t\tballot_op->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tballot_op->addIdOperand(builder.makeBoolConstant(true));\n\t\tauto mask_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpBitwiseAnd);\n\t\tmask_op->addIdOperand(ballot_op->getResultId());\n\t\tmask_op->addIdOperand(mask_id);\n\t\tmask_id = mask_op->getResultId();\n\t\tadd_instruction(entry, std::move(ballot_op));\n\t\tadd_instruction(entry, std::move(mask_op));\n\t\tbuilder.createBranch(header_block);\n\t}\n\n\tbuilder.setBuildPoint(header_block);\n\t{\n\t\tbuilder.createLoopMerge(merge_block, body_block, 0);\n\t\tbuilder.createBranch(body_block);\n\t}\n\n\tspv::Id result_id;\n\tbuilder.setBuildPoint(body_block);\n\t{\n\t\tauto broadcast_first =\n\t\t    std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBroadcastFirst);\n\t\tbroadcast_first->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tbroadcast_first->addIdOperand(mask_id);\n\n\t\tauto compare = std::make_unique<spv::Instruction>(builder.getUniqueId(), bvec4_type, spv::OpIEqual);\n\t\tcompare->addIdOperand(mask_id);\n\t\tcompare->addIdOperand(broadcast_first->getResultId());\n\n\t\tauto compare_reduce = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpAll);\n\t\tcompare_reduce->addIdOperand(compare->getResultId());\n\t\tspv::Id compare_reduce_id = compare_reduce->getResultId();\n\n\t\tauto prefix_input = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLogicalAnd);\n\t\tprefix_input->addIdOperand(compare_reduce_id);\n\t\tprefix_input->addIdOperand(value_id);\n\n\t\tauto modified_ballot =\n\t\t    std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBallot);\n\t\tmodified_ballot->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tmodified_ballot->addIdOperand(prefix_input->getResultId());\n\t\tauto count =\n\t\t    std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpGroupNonUniformBallotBitCount);\n\t\tcount->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tcount->addImmediateOperand(spv::GroupOperationExclusiveScan);\n\t\tcount->addIdOperand(modified_ballot->getResultId());\n\t\tresult_id = count->getResultId();\n\n\t\tadd_instruction(body_block, std::move(broadcast_first));\n\t\tadd_instruction(body_block, std::move(compare));\n\t\tadd_instruction(body_block, std::move(compare_reduce));\n\t\tadd_instruction(body_block, std::move(prefix_input));\n\t\tadd_instruction(body_block, std::move(modified_ballot));\n\t\tadd_instruction(body_block, std::move(count));\n\t\tbuilder.createConditionalBranch(compare_reduce_id, merge_block, header_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\n\tif (return_block)\n\t{\n\t\tbuilder.createBranch(return_block);\n\t\tbuilder.setBuildPoint(return_block);\n\n\t\tauto phi = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpPhi);\n\t\tphi->addIdOperand(result_id);\n\t\tphi->addIdOperand(merge_block->getId());\n\t\tphi->addIdOperand(undef_id);\n\t\tphi->addIdOperand(outer_entry->getId());\n\t\tresult_id = phi->getResultId();\n\t\tadd_instruction(return_block, std::move(phi));\n\t}\n\n\tbuilder.makeReturn(false, result_id);\n\tbuilder.setBuildPoint(current_build_point);\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformArithmetic);\n\twave_multi_prefix_count_bits_id = func->getId();\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_wave_active_all_equal_masked(SPIRVModule &module, spv::Id type_id)\n{\n\tfor (auto &calls : wave_active_all_equal_masked_ids)\n\t\tif (calls.first == type_id)\n\t\t\treturn calls.second;\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformVote);\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, bool_type,\n\t                                       \"WaveActiveAllEqual\",\n\t                                       { type_id, bool_type }, {}, &entry);\n\n\tauto *is_helper_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *is_active_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tspv::Id equal_id, undef_id;\n\n\tbuilder.setBuildPoint(entry);\n\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(func->getParamId(1), is_helper_block, is_active_block);\n\n\t{\n\t\tbuilder.setBuildPoint(is_helper_block);\n\t\t// Assist in scalar promotion, if we set something concrete, we will force VGPR.\n\t\tundef_id = builder.createUndefined(bool_type);\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\t{\n\t\tbuilder.setBuildPoint(is_active_block);\n\t\tauto all_equal = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpGroupNonUniformAllEqual);\n\t\tall_equal->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tall_equal->addIdOperand(func->getParamId(0));\n\t\tequal_id = all_equal->getResultId();\n\t\tadd_instruction(is_active_block, std::move(all_equal));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\tauto phi = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpPhi);\n\tphi->addIdOperand(equal_id);\n\tphi->addIdOperand(is_active_block->getId());\n\tphi->addIdOperand(undef_id);\n\tphi->addIdOperand(is_helper_block->getId());\n\tequal_id = phi->getResultId();\n\tadd_instruction(merge_block, std::move(phi));\n\n\tbuilder.makeReturn(false, equal_id);\n\tbuilder.setBuildPoint(current_build_point);\n\twave_active_all_equal_masked_ids.emplace_back(type_id, func->getId());\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_wave_read_first_lane_masked(SPIRVModule &module, spv::Id type_id)\n{\n\tfor (auto &calls : wave_read_first_lane_masked_ids)\n\t\tif (calls.first == type_id)\n\t\t\treturn calls.second;\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformShuffle);\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, type_id,\n\t                                       \"WaveReadFirstLane\",\n\t                                       { type_id, bool_type }, {}, &entry);\n\n\tbuilder.setBuildPoint(entry);\n\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec4_type = builder.makeVectorType(uint_type, 4);\n\n\t// Shuffle path is more robust since it will avoid undefs.\n\t// Also matches codegen on AMD.\n\t// The branchy style where helpers receive undefs confuses NV it seems ...\n\n\tauto not_inst = std::make_unique<spv::Instruction>(\n\t\tbuilder.getUniqueId(), bool_type, spv::OpLogicalNot);\n\tnot_inst->addIdOperand(func->getParamId(1));\n\n\tauto ballot = std::make_unique<spv::Instruction>(\n\t\tbuilder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBallot);\n\tballot->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tballot->addIdOperand(not_inst->getResultId());\n\n\tauto lsb = std::make_unique<spv::Instruction>(\n\t\tbuilder.getUniqueId(), builder.makeUintType(32), spv::OpGroupNonUniformBallotFindLSB);\n\tlsb->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tlsb->addIdOperand(ballot->getResultId());\n\n\tauto shuffle = std::make_unique<spv::Instruction>(\n\t\tbuilder.getUniqueId(), type_id, spv::OpGroupNonUniformShuffle);\n\tshuffle->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tshuffle->addIdOperand(func->getParamId(0));\n\tshuffle->addIdOperand(lsb->getResultId());\n\n\t// Undocumented requirement, if all lanes are helpers, 0 is returned.\n\tauto ballot_real_lane_count = std::make_unique<spv::Instruction>(\n\t    builder.getUniqueId(), uint_type, spv::OpGroupNonUniformBallotBitCount);\n\tballot_real_lane_count->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tballot_real_lane_count->addImmediateOperand(spv::GroupOperationReduce);\n\tballot_real_lane_count->addIdOperand(ballot->getResultId());\n\tauto ballot_has_real_lane = std::make_unique<spv::Instruction>(\n\t\tbuilder.getUniqueId(), bool_type, spv::OpINotEqual);\n\tballot_has_real_lane->addIdOperand(ballot_real_lane_count->getResultId());\n\tballot_has_real_lane->addIdOperand(builder.makeUintConstant(0));\n\n\tauto select_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), type_id, spv::OpSelect);\n\tselect_op->addIdOperand(ballot_has_real_lane->getResultId());\n\tselect_op->addIdOperand(shuffle->getResultId());\n\tselect_op->addIdOperand(builder.makeNullConstant(type_id));\n\tspv::Id ret_id = select_op->getResultId();\n\n\tadd_instruction(entry, std::move(not_inst));\n\tadd_instruction(entry, std::move(ballot));\n\tadd_instruction(entry, std::move(lsb));\n\tadd_instruction(entry, std::move(shuffle));\n\tadd_instruction(entry, std::move(ballot_real_lane_count));\n\tadd_instruction(entry, std::move(ballot_has_real_lane));\n\tadd_instruction(entry, std::move(select_op));\n\tbuilder.makeReturn(false, ret_id);\n\n\tbuilder.setBuildPoint(current_build_point);\n\twave_read_first_lane_masked_ids.emplace_back(type_id, func->getId());\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_wave_is_first_lane_masked(SPIRVModule &module)\n{\n\tif (wave_is_first_lane_masked_id)\n\t\treturn wave_is_first_lane_masked_id;\n\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, bool_type,\n\t                                       \"WaveIsFirstLane\",\n\t                                       { bool_type }, {}, &entry);\n\n\tauto *is_helper_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *is_active_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tspv::Id elect_id;\n\n\tbuilder.setBuildPoint(entry);\n\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(func->getParamId(0), is_helper_block, is_active_block);\n\n\t{\n\t\tbuilder.setBuildPoint(is_helper_block);\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\t{\n\t\tbuilder.setBuildPoint(is_active_block);\n\t\tauto elect = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpGroupNonUniformElect);\n\t\telect->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\telect_id = elect->getResultId();\n\t\tadd_instruction(is_active_block, std::move(elect));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\tauto phi = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpPhi);\n\tphi->addIdOperand(elect_id);\n\tphi->addIdOperand(is_active_block->getId());\n\tphi->addIdOperand(builder.makeBoolConstant(false));\n\tphi->addIdOperand(is_helper_block->getId());\n\telect_id = phi->getResultId();\n\tadd_instruction(merge_block, std::move(phi));\n\n\tbuilder.makeReturn(false, elect_id);\n\tbuilder.setBuildPoint(current_build_point);\n\twave_is_first_lane_masked_id = func->getId();\n\treturn wave_is_first_lane_masked_id;\n}\n\nspv::Id SPIRVModule::Impl::build_wave_match(SPIRVModule &module, spv::Id type_id)\n{\n\tfor (auto &type : wave_match_call_ids)\n\t\tif (type.first == type_id)\n\t\t\treturn type.second;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec4_type = builder.makeVectorType(uint_type, 4);\n\tspv::Id bool_type = builder.makeBoolType();\n\tVector<spv::Id> types = { type_id };\n\tif (!helper_lanes_participate_in_wave_ops)\n\t\ttypes.push_back(bool_type);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, uvec4_type,\n\t                                       \"WaveMatch\",\n\t                                       types, {}, &entry);\n\tspv::Id value_id = func->getParamId(0);\n\n\tauto *header_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tspv::Block *outer_header = nullptr;\n\tspv::Block *return_block = nullptr;\n\tspv::Id undef_id = 0;\n\n\tbuilder.setBuildPoint(entry);\n\tbuilder.createBranch(header_block);\n\tbuilder.setBuildPoint(header_block);\n\n\tif (!helper_lanes_participate_in_wave_ops)\n\t{\n\t\treturn_block = new spv::Block(builder.getUniqueId(), *func);\n\t\tauto *inner_header_block = new spv::Block(builder.getUniqueId(), *func);\n\t\tundef_id = builder.createUndefined(uvec4_type);\n\t\tbuilder.createSelectionMerge(return_block, 0);\n\t\tbuilder.createConditionalBranch(func->getParamId(1), return_block, inner_header_block);\n\t\touter_header = header_block;\n\t\theader_block = inner_header_block;\n\t\tbuilder.setBuildPoint(header_block);\n\t}\n\n\tbuilder.createLoopMerge(merge_block, body_block, 0);\n\tbuilder.createBranch(body_block);\n\n\tauto broadcast_first = std::make_unique<spv::Instruction>(builder.getUniqueId(), type_id, spv::OpGroupNonUniformBroadcastFirst);\n\tbroadcast_first->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbroadcast_first->addIdOperand(value_id);\n\n\t// We cannot scalarize floats safely due to NaNs. Caller will bitcast to uint first.\n\tassert(builder.getTypeClass(type_id) != spv::OpTypeFloat);\n\tspv::Op equal_op;\n\tif (builder.getTypeClass(type_id) == spv::OpTypeBool)\n\t\tequal_op = spv::OpLogicalEqual;\n\telse\n\t\tequal_op = spv::OpIEqual;\n\n\tauto compare = std::make_unique<spv::Instruction>(builder.getUniqueId(), builder.makeBoolType(), equal_op);\n\tcompare->addIdOperand(value_id);\n\tcompare->addIdOperand(broadcast_first->getResultId());\n\tspv::Id compare_id = compare->getResultId();\n\n\tauto ballot = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBallot);\n\tballot->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tballot->addIdOperand(compare->getResultId());\n\tspv::Id ballot_id = ballot->getResultId();\n\n\tbuilder.setBuildPoint(body_block);\n\tadd_instruction(body_block, std::move(broadcast_first));\n\tadd_instruction(body_block, std::move(compare));\n\tadd_instruction(body_block, std::move(ballot));\n\tbuilder.createConditionalBranch(compare_id, merge_block, header_block);\n\n\tbuilder.setBuildPoint(merge_block);\n\n\tif (return_block)\n\t{\n\t\tbuilder.createBranch(return_block);\n\t\tbuilder.setBuildPoint(return_block);\n\n\t\tauto phi = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpPhi);\n\t\tphi->addIdOperand(ballot_id);\n\t\tphi->addIdOperand(merge_block->getId());\n\t\tphi->addIdOperand(undef_id);\n\t\tphi->addIdOperand(outer_header->getId());\n\t\tballot_id = phi->getResultId();\n\t\tadd_instruction(return_block, std::move(phi));\n\t}\n\n\tbuilder.makeReturn(false, ballot_id);\n\tbuilder.setBuildPoint(current_build_point);\n\n\twave_match_call_ids.emplace_back(type_id, func->getId());\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_quad_vote(SPIRVModule &module, HelperCall call)\n{\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, bool_type,\n\t                                       call == HelperCall::QuadAll ? \"QuadAll\" : \"QuadAny\",\n\t                                       { bool_type }, {}, &entry);\n\n\tbuilder.setBuildPoint(entry);\n\tspv::Id ids[4];\n\tfor (unsigned i = 0; i < 4; i++)\n\t{\n\t\tauto broadcast = std::make_unique<spv::Instruction>(\n\t\t\t\tbuilder.getUniqueId(), bool_type, spv::OpGroupNonUniformQuadBroadcast);\n\t\tbroadcast->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tbroadcast->addIdOperand(func->getParamId(0));\n\t\tbroadcast->addIdOperand(builder.makeUintConstant(i));\n\t\tids[i] = broadcast->getResultId();\n\t\tadd_instruction(entry, std::move(broadcast));\n\t}\n\n\tspv::Op op = call == HelperCall::QuadAll ? spv::OpLogicalAnd : spv::OpLogicalOr;\n\n\tspv::Id ret_id = ids[0];\n\tfor (unsigned i = 1; i < 4; i++)\n\t{\n\t\tauto logic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, op);\n\t\tlogic_op->addIdOperand(ret_id);\n\t\tlogic_op->addIdOperand(ids[i]);\n\t\tret_id = logic_op->getResultId();\n\t\tadd_instruction(entry, std::move(logic_op));\n\t}\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformQuad);\n\tbuilder.makeReturn(false, ret_id);\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_quad_all(SPIRVModule &module)\n{\n\tif (quad_all_call_id)\n\t\treturn quad_all_call_id;\n\tquad_all_call_id = build_quad_vote(module, HelperCall::QuadAll);\n\treturn quad_all_call_id;\n}\n\nspv::Id SPIRVModule::Impl::build_quad_any(SPIRVModule &module)\n{\n\tif (quad_any_call_id)\n\t\treturn quad_any_call_id;\n\tquad_any_call_id = build_quad_vote(module, HelperCall::QuadAny);\n\treturn quad_any_call_id;\n}\n\nspv::Id SPIRVModule::Impl::build_image_atomic_r64_compact(\n\tSPIRVModule &module, bool array, bool non_uniform)\n{\n\tspv::Id *call_id;\n\tconst char *name;\n\tif (array)\n\t{\n\t\tif (non_uniform)\n\t\t{\n\t\t\tcall_id = &image_r64_array_atomic_non_uniform_call_id;\n\t\t\tname = \"WriteFeedbackArrayNonUniform\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcall_id = &image_r64_array_atomic_call_id;\n\t\t\tname = \"WriteFeedbackArray\";\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (non_uniform)\n\t\t{\n\t\t\tcall_id = &image_r64_atomic_non_uniform_call_id;\n\t\t\tname = \"WriteFeedbackNonUniform\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcall_id = &image_r64_atomic_call_id;\n\t\t\tname = \"WriteFeedback\";\n\t\t}\n\t}\n\n\tif (*call_id)\n\t\treturn *call_id;\n\n\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformArithmetic);\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Id image_type = builder.makeImageType(builder.makeUintType(64),\n\t                                           spv::Dim2D, false, array, false, 2, spv::ImageFormatR64ui);\n\tspv::Id ptr_image_type = builder.makePointer(spv::StorageClassUniformConstant, image_type);\n\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id int_type = builder.makeIntType(32);\n\tspv::Id coord_type = builder.makeVectorType(int_type, array ? 3 : 2);\n\tspv::Id bvec_type = builder.makeVectorType(bool_type, array ? 3 : 2);\n\tspv::Id u64_type = builder.makeUintType(64);\n\tspv::Id ptr_atomic_type = builder.makePointer(spv::StorageClassImage, u64_type);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(), name,\n\t                                       { ptr_image_type, coord_type, u64_type, bool_type }, {}, &entry);\n\n\tspv::Id image_ptr = func->getParamId(0);\n\tspv::Id coord = func->getParamId(1);\n\tspv::Id value = func->getParamId(2);\n\tspv::Id active = func->getParamId(3);\n\n\tbuilder.addName(image_ptr, \"img\");\n\tbuilder.addName(coord, \"coord\");\n\tbuilder.addName(value, \"value\");\n\tbuilder.addName(active, \"active_lane\");\n\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *loop_merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *loop_body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *loop_continue_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *write_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *write_merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *elect_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *elect_merge_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tbuilder.setBuildPoint(entry);\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(active, body_block, merge_block);\n\n\tspv::Id var_is_done = builder.createVariableWithInitializer(spv::StorageClassFunction, bool_type,\n\t                                                            builder.makeBoolConstant(false), \"is_done\");\n\n\tbuilder.setBuildPoint(body_block);\n\t{\n\t\tauto load = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLoad);\n\t\tauto inot = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLogicalNot);\n\t\tspv::Id inot_id = inot->getResultId();\n\t\tload->addIdOperand(var_is_done);\n\t\tinot->addIdOperand(load->getResultId());\n\t\tadd_instruction(body_block, std::move(load));\n\t\tadd_instruction(body_block, std::move(inot));\n\t\tbuilder.createLoopMerge(loop_merge_block, loop_continue_block, 0);\n\t\tbuilder.createConditionalBranch(inot_id, loop_body_block, loop_merge_block);\n\n\t\tbuilder.setBuildPoint(loop_body_block);\n\t\t{\n\t\t\tauto first = std::make_unique<spv::Instruction>(builder.getUniqueId(), coord_type, spv::OpGroupNonUniformBroadcastFirst);\n\t\t\tauto compare_coord = std::make_unique<spv::Instruction>(builder.getUniqueId(), bvec_type, spv::OpIEqual);\n\t\t\tauto all_equal = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpAll);\n\t\t\tauto store = std::make_unique<spv::Instruction>(spv::OpStore);\n\n\t\t\tfirst->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tfirst->addIdOperand(coord);\n\t\t\tcompare_coord->addIdOperand(coord);\n\t\t\tcompare_coord->addIdOperand(first->getResultId());\n\t\t\tall_equal->addIdOperand(compare_coord->getResultId());\n\t\t\tstore->addIdOperand(var_is_done);\n\t\t\tstore->addIdOperand(all_equal->getResultId());\n\n\t\t\tspv::Id cond_id = all_equal->getResultId();\n\t\t\tadd_instruction(loop_body_block, std::move(first));\n\t\t\tadd_instruction(loop_body_block, std::move(compare_coord));\n\t\t\tadd_instruction(loop_body_block, std::move(all_equal));\n\t\t\tadd_instruction(loop_body_block, std::move(store));\n\n\t\t\tbuilder.createSelectionMerge(write_merge_block, 0);\n\t\t\tbuilder.createConditionalBranch(cond_id, write_block, write_merge_block);\n\t\t\tbuilder.setBuildPoint(write_block);\n\t\t\t{\n\t\t\t\tauto or_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), u64_type, spv::OpGroupNonUniformBitwiseOr);\n\t\t\t\tauto elect = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpGroupNonUniformElect);\n\t\t\t\tor_op->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\t\tor_op->addImmediateOperand(spv::GroupOperationReduce);\n\t\t\t\tor_op->addIdOperand(value);\n\t\t\t\telect->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\t\tspv::Id elect_id = elect->getResultId();\n\t\t\t\tspv::Id or_op_id = or_op->getResultId();\n\t\t\t\tadd_instruction(write_block, std::move(or_op));\n\t\t\t\tadd_instruction(write_block, std::move(elect));\n\n\t\t\t\tbuilder.createSelectionMerge(elect_merge_block, 0);\n\t\t\t\tbuilder.createConditionalBranch(elect_id, elect_block, elect_merge_block);\n\t\t\t\tbuilder.setBuildPoint(elect_block);\n\t\t\t\t{\n\t\t\t\t\tauto texel = std::make_unique<spv::Instruction>(builder.getUniqueId(), ptr_atomic_type, spv::OpImageTexelPointer);\n\t\t\t\t\tif (non_uniform)\n\t\t\t\t\t\tbuilder.addDecoration(texel->getResultId(), spv::DecorationNonUniform);\n\t\t\t\t\tauto atomic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), u64_type, spv::OpAtomicOr);\n\t\t\t\t\ttexel->addIdOperand(image_ptr);\n\t\t\t\t\ttexel->addIdOperand(coord);\n\t\t\t\t\ttexel->addIdOperand(builder.makeIntConstant(0));\n\t\t\t\t\tatomic_op->addIdOperand(texel->getResultId());\n\t\t\t\t\tatomic_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\t\t\t\tatomic_op->addIdOperand(builder.makeUintConstant(0));\n\t\t\t\t\tatomic_op->addIdOperand(or_op_id);\n\t\t\t\t\tadd_instruction(elect_block, std::move(texel));\n\t\t\t\t\tadd_instruction(elect_block, std::move(atomic_op));\n\t\t\t\t\tbuilder.createBranch(elect_merge_block);\n\t\t\t\t}\n\n\t\t\t\tbuilder.setBuildPoint(elect_merge_block);\n\t\t\t\tbuilder.createBranch(write_merge_block);\n\t\t\t}\n\n\t\t\tbuilder.setBuildPoint(write_merge_block);\n\t\t\tbuilder.createBranch(loop_continue_block);\n\n\t\t\tbuilder.setBuildPoint(loop_continue_block);\n\t\t\tbuilder.createBranch(body_block);\n\t\t}\n\n\t\tbuilder.setBuildPoint(loop_merge_block);\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\tbuilder.makeReturn(false);\n\n\tbuilder.addCapability(spv::CapabilityInt64Atomics);\n\n\tbuilder.setBuildPoint(current_build_point);\n\t*call_id = func->getId();\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_node_coalesce_payload_offset(\n    SPIRVModule &module, const spv::Id *ids, uint32_t id_count)\n{\n\tif (id_count != 3)\n\t\treturn 0;\n\n\tif (node_coalesce_payload_offset_call_id)\n\t\treturn node_coalesce_payload_offset_call_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, uint_type,\n\t                                       \"NodeCoalescePayloadOffset\",\n\t                                       { uint_type, uvec2_type },\n\t                                       {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"offset\");\n\tbuilder.addName(func->getParamId(1), \"offsets_bda\");\n\n\tauto *is_entry_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *is_node_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge = new spv::Block(builder.getUniqueId(), *func);\n\n\tspv::Id is_entry_id = ids[0];\n\tspv::Id private_stride_var_id = ids[1];\n\tspv::Id u32_array_ptr_type_id = ids[2];\n\tspv::Id entry_result_id = 0;\n\tspv::Id node_result_id = 0;\n\n\tbuilder.setBuildPoint(entry);\n\tbuilder.createSelectionMerge(merge, 0);\n\tbuilder.createConditionalBranch(is_entry_id, is_entry_block, is_node_block);\n\n\tbuilder.setBuildPoint(is_entry_block);\n\t{\n\t\tauto load = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(), uint_type, spv::OpLoad);\n\t\tauto mul = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(), uint_type, spv::OpIMul);\n\n\t\tload->addIdOperand(private_stride_var_id);\n\t\tmul->addIdOperand(load->getResultId());\n\t\tmul->addIdOperand(func->getParamId(0));\n\n\t\tentry_result_id = mul->getResultId();\n\t\tadd_instruction(is_entry_block, std::move(load));\n\t\tadd_instruction(is_entry_block, std::move(mul));\n\t\tbuilder.createBranch(merge);\n\t}\n\n\tbuilder.setBuildPoint(is_node_block);\n\t{\n\t\tauto bitcast = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(), u32_array_ptr_type_id, spv::OpBitcast);\n\t\tauto chain = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(), builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t\t    spv::OpInBoundsAccessChain);\n\t\tauto load = std::make_unique<spv::Instruction>(\n\t\t\tbuilder.getUniqueId(), uint_type, spv::OpLoad);\n\n\t\tbitcast->addIdOperand(func->getParamId(1));\n\t\tchain->addIdOperand(bitcast->getResultId());\n\t\tchain->addIdOperand(builder.makeUintConstant(0));\n\t\tchain->addIdOperand(func->getParamId(0));\n\t\tload->addIdOperand(chain->getResultId());\n\t\tload->addImmediateOperand(spv::MemoryAccessAlignedMask);\n\t\tload->addImmediateOperand(sizeof(uint32_t));\n\t\tnode_result_id = load->getResultId();\n\t\tadd_instruction(is_node_block, std::move(bitcast));\n\t\tadd_instruction(is_node_block, std::move(chain));\n\t\tadd_instruction(is_node_block, std::move(load));\n\t\tbuilder.createBranch(merge);\n\t}\n\n\tbuilder.setBuildPoint(merge);\n\n\tauto phi = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpPhi);\n\tphi->addIdOperand(entry_result_id);\n\tphi->addIdOperand(is_entry_block->getId());\n\tphi->addIdOperand(node_result_id);\n\tphi->addIdOperand(is_node_block->getId());\n\tspv::Id return_value = phi->getResultId();\n\tadd_instruction(merge, std::move(phi));\n\tbuilder.makeReturn(false, return_value);\n\tnode_coalesce_payload_offset_call_id = func->getId();\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_allocate_node_records_waterfall(SPIRVModule &module)\n{\n\tif (allocate_thread_node_records_waterfall_call_id)\n\t\treturn allocate_thread_node_records_waterfall_call_id;\n\n\tspv::Id inner_call_id = module.get_helper_call_id(HelperCall::AllocateThreadNodeRecords);\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uint64_type = builder.makeUintType(64);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, uint_type,\n\t                                       \"AllocateThreadNodeRecordsWaterfall\",\n\t                                       { uint64_type, uint_type, uint_type, uint_type, uint_type },\n\t                                       {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"AtomicCountersBDA\");\n\tbuilder.addName(func->getParamId(1), \"NodeMetadataIndex\");\n\tbuilder.addName(func->getParamId(2), \"Count\");\n\tbuilder.addName(func->getParamId(3), \"Stride\");\n\tbuilder.addName(func->getParamId(4), \"AllocationOffset\");\n\n\tauto *loop_header = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *body_header = new spv::Block(builder.getUniqueId(), *func);\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *continue_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *body_merge = new spv::Block(builder.getUniqueId(), *func);\n\n\tbuilder.setBuildPoint(entry);\n\tbuilder.createBranch(loop_header);\n\n\tbuilder.setBuildPoint(loop_header);\n\tbuilder.createLoopMerge(merge_block, continue_block, 0);\n\tbuilder.createBranch(body_header);\n\n\tbuilder.setBuildPoint(body_header);\n\tauto broadcast = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpGroupNonUniformBroadcastFirst);\n\tbroadcast->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tbroadcast->addIdOperand(func->getParamId(1));\n\tspv::Id broadcast_id = broadcast->getResultId();\n\n\tauto do_work = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIEqual);\n\tdo_work->addIdOperand(broadcast->getResultId());\n\tdo_work->addIdOperand(func->getParamId(1));\n\tspv::Id do_work_cond_id = do_work->getResultId();\n\n\tadd_instruction(body_header, std::move(broadcast));\n\tadd_instruction(body_header, std::move(do_work));\n\tbuilder.createSelectionMerge(body_merge, 0);\n\tbuilder.createConditionalBranch(do_work_cond_id, body_block, body_merge);\n\n\tbuilder.setBuildPoint(body_block);\n\tspv::Id return_value;\n\t{\n\t\tauto call_inner = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpFunctionCall);\n\t\tcall_inner->addIdOperand(inner_call_id);\n\t\tcall_inner->addIdOperand(func->getParamId(0));\n\t\tcall_inner->addIdOperand(broadcast_id);\n\t\tcall_inner->addIdOperand(func->getParamId(2));\n\t\tcall_inner->addIdOperand(func->getParamId(3));\n\t\tcall_inner->addIdOperand(func->getParamId(4));\n\n\t\treturn_value = call_inner->getResultId();\n\t\tadd_instruction(body_block, std::move(call_inner));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(body_merge);\n\tbuilder.createBranch(continue_block);\n\tbuilder.setBuildPoint(continue_block);\n\tbuilder.createBranch(loop_header);\n\n\tbuilder.setBuildPoint(merge_block);\n\tbuilder.makeReturn(false, return_value);\n\tbuilder.setBuildPoint(current_build_point);\n\tallocate_thread_node_records_waterfall_call_id = func->getId();\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_increment_node_count(SPIRVModule &, bool per_thread)\n{\n\tauto &call_id = per_thread ? increment_thread_node_count_call_id : increment_group_node_count_call_id;\n\tif (call_id)\n\t\treturn call_id;\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uint64_type = builder.makeUintType(64);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(),\n\t                                       per_thread ? \"IncrementThreadNodeCount\" : \"IncrementGroupNodeCount\",\n\t                                       { uint64_type, uint_type, uint_type },\n\t                                       {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"AtomicCountersBDA\");\n\tbuilder.addName(func->getParamId(1), \"NodeMetadataIndex\");\n\tbuilder.addName(func->getParamId(2), \"Count\");\n\n\tspv::Id total_count_id = func->getParamId(2);\n\n\tspv::Block *body_block = nullptr;\n\tspv::Block *merge_block = nullptr;\n\n\tif (!per_thread)\n\t{\n\t\tbody_block = new spv::Block(builder.getUniqueId(), *func);\n\t\tmerge_block = new spv::Block(builder.getUniqueId(), *func);\n\t}\n\n\tspv::Id uint_array_type = builder.makeRuntimeArray(uint_type);\n\tbuilder.addDecoration(uint_array_type, spv::DecorationArrayStride, 4);\n\tspv::Id struct_type_id = builder.makeStructType({ uint_type, uint_type, uint_array_type }, \"NodeAtomicsEmpty\");\n\tbuilder.addDecoration(struct_type_id, spv::DecorationBlock);\n\tbuilder.addMemberName(struct_type_id, 0, \"payloadCount\");\n\tbuilder.addMemberName(struct_type_id, 1, \"fusedCount\");\n\tbuilder.addMemberName(struct_type_id, 2, \"perNodeTotal\");\n\tbuilder.addMemberDecoration(struct_type_id, 0, spv::DecorationOffset, 0);\n\tbuilder.addMemberDecoration(struct_type_id, 1, spv::DecorationOffset, 4);\n\tbuilder.addMemberDecoration(struct_type_id, 2, spv::DecorationOffset, 8);\n\n\tauto cast_op = std::make_unique<spv::Instruction>(\n\t    builder.getUniqueId(),\n\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, struct_type_id),\n\t    spv::OpBitcast);\n\tcast_op->addIdOperand(func->getParamId(0));\n\n\tauto chain_index_op = std::make_unique<spv::Instruction>(\n\t    builder.getUniqueId(),\n\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t    spv::OpInBoundsAccessChain);\n\tchain_index_op->addIdOperand(cast_op->getResultId());\n\tchain_index_op->addIdOperand(builder.makeUintConstant(2));\n\tchain_index_op->addIdOperand(func->getParamId(1));\n\n\tauto atomic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpAtomicIAdd);\n\tatomic_op->addIdOperand(chain_index_op->getResultId());\n\tatomic_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\tatomic_op->addIdOperand(builder.makeUintConstant(0)); // There is no implied sync.\n\tatomic_op->addIdOperand(total_count_id);\n\n\tauto *body = per_thread ? entry : body_block;\n\tadd_instruction(body, std::move(cast_op));\n\tadd_instruction(body, std::move(chain_index_op));\n\tadd_instruction(body, std::move(atomic_op));\n\n\tif (!per_thread)\n\t{\n\t\tspv::Id local_invocation_index = get_builtin_shader_input(spv::BuiltInLocalInvocationIndex);\n\t\tauto load_local_index = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpLoad);\n\t\tload_local_index->addIdOperand(local_invocation_index);\n\n\t\tauto is_first_lane = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIEqual);\n\t\tis_first_lane->addIdOperand(load_local_index->getResultId());\n\t\tis_first_lane->addIdOperand(builder.makeUintConstant(0));\n\t\tspv::Id is_first_lane_id = is_first_lane->getResultId();\n\t\tadd_instruction(entry, std::move(load_local_index));\n\t\tadd_instruction(entry, std::move(is_first_lane));\n\n\t\tbuilder.setBuildPoint(entry);\n\t\tbuilder.createSelectionMerge(merge_block, 0);\n\t\tbuilder.createConditionalBranch(is_first_lane_id, body_block, merge_block);\n\n\t\tbuilder.setBuildPoint(body_block);\n\t\tbuilder.createBranch(merge_block);\n\t\tbuilder.setBuildPoint(merge_block);\n\t\tbuilder.makeReturn(false);\n\t}\n\telse\n\t{\n\t\tbuilder.setBuildPoint(entry);\n\t\tbuilder.makeReturn(false);\n\t}\n\n\tbuilder.setBuildPoint(current_build_point);\n\tcall_id = func->getId();\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_allocate_node_records(SPIRVModule &, bool per_thread)\n{\n\tauto &call_id = per_thread ? allocate_thread_node_records_call_id : allocate_group_node_records_call_id;\n\tif (call_id)\n\t\treturn call_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uint64_type = builder.makeUintType(64);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, uint_type,\n\t                                       per_thread ? \"AllocateThreadNodeRecords\" : \"AllocateGroupNodeRecords\",\n\t                                       { uint64_type, uint_type, uint_type, uint_type, uint_type },\n\t                                       {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"AtomicCountersBDA\");\n\tbuilder.addName(func->getParamId(1), \"NodeMetadataIndex\");\n\tbuilder.addName(func->getParamId(2), \"Count\");\n\tbuilder.addName(func->getParamId(3), \"Stride\");\n\tbuilder.addName(func->getParamId(4), \"AllocationOffset\");\n\n\tspv::Id total_count_id;\n\tspv::Id phi_undefined_id = 0;\n\n\tif (per_thread)\n\t{\n\t\t// Do this on a per-wave basis. The node metadata index can be divergent, and we need to consider\n\t\t// that the outer function is a waterfall loop.\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\t\tbuilder.addCapability(spv::CapabilityGroupNonUniformArithmetic);\n\n\t\tauto counts_total =\n\t\t    std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpGroupNonUniformIAdd);\n\t\tcounts_total->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tcounts_total->addImmediateOperand(spv::GroupOperationReduce);\n\t\tcounts_total->addIdOperand(func->getParamId(2));\n\n\t\ttotal_count_id = counts_total->getResultId();\n\t\tadd_instruction(entry, std::move(counts_total));\n\n\t\tphi_undefined_id = builder.createUndefined(uint_type);\n\t}\n\telse\n\t{\n\t\ttotal_count_id = func->getParamId(2);\n\t}\n\n\tauto *return_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto check_empty = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIEqual);\n\tcheck_empty->addIdOperand(total_count_id);\n\tcheck_empty->addIdOperand(builder.makeUintConstant(0));\n\tspv::Id return_early_cond_id = check_empty->getResultId();\n\tadd_instruction(entry, std::move(check_empty));\n\n\tauto *reconverge_block = new spv::Block(builder.getUniqueId(), *func);\n\tbuilder.setBuildPoint(entry);\n\tbuilder.createSelectionMerge(reconverge_block, 0);\n\tbuilder.createConditionalBranch(return_early_cond_id, return_block, reconverge_block);\n\tbuilder.setBuildPoint(return_block);\n\tbuilder.makeReturn(false, builder.makeUintConstant(0));\n\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tspv::Id shared_id = 0;\n\tif (!per_thread)\n\t\tshared_id = create_variable(spv::StorageClassWorkgroup, uint_type, \"AllocateGroupNodeRecordsShared\");\n\n\tspv::Id is_first_lane_id;\n\n\tif (per_thread)\n\t{\n\t\tauto is_first_lane = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpGroupNonUniformElect);\n\t\tis_first_lane->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tis_first_lane_id = is_first_lane->getResultId();\n\t\tadd_instruction(reconverge_block, std::move(is_first_lane));\n\t}\n\telse\n\t{\n\t\tspv::Id local_invocation_index = get_builtin_shader_input(spv::BuiltInLocalInvocationIndex);\n\t\tauto load_local_index = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpLoad);\n\t\tload_local_index->addIdOperand(local_invocation_index);\n\n\t\tauto is_first_lane = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIEqual);\n\t\tis_first_lane->addIdOperand(load_local_index->getResultId());\n\t\tis_first_lane->addIdOperand(builder.makeUintConstant(0));\n\t\tis_first_lane_id = is_first_lane->getResultId();\n\t\tadd_instruction(reconverge_block, std::move(load_local_index));\n\t\tadd_instruction(reconverge_block, std::move(is_first_lane));\n\t}\n\n\tbuilder.setBuildPoint(reconverge_block);\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(is_first_lane_id, body_block, merge_block);\n\n\tspv::Id payload_offset_id;\n\tbuilder.setBuildPoint(body_block);\n\t{\n\t\t// Compute required payload bytes to allocate, and align.\n\t\tauto mul_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIMul);\n\t\tmul_op->addIdOperand(total_count_id);\n\t\tmul_op->addIdOperand(func->getParamId(3));\n\n\t\tauto add_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIAdd);\n\t\tadd_op->addIdOperand(mul_op->getResultId());\n\t\tadd_op->addIdOperand(builder.makeUintConstant(15));\n\n\t\tauto and_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpBitwiseAnd);\n\t\tand_op->addIdOperand(add_op->getResultId());\n\t\tand_op->addIdOperand(builder.makeUintConstant(~15u));\n\n\t\tspv::Id uint_array_type = builder.makeRuntimeArray(uint_type);\n\t\tbuilder.addDecoration(uint_array_type, spv::DecorationArrayStride, 4);\n\t\tspv::Id struct_type_id = builder.makeStructType({ uint_type, uint_type, uint_array_type }, \"NodeAtomics\");\n\t\tbuilder.addDecoration(struct_type_id, spv::DecorationBlock);\n\t\tbuilder.addMemberName(struct_type_id, 0, \"payloadCount\");\n\t\tbuilder.addMemberName(struct_type_id, 1, \"fusedCount\");\n\t\tbuilder.addMemberName(struct_type_id, 2, \"perNodeTotal\");\n\t\tbuilder.addMemberDecoration(struct_type_id, 0, spv::DecorationOffset, 0);\n\t\tbuilder.addMemberDecoration(struct_type_id, 1, spv::DecorationOffset, 4);\n\t\tbuilder.addMemberDecoration(struct_type_id, 2, spv::DecorationOffset, 8);\n\n\t\tauto cast_op = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(),\n\t\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, struct_type_id),\n\t\t    spv::OpBitcast);\n\t\tcast_op->addIdOperand(func->getParamId(0));\n\n\t\tauto chain_payload_total_op = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(),\n\t\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t\t    spv::OpInBoundsAccessChain);\n\t\tchain_payload_total_op->addIdOperand(cast_op->getResultId());\n\t\tchain_payload_total_op->addIdOperand(builder.makeUintConstant(0));\n\n\t\tauto chain_fused_total_op = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(),\n\t\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t\t    spv::OpInBoundsAccessChain);\n\t\tchain_fused_total_op->addIdOperand(cast_op->getResultId());\n\t\tchain_fused_total_op->addIdOperand(builder.makeUintConstant(1));\n\n\t\tauto payload_total_atomic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpAtomicIAdd);\n\t\tpayload_total_atomic_op->addIdOperand(chain_payload_total_op->getResultId());\n\t\tpayload_total_atomic_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tpayload_total_atomic_op->addIdOperand(builder.makeUintConstant(0)); // There is no implied sync.\n\t\tpayload_total_atomic_op->addIdOperand(and_op->getResultId());\n\n\t\tspv::Id node_index = func->getParamId(1);\n\n\t\tauto chain_node_total_op = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(),\n\t\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t\t    spv::OpInBoundsAccessChain);\n\t\tchain_node_total_op->addIdOperand(cast_op->getResultId());\n\t\tchain_node_total_op->addIdOperand(builder.makeUintConstant(2));\n\t\tchain_node_total_op->addIdOperand(node_index);\n\n\t\tauto atomic_total_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpAtomicIAdd);\n\t\tatomic_total_op->addIdOperand(chain_node_total_op->getResultId());\n\t\tatomic_total_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tatomic_total_op->addIdOperand(builder.makeUintConstant(0)); // There is no implied sync.\n\t\tatomic_total_op->addIdOperand(total_count_id);\n\n\t\tauto shift_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpShiftLeftLogical);\n\t\tshift_op->addIdOperand(node_index);\n\t\tshift_op->addIdOperand(builder.makeUintConstant(8));\n\n\t\tauto count_minus_1 = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpISub);\n\t\tcount_minus_1->addIdOperand(total_count_id);\n\t\tcount_minus_1->addIdOperand(builder.makeUintConstant(1));\n\n\t\tauto or_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpBitwiseOr);\n\t\tor_op->addIdOperand(shift_op->getResultId());\n\t\tor_op->addIdOperand(count_minus_1->getResultId());\n\n\t\tauto fused_atomic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpAtomicIIncrement);\n\t\tfused_atomic_op->addIdOperand(chain_fused_total_op->getResultId());\n\t\tfused_atomic_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tfused_atomic_op->addIdOperand(builder.makeUintConstant(0)); // There is no implied sync.\n\n\t\tauto fused_mul2 = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIMul);\n\t\tfused_mul2->addIdOperand(builder.makeUintConstant(2));\n\t\tfused_mul2->addIdOperand(fused_atomic_op->getResultId());\n\n\t\tauto payload_add_atomic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIAdd);\n\t\tpayload_add_atomic_op->addIdOperand(func->getParamId(4));\n\t\tpayload_add_atomic_op->addIdOperand(fused_mul2->getResultId());\n\n\t\tauto payload_add_atomic_op_plus_1 = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIAdd);\n\t\tpayload_add_atomic_op_plus_1->addIdOperand(payload_add_atomic_op->getResultId());\n\t\tpayload_add_atomic_op_plus_1->addIdOperand(builder.makeUintConstant(1));\n\n\t\tauto chain_payload_op = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(),\n\t\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t\t    spv::OpInBoundsAccessChain);\n\t\tchain_payload_op->addIdOperand(cast_op->getResultId());\n\t\tchain_payload_op->addIdOperand(builder.makeUintConstant(2));\n\t\tchain_payload_op->addIdOperand(payload_add_atomic_op->getResultId());\n\n\t\tauto store_payload_inst = std::make_unique<spv::Instruction>(spv::OpStore);\n\t\tstore_payload_inst->addIdOperand(chain_payload_op->getResultId());\n\t\tstore_payload_inst->addIdOperand(or_op->getResultId());\n\t\tstore_payload_inst->addImmediateOperand(spv::MemoryAccessAlignedMask);\n\t\tstore_payload_inst->addImmediateOperand(8);\n\n\t\tauto chain_payload_op_plus_1 = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(),\n\t\t    builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t\t    spv::OpInBoundsAccessChain);\n\t\tchain_payload_op_plus_1->addIdOperand(cast_op->getResultId());\n\t\tchain_payload_op_plus_1->addIdOperand(builder.makeUintConstant(2));\n\t\tchain_payload_op_plus_1->addIdOperand(payload_add_atomic_op_plus_1->getResultId());\n\n\t\tauto store_payload_inst_plus_1 = std::make_unique<spv::Instruction>(spv::OpStore);\n\t\tstore_payload_inst_plus_1->addIdOperand(chain_payload_op_plus_1->getResultId());\n\t\tstore_payload_inst_plus_1->addIdOperand(payload_total_atomic_op->getResultId());\n\t\tstore_payload_inst_plus_1->addImmediateOperand(spv::MemoryAccessAlignedMask);\n\t\tstore_payload_inst_plus_1->addImmediateOperand(4);\n\n\t\tpayload_offset_id = payload_total_atomic_op->getResultId();\n\n\t\tadd_instruction(body_block, std::move(mul_op));\n\t\tadd_instruction(body_block, std::move(add_op));\n\t\tadd_instruction(body_block, std::move(and_op));\n\t\tadd_instruction(body_block, std::move(cast_op));\n\t\tadd_instruction(body_block, std::move(chain_payload_total_op));\n\t\tadd_instruction(body_block, std::move(chain_fused_total_op));\n\t\tadd_instruction(body_block, std::move(payload_total_atomic_op));\n\t\tadd_instruction(body_block, std::move(chain_node_total_op));\n\t\tadd_instruction(body_block, std::move(shift_op));\n\t\tadd_instruction(body_block, std::move(count_minus_1));\n\t\tadd_instruction(body_block, std::move(or_op));\n\t\tadd_instruction(body_block, std::move(fused_atomic_op));\n\t\tadd_instruction(body_block, std::move(fused_mul2));\n\t\tadd_instruction(body_block, std::move(atomic_total_op));\n\t\tadd_instruction(body_block, std::move(payload_add_atomic_op));\n\t\tadd_instruction(body_block, std::move(payload_add_atomic_op_plus_1));\n\t\tadd_instruction(body_block, std::move(chain_payload_op));\n\t\tadd_instruction(body_block, std::move(store_payload_inst));\n\t\tadd_instruction(body_block, std::move(chain_payload_op_plus_1));\n\t\tadd_instruction(body_block, std::move(store_payload_inst_plus_1));\n\n\t\tif (!per_thread)\n\t\t{\n\t\t\tauto store_inst = std::make_unique<spv::Instruction>(spv::OpStore);\n\t\t\tstore_inst->addIdOperand(shared_id);\n\t\t\tstore_inst->addIdOperand(payload_offset_id);\n\t\t\tif (builder.hasCapability(spv::CapabilityVulkanMemoryModel))\n\t\t\t\tstore_inst->addImmediateOperand(spv::MemoryAccessNonPrivatePointerMask);\n\t\t\tadd_instruction(body_block, std::move(store_inst));\n\t\t}\n\n\t\tbuilder.createBranch(merge_block);\n\t}\n\tbuilder.setBuildPoint(merge_block);\n\n\tif (!per_thread)\n\t{\n\t\tauto barrier_op = std::make_unique<spv::Instruction>(spv::OpControlBarrier);\n\t\tbarrier_op->addIdOperand(builder.makeUintConstant(spv::ScopeWorkgroup));\n\t\tbarrier_op->addIdOperand(builder.makeUintConstant(spv::ScopeWorkgroup));\n\t\tbarrier_op->addIdOperand(builder.getWorkgroupBarrierSemanticsId());\n\t\tadd_instruction(merge_block, std::move(barrier_op));\n\t}\n\n\tspv::Id return_value;\n\n\tif (per_thread)\n\t{\n\t\tauto counts_offsets =\n\t\t    std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpGroupNonUniformIAdd);\n\t\tcounts_offsets->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tcounts_offsets->addImmediateOperand(spv::GroupOperationExclusiveScan);\n\t\tcounts_offsets->addIdOperand(func->getParamId(2));\n\n\t\tauto phi_node = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpPhi);\n\t\tphi_node->addIdOperand(payload_offset_id);\n\t\tphi_node->addIdOperand(body_block->getId());\n\t\tphi_node->addIdOperand(phi_undefined_id);\n\t\tphi_node->addIdOperand(reconverge_block->getId());\n\n\t\tauto broadcast_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpGroupNonUniformBroadcastFirst);\n\t\tbroadcast_op->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\tbroadcast_op->addIdOperand(phi_node->getResultId());\n\n\t\tauto mul_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIMul);\n\t\tmul_op->addIdOperand(counts_offsets->getResultId());\n\t\tmul_op->addIdOperand(func->getParamId(3));\n\n\t\tauto add_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIAdd);\n\t\tadd_op->addIdOperand(broadcast_op->getResultId());\n\t\tadd_op->addIdOperand(mul_op->getResultId());\n\n\t\treturn_value = add_op->getResultId();\n\n\t\tadd_instruction(merge_block, std::move(phi_node));\n\t\tadd_instruction(merge_block, std::move(broadcast_op));\n\t\tadd_instruction(merge_block, std::move(counts_offsets));\n\t\tadd_instruction(merge_block, std::move(mul_op));\n\t\tadd_instruction(merge_block, std::move(add_op));\n\t}\n\telse\n\t{\n\t\tauto load_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpLoad);\n\t\tload_op->addIdOperand(shared_id);\n\t\tif (builder.hasCapability(spv::CapabilityVulkanMemoryModel))\n\t\t\tload_op->addImmediateOperand(spv::MemoryAccessNonPrivatePointerMask);\n\t\treturn_value = load_op->getResultId();\n\t\tadd_instruction(merge_block, std::move(load_op));\n\t}\n\n\tif (!per_thread)\n\t{\n\t\t// Avoid WAR hazard for back-to-back allocations.\n\t\tauto barrier_op = std::make_unique<spv::Instruction>(spv::OpControlBarrier);\n\t\tbarrier_op->addIdOperand(builder.makeUintConstant(spv::ScopeWorkgroup));\n\t\tbarrier_op->addIdOperand(builder.makeUintConstant(spv::ScopeWorkgroup));\n\t\tbarrier_op->addIdOperand(builder.makeUintConstant(\n\t\t    spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsWorkgroupMemoryMask));\n\t\tadd_instruction(merge_block, std::move(barrier_op));\n\t}\n\n\tbuilder.makeReturn(false, return_value);\n\tbuilder.setBuildPoint(current_build_point);\n\tcall_id = func->getId();\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_finish_cross_group_sharing(SPIRVModule &module)\n{\n\tif (finish_cross_group_sharing_call_id)\n\t\treturn finish_cross_group_sharing_call_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uint64_type = builder.makeUintType(64);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, bool_type,\n\t                                       \"FinishCrossGroupSharing\",\n\t                                       { uint64_type }, {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"CounterBDA\");\n\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tspv::Id local_invocation_index = get_builtin_shader_input(spv::BuiltInLocalInvocationIndex);\n\tspv::Id shared_id = create_variable(spv::StorageClassWorkgroup, bool_type, \"FinishCrossGroupSharingBroadcast\");\n\n\tauto load_local_index = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpLoad);\n\tload_local_index->addIdOperand(local_invocation_index);\n\n\tauto is_first_lane = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIEqual);\n\tis_first_lane->addIdOperand(load_local_index->getResultId());\n\tis_first_lane->addIdOperand(builder.makeUintConstant(0));\n\tspv::Id cond_id = is_first_lane->getResultId();\n\n\tadd_instruction(entry, std::move(load_local_index));\n\tadd_instruction(entry, std::move(is_first_lane));\n\tbuilder.setBuildPoint(entry);\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(cond_id, body_block, merge_block);\n\n\tbuilder.setBuildPoint(body_block);\n\t{\n\t\tauto cast_op = std::make_unique<spv::Instruction>(\n\t\t\tbuilder.getUniqueId(),\n\t\t\tbuilder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type),\n\t\t\tspv::OpBitcast);\n\t\tcast_op->addIdOperand(func->getParamId(0));\n\n\t\tauto atomic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpAtomicIDecrement);\n\t\tatomic_op->addIdOperand(cast_op->getResultId());\n\t\tatomic_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tatomic_op->addIdOperand(builder.makeUintConstant(0)); // There is no implied sync.\n\n\t\tauto is_last_wg = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIEqual);\n\t\tis_last_wg->addIdOperand(atomic_op->getResultId());\n\t\tis_last_wg->addIdOperand(builder.makeUintConstant(1));\n\n\t\tauto store_inst = std::make_unique<spv::Instruction>(spv::OpStore);\n\t\tstore_inst->addIdOperand(shared_id);\n\t\tstore_inst->addIdOperand(is_last_wg->getResultId());\n\t\tif (builder.hasCapability(spv::CapabilityVulkanMemoryModel))\n\t\t\tstore_inst->addImmediateOperand(spv::MemoryAccessNonPrivatePointerMask);\n\n\t\tadd_instruction(body_block, std::move(cast_op));\n\t\tadd_instruction(body_block, std::move(atomic_op));\n\t\tadd_instruction(body_block, std::move(is_last_wg));\n\t\tadd_instruction(body_block, std::move(store_inst));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\tbuilder.setBuildPoint(merge_block);\n\n\t// We don't need double barrier since FinishGroupSharing can only be called once.\n\t// There is no risk of WAR hazard on the same shared memory.\n\tauto barrier_op = std::make_unique<spv::Instruction>(spv::OpControlBarrier);\n\tbarrier_op->addIdOperand(builder.makeUintConstant(spv::ScopeWorkgroup));\n\tbarrier_op->addIdOperand(builder.makeUintConstant(spv::ScopeWorkgroup));\n\tbarrier_op->addIdOperand(builder.getWorkgroupBarrierSemanticsId());\n\n\tauto load_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLoad);\n\tload_op->addIdOperand(shared_id);\n\tif (builder.hasCapability(spv::CapabilityVulkanMemoryModel))\n\t\tload_op->addImmediateOperand(spv::MemoryAccessNonPrivatePointerMask);\n\n\tspv::Id return_value = load_op->getResultId();\n\tadd_instruction(merge_block, std::move(barrier_op));\n\tadd_instruction(merge_block, std::move(load_op));\n\n\tbuilder.makeReturn(false, return_value);\n\tbuilder.setBuildPoint(current_build_point);\n\tfinish_cross_group_sharing_call_id = func->getId();\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_robust_atomic_counter_op(SPIRVModule &module)\n{\n\tif (robust_atomic_counter_call_id)\n\t\treturn robust_atomic_counter_call_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id bda_type = builder.makeVectorType(uint_type, 2);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, uint_type,\n\t                                       \"RobustPhysicalAtomicCounter\",\n\t                                       { bda_type, uint_type, uint_type }, {}, &entry);\n\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id bvec2_type = builder.makeVectorType(bool_type, 2);\n\n\tspv::Id null_bda = builder.makeNullConstant(bda_type);\n\tauto compare = std::make_unique<spv::Instruction>(builder.getUniqueId(), bvec2_type, spv::OpINotEqual);\n\tcompare->addIdOperand(func->getParamId(0));\n\tcompare->addIdOperand(null_bda);\n\tauto not_zero = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpAny);\n\tnot_zero->addIdOperand(compare->getResultId());\n\tspv::Id cond_id = not_zero->getResultId();\n\tadd_instruction(entry, std::move(compare));\n\tadd_instruction(entry, std::move(not_zero));\n\tbuilder.setBuildPoint(entry);\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(cond_id, body_block, merge_block);\n\n\tspv::Id loaded_id;\n\t{\n\t\tbuilder.setBuildPoint(body_block);\n\t\tspv::Id uint_ptr_type = builder.makePointer(spv::StorageClassPhysicalStorageBuffer, uint_type);\n\t\tauto bitcast_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_ptr_type, spv::OpBitcast);\n\t\tbitcast_op->addIdOperand(func->getParamId(0));\n\t\tauto atomic_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpAtomicIAdd);\n\t\tatomic_op->addIdOperand(bitcast_op->getResultId());\n\t\tatomic_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tatomic_op->addIdOperand(builder.makeUintConstant(0));\n\t\tatomic_op->addIdOperand(func->getParamId(1));\n\t\tauto add_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpIAdd);\n\t\tadd_op->addIdOperand(atomic_op->getResultId());\n\t\tadd_op->addIdOperand(func->getParamId(2));\n\t\tloaded_id = add_op->getResultId();\n\t\tadd_instruction(body_block, std::move(bitcast_op));\n\t\tadd_instruction(body_block, std::move(atomic_op));\n\t\tadd_instruction(body_block, std::move(add_op));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\tauto phi_op = std::make_unique<spv::Instruction>(\n\t    builder.getUniqueId(), uint_type, spv::OpPhi);\n\tphi_op->addIdOperand(builder.makeUintConstant(0));\n\tphi_op->addIdOperand(entry->getId());\n\tphi_op->addIdOperand(loaded_id);\n\tphi_op->addIdOperand(body_block->getId());\n\tspv::Id return_value = phi_op->getResultId();\n\tadd_instruction(merge_block, std::move(phi_op));\n\tbuilder.makeReturn(false, return_value);\n\n\tbuilder.setBuildPoint(current_build_point);\n\trobust_atomic_counter_call_id = func->getId();\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_robust_physical_cbv_load(SPIRVModule &module, spv::Id type_id, spv::Id ptr_type_id,\n                                                          unsigned alignment)\n{\n\tfor (auto &func : physical_cbv_call_ids)\n\t\tif (func.ptr_type_id == ptr_type_id && func.type_id == type_id && func.alignment == alignment)\n\t\t\treturn func.func_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id bda_type = builder.makeVectorType(uint_type, 2);\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, type_id,\n\t\t\t\t\t\t\t\t\t\t   \"RobustPhysicalCBVLoad\",\n\t\t\t\t\t\t\t\t\t\t   { bda_type, uint_type }, {}, &entry);\n\n\tspv::Id bda_value_id = func->getParamId(0);\n\tspv::Id index_id = func->getParamId(1);\n\n\tauto *body_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tbuilder.setBuildPoint(entry);\n\tauto compare = std::make_unique<spv::Instruction>(builder.getUniqueId(), builder.makeBoolType(), spv::OpULessThan);\n\tcompare->addIdOperand(index_id);\n\tcompare->addIdOperand(builder.makeUintConstant(64 * 1024 / alignment));\n\tspv::Id compare_id = compare->getResultId();\n\tadd_instruction(entry, std::move(compare));\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(compare_id, body_block, merge_block);\n\n\tspv::Id loaded_id;\n\t{\n\t\tbuilder.setBuildPoint(body_block);\n\t\tauto bitcast_op = std::make_unique<spv::Instruction>(\n\t\t\t\tbuilder.getUniqueId(), ptr_type_id, spv::OpBitcast);\n\t\tauto chain_op = std::make_unique<spv::Instruction>(\n\t\t\t\tbuilder.getUniqueId(),\n\t\t\t\tbuilder.makePointer(spv::StorageClassPhysicalStorageBuffer, type_id),\n\t\t\t\tspv::OpInBoundsAccessChain);\n\t\tauto load_op = std::make_unique<spv::Instruction>(\n\t\t\t\tbuilder.getUniqueId(), type_id, spv::OpLoad);\n\t\tbitcast_op->addIdOperand(bda_value_id);\n\t\tchain_op->addIdOperand(bitcast_op->getResultId());\n\t\tchain_op->addIdOperand(builder.makeUintConstant(0));\n\t\tchain_op->addIdOperand(index_id);\n\t\tload_op->addIdOperand(chain_op->getResultId());\n\t\tload_op->addImmediateOperand(spv::MemoryAccessAlignedMask);\n\t\tload_op->addImmediateOperand(alignment);\n\t\tloaded_id = load_op->getResultId();\n\t\tadd_instruction(body_block, std::move(bitcast_op));\n\t\tadd_instruction(body_block, std::move(chain_op));\n\t\tadd_instruction(body_block, std::move(load_op));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\tauto phi_op = std::make_unique<spv::Instruction>(\n\t\t\tbuilder.getUniqueId(), type_id, spv::OpPhi);\n\tphi_op->addIdOperand(builder.makeNullConstant(type_id));\n\tphi_op->addIdOperand(entry->getId());\n\tphi_op->addIdOperand(loaded_id);\n\tphi_op->addIdOperand(body_block->getId());\n\tspv::Id return_value = phi_op->getResultId();\n\tadd_instruction(merge_block, std::move(phi_op));\n\tbuilder.makeReturn(false, return_value);\n\n\tbuilder.setBuildPoint(current_build_point);\n\tphysical_cbv_call_ids.push_back({ type_id, ptr_type_id, alignment, func->getId() });\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_is_quad_uniform_control_flow(SPIRVModule &module)\n{\n\tif (is_quad_uniform_call_id)\n\t\treturn is_quad_uniform_call_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec4_type = builder.makeVectorType(uint_type, 4);\n\tspv::Id bool_type = builder.makeBoolType();\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, bool_type,\n\t                                       \"IsQuadUniformControlFlow\",\n\t                                       {}, {}, &entry);\n\n\tauto ballot_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpGroupNonUniformBallot);\n\tballot_op->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\tballot_op->addIdOperand(builder.makeBoolConstant(true));\n\n\tspv::Id uint_2 = builder.makeUintConstant(2);\n\tspv::Id uint_1 = builder.makeUintConstant(1);\n\tuint_2 = builder.makeCompositeConstant(uvec4_type, { uint_2, uint_2, uint_2, uint_2 });\n\tuint_1 = builder.makeCompositeConstant(uvec4_type, { uint_1, uint_1, uint_1, uint_1 });\n\n\tauto shift_2 = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpShiftRightLogical);\n\tshift_2->addIdOperand(ballot_op->getResultId());\n\tshift_2->addIdOperand(uint_2);\n\tauto and_2 = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpBitwiseAnd);\n\tand_2->addIdOperand(ballot_op->getResultId());\n\tand_2->addIdOperand(shift_2->getResultId());\n\tauto shift_1 = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpShiftRightLogical);\n\tshift_1->addIdOperand(and_2->getResultId());\n\tshift_1->addIdOperand(uint_1);\n\tauto and_1 = std::make_unique<spv::Instruction>(builder.getUniqueId(), uvec4_type, spv::OpBitwiseAnd);\n\tand_1->addIdOperand(and_2->getResultId());\n\tand_1->addIdOperand(shift_1->getResultId());\n\n\tauto load_invocation_id = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpLoad);\n\tload_invocation_id->addIdOperand(get_builtin_shader_input(spv::BuiltInSubgroupLocalInvocationId));\n\n\tauto and_invocation_id = std::make_unique<spv::Instruction>(builder.getUniqueId(), uint_type, spv::OpBitwiseAnd);\n\tand_invocation_id->addIdOperand(load_invocation_id->getResultId());\n\tand_invocation_id->addIdOperand(builder.makeUintConstant(~3u));\n\n\tauto extract_op = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpGroupNonUniformBallotBitExtract);\n\textract_op->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\textract_op->addIdOperand(and_1->getResultId());\n\textract_op->addIdOperand(and_invocation_id->getResultId());\n\tspv::Id result_id = extract_op->getResultId();\n\n\tentry->addInstruction(std::move(ballot_op));\n\tentry->addInstruction(std::move(shift_2));\n\tentry->addInstruction(std::move(and_2));\n\tentry->addInstruction(std::move(shift_1));\n\tentry->addInstruction(std::move(and_1));\n\tentry->addInstruction(std::move(load_invocation_id));\n\tentry->addInstruction(std::move(and_invocation_id));\n\tentry->addInstruction(std::move(extract_op));\n\n\tbuilder.makeReturn(false, result_id);\n\tbuilder.setBuildPoint(current_build_point);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniformBallot);\n\tbuilder.addCapability(spv::CapabilityGroupNonUniform);\n\n\tis_quad_uniform_call_id = func->getId();\n\treturn is_quad_uniform_call_id;\n}\n\nspv::Id SPIRVModule::Impl::build_coop_mat_saturation_fixup(SPIRVModule &module, spv::Id type_id)\n{\n\tfor (auto &ops : coop_mat_conv_ids)\n\t\tif (ops.output_type == type_id && ops.input_type == type_id && ops.call == HelperCall::CoopMatSaturationFixup)\n\t\t\treturn ops.func_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id bool_type = builder.makeBoolType();\n\n\t// RADV workaround. It fails to understand coopmat passed as value.\n\tspv::Id input_ptr_type = builder.makePointer(spv::StorageClassFunction, type_id);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, type_id,\n\t                                       \"CoopMatSaturationFixup\",\n\t                                       { input_ptr_type }, {}, &entry);\n\n\tspv::Id output_id = create_variable(spv::StorageClassFunction, type_id, \"coop_output\");\n\tauto *len = builder.addInstruction(uint_type, spv::OpCooperativeMatrixLengthKHR);\n\tlen->addIdOperand(type_id);\n\n\tauto *header = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge = new spv::Block(builder.getUniqueId(), *func);\n\tbuilder.createBranch(header);\n\tbuilder.setBuildPoint(header);\n\n\tunsigned bits = builder.getScalarTypeWidth(builder.getContainedTypeId(type_id));\n\n\t{\n\t\tauto *phi = builder.addInstruction(uint_type, spv::OpPhi);\n\t\tauto *iter = builder.addInstruction(uint_type, spv::OpIAdd);\n\t\titer->addIdOperand(phi->getResultId());\n\t\titer->addIdOperand(builder.makeUintConstant(1));\n\n\t\tphi->addIdOperand(builder.makeUintConstant(0));\n\t\tphi->addIdOperand(entry->getId());\n\t\tphi->addIdOperand(iter->getResultId());\n\t\tphi->addIdOperand(header->getId());\n\n\t\tauto *input_chain = builder.addInstruction(\n\t\t    builder.makePointer(spv::StorageClassFunction, builder.getContainedTypeId(type_id)), spv::OpInBoundsAccessChain);\n\t\tinput_chain->addIdOperand(func->getParamId(0));\n\t\tinput_chain->addIdOperand(phi->getResultId());\n\n\t\tauto *load = builder.addInstruction(builder.getContainedTypeId(type_id), spv::OpLoad);\n\t\tload->addIdOperand(input_chain->getResultId());\n\n\t\tauto *is_inf = builder.addInstruction(builder.makeBoolType(), spv::OpIsInf);\n\t\tis_inf->addIdOperand(load->getResultId());\n\n\t\tauto *select = builder.addInstruction(builder.getContainedTypeId(type_id), spv::OpSelect);\n\t\tselect->addIdOperand(is_inf->getResultId());\n\t\tif (bits == 32)\n\t\t\tselect->addIdOperand(builder.makeFloatConstant(std::numeric_limits<float>::quiet_NaN()));\n\t\telse\n\t\t\tselect->addIdOperand(builder.makeFloat16Constant(0xffff));\n\t\tselect->addIdOperand(load->getResultId());\n\n\t\tauto *output_chain = builder.addInstruction(\n\t\t    builder.makePointer(spv::StorageClassFunction, builder.getContainedTypeId(type_id)), spv::OpInBoundsAccessChain);\n\t\toutput_chain->addIdOperand(output_id);\n\t\toutput_chain->addIdOperand(phi->getResultId());\n\t\tauto *store = builder.addInstruction(spv::OpStore);\n\t\tstore->addIdOperand(output_chain->getResultId());\n\t\tstore->addIdOperand(select->getResultId());\n\n\t\tauto *cmp = builder.addInstruction(bool_type, spv::OpULessThan);\n\t\tcmp->addIdOperand(iter->getResultId());\n\t\tcmp->addIdOperand(len->getResultId());\n\t\tbuilder.createLoopMerge(merge, header, 0);\n\t\tbuilder.createConditionalBranch(cmp->getResultId(), header, merge);\n\t}\n\n\tbuilder.setBuildPoint(merge);\n\tauto *loaded_result = builder.addInstruction(type_id, spv::OpLoad);\n\tloaded_result->addIdOperand(output_id);\n\tbuilder.makeReturn(false, loaded_result->getResultId());\n\tbuilder.setBuildPoint(current_build_point);\n\tcoop_mat_conv_ids.push_back({ type_id, type_id, func->getId(), HelperCall::CoopMatSaturationFixup });\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_coop_mat_transfer(SPIRVModule &module, const spv::Id *ids, uint32_t id_count)\n{\n\tif (id_count != 2)\n\t\treturn 0;\n\n\tspv::Id input_type = ids[0];\n\tspv::Id output_type = ids[1];\n\tfor (auto &ops : coop_mat_conv_ids)\n\t\tif (ops.output_type == output_type && ops.input_type == input_type && ops.call == HelperCall::CoopMatTransfer)\n\t\t\treturn ops.func_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id bool_type = builder.makeBoolType();\n\n\t// RADV workaround. It fails to understand coopmat passed as value.\n\tspv::Id input_ptr_type = builder.makePointer(spv::StorageClassFunction, input_type);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, output_type,\n\t                                       \"CoopMatTransfer\",\n\t                                       { input_ptr_type }, {}, &entry);\n\n\tspv::Id output_id = create_variable(spv::StorageClassFunction, output_type, \"coop_output\");\n\tauto *len = builder.addInstruction(uint_type, spv::OpCooperativeMatrixLengthKHR);\n\tlen->addIdOperand(output_type);\n\n\tauto *header = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge = new spv::Block(builder.getUniqueId(), *func);\n\tbuilder.createBranch(header);\n\tbuilder.setBuildPoint(header);\n\t{\n\t\tauto *phi = builder.addInstruction(uint_type, spv::OpPhi);\n\t\tauto *iter = builder.addInstruction(uint_type, spv::OpIAdd);\n\t\titer->addIdOperand(phi->getResultId());\n\t\titer->addIdOperand(builder.makeUintConstant(1));\n\n\t\tphi->addIdOperand(builder.makeUintConstant(0));\n\t\tphi->addIdOperand(entry->getId());\n\t\tphi->addIdOperand(iter->getResultId());\n\t\tphi->addIdOperand(header->getId());\n\n\t\tauto *input_chain = builder.addInstruction(\n\t\t    builder.makePointer(spv::StorageClassFunction, builder.getContainedTypeId(input_type)), spv::OpInBoundsAccessChain);\n\t\tinput_chain->addIdOperand(func->getParamId(0));\n\t\tinput_chain->addIdOperand(phi->getResultId());\n\n\t\tauto *load = builder.addInstruction(builder.getContainedTypeId(input_type), spv::OpLoad);\n\t\tload->addIdOperand(input_chain->getResultId());\n\n\t\tauto *output_chain = builder.addInstruction(\n\t\t    builder.makePointer(spv::StorageClassFunction, builder.getContainedTypeId(output_type)), spv::OpInBoundsAccessChain);\n\t\toutput_chain->addIdOperand(output_id);\n\t\toutput_chain->addIdOperand(phi->getResultId());\n\t\tauto *store = builder.addInstruction(spv::OpStore);\n\t\tstore->addIdOperand(output_chain->getResultId());\n\t\tstore->addIdOperand(load->getResultId());\n\n\t\tauto *cmp = builder.addInstruction(bool_type, spv::OpULessThan);\n\t\tcmp->addIdOperand(iter->getResultId());\n\t\tcmp->addIdOperand(len->getResultId());\n\t\tbuilder.createLoopMerge(merge, header, 0);\n\t\tbuilder.createConditionalBranch(cmp->getResultId(), header, merge);\n\t}\n\n\tbuilder.setBuildPoint(merge);\n\tauto *loaded_result = builder.addInstruction(output_type, spv::OpLoad);\n\tloaded_result->addIdOperand(output_id);\n\tbuilder.makeReturn(false, loaded_result->getResultId());\n\tbuilder.setBuildPoint(current_build_point);\n\tcoop_mat_conv_ids.push_back({ input_type, output_type, func->getId(), HelperCall::CoopMatTransfer });\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_coop_mat_saturate_fp8(SPIRVModule &module, spv::Id type_id)\n{\n\tfor (auto &ops : coop_mat_conv_ids)\n\t\tif (ops.output_type == type_id && ops.input_type == type_id && ops.call == HelperCall::CoopMatSaturateFP8)\n\t\t\treturn ops.func_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id bool_type = builder.makeBoolType();\n\n\t// RADV workaround. It fails to understand coopmat passed as value.\n\tspv::Id f16_ptr_type = builder.makePointer(spv::StorageClassFunction, type_id);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, type_id,\n\t                                       \"CoopMatSaturateFP8\",\n\t                                       { f16_ptr_type }, {}, &entry);\n\n\tspv::Id output_id = create_variable(spv::StorageClassFunction, type_id, \"coop_output\");\n\tauto *len = builder.addInstruction(uint_type, spv::OpCooperativeMatrixLengthKHR);\n\tlen->addIdOperand(type_id);\n\n\tauto *header = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge = new spv::Block(builder.getUniqueId(), *func);\n\tbuilder.createBranch(header);\n\tbuilder.setBuildPoint(header);\n\t{\n\t\tauto *phi = builder.addInstruction(uint_type, spv::OpPhi);\n\t\tauto *iter = builder.addInstruction(uint_type, spv::OpIAdd);\n\t\titer->addIdOperand(phi->getResultId());\n\t\titer->addIdOperand(builder.makeUintConstant(1));\n\n\t\tphi->addIdOperand(builder.makeUintConstant(0));\n\t\tphi->addIdOperand(entry->getId());\n\t\tphi->addIdOperand(iter->getResultId());\n\t\tphi->addIdOperand(header->getId());\n\n\t\tauto *input_chain = builder.addInstruction(\n\t\t    builder.makePointer(spv::StorageClassFunction, builder.makeFloatType(16)), spv::OpInBoundsAccessChain);\n\t\tinput_chain->addIdOperand(func->getParamId(0));\n\t\tinput_chain->addIdOperand(phi->getResultId());\n\n\t\tauto *load = builder.addInstruction(builder.makeFloatType(16), spv::OpLoad);\n\t\tload->addIdOperand(input_chain->getResultId());\n\n\t\tspv::Id glsl450 = builder.import(\"GLSL.std.450\");\n\t\tauto *clamp = builder.addInstruction(builder.makeFloatType(16), spv::OpExtInst);\n\t\tclamp->addIdOperand(glsl450);\n\t\tclamp->addImmediateOperand(GLSLstd450NClamp);\n\t\tclamp->addIdOperand(load->getResultId());\n\t\tclamp->addIdOperand(builder.makeFloat16Constant(0x5f00 | 0x8000));\n\t\tclamp->addIdOperand(builder.makeFloat16Constant(0x5f00)); // 448.0.\n\n\t\tauto *output_chain = builder.addInstruction(\n\t\t    builder.makePointer(spv::StorageClassFunction, builder.makeFloatType(16)), spv::OpInBoundsAccessChain);\n\t\toutput_chain->addIdOperand(output_id);\n\t\toutput_chain->addIdOperand(phi->getResultId());\n\t\tauto *store = builder.addInstruction(spv::OpStore);\n\t\tstore->addIdOperand(output_chain->getResultId());\n\t\tstore->addIdOperand(clamp->getResultId());\n\n\t\tauto *cmp = builder.addInstruction(bool_type, spv::OpULessThan);\n\t\tcmp->addIdOperand(iter->getResultId());\n\t\tcmp->addIdOperand(len->getResultId());\n\t\tbuilder.createLoopMerge(merge, header, 0);\n\t\tbuilder.createConditionalBranch(cmp->getResultId(), header, merge);\n\t}\n\n\tbuilder.setBuildPoint(merge);\n\tauto *loaded_result = builder.addInstruction(type_id, spv::OpLoad);\n\tloaded_result->addIdOperand(output_id);\n\tbuilder.makeReturn(false, loaded_result->getResultId());\n\tbuilder.setBuildPoint(current_build_point);\n\tcoop_mat_conv_ids.push_back({ type_id, type_id, func->getId(), HelperCall::CoopMatSaturateFP8 });\n\treturn func->getId();\n}\n\nstatic spv::Id make_i16vec2_constant(spv::Builder &builder, int16_t val)\n{\n\tspv::Id constant = builder.makeInt16Constant(val);\n\tspv::Id s16vec2_type = builder.makeVectorType(builder.makeIntType(16), 2);\n\treturn builder.makeCompositeConstant(s16vec2_type, { constant, constant });\n}\n\nstatic spv::Id make_u16vec2_constant(spv::Builder &builder, uint16_t val)\n{\n\tspv::Id constant = builder.makeUint16Constant(val);\n\tspv::Id s16vec2_type = builder.makeVectorType(builder.makeUintType(16), 2);\n\treturn builder.makeCompositeConstant(s16vec2_type, { constant, constant });\n}\n\nspv::Id SPIRVModule::Impl::build_coop_mat_fp16_to_fp8(SPIRVModule &module, const spv::Id *ids, uint32_t id_count)\n{\n\tif (id_count != 2)\n\t\treturn 0;\n\n\tspv::Id u8mat_type = ids[0];\n\tspv::Id f16mat_type = ids[1];\n\n\tfor (auto &ops : coop_mat_conv_ids)\n\t\tif (ops.output_type == u8mat_type && ops.input_type == f16mat_type && ops.call == HelperCall::CoopMatFP16toFP8)\n\t\t\treturn ops.func_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id f16_type = builder.makeFloatType(16);\n\tspv::Id s16_type = builder.makeIntType(16);\n\tspv::Id u8_type = builder.makeUintType(8);\n\n\tspv::Id bvec2_type = builder.makeVectorType(bool_type, 2);\n\tspv::Id f16vec2_type = builder.makeVectorType(f16_type, 2);\n\tspv::Id s16vec2_type = builder.makeVectorType(s16_type, 2);\n\tspv::Id u8vec2_type = builder.makeVectorType(u8_type, 2);\n\n\t// RADV workaround. It fails to understand coopmat passed as value.\n\tspv::Id f16_ptr_type = builder.makePointer(spv::StorageClassFunction, f16mat_type);\n\n\tauto *func =\n\t    builder.makeFunctionEntry(spv::NoPrecision, u8mat_type, \"CoopMatFP16toFP8\", { f16_ptr_type }, {}, &entry);\n\n\tspv::Id output_id = create_variable(spv::StorageClassFunction, u8mat_type, \"coop_output\");\n\tauto *len = builder.addInstruction(uint_type, spv::OpCooperativeMatrixLengthKHR);\n\tlen->addIdOperand(u8mat_type);\n\n\tauto *header = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge = new spv::Block(builder.getUniqueId(), *func);\n\tbuilder.createBranch(header);\n\tbuilder.setBuildPoint(header);\n\t{\n\t\tauto *phi = builder.addInstruction(uint_type, spv::OpPhi);\n\t\tauto *iter = builder.addInstruction(uint_type, spv::OpIAdd);\n\t\titer->addIdOperand(phi->getResultId());\n\t\t// Process two elemts at once because AMD has i16vec2 instructions\n\t\t// Assume coop mat length is always a multiple of 2.\n\t\titer->addIdOperand(builder.makeUintConstant(2));\n\n\t\tphi->addIdOperand(builder.makeUintConstant(0));\n\t\tphi->addIdOperand(entry->getId());\n\t\tphi->addIdOperand(iter->getResultId());\n\t\tphi->addIdOperand(header->getId());\n\n\t\tauto *index1 = builder.addInstruction(uint_type, spv::OpIAdd);\n\t\tindex1->addIdOperand(phi->getResultId());\n\t\tindex1->addIdOperand(builder.makeUintConstant(1));\n\n\t\tspv::Id components[2];\n\n\t\tfor (unsigned i = 0; i < 2; i++)\n\t\t{\n\t\t\tspv::Id index = i ? index1->getResultId() : phi->getResultId();\n\n\t\t\tauto *input_chain = builder.addInstruction(builder.makePointer(spv::StorageClassFunction, f16_type),\n\t\t\t                                           spv::OpInBoundsAccessChain);\n\t\t\tinput_chain->addIdOperand(func->getParamId(0));\n\t\t\tinput_chain->addIdOperand(index);\n\n\t\t\tauto *load = builder.addInstruction(f16_type, spv::OpLoad);\n\t\t\tload->addIdOperand(input_chain->getResultId());\n\n\t\t\tcomponents[i] = load->getResultId();\n\t\t}\n\n\t\tauto *composite = builder.addInstruction(f16vec2_type, spv::OpCompositeConstruct);\n\t\tcomposite->addIdOperand(components[0]);\n\t\tcomposite->addIdOperand(components[1]);\n\n\t\tauto *bitcast = builder.addInstruction(s16vec2_type, spv::OpBitcast);\n\t\tbitcast->addIdOperand(composite->getResultId());\n\n\t\t// Extract the sign bit.\n\t\tauto *sign_in_lsb = builder.addInstruction(s16vec2_type, spv::OpShiftRightLogical);\n\t\tsign_in_lsb->addIdOperand(bitcast->getResultId());\n\t\tsign_in_lsb->addIdOperand(make_i16vec2_constant(builder, 15));\n\n\t\tauto *sign_bit = builder.addInstruction(s16vec2_type, spv::OpShiftLeftLogical);\n\t\tsign_bit->addIdOperand(sign_in_lsb->getResultId());\n\t\tsign_bit->addIdOperand(make_i16vec2_constant(builder, 7));\n\t\t///\n\n\t\t// When the input is shifted like this the result is E5M3 in upper byte, which is very handy.\n\t\tauto *unsigned_e5m11 = builder.addInstruction(s16vec2_type, spv::OpShiftLeftLogical);\n\t\tunsigned_e5m11->addIdOperand(bitcast->getResultId());\n\t\tunsigned_e5m11->addIdOperand(make_i16vec2_constant(builder, 1));\n\n\t\t// Shift -15 bias to -7 bias.\n\t\tauto *shift_exponent = builder.addInstruction(s16vec2_type, spv::OpISub);\n\t\tshift_exponent->addIdOperand(unsigned_e5m11->getResultId());\n\t\tshift_exponent->addIdOperand(make_i16vec2_constant(builder, 8 << 11));\n\t\tunsigned_e5m11 = shift_exponent;\n\n\t\tauto *exponent = builder.addInstruction(s16vec2_type, spv::OpShiftRightArithmetic);\n\t\texponent->addIdOperand(shift_exponent->getResultId());\n\t\texponent->addIdOperand(make_i16vec2_constant(builder, 11));\n\n\t\tauto *exponent_minus1 = builder.addInstruction(s16vec2_type, spv::OpISub);\n\t\texponent_minus1->addIdOperand(exponent->getResultId());\n\t\texponent_minus1->addIdOperand(make_i16vec2_constant(builder, 1));\n\n\t\tauto *denorm_shamt = builder.addInstruction(s16vec2_type, spv::OpSNegate);\n\t\tdenorm_shamt->addIdOperand(exponent_minus1->getResultId());\n\n\t\t// Ensure we don't get negative shift.\n\t\tspv::Id glsl450 = builder.import(\"GLSL.std.450\");\n\t\tauto *clamp = builder.addInstruction(s16vec2_type, spv::OpExtInst);\n\t\tclamp->addIdOperand(glsl450);\n\t\tclamp->addImmediateOperand(GLSLstd450SMax);\n\t\tclamp->addIdOperand(denorm_shamt->getResultId());\n\t\tclamp->addIdOperand(make_i16vec2_constant(builder, 0));\n\t\tdenorm_shamt = clamp;\n\n\t\t// If we're denorm, the arith shift ensures the upper bits are all 1.\n\t\tauto *denorm_mask = builder.addInstruction(s16vec2_type, spv::OpBitwiseAnd);\n\t\tdenorm_mask->addIdOperand(exponent_minus1->getResultId());\n\t\tdenorm_mask->addIdOperand(make_i16vec2_constant(builder, 1 << 11));\n\n\t\t// Serves as a clamping function.\n\t\t// If the exponent goes negative here, we need to emit a 0 exponent, marking that we're in denorm region.\n\t\tauto *clear_exponent_neg_mask = builder.addInstruction(s16vec2_type, spv::OpBitwiseAnd);\n\t\tclear_exponent_neg_mask->addIdOperand(exponent_minus1->getResultId());\n\t\tclear_exponent_neg_mask->addIdOperand(make_i16vec2_constant(builder, int16_t(0x1f << 11)));\n\t\tauto *clear_exponent_mask = builder.addInstruction(s16vec2_type, spv::OpBitwiseXor);\n\t\tclear_exponent_mask->addIdOperand(clear_exponent_neg_mask->getResultId());\n\t\tclear_exponent_mask->addIdOperand(make_i16vec2_constant(builder, -1));\n\n\t\t// Clamp negative exponent to 0.\n\t\t{\n\t\t\tauto *mask = builder.addInstruction(s16vec2_type, spv::OpBitwiseAnd);\n\t\t\tmask->addIdOperand(unsigned_e5m11->getResultId());\n\t\t\tmask->addIdOperand(clear_exponent_mask->getResultId());\n\t\t\tunsigned_e5m11 = mask;\n\t\t}\n\n\t\t// If denorm, add in the implicit 1.xxxx.\n\t\t{\n\t\t\tauto *mask = builder.addInstruction(s16vec2_type, spv::OpBitwiseOr);\n\t\t\tmask->addIdOperand(unsigned_e5m11->getResultId());\n\t\t\tmask->addIdOperand(denorm_mask->getResultId());\n\t\t\tunsigned_e5m11 = mask;\n\t\t}\n\n\t\t// Before we shift, we need to capture any possible rounding bits.\n\t\t// Only capture the lower 7 bits.\n\t\t// If we shift more than 7 we've already exhausted all denorm bits on E4M3 anyway, so don't need to care.\n\t\t// Cannot capture the top bit in lower half since we might get a false positive for 0.5 condition.\n\t\tauto *pre_denorm_rounding_bits = builder.addInstruction(s16vec2_type, spv::OpBitwiseAnd);\n\t\tpre_denorm_rounding_bits->addIdOperand(unsigned_e5m11->getResultId());\n\t\tpre_denorm_rounding_bits->addIdOperand(make_i16vec2_constant(builder, 0x7f));\n\n\t\t// Now we apply the denorm shift.\n\t\tauto *denorm_shift = builder.addInstruction(s16vec2_type, spv::OpShiftRightArithmetic);\n\t\tdenorm_shift->addIdOperand(unsigned_e5m11->getResultId());\n\t\tdenorm_shift->addIdOperand(denorm_shamt->getResultId());\n\t\tunsigned_e5m11 = denorm_shift;\n\n\t\t// Capture any rounding bits.\n\t\t// If we shift due to denorms,\n\t\t// we have to know if we shifted away bits that are relevant to RTE.\n\t\tauto *rounding_bits = builder.addInstruction(s16vec2_type, spv::OpBitwiseOr);\n\t\trounding_bits->addIdOperand(unsigned_e5m11->getResultId());\n\t\trounding_bits->addIdOperand(pre_denorm_rounding_bits->getResultId());\n\n\t\tauto *unsigned_e5m3 = builder.addInstruction(s16vec2_type, spv::OpShiftRightLogical);\n\t\tunsigned_e5m3->addIdOperand(unsigned_e5m11->getResultId());\n\t\tunsigned_e5m3->addIdOperand(make_i16vec2_constant(builder, 8));\n\n\t\tauto *is_odd = builder.addInstruction(s16vec2_type, spv::OpBitwiseAnd);\n\t\tis_odd->addIdOperand(unsigned_e5m3->getResultId());\n\t\tis_odd->addIdOperand(make_i16vec2_constant(builder, 1));\n\n\t\tauto *or_rounding_bits = builder.addInstruction(s16vec2_type, spv::OpBitwiseOr);\n\t\tor_rounding_bits->addIdOperand(is_odd->getResultId());\n\t\tor_rounding_bits->addIdOperand(rounding_bits->getResultId());\n\n\t\t// To get > 0x80 in lower bits either the fraction is > 0.5, or it's exactly 0.5 and the upper part is odd,\n\t\t// which would make the result 0x81.\n\t\t// We shift the high bits away and then compare with 0x8000\n\n\t\tauto *rounding_bits_in_msb = builder.addInstruction(s16vec2_type, spv::OpShiftLeftLogical);\n\t\trounding_bits_in_msb->addIdOperand(or_rounding_bits->getResultId());\n\t\trounding_bits_in_msb->addIdOperand(make_i16vec2_constant(builder, 8));\n\n\t\tauto *should_round = builder.addInstruction(bvec2_type, spv::OpUGreaterThan);\n\t\tshould_round->addIdOperand(rounding_bits_in_msb->getResultId());\n\t\tshould_round->addIdOperand(make_u16vec2_constant(builder, 0x8000));\n\n\t\t// Compensate for exponent bias when dealing with denorms.\n\t\tauto *rounding = builder.addInstruction(s16vec2_type, spv::OpSelect);\n\t\trounding->addIdOperand(should_round->getResultId());\n\t\trounding->addIdOperand(make_i16vec2_constant(builder, 1));\n\t\trounding->addIdOperand(make_i16vec2_constant(builder, 0));\n\n\t\t// Add rounding.\n\t\tauto *add_rounding = builder.addInstruction(s16vec2_type, spv::OpIAdd);\n\t\tadd_rounding->addIdOperand(unsigned_e5m3->getResultId());\n\t\tadd_rounding->addIdOperand(rounding->getResultId());\n\n\t\t// Mask away the top exponent. We should be in range now anyway.\n\t\tauto *e4m3 = builder.addInstruction(s16vec2_type, spv::OpBitwiseAnd);\n\t\te4m3->addIdOperand(add_rounding->getResultId());\n\t\te4m3->addIdOperand(make_i16vec2_constant(builder, 0x7f));\n\n\t\t// OR in the sign bit.\n\t\tauto *with_sign = builder.addInstruction(s16vec2_type, spv::OpBitwiseOr);\n\t\twith_sign->addIdOperand(e4m3->getResultId());\n\t\twith_sign->addIdOperand(sign_bit->getResultId());\n\n\t\tauto *trunc = builder.addInstruction(u8vec2_type, spv::OpUConvert);\n\t\ttrunc->addIdOperand(with_sign->getResultId());\n\n\t\tfor (unsigned i = 0; i < 2; i++)\n\t\t{\n\t\t\tspv::Id index = i ? index1->getResultId() : phi->getResultId();\n\n\t\t\tauto *output_chain = builder.addInstruction(builder.makePointer(spv::StorageClassFunction, u8_type),\n\t\t\t                                            spv::OpInBoundsAccessChain);\n\t\t\toutput_chain->addIdOperand(output_id);\n\t\t\toutput_chain->addIdOperand(index);\n\n\t\t\tauto *component = builder.addInstruction(u8_type, spv::OpCompositeExtract);\n\t\t\tcomponent->addIdOperand(trunc->getResultId());\n\t\t\tcomponent->addImmediateOperand(i);\n\n\t\t\tauto *store = builder.addInstruction(spv::OpStore);\n\t\t\tstore->addIdOperand(output_chain->getResultId());\n\t\t\tstore->addIdOperand(component->getResultId());\n\t\t}\n\n\t\tauto *cmp = builder.addInstruction(bool_type, spv::OpULessThan);\n\t\tcmp->addIdOperand(iter->getResultId());\n\t\tcmp->addIdOperand(len->getResultId());\n\t\tbuilder.createLoopMerge(merge, header, 0);\n\t\tbuilder.createConditionalBranch(cmp->getResultId(), header, merge);\n\t}\n\n\tbuilder.setBuildPoint(merge);\n\tauto *loaded_result = builder.addInstruction(u8mat_type, spv::OpLoad);\n\tloaded_result->addIdOperand(output_id);\n\tbuilder.makeReturn(false, loaded_result->getResultId());\n\tbuilder.setBuildPoint(current_build_point);\n\tcoop_mat_conv_ids.push_back({ f16mat_type, u8mat_type, func->getId(), HelperCall::CoopMatFP16toFP8 });\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::build_coop_mat_fp8_to_fp16(SPIRVModule &module, const spv::Id *ids, uint32_t id_count)\n{\n\tif (id_count != 2)\n\t\treturn 0;\n\n\tspv::Id u8_type = ids[0];\n\tspv::Id f16_type = ids[1];\n\n\tfor (auto &ops : coop_mat_conv_ids)\n\t\tif (ops.input_type == u8_type && ops.output_type == f16_type && ops.call == HelperCall::CoopMatFP8toFP16)\n\t\t\treturn ops.func_id;\n\n\tauto *current_build_point = builder.getBuildPoint();\n\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id bool_type = builder.makeBoolType();\n\n\t// RADV workaround. It fails to understand coopmat passed as value.\n\tspv::Id u8_ptr_type = builder.makePointer(spv::StorageClassFunction, u8_type);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, f16_type,\n\t                                       \"CoopMatFP8toFP16\",\n\t                                       { u8_ptr_type }, {}, &entry);\n\n\tspv::Id output_id = create_variable(spv::StorageClassFunction, f16_type, \"coop_output\");\n\n\tauto *len = builder.addInstruction(uint_type, spv::OpCooperativeMatrixLengthKHR);\n\tlen->addIdOperand(u8_type);\n\n\tauto *header = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge = new spv::Block(builder.getUniqueId(), *func);\n\tbuilder.createBranch(header);\n\tbuilder.setBuildPoint(header);\n\t{\n\t\tauto *phi = builder.addInstruction(uint_type, spv::OpPhi);\n\t\tauto *iter = builder.addInstruction(uint_type, spv::OpIAdd);\n\t\titer->addIdOperand(phi->getResultId());\n\t\titer->addIdOperand(builder.makeUintConstant(1));\n\n\t\tphi->addIdOperand(builder.makeUintConstant(0));\n\t\tphi->addIdOperand(entry->getId());\n\t\tphi->addIdOperand(iter->getResultId());\n\t\tphi->addIdOperand(header->getId());\n\n\t\tauto *input_chain = builder.addInstruction(\n\t\t\tbuilder.makePointer(spv::StorageClassFunction, builder.makeUintType(8)), spv::OpInBoundsAccessChain);\n\t\tinput_chain->addIdOperand(func->getParamId(0));\n\t\tinput_chain->addIdOperand(phi->getResultId());\n\n\t\tauto *load = builder.addInstruction(builder.makeUintType(8), spv::OpLoad);\n\t\tload->addIdOperand(input_chain->getResultId());\n\n\t\tauto *sext = builder.addInstruction(builder.makeIntType(16), spv::OpSConvert);\n\t\tsext->addIdOperand(load->getResultId());\n\n\t\tauto *shift = builder.addInstruction(builder.makeIntType(16), spv::OpShiftLeftLogical);\n\t\tshift->addIdOperand(sext->getResultId());\n\t\tshift->addIdOperand(builder.makeInt16Constant(7));\n\n\t\tauto *mask = builder.addInstruction(builder.makeIntType(16), spv::OpBitwiseAnd);\n\t\tmask->addIdOperand(shift->getResultId());\n\t\tmask->addIdOperand(builder.makeInt16Constant(int16_t(0xffff ^ 0x4000)));\n\n\t\tauto *bitcast = builder.addInstruction(builder.makeFloatType(16), spv::OpBitcast);\n\t\tbitcast->addIdOperand(mask->getResultId());\n\n\t\tauto *output_chain = builder.addInstruction(\n\t\t\tbuilder.makePointer(spv::StorageClassFunction, builder.makeFloatType(16)), spv::OpInBoundsAccessChain);\n\t\toutput_chain->addIdOperand(output_id);\n\t\toutput_chain->addIdOperand(phi->getResultId());\n\t\tauto *store = builder.addInstruction(spv::OpStore);\n\t\tstore->addIdOperand(output_chain->getResultId());\n\t\tstore->addIdOperand(bitcast->getResultId());\n\n\t\tauto *cmp = builder.addInstruction(bool_type, spv::OpULessThan);\n\t\tcmp->addIdOperand(iter->getResultId());\n\t\tcmp->addIdOperand(len->getResultId());\n\t\tbuilder.createLoopMerge(merge, header, 0);\n\t\tbuilder.createConditionalBranch(cmp->getResultId(), header, merge);\n\t}\n\n\tbuilder.setBuildPoint(merge);\n\tauto *loaded_result = builder.addInstruction(f16_type, spv::OpLoad);\n\tloaded_result->addIdOperand(output_id);\n\n\t// Need post-scale to correctly deal with denorms.\n\tauto *scale = builder.addInstruction(f16_type, spv::OpMatrixTimesScalar);\n\tscale->addIdOperand(loaded_result->getResultId());\n\tscale->addIdOperand(builder.makeFloat16Constant(0x5c00 /* 256.0 */));\n\n\tbuilder.makeReturn(false, scale->getResultId());\n\n\tbuilder.setBuildPoint(current_build_point);\n\tcoop_mat_conv_ids.push_back({ u8_type, f16_type, func->getId(), HelperCall::CoopMatFP8toFP16 });\n\treturn func->getId();\n}\n\nspv::Id SPIRVModule::Impl::get_helper_call_id(SPIRVModule &module, HelperCall call,\n                                              const spv::Id *aux_ids, uint32_t aux_ids_count)\n{\n\tswitch (call)\n\t{\n\tcase HelperCall::NodeCoalescePayloadOffset:\n\t\treturn build_node_coalesce_payload_offset(module, aux_ids, aux_ids_count);\n\tcase HelperCall::CoopMatFP8toFP16:\n\t\treturn build_coop_mat_fp8_to_fp16(module, aux_ids, aux_ids_count);\n\tcase HelperCall::CoopMatFP16toFP8:\n\t\treturn build_coop_mat_fp16_to_fp8(module, aux_ids, aux_ids_count);\n\tcase HelperCall::CoopMatTransfer:\n\t\treturn build_coop_mat_transfer(module, aux_ids, aux_ids_count);\n\tdefault:\n\t\tbreak;\n\t}\n\treturn 0;\n}\n\nspv::Id SPIRVModule::Impl::get_helper_call_id(SPIRVModule &module, HelperCall call, spv::Id type_id)\n{\n\tswitch (call)\n\t{\n\tcase HelperCall::DescriptorQACheck:\n\t\treturn build_descriptor_qa_check(module);\n\n\tcase HelperCall::WaveMatch:\n\t\treturn build_wave_match(module, type_id);\n\n\tcase HelperCall::WaveMultiPrefixCountBits:\n\t\treturn build_wave_multi_prefix_count_bits(module);\n\n\tcase HelperCall::WaveMultiPrefixFAdd:\n\t\treturn build_wave_multi_prefix_op(module, spv::OpGroupNonUniformFAdd, type_id);\n\tcase HelperCall::WaveMultiPrefixIAdd:\n\t\treturn build_wave_multi_prefix_op(module, spv::OpGroupNonUniformIAdd, type_id);\n\tcase HelperCall::WaveMultiPrefixFMul:\n\t\treturn build_wave_multi_prefix_op(module, spv::OpGroupNonUniformFMul, type_id);\n\tcase HelperCall::WaveMultiPrefixIMul:\n\t\treturn build_wave_multi_prefix_op(module, spv::OpGroupNonUniformIMul, type_id);\n\tcase HelperCall::WaveMultiPrefixBitOr:\n\t\treturn build_wave_multi_prefix_op(module, spv::OpGroupNonUniformBitwiseOr, type_id);\n\tcase HelperCall::WaveMultiPrefixBitAnd:\n\t\treturn build_wave_multi_prefix_op(module, spv::OpGroupNonUniformBitwiseAnd, type_id);\n\tcase HelperCall::WaveMultiPrefixBitXor:\n\t\treturn build_wave_multi_prefix_op(module, spv::OpGroupNonUniformBitwiseXor, type_id);\n\tcase HelperCall::WaveIsFirstLaneMasked:\n\t\treturn build_wave_is_first_lane_masked(module);\n\tcase HelperCall::WaveActiveAllEqualMasked:\n\t\treturn build_wave_active_all_equal_masked(module, type_id);\n\tcase HelperCall::WaveReadFirstLaneMasked:\n\t\treturn build_wave_read_first_lane_masked(module, type_id);\n\tcase HelperCall::RobustAtomicCounter:\n\t\treturn build_robust_atomic_counter_op(module);\n\tcase HelperCall::QuadAll:\n\t\treturn build_quad_all(module);\n\tcase HelperCall::QuadAny:\n\t\treturn build_quad_any(module);\n\tcase HelperCall::AtomicImageArrayR64Compact:\n\tcase HelperCall::AtomicImageR64Compact:\n\tcase HelperCall::AtomicImageArrayR64CompactNonUniform:\n\tcase HelperCall::AtomicImageR64CompactNonUniform:\n\t\treturn build_image_atomic_r64_compact(\n\t\t\tmodule,\n\t\t\tcall == HelperCall::AtomicImageArrayR64Compact || call == HelperCall::AtomicImageArrayR64CompactNonUniform,\n\t\t\tcall == HelperCall::AtomicImageR64CompactNonUniform || call == HelperCall::AtomicImageArrayR64CompactNonUniform);\n\tcase HelperCall::FinishCrossGroupSharing:\n\t\treturn build_finish_cross_group_sharing(module);\n\tcase HelperCall::AllocateGroupNodeRecords:\n\t\treturn build_allocate_node_records(module, false);\n\tcase HelperCall::AllocateThreadNodeRecords:\n\t\treturn build_allocate_node_records(module, true);\n\tcase HelperCall::AllocateThreadNodeRecordsWaterfall:\n\t\treturn build_allocate_node_records_waterfall(module);\n\tcase HelperCall::GroupIncrementOutputCount:\n\t\treturn build_increment_node_count(module, false);\n\tcase HelperCall::ThreadIncrementOutputCount:\n\t\treturn build_increment_node_count(module, true);\n\tcase HelperCall::IsQuadUniformControlFlow:\n\t\treturn build_is_quad_uniform_control_flow(module);\n\tcase HelperCall::ValidateBDALoadStore:\n\t\treturn build_validate_bda_load_store(module);\n\tcase HelperCall::AllocateInvocationID:\n\t\treturn build_allocate_invocation_id(module);\n\tcase HelperCall::CoopMatSaturationFixup:\n\t\treturn build_coop_mat_saturation_fixup(module, type_id);\n\tcase HelperCall::CoopMatSaturateFP8:\n\t\treturn build_coop_mat_saturate_fp8(module, type_id);\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nSPIRVModule::SPIRVModule()\n{\n\timpl = std::make_unique<Impl>(*this);\n}\n\nvoid SPIRVModule::emit_entry_point(spv::ExecutionModel model, const char *name, bool physical_storage,\n                                   spv::MemoryModel memory_model)\n{\n\tif (memory_model == spv::MemoryModelVulkan)\n\t\tset_override_spirv_version(0x10600);\n\timpl->emit_entry_point(model, name, physical_storage, memory_model);\n}\n\nbool SPIRVModule::Impl::execution_model_is_ray_tracing() const\n{\n\tswitch (execution_model)\n\t{\n\tcase spv::ExecutionModelRayGenerationKHR:\n\tcase spv::ExecutionModelAnyHitKHR:\n\tcase spv::ExecutionModelIntersectionKHR:\n\tcase spv::ExecutionModelMissKHR:\n\tcase spv::ExecutionModelClosestHitKHR:\n\tcase spv::ExecutionModelCallableKHR:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool SPIRVModule::Impl::spirv_requires_14() const\n{\n\tstatic const uint32_t Version_1_4 = 0x00010400;\n\tif (override_spirv_version)\n\t{\n\t\treturn override_spirv_version >= Version_1_4;\n\t}\n\telse\n\t{\n\t\treturn execution_model_is_ray_tracing() || execution_model == spv::ExecutionModelMeshEXT ||\n\t\t       execution_model == spv::ExecutionModelTaskEXT;\n\t}\n}\n\nbool SPIRVModule::Impl::finalize_spirv(Vector<uint32_t> &spirv)\n{\n\tspirv.clear();\n\n\tmark_error = false;\n\tbuilder.dump(spirv);\n\tif (spirv.size() >= 2)\n\t{\n\t\tif (override_spirv_version)\n\t\t{\n\t\t\tspirv[1] = override_spirv_version;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstatic const uint32_t Version_1_3 = 0x00010300;\n\t\t\tstatic const uint32_t Version_1_4 = 0x00010400;\n\t\t\tspirv[1] = spirv_requires_14() ? Version_1_4 : Version_1_3;\n\t\t}\n\t}\n\treturn !mark_error;\n}\n\nvoid SPIRVModule::Impl::register_block(CFGNode *node)\n{\n\tif (!node->userdata || node->id == 0)\n\t{\n\t\tauto *bb = new spv::Block(builder.getUniqueId(), *active_function);\n#if 0\n\t\tif (!node->name.empty())\n\t\t\tbuilder.addName(bb->getId(), node->name.c_str());\n#endif\n\t\tactive_function->addBlock(bb);\n\t\tnode->id = bb->getId();\n\t\tnode->userdata = bb;\n\t}\n}\n\nvoid SPIRVModule::Impl::add_instrumented_instruction(spv::Op op, spv::Block *bb, spv::Id id)\n{\n\tif (id == 0 || !instruction_instrumentation.info.enabled)\n\t\treturn;\n\n\tspv::Id *call_id = nullptr;\n\tspv::Id type_id = 0;\n\n\tif (op == spv::OpAssumeTrueKHR)\n\t{\n\t\tcall_id = &instruction_instrumentation.assume_true_call_id;\n\t}\n\telse\n\t{\n\t\ttype_id = builder.getTypeId(id);\n\t\tif (builder.getTypeClass(type_id) != spv::OpTypeFloat)\n\t\t\treturn;\n\n\t\tswitch (builder.getScalarTypeWidth(type_id))\n\t\t{\n\t\tcase 16:\n\t\t\tcall_id = &instruction_instrumentation.nan_inf_instrument_fp16_call_id;\n\t\t\tbreak;\n\n\t\tcase 32:\n\t\t\tcall_id = &instruction_instrumentation.nan_inf_instrument_fp32_call_id;\n\t\t\tbreak;\n\n\t\tcase 64:\n\t\t\tcall_id = &instruction_instrumentation.nan_inf_instrument_fp64_call_id;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!instruction_instrumentation.should_report_instrumentation_id)\n\t{\n\t\tinstruction_instrumentation.should_report_instrumentation_id = create_variable_with_initializer(\n\t\t\tspv::StorageClassPrivate, builder.makeBoolType(),\n\t\t\tbuilder.makeBoolConstant(true), \"ShouldReportInstrumentation\");\n\n\t\tspv::Id u32_type = builder.makeUintType(32);\n\t\tspv::Id uvec4_type = builder.makeVectorType(u32_type, 4);\n\t\tspv::Id u32_array_type = builder.makeRuntimeArray(u32_type);\n\t\tbuilder.addDecoration(u32_array_type, spv::DecorationArrayStride, 4);\n\t\tspv::Id control_data = builder.makeStructType({ u32_array_type }, \"InstrumentationControlDataSSBO\");\n\t\tbuilder.addMemberDecoration(control_data, 0, spv::DecorationOffset, 0);\n\t\tbuilder.addMemberName(control_data, 0, \"atomics\");\n\t\tbuilder.addDecoration(control_data, spv::DecorationBlock);\n\t\tinstruction_instrumentation.global_nan_inf_control_var_id =\n\t\t\tcreate_variable(spv::StorageClassStorageBuffer, control_data, \"InstrumentationControlData\");\n\n\t\tbuilder.addDecoration(instruction_instrumentation.global_nan_inf_control_var_id,\n\t\t                      spv::DecorationDescriptorSet, instruction_instrumentation.info.control_desc_set);\n\n\t\tbuilder.addDecoration(instruction_instrumentation.global_nan_inf_control_var_id,\n\t\t                      spv::DecorationBinding,\n\t\t                      instruction_instrumentation.info.control_binding);\n\n\t\tspv::Id payload_data_array = builder.makeRuntimeArray(uvec4_type);\n\t\tbuilder.addDecoration(payload_data_array, spv::DecorationArrayStride, 16);\n\n\t\tspv::Id payload_block = builder.makeStructType({ payload_data_array }, \"InstrumentationDataSSBO\");\n\t\tbuilder.addMemberName(payload_block, 0, \"data\");\n\t\tbuilder.addMemberDecoration(payload_block, 0, spv::DecorationOffset, 0);\n\t\tbuilder.addDecoration(payload_block, spv::DecorationBlock);\n\t\tinstruction_instrumentation.global_nan_inf_data_var_id =\n\t\t\tcreate_variable(spv::StorageClassStorageBuffer, payload_block, \"InstrumentationData\");\n\n\t\tbuilder.addDecoration(instruction_instrumentation.global_nan_inf_data_var_id,\n\t\t                      spv::DecorationDescriptorSet, instruction_instrumentation.info.payload_desc_set);\n\n\t\tbuilder.addDecoration(instruction_instrumentation.global_nan_inf_data_var_id,\n\t\t                      spv::DecorationBinding,\n\t\t                      instruction_instrumentation.info.payload_binding);\n\t}\n\n\tif (call_id && !*call_id)\n\t{\n\t\tif (op == spv::OpAssumeTrueKHR)\n\t\t\t*call_id = build_assume_true_call_function(self, instruction_instrumentation);\n\t\telse\n\t\t\t*call_id = build_nan_inf_instrument_call_function(self, instruction_instrumentation, type_id);\n\t}\n\n\tauto call = std::make_unique<spv::Instruction>(builder.getUniqueId(), builder.makeVoidType(), spv::OpFunctionCall);\n\tcall->addIdOperand(*call_id);\n\tcall->addIdOperand(id);\n\tcall->addIdOperand(builder.makeUintConstant(++instruction_instrumentation.instruction_count));\n\tbb->addInstruction(std::move(call));\n}\n\nvoid SPIRVModule::Impl::add_instruction(spv::Block *bb, std::unique_ptr<spv::Instruction> inst)\n{\n\tspv::Op op = inst->getOpCode();\n\tspv::Id id = inst->getResultId();\n\tspv::Id type_id = inst->getTypeId();\n\n\tif (id != 0 && instruction_instrumentation.info.enabled &&\n\t    instruction_instrumentation.info.type == InstructionInstrumentationType::FlushNaNToZero &&\n\t    builder.getTypeClass(type_id) == spv::OpTypeFloat && op != spv::OpPhi)\n\t{\n\t\t// A bit special since we're rewriting the IDs.\n\t\tspv::Id new_id = builder.getUniqueId();\n\t\tspv::Id nan_id = builder.getUniqueId();\n\t\tinst->setResultId(new_id);\n\n\t\tspv::Id null_const = builder.makeNullConstant(type_id);\n\t\tauto is_nan = std::make_unique<spv::Instruction>(nan_id, builder.makeBoolType(), spv::OpIsNan);\n\t\tis_nan->addIdOperand(new_id);\n\t\tauto replaced = std::make_unique<spv::Instruction>(id, type_id, spv::OpSelect);\n\t\treplaced->addIdOperand(nan_id);\n\t\treplaced->addIdOperand(null_const);\n\t\treplaced->addIdOperand(new_id);\n\n\t\tbb->addInstruction(std::move(inst));\n\t\tbb->addInstruction(std::move(is_nan));\n\t\tbb->addInstruction(std::move(replaced));\n\t}\n\telse\n\t{\n\t\tbb->addInstruction(std::move(inst));\n\n\t\t// For Full instrumentation add everything, otherwise, we need specialized instrumentation.\n\t\tif (instruction_instrumentation.info.enabled &&\n\t\t    instruction_instrumentation.info.type == InstructionInstrumentationType::FullNanInf &&\n\t\t    op != spv::OpPhi)\n\t\t{\n\t\t\tadd_instrumented_instruction(op, bb, id);\n\t\t}\n\t}\n}\n\nvoid SPIRVModule::Impl::emit_basic_block(CFGNode *node)\n{\n\tauto *bb = get_spv_block(node);\n\tauto &ir = node->ir;\n\n\tbuilder.setBuildPoint(bb);\n\n\tspv::Block *fake_loop_block = nullptr;\n\n\t// Break-like loops might not have a continue block.\n\t// Infinite loops won't have merge blocks.\n\tif (node->ir.merge_info.merge_type == MergeType::Loop &&\n\t    (int(node->ir.merge_info.merge_block != nullptr) +\n\t     int(node->ir.merge_info.continue_block != nullptr) == 1))\n\t{\n\t\tfake_loop_block = new spv::Block(builder.getUniqueId(), *active_function);\n\t}\n\n\t// Emit phi nodes.\n\tfor (auto &phi : ir.phi)\n\t{\n\t\tif (!phi.id)\n\t\t\tcontinue;\n\n\t\tauto phi_op = std::make_unique<spv::Instruction>(phi.id, phi.type_id, spv::OpPhi);\n\t\tfor (auto &incoming : phi.incoming)\n\t\t{\n\t\t\tphi_op->addIdOperand(incoming.id);\n\t\t\tphi_op->addIdOperand(incoming.block->id);\n\t\t}\n\n\t\tif (fake_loop_block && !node->ir.merge_info.continue_block)\n\t\t{\n\t\t\tbuilder.setBuildPoint(fake_loop_block);\n\t\t\tphi_op->addIdOperand(builder.createUndefined(phi.type_id));\n\t\t\tbuilder.setBuildPoint(bb);\n\t\t\tphi_op->addIdOperand(fake_loop_block->getId());\n\t\t}\n\n\t\tif (phi.relaxed)\n\t\t\tbuilder.addDecoration(phi.id, spv::DecorationRelaxedPrecision);\n\n\t\tadd_instruction(bb, std::move(phi_op));\n\t}\n\n\tbool implicit_terminator = false;\n\tspv::Id rewrite_phi_incoming_from = node->id;\n\tspv::Id rewrite_phi_incoming_to = 0;\n\n\tconst auto emit_loop_header = [&](spv::Block *replacement_continue_bb) {\n\t\tauto *continue_bb = ir.merge_info.continue_block ? get_spv_block(ir.merge_info.continue_block) : nullptr;\n\t\tif (replacement_continue_bb)\n\t\t\tcontinue_bb = replacement_continue_bb;\n\n\t\tif (ir.merge_info.merge_block && ir.merge_info.continue_block)\n\t\t{\n\t\t\tbuilder.createLoopMerge(get_spv_block(ir.merge_info.merge_block),\n\t\t\t                        continue_bb,\n\t\t\t                        ir.merge_info.loop_control_mask);\n\t\t}\n\t\telse if (ir.merge_info.merge_block)\n\t\t{\n\t\t\tcontinue_bb = fake_loop_block;\n\t\t\tactive_function->addBlock(continue_bb);\n\t\t\tbuilder.setBuildPoint(continue_bb);\n\t\t\tbuilder.createBranch(get_spv_block(node));\n\t\t\tbuilder.setBuildPoint(bb);\n\t\t\tbuilder.createLoopMerge(get_spv_block(ir.merge_info.merge_block), continue_bb, 0);\n\t\t}\n\t\telse if (ir.merge_info.continue_block)\n\t\t{\n\t\t\tauto *merge_bb = fake_loop_block;\n\t\t\tactive_function->addBlock(merge_bb);\n\t\t\tbuilder.setBuildPoint(merge_bb);\n\t\t\tbuilder.createUnreachable();\n\t\t\tbuilder.setBuildPoint(bb);\n\t\t\tbuilder.createLoopMerge(merge_bb, continue_bb, 0);\n\t\t}\n\t};\n\n\t// Emit opcodes.\n\tfor (auto *op : ir.operations)\n\t{\n\t\tif (implicit_terminator)\n\t\t\tbreak;\n\n\t\tif (op->flags & Operation::SubgroupSyncPre)\n\t\t{\n\t\t\tauto *pre = builder.addInstruction(spv::OpControlBarrier);\n\t\t\tpre->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tpre->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tpre->addIdOperand(builder.getWorkgroupBarrierSemanticsId());\n\t\t}\n\n\t\tif (op->op == spv::OpIsHelperInvocationEXT && !caps.supports_demote)\n\t\t{\n\t\t\tspv::Id helper_var_id = get_builtin_shader_input(spv::BuiltInHelperInvocation);\n\n\t\t\tif (discard_state_var_id)\n\t\t\t{\n\t\t\t\tauto is_helper = std::make_unique<spv::Instruction>(builder.getUniqueId(), builder.makeBoolType(), spv::OpLoad);\n\t\t\t\tis_helper->addIdOperand(helper_var_id);\n\t\t\t\tspv::Id is_helper_id = is_helper->getResultId();\n\t\t\t\tadd_instruction(bb, std::move(is_helper));\n\n\t\t\t\tauto loaded_var = std::make_unique<spv::Instruction>(builder.getUniqueId(), builder.makeBoolType(), spv::OpLoad);\n\t\t\t\tloaded_var->addIdOperand(discard_state_var_id);\n\t\t\t\tspv::Id is_discard_id = loaded_var->getResultId();\n\t\t\t\tadd_instruction(bb, std::move(loaded_var));\n\n\t\t\t\tauto or_inst = std::make_unique<spv::Instruction>(op->id, op->type_id, spv::OpLogicalOr);\n\t\t\t\tor_inst->addIdOperand(is_helper_id);\n\t\t\t\tor_inst->addIdOperand(is_discard_id);\n\t\t\t\tadd_instruction(bb, std::move(or_inst));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto is_helper = std::make_unique<spv::Instruction>(op->id, op->type_id, spv::OpLoad);\n\t\t\t\tis_helper->addIdOperand(helper_var_id);\n\t\t\t\tadd_instruction(bb, std::move(is_helper));\n\t\t\t}\n\t\t}\n\t\telse if (op->op == spv::OpDemoteToHelperInvocationEXT && !caps.supports_demote)\n\t\t{\n\t\t\tif (op->num_arguments)\n\t\t\t\tbuild_discard_call_early_cond(op->arguments[0]);\n\t\t\telse\n\t\t\t\tbuild_discard_call_early();\n\t\t}\n\t\telse if (op->op == spv::OpDemoteToHelperInvocationEXT && op->num_arguments)\n\t\t{\n\t\t\tbuilder.addExtension(\"SPV_EXT_demote_to_helper_invocation\");\n\t\t\tbuilder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);\n\t\t\tbuild_demote_call_cond(op->arguments[0]);\n\t\t}\n\t\telse if (op->op == spv::PseudoOpInstrumentExternallyVisibleStore || op->op == spv::OpAssumeTrueKHR)\n\t\t{\n\t\t\tadd_instrumented_instruction(op->op, bb, op->arguments[0]);\n\t\t}\n\t\telse if (op->op == spv::PseudoOpReturnCond ||\n\t\t         op->op == spv::PseudoOpMaskedLoad ||\n\t\t         op->op == spv::PseudoOpMaskedStore)\n\t\t{\n\t\t\t// Have to ensure we emit loop header before we replace block.\n\t\t\tif (ir.merge_info.merge_type == MergeType::Loop && rewrite_phi_incoming_to == 0)\n\t\t\t{\n\t\t\t\tauto *direct_bb = new spv::Block(builder.getUniqueId(), *active_function);\n\n\t\t\t\t// Handle post-domination rule.\n\t\t\t\tif (ir.merge_info.continue_block && get_spv_block(ir.merge_info.continue_block) == bb)\n\t\t\t\t\temit_loop_header(direct_bb);\n\t\t\t\telse\n\t\t\t\t\temit_loop_header(nullptr);\n\n\t\t\t\tactive_function->addBlock(direct_bb);\n\t\t\t\tbuilder.createBranch(direct_bb);\n\t\t\t\tbb = direct_bb;\n\t\t\t\tbuilder.setBuildPoint(bb);\n\t\t\t}\n\n\t\t\t// Pseudo-op. Conditional return.\n\t\t\tauto *inner_bb = new spv::Block(builder.getUniqueId(), *active_function);\n\t\t\tauto *merge_bb = new spv::Block(builder.getUniqueId(), *active_function);\n\t\t\tactive_function->addBlock(inner_bb);\n\t\t\tactive_function->addBlock(merge_bb);\n\t\t\tbuilder.createSelectionMerge(merge_bb, 0);\n\t\t\tbuilder.createConditionalBranch(op->arguments[op->num_arguments - 1], inner_bb, merge_bb);\n\t\t\tbuilder.setBuildPoint(inner_bb);\n\n\t\t\tspv::Id inner_id = 0;\n\n\t\t\tif (op->op == spv::PseudoOpReturnCond)\n\t\t\t{\n\t\t\t\tbuilder.makeReturn(false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstd::unique_ptr<spv::Instruction> inst;\n\t\t\t\tif (op->op == spv::PseudoOpMaskedStore)\n\t\t\t\t{\n\t\t\t\t\tinst = std::make_unique<spv::Instruction>(spv::OpStore);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tinner_id = builder.getUniqueId();\n\t\t\t\t\tinst = std::make_unique<spv::Instruction>(inner_id, op->type_id, spv::OpLoad);\n\t\t\t\t\tassert(op->type_id);\n\t\t\t\t}\n\n\t\t\t\tunsigned literal_mask = op->get_literal_mask();\n\t\t\t\tfor (unsigned i = 0; i < op->num_arguments - 1; i++)\n\t\t\t\t{\n\t\t\t\t\tspv::Id arg = op->arguments[i];\n\t\t\t\t\tif (literal_mask & 1u)\n\t\t\t\t\t\tinst->addImmediateOperand(arg);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tassert(arg);\n\t\t\t\t\t\tinst->addIdOperand(arg);\n\t\t\t\t\t}\n\t\t\t\t\tliteral_mask >>= 1u;\n\t\t\t\t}\n\t\t\t\tadd_instruction(inner_bb, std::move(inst));\n\t\t\t\tbuilder.createBranch(merge_bb);\n\t\t\t}\n\n\t\t\tbuilder.setBuildPoint(merge_bb);\n\n\t\t\tif (op->op == spv::PseudoOpMaskedLoad)\n\t\t\t{\n\t\t\t\tauto phi = std::make_unique<spv::Instruction>(op->id, op->type_id, spv::OpPhi);\n\t\t\t\tphi->addIdOperand(inner_id);\n\t\t\t\tphi->addIdOperand(inner_bb->getId());\n\t\t\t\tphi->addIdOperand(builder.makeNullConstant(op->type_id));\n\t\t\t\tphi->addIdOperand(bb->getId());\n\t\t\t\tadd_instruction(merge_bb, std::move(phi));\n\t\t\t}\n\n\t\t\t// If this is called in a continue block, the loop header might have a PHI incoming,\n\t\t\t// and we'll have to rewrite that.\n\t\t\t// For purposes of handling PHI later, the incoming block is this ID, i.e. the selection construct merge.\n\t\t\tnode->id = merge_bb->getId();\n\t\t\trewrite_phi_incoming_to = node->id;\n\t\t\tbb = merge_bb;\n\t\t}\n\t\telse if (op->op != spv::OpNop)\n\t\t{\n\t\t\tif (op->op == spv::OpDemoteToHelperInvocationEXT || op->op == spv::OpIsHelperInvocationEXT)\n\t\t\t{\n\t\t\t\tbuilder.addExtension(\"SPV_EXT_demote_to_helper_invocation\");\n\t\t\t\tbuilder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);\n\t\t\t}\n\t\t\telse if (op->op == spv::OpTerminateRayKHR || op->op == spv::OpIgnoreIntersectionKHR ||\n\t\t\t         op->op == spv::OpEmitMeshTasksEXT)\n\t\t\t{\n\t\t\t\t// In DXIL, these must be by unreachable.\n\t\t\t\t// There is no [[noreturn]] qualifier used for these intrinsics apparently.\n\t\t\t\t// EmitMeshTasksEXT is similar, but ret void comes after.\n\t\t\t\timplicit_terminator = true;\n\t\t\t}\n\n\t\t\tstd::unique_ptr<spv::Instruction> inst;\n\t\t\tif (op->id != 0)\n\t\t\t{\n\t\t\t\tassert(op->type_id);\n\t\t\t\tinst = std::make_unique<spv::Instruction>(op->id, op->type_id, op->op);\n\t\t\t}\n\t\t\telse\n\t\t\t\tinst = std::make_unique<spv::Instruction>(op->op);\n\n\t\t\tunsigned literal_mask = op->get_literal_mask();\n\n\t\t\tfor (auto &arg : *op)\n\t\t\t{\n\t\t\t\tif (literal_mask & 1u)\n\t\t\t\t\tinst->addImmediateOperand(arg);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tassert(arg);\n\t\t\t\t\tinst->addIdOperand(arg);\n\t\t\t\t}\n\t\t\t\tliteral_mask >>= 1u;\n\t\t\t}\n\t\t\tadd_instruction(bb, std::move(inst));\n\t\t}\n\n\t\tif (op->flags & Operation::SubgroupSyncPost)\n\t\t{\n\t\t\tauto *post = builder.addInstruction(spv::OpControlBarrier);\n\t\t\tpost->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tpost->addIdOperand(builder.makeUintConstant(spv::ScopeSubgroup));\n\t\t\tpost->addIdOperand(builder.getWorkgroupBarrierSemanticsId());\n\t\t}\n\t}\n\n\tif (implicit_terminator)\n\t{\n\t\tif (ir.merge_info.merge_type != MergeType::None)\n\t\t{\n\t\t\tLOGE(\"Basic block has implicit terminator, but attempts to merge execution?\\n\");\n\t\t\tmark_error = true;\n\t\t}\n\t\telse if (ir.terminator.type != Terminator::Type::Unreachable && ir.terminator.type != Terminator::Type::Return)\n\t\t{\n\t\t\tLOGE(\"Implicitly terminated blocks must terminate with Unreachable or Return.\\n\");\n\t\t\tmark_error = true;\n\t\t}\n\n\t\treturn;\n\t}\n\n\t// Emit structured merge information.\n\tswitch (ir.merge_info.merge_type)\n\t{\n\tcase MergeType::Selection:\n\t\tif (ir.merge_info.merge_block)\n\t\t{\n\t\t\tbuilder.createSelectionMerge(get_spv_block(ir.merge_info.merge_block), ir.merge_info.selection_control_mask);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *unreachable_bb = new spv::Block(builder.getUniqueId(), *active_function);\n\t\t\tactive_function->addBlock(unreachable_bb);\n\t\t\tbuilder.setBuildPoint(unreachable_bb);\n\t\t\tbuilder.createUnreachable();\n\t\t\tbuilder.setBuildPoint(bb);\n\t\t\tbuilder.createSelectionMerge(unreachable_bb, 0);\n\t\t}\n\t\tbreak;\n\n\tcase MergeType::Loop:\n\t\tif (rewrite_phi_incoming_to == 0)\n\t\t\temit_loop_header(nullptr);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\t// Emit terminator.\n\tswitch (ir.terminator.type)\n\t{\n\tcase Terminator::Type::Unreachable:\n\t{\n\t\tbuilder.createUnreachable();\n\t\tbreak;\n\t}\n\n\tcase Terminator::Type::Branch:\n\t{\n\t\tauto *direct_target = get_spv_block(ir.terminator.direct_block);\n\t\tbuilder.createBranch(direct_target);\n\t\tif (rewrite_phi_incoming_to)\n\t\t\tdirect_target->rewritePhiIncoming(rewrite_phi_incoming_from, rewrite_phi_incoming_to);\n\t\tbreak;\n\t}\n\n\tcase Terminator::Type::Condition:\n\t{\n\t\tauto *true_block = get_spv_block(ir.terminator.true_block);\n\t\tauto *false_block = get_spv_block(ir.terminator.false_block);\n\n\t\t// This used to pass validator, but latest SPIRV-Tools as of 2023-02 started caring about it.\n\t\t// Patch this up late by rewriting loop header + conditional branch as\n\t\t// loop header -> direct -> selection merge to unreachable -> conditional branch.\n\t\t// It's easier to patch it up here than rewriting the CFG itself.\n\t\t// We only need to rewrite PHI incoming blocks.\n\t\t// A conditional terminator is fine if one of the branches target merge or continue block,\n\t\t// since a selection merge is no longer required.\n\t\tif (node->ir.merge_info.merge_type == MergeType::Loop &&\n\t\t    node->ir.terminator.type == Terminator::Type::Condition &&\n\t\t    node->ir.terminator.true_block != node->ir.merge_info.merge_block &&\n\t\t    node->ir.terminator.true_block != node->ir.merge_info.continue_block &&\n\t\t    node->ir.terminator.false_block != node->ir.merge_info.merge_block &&\n\t\t    node->ir.terminator.false_block != node->ir.merge_info.continue_block)\n\t\t{\n\t\t\tif (rewrite_phi_incoming_to == 0)\n\t\t\t{\n\t\t\t\tauto *fake_selection_bb = new spv::Block(builder.getUniqueId(), *active_function);\n\t\t\t\tauto *unreachable_bb = new spv::Block(builder.getUniqueId(), *active_function);\n\t\t\t\tactive_function->addBlock(fake_selection_bb);\n\t\t\t\tactive_function->addBlock(unreachable_bb);\n\t\t\t\tbuilder.createBranch(fake_selection_bb);\n\t\t\t\tbuilder.setBuildPoint(fake_selection_bb);\n\t\t\t\tbuilder.createSelectionMerge(unreachable_bb, 0);\n\t\t\t\tbuilder.createConditionalBranch(ir.terminator.conditional_id, true_block, false_block);\n\t\t\t\tbuilder.setBuildPoint(unreachable_bb);\n\t\t\t\tbuilder.createUnreachable();\n\n\t\t\t\t// For purposes of handling PHI later, the incoming block is this ID, i.e. the selection construct.\n\t\t\t\t// Any branches that target the loop header have already been resolved since we emit SPIR-V blocks\n\t\t\t\t// in traversal order.\n\t\t\t\t// We don't need to consider single loop block constructs since those will never hit this\n\t\t\t\t// code path. In that case, true or false block would have targeted continue block and\n\t\t\t\t// avoided this workaround in the first place.\n\t\t\t\tnode->id = fake_selection_bb->getId();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// If we added blocks through masked ops, we have become a selection\n\t\t\t\t// construction instead of a loop, and we have to add a merge target to make this valid.\n\t\t\t\t// If we are directly branching to continue or merge target, we can omit a merge,\n\t\t\t\t// since that case does not need a merge.\n\t\t\t\tauto *unreachable_bb = new spv::Block(builder.getUniqueId(), *active_function);\n\t\t\t\tactive_function->addBlock(unreachable_bb);\n\t\t\t\tbuilder.setBuildPoint(unreachable_bb);\n\t\t\t\tbuilder.createUnreachable();\n\t\t\t\tbuilder.setBuildPoint(bb);\n\t\t\t\tbuilder.createSelectionMerge(unreachable_bb, 0);\n\t\t\t\tbuilder.createConditionalBranch(ir.terminator.conditional_id,\n\t\t\t\t                                true_block, false_block);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbuilder.createConditionalBranch(ir.terminator.conditional_id,\n\t\t\t                                true_block, false_block);\n\t\t}\n\n\t\tif (rewrite_phi_incoming_to)\n\t\t{\n\t\t\ttrue_block->rewritePhiIncoming(rewrite_phi_incoming_from, rewrite_phi_incoming_to);\n\t\t\tfalse_block->rewritePhiIncoming(rewrite_phi_incoming_from, rewrite_phi_incoming_to);\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase Terminator::Type::Switch:\n\t{\n\t\tauto switch_op = std::make_unique<spv::Instruction>(spv::OpSwitch);\n\t\tswitch_op->addIdOperand(ir.terminator.conditional_id);\n\n\t\tauto default_itr = std::find_if(ir.terminator.cases.begin(), ir.terminator.cases.end(),\n\t\t                                [](const Terminator::Case &c) { return c.is_default; });\n\t\tassert(default_itr != ir.terminator.cases.end());\n\t\tswitch_op->addIdOperand(default_itr->node->id);\n\n\t\tauto *default_block = get_spv_block(default_itr->node);\n\t\tdefault_block->addPredecessor(bb);\n\t\tif (rewrite_phi_incoming_to)\n\t\t\tdefault_block->rewritePhiIncoming(rewrite_phi_incoming_from, rewrite_phi_incoming_to);\n\t\tfor (auto &switch_case : ir.terminator.cases)\n\t\t{\n\t\t\tif (switch_case.is_default)\n\t\t\t\tcontinue;\n\t\t\tswitch_op->addImmediateOperand(switch_case.value);\n\t\t\tswitch_op->addIdOperand(switch_case.node->id);\n\n\t\t\tauto *case_block = get_spv_block(switch_case.node);\n\t\t\tcase_block->addPredecessor(bb);\n\t\t\tif (rewrite_phi_incoming_to)\n\t\t\t\tcase_block->rewritePhiIncoming(rewrite_phi_incoming_from, rewrite_phi_incoming_to);\n\t\t}\n\t\tadd_instruction(bb, std::move(switch_op));\n\t\tbreak;\n\t}\n\n\tcase Terminator::Type::Kill:\n\t{\n\t\tauto kill_op = std::make_unique<spv::Instruction>(spv::OpKill);\n\t\tadd_instruction(bb, std::move(kill_op));\n\t\tbreak;\n\t}\n\n\tcase Terminator::Type::Return:\n\t{\n\t\tif (discard_state_var_id)\n\t\t\tbuild_discard_call_exit();\n\t\tbuilder.makeReturn(false, ir.terminator.return_value);\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nbool SPIRVModule::finalize_spirv(Vector<uint32_t> &spirv) const\n{\n\treturn impl->finalize_spirv(spirv);\n}\n\nvoid SPIRVModule::Impl::emit_entry_point_function_body(CFGStructurizer &structurizer)\n{\n\tactive_function = entry_function;\n\t{\n\t\tstructurizer.traverse(*this);\n\t\tbuilder.setBuildPoint(active_function->getEntryBlock());\n\t\tbuilder.createBranch(get_spv_block(structurizer.get_entry_block()));\n\t\tbuilder.leaveFunction();\n\t}\n\tactive_function = nullptr;\n}\n\nvoid SPIRVModule::Impl::emit_leaf_function_body(spv::Function *func, CFGStructurizer &structurizer)\n{\n\tactive_function = func;\n\t{\n\t\tstructurizer.traverse(*this);\n\t\tbuilder.setBuildPoint(active_function->getEntryBlock());\n\t\tbuilder.createBranch(get_spv_block(structurizer.get_entry_block()));\n\t\tbuilder.leaveFunction();\n\t}\n\tactive_function = nullptr;\n}\n\nvoid SPIRVModule::Impl::register_active_variable(spv::StorageClass storage, spv::Id id)\n{\n\tbool register_entry_point;\n\t// In SPIR-V 1.4, any global variable is part of the interface.\n\tif (spirv_requires_14())\n\t\tregister_entry_point = storage != spv::StorageClassFunction;\n\telse\n\t\tregister_entry_point = storage == spv::StorageClassOutput || storage == spv::StorageClassInput;\n\n\tif (register_entry_point)\n\t\tentry_point->addIdOperand(id);\n}\n\nspv::Id SPIRVModule::Impl::create_variable(spv::StorageClass storage, spv::Id type, const char *name)\n{\n\tspv::Id id = builder.createVariable(storage, type, name);\n\tregister_active_variable(storage, id);\n\treturn id;\n}\n\nspv::Id SPIRVModule::Impl::create_variable_with_initializer(spv::StorageClass storage, spv::Id type,\n                                                            spv::Id initializer, const char *name)\n{\n\tspv::Id id = builder.createVariableWithInitializer(storage, type, initializer, name);\n\tregister_active_variable(storage, id);\n\treturn id;\n}\n\nvoid SPIRVModule::emit_entry_point_function_body(CFGStructurizer &structurizer)\n{\n\timpl->emit_entry_point_function_body(structurizer);\n}\n\nvoid SPIRVModule::emit_leaf_function_body(spv::Function *func, CFGStructurizer &structurizer)\n{\n\timpl->emit_leaf_function_body(func, structurizer);\n}\n\nspv::Builder &SPIRVModule::get_builder()\n{\n\treturn impl->builder;\n}\n\nspv::Instruction *SPIRVModule::get_entry_point()\n{\n\treturn impl->entry_point;\n}\n\nspv::Function *SPIRVModule::get_entry_function()\n{\n\treturn impl->entry_function;\n}\n\nuint32_t SPIRVModule::allocate_id()\n{\n\treturn impl->builder.getUniqueId();\n}\n\nuint32_t SPIRVModule::allocate_ids(uint32_t count)\n{\n\treturn impl->builder.getUniqueIds(count);\n}\n\nvoid SPIRVModule::enable_shader_discard(bool supports_demote)\n{\n\timpl->enable_shader_discard(supports_demote);\n}\n\nspv::Id SPIRVModule::get_builtin_shader_input(spv::BuiltIn builtin)\n{\n\treturn impl->get_builtin_shader_input(builtin);\n}\n\nspv::Id SPIRVModule::get_builtin_shader_output(spv::BuiltIn builtin)\n{\n\treturn impl->get_builtin_shader_output(builtin);\n}\n\nbool SPIRVModule::has_builtin_shader_input(spv::BuiltIn builtin) const\n{\n\treturn impl->has_builtin_shader_input(builtin);\n}\n\nbool SPIRVModule::has_builtin_shader_output(spv::BuiltIn builtin) const\n{\n\treturn impl->has_builtin_shader_output(builtin);\n}\n\nvoid SPIRVModule::register_builtin_shader_input(spv::Id id, spv::BuiltIn builtin)\n{\n\timpl->register_builtin_shader_input(id, builtin);\n}\n\nvoid SPIRVModule::register_builtin_shader_output(spv::Id id, spv::BuiltIn builtin)\n{\n\timpl->register_builtin_shader_output(id, builtin);\n}\n\nbool SPIRVModule::query_builtin_shader_input(spv::Id id, spv::BuiltIn *builtin) const\n{\n\treturn impl->query_builtin_shader_input(id, builtin);\n}\n\nbool SPIRVModule::builtin_requires_volatile(spv::BuiltIn builtin) const\n{\n\treturn impl->builtin_requires_volatile(builtin);\n}\n\nbool SPIRVModule::query_builtin_shader_output(spv::Id id, spv::BuiltIn *builtin) const\n{\n\treturn impl->query_builtin_shader_output(id, builtin);\n}\n\nOperation *SPIRVModule::allocate_op()\n{\n\treturn impl->operation_pool.allocate();\n}\n\nOperation *SPIRVModule::allocate_op(spv::Op op)\n{\n\treturn impl->operation_pool.allocate(op);\n}\n\nOperation *SPIRVModule::allocate_op(spv::Op op, spv::Id id, spv::Id type_id)\n{\n\treturn impl->operation_pool.allocate(op, id, type_id);\n}\n\nspv::Id SPIRVModule::create_variable(spv::StorageClass storage, spv::Id type, const char *name)\n{\n\treturn impl->create_variable(storage, type, name);\n}\n\nspv::Id SPIRVModule::create_variable_with_initializer(spv::StorageClass storage, spv::Id type,\n                                                      spv::Id initializer, const char *name)\n{\n\treturn impl->create_variable_with_initializer(storage, type, initializer, name);\n}\n\nspv::Id SPIRVModule::get_helper_call_id(HelperCall call, spv::Id type_id)\n{\n\treturn impl->get_helper_call_id(*this, call, type_id);\n}\n\nspv::Id SPIRVModule::get_helper_call_id(HelperCall call, const spv::Id *aux_ids, uint32_t aux_id_count)\n{\n\treturn impl->get_helper_call_id(*this, call, aux_ids, aux_id_count);\n}\n\nspv::Id SPIRVModule::get_robust_physical_cbv_load_call_id(spv::Id type_id, spv::Id ptr_type_id, unsigned alignment)\n{\n\treturn impl->build_robust_physical_cbv_load(*this, type_id, ptr_type_id, alignment);\n}\n\nvoid SPIRVModule::set_descriptor_qa_info(const DescriptorQAInfo &info)\n{\n\timpl->descriptor_qa_info = info;\n}\n\nvoid SPIRVModule::set_instruction_instrumentation_info(const InstructionInstrumentationInfo &info)\n{\n\timpl->instruction_instrumentation.info = info;\n}\n\nconst DescriptorQAInfo &SPIRVModule::get_descriptor_qa_info() const\n{\n\treturn impl->descriptor_qa_info;\n}\n\nvoid SPIRVModule::set_override_spirv_version(uint32_t version)\n{\n\timpl->override_spirv_version = std::max<uint32_t>(impl->override_spirv_version, version);\n}\n\nvoid SPIRVModule::set_helper_lanes_participate_in_wave_ops(bool enable)\n{\n\timpl->helper_lanes_participate_in_wave_ops = enable;\n}\n\nvoid SPIRVModule::set_entry_build_point(spv::Function *func)\n{\n\tget_builder().setBuildPoint(func->getEntryBlock());\n}\n\nbool SPIRVModule::opcode_has_side_effect_and_result(spv::Op opcode)\n{\n\tswitch (opcode)\n\t{\n\tcase spv::OpAtomicIAdd:\n\tcase spv::OpAtomicIDecrement:\n\tcase spv::OpAtomicIIncrement:\n\tcase spv::OpAtomicISub:\n\tcase spv::OpAtomicAnd:\n\tcase spv::OpAtomicOr:\n\tcase spv::OpAtomicXor:\n\tcase spv::OpAtomicUMax:\n\tcase spv::OpAtomicUMin:\n\tcase spv::OpAtomicSMax:\n\tcase spv::OpAtomicSMin:\n\tcase spv::OpAtomicFAddEXT:\n\tcase spv::OpAtomicFMaxEXT:\n\tcase spv::OpAtomicFMinEXT:\n\tcase spv::OpAtomicCompareExchange:\n\tcase spv::OpAtomicCompareExchangeWeak:\n\tcase spv::OpAtomicExchange:\n\tcase spv::OpAtomicStore:\n\tcase spv::OpFunctionCall: // This depends, but we have to assume it might.\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool SPIRVModule::opcode_is_control_dependent(spv::Op opcode)\n{\n\t// An opcode is considered control dependent if it is affected by other invocations in the subgroup.\n\tswitch (opcode)\n\t{\n\t\t// Anything derivatives\n\tcase spv::OpDPdx:\n\tcase spv::OpDPdxCoarse:\n\tcase spv::OpDPdxFine:\n\tcase spv::OpDPdy:\n\tcase spv::OpDPdyCoarse:\n\tcase spv::OpDPdyFine:\n\tcase spv::OpFwidth:\n\tcase spv::OpFwidthCoarse:\n\tcase spv::OpFwidthFine:\n\n\t\t// Anything implicit LOD\n\tcase spv::OpImageSampleImplicitLod:\n\tcase spv::OpImageSampleDrefImplicitLod:\n\tcase spv::OpImageSampleProjImplicitLod:\n\tcase spv::OpImageSampleProjDrefImplicitLod:\n\tcase spv::OpImageSparseSampleImplicitLod:\n\tcase spv::OpImageSparseSampleDrefImplicitLod:\n\tcase spv::OpImageSparseSampleProjImplicitLod:\n\tcase spv::OpImageSparseSampleProjDrefImplicitLod:\n\tcase spv::OpImageQueryLod:\n\tcase spv::OpImageDrefGather:\n\tcase spv::OpImageGather:\n\tcase spv::OpImageSparseDrefGather:\n\tcase spv::OpImageSparseGather:\n\n\t\t// Anything subgroups\n\tcase spv::OpGroupNonUniformElect:\n\tcase spv::OpGroupNonUniformAll:\n\tcase spv::OpGroupNonUniformAny:\n\tcase spv::OpGroupNonUniformAllEqual:\n\tcase spv::OpGroupNonUniformBroadcast:\n\tcase spv::OpGroupNonUniformBroadcastFirst:\n\tcase spv::OpGroupNonUniformBallot:\n\tcase spv::OpGroupNonUniformInverseBallot:\n\tcase spv::OpGroupNonUniformBallotBitExtract:\n\tcase spv::OpGroupNonUniformBallotBitCount:\n\tcase spv::OpGroupNonUniformBallotFindLSB:\n\tcase spv::OpGroupNonUniformBallotFindMSB:\n\tcase spv::OpGroupNonUniformShuffle:\n\tcase spv::OpGroupNonUniformShuffleXor:\n\tcase spv::OpGroupNonUniformShuffleUp:\n\tcase spv::OpGroupNonUniformShuffleDown:\n\tcase spv::OpGroupNonUniformIAdd:\n\tcase spv::OpGroupNonUniformFAdd:\n\tcase spv::OpGroupNonUniformIMul:\n\tcase spv::OpGroupNonUniformFMul:\n\tcase spv::OpGroupNonUniformSMin:\n\tcase spv::OpGroupNonUniformUMin:\n\tcase spv::OpGroupNonUniformFMin:\n\tcase spv::OpGroupNonUniformSMax:\n\tcase spv::OpGroupNonUniformUMax:\n\tcase spv::OpGroupNonUniformFMax:\n\tcase spv::OpGroupNonUniformBitwiseAnd:\n\tcase spv::OpGroupNonUniformBitwiseOr:\n\tcase spv::OpGroupNonUniformBitwiseXor:\n\tcase spv::OpGroupNonUniformLogicalAnd:\n\tcase spv::OpGroupNonUniformLogicalOr:\n\tcase spv::OpGroupNonUniformLogicalXor:\n\tcase spv::OpGroupNonUniformQuadBroadcast:\n\tcase spv::OpGroupNonUniformQuadSwap:\n\n\t\t// Control barriers\n\tcase spv::OpControlBarrier:\n\tcase spv::OpMemoryBarrier:\n\n\t\t// Internal helpers function calls may or may not include control dependent ops.\n\tcase spv::OpFunctionCall:\n\n\t\t// Cooperative matrix is control sensitive.\n\tcase spv::OpCooperativeMatrixLoadKHR:\n\tcase spv::OpCooperativeMatrixStoreKHR:\n\tcase spv::OpCooperativeMatrixMulAddKHR:\n\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nSPIRVModule::~SPIRVModule()\n{\n}\n} // namespace dxil_spv\n"
  },
  {
    "path": "spirv_module.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"cfg_structurizer.hpp\"\n#include \"ir.hpp\"\n#include \"descriptor_qa.hpp\"\n#include <memory>\n\nnamespace spv\n{\nclass Function;\nclass Builder;\nclass Instruction;\n\nstatic constexpr spv::Op PseudoOpReturnCond = spv::Op(0x100000);\nstatic constexpr spv::Op PseudoOpInstrumentExternallyVisibleStore = spv::Op(0x100001);\nstatic constexpr spv::Op PseudoOpMaskedLoad = spv::Op(0x100002);\nstatic constexpr spv::Op PseudoOpMaskedStore = spv::Op(0x100003);\n} // namespace spv\n\nnamespace dxil_spv\n{\nstruct CFGNode;\nclass CFGNodePool;\n\nenum class HelperCall\n{\n\tDescriptorQACheck,\n\tWaveMatch,\n\tWaveMultiPrefixFAdd,\n\tWaveMultiPrefixIAdd,\n\tWaveMultiPrefixFMul,\n\tWaveMultiPrefixIMul,\n\tWaveMultiPrefixBitAnd,\n\tWaveMultiPrefixBitOr,\n\tWaveMultiPrefixBitXor,\n\tWaveMultiPrefixCountBits,\n\tRobustAtomicCounter,\n\tQuadAll,\n\tQuadAny,\n\tWaveIsFirstLaneMasked,\n\tWaveActiveAllEqualMasked,\n\tWaveReadFirstLaneMasked,\n\tAtomicImageR64Compact,\n\tAtomicImageArrayR64Compact,\n\tAtomicImageR64CompactNonUniform,\n\tAtomicImageArrayR64CompactNonUniform,\n\tFinishCrossGroupSharing,\n\tAllocateThreadNodeRecords,\n\tAllocateGroupNodeRecords,\n\tAllocateThreadNodeRecordsWaterfall,\n\tThreadIncrementOutputCount,\n\tGroupIncrementOutputCount,\n\tNodeCoalescePayloadOffset,\n\tIsQuadUniformControlFlow,\n\tValidateBDALoadStore,\n\tAllocateInvocationID,\n\tCoopMatFP8toFP16,\n\tCoopMatFP16toFP8,\n\tCoopMatTransfer,\n\tCoopMatSaturationFixup,\n\tCoopMatSaturateFP8\n};\n\nenum class BDAOperation\n{\n\tLoad,\n\tStore,\n\tAtomicRMW,\n\tIndirectRead\n};\n\nclass SPIRVModule\n{\npublic:\n\tSPIRVModule();\n\t~SPIRVModule();\n\tbool finalize_spirv(Vector<uint32_t> &spirv) const;\n\n\tuint32_t allocate_id();\n\tuint32_t allocate_ids(uint32_t count);\n\n\tvoid emit_entry_point(spv::ExecutionModel model, const char *name, bool physical_storage,\n\t                      spv::MemoryModel memory_model);\n\tvoid emit_entry_point_function_body(CFGStructurizer &structurizer);\n\tvoid emit_leaf_function_body(spv::Function *func, CFGStructurizer &structurizer);\n\n\tspv::Builder &get_builder();\n\tspv::Instruction *get_entry_point();\n\tspv::Function *get_entry_function();\n\n\tvoid enable_shader_discard(bool support_demote);\n\tspv::Id get_builtin_shader_input(spv::BuiltIn builtin);\n\tspv::Id get_builtin_shader_output(spv::BuiltIn builtin);\n\tbool has_builtin_shader_input(spv::BuiltIn builtin) const;\n\tbool has_builtin_shader_output(spv::BuiltIn builtin) const;\n\tvoid register_builtin_shader_input(spv::Id id, spv::BuiltIn builtin);\n\tbool query_builtin_shader_input(spv::Id id, spv::BuiltIn *builtin) const;\n\tbool builtin_requires_volatile(spv::BuiltIn builtin) const;\n\n\tvoid register_builtin_shader_output(spv::Id id, spv::BuiltIn builtin);\n\tbool query_builtin_shader_output(spv::Id id, spv::BuiltIn *builtin) const;\n\n\tOperation *allocate_op();\n\tOperation *allocate_op(spv::Op op);\n\tOperation *allocate_op(spv::Op op, spv::Id id, spv::Id type_id);\n\n\tspv::Id create_variable(spv::StorageClass storage, spv::Id type, const char *name = nullptr);\n\tspv::Id create_variable_with_initializer(spv::StorageClass storage, spv::Id type, spv::Id initializer,\n\t                                         const char *name = nullptr);\n\n\tspv::Id get_helper_call_id(HelperCall call, spv::Id type_id = 0);\n\tspv::Id get_helper_call_id(HelperCall call, const spv::Id *aux_ids, uint32_t aux_id_count);\n\tspv::Id get_robust_physical_cbv_load_call_id(spv::Id type_id, spv::Id ptr_type_id, unsigned alignment);\n\tvoid set_descriptor_qa_info(const DescriptorQAInfo &info);\n\tvoid set_instruction_instrumentation_info(const InstructionInstrumentationInfo &info);\n\tconst DescriptorQAInfo &get_descriptor_qa_info() const;\n\n\tstatic bool opcode_is_control_dependent(spv::Op opcode);\n\tstatic bool opcode_has_side_effect_and_result(spv::Op opcode);\n\n\tvoid set_override_spirv_version(uint32_t version);\n\tvoid set_helper_lanes_participate_in_wave_ops(bool enable);\n\n\tvoid set_entry_build_point(spv::Function *func);\n\n\tDXIL_SPV_OVERRIDE_NEW_DELETE\n\nprivate:\n\tstruct Impl;\n\tstd::unique_ptr<Impl> impl;\n};\n} // namespace dxil_spv\n"
  },
  {
    "path": "spirv_module_instrumentation.cpp",
    "content": "/* Copyright (c) 2025 Hans-Kristian Arntzen for Valve Corporation\n*\n* SPDX-License-Identifier: MIT\n*\n* Permission is hereby granted, free of charge, to any person obtaining\n* a copy of this software and associated documentation files (the\n* \"Software\"), to deal in the Software without restriction, including\n* without limitation the rights to use, copy, modify, merge, publish,\n* distribute, sublicense, and/or sell copies of the Software, and to\n* permit persons to whom the Software is furnished to do so, subject to\n* the following conditions:\n*\n* The above copyright notice and this permission notice shall be\n* included in all copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#include \"spirv_module.hpp\"\n#include \"SpvBuilder.h\"\n#include \"GLSL.std.450.h\"\n\nnamespace dxil_spv\n{\nstatic spv::Id build_instrumentation_ssbo(SPIRVModule &module, spv::Id data_type, uint32_t stride, const char *member_name,\n                                          const char *block_name, const char *variable_name,\n                                          uint32_t desc_set, uint32_t binding)\n{\n\tauto &builder = module.get_builder();\n\n\tspv::Id data_array_type = builder.makeRuntimeArray(data_type);\n\tbuilder.addDecoration(data_array_type, spv::DecorationArrayStride, stride);\n\tspv::Id block_type = builder.makeStructType({ data_array_type }, block_name);\n\tbuilder.addMemberName(block_type, 0, member_name);\n\tbuilder.addMemberDecoration(block_type, 0, spv::DecorationOffset, 0);\n\tbuilder.addDecoration(block_type, spv::DecorationBlock);\n\n\tspv::Id var_id = module.create_variable(spv::StorageClassStorageBuffer, block_type, variable_name);\n\tbuilder.addDecoration(var_id, spv::DecorationDescriptorSet, desc_set);\n\tbuilder.addDecoration(var_id, spv::DecorationBinding, binding);\n\treturn var_id;\n}\n\nstatic spv::Id build_u64_add_u32(spv::Builder &builder, spv::Id a, spv::Id b)\n{\n\tspv::Id u32_type = builder.makeUintType(32);\n\tauto *extract_lo = builder.addInstruction(u32_type, spv::OpCompositeExtract);\n\textract_lo->addIdOperand(a);\n\textract_lo->addImmediateOperand(0);\n\tauto *extract_hi = builder.addInstruction(u32_type, spv::OpCompositeExtract);\n\textract_hi->addIdOperand(a);\n\textract_hi->addImmediateOperand(1);\n\n\tspv::Id struct_type = builder.makeStructType({ u32_type, u32_type }, \"IAddCarryResult\");\n\tauto *add_carry = builder.addInstruction(struct_type, spv::OpIAddCarry);\n\tadd_carry->addIdOperand(extract_lo->getResultId());\n\tadd_carry->addIdOperand(b);\n\n\tauto *extract_carry_lo = builder.addInstruction(u32_type, spv::OpCompositeExtract);\n\textract_carry_lo->addIdOperand(add_carry->getResultId());\n\textract_carry_lo->addImmediateOperand(0);\n\n\tauto *extract_carry = builder.addInstruction(u32_type, spv::OpCompositeExtract);\n\textract_carry->addIdOperand(add_carry->getResultId());\n\textract_carry->addImmediateOperand(1);\n\n\tauto *add_hi = builder.addInstruction(u32_type, spv::OpIAdd);\n\tadd_hi->addIdOperand(extract_hi->getResultId());\n\tadd_hi->addIdOperand(extract_carry->getResultId());\n\n\tspv::Id uvec2_type = builder.makeVectorType(u32_type, 2);\n\tauto *combine = builder.addInstruction(uvec2_type, spv::OpCompositeConstruct);\n\tcombine->addIdOperand(extract_carry_lo->getResultId());\n\tcombine->addIdOperand(add_hi->getResultId());\n\n\treturn combine->getResultId();\n}\n\nstatic spv::Id build_byte_mask(spv::Builder &builder, spv::Id addr_lo_id, spv::Id byte_count)\n{\n\tspv::Id u32_type = builder.makeUintType(32);\n\tauto *extract = builder.addInstruction(u32_type, spv::OpBitFieldUExtract);\n\tauto *and_op = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\tauto *shift_op = builder.addInstruction(u32_type, spv::OpShiftLeftLogical);\n\tauto *and2_op = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\n\textract->addIdOperand(builder.makeUintConstant(~0u));\n\textract->addIdOperand(builder.makeUintConstant(0u));\n\textract->addIdOperand(byte_count);\n\tand_op->addIdOperand(addr_lo_id);\n\tand_op->addIdOperand(builder.makeUintConstant(15));\n\tshift_op->addIdOperand(extract->getResultId());\n\tshift_op->addIdOperand(and_op->getResultId());\n\tand2_op->addIdOperand(shift_op->getResultId());\n\tand2_op->addIdOperand(builder.makeUintConstant(0xffff));\n\n\treturn and2_op->getResultId();\n}\n\nstatic spv::Id build_word_mask(spv::Builder &builder, spv::Id addr_lo_id, spv::Id byte_count)\n{\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tauto *mask_op = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\tauto *add_op = builder.addInstruction(u32_type, spv::OpIAdd);\n\tauto *add3_op = builder.addInstruction(u32_type, spv::OpIAdd);\n\tauto *slr2 = builder.addInstruction(u32_type, spv::OpShiftRightLogical);\n\tauto *extract_shift = builder.addInstruction(u32_type, spv::OpBitFieldUExtract);\n\tauto *extract = builder.addInstruction(u32_type, spv::OpBitFieldUExtract);\n\tauto *shifted = builder.addInstruction(u32_type, spv::OpShiftLeftLogical);\n\tauto *final_mask = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\n\tmask_op->addIdOperand(addr_lo_id);\n\tmask_op->addIdOperand(builder.makeUintConstant(3));\n\tadd_op->addIdOperand(mask_op->getResultId());\n\tadd_op->addIdOperand(byte_count);\n\tadd3_op->addIdOperand(add_op->getResultId());\n\tadd3_op->addIdOperand(builder.makeUintConstant(3));\n\tslr2->addIdOperand(add3_op->getResultId());\n\tslr2->addIdOperand(builder.makeUintConstant(2));\n\n\textract_shift->addIdOperand(addr_lo_id);\n\textract_shift->addIdOperand(builder.makeUintConstant(2));\n\textract_shift->addIdOperand(builder.makeUintConstant(2));\n\n\textract->addIdOperand(builder.makeUintConstant(~0u));\n\textract->addIdOperand(builder.makeUintConstant(0));\n\textract->addIdOperand(slr2->getResultId());\n\n\tshifted->addIdOperand(extract->getResultId());\n\tshifted->addIdOperand(extract_shift->getResultId());\n\n\tfinal_mask->addIdOperand(shifted->getResultId());\n\tfinal_mask->addIdOperand(builder.makeUintConstant(0xf));\n\n\treturn final_mask->getResultId();\n}\n\nstatic spv::Id build_hash_call(SPIRVModule &module)\n{\n\tauto &builder = module.get_builder();\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\n\tauto *func =\n\t    builder.makeFunctionEntry(spv::NoPrecision, uint_type, \"AddrHash\", { uvec2_type, uint_type }, {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"addr\");\n\tbuilder.addName(func->getParamId(1), \"prime\");\n\n\tauto *extract0 = builder.addInstruction(uint_type, spv::OpCompositeExtract);\n\tauto *extract1 = builder.addInstruction(uint_type, spv::OpCompositeExtract);\n\tauto *shift_lo = builder.addInstruction(uint_type, spv::OpShiftRightLogical);\n\tauto *mask_hi = builder.addInstruction(uint_type, spv::OpBitwiseAnd);\n\tauto *construct = builder.addInstruction(uvec2_type, spv::OpCompositeConstruct);\n\tauto *splat = builder.addInstruction(uvec2_type, spv::OpCompositeConstruct);\n\n\textract0->addIdOperand(func->getParamId(0));\n\textract0->addImmediateOperand(0);\n\textract1->addIdOperand(func->getParamId(0));\n\textract1->addImmediateOperand(1);\n\n\tshift_lo->addIdOperand(extract0->getResultId());\n\tshift_lo->addIdOperand(builder.makeUintConstant(4));\n\tmask_hi->addIdOperand(extract1->getResultId());\n\tmask_hi->addIdOperand(builder.makeUintConstant(0xffff));\n\n\tconstruct->addIdOperand(shift_lo->getResultId());\n\tconstruct->addIdOperand(mask_hi->getResultId());\n\n\tsplat->addIdOperand(func->getParamId(1));\n\tsplat->addIdOperand(func->getParamId(1));\n\n\tspv::Id ret_id = construct->getResultId();\n\tspv::Id splat_id = splat->getResultId();\n\n\tspv::Id const8 = builder.makeUintConstant(8);\n\tspv::Id const8_splat = builder.makeCompositeConstant(uvec2_type, { const8, const8 });\n\n\tfor (int i = 0; i < 6; i++)\n\t{\n\t\tauto *shuffle = builder.addInstruction(uvec2_type, spv::OpVectorShuffle);\n\t\tshuffle->addIdOperand(ret_id);\n\t\tshuffle->addIdOperand(ret_id);\n\t\tshuffle->addImmediateOperand(1);\n\t\tshuffle->addImmediateOperand(0);\n\n\t\tauto *shifted = builder.addInstruction(uvec2_type, spv::OpShiftRightLogical);\n\t\tshifted->addIdOperand(ret_id);\n\t\tshifted->addIdOperand(const8_splat);\n\n\t\tauto *xor_op = builder.addInstruction(uvec2_type, spv::OpBitwiseXor);\n\t\txor_op->addIdOperand(shifted->getResultId());\n\t\txor_op->addIdOperand(shuffle->getResultId());\n\n\t\tauto *mult = builder.addInstruction(uvec2_type, spv::OpIMul);\n\t\tmult->addIdOperand(xor_op->getResultId());\n\t\tmult->addIdOperand(splat_id);\n\n\t\tret_id = mult->getResultId();\n\t}\n\n\tauto *extract = builder.addInstruction(uint_type, spv::OpCompositeExtract);\n\textract->addIdOperand(ret_id);\n\textract->addImmediateOperand(0);\n\tret_id = extract->getResultId();\n\n\tbuilder.makeReturn(false, ret_id);\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n\nstatic spv::Id build_hash_mask(spv::Builder &builder, spv::Id var_id)\n{\n\tauto *len = builder.addInstruction(builder.makeUintType(32), spv::OpArrayLength);\n\tauto *find_msb = builder.addInstruction(builder.makeUintType(32), spv::OpExtInst);\n\tauto *extract = builder.addInstruction(builder.makeUintType(32), spv::OpBitFieldUExtract);\n\n\tspv::Id glsl = builder.import(\"GLSL.std.450\");\n\n\tlen->addIdOperand(var_id);\n\tlen->addImmediateOperand(0);\n\n\tfind_msb->addIdOperand(glsl);\n\tfind_msb->addImmediateOperand(GLSLstd450FindUMsb);\n\tfind_msb->addIdOperand(len->getResultId());\n\n\textract->addIdOperand(builder.makeUintConstant(~0u));\n\textract->addIdOperand(builder.makeUintConstant(0));\n\textract->addIdOperand(find_msb->getResultId());\n\n\treturn extract->getResultId();\n}\n\nstatic spv::Id build_hash_offset(spv::Builder &builder, spv::Id var_id)\n{\n\tauto *len = builder.addInstruction(builder.makeUintType(32), spv::OpArrayLength);\n\tauto *find_msb = builder.addInstruction(builder.makeUintType(32), spv::OpExtInst);\n\tauto *extract = builder.addInstruction(builder.makeUintType(32), spv::OpBitFieldUExtract);\n    auto *extract_minus_1 = builder.addInstruction(builder.makeUintType(32), spv::OpISub);\n\n\tspv::Id glsl = builder.import(\"GLSL.std.450\");\n\n\tlen->addIdOperand(var_id);\n\tlen->addImmediateOperand(0);\n\n\tfind_msb->addIdOperand(glsl);\n\tfind_msb->addImmediateOperand(GLSLstd450FindUMsb);\n\tfind_msb->addIdOperand(len->getResultId());\n\n\textract->addIdOperand(len->getResultId());\n\textract->addIdOperand(builder.makeUintConstant(0));\n\textract->addIdOperand(find_msb->getResultId());\n\n    extract_minus_1->addIdOperand(extract->getResultId());\n    extract_minus_1->addIdOperand(builder.makeUintConstant(1));\n\n    return extract_minus_1->getResultId();\n}\n\nstatic spv::Id build_get_invalidation_mask(spv::Builder &builder, spv::Id id, spv::Id byte_mask_id, spv::Id word_mask_id)\n{\n\tstatic const uint64_t invalidation_masks[] = {\n\t\t0x0fffff0000, // Load -> store and atomics no longer valid\n\t\t0xffffffffff, // Store -> nothing is valid\n\t\t0xf0ffffffff, // AtomicRMW -> only atomics are valid\n\t\t0x0fffff0000, // IndirectRead -> same as load\n\t};\n\n    spv::Id u32_type = builder.makeUintType(32);\n\tspv::Id u64_type = builder.makeUintType(64);\n\tspv::Id u64vec4_type = builder.makeVectorType(u64_type, 4);\n\tVector<spv::Id> invalidation_mask_elems;\n\tinvalidation_mask_elems.reserve(4);\n\tfor (auto &mask : invalidation_masks)\n\t\tinvalidation_mask_elems.push_back(builder.makeUint64Constant(mask));\n\tspv::Id invalidation_table = builder.makeCompositeConstant(u64vec4_type, invalidation_mask_elems);\n\n\tauto *extract = builder.addInstruction(u64_type, spv::OpVectorExtractDynamic);\n\textract->addIdOperand(invalidation_table);\n\textract->addIdOperand(id);\n\n    auto *byte_mask_shift = builder.addInstruction(u32_type, spv::OpShiftLeftLogical);\n    auto *word_mask_shift = builder.addInstruction(u32_type, spv::OpShiftLeftLogical);\n    byte_mask_shift->addIdOperand(byte_mask_id);\n    byte_mask_shift->addIdOperand(builder.makeUintConstant(16));\n    word_mask_shift->addIdOperand(word_mask_id);\n    word_mask_shift->addIdOperand(builder.makeUintConstant(4));\n\n    auto *byte_mask_or = builder.addInstruction(u32_type, spv::OpBitwiseOr);\n    auto *word_mask_or = builder.addInstruction(u32_type, spv::OpBitwiseOr);\n    byte_mask_or->addIdOperand(byte_mask_id);\n    byte_mask_or->addIdOperand(byte_mask_shift->getResultId());\n    word_mask_or->addIdOperand(word_mask_id);\n    word_mask_or->addIdOperand(word_mask_shift->getResultId());\n\n    auto *composite = builder.addInstruction(builder.makeVectorType(u32_type, 2), spv::OpCompositeConstruct);\n    composite->addIdOperand(byte_mask_or->getResultId());\n    composite->addIdOperand(word_mask_or->getResultId());\n\n    auto *bitcast = builder.addInstruction(u64_type, spv::OpBitcast);\n    bitcast->addIdOperand(composite->getResultId());\n\n    auto *mask = builder.addInstruction(u64_type, spv::OpBitwiseAnd);\n    mask->addIdOperand(extract->getResultId());\n    mask->addIdOperand(bitcast->getResultId());\n\n\tbuilder.addName(mask->getResultId(), \"invalidation_mask\");\n\n\treturn mask->getResultId();\n}\n\nstatic spv::Id build_takes_exclusive_ownership(spv::Builder &builder, spv::Id atomic_result, spv::Id byte_mask)\n{\n\tauto *shift = builder.addInstruction(builder.makeUintType(32), spv::OpShiftRightLogical);\n\tshift->addIdOperand(atomic_result);\n\tshift->addIdOperand(builder.makeUintConstant(16));\n\n\tauto *and_op = builder.addInstruction(builder.makeUintType(32), spv::OpBitwiseAnd);\n\tand_op->addIdOperand(shift->getResultId());\n\tand_op->addIdOperand(byte_mask);\n\n\tauto *cmp = builder.addInstruction(builder.makeBoolType(), spv::OpIEqual);\n\tcmp->addIdOperand(and_op->getResultId());\n\tcmp->addIdOperand(builder.makeUintConstant(0));\n\n\treturn cmp->getResultId();\n}\n\nspv::Id build_allocate_invocation_id_function(SPIRVModule &module, uint32_t desc_set, uint32_t binding)\n{\n\tauto &builder = module.get_builder();\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\n\tspv::Id bloom_var_id = build_instrumentation_ssbo(\n\t\tmodule, uint_type, 4, \"atomics\", \"BloomBufferInvocationSSBO\", \"BloomBufferInvocation\", desc_set, binding);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, uint_type, \"AllocateInvocationID\",\n\t                                       {}, {}, &entry);\n\n\tauto *len = builder.addInstruction(uint_type, spv::OpArrayLength);\n\tlen->addIdOperand(bloom_var_id);\n\tlen->addImmediateOperand(0);\n\n\tauto *len_minus_1 = builder.addInstruction(uint_type, spv::OpISub);\n\tlen_minus_1->addIdOperand(len->getResultId());\n\tlen_minus_1->addIdOperand(builder.makeUintConstant(1));\n\n\tauto *chain = builder.addInstruction(builder.makePointer(spv::StorageClassStorageBuffer, uint_type), spv::OpAccessChain);\n\tchain->addIdOperand(bloom_var_id);\n\tchain->addIdOperand(builder.makeUintConstant(0));\n\tchain->addIdOperand(len_minus_1->getResultId());\n\n\tauto *atomic_add = builder.addInstruction(uint_type, spv::OpAtomicIAdd);\n\tatomic_add->addIdOperand(chain->getResultId());\n\tatomic_add->addIdOperand(builder.getAtomicDeviceScopeId());\n\tatomic_add->addIdOperand(builder.makeUintConstant(0));\n\tatomic_add->addIdOperand(builder.makeUintConstant(1103633207u));\n\n\tbuilder.makeReturn(false, atomic_add->getResultId());\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n\nspv::Id build_validate_bda_load_store_function(SPIRVModule &module, uint32_t desc_set, uint32_t binding)\n{\n\tauto &builder = module.get_builder();\n\n\tspv::Id hash_call_id = build_hash_call(module);\n\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id uint_type = builder.makeUintType(32);\n\tspv::Id u64_type = builder.makeUintType(64);\n\tspv::Id uvec2_type = builder.makeVectorType(uint_type, 2);\n\tspv::Id bool_type = builder.makeBoolType();\n\n\tspv::Id bloom_var_id_64 = build_instrumentation_ssbo(\n\t\tmodule, u64_type, 8, \"atomics\", \"BloomBufferSSBO\", \"BloomBuffer\", desc_set, binding);\n\tspv::Id bloom_var_id_32 = build_instrumentation_ssbo(\n\t\tmodule, uvec2_type, 8, \"atomics\", \"BloomBuffer32SSBO\", \"BloomBuffer32\", desc_set, binding);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, bool_type, \"ValidateBDALoadStore\",\n\t                                       { uvec2_type, uint_type, uint_type, uint_type, uint_type, bool_type }, {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"BDA\");\n\tbuilder.addName(func->getParamId(1), \"offset\");\n\tbuilder.addName(func->getParamId(2), \"len\");\n\tbuilder.addName(func->getParamId(3), \"type\");\n\tbuilder.addName(func->getParamId(4), \"invocation_id\");\n\tbuilder.addName(func->getParamId(5), \"in_bounds\");\n\tbuilder.setBuildPoint(entry);\n\n\tauto *early_return_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *body = new spv::Block(builder.getUniqueId(), *func);\n\n\tbuilder.createSelectionMerge(body, 0);\n\tbuilder.createConditionalBranch(func->getParamId(5), body, early_return_block);\n\tbuilder.setBuildPoint(early_return_block);\n\tbuilder.makeReturn(false, builder.makeBoolConstant(true));\n\tbuilder.setBuildPoint(body);\n\n\tspv::Id addr_id = build_u64_add_u32(builder, func->getParamId(0), func->getParamId(1));\n\tbuilder.addName(addr_id, \"addr\");\n\tspv::Id addr_lo_id;\n\n\tauto *extract_lo = builder.addInstruction(uint_type, spv::OpCompositeExtract);\n\textract_lo->addIdOperand(addr_id);\n\textract_lo->addImmediateOperand(0);\n\taddr_lo_id = extract_lo->getResultId();\n\tbuilder.addName(addr_lo_id, \"addr_lo\");\n\n\tspv::Id byte_mask_id = build_byte_mask(builder, addr_lo_id, func->getParamId(2));\n\tspv::Id word_mask_id = build_word_mask(builder, addr_lo_id, func->getParamId(2));\n\tbuilder.addName(byte_mask_id, \"byte_mask\");\n\tbuilder.addName(word_mask_id, \"word_mask\");\n\n\tspv::Id hash_mask = build_hash_mask(builder, bloom_var_id_64);\n\tspv::Id hash_offset = build_hash_offset(builder, bloom_var_id_64);\n\tbuilder.addName(hash_mask, \"hash_mask\");\n\tbuilder.addName(hash_offset, \"hash_offset\");\n\n    constexpr int NumHashes = 16;\n    constexpr int NumLockHashes = 8;\n    static_assert(NumLockHashes <= NumHashes, \"Lock hashes must be less or equal.\");\n\tspv::Id hashes[NumHashes];\n\n\tfor (int i = 0; i < NumHashes; i++)\n\t{\n        // Just pick random primes.\n\t\tstatic const uint32_t noise_primes[NumHashes] = {\n\t\t\t1103515245u,\n\t\t\t1103518333u,\n\t\t\t1103539331u,\n\t\t\t1103633207u,\n\t\t\t10006121u,\n\t\t\t4004951u,\n\t\t\t5005159u,\n\t\t\t6004811u,\n            383u,\n            821u,\n            661u,\n            1091u,\n            1117u,\n            3947u,\n            4253u,\n            7691u,\n\t\t};\n\n\t\tauto *call = builder.addInstruction(uint_type, spv::OpFunctionCall);\n\t\tcall->addIdOperand(hash_call_id);\n\t\tcall->addIdOperand(addr_id);\n\t\tcall->addIdOperand(builder.makeUintConstant(noise_primes[i]));\n\n\t\tauto *mask = builder.addInstruction(uint_type, spv::OpBitwiseAnd);\n\t\tmask->addIdOperand(call->getResultId());\n\t\tmask->addIdOperand(hash_mask);\n\n\t\tauto *add_offset = builder.addInstruction(uint_type, spv::OpIAdd);\n\t\tadd_offset->addIdOperand(mask->getResultId());\n\t\tadd_offset->addIdOperand(hash_offset);\n\n\t\thashes[i] = add_offset->getResultId();\n\t\tbuilder.addName(hashes[i], \"bloom_index\");\n\t}\n\n\tspv::Id invalidation_mask = build_get_invalidation_mask(builder, func->getParamId(3), byte_mask_id, word_mask_id);\n\n\tspv::Id atomic_result = 0;\n\tfor (auto hash : hashes)\n\t{\n\t\tauto *chain = builder.addInstruction(builder.makePointer(spv::StorageClassStorageBuffer, u64_type),\n\t\t                                     spv::OpInBoundsAccessChain);\n\t\tchain->addIdOperand(bloom_var_id_64);\n\t\tchain->addIdOperand(builder.makeUintConstant(0));\n\t\tchain->addIdOperand(hash);\n\n\t\tauto *atom = builder.addInstruction(u64_type, spv::OpAtomicOr);\n\t\tatom->addIdOperand(chain->getResultId());\n\t\tatom->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tatom->addIdOperand(builder.makeUintConstant(0)); // Relaxed\n\t\tatom->addIdOperand(invalidation_mask);\n\n\t\tbuilder.addName(atom->getResultId(), \"prev_hazard_partial\");\n\n\t\tif (atomic_result == 0)\n\t\t{\n\t\t\tatomic_result = atom->getResultId();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *and_op = builder.addInstruction(u64_type, spv::OpBitwiseAnd);\n\t\t\tand_op->addIdOperand(atomic_result);\n\t\t\tand_op->addIdOperand(atom->getResultId());\n\t\t\tatomic_result = and_op->getResultId();\n\t\t}\n\n\t\tbuilder.addCapability(spv::CapabilityInt64Atomics);\n\t}\n\n\tauto *atomic_result_uvec2 = builder.addInstruction(uvec2_type, spv::OpBitcast);\n\tatomic_result_uvec2->addIdOperand(atomic_result);\n\tbuilder.addName(atomic_result_uvec2->getResultId(), \"prev_hazard\");\n\n\tauto *atomic_result_lo = builder.addInstruction(uint_type, spv::OpCompositeExtract);\n\tatomic_result_lo->addIdOperand(atomic_result_uvec2->getResultId());\n\tatomic_result_lo->addImmediateOperand(0);\n\tbuilder.addName(atomic_result_lo->getResultId(), \"prev_hazard_lo\");\n\n\tauto *atomic_result_hi = builder.addInstruction(uint_type, spv::OpCompositeExtract);\n\tatomic_result_hi->addIdOperand(atomic_result_uvec2->getResultId());\n\tatomic_result_hi->addImmediateOperand(1);\n\tbuilder.addName(atomic_result_hi->getResultId(), \"prev_hazard_hi\");\n\n\t// Compute if we took ownership of this byte region. If that's the case then we have zero write hazard overlap.\n\t// Every memory access marks STORE as a hazard.\n\tspv::Id has_exclusive = build_takes_exclusive_ownership(builder, atomic_result_lo->getResultId(), byte_mask_id);\n\tbuilder.addName(has_exclusive, \"has_exclusive_access\");\n\n\tspv::Id has_complete_self_lock = 0;\n\n\tfor (int i = 0; i < NumLockHashes; i++)\n\t{\n\t\tint base_bit;\n\n\t\tif (i < 4)\n\t\t\tbase_bit = std::min<int>(9 * i, 23);\n\t\telse\n\t\t\tbase_bit = std::min<int>(8 * (i & 3) + 1, 22);\n\n\t\tspv::Id lock_mask_id = 0;\n\n\t\tfor (int j = 0; j < 3; j++)\n\t\t{\n\t\t\t// Generate the invocation lock mask. We will set 12 bits in total across 96 available bits.\n\t\t\tauto *extract = builder.addInstruction(uint_type, spv::OpBitFieldUExtract);\n\t\t\textract->addIdOperand(func->getParamId(4));\n\t\t\textract->addIdOperand(builder.makeIntConstant(base_bit + 3 * j));\n\t\t\textract->addIdOperand(builder.makeIntConstant(3));\n\n\t\t\tauto *shift = builder.addInstruction(uint_type, spv::OpShiftLeftLogical);\n\t\t\tshift->addIdOperand(builder.makeUintConstant(1u << (8 + 8 * j)));\n\t\t\tshift->addIdOperand(extract->getResultId());\n\n\t\t\tif (lock_mask_id == 0)\n\t\t\t{\n\t\t\t\tlock_mask_id = shift->getResultId();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto *or_op = builder.addInstruction(uint_type, spv::OpBitwiseOr);\n\t\t\t\tor_op->addIdOperand(lock_mask_id);\n\t\t\t\tor_op->addIdOperand(shift->getResultId());\n\t\t\t\tlock_mask_id = or_op->getResultId();\n\t\t\t}\n\t\t}\n\n\t\tbuilder.addName(lock_mask_id, \"lock_mask\");\n\n\t\tauto *sel = builder.addInstruction(uint_type, spv::OpSelect);\n\t\tsel->addIdOperand(has_exclusive);\n\t\tsel->addIdOperand(lock_mask_id);\n\t\tsel->addIdOperand(builder.makeUintConstant(0));\n\n\t\tauto *chain = builder.addInstruction(builder.makePointer(spv::StorageClassStorageBuffer, uint_type),\n\t\t                                     spv::OpInBoundsAccessChain);\n\t\tchain->addIdOperand(bloom_var_id_32);\n\t\tchain->addIdOperand(builder.makeUintConstant(0));\n\t\tchain->addIdOperand(hashes[i]);\n\t\tchain->addIdOperand(builder.makeUintConstant(1));\n\n\t\tauto *atom = builder.addInstruction(uint_type, spv::OpAtomicOr);\n\t\tatom->addIdOperand(chain->getResultId());\n\t\tatom->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tatom->addIdOperand(builder.makeUintConstant(0));\n\t\tatom->addIdOperand(sel->getResultId());\n\t\tbuilder.addName(atom->getResultId(), \"prev_lock\");\n\n\t\tspv::Id lock_feedback = atom->getResultId();\n\n\t\tauto *and_op = builder.addInstruction(uint_type, spv::OpBitwiseAnd);\n\t\tand_op->addIdOperand(lock_feedback);\n\t\tand_op->addIdOperand(lock_mask_id);\n\n\t\tauto *eq_op = builder.addInstruction(bool_type, spv::OpIEqual);\n\t\teq_op->addIdOperand(and_op->getResultId());\n\t\teq_op->addIdOperand(lock_mask_id);\n\n\t\tif (has_complete_self_lock == 0)\n\t\t{\n\t\t\thas_complete_self_lock = eq_op->getResultId();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto *logical_and = builder.addInstruction(bool_type, spv::OpLogicalAnd);\n\t\t\tlogical_and->addIdOperand(has_complete_self_lock);\n\t\t\tlogical_and->addIdOperand(eq_op->getResultId());\n\t\t\thas_complete_self_lock = logical_and->getResultId();\n\t\t}\n\t}\n\n\tbuilder.addName(has_complete_self_lock, \"has_complete_self_lock\");\n\n\tVector<spv::Block *> segments;\n\t// The AST-based builder is a bit awkward to use in this context ...\n\tbuilder.makeSwitch(func->getParamId(3), 0, 4, { 0, 1, 2 }, { 0, 1, 2 }, 3, segments);\n\tbuilder.endSwitch(segments);\n\tauto *merge = builder.getBuildPoint();\n\tspv::Id hazards[4];\n\n\tbuilder.setBuildPoint(segments[int(BDAOperation::Load)]);\n\t{\n\t\tauto *mask = builder.addInstruction(uint_type, spv::OpBitwiseAnd);\n\t\tauto *neq = builder.addInstruction(bool_type, spv::OpINotEqual);\n\t\tmask->addIdOperand(atomic_result_lo->getResultId());\n\t\tmask->addIdOperand(byte_mask_id);\n\t\tneq->addIdOperand(mask->getResultId());\n\t\tneq->addIdOperand(builder.makeUintConstant(0));\n\t\thazards[int(BDAOperation::Load)] = neq->getResultId();\n\t\tbuilder.createBranch(merge);\n\t}\n\n\tbuilder.setBuildPoint(segments[int(BDAOperation::Store)]);\n\t{\n\t\tauto *shift = builder.addInstruction(uint_type, spv::OpShiftLeftLogical);\n\t\tshift->addIdOperand(byte_mask_id);\n\t\tshift->addIdOperand(builder.makeUintConstant(16));\n\t\tauto *mask = builder.addInstruction(uint_type, spv::OpBitwiseAnd);\n\t\tauto *neq = builder.addInstruction(bool_type, spv::OpINotEqual);\n\t\tmask->addIdOperand(atomic_result_lo->getResultId());\n\t\tmask->addIdOperand(shift->getResultId());\n\t\tneq->addIdOperand(mask->getResultId());\n\t\tneq->addIdOperand(builder.makeUintConstant(0));\n\t\thazards[int(BDAOperation::Store)] = neq->getResultId();\n\t\tbuilder.createBranch(merge);\n\t}\n\n\tbuilder.setBuildPoint(segments[int(BDAOperation::AtomicRMW)]);\n\t{\n\t\tauto *mask = builder.addInstruction(uint_type, spv::OpBitwiseAnd);\n\t\tauto *neq = builder.addInstruction(bool_type, spv::OpINotEqual);\n\t\tmask->addIdOperand(atomic_result_hi->getResultId());\n\t\tmask->addIdOperand(word_mask_id);\n\t\tneq->addIdOperand(mask->getResultId());\n\t\tneq->addIdOperand(builder.makeUintConstant(0));\n\t\thazards[int(BDAOperation::AtomicRMW)] = neq->getResultId();\n\t\tbuilder.createBranch(merge);\n\t}\n\n\tbuilder.setBuildPoint(segments[int(BDAOperation::IndirectRead)]);\n\t{\n\t\tauto *shift = builder.addInstruction(uint_type, spv::OpShiftLeftLogical);\n\t\tshift->addIdOperand(word_mask_id);\n\t\tshift->addIdOperand(builder.makeUintConstant(4));\n\t\tauto *mask = builder.addInstruction(uint_type, spv::OpBitwiseAnd);\n\t\tauto *neq = builder.addInstruction(bool_type, spv::OpINotEqual);\n\t\tmask->addIdOperand(atomic_result_hi->getResultId());\n\t\tmask->addIdOperand(shift->getResultId());\n\t\tneq->addIdOperand(mask->getResultId());\n\t\tneq->addIdOperand(builder.makeUintConstant(0));\n\t\thazards[int(BDAOperation::IndirectRead)] = neq->getResultId();\n\t\tbuilder.createBranch(merge);\n\t}\n\n\tbuilder.setBuildPoint(merge);\n\n\tauto *hazard_phi = builder.addInstruction(bool_type, spv::OpPhi);\n\tfor (int i = 0; i < 4; i++)\n\t{\n\t\thazard_phi->addIdOperand(hazards[i]);\n\t\thazard_phi->addIdOperand(segments[i]->getId());\n\t}\n\tbuilder.addName(hazard_phi->getResultId(), \"hazard\");\n\n\tauto *inv_hazard = builder.addInstruction(bool_type, spv::OpLogicalNot);\n\tinv_hazard->addIdOperand(hazard_phi->getResultId());\n\n\t// Compute self-hazard.\n\tauto *ret = builder.addInstruction(bool_type, spv::OpLogicalOr);\n\tret->addIdOperand(inv_hazard->getResultId());\n\tret->addIdOperand(has_complete_self_lock);\n\n\tbuilder.makeReturn(false, ret->getResultId());\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n\nvoid emit_instrumentation_hash(SPIRVModule &module, const InstructionInstrumentationState &instrumentation,\n                               spv::Function *func, spv::Id value_id, spv::Id instruction_id)\n{\n\tauto &builder = module.get_builder();\n\tauto *write_payload_path = new spv::Block(builder.getUniqueId(), *func);\n\tauto *merge_payload_path = new spv::Block(builder.getUniqueId(), *func);\n\n\tspv::Id u32_type = builder.makeUintType(32);\n\tspv::Id bool_type = builder.makeBoolType();\n\tauto *prime_mul = builder.addInstruction(u32_type, spv::OpIMul);\n\tauto *hash = builder.addInstruction(u32_type, spv::OpBitwiseXor);\n\n\tprime_mul->addIdOperand(instruction_id);\n\tprime_mul->addIdOperand(builder.makeUintConstant(97)); // Arbitrary prime number\n\n\thash->addIdOperand(prime_mul->getResultId());\n\tauto shader_hash = instrumentation.info.shader_hash;\n\thash->addIdOperand(builder.makeUintConstant(uint32_t(shader_hash) ^ uint32_t(shader_hash >> 32)));\n\n\tif (!value_id)\n\t{\n\t\t// For AssumeTrue instrumentation, we're more interested in the dispatch ID.\n\t\t// We've reserved space for it in the second last u32 of the control buffer.\n\t\tauto *len = builder.addInstruction(u32_type, spv::OpArrayLength);\n\t\tlen->addIdOperand(instrumentation.global_nan_inf_control_var_id);\n\t\tlen->addImmediateOperand(0);\n\n\t\tauto *len_minus_2 = builder.addInstruction(u32_type, spv::OpISub);\n\t\tlen_minus_2->addIdOperand(len->getResultId());\n\t\tlen_minus_2->addIdOperand(builder.makeUintConstant(2));\n\n\t\tauto *cookie_chain = builder.addInstruction(\n\t\t    builder.makePointer(spv::StorageClassStorageBuffer, u32_type), spv::OpAccessChain);\n\t\tcookie_chain->addIdOperand(instrumentation.global_nan_inf_control_var_id);\n\t\tcookie_chain->addIdOperand(builder.makeUintConstant(0));\n\t\tcookie_chain->addIdOperand(len_minus_2->getResultId());\n\n\t\tauto *load = builder.addInstruction(u32_type, spv::OpLoad);\n\t\tload->addIdOperand(cookie_chain->getResultId());\n\t\tvalue_id = load->getResultId();\n\n\t\tauto *mul = builder.addInstruction(u32_type, spv::OpIMul);\n\t\tmul->addIdOperand(value_id);\n\t\tmul->addIdOperand(builder.makeUintConstant(51329u));\n\n\t\t// Allow each dispatch to report their own faults.\n\t\tauto *ext_hash = builder.addInstruction(u32_type, spv::OpBitwiseXor);\n\t\text_hash->addIdOperand(hash->getResultId());\n\t\text_hash->addIdOperand(mul->getResultId());\n\n\t\thash = ext_hash;\n\t}\n\n\tauto *payload_size = builder.addInstruction(u32_type, spv::OpArrayLength);\n\tauto *sub_1 = builder.addInstruction(u32_type, spv::OpISub);\n\tauto *mask = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\tauto *control_word = builder.addInstruction(u32_type, spv::OpShiftRightLogical);\n\tauto *control_bit = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\tauto *control_mask = builder.addInstruction(u32_type, spv::OpShiftLeftLogical);\n\tauto *access_chain = builder.addInstruction(\n\t    builder.makePointer(spv::StorageClassStorageBuffer, u32_type),\n\t    spv::OpAccessChain);\n\tauto *atomic_or = builder.addInstruction(u32_type, spv::OpAtomicOr);\n\tauto *atomic_result_mask = builder.addInstruction(u32_type, spv::OpBitwiseAnd);\n\tauto *atomic_need_write = builder.addInstruction(bool_type, spv::OpIEqual);\n\tauto *store_op = builder.addInstruction(spv::OpStore);\n\n\tpayload_size->addIdOperand(instrumentation.global_nan_inf_data_var_id);\n\tpayload_size->addImmediateOperand(0);\n\tsub_1->addIdOperand(payload_size->getResultId());\n\tsub_1->addIdOperand(builder.makeUintConstant(1));\n\tmask->addIdOperand(hash->getResultId());\n\tmask->addIdOperand(sub_1->getResultId());\n\tspv::Id mask_id = mask->getResultId();\n\n\tcontrol_word->addIdOperand(mask->getResultId());\n\tcontrol_word->addIdOperand(builder.makeUintConstant(4));\n\tcontrol_bit->addIdOperand(mask->getResultId());\n\tcontrol_bit->addIdOperand(builder.makeUintConstant(15));\n\tcontrol_mask->addIdOperand(builder.makeUintConstant(1));\n\tcontrol_mask->addIdOperand(control_bit->getResultId());\n\n\taccess_chain->addIdOperand(instrumentation.global_nan_inf_control_var_id);\n\taccess_chain->addIdOperand(builder.makeUintConstant(0));\n\taccess_chain->addIdOperand(control_word->getResultId());\n\n\tatomic_or->addIdOperand(access_chain->getResultId());\n\tatomic_or->addIdOperand(builder.getAtomicDeviceScopeId());\n\tatomic_or->addIdOperand(builder.makeUintConstant(0));\n\tatomic_or->addIdOperand(control_mask->getResultId());\n\n\tatomic_result_mask->addIdOperand(atomic_or->getResultId());\n\tatomic_result_mask->addIdOperand(control_mask->getResultId());\n\tatomic_need_write->addIdOperand(atomic_result_mask->getResultId());\n\tatomic_need_write->addIdOperand(builder.makeUintConstant(0));\n\n\tstore_op->addIdOperand(instrumentation.should_report_instrumentation_id);\n\tstore_op->addIdOperand(builder.makeBoolConstant(false));\n\n\tspv::Id cond_id = atomic_need_write->getResultId();\n\tspv::Id control_mask_id = control_mask->getResultId();\n\tspv::Id control_chain_id = access_chain->getResultId();\n\n\tbuilder.createSelectionMerge(merge_payload_path, 0);\n\tbuilder.createConditionalBranch(cond_id, write_payload_path, merge_payload_path);\n\tbuilder.setBuildPoint(write_payload_path);\n\t{\n\t\tspv::Id uvec4_type = builder.makeVectorType(u32_type, 4);\n\n\t\tauto *composite = builder.addInstruction(uvec4_type, spv::OpCompositeConstruct);\n\t\tauto *shift_16 = builder.addInstruction(u32_type, spv::OpShiftLeftLogical);\n\t\taccess_chain = builder.addInstruction(\n\t\t\tbuilder.makePointer(spv::StorageClassStorageBuffer, uvec4_type),\n\t\t\tspv::OpAccessChain);\n\t\tstore_op = builder.addInstruction(spv::OpStore);\n\t\tauto *barrier_op = builder.addInstruction(spv::OpMemoryBarrier);\n\t\tatomic_or = builder.addInstruction(u32_type, spv::OpAtomicOr);\n\t\t// Important this comes after the atomic or.\n\t\tauto *barrier_op2 = builder.addInstruction(spv::OpMemoryBarrier);\n\n\t\tcomposite->addIdOperand(builder.makeUintConstant(uint32_t(shader_hash >> 0)));\n\t\tcomposite->addIdOperand(builder.makeUintConstant(uint32_t(shader_hash >> 32)));\n\t\tcomposite->addIdOperand(func->getParamId(1));\n\t\tcomposite->addIdOperand(value_id);\n\n\t\tshift_16->addIdOperand(control_mask_id);\n\t\tshift_16->addIdOperand(builder.makeUintConstant(16));\n\n\t\taccess_chain->addIdOperand(instrumentation.global_nan_inf_data_var_id);\n\t\taccess_chain->addIdOperand(builder.makeUintConstant(0));\n\t\taccess_chain->addIdOperand(mask_id);\n\n\t\tstore_op->addIdOperand(access_chain->getResultId());\n\t\tstore_op->addIdOperand(composite->getResultId());\n\t\tif (builder.hasCapability(spv::CapabilityVulkanMemoryModel))\n\t\t\tstore_op->addImmediateOperand(spv::MemoryAccessNonPrivatePointerMask);\n\n\t\tbarrier_op->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tbarrier_op->addIdOperand(builder.makeUintConstant(spv::MemorySemanticsUniformMemoryMask |\n\t\t                                                  spv::MemorySemanticsAcquireReleaseMask));\n\t\tbarrier_op2->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tbarrier_op2->addIdOperand(builder.makeUintConstant(spv::MemorySemanticsUniformMemoryMask |\n\t\t                                                   spv::MemorySemanticsAcquireReleaseMask));\n\n\t\tatomic_or->addIdOperand(control_chain_id);\n\t\tatomic_or->addIdOperand(builder.getAtomicDeviceScopeId());\n\t\tatomic_or->addIdOperand(builder.makeUintConstant(0));\n\t\tatomic_or->addIdOperand(shift_16->getResultId());\n\n\t\tbuilder.createBranch(merge_payload_path);\n\t}\n\tbuilder.setBuildPoint(merge_payload_path);\n}\n\nspv::Id build_assume_true_call_function(SPIRVModule &module, const InstructionInstrumentationState &instrumentation)\n{\n\tauto &builder = module.get_builder();\n\n\t// Use normal bb->addInstruction here since we don't want to instrument the code that is doing instrumentation :')\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(),\n\t                                       \"AssumeTrue\",\n\t                                       { bool_type, u32_type }, {}, &entry);\n\n\tbuilder.addName(func->getParamId(0), \"value\");\n\tbuilder.addName(func->getParamId(1), \"inst\");\n\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *fail_block = new spv::Block(builder.getUniqueId(), *func);\n\n\tauto should_report = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLogicalNot);\n\tshould_report->addIdOperand(func->getParamId(0));\n\n\tauto loaded = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLoad);\n\tloaded->addIdOperand(instrumentation.should_report_instrumentation_id);\n\n\tauto will_report = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLogicalAnd);\n\twill_report->addIdOperand(should_report->getResultId());\n\twill_report->addIdOperand(loaded->getResultId());\n\n\tspv::Id cond_id = will_report->getResultId();\n\n\tentry->addInstruction(std::move(should_report));\n\tentry->addInstruction(std::move(loaded));\n\tentry->addInstruction(std::move(will_report));\n\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(cond_id, fail_block, merge_block);\n\n\tbuilder.setBuildPoint(fail_block);\n\t{\n\t\t// Dummy value is stored.\n\t\temit_instrumentation_hash(module, instrumentation, func, 0, func->getParamId(1));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\tbuilder.makeReturn(false);\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n\nspv::Id build_nan_inf_instrument_call_function(\n    SPIRVModule &module, const InstructionInstrumentationState &instrumentation, spv::Id type_id)\n{\n\tauto &builder = module.get_builder();\n\n\t// Use normal bb->addInstruction here since we don't want to instrument the code that is doing instrumentation :')\n\tauto *current_build_point = builder.getBuildPoint();\n\tspv::Block *entry = nullptr;\n\tspv::Id bool_type = builder.makeBoolType();\n\tspv::Id u32_type = builder.makeUintType(32);\n\n\tauto *func = builder.makeFunctionEntry(spv::NoPrecision, builder.makeVoidType(),\n\t                                       \"NanInfInstrumentation\",\n\t                                       { type_id, u32_type }, {}, &entry);\n\n\tauto *merge_block = new spv::Block(builder.getUniqueId(), *func);\n\tauto *first_nan_inf_path = new spv::Block(builder.getUniqueId(), *func);\n\n\tbuilder.addName(func->getParamId(0), \"value\");\n\tbuilder.addName(func->getParamId(1), \"inst\");\n\n\tbuilder.setBuildPoint(entry);\n\n\t// TODO: Find a way to make this more programmable?\n\tauto is_nan = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIsNan);\n\tauto is_inf = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpIsInf);\n\tauto is_not_normal = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLogicalOr);\n\tauto should_report = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLoad);\n\tauto will_report = std::make_unique<spv::Instruction>(builder.getUniqueId(), bool_type, spv::OpLogicalAnd);\n\n\tis_nan->addIdOperand(func->getParamId(0));\n\tis_inf->addIdOperand(func->getParamId(0));\n\tis_not_normal->addIdOperand(is_nan->getResultId());\n\tis_not_normal->addIdOperand(is_inf->getResultId());\n\tshould_report->addIdOperand(instrumentation.should_report_instrumentation_id);\n\twill_report->addIdOperand(should_report->getResultId());\n\twill_report->addIdOperand(is_not_normal->getResultId());\n\tspv::Id cond_id = will_report->getResultId();\n\n\tentry->addInstruction(std::move(is_nan));\n\tentry->addInstruction(std::move(is_inf));\n\tentry->addInstruction(std::move(is_not_normal));\n\tentry->addInstruction(std::move(should_report));\n\tentry->addInstruction(std::move(will_report));\n\n\tbuilder.createSelectionMerge(merge_block, 0);\n\tbuilder.createConditionalBranch(cond_id, first_nan_inf_path, merge_block);\n\n\tbuilder.setBuildPoint(first_nan_inf_path);\n\t{\n\t\tspv::Id value_id = func->getParamId(0);\n\t\tif (builder.getScalarTypeWidth(type_id) != 32)\n\t\t{\n\t\t\tauto conv = std::make_unique<spv::Instruction>(\n\t\t\t    builder.getUniqueId(), builder.makeFloatType(32), spv::OpFConvert);\n\t\t\tconv->addIdOperand(value_id);\n\t\t\tvalue_id = conv->getResultId();\n\t\t\tfirst_nan_inf_path->addInstruction(std::move(conv));\n\t\t}\n\n\t\tauto bitcast = std::make_unique<spv::Instruction>(\n\t\t    builder.getUniqueId(), u32_type, spv::OpBitcast);\n\t\tbitcast->addIdOperand(value_id);\n\t\tvalue_id = bitcast->getResultId();\n\t\tfirst_nan_inf_path->addInstruction(std::move(bitcast));\n\n\t\temit_instrumentation_hash(module, instrumentation, func, value_id, func->getParamId(1));\n\t\tbuilder.createBranch(merge_block);\n\t}\n\n\tbuilder.setBuildPoint(merge_block);\n\tbuilder.makeReturn(false);\n\tbuilder.setBuildPoint(current_build_point);\n\treturn func->getId();\n}\n\n}"
  },
  {
    "path": "spirv_module_instrumentation.hpp",
    "content": "/* Copyright (c) 2025 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include \"spirv_module.hpp\"\n#include \"descriptor_qa.hpp\"\n\nnamespace spv\n{\nclass Function;\n}\n\nnamespace dxil_spv\n{\nspv::Id build_validate_bda_load_store_function(SPIRVModule &module, uint32_t desc_set, uint32_t binding);\nspv::Id build_allocate_invocation_id_function(SPIRVModule &module, uint32_t desc_set, uint32_t binding);\nspv::Id build_assume_true_call_function(SPIRVModule &module, const InstructionInstrumentationState &instrumentation);\nspv::Id build_nan_inf_instrument_call_function(\n    SPIRVModule &module, const InstructionInstrumentationState &instrumentation, spv::Id type_id);\nvoid emit_instrumentation_hash(SPIRVModule &module, const InstructionInstrumentationState &instrumentation,\n                               spv::Function *func, spv::Id value_id, spv::Id instruction_id);\n} // namespace dxil_spv\n"
  },
  {
    "path": "test_shaders.py",
    "content": "#!/usr/bin/env python3\n\n#\n# Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n#\n# SPDX-License-Identifier: MIT\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n# \n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n# \n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nimport sys\nimport os\nimport os.path\nimport subprocess\nimport tempfile\nimport re\nimport itertools\nimport hashlib\nimport shutil\nimport argparse\nimport codecs\nimport json\nimport multiprocessing\nimport errno\nfrom functools import partial\n\nclass Paths():\n    def __init__(self, dxc, dxil_spirv):\n        self.dxc = dxc \n        self.dxil_spirv = dxil_spirv \n\ndef remove_file(path):\n    os.remove(path)\n\ndef create_temporary(suff = ''):\n    f, path = tempfile.mkstemp(suffix = suff)\n    os.close(f)\n    return path\n\ndef get_sm(shader, version_minor):\n    minor_version = '_{}'.format(version_minor)\n    lib_version = 'lib_6_{}'.format(5 if version_minor <= 5 else 6)\n    mesh_version = '_{}'.format(5 if version_minor <= 5 else version_minor)\n    _, ext = os.path.splitext(shader)\n    if ext == '.vert':\n        return 'vs_6' + minor_version\n    elif ext == '.frag':\n        return 'ps_6' + minor_version\n    elif ext == '.comp':\n        return 'lib_6_8' if '.node.' in shader else ('cs_6' + minor_version)\n    elif ext == '.tesc':\n        return 'hs_6' + minor_version\n    elif ext == '.tese':\n        return 'ds_6' + minor_version\n    elif ext == '.geom':\n        return 'gs_6' + minor_version\n    elif ext == '.mesh':\n        return 'ms_6' + mesh_version\n    elif ext == '.task':\n        return 'as_6' + mesh_version\n    elif ext == '.rmiss':\n        return lib_version\n    elif ext == '.rint':\n        return lib_version\n    elif ext == '.rgen':\n        return lib_version\n    elif ext == '.rhit':\n        return lib_version\n    elif ext == '.rcall':\n        return lib_version\n    elif ext == '.rany':\n        return lib_version\n    elif ext == '.rclosest':\n        return lib_version\n    else:\n        return ''\n\ndef cross_compile_dxil(shader, args, paths, is_asm):\n    glsl_path = create_temporary(os.path.basename(shader))\n    version_minor = 5\n    if '.sm60.' in shader:\n        version_minor = 0\n    elif '.sm66.' in shader:\n        version_minor = 6\n    elif '.sm67.' in shader:\n        version_minor = 7\n\n    if not is_asm:\n        dxil_path = create_temporary()\n        dxil_cmd = [paths.dxc, '-Qstrip_reflect', '-Qstrip_debug', '-Vd', '-T' + get_sm(shader, version_minor), '-Fo', dxil_path, shader]\n        if version_minor >= 2:\n            dxil_cmd.append('-enable-16bit-types')\n        if '.denorm-ftz.' in shader:\n            dxil_cmd += ['-denorm', 'ftz']\n        if '.denorm-preserve.' in shader:\n            dxil_cmd += ['-denorm', 'preserve']\n        if '.no-legacy-cbuf-layout.' in shader:\n            dxil_cmd += ['-no-legacy-cbuf-layout']\n        subprocess.check_call(dxil_cmd)\n    else:\n        dxil_path = shader\n\n    hlsl_cmd = [paths.dxil_spirv, '--output', glsl_path, dxil_path, '--vertex-input', 'ATTR', '0']\n    skip_glsl = '.noglsl.' in shader\n\n    if not args.bench:\n        hlsl_cmd += ['--asm']\n        if not skip_glsl:\n            hlsl_cmd += ['--glsl']\n\n    if '.bc.' in shader:\n        hlsl_cmd += ['--raw-llvm']\n\n    hlsl_cmd += ['--allow-arithmetic-relaxed-precision', '--subgroup-size', '32', '64']\n\n    if '.root-constant.' in shader:\n        hlsl_cmd.append('--root-constant')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('4')\n        hlsl_cmd.append('12')\n        hlsl_cmd.append('--root-constant')\n        hlsl_cmd.append('1')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('16')\n    if '.stream-out.' in shader:\n        hlsl_cmd.append('--stream-output')\n        hlsl_cmd.append('SV_Position')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('16')\n        hlsl_cmd.append('32')\n        hlsl_cmd.append('1')\n\n        hlsl_cmd.append('--stream-output')\n        hlsl_cmd.append('StreamOut')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('32')\n        hlsl_cmd.append('0')\n\n        hlsl_cmd.append('--stream-output')\n        hlsl_cmd.append('StreamOut')\n        hlsl_cmd.append('1')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('16')\n        hlsl_cmd.append('1')\n\n    if '.rt-swizzle.' in shader:\n        hlsl_cmd.append('--output-rt-swizzle')\n        hlsl_cmd.append('0')\n        hlsl_cmd.append('wxyz')\n        hlsl_cmd.append('--output-rt-swizzle')\n        hlsl_cmd.append('1')\n        hlsl_cmd.append('yxwz')\n\n    if '.bindless.' in shader:\n        hlsl_cmd.append('--bindless')\n    if '.nobda.' in shader:\n        hlsl_cmd.append('--no-bda')\n    if '.local-root-signature.' in shader:\n        hlsl_cmd.append('--local-root-signature')\n    if '.uav-counter-texel-buffer.' in shader:\n        hlsl_cmd.append('--uav-counter-force-texel-buffer')\n    if '.uav-counter-ssbo.' in shader:\n        hlsl_cmd.append('--uav-counter-force-ssbo')\n\n    if '.inline-ubo.' in shader:\n        hlsl_cmd.append('--root-constant-inline-ubo')\n        hlsl_cmd.append('6')\n        hlsl_cmd.append('1')\n\n    if '.cbv-as-ssbo.' in shader:\n        hlsl_cmd.append('--bindless-cbv-as-ssbo')\n\n    if '.invalid.' not in shader:\n        hlsl_cmd.append('--validate')\n\n    if ('.demote-to-helper.' in shader) or is_asm:\n        hlsl_cmd.append('--enable-shader-demote')\n    if '.i8dot.' in shader:\n        hlsl_cmd.append('--enable-shader-i8-dot')\n    if '.dual-source-blending.' in shader:\n        hlsl_cmd.append('--enable-dual-source-blending')\n    if ('.ssbo.' in shader) or is_asm:\n        hlsl_cmd.append('--ssbo-uav')\n        hlsl_cmd.append('--ssbo-srv')\n    if '.ssbo-rtas.' in shader:\n        hlsl_cmd.append('--ssbo-rtas')\n    if '.input-attachment.' in shader:\n        hlsl_cmd.append('--input-attachments')\n    if '.raw-va-stride-offset.' in shader:\n        hlsl_cmd.append('--physical-address-descriptor-indexing')\n        hlsl_cmd.append('4')\n        hlsl_cmd.append('3')\n    if '.ssbo-align.' in shader:\n        hlsl_cmd.append('--ssbo-alignment')\n        hlsl_cmd.append('64')\n    if '.typed-uav-without-format.' in shader:\n        hlsl_cmd.append('--typed-uav-read-without-format')\n    if '.typed-buffer-offset.' in shader:\n        hlsl_cmd.append('--bindless')\n        hlsl_cmd.append('--bindless-typed-buffer-offsets')\n\n    if '.root-descriptor.' in shader:\n        hlsl_cmd += ['--root-descriptor', 'cbv', '0', '0']\n        hlsl_cmd += ['--root-descriptor', 'srv', '0', '0']\n        hlsl_cmd += ['--root-descriptor', 'uav', '0', '0']\n        hlsl_cmd += ['--root-descriptor', 'uav', '0', '1']\n\n    if '.offset-layout.' in shader:\n        hlsl_cmd += ['--bindless-offset-buffer-layout', '0', '1', '2']\n    if not args.bench:\n        if '.lib.' in shader:\n            hlsl_cmd += ['--debug-all-entry-points']\n    if '.16bit-io.' in shader:\n        hlsl_cmd += ['--storage-input-output-16bit']\n    if '.descriptor-qa.' in shader:\n        hlsl_cmd += ['--descriptor-qa', '10', '10', 'deadbeef']\n    if ('.native-fp16.' in shader) or is_asm:\n        hlsl_cmd += ['--min-precision-native-16bit']\n    if '.invariant.' in shader:\n        hlsl_cmd += ['--invariant-position']\n    if '.partitioned.' in shader:\n        hlsl_cmd += ['--subgroup-partitioned-nv']\n    if '.noderivs.' in shader:\n        hlsl_cmd += ['--no-compute-shader-derivatives']\n    if '.quad-maximal-reconvergence.' in shader:\n        hlsl_cmd += ['--quad-control-maximal-reconvergence']\n    if '.raw-access-chains.' in shader:\n        hlsl_cmd += ['--raw-access-chains-nv']\n    if '.extended-robustness.' in shader:\n        hlsl_cmd += ['--extended-robustness']\n    if 'bda-instrumentation.' in shader:\n        hlsl_cmd += ['--instruction-instrumentation', '4', '0', '2', 'abcd']\n    if '.auto-group-shared-barrier.' in shader:\n        hlsl_cmd += ['--shader-quirk', '8']\n    if '.vkmm.' in shader:\n        hlsl_cmd += ['--vkmm']\n    if '.full-wmma.' in shader:\n        hlsl_cmd += ['--full-wmma', '1', '1']\n    if '.nv-coopmat2.' in shader:\n        hlsl_cmd += ['--full-wmma', '0', '1']\n    if '.nvapi.' in shader:\n        hlsl_cmd += ['--nvapi', '127', '0']\n    if '.heap-robustness-cbv.' in shader:\n        hlsl_cmd += ['--meta-descriptor', '0', '3', '10', '20']\n    if '.heap-raw-va-cbv.' in shader:\n        hlsl_cmd += ['--meta-descriptor', '1', '4', '10', '21']\n    if '.heap-robustness.' in shader:\n        hlsl_cmd += ['--descriptor-heap-robustness']\n    if '.view-instancing.' in shader:\n        hlsl_cmd += ['--view-instancing']\n        hlsl_cmd += ['--meta-descriptor', '2', '3', '10', '22']\n    if '.view-instance-mask.' in shader:\n        hlsl_cmd += ['--meta-descriptor', '3', '3', '10', '23']\n    if '.last-pre-raster.' in shader:\n        hlsl_cmd += ['--view-instancing-last-pre-rasterization-stage']\n    if '.view-instancing-multiview.' in shader:\n        hlsl_cmd += ['--view-index-to-view-instance-spec-id', '1000']\n    if '.view-instancing-viewport-offset.' in shader:\n        hlsl_cmd += ['--view-instance-to-viewport-spec-id', '1001']\n    if '.mixed-float-dot-product.' in shader:\n        hlsl_cmd += ['--mixed-float-dot-product']\n\n    subprocess.check_call(hlsl_cmd)\n    if is_asm:\n        return glsl_path\n    else:\n        return (dxil_path, glsl_path)\n\ndef make_unix_newline(buf):\n    decoded = codecs.decode(buf, 'utf-8')\n    decoded = decoded.replace('\\r', '')\n    return codecs.encode(decoded, 'utf-8')\n\ndef md5_for_file(path):\n    md5 = hashlib.md5()\n    with open(path, 'rb') as f:\n        for chunk in iter(lambda: make_unix_newline(f.read(8192)), b''):\n            md5.update(chunk)\n    return md5.digest()\n\ndef make_reference_dir(path):\n    base = os.path.dirname(path)\n    if not os.path.exists(base):\n        os.makedirs(base)\n\ndef reference_path(directory, relpath, opt):\n    split_paths = os.path.split(directory)\n    reference_dir = os.path.join(split_paths[0], 'reference/' + ('opt/' if opt else ''))\n    reference_dir = os.path.join(reference_dir, split_paths[1])\n    return os.path.join(reference_dir, relpath)\n\ndef regression_check(shader, glsl, args):\n    reference = reference_path(shader[0], shader[1], args.opt)\n    joined_path = os.path.join(shader[0], shader[1])\n    print('Reference shader path:', reference)\n\n    if os.path.exists(reference):\n        if md5_for_file(glsl) != md5_for_file(reference):\n            if args.update:\n                print('Generated source code has changed for {}!'.format(reference))\n                # If we expect changes, update the reference file.\n                if os.path.exists(reference):\n                    remove_file(reference)\n                make_reference_dir(reference)\n                shutil.move(glsl, reference)\n            else:\n                print('Generated source code in {} does not match reference {}!'.format(glsl, reference))\n                with open(glsl, 'r') as f:\n                    print('')\n                    print('Generated:')\n                    print('======================')\n                    print(f.read())\n                    print('======================')\n                    print('')\n\n                # Otherwise, fail the test. Keep the shader file around so we can inspect.\n                if not args.keep:\n                    remove_file(glsl)\n                raise RuntimeError('Does not match reference')\n        else:\n            remove_file(glsl)\n    else:\n        print('Found new shader {}. Placing generated source code in {}'.format(joined_path, reference))\n        make_reference_dir(reference)\n        shutil.move(glsl, reference)\n\ndef test_shader(shader, args, paths):\n    joined_path = os.path.join(shader[0], shader[1])\n\n    print('Testing shader:', joined_path)\n\n    if joined_path.endswith('.dxil') or joined_path.endswith('.dxbc'):\n        glsl = cross_compile_dxil(joined_path, args, paths, True)\n        if not args.bench:\n            regression_check(shader, glsl, args)\n        else:\n            remove_file(glsl)\n    elif not (joined_path.endswith('.inc') or joined_path.endswith('.h')):\n        dxil, glsl = cross_compile_dxil(joined_path, args, paths, False)\n        if not args.bench:\n            regression_check(shader, glsl, args)\n        else:\n            remove_file(glsl)\n        remove_file(dxil)\n\ndef test_shader_file(relpath, args):\n    paths = Paths(args.dxc, args.dxil_spirv)\n    try:\n        test_shader((args.folder, relpath), args, paths)\n        return None\n    except Exception as e:\n        return e\n\ndef test_shaders(args):\n    all_files = []\n    walk_path = os.path.join(args.folder, args.subfolder) if args.subfolder else args.folder\n    for root, dirs, files in os.walk(walk_path):\n        files = [ f for f in files if not f.startswith(\".\") ]   #ignore system files (esp OSX)\n        for i in files:\n            path = os.path.join(root, i)\n            relpath = os.path.relpath(path, args.folder)\n            all_files.append(relpath)\n\n    # The child processes in parallel execution mode don't have the proper state for the global args variable, so\n    # at this point we need to switch to explicit arguments\n    if args.parallel:\n        pool = multiprocessing.Pool(multiprocessing.cpu_count())\n\n        results = []\n        for f in all_files:\n            results.append(pool.apply_async(test_shader_file,\n                args = (f, args)))\n\n        for res in results:\n            error = res.get()\n            if error is not None:\n                pool.close()\n                pool.join()\n                print('Error:', error)\n                sys.exit(1)\n    else:\n        for i in all_files:\n            e = test_shader_file(i, args)\n            if e is not None:\n                print('Error:', e)\n                sys.exit(1)\n\ndef main():\n    parser = argparse.ArgumentParser(description = 'Script for regression testing.')\n    parser.add_argument('folder',\n            help = 'Folder containing shader files to test.')\n    parser.add_argument('--update',\n            action = 'store_true',\n            help = 'Updates reference files if there is a mismatch. Use when legitimate changes in output is found.')\n    parser.add_argument('--keep',\n            action = 'store_true',\n            help = 'Leave failed GLSL shaders on disk if they fail regression. Useful for debugging.')\n    parser.add_argument('--opt',\n            action = 'store_true',\n            help = 'Run DXC optimization passes as well.')\n    parser.add_argument('--parallel',\n            action = 'store_true',\n            help = 'Execute tests in parallel.  Useful for doing regression quickly, but bad for debugging and stat output.')\n    parser.add_argument('--dxc',\n            default = './external/dxc-build/bin/dxc',\n            help = 'Explicit path to DXC')\n    parser.add_argument('--dxil-spirv',\n            default = './dxil-spirv',\n            help = 'Explicit path to dxil-spirv')\n    parser.add_argument('--subfolder',\n            help = 'Only test specific subfolder')\n    parser.add_argument('--bench',\n                        action = 'store_true',\n                        help = 'Disable any non dxil-spirv work, for benchmarking')\n\n    args = parser.parse_args()\n    if not args.folder:\n        sys.stderr.write('Need shader folder.\\n')\n        sys.exit(1)\n\n    test_shaders(args)\n    print('Tests completed!')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "third_party/CMakeLists.txt",
    "content": "add_subdirectory(spirv-headers EXCLUDE_FROM_ALL)\nset(SPIRV-Headers_SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/spirv-headers\" CACHE STRING \"SPIRV-Headers path\" FORCE)\n\nadd_library(dxil-spirv-headers INTERFACE)\ntarget_include_directories(dxil-spirv-headers INTERFACE\n        ${CMAKE_CURRENT_SOURCE_DIR}/spirv-headers/include/spirv/unified1)\n\nset(DXBC_SPV_SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/../subprojects/dxbc-spirv\")\n\nadd_library(dxbc-spirv STATIC\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_api.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_api.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_container.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_container.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_converter.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_converter.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_disasm.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_disasm.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_interface.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_interface.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_io_map.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_io_map.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_parser.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_parser.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_registers.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_registers.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_resources.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_resources.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_signature.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_signature.h\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_types.cpp\n        ${DXBC_SPV_SOURCE_DIR}/dxbc/dxbc_types.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_builder.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_builder.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_container.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_disasm.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_disasm.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_divergence.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_divergence.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_dominance.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_dominance.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_legalize.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_legalize.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_utils.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/ir_utils.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_arithmetic.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_arithmetic.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_buffer_kind.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_buffer_kind.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_cfg_cleanup.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_cfg_cleanup.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_cfg_convert.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_cfg_convert.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_cse.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_cse.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_derivative.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_derivative.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_descriptor_indexing.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_descriptor_indexing.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_function.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_function.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_lower_consume.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_lower_consume.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_lower_io.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_lower_io.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_lower_min16.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_lower_min16.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_propagate_types.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_propagate_types.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_propagate_resource_types.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_propagate_resource_types.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_remove_unused.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_remove_unused.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_scalarize.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_scalarize.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_scratch.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_scratch.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_ssa.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_ssa.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_ssa_utils.h\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_sync.cpp\n        ${DXBC_SPV_SOURCE_DIR}/ir/passes/ir_pass_sync.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_bit.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_debug.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_flags.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_float16.cpp\n        ${DXBC_SPV_SOURCE_DIR}/util/util_float16.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_hash.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_log.cpp\n        ${DXBC_SPV_SOURCE_DIR}/util/util_log.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_md5.cpp\n        ${DXBC_SPV_SOURCE_DIR}/util/util_md5.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_small_vector.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_swizzle.cpp\n        ${DXBC_SPV_SOURCE_DIR}/util/util_swizzle.h\n        ${DXBC_SPV_SOURCE_DIR}/util/util_vle.h)\n\nadd_library(dxbc-spirv-test STATIC\n        ${DXBC_SPV_SOURCE_DIR}/tests/test_common.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/test_main.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_common.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_dump.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_io.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_io.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_resources.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_resources.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_arithmetic.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_arithmetic.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_buffer_kind.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_buffer_kind.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_lower_io.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_lower_io.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_scalarize.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_pass_scalarize.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_arithmetic.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_arithmetic.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_misc.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_misc.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_spirv.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/api/test_api_spirv.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/ir/test_ir.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/ir/test_ir_builder.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/ir/test_ir_op.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/ir/test_ir_serialize.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/ir/test_ir_type.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/util/test_util.h\n        ${DXBC_SPV_SOURCE_DIR}/tests/util/test_util_small_vector.cpp\n        ${DXBC_SPV_SOURCE_DIR}/tests/util/test_util_vle.cpp)\n\ntarget_include_directories(dxbc-spirv\n        PUBLIC ${DXBC_SPV_SOURCE_DIR}\n        PRIVATE ${DXBC_SPV_SOURCE_DIR}/ir)\ntarget_include_directories(dxbc-spirv-test PUBLIC ${DXBC_SPV_SOURCE_DIR}/tests)\ntarget_compile_features(dxbc-spirv PUBLIC cxx_std_17)\ntarget_compile_features(dxbc-spirv-test PUBLIC cxx_std_17)\nset_target_properties(dxbc-spirv PROPERTIES POSITION_INDEPENDENT_CODE ON)\nif (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES \"Clang\"))\n    target_compile_options(dxbc-spirv PRIVATE -fvisibility=hidden)\nendif()\ntarget_link_libraries(dxbc-spirv-test PRIVATE dxbc-spirv)\n\nif (DXIL_SPIRV_CLI)\n    set(SPIRV_WERROR OFF CACHE STRING \"\" FORCE)\n    # SPIRV-Tools refuses to configure if this is not set.\n    set(CMAKE_CXX_STANDARD 17)\n    add_subdirectory(SPIRV-Tools EXCLUDE_FROM_ALL)\n    add_subdirectory(SPIRV-Cross EXCLUDE_FROM_ALL)\nendif()\n\nadd_library(glslang-spirv-builder STATIC\n        glslang-spirv/spvIR.h\n        glslang-spirv/Logger.cpp\n        glslang-spirv/Logger.h\n        glslang-spirv/InReadableOrder.cpp\n        glslang-spirv/SpvBuilder.h\n        glslang-spirv/SpvBuilder.cpp)\nset_target_properties(glslang-spirv-builder PROPERTIES POSITION_INDEPENDENT_CODE ON)\ntarget_compile_definitions(glslang-spirv-builder PUBLIC AMD_EXTENSIONS)\nif (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES \"Clang\"))\n    target_compile_options(glslang-spirv-builder PRIVATE -fvisibility=hidden)\nendif()\ntarget_link_libraries(glslang-spirv-builder PRIVATE dxil-utils)\n\ntarget_include_directories(glslang-spirv-builder PUBLIC\n        ${CMAKE_CURRENT_SOURCE_DIR}/glslang-spirv)\ntarget_link_libraries(glslang-spirv-builder PUBLIC dxil-spirv-headers)\n\nadd_library(bc-decoder STATIC\n        bc-decoder/llvm_bitreader.h bc-decoder/llvm_decoder.cpp\n        bc-decoder/llvm_decoder.h)\ntarget_include_directories(bc-decoder PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bc-decoder)\nset_target_properties(bc-decoder PROPERTIES POSITION_INDEPENDENT_CODE ON)\nif (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES \"Clang\"))\n    target_compile_options(bc-decoder PRIVATE -fvisibility=hidden)\nendif()\ntarget_link_libraries(bc-decoder PRIVATE dxil-utils)\n"
  },
  {
    "path": "third_party/bc-decoder/llvm_bitreader.h",
    "content": "/******************************************************************************\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2020 Baldur Karlsson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n ******************************************************************************/\n\n#pragma once\n\n#include <assert.h>\n#include <string.h>\n\nnamespace LLVMBC\n{\n#define MAKE_FOURCC(a, b, c, d) (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24))\nusing byte = uint8_t;\nclass BitReader\n{\npublic:\n  BitReader(const byte *bits, size_t length)\n      : m_Bits(bits), m_Start(bits), m_End(bits + length), m_Offset(0)\n  {\n  }\n  size_t ByteOffset() const { return m_Bits - m_Start; }\n  size_t BitOffset() const { return ByteOffset() * 8 + m_Offset; }\n  size_t ByteLength() const { return m_End - m_Start; }\n  size_t BitLength() const { return (m_End - m_Start) * 8; }\n  bool AtEndOfStream() const { return m_Bits >= m_End; }\n  void SeekByte(size_t byteOffset)\n  {\n    m_Bits = m_Start + byteOffset;\n    m_Offset = 0;\n  }\n  void SeekBit(size_t bitOffset)\n  {\n    m_Bits = m_Start + (bitOffset / 8);\n    m_Offset = (bitOffset % 8);\n  }\n  char c6()\n  {\n    byte scratch[8];\n    scratch[0] = 0;\n    byte &c = scratch[0];\n\n    ReadBits(6, &c);\n\n    if(c <= 25)\n      return char('a' + c);\n    else if(c <= 51)\n      return char('A' + c - 26);\n    else if(c <= 61)\n      return char('0' + c - 52);\n    else if(c == 62)\n      return '.';\n    else if(c == 63)\n      return '_';\n\n    return '?';\n  }\n\n  template <typename T>\n  T fixed(const size_t bitWidth)\n  {\n    byte scratch[8] = {};\n\n    assert(bitWidth <= 64);\n\n    ReadBits(bitWidth, scratch);\n\n    T ret;\n    memcpy(&ret, scratch, sizeof(T));\n    return ret;\n  }\n\n  template <typename T>\n  T vbr(const size_t groupBitSize)\n  {\n    uint64_t ret = 0;\n\n    assert(groupBitSize > 1 && \"chunk size must be greater than 1\");\n    assert(groupBitSize <= 8 && \"Only chunk sizes up to 8 supported\");\n\n    // Avoid false positive warning.\n    byte scratch[8] = {};\n\n    const byte hibit = 1 << (groupBitSize - 1);\n    const byte lobits = hibit - 1;\n\n    uint64_t shift = 0;\n    do\n    {\n      ReadBits(groupBitSize, scratch);\n\n      assert(shift <= 63);\n\n      ret += (uint64_t(scratch[0] & lobits) << shift);\n\n      shift += uint64_t(groupBitSize - 1);\n    } while(scratch[0] & hibit);\n\n#ifndef NDEBUG\n    // check for overflow of the return type\n    const uint64_t mask = ((1ULL << (sizeof(T) * 8 - 1)) - 1) << 1 | 1;\n    assert((ret & mask) == ret);\n#endif\n\n    return T(ret);\n  }\n\n  template <typename T>\n  T svbr(size_t groupBitSize)\n  {\n    // the value will fit in a uint64_t because the any negative values with the high bit set, which\n    // would overflow when shifted, no longer have the high bit set after being negated.\n    uint64_t var = vbr<uint64_t>(groupBitSize);\n\n    // if the low bit is set, it's negative\n    if(var & 0x1)\n    {\n      return T(-int64_t(var >> 1));\n    }\n    else\n    {\n      return T(var >> 1);\n    }\n  }\n\n  template <typename T>\n  T Read()\n  {\n    byte scratch[sizeof(T)] = {};\n\n    ReadBits(sizeof(T) * 8, scratch);\n\n    T ret;\n    memcpy(&ret, scratch, sizeof(T));\n    return ret;\n  }\n\n  void ReadBlob(const byte *&blobptr, size_t &bloblen)\n  {\n    // get the blob length\n    bloblen = vbr<size_t>(6);\n\n    // align to dword boundary\n    align32bits();\n\n    // the blob is at m_Bits now\n    blobptr = m_Bits;\n\n    // advance by the length, and align up as well\n    m_Bits += bloblen;\n    align32bits();\n  }\n\n  void align32bits()\n  {\n    // skip the rest of the current byte, if we're part-way through\n    if(m_Offset > 0)\n      Advance(8 - m_Offset);\n\n    const size_t byteOffs = ByteOffset();\n    const size_t alignedByteOffs = (byteOffs + 0x3) & ~0x3;\n\n    // advance by N bytes to dword align the stream\n    m_Bits += (alignedByteOffs - byteOffs);\n  }\n\nprivate:\n  const byte *m_Bits, *m_Start, *m_End;\n  size_t m_Offset;\n\n  void Advance(size_t N)\n  {\n    m_Offset += N;\n    // shouldn't read more than this byte\n    assert(m_Offset <= 8);\n\n    // roll over to next byte after consuming all 8 bits\n    if(m_Offset == 8)\n    {\n      m_Bits++;\n      m_Offset = 0;\n    }\n  }\n\n  void ReadBits(size_t bitsToRead, byte *dst)\n  {\n    if(BitOffset() + bitsToRead > BitLength())\n    {\n      // read 0s off the end of the stream.\n      // set any whole bytes to 0:\n      while(bitsToRead >= 8)\n      {\n        *dst = 0;\n        dst++;\n        bitsToRead -= 8;\n      }\n\n      // set any remaining bits to 0:\n      if(bitsToRead)\n        *dst &= ~((1 << bitsToRead) - 1);\n\n      m_Bits = m_End;\n      m_Offset = 0;\n      return;\n    }\n\n    size_t dstoffs = 0;\n\n    // if we're already partway through a byte, read as many bits as we need and we can\n    if(m_Offset != 0)\n    {\n      const size_t avail = 8 - m_Offset;\n\n      if(avail == bitsToRead)\n      {\n        // if we have just enough in this byte, great! shift and mask off, and update the offset\n\n        // grab the bits into the low end\n        *dst = (*m_Bits >> m_Offset);\n\n        Advance(bitsToRead);\n\n        return;\n      }\n      else if(avail > bitsToRead)\n      {\n        // we have more than enough. Similar to above but we need to mask out only the bits we need.\n\n        // grab the bits into the low end and mask\n        *dst = (*m_Bits >> m_Offset) & ((1 << bitsToRead) - 1);\n\n        Advance(bitsToRead);\n\n        return;\n      }\n      else\n      {\n        // we don't have enough. Consume what we can then continue\n        *dst = (*m_Bits >> m_Offset);\n\n        dstoffs = avail;\n        bitsToRead -= avail;\n\n        Advance(avail);\n      }\n    }\n    else\n    {\n      // ensure if we didn't read any bits that the byte is zeroed out, so we can OR on bits below\n      // without needing to worry\n      *dst = 0;\n    }\n\n    // we're now at the start of a byte since we read any remainder above.\n    assert(m_Offset == 0);\n\n    // if we have to read whole bytes, do that here.\n    if(bitsToRead >= 8)\n    {\n      if(dstoffs == 0)\n      {\n        // if dstoffs is 0 then it's an easy case, we can just copy all the whole bytes into *dst\n        memcpy(dst, m_Bits, bitsToRead / 8);\n\n        // manual advance\n        m_Bits += (bitsToRead / 8);\n        dst += (bitsToRead / 8);\n\n        // make sure we read any sub-byte remainder\n        bitsToRead &= 0x7;\n      }\n      else\n      {\n        while(bitsToRead >= 8)\n        {\n          // manual advance\n          const byte cur = *m_Bits;\n          m_Bits++;\n\n          bitsToRead -= 8;\n\n          // dstoffs doesn't change because we wrap around to the same offset in the next byte.\n          // However we do need to shuffle the bits in cur around to add what will fit into the\n          // current byte, and then the remainder into the next byte.\n          *dst |= (cur << dstoffs);\n          dst++;\n          *dst = (cur >> (8 - dstoffs));\n        }\n      }\n    }\n\n    // if nothing remains, return\n    if(bitsToRead == 0)\n      return;\n\n    // we should now have no more than than 7 bits to read\n    assert(bitsToRead < 8);\n\n    // this is the mask to get only the bits we want\n    const byte mask = ((1 << bitsToRead) - 1);\n\n    // take the bits that we want from the next byte (knowing we want the low-order bits), and shift\n    // them into where they should go.\n    byte data = *m_Bits & mask;\n\n    // check if we overlap into the next destination byte\n    if(dstoffs + bitsToRead <= 8)\n    {\n      *dst |= data << dstoffs;\n    }\n    else\n    {\n      *dst |= data << dstoffs;\n      dst++;\n      *dst = data >> (8 - dstoffs);\n    }\n\n    // consume the bits we used\n    Advance(bitsToRead);\n  }\n};\n\n};    // namespace LLVMBC\n"
  },
  {
    "path": "third_party/bc-decoder/llvm_decoder.cpp",
    "content": "/******************************************************************************\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2020 Baldur Karlsson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n ******************************************************************************/\n\n#include \"thread_local_allocator.hpp\"\n#include \"llvm_decoder.h\"\n\nnamespace LLVMBC\n{\nenum class AbbrevEncoding : uint8_t\n{\n  Fixed = 1,\n  VBR = 2,\n  Array = 3,\n  Char6 = 4,\n  Blob = 5,\n  // the abbrev encoding is only 3 bits, so 8 is not representable, we can store whether or not\n  // we're a literal this way.\n  Literal = 8,\n};\n\nstruct AbbrevParam\n{\n  AbbrevEncoding encoding;\n  uint64_t value;    // this is also the bitwidth for Fixed/VBR\n};\n\nstruct AbbrevDesc\n{\n  dxil_spv::Vector<AbbrevParam> params;\n};\n\n// the temporary context while pushing/popping blocks\nstruct BlockContext\n{\n  DXIL_SPV_OVERRIDE_NEW_DELETE\n  BlockContext(size_t size = 2) : abbrevSize(size) {}\n  size_t abbrevSize;\n  dxil_spv::Vector<AbbrevDesc> abbrevs;\n};\n\n// the permanent block info defined by BLOCKINFO\nstruct BlockInfo\n{\n  // dxil_spv::String blockname;\n  // dxil_spirv::Vector<dxil_spv::String> recordnames;\n  dxil_spv::Vector<AbbrevDesc> abbrevs;\n};\n\nenum AbbrevId\n{\n  END_BLOCK = 0,\n  ENTER_SUBBLOCK = 1,\n  DEFINE_ABBREV = 2,\n  UNABBREV_RECORD = 3,\n  APPLICATION_ABBREV = 4,\n};\n\nenum class BlockInfoRecord\n{\n  SETBID = 1,\n  BLOCKNAME = 2,\n  SETRECORDNAME = 3,\n};\n\nBitcodeReader::BitcodeReader(const byte *bitcode, size_t length) : b(bitcode, length)\n{\n  uint32_t magic = b.Read<uint32_t>();\n  (void)magic;\n  assert(magic == uint32_t(MAKE_FOURCC('B', 'C', 0xC0, 0xDE)));\n}\n\nBitcodeReader::~BitcodeReader()\n{\n  for(auto it = blockInfo.begin(); it != blockInfo.end(); ++it)\n    delete it->second;\n}\n\nBlockOrRecord BitcodeReader::ReadToplevelBlock()\n{\n  BlockOrRecord ret;\n\n  // should hit ENTER_SUBBLOCK first for top-level block\n  uint32_t abbrevID = b.fixed<uint32_t>(abbrevSize());\n  (void)abbrevID;\n  assert(abbrevID == ENTER_SUBBLOCK);\n\n  ReadBlockContents(ret);\n\n  return ret;\n}\n\nbool BitcodeReader::AtEndOfStream()\n{\n  return b.AtEndOfStream();\n}\n\nvoid BitcodeReader::ReadBlockContents(BlockOrRecord &block)\n{\n  block.id = b.vbr<uint32_t>(8);\n\n  blockStack.push_back(new BlockContext(b.vbr<size_t>(4)));\n\n  b.align32bits();\n  block.blockDwordLength = b.Read<uint32_t>();\n\n  // used for blockinfo only\n  BlockInfo *curBlockInfo = NULL;\n\n  uint32_t abbrevID = ~0U;\n  do\n  {\n    abbrevID = b.fixed<uint32_t>(abbrevSize());\n\n    if(abbrevID == END_BLOCK)\n    {\n      b.align32bits();\n    }\n    else if(abbrevID == ENTER_SUBBLOCK)\n    {\n      BlockOrRecord sub;\n\n      ReadBlockContents(sub);\n\n      block.children.push_back(sub);\n    }\n    else if(abbrevID == DEFINE_ABBREV)\n    {\n      AbbrevDesc a;\n\n      uint32_t numops = b.vbr<uint32_t>(5);\n\n      a.params.resize(numops);\n\n      for(uint32_t i = 0; i < numops; i++)\n      {\n        AbbrevParam &param = a.params[i];\n\n        bool lit = b.fixed<bool>(1);\n\n        if(lit)\n        {\n          param.encoding = AbbrevEncoding::Literal;\n          param.value = b.vbr<uint64_t>(8);\n        }\n        else\n        {\n          param.encoding = b.fixed<AbbrevEncoding>(3);\n\n          if(param.encoding == AbbrevEncoding::Fixed || param.encoding == AbbrevEncoding::VBR)\n          {\n            param.value = b.vbr<uint64_t>(5);\n          }\n        }\n      }\n\n      if(curBlockInfo)\n        curBlockInfo->abbrevs.push_back(a);\n      else\n        blockStack.back()->abbrevs.push_back(a);\n    }\n    else if(abbrevID == UNABBREV_RECORD)\n    {\n      BlockOrRecord r;\n      r.id = b.vbr<uint32_t>(6);\n      uint32_t numops = b.vbr<uint32_t>(6);\n      r.ops.resize(numops);\n      for(uint32_t i = 0; i < numops; i++)\n        r.ops[i] = b.vbr<uint64_t>(6);\n\n      if(block.id == 0)    // BLOCKINFO is block 0\n      {\n        switch(BlockInfoRecord(r.id))\n        {\n          case BlockInfoRecord::SETBID:\n          {\n            curBlockInfo = blockInfo[(uint32_t)r.ops[0]];\n            if(curBlockInfo == NULL)\n              curBlockInfo = blockInfo[(uint32_t)r.ops[0]] = new BlockInfo;\n            break;\n          }\n          case BlockInfoRecord::BLOCKNAME:\n          {\n            // skipped because this is so rarely used\n            /*\n            for(uint32_t i = 0; i < r.ops.size(); i++)\n              curBlockInfo->blockname.push_back((char)r.ops[i]);\n              */\n            break;\n          }\n          case BlockInfoRecord::SETRECORDNAME:\n          {\n            // skipped because this is so rarely used\n            /*\n            uint32_t record = (uint32_t)r.ops[0];\n            if(record >= curBlockInfo->recordnames.size())\n              curBlockInfo->recordnames.resize(record + 1);\n            r.ops.erase(r.ops.begin());\n            for(uint32_t i = 0; i < r.ops.size(); i++)\n              curBlockInfo->recordnames[record].push_back((char)r.ops[i]);\n              */\n            break;\n          }\n        }\n      }\n\n      block.children.push_back(r);\n    }\n    else\n    {\n      const AbbrevDesc &a = getAbbrev(block.id, abbrevID);\n\n      BlockOrRecord r;\n\n      // should have at least one param for the code itself\n      assert(!a.params.empty());\n\n      r.id = (uint32_t)decodeAbbrevParam(a.params[0]);\n\n      // process the rest of the operands - since some might be arrays we don't know until we\n      // process it how many ops the record will end up with but it will be at least one per\n      // parameter.\n      r.ops.reserve(a.params.size() - 1);\n      for(size_t i = 1; i < a.params.size(); i++)\n      {\n        const AbbrevParam &param = a.params[i];\n\n        if(param.encoding == AbbrevEncoding::Array)\n        {\n          // must be another param to specify the value type, and it must be the last\n          assert(i + 1 == a.params.size() - 1);\n          const AbbrevParam &elType = a.params[i + 1];\n\n          size_t arrayLen = b.vbr<size_t>(6);\n\n          for(size_t el = 0; el < arrayLen; el++)\n            r.ops.push_back(decodeAbbrevParam(elType));\n\n          break;\n        }\n        else if(param.encoding == AbbrevEncoding::Blob)\n        {\n          // blob must be the last value\n          assert(i == a.params.size() - 1);\n          b.ReadBlob(r.blob, r.blobLength);\n\n          break;\n        }\n        else\n        {\n          r.ops.push_back(decodeAbbrevParam(param));\n        }\n      }\n\n      block.children.push_back(r);\n    }\n  } while(abbrevID != END_BLOCK);\n\n  delete blockStack.back();\n  blockStack.erase(blockStack.begin() + (blockStack.size() - 1));\n}\n\nuint64_t BitcodeReader::decodeAbbrevParam(const AbbrevParam &param)\n{\n  assert(param.encoding != AbbrevEncoding::Array && param.encoding != AbbrevEncoding::Blob);\n\n  switch(param.encoding)\n  {\n    case AbbrevEncoding::Fixed: return b.fixed<uint64_t>((size_t)param.value);\n    case AbbrevEncoding::VBR: return b.vbr<uint64_t>((size_t)param.value);\n    case AbbrevEncoding::Char6: return b.c6();\n    case AbbrevEncoding::Literal: return param.value;\n  \n    case AbbrevEncoding::Array:\n    case AbbrevEncoding::Blob:\n      return 0;\n  }\n\n  return 0;\n}\n\nsize_t BitcodeReader::abbrevSize() const\n{\n  if(blockStack.empty())\n    return 2;\n  return blockStack.back()->abbrevSize;\n}\n\nconst AbbrevDesc &BitcodeReader::getAbbrev(uint32_t blockId, uint32_t abbrevID)\n{\n  const BlockInfo *info = blockInfo[blockId];\n\n  // IDs start at the first application specified ID. Rebase to that to get 0-base indices\n  assert(abbrevID >= APPLICATION_ABBREV);\n  abbrevID -= APPLICATION_ABBREV;\n\n  if(info)\n  {\n    // IDs are first assigned to those permanently from BLOCKINFO\n    if(abbrevID < info->abbrevs.size())\n      return info->abbrevs[abbrevID];\n\n    // block-local IDs start after the BLOCKINFO ones\n    abbrevID -= (uint32_t)info->abbrevs.size();\n  }\n\n  assert(!blockStack.empty());\n  assert(abbrevID < blockStack.back()->abbrevs.size());\n\n  return blockStack.back()->abbrevs[abbrevID];\n}\n\ndxil_spv::String BlockOrRecord::getString(size_t startOffset) const\n{\n  dxil_spv::String ret;\n  ret.resize(ops.size() - startOffset);\n  for(size_t i = 0; i < ret.size(); i++)\n    ret[i] = (char)ops[i + startOffset];\n  return ret;\n}\n\n};    // namespace LLVMBC\n\n#if ENABLE_UNIT_TESTS\n\n#include \"3rdparty/catch/catch.hpp\"\n\nTEST_CASE(\"Check LLVM bitreader\", \"[llvm]\")\n{\n  SECTION(\"Check simple reading of bytes\")\n  {\n    byte bits[] = {0x01, 0x02, 0x40, 0x80, 0xff};\n\n    LLVMBC::BitReader b(bits, sizeof(bits));\n\n    CHECK(!b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 0);\n\n    // ensure we can read it all out again in whole bytes\n    for(size_t i = 0; i < sizeof(bits); i++)\n    {\n      byte val = b.Read<byte>();\n      CHECK(val == bits[i]);\n      if(i + 1 < sizeof(bits))\n        CHECK(!b.AtEndOfStream());\n      else\n        CHECK(b.AtEndOfStream());\n      CHECK(b.ByteOffset() == i + 1);\n      CHECK(b.BitOffset() == (i + 1) * 8);\n    }\n  }\n\n  SECTION(\"Check seeking within the stream\")\n  {\n    byte bits[] = {0x01, 0x4f, 0x8c, 0xff};\n    byte val;\n\n    LLVMBC::BitReader b(bits, sizeof(bits));\n\n    CHECK(!b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 0);\n\n    b.SeekByte(4);\n\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 4);\n    CHECK(b.BitOffset() == 32);\n\n    b.SeekBit(32);\n\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 4);\n    CHECK(b.BitOffset() == 32);\n\n    b.SeekBit(29);\n\n    CHECK(!b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 3);\n    CHECK(b.BitOffset() == 29);\n\n    val = b.fixed<byte>(3);\n\n    CHECK(val == 0x7);\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 4);\n    CHECK(b.BitOffset() == 32);\n\n    b.SeekBit(0);\n\n    CHECK(!b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 0);\n  }\n\n  SECTION(\"Check with empty bitstream\")\n  {\n    byte bits[] = {0};\n\n    LLVMBC::BitReader b(bits, 0);\n\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 0);\n  }\n\n  SECTION(\"Check out of bounds behaviour\")\n  {\n    byte bits[] = {0x40, 0x80, 0xff};\n\n    LLVMBC::BitReader b(bits, sizeof(bits));\n\n    CHECK(!b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 0);\n\n    // first read is fully satisfied, we get the value we expect\n    uint32_t val1 = b.fixed<uint32_t>(17);\n    CHECK(val1 == 0x18040);\n\n    // second read is partially out of bounds, we should read all 0s\n    uint32_t val2 = b.fixed<uint32_t>(16);\n    CHECK(val2 == 0);\n\n    // should be exactly at the end of the stream\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == sizeof(bits));\n    CHECK(b.BitOffset() == sizeof(bits) * 8);\n  }\n\n  SECTION(\"Check fixed encoding\")\n  {\n    // 0x96 = 0b 1001 0110\n    // 0xF0 = 0b 1111 0000\n    // 0xA5 = 0b 1010 0101\n    // 0x3C = 0b 0011 1100\n\n    // we pad out with 0s so we don't read off the end of the stream when reading up to 4 32-bit\n    // values\n    byte bits[] = {\n        // dword 1\n        0x96, 0xf0, 0xA5, 0x3C,\n        // padding dword\n        0x00, 0x00, 0x00, 0x00,\n        // padding dword\n        0x00, 0x00, 0x00, 0x00,\n        // padding dword\n        0x00, 0x00, 0x00, 0x00,\n    };\n\n    LLVMBC::BitReader b(bits, sizeof(bits));\n\n    // for each of the bit widths, 1 to 32, read 4 values.\n    // This should decode from the LSB to MSB in the bitstream - in the commented values above that\n    // is right-to-left then top-to-bottom\n    uint32_t expected[32][4] = {\n        // i_1\n        {0x00, 0x01, 0x01, 0x00},\n        // i_2\n        {0x02, 0x01, 0x01, 0x02},\n        // i_3\n        {0x06, 0x02, 0x02, 0x00},\n        // i_4\n        {0x06, 0x09, 0x00, 0x0f},\n        // i_5\n        {0x16, 0x04, 0x1C, 0x0B},\n        // i_6\n        {0x16, 0x02, 0x1F, 0x29},\n        // i_7\n        {0x16, 0x61, 0x17, 0x65},\n        // i_8\n        {0x96, 0xF0, 0xA5, 0x3C},\n\n        // i_9\n        {0x0096, 0x00F8, 0x0129, 0x0007},\n        // i_10\n        {0x0096, 0x017C, 0x03CA, 0x0000},\n        // i_11\n        {0x0096, 0x04BE, 0x00F2, 0x0000},\n        // i_12\n        {0x0096, 0x0A5F, 0x003C, 0x0000},\n        // i_13\n        {0x1096, 0x052F, 0x000F, 0x0000},\n        // i_14\n        {0x3096, 0x3297, 0x0003, 0x0000},\n        // i_15\n        {0x7096, 0x794B, 0x0000, 0x0000},\n        // i_16\n        {0xF096, 0x3CA5, 0x0000, 0x0000},\n\n        // i_17\n        {0x0001F096, 0x00001E52},\n        // i_18\n        {0x0001F096, 0x00000F29},\n        // i_19\n        {0x0005F096, 0x00000794},\n        // i_20\n        {0x0005F096, 0x000003CA},\n        // i_21\n        {0x0005F096, 0x000001E5},\n        // i_22\n        {0x0025F096, 0x000000F2},\n        // i_23\n        {0x0025F096, 0x00000079},\n        // i_24\n        {0x00A5F096, 0x0000003C},\n        // i_25\n        {0x00A5F096, 0x0000001E},\n        // i_26\n        {0x00A5F096, 0x0000000F},\n        // i_27\n        {0x04A5F096, 0x00000007},\n        // i_28\n        {0x0CA5F096, 0x00000003},\n        // i_29\n        {0x1CA5F096, 0x00000001},\n        // i_30\n        {0x3CA5F096, 0x00000000},\n        // i_31\n        {0x3CA5F096, 0x00000000},\n        // i_32\n        {0x3CA5F096, 0x00000000},\n    };\n\n    for(size_t i = 0; i < 32; i++)\n    {\n      b.SeekBit(0);\n      uint32_t read;\n\n      INFO(\"Bit width: \" << uint32_t(i + 1));\n\n      read = b.fixed<uint32_t>(i + 1);\n      CHECK(read == expected[i][0]);\n\n      read = b.fixed<uint32_t>(i + 1);\n      CHECK(read == expected[i][1]);\n\n      read = b.fixed<uint32_t>(i + 1);\n      CHECK(read == expected[i][2]);\n\n      read = b.fixed<uint32_t>(i + 1);\n      CHECK(read == expected[i][3]);\n    }\n\n    // should be exactly at the end of the stream\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == sizeof(bits));\n    CHECK(b.BitOffset() == sizeof(bits) * 8);\n  }\n\n  SECTION(\"Check variable encoding\")\n  {\n    SECTION(\"Single chunk, no extension\")\n    {\n      // just set as many bits as we can in one chunk, so all 1s except the MSB\n\n      byte bits[] = {\n          // i_vbr0 (padding)\n          0,\n          // i_vbr1 (padding)\n          0,\n          // i_vbr2\n          0x01,\n          // i_vbr3\n          0x03,\n          // i_vbr4\n          0x07,\n          // i_vbr5\n          0x0f,\n          // i_vbr6\n          0x1f,\n          // i_vbr7\n          0x3f,\n          // i_vbr8\n          0x7f,\n      };\n\n      LLVMBC::BitReader b(bits, sizeof(bits));\n\n      for(size_t i = 2; i <= 8; i++)\n      {\n        INFO(\"VBR group size: \" << uint32_t(i));\n        b.SeekByte(i);\n\n        uint64_t val = b.vbr<uint64_t>(i);\n        CHECK(val == bits[i]);\n      }\n\n      // should be exactly at the end of the stream\n      CHECK(b.AtEndOfStream());\n      CHECK(b.ByteOffset() == sizeof(bits));\n      CHECK(b.BitOffset() == sizeof(bits) * 8);\n    }\n\n    SECTION(\"Two chunks, one extension\")\n    {\n      // set all bits that we can from two chunks - that means the first chunk is all 1s, the second\n      // is all 1s except the leading 0\n\n      byte bits[] = {\n          // i_vbr0 (padding)\n          0, 0,\n          // i_vbr1 (padding)\n          0, 0,\n          // i_vbr2\n          0x07, 0x00,    // 0b 01 11\n          // i_vbr3\n          0x1f, 0x00,    // 0b 011 111\n          // i_vbr4\n          0x7f, 0x00,    // 0b 0111 1111\n          // i_vbr5\n          0xff, 0x01,    // 0b 01111 11111\n          // i_vbr6\n          0xff, 0x07,    // 0b 011111 111111\n          // i_vbr7\n          0xff, 0x1f,    // 0b 0111111 1111111\n          // i_vbr8\n          0xff, 0x7f,    // 0b 01111111 11111111\n      };\n\n      uint64_t expected[] = {\n          0, 0,\n          // i_vbr2\n          0x0003,\n          // i_vbr3\n          0x000f,\n          // i_vbr4\n          0x003f,\n          // i_vbr5\n          0x00ff,\n          // i_vbr6\n          0x03ff,\n          // i_vbr7\n          0x0fff,\n          // i_vbr8\n          0x3fff,\n      };\n\n      LLVMBC::BitReader b(bits, sizeof(bits));\n\n      for(size_t i = 2; i <= 8; i++)\n      {\n        INFO(\"VBR group size: \" << uint32_t(i));\n        b.SeekByte(i * 2);\n\n        uint64_t val = b.vbr<uint64_t>(i);\n        CHECK(val == expected[i]);\n      }\n\n      // should be exactly at the end of the stream\n      CHECK(b.AtEndOfStream());\n      CHECK(b.ByteOffset() == sizeof(bits));\n      CHECK(b.BitOffset() == sizeof(bits) * 8);\n    }\n\n    SECTION(\"Five chunks, four extensions\")\n    {\n      // set an alternating 10 pattern from the top bit. Each group except the last has a leading 1\n\n      byte bits[] = {\n          // i_vbr0 (padding)\n          0, 0, 0, 0, 0,\n          // i_vbr1 (padding)\n          0, 0, 0, 0, 0,\n          // i_vbr2\n          0xBB, 0x01, 0x00, 0x00, 0x00,    // 0b 01 10 11 10 11\n          // i_vbr3\n          0xB6, 0x2D, 0x00, 0x00, 0x00,    // 0b 010 110 110 110 110\n          // i_vbr4\n          0xAD, 0xAD, 0x05, 0x00, 0x00,    // 0b 0101 1010 1101 1010 1101\n          // i_vbr5\n          0x5A, 0x6B, 0xAD, 0x00, 0x00,    // 0b 01010 11010 11010 11010 11010\n          // i_vbr6\n          0xB5, 0x5A, 0xAB, 0x15, 0x00,    // 0b 010101 101010 110101 101010 110101\n          // i_vbr7\n          0x6A, 0xB5, 0x5A, 0xAD, 0x02,    // 0b 0101010 1101010 1101010 1101010 1101010\n          // i_vbr8\n          0xD5, 0xAA, 0xD5, 0xAA, 0x55,    // 0b 01010101 10101010 11010101 10101010 11010101\n      };\n\n      uint64_t expected[] = {\n          0, 0,\n          // i_vbr2\n          0x0000000015ULL,    // 0b 1 0 1 0 1\n          // i_vbr3\n          0x00000002AAULL,    // 0b 10 10 10 10 10\n          // i_vbr4\n          0x0000005555ULL,    // 0b 101 010 101 010 101\n          // i_vbr5\n          0x00000AAAAAULL,    // 0b 1010 1010 1010 1010 1010\n          // i_vbr6\n          0x0001555555ULL,    // 0b 10101 01010 10101 01010 10101\n          // i_vbr7\n          0x002AAAAAAAULL,    // 0b 101010 101010 101010 101010 101010\n          // i_vbr8\n          0x0555555555ULL,    // 0b 1010101 0101010 1010101 0101010 1010101\n      };\n\n      LLVMBC::BitReader b(bits, sizeof(bits));\n\n      for(size_t i = 2; i <= 8; i++)\n      {\n        INFO(\"VBR group size: \" << uint32_t(i));\n        b.SeekByte(i * 5);\n\n        uint64_t val = b.vbr<uint64_t>(i);\n        CHECK(val == expected[i]);\n      }\n\n      // should be exactly at the end of the stream\n      CHECK(b.AtEndOfStream());\n      CHECK(b.ByteOffset() == sizeof(bits));\n      CHECK(b.BitOffset() == sizeof(bits) * 8);\n    }\n\n    SECTION(\"Check signed vbr decoding\")\n    {\n      // we don't check every possible bit width since this is decoded the same as vbr except for a\n      // post-check and shift. Instead we use vbr4 since it's convenient for hex literals\n      byte bits[] = {\n          0x04,                // 0b 0100 = +2\n          0x05,                // 0b 0101 = -2\n          0xBA, 0x9E, 0x68,    // 0b 0110 1000 1001 1110 1011 1010 = +98765\n          0xBB, 0x9E, 0x68,    // 0b 0110 1000 1001 1110 1011 1011 = -98765\n          // INT64_MAX. 64-bits encoded in 3-bit groups is 22 groups, so 22 * 4-bit encoded groups\n          // is 88 bits, meaning 11 bytes\n          0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,\n          // INT64_MIN. Same as above but with the LSB set to 1\n          0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,\n          // one more value just to check that we didn't overrun above\n          0x06,    // 0b 0110 = +3\n      };\n\n      LLVMBC::BitReader b(bits, sizeof(bits));\n\n      int64_t val;\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == 2);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == 0);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == -2);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == 0);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == 98765);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == -98765);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == INT64_MAX);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == -INT64_MAX);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == 3);\n\n      val = b.svbr<int64_t>(4);\n      CHECK(val == 0);\n\n      // should be exactly at the end of the stream\n      CHECK(b.AtEndOfStream());\n      CHECK(b.ByteOffset() == sizeof(bits));\n      CHECK(b.BitOffset() == sizeof(bits) * 8);\n    }\n  }\n\n  SECTION(\"Check char6 encoding\")\n  {\n    byte bits[64] = {};\n    for(size_t i = 0; i < sizeof(bits); i++)\n      bits[i] = i & 0xff;\n\n    // this is the char6 encoding\n    const char string[] = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._\";\n\n    RDCCOMPILE_ASSERT(sizeof(string) - 1 == sizeof(bits),\n                      \"bits byte array and string should be same size.\");\n\n    LLVMBC::BitReader b(bits, sizeof(bits));\n\n    for(size_t i = 0; i < sizeof(bits); i++)\n    {\n      char c = b.c6();\n      // for simplicity we read padding too\n      byte pad = b.fixed<byte>(2);\n\n      CHECK(c == string[i]);\n      CHECK(pad == 0);\n    }\n  }\n\n  SECTION(\"Check 32-bit aligning\")\n  {\n    byte bits[] = {\n        // first i_4 value\n        0x04,\n        // padding for alignment\n        0x00, 0x00, 0x00,\n\n        // second two i_4 values\n        0xF5,\n        // i_24 value\n        0xCA, 0x99, 0x23,\n\n        // no padding - already aligned\n\n        // i_6 value and i_2 value\n        0xBF,\n    };\n\n    LLVMBC::BitReader b(bits, sizeof(bits));\n\n    CHECK(!b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 0);\n\n    uint32_t val;\n\n    // first read is fully satisfied, we get the value we expect\n    val = b.fixed<uint32_t>(4);\n    CHECK(val == 0x4);\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 4);\n\n    b.align32bits();\n\n    CHECK(b.ByteOffset() == 4);\n    CHECK(b.BitOffset() == 32);\n\n    val = b.fixed<uint32_t>(4);\n    CHECK(val == 0x5);\n\n    val = b.fixed<uint32_t>(4);\n    CHECK(val == 0xf);\n\n    val = b.fixed<uint32_t>(24);\n    CHECK(val == 0x2399CA);\n\n    CHECK(b.ByteOffset() == 8);\n    CHECK(b.BitOffset() == 64);\n\n    // should be a no-op because we're already aligned\n    b.align32bits();\n\n    CHECK(b.ByteOffset() == 8);\n    CHECK(b.BitOffset() == 64);\n\n    val = b.fixed<uint32_t>(6);\n    CHECK(val == 0x3f);\n\n    val = b.fixed<uint32_t>(2);\n    CHECK(val == 0x2);\n\n    // should be exactly at the end of the stream\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == sizeof(bits));\n    CHECK(b.BitOffset() == sizeof(bits) * 8);\n  }\n\n  SECTION(\"Check blob fetch\")\n  {\n    // size = 16 bytes for encoded data and first blob, 70 bytes for second blob, 2 bytes trailing\n    // padding\n    byte bits[16 + 70 + 2] = {\n        // first vbr_6 length\n        0x06,\n        // padding for alignment\n        0x00, 0x00, 0x00,\n\n        // blob data\n        0xF5, 0x00, 0xCA, 0x40, 0x99, 0x23,\n\n        // padding for trailing alignment\n        0x00, 0x00,\n\n        // i_20 dummy to get us to the point where two vbr_6 chunks would be aligned\n        // we choose a length of 70, which is 0b10 00110, then vbr_6 encoded it becomes\n        // 0b000010 100110 which is 0xA6, over 12 bits. That leaves 4 bits in the upper part of\n        // the last byte of the i_20, and the remaining 8 in the next byte\n        0x5B, 0xC2, 0x64, 0x0A,\n    };\n\n    LLVMBC::BitReader b(bits, sizeof(bits));\n\n    CHECK(!b.AtEndOfStream());\n    CHECK(b.ByteOffset() == 0);\n    CHECK(b.BitOffset() == 0);\n\n    const byte *ptr = NULL;\n    size_t size = 0;\n\n    b.ReadBlob(ptr, size);\n\n    CHECK(size == 6);\n    CHECK(ptr == &bits[4]);\n\n    uint32_t val = b.fixed<uint32_t>(20);\n    CHECK(val == 0x4C25B);\n\n    ptr = NULL;\n    size = 0;\n\n    b.ReadBlob(ptr, size);\n\n    CHECK(size == 70);\n    CHECK(ptr == &bits[16]);\n\n    // should be exactly at the end of the stream\n    CHECK(b.AtEndOfStream());\n    CHECK(b.ByteOffset() == sizeof(bits));\n    CHECK(b.BitOffset() == sizeof(bits) * 8);\n  }\n}\n\n#endif\n"
  },
  {
    "path": "third_party/bc-decoder/llvm_decoder.h",
    "content": "/******************************************************************************\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2020 Baldur Karlsson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n ******************************************************************************/\n\n#pragma once\n\n#include \"thread_local_allocator.hpp\"\n#include \"llvm_bitreader.h\"\n#include <stdint.h>\n\nnamespace LLVMBC\n{\nstruct BlockOrRecord\n{\n  uint32_t id;\n  uint32_t blockDwordLength = 0;    // 0 for records\n\n  bool IsBlock() const { return blockDwordLength > 0; }\n  bool IsRecord() const { return blockDwordLength == 0; }\n  // if a block, the child blocks/records\n  dxil_spv::Vector<BlockOrRecord> children;\n\n  dxil_spv::String getString(size_t startOffset = 0) const;\n\n  // if a record, the ops\n  dxil_spv::Vector<uint64_t> ops;\n  // if this is an abbreviated record with a blob, this is the last operand\n  // this points into the overall byte storage, so the lifetime is limited.\n  const byte *blob = NULL;\n  size_t blobLength = 0;\n};\n\nstruct AbbrevParam;\nstruct AbbrevDesc;\nstruct BlockContext;\nstruct BlockInfo;\n\nclass BitcodeReader\n{\npublic:\n  BitcodeReader(const byte *bitcode, size_t length);\n  ~BitcodeReader();\n  BlockOrRecord ReadToplevelBlock();\n  bool AtEndOfStream();\n\nprivate:\n  BitReader b;\n\n  void ReadBlockContents(BlockOrRecord &block);\n  const AbbrevDesc &getAbbrev(uint32_t blockId, uint32_t abbrevID);\n  size_t abbrevSize() const;\n  uint64_t decodeAbbrevParam(const AbbrevParam &param);\n\n  dxil_spv::Vector<BlockContext *> blockStack;\n  dxil_spv::UnorderedMap<uint32_t, BlockInfo *> blockInfo;\n};\n\n};    // namespace LLVMBC\n"
  },
  {
    "path": "third_party/cli_parser/cli_parser.cpp",
    "content": "/* Copyright (c) 2017-2019 Hans-Kristian Arntzen\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// Reused from Granite.\n\n#include \"cli_parser.hpp\"\n#include \"logging.hpp\"\n#include <limits>\n\nusing namespace std;\n\nnamespace dxil_spv\n{\nCLIParser::CLIParser(CLICallbacks cbs_, int argc_, char *argv_[])\n\t: cbs(move(cbs_)), argc(argc_), argv(argv_)\n{\n}\n\nbool CLIParser::parse()\n{\n\twhile (argc && !ended_state)\n\t{\n\t\tconst char *next = *argv++;\n\t\targc--;\n\n\t\tif (*next != '-' && cbs.default_handler)\n\t\t{\n\t\t\tcbs.default_handler(next);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto itr = cbs.callbacks.find(next);\n\t\t\tif (itr == ::end(cbs.callbacks))\n\t\t\t{\n\t\t\t\tif (unknown_argument_is_default)\n\t\t\t\t\tcbs.default_handler(next);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (cbs.error_handler)\n\t\t\t\t\t\tcbs.error_handler();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\titr->second(*this);\n\t\t}\n\t}\n\treturn true;\n}\n\nvoid CLIParser::end()\n{\n\tended_state = true;\n}\n\nunsigned CLIParser::next_uint()\n{\n\tif (!argc)\n\t{\n\t\tLOGE(\"Tried to parse uint, but nothing left in arguments.\\n\");\n\t\tif (cbs.error_handler)\n\t\t\tcbs.error_handler();\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tauto val = stoul(*argv);\n\tif (val > numeric_limits<unsigned>::max())\n\t{\n\t\tLOGE(\"next_uint() out of range.\\n\");\n\t\tif (cbs.error_handler)\n\t\t\tcbs.error_handler();\n\t\texit(EXIT_FAILURE);\n\t}\n\n\targc--;\n\targv++;\n\n\treturn unsigned(val);\n}\n\ndouble CLIParser::next_double()\n{\n\tif (!argc)\n\t{\n\t\tLOGE(\"Tried to parse double, but nothing left in arguments.\\n\");\n\t\tif (cbs.error_handler)\n\t\t\tcbs.error_handler();\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tdouble val = stod(*argv);\n\n\targc--;\n\targv++;\n\n\treturn val;\n}\n\nconst char *CLIParser::next_string()\n{\n\tif (!argc)\n\t{\n\t\tLOGE(\"Tried to parse string, but nothing left in arguments.\\n\");\n\t\tif (cbs.error_handler)\n\t\t\tcbs.error_handler();\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tconst char *ret = *argv;\n\targc--;\n\targv++;\n\treturn ret;\n}\n}\n"
  },
  {
    "path": "third_party/cli_parser/cli_parser.hpp",
    "content": "/* Copyright (c) 2017-2019 Hans-Kristian Arntzen\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// Reused from Granite.\n\n#pragma once\n\n#include <functional>\n#include <string>\n#include <unordered_map>\n#include <utility>\n\nnamespace dxil_spv\n{\nclass CLIParser;\n\nstruct CLICallbacks\n{\n\tvoid add(const char *cli, const std::function<void(CLIParser &)> &func)\n\t{\n\t\tcallbacks[cli] = func;\n\t}\n\n\tstd::unordered_map<std::string, std::function<void(CLIParser &)>> callbacks;\n\tstd::function<void()> error_handler;\n\tstd::function<void(const char *)> default_handler;\n};\n\nclass CLIParser\n{\npublic:\n\tCLIParser(CLICallbacks cbs_, int argc_, char *argv_[]);\n\n\tbool parse();\n\n\tvoid end();\n\n\tunsigned next_uint();\n\n\tdouble next_double();\n\n\tconst char *next_string();\n\n\tbool is_ended_state() const\n\t{\n\t\treturn ended_state;\n\t}\n\n\tvoid ignore_unknown_arguments()\n\t{\n\t\tunknown_argument_is_default = true;\n\t}\n\nprivate:\n\tCLICallbacks cbs;\n\tint argc;\n\tchar **argv;\n\tbool ended_state = false;\n\tbool unknown_argument_is_default = false;\n};\n}\n"
  },
  {
    "path": "third_party/glslang-spirv/InReadableOrder.cpp",
    "content": "//\n// Copyright (C) 2016 Google, Inc.\n//\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//    Redistributions of source code must retain the above copyright\n//    notice, this list of conditions and the following disclaimer.\n//\n//    Redistributions in binary form must reproduce the above\n//    copyright notice, this list of conditions and the following\n//    disclaimer in the documentation and/or other materials provided\n//    with the distribution.\n//\n//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its\n//    contributors may be used to endorse or promote products derived\n//    from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n// The SPIR-V spec requires code blocks to appear in an order satisfying the\n// dominator-tree direction (ie, dominator before the dominated).  This is,\n// actually, easy to achieve: any pre-order CFG traversal algorithm will do it.\n// Because such algorithms visit a block only after traversing some path to it\n// from the root, they necessarily visit the block's idom first.\n//\n// But not every graph-traversal algorithm outputs blocks in an order that\n// appears logical to human readers.  The problem is that unrelated branches may\n// be interspersed with each other, and merge blocks may come before some of the\n// branches being merged.\n//\n// A good, human-readable order of blocks may be achieved by performing\n// depth-first search but delaying merge nodes until after all their branches\n// have been visited.  This is implemented below by the inReadableOrder()\n// function.\n\n#include \"spvIR.h\"\n\n#include <cassert>\n#include \"thread_local_allocator.hpp\"\n\nusing spv::Block;\nusing spv::Id;\n\nnamespace {\n// Traverses CFG in a readable order, invoking a pre-set callback on each block.\n// Use by calling visit() on the root block.\nclass ReadableOrderTraverser {\npublic:\n    explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {}\n    // Visits the block if it hasn't been visited already and isn't currently\n    // being delayed.  Invokes callback(block), then descends into its\n    // successors.  Delays merge-block and continue-block processing until all\n    // the branches have been completed.\n    void visit(Block* block)\n    {\n        assert(block);\n        if (visited_.count(block) || delayed_.count(block))\n            return;\n        callback_(block);\n        visited_.insert(block);\n        Block* mergeBlock = nullptr;\n        Block* continueBlock = nullptr;\n        auto mergeInst = block->getMergeInstruction();\n        if (mergeInst) {\n            Id mergeId = mergeInst->getIdOperand(0);\n            mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();\n            delayed_.insert(mergeBlock);\n            if (mergeInst->getOpCode() == spv::OpLoopMerge) {\n                Id continueId = mergeInst->getIdOperand(1);\n                continueBlock =\n                    block->getParent().getParent().getInstruction(continueId)->getBlock();\n                delayed_.insert(continueBlock);\n            }\n        }\n        const auto successors = block->getSuccessors();\n        for (auto it = successors.cbegin(); it != successors.cend(); ++it)\n            visit(*it);\n        if (continueBlock) {\n            delayed_.erase(continueBlock);\n            visit(continueBlock);\n        }\n        if (mergeBlock) {\n            delayed_.erase(mergeBlock);\n            visit(mergeBlock);\n        }\n    }\n\nprivate:\n    std::function<void(Block*)> callback_;\n    // Whether a block has already been visited or is being delayed.\n    dxil_spv::UnorderedSet<Block *> visited_, delayed_;\n};\n}\n\nvoid spv::inReadableOrder(Block* root, std::function<void(Block*)> callback)\n{\n    ReadableOrderTraverser(callback).visit(root);\n}\n"
  },
  {
    "path": "third_party/glslang-spirv/Logger.cpp",
    "content": "//\n// Copyright (C) 2016 Google, Inc.\n//\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//    Redistributions of source code must retain the above copyright\n//    notice, this list of conditions and the following disclaimer.\n//\n//    Redistributions in binary form must reproduce the above\n//    copyright notice, this list of conditions and the following\n//    disclaimer in the documentation and/or other materials provided\n//    with the distribution.\n//\n//    Neither the name of Google Inc. nor the names of its\n//    contributors may be used to endorse or promote products derived\n//    from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n#include \"Logger.h\"\n\n#include <algorithm>\n#include <iterator>\n#include <sstream>\n\nnamespace spv {\n\nvoid SpvBuildLogger::tbdFunctionality(const dxil_spv::String& f)\n{\n    if (std::find(std::begin(tbdFeatures), std::end(tbdFeatures), f) == std::end(tbdFeatures))\n        tbdFeatures.push_back(f);\n}\n\nvoid SpvBuildLogger::missingFunctionality(const dxil_spv::String& f)\n{\n    if (std::find(std::begin(missingFeatures), std::end(missingFeatures), f) == std::end(missingFeatures))\n        missingFeatures.push_back(f);\n}\n\ndxil_spv::String SpvBuildLogger::getAllMessages() const {\n    dxil_spv::StringStream messages;\n    for (auto it = tbdFeatures.cbegin(); it != tbdFeatures.cend(); ++it)\n        messages << \"TBD functionality: \" << *it << \"\\n\";\n    for (auto it = missingFeatures.cbegin(); it != missingFeatures.cend(); ++it)\n        messages << \"Missing functionality: \" << *it << \"\\n\";\n    for (auto it = warnings.cbegin(); it != warnings.cend(); ++it)\n        messages << \"warning: \" << *it << \"\\n\";\n    for (auto it = errors.cbegin(); it != errors.cend(); ++it)\n        messages << \"error: \" << *it << \"\\n\";\n    return messages.str();\n}\n\n} // end spv namespace\n"
  },
  {
    "path": "third_party/glslang-spirv/Logger.h",
    "content": "//\n// Copyright (C) 2016 Google, Inc.\n//\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//    Redistributions of source code must retain the above copyright\n//    notice, this list of conditions and the following disclaimer.\n//\n//    Redistributions in binary form must reproduce the above\n//    copyright notice, this list of conditions and the following\n//    disclaimer in the documentation and/or other materials provided\n//    with the distribution.\n//\n//    Neither the name of Google Inc. nor the names of its\n//    contributors may be used to endorse or promote products derived\n//    from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n#ifndef GLSLANG_SPIRV_LOGGER_H\n#define GLSLANG_SPIRV_LOGGER_H\n\n#include \"thread_local_allocator.hpp\"\n\nnamespace spv {\n\n// A class for holding all SPIR-V build status messages, including\n// missing/TBD functionalities, warnings, and errors.\nclass SpvBuildLogger {\npublic:\n    SpvBuildLogger() {}\n\n    // Registers a TBD functionality.\n    void tbdFunctionality(const dxil_spv::String& f);\n    // Registers a missing functionality.\n    void missingFunctionality(const dxil_spv::String& f);\n\n    // Logs a warning.\n    void warning(const dxil_spv::String& w) { warnings.push_back(w); }\n    // Logs an error.\n    void error(const dxil_spv::String& e) { errors.push_back(e); }\n\n    // Returns all messages accumulated in the order of:\n    // TBD functionalities, missing functionalities, warnings, errors.\n    dxil_spv::String getAllMessages() const;\n\nprivate:\n    SpvBuildLogger(const SpvBuildLogger&);\n\n    dxil_spv::Vector<dxil_spv::String> tbdFeatures;\n    dxil_spv::Vector<dxil_spv::String> missingFeatures;\n    dxil_spv::Vector<dxil_spv::String> warnings;\n    dxil_spv::Vector<dxil_spv::String> errors;\n};\n\n} // end spv namespace\n\n#endif // GLSLANG_SPIRV_LOGGER_H\n"
  },
  {
    "path": "third_party/glslang-spirv/SpvBuilder.cpp",
    "content": "//\n// Copyright (C) 2014-2015 LunarG, Inc.\n// Copyright (C) 2015-2016 Google, Inc.\n//\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//    Redistributions of source code must retain the above copyright\n//    notice, this list of conditions and the following disclaimer.\n//\n//    Redistributions in binary form must reproduce the above\n//    copyright notice, this list of conditions and the following\n//    disclaimer in the documentation and/or other materials provided\n//    with the distribution.\n//\n//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its\n//    contributors may be used to endorse or promote products derived\n//    from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n//\n// Helper for making SPIR-V IR.  Generally, this is documented in the header\n// SpvBuilder.h.\n//\n\n#include <cassert>\n#include <cstdlib>\n\n#include <algorithm>\n\n#include \"SpvBuilder.h\"\n\n#ifndef _WIN32\n    #include <cstdio>\n#endif\n\nnamespace spv {\n\nBuilder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :\n    source(SourceLanguageUnknown),\n    sourceVersion(0),\n    sourceFileStringId(NoResult),\n    currentLine(0),\n    emitOpLines(false),\n    addressModel(AddressingModelLogical),\n    memoryModel(MemoryModelGLSL450),\n    builderNumber(magicNumber),\n    buildPoint(0),\n    uniqueId(0),\n    entryPointFunction(0),\n    generatingOpCodeForSpecConst(false),\n    logger(buildLogger)\n{\n    clearAccessChain();\n}\n\nBuilder::~Builder()\n{\n}\n\nId Builder::import(const char* name)\n{\n    for (auto &id : importIDCache)\n        if (id.first == name)\n            return id.second;\n\n    Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport);\n    import->addStringOperand(name);\n\n    imports.push_back(std::unique_ptr<Instruction>(import));\n    importIDCache.emplace_back(name, import->getResultId());\n    return import->getResultId();\n}\n\n// Emit an OpLine if we've been asked to emit OpLines and the line number\n// has changed since the last time, and is a valid line number.\nvoid Builder::setLine(int lineNum)\n{\n    if (lineNum != 0 && lineNum != currentLine) {\n        currentLine = lineNum;\n        if (emitOpLines)\n            addLine(sourceFileStringId, currentLine, 0);\n    }\n}\n\nspv::Instruction *Builder::addInstruction(spv::Id typeId, spv::Op op)\n{\n    auto inst = std::make_unique<spv::Instruction>(getUniqueId(), typeId, op);\n    auto *ret = inst.get();\n    getBuildPoint()->addInstruction(std::move(inst));\n    return ret;\n}\n\nspv::Instruction *Builder::addInstruction(spv::Op op)\n{\n    auto inst = std::make_unique<spv::Instruction>(op);\n    auto *ret = inst.get();\n    getBuildPoint()->addInstruction(std::move(inst));\n    return ret;\n}\n\nvoid Builder::addLine(Id fileName, int lineNum, int column)\n{\n    Instruction* line = new Instruction(OpLine);\n    line->addIdOperand(fileName);\n    line->addImmediateOperand(lineNum);\n    line->addImmediateOperand(column);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(line));\n}\n\nvoid Builder::addExternal(std::unique_ptr<Instruction> inst)\n{\n    externals.push_back(std::move(inst));\n}\n\nspv::Id Builder::addString(const dxil_spv::String &str)\n{\n    auto spv_str = std::make_unique<Instruction>(getUniqueId(), NoType, OpString);\n    spv_str->addStringOperand(str.c_str());\n    spv::Id ret = spv_str->getResultId();\n    strings.push_back(std::move(spv_str));\n    return ret;\n}\n\n// For creating new groupedTypes (will return old type if the requested one was already made).\nId Builder::makeVoidType()\n{\n    Instruction* type;\n    if (groupedTypes[OpTypeVoid].size() == 0) {\n        type = new Instruction(getUniqueId(), NoType, OpTypeVoid);\n        groupedTypes[OpTypeVoid].push_back(type);\n        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n        module.mapInstruction(type);\n    } else\n        type = groupedTypes[OpTypeVoid].back();\n\n    return type->getResultId();\n}\n\nId Builder::makeBoolType()\n{\n    Instruction* type;\n    if (groupedTypes[OpTypeBool].size() == 0) {\n        type = new Instruction(getUniqueId(), NoType, OpTypeBool);\n        groupedTypes[OpTypeBool].push_back(type);\n        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n        module.mapInstruction(type);\n    } else\n        type = groupedTypes[OpTypeBool].back();\n\n    return type->getResultId();\n}\n\nId Builder::makeSamplerType()\n{\n    Instruction* type;\n    if (groupedTypes[OpTypeSampler].size() == 0) {\n        type = new Instruction(getUniqueId(), NoType, OpTypeSampler);\n        groupedTypes[OpTypeSampler].push_back(type);\n        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n        module.mapInstruction(type);\n    } else\n        type = groupedTypes[OpTypeSampler].back();\n\n    return type->getResultId();\n}\n\nId Builder::makeAccelerationStructureType()\n{\n    Instruction* type;\n    if (!acceleration_structure_type)\n    {\n        type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR);\n        acceleration_structure_type = type;\n        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n        module.mapInstruction(type);\n    } else\n        type = acceleration_structure_type;\n\n    return type->getResultId();\n}\n\nId Builder::makeRayQueryType()\n{\n    Instruction* type;\n    if (!ray_query_type)\n    {\n        type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryKHR);\n        ray_query_type = type;\n        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n        module.mapInstruction(type);\n    } else\n        type = ray_query_type;\n\n    return type->getResultId();\n}\n\nId Builder::makeHitObjectNVType()\n{\n    Instruction *type;\n    if (!hit_object_nv_type)\n    {\n        type = new Instruction(getUniqueId(), NoType, OpTypeHitObjectNV);\n        hit_object_nv_type = type;\n        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n        module.mapInstruction(type);\n    } else\n        type = hit_object_nv_type;\n\n    return type->getResultId();\n}\n\nId Builder::makePointer(StorageClass storageClass, Id pointee)\n{\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {\n        type = groupedTypes[OpTypePointer][t];\n        if (type->getImmediateOperand(0) == (unsigned)storageClass &&\n            type->getIdOperand(1) == pointee)\n            return type->getResultId();\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypePointer);\n    type->addImmediateOperand(storageClass);\n    type->addIdOperand(pointee);\n    groupedTypes[OpTypePointer].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    return type->getResultId();\n}\n\nId Builder::makeIntegerType(int width, bool hasSign)\n{\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) {\n        type = groupedTypes[OpTypeInt][t];\n        if (type->getImmediateOperand(0) == (unsigned)width &&\n            type->getImmediateOperand(1) == (hasSign ? 1u : 0u))\n            return type->getResultId();\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeInt);\n    type->addImmediateOperand(width);\n    type->addImmediateOperand(hasSign ? 1 : 0);\n    groupedTypes[OpTypeInt].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    // deal with capabilities\n    switch (width) {\n    case 8:\n        addCapability(CapabilityInt8);\n        break;\n    case 16:\n        addCapability(CapabilityInt16);\n        break;\n    case 64:\n        addCapability(CapabilityInt64);\n        break;\n    default:\n        break;\n    }\n\n    return type->getResultId();\n}\n\nId Builder::makeFloatType(int width, int encoding)\n{\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) {\n        type = groupedTypes[OpTypeFloat][t];\n        if (encoding >= 0) {\n            if (type->getNumOperands() == 2 &&\n                type->getImmediateOperand(0) == (unsigned)width &&\n                type->getImmediateOperand(1) == (unsigned)encoding) {\n                return type->getResultId();\n            }\n        } else if (type->getNumOperands() == 1 && type->getImmediateOperand(0) == (unsigned)width) {\n            return type->getResultId();\n        }\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeFloat);\n    type->addImmediateOperand(width);\n    if (encoding >= 0)\n        type->addImmediateOperand(encoding);\n    groupedTypes[OpTypeFloat].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    // deal with capabilities\n    switch (width) {\n    case 8:\n        if (encoding >= 0) {\n            // Ignore encoding -1 case. It's not legal SPIR-V, only used by hack path.\n            addExtension(\"SPV_EXT_float8\");\n            addCapability(CapabilityFloat8EXT);\n            addCapability(CapabilityFloat8CooperativeMatrixEXT);\n        }\n        break;\n    case 16:\n        addCapability(CapabilityFloat16);\n        break;\n    case 64:\n        addCapability(CapabilityFloat64);\n        break;\n    default:\n        break;\n    }\n\n    return type->getResultId();\n}\n\nId Builder::makeCooperativeMatrixType(spv::Id scalar_type, spv::Id rows, spv::Id cols, spv::Id use)\n{\n\tInstruction* type;\n\tfor (int t = 0; t < (int)coopmatTypes.size(); ++t) {\n\t\ttype = coopmatTypes[t];\n\t\tif (type->getIdOperand(0) == scalar_type &&\n\t\t    type->getIdOperand(2) == rows &&\n\t\t    type->getIdOperand(3) == cols &&\n\t\t    type->getIdOperand(4) == use)\n\t\t\treturn type->getResultId();\n\t}\n\n\taddExtension(\"SPV_KHR_cooperative_matrix\");\n\taddCapability(spv::CapabilityCooperativeMatrixKHR);\n\ttype = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixKHR);\n\ttype->addIdOperand(scalar_type);\n\ttype->addIdOperand(makeUintConstant(spv::ScopeSubgroup));\n\ttype->addIdOperand(rows);\n\ttype->addIdOperand(cols);\n\ttype->addIdOperand(use);\n\tcoopmatTypes.push_back(type);\n\tconstantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n\tmodule.mapInstruction(type);\n\n\treturn type->getResultId();\n}\n\n// Make a struct without checking for duplication.\n// See makeStructResultType() for non-decorated structs\n// needed as the result of some instructions, which does\n// check for duplicates.\nId Builder::makeStructType(const dxil_spv::Vector<Id>& members, const char* name)\n{\n    // Don't look for previous one, because in the general case,\n    // structs can be duplicated except for decorations.\n\n    // not found, make it\n    Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeStruct);\n    for (int op = 0; op < (int)members.size(); ++op)\n        type->addIdOperand(members[op]);\n    groupedTypes[OpTypeStruct].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n    addName(type->getResultId(), name);\n\n    return type->getResultId();\n}\n\n// Make a struct for the simple results of several instructions,\n// checking for duplication.\nId Builder::makeStructResultType(Id type0, Id type1)\n{\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeStruct].size(); ++t) {\n        type = groupedTypes[OpTypeStruct][t];\n        if (type->getNumOperands() != 2)\n            continue;\n        if (type->getIdOperand(0) != type0 ||\n            type->getIdOperand(1) != type1)\n            continue;\n        return type->getResultId();\n    }\n\n    // not found, make it\n    dxil_spv::Vector<spv::Id> members;\n    members.push_back(type0);\n    members.push_back(type1);\n\n    return makeStructType(members, \"ResType\");\n}\n\nId Builder::makeVectorType(Id component, int size)\n{\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeVector].size(); ++t) {\n        type = groupedTypes[OpTypeVector][t];\n        if (type->getIdOperand(0) == component &&\n            type->getImmediateOperand(1) == (unsigned)size)\n            return type->getResultId();\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeVector);\n    type->addIdOperand(component);\n    type->addImmediateOperand(size);\n    groupedTypes[OpTypeVector].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    return type->getResultId();\n}\n\nId Builder::makeMatrixType(Id component, int cols, int rows)\n{\n    assert(cols <= maxMatrixSize && rows <= maxMatrixSize);\n\n    Id column = makeVectorType(component, rows);\n\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeMatrix].size(); ++t) {\n        type = groupedTypes[OpTypeMatrix][t];\n        if (type->getIdOperand(0) == column &&\n            type->getImmediateOperand(1) == (unsigned)cols)\n            return type->getResultId();\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeMatrix);\n    type->addIdOperand(column);\n    type->addImmediateOperand(cols);\n    groupedTypes[OpTypeMatrix].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    return type->getResultId();\n}\n\n// TODO: performance: track arrays per stride\n// If a stride is supplied (non-zero) make an array.\n// If no stride (0), reuse previous array types.\n// 'size' is an Id of a constant or specialization constant of the array size\nId Builder::makeArrayType(Id element, Id sizeId, int stride)\n{\n    Instruction* type;\n    if (stride == 0) {\n        // try to find existing type\n        for (int t = 0; t < (int)groupedTypes[OpTypeArray].size(); ++t) {\n            type = groupedTypes[OpTypeArray][t];\n            if (type->getIdOperand(0) == element &&\n                type->getIdOperand(1) == sizeId &&\n                !hasDecoration(type->getResultId(), spv::DecorationArrayStride))\n                return type->getResultId();\n        }\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeArray);\n    type->addIdOperand(element);\n    type->addIdOperand(sizeId);\n    groupedTypes[OpTypeArray].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    return type->getResultId();\n}\n\nId Builder::makeRuntimeArray(Id element)\n{\n    Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeRuntimeArray);\n    type->addIdOperand(element);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    return type->getResultId();\n}\n\nId Builder::makeFunctionType(Id returnType, const dxil_spv::Vector<Id>& paramTypes)\n{\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeFunction].size(); ++t) {\n        type = groupedTypes[OpTypeFunction][t];\n        if (type->getIdOperand(0) != returnType || (int)paramTypes.size() != type->getNumOperands() - 1)\n            continue;\n        bool mismatch = false;\n        for (int p = 0; p < (int)paramTypes.size(); ++p) {\n            if (paramTypes[p] != type->getIdOperand(p + 1)) {\n                mismatch = true;\n                break;\n            }\n        }\n        if (! mismatch)\n            return type->getResultId();\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeFunction);\n    type->addIdOperand(returnType);\n    for (int p = 0; p < (int)paramTypes.size(); ++p)\n        type->addIdOperand(paramTypes[p]);\n    groupedTypes[OpTypeFunction].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    return type->getResultId();\n}\n\nId Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format)\n{\n    assert(sampled == 1 || sampled == 2);\n\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeImage].size(); ++t) {\n        type = groupedTypes[OpTypeImage][t];\n        if (type->getIdOperand(0) == sampledType &&\n            type->getImmediateOperand(1) == (unsigned int)dim &&\n            type->getImmediateOperand(2) == (  depth ? 1u : 0u) &&\n            type->getImmediateOperand(3) == (arrayed ? 1u : 0u) &&\n            type->getImmediateOperand(4) == (     ms ? 1u : 0u) &&\n            type->getImmediateOperand(5) == sampled &&\n            type->getImmediateOperand(6) == (unsigned int)format)\n            return type->getResultId();\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeImage);\n    type->addIdOperand(sampledType);\n    type->addImmediateOperand(   dim);\n    type->addImmediateOperand(  depth ? 1 : 0);\n    type->addImmediateOperand(arrayed ? 1 : 0);\n    type->addImmediateOperand(     ms ? 1 : 0);\n    type->addImmediateOperand(sampled);\n    type->addImmediateOperand((unsigned int)format);\n\n    groupedTypes[OpTypeImage].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    // deal with capabilities\n    switch (dim) {\n    case DimBuffer:\n        if (sampled == 1)\n            addCapability(CapabilitySampledBuffer);\n        else\n            addCapability(CapabilityImageBuffer);\n        break;\n    case Dim1D:\n        if (sampled == 1)\n            addCapability(CapabilitySampled1D);\n        else\n            addCapability(CapabilityImage1D);\n        break;\n    case DimCube:\n        if (arrayed) {\n            if (sampled == 1)\n                addCapability(CapabilitySampledCubeArray);\n            else\n                addCapability(CapabilityImageCubeArray);\n        }\n        break;\n    case DimRect:\n        if (sampled == 1)\n            addCapability(CapabilitySampledRect);\n        else\n            addCapability(CapabilityImageRect);\n        break;\n    case DimSubpassData:\n        addCapability(CapabilityInputAttachment);\n        break;\n    default:\n        break;\n    }\n\n    if (ms) {\n        if (sampled == 2) {\n            // Images used with subpass data are not storage\n            // images, so don't require the capability for them.\n            if (dim != Dim::DimSubpassData)\n                addCapability(CapabilityStorageImageMultisample);\n            if (arrayed)\n                addCapability(CapabilityImageMSArray);\n        }\n    }\n\n    return type->getResultId();\n}\n\nId Builder::makeSampledImageType(Id imageType)\n{\n    // try to find it\n    Instruction* type;\n    for (int t = 0; t < (int)groupedTypes[OpTypeSampledImage].size(); ++t) {\n        type = groupedTypes[OpTypeSampledImage][t];\n        if (type->getIdOperand(0) == imageType)\n            return type->getResultId();\n    }\n\n    // not found, make it\n    type = new Instruction(getUniqueId(), NoType, OpTypeSampledImage);\n    type->addIdOperand(imageType);\n\n    groupedTypes[OpTypeSampledImage].push_back(type);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));\n    module.mapInstruction(type);\n\n    return type->getResultId();\n}\n\nId Builder::getDerefTypeId(Id resultId) const\n{\n    Id typeId = getTypeId(resultId);\n    assert(isPointerType(typeId));\n\n    return module.getInstruction(typeId)->getImmediateOperand(1);\n}\n\nOp Builder::getMostBasicTypeClass(Id typeId) const\n{\n    Instruction* instr = module.getInstruction(typeId);\n\n    Op typeClass = instr->getOpCode();\n    switch (typeClass)\n    {\n    case OpTypeVoid:\n    case OpTypeBool:\n    case OpTypeInt:\n    case OpTypeFloat:\n    case OpTypeStruct:\n        return typeClass;\n    case OpTypeVector:\n    case OpTypeMatrix:\n    case OpTypeArray:\n    case OpTypeRuntimeArray:\n        return getMostBasicTypeClass(instr->getIdOperand(0));\n    case OpTypePointer:\n        return getMostBasicTypeClass(instr->getIdOperand(1));\n    default:\n        assert(0);\n        return OpTypeFloat;\n    }\n}\n\nint Builder::getNumTypeConstituents(Id typeId) const\n{\n    Instruction* instr = module.getInstruction(typeId);\n\n    switch (instr->getOpCode())\n    {\n    case OpTypeBool:\n    case OpTypeInt:\n    case OpTypeFloat:\n        return 1;\n    case OpTypeVector:\n    case OpTypeMatrix:\n        return instr->getImmediateOperand(1);\n    case OpTypeArray:\n    {\n        Id lengthId = instr->getImmediateOperand(1);\n        return module.getInstruction(lengthId)->getImmediateOperand(0);\n    }\n    case OpTypeStruct:\n        return instr->getNumOperands();\n    default:\n        assert(0);\n        return 1;\n    }\n}\n\n// Return the lowest-level type of scalar that an homogeneous composite is made out of.\n// Typically, this is just to find out if something is made out of ints or floats.\n// However, it includes returning a structure, if say, it is an array of structure.\nId Builder::getScalarTypeId(Id typeId) const\n{\n    Instruction* instr = module.getInstruction(typeId);\n\n    Op typeClass = instr->getOpCode();\n    switch (typeClass)\n    {\n    case OpTypeVoid:\n    case OpTypeBool:\n    case OpTypeInt:\n    case OpTypeFloat:\n    case OpTypeStruct:\n        return instr->getResultId();\n    case OpTypeVector:\n    case OpTypeMatrix:\n    case OpTypeArray:\n    case OpTypeRuntimeArray:\n    case OpTypePointer:\n        return getScalarTypeId(getContainedTypeId(typeId));\n    default:\n        assert(0);\n        return NoResult;\n    }\n}\n\n// Return the type of 'member' of a composite.\nId Builder::getContainedTypeId(Id typeId, int member) const\n{\n    Instruction* instr = module.getInstruction(typeId);\n\n    Op typeClass = instr->getOpCode();\n    switch (typeClass)\n    {\n    case OpTypeVector:\n    case OpTypeMatrix:\n    case OpTypeArray:\n    case OpTypeRuntimeArray:\n    case OpTypeCooperativeMatrixKHR:\n        return instr->getIdOperand(0);\n    case OpTypePointer:\n        return instr->getIdOperand(1);\n    case OpTypeStruct:\n        return instr->getIdOperand(member);\n    default:\n        assert(0);\n        return NoResult;\n    }\n}\n\n// Return the immediately contained type of a given composite type.\nId Builder::getContainedTypeId(Id typeId) const\n{\n    return getContainedTypeId(typeId, 0);\n}\n\n// See if a scalar constant of this type has already been created, so it\n// can be reused rather than duplicated.  (Required by the specification).\nId Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const\n{\n    Instruction* constant;\n    for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {\n        constant = groupedConstants[typeClass][i];\n        if (constant->getOpCode() == opcode &&\n            constant->getTypeId() == typeId &&\n            constant->getImmediateOperand(0) == value)\n            return constant->getResultId();\n    }\n\n    return 0;\n}\n\n// Version of findScalarConstant (see above) for scalars that take two operands (e.g. a 'double' or 'int64').\nId Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const\n{\n    Instruction* constant;\n    for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {\n        constant = groupedConstants[typeClass][i];\n        if (constant->getOpCode() == opcode &&\n            constant->getTypeId() == typeId &&\n            constant->getImmediateOperand(0) == v1 &&\n            constant->getImmediateOperand(1) == v2)\n            return constant->getResultId();\n    }\n\n    return 0;\n}\n\n// Return true if consuming 'opcode' means consuming a constant.\n// \"constant\" here means after final transform to executable code,\n// the value consumed will be a constant, so includes specialization.\nbool Builder::isConstantOpCode(Op opcode) const\n{\n    switch (opcode) {\n    case OpUndef:\n    case OpConstantTrue:\n    case OpConstantFalse:\n    case OpConstant:\n    case OpConstantComposite:\n    case OpConstantSampler:\n    case OpConstantNull:\n    case OpSpecConstantTrue:\n    case OpSpecConstantFalse:\n    case OpSpecConstant:\n    case OpSpecConstantComposite:\n    case OpSpecConstantOp:\n        return true;\n    default:\n        return false;\n    }\n}\n\n// Return true if consuming 'opcode' means consuming a specialization constant.\nbool Builder::isSpecConstantOpCode(Op opcode) const\n{\n    switch (opcode) {\n    case OpSpecConstantTrue:\n    case OpSpecConstantFalse:\n    case OpSpecConstant:\n    case OpSpecConstantComposite:\n    case OpSpecConstantOp:\n        return true;\n    default:\n        return false;\n    }\n}\n\nId Builder::makeNullConstant(Id typeId)\n{\n    Instruction* c = new Instruction(getUniqueId(), typeId, OpConstantNull);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\nId Builder::makeBoolConstant(bool b, bool specConstant)\n{\n    Id typeId = makeBoolType();\n    Instruction* constant;\n    Op opcode = specConstant ? (b ? OpSpecConstantTrue : OpSpecConstantFalse) : (b ? OpConstantTrue : OpConstantFalse);\n\n    // See if we already made it. Applies only to regular constants, because specialization constants\n    // must remain distinct for the purpose of applying a SpecId decoration.\n    if (! specConstant) {\n        Id existing = 0;\n        for (int i = 0; i < (int)groupedConstants[OpTypeBool].size(); ++i) {\n            constant = groupedConstants[OpTypeBool][i];\n            if (constant->getTypeId() == typeId && constant->getOpCode() == opcode)\n                existing = constant->getResultId();\n        }\n\n        if (existing)\n            return existing;\n    }\n\n    // Make it\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    groupedConstants[OpTypeBool].push_back(c);\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\nId Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)\n{\n    Op opcode = specConstant ? OpSpecConstant : OpConstant;\n\n    // See if we already made it. Applies only to regular constants, because specialization constants\n    // must remain distinct for the purpose of applying a SpecId decoration.\n    if (! specConstant) {\n        Id existing = findScalarConstant(OpTypeInt, opcode, typeId, value);\n        if (existing)\n            return existing;\n    }\n\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    c->addImmediateOperand(value);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    groupedConstants[OpTypeInt].push_back(c);\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\nId Builder::makeInt64Constant(Id typeId, unsigned long long value, bool specConstant)\n{\n    Op opcode = specConstant ? OpSpecConstant : OpConstant;\n\n    unsigned op1 = value & 0xFFFFFFFF;\n    unsigned op2 = value >> 32;\n\n    // See if we already made it. Applies only to regular constants, because specialization constants\n    // must remain distinct for the purpose of applying a SpecId decoration.\n    if (! specConstant) {\n        Id existing = findScalarConstant(OpTypeInt, opcode, typeId, op1, op2);\n        if (existing)\n            return existing;\n    }\n\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    c->addImmediateOperand(op1);\n    c->addImmediateOperand(op2);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    groupedConstants[OpTypeInt].push_back(c);\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\nId Builder::makeFloatConstant(float f, bool specConstant)\n{\n    Op opcode = specConstant ? OpSpecConstant : OpConstant;\n    Id typeId = makeFloatType(32);\n    union { float fl; unsigned int ui; } u;\n    u.fl = f;\n    unsigned value = u.ui;\n\n    // See if we already made it. Applies only to regular constants, because specialization constants\n    // must remain distinct for the purpose of applying a SpecId decoration.\n    if (! specConstant) {\n        Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);\n        if (existing)\n            return existing;\n    }\n\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    c->addImmediateOperand(value);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    groupedConstants[OpTypeFloat].push_back(c);\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\nId Builder::makeDoubleConstant(double d, bool specConstant)\n{\n    Op opcode = specConstant ? OpSpecConstant : OpConstant;\n    Id typeId = makeFloatType(64);\n    union { double db; unsigned long long ull; } u;\n    u.db = d;\n    unsigned long long value = u.ull;\n    unsigned op1 = value & 0xFFFFFFFF;\n    unsigned op2 = value >> 32;\n\n    // See if we already made it. Applies only to regular constants, because specialization constants\n    // must remain distinct for the purpose of applying a SpecId decoration.\n    if (! specConstant) {\n        Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, op1, op2);\n        if (existing)\n            return existing;\n    }\n\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    c->addImmediateOperand(op1);\n    c->addImmediateOperand(op2);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    groupedConstants[OpTypeFloat].push_back(c);\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\n#ifdef AMD_EXTENSIONS\nId Builder::makeFloat16Constant(uint16_t f16, bool specConstant)\n{\n    Op opcode = specConstant ? OpSpecConstant : OpConstant;\n    Id typeId = makeFloatType(16);\n\n    unsigned value = f16;\n\n    // See if we already made it. Applies only to regular constants, because specialization constants\n    // must remain distinct for the purpose of applying a SpecId decoration.\n    if (!specConstant) {\n        Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);\n        if (existing)\n            return existing;\n    }\n\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    c->addImmediateOperand(value);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    groupedConstants[OpTypeFloat].push_back(c);\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\nId Builder::makeFloat8Constant(uint8_t f8, int encoding, bool specConstant)\n{\n    Op opcode = specConstant ? OpSpecConstant : OpConstant;\n    Id typeId = makeFloatType(8, encoding);\n\n    unsigned value = f8;\n\n    // See if we already made it. Applies only to regular constants, because specialization constants\n    // must remain distinct for the purpose of applying a SpecId decoration.\n    if (!specConstant) {\n        Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);\n        if (existing)\n            return existing;\n    }\n\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    c->addImmediateOperand(value);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n    groupedConstants[OpTypeFloat].push_back(c);\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n#endif\n\nId Builder::findCompositeConstant(Op typeClass, const dxil_spv::Vector<Id>& comps) const\n{\n    Instruction* constant = 0;\n    bool found = false;\n\n    if (typeClass == spv::OpTypeCooperativeMatrixKHR) {\n        for (int i = 0; i < (int)coopmatConstants.size() && !found; ++i) {\n            constant = coopmatConstants[i];\n            if (constant->getIdOperand(0) == comps[0])\n                found = true;\n        }\n    } else {\n        for (int i = 0; i < (int) groupedConstants[typeClass].size(); ++i) {\n            constant = groupedConstants[typeClass][i];\n\n            // same shape?\n            if (constant->getNumOperands() != (int) comps.size())\n                continue;\n\n            // same contents?\n            bool mismatch = false;\n            for (int op = 0; op < constant->getNumOperands(); ++op)\n            {\n                if (constant->getIdOperand(op) != comps[op])\n                {\n                    mismatch = true;\n                    break;\n                }\n            }\n            if (!mismatch)\n            {\n                found = true;\n                break;\n            }\n        }\n    }\n\n    return found ? constant->getResultId() : NoResult;\n}\n\n// Comments in header\nId Builder::makeCompositeConstant(Id typeId, const dxil_spv::Vector<Id>& members, bool specConstant)\n{\n    Op opcode = specConstant ? OpSpecConstantComposite : OpConstantComposite;\n    assert(typeId);\n    Op typeClass = getTypeClass(typeId);\n\n    switch (typeClass) {\n    case OpTypeVector:\n    case OpTypeArray:\n    case OpTypeStruct:\n    case OpTypeMatrix:\n    case OpTypeCooperativeMatrixKHR:\n        break;\n    default:\n        assert(0);\n        return makeFloatConstant(0.0);\n    }\n\n    if (! specConstant) {\n        Id existing = findCompositeConstant(typeClass, members);\n        if (existing)\n            return existing;\n    }\n\n    Instruction* c = new Instruction(getUniqueId(), typeId, opcode);\n    for (int op = 0; op < (int)members.size(); ++op)\n        c->addIdOperand(members[op]);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));\n\n    if (typeClass == OpTypeCooperativeMatrixKHR)\n        coopmatConstants.push_back(c);\n    else\n        groupedConstants[typeClass].push_back(c);\n\n    module.mapInstruction(c);\n\n    return c->getResultId();\n}\n\nInstruction* Builder::addEntryPoint(ExecutionModel model, Function* function, const char* name)\n{\n    Instruction* entryPoint = new Instruction(OpEntryPoint);\n    entryPoint->addImmediateOperand(model);\n    entryPoint->addIdOperand(function->getId());\n    entryPoint->addStringOperand(name);\n\n    entryPoints.push_back(std::unique_ptr<Instruction>(entryPoint));\n\n    return entryPoint;\n}\n\n// Currently relying on the fact that all 'value' of interest are small non-negative values.\nvoid Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int value1, int value2, int value3)\n{\n    for (auto &execMode : executionModes)\n    {\n        // For execution modes with arguments, we don't have an issue with duplication.\n        if (execMode->getIdOperand(0) == entryPoint->getId() &&\n                execMode->getImmediateOperand(1) == mode &&\n                execMode->getNumOperands() == 2)\n            return;\n    }\n\n    Instruction* instr = new Instruction(OpExecutionMode);\n    instr->addIdOperand(entryPoint->getId());\n    instr->addImmediateOperand(mode);\n    if (value1 >= 0)\n        instr->addImmediateOperand(value1);\n    if (value2 >= 0)\n        instr->addImmediateOperand(value2);\n    if (value3 >= 0)\n        instr->addImmediateOperand(value3);\n\n    executionModes.push_back(std::unique_ptr<Instruction>(instr));\n}\n\nvoid Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, spv::Id id1, spv::Id id2, spv::Id id3)\n{\n    Instruction* instr = new Instruction(OpExecutionModeId);\n    instr->addIdOperand(entryPoint->getId());\n    instr->addImmediateOperand(mode);\n    if (id1)\n        instr->addIdOperand(id1);\n    if (id2)\n        instr->addIdOperand(id2);\n    if (id3)\n        instr->addIdOperand(id3);\n\n    executionModes.push_back(std::unique_ptr<Instruction>(instr));\n}\n\nvoid Builder::addName(Id id, const char* string)\n{\n    Instruction* name = new Instruction(OpName);\n    name->addIdOperand(id);\n    name->addStringOperand(string);\n\n    names.push_back(std::unique_ptr<Instruction>(name));\n}\n\nvoid Builder::addMemberName(Id id, int memberNumber, const char* string)\n{\n    Instruction* name = new Instruction(OpMemberName);\n    name->addIdOperand(id);\n    name->addImmediateOperand(memberNumber);\n    name->addStringOperand(string);\n\n    names.push_back(std::unique_ptr<Instruction>(name));\n}\n\nvoid Builder::addDecoration(Id id, Decoration decoration, int num)\n{\n    if (decoration == spv::DecorationMax)\n        return;\n    Instruction* dec = new Instruction(OpDecorate);\n    dec->addIdOperand(id);\n    dec->addImmediateOperand(decoration);\n    if (num >= 0)\n        dec->addImmediateOperand(num);\n\n    decorations.push_back(std::unique_ptr<Instruction>(dec));\n}\n\nvoid Builder::removeDecorations(const dxil_spv::UnorderedSet<spv::Id> &ids)\n{\n    decorations.erase(std::remove_if(decorations.begin(), decorations.end(),\n                [&](const std::unique_ptr<Instruction> &inst) {\n                    return inst->getOpCode() == OpDecorate && ids.count(inst->getIdOperand(0)) != 0;\n                }), decorations.end());\n}\n\nbool Builder::hasDecoration(spv::Id id, spv::Decoration decoration) const\n{\n    for (auto &dec : decorations)\n        if (dec->getIdOperand(0) == id && dec->getImmediateOperand(1) == decoration)\n            return true;\n    return false;\n}\n\nvoid Builder::addUniqueDecoration(Id id, Decoration decoration, int num)\n{\n    for (auto &dec : decorations)\n    {\n        if (dec->getIdOperand(0) != id || dec->getImmediateOperand(1) != decoration)\n            continue;\n\n        // Can have same decoration but different literal parameter.\n        if (num < 0 && dec->getNumOperands() == 2)\n            return;\n        if (num >= 0 && dec->getImmediateOperand(2) == uint32_t(num))\n            return;\n    }\n\n    addDecoration(id, decoration, num);\n}\n\nvoid Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)\n{\n    Instruction* dec = new Instruction(OpMemberDecorate);\n    dec->addIdOperand(id);\n    dec->addImmediateOperand(member);\n    dec->addImmediateOperand(decoration);\n    if (num >= 0)\n        dec->addImmediateOperand(num);\n\n    decorations.push_back(std::unique_ptr<Instruction>(dec));\n}\n\n// Comments in header\nFunction* Builder::makeEntryPoint(const char* entryPoint)\n{\n    assert(! entryPointFunction);\n\n    Block* entry;\n    dxil_spv::Vector<Id> params;\n    dxil_spv::Vector<dxil_spv::Vector<Decoration>> decorations;\n\n    entryPointFunction = makeFunctionEntry(NoPrecision, makeVoidType(), entryPoint, params, decorations, &entry);\n\n    return entryPointFunction;\n}\n\n// Comments in header\nFunction* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,\n                                     const dxil_spv::Vector<Id>& paramTypes, const dxil_spv::Vector<dxil_spv::Vector<Decoration>>& decorations, Block **entry)\n{\n    // Make the function and initial instructions in it\n    Id typeId = makeFunctionType(returnType, paramTypes);\n    Id firstParamId = paramTypes.size() == 0 ? 0 : getUniqueIds((int)paramTypes.size());\n    Function* function = new Function(getUniqueId(), returnType, typeId, firstParamId, module);\n\n    // Set up the precisions\n    setPrecision(function->getId(), precision);\n    for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {\n        for (int d = 0; d < (int)decorations[p].size(); ++d)\n            addDecoration(firstParamId + p, decorations[p][d]);\n    }\n\n    // CFG\n    if (entry) {\n        *entry = new Block(getUniqueId(), *function);\n        function->addBlock(*entry);\n        setBuildPoint(*entry);\n    }\n\n    if (name)\n        addName(function->getId(), name);\n\n    functions.push_back(std::unique_ptr<Function>(function));\n\n    return function;\n}\n\n// Comments in header\nvoid Builder::makeReturn(bool implicit, Id retVal)\n{\n    if (retVal) {\n        Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);\n        inst->addIdOperand(retVal);\n        buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));\n    } else\n        buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(NoResult, NoType, OpReturn)));\n\n    if (! implicit)\n        createAndSetNoPredecessorBlock(\"post-return\");\n}\n\n// Comments in header\nvoid Builder::leaveFunction()\n{\n    Block* block = buildPoint;\n    Function& function = buildPoint->getParent();\n    assert(block);\n\n    // If our function did not contain a return, add a return void now.\n    if (! block->isTerminated()) {\n        if (function.getReturnType() == makeVoidType())\n            makeReturn(true);\n        else {\n            makeReturn(true, createUndefined(function.getReturnType()));\n        }\n    }\n}\n\n// Comments in header\nvoid Builder::makeDiscard()\n{\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(OpKill)));\n    createAndSetNoPredecessorBlock(\"post-discard\");\n}\n\n// Comments in header\nId Builder::createVariable(StorageClass storageClass, Id type, const char* name)\n{\n    return createVariableWithInitializer(storageClass, type, 0, name);\n}\n\nId Builder::createVariableWithInitializer(StorageClass storageClass, Id type, Id initializer, const char* name)\n{\n    Id pointerType = makePointer(storageClass, type);\n    Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);\n    inst->addImmediateOperand(storageClass);\n    if (initializer)\n        inst->addIdOperand(initializer);\n\n    switch (storageClass) {\n    case StorageClassFunction:\n        // Validation rules require the declaration in the entry block\n        buildPoint->getParent().addLocalVariable(std::unique_ptr<Instruction>(inst));\n        break;\n\n    default:\n        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));\n        module.mapInstruction(inst);\n        break;\n    }\n\n    if (name)\n        addName(inst->getResultId(), name);\n\n    return inst->getResultId();\n}\n\n// Comments in header\nId Builder::createUndefined(Id type)\n{\n  Instruction* inst = new Instruction(getUniqueId(), type, OpUndef);\n  buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));\n  module.mapInstruction(inst);\n  return inst->getResultId();\n}\n\nId Builder::createUndefinedConstant(Id type)\n{\n  Instruction* inst = new Instruction(getUniqueId(), type, OpUndef);\n  constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));\n  module.mapInstruction(inst);\n  return inst->getResultId();\n}\n\n// Comments in header\nvoid Builder::createStore(Id rValue, Id lValue)\n{\n    Instruction* store = new Instruction(OpStore);\n    store->addIdOperand(lValue);\n    store->addIdOperand(rValue);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(store));\n}\n\n// Comments in header\nId Builder::createLoad(Id lValue)\n{\n    Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);\n    load->addIdOperand(lValue);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(load));\n\n    return load->getResultId();\n}\n\n// Comments in header\nId Builder::createAccessChain(StorageClass storageClass, Id base, const dxil_spv::Vector<Id>& offsets)\n{\n    // Figure out the final resulting type.\n    spv::Id typeId = getTypeId(base);\n    assert(isPointerType(typeId) && offsets.size() > 0);\n    typeId = getContainedTypeId(typeId);\n    for (int i = 0; i < (int)offsets.size(); ++i) {\n        if (isStructType(typeId)) {\n            assert(isConstantScalar(offsets[i]));\n            typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));\n        } else\n            typeId = getContainedTypeId(typeId, offsets[i]);\n    }\n    typeId = makePointer(storageClass, typeId);\n\n    // Make the instruction\n    Instruction* chain = new Instruction(getUniqueId(), typeId, OpAccessChain);\n    chain->addIdOperand(base);\n    for (int i = 0; i < (int)offsets.size(); ++i)\n        chain->addIdOperand(offsets[i]);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(chain));\n\n    return chain->getResultId();\n}\n\nId Builder::createArrayLength(Id base, unsigned int member)\n{\n    spv::Id intType = makeIntType(32);\n    Instruction* length = new Instruction(getUniqueId(), intType, OpArrayLength);\n    length->addIdOperand(base);\n    length->addImmediateOperand(member);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(length));\n\n    return length->getResultId();\n}\n\nId Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)\n{\n    // Generate code for spec constants if in spec constant operation\n    // generation mode.\n    if (generatingOpCodeForSpecConst) {\n        return createSpecConstantOp(OpCompositeExtract, typeId, dxil_spv::Vector<Id>(1, composite), dxil_spv::Vector<Id>(1, index));\n    }\n    Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);\n    extract->addIdOperand(composite);\n    extract->addImmediateOperand(index);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));\n\n    return extract->getResultId();\n}\n\nId Builder::createCompositeExtract(Id composite, Id typeId, const dxil_spv::Vector<unsigned>& indexes)\n{\n    // Generate code for spec constants if in spec constant operation\n    // generation mode.\n    if (generatingOpCodeForSpecConst) {\n        return createSpecConstantOp(OpCompositeExtract, typeId, dxil_spv::Vector<Id>(1, composite), indexes);\n    }\n    Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);\n    extract->addIdOperand(composite);\n    for (int i = 0; i < (int)indexes.size(); ++i)\n        extract->addImmediateOperand(indexes[i]);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));\n\n    return extract->getResultId();\n}\n\nId Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned index)\n{\n    Instruction* insert = new Instruction(getUniqueId(), typeId, OpCompositeInsert);\n    insert->addIdOperand(object);\n    insert->addIdOperand(composite);\n    insert->addImmediateOperand(index);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));\n\n    return insert->getResultId();\n}\n\nId Builder::createCompositeInsert(Id object, Id composite, Id typeId, const dxil_spv::Vector<unsigned>& indexes)\n{\n    Instruction* insert = new Instruction(getUniqueId(), typeId, OpCompositeInsert);\n    insert->addIdOperand(object);\n    insert->addIdOperand(composite);\n    for (int i = 0; i < (int)indexes.size(); ++i)\n        insert->addImmediateOperand(indexes[i]);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));\n\n    return insert->getResultId();\n}\n\nId Builder::createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex)\n{\n    Instruction* extract = new Instruction(getUniqueId(), typeId, OpVectorExtractDynamic);\n    extract->addIdOperand(vector);\n    extract->addIdOperand(componentIndex);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));\n\n    return extract->getResultId();\n}\n\nId Builder::createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex)\n{\n    Instruction* insert = new Instruction(getUniqueId(), typeId, OpVectorInsertDynamic);\n    insert->addIdOperand(vector);\n    insert->addIdOperand(component);\n    insert->addIdOperand(componentIndex);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));\n\n    return insert->getResultId();\n}\n\n// An opcode that has no operands, no result id, and no type\nvoid Builder::createNoResultOp(Op opCode)\n{\n    Instruction* op = new Instruction(opCode);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n}\n\n// An opcode that has one operand, no result id, and no type\nvoid Builder::createNoResultOp(Op opCode, Id operand)\n{\n    Instruction* op = new Instruction(opCode);\n    op->addIdOperand(operand);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n}\n\n// An opcode that has one operand, no result id, and no type\nvoid Builder::createNoResultOp(Op opCode, const dxil_spv::Vector<Id>& operands)\n{\n    Instruction* op = new Instruction(opCode);\n    for (auto it = operands.cbegin(); it != operands.cend(); ++it)\n        op->addIdOperand(*it);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n}\n\nvoid Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics)\n{\n    Instruction* op = new Instruction(OpControlBarrier);\n    op->addImmediateOperand(makeUintConstant(execution));\n    op->addImmediateOperand(makeUintConstant(memory));\n    op->addImmediateOperand(makeUintConstant(semantics));\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n}\n\nvoid Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics)\n{\n    Instruction* op = new Instruction(OpMemoryBarrier);\n    op->addImmediateOperand(makeUintConstant(executionScope));\n    op->addImmediateOperand(makeUintConstant(memorySemantics));\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n}\n\n// An opcode that has one operands, a result id, and a type\nId Builder::createUnaryOp(Op opCode, Id typeId, Id operand)\n{\n    // Generate code for spec constants if in spec constant operation\n    // generation mode.\n    if (generatingOpCodeForSpecConst) {\n        return createSpecConstantOp(opCode, typeId, dxil_spv::Vector<Id>(1, operand), dxil_spv::Vector<Id>());\n    }\n    Instruction* op = new Instruction(getUniqueId(), typeId, opCode);\n    op->addIdOperand(operand);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n\n    return op->getResultId();\n}\n\nId Builder::createBinOp(Op opCode, Id typeId, Id left, Id right)\n{\n    // Generate code for spec constants if in spec constant operation\n    // generation mode.\n    if (generatingOpCodeForSpecConst) {\n        dxil_spv::Vector<Id> operands(2);\n        operands[0] = left; operands[1] = right;\n        return createSpecConstantOp(opCode, typeId, operands, dxil_spv::Vector<Id>());\n    }\n    Instruction* op = new Instruction(getUniqueId(), typeId, opCode);\n    op->addIdOperand(left);\n    op->addIdOperand(right);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n\n    return op->getResultId();\n}\n\nId Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3)\n{\n    // Generate code for spec constants if in spec constant operation\n    // generation mode.\n    if (generatingOpCodeForSpecConst) {\n        dxil_spv::Vector<Id> operands(3);\n        operands[0] = op1;\n        operands[1] = op2;\n        operands[2] = op3;\n        return createSpecConstantOp(\n            opCode, typeId, operands, dxil_spv::Vector<Id>());\n    }\n    Instruction* op = new Instruction(getUniqueId(), typeId, opCode);\n    op->addIdOperand(op1);\n    op->addIdOperand(op2);\n    op->addIdOperand(op3);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n\n    return op->getResultId();\n}\n\nId Builder::createOp(Op opCode, Id typeId, const dxil_spv::Vector<Id>& operands)\n{\n    Instruction* op = new Instruction(getUniqueId(), typeId, opCode);\n    for (auto it = operands.cbegin(); it != operands.cend(); ++it)\n        op->addIdOperand(*it);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n\n    return op->getResultId();\n}\n\nId Builder::createSpecConstantOp(Op opCode, Id typeId, const dxil_spv::Vector<Id>& operands, const dxil_spv::Vector<unsigned>& literals)\n{\n    Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);\n    op->addImmediateOperand((unsigned) opCode);\n    for (auto it = operands.cbegin(); it != operands.cend(); ++it)\n        op->addIdOperand(*it);\n    for (auto it = literals.cbegin(); it != literals.cend(); ++it)\n        op->addImmediateOperand(*it);\n    module.mapInstruction(op);\n    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(op));\n\n    return op->getResultId();\n}\n\nId Builder::createFunctionCall(spv::Function* function, const dxil_spv::Vector<spv::Id>& args)\n{\n    Instruction* op = new Instruction(getUniqueId(), function->getReturnType(), OpFunctionCall);\n    op->addIdOperand(function->getId());\n    for (int a = 0; a < (int)args.size(); ++a)\n        op->addIdOperand(args[a]);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n\n    return op->getResultId();\n}\n\n// Comments in header\nId Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, const dxil_spv::Vector<unsigned>& channels)\n{\n    if (channels.size() == 1)\n        return setPrecision(createCompositeExtract(source, typeId, channels.front()), precision);\n\n    if (generatingOpCodeForSpecConst) {\n        dxil_spv::Vector<Id> operands(2);\n        operands[0] = operands[1] = source;\n        return setPrecision(createSpecConstantOp(OpVectorShuffle, typeId, operands, channels), precision);\n    }\n    Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);\n    assert(isVector(source));\n    swizzle->addIdOperand(source);\n    swizzle->addIdOperand(source);\n    for (int i = 0; i < (int)channels.size(); ++i)\n        swizzle->addImmediateOperand(channels[i]);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(swizzle));\n\n    return setPrecision(swizzle->getResultId(), precision);\n}\n\n// Comments in header\nId Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const dxil_spv::Vector<unsigned>& channels)\n{\n    if (channels.size() == 1 && getNumComponents(source) == 1)\n        return createCompositeInsert(source, target, typeId, channels.front());\n\n    Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);\n    assert(isVector(target));\n    swizzle->addIdOperand(target);\n    if (accessChain.component != NoResult)\n        // For dynamic component selection, source does not involve in l-value swizzle\n        swizzle->addIdOperand(target);\n    else {\n        assert(getNumComponents(source) == (int)channels.size());\n        assert(isVector(source));\n        swizzle->addIdOperand(source);\n    }\n\n    // Set up an identity shuffle from the base value to the result value\n    unsigned int components[4];\n    int numTargetComponents = getNumComponents(target);\n    for (int i = 0; i < numTargetComponents; ++i)\n        components[i] = i;\n\n    // Punch in the l-value swizzle\n    for (int i = 0; i < (int)channels.size(); ++i) {\n        if (accessChain.component != NoResult)\n            components[i] = channels[i]; // Only shuffle the base value\n        else\n            components[channels[i]] = numTargetComponents + i;\n    }\n\n    // finish the instruction with these components selectors\n    for (int i = 0; i < numTargetComponents; ++i)\n        swizzle->addImmediateOperand(components[i]);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(swizzle));\n\n    return swizzle->getResultId();\n}\n\n// Comments in header\nvoid Builder::promoteScalar(Decoration precision, Id& left, Id& right)\n{\n    int direction = getNumComponents(right) - getNumComponents(left);\n\n    if (direction > 0)\n        left = smearScalar(precision, left, makeVectorType(getTypeId(left), getNumComponents(right)));\n    else if (direction < 0)\n        right = smearScalar(precision, right, makeVectorType(getTypeId(right), getNumComponents(left)));\n\n    return;\n}\n\n// Comments in header\nId Builder::smearScalar(Decoration precision, Id scalar, Id vectorType)\n{\n    assert(getNumComponents(scalar) == 1);\n    assert(getTypeId(scalar) == getScalarTypeId(vectorType));\n\n    int numComponents = getNumTypeComponents(vectorType);\n    if (numComponents == 1)\n        return scalar;\n\n    Instruction* smear = nullptr;\n    if (generatingOpCodeForSpecConst) {\n        auto members = dxil_spv::Vector<spv::Id>(numComponents, scalar);\n        // Sometime even in spec-constant-op mode, the temporary vector created by\n        // promoting a scalar might not be a spec constant. This should depend on\n        // the scalar.\n        // e.g.:\n        //  const vec2 spec_const_result = a_spec_const_vec2 + a_front_end_const_scalar;\n        // In such cases, the temporary vector created from a_front_end_const_scalar\n        // is not a spec constant vector, even though the binary operation node is marked\n        // as 'specConstant' and we are in spec-constant-op mode.\n        auto result_id = makeCompositeConstant(vectorType, members, isSpecConstant(scalar));\n        smear = module.getInstruction(result_id);\n    } else {\n        smear = new Instruction(getUniqueId(), vectorType, OpCompositeConstruct);\n        for (int c = 0; c < numComponents; ++c)\n            smear->addIdOperand(scalar);\n        buildPoint->addInstruction(std::unique_ptr<Instruction>(smear));\n    }\n\n    return setPrecision(smear->getResultId(), precision);\n}\n\n// Comments in header\nId Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const dxil_spv::Vector<Id>& args)\n{\n    Instruction* inst = new Instruction(getUniqueId(), resultType, OpExtInst);\n    inst->addIdOperand(builtins);\n    inst->addImmediateOperand(entryPoint);\n    for (int arg = 0; arg < (int)args.size(); ++arg)\n        inst->addIdOperand(args[arg]);\n\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));\n\n    return inst->getResultId();\n}\n\n// Accept all parameters needed to create a texture instruction.\n// Create the correct instruction based on the inputs, and make the call.\nId Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicitLod, const TextureParameters& parameters)\n{\n    static const int maxTextureArgs = 10;\n    Id texArgs[maxTextureArgs] = {};\n\n    //\n    // Set up the fixed arguments\n    //\n    int numArgs = 0;\n    bool explicitLod = false;\n    texArgs[numArgs++] = parameters.sampler;\n    texArgs[numArgs++] = parameters.coords;\n    if (parameters.Dref != NoResult)\n        texArgs[numArgs++] = parameters.Dref;\n    if (parameters.component != NoResult)\n        texArgs[numArgs++] = parameters.component;\n\n    //\n    // Set up the optional arguments\n    //\n    int optArgNum = numArgs;                        // track which operand, if it exists, is the mask of optional arguments\n    ++numArgs;                                      // speculatively make room for the mask operand\n    ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand\n    if (parameters.bias) {\n        mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);\n        texArgs[numArgs++] = parameters.bias;\n    }\n    if (parameters.lod) {\n        mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);\n        texArgs[numArgs++] = parameters.lod;\n        explicitLod = true;\n    } else if (parameters.gradX) {\n        mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);\n        texArgs[numArgs++] = parameters.gradX;\n        texArgs[numArgs++] = parameters.gradY;\n        explicitLod = true;\n    } else if (noImplicitLod && ! fetch && ! gather) {\n        // have to explicitly use lod of 0 if not allowed to have them be implicit, and\n        // we would otherwise be about to issue an implicit instruction\n        mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);\n        texArgs[numArgs++] = makeFloatConstant(0.0);\n        explicitLod = true;\n    }\n    if (parameters.offset) {\n        if (isConstant(parameters.offset))\n            mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetMask);\n        else {\n            addCapability(CapabilityImageGatherExtended);\n            mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask);\n        }\n        texArgs[numArgs++] = parameters.offset;\n    }\n    if (parameters.offsets) {\n        mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);\n        texArgs[numArgs++] = parameters.offsets;\n    }\n    if (parameters.sample) {\n        mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);\n        texArgs[numArgs++] = parameters.sample;\n    }\n    if (parameters.lodClamp) {\n        // capability if this bit is used\n        addCapability(CapabilityMinLod);\n\n        mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);\n        texArgs[numArgs++] = parameters.lodClamp;\n    }\n    if (mask == ImageOperandsMaskNone)\n        --numArgs;  // undo speculative reservation for the mask argument\n    else\n        texArgs[optArgNum] = mask;\n\n    //\n    // Set up the instruction\n    //\n    Op opCode = OpNop;  // All paths below need to set this\n    if (fetch) {\n        if (sparse)\n            opCode = OpImageSparseFetch;\n        else\n            opCode = OpImageFetch;\n    } else if (gather) {\n        if (parameters.Dref)\n            if (sparse)\n                opCode = OpImageSparseDrefGather;\n            else\n                opCode = OpImageDrefGather;\n        else\n            if (sparse)\n                opCode = OpImageSparseGather;\n            else\n                opCode = OpImageGather;\n    } else if (explicitLod) {\n        if (parameters.Dref) {\n            if (proj)\n                if (sparse)\n                    opCode = OpImageSparseSampleProjDrefExplicitLod;\n                else\n                    opCode = OpImageSampleProjDrefExplicitLod;\n            else\n                if (sparse)\n                    opCode = OpImageSparseSampleDrefExplicitLod;\n                else\n                    opCode = OpImageSampleDrefExplicitLod;\n        } else {\n            if (proj)\n                if (sparse)\n                    opCode = OpImageSparseSampleProjExplicitLod;\n                else\n                    opCode = OpImageSampleProjExplicitLod;\n            else\n                if (sparse)\n                    opCode = OpImageSparseSampleExplicitLod;\n                else\n                    opCode = OpImageSampleExplicitLod;\n        }\n    } else {\n        if (parameters.Dref) {\n            if (proj)\n                if (sparse)\n                    opCode = OpImageSparseSampleProjDrefImplicitLod;\n                else\n                    opCode = OpImageSampleProjDrefImplicitLod;\n            else\n                if (sparse)\n                    opCode = OpImageSparseSampleDrefImplicitLod;\n                else\n                    opCode = OpImageSampleDrefImplicitLod;\n        } else {\n            if (proj)\n                if (sparse)\n                    opCode = OpImageSparseSampleProjImplicitLod;\n                else\n                    opCode = OpImageSampleProjImplicitLod;\n            else\n                if (sparse)\n                    opCode = OpImageSparseSampleImplicitLod;\n                else\n                    opCode = OpImageSampleImplicitLod;\n        }\n    }\n\n    // See if the result type is expecting a smeared result.\n    // This happens when a legacy shadow*() call is made, which\n    // gets a vec4 back instead of a float.\n    Id smearedType = resultType;\n    if (! isScalarType(resultType)) {\n        switch (opCode) {\n        case OpImageSampleDrefImplicitLod:\n        case OpImageSampleDrefExplicitLod:\n        case OpImageSampleProjDrefImplicitLod:\n        case OpImageSampleProjDrefExplicitLod:\n            resultType = getScalarTypeId(resultType);\n            break;\n        default:\n            break;\n        }\n    }\n\n    Id typeId0 = 0;\n    Id typeId1 = 0;\n\n    if (sparse) {\n        typeId0 = resultType;\n        typeId1 = getDerefTypeId(parameters.texelOut);\n        resultType = makeStructResultType(typeId0, typeId1);\n    }\n\n    // Build the SPIR-V instruction\n    Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);\n    for (int op = 0; op < optArgNum; ++op)\n        textureInst->addIdOperand(texArgs[op]);\n    if (optArgNum < numArgs)\n        textureInst->addImmediateOperand(texArgs[optArgNum]);\n    for (int op = optArgNum + 1; op < numArgs; ++op)\n        textureInst->addIdOperand(texArgs[op]);\n    setPrecision(textureInst->getResultId(), precision);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(textureInst));\n\n    Id resultId = textureInst->getResultId();\n\n    if (sparse) {\n        // set capability\n        addCapability(CapabilitySparseResidency);\n\n        // Decode the return type that was a special structure\n        createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);\n        resultId = createCompositeExtract(resultId, typeId0, 0);\n        setPrecision(resultId, precision);\n    } else {\n        // When a smear is needed, do it, as per what was computed\n        // above when resultType was changed to a scalar type.\n        if (resultType != smearedType)\n            resultId = smearScalar(precision, resultId, smearedType);\n    }\n\n    return resultId;\n}\n\n// Comments in header\nId Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameters, bool isUnsignedResult)\n{\n    // All these need a capability\n    addCapability(CapabilityImageQuery);\n\n    // Figure out the result type\n    Id resultType = 0;\n    switch (opCode) {\n    case OpImageQuerySize:\n    case OpImageQuerySizeLod:\n    {\n        int numComponents = 0;\n        switch (getTypeDimensionality(getImageType(parameters.sampler))) {\n        case Dim1D:\n        case DimBuffer:\n            numComponents = 1;\n            break;\n        case Dim2D:\n        case DimCube:\n        case DimRect:\n        case DimSubpassData:\n            numComponents = 2;\n            break;\n        case Dim3D:\n            numComponents = 3;\n            break;\n\n        default:\n            assert(0);\n            break;\n        }\n        if (isArrayedImageType(getImageType(parameters.sampler)))\n            ++numComponents;\n\n        Id intType = isUnsignedResult ? makeUintType(32) : makeIntType(32);\n        if (numComponents == 1)\n            resultType = intType;\n        else\n            resultType = makeVectorType(intType, numComponents);\n\n        break;\n    }\n    case OpImageQueryLod:\n        resultType = makeVectorType(makeFloatType(32), 2);\n        break;\n    case OpImageQueryLevels:\n    case OpImageQuerySamples:\n        resultType = isUnsignedResult ? makeUintType(32) : makeIntType(32);\n        break;\n    default:\n        assert(0);\n        break;\n    }\n\n    Instruction* query = new Instruction(getUniqueId(), resultType, opCode);\n    query->addIdOperand(parameters.sampler);\n    if (parameters.coords)\n        query->addIdOperand(parameters.coords);\n    if (parameters.lod)\n        query->addIdOperand(parameters.lod);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(query));\n\n    return query->getResultId();\n}\n\n// External comments in header.\n// Operates recursively to visit the composite's hierarchy.\nId Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, bool equal)\n{\n    Id boolType = makeBoolType();\n    Id valueType = getTypeId(value1);\n\n    Id resultId = NoResult;\n\n    int numConstituents = getNumTypeConstituents(valueType);\n\n    // Scalars and Vectors\n\n    if (isScalarType(valueType) || isVectorType(valueType)) {\n        assert(valueType == getTypeId(value2));\n        // These just need a single comparison, just have\n        // to figure out what it is.\n        Op op;\n        switch (getMostBasicTypeClass(valueType)) {\n        case OpTypeFloat:\n            op = equal ? OpFOrdEqual : OpFOrdNotEqual;\n            break;\n        case OpTypeInt:\n        default:\n            op = equal ? OpIEqual : OpINotEqual;\n            break;\n        case OpTypeBool:\n            op = equal ? OpLogicalEqual : OpLogicalNotEqual;\n            precision = NoPrecision;\n            break;\n        }\n\n        if (isScalarType(valueType)) {\n            // scalar\n            resultId = createBinOp(op, boolType, value1, value2);\n        } else {\n            // vector\n            resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2);\n            setPrecision(resultId, precision);\n            // reduce vector compares...\n            resultId = createUnaryOp(equal ? OpAll : OpAny, boolType, resultId);\n        }\n\n        return setPrecision(resultId, precision);\n    }\n\n    // Only structs, arrays, and matrices should be left.\n    // They share in common the reduction operation across their constituents.\n    assert(isAggregateType(valueType) || isMatrixType(valueType));\n\n    // Compare each pair of constituents\n    for (int constituent = 0; constituent < numConstituents; ++constituent) {\n        dxil_spv::Vector<unsigned> indexes(1, constituent);\n        Id constituentType1 = getContainedTypeId(getTypeId(value1), constituent);\n        Id constituentType2 = getContainedTypeId(getTypeId(value2), constituent);\n        Id constituent1 = createCompositeExtract(value1, constituentType1, indexes);\n        Id constituent2 = createCompositeExtract(value2, constituentType2, indexes);\n\n        Id subResultId = createCompositeCompare(precision, constituent1, constituent2, equal);\n\n        if (constituent == 0)\n            resultId = subResultId;\n        else\n            resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision);\n    }\n\n    return resultId;\n}\n\n// OpCompositeConstruct\nId Builder::createCompositeConstruct(Id typeId, const dxil_spv::Vector<Id>& constituents)\n{\n    assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size()));\n\n    if (generatingOpCodeForSpecConst) {\n        // Sometime, even in spec-constant-op mode, the constant composite to be\n        // constructed may not be a specialization constant.\n        // e.g.:\n        //  const mat2 m2 = mat2(a_spec_const, a_front_end_const, another_front_end_const, third_front_end_const);\n        // The first column vector should be a spec constant one, as a_spec_const is a spec constant.\n        // The second column vector should NOT be spec constant, as it does not contain any spec constants.\n        // To handle such cases, we check the constituents of the constant vector to determine whether this\n        // vector should be created as a spec constant.\n        return makeCompositeConstant(typeId, constituents,\n                                     std::any_of(constituents.begin(), constituents.end(),\n                                                 [&](spv::Id id) { return isSpecConstant(id); }));\n    }\n\n    Instruction* op = new Instruction(getUniqueId(), typeId, OpCompositeConstruct);\n    for (int c = 0; c < (int)constituents.size(); ++c)\n        op->addIdOperand(constituents[c]);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));\n\n    return op->getResultId();\n}\n\n// Vector or scalar constructor\nId Builder::createConstructor(Decoration precision, const dxil_spv::Vector<Id>& sources, Id resultTypeId)\n{\n    Id result = NoResult;\n    unsigned int numTargetComponents = getNumTypeComponents(resultTypeId);\n    unsigned int targetComponent = 0;\n\n    // Special case: when calling a vector constructor with a single scalar\n    // argument, smear the scalar\n    if (sources.size() == 1 && isScalar(sources[0]) && numTargetComponents > 1)\n        return smearScalar(precision, sources[0], resultTypeId);\n\n    // accumulate the arguments for OpCompositeConstruct\n    dxil_spv::Vector<Id> constituents;\n    Id scalarTypeId = getScalarTypeId(resultTypeId);\n\n    // lambda to store the result of visiting an argument component\n    const auto latchResult = [&](Id comp) {\n        if (numTargetComponents > 1)\n            constituents.push_back(comp);\n        else\n            result = comp;\n        ++targetComponent;\n    };\n\n    // lambda to visit a vector argument's components\n    const auto accumulateVectorConstituents = [&](Id sourceArg) {\n        unsigned int sourceSize = getNumComponents(sourceArg);\n        unsigned int sourcesToUse = sourceSize;\n        if (sourcesToUse + targetComponent > numTargetComponents)\n            sourcesToUse = numTargetComponents - targetComponent;\n\n        for (unsigned int s = 0; s < sourcesToUse; ++s) {\n            dxil_spv::Vector<unsigned> swiz;\n            swiz.push_back(s);\n            latchResult(createRvalueSwizzle(precision, scalarTypeId, sourceArg, swiz));\n        }\n    };\n\n    // lambda to visit a matrix argument's components\n    const auto accumulateMatrixConstituents = [&](Id sourceArg) {\n        unsigned int sourceSize = getNumColumns(sourceArg) * getNumRows(sourceArg);\n        unsigned int sourcesToUse = sourceSize;\n        if (sourcesToUse + targetComponent > numTargetComponents)\n            sourcesToUse = numTargetComponents - targetComponent;\n\n        int col = 0;\n        int row = 0;\n        for (unsigned int s = 0; s < sourcesToUse; ++s) {\n            if (row >= getNumRows(sourceArg)) {\n                row = 0;\n                col++;\n            }\n            dxil_spv::Vector<Id> indexes;\n            indexes.push_back(col);\n            indexes.push_back(row);\n            latchResult(createCompositeExtract(sourceArg, scalarTypeId, indexes));\n            row++;\n        }\n    };\n\n    // Go through the source arguments, each one could have either\n    // a single or multiple components to contribute.\n    for (unsigned int i = 0; i < sources.size(); ++i) {\n        if (isScalar(sources[i]))\n            latchResult(sources[i]);\n        else if (isVector(sources[i]))\n            accumulateVectorConstituents(sources[i]);\n        else if (isMatrix(sources[i]))\n            accumulateMatrixConstituents(sources[i]);\n        else\n            assert(0);\n\n        if (targetComponent >= numTargetComponents)\n            break;\n    }\n\n    // If the result is a vector, make it from the gathered constituents.\n    if (constituents.size() > 0)\n        result = createCompositeConstruct(resultTypeId, constituents);\n\n    return setPrecision(result, precision);\n}\n\n// Comments in header\nId Builder::createMatrixConstructor(Decoration precision, const dxil_spv::Vector<Id>& sources, Id resultTypeId)\n{\n    Id componentTypeId = getScalarTypeId(resultTypeId);\n    int numCols = getTypeNumColumns(resultTypeId);\n    int numRows = getTypeNumRows(resultTypeId);\n\n    Instruction* instr = module.getInstruction(componentTypeId);\n    Id bitCount = instr->getIdOperand(0);\n\n    // Will use a two step process\n    // 1. make a compile-time 2D array of values\n    // 2. construct a matrix from that array\n\n    // Step 1.\n\n    // initialize the array to the identity matrix\n    Id ids[maxMatrixSize][maxMatrixSize];\n    Id  one = (bitCount == 64 ? makeDoubleConstant(1.0) : makeFloatConstant(1.0));\n    Id zero = (bitCount == 64 ? makeDoubleConstant(0.0) : makeFloatConstant(0.0));\n    for (int col = 0; col < 4; ++col) {\n        for (int row = 0; row < 4; ++row) {\n            if (col == row)\n                ids[col][row] = one;\n            else\n                ids[col][row] = zero;\n        }\n    }\n\n    // modify components as dictated by the arguments\n    if (sources.size() == 1 && isScalar(sources[0])) {\n        // a single scalar; resets the diagonals\n        for (int col = 0; col < 4; ++col)\n            ids[col][col] = sources[0];\n    } else if (isMatrix(sources[0])) {\n        // constructing from another matrix; copy over the parts that exist in both the argument and constructee\n        Id matrix = sources[0];\n        int minCols = std::min(numCols, getNumColumns(matrix));\n        int minRows = std::min(numRows, getNumRows(matrix));\n        for (int col = 0; col < minCols; ++col) {\n            dxil_spv::Vector<unsigned> indexes;\n            indexes.push_back(col);\n            for (int row = 0; row < minRows; ++row) {\n                indexes.push_back(row);\n                ids[col][row] = createCompositeExtract(matrix, componentTypeId, indexes);\n                indexes.pop_back();\n                setPrecision(ids[col][row], precision);\n            }\n        }\n    } else {\n        // fill in the matrix in column-major order with whatever argument components are available\n        int row = 0;\n        int col = 0;\n\n        for (int arg = 0; arg < (int)sources.size(); ++arg) {\n            Id argComp = sources[arg];\n            for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {\n                if (getNumComponents(sources[arg]) > 1) {\n                    argComp = createCompositeExtract(sources[arg], componentTypeId, comp);\n                    setPrecision(argComp, precision);\n                }\n                ids[col][row++] = argComp;\n                if (row == numRows) {\n                    row = 0;\n                    col++;\n                }\n            }\n        }\n    }\n\n    // Step 2:  Construct a matrix from that array.\n    // First make the column vectors, then make the matrix.\n\n    // make the column vectors\n    Id columnTypeId = getContainedTypeId(resultTypeId);\n    dxil_spv::Vector<Id> matrixColumns;\n    for (int col = 0; col < numCols; ++col) {\n        dxil_spv::Vector<Id> vectorComponents;\n        for (int row = 0; row < numRows; ++row)\n            vectorComponents.push_back(ids[col][row]);\n        Id column = createCompositeConstruct(columnTypeId, vectorComponents);\n        setPrecision(column, precision);\n        matrixColumns.push_back(column);\n    }\n\n    // make the matrix\n    return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision);\n}\n\n// Comments in header\nBuilder::If::If(Id cond, unsigned int ctrl, Builder& gb) :\n    builder(gb),\n    condition(cond),\n    control(ctrl),\n    elseBlock(0)\n{\n    function = &builder.getBuildPoint()->getParent();\n\n    // make the blocks, but only put the then-block into the function,\n    // the else-block and merge-block will be added later, in order, after\n    // earlier code is emitted\n    thenBlock = new Block(builder.getUniqueId(), *function);\n    mergeBlock = new Block(builder.getUniqueId(), *function);\n\n    // Save the current block, so that we can add in the flow control split when\n    // makeEndIf is called.\n    headerBlock = builder.getBuildPoint();\n\n    function->addBlock(thenBlock);\n    builder.setBuildPoint(thenBlock);\n}\n\n// Comments in header\nvoid Builder::If::makeBeginElse()\n{\n    // Close out the \"then\" by having it jump to the mergeBlock\n    builder.createBranch(mergeBlock);\n\n    // Make the first else block and add it to the function\n    elseBlock = new Block(builder.getUniqueId(), *function);\n    function->addBlock(elseBlock);\n\n    // Start building the else block\n    builder.setBuildPoint(elseBlock);\n}\n\n// Comments in header\nvoid Builder::If::makeEndIf()\n{\n    // jump to the merge block\n    builder.createBranch(mergeBlock);\n\n    // Go back to the headerBlock and make the flow control split\n    builder.setBuildPoint(headerBlock);\n    builder.createSelectionMerge(mergeBlock, control);\n    if (elseBlock)\n        builder.createConditionalBranch(condition, thenBlock, elseBlock);\n    else\n        builder.createConditionalBranch(condition, thenBlock, mergeBlock);\n\n    // add the merge block to the function\n    function->addBlock(mergeBlock);\n    builder.setBuildPoint(mergeBlock);\n}\n\n// Comments in header\nvoid Builder::makeSwitch(Id selector, unsigned int control, int numSegments, const dxil_spv::Vector<int>& caseValues,\n                         const dxil_spv::Vector<int>& valueIndexToSegment, int defaultSegment,\n                         dxil_spv::Vector<Block*>& segmentBlocks)\n{\n    Function& function = buildPoint->getParent();\n\n    // make all the blocks\n    for (int s = 0; s < numSegments; ++s)\n        segmentBlocks.push_back(new Block(getUniqueId(), function));\n\n    Block* mergeBlock = new Block(getUniqueId(), function);\n\n    // make and insert the switch's selection-merge instruction\n    createSelectionMerge(mergeBlock, control);\n\n    // make the switch instruction\n    Instruction* switchInst = new Instruction(NoResult, NoType, OpSwitch);\n    switchInst->addIdOperand(selector);\n    auto defaultOrMerge = (defaultSegment >= 0) ? segmentBlocks[defaultSegment] : mergeBlock;\n    switchInst->addIdOperand(defaultOrMerge->getId());\n    defaultOrMerge->addPredecessor(buildPoint);\n    for (int i = 0; i < (int)caseValues.size(); ++i) {\n        switchInst->addImmediateOperand(caseValues[i]);\n        switchInst->addIdOperand(segmentBlocks[valueIndexToSegment[i]]->getId());\n        segmentBlocks[valueIndexToSegment[i]]->addPredecessor(buildPoint);\n    }\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(switchInst));\n\n    // push the merge block\n    switchMerges.push(mergeBlock);\n}\n\n// Comments in header\nvoid Builder::addSwitchBreak()\n{\n    // branch to the top of the merge block stack\n    createBranch(switchMerges.top());\n    createAndSetNoPredecessorBlock(\"post-switch-break\");\n}\n\n// Comments in header\nvoid Builder::nextSwitchSegment(dxil_spv::Vector<Block*>& segmentBlock, int nextSegment)\n{\n    int lastSegment = nextSegment - 1;\n    if (lastSegment >= 0) {\n        // Close out previous segment by jumping, if necessary, to next segment\n        if (! buildPoint->isTerminated())\n            createBranch(segmentBlock[nextSegment]);\n    }\n    Block* block = segmentBlock[nextSegment];\n    block->getParent().addBlock(block);\n    setBuildPoint(block);\n}\n\n// Comments in header\nvoid Builder::endSwitch(dxil_spv::Vector<Block*>& /*segmentBlock*/)\n{\n    // Close out previous segment by jumping, if necessary, to next segment\n    if (! buildPoint->isTerminated())\n        addSwitchBreak();\n\n    switchMerges.top()->getParent().addBlock(switchMerges.top());\n    setBuildPoint(switchMerges.top());\n\n    switchMerges.pop();\n}\n\nBlock& Builder::makeNewBlock()\n{\n    Function& function = buildPoint->getParent();\n    auto block = new Block(getUniqueId(), function);\n    function.addBlock(block);\n    return *block;\n}\n\nBuilder::LoopBlocks& Builder::makeNewLoop()\n{\n    // This verbosity is needed to simultaneously get the same behavior\n    // everywhere (id's in the same order), have a syntax that works\n    // across lots of versions of C++, have no warnings from pedantic\n    // compilation modes, and leave the rest of the code alone.\n    Block& head            = makeNewBlock();\n    Block& body            = makeNewBlock();\n    Block& merge           = makeNewBlock();\n    Block& continue_target = makeNewBlock();\n    LoopBlocks blocks(head, body, merge, continue_target);\n    loops.push(blocks);\n    return loops.top();\n}\n\nvoid Builder::createLoopContinue()\n{\n    createBranch(&loops.top().continue_target);\n    // Set up a block for dead code.\n    createAndSetNoPredecessorBlock(\"post-loop-continue\");\n}\n\nvoid Builder::createLoopExit()\n{\n    createBranch(&loops.top().merge);\n    // Set up a block for dead code.\n    createAndSetNoPredecessorBlock(\"post-loop-break\");\n}\n\nvoid Builder::closeLoop()\n{\n    loops.pop();\n}\n\nvoid Builder::clearAccessChain()\n{\n    accessChain.base = NoResult;\n    accessChain.indexChain.clear();\n    accessChain.instr = NoResult;\n    accessChain.swizzle.clear();\n    accessChain.component = NoResult;\n    accessChain.preSwizzleBaseType = NoType;\n    accessChain.isRValue = false;\n}\n\n// Comments in header\nvoid Builder::accessChainPushSwizzle(dxil_spv::Vector<unsigned>& swizzle, Id preSwizzleBaseType)\n{\n    // swizzles can be stacked in GLSL, but simplified to a single\n    // one here; the base type doesn't change\n    if (accessChain.preSwizzleBaseType == NoType)\n        accessChain.preSwizzleBaseType = preSwizzleBaseType;\n\n    // if needed, propagate the swizzle for the current access chain\n    if (accessChain.swizzle.size()) {\n        dxil_spv::Vector<unsigned> oldSwizzle = accessChain.swizzle;\n        accessChain.swizzle.resize(0);\n        for (unsigned int i = 0; i < swizzle.size(); ++i) {\n            assert(swizzle[i] < oldSwizzle.size());\n            accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]);\n        }\n    } else\n        accessChain.swizzle = swizzle;\n\n    // determine if we need to track this swizzle anymore\n    simplifyAccessChainSwizzle();\n}\n\n// Comments in header\nvoid Builder::accessChainStore(Id rvalue)\n{\n    assert(accessChain.isRValue == false);\n\n    transferAccessChainSwizzle(true);\n    Id base = collapseAccessChain();\n\n    // If swizzle still exists, it is out-of-order or not full, we must load the target vector,\n    // extract and insert elements to perform writeMask and/or swizzle.\n    Id source = NoResult;\n    if (accessChain.swizzle.size()) {\n        Id tempBaseId = createLoad(base);\n        source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);\n    }\n\n    // dynamic component selection\n    if (accessChain.component != NoResult) {\n        Id tempBaseId = (source == NoResult) ? createLoad(base) : source;\n        source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, accessChain.component);\n    }\n\n    if (source == NoResult)\n        source = rvalue;\n\n    createStore(source, base);\n}\n\n// Comments in header\nId Builder::accessChainLoad(Decoration precision, Id resultType)\n{\n    Id id;\n\n    if (accessChain.isRValue) {\n        // transfer access chain, but keep it static, so we can stay in registers\n        transferAccessChainSwizzle(false);\n        if (accessChain.indexChain.size() > 0) {\n            Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;\n\n            // if all the accesses are constants, we can use OpCompositeExtract\n            dxil_spv::Vector<unsigned> indexes;\n            bool constant = true;\n            for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {\n                if (isConstantScalar(accessChain.indexChain[i]))\n                    indexes.push_back(getConstantScalar(accessChain.indexChain[i]));\n                else {\n                    constant = false;\n                    break;\n                }\n            }\n\n            if (constant)\n                id = createCompositeExtract(accessChain.base, swizzleBase, indexes);\n            else {\n                // make a new function variable for this r-value\n                Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), \"indexable\");\n\n                // store into it\n                createStore(accessChain.base, lValue);\n\n                // move base to the new variable\n                accessChain.base = lValue;\n                accessChain.isRValue = false;\n\n                // load through the access chain\n                id = createLoad(collapseAccessChain());\n            }\n            setPrecision(id, precision);\n        } else\n            id = accessChain.base;  // no precision, it was set when this was defined\n    } else {\n        transferAccessChainSwizzle(true);\n        // load through the access chain\n        id = createLoad(collapseAccessChain());\n        setPrecision(id, precision);\n    }\n\n    // Done, unless there are swizzles to do\n    if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)\n        return id;\n\n    // Do remaining swizzling\n    // First, static swizzling\n    if (accessChain.swizzle.size()) {\n        // static swizzle\n        Id swizzledType = getScalarTypeId(getTypeId(id));\n        if (accessChain.swizzle.size() > 1)\n            swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size());\n        id = createRvalueSwizzle(precision, swizzledType, id, accessChain.swizzle);\n    }\n\n    // dynamic single-component selection\n    if (accessChain.component != NoResult)\n        id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);\n\n    return id;\n}\n\nId Builder::accessChainGetLValue()\n{\n    assert(accessChain.isRValue == false);\n\n    transferAccessChainSwizzle(true);\n    Id lvalue = collapseAccessChain();\n\n    // If swizzle exists, it is out-of-order or not full, we must load the target vector,\n    // extract and insert elements to perform writeMask and/or swizzle.  This does not\n    // go with getting a direct l-value pointer.\n    assert(accessChain.swizzle.size() == 0);\n    assert(accessChain.component == NoResult);\n\n    return lvalue;\n}\n\n// comment in header\nId Builder::accessChainGetInferredType()\n{\n    // anything to operate on?\n    if (accessChain.base == NoResult)\n        return NoType;\n    Id type = getTypeId(accessChain.base);\n\n    // do initial dereference\n    if (! accessChain.isRValue)\n        type = getContainedTypeId(type);\n\n    // dereference each index\n    for (auto it = accessChain.indexChain.cbegin(); it != accessChain.indexChain.cend(); ++it) {\n        if (isStructType(type))\n            type = getContainedTypeId(type, getConstantScalar(*it));\n        else\n            type = getContainedTypeId(type);\n    }\n\n    // dereference swizzle\n    if (accessChain.swizzle.size() == 1)\n        type = getContainedTypeId(type);\n    else if (accessChain.swizzle.size() > 1)\n        type = makeVectorType(getContainedTypeId(type), (int)accessChain.swizzle.size());\n\n    // dereference component selection\n    if (accessChain.component)\n        type = getContainedTypeId(type);\n\n    return type;\n}\n\n// comment in header\nvoid Builder::eliminateDeadDecorations() {\n    dxil_spv::UnorderedSet<const Block*> reachable_blocks;\n    dxil_spv::UnorderedSet<Id> unreachable_definitions;\n    // Collect IDs defined in unreachable blocks. For each function, label the\n    // reachable blocks first. Then for each unreachable block, collect the\n    // result IDs of the instructions in it.\n    for (dxil_spv::Vector<Function*>::const_iterator fi = module.getFunctions().cbegin();\n        fi != module.getFunctions().cend(); fi++) {\n        Function* f = *fi;\n        Block* entry = f->getEntryBlock();\n        inReadableOrder(entry, [&reachable_blocks](const Block* b) {\n            reachable_blocks.insert(b);\n        });\n        for (dxil_spv::Vector<Block*>::const_iterator bi = f->getBlocks().cbegin();\n            bi != f->getBlocks().cend(); bi++) {\n            Block* b = *bi;\n            if (!reachable_blocks.count(b)) {\n                for (dxil_spv::Vector<std::unique_ptr<Instruction> >::const_iterator\n                         ii = b->getInstructions().cbegin();\n                    ii != b->getInstructions().cend(); ii++) {\n                    Instruction* i = ii->get();\n                    unreachable_definitions.insert(i->getResultId());\n                }\n            }\n        }\n    }\n    decorations.erase(std::remove_if(decorations.begin(), decorations.end(),\n        [&unreachable_definitions](std::unique_ptr<Instruction>& I) -> bool {\n            Instruction* inst = I.get();\n            Id decoration_id = inst->getIdOperand(0);\n            return unreachable_definitions.count(decoration_id) != 0;\n        }),\n        decorations.end());\n}\n\nvoid Builder::dump(dxil_spv::Vector<unsigned int>& out) const\n{\n    // Header, before first instructions:\n    out.push_back(MagicNumber);\n    out.push_back(Version);\n    out.push_back(builderNumber);\n    out.push_back(uniqueId + 1);\n    out.push_back(0);\n\n    // Capabilities\n    for (auto it = capabilities.cbegin(); it != capabilities.cend(); ++it) {\n        Instruction capInst(0, 0, OpCapability);\n        capInst.addImmediateOperand(*it);\n        capInst.dump(out);\n    }\n\n    for (auto it = extensions.cbegin(); it != extensions.cend(); ++it) {\n        Instruction extInst(0, 0, OpExtension);\n        extInst.addStringOperand(it->c_str());\n        extInst.dump(out);\n    }\n\n    dumpInstructions(out, imports);\n    Instruction memInst(0, 0, OpMemoryModel);\n    memInst.addImmediateOperand(addressModel);\n    memInst.addImmediateOperand(memoryModel);\n    memInst.dump(out);\n\n    // Instructions saved up while building:\n    dumpInstructions(out, entryPoints);\n    dumpInstructions(out, executionModes);\n\n    // Debug instructions\n    dumpInstructions(out, strings);\n    dumpModuleProcesses(out);\n    dumpSourceInstructions(out);\n    for (int e = 0; e < (int)sourceExtensions.size(); ++e) {\n        Instruction sourceExtInst(0, 0, OpSourceExtension);\n        sourceExtInst.addStringOperand(sourceExtensions[e]);\n        sourceExtInst.dump(out);\n    }\n    dumpInstructions(out, names);\n    dumpInstructions(out, lines);\n\n    // Annotation instructions\n    dumpInstructions(out, decorations);\n\n    dumpInstructions(out, constantsTypesGlobals);\n    dumpInstructions(out, externals);\n\n    // The functions\n    module.dump(out);\n}\n\n//\n// Protected methods.\n//\n\n// Turn the described access chain in 'accessChain' into an instruction\n// computing its address.  This *cannot* include complex swizzles, which must\n// be handled after this is called, but it does include swizzles that select\n// an individual element, as a single address of a scalar type can be\n// computed by an OpAccessChain instruction.\nId Builder::collapseAccessChain()\n{\n    assert(accessChain.isRValue == false);\n\n    if (accessChain.indexChain.size() > 0) {\n        if (accessChain.instr == 0) {\n            StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));\n            accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);\n        }\n\n        return accessChain.instr;\n    } else\n        return accessChain.base;\n\n    // note that non-trivial swizzling is left pending...\n}\n\n// clear out swizzle if it is redundant, that is reselecting the same components\n// that would be present without the swizzle.\nvoid Builder::simplifyAccessChainSwizzle()\n{\n    // If the swizzle has fewer components than the vector, it is subsetting, and must stay\n    // to preserve that fact.\n    if (getNumTypeComponents(accessChain.preSwizzleBaseType) > (int)accessChain.swizzle.size())\n        return;\n\n    // if components are out of order, it is a swizzle\n    for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {\n        if (i != accessChain.swizzle[i])\n            return;\n    }\n\n    // otherwise, there is no need to track this swizzle\n    accessChain.swizzle.clear();\n    if (accessChain.component == NoResult)\n        accessChain.preSwizzleBaseType = NoType;\n}\n\n// To the extent any swizzling can become part of the chain\n// of accesses instead of a post operation, make it so.\n// If 'dynamic' is true, include transferring a non-static component index,\n// otherwise, only transfer static indexes.\n//\n// Also, Boolean vectors are likely to be special.  While\n// for external storage, they should only be integer types,\n// function-local bool vectors could use sub-word indexing,\n// so keep that as a separate Insert/Extract on a loaded vector.\nvoid Builder::transferAccessChainSwizzle(bool dynamic)\n{\n    // too complex?\n    if (accessChain.swizzle.size() > 1)\n        return;\n\n    // non existent?\n    if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)\n        return;\n\n    // single component...\n\n    // skip doing it for Boolean vectors\n    if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType)))\n        return;\n\n    if (accessChain.swizzle.size() == 1) {\n        // handle static component\n        accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));\n        accessChain.swizzle.clear();\n        // note, the only valid remaining dynamic access would be to this one\n        // component, so don't bother even looking at accessChain.component\n        accessChain.preSwizzleBaseType = NoType;\n        accessChain.component = NoResult;\n    } else if (dynamic && accessChain.component != NoResult) {\n        // handle dynamic component\n        accessChain.indexChain.push_back(accessChain.component);\n        accessChain.preSwizzleBaseType = NoType;\n        accessChain.component = NoResult;\n    }\n}\n\n// Utility method for creating a new block and setting the insert point to\n// be in it. This is useful for flow-control operations that need a \"dummy\"\n// block proceeding them (e.g. instructions after a discard, etc).\nvoid Builder::createAndSetNoPredecessorBlock(const char* /*name*/)\n{\n    Block* block = new Block(getUniqueId(), buildPoint->getParent());\n    block->setUnreachable();\n    buildPoint->getParent().addBlock(block);\n    setBuildPoint(block);\n\n    // if (name)\n    //    addName(block->getId(), name);\n}\n\n// Comments in header\nvoid Builder::createBranch(Block* block)\n{\n    Instruction* branch = new Instruction(OpBranch);\n    branch->addIdOperand(block->getId());\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(branch));\n    block->addPredecessor(buildPoint);\n}\n\nvoid Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)\n{\n    Instruction* merge = new Instruction(OpSelectionMerge);\n    merge->addIdOperand(mergeBlock->getId());\n    merge->addImmediateOperand(control);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));\n}\n\nvoid Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control)\n{\n    Instruction* merge = new Instruction(OpLoopMerge);\n    merge->addIdOperand(mergeBlock->getId());\n    merge->addIdOperand(continueBlock->getId());\n    merge->addImmediateOperand(control);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));\n}\n\nvoid Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock)\n{\n    Instruction* branch = new Instruction(OpBranchConditional);\n    branch->addIdOperand(condition);\n    branch->addIdOperand(thenBlock->getId());\n    branch->addIdOperand(elseBlock->getId());\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(branch));\n    thenBlock->addPredecessor(buildPoint);\n    elseBlock->addPredecessor(buildPoint);\n}\n\nvoid Builder::createUnreachable()\n{\n    Instruction* merge = new Instruction(OpUnreachable);\n    buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));\n}\n\n// OpSource\n// [OpSourceContinued]\n// ...\nvoid Builder::dumpSourceInstructions(dxil_spv::Vector<unsigned int>& out) const\n{\n    const int maxWordCount = 0xFFFF;\n    const int opSourceWordCount = 4;\n    const int nonNullBytesPerInstruction = 4 * (maxWordCount - opSourceWordCount) - 1;\n\n    if (source != SourceLanguageUnknown) {\n        // OpSource Language Version File Source\n        Instruction sourceInst(NoResult, NoType, OpSource);\n        sourceInst.addImmediateOperand(source);\n        sourceInst.addImmediateOperand(sourceVersion);\n        // File operand\n        if (sourceFileStringId != NoResult) {\n            sourceInst.addIdOperand(sourceFileStringId);\n            // Source operand\n            if (sourceText.size() > 0) {\n                int nextByte = 0;\n                dxil_spv::String subString;\n                while ((int)sourceText.size() - nextByte > 0) {\n                    subString = sourceText.substr(nextByte, nonNullBytesPerInstruction);\n                    if (nextByte == 0) {\n                        // OpSource\n                        sourceInst.addStringOperand(subString.c_str());\n                        sourceInst.dump(out);\n                    } else {\n                        // OpSourcContinued\n                        Instruction sourceContinuedInst(OpSourceContinued);\n                        sourceContinuedInst.addStringOperand(subString.c_str());\n                        sourceContinuedInst.dump(out);\n                    }\n                    nextByte += nonNullBytesPerInstruction;\n                }\n            } else\n                sourceInst.dump(out);\n        } else\n            sourceInst.dump(out);\n    }\n}\n\nvoid Builder::dumpInstructions(dxil_spv::Vector<unsigned int>& out, const dxil_spv::Vector<std::unique_ptr<Instruction> >& instructions) const\n{\n    for (int i = 0; i < (int)instructions.size(); ++i) {\n        instructions[i]->dump(out);\n    }\n}\n\nvoid Builder::dumpModuleProcesses(dxil_spv::Vector<unsigned int>& out) const\n{\n    for (int i = 0; i < (int)moduleProcesses.size(); ++i) {\n        // TODO: switch this out for the 1.1 headers\n        const spv::Op OpModuleProcessed = (spv::Op)330;\n        Instruction moduleProcessed(OpModuleProcessed);\n        moduleProcessed.addStringOperand(moduleProcesses[i]);\n        moduleProcessed.dump(out);\n    }\n}\n\n}; // end spv namespace\n"
  },
  {
    "path": "third_party/glslang-spirv/SpvBuilder.h",
    "content": "//\n// Copyright (C) 2014-2015 LunarG, Inc.\n// Copyright (C) 2015-2016 Google, Inc.\n//\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//    Redistributions of source code must retain the above copyright\n//    notice, this list of conditions and the following disclaimer.\n//\n//    Redistributions in binary form must reproduce the above\n//    copyright notice, this list of conditions and the following\n//    disclaimer in the documentation and/or other materials provided\n//    with the distribution.\n//\n//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its\n//    contributors may be used to endorse or promote products derived\n//    from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n//\n// \"Builder\" is an interface to fully build SPIR-V IR.   Allocate one of\n// these to build (a thread safe) internal SPIR-V representation (IR),\n// and then dump it as a binary stream according to the SPIR-V specification.\n//\n// A Builder has a 1:1 relationship with a SPIR-V module.\n//\n\n#pragma once\n#ifndef SpvBuilder_H\n#define SpvBuilder_H\n\n#include \"Logger.h\"\n#include \"spirv.hpp\"\n#include \"spvIR.h\"\n\n#include <algorithm>\n#include <memory>\n#include <sstream>\n#include <stack>\n\n#include \"thread_local_allocator.hpp\"\n\nnamespace spv {\n\nclass Builder {\npublic:\n    Builder(unsigned int userNumber, SpvBuildLogger* logger);\n    virtual ~Builder();\n\n    static const int maxMatrixSize = 4;\n\n    void setSource(spv::SourceLanguage lang, int version)\n    {\n        source = lang;\n        sourceVersion = version;\n    }\n    void setSourceFile(const dxil_spv::String& file)\n    {\n        Instruction* fileString = new Instruction(getUniqueId(), NoType, OpString);\n        fileString->addStringOperand(file.c_str());\n        sourceFileStringId = fileString->getResultId();\n        strings.push_back(std::unique_ptr<Instruction>(fileString));\n    }\n    void setSourceText(const dxil_spv::String& text) { sourceText = text; }\n    void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }\n    void addModuleProcessed(const dxil_spv::String& p) { moduleProcesses.push_back(p.c_str()); }\n    void setEmitOpLines() { emitOpLines = true; }\n    void addExtension(const char* ext) { extensions.insert(ext); }\n    Id import(const char*);\n    void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)\n    {\n        addressModel = addr;\n        memoryModel = mem;\n    }\n\n    void addCapability(spv::Capability cap) { capabilities.insert(cap); }\n    bool hasCapability(spv::Capability cap) const\n    {\n        return capabilities.count(cap) != 0;\n    }\n\n    // To get a new <id> for anything needing a new one.\n    Id getUniqueId() { return ++uniqueId; }\n\n    // To get a set of new <id>s, e.g., for a set of function parameters\n    Id getUniqueIds(int numIds)\n    {\n        Id id = uniqueId + 1;\n        uniqueId += numIds;\n        return id;\n    }\n\n    spv::Instruction *addInstruction(spv::Id typeId, spv::Op op);\n    spv::Instruction *addInstruction(spv::Op op);\n\n    // Log the current line, and if different than the last one,\n    // issue a new OpLine, using the current file name.\n    void setLine(int line);\n    // Low-level OpLine. See setLine() for a layered helper.\n    void addLine(Id fileName, int line, int column);\n    void addExternal(std::unique_ptr<spv::Instruction> inst);\n    spv::Id addString(const dxil_spv::String &str);\n\n    // For creating new types (will return old type if the requested one was already made).\n    Id makeVoidType();\n    Id makeBoolType();\n    Id makePointer(StorageClass, Id type);\n    Id makeIntegerType(int width, bool hasSign);   // generic\n    Id makeIntType(int width) { return makeIntegerType(width, true); }\n    Id makeUintType(int width) { return makeIntegerType(width, false); }\n    Id makeFloatType(int width, int encoding = -1);\n    Id makeCooperativeMatrixType(spv::Id scalar_type, spv::Id rows, spv::Id cols, spv::Id use);\n    Id makeStructType(const dxil_spv::Vector<Id>& members, const char*);\n    Id makeStructResultType(Id type0, Id type1);\n    Id makeVectorType(Id component, int size);\n    Id makeMatrixType(Id component, int cols, int rows);\n    Id makeArrayType(Id element, Id sizeId, int stride);  // 0 stride means no stride decoration\n    Id makeRuntimeArray(Id element);\n    Id makeFunctionType(Id returnType, const dxil_spv::Vector<Id>& paramTypes);\n    Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);\n    Id makeAccelerationStructureType();\n    Id makeRayQueryType();\n    Id makeHitObjectNVType();\n    Id makeSamplerType();\n    Id makeSampledImageType(Id imageType);\n\n    // For querying about types.\n    spv::Instruction *getInstruction(Id id) { return module.getInstruction(id); }\n    Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }\n    Id getDerefTypeId(Id resultId) const;\n    Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }\n    Op getTypeClass(Id typeId) const { return getOpCode(typeId); }\n    Op getMostBasicTypeClass(Id typeId) const;\n    int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }\n    int getNumTypeConstituents(Id typeId) const;\n    int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }\n    Id getScalarTypeId(Id typeId) const;\n    Id getContainedTypeId(Id typeId) const;\n    Id getContainedTypeId(Id typeId, int) const;\n    StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }\n    ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }\n\n    bool isPointer(Id resultId)      const { return isPointerType(getTypeId(resultId)); }\n    bool isScalar(Id resultId)       const { return isScalarType(getTypeId(resultId)); }\n    bool isVector(Id resultId)       const { return isVectorType(getTypeId(resultId)); }\n    bool isMatrix(Id resultId)       const { return isMatrixType(getTypeId(resultId)); }\n    bool isAggregate(Id resultId)    const { return isAggregateType(getTypeId(resultId)); }\n    bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }\n\n    bool isBoolType(Id typeId)         const { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }\n    bool isIntType(Id typeId)          const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }\n    bool isUintType(Id typeId)         const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }\n    bool isFloatType(Id typeId)        const { return getTypeClass(typeId) == OpTypeFloat; }\n    bool isPointerType(Id typeId)      const { return getTypeClass(typeId) == OpTypePointer; }\n    bool isScalarType(Id typeId)       const { return getTypeClass(typeId) == OpTypeFloat  || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }\n    bool isVectorType(Id typeId)       const { return getTypeClass(typeId) == OpTypeVector; }\n    bool isMatrixType(Id typeId)       const { return getTypeClass(typeId) == OpTypeMatrix; }\n    bool isStructType(Id typeId)       const { return getTypeClass(typeId) == OpTypeStruct; }\n    bool isArrayType(Id typeId)        const {\n        auto typeClass = getTypeClass(typeId);\n        return typeClass == OpTypeArray || typeClass == OpTypeRuntimeArray;\n    }\n    bool isAggregateType(Id typeId)    const { return isArrayType(typeId) || isStructType(typeId); }\n    bool isImageType(Id typeId)        const { return getTypeClass(typeId) == OpTypeImage; }\n    bool isSamplerType(Id typeId)      const { return getTypeClass(typeId) == OpTypeSampler; }\n    bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }\n\n    bool isConstantOpCode(Op opcode) const;\n    bool isSpecConstantOpCode(Op opcode) const;\n    bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }\n    bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }\n    bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }\n    unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }\n    StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }\n\n    int getScalarTypeWidth(Id typeId) const\n    {\n        Id scalarTypeId = getScalarTypeId(typeId);\n        assert(getTypeClass(scalarTypeId) == OpTypeInt || getTypeClass(scalarTypeId) == OpTypeFloat);\n        return module.getInstruction(scalarTypeId)->getImmediateOperand(0);\n    }\n\n    int getTypeNumColumns(Id typeId) const\n    {\n        assert(isMatrixType(typeId));\n        return getNumTypeConstituents(typeId);\n    }\n    int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }\n    int getTypeNumRows(Id typeId) const\n    {\n        assert(isMatrixType(typeId));\n        return getNumTypeComponents(getContainedTypeId(typeId));\n    }\n    int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }\n\n    Dim getTypeDimensionality(Id typeId) const\n    {\n        assert(isImageType(typeId));\n        return (Dim)module.getInstruction(typeId)->getImmediateOperand(1);\n    }\n    Id getImageType(Id resultId) const\n    {\n        Id typeId = getTypeId(resultId);\n        assert(isImageType(typeId) || isSampledImageType(typeId));\n        return isSampledImageType(typeId) ? module.getInstruction(typeId)->getIdOperand(0) : typeId;\n    }\n    bool isArrayedImageType(Id typeId) const\n    {\n        assert(isImageType(typeId));\n        return module.getInstruction(typeId)->getImmediateOperand(3) != 0;\n    }\n    bool isMultisampledImageType(Id typeId) const\n    {\n        assert(isImageType(typeId));\n        return module.getInstruction(typeId)->getImmediateOperand(4) != 0;\n    }\n    bool isStorageImageType(Id typeId) const\n    {\n        assert(isImageType(typeId));\n        return module.getInstruction(typeId)->getImmediateOperand(5) == 2;\n    }\n    Id getImageComponentType(Id typeId) const\n    {\n        assert(isImageType(typeId));\n        return module.getInstruction(typeId)->getImmediateOperand(0);\n    }\n\n    // For making new constants (will return old constant if the requested one was already made).\n    Id makeBoolConstant(bool b, bool specConstant = false);\n    Id makeIntConstant(int i, bool specConstant = false)         { return makeIntConstant(makeIntType(32),  (unsigned)i, specConstant); }\n    Id makeUintConstant(unsigned u, bool specConstant = false)   { return makeIntConstant(makeUintType(32),           u, specConstant); }\n    Id makeInt64Constant(long long i, bool specConstant = false)            { return makeInt64Constant(makeIntType(64),  (unsigned long long)i, specConstant); }\n    Id makeUint64Constant(unsigned long long u, bool specConstant = false)  { return makeInt64Constant(makeUintType(64),                     u, specConstant); }\n#ifdef AMD_EXTENSIONS\n    Id makeInt16Constant(short i, bool specConstant = false)        { return makeIntConstant(makeIntType(16),      (unsigned)i, specConstant); }\n    Id makeUint16Constant(unsigned short u, bool specConstant = false)  { return makeIntConstant(makeUintType(16), (unsigned)u, specConstant); }\n    Id makeUint8Constant(unsigned char u, bool specConstant = false)  { return makeIntConstant(makeUintType(8), (unsigned)u, specConstant); }\n    Id makeInt8Constant(signed char u, bool specConstant = false)  { return makeIntConstant(makeIntType(8), (unsigned)u, specConstant); }\n#endif\n    Id makeFloatConstant(float f, bool specConstant = false);\n    Id makeDoubleConstant(double d, bool specConstant = false);\n#ifdef AMD_EXTENSIONS\n    Id makeFloat16Constant(uint16_t f16, bool specConstant = false);\n    Id makeFloat8Constant(uint8_t f8, int encoding, bool specConstant = false);\n#endif\n    Id makeNullConstant(Id type);\n\n    // Turn the array of constants into a proper spv constant of the requested type.\n    Id makeCompositeConstant(Id type, const dxil_spv::Vector<Id>& comps, bool specConst = false);\n\n    // Methods for adding information outside the CFG.\n    Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);\n    void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);\n    void addExecutionModeId(Function*, ExecutionMode mode, spv::Id id1 = 0, spv::Id id2 = 0, spv::Id id3 = 0);\n    void addName(Id, const char* name);\n    void addMemberName(Id, int member, const char* name);\n    void addDecoration(Id, Decoration, int num = -1);\n    void removeDecorations(const dxil_spv::UnorderedSet<spv::Id> &ids);\n    bool hasDecoration(Id, Decoration) const;\n    void addUniqueDecoration(Id, Decoration, int num = -1);\n    void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);\n\n    // At the end of what block do the next create*() instructions go?\n    void setBuildPoint(Block* bp) { buildPoint = bp; }\n    Block* getBuildPoint() const { return buildPoint; }\n\n    // Make the entry-point function. The returned pointer is only valid\n    // for the lifetime of this builder.\n    Function* makeEntryPoint(const char*);\n\n    // Make a shader-style function, and create its entry block if entry is non-zero.\n    // Return the function, pass back the entry.\n    // The returned pointer is only valid for the lifetime of this builder.\n    Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const dxil_spv::Vector<Id>& paramTypes,\n                                const dxil_spv::Vector<dxil_spv::Vector<Decoration>>& precisions, Block **entry = 0);\n\n    // Create a return. An 'implicit' return is one not appearing in the source\n    // code.  In the case of an implicit return, no post-return block is inserted.\n    void makeReturn(bool implicit, Id retVal = 0);\n\n    // Generate all the code needed to finish up a function.\n    void leaveFunction();\n\n    // Create a discard.\n    void makeDiscard();\n\n    // Create a global or function local or IO variable.\n    Id createVariable(StorageClass, Id type, const char* name = 0);\n    Id createVariableWithInitializer(StorageClass, Id type, Id initializer, const char* name = 0);\n\n    // Create an intermediate with an undefined value.\n    Id createUndefined(Id type);\n    // Create at global scope.\n    Id createUndefinedConstant(Id type);\n\n    // Store into an Id and return the l-value\n    void createStore(Id rValue, Id lValue);\n\n    // Load from an Id and return it\n    Id createLoad(Id lValue);\n\n    // Create an OpAccessChain instruction\n    Id createAccessChain(StorageClass, Id base, const dxil_spv::Vector<Id>& offsets);\n\n    // Create an OpArrayLength instruction\n    Id createArrayLength(Id base, unsigned int member);\n\n    // Create an OpCompositeExtract instruction\n    Id createCompositeExtract(Id composite, Id typeId, unsigned index);\n    Id createCompositeExtract(Id composite, Id typeId, const dxil_spv::Vector<unsigned>& indexes);\n    Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);\n    Id createCompositeInsert(Id object, Id composite, Id typeId, const dxil_spv::Vector<unsigned>& indexes);\n\n    Id createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex);\n    Id createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex);\n\n    void createNoResultOp(Op);\n    void createNoResultOp(Op, Id operand);\n    void createNoResultOp(Op, const dxil_spv::Vector<Id>& operands);\n    void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);\n    void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);\n    Id createUnaryOp(Op, Id typeId, Id operand);\n    Id createBinOp(Op, Id typeId, Id operand1, Id operand2);\n    Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);\n    Id createOp(Op, Id typeId, const dxil_spv::Vector<Id>& operands);\n    Id createFunctionCall(spv::Function*, const dxil_spv::Vector<spv::Id>&);\n    Id createSpecConstantOp(Op, Id typeId, const dxil_spv::Vector<spv::Id>& operands, const dxil_spv::Vector<unsigned>& literals);\n\n    // Take an rvalue (source) and a set of channels to extract from it to\n    // make a new rvalue, which is returned.\n    Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, const dxil_spv::Vector<unsigned>& channels);\n\n    // Take a copy of an lvalue (target) and a source of components, and set the\n    // source components into the lvalue where the 'channels' say to put them.\n    // An updated version of the target is returned.\n    // (No true lvalue or stores are used.)\n    Id createLvalueSwizzle(Id typeId, Id target, Id source, const dxil_spv::Vector<unsigned>& channels);\n\n    // If both the id and precision are valid, the id\n    // gets tagged with the requested precision.\n    // The passed in id is always the returned id, to simplify use patterns.\n    Id setPrecision(Id id, Decoration precision)\n    {\n        if (precision != NoPrecision && id != NoResult)\n            addDecoration(id, precision);\n\n        return id;\n    }\n\n    // Can smear a scalar to a vector for the following forms:\n    //   - promoteScalar(scalar, vector)  // smear scalar to width of vector\n    //   - promoteScalar(vector, scalar)  // smear scalar to width of vector\n    //   - promoteScalar(pointer, scalar) // smear scalar to width of what pointer points to\n    //   - promoteScalar(scalar, scalar)  // do nothing\n    // Other forms are not allowed.\n    //\n    // Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'.\n    // The type of the created vector is a vector of components of the same type as the scalar.\n    //\n    // Note: One of the arguments will change, with the result coming back that way rather than \n    // through the return value.\n    void promoteScalar(Decoration precision, Id& left, Id& right);\n\n    // Make a value by smearing the scalar to fill the type.\n    // vectorType should be the correct type for making a vector of scalarVal.\n    // (No conversions are done.)\n    Id smearScalar(Decoration precision, Id scalarVal, Id vectorType);\n\n    // Create a call to a built-in function.\n    Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, const dxil_spv::Vector<Id>& args);\n\n    // List of parameters used to create a texture operation\n    struct TextureParameters {\n        Id sampler;\n        Id coords;\n        Id bias;\n        Id lod;\n        Id Dref;\n        Id offset;\n        Id offsets;\n        Id gradX;\n        Id gradY;\n        Id sample;\n        Id component;\n        Id texelOut;\n        Id lodClamp;\n    };\n\n    // Select the correct texture operation based on all inputs, and emit the correct instruction\n    Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicit, const TextureParameters&);\n\n    // Emit the OpTextureQuery* instruction that was passed in.\n    // Figure out the right return value and type, and return it.\n    Id createTextureQueryCall(Op, const TextureParameters&, bool isUnsignedResult);\n\n    Id createSamplePositionCall(Decoration precision, Id, Id);\n\n    Id createBitFieldExtractCall(Decoration precision, Id, Id, Id, bool isSigned);\n    Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id);\n\n    // Reduction comparison for composites:  For equal and not-equal resulting in a scalar.\n    Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);\n\n    // OpCompositeConstruct\n    Id createCompositeConstruct(Id typeId, const dxil_spv::Vector<Id>& constituents);\n\n    // vector or scalar constructor\n    Id createConstructor(Decoration precision, const dxil_spv::Vector<Id>& sources, Id resultTypeId);\n\n    // matrix constructor\n    Id createMatrixConstructor(Decoration precision, const dxil_spv::Vector<Id>& sources, Id constructee);\n\n    // Helper to use for building nested control flow with if-then-else.\n    class If {\n    public:\n        If(Id condition, unsigned int ctrl, Builder& builder);\n        ~If() {}\n\n        void makeBeginElse();\n        void makeEndIf();\n\n    private:\n        If(const If&);\n        If& operator=(If&);\n\n        Builder& builder;\n        Id condition;\n        unsigned int control;\n        Function* function;\n        Block* headerBlock;\n        Block* thenBlock;\n        Block* elseBlock;\n        Block* mergeBlock;\n    };\n\n    // Make a switch statement.  A switch has 'numSegments' of pieces of code, not containing\n    // any case/default labels, all separated by one or more case/default labels.  Each possible\n    // case value v is a jump to the caseValues[v] segment.  The defaultSegment is also in this\n    // number space.  How to compute the value is given by 'condition', as in switch(condition).\n    //\n    // The SPIR-V Builder will maintain the stack of post-switch merge blocks for nested switches.\n    //\n    // Use a defaultSegment < 0 if there is no default segment (to branch to post switch).\n    //\n    // Returns the right set of basic blocks to start each code segment with, so that the caller's\n    // recursion stack can hold the memory for it.\n    //\n    void makeSwitch(Id condition, unsigned int control, int numSegments, const dxil_spv::Vector<int>& caseValues,\n                    const dxil_spv::Vector<int>& valueToSegment, int defaultSegment, dxil_spv::Vector<Block*>& segmentBB); // return argument\n\n    // Add a branch to the innermost switch's merge block.\n    void addSwitchBreak();\n\n    // Move to the next code segment, passing in the return argument in makeSwitch()\n    void nextSwitchSegment(dxil_spv::Vector<Block*>& segmentBB, int segment);\n\n    // Finish off the innermost switch.\n    void endSwitch(dxil_spv::Vector<Block*>& segmentBB);\n\n    struct LoopBlocks {\n        LoopBlocks(Block& head, Block& body, Block& merge, Block& continue_target) :\n            head(head), body(body), merge(merge), continue_target(continue_target) { }\n        Block &head, &body, &merge, &continue_target;\n        LoopBlocks& operator=(const LoopBlocks&) = delete;\n        LoopBlocks(const LoopBlocks&) = default;\n    private:\n        LoopBlocks();\n    };\n\n    // Start a new loop and prepare the builder to generate code for it.  Until\n    // closeLoop() is called for this loop, createLoopContinue() and\n    // createLoopExit() will target its corresponding blocks.\n    LoopBlocks& makeNewLoop();\n\n    // Create a new block in the function containing the build point.  Memory is\n    // owned by the function object.\n    Block& makeNewBlock();\n\n    // Add a branch to the continue_target of the current (innermost) loop.\n    void createLoopContinue();\n\n    // Add an exit (e.g. \"break\") from the innermost loop that we're currently\n    // in.\n    void createLoopExit();\n\n    // Close the innermost loop that you're in\n    void closeLoop();\n\n    //\n    // Access chain design for an R-Value vs. L-Value:\n    //\n    // There is a single access chain the builder is building at\n    // any particular time.  Such a chain can be used to either to a load or\n    // a store, when desired.\n    //\n    // Expressions can be r-values, l-values, or both, or only r-values:\n    //    a[b.c].d = ....  // l-value\n    //    ... = a[b.c].d;  // r-value, that also looks like an l-value\n    //    ++a[b.c].d;      // r-value and l-value\n    //    (x + y)[2];      // r-value only, can't possibly be l-value\n    //\n    // Computing an r-value means generating code.  Hence,\n    // r-values should only be computed when they are needed, not speculatively.\n    //\n    // Computing an l-value means saving away information for later use in the compiler,\n    // no code is generated until the l-value is later dereferenced.  It is okay\n    // to speculatively generate an l-value, just not okay to speculatively dereference it.\n    //\n    // The base of the access chain (the left-most variable or expression\n    // from which everything is based) can be set either as an l-value\n    // or as an r-value.  Most efficient would be to set an l-value if one\n    // is available.  If an expression was evaluated, the resulting r-value\n    // can be set as the chain base.\n    //\n    // The users of this single access chain can save and restore if they\n    // want to nest or manage multiple chains.\n    //\n\n    struct AccessChain {\n        Id base;                       // for l-values, pointer to the base object, for r-values, the base object\n        dxil_spv::Vector<Id> indexChain;\n        Id instr;                      // cache the instruction that generates this access chain\n        dxil_spv::Vector<unsigned> swizzle; // each dxil_spv::Vector element selects the next GLSL component number\n        Id component;                  // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present\n        Id preSwizzleBaseType;         // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present\n        bool isRValue;                 // true if 'base' is an r-value, otherwise, base is an l-value\n    };\n\n    //\n    // the SPIR-V builder maintains a single active chain that\n    // the following methods operate on\n    //\n\n    // for external save and restore\n    AccessChain getAccessChain() { return accessChain; }\n    void setAccessChain(AccessChain newChain) { accessChain = newChain; }\n\n    // clear accessChain\n    void clearAccessChain();\n\n    // set new base as an l-value base\n    void setAccessChainLValue(Id lValue)\n    {\n        assert(isPointer(lValue));\n        accessChain.base = lValue;\n    }\n\n    // set new base value as an r-value\n    void setAccessChainRValue(Id rValue)\n    {\n        accessChain.isRValue = true;\n        accessChain.base = rValue;\n    }\n\n    // push offset onto the end of the chain\n    void accessChainPush(Id offset)\n    {\n        accessChain.indexChain.push_back(offset);\n    }\n\n    // push new swizzle onto the end of any existing swizzle, merging into a single swizzle\n    void accessChainPushSwizzle(dxil_spv::Vector<unsigned>& swizzle, Id preSwizzleBaseType);\n\n    // push a variable component selection onto the access chain; supporting only one, so unsided\n    void accessChainPushComponent(Id component, Id preSwizzleBaseType)\n    {\n        accessChain.component = component;\n        if (accessChain.preSwizzleBaseType == NoType)\n            accessChain.preSwizzleBaseType = preSwizzleBaseType;\n    }\n\n    // use accessChain and swizzle to store value\n    void accessChainStore(Id rvalue);\n\n    // use accessChain and swizzle to load an r-value\n    Id accessChainLoad(Decoration precision, Id ResultType);\n\n    // get the direct pointer for an l-value\n    Id accessChainGetLValue();\n\n    // Get the inferred SPIR-V type of the result of the current access chain,\n    // based on the type of the base and the chain of dereferences.\n    Id accessChainGetInferredType();\n\n    // Remove OpDecorate instructions whose operands are defined in unreachable\n    // blocks.\n    void eliminateDeadDecorations();\n    void dump(dxil_spv::Vector<unsigned int>&) const;\n\n    void createBranch(Block* block);\n    void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);\n    void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);\n    void createUnreachable();\n\n    // Sets to generate opcode for specialization constants.\n    void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }\n    // Sets to generate opcode for non-specialization constants (normal mode).\n    void setToNormalCodeGenMode() { generatingOpCodeForSpecConst = false; }\n    // Check if the builder is generating code for spec constants.\n    bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; }\n\n    void createSelectionMerge(Block* mergeBlock, unsigned int control);\n\n    spv::Scope getAtomicDeviceScope() const\n    {\n        if (hasCapability(spv::CapabilityVulkanMemoryModel))\n            return spv::ScopeQueueFamily;\n        else\n            return spv::ScopeDevice;\n    }\n\n    spv::Id getAtomicDeviceScopeId()\n    {\n        return makeUintConstant(getAtomicDeviceScope());\n    }\n\n    spv::Id getWorkgroupBarrierSemanticsId()\n    {\n        uint32_t semantics = spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsWorkgroupMemoryMask;\n        if (hasCapability(spv::CapabilityVulkanMemoryModel))\n            semantics |= spv::MemorySemanticsMakeAvailableMask | spv::MemorySemanticsMakeVisibleMask;\n        return makeUintConstant(semantics);\n    }\n\nprotected:\n    Id makeIntConstant(Id typeId, unsigned value, bool specConstant);\n    Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);\n    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const;\n    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;\n    Id findCompositeConstant(Op typeClass, const dxil_spv::Vector<Id>& comps) const;\n    Id collapseAccessChain();\n    void transferAccessChainSwizzle(bool dynamic);\n    void simplifyAccessChainSwizzle();\n    void createAndSetNoPredecessorBlock(const char*);\n    void dumpSourceInstructions(dxil_spv::Vector<unsigned int>&) const;\n    void dumpInstructions(dxil_spv::Vector<unsigned int>&, const dxil_spv::Vector<std::unique_ptr<Instruction> >&) const;\n    void dumpModuleProcesses(dxil_spv::Vector<unsigned int>&) const;\n\n    SourceLanguage source;\n    int sourceVersion;\n    spv::Id sourceFileStringId;\n    dxil_spv::String sourceText;\n    int currentLine;\n    bool emitOpLines;\n    dxil_spv::Set<dxil_spv::String> extensions;\n    dxil_spv::Vector<const char*> sourceExtensions;\n    dxil_spv::Vector<const char*> moduleProcesses;\n    AddressingModel addressModel;\n    MemoryModel memoryModel;\n    dxil_spv::Set<spv::Capability> capabilities;\n    int builderNumber;\n    Module module;\n    Block* buildPoint;\n    Id uniqueId;\n    Function* entryPointFunction;\n    bool generatingOpCodeForSpecConst;\n    AccessChain accessChain;\n\n    // special blocks of instructions for output\n    dxil_spv::Vector<std::unique_ptr<Instruction> > strings;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > imports;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > entryPoints;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > executionModes;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > names;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > lines;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > decorations;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > constantsTypesGlobals;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > externals;\n    dxil_spv::Vector<std::unique_ptr<Function> > functions;\n\n    // not output, internally used for quick & dirty canonical (unique) creation\n    dxil_spv::Vector<Instruction*> groupedConstants[OpConstant];  // all types appear before OpConstant\n    dxil_spv::Vector<Instruction*> groupedTypes[OpConstant];\n    dxil_spv::Vector<Instruction*> coopmatConstants;  // all types appear before OpConstant\n    dxil_spv::Vector<Instruction*> coopmatTypes;\n    Instruction *acceleration_structure_type = nullptr;\n    Instruction *ray_query_type = nullptr;\n    Instruction *hit_object_nv_type = nullptr;\n\n    // stack of switches\n    std::stack<Block*> switchMerges;\n\n    // Our loop stack.\n    std::stack<LoopBlocks> loops;\n\n    // The stream for outputting warnings and errors.\n    SpvBuildLogger* logger;\n\n    dxil_spv::Vector<std::pair<dxil_spv::String, spv::Id>> importIDCache;\n};  // end Builder class\n\n};  // end spv namespace\n\n#endif // SpvBuilder_H\n"
  },
  {
    "path": "third_party/glslang-spirv/spvIR.h",
    "content": "//\n// Copyright (C) 2014 LunarG, Inc.\n//\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//    Redistributions of source code must retain the above copyright\n//    notice, this list of conditions and the following disclaimer.\n//\n//    Redistributions in binary form must reproduce the above\n//    copyright notice, this list of conditions and the following\n//    disclaimer in the documentation and/or other materials provided\n//    with the distribution.\n//\n//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its\n//    contributors may be used to endorse or promote products derived\n//    from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n// SPIRV-IR\n//\n// Simple in-memory representation (IR) of SPIRV.  Just for holding\n// Each function's CFG of blocks.  Has this hierarchy:\n//  - Module, which is a list of\n//    - Function, which is a list of\n//      - Block, which is a list of\n//        - Instruction\n//\n\n#pragma once\n#ifndef spvIR_H\n#define spvIR_H\n\n#include \"spirv.hpp\"\n#include \"thread_local_allocator.hpp\"\n\n#include <algorithm>\n#include <cassert>\n#include <functional>\n#include <iostream>\n#include <memory>\n#include <utility>\n\nnamespace spv {\n\nclass Block;\nclass Function;\nclass Module;\n\nconst Id NoResult = 0;\nconst Id NoType = 0;\n\nconst Decoration NoPrecision = DecorationMax;\n\n#ifdef __GNUC__\n#   define POTENTIALLY_UNUSED __attribute__((unused))\n#else\n#   define POTENTIALLY_UNUSED\n#endif\n\nPOTENTIALLY_UNUSED\nconst MemorySemanticsMask MemorySemanticsAllMemory =\n                (MemorySemanticsMask)(MemorySemanticsSequentiallyConsistentMask |\n                                      MemorySemanticsUniformMemoryMask |\n                                      MemorySemanticsSubgroupMemoryMask |\n                                      MemorySemanticsWorkgroupMemoryMask |\n                                      MemorySemanticsCrossWorkgroupMemoryMask |\n                                      MemorySemanticsAtomicCounterMemoryMask |\n                                      MemorySemanticsImageMemoryMask);\n\n//\n// SPIR-V IR instruction.\n//\n\nclass Instruction {\npublic:\n    Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }\n    explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }\n    virtual ~Instruction() {}\n    void addIdOperand(Id id) { operands.push_back(id); }\n    void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }\n    void addStringOperand(const char* str)\n    {\n        unsigned int word;\n        char* wordString = (char*)&word;\n        char* wordPtr = wordString;\n        int charCount = 0;\n        char c;\n        do {\n            c = *(str++);\n            *(wordPtr++) = c;\n            ++charCount;\n            if (charCount == 4) {\n                addImmediateOperand(word);\n                wordPtr = wordString;\n                charCount = 0;\n            }\n        } while (c != 0);\n\n        // deal with partial last word\n        if (charCount > 0) {\n            // pad with 0s\n            for (; charCount < 4; ++charCount)\n                *(wordPtr++) = 0;\n            addImmediateOperand(word);\n        }\n    }\n    void setBlock(Block* b) { block = b; }\n    Block* getBlock() const { return block; }\n    Op getOpCode() const { return opCode; }\n    int getNumOperands() const { return (int)operands.size(); }\n    Id getResultId() const { return resultId; }\n    void setResultId(Id id) { resultId = id; }\n    Id getTypeId() const { return typeId; }\n    Id getIdOperand(int op) const { return operands[op]; }\n    void setIdOperand(int op, spv::Id id) { operands[op] = id; }\n    unsigned int getImmediateOperand(int op) const { return operands[op]; }\n\n    // Write out the binary form.\n    void dump(dxil_spv::Vector<unsigned int>& out) const\n    {\n        // Compute the wordCount\n        unsigned int wordCount = 1;\n        if (typeId)\n            ++wordCount;\n        if (resultId)\n            ++wordCount;\n        wordCount += (unsigned int)operands.size();\n\n        // Write out the beginning of the instruction\n        out.push_back(((wordCount) << WordCountShift) | opCode);\n        if (typeId)\n            out.push_back(typeId);\n        if (resultId)\n            out.push_back(resultId);\n\n        // Write out the operands\n        for (int op = 0; op < (int)operands.size(); ++op)\n            out.push_back(operands[op]);\n    }\n\n    DXIL_SPV_OVERRIDE_NEW_DELETE\n\nprotected:\n    Instruction(const Instruction&);\n    Id resultId;\n    Id typeId;\n    Op opCode;\n    dxil_spv::Vector<Id> operands;\n    Block* block;\n};\n\n//\n// SPIR-V IR block.\n//\n\nclass Block {\npublic:\n    Block(Id id, Function& parent);\n    virtual ~Block()\n    {\n    }\n\n    Id getId() { return instructions.front()->getResultId(); }\n\n    Function& getParent() const { return parent; }\n    void addInstruction(std::unique_ptr<Instruction> inst);\n    void addPredecessor(Block* pred) { predecessors.push_back(pred); pred->successors.push_back(this);}\n    void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }\n    const dxil_spv::Vector<Block*>& getPredecessors() const { return predecessors; }\n    const dxil_spv::Vector<Block*>& getSuccessors() const { return successors; }\n    const dxil_spv::Vector<std::unique_ptr<Instruction> >& getInstructions() const {\n        return instructions;\n    }\n    void setUnreachable() { unreachable = true; }\n    bool isUnreachable() const { return unreachable; }\n    // Returns the block's merge instruction, if one exists (otherwise null).\n    const Instruction* getMergeInstruction() const {\n        if (instructions.size() < 2) return nullptr;\n        const Instruction* nextToLast = (instructions.cend() - 2)->get();\n        switch (nextToLast->getOpCode()) {\n            case OpSelectionMerge:\n            case OpLoopMerge:\n                return nextToLast;\n            default:\n                return nullptr;\n        }\n        return nullptr;\n    }\n\n    void rewritePhiIncoming(spv::Id from_id, spv::Id to_id);\n\n    bool isTerminated() const\n    {\n        switch (instructions.back()->getOpCode()) {\n        case OpBranch:\n        case OpBranchConditional:\n        case OpSwitch:\n        case OpKill:\n        case OpReturn:\n        case OpReturnValue:\n        case OpUnreachable:\n            return true;\n        default:\n            return false;\n        }\n    }\n\n    void dump(dxil_spv::Vector<unsigned int>& out) const\n    {\n        instructions[0]->dump(out);\n        for (int i = 0; i < (int)localVariables.size(); ++i)\n            localVariables[i]->dump(out);\n        for (int i = 1; i < (int)instructions.size(); ++i)\n            instructions[i]->dump(out);\n    }\n\n    DXIL_SPV_OVERRIDE_NEW_DELETE\n\nprotected:\n    Block(const Block&);\n    Block& operator=(Block&);\n\n    // To enforce keeping parent and ownership in sync:\n    friend Function;\n\n    dxil_spv::Vector<std::unique_ptr<Instruction> > instructions;\n    dxil_spv::Vector<Block*> predecessors, successors;\n    dxil_spv::Vector<std::unique_ptr<Instruction> > localVariables;\n    Function& parent;\n\n    // track whether this block is known to be uncreachable (not necessarily\n    // true for all unreachable blocks, but should be set at least\n    // for the extraneous ones introduced by the builder).\n    bool unreachable;\n};\n\n// Traverses the control-flow graph rooted at root in an order suited for\n// readable code generation.  Invokes callback at every node in the traversal\n// order.\nvoid inReadableOrder(Block* root, std::function<void(Block*)> callback);\n\n//\n// SPIR-V IR Function.\n//\n\nclass Function {\npublic:\n    Function(Id id, Id resultType, Id functionType, Id firstParam, Module& parent);\n    virtual ~Function()\n    {\n        for (int i = 0; i < (int)parameterInstructions.size(); ++i)\n            delete parameterInstructions[i];\n\n        for (int i = 0; i < (int)blocks.size(); ++i)\n            delete blocks[i];\n    }\n    Id getId() const { return functionInstruction.getResultId(); }\n    Id getParamId(int p) { return parameterInstructions[p]->getResultId(); }\n\n    void addBlock(Block* block) { blocks.push_back(block); }\n    void removeBlock(Block* block)\n    {\n        auto found = find(blocks.begin(), blocks.end(), block);\n        assert(found != blocks.end());\n        blocks.erase(found);\n        delete block;\n    }\n\n    Module& getParent() const { return parent; }\n    Block* getEntryBlock() const { return blocks.front(); }\n    Block* getLastBlock() const { return blocks.back(); }\n    const dxil_spv::Vector<Block*>& getBlocks() const { return blocks; }\n    void addLocalVariable(std::unique_ptr<Instruction> inst);\n    Id getReturnType() const { return functionInstruction.getTypeId(); }\n\n    void moveLocalDeclarationsFrom(Function* other);\n\n    void setImplicitThis() { implicitThis = true; }\n    bool hasImplicitThis() const { return implicitThis; }\n\n    void dump(dxil_spv::Vector<unsigned int>& out) const\n    {\n        // OpFunction\n        functionInstruction.dump(out);\n\n        // OpFunctionParameter\n        for (int p = 0; p < (int)parameterInstructions.size(); ++p)\n            parameterInstructions[p]->dump(out);\n\n        // Blocks\n        inReadableOrder(blocks[0], [&out](const Block* b) { b->dump(out); });\n        Instruction end(0, 0, OpFunctionEnd);\n        end.dump(out);\n    }\n\n    DXIL_SPV_OVERRIDE_NEW_DELETE\n\nprotected:\n    Function(const Function&);\n    Function& operator=(Function&);\n\n    Module& parent;\n    Instruction functionInstruction;\n    dxil_spv::Vector<Instruction*> parameterInstructions;\n    dxil_spv::Vector<Block*> blocks;\n    bool implicitThis;  // true if this is a member function expecting to be passed a 'this' as the first argument\n};\n\n//\n// SPIR-V IR Module.\n//\n\nclass Module {\npublic:\n    Module() {}\n    virtual ~Module()\n    {\n        // TODO delete things\n    }\n\n    void addFunction(Function *fun) { functions.push_back(fun); }\n\n    void mapInstruction(Instruction *instruction)\n    {\n        spv::Id resultId = instruction->getResultId();\n        // map the instruction's result id\n        if (resultId >= idToInstruction.size())\n            idToInstruction.resize(resultId + 16);\n        idToInstruction[resultId] = instruction;\n    }\n\n    Instruction* getInstruction(Id id) const\n    {\n        if (id < idToInstruction.size())\n            return idToInstruction[id];\n        else\n            return nullptr;\n    }\n\n    const dxil_spv::Vector<Function*>& getFunctions() const { return functions; }\n    spv::Id getTypeId(Id resultId) const { return idToInstruction[resultId]->getTypeId(); }\n    StorageClass getStorageClass(Id typeId) const\n    {\n        assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);\n        return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0);\n    }\n\n    void dump(dxil_spv::Vector<unsigned int>& out) const\n    {\n        for (int f = 0; f < (int)functions.size(); ++f)\n            functions[f]->dump(out);\n    }\n\n    DXIL_SPV_OVERRIDE_NEW_DELETE\n\nprotected:\n    Module(const Module&);\n    dxil_spv::Vector<Function*> functions;\n\n    // map from result id to instruction having that result id\n    dxil_spv::Vector<Instruction*> idToInstruction;\n\n    // map from a result id to its type id\n};\n\n//\n// Implementation (it's here due to circular type definitions).\n//\n\n// Add both\n// - the OpFunction instruction\n// - all the OpFunctionParameter instructions\n__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)\n    : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false)\n{\n    // OpFunction\n    functionInstruction.addImmediateOperand(FunctionControlMaskNone);\n    functionInstruction.addIdOperand(functionType);\n    parent.mapInstruction(&functionInstruction);\n    parent.addFunction(this);\n\n    // OpFunctionParameter\n    Instruction* typeInst = parent.getInstruction(functionType);\n    int numParams = typeInst->getNumOperands() - 1;\n    for (int p = 0; p < numParams; ++p) {\n        Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), OpFunctionParameter);\n        parent.mapInstruction(param);\n        parameterInstructions.push_back(param);\n    }\n}\n\n__inline void Function::moveLocalDeclarationsFrom(Function* other)\n{\n    blocks[0]->localVariables.clear();\n    std::swap(blocks[0]->localVariables, other->blocks[0]->localVariables);\n\n    // There shouldn't be any actual code here yet, just Undef declarations, if anything.\n    for (auto &b : other->blocks)\n    {\n        for (auto &inst : b->instructions)\n        {\n            if (inst->getOpCode() == spv::OpUndef)\n            {\n                blocks[0]->instructions.push_back(std::move(inst));\n                inst = {};\n            }\n        }\n\n        auto itr = std::remove_if(b->instructions.begin(), b->instructions.end(),\n                [](const std::unique_ptr<spv::Instruction> &inst) {\n                    return !inst;\n                });\n        b->instructions.erase(itr, b->instructions.end());\n    }\n}\n\n__inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)\n{\n    Instruction* raw_instruction = inst.get();\n    blocks[0]->addLocalVariable(std::move(inst));\n    parent.mapInstruction(raw_instruction);\n}\n\n__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)\n{\n    instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, OpLabel)));\n    instructions.back()->setBlock(this);\n    parent.getParent().mapInstruction(instructions.back().get());\n}\n\n__inline void Block::addInstruction(std::unique_ptr<Instruction> inst)\n{\n    Instruction* raw_instruction = inst.get();\n    instructions.push_back(std::move(inst));\n    raw_instruction->setBlock(this);\n    if (raw_instruction->getResultId())\n        parent.getParent().mapInstruction(raw_instruction);\n}\n\n__inline void Block::rewritePhiIncoming(spv::Id from_id, spv::Id to_id)\n{\n    for (auto &inst : instructions)\n    {\n        if (inst->getOpCode() == spv::OpPhi)\n        {\n            for (int i = 1, n = inst->getNumOperands(); i < n; i += 2)\n                if (inst->getIdOperand(i) == from_id)\n                    inst->setIdOperand(i, to_id);\n        }\n    }\n}\n\n};  // end spv namespace\n\n#endif // spvIR_H\n"
  },
  {
    "path": "util/thread_local_allocator.cpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"thread_local_allocator.hpp\"\n#include <assert.h>\n#include <stdint.h>\n#include <memory>\n\nnamespace dxil_spv\n{\nstatic constexpr size_t BLOCK_SIZE = 64 * 1024;\n\nclass ChainAllocator\n{\npublic:\n\tvoid reset();\n\tvoid *allocate(size_t size);\n\nprivate:\n\tstruct MallocDeleter\n\t{\n\t\tvoid operator()(void *ptr)\n\t\t{\n\t\t\tfree(ptr);\n\t\t}\n\t};\n\n\tstruct Block\n\t{\n\t\texplicit Block(size_t size);\n\t\tvoid *allocate(size_t size);\n\n\t\tstd::unique_ptr<uint8_t, MallocDeleter> block;\n\t\tsize_t offset = 0;\n\t\tsize_t block_size = 0;\n\t};\n\tstd::vector<Block> blocks;\n\tstd::vector<Block> huge_blocks;\n\tunsigned block_index = 0;\n\n\tbool ensure_block();\n\tvoid *allocate_huge(size_t size);\n};\n\nChainAllocator::Block::Block(size_t size)\n\t: block(static_cast<uint8_t *>(malloc(size))), block_size(size)\n{\n}\n\nvoid *ChainAllocator::Block::allocate(size_t size)\n{\n\toffset = (offset + 15) & ~size_t(15);\n\tif (offset + size <= block_size)\n\t{\n\t\tvoid *ret = block.get() + offset;\n\t\toffset += size;\n\t\treturn ret;\n\t}\n\telse\n\t\treturn nullptr;\n}\n\nstatic thread_local ChainAllocator *allocator;\n\nvoid ChainAllocator::reset()\n{\n\tfor (auto &block : blocks)\n\t\tblock.offset = 0;\n\tblock_index = 0;\n\thuge_blocks.clear();\n}\n\nbool ChainAllocator::ensure_block()\n{\n\tblocks.emplace_back(BLOCK_SIZE);\n\treturn bool(blocks.back().block);\n}\n\nvoid *ChainAllocator::allocate_huge(size_t size)\n{\n\thuge_blocks.emplace_back(size);\n\treturn huge_blocks.back().block.get();\n}\n\nvoid *ChainAllocator::allocate(size_t size)\n{\n\tif (size > BLOCK_SIZE)\n\t\treturn allocate_huge(size);\n\n\tif (block_index >= blocks.size() && !ensure_block())\n\t\treturn nullptr;\n\n\tvoid *ptr = blocks[block_index].allocate(size);\n\tif (ptr)\n\t\treturn ptr;\n\n\tblock_index++;\n\tif (block_index >= blocks.size() && !ensure_block())\n\t\treturn nullptr;\n\n\treturn blocks[block_index].allocate(size);\n}\n\nvoid *allocate_in_thread(size_t size)\n{\n\tif (!allocator)\n\t\treturn malloc(size);\n\n\treturn allocator->allocate(size);\n}\n\nvoid free_in_thread(void *ptr)\n{\n\tif (!allocator)\n\t{\n\t\tfree(ptr);\n\t\treturn;\n\t}\n\n\t// Don't bother freeing ...\n}\n\nvoid begin_thread_allocator_context()\n{\n\tassert(!allocator);\n\tallocator = new ChainAllocator;\n}\n\nvoid end_thread_allocator_context()\n{\n\tassert(allocator);\n\tdelete allocator;\n\tallocator = nullptr;\n}\n\nvoid reset_thread_allocator_context()\n{\n\tassert(allocator);\n\tallocator->reset();\n}\n}\n"
  },
  {
    "path": "util/thread_local_allocator.hpp",
    "content": "/* Copyright (c) 2019-2022 Hans-Kristian Arntzen for Valve Corporation\n *\n * SPDX-License-Identifier: MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#pragma once\n\n#include <vector>\n#include <unordered_set>\n#include <unordered_map>\n#include <set>\n#include <string>\n#include <sstream>\n#include <functional>\n#include <stdlib.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stddef.h>\n\nnamespace dxil_spv\n{\nvoid *allocate_in_thread(std::size_t size);\nvoid free_in_thread(void *ptr);\n\ntemplate <typename T>\nclass ThreadLocalAllocator\n{\npublic:\n\tusing value_type = T;\n\n\tThreadLocalAllocator() noexcept = default;\n\ttemplate <typename U>\n\tThreadLocalAllocator(const ThreadLocalAllocator<U> &) noexcept {}\n\n\tvalue_type *allocate(size_t n)\n\t{\n\t\treturn static_cast<value_type *>(allocate_in_thread(sizeof(T) * n));\n\t}\n\n\tvoid deallocate(value_type *p, std::size_t)\n\t{\n\t\tfree_in_thread(p);\n\t}\n\n\tusing is_always_equal = std::true_type;\n};\n\ntemplate <typename A, typename B>\nstatic inline bool operator==(const ThreadLocalAllocator<A> &, const ThreadLocalAllocator<B> &)\n{\n\treturn true;\n}\n\ntemplate <typename A, typename B>\nstatic inline bool operator!=(const ThreadLocalAllocator<A> &, const ThreadLocalAllocator<B> &)\n{\n\treturn false;\n}\n\ntemplate <typename T>\nusing Vector = std::vector<T, ThreadLocalAllocator<T>>;\n\ntemplate <typename T, typename Hash = std::hash<T>>\nusing UnorderedSet = std::unordered_set<T, Hash, std::equal_to<T>, ThreadLocalAllocator<T>>;\n\ntemplate <typename T>\nusing Set = std::set<T, std::less<T>, ThreadLocalAllocator<T>>;\n\nusing String = std::basic_string<char, std::char_traits<char>, ThreadLocalAllocator<char>>;\nusing StringStream = std::basic_ostringstream<char, std::char_traits<char>, ThreadLocalAllocator<char>>;\n\ntemplate <typename Key, typename Value, typename Hash = std::hash<Key>>\nusing UnorderedMap = std::unordered_map<Key, Value, Hash, std::equal_to<Key>, ThreadLocalAllocator<std::pair<const Key, Value>>>;\n\nvoid begin_thread_allocator_context();\nvoid end_thread_allocator_context();\nvoid reset_thread_allocator_context();\n\ntemplate <typename T>\nstatic inline String to_string(T&& t)\n{\n\tauto v = std::to_string(std::forward<T>(t));\n\tString ret(v.begin(), v.end());\n\treturn ret;\n}\n}\n\nnamespace std\n{\ntemplate <>\nstruct hash<dxil_spv::String>\n{\n\tsize_t operator()(const dxil_spv::String &str) const\n\t{\n\t\tuint64_t h = 0xcbf29ce484222325ull;\n\t\tfor (auto c : str)\n\t\t\th = (h * 0x100000001b3ull) ^ uint8_t(c);\n\t\treturn size_t(h);\n\t}\n};\n}\n\n#define DXIL_SPV_OVERRIDE_NEW_DELETE \\\n\tvoid *operator new(size_t size) { return ::dxil_spv::allocate_in_thread(size); } \\\n\tvoid operator delete(void *ptr) { ::dxil_spv::free_in_thread(ptr); } \\\n\tvoid *operator new[](size_t size) { return ::dxil_spv::allocate_in_thread(size); } \\\n\tvoid operator delete[](void *ptr) { ::dxil_spv::free_in_thread(ptr); }\n"
  }
]